Bladeren bron

解决冲突

guohui 1 jaar geleden
bovenliggende
commit
8f2590271b
3 gewijzigde bestanden met toevoegingen van 336 en 17 verwijderingen
  1. 321 17
      pro/src/Cellular.c
  2. 11 0
      pro/src/Cellular.h
  3. 4 0
      pro/src/common.h

+ 321 - 17
pro/src/Cellular.c

@@ -15,10 +15,12 @@
 #define SERIAL_PORT "/dev/ttyUSB1"
 #define BAUD_RATE B115200
 #define READ_TIMEOUT 100000  // 微秒
-#define QUERY_INTERVAL 2000000  // 查询间隔,毫秒
-#define RECONNECT_INTERVAL 10000000  // 查询间隔,毫秒
+#define QUERY_INTERVAL 5000000  // 查询间隔,毫秒
+#define RECONNECT_INTERVAL 10000000  // 连接4G模组间隔,毫秒
 #define RSSI2dBm_1 -113  // LTE、HSDPA网络最小信号值,对应RSSI值范围0-57
 #define RSSI2dBm_2 -116  // TD-SCDMA网络最小信号值,对应RSSI值范围100-199
+char g_ec200Buf[1024] = {0};  
+
 
 int set_serial_attributes(int fd, int speed)
 {
@@ -91,6 +93,131 @@ int read_response(int fd, char *buf, size_t len)
     return n;
 }
 
+ 
+/*
+ @brief 发送AT命令
+ @param pCmd -[in] 命令字符串
+ @param pRes -[in] 需要检测的返回命令字符串
+ @param timeOut -[in] 等待时间
+ @param sendNum -[in] 命令发送次数
+ @return 1 - 成功;0 - 失败
+*/
+uint8_t sendCmd(int fd, char *pCmd, char *pRes, uint32_t timeOut, uint8_t sendNum)
+{
+    uint8_t i = 0;
+    uint32_t time;
+    memset(g_ec200Buf, 0, sizeof(g_ec200Buf));                                                     // 清空缓存	
+    for(i = 0; i < sendNum; i++)
+	{
+        time = timeOut * 10;
+        send_at_command(fd, pCmd);
+        while(time--)
+        {
+            if(read_response(fd, g_ec200Buf, sizeof(g_ec200Buf)))                                              // 如果串口接收完成
+            {
+                if(strstr((const char *)g_ec200Buf, pRes) != NULL)             // 如果检索到关键词
+                {
+                    return 1;
+                }
+            }	
+			usleep(READ_TIMEOUT); // 等待响应                                              // 等待100毫秒
+        }
+        memset(g_ec200Buf, 0, sizeof(g_ec200Buf));       
+    }
+    return 0;
+}
+
+uint8_t EC200_CheckOnce(int fd)
+{
+    uint8_t result = 0;
+    uint8_t step = 0;
+    char buf[256];
+    switch(step)
+    {
+        case 0:
+            if(sendCmd(fd,"AT\r\n","OK", 10, 5))                                   // 测试AT指令功能是否正常
+            {
+                step++;
+            }
+            else
+            {
+                log_e("Err:AT\r\n");
+                _globalCellularManager.Link_status=false;
+                _globalCellularManager.RS_status=false;
+                break;
+            } 
+        case 1:
+            if (sendCmd(fd, "AT+CPIN?\r\n", "+CPIN: READY", 5, 1)) // 查询SIM卡是否正常,返回ready则表示SIM卡正常
+            {
+                step++;
+            }
+            else
+            {
+                log_e("Err:AT+CPIN?\r\n"); // 5秒内,无法识别SIM状态,重启模块
+                _globalCellularManager.Link_status = false;
+                break;
+            }
+        case 2:
+            if (sendCmd(fd, "AT+CREG?\r\n", "+CREG: 0,1", 5, 1)) // 查询模组是否注册上GSM网络
+            {
+                step++;
+                get_cops(fd);
+                get_cimi(fd);
+                get_APN(fd);
+                get_rssi(fd);
+            }
+            else
+            {
+                log_e("Err:AT+CREG?\r\n");                                     // 5秒内,没有注册上CS业务,
+                 _globalCellularManager.Link_status=false;
+                break;
+            }
+        case 3:
+            if(sendCmd(fd,"AT+CGREG?\r\n","+CGREG: 0,1", 5, 1))                   // 查询模组是否注册上GPRS网络
+            {
+                step++;                                                 
+            }
+            else
+            {
+                log_e("Err:AT+CGREG?\r\n");                                    // 60秒内,没有注册上PS业务
+                  _globalCellularManager.Link_status=false; 
+                break;
+            }
+        case 4:
+            memset(buf, 0, sizeof(buf));
+            sprintf(buf, "AT+QICSGP=1,1,\"%s\",\"\",\"\",1\r\n", _globalCellularManager.Cellular_APN);
+            if(sendCmd(fd,buf, "OK", 10,2)) // 根据APN接入点配置场景,场景默认为1
+            {
+                result = 1;
+                if (!_globalCellularManager.Link_status)
+                {
+                    if (sendCmd(fd,"AT+QIDEACT=1\r\n", "OK", 40, 1)) // 在激活GPRS场景之前先关闭GPRS场景,确保连接正确
+                    {
+                        if (sendCmd(fd,"AT+QIACT=1\r\n", "OK", 150, 1)) // 激活移动场景
+                        {
+                            _globalCellularManager.Link_status=true;             
+                        }
+                        else // 等待150秒后,没有响应重启模块
+                        {
+                            log_e("Err:AT+QIACT=1\r\n"); // 重启模块
+                        }
+                    }
+                    else // 等待40秒后,没有响应重启模块
+                    {
+                        log_e("Err:AT+QIDEACT=1\r\n"); // 重启模块      
+                    }
+                }    
+            }
+            else
+            {
+                log_e("Err:AT+QICSGP=1,1\r\n");                                // 如果3次都没停止成功或超过40秒没有回应,则重启模块
+                _globalCellularManager.Link_status=false;
+                break;
+            }
+    }
+    return result;
+}
+
 int get_rssi(int fd)
 {
     char buf[256];
@@ -158,12 +285,10 @@ int get_cops(int fd)
                 token = strtok(NULL, ",");
                 if (token != NULL)
                 {
-                    token = strtok(NULL, ",");
-                    if (token != NULL)
-                    {
+    
                         if (token[0] == '"' && strlen(token) > 2 && token[strlen(token) - 1] == '"')
                         {
-                            int len = strlen(token) - 2;
+                            int len = strlen(token) - 1;
                             if (len >= 0 && len <= 64)
                             {
                                 strncpy(_globalCellularManager.Cellular_name, token + 1, len);
@@ -175,8 +300,7 @@ int get_cops(int fd)
                             // 如果格式不正确,则清空运营商名称
                             sprintf(_globalCellularManager.Cellular_name, "-");
                         }
-                    }
-                    else  return -1;
+
                 }
                 else  return -1;
             }
@@ -209,6 +333,12 @@ int get_cimi(int fd)
         }
         else
         {
+            char *pos = strstr(cimi_start, "OK"); // 查找子字符串的位置
+            if (pos != NULL)
+            {
+                // 将pos指向的位置替换为字符串结束符,从而删除子字符串之后的内容
+                *(pos) = '\0';
+            }
             int cimi_size = strlen(cimi_start);
             strncpy(_globalCellularManager.Cellular_Num, cimi_start, cimi_size);
         }
