Cellular.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687
  1. #include <time.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <termios.h>
  8. #include <errno.h>
  9. #include "cJSON.h"
  10. #include "json_handle.h"
  11. #include "websocket_handle.h"
  12. #include "common.h"
  13. #include "sys.h"
  14. #include "Cellular.h"
  15. #include <pthread.h>
  16. #include "thread.h"
  17. #include "paras.h"
  18. #include "lock.h"
  19. #include "elog.h"
  20. #include "cfg.h"
  21. #include "sqlite_handle.h"
  22. #if 0
  23. #define LOGE log_e
  24. #define LOGW log_w
  25. #define LOGD log_d
  26. #else
  27. #define LOGD printf
  28. #define LOGW printf
  29. #define LOGE printf
  30. #endif
  31. #define RETRY_TIMES 1
  32. #define BUF_LEN 2000
  33. #define AT_PORT "/dev/ttyUSB1"
  34. #define BAUD_RATE B115200
  35. #define QUERY_INTERVAL 1000 // 查询间隔,毫秒
  36. #define RSSI_DBM_MIN1 -113 // LTE、HSDPA网络最小信号值,对应RSSI值范围0-57
  37. #define RSSI_DBM_MIN2 -116 // TD-SCDMA网络最小信号值,对应RSSI值范围100-199
  38. #define CONTEXT_ID "1" //1~15
  39. #define CONNECT_ID "0" //0~11
  40. #define CONNECT_TIMEOUT "5"
  41. #define CHUNCK_SIZE 1460
  42. #define MQTT_VER 4 //3: v3.1 4: v3.1.1
  43. #define MQTT_WILL 0
  44. #define MQTT_RETAIN 0
  45. #define MQTT_MAX 6
  46. #define MQTT_QOS 2
  47. #define MQTT_CHUNCK_SIZE 1500
  48. #define SMS_SEND_MAX 500
  49. #define UNLINK_MAX 3
  50. int UnLinkCount=0;
  51. enum {
  52. AT_OK=0,
  53. AT_ERR,
  54. AT_TOUT,
  55. };
  56. enum {
  57. AT_STAT_UNINIT=0,
  58. AT_STAT_INITED,
  59. };
  60. enum {
  61. SOCK_TCP=0,
  62. SOCK_UDP,
  63. };
  64. enum {
  65. URC_SOCK=0,
  66. URC_MQTT,
  67. URC_GNSS,
  68. URC_NTP,
  69. URC_SMS,
  70. URC_CALL,
  71. URC_ERR,
  72. };
  73. typedef int (*urc_fn_t)(int urc, void *data, int len);
  74. typedef struct {
  75. int cmd;
  76. char para[100];
  77. }at_para_t;
  78. typedef struct {
  79. char *cmd;
  80. char *ok;
  81. char *err;
  82. int timeout; //ms
  83. }at_cmd_t;
  84. typedef struct {
  85. int cmd;
  86. char *buf;
  87. int dlen;
  88. int blen;
  89. }at_buf_t;
  90. typedef struct {
  91. at_buf_t rx;
  92. at_buf_t tx;
  93. }at_data_t;
  94. typedef struct {
  95. void *h;
  96. int sock;
  97. int cont_id; //1~15
  98. int cont_type; //1:ipv4 2:ipv6 3:ipv4+ipv6
  99. int conn_id;
  100. char apn[64];
  101. char username[128];
  102. char password[128];
  103. int authentication; //0:none 1:PAP 2:CHAP 3:PAP OR CHAP
  104. int cdma_pwd; //0:no save 1:save
  105. }sock_conn_t;
  106. typedef struct {
  107. char host[100];
  108. uint16_t port;
  109. char username[64];
  110. char password[64];
  111. }mqtt_para_t;
  112. typedef struct {
  113. int flag;
  114. int qos;
  115. int retain;
  116. char topic[256];
  117. char message[256];
  118. int message_len;
  119. }mqtt_will_t;
  120. typedef struct {
  121. char product_key[64]; //aliyun used
  122. char device_name[64]; //aliyun used
  123. char device_secret[64]; //aliyun/ used
  124. char product_id[64]; //onenet used
  125. char access_key[64]; //onenet used
  126. int hw_time_enable; //huawei used
  127. char product_secret[64]; //huawei used
  128. char node_id[64];
  129. }mqtt_plat_t;
  130. typedef struct {
  131. void *h;
  132. int ver; //3:v3.1 4:v3.1.1
  133. int pdpId; //1~15
  134. int cliId;
  135. uint16_t msgId;
  136. int qos;
  137. int retain;
  138. mqtt_will_t will;
  139. int timeout; //1~60, default:5
  140. int retry_times;
  141. int timeout_notice;
  142. int clean_session;
  143. int keep_alive_time; //0~3600 seconds default:120, 0:do not disconnect
  144. int ssl_enable;
  145. int ssl_ctx_id;
  146. int msg_recv_mode; //0: urc, 1: not urc
  147. int msg_len_enable;
  148. int ping_interval; //5~60, default:5
  149. int proto_chk_enable; //0:no check 1:check
  150. int send_mode; //0:string 1:hex
  151. int recv_mode; //0:string 1:hex
  152. int view_mode; //0:no echo 1:echo
  153. int edit_mode; //0:timeout not quit 1:timeout quit
  154. int edit_time; //1~120 seconds
  155. mqtt_plat_t plat;
  156. }mqtt_conn_t;
  157. typedef struct {
  158. int fd;
  159. CellInfo_t *pcell;
  160. lock_t lck;
  161. char prod_id[32];
  162. int stat;
  163. cell_all_t all;
  164. int curcmd; //current cmd
  165. mqtt_conn_t mq_conn[MQTT_MAX];
  166. at_data_t data[AT_CMD_MAX];
  167. GlobalDeviceManager *dm;
  168. }cell_handle_t;
  169. static cell_handle_t ceHandle={0};
  170. static at_cmd_t all_cmd[AT_CMD_MAX]={
  171. //genernal cmd
  172. {"AT", "OK", "ERROR", 300}, //测试命令
  173. {"ATI", "OK", "ERROR", 300}, //显示MT的ID信息
  174. {"AT+GMI", "OK", "ERROR", 300}, //请求制造商信息
  175. {"AT+GMM", "OK", "ERROR", 300}, //请求TA型号ID
  176. {"AT+GMR", "OK", "ERROR", 300}, //请求TA固件版本ID
  177. {"AT+CGMI", "OK", "ERROR", 300}, //同GMI
  178. {"AT+CGMM", "OK", "ERROR", 300}, //同GMM
  179. {"AT+CGMR", "OK", "ERROR", 300}, //同GMR
  180. {"AT+GSN", "OK", "ERROR", 300}, //请求国际移动设备识别码(IMEI)
  181. {"AT+CGSN", "OK", "ERROR", 300}, //同GSN
  182. {"AT&F", "OK", "ERROR", 300}, //重置AT命令设置为出厂设置
  183. {"AT&V", "OK", "ERROR", 300}, //显示当前配置
  184. {"AT&W", "OK", "ERROR", 300}, //存储当前设置到用户自定义配置文件
  185. {"ATZ", "OK", "ERROR", 300}, //从用户定义配置文件还原所有AT命令设置
  186. {"ATQ", "OK", "ERROR", 300}, //设置结果码回显模式
  187. {"ATV", "OK", "ERROR", 300}, //TA响应格式
  188. {"ATE0", "OK", "ERROR", 300}, //设置命令回显模式
  189. {"ATS3", "OK", "ERROR", 300}, //设置命令行终止符
  190. {"ATS4", "OK", "ERROR", 300}, //设置响应格式字符
  191. {"ATS5", "OK", "ERROR", 300}, //设置命令行编辑字符
  192. {"ATX", "OK", "ERROR", 300}, //设置CONNECT结果码格式和检测呼叫进程
  193. {"AT+CFUN", "OK", "ERROR", 15000}, //设置功能模式
  194. {"AT+CMEE", "OK", "ERROR", 300}, //设置错误讯息格式
  195. {"AT+CSCS", "OK", "ERROR", 300}, //选择TE字符集
  196. {"AT+QURCCFG", "OK", "ERROR", 300}, //配置URC指示选项
  197. {"AT+QPPPDROP", "OK", "ERROR", 300}, //终止PPP连接
  198. //serial cmd
  199. {"AT&C", "OK", "ERROR", 300}, //设置DCD信号模式
  200. {"AT&D", "OK", "ERROR", 300}, //设置DTR信号模式
  201. {"AT+IFC", "OK", "ERROR", 300}, //设置串口的流控方式
  202. {"AT+IPR", "OK", "ERROR", 300}, //设置固定的串口通信波特率
  203. //status cmd
  204. {"AT+CPAS", "OK", "ERROR", 300}, //查询ME活动状态
  205. {"AT+CEER", "OK", "ERROR", 300}, //上报扩展错误
  206. {"AT+QCFG", "OK", "ERROR", 300}, //扩展命令, 较多子命令
  207. {"AT+QINDCFG", "OK", "ERROR", 300}, //控制URC上报
  208. //sim cmd
  209. {"AT+CIMI", "OK", "ERROR", 300}, //查询IMSI
  210. {"AT+CLCK", "OK", "ERROR", 5000}, //功能锁定
  211. {"AT+CPIN", "OK", "ERROR", 5000}, //PIN管理
  212. {"AT+CPWD", "OK", "ERROR", 5000}, //修改密码
  213. {"AT+CSIM", "OK", "ERROR", 300}, //通用(U)SIM卡访问
  214. {"AT+CRSM", "OK", "ERROR", 300}, //(U)SIM卡受限访问
  215. {"AT+QCCID", "OK", "ERROR", 300}, //查询ICCID
  216. {"AT+QPINC", "OK", "ERROR", 300}, //获取PIN剩余重试次数
  217. {"AT+QINISTAT", "OK", "ERROR", 300}, //查询(U)SIM卡初始化状态
  218. {"AT+QSIMDET", "OK", "ERROR", 300}, //(U)SIM卡检测
  219. {"AT+QSIMSTAT", "OK", "ERROR", 300}, //(U)SIM卡插拔状态上报
  220. {"AT+QDSIM", "OK", "ERROR", 50000}, //选择(U)SIM卡
  221. //network service cmd
  222. {"AT+COPS", "OK", "ERROR", 300000}, //选择运营商
  223. {"AT+CREG", "OK", "ERROR", 300}, //CS域网络注册状态
  224. {"AT+CSQ", "OK", "ERROR", 300}, //查询信号强度
  225. {"AT+CPOL", "OK", "ERROR", 300}, //配置首选运营商列表
  226. {"AT+COPN", "OK", "ERROR", 300}, //查询运营商名称列表
  227. {"AT+CTZU", "OK", "ERROR", 300}, //自动更新时区
  228. {"AT+CTZR", "OK", "ERROR", 300}, //上报时区变化
  229. {"AT+QLTS", "OK", "ERROR", 500}, //获取通过网络同步的最新时间
  230. {"AT+QNWINFO", "OK", "ERROR", 300}, //查询网络信息
  231. //call cmd
  232. {"ATA", "OK", "ERROR", 90000}, //呼叫应答
  233. {"ATD", "OK", "ERROR", 5000}, //发起呼叫
  234. {"AT+COLP", "OK", "ERROR", 15000}, //被叫线路识别显示
  235. {"AT+ATH", "OK", "ERROR", 90000}, //挂断现有连接
  236. {"AT+CHUP", "OK", "ERROR", 90000}, //挂断语音通话
  237. {"+++", "OK", "ERROR", 300}, //从数据模式切换至命令模式
  238. {"AT+ATO", "OK", "ERROR", 300}, //从命令模式切换至数据模式
  239. {"AT+ATSO", "OK", "ERROR", 300}, //设置自动应答前振铃次数
  240. {"AT+CLCC", "OK", "ERROR", 300}, //查询当前 ME 呼叫
  241. {"AT^DSCI", "OK", "ERROR", 300}, //指示呼叫状态
  242. //phonebook cmd
  243. {"AT+CNUM", "OK", "ERROR", 300}, //查询本机号码
  244. {"AT+CPBF", "OK", "ERROR", 300}, //搜索电话本
  245. {"AT+CPBR", "OK", "ERROR", 300}, //读取电话本条目
  246. {"AT+CPBS", "OK", "ERROR", 300}, //设置电话本存储器
  247. {"AT+CPBW", "OK", "ERROR", 300}, //写入电话本
  248. //sms cmd
  249. {"AT+CSMS", "OK", "ERROR", 300}, //选择短消息服务类型
  250. {"AT+CMGF", "OK", "ERROR", 300}, //配置短消息模式
  251. {"AT+CSCA", "OK", "ERROR", 300}, //设置短消息服务中心地址
  252. {"AT+CPMS", "OK", "ERROR", 300}, //配置短消息首选存储位置
  253. {"AT+CMGD", "OK", "ERROR", 300}, //删除短消息
  254. {"AT+CMGL", "OK", "ERROR", 300}, //按状态读取短消息
  255. {"AT+CMGR", "OK", "ERROR", 300}, //按照索引读取短消息
  256. {"AT+CMGS", ">", "ERROR", 120000}, //发送短消息
  257. {"AT+CMMS", "OK", "ERROR", 300}, //发送多条短消息
  258. {"AT+CMGW", "OK", "ERROR", 300}, //存储短消息
  259. {"AT+CMSS", "OK", "ERROR", 300}, //从存储器发送短消息
  260. {"AT+CNMA", "OK", "ERROR", 300}, //新短消息确认
  261. {"AT+CNMI", "OK", "ERROR", 300}, //设置短消息上报方式
  262. {"AT+CSCB", "OK", "ERROR", 300}, //选择小区广播消息类型
  263. {"AT+CSDH", "OK", "ERROR", 300}, //设置文本模式下参数显示
  264. {"AT+CSMP", "OK", "ERROR", 300}, //设置短消息文本模式参数
  265. {"AT+QCMGS", "OK", "ERROR", 120000}, //发送级联短消息
  266. {"AT+QCMGR", "OK", "ERROR", 300}, //读取级联短消息
  267. //gps cmd
  268. {"AT+QGPSCFG", "OK", "ERROR", 300}, //配置GNSS
  269. {"AT+QGPSDEL", "OK", "ERROR", 300}, //删除辅助数据
  270. {"AT+QGPS", "OK", "ERROR", 300}, //打开GNSS
  271. {"AT+QGPSEND", "OK", "ERROR", 300}, //关闭GNSS
  272. {"AT+QGPSLOC", "OK", "ERROR", 300}, //获取定位信息
  273. {"AT+QGPSNMEA", "OK", "ERROR", 300}, //获取指定的NMEA语句
  274. {"AT+QAGPS", "OK", "ERROR", 300}, //启用/禁用AGPS
  275. //tcp/udp cmd
  276. {"AT+QICFG", "OK", "ERROR", 300}, //配置可选参数
  277. {"AT+QICSGP", "OK", "ERROR", 300}, //配置TCP/IP场景参数
  278. {"AT+QIACT", "OK", "ERROR", 10000}, //激活PDP场景
  279. {"AT+QIDEACT", "OK", "ERROR", 10000}, //去激活PDP场景
  280. {"AT+QIOPEN", "OK", "ERROR", 300}, //打开Socket服务
  281. {"AT+QICLOSE", "OK", "ERROR", 300}, //关闭Socket服务
  282. {"AT+QISTATE", "OK", "ERROR", 300}, //查询Socket服务状态
  283. {"AT+QISEND", ">", "ERROR", 300}, //发送数据
  284. {"AT+QIRD", "OK", "ERROR", 300}, //读取收到的TCP/IP数据
  285. {"AT+QISENDEX", "OK", "ERROR", 300}, //发送16进制字符串数据
  286. {"AT+QISWTMD", "OK", "ERROR", 300}, //切换数据访问模式
  287. {"AT+QNTP", "OK", "ERROR", 300}, //进行远程服务器Ping操作
  288. {"AT+QPING", "+QPING", "ERROR", 3000}, //使用NTP服务器同步本地时间
  289. {"AT+QIDNSCFG", "OK", "ERROR", 300}, //配置DNS服务器地址
  290. {"AT+QIDNSGIP", "OK", "ERROR", 300}, //用域名获取IP地址
  291. {"AT+QISDE", "OK", "ERROR", 300}, //控制是否回显AT+QISEND要发送的
  292. {"AT+QIGETERROR", "OK", "ERROR", 300}, //查询上一个AT命令错误代码
  293. //mqtt cmd
  294. {"AT+QMTCFG", "OK", "ERROR", 300}, //配置MQTT可选参数
  295. {"AT+QMTOPEN", "OK", "ERROR", 300}, //打开MQTT客户端网络
  296. {"AT+QMTCLOSE", "OK", "ERROR", 300}, //关闭MQTT客户端网络
  297. {"AT+QMTCONN", "OK", "ERROR", 300}, //连接客户端到MQTT服务器
  298. {"AT+QMTDISC", "OK", "ERROR", 300}, //客户端断开与MQTT服务器的连接
  299. {"AT+QMTSUB", "OK", "ERROR", 300}, //订阅主题
  300. {"AT+QMTUNS", "OK", "ERROR", 300}, //退订主题
  301. {"AT+QMTPUBEX", ">", "ERROR", 300}, //发布消息
  302. {"AT+QMTRECV", "OK", "ERROR", 300}, //从缓存中读取消息
  303. //domain cmd
  304. {"AT+CGATT", "OK", "ERROR", 140000}, //PS域附着或去附着
  305. {"AT+CGDCONT", "OK", "ERROR", 3000}, //定义PDP上下文
  306. {"AT+CGQREQ", "OK", "ERROR", 300}, //服务质量参数请求
  307. {"AT+CGQMIN", "OK", "ERROR", 300}, //服务质量参数(最低可接受的)
  308. {"AT+CGEQREQ", "OK", "ERROR", 300}, //3G服务质量参数(请求的)
  309. {"AT+CGEQMIN", "OK", "ERROR", 300}, //3G 服务质量参数(最低可接受的)
  310. {"AT+CGACT", "OK", "ERROR", 150000}, //PDP上下文激活/去激活
  311. {"AT+CGDATA", "OK", "ERROR", 300}, //进入数据传输状态
  312. {"AT+CGPADDR", "OK", "ERROR", 300}, //显示PDP地址
  313. {"AT+CGCLASS", "OK", "ERROR", 300}, //GPRS移动站点等级
  314. {"AT+CGEREG", "OK", "ERROR", 300}, //PS域网络注册状态
  315. {"AT+CGEREP", "OK", "ERROR", 300}, //分组域事件上报
  316. {"AT+CGSMS", "OK", "ERROR", 300}, //选择MO短消息服务
  317. {"AT+CEREG", "OK", "ERROR", 300}, //EPS网络注册状态
  318. {"AT+QGDCNT", "OK", "ERROR", 300}, //流量统计
  319. {"AT+QAUGDCNT", "OK", "ERROR", 300}, //自动保存流量统计
  320. {"AT+QNETDEVCTL", "OK", "ERROR", 2000}, //连接USB网卡
  321. {"AT+QCEERCATCFG", "OK", "ERROR", 300}, //配置2G/4G下AT+CEER返回格式
  322. //hardware cmd
  323. {"AT+QPOWD", "OK", "ERROR", 300}, //关闭模块
  324. {"AT+CCLK", "OK", "ERROR", 300}, //实时时钟
  325. {"AT+QSCLK", "OK", "ERROR", 300}, //禁用/启用睡眠模式
  326. };
  327. at_para_t init_para[]={
  328. {AT_CMD_AT, ""},
  329. {AT_CMD_ATE, "0"},
  330. {AT_CMD_CPIN, "?"},
  331. {AT_CMD_CREG, "?"},
  332. //{AT_CMD_CGDCONT, ""},
  333. {AT_CMD_QICSGP, ""},
  334. {AT_CMD_QIDEACT, "="CONTEXT_ID},
  335. {AT_CMD_QIACT, "="CONTEXT_ID},
  336. {AT_CMD_QCFG, "=\"usbnet\",1"}, //set module to ecm mode
  337. {AT_CMD_QNETDEVCTL, "=3,"CONTEXT_ID",0"},
  338. {AT_CMD_CMGF, "=1"},
  339. {AT_CMD_CSCS, "=GSM"},
  340. #ifdef GNSS_ENABLE
  341. {AT_CMD_QGPS, "=1"},
  342. {AT_CMD_QGPSCFG, "=\"gnssconfig\",5"},
  343. {AT_CMD_QGPSCFG, "=\"gpsnmeatype\",1"},
  344. #endif
  345. {-1, ""},
  346. };
  347. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  348. static at_cmd_t* data_of(int cmd)
  349. {
  350. return &all_cmd[cmd];
  351. }
  352. static int rssi_to_dbm(int rssi)
  353. {
  354. int dbm=0;
  355. if(rssi>=0 && rssi<57) {
  356. dbm = RSSI_DBM_MIN1+rssi*2;
  357. }
  358. else if(rssi>=100 && rssi<199) {
  359. dbm = RSSI_DBM_MIN2+rssi-100;
  360. }
  361. return dbm;
  362. }
  363. static char* str_get(char *buf, char c)
  364. {
  365. int i,len=strlen(buf);
  366. for(i=0; i<len; i++) {
  367. if(buf[i]==c) return buf+i;
  368. }
  369. return buf;
  370. }
  371. static int mem_find(char *buf, int len, char *str)
  372. {
  373. int i,slen=strlen(str);
  374. for(i=0; i<=len-slen; i++) {
  375. if(memcmp(buf+i, str, slen)==0) {
  376. return 0;
  377. }
  378. }
  379. return -1;
  380. }
  381. static void mem_print(char *buf, int len)
  382. {
  383. int i;
  384. for(i=0; i<len; i++) {
  385. LOGD("%d, ", buf[i]);
  386. if((i+1)%16==0) LOGD("\n");
  387. }
  388. LOGD("\n");
  389. }
  390. static int nic_set(int nic, int on)
  391. {
  392. char tmp[200],path[100];
  393. const char *ifname=sys_get_ifname(nic);
  394. sprintf(path, "/var/run/udhcpc_%s.pid", ifname);
  395. sprintf(tmp, "kill $(cat %s)", path);
  396. system(tmp);
  397. sprintf(tmp, "ip link set dev %s %s", ifname, on?"up":"down");
  398. system(tmp);
  399. if(on) {
  400. sprintf(tmp, "udhcpc -R -b -i %s -p %s ", ifname, path);
  401. system(tmp);
  402. }
  403. return 0;
  404. }
  405. static int cell_reset(cell_handle_t *h);
  406. static int cell_sock_init(cell_handle_t *h);
  407. static int cell_get_info(cell_handle_t *h, cell_info_t *info);
  408. static int cell_get_stat(cell_handle_t *h, cell_stat_t *stat);
  409. static void conn_init(cell_handle_t *h, mqtt_conn_t *conn);
  410. //////////////////////////////////////////////////////////////////////////////////
  411. static int port_setup(cell_handle_t *h, int speed);
  412. static void msleep(int ms)
  413. {
  414. usleep(ms*1000);
  415. }
  416. static void reset_var( cell_handle_t *h)
  417. {
  418. h->stat=AT_STAT_UNINIT;
  419. h->all.stat.dbm = 0;
  420. h->all.stat.ber = 0;
  421. h->all.stat.nsta = 0;
  422. h->all.stat.altitude = 0;
  423. sprintf(h->all.stat.latitude, "-");
  424. sprintf(h->all.stat.longitude, "-");
  425. h->all.stat.utctime = 0;
  426. h->all.stat.linked = 0;
  427. sprintf(h->all.stat.ipv4, "-");
  428. sprintf(h->all.stat.ipv4, "-");
  429. sprintf(h->all.info.apn, "-");
  430. sprintf(h->all.info.cnum, "-");
  431. sprintf(h->all.info.imsi, "-");
  432. sprintf(h->all.info.imei, "-");
  433. sprintf(h->all.info.isp, "-");
  434. }
  435. static int port_init(cell_handle_t *h)
  436. {
  437. h->fd = open(AT_PORT, O_RDWR | O_NOCTTY | O_NONBLOCK);
  438. if(h->fd<0) {
  439. return -1;
  440. }
  441. port_setup(h, BAUD_RATE);
  442. return 0;
  443. }
  444. static int port_deinit(cell_handle_t *h)
  445. {
  446. if(h->fd<0) {
  447. return -1;
  448. }
  449. int r=close(h->fd);
  450. h->fd=-1;
  451. sleep(2);
  452. return r;
  453. }
  454. static int port_read(cell_handle_t *h, void *data, int len)
  455. {
  456. return read(h->fd, data, len);
  457. }
  458. static int port_write(cell_handle_t *h, void *data, int len)
  459. {
  460. return write(h->fd, data, len);
  461. }
  462. static int port_setup(cell_handle_t *h, int speed)
  463. {
  464. struct termios tty;
  465. if (tcgetattr(h->fd, &tty) != 0) {
  466. LOGE("Read 4G Module tcgetattr!!!\n");
  467. return -1;
  468. }
  469. cfsetospeed(&tty, speed);
  470. cfsetispeed(&tty, speed);
  471. tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
  472. tty.c_iflag &= ~IGNBRK; // disable break processing
  473. tty.c_lflag = 0; // no signaling chars, no echo,
  474. // no canonical processing
  475. tty.c_oflag = 0; // no remapping, no delays
  476. tty.c_cc[VMIN] = 0; // read doesn't block
  477. tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
  478. tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
  479. tty.c_cflag |= (CLOCAL | CREAD); // ignore modem controls,
  480. // enable reading
  481. tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
  482. tty.c_cflag |= 0;
  483. tty.c_cflag &= ~CSTOPB;
  484. tty.c_cflag &= ~CRTSCTS;
  485. if (tcsetattr(h->fd, TCSANOW, &tty) != 0) {
  486. LOGE("Read 4G Module tcsetattr!!!\n");
  487. return -1;
  488. }
  489. return 0;
  490. }
  491. static int port_wait(cell_handle_t *h, int timeout)
  492. {
  493. int r;
  494. char buf[100];
  495. fd_set fset;
  496. struct timeval tv;
  497. tv.tv_sec = timeout/1000;
  498. tv.tv_usec = (timeout%1000)*1000;
  499. if(h->fd < 0)
  500. return -1;
  501. FD_ZERO(&fset); FD_SET(h->fd, &fset);
  502. r = select(h->fd + 1, &fset, NULL, NULL, &tv);
  503. if (r<=0) {
  504. if(r<0) {
  505. //LOGE("port_wait error %s\n", strerror(errno));
  506. }
  507. else {
  508. //LOGE("port_wait timeout\n");
  509. }
  510. }
  511. return r;
  512. }
  513. static int port_recv(cell_handle_t *h, char *buf, int buflen, int timeout)
  514. {
  515. int r;
  516. r = port_wait(h, timeout);
  517. if(r<0) {
  518. return -1;
  519. }
  520. r = port_read(h, buf, buflen);
  521. if(r<=0) {
  522. return -1;
  523. }
  524. return r;
  525. }
  526. static int send_cmd(cell_handle_t *h, int cmd, char *para, char *rcv, int rcvlen)
  527. {
  528. int i,r,l,tout,finish=0;
  529. int tlen=0,buflen,wait_step=10;
  530. char buf[BUF_LEN],*pbuf;
  531. at_cmd_t *pcmd=data_of(cmd);
  532. sprintf(buf, "%s%s\r", pcmd->cmd, para?para:"");
  533. LOGD("[tx]: %s\n", buf);
  534. for (i = 0; i < RETRY_TIMES; i++)
  535. {
  536. tout = 0;
  537. port_write(h, buf, strlen(buf));
  538. while (tout < pcmd->timeout)
  539. {
  540. l = port_wait(h, wait_step);
  541. if (l > 0)
  542. {
  543. if (rcv && rcvlen > 0)
  544. {
  545. pbuf = rcv;
  546. buflen = rcvlen;
  547. }
  548. else
  549. {
  550. pbuf = buf;
  551. buflen = sizeof(buf);
  552. }
  553. l = port_read(h, pbuf + tlen, buflen);
  554. if (l > 0)
  555. {
  556. tlen += l;
  557. pbuf[tlen] = 0;
  558. LOGD("[rx]: %s\n", pbuf);
  559. if (pcmd->ok && strlen(pcmd->ok) && strstr(pbuf, pcmd->ok))
  560. {
  561. return AT_OK;
  562. }
  563. if (pcmd->err && strlen(pcmd->err) && strstr(pbuf, pcmd->err))
  564. {
  565. // 指令不通则重置模块
  566. if (cmd != AT_CMD_CFUN && cmd != AT_CMD_QIDEACT )
  567. {
  568. cell_reset(h);
  569. }
  570. return AT_ERR;
  571. }
  572. }
  573. }
  574. tout += wait_step;
  575. usleep(1000);
  576. }
  577. }
  578. //AT不通重启串口
  579. if (cmd != AT_CMD_QIDEACT && cmd != AT_CMD_CFUN )
  580. {
  581. port_deinit(h);
  582. port_init(h);
  583. }
  584. return AT_TOUT;
  585. }
  586. static int send_data(cell_handle_t *h, void *data, int len, int timeout)
  587. {
  588. char buf[100];
  589. int l,tlen=0,tout=0,wait_step=10;
  590. l = port_write(h, data, len);
  591. if(l==len) {
  592. while(tout<timeout) {
  593. l = port_wait(h, wait_step);
  594. if(l>0) {
  595. l = port_read(h, buf, sizeof(buf));
  596. if(l>0) {
  597. tlen += l; buf[tlen] = 0;
  598. if(strstr(buf, "OK")) {
  599. return AT_OK;
  600. }
  601. else if(strstr(buf, "ERROR")) {
  602. return AT_ERR;
  603. }
  604. }
  605. }
  606. tout += wait_step;
  607. }
  608. }
  609. return AT_TOUT;
  610. }
  611. ////////////////////////////////////////////////////////////////////////////
  612. static int cell_reset(cell_handle_t *h)
  613. {
  614. reset_var(h);
  615. int r;
  616. r = send_cmd(h, AT_CMD_CFUN, "=1,1", NULL, 0);
  617. // if(r==AT_OK) {
  618. // h->stat = AT_STAT_UNINIT;
  619. //}
  620. sleep(5);//等待模块复位完成
  621. return (r==AT_OK)?0:-1;
  622. }
  623. static int cell_init(cell_handle_t *h)
  624. {
  625. int i,r;
  626. at_para_t *p=init_para;
  627. if(h->stat==AT_STAT_INITED) {
  628. return 0;
  629. }
  630. for(i=0;; i++) {
  631. if(p[i].cmd==-1) {
  632. break;
  633. }
  634. if(p[i].cmd==AT_CMD_CGDCONT) {
  635. sprintf(p[i].para, "=%s,\"IPV4V6\",\"%s\"", CONTEXT_ID, h->pcell->apn);
  636. }
  637. else if(p[i].cmd==AT_CMD_QICSGP) {
  638. sprintf(p[i].para, "=%s,3,\"%s\",\"%s\",\"%s\"", CONTEXT_ID, h->pcell->apn,h->pcell->username,h->pcell->password);
  639. }
  640. r = send_cmd(h, p[i].cmd, p[i].para, NULL, 0);
  641. if(r!=AT_OK) {
  642. break;
  643. }
  644. }
  645. if(r==0) {
  646. h->stat = AT_STAT_INITED;
  647. cell_get_info(h, &h->all.info);
  648. }
  649. return r?-1:0;
  650. }
  651. static int cell_deinit(cell_handle_t *h)
  652. {
  653. int r=-1;
  654. char buf[400];
  655. r = send_cmd(h, AT_CMD_QIDEACT, "="CONTEXT_ID, buf, sizeof(buf));
  656. if(r==AT_OK) {
  657. return r;
  658. }
  659. return r;
  660. }
  661. static int cell_get_ip(cell_handle_t *h, cell_stat_t *stat)
  662. {
  663. char buf[200];
  664. int r=-1;
  665. memset(stat->ipv4, 0, sizeof(stat->ipv4));
  666. memset(stat->ipv6, 0, sizeof(stat->ipv6));
  667. if(h->stat==AT_STAT_UNINIT) {
  668. return -1;
  669. }
  670. r = send_cmd(h, AT_CMD_QIACT, "?", buf, sizeof(buf));
  671. if (r != AT_OK)
  672. {
  673. return -1;
  674. }
  675. r = sscanf(str_get(buf, '+'), "+QIACT: %*d,%*d,%*d,\"%15[^\"]\",\"%63[^\"]\"", stat->ipv4, stat->ipv6);
  676. LOGD("Cellular IPV4: %s\n",stat->ipv4);
  677. LOGD("Cellular IPV6:%s\n", stat->ipv6);
  678. return 0;
  679. }
  680. static int cell_get_info(cell_handle_t *h, cell_info_t *info)
  681. {
  682. int r;
  683. char buf[400];
  684. if(h->stat==AT_STAT_UNINIT) {
  685. return -1;
  686. }
  687. memset(info, 0, sizeof(cell_info_t));
  688. // r = send_cmd(h, AT_CMD_CNUM, NULL, buf, sizeof(buf));
  689. // if(r==AT_OK) {
  690. // r = sscanf(str_get(buf,'+'), "+CNUM: %*s,%s,%*d", info->cnum);
  691. // }
  692. r = send_cmd(h, AT_CMD_GSN, NULL, buf, sizeof(buf));
  693. if(r==AT_OK) {
  694. r = sscanf(str_get(buf,'+'), "%s", info->imei);
  695. }
  696. r = send_cmd(h, AT_CMD_CIMI, NULL, buf, sizeof(buf));
  697. if(r==AT_OK) {
  698. r = sscanf(str_get(buf,'+'), "%s", info->imsi);
  699. }
  700. r = send_cmd(h, AT_CMD_CGDCONT, "?", buf, sizeof(buf));
  701. if(r==AT_OK) {
  702. r = sscanf(str_get(buf,'+'), "+CGDCONT: %*d,\"%*[^\"]\",\"%[^\"]", info->apn);
  703. }
  704. r = send_cmd(h, AT_CMD_COPS, "?", buf, sizeof(buf));
  705. if(r==AT_OK) {
  706. r = sscanf(str_get(buf,'+'), "+COPS: %*d,%*d,\"%[^\"]", info->isp);
  707. }
  708. //cell_get_ip(h, &h->all.stat);
  709. LOGD("___info->apn: %s\n", info->apn);
  710. LOGD("___info->isp: %s\n", info->isp);
  711. LOGD("___info->imei: %s\n", info->imei);
  712. LOGD("___info->imsi: %s\n", info->imsi);
  713. LOGD("___info->cnum: %s\n", info->cnum);
  714. return 0;
  715. }
  716. static int cell_get_sig(cell_handle_t *h, cell_stat_t *stat)
  717. {
  718. char buf[200];
  719. int rssi,ber,r=-1;
  720. if(h->stat==AT_STAT_UNINIT) {
  721. return -1;
  722. }
  723. r = send_cmd(h, AT_CMD_CSQ, NULL, buf, sizeof(buf));
  724. if (r != AT_OK)
  725. {
  726. return -1;
  727. }
  728. r = sscanf(str_get(buf, '+'), "%*s %d,%d", &rssi, &ber);
  729. if (r < 2)
  730. {
  731. return -1;
  732. }
  733. stat->dbm = rssi_to_dbm(rssi);
  734. stat->ber = ber;
  735. return 0;
  736. }
  737. static int cell_get_gnss(cell_handle_t *h, cell_stat_t *stat)
  738. {
  739. int r;
  740. char buf[200],utc[32],date[32];
  741. #ifdef GNSS_ENABLE
  742. if(h->stat==AT_STAT_UNINIT) {
  743. return -1;
  744. }
  745. r = send_cmd(h, AT_CMD_QGPSLOC, "=0", buf, sizeof(buf));
  746. if(r!=AT_OK) {
  747. return -1;
  748. }
  749. 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);
  750. if(r<6) {
  751. return -1;
  752. }
  753. //
  754. #endif
  755. return 0;
  756. }
  757. static int cell_get_ping(cell_handle_t *h, cell_stat_t *stat)
  758. {
  759. int r,ret;
  760. char buf[200],utc[32],date[32];
  761. if(h->stat==AT_STAT_UNINIT) {
  762. stat->linked = 0;
  763. return -1;
  764. }
  765. /*
  766. r = send_cmd(h, AT_CMD_QPING, "=1,\"www.baidu.com\",3,2,", buf, sizeof(buf));
  767. if(r!=AT_OK) {
  768. stat->linked = 0;
  769. return -1;
  770. }
  771. r = sscanf(str_get(buf,'+'), "+QPING: %d", &ret);
  772. if(r<1) {
  773. stat->linked = 0;
  774. return -1;
  775. }
  776. if(ret==0) {
  777. stat->linked = 1;
  778. }
  779. else {
  780. stat->linked = 0;
  781. }
  782. */
  783. r = send_cmd(h, AT_CMD_CGATT, "?", buf, sizeof(buf));
  784. if(r!=AT_OK) {
  785. stat->linked = 0;
  786. return -1;
  787. }
  788. r = sscanf(str_get(buf,'+'), "+CGATT: %d", &ret);
  789. if(r<1) {
  790. stat->linked = 0;
  791. return -1;
  792. }
  793. if(ret==1) {
  794. stat->linked = 1;
  795. }
  796. else {
  797. stat->linked = 0;
  798. }
  799. return 0;
  800. }
  801. static int cell_get_time(cell_handle_t *h, cell_stat_t *stat)
  802. {
  803. int r,offset;
  804. char opr,buf[200],date[24],time[24];
  805. struct tm utc_tm;
  806. if(h->stat==AT_STAT_UNINIT) {
  807. return -1;
  808. }
  809. r = send_cmd(h, AT_CMD_QLTS, "=1", buf, sizeof(buf));
  810. if(r!=AT_OK) {
  811. return -1;
  812. }
  813. 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);
  814. if(r<6) {
  815. return -1;
  816. }
  817. stat->utctime = mktime2(&utc_tm, 0);
  818. //print_time("999", &utc_tm);
  819. return 0;
  820. }
  821. static int cell_get_stat(cell_handle_t *h, cell_stat_t *stat)
  822. {
  823. if(h->stat==AT_STAT_UNINIT) {
  824. return -1;
  825. }
  826. cell_get_sig(h, stat);
  827. cell_get_gnss(h, stat);
  828. cell_get_ping(h, stat);
  829. cell_get_time(h, stat);
  830. cell_get_ip(h, stat);
  831. return 0;
  832. }
  833. static int cell_sock_conn(cell_handle_t *h, int sock, char *host, uint16_t port, sock_conn_t *conn)
  834. {
  835. int r;
  836. char buf[200];
  837. if(h->stat==AT_STAT_UNINIT) {
  838. return -1;
  839. }
  840. sprintf(buf, "=%s,%s,%s,“%s”,%d,0,1", CONTEXT_ID, CONNECT_ID, (sock==SOCK_TCP)?"TCP":"UDP", host, port);
  841. r = send_cmd(h, AT_CMD_QIOPEN, buf, NULL, 0);
  842. if(r!=AT_OK) {
  843. return -1;
  844. }
  845. conn->h = h;
  846. conn->sock = sock;
  847. conn->cont_id = atoi(CONTEXT_ID);
  848. conn->conn_id = atoi(CONNECT_ID);
  849. return 0;
  850. }
  851. static int cell_sock_disconn(sock_conn_t *conn)
  852. {
  853. int r;
  854. char buf[200];
  855. cell_handle_t *h=(cell_handle_t*)conn->h;
  856. if(h->stat==AT_STAT_UNINIT) {
  857. return -1;
  858. }
  859. sprintf(buf, "=%s,%s", CONNECT_ID, CONNECT_TIMEOUT);
  860. r = send_cmd(h, AT_CMD_QICLOSE, buf, NULL, 0);
  861. if(r!=AT_OK) {
  862. return -1;
  863. }
  864. conn->h = NULL;
  865. conn->sock = -1;
  866. conn->cont_id = -1;
  867. conn->conn_id = -1;
  868. return 0;
  869. }
  870. static int cell_sock_send(sock_conn_t *conn, void *data, int len)
  871. {
  872. int r=0,rt,offset=0,remain_len,send_len;
  873. char buf[100],*pd=(char*)data;
  874. cell_handle_t *h=(cell_handle_t*)conn->h;
  875. if(h->stat==AT_STAT_UNINIT) {
  876. return -1;
  877. }
  878. sprintf(buf, "=%d,%d", conn->conn_id, len);
  879. rt = send_cmd(h, AT_CMD_QISEND, buf, NULL, 0);
  880. if(rt!=AT_OK) {
  881. return -1;
  882. }
  883. while(offset<len) {
  884. remain_len = len - offset;
  885. send_len = (remain_len>CHUNCK_SIZE)?CHUNCK_SIZE:remain_len;
  886. rt = send_data(h, data+offset, send_len, 500);
  887. if(rt!=AT_OK) {
  888. r = -1; break;
  889. }
  890. offset += send_len;
  891. }
  892. return r;
  893. }
  894. static int cell_sock_stat(sock_conn_t *conn)
  895. {
  896. int r;
  897. char buf[100];
  898. cell_handle_t *h=(cell_handle_t*)conn->h;
  899. if(h->stat==AT_STAT_UNINIT) {
  900. return -1;
  901. }
  902. r = send_cmd(h, AT_CMD_QISTATE, NULL, buf, sizeof(buf));
  903. if(r!=AT_OK) {
  904. return -1;
  905. }
  906. return 0;
  907. }
  908. static int cell_sock_connected(cell_handle_t *h)
  909. {
  910. return 0;
  911. }
  912. static mqtt_conn_t* get_mqtt_conn_free(cell_handle_t *h)
  913. {
  914. int i;
  915. for(i=0; i<MQTT_MAX; i++) {
  916. if(h->mq_conn[i].h==NULL) {
  917. return &h->mq_conn[i];
  918. }
  919. }
  920. return NULL;
  921. }
  922. static int cell_mqtt_init(cell_handle_t *h)
  923. {
  924. int i;
  925. at_cmd_t *pcmd=NULL;
  926. for(i=0; i<MQTT_MAX; i++) {
  927. h->mq_conn[i].cliId = i;
  928. }
  929. return 0;
  930. }
  931. static int cell_mqtt_conn(cell_handle_t *h, mqtt_para_t *para)
  932. {
  933. int r;
  934. char tmp[200],buf[100];
  935. mqtt_conn_t *conn=NULL;
  936. conn = get_mqtt_conn_free(h);
  937. if(!conn) {
  938. return -1;
  939. }
  940. conn_init(h, conn);
  941. sprintf(tmp, "=%d,\"%s\",%d", conn->cliId, para->host, para->port);
  942. r = send_cmd(h, AT_CMD_QMTOPEN, tmp, buf, sizeof(buf));
  943. if(r!=AT_OK) {
  944. return -1;
  945. }
  946. sprintf(tmp, "=%d,\"mqtt%d\",\"%s\",\"%s\"", conn->cliId, conn->cliId, para->username, para->password);
  947. r = send_cmd(h, AT_CMD_QMTCONN, tmp, buf, sizeof(buf));
  948. if(r!=AT_OK) {
  949. return -1;
  950. }
  951. conn->h = h;
  952. conn->qos = 2;
  953. conn->retain = 0;
  954. return 0;
  955. }
  956. static int cell_mqtt_disconn(mqtt_conn_t *conn)
  957. {
  958. int r;
  959. char tmp[100],buf[100];
  960. at_cmd_t *pcmd=NULL;
  961. sprintf(tmp, "=%d", conn->cliId);
  962. r = send_cmd(conn->h, AT_CMD_QMTDISC, tmp, buf, sizeof(buf));
  963. if(r!=AT_OK) {
  964. return -1;
  965. }
  966. r = send_cmd(conn->h, AT_CMD_QMTCLOSE, tmp, buf, sizeof(buf));
  967. if(r!=AT_OK) {
  968. return -1;
  969. }
  970. conn->msgId = 0;
  971. conn->h = NULL;
  972. return 0;
  973. }
  974. static int cell_mqtt_sub(mqtt_conn_t *conn, char *topic)
  975. {
  976. int r;
  977. char buf[500];
  978. at_cmd_t *pcmd=NULL;
  979. sprintf(buf, "=%d, %d, \"%s\",%d", conn->cliId, conn->msgId, topic, conn->qos);
  980. r = send_cmd(conn->h, AT_CMD_QMTSUB, buf, NULL, 0);
  981. if(r!=AT_OK) {
  982. return -1;
  983. }
  984. return 0;
  985. }
  986. static int cell_mqtt_pub(mqtt_conn_t *conn, char *topic, void *data, int len)
  987. {
  988. char buf[200],*pd=(char*)data;
  989. int r=0,rt,offset=0,remain_len,send_len;
  990. sprintf(buf, "=%d,%d,%d,%d,\"%s\",%d", conn->cliId, conn->msgId, conn->qos, conn->retain, topic, len);
  991. rt = send_cmd(conn->h, AT_CMD_QMTPUB, NULL, buf, sizeof(buf));
  992. if(rt!=AT_OK) {
  993. return -1;
  994. }
  995. while(offset<len) {
  996. remain_len = len - offset;
  997. send_len = (remain_len>CHUNCK_SIZE)?CHUNCK_SIZE:remain_len;
  998. rt = send_data(conn->h, data+offset, send_len, 500);
  999. if(rt!=AT_OK) {
  1000. r = -1; break;
  1001. }
  1002. offset += send_len;
  1003. }
  1004. return 0;
  1005. }
  1006. static int cell_send_sms(cell_handle_t *h, char *number, char *txt)
  1007. {
  1008. int r=-1,rt;
  1009. char tmp[100],buf[300];
  1010. if(h->stat==AT_STAT_UNINIT) {
  1011. return -1;
  1012. }
  1013. // char* unicode_str=utf8_to_unicode_string(txt);
  1014. //if (!unicode_str) return -1;
  1015. //log_i("unicode_str,%s\n", unicode_str);
  1016. log_i("chinese,%s\n", txt);
  1017. char ucs2_sms[256];
  1018. int ss=chinese_to_ucs2(txt, ucs2_sms,sizeof(ucs2_sms)); // 转换为 UCS2 编码
  1019. if (ss!=0) return -1;
  1020. log_i("ucs2_sms,%s\n", ucs2_sms);
  1021. sprintf(tmp, "=\"%s\"", "UCS2");
  1022. r = send_cmd(h, AT_CMD_CSCS, tmp, buf, sizeof(buf));
  1023. if (r != AT_OK)
  1024. {
  1025. return -1;
  1026. }
  1027. sprintf(tmp, "=17,71,0,8");
  1028. r = send_cmd(h, AT_CMD_CSMP, tmp, buf, sizeof(buf));
  1029. if (r != AT_OK)
  1030. {
  1031. return -1;
  1032. }
  1033. sprintf(tmp, "=\"%s\"", number);
  1034. r = send_cmd(h, AT_CMD_CMGS, tmp, buf, sizeof(buf));
  1035. if (r != AT_OK)
  1036. {
  1037. return -1;
  1038. }
  1039. snprintf(buf, sizeof(buf), "%s\x1a", ucs2_sms);
  1040. r = send_data(h, buf, strlen(buf), 5000);
  1041. SMS_SEND_COUNT++;
  1042. return r;
  1043. }
  1044. int cell_send_sms_all(int type, int subtype, int alarm_type,char *txt)
  1045. {
  1046. cell_handle_t *h=&ceHandle;
  1047. if (!__globalDeviceManage._globalDevInfo.cell.Cellular_enable || __globalDeviceManage._globalDevInfo.cell.mode==0 || SMS_SEND_COUNT >= SMS_SEND_MAX)
  1048. {
  1049. return -1;
  1050. }
  1051. char temp[128];
  1052. char *prod_name = h->dm->_globalDevInfo.product.name;
  1053. char prod_id[32];
  1054. strcpy( prod_id,h->dm->_globalDevInfo.product.number);
  1055. int langID = h->dm->_globalDevInfo.product.language;
  1056. switch (type)
  1057. {
  1058. case ALARM_TYPE_POWER:
  1059. {
  1060. if (subtype)
  1061. {
  1062. switch (alarm_type)
  1063. {
  1064. case ENABLE_TAC_V_UP:
  1065. case ENABLE_TAC_V_DOWN:
  1066. snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_V[langID], language_exceed[langID], language_alarm[langID]);
  1067. break;
  1068. case ENABLE_TAC_A_UP:
  1069. snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_A[langID], language_exceed[langID], language_alarm[langID]);
  1070. break;
  1071. case ENABLE_TAC_W_UP:
  1072. snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_W[langID], language_exceed[langID], language_alarm[langID]);
  1073. break;
  1074. case ENABLE_TAC_P_UP:
  1075. snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_P[langID], language_exceed[langID], language_alarm[langID]);
  1076. break;
  1077. case ENABLE_TAC_STIME:
  1078. case ENABLE_TAC_ETIME:
  1079. snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_alarm_phase_lose[langID], language_alarm[langID]);
  1080. break;
  1081. default:
  1082. return -1;
  1083. }
  1084. }
  1085. else
  1086. {
  1087. switch (alarm_type)
  1088. {
  1089. case WARNING_V_UP:
  1090. case WARNING_V_DOWN:
  1091. snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_V[langID], language_exceed[langID], language_alarm[langID]);
  1092. break;
  1093. case WARNING_A_UP:
  1094. snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_A[langID], language_exceed[langID], language_alarm[langID]);
  1095. break;
  1096. case WARNING_W_UP:
  1097. snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_W[langID], language_exceed[langID], language_alarm[langID]);
  1098. break;
  1099. case WARNING_P_UP:
  1100. snprintf(temp, sizeof(temp), "%s %s %s %s %s", prod_name, prod_id, language_alarm_P[langID], language_exceed[langID], language_alarm[langID]);
  1101. break;
  1102. case 0 ... 2:
  1103. snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_alarm_phase_lose[langID], language_alarm[langID]);
  1104. break;
  1105. default:
  1106. return -1;
  1107. }
  1108. }
  1109. }
  1110. break;
  1111. case ALARM_TYPE_SENSOR:
  1112. {
  1113. switch (subtype)
  1114. {
  1115. case SENSOR_TYPE_TEMP_DOUBLE:
  1116. case SENSOR_TYPE_TEMP_HUMI:
  1117. case SENSOR_TYPE_TEMP:
  1118. snprintf(temp, sizeof(temp), "%s %s %s/%s %s", prod_name, prod_id, language_temperature[langID], language_humidity[langID], language_alarm[langID]);
  1119. break;
  1120. case SENSOR_TYPE_SMOKE:
  1121. snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_sensor_smoke[langID], language_alarm[langID]);
  1122. break;
  1123. case SENSOR_TYPE_WATER:
  1124. snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_humidity[langID], language_alarm[langID]);
  1125. break;
  1126. case SENSOR_TYPE_ACCESS:
  1127. snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_sensor_access[langID], language_alarm[langID]);
  1128. break;
  1129. case SENSOR_TYPE_GAS:
  1130. snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_atmosphere_gas[langID], language_alarm[langID]);
  1131. break;
  1132. case SENSOR_TYPE_AIR_PRESS:
  1133. snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_atmosphere_pressure[langID], language_alarm[langID]);
  1134. break;
  1135. case SENSOR_TYPE_LEAK:
  1136. snprintf(temp, sizeof(temp), "%s %s %s %s", prod_name, prod_id, language_sensor_leak[langID], language_alarm[langID]);
  1137. break;
  1138. default:
  1139. return -1;
  1140. }
  1141. }
  1142. break;
  1143. case ALARM_TYPE_NETWORK:
  1144. {
  1145. snprintf(temp, sizeof(temp), "%s %s %s", prod_name, prod_id, language_alarm_Type_Network[langID]);
  1146. }
  1147. break;
  1148. default:
  1149. return -1;
  1150. }
  1151. char result[256];
  1152. snprintf(result, sizeof(result), "%s, %s", temp, txt);
  1153. for (int i = 0; i < MAIL_RECV_MAX; i++)
  1154. {
  1155. if (strcmp(__globalDeviceManage._globalDevInfo.cell.sms_recv[i].account, "") != 0)
  1156. {
  1157. cell_send_sms(h, __globalDeviceManage._globalDevInfo.cell.sms_recv[i].account, result);
  1158. sleep(1);
  1159. }
  1160. }
  1161. return 1;
  1162. }
  1163. static int cell_send_call(cell_handle_t *h, char *number, void *data, int len)
  1164. {
  1165. int r;
  1166. char buf[100];
  1167. if(h->stat==AT_STAT_UNINIT) {
  1168. return -1;
  1169. }
  1170. sprintf(buf, "%s", number);
  1171. r = send_cmd(h, AT_CMD_ATD, NULL, buf, sizeof(buf));
  1172. if(r!=AT_OK) {
  1173. return -1;
  1174. }
  1175. return 0;
  1176. }
  1177. /////////////////////////////////////////////////////////////////////////
  1178. static int conn_cfg(mqtt_conn_t *conn, char *item, char *value)
  1179. {
  1180. int r;
  1181. char tmp[100],buf[200];
  1182. cell_handle_t *h=(cell_handle_t*)conn->h;
  1183. if(h->stat==AT_STAT_UNINIT) {
  1184. return -1;
  1185. }
  1186. sprintf(tmp, "=\"%s\",%s", item, value);
  1187. r = send_cmd(h, AT_CMD_QMTCFG, NULL, buf, sizeof(buf));
  1188. if(r!=AT_OK) {
  1189. return -1;
  1190. }
  1191. return 0;
  1192. }
  1193. static void conn_init(cell_handle_t *h, mqtt_conn_t *conn)
  1194. {
  1195. char buf[100];
  1196. conn->h = h;
  1197. conn->ver = MQTT_VER;
  1198. conn->pdpId = conn->cliId+1; //1~15
  1199. conn->msgId = 0;
  1200. conn->qos = MQTT_QOS;
  1201. conn->retain = 1;
  1202. conn->will.flag = MQTT_WILL;
  1203. conn->will.qos = MQTT_QOS;
  1204. conn->will.retain = MQTT_RETAIN;
  1205. strcpy(conn->will.topic, "");
  1206. strcpy(conn->will.message, "");
  1207. conn->will.message_len = strlen(conn->will.message);
  1208. conn->timeout = 10; //1~60, default:5
  1209. conn->retry_times = 3;
  1210. conn->timeout_notice = 1;
  1211. conn->clean_session = 1;
  1212. conn->ssl_enable = 0;
  1213. conn->ssl_ctx_id = 0;
  1214. conn->msg_recv_mode = 0; //0: urc, 1: not urc
  1215. conn->msg_len_enable = 1;
  1216. conn->ping_interval = 5; //5~60, default:5
  1217. conn->proto_chk_enable = 0; //0:no check 1:check
  1218. conn->send_mode = 0; //0:string 1:hex
  1219. conn->recv_mode = 0; //0:string 1:hex
  1220. conn->view_mode = 0; //0:no echo 1:echo
  1221. conn->edit_mode = 0; //0:timeout not quit 1:timeout quit
  1222. conn->edit_time = 5; //1~120 seconds
  1223. //conn->plat.product_key[64]; //aliyun used
  1224. //conn->plat.device_name[64]; //aliyun used
  1225. //conn->plat.device_secret[64]; //aliyun/ used
  1226. //conn->plat.hw_time_enable; //huawei used
  1227. //conn->plat.product_secret[64]; //huawei used
  1228. //conn->plat.node_id[64];
  1229. //conn->plat.product_id[64]; //onenet used
  1230. //conn->plat.access_key[64]; //onenet used
  1231. sprintf(buf, "%d,%d", conn->cliId, conn->ver);
  1232. conn_cfg(conn, "version", buf);
  1233. sprintf(buf, "%d,%d", conn->cliId, conn->pdpId);
  1234. conn_cfg(conn, "pdpcid", buf);
  1235. sprintf(buf, "%d,%d", conn->cliId, conn->keep_alive_time);
  1236. conn_cfg(conn, "keepalive", buf);
  1237. sprintf(buf, "%d,%d", conn->cliId, conn->clean_session);
  1238. conn_cfg(conn, "session", buf);
  1239. sprintf(buf, "%d,%d,%d,%d", conn->cliId, conn->timeout, conn->retry_times, conn->timeout_notice);
  1240. conn_cfg(conn, "timeout", buf);
  1241. sprintf(buf, "%d,%d,%d", conn->cliId, conn->ssl_enable, conn->ssl_ctx_id);
  1242. conn_cfg(conn, "ssl", buf);
  1243. sprintf(buf, "%d,%d", conn->cliId, conn->ping_interval);
  1244. conn_cfg(conn, "qmtping", buf);
  1245. //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);
  1246. //conn_cfg(conn, "will", buf);
  1247. //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);
  1248. //conn_cfg(conn, "willex", buf);
  1249. sprintf(buf, "%d,%d", conn->cliId, conn->send_mode);
  1250. conn_cfg(conn, "send/mode", buf);
  1251. sprintf(buf, "%d,%d,%d", conn->cliId, conn->msg_recv_mode, conn->msg_len_enable);
  1252. conn_cfg(conn, "recv/mode", buf);
  1253. sprintf(buf, "%d,%d", conn->cliId, conn->view_mode);
  1254. conn_cfg(conn, "view/mode", buf);
  1255. sprintf(buf, "%d,%d,%d", conn->cliId, conn->edit_mode, conn->edit_time);
  1256. conn_cfg(conn, "edit/timeout", buf);
  1257. sprintf(buf, "%d,%d", conn->cliId, conn->proto_chk_enable);
  1258. conn_cfg(conn, "protocol/check", buf);
  1259. sprintf(buf, "%d,%d,%d", conn->cliId, conn->send_mode, conn->recv_mode);
  1260. conn_cfg(conn, "dataformat", buf);
  1261. #if 0 //aliyun
  1262. sprintf(buf, "%d,\"%s\",\"%s\",\"%s\"", conn->cliId, conn->plat.product_key, conn->plat.device_name, conn->plat.device_secret);
  1263. conn_cfg(conn, "aliauth", buf);
  1264. #endif
  1265. #if 0 //huawei
  1266. sprintf(buf, "%d,\"%s\",\"%s\"", conn->cliId, conn->plat.product_id, conn->plat.device_secret);
  1267. conn_cfg(conn, "hwauth", buf);
  1268. sprintf(buf, "%d,\"%s\",\"%s\",\"%s\"", conn->cliId, conn->plat.product_id, conn->plat.product_secret, conn->plat.node_id);
  1269. conn_cfg(conn, "hwprodid", buf);
  1270. #endif
  1271. #if 0 //onenet
  1272. sprintf(buf, "%d,\"%s\",\"%s\"", conn->cliId, conn->plat.product_id, conn->plat.access_key);
  1273. conn_cfg(conn, "onenet", buf);
  1274. #endif
  1275. }
  1276. static int cell_test(cell_handle_t *h)
  1277. {
  1278. int r;
  1279. cell_info_t info;
  1280. cell_stat_t stat;
  1281. cell_get_info(h, &info);
  1282. while(1) {
  1283. r = cell_get_stat(h, &stat);
  1284. if(r==0) {
  1285. LOGD("___dbm: %d ber: %d\n", stat.dbm, stat.ber);
  1286. }
  1287. else {
  1288. LOGE("___ get stat failed\n");
  1289. }
  1290. sleep(3);
  1291. }
  1292. return 0;
  1293. }
  1294. /////////////////////////////////////////////////////////////////////////
  1295. static int urc_handle(char *data, int len)
  1296. {
  1297. char *key=NULL;
  1298. key = "+QIURC: ";
  1299. if(strstr(data, key)) {
  1300. }
  1301. key = "+QMT";
  1302. if(strstr(data, key)) {
  1303. }
  1304. return 0;
  1305. }
  1306. static void* cellular_thread(void *arg)
  1307. {
  1308. int r;
  1309. uint32_t cnt=0,prelinkcnt=0;
  1310. char rxbuf[BUF_LEN];
  1311. thread_handle_t *th=(thread_handle_t*)arg;
  1312. cell_handle_t *h=(cell_handle_t*)th->arg;
  1313. port_init(h);
  1314. while (th->quit==0) {
  1315. cnt++;
  1316. if(h->pcell->mode) {
  1317. if (h->fd<0)
  1318. {
  1319. port_init(h);
  1320. }
  1321. if(cnt%5==0) {
  1322. cell_init(h);
  1323. }
  1324. if (cnt % 5 == 0)
  1325. {
  1326. // cell_get_info(h, &h->all.info);
  1327. cell_get_stat(h, &h->all.stat);
  1328. }
  1329. if (h->all.stat.linked == 1)
  1330. {
  1331. prelinkcnt = cnt;
  1332. }
  1333. if (cnt -prelinkcnt >=60 && h->all.stat.linked == 0)
  1334. {
  1335. prelinkcnt = cnt;
  1336. cell_reset(h);
  1337. }
  1338. }
  1339. else
  1340. {
  1341. if( h->fd>=0)
  1342. {
  1343. cell_deinit(h);
  1344. port_deinit(h);
  1345. }
  1346. reset_var(h);
  1347. }
  1348. UpdateCellularManager(&h->all);
  1349. sleep(1);
  1350. }
  1351. cell_deinit(h);
  1352. port_deinit(h);
  1353. pthread_exit(NULL);
  1354. }
  1355. int cellular_reset(void)
  1356. {
  1357. int r=-1;
  1358. cell_handle_t *h=&ceHandle;
  1359. r = cell_reset(h);
  1360. return r;
  1361. }
  1362. int cellular_init(void)
  1363. {
  1364. int r;
  1365. cell_handle_t *h=&ceHandle;
  1366. if (__globalDeviceManage._globalDevInfo.cell.Cellular_enable)
  1367. {
  1368. memset(h, 0, sizeof(cell_handle_t));
  1369. h->dm = &__globalDeviceManage;
  1370. h->pcell = &h->dm->_globalDevInfo.cell;
  1371. strcpy( h->prod_id,h->dm->_globalDevInfo.product.number);
  1372. h->lck = lock_d_init();
  1373. nic_set(NIC_USB, 1);
  1374. dev_SMS_get(h->dm->db, h->pcell);
  1375. thread_start(THREAD_ID_CELLULAR, cellular_thread, h);
  1376. }
  1377. return 0;
  1378. }
  1379. int cellular_deinit(void)
  1380. {
  1381. cell_handle_t *h=&ceHandle;
  1382. if (__globalDeviceManage._globalDevInfo.cell.Cellular_enable)
  1383. {
  1384. lock_d_deinit(h->lck);
  1385. thread_stop(THREAD_ID_CELLULAR);
  1386. }
  1387. return 0;
  1388. }
  1389. int cellular_get_all(cell_all_t *all)
  1390. {
  1391. int r=-1;
  1392. cell_handle_t *h=&ceHandle;
  1393. if(all) {
  1394. *all = h->all;
  1395. r = 0;
  1396. }
  1397. return r;
  1398. }
  1399. int cellular_is_connected(void)
  1400. {
  1401. int r=0;
  1402. cell_handle_t *h=&ceHandle;
  1403. if (__globalDeviceManage._globalDevInfo.cell.Cellular_enable)
  1404. {
  1405. r = h->all.stat.linked;
  1406. }
  1407. return r;
  1408. }
  1409. int UpdateCellularManager( cell_all_t *all)
  1410. {
  1411. int r = -1;
  1412. if (all)
  1413. {
  1414. __globalDeviceManage._globalDevInfo.cell.Link_status = all->stat.linked;
  1415. __globalDeviceManage._globalDevInfo.cell.Signal_strength = all->stat.dbm;
  1416. strcpy( __globalDeviceManage._globalDevInfo.cell.apn , all->info.apn);
  1417. strcpy( __globalDeviceManage._globalDevInfo.cell.Cellular_name , all->info.isp);
  1418. strcpy( __globalDeviceManage._globalDevInfo.cell.Cellular_Num , all->info.imei);
  1419. r=0;
  1420. }
  1421. return r;
  1422. }
  1423. int cellular_test(void)
  1424. {
  1425. cell_handle_t *h=&ceHandle;
  1426. cell_test(h);
  1427. return 0;
  1428. }