ec800m.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561
  1. #include "CONFIG.h"
  2. #if EC800M
  3. #include "stm32f10x.h"
  4. #include <stdio.h>
  5. #include <stdarg.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include "ec800m.h"
  9. #include "Common_Util.h"
  10. #include "Log_Module.h"
  11. #include "At_Module.h"
  12. /**
  13. * 龙三郎
  14. **/
  15. // 方法声明
  16. void ec800m_reset(void); // 重置状态。该文件中的方法共用状态,在使用下面的方法前需要重置一下状态。
  17. void ec800m_exit_sleep(void); // 退出休眠
  18. void ec800m_enter_sleep(void); // 进入休眠
  19. /**
  20. * 查询休眠模式
  21. * 输入<<
  22. *
  23. * 输出>>
  24. * n 睡眠模式。0 禁用,默认;1 启用。
  25. **/
  26. enum Result ec800m_query_sleep(uint8_t * n); // 查询休眠模式。
  27. enum Result ec800m_query_sleep_sync(uint8_t * n); // 查询休眠模式。同步
  28. /**
  29. * 设置休眠模式
  30. * 输入<<
  31. * n 参数。0 禁用;1启用。
  32. * 输出>>
  33. *
  34. **/
  35. enum Result ec800m_set_sleep(uint8_t n); // 设置休眠模式。
  36. enum Result ec800m_set_sleep_sync(uint8_t n); // 设置休眠模式。同步
  37. /**
  38. * 设置功能模式
  39. * 输入<<
  40. * fun 0 最小功能模式;1 全功能模式。
  41. * 输出>>
  42. *
  43. **/
  44. enum Result ec800m_set_cfun(uint8_t fun);
  45. enum Result ec800m_set_cfun_sync(uint8_t fun); // 同步
  46. /**
  47. * 设置ps域网络注册状态
  48. * 输入<<
  49. * n 0 禁止上报网络注册;1 允许上报网络注册;2 允许上报网络注册和位置信息
  50. * 输出>>
  51. *
  52. **/
  53. enum Result ec800m_set_cgreg(uint8_t n);
  54. enum Result ec800m_set_cgreg_sync(uint8_t n); // 同步
  55. /**
  56. * 查询ps域网络注册状态
  57. * 输入<<
  58. *
  59. * 输出>>
  60. * n 控制指定URC的上报。0 禁止上报网络注册;1 允许上报网络注册;2 允许上报网络注册和位置信息
  61. * stat 网络注册状态。0 未注册;1 已注册,归属地网络; 2 未注册;3 注册被拒绝;4 未知;5 已注册,漫游。
  62. * lac 基站位置区号。用于基站定位,2个字节。
  63. * ci 基站小区ID。用于基站定位,4个字节。
  64. *
  65. **/
  66. enum Result ec800m_query_cgreg(uint8_t * n, uint8_t * stat, uint16_t * lac, uint32_t * ci);
  67. enum Result ec800m_query_cgreg_sync(uint8_t * n, uint8_t * stat, uint16_t * lac, uint32_t * ci); // 同步
  68. /**
  69. * 查询socket服务状态
  70. * 输入<<
  71. * connectID Socket ID。范围1-11
  72. *
  73. * 输出>>
  74. * state Socket服务状态。0 未连接;1 正在连接;2 已建立连接;3 服务正在监听;4 连接断开。
  75. *
  76. *
  77. **/
  78. enum Result ec800m_query_socket_state(uint8_t connectID, uint8_t * state);
  79. enum Result ec800m_query_socket_state_sync(uint8_t connectID, uint8_t * state); // 同步
  80. /**
  81. * 打开socket服务
  82. * 输入<<
  83. * connectID Socket ID。范围1-11
  84. * service_type Socket服务类型。取值为"UDP", "TCP"。
  85. * IP_address 远程服务器地址
  86. * remote_port 远程服务器端口
  87. * access_mode Socket服务的数据访问模式。0 缓存模式;1 直吐模式;2 透传模式。
  88. *
  89. * 输出>>
  90. * err 操作错误代码。0 表示没有错误;其余参考移远文档。
  91. *
  92. **/
  93. enum Result ec800m_open_socket(uint8_t connectID, char * service_type, char * IP_address, uint16_t remote_port, uint8_t access_mode, uint16_t * err);
  94. enum Result ec800m_open_socket_sync(uint8_t connectID, char * service_type, char * IP_address, uint16_t remote_port, uint8_t access_mode, uint16_t * err); // 同步
  95. /**
  96. * 关闭socket服务
  97. * 输入<<
  98. * connectID Socket ID。范围1-11
  99. *
  100. * 输出>>
  101. *
  102. **/
  103. enum Result ec800m_close_socket(uint8_t connectID);
  104. enum Result ec800m_close_socket_sync(uint8_t connectID); // 同步
  105. /**
  106. * 解释:控制是否回显AT+QISEND要发送的数据
  107. * 为了便于处理返回,发送数据时需要关闭回显。
  108. * 输入<<
  109. * echo 是否回显AT+QISEND要发送的数据。0 不回显;1 回显。默认是回显
  110. *
  111. * 输出>>
  112. *
  113. **/
  114. enum Result ec800m_set_qisde(uint8_t echo);
  115. enum Result ec800m_set_qisde_sync(uint8_t echo); // 同步
  116. /**
  117. * 发送数据
  118. * 输入<<
  119. * connectID Socket ID。范围1-11。
  120. * send_length 发送长度。
  121. * data 待发送的数据。
  122. *
  123. *
  124. **/
  125. enum Result ec800m_send(uint8_t connectID, uint8_t * data, uint16_t data_length);
  126. enum Result ec800m_send_sync(uint8_t connectID, uint8_t * data, uint16_t data_length); // 同步
  127. /**
  128. * 接收数据
  129. * 输入<<
  130. * connectID Socket ID。范围0-11。
  131. *
  132. * 输出>>
  133. * data 接收的数据。
  134. * data_length 接收的数据长度。
  135. **/
  136. enum Result ec800m_recv(uint8_t connectID, uint8_t * data, uint16_t * data_length); // 接收数据
  137. /**
  138. * 接收数据。带计时
  139. * 输入<<
  140. * connectID Socket ID。范围0-11。
  141. *
  142. * 输出>>
  143. * data 接收的数据。
  144. * data_length 接收的数据长度。
  145. *
  146. **/
  147. enum Result ec800m_recv_with_time(uint8_t connectID, uint8_t * data, uint16_t * data_length, uint32_t time_out);
  148. enum Result ec800m_recv_with_time_sync(uint8_t connectID, uint8_t * data, uint16_t * data_length, uint32_t time_out); // 同步
  149. /**
  150. * 解释:关闭模块
  151. * 关闭模块,关闭后会自动重启。
  152. * 输入<<
  153. * n 模块关机方式。0 立即关机;1 正常关机。默认是1
  154. *
  155. *
  156. **/
  157. enum Result ec800m_power_down(uint8_t n);
  158. enum Result ec800m_power_down_sync(uint8_t n); // 同步
  159. /**
  160. * 模块是否启动成功
  161. * 输入<<
  162. *
  163. * 输出>>
  164. *
  165. **/
  166. enum Result ec800m_ready(void);
  167. /**
  168. * 查询信号质量
  169. * 输入<<
  170. *
  171. * 输出>>
  172. * RSRP
  173. * RSRQ
  174. * RSSI
  175. * SINR
  176. **/
  177. enum Result ec800m_qeng_servingcell(int * RSRP, int * RSRQ, int * RSSI, int * SINR);
  178. enum Result ec800m_qeng_servingcell_sync(int * RSRP, int * RSRQ, int * RSSI, int * SINR);
  179. /**
  180. * 查询ICCID
  181. * 输入<<
  182. *
  183. * 输出>>
  184. * iccid SIM卡卡号
  185. **/
  186. enum Result ec800m_query_qccid(char * iccid);
  187. enum Result ec800m_query_qccid_sync(char * iccid);
  188. // AT指令
  189. static char AT_CMD[256];
  190. // EC800M提供的一些方法
  191. struct EC800M_Struct ec800m =
  192. {
  193. .timer = {
  194. .time = 0,
  195. .flag = 0
  196. },
  197. .reset = ec800m_reset,
  198. .exit_sleep = ec800m_exit_sleep,
  199. .enter_sleep = ec800m_enter_sleep,
  200. .query_sleep = ec800m_query_sleep,
  201. .query_sleep_sync = ec800m_query_sleep_sync,
  202. .set_sleep = ec800m_set_sleep,
  203. .set_sleep_sync = ec800m_set_sleep_sync,
  204. .set_cfun = ec800m_set_cfun,
  205. .set_cfun_sync = ec800m_set_cfun_sync,
  206. .set_cgreg = ec800m_set_cgreg,
  207. .set_cgreg_sync = ec800m_set_cgreg_sync,
  208. .query_cgreg = ec800m_query_cgreg,
  209. .query_cgreg_sync = ec800m_query_cgreg_sync,
  210. .query_socket_state = ec800m_query_socket_state,
  211. .query_socket_state_sync = ec800m_query_socket_state_sync,
  212. .open_socket = ec800m_open_socket,
  213. .open_socket_sync = ec800m_open_socket_sync,
  214. .close_socket = ec800m_close_socket,
  215. .close_socket_sync = ec800m_close_socket_sync,
  216. .set_qisde = ec800m_set_qisde,
  217. .set_qisde_sync = ec800m_set_qisde_sync,
  218. .send = ec800m_send,
  219. .send_sync = ec800m_send_sync,
  220. .recv = ec800m_recv,
  221. .recv_with_time = ec800m_recv_with_time,
  222. .recv_with_time_sync = ec800m_recv_with_time_sync,
  223. .power_down = ec800m_power_down,
  224. .power_down_sync = ec800m_power_down_sync,
  225. .ready = ec800m_ready,
  226. .qeng_servingcell = ec800m_qeng_servingcell,
  227. .qeng_servingcell_sync = ec800m_qeng_servingcell_sync,
  228. .query_qccid = ec800m_query_qccid,
  229. .query_qccid_sync = ec800m_query_qccid_sync
  230. };
  231. // 发送AT指令
  232. static void send_data(uint8_t * data, uint16_t length)
  233. {
  234. // 发送AT指令
  235. AT_Send_Bytes(data, length);
  236. }
  237. // 发送AT指令
  238. static uint8_t send_at_string(char * cmd)
  239. {
  240. uint8_t state = 0;
  241. if(AT_Get_Status() == AT_Status_None)
  242. {
  243. // 发送AT指令
  244. AT_Send_String(cmd);
  245. state = 1;
  246. }
  247. return state;
  248. }
  249. // 获取状态
  250. static enum STATUS getStatus(void)
  251. {
  252. return ec800m.status;
  253. }
  254. // 设置状态
  255. static void setStatus(enum STATUS status)
  256. {
  257. ec800m.status = status;
  258. }
  259. // 获取定时
  260. static uint32_t getTimerMs(void)
  261. {
  262. return time_get_delay(&ec800m.timer);
  263. }
  264. // 清除定时
  265. static void clearTimer(void)
  266. {
  267. time_clear(&ec800m.timer);
  268. }
  269. // 设置定时
  270. //static void setTimerMs(uint32_t time)
  271. //{
  272. // ec800m.timer_ms = time;
  273. //}
  274. // 获取ID
  275. static uint8_t getActiveID(void)
  276. {
  277. return ec800m.activeID;
  278. }
  279. static void setActiveID(uint8_t activeID)
  280. {
  281. ec800m.activeID = activeID;
  282. }
  283. // 验证ID
  284. static uint8_t verifyActiveID(uint8_t activeID)
  285. {
  286. if(getActiveID() == 0 || getActiveID() == activeID){ return 1; }
  287. else
  288. {
  289. Log_Printf_Debug("activeID repetition!\r\n");
  290. return 0;
  291. }
  292. }
  293. // 返回超时结果
  294. static enum Result overtime(void)
  295. {
  296. setStatus(Status_Overtime); // 超时
  297. // 发送日志
  298. Log_Printf_Debug("接收超时: %d\r\n", AT_result_length());
  299. Log_SendArray_Debug(AT_result(), AT_result_length());
  300. return Result_Failed; // 结果
  301. }
  302. // 返回成功结果
  303. static enum Result success_no_log(void)
  304. {
  305. // 成功
  306. setStatus(Status_Success);
  307. // 结果
  308. return Result_Success;
  309. }
  310. // 返回成功结果
  311. static enum Result success(void)
  312. {
  313. // 发送日志
  314. Log_Printf_Debug("接收成功: %d\r\n", AT_result_length());
  315. Log_SendArray_Debug(AT_result(), AT_result_length());
  316. return success_no_log();
  317. }
  318. // 返回失败结果
  319. static enum Result failed(int type)
  320. {
  321. // 失败
  322. setStatus(Status_Failed);
  323. if(type == 1)
  324. {
  325. Log_Printf_Debug("activeID: %d, error: 接收结果过期,请重置状态\r\n", ec800m.activeID); // 打印日志
  326. }
  327. else if(type == 2)
  328. {
  329. // 发送日志
  330. Log_Printf_Debug("activeID: %d, AT接收失败: %d\r\n", ec800m.activeID, AT_result_length());
  331. Log_SendArray_Debug(AT_result(), AT_result_length());
  332. }
  333. else
  334. {
  335. Log_Printf_Debug("activeID: %d, error: 未知错误类型\r\n", ec800m.activeID); // 打印日志
  336. }
  337. // 失败结果
  338. return Result_Failed;
  339. }
  340. // 重置状态。该文件中的方法共用状态,在使用方法前需要重置一下状态。
  341. void ec800m_reset(void)
  342. {
  343. setStatus(Status_None); // 重置状态
  344. setActiveID(0); // 重置ID
  345. clearTimer(); // 重置计时
  346. AT_Clear(); // 清除AT指令
  347. }
  348. // 发送指令并改变状态
  349. enum Result send_at_nolog(char * cmd, uint8_t activeID)
  350. {
  351. if(send_at_string(cmd)) // 发送AT指令
  352. {
  353. Log_Printf_Debug("发送成功: %d\r\n", strlen(cmd)); // 打印日志
  354. setActiveID(activeID); // 活动ID
  355. setStatus(Status_Sending); // 设置已发送
  356. clearTimer(); // 重置计时
  357. return Result_None; // 未知结果
  358. }
  359. else
  360. {
  361. Log_Printf_Debug("activeID: %d, error: AT指令发送失败\r\n", ec800m.activeID); // 打印日志
  362. return Result_Failed; // 失败结果
  363. }
  364. }
  365. enum Result send_at(char * cmd, uint8_t activeID)
  366. {
  367. enum Result result = send_at_nolog(cmd, activeID);
  368. if(result == Result_None) // 发送成功
  369. {
  370. Log_Printf_Debug(cmd); // 打印AT指令
  371. }
  372. return result;
  373. }
  374. // 退出休眠
  375. void ec800m_exit_sleep(void)
  376. {
  377. GPIO_ResetBits(WAKE_GPIO, WAKE_GPIO_Pin); // 拉低io口,唤醒模组
  378. }
  379. // 进入休眠
  380. void ec800m_enter_sleep(void)
  381. {
  382. GPIO_SetBits(WAKE_GPIO, WAKE_GPIO_Pin); // 拉高io口,进入睡眠
  383. }
  384. /**
  385. * 查询休眠模式
  386. * 输入<<
  387. *
  388. * 输出>>
  389. * n 睡眠模式。0 禁用,默认;1 启用。
  390. *
  391. **/
  392. enum Result ec800m_query_sleep(uint8_t * n)
  393. {
  394. enum Result result = Result_None;
  395. int activeID = 1, time = 500; // 活动ID, 超时时间
  396. if(!verifyActiveID(activeID)){ return Result_Failed; } // 校验ID
  397. // 判断状态
  398. if(getStatus() == Status_None) // 空闲状态
  399. {
  400. sprintf(AT_CMD, "AT+QSCLK?\r\r\n"); // 拼接AT指令
  401. result = send_at(AT_CMD, activeID);
  402. }
  403. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  404. {
  405. result = failed(1); // 失败
  406. }
  407. else if(getTimerMs() > time) // 正在发送状态。判断超时
  408. {
  409. result = overtime(); // 超时
  410. }
  411. if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  412. {
  413. result = success(); // 成功
  414. // 处理返回结果
  415. char * saveptr = NULL;
  416. char * split = "\r\n";
  417. // 第一行
  418. char * Line1 = strtok_r((char * )AT_result(), split, &saveptr);
  419. // 第二行
  420. char * Line2 = strtok_r(NULL, split, &saveptr);
  421. // 拆解第二行
  422. char * saveptr_inner = NULL;
  423. char * split_inner = ": ";
  424. strtok_r(Line2, split_inner, &saveptr_inner);
  425. // 获取mode
  426. * n = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  427. }
  428. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  429. {
  430. result = failed(2); // 失败
  431. }
  432. return result;
  433. }
  434. /**
  435. * 查询休眠模式。同步方法
  436. * 输入<<
  437. *
  438. * 输出>>
  439. * n 睡眠模式。0 禁用,默认;1 启用。
  440. *
  441. **/
  442. enum Result ec800m_query_sleep_sync(uint8_t * n)
  443. {
  444. enum Result result = Result_None;
  445. while(1)
  446. {
  447. result = ec800m_query_sleep(n);
  448. if(result != Result_None)
  449. {
  450. // 重置
  451. ec800m.reset();
  452. break;
  453. }
  454. }
  455. return result;
  456. }
  457. /**
  458. * 设置休眠模式
  459. * n 参数。0 禁用;1启用。
  460. **/
  461. enum Result ec800m_set_sleep(uint8_t n)
  462. {
  463. enum Result result = Result_None;
  464. int activeID = 2, time = 500; // 活动ID, 超时时间
  465. if(!verifyActiveID(activeID)){ return Result_Failed; } // 校验ID
  466. // 判断状态
  467. if(getStatus() == Status_None) // 空闲状态
  468. {
  469. sprintf(AT_CMD, "AT+QSCLK=%d\r\r\n", n); // 拼接AT指令
  470. result = send_at(AT_CMD, activeID);
  471. }
  472. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  473. {
  474. result = failed(1); // 失败
  475. }
  476. else if(getTimerMs() > time) // 正在发送状态。判断超时
  477. {
  478. result = overtime(); // 超时
  479. }
  480. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  481. {
  482. result = success(); // 成功
  483. }
  484. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  485. {
  486. result = failed(2); // 失败
  487. }
  488. return result;
  489. }
  490. /**
  491. * 设置休眠模式。同步
  492. * n 参数。0 禁用;1启用。
  493. **/
  494. enum Result ec800m_set_sleep_sync(uint8_t n)
  495. {
  496. enum Result result = Result_None;
  497. while(1)
  498. {
  499. result = ec800m_set_sleep(n);
  500. if(result != Result_None)
  501. {
  502. // 重置
  503. ec800m.reset();
  504. break;
  505. }
  506. }
  507. return result;
  508. }
  509. /**
  510. * 设置功能模式
  511. * fun 0 最小功能模式;1 全功能模式。
  512. **/
  513. enum Result ec800m_set_cfun(uint8_t fun)
  514. {
  515. enum Result result = Result_None;
  516. int activeID = 4, time; // 活动ID, 超时时间
  517. // 校验参数
  518. if(fun == 0){ time = 3000; }
  519. else if(fun == 1){ time = 5000; }
  520. else
  521. {
  522. Log_Printf_Debug("set_cfun params error!\r\n");
  523. return Result_Failed;
  524. }
  525. // 校验ID
  526. if(!verifyActiveID(activeID)){ return Result_Failed; }
  527. // 判断状态
  528. if(getStatus() == Status_None) // 空闲状态
  529. {
  530. sprintf(AT_CMD, "AT+CFUN=%d\r\r\n", fun); // 拼接AT指令
  531. result = send_at(AT_CMD, activeID);
  532. }
  533. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  534. {
  535. result = failed(1); // 失败
  536. }
  537. else if(getTimerMs() > time) // 正在发送状态。判断超时
  538. {
  539. result = overtime(); // 超时
  540. }
  541. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  542. {
  543. // 防止接收不完整
  544. if(AT_wait_time() > 10) // 过10ms之后再取数据,避免数据截断。
  545. {
  546. result = success(); // 成功
  547. }
  548. }
  549. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  550. {
  551. result = failed(2); // 失败
  552. }
  553. return result;
  554. }
  555. /**
  556. * 设置功能模式
  557. * 输入<<
  558. * fun 0 最小功能模式;1 全功能模式。
  559. * 输出>>
  560. *
  561. **/
  562. enum Result ec800m_set_cfun_sync(uint8_t fun)
  563. {
  564. enum Result result = Result_None;
  565. while(1)
  566. {
  567. result = ec800m_set_cfun(fun);
  568. if(result != Result_None)
  569. {
  570. // 重置
  571. ec800m.reset();
  572. break;
  573. }
  574. }
  575. return result;
  576. }
  577. /**
  578. * 设置ps域网络注册状态
  579. * n 0 禁止上报网络注册;1 允许上报网络注册;2 允许上报网络注册和位置信息
  580. **/
  581. enum Result ec800m_set_cgreg(uint8_t n)
  582. {
  583. enum Result result = Result_None;
  584. int activeID = 6, time = 500; // 活动ID, 超时时间
  585. // 校验参数
  586. if(n > 2)
  587. {
  588. Log_Printf_Debug("set_cgreg params error!\r\n");
  589. return Result_Failed;
  590. }
  591. // 校验ID
  592. if(!verifyActiveID(activeID)){ return Result_Failed; }
  593. // 判断状态
  594. if(getStatus() == Status_None) // 空闲状态
  595. {
  596. sprintf(AT_CMD, "AT+CGREG=%d\r\r\n", n); // 拼接AT指令
  597. result = send_at(AT_CMD, activeID);
  598. }
  599. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  600. {
  601. result = failed(1); // 失败
  602. }
  603. else if(getTimerMs() > time) // 正在发送状态。判断超时
  604. {
  605. result = overtime(); // 超时
  606. }
  607. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  608. {
  609. result = success(); // 成功
  610. }
  611. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  612. {
  613. result = failed(2); // 失败
  614. }
  615. return result;
  616. }
  617. /**
  618. * 设置ps域网络注册状态
  619. * 输入<<
  620. * n 0 禁止上报网络注册;1 允许上报网络注册;2 允许上报网络注册和位置信息
  621. * 输出>>
  622. *
  623. **/
  624. enum Result ec800m_set_cgreg_sync(uint8_t n)
  625. {
  626. enum Result result = Result_None;
  627. while(1)
  628. {
  629. result = ec800m_set_cgreg(n);
  630. if(result != Result_None)
  631. {
  632. // 重置
  633. ec800m.reset();
  634. break;
  635. }
  636. }
  637. return result;
  638. }
  639. /**
  640. * 查询ps域网络注册状态
  641. * 输入<<
  642. *
  643. * 输出>>
  644. * n 控制指定URC的上报。0 禁止上报网络注册;1 允许上报网络注册;2 允许上报网络注册和位置信息
  645. * stat 网络注册状态。0 未注册;1 已注册,归属地网络; 2 未注册;3 注册被拒绝;4 未知;5 已注册,漫游。
  646. * lac 基站位置区号。用于基站定位,2个字节。
  647. * ci 基站小区ID。用于基站定位,4个字节。
  648. *
  649. **/
  650. enum Result ec800m_query_cgreg(uint8_t * n, uint8_t * stat, uint16_t * lac, uint32_t * ci)
  651. {
  652. enum Result result = Result_None;
  653. int activeID = 9, time = 500; // 活动ID, 超时时间
  654. // 校验ID
  655. if(!verifyActiveID(activeID)){ return Result_Failed; }
  656. // 判断状态
  657. if(getStatus() == Status_None) // 空闲状态
  658. {
  659. sprintf(AT_CMD, "AT+CGREG?\r\r\n"); // 拼接AT指令
  660. result = send_at(AT_CMD, activeID);
  661. }
  662. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  663. {
  664. result = failed(1); // 失败
  665. }
  666. else if(getTimerMs() > time) // 正在发送状态。判断超时
  667. {
  668. result = overtime(); // 超时
  669. }
  670. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  671. {
  672. result = success(); // 成功
  673. // 处理返回结果
  674. char * saveptr = NULL;
  675. char * split = "\r\n";
  676. // 第一行
  677. strtok_r((char * )AT_result(), split, &saveptr);
  678. // 第二行
  679. char * Line2 = strtok_r(NULL, split, &saveptr);
  680. // 拆解第二行
  681. char * saveptr_inner = NULL;
  682. char * split_inner = ": ,\"";
  683. strtok_r(Line2, split_inner, &saveptr_inner);
  684. * n = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  685. * stat = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  686. * lac = strtoul(strtok_r(NULL, split_inner, &saveptr_inner), NULL, 16);
  687. * ci = strtoul(strtok_r(NULL, split_inner, &saveptr_inner), NULL, 16);
  688. // 打印
  689. Log_Printf_Debug("mode: %d, stat: %d, lac: %d, ci: %d\r\n", * n, * stat, * lac, * ci);
  690. }
  691. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  692. {
  693. result = failed(2); // 失败
  694. }
  695. return result;
  696. }
  697. /**
  698. * 查询ps域网络注册状态
  699. * 输入<<
  700. *
  701. * 输出>>
  702. * n 控制指定URC的上报。0 禁止上报网络注册;1 允许上报网络注册;2 允许上报网络注册和位置信息
  703. * stat 网络注册状态。0 未注册;1 已注册,归属地网络; 2 未注册;3 注册被拒绝;4 未知;5 已注册,漫游。
  704. * lac 基站位置区号。用于基站定位,2个字节。
  705. * ci 基站小区ID。用于基站定位,4个字节。
  706. *
  707. **/
  708. enum Result ec800m_query_cgreg_sync(uint8_t * n, uint8_t * stat, uint16_t * lac, uint32_t * ci)
  709. {
  710. enum Result result = Result_None;
  711. while(1)
  712. {
  713. result = ec800m_query_cgreg(n, stat, lac, ci);
  714. if(result != Result_None)
  715. {
  716. // 重置
  717. ec800m.reset();
  718. break;
  719. }
  720. }
  721. return result;
  722. }
  723. /**
  724. * 查询socket服务状态
  725. * connectID Socket ID。范围1-11
  726. * state Socket服务状态。0 未连接;1 正在连接;2 已建立连接;3 服务正在监听;4 连接断开。
  727. *
  728. * activeID 9
  729. **/
  730. enum Result ec800m_query_socket_state(uint8_t connectID, uint8_t * state)
  731. {
  732. enum Result result = Result_None;
  733. int activeID = 9, time = 500; // 活动ID, 超时时间
  734. // 校验ID
  735. if(!verifyActiveID(activeID)){ return Result_Failed; }
  736. // 判断状态
  737. if(getStatus() == Status_None) // 空闲状态
  738. {
  739. sprintf(AT_CMD, "AT+QISTATE=1,%d\r\r\n", connectID); // 拼接AT指令
  740. result = send_at(AT_CMD, activeID);
  741. }
  742. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  743. {
  744. result = failed(1); // 失败
  745. }
  746. else if(getTimerMs() > time) // 正在发送状态。判断超时
  747. {
  748. result = overtime(); // 超时
  749. }
  750. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  751. {
  752. result = success(); // 成功
  753. // 处理返回结果
  754. char * saveptr = NULL;
  755. char * split = "\r\n";
  756. // 第一行
  757. strtok_r((char * )AT_result(), split, &saveptr);
  758. // 第二行
  759. char * Line2 = strtok_r(NULL, split, &saveptr);
  760. // 查询结果为空
  761. if(strcmp(Line2, "OK") == 0){ * state = 0; }
  762. else
  763. {
  764. // 拆解第二行
  765. char * saveptr_inner = NULL;
  766. char * split_inner = ": ,\"";
  767. strtok_r(Line2, split_inner, &saveptr_inner);
  768. strtok_r(NULL, split_inner, &saveptr_inner);
  769. strtok_r(NULL, split_inner, &saveptr_inner);
  770. strtok_r(NULL, split_inner, &saveptr_inner);
  771. strtok_r(NULL, split_inner, &saveptr_inner);
  772. strtok_r(NULL, split_inner, &saveptr_inner);
  773. * state = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  774. }
  775. // 打印
  776. Log_Printf_Debug("result: %d\r\n", * state);
  777. }
  778. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  779. {
  780. result = failed(2); // 失败
  781. }
  782. return result;
  783. }
  784. /**
  785. * 查询socket服务状态
  786. * connectID Socket ID。范围1-11
  787. * state Socket服务状态。0 未连接;1 正在连接;2 已建立连接;3 服务正在监听;4 连接断开。
  788. *
  789. * activeID 9
  790. **/
  791. enum Result ec800m_query_socket_state_sync(uint8_t connectID, uint8_t * state)
  792. {
  793. enum Result result = Result_None;
  794. while(1)
  795. {
  796. result = ec800m_query_socket_state(connectID, state);
  797. if(result != Result_None)
  798. {
  799. // 重置
  800. ec800m.reset();
  801. break;
  802. }
  803. }
  804. return result;
  805. }
  806. /**
  807. * 打开socket服务
  808. * 输入<<
  809. * connectID Socket ID。范围1-11
  810. * service_type Socket服务类型。取值为"UDP", "TCP"。
  811. * IP_address 远程服务器地址
  812. * remote_port 远程服务器端口
  813. * access_mode Socket服务的数据访问模式。0 缓存模式;1 直吐模式;2 透传模式。
  814. *
  815. * 输出>>
  816. * err 操作错误代码。0 表示没有错误;其余参考移远文档。
  817. *
  818. * activeID 19
  819. **/
  820. enum Result ec800m_open_socket(uint8_t connectID, char * service_type, char * IP_address, uint16_t remote_port, uint8_t access_mode, uint16_t * err)
  821. {
  822. enum Result result = Result_None;
  823. int activeID = 19, time = 3000; // 活动ID, 超时时间
  824. // 校验ID
  825. if(!verifyActiveID(activeID)){ return Result_Failed; }
  826. // 判断状态
  827. if(getStatus() == Status_None) // 空闲状态
  828. {
  829. sprintf(AT_CMD, "AT+QIOPEN=1,%d,\"%s\",\"%s\",%d,%d,%d\r\r\n", connectID, service_type, IP_address, remote_port, 0, access_mode); // 拼接AT指令
  830. result = send_at(AT_CMD, activeID);
  831. }
  832. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  833. {
  834. result = failed(1); // 失败
  835. }
  836. else if(getTimerMs() > time) // 正在发送状态。判断超时
  837. {
  838. result = overtime(); // 超时
  839. }
  840. else if(strstr((char * )AT_result(), "+QIOPEN: ") != NULL) // 查询是否返回
  841. {
  842. result = success(); // 成功
  843. // 处理返回结果
  844. char * saveptr = NULL;
  845. char * split = "\r\n";
  846. // 第一行
  847. strtok_r((char * )AT_result(), split, &saveptr);
  848. // 第二行
  849. char * Line2 = strtok_r(NULL, split, &saveptr);
  850. // 第三行
  851. char * Line3 = strtok_r(NULL, split, &saveptr);
  852. // 查询结果为空
  853. if(strcmp(Line2, "OK") == 0)
  854. {
  855. // 拆解第三行
  856. char * saveptr_inner = NULL;
  857. char * split_inner = ": ,\"";
  858. strtok_r(Line3, split_inner, &saveptr_inner);
  859. uint8_t connID = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  860. * err = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  861. Log_Printf_Debug("result: %d, %d\r\n", connID, * err);
  862. }
  863. }
  864. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  865. {
  866. result = failed(2); // 失败
  867. }
  868. return result;
  869. }
  870. /**
  871. * 打开socket服务
  872. * 输入<<
  873. * connectID Socket ID。范围1-11
  874. * service_type Socket服务类型。取值为"UDP", "TCP"。
  875. * IP_address 远程服务器地址
  876. * remote_port 远程服务器端口
  877. * access_mode Socket服务的数据访问模式。0 缓存模式;1 直吐模式;2 透传模式。
  878. *
  879. * 输出>>
  880. * err 操作错误代码。0 表示没有错误;其余参考移远文档。
  881. *
  882. * activeID 19
  883. **/
  884. enum Result ec800m_open_socket_sync(uint8_t connectID, char * service_type, char * IP_address, uint16_t remote_port, uint8_t access_mode, uint16_t * err)
  885. {
  886. enum Result result = Result_None;
  887. while(1)
  888. {
  889. result = ec800m_open_socket(connectID, service_type, IP_address, remote_port, access_mode, err);
  890. if(result != Result_None)
  891. {
  892. // 重置
  893. ec800m.reset();
  894. break;
  895. }
  896. }
  897. return result;
  898. }
  899. /**
  900. * 关闭socket服务
  901. * 输入<<
  902. * connectID Socket ID。范围1-11
  903. *
  904. * activeID 29
  905. **/
  906. enum Result ec800m_close_socket(uint8_t connectID)
  907. {
  908. enum Result result = Result_None;
  909. int activeID = 29, time = 500; // 活动ID, 超时时间
  910. // 校验ID
  911. if(!verifyActiveID(activeID)){ return Result_Failed; }
  912. // 判断状态
  913. if(getStatus() == Status_None) // 空闲状态
  914. {
  915. sprintf(AT_CMD, "AT+QICLOSE=%d\r\r\n", connectID); // 拼接AT指令
  916. result = send_at(AT_CMD, activeID);
  917. }
  918. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  919. {
  920. result = failed(1); // 失败
  921. }
  922. else if(getTimerMs() > time) // 正在发送状态。判断超时
  923. {
  924. result = overtime(); // 超时
  925. }
  926. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  927. {
  928. result = success(); // 成功
  929. }
  930. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  931. {
  932. result = failed(2); // 失败
  933. }
  934. return result;
  935. }
  936. /**
  937. * 关闭socket服务
  938. * 输入<<
  939. * connectID Socket ID。范围1-11
  940. *
  941. * activeID 29
  942. **/
  943. enum Result ec800m_close_socket_sync(uint8_t connectID)
  944. {
  945. enum Result result = Result_None;
  946. while(1)
  947. {
  948. result = ec800m_close_socket(connectID);
  949. if(result != Result_None)
  950. {
  951. // 重置
  952. ec800m.reset();
  953. break;
  954. }
  955. }
  956. return result;
  957. }
  958. /**
  959. * 解释:控制是否回显AT+QISEND要发送的数据
  960. * 为了便于处理返回,发送数据时需要关闭回显。
  961. * 输入<<
  962. * echo 是否回显AT+QISEND要发送的数据。0 不回显;1 回显。默认是回显
  963. *
  964. * activeID 45
  965. **/
  966. enum Result ec800m_set_qisde(uint8_t echo)
  967. {
  968. enum Result result = Result_None;
  969. int activeID = 45, time = 500; // 活动ID, 超时时间
  970. // 校验ID
  971. if(!verifyActiveID(activeID)){ return Result_Failed; }
  972. // 判断状态
  973. if(getStatus() == Status_None) // 空闲状态
  974. {
  975. sprintf(AT_CMD, "AT+QISDE=%d\r\r\n", echo); // 拼接AT指令
  976. result = send_at(AT_CMD, activeID);
  977. }
  978. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  979. {
  980. result = failed(1); // 失败
  981. }
  982. else if(getTimerMs() > time) // 正在发送状态。判断超时
  983. {
  984. result = overtime(); // 超时
  985. }
  986. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  987. {
  988. result = success(); // 成功
  989. }
  990. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  991. {
  992. result = failed(2); // 失败
  993. }
  994. return result;
  995. }
  996. /**
  997. * 解释:控制是否回显AT+QISEND要发送的数据
  998. * 为了便于处理返回,发送数据时需要关闭回显。
  999. * 输入<<
  1000. * echo 是否回显AT+QISEND要发送的数据。0 不回显;1 回显。默认是回显
  1001. *
  1002. * activeID 45
  1003. **/
  1004. enum Result ec800m_set_qisde_sync(uint8_t echo)
  1005. {
  1006. enum Result result = Result_None;
  1007. while(1)
  1008. {
  1009. result = ec800m_set_qisde(echo);
  1010. if(result != Result_None)
  1011. {
  1012. // 重置
  1013. ec800m.reset();
  1014. break;
  1015. }
  1016. }
  1017. return result;
  1018. }
  1019. /**
  1020. * 发送数据
  1021. * 输入<<
  1022. * connectID Socket ID。范围1-11。
  1023. * send_length 发送长度。
  1024. * data 待发送的数据。
  1025. *
  1026. * activeID 49
  1027. **/
  1028. enum Result ec800m_send(uint8_t connectID, uint8_t * data, uint16_t data_length)
  1029. {
  1030. enum Result result = Result_None;
  1031. int activeID = 49, time = 10000; // 活动ID, 超时时间
  1032. // 校验ID
  1033. if(!verifyActiveID(activeID)){ return Result_Failed; }
  1034. // 判断状态
  1035. if(getStatus() == Status_None) // 空闲状态
  1036. {
  1037. sprintf(AT_CMD, "AT+QISEND=%d,%d\r\r\n", connectID, data_length); // 拼接AT指令
  1038. result = send_at(AT_CMD, activeID);
  1039. }
  1040. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  1041. {
  1042. result = failed(1); // 失败
  1043. }
  1044. else if(getTimerMs() > time) // 正在发送状态。判断超时
  1045. {
  1046. result = overtime(); // 超时
  1047. }
  1048. else if(strstr((char * )AT_result(), "> ") != NULL) // 有响应
  1049. {
  1050. // 发送日志
  1051. Log_Printf_Debug("AT返回: %d\r\n", AT_result_length());
  1052. Log_SendArray_Debug(AT_result(), AT_result_length());
  1053. // Log_Printf_Debug("coap:\r\n");
  1054. // Log_SendHex(data, data_length);
  1055. // Log_Printf_Debug("\r\n");
  1056. // 发送数据
  1057. send_data(data, data_length);
  1058. // 清理一下AT返回结果缓存
  1059. AT_Clear_Result();
  1060. }
  1061. else if(strstr((char * )AT_result(), "SEND OK\r\n") != NULL) // 查询是否返回
  1062. {
  1063. result = success(); // 成功
  1064. }
  1065. else if(strstr((char * )AT_result(), "SEND FALL\r\n") != NULL) // 查询是否返回
  1066. {
  1067. result = failed(2); // 失败
  1068. }
  1069. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  1070. {
  1071. result = failed(2); // 失败
  1072. }
  1073. return result;
  1074. }
  1075. /**
  1076. * 发送数据
  1077. * 输入<<
  1078. * connectID Socket ID。范围1-11。
  1079. * send_length 发送长度。
  1080. * data 待发送的数据。
  1081. *
  1082. * activeID 49
  1083. **/
  1084. enum Result ec800m_send_sync(uint8_t connectID, uint8_t * data, uint16_t data_length)
  1085. {
  1086. enum Result result = Result_None;
  1087. while(1)
  1088. {
  1089. result = ec800m_send(connectID, data, data_length);
  1090. if(result != Result_None)
  1091. {
  1092. // 重置
  1093. ec800m.reset();
  1094. break;
  1095. }
  1096. }
  1097. return result;
  1098. }
  1099. /**
  1100. * 接收数据
  1101. * 输入<<
  1102. * connectID Socket ID。范围0-11。
  1103. *
  1104. * 输出>>
  1105. * data 接收的数据。
  1106. * data_length 接收的数据长度。
  1107. *
  1108. **/
  1109. enum Result ec800m_recv(uint8_t connectID, uint8_t * data, uint16_t * data_length)
  1110. {
  1111. // 设置AT为使用中,防止被其他程序占用
  1112. AT_Set_Status(AT_Status_Using);
  1113. enum Result result = Result_None;
  1114. // 校验参数
  1115. if(connectID > 11)
  1116. {
  1117. Log_Printf_Debug("recv params error!\r\n");
  1118. return Result_Failed;
  1119. }
  1120. char cmp[20];
  1121. sprintf(cmp, "+QIURC: \"recv\",%d", connectID); // 拼接AT指令
  1122. // 判断是否接收到
  1123. if(strstr((char * )AT_result(), cmp) != NULL)
  1124. {
  1125. // 防止接收不完整
  1126. uint32_t last_time = AT_wait_time();
  1127. if(last_time > 10) // 过10ms之后再取数据,避免数据截断。
  1128. {
  1129. // 发送日志
  1130. Log_Printf_Debug("AT返回: %d, time_diff: %d\r\n", AT_result_length(), last_time);
  1131. // Log_SendArray_Debug(AT_result(), AT_result_length());
  1132. char * saveptr = NULL;
  1133. char * split = "\r\n";
  1134. char * Line1 = strtok_r((char * )AT_result(), split, &saveptr);
  1135. uint8_t Line1_Len = strlen(Line1);
  1136. Log_Printf_Debug("Line1(%d): %s\r\n",Line1_Len ,Line1);
  1137. // 分割Line1,获取报文长度
  1138. char * saveptr_inner = NULL;
  1139. char * split_inner = ",";
  1140. strtok_r(Line1, split_inner, &saveptr_inner);
  1141. strtok_r(NULL, split_inner, &saveptr_inner);
  1142. * data_length = strtoul(strtok_r(NULL, split_inner, &saveptr_inner), NULL, 10);
  1143. uint16_t line_length = Line1_Len + 4;
  1144. // 内存拷贝
  1145. memcpy(data, AT_result() + line_length, * data_length);
  1146. // 成功
  1147. result = Result_Success;
  1148. // 清理一下AT返回结果缓存
  1149. AT_Clear_Result();
  1150. }
  1151. }
  1152. return result;
  1153. }
  1154. /**
  1155. * 接收数据。带计时
  1156. * 输入<<
  1157. * connectID Socket ID。范围0-11。
  1158. *
  1159. * 输出>>
  1160. * data 接收的数据。
  1161. * data_length 接收的数据长度。
  1162. *
  1163. **/
  1164. enum Result ec800m_recv_with_time(uint8_t connectID, uint8_t * data, uint16_t * data_length, uint32_t time_out)
  1165. {
  1166. enum Result result = Result_None;
  1167. int activeID = 59, time = time_out; // 活动ID, 超时时间
  1168. // 校验ID
  1169. if(!verifyActiveID(activeID)){ return Result_Failed; }
  1170. // 判断状态
  1171. if(getStatus() == Status_None) // 空闲状态
  1172. {
  1173. setStatus(Status_Sending);
  1174. }
  1175. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  1176. {
  1177. result = failed(1); // 失败
  1178. }
  1179. else if(getTimerMs() > time) // 正在发送状态。判断超时
  1180. {
  1181. result = overtime(); // 超时
  1182. }
  1183. else
  1184. {
  1185. // 接收数据
  1186. result = ec800m.recv(connectID, data, data_length);
  1187. if(result == Result_Success)
  1188. {
  1189. result = success_no_log(); // 成功
  1190. }
  1191. }
  1192. return result;
  1193. }
  1194. /**
  1195. * 接收数据。带计时
  1196. * 输入<<
  1197. * connectID Socket ID。范围0-11。
  1198. *
  1199. * 输出>>
  1200. * data 接收的数据。
  1201. * data_length 接收的数据长度。
  1202. *
  1203. **/
  1204. enum Result ec800m_recv_with_time_sync(uint8_t connectID, uint8_t * data, uint16_t * data_length, uint32_t time_out)
  1205. {
  1206. enum Result result = Result_None;
  1207. while(1)
  1208. {
  1209. result = ec800m_recv_with_time(connectID, data, data_length, time_out);
  1210. if(result != Result_None)
  1211. {
  1212. // 重置
  1213. ec800m.reset();
  1214. break;
  1215. }
  1216. }
  1217. return result;
  1218. }
  1219. /**
  1220. * 解释:关闭模块
  1221. * 关闭模块,关闭后会自动重启。
  1222. * 输入<<
  1223. * n 模块关机方式。0 立即关机;1 正常关机。默认是1
  1224. *
  1225. * activeID 69
  1226. **/
  1227. enum Result ec800m_power_down(uint8_t n)
  1228. {
  1229. enum Result result = Result_None;
  1230. int activeID = 69, time = 3000; // 活动ID, 超时时间
  1231. // 校验ID
  1232. if(!verifyActiveID(activeID)){ return Result_Failed; }
  1233. // 判断状态
  1234. if(getStatus() == Status_None) // 空闲状态
  1235. {
  1236. sprintf(AT_CMD, "AT+QPOWD=%d\r\r\n", n); // 拼接AT指令
  1237. result = send_at(AT_CMD, activeID);
  1238. }
  1239. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  1240. {
  1241. result = failed(1); // 失败
  1242. }
  1243. else if(getTimerMs() > time) // 正在发送状态。判断超时
  1244. {
  1245. result = overtime();
  1246. }
  1247. else if(strstr((char * )AT_result(), "POWERED DOWN\r\n") != NULL) // 查询是否返回
  1248. {
  1249. result = success();
  1250. }
  1251. return result;
  1252. }
  1253. /**
  1254. * 解释:关闭模块。同步
  1255. * 关闭模块,关闭后会自动重启。
  1256. * 输入<<
  1257. * n 模块关机方式。0 立即关机;1 正常关机。默认是1
  1258. *
  1259. * activeID 69
  1260. **/
  1261. enum Result ec800m_power_down_sync(uint8_t n)
  1262. {
  1263. enum Result result = Result_None;
  1264. while(1)
  1265. {
  1266. result = ec800m_power_down(n);
  1267. if(result != Result_None)
  1268. {
  1269. // 重置
  1270. ec800m.reset();
  1271. break;
  1272. }
  1273. }
  1274. return result;
  1275. }
  1276. /**
  1277. * 模块是否启动成功
  1278. * 输入<<
  1279. *
  1280. * 输出>>
  1281. *
  1282. **/
  1283. enum Result ec800m_ready(void)
  1284. {
  1285. if(AT_Get_Status() != AT_Status_None)
  1286. {
  1287. return Result_None;
  1288. }
  1289. enum Result result = Result_None;
  1290. // 判断是否接收到
  1291. uint8_t RDY[5]="RDY";
  1292. if(memmem(AT_result(),AT_result_length(),RDY,strlen((char *)RDY)) != 0)
  1293. {
  1294. uint32_t last_time = AT_wait_time();
  1295. if(last_time > 20) // 过10ms之后再取数据,避免数据截断。
  1296. {
  1297. // 发送日志
  1298. Log_Printf_Debug("AT返回: %d\r\n", AT_result_length());
  1299. Log_SendArray_Debug(AT_result(), AT_result_length());
  1300. // 成功结果
  1301. result = Result_Success;
  1302. // 清理一下AT返回结果缓存
  1303. AT_Clear_Result();
  1304. }
  1305. }
  1306. return result;
  1307. }
  1308. /**
  1309. * 查询信号质量
  1310. * 输入<<
  1311. *
  1312. * 输出>>
  1313. * RSRP
  1314. * RSRQ
  1315. * RSSI
  1316. * SINR
  1317. **/
  1318. enum Result ec800m_qeng_servingcell(int * RSRP, int * RSRQ, int * RSSI, int * SINR)
  1319. {
  1320. enum Result result = Result_None;
  1321. int activeID = 71, time = 500; // 活动ID, 超时时间
  1322. // 校验ID
  1323. if(!verifyActiveID(activeID)){ return Result_Failed; }
  1324. // 判断状态
  1325. if(getStatus() == Status_None) // 空闲状态
  1326. {
  1327. sprintf(AT_CMD, "AT+QENG=\"servingcell\"\r\r\n"); // 拼接AT指令
  1328. result = send_at(AT_CMD, activeID);
  1329. }
  1330. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  1331. {
  1332. result = failed(1); // 失败
  1333. }
  1334. else if(getTimerMs() > time) // 正在发送状态。判断超时
  1335. {
  1336. result = overtime(); // 超时
  1337. }
  1338. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  1339. {
  1340. result = success(); // 成功
  1341. // 处理返回结果
  1342. char * saveptr = NULL;
  1343. char * split = "\r\n";
  1344. // 第一行
  1345. strtok_r((char * )AT_result(), split, &saveptr);
  1346. // 第二行
  1347. char * Line2 = strtok_r(NULL, split, &saveptr);
  1348. // 拆解第二行
  1349. char * saveptr_inner = NULL;
  1350. char * split_inner = ": ,\"";
  1351. strtok_r(Line2, split_inner, &saveptr_inner);
  1352. strtok_r(NULL, split_inner, &saveptr_inner);
  1353. strtok_r(NULL, split_inner, &saveptr_inner);
  1354. strtok_r(NULL, split_inner, &saveptr_inner);
  1355. strtok_r(NULL, split_inner, &saveptr_inner);
  1356. strtok_r(NULL, split_inner, &saveptr_inner);
  1357. strtok_r(NULL, split_inner, &saveptr_inner);
  1358. strtok_r(NULL, split_inner, &saveptr_inner);
  1359. strtok_r(NULL, split_inner, &saveptr_inner);
  1360. strtok_r(NULL, split_inner, &saveptr_inner);
  1361. strtok_r(NULL, split_inner, &saveptr_inner);
  1362. strtok_r(NULL, split_inner, &saveptr_inner);
  1363. strtok_r(NULL, split_inner, &saveptr_inner);
  1364. strtok_r(NULL, split_inner, &saveptr_inner);
  1365. * RSRP = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  1366. * RSRQ = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  1367. * RSSI = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  1368. * SINR = atoi(strtok_r(NULL, split_inner, &saveptr_inner));
  1369. // 打印
  1370. Log_Printf_Debug("RSRP: %d, RSRQ: %d, RSSI: %d, SINR: %d\r\n", * RSRP, * RSRQ, * RSSI, * SINR);
  1371. }
  1372. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  1373. {
  1374. result = failed(2); // 失败
  1375. }
  1376. return result;
  1377. }
  1378. enum Result ec800m_qeng_servingcell_sync(int * RSRP, int * RSRQ, int * RSSI, int * SINR)
  1379. {
  1380. enum Result result = Result_None;
  1381. while(1)
  1382. {
  1383. result = ec800m_qeng_servingcell(RSRP, RSRQ, RSSI, SINR);
  1384. if(result != Result_None)
  1385. {
  1386. // 重置
  1387. ec800m.reset();
  1388. break;
  1389. }
  1390. }
  1391. return result;
  1392. }
  1393. /**
  1394. * 查询ICCID
  1395. * 输入<<
  1396. *
  1397. * 输出>>
  1398. * iccid SIM卡卡号
  1399. **/
  1400. enum Result ec800m_query_qccid(char * iccid)
  1401. {
  1402. enum Result result = Result_None;
  1403. int activeID = 75, time = 500; // 活动ID, 超时时间
  1404. // 校验ID
  1405. if(!verifyActiveID(activeID)){ return Result_Failed; }
  1406. // 判断状态
  1407. if(getStatus() == Status_None) // 空闲状态
  1408. {
  1409. sprintf(AT_CMD, "AT+QCCID\r\r\n"); // 拼接AT指令
  1410. result = send_at(AT_CMD, activeID);
  1411. }
  1412. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  1413. {
  1414. result = failed(1); // 失败
  1415. }
  1416. else if(getTimerMs() > time) // 正在发送状态。判断超时
  1417. {
  1418. result = overtime(); // 超时
  1419. }
  1420. else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  1421. {
  1422. result = success(); // 成功
  1423. // 处理返回结果
  1424. char * saveptr = NULL;
  1425. char * split = "\r\n";
  1426. // 第一行
  1427. char * Line1 = strtok_r((char * )AT_result(), split, &saveptr);
  1428. // 第二行
  1429. char * Line2 = strtok_r(NULL, split, &saveptr);
  1430. // 拆解第二行
  1431. char * saveptr_inner = NULL;
  1432. char * split_inner = ": ,\"";
  1433. strtok_r(Line2, split_inner, &saveptr_inner);
  1434. // 字符串拷贝
  1435. strcpy(iccid, strtok_r(NULL, split_inner, &saveptr_inner));
  1436. // 打印
  1437. Log_Printf_Debug("ICCID: %s\r\n", iccid);
  1438. }
  1439. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  1440. {
  1441. result = failed(2); // 失败
  1442. }
  1443. return result;
  1444. }
  1445. enum Result ec800m_query_qccid_sync(char * iccid)
  1446. {
  1447. enum Result result = Result_None;
  1448. while(1)
  1449. {
  1450. result = ec800m_query_qccid(iccid);
  1451. if(result != Result_None)
  1452. {
  1453. // 重置
  1454. ec800m.reset();
  1455. break;
  1456. }
  1457. }
  1458. return result;
  1459. }
  1460. #endif