@@ -216,10 +346,55 @@ int get_cimi(int fd)
     }
     else
         return -1;
-
+    
     return 0;
 }
+int get_APN(int fd)
+{
+    /*
+    char buf[256];
+    // 4 发送AT+CGDCONT指令查询APN信息
+    const char *cgdcont_cmd = "AT+CGDCONT?\r";
+    send_at_command(fd, cgdcont_cmd);
+    memset(buf, 0, sizeof(buf));
+    read_response(fd, buf, sizeof(buf));
+    char *apn_start = strstr(buf, "+CGDCONT: ");
+    if (apn_start)
+    {
+        apn_start += strlen("+CGDCONT: ");
+        char *token = strtok((char *)apn_start, ",");
+        if (token != NULL)
+        {
+            // 跳过CID字段并获取APN名称
+            token = strtok(NULL, "\"");
+            if (token != NULL)
+            {
+                int apn_size = strlen(token);
+                strncpy(_globalCellularManager.Cellular_APN, token, apn_size);
+            }
+            else  return -1;
+        }
+    }*/
 
+    if (strstr(_globalCellularManager.Cellular_name, "CHINA MOBILE") || strstr(_globalCellularManager.Cellular_name, "CMCC") || strstr(_globalCellularManager.Cellular_name, "46000"))
+    {
+        strcpy(_globalCellularManager.Cellular_APN, "cmnet"); // 示例APN,实际可能不同
+    }
+    else if (strstr(_globalCellularManager.Cellular_name, "CHN-UNICOM") || strstr(_globalCellularManager.Cellular_name, "UNICOM") || strstr(_globalCellularManager.Cellular_name, "46001"))
+    {
+        strcpy(_globalCellularManager.Cellular_APN, "uninet"); // 示例APN,实际可能不同
+    }
+    else if (strstr(_globalCellularManager.Cellular_name, "CHN-CT") || strstr(_globalCellularManager.Cellular_name, "CT") || strstr(_globalCellularManager.Cellular_name, "46011"))
+    {
+        strcpy(_globalCellularManager.Cellular_APN, "ctnet"); // 示例APN,实际可能不同
+    }
+    else
+    {
+        memset(_globalCellularManager.Cellular_APN, 0, sizeof(_globalCellularManager.Cellular_APN));
+        return -1; // 未知的运营商名称
+    }
+    return 0;
+}
 
 static void* Cellular_thread(void *arg)
 {
@@ -227,7 +402,7 @@ static void* Cellular_thread(void *arg)
 
     while (_globalCellularManager.mode)
     {
-        if (!_globalCellularManager.Link_status)
+        if (!_globalCellularManager.RS_status)
         {
             fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_SYNC);
             if (fd < 0)
@@ -243,11 +418,12 @@ static void* Cellular_thread(void *arg)
                 }
                 else
                 {
-                    _globalCellularManager.Link_status = true;
-                     log_i("Open 4G Module Success!!!\n");
+                    _globalCellularManager.RS_status = true;
+                    _globalCellularManager.RS_fd=fd;
+                    log_i("Open 4G Module Success!!!\n");
                 }
             }
