ec800m.c 40 KB

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