赞
踩
阿里云对接需要用的是PRODUCTKEY,DEVICENAME和DEVICESECRET,开始直接用MQTT的例子硬怼,没成功,后面看了文档,发现阿里云对接的client_id,username和password是通过三要素生成的。
找了一下代码,发现再device/xradio/xr806/xr_skylark/src/net/cloud/aliyun下面有阿里云的东西,遂打开看了一下,刚好有加密过程。就直接拿过来用了,不过这里出现了一点小插曲,一直引用不到里面的接口。折腾了半天不行,一怒之下,给复制出来了。
创建app站内有很多文章就不再赘述,创建好以后代码结构如下:
其中,inc是把device/xradio/xr806/xr_skylark/include/net/cloud/aliyun下面的inc复制出来的;
src下面的aliyun,是直接把
device/xradio/xr806/xr_skylark/src/net/cloud/aliyun
复制出来的;
wifi,mqtt,uart的都有例子,就拿过来,改一改。大体流程是
先初始化wifi,连接wifi成功获取到网络权限以后,初始化mqtt的task,待mqtt的task连接到阿里云iot以后,初始化uart task,初始化OK以后开始轮询接收uart1数据,并透传给阿里云。
不BB了,直接上代码:
ohosdemo下的BUILD.gn
group("ohosdemo") {
deps = [
#"hello_demo:app_hello",
"mqtt2uart_demo:app_uart2mqtt",
]
}
mqtt2uart_demo下的BUILD.gn
import("//device/xradio/xr806/liteos_m/config.gni") static_library("app_uart2mqtt") { configs = [] sources = [ "src/main.c", "src/aliyun/alink_auth.c", "src/aliyun/alink_ca.c", "src/aliyun/alink_cjson_get.c", "src/aliyun/alink_mqtt_client.c", "src/aliyun/alink_utils.c", ] cflags = board_cflags include_dirs = board_include_dirs include_dirs += [ "inc", "//kernel/liteos_m/kernel/arch/include", "//base/iot_hardware/peripheral/interfaces/kits", ".", "//utils/native/lite/include", "//foundation/communication/wifi_lite/interfaces/wifiservice", "//device/xradio/xr806/xr_skylark/project" ] }
main.c
#include <string.h> #include "ohos_init.h" #include "kernel/os/os.h" #include "iot_gpio.h" #include "wifi_device.h" #include "common/framework/net_ctrl.h" #include "mqtt_client.h" #include "driver/chip/hal_uart.h" #include "iot_uart.h" static OS_Thread_t g_main_thread; static OS_Thread_t g_mqtt_thread; static OS_Thread_t g_uart_thread; #define WIFI_DEVICE_CONNECT_AP_SSID "XXXXX"//这里填你家路由器的SSID #define WIFI_DEVICE_CONNECT_AP_PSK "XXXXX"//这里填你家路由器的PWD #define MQTT_CLIENT_ID "2022666" #define MQTT_HOST_NAME "iot-as-mqtt.cn-shanghai.aliyuncs.com" #define MQTT_PORT "1883" #define MQTT_PRODUCTKEY "a1oz5VdCSZk" #define MQTT_DEVICENAME "DHTER000S" #define MQTT_DEVICESECRET "8368b89e723216bccb471434969391e5" #define MQTT_SECUREMODE "2" #define MQTT_RECV_TOPIC MQTT_PRODUCTKEY"/"MQTT_DEVICENAME"/user/get" //下发TOPIC #define MQTT_UPDATE_TOPIC MQTT_PRODUCTKEY"/"MQTT_DEVICENAME"/user/update"//上报TOPIC #define MQTT_BUF_SIZE (2*1024) static MQTTPacket_connectData mqtt_demo_connectData = MQTTPacket_connectData_initializer; static Client mqtt_demo_client; static Network mqtt_demo_network; #define UART_BUFFER_MAXSIZE 100 static int mqtt_demo_publish(char *topic, char *msg) ; static int mqtt_demo_init(void) { char *send_buf; char *recv_buf; mqtt_para_init(); aliot_device_info(MQTT_PRODUCTKEY, MQTT_DEVICENAME, MQTT_DEVICESECRET, MQTT_CLIENT_ID, MQTT_SECUREMODE); printf("str_clientID = %s\n", xr_devc_info.client_id); printf("str_user_name = %s\n", xr_devc_info.user_name); printf("sha1_pwd = %s\n", xr_devc_info.password); mqtt_demo_connectData.clientID.cstring = xr_devc_info.client_id; mqtt_demo_connectData.keepAliveInterval = 30; // 30s mqtt_demo_connectData.cleansession = 0; mqtt_demo_connectData.MQTTVersion = 4; //Version of MQTT 3.1.1 send_buf = malloc(MQTT_BUF_SIZE); if (send_buf == NULL) { printf("no memory\n"); return -1; } recv_buf = malloc(MQTT_BUF_SIZE); if (recv_buf == NULL) { free(send_buf); printf("no memory\n"); return -1; } /* init network */ NewNetwork(&mqtt_demo_network); /* init mqtt client object */ MQTTClient(&mqtt_demo_client, &mqtt_demo_network, 6000, (unsigned char *)send_buf, MQTT_BUF_SIZE, (unsigned char *)recv_buf, MQTT_BUF_SIZE); /* set username and password */ mqtt_demo_connectData.username.cstring = xr_devc_info.user_name; mqtt_demo_connectData.password.cstring = xr_devc_info.password; return 0; } static int mqtt_demo_connect(char *host_name, char *host_port) { int ret = -1; ret = ConnectNetwork(&mqtt_demo_network, host_name, atoi(host_port)); if (ret != 0) { printf("mqtt connect faild, ret:%d, host:%s, port:%s\n", ret, host_name, host_port); goto exit; } ret = MQTTConnect(&mqtt_demo_client, &mqtt_demo_connectData); if (ret != 0) { printf("mqtt connect faild, ret:%d\n", ret); mqtt_demo_network.disconnect(&mqtt_demo_network); goto exit; } printf("mqtt connected\n"); exit: return ret; } static void mqtt_demo_msg_cb(MessageData *data) { printf("get a message, topic: %.*s, msg: %.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data, data->message->payloadlen, (char *)data->message->payload); } static int mqtt_demo_subscribe(char *topic) { int ret = -1; if (mqtt_demo_client.isconnected) { ret = MQTTSubscribe(&mqtt_demo_client, topic, 0, mqtt_demo_msg_cb); if (ret != 0) printf("mqtt subscribe faild ret:%d\n", ret); } return ret; } static int mqtt_demo_unsubscribe(char *topic) { int ret = -1; if (mqtt_demo_client.isconnected) { ret = MQTTUnsubscribe(&mqtt_demo_client, topic); if (ret != 0) printf("mqtt unsubscribe faild, ret:%d\n", ret); } return ret; } static int mqtt_demo_publish(char *topic, char *msg) { int ret = -1; MQTTMessage message; memset(&message, 0, sizeof(message)); message.qos = 0; message.retained = 0; /* disable retain the message in server */ message.payload = msg; message.payloadlen = strlen(msg); ret = MQTTPublish(&mqtt_demo_client, topic, &message); if (ret != 0) printf("mqtt publish faild, ret:%d\n", ret); return ret; } static int mqtt_demo_disconnect(void) { int ret = -1; if (mqtt_demo_client.isconnected) { ret = MQTTDisconnect(&mqtt_demo_client); if (ret != 0) printf("mqtt disconnect fail, ret:%d\n", ret); mqtt_demo_network.disconnect(&mqtt_demo_network); } return ret; } static void mqtt_demo_deinit(void) { if (mqtt_demo_client.buf) { free(mqtt_demo_client.buf); mqtt_demo_client.buf = NULL; } if (mqtt_demo_client.readbuf) { free(mqtt_demo_client.readbuf); mqtt_demo_client.readbuf = NULL; } } static void uart_task(void *arg) { int ret; unsigned int uart_id = 1; unsigned int uart_len; unsigned char uart_rx_buffer[UART_BUFFER_MAXSIZE]; unsigned char uart_tx_buffer[UART_BUFFER_MAXSIZE]; static IotUartAttribute uart_param = { 115200, IOT_UART_DATA_BIT_8, IOT_UART_STOP_BIT_1, IOT_UART_PARITY_NONE, 0, 0, 0 }; printf("uart%d test start\r\n", uart_id); IoTUartInit(uart_id, &uart_param); IoTUartWrite(uart_id, "uart1 init OK\r\n", 15); while (1) { memset((char *)uart_rx_buffer, 0, UART_BUFFER_MAXSIZE); ret = IoTUartRead(uart_id, uart_rx_buffer, UART_BUFFER_MAXSIZE); if (ret > 0) { printf("recv len=%d, data:%s\r\n", ret, uart_rx_buffer); if(0 == mqtt_demo_publish(MQTT_UPDATE_TOPIC, uart_rx_buffer)) { memset(uart_tx_buffer, 0, UART_BUFFER_MAXSIZE); uart_len = snprintf((char *)uart_tx_buffer, UART_BUFFER_MAXSIZE, "uart%d send data:[%s] OK\r\n", uart_id, uart_rx_buffer); IoTUartWrite(uart_id, uart_tx_buffer, uart_len); } else { printf("Publish data failed!!\n"); } } OS_MSleep(100); //100ms } exit: IoTUartDeinit(uart_id); OS_ThreadDelete(&g_uart_thread); printf("uart%d test end\r\n", uart_id); } static void mqtt_task(void *arg) { int ret; int reconnect_times = 0; mqtt_demo_init(); ret = mqtt_demo_connect(MQTT_HOST_NAME, MQTT_PORT); if (ret != 0) goto exit; ret = mqtt_demo_subscribe(MQTT_RECV_TOPIC); if (ret != 0) goto exit; mqtt_demo_publish(MQTT_UPDATE_TOPIC, "mqtt init OK"); if (!OS_ThreadIsValid(&g_uart_thread)) { OS_ThreadCreate(&g_uart_thread, "uart_task", uart_task, (void *)NULL, OS_THREAD_PRIO_APP, (8 * 1024)); } while (1) { ret = MQTTYield(&mqtt_demo_client, 500); if (ret != 0) { printf("mqtt yield err, ret:%d\n", ret); reconnect: printf("mqtt reconnect\n"); mqtt_demo_disconnect(); ret = mqtt_demo_connect(MQTT_HOST_NAME, MQTT_PORT); if (ret != 0) { reconnect_times++; if (reconnect_times > 5) goto exit; OS_MSleep(5000); //5s goto reconnect; } } } exit: printf("mqtt disconnect\n"); mqtt_demo_unsubscribe(MQTT_RECV_TOPIC); mqtt_demo_disconnect(); mqtt_demo_deinit(); OS_ThreadDelete(&g_mqtt_thread); } static void net_cb(uint32_t event, uint32_t data, void *arg) { uint16_t type = EVENT_SUBTYPE(event); switch (type) { case NET_CTRL_MSG_NETWORK_UP: printf("NET_CTRL_MSG_NETWORK_UP\n"); if (!OS_ThreadIsValid(&g_mqtt_thread)) { OS_ThreadCreate(&g_mqtt_thread, "connect_to_server_task", mqtt_task, (void *)NULL, OS_THREAD_PRIO_APP, (8 * 1024)); } break; case NET_CTRL_MSG_NETWORK_DOWN: break; default: break; } } static void MainThread(void *arg) { printf("MainThread start\r\n"); if (WIFI_SUCCESS != EnableWifi()) { printf("Error: EnableWifi fail\n"); return; } OS_Sleep(1); if (WIFI_SUCCESS != Scan()) { printf("Error: Scan fail.\n"); return; } OS_Sleep(3);//这里为了方便用延时,实际用回调更好,否则3秒可能不够 const char ssid_want_connect[] = WIFI_DEVICE_CONNECT_AP_SSID; const char psk[] = WIFI_DEVICE_CONNECT_AP_PSK; WifiScanInfo scan_results[30]; unsigned int scan_num = 30; if (WIFI_SUCCESS != GetScanInfoList(scan_results, &scan_num)) { printf("Error: GetScanInfoList fail.\n"); return; } WifiDeviceConfig config = { 0 }; int netId = 0; int i; for (i = 0; i < scan_num; i++) { printf("ssid: %s ", scan_results[i].ssid); printf("securityType: %d\n", scan_results[i].securityType); if (0 == strcmp(scan_results[i].ssid, ssid_want_connect)) { memcpy(config.ssid, scan_results[i].ssid, WIFI_MAX_SSID_LEN); memcpy(config.bssid, scan_results[i].bssid, WIFI_MAC_LEN); strcpy(config.preSharedKey, psk); config.securityType = scan_results[i].securityType; config.wapiPskType = WIFI_PSK_TYPE_ASCII; config.freq = scan_results[i].frequency; break; } } if (i >= scan_num) { printf("Error: No found ssid in scan_results\n"); return; } if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId)) { printf("Error: AddDeviceConfig Fail\n"); return; } printf("Config Success\n"); if (WIFI_SUCCESS != ConnectTo(netId)) { printf("Error: ConnectTo Fail\n"); return; } observer_base *net_ob; net_ob = sys_callback_observer_create(CTRL_MSG_TYPE_NETWORK, NET_CTRL_MSG_ALL, net_cb, NULL); if (net_ob == NULL) return; if (sys_ctrl_attach(net_ob) != 0) return; while (1) { OS_MSleep(500); } } void UART2MQTTMain(void) { if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) { printf("[ERR] Create MainThread Failed\n"); } } SYS_RUN(UART2MQTTMain);
1.aliyun的lib引用不到
偷懒,直接复制出来的;
2.mqtt yield err, ret:-1
抓包发现,有时候发的keepalive包没有得到响应,怀疑是本地网络不好,后来连上家里的wifi就没问题了。
做了一个简单的修改,发包一次不响应过会再发一次。三次收不到才认为是短线,才发起reconnect。
文件:MQTTClient.c
函数:int keepalive(Client* c)
修改如下:
if (expired(&c->last_sent) || expired(&c->last_received)) { if (c->ping_outstanding) { MQTT_WARN("PINGRESP not received in keepalive interval %d.\n",c->ping_outstanding); if(c->ping_outstanding <= 3){ Timer timer; InitTimer(&timer); countdown_ms(&timer, 1000); int len = MQTTSerialize_pingreq(c->buf, c->buf_size); if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packet c->ping_outstanding++; } else { rc = FAILURE; /* PINGRESP not received in keepalive interval */ } } else { Timer timer; InitTimer(&timer); countdown_ms(&timer, 1000); int len = MQTTSerialize_pingreq(c->buf, c->buf_size); if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packet c->ping_outstanding = 1; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。