Symfoware

Symfowareについての考察blog

C言語でMQTTクライアントを動作させる(paho.mqtt.embedded-c)

MQTTブローカー「mosquitto」をインストール。
Pythonクライアントからイベントの送受信を行ってみました。
MQTTブローカー mosquittoをUbuntu 18.04へインストールする
MQTTクライアントpahoでmosquittoに接続する(Python使用)

MQTTクライアントは各種用意されていますが、
今回はC言語にトライしてみようと思います。
Embedded MQTT C/C++ Client Libraries


ソースの取得



gitリポジトリはこちら。
https://github.com/eclipse/paho.mqtt.embedded-c

ソースを取得します。


$ git clone https://github.com/eclipse/paho.mqtt.embedded-c





クライアントプログラム



プログラムの作成はこちらが非常に参考になりました。
ESP8266にMQTTを実装する (その1)

ダウンロードしたソースの中で必要なのは
MQTTPacket/src
の中身一式です。

912_01.png

「src」を「packet」にリネームして、これから作成するプログラムを配置する
ディレクトリにコピーしました。

912_02.png

もう一箇所
「samples」にある
・pub0sub1.c
・transport.c
・transport.h

をコピーしておきます。

912_03.png

最終的なフォルダ階層はこうなりました。

912_04.png


ここから、「pub0sub1.c」を一箇所編集します。
59行目、「char *host」の指定をMQTTサーバーのIPアドレスに変更。


  1. /*******************************************************************************
  2. * Copyright (c) 2014 IBM Corp.
  3. *
  4. * All rights reserved. This program and the accompanying materials
  5. * are made available under the terms of the Eclipse Public License v1.0
  6. * and Eclipse Distribution License v1.0 which accompany this distribution.
  7. *
  8. * The Eclipse Public License is available at
  9. *    http://www.eclipse.org/legal/epl-v10.html
  10. * and the Eclipse Distribution License is available at
  11. * http://www.eclipse.org/org/documents/edl-v10.php.
  12. *
  13. * Contributors:
  14. *    Ian Craggs - initial API and implementation and/or initial documentation
  15. *    Sergio R. Caprile - clarifications and/or documentation extension
  16. *******************************************************************************/
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include "MQTTPacket.h"
  21. #include "transport.h"
  22. /* This is in order to get an asynchronous signal to stop the sample,
  23. as the code loops waiting for msgs on the subscribed topic.
  24. Your actual code will depend on your hw and approach*/
  25. #include <signal.h>
  26. int toStop = 0;
  27. void cfinish(int sig)
  28. {
  29.     signal(SIGINT, NULL);
  30.     toStop = 1;
  31. }
  32. void stop_init(void)
  33. {
  34.     signal(SIGINT, cfinish);
  35.     signal(SIGTERM, cfinish);
  36. }
  37. /* */
  38. int main(int argc, char *argv[])
  39. {
  40.     MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
  41.     int rc = 0;
  42.     int mysock = 0;
  43.     unsigned char buf[200];
  44.     int buflen = sizeof(buf);
  45.     int msgid = 1;
  46.     MQTTString topicString = MQTTString_initializer;
  47.     int req_qos = 0;
  48.     char* payload = "mypayload";
  49.     int payloadlen = strlen(payload);
  50.     int len = 0;
  51.     // MQTTサーバーのIPに変更
  52.     char *host = "192.168.1.102";
  53.     int port = 1883;
  54.     stop_init();
  55.     if (argc > 1)
  56.         host = argv[1];
  57.     if (argc > 2)
  58.         port = atoi(argv[2]);
  59.     mysock = transport_open(host, port);
  60.     if(mysock < 0)
  61.         return mysock;
  62.     printf("Sending to hostname %s port %d\n", host, port);
  63.     data.clientID.cstring = "me";
  64.     data.keepAliveInterval = 20;
  65.     data.cleansession = 1;
  66.     data.username.cstring = "testuser";
  67.     data.password.cstring = "testpassword";
  68.     len = MQTTSerialize_connect(buf, buflen, &data);
  69.     rc = transport_sendPacketBuffer(mysock, buf, len);
  70.     /* wait for connack */
  71.     if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK)
  72.     {
  73.         unsigned char sessionPresent, connack_rc;
  74.         if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)
  75.         {
  76.             printf("Unable to connect, return code %d\n", connack_rc);
  77.             goto exit;
  78.         }
  79.     }
  80.     else
  81.         goto exit;
  82.     /* subscribe */
  83.     topicString.cstring = "substopic";
  84.     len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);
  85.     rc = transport_sendPacketBuffer(mysock, buf, len);
  86.     if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK)     /* wait for suback */
  87.     {
  88.         unsigned short submsgid;
  89.         int subcount;
  90.         int granted_qos;
  91.         rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
  92.         if (granted_qos != 0)
  93.         {
  94.             printf("granted qos != 0, %d\n", granted_qos);
  95.             goto exit;
  96.         }
  97.     }
  98.     else
  99.         goto exit;
  100.     /* loop getting msgs on subscribed topic */
  101.     topicString.cstring = "pubtopic";
  102.     while (!toStop)
  103.     {
  104.         /* transport_getdata() has a built-in 1 second timeout,
  105.         your mileage will vary */
  106.         if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH)
  107.         {
  108.             unsigned char dup;
  109.             int qos;
  110.             unsigned char retained;
  111.             unsigned short msgid;
  112.             int payloadlen_in;
  113.             unsigned char* payload_in;
  114.             int rc;
  115.             MQTTString receivedTopic;
  116.             rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
  117.                     &payload_in, &payloadlen_in, buf, buflen);
  118.             printf("message arrived %.*s\n", payloadlen_in, payload_in);
  119.         }
  120.         printf("publishing reading\n");
  121.         len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen);
  122.         rc = transport_sendPacketBuffer(mysock, buf, len);
  123.     }
  124.     printf("disconnecting\n");
  125.     len = MQTTSerialize_disconnect(buf, buflen);
  126.     rc = transport_sendPacketBuffer(mysock, buf, len);
  127. exit:
  128.     transport_close(mysock);
  129.     return 0;
  130. }



samples/buildを参考にコンパイル。


$ gcc -Wall -c transport.c -Os -s
$ gcc pub0sub1.c transport.o -I ./packet ./packet/MQTTConnectClient.c ./packet/MQTTSerializePublish.c \
./packet/MQTTPacket.c ./packet/MQTTSubscribeClient.c -o pub0sub1 ./packet/MQTTDeserializePublish.c -Os -s \
./packet/MQTTConnectServer.c ./packet/MQTTSubscribeServer.c ./packet/MQTTUnsubscribeServer.c \
./packet/MQTTUnsubscribeClient.c -ggdb



「pub0sub1」が生成されるので実行します。


$ ./pub0sub1



「substopic」にメッセージを送信するとプログラムで受信。
「pubtopic」を監視すると、プログラムからメッセージが送信されていることが確認できます。

912_05.gif




【参考URL】

ESP8266にMQTTを実装する (その1)
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/07/12(木) 22:36:23|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
| ホーム | Ubuntu 18.04にArduino IDEをインストールして、プログラムをArduinoに書き込む>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
https://symfoware.blog.fc2.com/tb.php/2231-bf31050d
この記事にトラックバックする(FC2ブログユーザー)