1
0

net_sockets.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*
  2. * File : lwip_sockets.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2015, 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. * 2015-02-17 Bernard First version
  23. */
  24. #include <dfs.h>
  25. #include <dfs_posix.h>
  26. #include <dfs_poll.h>
  27. #include <sys/socket.h>
  28. #include "dfs_net.h"
  29. static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
  30. {
  31. int s;
  32. struct lwip_sock *sock;
  33. uint32_t event = 0;
  34. SYS_ARCH_DECL_PROTECT(lev);
  35. LWIP_UNUSED_ARG(len);
  36. /* Get socket */
  37. if (conn)
  38. {
  39. s = conn->socket;
  40. if (s < 0)
  41. {
  42. /* Data comes in right away after an accept, even though
  43. * the server task might not have created a new socket yet.
  44. * Just count down (or up) if that's the case and we
  45. * will use the data later. Note that only receive events
  46. * can happen before the new socket is set up. */
  47. SYS_ARCH_PROTECT(lev);
  48. if (conn->socket < 0)
  49. {
  50. if (evt == NETCONN_EVT_RCVPLUS)
  51. {
  52. conn->socket--;
  53. }
  54. SYS_ARCH_UNPROTECT(lev);
  55. return;
  56. }
  57. s = conn->socket;
  58. SYS_ARCH_UNPROTECT(lev);
  59. }
  60. sock = lwip_tryget_socket(s);
  61. if (!sock)
  62. {
  63. return;
  64. }
  65. }
  66. else
  67. {
  68. return;
  69. }
  70. SYS_ARCH_PROTECT(lev);
  71. /* Set event as required */
  72. switch (evt)
  73. {
  74. case NETCONN_EVT_RCVPLUS:
  75. sock->rcvevent++;
  76. break;
  77. case NETCONN_EVT_RCVMINUS:
  78. sock->rcvevent--;
  79. break;
  80. case NETCONN_EVT_SENDPLUS:
  81. sock->sendevent = 1;
  82. break;
  83. case NETCONN_EVT_SENDMINUS:
  84. sock->sendevent = 0;
  85. break;
  86. case NETCONN_EVT_ERROR:
  87. sock->errevent = 1;
  88. break;
  89. default:
  90. LWIP_ASSERT("unknown event", 0);
  91. break;
  92. }
  93. if (sock->lastdata || sock->rcvevent > 0) event |= POLLIN;
  94. if (sock->sendevent) event |= POLLOUT;
  95. if (sock->errevent) event |= POLLERR;
  96. SYS_ARCH_UNPROTECT(lev);
  97. if (event)
  98. {
  99. rt_wqueue_wakeup(&sock->wait_head, (void*)event);
  100. }
  101. }
  102. int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
  103. {
  104. int new_client = -1;
  105. int sock = dfs_net_getsocket(s);
  106. new_client = lwip_accept(sock, addr, addrlen);
  107. if (new_client != -1)
  108. {
  109. /* this is a new socket, create it in file system fd */
  110. int fd;
  111. struct dfs_fd *d;
  112. struct lwip_sock *lwsock;
  113. /* allocate a fd */
  114. fd = fd_new();
  115. if (fd < 0)
  116. {
  117. rt_set_errno(-ENOMEM);
  118. lwip_close(sock);
  119. return -1;
  120. }
  121. d = fd_get(fd);
  122. /* this is a socket fd */
  123. d->type = FT_SOCKET;
  124. d->path = RT_NULL;
  125. d->fops = dfs_net_get_fops();
  126. /* initialize wait head */
  127. lwsock = lwip_tryget_socket(new_client);
  128. rt_wqueue_init(&(lwsock->wait_head));
  129. d->flags = O_RDWR; /* set flags as read and write */
  130. d->size = 0;
  131. d->pos = 0;
  132. /* set socket to the data of dfs_fd */
  133. d->data = (void *) new_client;
  134. /* release the ref-count of fd */
  135. fd_put(d);
  136. return fd;
  137. }
  138. return new_client;
  139. }
  140. RTM_EXPORT(accept);
  141. int bind(int s, const struct sockaddr *name, socklen_t namelen)
  142. {
  143. int sock = dfs_net_getsocket(s);
  144. return lwip_bind(sock, name, namelen);
  145. }
  146. RTM_EXPORT(bind);
  147. int shutdown(int s, int how)
  148. {
  149. int sock;
  150. struct dfs_fd *d;
  151. d = fd_get(s);
  152. if (d == RT_NULL)
  153. {
  154. rt_set_errno(-EBADF);
  155. return -1;
  156. }
  157. sock = dfs_net_getsocket(s);
  158. if (lwip_shutdown(sock, how) == 0)
  159. {
  160. /* socket has been closed, delete it from file system fd */
  161. fd_put(d);
  162. fd_put(d);
  163. return 0;
  164. }
  165. return -1;
  166. }
  167. RTM_EXPORT(shutdown);
  168. int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
  169. {
  170. int sock = dfs_net_getsocket(s);
  171. return lwip_getpeername(sock, name, namelen);
  172. }
  173. RTM_EXPORT(getpeername);
  174. int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
  175. {
  176. int sock = dfs_net_getsocket(s);
  177. return lwip_getsockname(sock, name, namelen);
  178. }
  179. RTM_EXPORT(getsockname);
  180. int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
  181. {
  182. int sock = dfs_net_getsocket(s);
  183. return lwip_getsockopt(sock, level, optname, optval, optlen);
  184. }
  185. RTM_EXPORT(getsockopt);
  186. int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
  187. {
  188. int sock = dfs_net_getsocket(s);
  189. #if LWIP_VERSION_MAJOR < 2U
  190. #error "Your lwIP version is not supported. Please using lwIP 2.0.0+."
  191. #endif
  192. return lwip_setsockopt(sock, level, optname, optval, optlen);
  193. }
  194. RTM_EXPORT(setsockopt);
  195. int connect(int s, const struct sockaddr *name, socklen_t namelen)
  196. {
  197. int sock = dfs_net_getsocket(s);
  198. return lwip_connect(sock, name, namelen);
  199. }
  200. RTM_EXPORT(connect);
  201. int listen(int s, int backlog)
  202. {
  203. int sock = dfs_net_getsocket(s);
  204. return lwip_listen(sock, backlog);
  205. }
  206. RTM_EXPORT(listen);
  207. int recv(int s, void *mem, size_t len, int flags)
  208. {
  209. int sock = dfs_net_getsocket(s);
  210. return lwip_recv(sock, mem, len, flags);
  211. }
  212. RTM_EXPORT(recv);
  213. int recvfrom(int s, void *mem, size_t len, int flags,
  214. struct sockaddr *from, socklen_t *fromlen)
  215. {
  216. int sock = dfs_net_getsocket(s);
  217. return lwip_recvfrom(sock, mem, len, flags, from, fromlen);
  218. }
  219. RTM_EXPORT(recvfrom);
  220. int send(int s, const void *dataptr, size_t size, int flags)
  221. {
  222. int sock = dfs_net_getsocket(s);
  223. return lwip_send(sock, dataptr, size, flags);
  224. }
  225. RTM_EXPORT(send);
  226. int sendto(int s, const void *dataptr, size_t size, int flags,
  227. const struct sockaddr *to, socklen_t tolen)
  228. {
  229. int sock = dfs_net_getsocket(s);
  230. return lwip_sendto(sock, dataptr, size, flags, to, tolen);
  231. }
  232. RTM_EXPORT(sendto);
  233. int socket(int domain, int type, int protocol)
  234. {
  235. /* create a BSD socket */
  236. int fd;
  237. int sock;
  238. struct dfs_fd *d;
  239. struct lwip_sock *lwsock;
  240. /* allocate a fd */
  241. fd = fd_new();
  242. if (fd < 0)
  243. {
  244. rt_set_errno(-ENOMEM);
  245. return -1;
  246. }
  247. d = fd_get(fd);
  248. /* create socket in lwip and then put it to the dfs_fd */
  249. sock = lwip_socket(domain, type, protocol);
  250. if (sock >= 0)
  251. {
  252. /* this is a socket fd */
  253. d->type = FT_SOCKET;
  254. d->path = NULL;
  255. d->fops = dfs_net_get_fops();
  256. d->flags = O_RDWR; /* set flags as read and write */
  257. d->size = 0;
  258. d->pos = 0;
  259. /* set socket to the data of dfs_fd */
  260. d->data = (void *) sock;
  261. lwsock = lwip_tryget_socket(sock);
  262. rt_wqueue_init(&(lwsock->wait_head));
  263. lwsock->conn->callback = event_callback;
  264. }
  265. else
  266. {
  267. /* release fd */
  268. fd_put(d);
  269. fd_put(d);
  270. rt_set_errno(-ENOMEM);
  271. return -1;
  272. }
  273. /* release the ref-count of fd */
  274. fd_put(d);
  275. return fd;
  276. }
  277. RTM_EXPORT(socket);
  278. int closesocket(int s)
  279. {
  280. int sock = dfs_net_getsocket(s);
  281. struct dfs_fd *d;
  282. d = fd_get(s);
  283. /* socket has been closed, delete it from file system fd */
  284. fd_put(d);
  285. fd_put(d);
  286. return lwip_close(sock);
  287. }
  288. RTM_EXPORT(closesocket);
  289. int ioctlsocket(int s, long cmd, void *arg)
  290. {
  291. int sock = dfs_net_getsocket(s);
  292. return lwip_ioctl(sock, cmd, arg);
  293. }
  294. RTM_EXPORT(ioctlsocket);