af_inet_lwip.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-05-17 ChenYong First version
  9. */
  10. #include <rtthread.h>
  11. #include <lwip/sockets.h>
  12. #include <lwip/netdb.h>
  13. #include <lwip/api.h>
  14. #include <lwip/init.h>
  15. #ifdef SAL_USING_POSIX
  16. #include <dfs_poll.h>
  17. #endif
  18. #include <sal.h>
  19. #include <af_inet.h>
  20. #if LWIP_VERSION < 0x2000000
  21. #define SELWAIT_T int
  22. #else
  23. #ifndef SELWAIT_T
  24. #define SELWAIT_T u8_t
  25. #endif
  26. #endif
  27. #ifdef SAL_USING_POSIX
  28. /*
  29. * Re-define lwip socket
  30. *
  31. * NOTE: please make sure the definitions same in lwip::net_socket.c
  32. */
  33. struct lwip_sock {
  34. /** sockets currently are built on netconns, each socket has one netconn */
  35. struct netconn *conn;
  36. /** data that was left from the previous read */
  37. void *lastdata;
  38. /** offset in the data that was left from the previous read */
  39. u16_t lastoffset;
  40. /** number of times data was received, set by event_callback(),
  41. tested by the receive and select functions */
  42. s16_t rcvevent;
  43. /** number of times data was ACKed (free send buffer), set by event_callback(),
  44. tested by select */
  45. u16_t sendevent;
  46. /** error happened for this socket, set by event_callback(), tested by select */
  47. u16_t errevent;
  48. /** last error that occurred on this socket */
  49. #if LWIP_VERSION < 0x2000000
  50. int err;
  51. #else
  52. u8_t err;
  53. #endif
  54. /** counter of how many threads are waiting for this socket using select */
  55. SELWAIT_T select_waiting;
  56. rt_wqueue_t wait_head;
  57. };
  58. extern struct lwip_sock *lwip_tryget_socket(int s);
  59. static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
  60. {
  61. int s;
  62. struct lwip_sock *sock;
  63. uint32_t event = 0;
  64. SYS_ARCH_DECL_PROTECT(lev);
  65. LWIP_UNUSED_ARG(len);
  66. /* Get socket */
  67. if (conn)
  68. {
  69. s = conn->socket;
  70. if (s < 0)
  71. {
  72. /* Data comes in right away after an accept, even though
  73. * the server task might not have created a new socket yet.
  74. * Just count down (or up) if that's the case and we
  75. * will use the data later. Note that only receive events
  76. * can happen before the new socket is set up. */
  77. SYS_ARCH_PROTECT(lev);
  78. if (conn->socket < 0)
  79. {
  80. if (evt == NETCONN_EVT_RCVPLUS)
  81. {
  82. conn->socket--;
  83. }
  84. SYS_ARCH_UNPROTECT(lev);
  85. return;
  86. }
  87. s = conn->socket;
  88. SYS_ARCH_UNPROTECT(lev);
  89. }
  90. sock = lwip_tryget_socket(s);
  91. if (!sock)
  92. {
  93. return;
  94. }
  95. }
  96. else
  97. {
  98. return;
  99. }
  100. SYS_ARCH_PROTECT(lev);
  101. /* Set event as required */
  102. switch (evt)
  103. {
  104. case NETCONN_EVT_RCVPLUS:
  105. sock->rcvevent++;
  106. break;
  107. case NETCONN_EVT_RCVMINUS:
  108. sock->rcvevent--;
  109. break;
  110. case NETCONN_EVT_SENDPLUS:
  111. sock->sendevent = 1;
  112. break;
  113. case NETCONN_EVT_SENDMINUS:
  114. sock->sendevent = 0;
  115. break;
  116. case NETCONN_EVT_ERROR:
  117. sock->errevent = 1;
  118. break;
  119. default:
  120. LWIP_ASSERT("unknown event", 0);
  121. break;
  122. }
  123. if (sock->lastdata || sock->rcvevent > 0)
  124. event |= POLLIN;
  125. if (sock->sendevent)
  126. event |= POLLOUT;
  127. if (sock->errevent)
  128. event |= POLLERR;
  129. SYS_ARCH_UNPROTECT(lev);
  130. if (event)
  131. {
  132. rt_wqueue_wakeup(&sock->wait_head, (void*) event);
  133. }
  134. }
  135. #endif /* SAL_USING_POSIX */
  136. static int inet_socket(int domain, int type, int protocol)
  137. {
  138. #ifdef SAL_USING_POSIX
  139. int socket;
  140. socket = lwip_socket(domain, type, protocol);
  141. if (socket >= 0)
  142. {
  143. struct lwip_sock *lwsock;
  144. lwsock = lwip_tryget_socket(socket);
  145. lwsock->conn->callback = event_callback;
  146. rt_wqueue_init(&lwsock->wait_head);
  147. }
  148. return socket;
  149. #else
  150. return lwip_socket(domain, type, protocol);
  151. #endif /* SAL_USING_POSIX */
  152. }
  153. static int inet_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
  154. {
  155. #ifdef SAL_USING_POSIX
  156. int new_socket;
  157. new_socket = lwip_accept(socket, addr, addrlen);
  158. if (new_socket >= 0)
  159. {
  160. struct lwip_sock *lwsock;
  161. lwsock = lwip_tryget_socket(new_socket);
  162. rt_wqueue_init(&lwsock->wait_head);
  163. }
  164. return new_socket;
  165. #else
  166. return lwip_accept(socket, addr, addrlen);
  167. #endif /* SAL_USING_POSIX */
  168. }
  169. static int inet_getsockname(int socket, struct sockaddr *name, socklen_t *namelen)
  170. {
  171. #if LWIP_VERSION_MAJOR < 2U
  172. rt_kprintf("ERROR: Your lwIP version is not supported. Please using lwIP 2.0.0+.\n");
  173. RT_ASSERT(LWIP_VERSION_MAJOR >= 2U);
  174. #endif
  175. return lwip_getsockname(socket, name, namelen);
  176. }
  177. #ifdef SAL_USING_POSIX
  178. static int inet_poll(struct dfs_fd *file, struct rt_pollreq *req)
  179. {
  180. int mask = 0;
  181. struct lwip_sock *sock;
  182. struct sal_socket *sal_sock;
  183. sal_sock = sal_get_socket((int) file->data);
  184. if(!sal_sock)
  185. {
  186. return -1;
  187. }
  188. sock = lwip_tryget_socket((int)sal_sock->user_data);
  189. if (sock != NULL)
  190. {
  191. rt_base_t level;
  192. rt_poll_add(&sock->wait_head, req);
  193. level = rt_hw_interrupt_disable();
  194. if (sock->lastdata || sock->rcvevent)
  195. {
  196. mask |= POLLIN;
  197. }
  198. if (sock->sendevent)
  199. {
  200. mask |= POLLOUT;
  201. }
  202. if (sock->errevent)
  203. {
  204. mask |= POLLERR;
  205. }
  206. rt_hw_interrupt_enable(level);
  207. }
  208. return mask;
  209. }
  210. #endif
  211. static const struct proto_ops lwip_inet_stream_ops = {
  212. inet_socket,
  213. lwip_close,
  214. lwip_bind,
  215. lwip_listen,
  216. lwip_connect,
  217. inet_accept,
  218. lwip_sendto,
  219. lwip_recvfrom,
  220. lwip_getsockopt,
  221. //TODO fix on 1.4.1
  222. lwip_setsockopt,
  223. lwip_shutdown,
  224. lwip_getpeername,
  225. inet_getsockname,
  226. lwip_ioctl,
  227. #ifdef SAL_USING_POSIX
  228. inet_poll,
  229. #endif
  230. };
  231. static int inet_create(struct sal_socket *socket, int type, int protocol)
  232. {
  233. RT_ASSERT(socket);
  234. //TODO Check type & protocol
  235. socket->ops = &lwip_inet_stream_ops;
  236. return 0;
  237. }
  238. static const struct proto_family lwip_inet_family_ops = {
  239. "lwip",
  240. AF_INET,
  241. AF_INET,
  242. inet_create,
  243. lwip_gethostbyname,
  244. lwip_gethostbyname_r,
  245. lwip_freeaddrinfo,
  246. lwip_getaddrinfo,
  247. };
  248. int lwip_inet_init(void)
  249. {
  250. sal_proto_family_register(&lwip_inet_family_ops);
  251. return 0;
  252. }
  253. INIT_COMPONENT_EXPORT(lwip_inet_init);