at_socket_ec20.c 37 KB

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