bc260.c 43 KB

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