rtlink_port_tcp.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-7-13 songchao the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtlink_port.h>
  12. #include <string.h>
  13. #if !defined(SAL_USING_POSIX)
  14. #error "Please enable SAL_USING_POSIX!"
  15. #else
  16. #include <sys/time.h>
  17. #include <sys/select.h>
  18. #endif
  19. #include <sys/socket.h> /* To use the BSD socket, you need to include the socket.h header file */
  20. #include "netdb.h"
  21. #define DBG_TAG "rtlink_port"
  22. #define DBG_LVL DBG_LOG
  23. #include <rtdbg.h>
  24. #define BUFSZ 4096
  25. static struct sockaddr_in remote_addr;
  26. static uint8_t socket_buffer[BUFSZ];
  27. static int32_t rtlink_socket = -1;
  28. static int32_t connect_socket = -1;
  29. static int32_t rtlink_tcp_delete_flag = 0;
  30. #ifdef RTLINK_IN_SERVER_MODE
  31. static struct sockaddr_in local_addr;
  32. #endif
  33. static void rtlink_socket_thread_entry(void *param)
  34. {
  35. fd_set readset;
  36. uint32_t bytes_received;
  37. struct timeval timeout;
  38. struct sockaddr_in;
  39. uint32_t recv_count = 0;
  40. #ifdef RTLINK_IN_SERVER_MODE
  41. fd_set connectset;
  42. socklen_t addr_len;
  43. addr_len = sizeof(struct sockaddr);
  44. #endif
  45. timeout.tv_sec = 0;
  46. timeout.tv_usec = 10000;
  47. while(1)
  48. {
  49. if(rtlink_socket < 0)
  50. {
  51. rt_thread_delay(100);
  52. if(rtlink_tcp_delete_flag == 1)
  53. {
  54. LOG_D("rtlink tcp thread exit\n");
  55. return;
  56. }
  57. }
  58. else
  59. {
  60. #ifdef RTLINK_IN_SERVER_MODE
  61. FD_ZERO(&connectset);
  62. FD_SET(rtlink_socket, &connectset);
  63. if (select(rtlink_socket + 1, &connectset, RT_NULL, RT_NULL, &timeout) == 0)
  64. {
  65. continue;
  66. }
  67. connect_socket = accept(rtlink_socket, (struct sockaddr *)&remote_addr, &addr_len);
  68. if (connect_socket < 0)
  69. {
  70. LOG_E("accept connection failed! errno = %d", errno);
  71. continue;
  72. }
  73. LOG_D("accept success\n");
  74. #else
  75. if(connect_socket < 0)
  76. {
  77. if (connect(rtlink_socket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
  78. {
  79. LOG_D("Connect to IP %s port %d failed!",RTLINK_REMOTE_HOST_IP,RTLINK_REMOTE_TCP_PORT);
  80. rt_thread_delay(1000);
  81. continue;
  82. }
  83. else
  84. {
  85. connect_socket = rtlink_socket;
  86. LOG_D("Connect to IP %s port %d success",RTLINK_REMOTE_HOST_IP,RTLINK_REMOTE_TCP_PORT);
  87. }
  88. }
  89. #endif
  90. while(connect_socket >= 0)
  91. {
  92. FD_ZERO(&readset);
  93. FD_SET(connect_socket, &readset);
  94. if (select(connect_socket + 1, &readset, RT_NULL, RT_NULL, &timeout) == 0)
  95. {
  96. continue;
  97. }
  98. else
  99. {
  100. if(connect_socket >= 0)
  101. {
  102. bytes_received = recv(connect_socket, socket_buffer, BUFSZ - 1, 0);
  103. if (bytes_received < 0)
  104. {
  105. LOG_E("Received error, close the socket.");
  106. closesocket(connect_socket);
  107. connect_socket = -1;
  108. }
  109. else if (bytes_received == 0)
  110. {
  111. LOG_W("Received warning, recv function return 0.");
  112. }
  113. else
  114. {
  115. recv_count++;
  116. rt_link_hw_write_cb(&socket_buffer, bytes_received);
  117. }
  118. }
  119. }
  120. }
  121. }
  122. }
  123. }
  124. rt_err_t rt_link_port_reconnect(void)
  125. {
  126. return RT_EOK;
  127. }
  128. rt_size_t rt_link_port_send(void *data, rt_size_t length)
  129. {
  130. rt_size_t size = 0;
  131. ssize_t ret;
  132. if(connect_socket >= 0)
  133. {
  134. ret = send(connect_socket, data, length, 0);
  135. if (ret < 0)
  136. {
  137. LOG_E("send error, close the socket.");
  138. closesocket(connect_socket);
  139. connect_socket = -1;
  140. }
  141. else if (ret == 0)
  142. {
  143. LOG_W("Send warning, send function return 0.");
  144. }
  145. }
  146. return size;
  147. }
  148. rt_err_t rt_link_port_init(void)
  149. {
  150. if ((rtlink_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  151. {
  152. LOG_E("Create socket error");
  153. goto __exit;
  154. }
  155. #ifdef RTLINK_IN_SERVER_MODE
  156. local_addr.sin_family = AF_INET;
  157. local_addr.sin_port = htons(RTLINK_LOCAL_TCP_PORT);
  158. local_addr.sin_addr.s_addr = INADDR_ANY;
  159. rt_memset(&(local_addr.sin_zero), 0, sizeof(local_addr.sin_zero));
  160. if (bind(rtlink_socket, (struct sockaddr *)&local_addr,sizeof(struct sockaddr)) == -1)
  161. {
  162. LOG_E("Unable to bind");
  163. goto __exit;
  164. }
  165. LOG_D("bind to port %d ip_addr %s success\n",RTLINK_LOCAL_TCP_PORT,RTLINK_REMOTE_HOST_IP);
  166. if (listen(rtlink_socket, 10) == -1)
  167. {
  168. LOG_E("Listen error");
  169. goto __exit;
  170. }
  171. #else
  172. remote_addr.sin_family = AF_INET;
  173. remote_addr.sin_port = htons(RTLINK_REMOTE_TCP_PORT);
  174. remote_addr.sin_addr.s_addr = inet_addr(RTLINK_REMOTE_HOST_IP);
  175. rt_memset(&(remote_addr.sin_zero), 0, sizeof(remote_addr.sin_zero));
  176. #endif
  177. rtlink_tcp_delete_flag = 0;
  178. rt_thread_t rtlink_socket_tid;
  179. rtlink_socket_tid = rt_thread_create("rl_sock",
  180. rtlink_socket_thread_entry,
  181. RT_NULL,
  182. 4096,
  183. RT_THREAD_PRIORITY_MAX - 2,
  184. 2);
  185. if (rtlink_socket_tid != RT_NULL)
  186. {
  187. rt_thread_startup(rtlink_socket_tid);
  188. }
  189. else
  190. {
  191. goto __exit;
  192. }
  193. return RT_EOK;
  194. __exit:
  195. if(rtlink_socket >= 0)
  196. {
  197. closesocket(rtlink_socket);
  198. rtlink_socket = -1;
  199. }
  200. return RT_ERROR;
  201. }
  202. rt_err_t rt_link_port_deinit(void)
  203. {
  204. rtlink_tcp_delete_flag = 1;
  205. #ifdef RTLINK_IN_SERVER_MODE
  206. if(rtlink_socket >= 0)
  207. {
  208. closesocket(rtlink_socket);
  209. rtlink_socket = -1;
  210. }
  211. if(connect_socket >= 0)
  212. {
  213. closesocket(connect_socket);
  214. connect_socket = -1;
  215. }
  216. #else
  217. if(rtlink_socket >= 0)
  218. {
  219. closesocket(rtlink_socket);
  220. rtlink_socket = -1;
  221. connect_socket = -1;
  222. }
  223. #endif
  224. return RT_EOK;
  225. }