|
|
@@ -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;
|
|
|
}
|
|
|
|
|
|
+
|