bc260.c 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788
  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 "AT.h"
  23. #include "bc260.h"
  24. #include "sys.h"
  25. #if NBFLAG
  26. // 方法声明
  27. void bc260y_reset(void); // 重置状态。该文件中的方法共用状态,在使用下面的方法前需要重置一下状态。
  28. enum Result bc260y_exit_sleep(void); // 退出休眠
  29. enum Result bc260y_exit_sleep_sync(void); // 退出休眠
  30. void bc260y_enter_sleep(void); // 进入休眠
  31. /**
  32. * 查询休眠模式
  33. * 输入<<
  34. *
  35. * 输出>>
  36. * n 睡眠模式。0 禁用,默认;1 启用。
  37. **/
  38. enum Result bc260y_query_sleep(uint8_t * n); // 查询休眠模式。
  39. enum Result bc260y_query_sleep_sync(uint8_t * n); // 查询休眠模式。同步
  40. /**
  41. * 设置休眠模式
  42. * 输入<<
  43. * n 参数。0 禁用;1启用。
  44. * 输出>>
  45. *
  46. **/
  47. enum Result bc260y_set_sleep(uint8_t n); // 设置休眠模式。
  48. enum Result bc260y_set_sleep_sync(uint8_t n); // 设置休眠模式。同步
  49. /**
  50. * 设置功能模式
  51. * 输入<<
  52. * fun 0 最小功能模式;1 全功能模式。
  53. * 输出>>
  54. *
  55. **/
  56. enum Result bc260y_set_cfun(uint8_t fun);
  57. enum Result bc260y_set_cfun_sync(uint8_t fun); // 同步
  58. /**
  59. * 设置ps域网络注册状态
  60. * 输入<<
  61. * n 0 禁止上报网络注册;1 允许上报网络注册;2 允许上报网络注册和位置信息
  62. * 输出>>
  63. *
  64. **/
  65. enum Result bc260y_set_cgreg(uint8_t n);
  66. enum Result bc260y_set_cgreg_sync(uint8_t n); // 同步
  67. /**
  68. * 查询ps域网络注册状态
  69. * 输入<<
  70. *
  71. * 输出>>
  72. * n 控制指定URC的上报。0 禁止上报网络注册;1 允许上报网络注册;2 允许上报网络注册和位置信息
  73. * stat 网络注册状态。0 未注册;1 已注册,归属地网络; 2 未注册;3 注册被拒绝;4 未知;5 已注册,漫游。
  74. * lac 基站位置区号。用于基站定位,2个字节。
  75. * ci 基站小区ID。用于基站定位,4个字节。
  76. *
  77. **/
  78. enum Result bc260y_query_cgreg(uint8_t * n, uint8_t * stat, uint16_t * lac, uint32_t * ci);
  79. enum Result bc260y_query_cgreg_sync(uint8_t * n, uint8_t * stat, uint16_t * lac, uint32_t * ci); // 同步
  80. /**
  81. * 查询socket服务状态
  82. * 输入<<
  83. * connectID Socket ID。范围1-11
  84. *
  85. * 输出>>
  86. * state Socket服务状态。0 未连接;1 正在连接;2 已建立连接;3 服务正在监听;4 连接断开。
  87. *
  88. *
  89. **/
  90. enum Result bc260y_query_socket_state(uint8_t connectID, uint8_t * state);
  91. enum Result bc260y_query_socket_state_sync(uint8_t connectID, uint8_t * state); // 同步
  92. /**
  93. * 打开socket服务
  94. * 输入<<
  95. * connectID Socket ID。范围1-11
  96. * service_type Socket服务类型。取值为"UDP", "TCP"。
  97. * IP_address 远程服务器地址
  98. * remote_port 远程服务器端口
  99. * access_mode Socket服务的数据访问模式。0 缓存模式;1 直吐模式;2 透传模式。
  100. *
  101. * 输出>>
  102. * err 操作错误代码。0 表示没有错误;其余参考移远文档。
  103. *
  104. **/
  105. 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);
  106. 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); // 同步
  107. /**
  108. * 关闭socket服务
  109. * 输入<<
  110. * connectID Socket ID。范围1-11
  111. *
  112. * 输出>>
  113. *
  114. **/
  115. enum Result bc260y_close_socket(uint8_t connectID);
  116. enum Result bc260y_close_socket_sync(uint8_t connectID); // 同步
  117. /**
  118. * 解释:控制是否回显AT+QISEND要发送的数据
  119. * 为了便于处理返回,发送数据时需要关闭回显。
  120. * 输入<<
  121. * echo 是否回显AT+QISEND要发送的数据。0 不回显;1 回显。默认是回显
  122. *
  123. * 输出>>
  124. *
  125. **/
  126. enum Result bc260y_set_qisde(uint8_t echo);
  127. enum Result bc260y_set_qisde_sync(uint8_t echo); // 同步
  128. /**
  129. * 发送数据
  130. * 输入<<
  131. * connectID Socket ID。范围1-11。
  132. * send_length 发送长度。
  133. * data 待发送的数据。
  134. *
  135. *
  136. **/
  137. enum Result bc260y_send(uint8_t connectID, uint8_t * data, uint16_t data_length);
  138. enum Result bc260y_send_sync(uint8_t connectID, uint8_t * data, uint16_t data_length); // 同步
  139. /**
  140. * 接收数据
  141. * 输入<<
  142. * connectID Socket ID。范围0-11。
  143. *
  144. * 输出>>
  145. * data 接收的数据。
  146. * data_length 接收的数据长度。
  147. **/
  148. enum Result bc260y_recv(uint8_t connectID, uint8_t * data, uint16_t * data_length); // 接收数据
  149. /**
  150. * 接收数据。带计时
  151. * 输入<<
  152. * connectID Socket ID。范围0-11。
  153. *
  154. * 输出>>
  155. * data 接收的数据。
  156. * data_length 接收的数据长度。
  157. *
  158. **/
  159. enum Result bc260y_recv_with_time(uint8_t connectID, uint8_t * data, uint16_t * data_length, uint32_t time_out);
  160. enum Result bc260y_recv_with_time_sync(uint8_t connectID, uint8_t * data, uint16_t * data_length, uint32_t time_out); // 同步
  161. /**
  162. * 解释:关闭模块
  163. * 关闭模块,关闭后会自动重启。
  164. * 输入<<
  165. * n 模块关机方式。0 立即关机;1 正常关机。默认是1
  166. *
  167. *
  168. **/
  169. enum Result bc260y_power_down(uint8_t n);
  170. enum Result bc260y_power_down_sync(uint8_t n); // 同步
  171. /**
  172. * 模块是否启动成功
  173. * 输入<<
  174. *
  175. * 输出>>
  176. *
  177. **/
  178. enum Result bc260y_ready(void);
  179. /**
  180. * 查询信号质量
  181. * 输入<<
  182. *
  183. * 输出>>
  184. * RSRP
  185. * RSRQ
  186. * RSSI
  187. * SINR
  188. **/
  189. enum Result bc260y_qeng_servingcell(int * RSRP, int * RSRQ, int * RSSI, int * SINR);
  190. enum Result bc260y_qeng_servingcell_sync(int * RSRP, int * RSRQ, int * RSSI, int * SINR);
  191. /**
  192. * 查询ICCID
  193. * 输入<<
  194. *
  195. * 输出>>
  196. * iccid SIM卡卡号
  197. **/
  198. enum Result bc260y_query_qccid(char * iccid);
  199. enum Result bc260y_query_qccid_sync(char * iccid);
  200. /**
  201. * 配置发送数据格式
  202. * 输入<<
  203. *n 0数据格式为文本字符串,1为十六进制字符串
  204. *
  205. **/
  206. enum Result bc260y_dataformat(uint8_t n);
  207. enum Result bc260y_dataformat_sync(uint8_t n);
  208. //
  209. extern struct AT_Struct AT;
  210. // AT指令
  211. static char AT_CMD[256];
  212. // EC800M提供的一些方法
  213. struct BC260Y bc260y =
  214. {
  215. .reset = bc260y_reset,
  216. .exit_sleep = bc260y_exit_sleep,
  217. .exit_sleep_sync = bc260y_exit_sleep_sync,
  218. .enter_sleep = bc260y_enter_sleep,
  219. .query_sleep = bc260y_query_sleep,
  220. .query_sleep_sync = bc260y_query_sleep_sync,
  221. .set_sleep = bc260y_set_sleep,
  222. .set_sleep_sync = bc260y_set_sleep_sync,
  223. .set_cfun = bc260y_set_cfun,
  224. .set_cfun_sync = bc260y_set_cfun_sync,
  225. .set_cgreg = bc260y_set_cgreg,
  226. .set_cgreg_sync = bc260y_set_cgreg_sync,
  227. .query_cgreg = bc260y_query_cgreg,
  228. .query_cgreg_sync = bc260y_query_cgreg_sync,
  229. .query_socket_state = bc260y_query_socket_state,
  230. .query_socket_state_sync = bc260y_query_socket_state_sync,
  231. .open_socket = bc260y_open_socket,
  232. .open_socket_sync = bc260y_open_socket_sync,
  233. .close_socket = bc260y_close_socket,
  234. .close_socket_sync = bc260y_close_socket_sync,
  235. .set_qisde = bc260y_set_qisde,
  236. .set_qisde_sync = bc260y_set_qisde_sync,
  237. .send = bc260y_send,
  238. .send_sync = bc260y_send_sync,
  239. .recv = bc260y_recv,
  240. .recv_with_time = bc260y_recv_with_time,
  241. .recv_with_time_sync = bc260y_recv_with_time_sync,
  242. .power_down = bc260y_power_down,
  243. .power_down_sync = bc260y_power_down_sync,
  244. .ready = bc260y_ready,
  245. .qeng_servingcell = bc260y_qeng_servingcell,
  246. .qeng_servingcell_sync = bc260y_qeng_servingcell_sync,
  247. .query_qccid = bc260y_query_qccid,
  248. .query_qccid_sync = bc260y_query_qccid_sync,
  249. .dataformat= bc260y_dataformat,
  250. .dataformat_sync= bc260y_dataformat_sync
  251. };
  252. // 发送AT指令
  253. //static void send_data(uint8_t * data, uint16_t length)
  254. //{
  255. // // 发送AT指令
  256. // AT_Send_Bytes(data, length);
  257. //}
  258. // 发送AT指令
  259. static uint8_t send_at_string(char * cmd)
  260. {
  261. uint8_t state = 0;
  262. if(AT.status == AT_Status_None)
  263. {
  264. // 发送AT指令
  265. AT_Send_String(cmd);
  266. state = 1;
  267. }
  268. return state;
  269. }
  270. // 获取状态
  271. static enum STATUS getStatus(void)
  272. {
  273. return bc260y.status;
  274. }
  275. // 设置状态
  276. static void setStatus(enum STATUS status)
  277. {
  278. bc260y.status = status;
  279. }
  280. // 获取定时
  281. static uint32_t getTimerMs(void)
  282. {
  283. return bc260y.timer_ms;
  284. }
  285. // 设置定时
  286. static void setTimerMs(uint32_t time)
  287. {
  288. bc260y.timer_ms = time;
  289. }
  290. // 获取ID
  291. static uint8_t getActiveID(void)
  292. {
  293. return bc260y.activeID;
  294. }
  295. static void setActiveID(uint8_t activeID)
  296. {
  297. bc260y.activeID = activeID;
  298. }
  299. // 验证ID
  300. static uint8_t verifyActiveID(uint8_t activeID)
  301. {
  302. if(getActiveID() == 0 || getActiveID() == activeID){ return 1; }
  303. else
  304. {
  305. Log_Printf_Debug("activeID repetition!\r\n");
  306. return 0;
  307. }
  308. }
  309. // 返回超时结果
  310. static enum Result overtime(void)
  311. {
  312. setStatus(Status_Overtime); // 超时
  313. return Result_Failed; // 结果
  314. }
  315. // 返回成功结果
  316. static enum Result success(void)
  317. {
  318. // 成功
  319. setStatus(Status_Success);
  320. // 结果
  321. return Result_Success;
  322. }
  323. // 返回失败结果
  324. static enum Result failed(void)
  325. {
  326. // 失败
  327. setStatus(Status_Failed);
  328. // 失败结果
  329. return Result_Failed;
  330. }
  331. // 重置状态。该文件中的方法共用状态,在使用方法前需要重置一下状态。
  332. void bc260y_reset(void)
  333. {
  334. setStatus(Status_None); // 重置状态
  335. setActiveID(0); // 重置ID
  336. setTimerMs(0); // 重置计时
  337. AT_Clear(); // 清除AT指令
  338. }
  339. // 发送指令并改变状态
  340. enum Result send_at(char * cmd, uint8_t activeID)
  341. {
  342. Log_Printf_Debug(cmd); // 打印AT指令
  343. if(send_at_string(cmd)) // 发送AT指令
  344. {
  345. setActiveID(activeID); // 活动ID
  346. setStatus(Status_Sending); // 设置已发送
  347. setTimerMs(0); // 重置计时
  348. return Result_None; // 未知结果
  349. }
  350. else
  351. {
  352. Log_Printf_Debug("AT指令发送失败\r\n"); // 打印日志
  353. return Result_Failed; // 失败结果
  354. }
  355. }
  356. // 退出休眠
  357. enum Result bc260y_exit_sleep(void)
  358. {
  359. //GPIO_SetBits(WAKE_GPIO, WAKE_GPIO_Pin);// nb拉高io口,唤醒模组
  360. enum Result result = Result_None;
  361. int activeID = 1, time = 500; // 活动ID, 超时时间
  362. if(!verifyActiveID(activeID)){ return Result_Failed; } // 校验ID
  363. // 判断状态
  364. if(getStatus() == Status_None) // 空闲状态
  365. {
  366. sprintf(AT_CMD, "AT\r\r\n"); // 拼接AT指令
  367. result = send_at(AT_CMD, activeID);
  368. }
  369. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  370. {
  371. Log_Printf_Debug("返回结果过期1,请重置状态\r\n"); // 打印日志
  372. result = failed(); // 失败
  373. }
  374. else if(getTimerMs() > time) // 正在发送状态。判断超时
  375. {
  376. Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志
  377. Log_SendArray_Debug(AT_result(), AT_result_length());
  378. result = overtime(); // 超时
  379. }
  380. if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回
  381. {
  382. // 发送日志
  383. Log_Printf_Debug("AT返回: %d\r\n", AT_result_length());
  384. Log_SendArray_Debug(AT_result(), AT_result_length());
  385. result = success(); // 成功
  386. }
  387. else if(strstr((char * )AT_result(), "+QNBIOTEVENT:") != NULL)
  388. {
  389. // 发送日志
  390. Log_Printf_Debug("AT返回: %d\r\n", AT_result_length());
  391. Log_SendArray_Debug(AT_result(), AT_result_length());
  392. result = success(); // 成功
  393. }
  394. else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回
  395. {
  396. // 发送日志
  397. Log_Printf_Debug("AT返回: %d\r\n", AT_result_length());
  398. Log_SendArray_Debug(AT_result(), AT_result_length());
  399. result = failed(); // 失败
  400. }
  401. return result;
  402. }
  403. enum Result bc260y_exit_sleep_sync()
  404. {
  405. enum Result result = Result_None;
  406. while(1)
  407. {
  408. result = bc260y_exit_sleep();
  409. if(result != Result_None)
  410. {
  411. // 重置
  412. bc260y.reset();
  413. break;
  414. }
  415. }
  416. return result;
  417. }
  418. // 进入休眠
  419. void bc260y_enter_sleep(void)
  420. {
  421. GPIO_ResetBits(WAKE_GPIO, WAKE_GPIO_Pin); // nb拉低io口,进入睡眠
  422. }
  423. /**
  424. * 查询休眠模式
  425. * 输入<<
  426. *
  427. * 输出>>
  428. * n 睡眠模式。0 禁用,默认;1 启用。
  429. *
  430. **/
  431. enum Result bc260y_query_sleep(uint8_t * n)
  432. {
  433. enum Result result = Result_None;
  434. int activeID = 1, time = 500; // 活动ID, 超时时间
  435. if(!verifyActiveID(activeID)){ return Result_Failed; } // 校验ID
  436. // 判断状态
  437. if(getStatus() == Status_None) // 空闲状态
  438. {
  439. sprintf(AT_CMD, "AT+QSCLK?\r\r\n"); // 拼接AT指令
  440. result = send_at(AT_CMD, activeID);
  441. }
  442. else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用
  443. {
  444. Log_Printf_Debug("返回结果过期1,请重置状态\r\n"); // 打印日志
  445. result = failed(); // 失败
  446. }
  447. else if(getTimerMs() > time) // 正在发送状态。判断超时
  448. {
  449. Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志
  450. result = overtime(); // 超时
  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. #else
  1653. #endif