OpenHarmony上利用Paho MQTT連接云平臺
1. 引言
近年來,物聯(lián)網(wǎng)(Internet of Things, IoT)技術(shù)的快速發(fā)展改變了各行各業(yè),讓設備之間實現(xiàn)了無縫連接和智能互動。從傳感器到智能家電,物聯(lián)網(wǎng)設備需要與云服務進行高效通信,以傳輸數(shù)據(jù)、接收指令并實現(xiàn)遠程管理。這一轉(zhuǎn)變促使了專門針對物聯(lián)網(wǎng)部署需求開發(fā)的專業(yè)物聯(lián)網(wǎng)平臺和通信協(xié)議,如CoAP (Constrained Application Protocol)、AMQP (Advanced Message Queuing Protocol)、DDS (Data Distribution Service)、WebSocket等。除上述協(xié)議外,MQTT (Message Queuing Telemetry Transport)因其適應資源受限設備、簡單易用的設計、強大的消息傳輸能力和廣泛的應用支持而成為物聯(lián)網(wǎng)通信的常用選擇。它不僅滿足了各種物聯(lián)網(wǎng)設備和應用程序之間實時通信的需求,還提供了靈活的部署和擴展選項,適應了不同規(guī)模和復雜度的物聯(lián)網(wǎng)解決方案[1]。
Paho MQTT是一個開源的MQTT庫,由Eclipse Paho項目提供支持。它提供了多種編程語言的實現(xiàn),包括C、C++、Java、Python等,旨在幫助開發(fā)者輕松地在各種設備和平臺上實現(xiàn)MQTT通信協(xié)議。本文專注于將Paho MQTT客戶端庫移植到OpenHarmony項目中的LiteOS內(nèi)核處理器上,如海思Hi3861芯片,實現(xiàn)與云平臺的連接。在OpenHarmony項目的LiteOS內(nèi)核處理器上集成MQTT不僅增強了設備與云端高效通信的能力,還為創(chuàng)建互聯(lián)物聯(lián)網(wǎng)生態(tài)系統(tǒng)的整體目標作出了貢獻。
2. MQTT協(xié)議
MQTT協(xié)議是一種輕量級的、基于發(fā)布/訂閱模式的消息傳輸協(xié)議,最早由IBM開發(fā)于1999年,用于傳感器和施工機器之間的通信。隨后,協(xié)議被開放,成為OASIS (Organization for the Advancement of Structured Information Standards,結(jié)構(gòu)化信息標準推動組織)標準,并在眾多物聯(lián)網(wǎng)應用中得到廣泛應用。MQTT協(xié)議在物聯(lián)網(wǎng)領(lǐng)域起初設計用于傳感器網(wǎng)絡和設備間的低帶寬、高效率通信。其輕量級和簡單的發(fā)布/訂閱模式使得設備能夠節(jié)省能源和帶寬,適用于智能家居、工業(yè)自動化和智能城市等多種場景。
2.1. MQTT的架構(gòu)
MQTT的客戶端是消息發(fā)布者或者消息訂閱者,它們與MQTT Broker進行通信來實現(xiàn)數(shù)據(jù)的傳輸和接收[2]??蛻舳丝梢允歉鞣N設備或應用程序,包括傳感器、嵌入式設備、移動應用等。MQTT的客戶端和Broker之間的關(guān)系如圖1所示。
Figure 1. MQTT network architecture
客戶端在MQTT中的主要功能包括:
發(fā)布消息:客戶端可以向Broker發(fā)布(或發(fā)送)消息,消息可以是任何格式的數(shù)據(jù),通常包含有用的傳感器數(shù)據(jù)、控制命令等。
訂閱主題:客戶端可以向Broker訂閱(或接收)特定的主題(Topic),通過主題來過濾和接收感興趣的消息。主題可以使用通配符來實現(xiàn)更靈活的訂閱規(guī)則。
接收消息:客戶端通過訂閱主題,可以接收來自Broker轉(zhuǎn)發(fā)的消息,并進行相應的處理和分析。
客戶端可以選擇不同的消息服務質(zhì)量(QoS)級別來控制消息傳遞的可靠性和效率,包括至多傳遞一次(QoS 0)、至少傳遞一次(QoS 1)、恰好傳遞一次(QoS 2)。
MQTT的Broker是中介服務器,負責管理客戶端之間的消息傳遞。Broker接收來自發(fā)布者(發(fā)布消息的客戶端)的消息,并確保將這些消息按照訂閱者(訂閱消息的客戶端)的需求正確分發(fā)。Broker在MQTT協(xié)議中的關(guān)鍵作用包括:
消息路由和分發(fā):根據(jù)訂閱關(guān)系,將發(fā)布者發(fā)送的消息分發(fā)給所有訂閱了相關(guān)主題的客戶端。
連接管理:管理客戶端的連接和狀態(tài),確保每個連接的可靠性和安全性。
QoS管理:根據(jù)客戶端設置的QoS級別,確保消息的按時傳遞和確認。
2.2. MQTT的報文
為了讓客戶端和Broker之間進行通信,MQTT協(xié)議定義了不同類型的消息(稱為報文),如CONNECT、CONNACK、PUBLISH、PUBACK、SUBSCRIBE、SUBACK、UNSUBSCRIBE等。報文包含固定報頭、可變報頭(部分報文包含)、負載(部分報文包含)。固定報頭定義了報文類型、控制標志和后續(xù)數(shù)據(jù)長度,可變頭部則依據(jù)報文類型規(guī)定了各自的詳細信息,如后續(xù)消息內(nèi)容、QoS級別等。負載用于攜帶實際數(shù)據(jù)內(nèi)容。這種設計使得MQTT能夠在各種網(wǎng)絡條件下高效傳輸消息,并支持靈活的通信需求和服務質(zhì)量保證。
3. Paho MQTT庫
3.1. 簡介
Paho項目致力于提供開源的、可擴展的消息傳遞協(xié)議實現(xiàn),支持M2M (Machine-to-Machine)和物聯(lián)網(wǎng)的各種應用。它特別關(guān)注設備連接中的物理限制和成本問題。Paho MQTT C是Paho項目的一部分,是專門為C語言開發(fā)的MQTT客戶端庫。Paho MQTT C庫旨在提供一個可靠、高效的實現(xiàn),使開發(fā)者能夠輕松地在C語言環(huán)境中實現(xiàn)MQTT的發(fā)布和訂閱功能[3]。
3.2. 庫文件內(nèi)容
應用于嵌入式的Paho MQTT C庫文件中,能夠被移植的代碼位于MQTTPacket、MQTTClient-C、MQTTClient文件夾。
MQTTPacket文件夾包含了MQTT協(xié)議報文的解析和封裝功能。這些文件提供了處理MQTT協(xié)議中不同報文(如CONNECT、PUBLISH、SUBSCRIBE等)的代碼實現(xiàn)。它們負責將MQTT消息編碼為字節(jié)流(序列化),或者將接收到的字節(jié)流解析為可操作的消息(反序列化)。
MQTTClient-C文件夾包含了MQTT客戶端的C語言實現(xiàn)的核心部分。這些文件實現(xiàn)了MQTT客戶端的連接、發(fā)布、訂閱、斷開連接等功能。它們是構(gòu)建在MQTTPacket基礎之上的更高級別的抽象,提供了一個易于使用和集成的MQTT客戶端接口。在移植過程中,我們需要對這個文件夾中的一些網(wǎng)絡接口進行修改,才能利用其中的函數(shù)正常地與服務器通信。
MQTTClient是一個最初為mbed編寫的C++庫,現(xiàn)已移植到其他平臺上使用。該庫基于并且需要MQTTPacket。對于僅使用C語言的系統(tǒng)來說,可以忽略此文件夾。
表1說明了MQTTPacket文件夾中與客戶端有關(guān)的文件的作用。
Table 1. The role of files in the MQTTPacket folder
由于這些文件只負責處理報文格式,不涉及與單片機有關(guān)的通信接口,因此在移植過程中直接復制到工程中即可,不需要修改。
MQTTClient-C文件夾中使用的主要是MQTTClient.c文件。該文件是MQTT客戶端庫的核心實現(xiàn),負責實現(xiàn)MQTT協(xié)議的各種功能,提供了連接Broker、發(fā)布和訂閱消息等高級抽象接口。它通過調(diào)用MQTTPacket文件夾中的程序來封裝報文,并通過調(diào)用相關(guān)的網(wǎng)絡接口將這些報文發(fā)送出去。在該文件中,初始化函數(shù)MQTTClientInit()需要調(diào)用Network結(jié)構(gòu)體來傳入有關(guān)Socket網(wǎng)絡接口。該結(jié)構(gòu)體涉及到Socket接口編號、接收函數(shù)、發(fā)送函數(shù)。因此需要編寫程序來初始化Socket接口,并編寫接收和發(fā)送函數(shù),以供MQTTClient.c文件中的函數(shù)調(diào)用。還需要編寫供超時判斷用的計時函數(shù)。
官方的MQTTClient-C文件夾中已經(jīng)打包好了一些例程,它們適配于FreeRTOS、Linux、CC3200。移植時需要依據(jù)這些例程編寫一個程序文件(此處名稱為Hi3861_PahoMQTT.c),為MQTTClient.c文件中的函數(shù)配置好網(wǎng)絡接口和計時函數(shù)。網(wǎng)絡接口利用Socket通過TCP的方式連接到服務器并進行通信,計時函數(shù)用于通信超時判斷。要編寫的文件中的程序內(nèi)容如表2所示。
圖2通過發(fā)布消息的流程來說明在Hi3861_PahoMQTT.c文件中增加的程序的作用。
Table 2. Programs that need to be written during migration
|
Figure 2. The process of publishing messages using the paho.mqtt.c library
從圖2中可以看到,為了移植嵌入式的Paho MQTT C庫而新增的幾個函數(shù)的主要作用是初始化Socket接口、設置利用Socket進行接收和發(fā)送數(shù)據(jù)的函數(shù),然后利用Socket連接服務器。配置完成后,設備后續(xù)與MQTT Broker進行連接認證、發(fā)布消息都依靠的是MQTTClient.c文件中的相關(guān)函數(shù)。這些函數(shù)通過調(diào)用MQTTPacket文件夾中的函數(shù)來進行報文的封裝或解析,利用與Socket相關(guān)的函數(shù)進行數(shù)據(jù)的接收和發(fā)送。
4. 在Hi3861上移植Paho MQTT
Hi3861是海思推出的一款支持WiFi功能的處理器,其內(nèi)核采用OpenHarmony架構(gòu)下的LiteOS操作系統(tǒng)[4]。在官方提供的工程文件中,已經(jīng)實現(xiàn)了在LiteOS系統(tǒng)下的WiFi連接接口和用于實現(xiàn)TCP/IP協(xié)議棧的LwIP (Light weight IP)庫。通過調(diào)用這些接口,Hi3861可以連接到WiFi熱點上面,獲取到IP地址,并創(chuàng)建Socket套接字[5]。移植前需要將Paho MQTT C庫相關(guān)文件復制到工程中,并設置好BUILD.gn項目構(gòu)建文件。
在LiteOS操作系統(tǒng)中,setsockopt()函數(shù)用于配置套接字的選項,如協(xié)議級別、接收發(fā)送的超時時間、保活機制等,recv()用于從Socket接收數(shù)據(jù),send()用于向Socket發(fā)送數(shù)據(jù)。因此,在第3.3節(jié)提到的NetworkRead()函數(shù)中需要先通過setsockopt()設置接收超時時間,然后調(diào)用recv()函數(shù)進行數(shù)據(jù)的接收;在NetworkWrite()函數(shù)中需要先通過setsockopt()設置發(fā)送超時時間,然后調(diào)用send()函數(shù)進行數(shù)據(jù)的發(fā)送。LiteOS中的socket()函數(shù)用來創(chuàng)建一個新的套接字(Socket),connect()函數(shù)用于在客戶端套接字上建立與遠程服務器的連接。因此這兩個函數(shù)需要在NetworkConnect()函數(shù)中對這兩個函數(shù)進行調(diào)用,從而連接到云平臺的服務器上。
另外還需要移植用于超時判斷的定時器相關(guān)函數(shù),方法主要是通過內(nèi)核Tick計數(shù)獲取函數(shù)osKernelGetTickCount()和系統(tǒng)定時器計數(shù)獲取函數(shù)osKernelGetSysTimerCount(),配合計數(shù)頻率來計算秒數(shù)和微秒數(shù),這涉及到對MQTTClient.c中的TimerIsExpired()、TimerCountdownMS()、TimerCountdown()、TimerLeftMS()這幾個函數(shù)的重定義。
配置好MQTTClient.c中的函數(shù)接口后,即可調(diào)用MQTTClient.c中的相關(guān)函數(shù)進行MQTT的認證、訂閱、取消訂閱、發(fā)布、接收相關(guān)操作了。
5. 實驗部署
本文采用華清遠見研發(fā)的FS-Hi3861開發(fā)板進行Hi3861工程的部署,使用華為云平臺的設備接入IoTDA資源作為MQTT服務器。
首先需要在華為云的設備接入IoTDA資源中創(chuàng)建產(chǎn)品及相關(guān)屬性、命令。屬性為設備上報的數(shù)據(jù),命令為向設備下發(fā)的數(shù)據(jù),這兩種數(shù)據(jù)的話題和格式是不一樣的。然后注冊一個設備,獲取到設備的鑒權(quán)信息,包括客戶端ID、用戶名、密碼。
設備需要利用MQTTClient.c中的MQTTConnect()函數(shù)包裝好鑒權(quán)信息,與服務器進行認證。認證通過后,在華為云中會顯示設備處于在線狀態(tài)。然后,設備可以利用MQTTPublish()函數(shù)按照華為云規(guī)定的格式向指定的話題發(fā)布屬性數(shù)據(jù)。設備還可以利用MQTTSubscribe()函數(shù)訂閱指定的話題,并通過MQTTRun()函數(shù)接收云平臺下發(fā)的數(shù)據(jù)。
6. 未來工作
本文以Hi3861為例,介紹了在OpenHarmony項目的LiteOS內(nèi)核上面通過移植Paho MQTT連接MQTT云平臺的方法。由于云平臺通常使用JSON格式進行數(shù)據(jù)傳遞,因此在未來的項目中,將通過移植cJSON庫的方式進行數(shù)據(jù)的序列化和反序列化,從而更加方便地傳輸傳感器數(shù)據(jù)并解析相關(guān)指令。另外,為了便于傳感器網(wǎng)絡的建立,未來的項目將探討利用Hi3861進行Mesh組網(wǎng),從而擴展傳感范圍的方式。為了適應低功耗需求,未來的項目也將探討低功耗WiFi模式下MQTT的應用。