00. 目录
文章目录
00. 目录01. 概述02. 开发环境03. 创建产品04. 注册设备05. C语言工程下载06. 编译OpenSSL库07. 编译paho库08. 编译C参考代码09. 属性上报10. 接收下发命令11. 通过云端获取设备上报的数据12. 附录01. 概述
基于C代码演示设备通过MQTTS/MQTT协议接入华为云物联网平台,通过平台接口实现南向“数据上报”、“命令下发”的功能,通过应用侧的示例代码接收北向服务端订阅的消息示例。以智慧路灯为例,设备将光照强度等信息上报到IoT平台,应用服务器再接收从平台推送来的设备数据。
02. 开发环境
Linux操作系统,且已安装好gcc(建议4.8及以上版本)。作者使用Ubuntu20.04系统。
03. 创建产品
产品模型是用来描述设备能力的文件,通过JSON的格式定义了设备的基本属性、上报数据和下发命令的消息格式。定义产品模型,即在物联网平台构建一款设备的抽象模型,使平台理解该款设备的功能。
3.1 访问设备接入服务,单击“管理控制台”进入设备接入控制台。
3.2 选择左侧导航栏的“产品”,单击右上角“创建产品”。
3.3 在弹出的窗口中,可以参考图中的内容填写。
3.4 下载模型文件,该模型文件已开发完毕(由开发产品模型开发完毕的产品模型导出)。
3.5 创建成功后,点击刚创建的产品,然后点击上传模型文件(无需解压,并且压缩包的名称不能有括号),上传刚下载的模型文件
04. 注册设备
4.1 选择设备接入服务左侧导航栏的“设备”,选中右上角的“注册设备”按钮。
4.2 在弹出的窗口中,可以参考图中的内容填写(产品需要选择刚刚创建的产品,密钥不填写,则由平台自动生成,这里是由平台自动生成)然后点击“确定”按钮。
4.3 设备创建成功后,需要保存一下设备ID和密钥(后续设备连接的时候需要用到)。
05. C语言工程下载
5.1 下载quickStart©样例。
5.2 将代码拷贝到Ubuntu运行环境中。代码文件层级如下图。
deng@local:~/iot$ tree quickStartCquickStartC├── conf│ └── rootcert.pem├── include│ ├── base│ │ ├── MQTTAsync.h│ │ ├── MQTTClient.h│ │ ├── MQTTClientPersistence.h│ │ ├── MQTTProperties.h│ │ ├── MQTTReasonCodes.h│ │ └── MQTTSubscribeOpts.h│ ├── openssl│ └── util│ └── string_util.h├── lib├── Makefile└── src├── mqtt_c_demo.c└── util└── string_util.c8 directories, 11 filesdeng@local:~/iot$ 代码目录简述:src:源码目录mqtt_c_demo:demo核心源码;util/string_util.c:工具资源文件;conf:证书目录rootcert.pem:设备校验平台身份的证书,用于设备侧接入物联网平台登录鉴权使用;include: 头文件目录base目录:存放依赖的paho头文件openssl目录:存放依赖的openssl头文件util目录:存放依赖的工具资源头文件lib:依赖库文件libcrypto.so*/libssl.so*: openssl库文件libpaho-mqtt3as.so*: paho库文件Makefile:Makefile文件
06. 编译OpenSSL库
6.1 下载openssl,上传到Ubuntu任意目录下,并使用如下命令解压:
deng@local:~/iot$ tar -xzvf openssl-1.1.1d.tar.gz
6.2 执行以下命令进入openssl源码目录
deng@local:~/iot$ cd openssl-1.1.1d/
6.3 创建openssl编译后的目录
deng@local:~/iot/openssl-1.1.1d$ mkdir ~/openssl
6.4 创建配置文件目录
deng@local:~/iot/openssl-1.1.1d$ mkdir ~/openssl/config
6.5 运行如下配置命令
deng@local:~/iot/openssl-1.1.1d$ ./config shared --prefix=/home/deng/openssl --openssldir=/home/deng/openssl/config
其中“prefix”是安装目录,“openssldir”是配置文件目录,“shared”作用是生成动态链接库(即.so库) 。
如果编译有问题,配置命令加上no-asm(表示不使用汇编代码)
./config no-asm shared --prefix=/home/deng/openssl --openssldir=/home/deng/openssl/config
6.6 在openssl源码目录下,运行make depend命令。
deng@local:~/iot/openssl-1.1.1d$ make depend
6.7 运行make命令进行编译
deng@local:~/iot/openssl-1.1.1d$ make
6.8 安装openssl
deng@local:~/iot/openssl-1.1.1d$ make install
6.9 拷贝动态库和头文件
在配置的openssl安装目录下home/deng/openssl找到lib目录,有生成的库文件:“libcrypto.so.1.1”、“libssl.so.1.1”和软链接“libcrypto.so”、“libssl.so”,请将这些文件拷贝到quickStart©的lib文件夹下(同时将/home/deng/openssl/include/openssl里的内容拷贝到quickStart©的include/openssl下)。
deng@local:~/openssl/lib$ pwd/home/deng/openssl/libdeng@local:~/openssl/lib$ cp libcrypto.so.1.1 libssl.so.1.1 libcrypto.so libssl.so /home/deng/iot/quickStartC/lib/deng@local:~/openssl/include/openssl$ pwd/home/deng/openssl/include/openssldeng@local:~/openssl/include/openssl$ cp * /home/deng/iot/quickStartC/include/openssl/deng@local:~/openssl/include/openssl$
温馨提示:
有的编译工具是32位的,如果在64位的linux机器上使用,这时只要将Makefile中的-m64都删除,再进行编译即可。
07. 编译paho库
7.1下载paho.mqtt.c源码。
7.2 上传到Ubuntu编译机。
7.3 解压
deng@local:~/iot$ tar -xzvf paho.mqtt.c-1.3.2.tar.gz
7.4 通过如下命令进行编辑Makefile
deng@local:~/iot/paho.mqtt.c-1.3.2$ pwd/home/deng/iot/paho.mqtt.c-1.3.2deng@local:~/iot/paho.mqtt.c-1.3.2$ vim Makefile +134
7.5 在134行之后添加下面两行(自定义的openssl的头文件和库文件)
CFLAGS += -I/home/deng/openssl/includeLDFLAGS += -L/home/deng/openssl/lib -lrt
7.6 修改Makefile中的一下几行
7.7 执行清空命令
deng@local:~/iot/paho.mqtt.c-1.3.2$ make clean
7.8 执行编译命令
deng@local:~/iot/paho.mqtt.c-1.3.2$ make
7.9 编译完成后,可以在build/output目录下看到编译成功的库。
deng@local:~/iot/paho.mqtt.c-1.3.2/build/output$ pwd/home/deng/iot/paho.mqtt.c-1.3.2/build/outputdeng@local:~/iot/paho.mqtt.c-1.3.2/build/output$ lslibpaho-mqtt3a.so libpaho-mqtt3a.so.1.3 libpaho-mqtt3as.so.1 libpaho-mqtt3c.so libpaho-mqtt3c.so.1.3 libpaho-mqtt3cs.so.1 sampleslibpaho-mqtt3a.so.1 libpaho-mqtt3as.solibpaho-mqtt3as.so.1.3 libpaho-mqtt3c.so.1 libpaho-mqtt3cs.solibpaho-mqtt3cs.so.1.3 testdeng@local:~/iot/paho.mqtt.c-1.3.2/build/output$
7.10 拷贝paho库文件。
当前SDK仅用到了libpaho-mqtt3as,请将**“libpaho-mqtt3as.so”和“libpaho-mqtt3as.so.1”**文件拷贝到quickStart©的lib文件夹下。(同时回到paho源代码路径,进入src目录,将MQTTAsync.h、MQTTClient.h、MQTTClientPersistence.h、MQTTProperties.h、MQTTReasonCodes.h、MQTTSubscribeOpts.h拷贝到quickStart©的include/base文件夹下)。
deng@local:~/iot/paho.mqtt.c-1.3.2/build/output$ pwd/home/deng/iot/paho.mqtt.c-1.3.2/build/outputdeng@local:~/iot/paho.mqtt.c-1.3.2/build/output$ cp libpaho-mqtt3as.so libpaho-mqtt3as.so.1 /home/deng/iot/quickStartC/lib/deng@local:~/iot/paho.mqtt.c-1.3.2/build/output$ deng@local:~/iot/paho.mqtt.c-1.3.2/src$ cp MQTTAsync.h MQTTClient.h MQTTClientPersistence.h MQTTProperties.h MQTTReasonCodes.h MQTTSubscribeOpts.h MQTTExportDeclarations.h /home/deng/iot/quickStartC/include/base/deng@local:~/iot/paho.mqtt.c-1.3.2/src$
08. 编译C参考代码
设备或网关在接入物联网平台时首先需要和平台建立连接,从而将设备或网关与平台进行关联。开发者通过传入设备信息,将设备或网关连接到物联网平台。
8.1 设置参数,只需修改username和password。
char *uri = "ssl://iot--north-:8883";int port = 8883;char *username = "yourDeviceId"; //设备Id,在平台注册设备成功后返回char *password = "yourSecret"; //密钥,在平台注册设备成功后返回
温馨提示
MQTTS为8883端口接入,如果使用MQTT协议接入,url为:tcp://iot--north-:1883, port为1883。
8.2 编译出现如下错误
mqtt_c_demo.o:在函数‘mqtt_connect_failure’中:/home/deng/iot/quickStartC/./src/mqtt_c_demo.c:61:对‘pow’未定义的引用collect2: error: ld returned 1 exit statusMakefile:27: recipe for target 'MQTT_Demo.o' failedmake: *** [MQTT_Demo.o] Error 1
8.3 修改Makefile
deng@local:~/iot/quickStartC$ vim Makefile +27# 增加-lm$(TARGET): $(OBJS)$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS) -lm
8.4 再次编译
deng@local:~/iot/quickStartC$ make
8.5 运行
执行make进行编译。如果是32位的操作系统,请删除Makefile中的"-m64"。
执行**export LD_LIBRARY_PATH=./lib/**加载库文件。
运行**./MQTT_Demo.o**。
8.6 连接成功后,打印“connect success”,同时在控制台可看到设备已在线。
deng@local:~/iot/quickStartC$ ./MQTT_Demo.omqtt_connect() mqttClientCreateFlag = 1.begin to connect the server.connect success.
09. 属性上报
属性上报是指设备主动向平台上报自己的属性(该示例代码已实现自动定时上报功能,可参考下一节在iot平台查看设备上报的数据内容)
//publish datachar *payload = "{\"services\":[{\"service_id\":\"BasicData\",\"properties\":{\"luminance\":32},\"eventTime\":NULL}]}";
消息体payload组装格式为JSON,其中service_id要与产品模型中的定义对应,properties是设备的属性;luminance表示路灯亮度;event_time为可选项,为设备采集数据UTC时间,不填写默认使用系统时间。
设备上报属性成功后,demo控制台中会打印“publish success”字样。
同时在设备详情页面查看到上报的属性:
10. 接收下发命令
订阅了命令Topic后,可以在控制台下发同步命令。
命令下发后,demo中接收到命令:
mqtt_message_arrive() success, the topic is $oc/devices/64787013f4d13061fc88b66f_Test1111/sys/commands/request_id=6f25785d-d21f-42cf-b2ac-9ad9fc6f0ae5, the payload is {"paras":{"switch":"OFF"},"service_id":"BasicData","command_name":"lightControl"}
11. 通过云端获取设备上报的数据
当数据到达平台后,应用服务器可以使用AMQP来接收推送消息。
12. 附录
参考:华为云社区
下载:基于C示例代码的快速体验代码