ec800m.c 39 KB

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