#include #include #include #include #include #include #include #include #include "cJSON.h" #include "json_handle.h" #include "websocket_handle.h" #include "common.h" #include "sys.h" #include "Cellular.h" #include #include "thread.h" #include "paras.h" #include "lock.h" #include "elog.h" #include "cfg.h" #include "sqlite_handle.h" #if 0 #define LOGE log_e #define LOGW log_w #define LOGD log_d #else #define LOGD printf #define LOGW printf #define LOGE printf #endif #define RETRY_TIMES 1 #define BUF_LEN 2000 #define AT_PORT "/dev/ttyUSB1" #define BAUD_RATE B115200 #define QUERY_INTERVAL 1000 // 查询间隔,毫秒 #define RSSI_DBM_MIN1 -113 // LTE、HSDPA网络最小信号值,对应RSSI值范围0-57 #define RSSI_DBM_MIN2 -116 // TD-SCDMA网络最小信号值,对应RSSI值范围100-199 #define CONTEXT_ID "1" //1~15 #define CONNECT_ID "0" //0~11 #define CONNECT_TIMEOUT "5" #define CHUNCK_SIZE 1460 #define MQTT_VER 4 //3: v3.1 4: v3.1.1 #define MQTT_WILL 0 #define MQTT_RETAIN 0 #define MQTT_MAX 6 #define MQTT_QOS 2 #define MQTT_CHUNCK_SIZE 1500 #define SMS_SEND_MAX 500 #define UNLINK_MAX 3 #define MAX_CONNECTIONS 6 // EC200N最多支持6个连接 int UnLinkCount=0; enum { AT_OK=0, AT_ERR, AT_TOUT, }; enum { AT_STAT_UNINIT=0, AT_STAT_INITED, }; enum { SOCK_TCP=0, SOCK_UDP, }; enum { URC_SOCK=0, URC_MQTT, URC_GNSS, URC_NTP, URC_SMS, URC_CALL, URC_ERR, }; typedef int (*urc_fn_t)(int urc, void *data, int len); typedef struct { int cmd; char para[100]; }at_para_t; typedef struct { char *cmd; char *ok; char *err; int timeout; //ms }at_cmd_t; typedef struct { int cmd; char *buf; int dlen; int blen; }at_buf_t; typedef struct { at_buf_t rx; at_buf_t tx; }at_data_t; typedef struct { void *h; int sock; int cont_id; //1~15 int cont_type; //1:ipv4 2:ipv6 3:ipv4+ipv6 int conn_id; char apn[64]; char username[128]; char password[128]; int authentication; //0:none 1:PAP 2:CHAP 3:PAP OR CHAP int cdma_pwd; //0:no save 1:save }sock_conn_t; typedef struct { char host[100]; uint16_t port; char username[64]; char password[64]; }mqtt_para_t; typedef struct { int flag; int qos; int retain; char topic[256]; char message[256]; int message_len; }mqtt_will_t; typedef struct { char product_key[64]; //aliyun used char device_name[64]; //aliyun used char device_secret[64]; //aliyun/ used char product_id[64]; //onenet used char access_key[64]; //onenet used int hw_time_enable; //huawei used char product_secret[64]; //huawei used char node_id[64]; }mqtt_plat_t; typedef struct { void *h; int ver; //3:v3.1 4:v3.1.1 int pdpId; //1~15 int cliId; uint16_t msgId; int qos; int retain; mqtt_will_t will; int timeout; //1~60, default:5 int retry_times; int timeout_notice; int clean_session; int keep_alive_time; //0~3600 seconds default:120, 0:do not disconnect int ssl_enable; int ssl_ctx_id; int msg_recv_mode; //0: urc, 1: not urc int msg_len_enable; int ping_interval; //5~60, default:5 int proto_chk_enable; //0:no check 1:check int send_mode; //0:string 1:hex int recv_mode; //0:string 1:hex int view_mode; //0:no echo 1:echo int edit_mode; //0:timeout not quit 1:timeout quit int edit_time; //1~120 seconds mqtt_plat_t plat; }mqtt_conn_t; typedef struct { int fd; CellInfo_t *pcell; //lock_t lck; char prod_id[32]; int stat; cell_all_t all; int curcmd; //current cmd mqtt_conn_t mq_conn[MQTT_MAX]; at_data_t data[AT_CMD_MAX]; GlobalDeviceManager *dm; }cell_handle_t; static cell_handle_t ceHandle={0}; static at_cmd_t all_cmd[AT_CMD_MAX]={ //genernal cmd {"AT", "OK", "ERROR", 300}, //测试命令 {"ATI", "OK", "ERROR", 300}, //显示MT的ID信息 {"AT+GMI", "OK", "ERROR", 300}, //请求制造商信息 {"AT+GMM", "OK", "ERROR", 300}, //请求TA型号ID {"AT+GMR", "OK", "ERROR", 300}, //请求TA固件版本ID {"AT+CGMI", "OK", "ERROR", 300}, //同GMI {"AT+CGMM", "OK", "ERROR", 300}, //同GMM {"AT+CGMR", "OK", "ERROR", 300}, //同GMR {"AT+GSN", "OK", "ERROR", 300}, //请求国际移动设备识别码(IMEI) {"AT+CGSN", "OK", "ERROR", 300}, //同GSN {"AT&F", "OK", "ERROR", 300}, //重置AT命令设置为出厂设置 {"AT&V", "OK", "ERROR", 300}, //显示当前配置 {"AT&W", "OK", "ERROR", 300}, //存储当前设置到用户自定义配置文件 {"ATZ", "OK", "ERROR", 300}, //从用户定义配置文件还原所有AT命令设置 {"ATQ", "OK", "ERROR", 300}, //设置结果码回显模式 {"ATV", "OK", "ERROR", 300}, //TA响应格式 {"ATE0", "OK", "ERROR", 300}, //设置命令回显模式 {"ATS3", "OK", "ERROR", 300}, //设置命令行终止符 {"ATS4", "OK", "ERROR", 300}, //设置响应格式字符 {"ATS5", "OK", "ERROR", 300}, //设置命令行编辑字符 {"ATX", "OK", "ERROR", 300}, //设置CONNECT结果码格式和检测呼叫进程 {"AT+CFUN", "OK", "ERROR", 15000}, //设置功能模式 {"AT+CMEE", "OK", "ERROR", 300}, //设置错误讯息格式 {"AT+CSCS", "OK", "ERROR", 300}, //选择TE字符集 {"AT+QURCCFG", "OK", "ERROR", 300}, //配置URC指示选项 {"AT+QPPPDROP", "OK", "ERROR", 300}, //终止PPP连接 //serial cmd {"AT&C", "OK", "ERROR", 300}, //设置DCD信号模式 {"AT&D", "OK", "ERROR", 300}, //设置DTR信号模式 {"AT+IFC", "OK", "ERROR", 300}, //设置串口的流控方式 {"AT+IPR", "OK", "ERROR", 300}, //设置固定的串口通信波特率 //status cmd {"AT+CPAS", "OK", "ERROR", 300}, //查询ME活动状态 {"AT+CEER", "OK", "ERROR", 300}, //上报扩展错误 {"AT+QCFG", "OK", "ERROR", 300}, //扩展命令, 较多子命令 {"AT+QINDCFG", "OK", "ERROR", 300}, //控制URC上报 //sim cmd {"AT+CIMI", "OK", "ERROR", 300}, //查询IMSI {"AT+CLCK", "OK", "ERROR", 5000}, //功能锁定 {"AT+CPIN", "OK", "ERROR", 5000}, //PIN管理 {"AT+CPWD", "OK", "ERROR", 5000}, //修改密码 {"AT+CSIM", "OK", "ERROR", 300}, //通用(U)SIM卡访问 {"AT+CRSM", "OK", "ERROR", 300}, //(U)SIM卡受限访问 {"AT+QCCID", "OK", "ERROR", 300}, //查询ICCID {"AT+QPINC", "OK", "ERROR", 300}, //获取PIN剩余重试次数 {"AT+QINISTAT", "OK", "ERROR", 300}, //查询(U)SIM卡初始化状态 {"AT+QSIMDET", "OK", "ERROR", 300}, //(U)SIM卡检测 {"AT+QSIMSTAT", "OK", "ERROR", 300}, //(U)SIM卡插拔状态上报 {"AT+QDSIM", "OK", "ERROR", 50000}, //选择(U)SIM卡 //network service cmd {"AT+COPS", "OK", "ERROR", 300000}, //选择运营商 {"AT+CREG", "OK", "ERROR", 300}, //CS域网络注册状态 {"AT+CSQ", "OK", "ERROR", 300}, //查询信号强度 {"AT+CPOL", "OK", "ERROR", 300}, //配置首选运营商列表 {"AT+COPN", "OK", "ERROR", 300}, //查询运营商名称列表 {"AT+CTZU", "OK", "ERROR", 300}, //自动更新时区 {"AT+CTZR", "OK", "ERROR", 300}, //上报时区变化 {"AT+QLTS", "OK", "ERROR", 500}, //获取通过网络同步的最新时间 {"AT+QNWINFO", "OK", "ERROR", 300}, //查询网络信息 //call cmd {"ATA", "OK", "ERROR", 90000}, //呼叫应答 {"ATD", "OK", "ERROR", 5000}, //发起呼叫 {"AT+COLP", "OK", "ERROR", 15000}, //被叫线路识别显示 {"AT+ATH", "OK", "ERROR", 90000}, //挂断现有连接 {"AT+CHUP", "OK", "ERROR", 90000}, //挂断语音通话 {"+++", "OK", "ERROR", 300}, //从数据模式切换至命令模式 {"AT+ATO", "OK", "ERROR", 300}, //从命令模式切换至数据模式 {"AT+ATSO", "OK", "ERROR", 300}, //设置自动应答前振铃次数 {"AT+CLCC", "OK", "ERROR", 300}, //查询当前 ME 呼叫 {"AT^DSCI", "OK", "ERROR", 300}, //指示呼叫状态 //phonebook cmd {"AT+CNUM", "OK", "ERROR", 300}, //查询本机号码 {"AT+CPBF", "OK", "ERROR", 300}, //搜索电话本 {"AT+CPBR", "OK", "ERROR", 300}, //读取电话本条目 {"AT+CPBS", "OK", "ERROR", 300}, //设置电话本存储器 {"AT+CPBW", "OK", "ERROR", 300}, //写入电话本 //sms cmd {"AT+CSMS", "OK", "ERROR", 300}, //选择短消息服务类型 {"AT+CMGF", "OK", "ERROR", 300}, //配置短消息模式 {"AT+CSCA", "OK", "ERROR", 300}, //设置短消息服务中心地址 {"AT+CPMS", "OK", "ERROR", 300}, //配置短消息首选存储位置 {"AT+CMGD", "OK", "ERROR", 300}, //删除短消息 {"AT+CMGL", "OK", "ERROR", 300}, //按状态读取短消息 {"AT+CMGR", "OK", "ERROR", 300}, //按照索引读取短消息 {"AT+CMGS", ">", "ERROR", 120000}, //发送短消息 {"AT+CMMS", "OK", "ERROR", 300}, //发送多条短消息 {"AT+CMGW", "OK", "ERROR", 300}, //存储短消息 {"AT+CMSS", "OK", "ERROR", 300}, //从存储器发送短消息 {"AT+CNMA", "OK", "ERROR", 300}, //新短消息确认 {"AT+CNMI", "OK", "ERROR", 300}, //设置短消息上报方式 {"AT+CSCB", "OK", "ERROR", 300}, //选择小区广播消息类型 {"AT+CSDH", "OK", "ERROR", 300}, //设置文本模式下参数显示 {"AT+CSMP", "OK", "ERROR", 300}, //设置短消息文本模式参数 {"AT+QCMGS", "OK", "ERROR", 120000}, //发送级联短消息 {"AT+QCMGR", "OK", "ERROR", 300}, //读取级联短消息 //gps cmd {"AT+QGPSCFG", "OK", "ERROR", 300}, //配置GNSS {"AT+QGPSDEL", "OK", "ERROR", 300}, //删除辅助数据 {"AT+QGPS", "OK", "ERROR", 300}, //打开GNSS {"AT+QGPSEND", "OK", "ERROR", 300}, //关闭GNSS {"AT+QGPSLOC", "OK", "ERROR", 300}, //获取定位信息 {"AT+QGPSNMEA", "OK", "ERROR", 300}, //获取指定的NMEA语句 {"AT+QAGPS", "OK", "ERROR", 300}, //启用/禁用AGPS //tcp/udp cmd {"AT+QICFG", "OK", "ERROR", 300}, //配置可选参数 {"AT+QICSGP", "OK", "ERROR", 300}, //配置TCP/IP场景参数 {"AT+QIACT", "OK", "ERROR", 10000}, //激活PDP场景 {"AT+QIDEACT", "OK", "ERROR", 10000}, //去激活PDP场景 {"AT+QIOPEN", "OK", "ERROR", 300}, //打开Socket服务 {"AT+QICLOSE", "OK", "ERROR", 300}, //关闭Socket服务 {"AT+QISTATE", "OK", "ERROR", 300}, //查询Socket服务状态 {"AT+QISEND", ">", "ERROR", 300}, //发送数据 {"AT+QIRD", "OK", "ERROR", 300}, //读取收到的TCP/IP数据 {"AT+QISENDEX", "OK", "ERROR", 300}, //发送16进制字符串数据 {"AT+QISWTMD", "OK", "ERROR", 300}, //切换数据访问模式 {"AT+QNTP", "OK", "ERROR", 300}, //进行远程服务器Ping操作 {"AT+QPING", "+QPING", "ERROR", 3000}, //使用NTP服务器同步本地时间 {"AT+QIDNSCFG", "OK", "ERROR", 300}, //配置DNS服务器地址 {"AT+QIDNSGIP", "OK", "ERROR", 300}, //用域名获取IP地址 {"AT+QISDE", "OK", "ERROR", 300}, //控制是否回显AT+QISEND要发送的 {"AT+QIGETERROR", "OK", "ERROR", 300}, //查询上一个AT命令错误代码 //mqtt cmd {"AT+QMTCFG", "OK", "ERROR", 300}, //配置MQTT可选参数 {"AT+QMTOPEN", "OK", "ERROR", 300}, //打开MQTT客户端网络 {"AT+QMTCLOSE", "OK", "ERROR", 300}, //关闭MQTT客户端网络 {"AT+QMTCONN", "OK", "ERROR", 300}, //连接客户端到MQTT服务器 {"AT+QMTDISC", "OK", "ERROR", 300}, //客户端断开与MQTT服务器的连接 {"AT+QMTSUB", "OK", "ERROR", 300}, //订阅主题 {"AT+QMTUNS", "OK", "ERROR", 300}, //退订主题 {"AT+QMTPUBEX", ">", "ERROR", 300}, //发布消息 {"AT+QMTRECV", "OK", "ERROR", 300}, //从缓存中读取消息 //domain cmd {"AT+CGATT", "OK", "ERROR", 140000}, //PS域附着或去附着 {"AT+CGDCONT", "OK", "ERROR", 3000}, //定义PDP上下文 {"AT+CGQREQ", "OK", "ERROR", 300}, //服务质量参数请求 {"AT+CGQMIN", "OK", "ERROR", 300}, //服务质量参数(最低可接受的) {"AT+CGEQREQ", "OK", "ERROR", 300}, //3G服务质量参数(请求的) {"AT+CGEQMIN", "OK", "ERROR", 300}, //3G 服务质量参数(最低可接受的) {"AT+CGACT", "OK", "ERROR", 150000}, //PDP上下文激活/去激活 {"AT+CGDATA", "OK", "ERROR", 300}, //进入数据传输状态 {"AT+CGPADDR", "OK", "ERROR", 300}, //显示PDP地址 {"AT+CGCLASS", "OK", "ERROR", 300}, //GPRS移动站点等级 {"AT+CGEREG", "OK", "ERROR", 300}, //PS域网络注册状态 {"AT+CGEREP", "OK", "ERROR", 300}, //分组域事件上报 {"AT+CGSMS", "OK", "ERROR", 300}, //选择MO短消息服务 {"AT+CEREG", "OK", "ERROR", 300}, //EPS网络注册状态 {"AT+QGDCNT", "OK", "ERROR", 300}, //流量统计 {"AT+QAUGDCNT", "OK", "ERROR", 300}, //自动保存流量统计 {"AT+QNETDEVCTL", "OK", "ERROR", 2000}, //连接USB网卡 {"AT+QCEERCATCFG", "OK", "ERROR", 300}, //配置2G/4G下AT+CEER返回格式 //hardware cmd {"AT+QPOWD", "OK", "ERROR", 300}, //关闭模块 {"AT+CCLK", "OK", "ERROR", 300}, //实时时钟 {"AT+QSCLK", "OK", "ERROR", 300}, //禁用/启用睡眠模式 }; at_para_t init_para[]={ {AT_CMD_AT, ""}, {AT_CMD_ATE, "0"}, {AT_CMD_QSIMDET, "=1,1"}, {AT_CMD_CPIN, "?"}, {AT_CMD_CREG, "?"}, //{AT_CMD_CGDCONT, ""}, {AT_CMD_QICSGP, ""}, {AT_CMD_QIDEACT, "="CONTEXT_ID}, {AT_CMD_QIACT, "="CONTEXT_ID}, {AT_CMD_QCFG, "=\"usbnet\",1"}, //set module to ecm mode {AT_CMD_QNETDEVCTL, "=3,"CONTEXT_ID",0"}, {AT_CMD_CMGF, "=1"}, {AT_CMD_CSCS, "=GSM"}, #ifdef GNSS_ENABLE {AT_CMD_QGPS, "=1"}, {AT_CMD_QGPSCFG, "=\"gnssconfig\",5"}, {AT_CMD_QGPSCFG, "=\"gpsnmeatype\",1"}, #endif {-1, ""}, }; /////////////////////////////////////////////////////////////////////////////////////////////////////// static at_cmd_t* data_of(int cmd) { return &all_cmd[cmd]; } static int rssi_to_dbm(int rssi) { int dbm=0; if(rssi>=0 && rssi<57) { dbm = RSSI_DBM_MIN1+rssi*2; } else if(rssi>=100 && rssi<199) { dbm = RSSI_DBM_MIN2+rssi-100; } return dbm; } static char* str_get(char *buf, char c) { int i,len=strlen(buf); for(i=0; istat=AT_STAT_UNINIT; h->all.stat.dbm = 0; h->all.stat.ber = 0; h->all.stat.nsta = 0; h->all.stat.altitude = 0; sprintf(h->all.stat.latitude, "-"); sprintf(h->all.stat.longitude, "-"); h->all.stat.utctime = 0; h->all.stat.linked = 0; sprintf(h->all.stat.ipv4, "-"); sprintf(h->all.stat.ipv6, "-"); sprintf(h->all.info.apn, "-"); sprintf(h->all.info.cnum, "-"); sprintf(h->all.info.imsi, "-"); sprintf(h->all.info.imei, "-"); sprintf(h->all.info.isp, "-"); } static int port_init(cell_handle_t *h) { h->fd = open(AT_PORT, O_RDWR | O_NOCTTY | O_NONBLOCK); if(h->fd<0) { return -1; } port_setup(h, BAUD_RATE); return 0; } static int port_deinit(cell_handle_t *h) { if(h->fd<0) { return -1; } int r=close(h->fd); h->fd=-1; sleep(2); return r; } static int port_read(cell_handle_t *h, void *data, int len) { return read(h->fd, data, len); } static int port_write(cell_handle_t *h, void *data, int len) { return write(h->fd, data, len); } static int port_setup(cell_handle_t *h, int speed) { struct termios tty; if (tcgetattr(h->fd, &tty) != 0) { LOGE("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(h->fd, TCSANOW, &tty) != 0) { LOGE("Read 4G Module tcsetattr!!!\n"); return -1; } return 0; } static int port_wait(cell_handle_t *h, int timeout) { int r; char buf[100]; fd_set fset; struct timeval tv; tv.tv_sec = timeout/1000; tv.tv_usec = (timeout%1000)*1000; if(h->fd < 0) return -1; FD_ZERO(&fset); FD_SET(h->fd, &fset); r = select(h->fd + 1, &fset, NULL, NULL, &tv); if (r<=0) { if(r<0) { //LOGE("port_wait error %s\n", strerror(errno)); } else { //LOGE("port_wait timeout\n"); } } return r; } static int port_recv(cell_handle_t *h, char *buf, int buflen, int timeout) { int r; r = port_wait(h, timeout); if(r<0) { return -1; } r = port_read(h, buf, buflen); if(r<=0) { return -1; } return r; } static int send_cmd(cell_handle_t *h, int cmd, char *para, char *rcv, int rcvlen) { int i,r,l,tout,finish=0; int tlen=0,buflen,wait_step=10; char buf[BUF_LEN],*pbuf; at_cmd_t *pcmd=data_of(cmd); sprintf(buf, "%s%s\r", pcmd->cmd, para?para:""); LOGD("[tx]: %s\n", buf); for (i = 0; i < RETRY_TIMES; i++) { tout = 0; port_write(h, buf, strlen(buf)); while (tout < pcmd->timeout) { l = port_wait(h, wait_step); if (l > 0) { if (rcv && rcvlen > 0) { pbuf = rcv; buflen = rcvlen; } else { pbuf = buf; buflen = sizeof(buf); } l = port_read(h, pbuf + tlen, buflen); if (l > 0) { tlen += l; pbuf[tlen] = 0; LOGD("[rx]: %s\n", pbuf); if (pcmd->ok && strlen(pcmd->ok) && strstr(pbuf, pcmd->ok)) { return AT_OK; } if (pcmd->err && strlen(pcmd->err) && strstr(pbuf, pcmd->err)) { // 指令不通则重置模块 // if (cmd != AT_CMD_CFUN && cmd != AT_CMD_QIDEACT ) // { // cell_reset(h); // } return AT_ERR; } } } tout += wait_step; usleep(1000); } } //AT不通重启串口 // if (cmd != AT_CMD_QIDEACT && cmd != AT_CMD_CFUN ) // { // port_deinit(h); // port_init(h); // } return AT_TOUT; } static int send_data(cell_handle_t *h, void *data, int len, int timeout) { char buf[100]; int l,tlen=0,tout=0,wait_step=10; l = port_write(h, data, len); if(l==len) { while(tout0) { l = port_read(h, buf, sizeof(buf)); if(l>0) { tlen += l; buf[tlen] = 0; if(strstr(buf, "OK")) { return AT_OK; } else if(strstr(buf, "ERROR")) { return AT_ERR; } } } tout += wait_step; } } return AT_TOUT; } //////////////////////////////////////////////////////////////////////////// static int cell_reset(cell_handle_t *h) { int r=AT_OK; // r = send_cmd(h, AT_CMD_CFUN, "=1,1", NULL, 0); // if(r==AT_OK) { // h->stat = AT_STAT_UNINIT; //} //sleep(5);//等待模块复位完成 // if (r == AT_OK) // { // port_deinit(h); // port_init(h); // } return (r==AT_OK)?0:-1; } static int cell_init(cell_handle_t *h) { int i,r; at_para_t *p=init_para; if(h->stat==AT_STAT_INITED) { return 0; } for(i=0;; i++) { if(p[i].cmd==-1) { break; } if(p[i].cmd==AT_CMD_CGDCONT) { sprintf(p[i].para, "=%s,\"IPV4V6\",\"%s\"", CONTEXT_ID, h->pcell->apn); } else if(p[i].cmd==AT_CMD_QICSGP) { sprintf(p[i].para, "=%s,3,\"%s\",\"%s\",\"%s\"", CONTEXT_ID, h->pcell->apn,h->pcell->username,h->pcell->password); } r = send_cmd(h, p[i].cmd, p[i].para, NULL, 0); if(r!=AT_OK) { if (p[i].cmd==AT_CMD_AT) { port_deinit(h); port_init(h); } break; } } if(r==0) { h->stat = AT_STAT_INITED; nic_set(NIC_USB, 1); cell_get_info(h, &h->all.info); } return r?-1:0; } static int cell_deinit(cell_handle_t *h) { int r=-1; char buf[400]; r = send_cmd(h, AT_CMD_QIDEACT, "="CONTEXT_ID, buf, sizeof(buf)); if(r==AT_OK) { return r; } return r; } static int cell_get_ip(cell_handle_t *h, cell_stat_t *stat) { char buf[200]; int r=-1; memset(stat->ipv4, 0, sizeof(stat->ipv4)); memset(stat->ipv6, 0, sizeof(stat->ipv6)); if(h->stat==AT_STAT_UNINIT) { return -1; } r = send_cmd(h, AT_CMD_QIACT, "?", buf, sizeof(buf)); if (r != AT_OK) { return -1; } r = sscanf(str_get(buf, '+'), "+QIACT: %*d,%*d,%*d,\"%15[^\"]\",\"%63[^\"]\"", stat->ipv4, stat->ipv6); LOGD("Cellular IPV4: %s\n",stat->ipv4); LOGD("Cellular IPV6:%s\n", stat->ipv6); return 0; } static int cell_get_info(cell_handle_t *h, cell_info_t *info) { int r; char buf[400]; if(h->stat==AT_STAT_UNINIT) { return -1; } memset(info, 0, sizeof(cell_info_t)); // r = send_cmd(h, AT_CMD_CNUM, NULL, buf, sizeof(buf)); // if(r==AT_OK) { // r = sscanf(str_get(buf,'+'), "+CNUM: %*s,%s,%*d", info->cnum); // } r = send_cmd(h, AT_CMD_GSN, NULL, buf, sizeof(buf)); if(r==AT_OK) { r = sscanf(str_get(buf,'+'), "%s", info->imei); } r = send_cmd(h, AT_CMD_CIMI, NULL, buf, sizeof(buf)); if(r==AT_OK) { r = sscanf(str_get(buf,'+'), "%s", info->imsi); } r = send_cmd(h, AT_CMD_CGDCONT, "?", buf, sizeof(buf)); if(r==AT_OK) { r = sscanf(str_get(buf,'+'), "+CGDCONT: %*d,\"%*[^\"]\",\"%[^\"]", info->apn); } r = send_cmd(h, AT_CMD_COPS, "?", buf, sizeof(buf)); if(r==AT_OK) { r = sscanf(str_get(buf,'+'), "+COPS: %*d,%*d,\"%[^\"]", info->isp); } //cell_get_ip(h, &h->all.stat); LOGD("___info->apn: %s\n", info->apn); LOGD("___info->isp: %s\n", info->isp); LOGD("___info->imei: %s\n", info->imei); LOGD("___info->imsi: %s\n", info->imsi); LOGD("___info->cnum: %s\n", info->cnum); return 0; } static int cell_get_sig(cell_handle_t *h, cell_stat_t *stat) { char buf[200]; int rssi,ber,r=-1; if(h->stat==AT_STAT_UNINIT) { return -1; } r = send_cmd(h, AT_CMD_CSQ, NULL, buf, sizeof(buf)); if (r != AT_OK) { return -1; } r = sscanf(str_get(buf, '+'), "%*s %d,%d", &rssi, &ber); if (r < 2) { return -1; } stat->dbm = rssi_to_dbm(rssi); stat->ber = ber; return 0; } static int cell_get_gnss(cell_handle_t *h, cell_stat_t *stat) { int r; char buf[200],utc[32],date[32]; #ifdef GNSS_ENABLE if(h->stat==AT_STAT_UNINIT) { return -1; } r = send_cmd(h, AT_CMD_QGPSLOC, "=0", buf, sizeof(buf)); if(r!=AT_OK) { return -1; } r = sscanf(str_get(buf,'+'), "+QGPSLOC: %s,%s,%s,%*d,%d,%*d,%*d,%*d,%*d,%s,%d", utc, stat->latitude, stat->longitude, &stat->altitude, date, &stat->nsta); if(r<6) { return -1; } // #endif return 0; } static int cell_get_ping(cell_handle_t *h, cell_stat_t *stat) { int r,ret; char buf[200],utc[32],date[32]; if(h->stat==AT_STAT_UNINIT) { stat->linked = 0; return -1; } /* r = send_cmd(h, AT_CMD_QPING, "=1,\"www.baidu.com\",3,2,", buf, sizeof(buf)); if(r!=AT_OK) { stat->linked = 0; return -1; } r = sscanf(str_get(buf,'+'), "+QPING: %d", &ret); if(r<1) { stat->linked = 0; return -1; } if(ret==0) { stat->linked = 1; } else { stat->linked = 0; } */ r = send_cmd(h, AT_CMD_CGATT, "?", buf, sizeof(buf)); if(r!=AT_OK) { stat->linked = 0; return -1; } r = sscanf(str_get(buf,'+'), "+CGATT: %d", &ret); if(r<1) { stat->linked = 0; return -1; } if(ret==1) { stat->linked = 1; } else { stat->linked = 0; } return 0; } static int cell_get_time(cell_handle_t *h, cell_stat_t *stat) { int r,offset; char opr,buf[200],date[24],time[24]; struct tm utc_tm; if(h->stat==AT_STAT_UNINIT) { return -1; } r = send_cmd(h, AT_CMD_QLTS, "=1", buf, sizeof(buf)); if(r!=AT_OK) { return -1; } r = sscanf(str_get(buf,'+'), "+QLTS: \"%d/%d/%d,%d:%d:%d",&utc_tm.tm_year,&utc_tm.tm_mon,&utc_tm.tm_mday,&utc_tm.tm_hour,&utc_tm.tm_min,&utc_tm.tm_sec); if(r<6) { return -1; } stat->utctime = mktime2(&utc_tm, 0); //print_time("999", &utc_tm); return 0; } static int cell_get_stat(cell_handle_t *h, cell_stat_t *stat) { if(h->stat==AT_STAT_UNINIT) { return -1; } cell_get_sig(h, stat); cell_get_gnss(h, stat); cell_get_ping(h, stat); cell_get_time(h, stat); cell_get_ip(h, stat); return 0; } static int cell_sock_conn(cell_handle_t *h, int sock, char *host, uint16_t port, sock_conn_t *conn) { int r; char buf[200]; if(h->stat==AT_STAT_UNINIT) { return -1; } sprintf(buf, "=%s,%s,%s,“%s”,%d,0,1", CONTEXT_ID, CONNECT_ID, (sock==SOCK_TCP)?"TCP":"UDP", host, port); r = send_cmd(h, AT_CMD_QIOPEN, buf, NULL, 0); if(r!=AT_OK) { return -1; } conn->h = h; conn->sock = sock; conn->cont_id = atoi(CONTEXT_ID); conn->conn_id = atoi(CONNECT_ID); return 0; } static int cell_sock_disconn(sock_conn_t *conn) { int r; char buf[200]; cell_handle_t *h=(cell_handle_t*)conn->h; if(h->stat==AT_STAT_UNINIT) { return -1; } sprintf(buf, "=%s,%s", CONNECT_ID, CONNECT_TIMEOUT); r = send_cmd(h, AT_CMD_QICLOSE, buf, NULL, 0); if(r!=AT_OK) { return -1; } conn->h = NULL; conn->sock = -1; conn->cont_id = -1; conn->conn_id = -1; return 0; } static int cell_sock_send(sock_conn_t *conn, void *data, int len) { int r=0,rt,offset=0,remain_len,send_len; char buf[100],*pd=(char*)data; cell_handle_t *h=(cell_handle_t*)conn->h; if(h->stat==AT_STAT_UNINIT) { return -1; } sprintf(buf, "=%d,%d", conn->conn_id, len); rt = send_cmd(h, AT_CMD_QISEND, buf, NULL, 0); if(rt!=AT_OK) { return -1; } while(offsetCHUNCK_SIZE)?CHUNCK_SIZE:remain_len; rt = send_data(h, data+offset, send_len, 500); if(rt!=AT_OK) { r = -1; break; } offset += send_len; } return r; } static int cell_sock_disconn_all(cell_handle_t *h) { int r; char buf[100]; if(h->stat==AT_STAT_UNINIT) { return -1; } int count = 0; uint8_t conn_ids[MAX_CONNECTIONS]; memset(conn_ids, 0, sizeof(conn_ids)); r = send_cmd(h, AT_CMD_QISTATE, NULL, buf, sizeof(buf)); if(r!=AT_OK) { return -1; } char *ptr = buf; while ((ptr = strstr(ptr, "+QISTATE: ")) != NULL && count < MAX_CONNECTIONS) { int conn_id; char conn_type[100]; char conn_IP[100]; if (sscanf(ptr, "+QISTATE: %d,%s,%s,", &conn_id,conn_type,conn_IP) == 1) { conn_ids[count++] = (uint8_t)conn_id; log_i("4G Cellular Found active connection: ID=%d, Type=%s, IP=%s", conn_id,conn_type,conn_IP); ptr += 10; // 跳过已解析的部分 } else break; } char closebuf[200]; for (int i = 0; i < count; i++) { char ids[10] = { 0 }; sprintf(ids, "%d", conn_ids[i]); sprintf(closebuf, "=%s,%s", ids, CONNECT_TIMEOUT); r = send_cmd(h, AT_CMD_QICLOSE, closebuf, NULL, 0); if (r != AT_OK) { log_e("4G Cellular active connection: ID=%d close Failed!!!!", conn_ids[i]); } else log_i("4G Cellular active connection: ID=%d close Successful!!!!", conn_ids[i]); } return 0; } static int cell_sock_connected(cell_handle_t *h) { return 0; } static mqtt_conn_t* get_mqtt_conn_free(cell_handle_t *h) { int i; for(i=0; imq_conn[i].h==NULL) { return &h->mq_conn[i]; } } return NULL; } static int cell_mqtt_init(cell_handle_t *h) { int i; at_cmd_t *pcmd=NULL; for(i=0; imq_conn[i].cliId = i; } return 0; } static int cell_mqtt_conn(cell_handle_t *h, mqtt_para_t *para) { int r; char tmp[200],buf[100]; mqtt_conn_t *conn=NULL; conn = get_mqtt_conn_free(h); if(!conn) { return -1; } conn_init(h, conn); sprintf(tmp, "=%d,\"%s\",%d", conn->cliId, para->host, para->port); r = send_cmd(h, AT_CMD_QMTOPEN, tmp, buf, sizeof(buf)); if(r!=AT_OK) { return -1; } sprintf(tmp, "=%d,\"mqtt%d\",\"%s\",\"%s\"", conn->cliId, conn->cliId, para->username, para->password); r = send_cmd(h, AT_CMD_QMTCONN, tmp, buf, sizeof(buf)); if(r!=AT_OK) { return -1; } conn->h = h; conn->qos = 2; conn->retain = 0; return 0; } static int cell_mqtt_disconn(mqtt_conn_t *conn) { int r; char tmp[100],buf[100]; at_cmd_t *pcmd=NULL; sprintf(tmp, "=%d", conn->cliId); r = send_cmd(conn->h, AT_CMD_QMTDISC, tmp, buf, sizeof(buf)); if(r!=AT_OK) { return -1; } r = send_cmd(conn->h, AT_CMD_QMTCLOSE, tmp, buf, sizeof(buf)); if(r!=AT_OK) { return -1; } conn->msgId = 0; conn->h = NULL; return 0; } static int cell_mqtt_sub(mqtt_conn_t *conn, char *topic) { int r; char buf[500]; at_cmd_t *pcmd=NULL; sprintf(buf, "=%d, %d, \"%s\",%d", conn->cliId, conn->msgId, topic, conn->qos); r = send_cmd(conn->h, AT_CMD_QMTSUB, buf, NULL, 0); if(r!=AT_OK) { return -1; } return 0; } static int cell_mqtt_pub(mqtt_conn_t *conn, char *topic, void *data, int len) { char buf[200],*pd=(char*)data; int r=0,rt,offset=0,remain_len,send_len; sprintf(buf, "=%d,%d,%d,%d,\"%s\",%d", conn->cliId, conn->msgId, conn->qos, conn->retain, topic, len); rt = send_cmd(conn->h, AT_CMD_QMTPUB, NULL, buf, sizeof(buf)); if(rt!=AT_OK) { return -1; } while(offsetCHUNCK_SIZE)?CHUNCK_SIZE:remain_len; rt = send_data(conn->h, data+offset, send_len, 500); if(rt!=AT_OK) { r = -1; break; } offset += send_len; } return 0; } static int cell_send_sms(cell_handle_t *h, char *number, char *txt) { int r=-1,rt; char tmp[100],buf[300]; if(h->stat==AT_STAT_UNINIT) { return -1; } // char* unicode_str=utf8_to_unicode_string(txt); //if (!unicode_str) return -1; //log_i("unicode_str,%s\n", unicode_str); log_i("chinese,%s\n", txt); char ucs2_sms[256]; int ss=chinese_to_ucs2(txt, ucs2_sms,sizeof(ucs2_sms)); // 转换为 UCS2 编码 if (ss!=0) return -1; log_i("ucs2_sms,%s\n", ucs2_sms); sprintf(tmp, "=\"%s\"", "UCS2"); r = send_cmd(h, AT_CMD_CSCS, tmp, buf, sizeof(buf)); if (r != AT_OK) { return -1; } sprintf(tmp, "=17,71,0,8"); r = send_cmd(h, AT_CMD_CSMP, tmp, buf, sizeof(buf)); if (r != AT_OK) { return -1; } sprintf(tmp, "=\"%s\"", number); r = send_cmd(h, AT_CMD_CMGS, tmp, buf, sizeof(buf)); if (r != AT_OK) { return -1; } snprintf(buf, sizeof(buf), "%s\x1a", ucs2_sms); r = send_data(h, buf, strlen(buf), 5000); SMS_SEND_COUNT++; return r; } int cell_send_sms_all(int type, int subtype, int alarm_type,char *txt) { cell_handle_t *h=&ceHandle; if (!__globalDeviceManage._globalDevInfo.cell.Cellular_enable || __globalDeviceManage._globalDevInfo.cell.mode==0 || SMS_SEND_COUNT >= SMS_SEND_MAX) { return -1; } char temp[128]; char *prod_name = h->dm->_globalDevInfo.product.name; char prod_id[32]; strcpy( prod_id,h->dm->_globalDevInfo.product.number); int langID = h->dm->_globalDevInfo.product.language; switch (type) { case ALARM_TYPE_POWER: { if (subtype) { switch (alarm_type) { case ENABLE_TAC_V_UP: case ENABLE_TAC_V_DOWN: snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_V[langID], language_exceed[langID], language_alarm[langID]); break; case ENABLE_TAC_A_UP: snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_A[langID], language_exceed[langID], language_alarm[langID]); break; case ENABLE_TAC_W_UP: snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_W[langID], language_exceed[langID], language_alarm[langID]); break; case ENABLE_TAC_P_UP: snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_P[langID], language_exceed[langID], language_alarm[langID]); break; case ENABLE_TAC_STIME: case ENABLE_TAC_ETIME: snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_alarm_phase_lose[langID], language_alarm[langID]); break; default: return -1; } } else { switch (alarm_type) { case WARNING_V_UP: case WARNING_V_DOWN: snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_V[langID], language_exceed[langID], language_alarm[langID]); break; case WARNING_A_UP: snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_A[langID], language_exceed[langID], language_alarm[langID]); break; case WARNING_W_UP: snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_W[langID], language_exceed[langID], language_alarm[langID]); break; case WARNING_P_UP: snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_P[langID], language_exceed[langID], language_alarm[langID]); break; case 0 ... 2: snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_alarm_phase_lose[langID], language_alarm[langID]); break; default: return -1; } } } break; case ALARM_TYPE_SENSOR: { switch (subtype) { case SENSOR_TYPE_TEMP_DOUBLE: case SENSOR_TYPE_TEMP_HUMI: case SENSOR_TYPE_TEMP: snprintf(temp, sizeof(temp), "%s %s %s/%s %s", prod_name, prod_id, language_temperature[langID], language_humidity[langID], language_alarm[langID]); break; case SENSOR_TYPE_SMOKE: snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_sensor_smoke[langID], language_alarm[langID]); break; case SENSOR_TYPE_WATER: snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_humidity[langID], language_alarm[langID]); break; case SENSOR_TYPE_ACCESS: snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_sensor_access[langID], language_alarm[langID]); break; case SENSOR_TYPE_GAS: snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_atmosphere_gas[langID], language_alarm[langID]); break; case SENSOR_TYPE_AIR_PRESS: snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_atmosphere_pressure[langID], language_alarm[langID]); break; case SENSOR_TYPE_LEAK: snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_sensor_leak[langID], language_alarm[langID]); break; default: return -1; } } break; case ALARM_TYPE_NETWORK: { snprintf(temp, sizeof(temp), "%s %s %s", prod_name, prod_id, language_alarm_Type_Network[langID]); } break; default: return -1; } char result[256]; snprintf(result, sizeof(result), "%s, %s", temp, txt); for (int i = 0; i < MAIL_RECV_MAX; i++) { if (strcmp(__globalDeviceManage._globalDevInfo.cell.sms_recv[i].account, "") != 0) { cell_send_sms(h, __globalDeviceManage._globalDevInfo.cell.sms_recv[i].account, result); sleep(1); } } return 1; } static int cell_send_call(cell_handle_t *h, char *number, void *data, int len) { int r; char buf[100]; if(h->stat==AT_STAT_UNINIT) { return -1; } sprintf(buf, "%s", number); r = send_cmd(h, AT_CMD_ATD, NULL, buf, sizeof(buf)); if(r!=AT_OK) { return -1; } return 0; } ///////////////////////////////////////////////////////////////////////// static int conn_cfg(mqtt_conn_t *conn, char *item, char *value) { int r; char tmp[100],buf[200]; cell_handle_t *h=(cell_handle_t*)conn->h; if(h->stat==AT_STAT_UNINIT) { return -1; } sprintf(tmp, "=\"%s\",%s", item, value); r = send_cmd(h, AT_CMD_QMTCFG, NULL, buf, sizeof(buf)); if(r!=AT_OK) { return -1; } return 0; } static void conn_init(cell_handle_t *h, mqtt_conn_t *conn) { char buf[100]; conn->h = h; conn->ver = MQTT_VER; conn->pdpId = conn->cliId+1; //1~15 conn->msgId = 0; conn->qos = MQTT_QOS; conn->retain = 1; conn->will.flag = MQTT_WILL; conn->will.qos = MQTT_QOS; conn->will.retain = MQTT_RETAIN; strcpy(conn->will.topic, ""); strcpy(conn->will.message, ""); conn->will.message_len = strlen(conn->will.message); conn->timeout = 10; //1~60, default:5 conn->retry_times = 3; conn->timeout_notice = 1; conn->clean_session = 1; conn->ssl_enable = 0; conn->ssl_ctx_id = 0; conn->msg_recv_mode = 0; //0: urc, 1: not urc conn->msg_len_enable = 1; conn->ping_interval = 5; //5~60, default:5 conn->proto_chk_enable = 0; //0:no check 1:check conn->send_mode = 0; //0:string 1:hex conn->recv_mode = 0; //0:string 1:hex conn->view_mode = 0; //0:no echo 1:echo conn->edit_mode = 0; //0:timeout not quit 1:timeout quit conn->edit_time = 5; //1~120 seconds //conn->plat.product_key[64]; //aliyun used //conn->plat.device_name[64]; //aliyun used //conn->plat.device_secret[64]; //aliyun/ used //conn->plat.hw_time_enable; //huawei used //conn->plat.product_secret[64]; //huawei used //conn->plat.node_id[64]; //conn->plat.product_id[64]; //onenet used //conn->plat.access_key[64]; //onenet used sprintf(buf, "%d,%d", conn->cliId, conn->ver); conn_cfg(conn, "version", buf); sprintf(buf, "%d,%d", conn->cliId, conn->pdpId); conn_cfg(conn, "pdpcid", buf); sprintf(buf, "%d,%d", conn->cliId, conn->keep_alive_time); conn_cfg(conn, "keepalive", buf); sprintf(buf, "%d,%d", conn->cliId, conn->clean_session); conn_cfg(conn, "session", buf); sprintf(buf, "%d,%d,%d,%d", conn->cliId, conn->timeout, conn->retry_times, conn->timeout_notice); conn_cfg(conn, "timeout", buf); sprintf(buf, "%d,%d,%d", conn->cliId, conn->ssl_enable, conn->ssl_ctx_id); conn_cfg(conn, "ssl", buf); sprintf(buf, "%d,%d", conn->cliId, conn->ping_interval); conn_cfg(conn, "qmtping", buf); //sprintf(buf, "%d,%d,%d,%d,\"%s\",\"%s\"", conn->cliId, conn->will.flag, conn->will.qos, conn->will.retain, conn->will.topic, conn->will.message); //conn_cfg(conn, "will", buf); //sprintf(buf, "%d,%d,%d,%d,\"%s\",%d", conn->cliId, conn->will.flag, conn->will.qos, conn->will.retain, conn->will.topic, conn->will.message_len); //conn_cfg(conn, "willex", buf); sprintf(buf, "%d,%d", conn->cliId, conn->send_mode); conn_cfg(conn, "send/mode", buf); sprintf(buf, "%d,%d,%d", conn->cliId, conn->msg_recv_mode, conn->msg_len_enable); conn_cfg(conn, "recv/mode", buf); sprintf(buf, "%d,%d", conn->cliId, conn->view_mode); conn_cfg(conn, "view/mode", buf); sprintf(buf, "%d,%d,%d", conn->cliId, conn->edit_mode, conn->edit_time); conn_cfg(conn, "edit/timeout", buf); sprintf(buf, "%d,%d", conn->cliId, conn->proto_chk_enable); conn_cfg(conn, "protocol/check", buf); sprintf(buf, "%d,%d,%d", conn->cliId, conn->send_mode, conn->recv_mode); conn_cfg(conn, "dataformat", buf); #if 0 //aliyun sprintf(buf, "%d,\"%s\",\"%s\",\"%s\"", conn->cliId, conn->plat.product_key, conn->plat.device_name, conn->plat.device_secret); conn_cfg(conn, "aliauth", buf); #endif #if 0 //huawei sprintf(buf, "%d,\"%s\",\"%s\"", conn->cliId, conn->plat.product_id, conn->plat.device_secret); conn_cfg(conn, "hwauth", buf); sprintf(buf, "%d,\"%s\",\"%s\",\"%s\"", conn->cliId, conn->plat.product_id, conn->plat.product_secret, conn->plat.node_id); conn_cfg(conn, "hwprodid", buf); #endif #if 0 //onenet sprintf(buf, "%d,\"%s\",\"%s\"", conn->cliId, conn->plat.product_id, conn->plat.access_key); conn_cfg(conn, "onenet", buf); #endif } static int cell_test(cell_handle_t *h) { int r; cell_info_t info; cell_stat_t stat; cell_get_info(h, &info); while(1) { r = cell_get_stat(h, &stat); if(r==0) { LOGD("___dbm: %d ber: %d\n", stat.dbm, stat.ber); } else { LOGE("___ get stat failed\n"); } sleep(3); } return 0; } ///////////////////////////////////////////////////////////////////////// static int urc_handle(char *data, int len) { char *key=NULL; key = "+QIURC: "; if(strstr(data, key)) { } key = "+QMT"; if(strstr(data, key)) { } return 0; } static void* cellular_thread(void *arg) { int r; uint32_t cnt=0,prelinkcnt=0; char rxbuf[BUF_LEN]; thread_handle_t *th=(thread_handle_t*)arg; cell_handle_t *h=(cell_handle_t*)th->arg; int nlinkedflag=0; port_init(h); while (th->quit==0) { cnt++; if(h->pcell->mode) { if (h->fd<0) { port_init(h); } if(cnt%5==0) { cell_init(h); } if (cnt % 5 == 0) { // cell_get_info(h, &h->all.info); cell_get_stat(h, &h->all.stat); } if (h->all.stat.linked == 1) { prelinkcnt = cnt; } else { if (nlinkedflag == 1) { nic_set(NIC_USB, 0); } reset_var(h); if (cnt - prelinkcnt >= 60) { prelinkcnt = cnt; cell_reset(h); } } nlinkedflag=h->all.stat.linked; } else { if( h->fd>=0) { //cell_sock_disconn_all(h); cell_deinit(h); port_deinit(h); } reset_var(h); } UpdateCellularManager(&h->all); sleep(1); } //cell_sock_disconn_all(h); reset_var(h); UpdateCellularManager(&h->all); cell_deinit(h); port_deinit(h); pthread_exit(NULL); } int cellular_reset(void) { int r=-1; cell_handle_t *h=&ceHandle; r = cell_reset(h); return r; } int cellular_init(void) { int r; cell_handle_t *h=&ceHandle; if (__globalDeviceManage._globalDevInfo.cell.Cellular_enable && __globalDeviceManage._globalDevInfo.cell.mode && !thread_is_running(THREAD_ID_CELLULAR)) { memset(h, 0, sizeof(cell_handle_t)); h->dm = &__globalDeviceManage; h->pcell = &h->dm->_globalDevInfo.cell; strcpy( h->prod_id,h->dm->_globalDevInfo.product.number); // h->lck = lock_d_init(); //nic_set(NIC_USB, 1); dev_SMS_get(h->dm->db, h->pcell); thread_start(THREAD_ID_CELLULAR, cellular_thread, h); } else return -1; return 0; } int cellular_deinit(void) { cell_handle_t *h=&ceHandle; if (__globalDeviceManage._globalDevInfo.cell.Cellular_enable && !__globalDeviceManage._globalDevInfo.cell.mode) { thread_stop(THREAD_ID_CELLULAR); nic_set(NIC_USB, 0); } return 0; } int cellular_get_all(cell_all_t *all) { int r=-1; cell_handle_t *h=&ceHandle; if(all) { *all = h->all; r = 0; } return r; } int cellular_is_connected(void) { int r=0; cell_handle_t *h=&ceHandle; if (__globalDeviceManage._globalDevInfo.cell.Cellular_enable) { r = h->all.stat.linked; } return r; } int UpdateCellularManager( cell_all_t *all) { int r = -1; if (all) { __globalDeviceManage._globalDevInfo.cell.Link_status = all->stat.linked; __globalDeviceManage._globalDevInfo.cell.Signal_strength = all->stat.dbm; strcpy( __globalDeviceManage._globalDevInfo.cell.apn , all->info.apn); strcpy( __globalDeviceManage._globalDevInfo.cell.Cellular_name , all->info.isp); strcpy( __globalDeviceManage._globalDevInfo.cell.Cellular_Num , all->info.imei); strcpy(__globalDeviceManage._globalDevInfo.cell.ipv4, all->stat.ipv4); strcpy(__globalDeviceManage._globalDevInfo.cell.ipv6, all->stat.ipv6); r = 0; } return r; } int cellular_test(void) { cell_handle_t *h=&ceHandle; cell_test(h); return 0; }