-            if (!_globalCellularManager.Link_status)
+            if (!_globalCellularManager.RS_status)
                 usleep(RECONNECT_INTERVAL);
             else
                 usleep(QUERY_INTERVAL);
@@ -256,13 +432,11 @@ static void* Cellular_thread(void *arg)
         {
             if (fd < 0)
             {
-                _globalCellularManager.Link_status = false;
+                InitCellularManager();
             }
             else
             {
-                get_rssi(fd);
-                get_cops(fd);
-                get_cimi(fd);
+                EC200_CheckOnce(fd);
             }
             // 等待一段时间再进行下一次查询
             usleep(QUERY_INTERVAL);
@@ -302,5 +476,135 @@ int Cellular_deinit(void)
 }
 
 
+bool  EC200_CreateTCPSocket(char *pIP,int pPort)
+{
+    bool ret = false;
+    char buf[256];
+    memset(buf, 0, sizeof(buf));
+    sprintf(buf, "AT+QIOPEN=1,0,\"TCP\",\"%s\",%d,0,0\r\n", pIP, pPort);
+
+    if (sendCmd(_globalCellularManager.RS_fd, buf, "+QIOPEN:", 150, 5))
+    {
+        ret = true;
+        log_i("Create 4G TCPSocket Success\r\n");
+    }
+    else
+    {
+        log_e("Err:Create 4G TCPSocket Failed\r\n");
+    }
+    return ret;
+}
+
+bool  EC200_CreateUDPService(int pLocalPort)
+{
+    bool ret = false;
+    char buf[256];
+    memset(buf, 0, sizeof(buf));
+    sprintf(buf, "AT+QIOPEN=1,2,\"UDP SERVICE\",\"%s\",%d,0,0\r\n", "127.0.0.1", pLocalPort);
+
+    if (sendCmd(_globalCellularManager.RS_fd, buf, "+QIOPEN:", 150, 5))
+    {
+        ret = true;
+        log_i("Create 4G UDP SERVICE  Success\r\n");
+    }
+    else
+    {
+        log_e("Err:Create 4G UDP SERVICE Failed\r\n");
+    }
+    return ret;
+}
+
+bool EC200S_SendTCPData(char *pData,bool *connectionFlag)
+{
+    *connectionFlag = true;
+    int ret = -1;
+    if (_globalCellularManager.Link_status)
+    {
+        if (sendCmd(_globalCellularManager.RS_fd, "AT+QISEND=0\r\n", ">", 30, 1))
+        {
+            if (write(_globalCellularManager.RS_fd, pData, strlen(pData)) < 0)
+            {
+                log_e("Send 4G TCP data failed!");
+                return ret;
+            }
+
+            uint8_t end_char = 0x1A; // Ctrl+Z
+            if (write(_globalCellularManager.RS_fd, &end_char, 1) < 0)
+            {
+                log_e("Send 4G TCP end char failed!");
+                return ret;
+            }
+
+            if (sendCmd(_globalCellularManager.RS_fd, "AT+QISEND=0,0\r\n", "OK", 5, 24)) // 2分钟后(每5秒查询一次,共24次)
+            {
+                ret = 0;
+            }
+            else
+            {
+                log_e("Err:AT+QISEND=0\r\n");
+                if (sendCmd(_globalCellularManager.RS_fd, "AT+QICLOSE=0\r\n", "OK", 10, 1)) // TCP连接出现异常,关闭TCP连接
+                {
+                    log_i("AT+QICLOSE\r\n");
+                    *connectionFlag = false;
+                }
+                else
+                {
+                    return ret;
+                }
+            }
+        }
+        else
+        {
+            return ret;
+        }
+    }
+    return ret;
+}
+
+
+bool EC200S_SendUDPData(char *pData,char *pIP,int pPort)
+{
+    int ret = -1;
+    char buf[256];
+    memset(buf, 0, sizeof(buf));
+    sprintf(buf, "AT+QISEND=2,%d,\"%s\",%d\r\n",  strlen(pData),pIP, pPort);
+    if (_globalCellularManager.Link_status)
+    {
+        if (sendCmd(_globalCellularManager.RS_fd, buf, ">", 30, 1))
+        {
+            if (write(_globalCellularManager.RS_fd, pData, strlen(pData)) < 0)
+            {
+                log_e("Send 4G UDP data failed!");
+                return ret;
+            }
+            else ret=0;
+        }
+        else
+        {
+            return ret;
+        }
+    }
+    return ret;
+}
+
 
