at_socket_ec20.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-06-12 chenyong first version
  9. * 2018-08-12 Marcus port to ec20
  10. * 2019-05-13 chenyong multi AT socket client support
  11. */
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <at_device_ec20.h>
  15. #define LOG_TAG "at.skt.ec20"
  16. #include <at_log.h>
  17. #if defined(AT_DEVICE_USING_EC20) && defined(AT_USING_SOCKET)
  18. #define EC20_MODULE_SEND_MAX_SIZE 1460
  19. /* set real event by current socket and current state */
  20. #define SET_EVENT(socket, event) (((socket + 1) << 16) | (event))
  21. /* AT socket event type */
  22. #define EC20_EVENT_CONN_OK (1L << 0)
  23. #define EC20_EVENT_SEND_OK (1L << 1)
  24. #define EC20_EVENT_RECV_OK (1L << 2)
  25. #define EC20_EVNET_CLOSE_OK (1L << 3)
  26. #define EC20_EVENT_CONN_FAIL (1L << 4)
  27. #define EC20_EVENT_SEND_FAIL (1L << 5)
  28. #define EC20_EVENT_DOMAIN_OK (1L << 6)
  29. static at_evt_cb_t at_evt_cb_set[] = {
  30. [AT_SOCKET_EVT_RECV] = NULL,
  31. [AT_SOCKET_EVT_CLOSED] = NULL,
  32. };
  33. static void at_tcp_ip_errcode_parse(int result)//TCP/IP_QIGETERROR
  34. {
  35. switch(result)
  36. {
  37. case 0 : LOG_D("%d : Operation successful", result); break;
  38. case 550 : LOG_E("%d : Unknown error", result); break;
  39. case 551 : LOG_E("%d : Operation blocked", result); break;
  40. case 552 : LOG_E("%d : Invalid parameters", result); break;
  41. case 553 : LOG_E("%d : Memory not enough", result); break;
  42. case 554 : LOG_E("%d : Create socket failed", result); break;
  43. case 555 : LOG_E("%d : Operation not supported", result); break;
  44. case 556 : LOG_E("%d : Socket bind failed", result); break;
  45. case 557 : LOG_E("%d : Socket listen failed", result); break;
  46. case 558 : LOG_E("%d : Socket write failed", result); break;
  47. case 559 : LOG_E("%d : Socket read failed", result); break;
  48. case 560 : LOG_E("%d : Socket accept failed", result); break;
  49. case 561 : LOG_E("%d : Open PDP context failed", result); break;
  50. case 562 : LOG_E("%d : Close PDP context failed", result); break;
  51. case 563 : LOG_W("%d : Socket identity has been used", result); break;
  52. case 564 : LOG_E("%d : DNS busy", result); break;
  53. case 565 : LOG_E("%d : DNS parse failed", result); break;
  54. case 566 : LOG_E("%d : Socket connect failed", result); break;
  55. // case 567 : LOG_W("%d : Socket has been closed", result); break;
  56. case 567 : break;
  57. case 568 : LOG_E("%d : Operation busy", result); break;
  58. case 569 : LOG_E("%d : Operation timeout", result); break;
  59. case 570 : LOG_E("%d : PDP context broken down", result); break;
  60. case 571 : LOG_E("%d : Cancel send", result); break;
  61. case 572 : LOG_E("%d : Operation not allowed", result); break;
  62. case 573 : LOG_E("%d : APN not configured", result); break;
  63. case 574 : LOG_E("%d : Port busy", result); break;
  64. default : LOG_E("%d : Unknown err code", result); break;
  65. }
  66. }
  67. #ifdef EC20_USING_HTTP
  68. static void at_http_errcode_parse(int result)//HTTP
  69. {
  70. switch(result)
  71. {
  72. case 0 : LOG_D("%d : Operation successful", result); break;
  73. case 701 : LOG_E("%d : HTTP(S) unknown error", result); break;
  74. case 702 : LOG_E("%d : HTTP(S) timeout", result); break;
  75. case 703 : LOG_E("%d : HTTP(S) busy", result); break;
  76. case 704 : LOG_E("%d : HTTP(S) UART busy", result); break;
  77. case 705 : LOG_E("%d : HTTP(S) no GET/POST requests", result); break;
  78. case 706 : LOG_E("%d : HTTP(S) network busy", result); break;
  79. case 707 : LOG_E("%d : HTTP(S) network open failed", result); break;
  80. case 708 : LOG_E("%d : HTTP(S) network no configuration", result); break;
  81. case 709 : LOG_E("%d : HTTP(S) network deactivated", result); break;
  82. case 710 : LOG_E("%d : HTTP(S) network error", result); break;
  83. case 711 : LOG_E("%d : HTTP(S) URL error", result); break;
  84. case 712 : LOG_E("%d : HTTP(S) empty URL", result); break;
  85. case 713 : LOG_E("%d : HTTP(S) IP address error", result); break;
  86. case 714 : LOG_E("%d : HTTP(S) DNS error", result); break;
  87. case 715 : LOG_E("%d : HTTP(S) socket create error", result); break;
  88. case 716 : LOG_E("%d : HTTP(S) socket connect error", result); break;
  89. case 717 : LOG_E("%d : HTTP(S) socket read error", result); break;
  90. case 718 : LOG_E("%d : HTTP(S) socket write error", result); break;
  91. case 719 : LOG_E("%d : HTTP(S) socket closed", result); break;
  92. case 720 : LOG_E("%d : HTTP(S) data encode error", result); break;
  93. case 721 : LOG_E("%d : HTTP(S) data decode error", result); break;
  94. case 722 : LOG_E("%d : HTTP(S) read timeout", result); break;
  95. case 723 : LOG_E("%d : HTTP(S) response failed", result); break;
  96. case 724 : LOG_E("%d : Incoming call busy", result); break;
  97. case 725 : LOG_E("%d : Voice call busy", result); break;
  98. case 726 : LOG_E("%d : Input timeout", result); break;
  99. case 727 : LOG_E("%d : Wait data timeout", result); break;
  100. case 728 : LOG_E("%d : Wait HTTP(S) response timeout", result); break;
  101. case 729 : LOG_E("%d : Memory allocation failed", result); break;
  102. case 730 : LOG_E("%d : Invalid parameter", result); break;
  103. default : LOG_E("%d : Unknown err code", result); break;
  104. }
  105. }
  106. static void at_http_rsponsecode_parse(int result)//HTTP
  107. {
  108. switch(result)
  109. {
  110. case 200 : LOG_D("%d : OK", result); break;
  111. case 400 : LOG_E("%d : Bad request", result); break;
  112. case 403 : LOG_E("%d : Forbidden", result); break;
  113. case 404 : LOG_E("%d : Not found", result); break;
  114. case 409 : LOG_E("%d : Conflict", result); break;
  115. case 411 : LOG_E("%d : Length required", result); break;
  116. case 500 : LOG_E("%d : Internal server error", result); break;
  117. case 502 : LOG_E("%d : Bad gate way", result); break;
  118. default : LOG_E("%d : Unknown err code", result); break;
  119. }
  120. }
  121. #endif /* EC20_USING_HTTP */
  122. #ifdef EC20_USING_FTP
  123. static void at_ftp_errcode_parse(int result)//FTP
  124. {
  125. switch(result)
  126. {
  127. case 0 : LOG_D("%d : Operation successful", result); break;
  128. case 601 : LOG_E("%d : Unknown error", result); break;
  129. case 602 : LOG_E("%d : FTP(S) server blocked", result); break;
  130. case 603 : LOG_E("%d : FTP(S) server busy", result); break;
  131. case 604 : LOG_E("%d : DNS parse failed", result); break;
  132. case 605 : LOG_E("%d : Network error", result); break;
  133. case 606 : LOG_E("%d : Control connection closed.", result); break;
  134. case 607 : LOG_E("%d : Data connection closed", result); break;
  135. case 608 : LOG_E("%d : Socket closed by peer", result); break;
  136. case 609 : LOG_E("%d : Timeout error", result); break;
  137. case 610 : LOG_E("%d : Invalid parameter", result); break;
  138. case 611 : LOG_E("%d : Failed to open file", result); break;
  139. case 612 : LOG_E("%d : File position invalid", result); break;
  140. case 613 : LOG_E("%d : File error", result); break;
  141. case 614 : LOG_E("%d : Service not available, closing control connection", result); break;
  142. case 615 : LOG_E("%d : Open data connection failed", result); break;
  143. case 616 : LOG_E("%d : Connection closed; transfer aborted", result); break;
  144. case 617 : LOG_E("%d : Requested file action not taken", result); break;
  145. case 618 : LOG_E("%d : Requested action aborted: local error in processing", result); break;
  146. case 619 : LOG_E("%d : Requested action not taken: insufficient system storage", result); break;
  147. case 620 : LOG_E("%d : Syntax error, command unrecognized", result); break;
  148. case 621 : LOG_E("%d : Syntax error in parameters or arguments", result); break;
  149. case 622 : LOG_E("%d : Command not implemented", result); break;
  150. case 623 : LOG_E("%d : Bad sequence of commands", result); break;
  151. case 624 : LOG_E("%d : Command parameter not implemented", result); break;
  152. case 625 : LOG_E("%d : Not logged in", result); break;
  153. case 626 : LOG_E("%d : Need account for storing files", result); break;
  154. case 627 : LOG_E("%d : Requested action not taken", result); break;
  155. case 628 : LOG_E("%d : Requested action aborted: page type unknown", result); break;
  156. case 629 : LOG_E("%d : Requested file action aborted", result); break;
  157. case 630 : LOG_E("%d : Requested file name invalid", result); break;
  158. case 631 : LOG_E("%d : SSL authentication failed", result); break;
  159. default : LOG_E("%d : Unknown err code", result); break;
  160. }
  161. }
  162. static void at_ftp_protocol_errcode_parse(int result)//FTP_Protocol
  163. {
  164. switch(result)
  165. {
  166. case 421 : LOG_E("%d : Service not available, closing control connection", result); break;
  167. case 425 : LOG_E("%d : Open data connection failed", result); break;
  168. case 426 : LOG_E("%d : Connection closed; transfer aborted", result); break;
  169. case 450 : LOG_E("%d : Requested file action not taken", result); break;
  170. case 451 : LOG_E("%d : Requested action aborted: local error in processing", result); break;
  171. case 452 : LOG_E("%d : Requested action not taken: insufficient system storage", result); break;
  172. case 500 : LOG_E("%d : Syntax error, command unrecognized", result); break;
  173. case 501 : LOG_E("%d : Syntax error in parameters or arguments", result); break;
  174. case 502 : LOG_E("%d : Command not implemented", result); break;
  175. case 503 : LOG_E("%d : Bad sequence of commands", result); break;
  176. case 504 : LOG_E("%d : Command parameter not implemented", result); break;
  177. case 530 : LOG_E("%d : Not logged in", result); break;
  178. case 532 : LOG_E("%d : Need account for storing files", result); break;
  179. case 550 : LOG_E("%d : Requested action not taken: file unavailable", result); break;
  180. case 551 : LOG_E("%d : Requested action aborted: page type unknown", result); break;
  181. case 552 : LOG_E("%d : Requested file action aborted: exceeded storage allocation", result); break;
  182. case 553 : LOG_E("%d : Requested action not taken: file name not allowed", result); break;
  183. default : LOG_E("%d : Unknown err code", result); break;
  184. }
  185. }
  186. #endif /* EC20_USING_FTP */
  187. #ifdef EC20_USING_SMTP
  188. static void at_smtp_errcode_parse(int result)//Email
  189. {
  190. switch(result)
  191. {
  192. case 651 : LOG_E("%d : Unknown error", result); break;
  193. case 652 : LOG_E("%d : The SMTP server is busy, such as uploading the body or sending an email.", result); break;
  194. case 653 : LOG_E("%d : Failed to get IP address according to the domain name.", result); break;
  195. case 654 : LOG_E("%d : Network error, such as failed to activate GPRS/CSD context, failed to establish the TCP connection with the SMTP server or failed to send an email to the SMTP server, etc.", result); break;
  196. case 655 : LOG_E("%d : Unsupported authentication type", result); break;
  197. case 656 : LOG_E("%d : The connection for the SMTP server is closed by peer.", result); break;
  198. case 657 : LOG_E("%d : GPRS/CSD context is deactivated.", result); break;
  199. case 658 : LOG_E("%d : Timeout", result); break;
  200. case 659 : LOG_E("%d : No recipient for the SMTP server", result); break;
  201. case 660 : LOG_E("%d : Failed to send an email", result); break;
  202. case 661 : LOG_E("%d : Failed to open a file", result); break;
  203. case 662 : LOG_E("%d : No enough memory for the attachment", result); break;
  204. case 663 : LOG_E("%d : Failed to save the attachment", result); break;
  205. case 664 : LOG_E("%d : The input parameter is wrong", result); break;
  206. case 665 : LOG_E("%d : SSL authentication failed", result); break;
  207. case 666 : LOG_E("%d : Service not available, closing transmission channel", result); break;
  208. case 667 : LOG_E("%d : Requested mail action not taken: mailbox unavailable", result); break;
  209. case 668 : LOG_E("%d : Requested action aborted: local error in processing", result); break;
  210. case 669 : LOG_E("%d : Requested action not taken: insufficient system storage", result); break;
  211. case 670 : LOG_E("%d : Syntax error, command unrecognized", result); break;
  212. case 671 : LOG_E("%d : Syntax error in parameters or arguments", result); break;
  213. case 672 : LOG_E("%d : Command not implemented", result); break;
  214. case 673 : LOG_E("%d : Bad sequence of commands", result); break;
  215. case 674 : LOG_E("%d : Command parameter not implemented", result); break;
  216. case 675 : LOG_E("%d : <domain> does not accept mail (see RFC1846)", result); break;
  217. case 676 : LOG_E("%d : Access denied", result); break;
  218. case 677 : LOG_E("%d : Authentication failed", result); break;
  219. case 678 : LOG_E("%d : Requested action not taken: mailbox unavailable", result); break;
  220. case 679 : LOG_E("%d : User not local; please try <forward-path>", result); break;
  221. case 680 : LOG_E("%d : Requested mail action aborted: exceeded storage allocation", result); break;
  222. case 681 : LOG_E("%d : Requested action not taken: mailbox name not allowed", result); break;
  223. case 682 : LOG_E("%d : Transaction failed", result); break;
  224. default : LOG_E("%d : Unknown err code", result); break;
  225. }
  226. }
  227. static void at_smtp_protocol_errcode_parse(int result)//Email_Protocol
  228. {
  229. switch(result)
  230. {
  231. case 421 : LOG_E("%d : Service not available, closing transmission channel", result); break;
  232. case 450 : LOG_E("%d : Requested mail action not taken: mailbox unavailable", result); break;
  233. case 451 : LOG_E("%d : Requested action aborted: local error in processing", result); break;
  234. case 452 : LOG_E("%d : Requested action not taken: insufficient system storage", result); break;
  235. case 500 : LOG_E("%d : Syntax error, command unrecognized", result); break;
  236. case 501 : LOG_E("%d : Syntax error in parameters or arguments", result); break;
  237. case 502 : LOG_E("%d : Command not implemented", result); break;
  238. case 503 : LOG_E("%d : Bad sequence of commands", result); break;
  239. case 504 : LOG_E("%d : Command parameter not implemented", result); break;
  240. case 521 : LOG_E("%d : <domain> does not accept mail (see RFC1846)", result); break;
  241. case 530 : LOG_E("%d : Access denied", result); break;
  242. case 535 : LOG_E("%d : Authentication failed", result); break;
  243. case 550 : LOG_E("%d : Requested action not taken: mailbox unavailable", result); break;
  244. case 551 : LOG_E("%d : User not local; please try <forward-path>", result); break;
  245. case 552 : LOG_E("%d : Requested mail action aborted: exceeded storage allocation", result); break;
  246. case 553 : LOG_E("%d : Requested action not taken: mailbox name not allowed", result); break;
  247. case 554 : LOG_E("%d : Transaction failed", result); break;
  248. default : LOG_E("%d : Unknown err code", result); break;
  249. }
  250. }
  251. #endif /* EC20_USING_SMTP */
  252. static int ec20_socket_event_send(struct at_device *device, uint32_t event)
  253. {
  254. return (int) rt_event_send(device->socket_event, event);
  255. }
  256. static int ec20_socket_event_recv(struct at_device *device, uint32_t event, uint32_t timeout, rt_uint8_t option)
  257. {
  258. int result = RT_EOK;
  259. rt_uint32_t recved;
  260. result = rt_event_recv(device->socket_event, event, option | RT_EVENT_FLAG_CLEAR, timeout, &recved);
  261. if (result != RT_EOK)
  262. {
  263. return -RT_ETIMEOUT;
  264. }
  265. return recved;
  266. }
  267. /**
  268. * close socket by AT commands.
  269. *
  270. * @param current socket
  271. *
  272. * @return 0: close socket success
  273. * -1: send AT commands error
  274. * -2: wait socket event timeout
  275. * -5: no memory
  276. */
  277. static int ec20_socket_close(struct at_socket *socket)
  278. {
  279. int result = RT_EOK;
  280. at_response_t resp = RT_NULL;
  281. int device_socket = (int) socket->user_data;
  282. struct at_device *device = (struct at_device *) socket->device;
  283. resp = at_create_resp(64, 0, 5 * RT_TICK_PER_SECOND);
  284. if (resp == RT_NULL)
  285. {
  286. LOG_E("no memory for resp create.");
  287. return -RT_ENOMEM;
  288. }
  289. /* default connection timeout is 10 seconds, but it set to 1 seconds is convenient to use.*/
  290. result = at_obj_exec_cmd(device->client, resp, "AT+QICLOSE=%d,1", device_socket);
  291. if (resp)
  292. {
  293. at_delete_resp(resp);
  294. }
  295. return result;
  296. }
  297. /**
  298. * create TCP/UDP client or server connect by AT commands.
  299. *
  300. * @param socket current socket
  301. * @param ip server or client IP address
  302. * @param port server or client port
  303. * @param type connect socket type(tcp, udp)
  304. * @param is_client connection is client
  305. *
  306. * @return 0: connect success
  307. * -1: connect failed, send commands error or type error
  308. * -2: wait socket event timeout
  309. * -5: no memory
  310. */
  311. static int ec20_socket_connect(struct at_socket *socket, char *ip, int32_t port,
  312. enum at_socket_type type, rt_bool_t is_client)
  313. {
  314. uint32_t event = 0;
  315. rt_bool_t retryed = RT_FALSE;
  316. at_response_t resp = RT_NULL;
  317. int result = 0, event_result = 0;
  318. int device_socket = (int) socket->user_data;
  319. struct at_device *device = (struct at_device *) socket->device;
  320. RT_ASSERT(ip);
  321. RT_ASSERT(port >= 0);
  322. resp = at_create_resp(128, 0, 5 * RT_TICK_PER_SECOND);
  323. if (resp == RT_NULL)
  324. {
  325. LOG_E("no memory for resp create.");
  326. return -RT_ENOMEM;
  327. }
  328. __retry:
  329. /* clear socket connect event */
  330. event = SET_EVENT(device_socket, EC20_EVENT_CONN_OK | EC20_EVENT_CONN_FAIL);
  331. ec20_socket_event_recv(device, event, 0, RT_EVENT_FLAG_OR);
  332. if (is_client)
  333. {
  334. switch (type)
  335. {
  336. case AT_SOCKET_TCP:
  337. /* send AT commands(AT+QIOPEN=<contextID>,<socket>,"<TCP/UDP>","<IP_address>/<domain_name>", */
  338. /* <remote_port>,<local_port>,<access_mode>) to connect TCP server */
  339. /* contextID = 1 : use same contextID as AT+QICSGP & AT+QIACT */
  340. /* local_port = 0 : local port assigned automatically */
  341. /* access_mode = 1 : Direct push mode */
  342. if (at_obj_exec_cmd(device->client, resp,
  343. "AT+QIOPEN=1,%d,\"TCP\",\"%s\",%d,0,1", device_socket, ip, port) < 0)
  344. {
  345. result = -RT_ERROR;
  346. goto __exit;
  347. }
  348. break;
  349. case AT_SOCKET_UDP:
  350. if (at_obj_exec_cmd(device->client, resp,
  351. "AT+QIOPEN=1,%d,\"UDP\",\"%s\",%d,0,1", device_socket, ip, port) < 0)
  352. {
  353. result = -RT_ERROR;
  354. goto __exit;
  355. }
  356. break;
  357. default:
  358. LOG_E("not supported connect type : %d.", type);
  359. return -RT_ERROR;
  360. }
  361. }
  362. /* waiting result event from AT URC, the device default connection timeout is 75 seconds, but it set to 10 seconds is convenient to use.*/
  363. if (ec20_socket_event_recv(device, SET_EVENT(device_socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
  364. {
  365. LOG_E("%s device socket(%d) wait connect result timeout.", device->name, device_socket);
  366. result = -RT_ETIMEOUT;
  367. goto __exit;
  368. }
  369. /* waiting OK or failed result */
  370. event_result = ec20_socket_event_recv(device,
  371. EC20_EVENT_CONN_OK | EC20_EVENT_CONN_FAIL, 1 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR);
  372. if (event_result < 0)
  373. {
  374. LOG_E("%s device socket(%d) wait connect OK|FAIL timeout.", device->name, device_socket);
  375. result = -RT_ETIMEOUT;
  376. goto __exit;
  377. }
  378. /* check result */
  379. if (event_result & EC20_EVENT_CONN_FAIL)
  380. {
  381. if (retryed == RT_FALSE)
  382. {
  383. LOG_D("%s device socket(%d) connect failed, the socket was not be closed and now will connect retey.",
  384. device->name, device_socket);
  385. /* default connection timeout is 10 seconds, but it set to 1 seconds is convenient to use.*/
  386. if (ec20_socket_close(socket) < 0)
  387. {
  388. result = -RT_ERROR;
  389. goto __exit;
  390. }
  391. retryed = RT_TRUE;
  392. goto __retry;
  393. }
  394. LOG_E("%s device socket(%d) connect failed.", device->name, device_socket);
  395. result = -RT_ERROR;
  396. goto __exit;
  397. }
  398. __exit:
  399. if (resp)
  400. {
  401. at_delete_resp(resp);
  402. }
  403. return result;
  404. }
  405. static int at_get_send_size(struct at_socket *socket, size_t *size, size_t *acked, size_t *nacked)
  406. {
  407. int result = 0;
  408. at_response_t resp = RT_NULL;
  409. int device_socket = (int) socket->user_data;
  410. struct at_device *device = (struct at_device *) socket->device;
  411. resp = at_create_resp(128, 0, 5 * RT_TICK_PER_SECOND);
  412. if (resp == RT_NULL)
  413. {
  414. LOG_E("no memory for resp create.", device->name);
  415. result = -RT_ENOMEM;
  416. goto __exit;
  417. }
  418. if (at_obj_exec_cmd(device->client, resp, "AT+QISEND=%d,0", device_socket) < 0)
  419. {
  420. result = -RT_ERROR;
  421. goto __exit;
  422. }
  423. if (at_resp_parse_line_args_by_kw(resp, "+QISEND:", "+QISEND: %d,%d,%d", size, acked, nacked) <= 0)
  424. {
  425. result = -RT_ERROR;
  426. goto __exit;
  427. }
  428. __exit:
  429. if (resp)
  430. {
  431. at_delete_resp(resp);
  432. }
  433. return result;
  434. }
  435. static int at_wait_send_finish(struct at_socket *socket, size_t settings_size)
  436. {
  437. /* get the timeout by the input data size */
  438. rt_tick_t timeout = rt_tick_from_millisecond(settings_size);
  439. rt_tick_t last_time = rt_tick_get();
  440. size_t size = 0, acked = 0, nacked = 0xFFFF;
  441. while (rt_tick_get() - last_time <= timeout)
  442. {
  443. at_get_send_size(socket, &size, &acked, &nacked);
  444. if (nacked == 0)
  445. {
  446. return RT_EOK;
  447. }
  448. rt_thread_mdelay(50);
  449. }
  450. return -RT_ETIMEOUT;
  451. }
  452. /**
  453. * send data to server or client by AT commands.
  454. *
  455. * @param socket current socket
  456. * @param buff send buffer
  457. * @param bfsz send buffer size
  458. * @param type connect socket type(tcp, udp)
  459. *
  460. * @return >=0: the size of send success
  461. * -1: send AT commands error or send data error
  462. * -2: waited socket event timeout
  463. * -5: no memory
  464. */
  465. static int ec20_socket_send(struct at_socket *socket, const char *buff, size_t bfsz, enum at_socket_type type)
  466. {
  467. uint32_t event = 0;
  468. int result = 0, event_result = 0;
  469. size_t cur_pkt_size = 0, sent_size = 0;
  470. at_response_t resp = RT_NULL;
  471. int device_socket = (int) socket->user_data;
  472. struct at_device *device = (struct at_device *) socket->device;
  473. struct at_device_ec20 *ec20 = (struct at_device_ec20 *) device->user_data;
  474. rt_mutex_t lock = at_device_get_client_lock(device);
  475. RT_ASSERT(buff);
  476. resp = at_create_resp(128, 2, 5 * RT_TICK_PER_SECOND);
  477. if (resp == RT_NULL)
  478. {
  479. LOG_E("no memory for resp create.");
  480. return -RT_ENOMEM;
  481. }
  482. rt_mutex_take(lock, RT_WAITING_FOREVER);
  483. /* set current socket for send URC event */
  484. ec20->user_data = (void *) device_socket;
  485. /* clear socket send event */
  486. event = SET_EVENT(device_socket, EC20_EVENT_SEND_OK | EC20_EVENT_SEND_FAIL);
  487. ec20_socket_event_recv(device, event, 0, RT_EVENT_FLAG_OR);
  488. /* set AT client end sign to deal with '>' sign.*/
  489. at_obj_set_end_sign(device->client, '>');
  490. while (sent_size < bfsz)
  491. {
  492. if (bfsz - sent_size < EC20_MODULE_SEND_MAX_SIZE)
  493. {
  494. cur_pkt_size = bfsz - sent_size;
  495. }
  496. else
  497. {
  498. cur_pkt_size = EC20_MODULE_SEND_MAX_SIZE;
  499. }
  500. /* send the "AT+QISEND" commands to AT server than receive the '>' response on the first line. */
  501. if (at_obj_exec_cmd(device->client, resp, "AT+QISEND=%d,%d", device_socket, cur_pkt_size) < 0)
  502. {
  503. result = -RT_ERROR;
  504. goto __exit;
  505. }
  506. /* send the real data to server or client */
  507. result = (int) at_client_send(buff + sent_size, cur_pkt_size);
  508. if (result == 0)
  509. {
  510. result = -RT_ERROR;
  511. goto __exit;
  512. }
  513. /* waiting result event from AT URC */
  514. if (ec20_socket_event_recv(device, SET_EVENT(device_socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
  515. {
  516. result = -RT_ETIMEOUT;
  517. goto __exit;
  518. }
  519. /* waiting OK or failed result */
  520. event_result = ec20_socket_event_recv(device,
  521. EC20_EVENT_SEND_OK | EC20_EVENT_SEND_FAIL, 1 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR);
  522. if (event_result < 0)
  523. {
  524. LOG_E("%s device socket(%d) wait sned OK|FAIL timeout.", device->name, device_socket);
  525. result = -RT_ETIMEOUT;
  526. goto __exit;
  527. }
  528. /* check result */
  529. if (event_result & EC20_EVENT_SEND_FAIL)
  530. {
  531. LOG_E("%s device socket(%d) send failed.", device->name, device_socket);
  532. result = -RT_ERROR;
  533. goto __exit;
  534. }
  535. if (type == AT_SOCKET_TCP)
  536. {
  537. // at_wait_send_finish(socket, cur_pkt_size);
  538. rt_thread_mdelay(10);
  539. }
  540. sent_size += cur_pkt_size;
  541. }
  542. __exit:
  543. /* reset the end sign for data conflict */
  544. at_obj_set_end_sign(device->client, 0);
  545. rt_mutex_release(lock);
  546. if (resp)
  547. {
  548. at_delete_resp(resp);
  549. }
  550. return result > 0 ? sent_size : result;
  551. }
  552. /**
  553. * domain resolve by AT commands.
  554. *
  555. * @param name domain name
  556. * @param ip parsed IP address, it's length must be 16
  557. *
  558. * @return 0: domain resolve success
  559. * -1: send AT commands error or response error
  560. * -2: wait socket event timeout
  561. * -5: no memory
  562. */
  563. static int ec20_domain_resolve(const char *name, char ip[16])
  564. {
  565. #define RESOLVE_RETRY 3
  566. int i, result;
  567. at_response_t resp = RT_NULL;
  568. struct at_device *device = RT_NULL;
  569. RT_ASSERT(name);
  570. RT_ASSERT(ip);
  571. device = at_device_get_first_initialized();
  572. if (device == RT_NULL)
  573. {
  574. LOG_E("get first init device failed.");
  575. return -RT_ERROR;
  576. }
  577. /* the maximum response time is 60 seconds, but it set to 10 seconds is convenient to use. */
  578. resp = at_create_resp(128, 0, 10 * RT_TICK_PER_SECOND);
  579. if (!resp)
  580. {
  581. LOG_E("no memory for resp create.");
  582. return -RT_ENOMEM;
  583. }
  584. /* clear EC20_EVENT_DOMAIN_OK */
  585. ec20_socket_event_recv(device, EC20_EVENT_DOMAIN_OK, 0, RT_EVENT_FLAG_OR);
  586. result = at_obj_exec_cmd(device->client, resp, "AT+QIDNSGIP=1,\"%s\"", name);
  587. if (result < 0)
  588. {
  589. goto __exit;
  590. }
  591. if (result == RT_EOK)
  592. {
  593. for(i = 0; i < RESOLVE_RETRY; i++)
  594. {
  595. /* waiting result event from AT URC, the device default connection timeout is 60 seconds.*/
  596. if (ec20_socket_event_recv(device, EC20_EVENT_DOMAIN_OK, 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
  597. {
  598. continue;
  599. }
  600. else
  601. {
  602. struct at_device_ec20 *ec20 = (struct at_device_ec20 *) device->user_data;
  603. char *recv_ip = (char *) ec20->socket_data;
  604. if (rt_strlen(recv_ip) < 8)
  605. {
  606. rt_thread_mdelay(100);
  607. /* resolve failed, maybe receive an URC CRLF */
  608. result = -RT_ERROR;
  609. continue;
  610. }
  611. else
  612. {
  613. rt_strncpy(ip, recv_ip, 15);
  614. ip[15] = '\0';
  615. result = RT_EOK;
  616. break;
  617. }
  618. }
  619. }
  620. /* response timeout */
  621. if (i == RESOLVE_RETRY)
  622. {
  623. result = -RT_ENOMEM;
  624. }
  625. }
  626. __exit:
  627. if (resp)
  628. {
  629. at_delete_resp(resp);
  630. }
  631. return result;
  632. }
  633. /**
  634. * set AT socket event notice callback
  635. *
  636. * @param event notice event
  637. * @param cb notice callback
  638. */
  639. static void ec20_socket_set_event_cb(at_socket_evt_t event, at_evt_cb_t cb)
  640. {
  641. if (event < sizeof(at_evt_cb_set) / sizeof(at_evt_cb_set[1]))
  642. {
  643. at_evt_cb_set[event] = cb;
  644. }
  645. }
  646. static void urc_connect_func(struct at_client *client, const char *data, rt_size_t size)
  647. {
  648. int device_socket = 0, result = 0;
  649. struct at_device *device = RT_NULL;
  650. char *client_name = client->device->parent.name;
  651. RT_ASSERT(data && size);
  652. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_CLIENT, client_name);
  653. if (device == RT_NULL)
  654. {
  655. LOG_E("get device(%s) failed.", client_name);
  656. return;
  657. }
  658. rt_sscanf(data, "+QIOPEN: %d,%d", &device_socket , &result);
  659. if (result == 0)
  660. {
  661. ec20_socket_event_send(device, SET_EVENT(device_socket, EC20_EVENT_CONN_OK));
  662. }
  663. else
  664. {
  665. at_tcp_ip_errcode_parse(result);
  666. ec20_socket_event_send(device, SET_EVENT(device_socket, EC20_EVENT_CONN_FAIL));
  667. }
  668. }
  669. static void urc_send_func(struct at_client *client, const char *data, rt_size_t size)
  670. {
  671. int device_socket = 0;
  672. struct at_device *device = RT_NULL;
  673. struct at_device_ec20 *ec20 = RT_NULL;
  674. char *client_name = client->device->parent.name;
  675. RT_ASSERT(data && size);
  676. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_CLIENT, client_name);
  677. if (device == RT_NULL)
  678. {
  679. LOG_E("get device(%s) failed.", client_name);
  680. return;
  681. }
  682. ec20 = (struct at_device_ec20 *) device->user_data;
  683. device_socket = (int) ec20->user_data;
  684. if (rt_strstr(data, "SEND OK"))
  685. {
  686. ec20_socket_event_send(device, SET_EVENT(device_socket, EC20_EVENT_SEND_OK));
  687. }
  688. else if (rt_strstr(data, "SEND FAIL"))
  689. {
  690. ec20_socket_event_send(device, SET_EVENT(device_socket, EC20_EVENT_SEND_FAIL));
  691. }
  692. }
  693. static void urc_close_func(struct at_client *client, const char *data, rt_size_t size)
  694. {
  695. int device_socket = 0;
  696. struct at_socket *socket = RT_NULL;
  697. struct at_device *device = RT_NULL;
  698. char *client_name = client->device->parent.name;
  699. RT_ASSERT(data && size);
  700. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_CLIENT, client_name);
  701. if (device == RT_NULL)
  702. {
  703. LOG_E("get device(%s) failed.", client_name);
  704. return;
  705. }
  706. rt_sscanf(data, "+QIURC: \"closed\",%d", &device_socket);
  707. /* get at socket object by device socket descriptor */
  708. socket = &(device->sockets[device_socket]);
  709. /* notice the socket is disconnect by remote */
  710. if (at_evt_cb_set[AT_SOCKET_EVT_CLOSED])
  711. {
  712. at_evt_cb_set[AT_SOCKET_EVT_CLOSED](socket, AT_SOCKET_EVT_CLOSED, NULL, 0);
  713. }
  714. }
  715. static void urc_recv_func(struct at_client *client, const char *data, rt_size_t size)
  716. {
  717. int device_socket = 0;
  718. rt_int32_t timeout;
  719. rt_size_t bfsz = 0, temp_size = 0;
  720. char *recv_buf = RT_NULL, temp[8] = {0};
  721. struct at_socket *socket = RT_NULL;
  722. struct at_device *device = RT_NULL;
  723. char *client_name = client->device->parent.name;
  724. RT_ASSERT(data && size);
  725. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_CLIENT, client_name);
  726. if (device == RT_NULL)
  727. {
  728. LOG_E("get device(%s) failed.", client_name);
  729. return;
  730. }
  731. /* get the current socket and receive buffer size by receive data */
  732. rt_sscanf(data, "+QIURC: \"recv\",%d,%d", &device_socket, (int *) &bfsz);
  733. /* set receive timeout by receive buffer length, not less than 10 ms */
  734. timeout = bfsz > 10 ? bfsz : 10;
  735. if (device_socket < 0 || bfsz == 0)
  736. {
  737. return;
  738. }
  739. recv_buf = (char *) rt_calloc(1, bfsz);
  740. if (recv_buf == RT_NULL)
  741. {
  742. LOG_E("no memory for URC receive buffer(%d).", bfsz);
  743. /* read and clean the coming data */
  744. while (temp_size < bfsz)
  745. {
  746. if (bfsz - temp_size > sizeof(temp))
  747. {
  748. at_client_obj_recv(client, temp, sizeof(temp), timeout);
  749. }
  750. else
  751. {
  752. at_client_obj_recv(client, temp, bfsz - temp_size, timeout);
  753. }
  754. temp_size += sizeof(temp);
  755. }
  756. return;
  757. }
  758. /* sync receive data */
  759. if (at_client_obj_recv(client, recv_buf, bfsz, timeout) != bfsz)
  760. {
  761. LOG_E("%s device receive size(%d) data failed.", device->name, bfsz);
  762. rt_free(recv_buf);
  763. return;
  764. }
  765. /* get at socket object by device socket descriptor */
  766. socket = &(device->sockets[device_socket]);
  767. /* notice the receive buffer and buffer size */
  768. if (at_evt_cb_set[AT_SOCKET_EVT_RECV])
  769. {
  770. at_evt_cb_set[AT_SOCKET_EVT_RECV](socket, AT_SOCKET_EVT_RECV, recv_buf, bfsz);
  771. }
  772. }
  773. static void urc_pdpdeact_func(struct at_client *client, const char *data, rt_size_t size)
  774. {
  775. int connectID = 0;
  776. RT_ASSERT(data && size);
  777. rt_sscanf(data, "+QIURC: \"pdpdeact\",%d", &connectID);
  778. LOG_E("context (%d) is deactivated.", connectID);
  779. }
  780. static void urc_dnsqip_func(struct at_client *client, const char *data, rt_size_t size)
  781. {
  782. int i = 0, j = 0;
  783. char recv_ip[16] = {0};
  784. int result, ip_count, dns_ttl;
  785. struct at_device *device = RT_NULL;
  786. struct at_device_ec20 *ec20 = RT_NULL;
  787. char *client_name = client->device->parent.name;
  788. RT_ASSERT(data && size);
  789. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_CLIENT, client_name);
  790. if (device == RT_NULL)
  791. {
  792. LOG_E("get device(%s) failed.", client_name);
  793. return;
  794. }
  795. ec20 = (struct at_device_ec20 *) device->user_data;
  796. for (i = 0; i < size; i++)
  797. {
  798. if (*(data + i) == '.')
  799. j++;
  800. }
  801. /* There would be several dns result, we just pickup one */
  802. if (j == 3)
  803. {
  804. rt_sscanf(data, "+QIURC: \"dnsgip\",\"%[^\"]", recv_ip);
  805. recv_ip[15] = '\0';
  806. /* set ec20 information socket data */
  807. if (ec20->socket_data == RT_NULL)
  808. {
  809. ec20->socket_data = rt_calloc(1, sizeof(recv_ip));
  810. if (ec20->socket_data == RT_NULL)
  811. {
  812. return;
  813. }
  814. }
  815. rt_memcpy(ec20->socket_data, recv_ip, sizeof(recv_ip));
  816. ec20_socket_event_send(device, EC20_EVENT_DOMAIN_OK);
  817. }
  818. else
  819. {
  820. rt_sscanf(data, "+QIURC: \"dnsgip\",%d,%d,%d", &result, &ip_count, &dns_ttl);
  821. if (result)
  822. {
  823. at_tcp_ip_errcode_parse(result);
  824. }
  825. }
  826. }
  827. static void urc_func(struct at_client *client, const char *data, rt_size_t size)
  828. {
  829. RT_ASSERT(data);
  830. LOG_I("URC data : %.*s", size, data);
  831. }
  832. static void urc_qiurc_func(struct at_client *client, const char *data, rt_size_t size)
  833. {
  834. RT_ASSERT(data && size);
  835. switch(*(data + 9))
  836. {
  837. case 'c' : urc_close_func(client, data, size); break;//+QIURC: "closed"
  838. case 'r' : urc_recv_func(client, data, size); break;//+QIURC: "recv"
  839. case 'p' : urc_pdpdeact_func(client, data, size); break;//+QIURC: "pdpdeact"
  840. case 'd' : urc_dnsqip_func(client, data, size); break;//+QIURC: "dnsgip"
  841. default : urc_func(client, data, size); break;
  842. }
  843. }
  844. static const struct at_urc urc_table[] =
  845. {
  846. {"SEND OK", "\r\n", urc_send_func},
  847. {"SEND FAIL", "\r\n", urc_send_func},
  848. {"+QIOPEN:", "\r\n", urc_connect_func},
  849. {"+QIURC:", "\r\n", urc_qiurc_func},
  850. };
  851. static const struct at_socket_ops ec20_socket_ops =
  852. {
  853. ec20_socket_connect,
  854. ec20_socket_close,
  855. ec20_socket_send,
  856. ec20_domain_resolve,
  857. ec20_socket_set_event_cb,
  858. #if defined(AT_SW_VERSION_NUM) && AT_SW_VERSION_NUM > 0x10300
  859. RT_NULL,
  860. #endif
  861. };
  862. int ec20_socket_init(struct at_device *device)
  863. {
  864. RT_ASSERT(device);
  865. /* register URC data execution function */
  866. at_obj_set_urc_table(device->client, urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
  867. return RT_EOK;
  868. }
  869. int ec20_socket_class_register(struct at_device_class *class)
  870. {
  871. RT_ASSERT(class);
  872. class->socket_num = AT_DEVICE_EC20_SOCKETS_NUM;
  873. class->socket_ops = &ec20_socket_ops;
  874. return RT_EOK;
  875. }
  876. #endif /* AT_DEVICE_USING_EC20 && AT_USING_SOCKET */