From 5986dce9e7d4ba4e3e72e327e8cab2901b69310f Mon Sep 17 00:00:00 2001 From: xuyanghang Date: Thu, 11 Jan 2024 13:40:03 +0800 Subject: [PATCH] 4G module EC200A NetworkInfo acquirement --- .../Framework/connection/4g/adapter_4g.c | 2 + .../Framework/connection/4g/ec200a/ec200a.c | 132 +++++++++++++++++- APP_Framework/Framework/connection/adapter.h | 15 ++ .../Framework/connection/adapter_agent.c | 37 +++++ APP_Framework/Framework/connection/at_agent.h | 1 + 5 files changed, 186 insertions(+), 1 deletion(-) diff --git a/APP_Framework/Framework/connection/4g/adapter_4g.c b/APP_Framework/Framework/connection/4g/adapter_4g.c index d3a6085d5..2e84dc6a4 100644 --- a/APP_Framework/Framework/connection/4g/adapter_4g.c +++ b/APP_Framework/Framework/connection/4g/adapter_4g.c @@ -136,6 +136,8 @@ int Adapter4GTest(void) AdapterDeviceOpen(adapter); AdapterDeviceControl(adapter, OPE_INT, &baud_rate); + AdapterDeviceNetstat(adapter); + AdapterDeviceConnect(adapter, CLIENT, server_addr, server_port, IPV4); while (1) { diff --git a/APP_Framework/Framework/connection/4g/ec200a/ec200a.c b/APP_Framework/Framework/connection/4g/ec200a/ec200a.c index d19f9b008..018e15e31 100644 --- a/APP_Framework/Framework/connection/4g/ec200a/ec200a.c +++ b/APP_Framework/Framework/connection/4g/ec200a/ec200a.c @@ -376,8 +376,138 @@ out: return -1; } -static int Ec200aNetstat() { +static void extractCarrierInfo(const char *response, struct NetworkInfo *networkInfo) +{ + const char *delimiter = "\""; + const char *token; + token = strtok(response, delimiter); + token = strtok(NULL, delimiter); + + if (strcmp(token, "CHINA MOBILE") == 0) { + networkInfo->carrier_type = CARRIER_CHINA_MOBILE; + } else if (strcmp(token, "CHN-UNICOM") == 0) { + networkInfo->carrier_type = CARRIER_CHINA_UNICOM; + } else if (strcmp(token, "CHN-CT") == 0) { + networkInfo->carrier_type = CARRIER_CHINA_TELECOM; + } else { + networkInfo->carrier_type = CARRIER_UNKNOWN; + } +} + +static int Ec200aNetstat(struct Adapter *adapter) { + char result[64] = {0}; + + struct NetworkInfo info = { + .carrier_type = CARRIER_UNKNOWN, + .signal_strength = 0, + .ip_address = "192.168.1.1" + }; + + int ret = 0; + int try = 0; + + 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+COPS?", get carrier type*/ + for(try = 0; try < TRY_TIMES; try++){ + ret = AtGetNetworkInfoReply(adapter->agent, EC200A_GET_COPS_CMD, result); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + extractCarrierInfo(result, &info); + adapter->network_info.carrier_type = info.carrier_type; + + /*step6: serial write "AT+CSQ", get carrier type*/ + memset(result, 0, sizeof(result)); + + for(try = 0; try < TRY_TIMES; try++){ + ret = AtGetNetworkInfoReply(adapter->agent, EC200A_GET_CSQ_CMD, result); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + if (sscanf(result, "AT+CSQ\n+CSQ: %d", &info.signal_strength) == 1) { + printf("Signal Strength: %d\n", info.signal_strength); + adapter->network_info.signal_strength = info.signal_strength; + } else { + printf("Failed to parse signal strength\n"); + goto out; + } + + /*step7: serial write "AT+CSQ", get carrier type*/ + memset(result, 0, sizeof(result)); + + for(try = 0; try < TRY_TIMES; try++){ + ret = AtGetNetworkInfoReply(adapter->agent, EC200A_GET_POP_IP, result); + if (ret == 0) { + break; + } + } + if (ret < 0) { + goto out; + } + if (sscanf(result, "AT+CGPADDR=1\n+CGPADDR: 1,\"%15[^\"]\"", info.ip_address) == 1) { + printf("IP Address: %s\n", info.ip_address); + strcpy(adapter->network_info.ip_address, info.ip_address); + } else { + printf("Failed to parse IP address\n"); + goto out; + } + + return 0; + +out: + ADAPTER_DEBUG("Ec200a get netstat failed. Power down\n"); + ret = AtCmdConfigAndCheck(adapter->agent, EC200A_CLOSE, EC200A_OK_REPLY); + return -1; } static const struct IpProtocolDone ec200a_done = diff --git a/APP_Framework/Framework/connection/adapter.h b/APP_Framework/Framework/connection/adapter.h index d11080fdf..3c60e0f73 100644 --- a/APP_Framework/Framework/connection/adapter.h +++ b/APP_Framework/Framework/connection/adapter.h @@ -118,6 +118,19 @@ enum IpType IPV6, }; +enum CarrierType { + CARRIER_CHINA_MOBILE = 1, + CARRIER_CHINA_UNICOM, + CARRIER_CHINA_TELECOM, + CARRIER_UNKNOWN, +}; + +struct NetworkInfo { + enum CarrierType carrier_type; + int signal_strength; + char ip_address[16]; +}; + struct AdapterData { uint32 len; @@ -186,6 +199,8 @@ struct Adapter enum NetRoleType net_role; enum AdapterStatus adapter_status; + struct NetworkInfo network_info; + char buffer[ADAPTER_BUFFSIZE]; void *done; diff --git a/APP_Framework/Framework/connection/adapter_agent.c b/APP_Framework/Framework/connection/adapter_agent.c index 353beab17..232c12670 100755 --- a/APP_Framework/Framework/connection/adapter_agent.c +++ b/APP_Framework/Framework/connection/adapter_agent.c @@ -225,6 +225,43 @@ __exit: return ret; } +int AtGetNetworkInfoReply(ATAgentType agent, char *cmd, char *result) +{ + int ret = 0; + if (NULL == agent || NULL == cmd) { + return -1; + } + + ATReplyType reply = CreateATReply(256); + if (NULL == reply) { + printf("%s %d at_create_resp failed!\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + + ret = ATOrderSend(agent, REPLY_TIME_OUT, reply, cmd); + if(ret < 0){ + printf("%s %d ATOrderSend failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + + const char *replyText = GetReplyText(reply); + if (replyText == NULL || replyText[0] == '\0') { + printf("%s %n get reply failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + + strncpy(result, replyText, 63); + result[63] = '\0'; + printf("[reply result: %s]\n", result); + +__exit: + DeleteATReply(reply); + return ret; +} + char *GetReplyText(ATReplyType reply) { return reply->reply_buffer; diff --git a/APP_Framework/Framework/connection/at_agent.h b/APP_Framework/Framework/connection/at_agent.h index 809d336e8..c96c3c3e3 100755 --- a/APP_Framework/Framework/connection/at_agent.h +++ b/APP_Framework/Framework/connection/at_agent.h @@ -104,5 +104,6 @@ int ParseATReply(char* str, const char *format, ...); void DeleteATReply(ATReplyType reply); int ATOrderSend(ATAgentType agent, uint32_t timeout_s, ATReplyType reply, const char *cmd_expr, ...); int AtCmdConfigAndCheck(ATAgentType agent, char *cmd, char *check); +int AtGetNetworkInfoReply(ATAgentType agent, char *cmd, char *result); #endif \ No newline at end of file