+void InitCellularManager()
+{
+    //_globalCellularManager.mode = 0;
+    _globalCellularManager.Link_status = false; // 4G网络连接状态
+    _globalCellularManager.Signal_strength = 0; // 4G信号强度
+    sprintf(_globalCellularManager.Cellular_name, "-");
+    sprintf(_globalCellularManager.Cellular_Num, "-");
+    //_globalCellularManager.Cellular_IMEI[64]="-"; // IMEI号
+
+   // _globalCellularManager.GPS_status = false;  // GPS功能启用
+    _globalCellularManager.GPS_latitude = 0.0;  // GPS��度
+    _globalCellularManager.GPS_longitude = 0.0; // GPS经度
+    _globalCellularManager.GPS_altitude = 0.0;  // GPS海��高度
+    _globalCellularManager.GPS_speed = 0.0;     // GPS速度,单位km/h
+    _globalCellularManager.GPS_nsat = 0;        // GPS��星数量
+    sprintf(_globalCellularManager.GPS_utc, "-");
+
+    //_globalCellularManager.SMS_status = false; // 短信功能启用
+}
 

+ 11 - 0
pro/src/Cellular.h

@@ -9,8 +9,19 @@ int set_serial_attributes(int fd, int speed);
 
 int read_response(int fd, char *buf, size_t len);
 
+
+uint8_t sendCmd(int fd, char *pCmd, char *pRes, uint32_t timeOut, uint8_t sendNum);
+uint8_t EC200_CheckOnce(int fd);
+
 int get_rssi(int fd);
 int get_cops(int fd);
 int get_cimi(int fd);
+int get_APN(int fd);
+
+
+bool  EC200_CreateTCPSocket(char *pIP,int pPort);
+bool  EC200_CreateUDPService(int pLocalPort);
+bool EC200S_SendTCPData(char *pData,bool *connectionFlag);
+bool EC200S_SendUDPData(char *pData,char *pIP,int pPort);
 
 #endif

+ 4 - 0
pro/src/common.h

@@ -561,8 +561,11 @@ typedef struct
 {
     int mode;         // 4G模块启用状态
     bool Link_status; // 4G网络连接状态
+    bool RS_status; // 4G模组串口访问状态
+    int RS_fd; // 4G模组串口访问状态
     float Signal_strength; // 信号强度
     char Cellular_name[64];// 4G网络名称
+    char Cellular_APN[64];// APN接入点名称
     char Cellular_Num[64];// 电话号码
 	
 	bool GPS_status; // GPS功能启用
@@ -1336,5 +1339,6 @@ int days_in_month(int year, int month);
 void add_day_to_date(char *date_str, int *year, int *month, int *day);
 
 void SetMenuAuthority(int RoleID);
+void InitCellularManager();
 
 #endif