Browse Source

1、4G模块信号强度、运营商及电话号码获取

liyuezong 1 year ago
parent
commit
67de80bd12
3 changed files with 285 additions and 20 deletions
  1. 267 20
      pro/src/Cellular.c
  2. 9 0
      pro/src/Cellular.h
  3. 9 0
      pro/src/appweb_handle.c

+ 267 - 20
pro/src/Cellular.c

@@ -3,14 +3,273 @@
 #include "Cellular.h"
 #include <pthread.h>
 #include "thread.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <errno.h>
+
+#define SERIAL_PORT "/dev/ttyUSB1"
+#define BAUD_RATE B115200
+#define READ_TIMEOUT 100000  // 微秒
+#define QUERY_INTERVAL 2000000  // 查询间隔,毫秒
+#define RECONNECT_INTERVAL 10000000  // 查询间隔,毫秒
+#define RSSI2dBm_1 -113  // LTE、HSDPA网络最小信号值,对应RSSI值范围0-57
+#define RSSI2dBm_2 -116  // TD-SCDMA网络最小信号值,对应RSSI值范围100-199
+
+int set_serial_attributes(int fd, int speed)
+{
+    if (fd < 0)
+        return -1;
+    struct termios tty;
+
+    if (tcgetattr(fd, &tty) != 0)
+    {
+        log_e("Read 4G Module tcgetattr!!!\n");
+        return -1;
+    }
+
+    cfsetospeed(&tty, speed);
+    cfsetispeed(&tty, speed);
+
+    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
+    tty.c_iflag &= ~IGNBRK;                     // disable break processing
+    tty.c_lflag = 0;                            // no signaling chars, no echo,
+                                                // no canonical processing
+    tty.c_oflag = 0;                            // no remapping, no delays
+    tty.c_cc[VMIN] = 0;                         // read doesn't block
+    tty.c_cc[VTIME] = 5;                        // 0.5 seconds read timeout
+
+    tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
+
+    tty.c_cflag |= (CLOCAL | CREAD);   // ignore modem controls,
+                                       // enable reading
+    tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
+    tty.c_cflag |= 0;
+    tty.c_cflag &= ~CSTOPB;
+    tty.c_cflag &= ~CRTSCTS;
+
+    if (tcsetattr(fd, TCSANOW, &tty) != 0)
+    {
+        log_e("Read 4G Module tcsetattr!!!\n");
+        return -1;
+    }
+    return 0;
+}
+void send_at_command(int fd, const char *cmd)
+{
+    if (fd < 0)
+        return;
+    write(fd, cmd, strlen(cmd));
+    usleep(READ_TIMEOUT); // 等待响应
+}
+
+int read_response(int fd, char *buf, size_t len)
+{
+    if (fd < 0)
+        return -1;
+
+    int n = read(fd, buf, len - 1);
+    if (n > 0)
+    {
+        buf[n] = '\0';
+    }
+    else if (n == 0)
+    {
+        // 读取到文件结束符,通常不会发生在串口通信中
+        buf[0] = '\0';
+    }
+    else
+    {
+        // 读取错误
+        log_e("Read 4G Module Failed!!!\n");
+        buf[0] = '\0';
+    }
+    return n;
+}
+
+int get_rssi(int fd)
+{
+    char buf[256];
+
+    // 1 发送AT+CSQ指令查询信号强度
+    const char *csq_cmd = "AT+CSQ\r";
+    send_at_command(fd, csq_cmd);
+    // 读取响应
+    memset(buf, 0, sizeof(buf));
+    read_response(fd, buf, sizeof(buf));
+    // 解析响应(这里假设响应格式为"+CSQ: <rssi>,<ber>\r\nOK\r\n")
+    char *rssi_start = strstr(buf, "+CSQ: ");
+    if (rssi_start)
+    {
+        rssi_start += strlen("+CSQ: ");
+        char *rssi_end = strchr(rssi_start, ',');
+        if (rssi_end)
+        {
+            *rssi_end = '\0';
+            int rssi = atoi(rssi_start);
+            if (rssi < 57 && rssi >= 0)
+            {
+                _globalCellularManager.Signal_strength = RSSI2dBm_1 + 2 * rssi;
+            }
+            else if (rssi < 199 && rssi >= 100)
+            {
+                _globalCellularManager.Signal_strength = RSSI2dBm_2 + rssi - 100;
+            }
+            else
+                _globalCellularManager.Signal_strength = 0;
+
+            log_i("Get 4G Signal Strength (RSSI): %d\n", rssi);
+        }
+        else return -1;
+    }
+    else
+    {
+        log_i("Unexpected response: %s\n", buf);
+        return -1;
+    }
+
+    return 0;
+}
+int get_cops(int fd)
+{
+    char buf[256];
+    // 2 发送AT+COPS指令查询运营商信息
+    const char *cops_cmd = "AT+COPS?\r";
+    send_at_command(fd, cops_cmd);
+    memset(buf, 0, sizeof(buf));
+    int n = read_response(fd, buf, sizeof(buf));
+    char *cops_start = strstr(buf, "+COPS: ");
+    if (cops_start)
+    {
+        cops_start += strlen("+COPS: ");
+        // buf[n] = '\0';
+        char *token = strtok((char *)cops_start, ",");
+        if (token != NULL)
+        {
+            // 跳过mode字段
+            token = strtok(NULL, ",");
+            if (token != NULL)
+            {
+                // 跳过format字段并获取act字段
+                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;
+                            if (len >= 0 && len <= 64)
+                            {
+                                strncpy(_globalCellularManager.Cellular_name, token + 1, len);
+                                _globalCellularManager.Cellular_name[len - 1] = '\0'; // 确保字符串以null结尾
+                            }
+                        }
+                        else
+                        {
+                            // 如果格式不正确,则清空运营商名称
+                            sprintf(_globalCellularManager.Cellular_name, "-");
+                        }
+                    }
+                    else  return -1;
+                }
+                else  return -1;
+            }
+            else  return -1;
+        }
+        else  return -1;
+        log_i("Get 4G Operator Infomation: %s\n", cops_start);
+    }
+    else  return -1;
+
+     return 0;
+}
+int get_cimi(int fd)
+{
+    char buf[256];
+    // 3 发送AT+CIMI指令查询电话号码
+    const char *cimi_cmd = "AT+CIMI\r";
+    send_at_command(fd, cimi_cmd);
+    // 读取响应
+    memset(buf, 0, sizeof(buf));
+    read_response(fd, buf, sizeof(buf));
+    char *cimi_start = strstr(buf, "+CIMI");
+    if (cimi_start)
+    {
+        cimi_start += strlen("+CIMI");
+        if (strstr(cimi_start, "+CME"))
+        {
+            // 如果获取到错误信息,则清空电话号码
+            sprintf(_globalCellularManager.Cellular_Num, "-");
+        }
+        else
+        {
+            int cimi_size = strlen(cimi_start);
+            strncpy(_globalCellularManager.Cellular_Num, cimi_start, cimi_size);
+        }
+        log_i("Get 4G CIMI Information: %s\n", cimi_start);
+    }
+    else
+        return -1;
+
+    return 0;
+}
 
 
 static void* Cellular_thread(void *arg)
 {
-    while(1) {
+    int fd;
 
-        sleep(100);
+    while (_globalCellularManager.mode)
+    {
+        if (!_globalCellularManager.Link_status)
+        {
+            fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_SYNC);
+            if (fd < 0)
+            {
+                log_e("Open 4G Module Failed!!!\n");
+            }
+            else
+            {
+                if (set_serial_attributes(fd, BAUD_RATE) < 0)
+                {
+                    close(fd);
+                    log_e("Open 4G Module Failed!!!\n");
+                }
+                else
+                {
+                    _globalCellularManager.Link_status = true;
+                     log_i("Open 4G Module Success!!!\n");
+                }
+            }
+            if (!_globalCellularManager.Link_status)
+                usleep(RECONNECT_INTERVAL);
+            else
+                usleep(QUERY_INTERVAL);
+        }
+        else
+        {
+            if (fd < 0)
+            {
+                _globalCellularManager.Link_status = false;
+            }
+            else
+            {
+                get_rssi(fd);
+                get_cops(fd);
+                get_cimi(fd);
+            }
+            // 等待一段时间再进行下一次查询
+            usleep(QUERY_INTERVAL);
+        }
     }
+
+    close(fd);
+    Cellular_deinit();
     pthread_exit(NULL);
 }
 
