From bbe1eba081dccfdbd3d1db1f1fe03ba4925d6220 Mon Sep 17 00:00:00 2001 From: xuyanghang Date: Fri, 12 Jan 2024 16:44:40 +0800 Subject: [PATCH] 4G module EC200A MQTT connection --- .../Framework/connection/4g/adapter_4g.c | 18 +- .../Framework/connection/4g/ec200a/Makefile | 2 +- .../Framework/connection/4g/ec200a/SConscript | 2 +- .../Framework/connection/4g/ec200a/ec200a.c | 12 +- .../connection/4g/ec200a/ec200a_mqtt.c | 216 +++++++++++++++++- APP_Framework/Framework/connection/adapter.c | 115 ++++++++++ APP_Framework/Framework/connection/adapter.h | 16 ++ 7 files changed, 371 insertions(+), 10 deletions(-) diff --git a/APP_Framework/Framework/connection/4g/adapter_4g.c b/APP_Framework/Framework/connection/4g/adapter_4g.c index 2e84dc6a4..329d8bb51 100644 --- a/APP_Framework/Framework/connection/4g/adapter_4g.c +++ b/APP_Framework/Framework/connection/4g/adapter_4g.c @@ -130,6 +130,11 @@ int Adapter4GTest(void) /* Using Public TCP server to test 4G Socket connection */ uint8 server_addr[64] = "xyheqmx.e3.luyouxia.net"; uint8 server_port[64] = "13333"; + uint8 client_id[64] = "quectel"; + uint8 username[64] = "test"; + uint8 password[64] = "test123456"; + uint8 topic_pub[64] = "/reply"; + uint8 topic_sub[64] = "/get"; adapter->socket.socket_id = 0; @@ -146,8 +151,19 @@ int Adapter4GTest(void) printf("4G recv msg %s\n", recv_msg); memset(recv_msg, 0, 256); } + + /* + AdapterDeviceMqttConnect(adapter, server_addr, server_port, client_id, username, password); + + while (1) { + AdapterDeviceMqttSend(adapter, topic_pub, send_msg, strlen(send_msg)); + AdapterDeviceMqttRecv(adapter, topic_sub, recv_msg, 256); + printf("4G mqtt recv msg %s\n", recv_msg); + memset(recv_msg, 0, 256); + } + */ #endif return 0; } -PRIV_SHELL_CMD_FUNCTION(Adapter4GTest, a EC200T or EC200A adpter sample, PRIV_SHELL_CMD_FUNC_ATTR); +PRIV_SHELL_CMD_FUNCTION(Adapter4GTest, a EC200T or EC200A adapter sample, PRIV_SHELL_CMD_FUNC_ATTR); diff --git a/APP_Framework/Framework/connection/4g/ec200a/Makefile b/APP_Framework/Framework/connection/4g/ec200a/Makefile index e9e545acb..a634a88d4 100644 --- a/APP_Framework/Framework/connection/4g/ec200a/Makefile +++ b/APP_Framework/Framework/connection/4g/ec200a/Makefile @@ -7,7 +7,7 @@ ifeq ($(CONFIG_ADD_NUTTX_FEATURES),y) endif ifeq ($(CONFIG_ADD_XIZI_FEATURES),y) - SRC_FILES := ec200a.c + SRC_FILES := ec200a.c ec200a_mqtt.c include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Framework/connection/4g/ec200a/SConscript b/APP_Framework/Framework/connection/4g/ec200a/SConscript index 84aeebc1e..a8e115b17 100644 --- a/APP_Framework/Framework/connection/4g/ec200a/SConscript +++ b/APP_Framework/Framework/connection/4g/ec200a/SConscript @@ -4,7 +4,7 @@ import os cwd = GetCurrentDir() src = [] if GetDepend(['ADAPTER_EC200A']): - src += ['ec200a.c'] + src += ['ec200a.c', 'ec200a_mqtt.c'] group = DefineGroup('connection 4g ec200a', src, depend = [], CPPPATH = [cwd]) Return('group') \ No newline at end of file diff --git a/APP_Framework/Framework/connection/4g/ec200a/ec200a.c b/APP_Framework/Framework/connection/4g/ec200a/ec200a.c index 018e15e31..114155f1e 100644 --- a/APP_Framework/Framework/connection/4g/ec200a/ec200a.c +++ b/APP_Framework/Framework/connection/4g/ec200a/ec200a.c @@ -22,7 +22,7 @@ #include #define EC200A_AT_MODE_CMD "+++" -#define EC200A_GET_QCCID_CMD "AT+QCCID\r\n" +#define EC200A_GET_QCCID_CMD "AT+QCCID\r\n" #define EC200A_GET_CPIN_CMD "AT+CPIN?\r\n" #define EC200A_GET_CREG_CMD "AT+CREG?\r\n" #define EC200A_CFG_TCP_CMD "AT+QICSGP" @@ -42,6 +42,11 @@ #define TRY_TIMES 10 +extern int Ec200aMqttConnect(struct Adapter *adapter, const char *ip, const char *port, const char *client_id, const char *username, const char *password); +extern int Ec200aMqttDisconnect(struct Adapter *adapter); +extern int Ec200aMqttSend(struct Adapter *adapter, const char *topic, const void *buf, size_t len); +extern int Ec200aMqttRecv(struct Adapter *adapter, const char *topic, void *buf, size_t len); + static void Ec200aPowerSet(void) { #ifdef ADAPTER_EC200A_USING_PWRKEY @@ -261,6 +266,7 @@ static int Ec200aConnect(struct Adapter *adapter, enum NetRoleType net_role, con /*step6: serial write "AT+QICLOSE", close socket connect before open socket*/ memset(ec200a_cmd, 0, sizeof(ec200a_cmd)); + sprintf(ec200a_cmd, EC200A_CLOSE_SOCKET_CMD, adapter->socket.socket_id); for(try = 0; try < TRY_TIMES; try++){ ret = AtCmdConfigAndCheck(adapter->agent, ec200a_cmd, EC200A_OK_REPLY); @@ -526,6 +532,10 @@ static const struct IpProtocolDone ec200a_done = .send = Ec200aSend, .recv = Ec200aRecv, .disconnect = Ec200aDisconnect, + .mqttconnect = Ec200aMqttConnect, + .mqttdisconnect = Ec200aMqttDisconnect, + .mqttsend = Ec200aMqttSend, + .mqttrecv = Ec200aMqttRecv, }; AdapterProductInfoType Ec200aAttach(struct Adapter *adapter) diff --git a/APP_Framework/Framework/connection/4g/ec200a/ec200a_mqtt.c b/APP_Framework/Framework/connection/4g/ec200a/ec200a_mqtt.c index 5f5a42e8e..3b5dde368 100644 --- a/APP_Framework/Framework/connection/4g/ec200a/ec200a_mqtt.c +++ b/APP_Framework/Framework/connection/4g/ec200a/ec200a_mqtt.c @@ -17,26 +17,230 @@ * @author AIIT XUOS Lab * @date 2024.1.5 */ +#include +#include +#define EC200A_GET_QCCID_CMD "AT+QCCID\r\n" +#define EC200A_GET_CPIN_CMD "AT+CPIN?\r\n" +#define EC200A_GET_CREG_CMD "AT+CREG?\r\n" +#define EC200A_CLOSE "AT+QPOWD\r\n" +#define EC200A_SET_MQTT_MODE_CMD "AT+QMTCFG=\"recv/mode\",0,0,1\r\n" +#define EC200A_SET_MQTT_SERVER_CMD "AT+QMTOPEN=0," +#define EC200A_SET_MQTT_CONNECT_CMD "AT+QMTCONN=0," +#define EC200A_SET_MQTT_DISCONN_CMD "AT+QMTDISC=0\r\n" +#define EC200A_SET_MQTT_PUBEX_CMD "AT+QMTPUBEX=0,0,0,0," +#define EC200A_SET_MQTT_SUB_CMD "AT+QMTSUB=0,1," -static int Ec200aMqttOpen() { +#define EC200A_OK_REPLY "OK" +#define EC200A_READY_REPLY "READY" +#define EC200A_CREG_REPLY ",1" +#define EC200A_PUBEX_REPLY ">" +#define TRY_TIMES 10 + +int Ec200aMqttConnect(struct Adapter *adapter, const char *ip, const char *port, const char *client_id, const char *username, const char *password) { + int ret = 0; + int try = 0; + uint8_t ec200a_cmd[64]; + + AtSetReplyEndChar(adapter->agent, 0x4F, 0x4B); + + /*step1: serial write "+++", quit transparent mode*/ + PrivTaskDelay(1500); //before +++ command, wait at least 1s + ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "+++"); + PrivTaskDelay(1500); //after +++ command, wait at least 1s + + /*step2: serial write "AT+CCID", get SIM ID*/ + for(try = 0; try < TRY_TIMES; try++){ + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_GET_QCCID_CMD, EC200A_OK_REPLY); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + + /*step3: serial write "AT+CPIN?", check SIM status*/ + for(try = 0; try < TRY_TIMES; try++){ + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_GET_CPIN_CMD, EC200A_READY_REPLY); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + + /*step4: serial write "AT+CREG?", check whether registered to GSM net*/ + PrivTaskDelay(1000); //before CREG command, wait 1s + + for(try = 0; try < TRY_TIMES; try++){ + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_GET_CREG_CMD, EC200A_CREG_REPLY); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + + /*step5: serial write "AT+QMTCFG=", config mqtt params*/ + for(try = 0; try < TRY_TIMES; try++){ + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_SET_MQTT_MODE_CMD, EC200A_OK_REPLY); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + + /*step6: serial write "AT+OPEN=", config mqtt ip and port*/ + memset(ec200a_cmd, 0, sizeof(ec200a_cmd)); + strcpy(ec200a_cmd, EC200A_SET_MQTT_SERVER_CMD); + strcat(ec200a_cmd, "\""); + strcat(ec200a_cmd, ip); + strcat(ec200a_cmd, "\","); + strcat(ec200a_cmd, port); + strcat(ec200a_cmd, "\r\n"); + for(try = 0; try < TRY_TIMES; try++){ + ret = AtCmdConfigAndCheck(adapter->agent, ec200a_cmd, EC200A_OK_REPLY); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + + /*step7: serial write "AT+QMTCONN=", config mqtt connection*/ + PrivTaskDelay(1000); //before mqtt connect command, wait 1s + + memset(ec200a_cmd, 0, sizeof(ec200a_cmd)); + strcpy(ec200a_cmd, EC200A_SET_MQTT_CONNECT_CMD); + strcat(ec200a_cmd, "\""); + strcat(ec200a_cmd, client_id); + strcat(ec200a_cmd, "\",\""); + strcat(ec200a_cmd, username); + strcat(ec200a_cmd, "\",\""); + strcat(ec200a_cmd, password); + strcat(ec200a_cmd, "\"\r\n"); + for(try = 0; try < TRY_TIMES; try++){ + ret = AtCmdConfigAndCheck(adapter->agent, ec200a_cmd, EC200A_OK_REPLY); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + + ADAPTER_DEBUG("Ec200a mqtt connect done\n"); + + return 0; + +out: + ADAPTER_DEBUG("Ec200a mqtt connect failed. Power down\n"); + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_CLOSE, EC200A_OK_REPLY); + return -1; } +int Ec200aMqttDisconnect(struct Adapter *adapter) +{ + int ret = 0; -static int Ec200aMqttClose() { + AtSetReplyEndChar(adapter->agent, 0x4F, 0x4B); + + /*step1: serial write "+++", quit transparent mode*/ + PrivTaskDelay(1500); //before +++ command, wait at least 1s + ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "+++"); + PrivTaskDelay(1500); //after +++ command, wait at least 1s + /*step2: serial write "AT+QMTDISC", close mqtt connect*/ + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_SET_MQTT_DISCONN_CMD, EC200A_OK_REPLY); + if (ret < 0) { + goto out; + } + + ADAPTER_DEBUG("Ec200a disconnect mqtt done\n"); + + return 0; + +out: + ADAPTER_DEBUG("Ec200a disconnect mqtt failed. Power down\n"); + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_CLOSE, EC200A_OK_REPLY); + return -1; } -static int Ec200aMqttConnect() { +int Ec200aMqttSend(struct Adapter *adapter, const char *topic, const void *buf, size_t len) { + int ret = 0; + int try = 0; + uint8_t ec200a_cmd[64]; + AtSetReplyEndChar(adapter->agent, 0x3E, 0x20); + + char len_str[10]; + sprintf(len_str, "%u", len); + memset(ec200a_cmd, 0, sizeof(ec200a_cmd)); + strcpy(ec200a_cmd, EC200A_SET_MQTT_PUBEX_CMD); + strcat(ec200a_cmd, "\""); + strcat(ec200a_cmd, topic); + strcat(ec200a_cmd, "\","); + strcat(ec200a_cmd, len_str); + strcat(ec200a_cmd, "\r\n"); + for(try = 0; try < TRY_TIMES; try++){ + ret = AtCmdConfigAndCheck(adapter->agent, ec200a_cmd, EC200A_PUBEX_REPLY); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + EntmSend(adapter->agent, buf, len); + + ADAPTER_DEBUG("Ec200a mqtt send done\n"); + + return 0; + +out: + ADAPTER_DEBUG("Ec200a mqtt send failed. Power down\n"); + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_CLOSE, EC200A_OK_REPLY); + return -1; } -static int Ec200aMqttSend() { +int Ec200aMqttRecv(struct Adapter *adapter, const char *topic, void *buf, size_t len) { + int ret = 0; + int try = 0; + uint8_t ec200a_cmd[64]; -} + AtSetReplyEndChar(adapter->agent, 0x4F, 0x4B); + memset(ec200a_cmd, 0, sizeof(ec200a_cmd)); + strcpy(ec200a_cmd, EC200A_SET_MQTT_SUB_CMD); + strcat(ec200a_cmd, "\""); + strcat(ec200a_cmd, topic); + strcat(ec200a_cmd, "\",0\r\n"); + + PrivTaskDelay(1000); //before mqtt sub topic command, wait 1s + for(try = 0; try < TRY_TIMES; try++){ + ret = AtCmdConfigAndCheck(adapter->agent, ec200a_cmd, EC200A_OK_REPLY); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + EntmRecv(adapter->agent, buf, len, 30); -static int Ec200aMqttRecv() { + ADAPTER_DEBUG("Ec200a mqtt recv done\n"); + return 0; + +out: + ADAPTER_DEBUG("Ec200a mqtt recv failed. Power down\n"); + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_CLOSE, EC200A_OK_REPLY); + return -1; } \ No newline at end of file diff --git a/APP_Framework/Framework/connection/adapter.c b/APP_Framework/Framework/connection/adapter.c index 3ac510f84..8b4d9ad59 100644 --- a/APP_Framework/Framework/connection/adapter.c +++ b/APP_Framework/Framework/connection/adapter.c @@ -902,3 +902,118 @@ int AdapterDeviceNetstat(struct Adapter *adapter) return result; } + +/** + * @description: Connect to a certain mqtt server + * @param adapter - adapter device pointer + * @param ip - connect ip + * @param port - connect port + * @param client_id - client id + * @param username - client username + * @param password - client password + * @return success: 0 , failure: other + */ +int AdapterDeviceMqttConnect(struct Adapter *adapter, const char *ip, const char *port, const char *client_id, const char *username, const char *password) +{ + if (!adapter) + return -1; + + if (PRIVATE_PROTOCOL == adapter->net_protocol) { + printf("AdapterDeviceMqttConnect not suuport private_protocol, please use join\n"); + return -1; + } else if (IP_PROTOCOL == adapter->net_protocol) { + struct IpProtocolDone *ip_done = (struct IpProtocolDone *)adapter->done; + + if (NULL == ip_done->mqttconnect) + return -1; + + return ip_done->mqttconnect(adapter, ip, port, client_id, username, password); + } else { + printf("AdapterDeviceMqttConnect net_protocol %d not support\n", adapter->net_protocol); + return -1; + } +} + +/** + * @description: Adapter disconnect from mqtt server + * @param adapter - adapter device pointer + * @return success: 0 , failure: other + */ +int AdapterDeviceMqttDisconnect(struct Adapter *adapter) +{ + if (!adapter) + return -1; + + if (PRIVATE_PROTOCOL == adapter->net_protocol) { + printf("AdapterDeviceMqttDisconnect not suuport private_protocol, please use join\n"); + return -1; + } else if (IP_PROTOCOL == adapter->net_protocol) { + struct IpProtocolDone *ip_done = (struct IpProtocolDone *)adapter->done; + + if (NULL == ip_done->mqttdisconnect) + return -1; + + return ip_done->mqttdisconnect(adapter); + } else { + printf("AdapterDeviceMqttDisconnect net_protocol %d not support\n", adapter->net_protocol); + return -1; + } +} + +/** + * @description: Send data to mqtt server + * @param adapter - adapter device pointer + * @param topic - publish topic + * @param buf - data buffer + * @param len - data length + * @return length of data written + */ +ssize_t AdapterDeviceMqttSend(struct Adapter *adapter, const char *topic, const void *buf, size_t len) +{ + if (!adapter) + return -1; + + if (PRIVATE_PROTOCOL == adapter->net_protocol) { + printf("AdapterDeviceMqttSend not support private_protocol, please use join\n"); + return -1; + } else if (IP_PROTOCOL == adapter->net_protocol) { + struct IpProtocolDone *ip_done = (struct IpProtocolDone *)adapter->done; + + if (NULL == ip_done->mqttsend) + return -1; + + return ip_done->mqttsend(adapter, topic, buf, len); + } else { + printf("AdapterDeviceMqttSend net_protocol %d not support\n", adapter->net_protocol); + return -1; + } +} + +/** + * @description: Receice data from mqtt server + * @param adapter - adapter device pointer + * @param topic - subscribe topic + * @param buf - buffer to save data + * @param len - buffer length + * @return gotten data length + */ +ssize_t AdapterDeviceMqttRecv(struct Adapter *adapter, const char *topic, void *buf, size_t len) +{ + if (!adapter) + return -1; + + if (PRIVATE_PROTOCOL == adapter->net_protocol) { + printf("AdapterDeviceMqttRecv not support private_protocol, please use join\n"); + return -1;; + } else if (IP_PROTOCOL == adapter->net_protocol) { + struct IpProtocolDone *ip_done = (struct IpProtocolDone *)adapter->done; + + if (NULL == ip_done->mqttrecv) + return -1; + + return ip_done->mqttrecv(adapter, topic, buf, len); + } else { + printf("AdapterDeviceMqttRecv net_protocol %d not support\n", adapter->net_protocol); + return -1; + } +} \ No newline at end of file diff --git a/APP_Framework/Framework/connection/adapter.h b/APP_Framework/Framework/connection/adapter.h index 3c60e0f73..16cab3d5f 100644 --- a/APP_Framework/Framework/connection/adapter.h +++ b/APP_Framework/Framework/connection/adapter.h @@ -163,6 +163,10 @@ struct IpProtocolDone int (*send)(struct Adapter *adapter, const void *buf, size_t len); int (*recv)(struct Adapter *adapter, void *buf, size_t len); int (*disconnect)(struct Adapter *adapter); + int (*mqttconnect)(struct Adapter *adapter, const char *ip, const char *port, const char *client_id, const char *username, const char *password); + int (*mqttdisconnect)(struct Adapter *adapter); + int (*mqttsend)(struct Adapter *adapter, const char *topic, const void *buf, size_t len); + int (*mqttrecv)(struct Adapter *adapter, const char *topic, const void *buf, size_t len); }; struct PrivProtocolDone @@ -269,6 +273,18 @@ int AdapterDevicePing(struct Adapter *adapter, const char *destination); /*Show the net status*/ int AdapterDeviceNetstat(struct Adapter *adapter); +/*Connect to a certain mqtt server*/ +int AdapterDeviceMqttConnect(struct Adapter *adapter, const char *ip, const char *port, const char *client_id, const char *username, const char *password); + +/*Adapter disconnect from mqtt server*/ +int AdapterDeviceMqttDisconnect(struct Adapter *adapter); + +/*Send data to mqtt server*/ +ssize_t AdapterDeviceMqttSend(struct Adapter *adapter, const char *topic, const void *buf, size_t len); + +/*Receice data from mqtt server*/ +ssize_t AdapterDeviceMqttRecv(struct Adapter *adapter, const char *topic, void *buf, size_t len); + #ifdef __cplusplus } #endif