at_socket_ec20.c 36 KB

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