@@ -23,28 +282,18 @@ static void* Cellular_thread(void *arg)
  */
 int Cellular_init(void)
 {
-    int r = -1;
-
-    InitCellularManager();
-    if (_globalCellularManager.mode == 1)
+    if (0==thread_is_running(THREAD_ID_Cellular))
     {
+        InitCellularManager();
         thread_start(THREAD_ID_Cellular, Cellular_thread, &_globalCellularManager);
-        r = 0;
     }
-
-    return r;
+    return 0;
 }
 
 int Cellular_deinit(void)
 {
-        int r=-1;
-
-        if (_globalCellularManager.mode == 1)
-        {
-            r = 0;
-        }
-
-        return r;
+    InitCellularManager();
+    return 0;
 }
 
 int WIFI_init(void)
@@ -54,7 +303,6 @@ int WIFI_init(void)
     InitWIFIManager();
     if (_globalWIFIManager.mode == 1)
     {
-
         //thread_start(THREAD_ID_Cellular, Cellular_thread, &_globalCellularManager);
         r = 0;
     }
@@ -65,12 +313,11 @@ int WIFI_init(void)
 int WIFI_deinit(void)
 {
         int r=-1;
-
         if (_globalWIFIManager.mode == 1)
         {
             r = 0;
         }
-
         return r;
 }
 
+

+ 9 - 0
pro/src/Cellular.h

@@ -7,4 +7,13 @@ int Cellular_deinit(void);
 int WIFI_init(void);
 int WIFI_deinit(void);
 
+void send_at_command(int fd, const char *cmd);
+int set_serial_attributes(int fd, int speed);
+
+int read_response(int fd, char *buf, size_t len);
+
+int get_rssi(int fd);
+int get_cops(int fd);
+int get_cimi(int fd);
+
 #endif

+ 9 - 0
pro/src/appweb_handle.c

@@ -16,6 +16,7 @@
 #include "language_common.h"
 #include "websocket_handle.h"
 #include "breaker_detection.h"
+#include "Cellular.h"
 
 #define TOTAL_COUNT 60
 #define FN_MAX  30
@@ -3886,6 +3887,14 @@ static void communicationManagement(void *conn)
     {
         _globalCellularManager.mode = reqInfo._4g_wifi_info.Cellular_mode;
         CellularWIFI_paras_save();
+        if (_globalCellularManager.mode)
+        {
+            Cellular_init();
+        }
+        else
+        {
+            thread_stop(THREAD_ID_Cellular);
+        }
          ack_str = ctrl_sts_ack_to_json(); 
     }
     else if(strcmp(reqInfo.type,"listWIFIPZQuery")==0) // WIFI处理