at_socket_me3616.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  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. * 2019-12-30 qiyongzhong first version
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <at_device_me3616.h>
  13. #define LOG_TAG "at.skt.me3616"
  14. #include <at_log.h>
  15. #if defined(AT_DEVICE_USING_ME3616) && defined(AT_USING_SOCKET)
  16. #define ME3616_MODULE_SEND_MAX_SIZE 512
  17. static int me3616_socket_fd[AT_DEVICE_ME3616_SOCKETS_NUM] = {0};
  18. static at_evt_cb_t at_evt_cb_set[] = {
  19. [AT_SOCKET_EVT_RECV] = NULL,
  20. [AT_SOCKET_EVT_CLOSED] = NULL,
  21. };
  22. static int me3616_get_socket_idx(int sock)
  23. {
  24. int i;
  25. if (sock < 0)
  26. {
  27. return(-1);
  28. }
  29. for (i=0; i<AT_DEVICE_ME3616_SOCKETS_NUM; i++)
  30. {
  31. if (me3616_socket_fd[i] == sock)
  32. return(i);
  33. }
  34. return(-1);
  35. }
  36. /**
  37. * close socket by AT commands.
  38. *
  39. * @param current socket
  40. *
  41. * @return 0: close socket success
  42. * -1: send AT commands error
  43. * -2: wait socket event timeout
  44. * -5: no memory
  45. */
  46. static int me3616_socket_close(struct at_socket *socket)
  47. {
  48. int result = RT_EOK;
  49. at_response_t resp = RT_NULL;
  50. int device_socket = (int) socket->user_data;
  51. struct at_device *device = (struct at_device *) socket->device;
  52. if (me3616_socket_fd[device_socket] == -1)
  53. {
  54. return RT_EOK;
  55. }
  56. resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
  57. if (resp == RT_NULL)
  58. {
  59. LOG_E("no memory for resp create.");
  60. return -RT_ENOMEM;
  61. }
  62. result = at_obj_exec_cmd(device->client, resp, "AT+ESOCL=%d", me3616_socket_fd[device_socket]);
  63. me3616_socket_fd[device_socket] = -1;
  64. at_delete_resp(resp);
  65. return result;
  66. }
  67. /**
  68. * create TCP/UDP client or server connect by AT commands.
  69. *
  70. * @param socket current socket
  71. * @param ip server or client IP address
  72. * @param port server or client port
  73. * @param type connect socket type(tcp, udp)
  74. * @param is_client connection is client
  75. *
  76. * @return 0: connect success
  77. * -1: connect failed, send commands error or type error
  78. * -2: wait socket event timeout
  79. * -5: no memory
  80. */
  81. static int me3616_socket_connect(struct at_socket *socket, char *ip, int32_t port,
  82. enum at_socket_type type, rt_bool_t is_client)
  83. {
  84. #define CONN_RESP_SIZE 128
  85. int type_code = 0;
  86. int result = RT_EOK;
  87. at_response_t resp = RT_NULL;
  88. int device_socket = (int) socket->user_data;
  89. struct at_device *device = (struct at_device *) socket->device;
  90. int sock = -1;
  91. RT_ASSERT(ip);
  92. RT_ASSERT(port >= 0);
  93. if ( ! is_client)
  94. {
  95. return -RT_ERROR;
  96. }
  97. switch(type)
  98. {
  99. case AT_SOCKET_TCP:
  100. type_code = 1;
  101. break;
  102. case AT_SOCKET_UDP:
  103. type_code = 2;
  104. break;
  105. default:
  106. LOG_E("%s device socket(%d) connect type error.", device->name, device_socket);
  107. return -RT_ERROR;
  108. }
  109. resp = at_create_resp(CONN_RESP_SIZE, 0, rt_tick_from_millisecond(300));
  110. if (resp == RT_NULL)
  111. {
  112. LOG_E("no memory for resp create.");
  113. return -RT_ENOMEM;
  114. }
  115. if (me3616_socket_fd[device_socket] != -1)
  116. {
  117. at_obj_exec_cmd(device->client, resp, "AT+ESOCL=%d", me3616_socket_fd[device_socket]);
  118. me3616_socket_fd[device_socket] = -1;
  119. }
  120. if (at_obj_exec_cmd(device->client, resp, "AT+ESOC=1,%d,1", type_code) < 0)
  121. {
  122. result = -RT_ERROR;
  123. goto __exit;
  124. }
  125. if (at_resp_parse_line_args_by_kw(resp, "+ESOC=", "+ESOC=%d", &sock) <= 0)
  126. {
  127. result = -RT_ERROR;
  128. goto __exit;
  129. }
  130. at_resp_set_info(resp, CONN_RESP_SIZE, 0, (45*RT_TICK_PER_SECOND));
  131. if (at_obj_exec_cmd(device->client, resp, "AT+ESOCON=%d,%d,\"%s\"", sock, port, ip) < 0)
  132. {
  133. at_resp_set_info(resp, CONN_RESP_SIZE, 0, rt_tick_from_millisecond(300));
  134. at_obj_exec_cmd(device->client, resp, "AT+ESOCL=%d", sock);
  135. result = -RT_ERROR;
  136. goto __exit;
  137. }
  138. me3616_socket_fd[device_socket] = sock;
  139. __exit:
  140. if (resp)
  141. {
  142. at_delete_resp(resp);
  143. }
  144. return result;
  145. }
  146. static int at_get_send_size(struct at_socket *socket, size_t *nacked)
  147. {
  148. int result = 0;
  149. at_response_t resp = RT_NULL;
  150. int device_socket = (int) socket->user_data;
  151. struct at_device *device = (struct at_device *) socket->device;
  152. int remain_size;
  153. resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
  154. if (resp == RT_NULL)
  155. {
  156. LOG_E("no memory for resp create.", device->name);
  157. return -RT_ENOMEM;
  158. }
  159. if (at_obj_exec_cmd(device->client, resp, "AT+ESOTCPBUF=%d", me3616_socket_fd[device_socket]) < 0)
  160. {
  161. result = -RT_ERROR;
  162. goto __exit;
  163. }
  164. if (at_resp_parse_line_args_by_kw(resp, "+ESOTCPBUF=", "+ESOTCPBUF=%d", &remain_size) <= 0)
  165. {
  166. result = -RT_ERROR;
  167. goto __exit;
  168. }
  169. *nacked = 4096 - remain_size;
  170. __exit:
  171. if (resp)
  172. {
  173. at_delete_resp(resp);
  174. }
  175. return result;
  176. }
  177. static int at_wait_send_finish(struct at_socket *socket, rt_tick_t timeout)
  178. {
  179. rt_tick_t last_time = rt_tick_get();
  180. size_t nacked = 0xFFFF;
  181. while (rt_tick_get() - last_time <= timeout)
  182. {
  183. at_get_send_size(socket, &nacked);
  184. if (nacked == 0)
  185. {
  186. return RT_EOK;
  187. }
  188. rt_thread_mdelay(50);
  189. }
  190. return -RT_ETIMEOUT;
  191. }
  192. /**
  193. * send data to server or client by AT commands.
  194. *
  195. * @param socket current socket
  196. * @param buff send buffer
  197. * @param bfsz send buffer size
  198. * @param type connect socket type(tcp, udp)
  199. *
  200. * @return >=0: the size of send success
  201. * -1: send AT commands error or send data error
  202. * -2: waited socket event timeout
  203. * -5: no memory
  204. */
  205. static int me3616_socket_send(struct at_socket *socket, const char *buff, size_t bfsz, enum at_socket_type type)
  206. {
  207. #define SEND_RESP_SIZE 128
  208. int result = 0;
  209. size_t cur_pkt_size = 0, sent_size = 0;
  210. at_response_t resp = RT_NULL;
  211. int device_socket = (int) socket->user_data;
  212. struct at_device *device = (struct at_device *) socket->device;
  213. rt_mutex_t lock = at_device_get_client_lock(device);
  214. RT_ASSERT(buff);
  215. resp = at_create_resp(SEND_RESP_SIZE, 2, RT_TICK_PER_SECOND/2);
  216. if (resp == RT_NULL)
  217. {
  218. LOG_E("no memory for resp create.");
  219. return -RT_ENOMEM;
  220. }
  221. rt_mutex_take(lock, RT_WAITING_FOREVER);
  222. while (sent_size < bfsz)
  223. {
  224. if (bfsz - sent_size < ME3616_MODULE_SEND_MAX_SIZE)
  225. {
  226. cur_pkt_size = bfsz - sent_size;
  227. }
  228. else
  229. {
  230. cur_pkt_size = ME3616_MODULE_SEND_MAX_SIZE;
  231. }
  232. at_resp_set_info(resp, SEND_RESP_SIZE, 2, RT_TICK_PER_SECOND/2);
  233. if (at_obj_exec_cmd(device->client, resp, "AT+ESOSENDRAW=%d,%d", me3616_socket_fd[device_socket], (int)cur_pkt_size) < 0)
  234. {
  235. result = -RT_ERROR;
  236. goto __exit;
  237. }
  238. if (at_resp_get_line_by_kw(resp, "CONNECT") == RT_NULL)
  239. {
  240. result = -RT_ERROR;
  241. goto __exit;
  242. }
  243. rt_thread_mdelay(5);//delay at least 4 ms
  244. /* send the real data to server or client */
  245. result = (int) at_client_obj_send(device->client, buff + sent_size, cur_pkt_size);
  246. if (result == 0)
  247. {
  248. result = -RT_ERROR;
  249. goto __exit;
  250. }
  251. /* wait respone "NO CARRIER ... OK " */
  252. at_resp_set_info(resp, SEND_RESP_SIZE, 0, (2*RT_TICK_PER_SECOND));
  253. if (at_obj_exec_cmd(device->client, resp, "") < 0)
  254. {
  255. result = -RT_ERROR;
  256. goto __exit;
  257. }
  258. if (type == AT_SOCKET_TCP)
  259. {
  260. at_wait_send_finish(socket, (5*RT_TICK_PER_SECOND));
  261. }
  262. else
  263. {
  264. rt_thread_mdelay(10);//delay at least 10 ms
  265. }
  266. sent_size += cur_pkt_size;
  267. }
  268. __exit:
  269. rt_mutex_release(lock);
  270. if (resp)
  271. {
  272. at_delete_resp(resp);
  273. }
  274. return result > 0 ? sent_size : result;
  275. }
  276. /**
  277. * domain resolve by AT commands.
  278. *
  279. * @param name domain name
  280. * @param ip parsed IP address, it's length must be 16
  281. *
  282. * @return 0: domain resolve success
  283. * -1: send AT commands error or response error
  284. * -2: wait socket event timeout
  285. * -5: no memory
  286. */
  287. static int me3616_domain_resolve(const char *name, char ip[16])
  288. {
  289. int result;
  290. at_response_t resp = RT_NULL;
  291. struct at_device *device = RT_NULL;
  292. RT_ASSERT(name);
  293. RT_ASSERT(ip);
  294. device = at_device_get_first_initialized();
  295. if (device == RT_NULL)
  296. {
  297. LOG_E("get first init device failed.");
  298. return -RT_ERROR;
  299. }
  300. resp = at_create_resp(128, 0, (15 * RT_TICK_PER_SECOND));
  301. if (!resp)
  302. {
  303. LOG_E("no memory for resp create.");
  304. return -RT_ENOMEM;
  305. }
  306. result = at_obj_exec_cmd(device->client, resp, "AT+EDNS=\"%s\"", name);
  307. if (result != RT_EOK)
  308. {
  309. LOG_E("%s device \"AT+EDNS=\"%s\"\" cmd error.", device->name, name);
  310. goto __exit;
  311. }
  312. if (at_resp_parse_line_args_by_kw(resp, "IPV4:", "IPV4:%s\r", ip) <= 0)
  313. {
  314. LOG_E("%s device prase \"AT+EDNS=\"%s\"\" cmd error.", device->name, name);
  315. result = -RT_ERROR;
  316. goto __exit;
  317. }
  318. ip[15] = 0;
  319. if (rt_strlen(ip) < 8)
  320. {
  321. result = -RT_ERROR;
  322. }
  323. else
  324. {
  325. result = RT_EOK;
  326. }
  327. __exit:
  328. if (resp)
  329. {
  330. at_delete_resp(resp);
  331. }
  332. return result;
  333. }
  334. /**
  335. * set AT socket event notice callback
  336. *
  337. * @param event notice event
  338. * @param cb notice callback
  339. */
  340. static void me3616_socket_set_event_cb(at_socket_evt_t event, at_evt_cb_t cb)
  341. {
  342. if (event < sizeof(at_evt_cb_set) / sizeof(at_evt_cb_set[1]))
  343. {
  344. at_evt_cb_set[event] = cb;
  345. }
  346. }
  347. static void urc_close_func(struct at_client *client, const char *data, rt_size_t size)
  348. {
  349. int sock = -1;
  350. int err_code = 0;
  351. int device_socket = 0;
  352. struct at_socket *socket = RT_NULL;
  353. struct at_device *device = RT_NULL;
  354. char *client_name = client->device->parent.name;
  355. RT_ASSERT(data && size);
  356. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_CLIENT, client_name);
  357. if (device == RT_NULL)
  358. {
  359. LOG_E("get device(%s) failed.", client_name);
  360. return;
  361. }
  362. rt_sscanf(data, "+ESOERR=%d,%d", &sock, &err_code);
  363. device_socket = me3616_get_socket_idx(sock);
  364. if (device_socket < 0 || err_code < 0 || err_code > 4)
  365. {
  366. return;
  367. }
  368. /* get at socket object by device socket descriptor */
  369. socket = &(device->sockets[device_socket]);
  370. /* notice the socket is disconnect by remote */
  371. if (at_evt_cb_set[AT_SOCKET_EVT_CLOSED])
  372. {
  373. at_evt_cb_set[AT_SOCKET_EVT_CLOSED](socket, AT_SOCKET_EVT_CLOSED, NULL, 0);
  374. }
  375. }
  376. static void urc_recv_func(struct at_client *client, const char *data, rt_size_t size)
  377. {
  378. int sock = -1;
  379. int device_socket = 0;
  380. rt_int32_t timeout;
  381. rt_size_t bfsz = 0, temp_size = 0;
  382. char *recv_buf = RT_NULL, temp[8] = {0};
  383. struct at_socket *socket = RT_NULL;
  384. struct at_device *device = RT_NULL;
  385. char *client_name = client->device->parent.name;
  386. RT_ASSERT(data && size);
  387. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_CLIENT, client_name);
  388. if (device == RT_NULL)
  389. {
  390. LOG_E("get device(%s) failed.", client_name);
  391. return;
  392. }
  393. rt_sscanf(data, "+ESONMI=%d,", &sock);
  394. device_socket = me3616_get_socket_idx(sock);
  395. if (device_socket < 0)
  396. {
  397. return;
  398. }
  399. while(temp_size < sizeof(temp))
  400. {
  401. at_client_obj_recv(client, temp+temp_size, 1, 10);
  402. if ( *(temp+temp_size) == ',')
  403. {
  404. *(temp+temp_size) = 0;
  405. break;
  406. }
  407. temp_size++;
  408. }
  409. if (temp_size == sizeof(temp))
  410. {
  411. return;
  412. }
  413. rt_sscanf(temp, "%d", (int *)&bfsz);
  414. if(bfsz == 0)
  415. {
  416. return;
  417. }
  418. timeout = bfsz > 10 ? bfsz : 10;
  419. recv_buf = (char *) rt_calloc(1, bfsz);
  420. if (recv_buf == RT_NULL)
  421. {
  422. LOG_E("no memory for URC receive buffer(%d).", bfsz);
  423. /* read and clean the coming data */
  424. temp_size = 0;
  425. while (temp_size < bfsz)
  426. {
  427. if (bfsz - temp_size > sizeof(temp))
  428. {
  429. at_client_obj_recv(client, temp, sizeof(temp), timeout);
  430. }
  431. else
  432. {
  433. at_client_obj_recv(client, temp, bfsz - temp_size, timeout);
  434. }
  435. temp_size += sizeof(temp);
  436. }
  437. return;
  438. }
  439. if (at_client_obj_recv(client, recv_buf, bfsz, timeout) != bfsz)
  440. {
  441. LOG_E("%s device receive size(%d) data failed.", device->name, bfsz);
  442. rt_free(recv_buf);
  443. return;
  444. }
  445. /* read end "\r\n" */
  446. at_client_obj_recv(client, temp, 2, 5);
  447. /* get at socket object by device socket descriptor */
  448. socket = &(device->sockets[device_socket]);
  449. /* notice the receive buffer and buffer size */
  450. if (at_evt_cb_set[AT_SOCKET_EVT_RECV])
  451. {
  452. at_evt_cb_set[AT_SOCKET_EVT_RECV](socket, AT_SOCKET_EVT_RECV, recv_buf, bfsz);
  453. }
  454. }
  455. static const struct at_urc urc_table[] =
  456. {
  457. {"+ESOERR=", "\r\n", urc_close_func},
  458. {"+ESONMI=", ",", urc_recv_func},
  459. };
  460. static const struct at_socket_ops me3616_socket_ops =
  461. {
  462. me3616_socket_connect,
  463. me3616_socket_close,
  464. me3616_socket_send,
  465. me3616_domain_resolve,
  466. me3616_socket_set_event_cb,
  467. #if defined(AT_SW_VERSION_NUM) && AT_SW_VERSION_NUM > 0x10300
  468. RT_NULL,
  469. #endif
  470. };
  471. int me3616_socket_init(struct at_device *device)
  472. {
  473. RT_ASSERT(device);
  474. rt_memset(me3616_socket_fd, -1, sizeof(me3616_socket_fd));
  475. /* register URC data execution function */
  476. at_obj_set_urc_table(device->client, urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
  477. return RT_EOK;
  478. }
  479. int me3616_socket_class_register(struct at_device_class *class)
  480. {
  481. RT_ASSERT(class);
  482. class->socket_num = AT_DEVICE_ME3616_SOCKETS_NUM;
  483. class->socket_ops = &me3616_socket_ops;
  484. return RT_EOK;
  485. }
  486. #endif /* AT_DEVICE_USING_ME3616 && AT_USING_SOCKET */