MQTT 在 OpenWRT 上的開發
建立 cross-compile 環境,撰寫一隻簡單的 MQTT 程式發表/訂閱資訊
撰寫一隻簡單的 MQTT 程式
在 OpenWRT 上進行開發之前,我們可以先寫一隻簡單的程式,來測試 MQTT 的功能,考慮到對 OpenWRT 的支援,我們使用 mosquitto API 來進行開發。
所撰寫的程式主要參考: https://mosquitto.org/man/libmosquitto-3.html。不過,在原本程式中 publish 的功能,我們做了一些修改,把 subscribe 的目標指到 info
,並新增一個 publish 指到 report
。考慮到原有的程式架構會不斷在迴圈中等候 subscribe 的資訊,我們先在 subscribe 之前進行一次 publish,程式如下:
#include <stdio.h>
#include <mosquitto.h>
void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
if(message->payloadlen){
printf("%s %s\n", message->topic, message->payload);
}else{
printf("%s (null)\n", message->topic);
}
fflush(stdout);
}
void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)
{
int i;
if(!result){
/* Subscribe to broker information topics on successful connect. */
mosquitto_subscribe(mosq, NULL, "info/#", 2);
}else{
fprintf(stderr, "Connect failed\n");
}
}
void my_subscribe_callback(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
{
int i;
printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
for(i=1; i<qos_count; i++){
printf(", %d", granted_qos[i]);
}
printf("\n");
}
int main(int argc, char *argv[])
{
int i;
char *host = "localhost";
int port = 1883;
int keepalive = 60;
bool clean_session = true;
struct mosquitto *mosq = NULL;
mosquitto_lib_init();
mosq = mosquitto_new(NULL, clean_session, NULL);
if(!mosq){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
mosquitto_connect_callback_set(mosq, my_connect_callback);
mosquitto_message_callback_set(mosq, my_message_callback);
mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
if(mosquitto_connect(mosq, host, port, keepalive)){
fprintf(stderr, "Unable to connect.\n");
return 1;
}
mosquitto_publish(mosq, NULL, "report", sizeof("hello"), "hello", 2, false);
mosquitto_loop_forever(mosq, -1, 1);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}
接著,我們進行程式的編譯,這裡要記得指定所使用的 library,才不會出現函式缺少的狀況。
$gcc main.c -lmosquitto -o mqtt_test
$./mqtt_test
執行後,實測可以 publish 訊息至 broker 上的report
,並持續更新info
上的資訊。
建立 cross-compile 環境
為了要建立在 OpenWRT 上的 MQTT 開發環境,我們首先要建立一個含有 mosquitto library 的 cross compiler。相同的,我們先到menuconfig
中,將 libmosquitto-nossl 勾選,如下圖所示:
在進行 make 之後,我們可以在build_dir
資料夾下,找到 libmosquitto-nossl 的資料夾,如下所示:
ofwrt@ofwrt-18:~/openwrt/build_dir/target-mips_24kc_musl$ ls
busybox-1.28.3 mosquitto-nossl
c-ares-1.14.0 ncurses-6.1
[...]
為了方便程式的開發,我們把相關的 header 檔移到程式所在的位置,如下指令所示:
cp -R ~/openwrt/build_dir/target-mips_24kc_musl/mosquitto-nossl/mosquitto-1.5.1/lib/*.h ~/mqtt/include
另外,make 產生的.so
檔則在staging_dir/target-mips_24kc_musl/usr/lib
資料夾中,我們把相關的檔案也移到資料夾下:
ofwrt@ofwrt-18:~/openwrt/staging_dir/target-mips_24kc_musl/usr/lib$ cp libmosquitto* ~/mqtt/lib/
接著,進行程式的編譯:
mips-openwrt-linux-gcc main_ofwrt.c -I ~/mqtt/include/ -L ~/mqtt/lib/ -lmosquitto -o mqtt_ofwrt
考慮到 mosquitto 已有對 OpenWRT 的支援,在/usr/lib
底下已有 mosquitto 的 linker 檔,因此,不需要額外把 linker 檔加入 OpenWRT 的環境中,就可直接執行程式,如下所示:
root@GL-AR750S:/usr/lib# ls libmosquitto*
libmosquitto.so libmosquitto.so.1
因此,編譯完後的檔案,只需要把權限設定正確,就可以在 OpenWRT 的 WiFi AP 上執行。
Last updated