PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/platform/FNET/fnet_stack/stack/fnet_socket.c

https://gitlab.com/fuggles/ucos
C | 1902 lines | 1320 code | 284 blank | 298 comment | 292 complexity | da81a98fa915b6c5799d5f3a82a56936 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /**************************************************************************
  2. *
  3. * Copyright 2011-2015 by Andrey Butok. FNET Community.
  4. * Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
  5. * Copyright 2003 by Andrey Butok. Motorola SPS.
  6. *
  7. ***************************************************************************
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Lesser General Public License Version 3
  10. * or later (the "LGPL").
  11. *
  12. * As a special exception, the copyright holders of the FNET project give you
  13. * permission to link the FNET sources with independent modules to produce an
  14. * executable, regardless of the license terms of these independent modules,
  15. * and to copy and distribute the resulting executable under terms of your
  16. * choice, provided that you also meet, for each linked independent module,
  17. * the terms and conditions of the license of that module.
  18. * An independent module is a module which is not derived from or based
  19. * on this library.
  20. * If you modify the FNET sources, you may extend this exception
  21. * to your version of the FNET sources, but you are not obligated
  22. * to do so. If you do not wish to do so, delete this
  23. * exception statement from your version.
  24. *
  25. * This program is distributed in the hope that it will be useful,
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  28. *
  29. * You should have received a copy of the GNU General Public License
  30. * and the GNU Lesser General Public License along with this program.
  31. * If not, see <http://www.gnu.org/licenses/>.
  32. *
  33. **********************************************************************/ /*!
  34. *
  35. * @file fnet_socket.c
  36. *
  37. * @author Andrey Butok
  38. *
  39. * @brief Socket interface implementation.
  40. *
  41. ***************************************************************************/
  42. #include "fnet.h"
  43. #include "fnet_socket_prv.h"
  44. #include "fnet_timer_prv.h"
  45. #include "fnet_prot.h"
  46. /************************************************************************
  47. * Global Data Structures
  48. *************************************************************************/
  49. int fnet_enabled = 0; /* Flag that the stack is initialized. */
  50. static unsigned short fnet_port_last = FNET_SOCKET_PORT_RESERVED + 1;
  51. /* Array of sockets descriptors. */
  52. static fnet_socket_t *fnet_socket_desc[FNET_CFG_SOCKET_MAX];
  53. /************************************************************************
  54. * Function Prototypes
  55. *************************************************************************/
  56. static SOCKET fnet_socket_desc_alloc(void);
  57. static void fnet_socket_desc_set(SOCKET desc, fnet_socket_t *sock);
  58. static void fnet_socket_desc_free(SOCKET desc);
  59. /* START PATCH: brian robertson */
  60. //static fnet_socket_t *fnet_socket_desc_find(SOCKET desc);
  61. fnet_socket_t *fnet_socket_desc_find(SOCKET desc);
  62. /* END PATCH */
  63. static int fnet_socket_addr_check_len(const struct sockaddr *addr, unsigned int addr_len);
  64. /************************************************************************
  65. * NAME: fnet_socket_init
  66. *
  67. * DESCRIPTION: Initialization of the socket layer.
  68. *************************************************************************/
  69. void fnet_socket_init( void )
  70. {
  71. fnet_memset_zero(fnet_socket_desc, sizeof(fnet_socket_desc));
  72. }
  73. /************************************************************************
  74. * NAME: fnet_socket_set_error
  75. *
  76. * DESCRIPTION: This function sets socket error.
  77. *************************************************************************/
  78. void fnet_socket_set_error( fnet_socket_t *sock, int error )
  79. {
  80. if(sock->options.local_error != FNET_OK)
  81. {
  82. error = sock->options.local_error;
  83. sock->options.local_error = FNET_OK;
  84. }
  85. sock->options.error = error;
  86. fnet_error_set(error);
  87. }
  88. /************************************************************************
  89. * NAME: fnet_socket_list_add
  90. *
  91. * DESCRIPTION: This function adds socket into the queue.
  92. *************************************************************************/
  93. void fnet_socket_list_add( fnet_socket_t ** head, fnet_socket_t *s )
  94. {
  95. fnet_isr_lock();
  96. s->next = *head;
  97. if(s->next != 0)
  98. s->next->prev = s;
  99. s->prev = 0;
  100. *head = s;
  101. fnet_isr_unlock();
  102. }
  103. /************************************************************************
  104. * NAME: fnet_socket_list_del
  105. *
  106. * DESCRIPTION: This function removes socket from the queue
  107. *************************************************************************/
  108. void fnet_socket_list_del( fnet_socket_t ** head, fnet_socket_t *s )
  109. {
  110. fnet_isr_lock();
  111. if(s->prev == 0)
  112. *head=s->next;
  113. else
  114. s->prev->next = s->next;
  115. if(s->next != 0)
  116. s->next->prev = s->prev;
  117. fnet_isr_unlock();
  118. }
  119. /************************************************************************
  120. * NAME: fnet_socket_desc_alloc
  121. *
  122. * DESCRIPTION: This function reserves socket descriptor.
  123. *************************************************************************/
  124. static SOCKET fnet_socket_desc_alloc( void )
  125. {
  126. int i;
  127. int res = FNET_ERR;
  128. fnet_isr_lock();
  129. for (i = 0; i < FNET_CFG_SOCKET_MAX; i++) /* Find the empty descriptor.*/
  130. {
  131. if(fnet_socket_desc[i] == 0)
  132. {
  133. fnet_socket_desc[i] = (fnet_socket_t *)FNET_SOCKET_DESC_RESERVED;
  134. res = i;
  135. break;
  136. }
  137. }
  138. fnet_isr_unlock();
  139. return (res);
  140. }
  141. /************************************************************************
  142. * NAME: fnet_socket_desc_set
  143. *
  144. * DESCRIPTION: This function assigns the socket descriptor to the socket.
  145. *************************************************************************/
  146. static void fnet_socket_desc_set( SOCKET desc, fnet_socket_t *sock )
  147. {
  148. fnet_socket_desc[desc] = sock;
  149. sock->descriptor = desc;
  150. }
  151. /************************************************************************
  152. * NAME: fnet_socket_desc_free
  153. *
  154. * DESCRIPTION: This function frees the socket descriptor.
  155. *************************************************************************/
  156. static void fnet_socket_desc_free( SOCKET desc )
  157. {
  158. fnet_socket_desc[desc] = 0;
  159. }
  160. /************************************************************************
  161. * NAME: fnet_socket_desc_find
  162. *
  163. * DESCRIPTION: This function looking for socket structure
  164. * associated with the socket descriptor.
  165. *************************************************************************/
  166. /* START PATCH: brian robertson */
  167. //static fnet_socket_t *fnet_socket_desc_find( SOCKET desc )
  168. fnet_socket_t *fnet_socket_desc_find( SOCKET desc )
  169. /* END PATCH */
  170. {
  171. fnet_socket_t *s = 0;
  172. if(fnet_enabled && (desc >= 0) && (desc!=SOCKET_INVALID))
  173. {
  174. if((desc < FNET_CFG_SOCKET_MAX))
  175. s = fnet_socket_desc[desc];
  176. }
  177. return (s);
  178. }
  179. /************************************************************************
  180. * NAME: fnet_socket_release
  181. *
  182. * DESCRIPTION: This function release all resources allocated for the socket.
  183. *************************************************************************/
  184. void fnet_socket_release( fnet_socket_t ** head, fnet_socket_t *sock )
  185. {
  186. fnet_isr_lock();
  187. fnet_socket_list_del(head, sock);
  188. fnet_socket_buffer_release(&sock->receive_buffer);
  189. fnet_socket_buffer_release(&sock->send_buffer);
  190. fnet_free(sock);
  191. fnet_isr_unlock();
  192. }
  193. /************************************************************************
  194. * NAME: fnet_socket_conflict
  195. *
  196. * DESCRIPTION: Return FNET_TRUE if there's a socket whose addresses 'confict'
  197. * with the supplied addresses.
  198. *************************************************************************/
  199. int fnet_socket_conflict( fnet_socket_t *head, const struct sockaddr *local_addr,
  200. const struct sockaddr *foreign_addr /*optional*/, int wildcard )
  201. {
  202. fnet_socket_t *sock = head;
  203. while(sock != 0)
  204. {
  205. if((sock->local_addr.sa_port == local_addr->sa_port)
  206. && ((fnet_socket_addr_is_unspecified(local_addr) && (wildcard)) || fnet_socket_addr_are_equal(&sock->local_addr, local_addr) )
  207. && (((foreign_addr == 0) && (wildcard)) || fnet_socket_addr_are_equal(&sock->foreign_addr, foreign_addr))
  208. && (((foreign_addr == 0) && (wildcard)) || (foreign_addr && (sock->foreign_addr.sa_port == foreign_addr->sa_port))) )
  209. return (FNET_TRUE);
  210. sock = sock->next;
  211. }
  212. return (FNET_FALSE);
  213. }
  214. /************************************************************************
  215. * NAME: fnet_socket_lookup
  216. *
  217. * DESCRIPTION: This function looks for a socket with the best match
  218. * to the local and foreign address parameters.
  219. *************************************************************************/
  220. fnet_socket_t *fnet_socket_lookup( fnet_socket_t *head, struct sockaddr *local_addr, struct sockaddr *foreign_addr, int protocol_number)
  221. {
  222. fnet_socket_t *sock;
  223. fnet_socket_t *match_sock = 0;
  224. int match_wildcard = 3;
  225. int wildcard;
  226. for (sock = head; sock != 0; sock = sock->next)
  227. {
  228. /* Compare local port number.*/
  229. if(sock->protocol_number != protocol_number)
  230. continue; /* Ignore. */
  231. /* Compare local port number.*/
  232. if(sock->local_addr.sa_port != local_addr->sa_port)
  233. continue; /* Ignore. */
  234. wildcard = 0;
  235. /* Compare local address.*/
  236. if(!fnet_socket_addr_is_unspecified(&sock->local_addr))
  237. {
  238. if(fnet_socket_addr_is_unspecified(local_addr))
  239. wildcard++;
  240. else if(!fnet_socket_addr_are_equal(&sock->local_addr, local_addr))
  241. continue;
  242. }
  243. else
  244. {
  245. if(!fnet_socket_addr_is_unspecified(local_addr))
  246. wildcard++;
  247. }
  248. /* Compare foreign address and port number.*/
  249. if(!fnet_socket_addr_is_unspecified(&sock->foreign_addr))
  250. {
  251. if(fnet_socket_addr_is_unspecified(foreign_addr))
  252. wildcard++;
  253. else if((!fnet_socket_addr_are_equal(&sock->foreign_addr, foreign_addr)) || (sock->foreign_addr.sa_port != foreign_addr->sa_port))
  254. continue;
  255. }
  256. else
  257. {
  258. if(!fnet_socket_addr_is_unspecified(foreign_addr))
  259. wildcard++;
  260. }
  261. if(wildcard < match_wildcard)
  262. {
  263. match_sock = sock;
  264. if((match_wildcard = wildcard) == 0)
  265. break; /* Exact match is found.*/
  266. }
  267. }
  268. return (match_sock);
  269. }
  270. /************************************************************************
  271. * NAME: fnet_socket_uniqueport
  272. *
  273. * DESCRIPTION: Choose a unique (non-conflicting) local port for the socket
  274. * list starting at 'head'. The port will always be
  275. * FNET_SOCKET_PORT_RESERVED < local_port <= FNET_SOCKET_PORT_USERRESERVED (ephemeral port).
  276. * In network byte order.
  277. *************************************************************************/
  278. unsigned short fnet_socket_get_uniqueport( fnet_socket_t *head, struct sockaddr *local_addr )
  279. {
  280. unsigned short local_port = fnet_port_last;
  281. struct sockaddr local_addr_tmp = *local_addr;
  282. fnet_isr_lock();
  283. do
  284. {
  285. if((++local_port <= FNET_SOCKET_PORT_RESERVED) || (local_port > FNET_SOCKET_PORT_USERRESERVED))
  286. local_port = FNET_SOCKET_PORT_RESERVED + 1;
  287. local_addr_tmp.sa_port = fnet_htons(local_port);
  288. }
  289. while (fnet_socket_conflict(head, &local_addr_tmp, FNET_NULL, 1));
  290. fnet_port_last = local_port;
  291. fnet_isr_unlock();
  292. return local_addr_tmp.sa_port;
  293. }
  294. /************************************************************************
  295. * NAME: fnet_socket_copy
  296. *
  297. * DESCRIPTION: This function creates new socket structure and fills
  298. * its proper fields by values from existing socket
  299. *************************************************************************/
  300. fnet_socket_t *fnet_socket_copy( fnet_socket_t *sock )
  301. {
  302. fnet_socket_t *sock_cp;
  303. if((sock_cp = (fnet_socket_t *)fnet_malloc(sizeof(fnet_socket_t))) != 0)
  304. {
  305. fnet_memcpy(sock_cp, sock, sizeof(fnet_socket_t));
  306. sock_cp->next = 0;
  307. sock_cp->prev = 0;
  308. sock_cp->descriptor = FNET_SOCKET_DESC_RESERVED;
  309. sock_cp->state = SS_UNCONNECTED;
  310. sock_cp->protocol_control = 0;
  311. sock_cp->head_con = 0;
  312. sock_cp->partial_con = 0;
  313. sock_cp->incoming_con = 0;
  314. sock_cp->receive_buffer.count = 0;
  315. sock_cp->receive_buffer.net_buf_chain = 0;
  316. sock_cp->send_buffer.count = 0;
  317. sock_cp->send_buffer.net_buf_chain = 0;
  318. sock_cp->options.error = FNET_OK;
  319. sock_cp->options.local_error = FNET_OK;
  320. return (sock_cp);
  321. }
  322. else
  323. return (0);
  324. }
  325. /************************************************************************
  326. * NAME: socket
  327. *
  328. * DESCRIPTION: This function creates a socket and returns
  329. * the descriptor to the application.
  330. *************************************************************************/
  331. SOCKET socket( fnet_address_family_t family, fnet_socket_type_t type, int protocol )
  332. {
  333. fnet_prot_if_t *prot;
  334. fnet_socket_t *sock;
  335. SOCKET res;
  336. int error = FNET_OK;
  337. fnet_os_mutex_lock();
  338. if(fnet_enabled == 0) /* Stack is disabled */
  339. {
  340. error = FNET_ERR_SYSNOTREADY;
  341. goto ERROR_1;
  342. }
  343. res = fnet_socket_desc_alloc();
  344. if(res == FNET_ERR)
  345. {
  346. error = FNET_ERR_NO_DESC; /* No more socket descriptors are available.*/
  347. goto ERROR_1;
  348. }
  349. if((prot = fnet_prot_find(family, type, protocol)) == 0)
  350. {
  351. error = FNET_ERR_PROTONOSUPPORT; /* Protocol not supported.*/
  352. goto ERROR_2;
  353. }
  354. if((sock = (fnet_socket_t *)fnet_malloc_zero(sizeof(fnet_socket_t))) == 0)
  355. {
  356. error = FNET_ERR_NOMEM; /* Cannot allocate memory.*/
  357. goto ERROR_2;
  358. }
  359. fnet_socket_desc_set(res, sock);
  360. sock->protocol_interface = prot;
  361. sock->local_addr.sa_family = family;
  362. sock->state = SS_UNCONNECTED;
  363. /* Save protocol number.*/
  364. sock->protocol_number = protocol;
  365. if(!sock->protocol_number)
  366. sock->protocol_number = prot->protocol;
  367. sock->foreign_addr.sa_family = family;
  368. fnet_socket_list_add(&prot->head, sock);
  369. if(prot->socket_api->prot_attach && (prot->socket_api->prot_attach(sock) == SOCKET_ERROR))
  370. {
  371. fnet_socket_release(&sock->protocol_interface->head, sock);
  372. error = fnet_error_get();
  373. goto ERROR_2;
  374. }
  375. fnet_os_mutex_unlock();
  376. return (res);
  377. ERROR_2:
  378. fnet_socket_desc_free(res);
  379. ERROR_1:
  380. fnet_error_set(error);
  381. fnet_os_mutex_unlock();
  382. return (SOCKET_INVALID);
  383. }
  384. /************************************************************************
  385. * NAME: connect
  386. *
  387. * DESCRIPTION: This function establishes a connection to
  388. * a specified socket.
  389. *************************************************************************/
  390. int connect( SOCKET s, struct sockaddr *name, unsigned int namelen )
  391. {
  392. fnet_socket_t *sock;
  393. int error = FNET_OK;
  394. struct sockaddr foreign_addr;
  395. struct sockaddr local_addr_tmp;
  396. int result;
  397. fnet_os_mutex_lock();
  398. if((sock = fnet_socket_desc_find(s)) != 0)
  399. {
  400. if(sock->state == SS_LISTENING) /* The socket is marked to accept connections (listen).*/
  401. {
  402. error = (int)FNET_ERR_OPNOTSUPP; /* Operation not supported.*/
  403. goto ERROR_SOCK;
  404. }
  405. /* The protocol is connection oriented.*/
  406. if(sock->protocol_interface->socket_api->con_req)
  407. {
  408. /* A connection has already been initiated.*/
  409. if(sock->state == SS_CONNECTED)
  410. {
  411. error = (int)FNET_ERR_ISCONN; /* Socket is already connected.*/
  412. goto ERROR_SOCK;
  413. }
  414. if(sock->state == SS_CONNECTING)
  415. {
  416. error = (int)FNET_ERR_INPROGRESS; /* The action is in progress. */
  417. goto ERROR_SOCK;
  418. }
  419. }
  420. if((error = fnet_socket_addr_check_len(name, (unsigned int)namelen)) != FNET_OK)
  421. {
  422. goto ERROR_SOCK;
  423. }
  424. foreign_addr = *name;
  425. if (fnet_socket_addr_is_unspecified(&foreign_addr))
  426. {
  427. error = (int)FNET_ERR_DESTADDRREQ; /* Destination address required.*/
  428. goto ERROR_SOCK;
  429. }
  430. if((foreign_addr.sa_port == 0U) && (sock->protocol_interface->type != SOCK_RAW))
  431. {
  432. error = (int)FNET_ERR_ADDRNOTAVAIL; /* Can't assign requested port.*/
  433. goto ERROR_SOCK;
  434. }
  435. local_addr_tmp = sock->local_addr;
  436. if (fnet_socket_addr_is_unspecified(&local_addr_tmp))
  437. {
  438. switch(local_addr_tmp.sa_family)
  439. {
  440. #if FNET_CFG_IP4
  441. case AF_INET:
  442. {
  443. fnet_netif_t *netif;
  444. if((netif = fnet_ip_route(((struct sockaddr_in *)(&foreign_addr))->sin_addr.s_addr)) == 0)
  445. {
  446. error = FNET_ERR_NETUNREACH; /* No route. */
  447. goto ERROR_SOCK;
  448. }
  449. ((struct sockaddr_in *)(&local_addr_tmp))->sin_addr.s_addr = netif->ip4_addr.address;
  450. }
  451. break;
  452. #endif /* FNET_CFG_IP4 */
  453. #if FNET_CFG_IP6
  454. case AF_INET6:
  455. {
  456. const fnet_ip6_addr_t *local_ip6_addr;
  457. /* Check if can find a route to the destination.*/
  458. if((local_ip6_addr = fnet_ip6_select_src_addr(fnet_netif_get_by_scope_id(((struct sockaddr_in6 *)(&foreign_addr))->sin6_scope_id),
  459. &((struct sockaddr_in6 *)(&foreign_addr))->sin6_addr.s6_addr))== FNET_NULL)
  460. {
  461. error = FNET_ERR_NETUNREACH; /* No route. */
  462. goto ERROR_SOCK;
  463. }
  464. /* Init local address.*/
  465. FNET_IP6_ADDR_COPY(local_ip6_addr, &((struct sockaddr_in6 *)(&local_addr_tmp))->sin6_addr.s6_addr);
  466. ((struct sockaddr_in6 *)(&local_addr_tmp))->sin6_scope_id = ((struct sockaddr_in6 *)(&foreign_addr))->sin6_scope_id;
  467. }
  468. break;
  469. #endif /* FNET_CFG_IP6 */
  470. }
  471. }
  472. if(local_addr_tmp.sa_port == 0)
  473. {
  474. local_addr_tmp.sa_port = fnet_socket_get_uniqueport(sock->protocol_interface->head,
  475. &local_addr_tmp); /* Get ephemeral port.*/
  476. }
  477. if(fnet_socket_conflict(sock->protocol_interface->head, &local_addr_tmp, &foreign_addr, 1))
  478. {
  479. error = FNET_ERR_ADDRINUSE; /* Address already in use. */
  480. goto ERROR_SOCK;
  481. }
  482. sock->local_addr = local_addr_tmp;
  483. /* Start the appropriate protocol connection.*/
  484. if(sock->protocol_interface->socket_api->prot_connect)
  485. result = sock->protocol_interface->socket_api->prot_connect(sock, &foreign_addr);
  486. else
  487. result = FNET_OK;
  488. }
  489. else
  490. {
  491. error = FNET_ERR_BAD_DESC; /* Bad descriptor.*/
  492. goto ERROR;
  493. }
  494. fnet_os_mutex_unlock();
  495. return (result);
  496. ERROR_SOCK:
  497. fnet_socket_set_error(sock, error);
  498. ERROR:
  499. fnet_error_set(error);
  500. fnet_os_mutex_unlock();
  501. return (SOCKET_ERROR);
  502. }
  503. /************************************************************************
  504. * NAME: bind
  505. *
  506. * DESCRIPTION: This function associates a local address with a socket.
  507. *************************************************************************/
  508. int bind( SOCKET s, const struct sockaddr *name, unsigned int namelen )
  509. {
  510. fnet_socket_t *sock;
  511. int error = FNET_OK;
  512. fnet_os_mutex_lock();
  513. if((sock = fnet_socket_desc_find(s)) != 0)
  514. {
  515. if((error = fnet_socket_addr_check_len(name, (unsigned int)namelen)) != FNET_OK)
  516. {
  517. goto ERROR_SOCK;
  518. }
  519. if((sock->local_addr.sa_port == 0) && fnet_socket_addr_is_unspecified(&sock->local_addr))
  520. {
  521. if(!fnet_socket_addr_is_multicast(name)) /* Is not multicast.*/
  522. {
  523. if(!fnet_socket_addr_is_unspecified(name) && !fnet_socket_addr_is_broadcast(&sock->local_addr, FNET_NULL) && (fnet_netif_get_by_sockaddr(name) == FNET_NULL))
  524. {
  525. /* The specified address is not a valid address for this system.*/
  526. error = FNET_ERR_ADDRNOTAVAIL;
  527. goto ERROR_SOCK;
  528. }
  529. if((name->sa_port != 0)
  530. && fnet_socket_conflict(sock->protocol_interface->head, name, FNET_NULL, 0))
  531. {
  532. error = FNET_ERR_ADDRINUSE; /* Address already in use. */
  533. goto ERROR_SOCK;
  534. }
  535. }
  536. fnet_socket_ip_addr_copy(name , &sock->local_addr);
  537. if((name->sa_port == 0) && (sock->protocol_interface->type != SOCK_RAW))
  538. {
  539. sock->local_addr.sa_port = fnet_socket_get_uniqueport(sock->protocol_interface->head, &sock->local_addr); /* Get ephemeral port.*/
  540. }
  541. else
  542. sock->local_addr.sa_port = name->sa_port;
  543. fnet_socket_buffer_release(&sock->receive_buffer);
  544. fnet_socket_buffer_release(&sock->send_buffer);
  545. }
  546. else
  547. {
  548. error = FNET_ERR_INVAL; /* The socket is already bound to an address.*/
  549. goto ERROR_SOCK;
  550. }
  551. }
  552. else
  553. {
  554. /* Bad descriptor.*/
  555. fnet_error_set(FNET_ERR_BAD_DESC);
  556. goto ERROR;
  557. }
  558. fnet_os_mutex_unlock();
  559. return (FNET_OK);
  560. ERROR_SOCK:
  561. fnet_socket_set_error(sock, error);
  562. ERROR:
  563. fnet_os_mutex_unlock();
  564. return (SOCKET_ERROR);
  565. }
  566. /************************************************************************
  567. * NAME: closesocket
  568. *
  569. * DESCRIPTION: This function closes an existing socket.
  570. *************************************************************************/
  571. int closesocket( SOCKET s )
  572. {
  573. fnet_socket_t *sock;
  574. int result = FNET_OK;
  575. int error;
  576. fnet_os_mutex_lock();
  577. if((sock = fnet_socket_desc_find(s)) != 0)
  578. {
  579. #if FNET_CFG_MULTICAST && FNET_CFG_IP4
  580. /* Leave all IPv4 multicast groups.*/
  581. {
  582. int i;
  583. for(i = 0; i < FNET_CFG_MULTICAST_SOCKET_MAX; i++)
  584. {
  585. if (sock->ip4_multicast_entry[i]!= FNET_NULL)
  586. {
  587. fnet_ip_multicast_leave_entry(sock->ip4_multicast_entry[i]);
  588. }
  589. }
  590. }
  591. #endif
  592. #if FNET_CFG_MULTICAST && FNET_CFG_IP6
  593. /* Leave all IPv6 multicast groups.*/
  594. {
  595. int i;
  596. for(i = 0; i < FNET_CFG_MULTICAST_SOCKET_MAX; i++)
  597. {
  598. if (sock->ip6_multicast_entry[i]!= FNET_NULL)
  599. {
  600. fnet_ip6_multicast_leave_entry(sock->ip6_multicast_entry[i]);
  601. }
  602. }
  603. }
  604. #endif
  605. if(sock->protocol_interface->socket_api->prot_detach)
  606. result = sock->protocol_interface->socket_api->prot_detach(sock);
  607. if(result == FNET_OK)
  608. fnet_socket_desc_free(s);
  609. }
  610. else
  611. {
  612. error = FNET_ERR_BAD_DESC; /* Bad descriptor.*/
  613. goto ERROR;
  614. }
  615. fnet_os_mutex_unlock();
  616. return (result);
  617. ERROR:
  618. fnet_error_set(error);
  619. fnet_os_mutex_unlock();
  620. return (SOCKET_ERROR);
  621. }
  622. /************************************************************************
  623. * NAME: shutdown
  624. *
  625. * DESCRIPTION: This function to disable reception, transmission, or both.
  626. *************************************************************************/
  627. int shutdown( SOCKET s, unsigned int how )
  628. {
  629. fnet_socket_t *sock;
  630. int result = FNET_OK;
  631. int error;
  632. fnet_os_mutex_lock();
  633. if((sock = fnet_socket_desc_find(s)) != 0)
  634. {
  635. if(sock->protocol_interface && sock->protocol_interface->socket_api->prot_shutdown)
  636. result = sock->protocol_interface->socket_api->prot_shutdown(sock, how);
  637. }
  638. else
  639. {
  640. error = FNET_ERR_BAD_DESC; /* Bad descriptor.*/
  641. goto ERROR;
  642. }
  643. fnet_os_mutex_unlock();
  644. return (result);
  645. ERROR:
  646. fnet_error_set(error);
  647. fnet_os_mutex_unlock();
  648. return (SOCKET_ERROR);
  649. }
  650. /************************************************************************
  651. * NAME: listen
  652. *
  653. * DESCRIPTION: This function places the socket into the state where
  654. * it is listening for an incoming connection.
  655. *************************************************************************/
  656. int listen( SOCKET s, int backlog )
  657. {
  658. fnet_socket_t *sock;
  659. int error;
  660. int result = FNET_OK;
  661. fnet_os_mutex_lock();
  662. if((sock = fnet_socket_desc_find(s)) != 0)
  663. {
  664. if((sock->state == SS_CONNECTING) || (sock->state == SS_CONNECTED))
  665. {
  666. error = FNET_ERR_ISCONN; /* Operation not supported.*/
  667. goto ERROR_SOCK;
  668. }
  669. if(sock->local_addr.sa_port == 0)
  670. {
  671. error = FNET_ERR_BOUNDREQ; /* The socket has not been bound.*/
  672. goto ERROR_SOCK;
  673. }
  674. if(backlog < 0)
  675. {
  676. error = FNET_ERR_INVAL; /* Invalid argument.*/
  677. goto ERROR_SOCK;
  678. }
  679. if(sock->protocol_interface && sock->protocol_interface->socket_api->prot_listen)
  680. {
  681. result = sock->protocol_interface->socket_api->prot_listen(sock, backlog);
  682. }
  683. else
  684. {
  685. error = FNET_ERR_OPNOTSUPP; /* Operation not supported.*/
  686. goto ERROR_SOCK;
  687. }
  688. }
  689. else
  690. {
  691. fnet_error_set(FNET_ERR_BAD_DESC);/* Bad descriptor.*/
  692. goto ERROR;
  693. }
  694. fnet_os_mutex_unlock();
  695. return (result);
  696. ERROR_SOCK:
  697. fnet_socket_set_error(sock, error);
  698. ERROR:
  699. fnet_os_mutex_unlock();
  700. return (SOCKET_ERROR);
  701. }
  702. /************************************************************************
  703. * NAME: accept
  704. *
  705. * DESCRIPTION: This function accepts a connection on a specified socket.
  706. *************************************************************************/
  707. SOCKET accept( SOCKET s, struct sockaddr *addr, unsigned int *addrlen )
  708. {
  709. fnet_socket_t *sock;
  710. fnet_socket_t *sock_new;
  711. SOCKET desc;
  712. int error;
  713. fnet_os_mutex_lock();
  714. if((sock = fnet_socket_desc_find(s)) != 0)
  715. {
  716. if(sock->protocol_interface && sock->protocol_interface->socket_api->prot_accept)
  717. {
  718. if(sock->state != SS_LISTENING)
  719. {
  720. error = FNET_ERR_INVAL; /* Invalid argument.*/
  721. goto ERROR_SOCK;
  722. }
  723. if(addr && addrlen)
  724. {
  725. if((error = fnet_socket_addr_check_len(&sock->local_addr, (unsigned int)(*addrlen) )) != FNET_OK )
  726. {
  727. goto ERROR_SOCK;
  728. }
  729. }
  730. if((desc = fnet_socket_desc_alloc()) != FNET_ERR)
  731. {
  732. fnet_isr_lock();
  733. if((sock_new = sock->protocol_interface->socket_api->prot_accept(sock)) == 0)
  734. {
  735. fnet_socket_desc_free(desc);
  736. fnet_isr_unlock();
  737. error = FNET_ERR_AGAIN;
  738. goto ERROR_SOCK;
  739. };
  740. fnet_socket_desc_set(desc, sock_new);
  741. fnet_socket_list_add(&sock->protocol_interface->head, sock_new);
  742. fnet_isr_unlock();
  743. if(addr && addrlen)
  744. {
  745. fnet_socket_addr_copy(&sock_new->foreign_addr, addr);
  746. }
  747. }
  748. else
  749. {
  750. error = FNET_ERR_NO_DESC; /* No more socket descriptors are available.*/
  751. goto ERROR_SOCK;
  752. }
  753. }
  754. else
  755. {
  756. error = FNET_ERR_OPNOTSUPP; /* Operation not supported.*/
  757. goto ERROR_SOCK;
  758. }
  759. }
  760. else
  761. {
  762. fnet_error_set(FNET_ERR_BAD_DESC);/* Bad descriptor.*/
  763. goto ERROR;
  764. }
  765. fnet_os_mutex_unlock();
  766. return (desc);
  767. ERROR_SOCK:
  768. fnet_socket_set_error(sock, error);
  769. ERROR:
  770. fnet_os_mutex_unlock();
  771. return (SOCKET_INVALID);
  772. }
  773. /************************************************************************
  774. * NAME: send
  775. *
  776. * DESCRIPTION: This function sends data on a connected socket.
  777. *************************************************************************/
  778. int send( SOCKET s, char *buf, unsigned int len, unsigned int flags )
  779. {
  780. return sendto(s, buf, len, flags, FNET_NULL, 0);
  781. }
  782. /************************************************************************
  783. * NAME: sendto
  784. *
  785. * DESCRIPTION: This function sends data to a specific destination.
  786. *************************************************************************/
  787. int sendto( SOCKET s, char *buf, unsigned int len, int flags, const struct sockaddr *to, unsigned int tolen )
  788. {
  789. fnet_socket_t *sock;
  790. int error;
  791. int result = FNET_OK;
  792. fnet_os_mutex_lock();
  793. if((sock = fnet_socket_desc_find(s)) != 0)
  794. {
  795. if((to == FNET_NULL) || (tolen == 0))
  796. {
  797. if(fnet_socket_addr_is_unspecified(&sock->foreign_addr))
  798. {
  799. error = FNET_ERR_NOTCONN; /* Socket is not connected.*/
  800. goto ERROR_SOCK;
  801. }
  802. to = FNET_NULL;
  803. }
  804. else
  805. {
  806. if((error = fnet_socket_addr_check_len(to, (unsigned int)tolen)) != FNET_OK)
  807. {
  808. goto ERROR_SOCK;
  809. }
  810. if(fnet_socket_addr_is_unspecified(to))
  811. {
  812. error = FNET_ERR_DESTADDRREQ; /* Destination address required.*/
  813. goto ERROR_SOCK;
  814. }
  815. }
  816. if(buf)
  817. {
  818. /* If the socket is shutdowned, return.*/
  819. if(sock->send_buffer.is_shutdown)
  820. {
  821. error = FNET_ERR_SHUTDOWN;
  822. goto ERROR_SOCK;
  823. }
  824. if(sock->protocol_interface->socket_api->prot_snd)
  825. {
  826. result = sock->protocol_interface->socket_api->prot_snd(sock, buf, len, flags, to);
  827. }
  828. else
  829. {
  830. error = FNET_ERR_OPNOTSUPP; /* Operation not supported.*/
  831. goto ERROR_SOCK;
  832. }
  833. }
  834. else
  835. {
  836. error = FNET_ERR_INVAL; /* Invalid argument.*/
  837. goto ERROR_SOCK;
  838. }
  839. }
  840. else
  841. {
  842. fnet_error_set(FNET_ERR_BAD_DESC);/* Bad descriptor.*/
  843. goto ERROR;
  844. }
  845. fnet_os_mutex_unlock();
  846. return (result);
  847. ERROR_SOCK:
  848. fnet_socket_set_error(sock, error);
  849. ERROR:
  850. fnet_os_mutex_unlock();
  851. return (SOCKET_ERROR);
  852. }
  853. /************************************************************************
  854. * NAME: recv
  855. *
  856. * DESCRIPTION: This function receives data from a connected socket.
  857. *************************************************************************/
  858. int recv( SOCKET s, char *buf, unsigned int len, unsigned int flags )
  859. {
  860. return recvfrom(s, buf, len, flags, FNET_NULL, FNET_NULL);
  861. }
  862. /************************************************************************
  863. * NAME: recvfrom
  864. *
  865. * DESCRIPTION: This function reads incoming data of socket and captures
  866. * the address from which the data was sent.
  867. *************************************************************************/
  868. int recvfrom( SOCKET s, char *buf, unsigned int len, unsigned int flags, struct sockaddr *from, unsigned int *fromlen )
  869. {
  870. fnet_socket_t *sock;
  871. int error;
  872. int result = FNET_OK;
  873. fnet_os_mutex_lock();
  874. if((sock = fnet_socket_desc_find(s)) != 0)
  875. {
  876. if(buf)
  877. {
  878. /* The sockets must be bound before calling recv.*/
  879. if((sock->local_addr.sa_port == 0) && (sock->protocol_interface->type != SOCK_RAW))
  880. {
  881. error = FNET_ERR_BOUNDREQ; /* The socket has not been bound with bind().*/
  882. goto ERROR_SOCK;
  883. }
  884. if(from && fromlen)
  885. {
  886. if((error = fnet_socket_addr_check_len(&sock->local_addr, (unsigned int)(*fromlen) )) != FNET_OK )
  887. {
  888. goto ERROR_SOCK;
  889. }
  890. }
  891. /* If the socket is shutdowned, return.*/
  892. if(sock->receive_buffer.is_shutdown)
  893. {
  894. error = FNET_ERR_SHUTDOWN;
  895. goto ERROR_SOCK;
  896. }
  897. if(sock->protocol_interface->socket_api->prot_rcv)
  898. {
  899. result = sock->protocol_interface->socket_api->prot_rcv(sock, buf, len, flags, (from && fromlen) ? from : FNET_NULL);
  900. }
  901. else
  902. {
  903. error = FNET_ERR_OPNOTSUPP; /* Operation not supported.*/
  904. goto ERROR_SOCK;
  905. }
  906. }
  907. else
  908. {
  909. error = FNET_ERR_INVAL; /* Invalid argument.*/
  910. goto ERROR_SOCK;
  911. }
  912. }
  913. else
  914. {
  915. fnet_error_set(FNET_ERR_BAD_DESC);/* Bad descriptor.*/
  916. goto ERROR;
  917. }
  918. fnet_os_mutex_unlock();
  919. return (result);
  920. ERROR_SOCK:
  921. fnet_socket_set_error(sock, error);
  922. ERROR:
  923. fnet_os_mutex_unlock();
  924. return (SOCKET_ERROR);
  925. }
  926. /************************************************************************
  927. * NAME: getsockname
  928. *
  929. * DESCRIPTION: This function retrieves the current name
  930. * for the specified socket.
  931. *************************************************************************/
  932. int getsockname( SOCKET s, struct sockaddr *name, unsigned int *namelen )
  933. {
  934. fnet_socket_t *sock;
  935. int error;
  936. fnet_os_mutex_lock();
  937. if((sock = fnet_socket_desc_find(s)) != 0)
  938. {
  939. if((name == 0) || (namelen == 0))
  940. {
  941. error = (int)FNET_ERR_INVAL;
  942. goto ERROR_SOCK;
  943. }
  944. if((error = fnet_socket_addr_check_len(&sock->local_addr, (unsigned int)(*namelen) )) != FNET_OK )
  945. {
  946. goto ERROR_SOCK;
  947. }
  948. if((sock->local_addr.sa_port == 0U) && (sock->protocol_interface->type != SOCK_RAW))
  949. {
  950. error = (int)FNET_ERR_BOUNDREQ; /* The socket has not been bound with bind().*/
  951. goto ERROR_SOCK;
  952. }
  953. fnet_socket_addr_copy(&sock->local_addr, name);
  954. }
  955. else
  956. {
  957. fnet_error_set((int)FNET_ERR_BAD_DESC);/* Bad descriptor.*/
  958. goto ERROR;
  959. }
  960. fnet_os_mutex_unlock();
  961. return (FNET_OK);
  962. ERROR_SOCK:
  963. fnet_socket_set_error(sock, error);
  964. ERROR:
  965. fnet_os_mutex_unlock();
  966. return (SOCKET_ERROR);
  967. }
  968. /************************************************************************
  969. * NAME: getpeername
  970. *
  971. * DESCRIPTION: This function retrieves the name of the peer
  972. * connected to the socket
  973. *************************************************************************/
  974. int getpeername( SOCKET s, struct sockaddr *name, unsigned int *namelen )
  975. {
  976. fnet_socket_t *sock;
  977. int error;
  978. fnet_os_mutex_lock();
  979. if((sock = fnet_socket_desc_find(s)) != 0)
  980. {
  981. if((name == 0) || (namelen == 0) )
  982. {
  983. error = FNET_ERR_INVAL;
  984. goto ERROR_SOCK;
  985. }
  986. if((error = fnet_socket_addr_check_len(&sock->local_addr, (unsigned int)(*namelen) )) != FNET_OK )
  987. {
  988. goto ERROR_SOCK;
  989. }
  990. if(fnet_socket_addr_is_unspecified(&sock->foreign_addr))
  991. {
  992. error = FNET_ERR_NOTCONN; /* Socket is not connected.*/
  993. goto ERROR_SOCK;
  994. }
  995. fnet_socket_addr_copy(&sock->foreign_addr, name);
  996. }
  997. else
  998. {
  999. fnet_error_set(FNET_ERR_BAD_DESC);/* Bad descriptor.*/
  1000. goto ERROR;
  1001. }
  1002. fnet_os_mutex_unlock();
  1003. return (FNET_OK);
  1004. ERROR_SOCK:
  1005. fnet_socket_set_error(sock, error);
  1006. ERROR:
  1007. fnet_os_mutex_unlock();
  1008. return (SOCKET_ERROR);
  1009. }
  1010. /************************************************************************
  1011. * NAME: setsockopt
  1012. *
  1013. * DESCRIPTION: This function sets the current value for a socket option
  1014. * associated with a socket
  1015. *************************************************************************/
  1016. int setsockopt( SOCKET s, int level, int optname, char *optval, unsigned int optlen )
  1017. {
  1018. fnet_socket_t *sock;
  1019. int error;
  1020. int result = FNET_OK;
  1021. fnet_os_mutex_lock();
  1022. if((sock = fnet_socket_desc_find(s)) != 0)
  1023. {
  1024. if(optval && optlen)
  1025. {
  1026. if(level != SOL_SOCKET)
  1027. {
  1028. if(sock->protocol_interface && sock->protocol_interface->socket_api->prot_setsockopt)
  1029. result = sock->protocol_interface->socket_api->prot_setsockopt(sock, level, optname, optval, optlen);
  1030. else
  1031. {
  1032. error = FNET_ERR_INVAL; /* Invalid argument.*/
  1033. goto ERROR_SOCK;
  1034. }
  1035. }
  1036. else
  1037. {
  1038. switch(optname) /* Socket options processing.*/
  1039. {
  1040. case SO_LINGER: /* Linger on close if data present.*/
  1041. if(optlen != sizeof(struct linger))
  1042. {
  1043. error = FNET_ERR_INVAL;
  1044. goto ERROR_SOCK;
  1045. }
  1046. sock->options.linger_ticks = ((struct linger *)optval)->l_linger
  1047. * (1000 / FNET_TIMER_PERIOD_MS);
  1048. if(((struct linger *)optval)->l_onoff)
  1049. sock->options.flags |= optname;
  1050. else
  1051. sock->options.flags &= ~optname;
  1052. break;
  1053. case SO_KEEPALIVE: /* Keep connections alive.*/
  1054. case SO_DONTROUTE: /* Just use interface addresses.*/
  1055. #if FNET_CFG_TCP_URGENT
  1056. case SO_OOBINLINE: /* Leave received OOB data in line.*/
  1057. #endif
  1058. if(optlen < sizeof(int))
  1059. {
  1060. error = FNET_ERR_INVAL;
  1061. goto ERROR_SOCK;
  1062. }
  1063. if(*((int *)optval))
  1064. sock->options.flags |= optname;
  1065. else
  1066. sock->options.flags &= ~optname;
  1067. break;
  1068. case SO_SNDBUF: /* Send buffer size.*/
  1069. case SO_RCVBUF: /* Receive buffer size.*/
  1070. if((optlen < sizeof(unsigned long)))
  1071. {
  1072. error = FNET_ERR_INVAL;
  1073. goto ERROR_SOCK;
  1074. }
  1075. if(optname == SO_SNDBUF)
  1076. sock->send_buffer.count_max = *((unsigned long *)optval);
  1077. else
  1078. sock->receive_buffer.count_max = *((unsigned long *)optval);
  1079. break;
  1080. default:
  1081. error = FNET_ERR_NOPROTOOPT; /* The option is unknown or unsupported. */
  1082. goto ERROR_SOCK;
  1083. }
  1084. }
  1085. }
  1086. else
  1087. {
  1088. error = FNET_ERR_INVAL; /* Invalid argument.*/
  1089. goto ERROR_SOCK;
  1090. }
  1091. }
  1092. else
  1093. {
  1094. fnet_error_set(FNET_ERR_BAD_DESC);/* Bad descriptor.*/
  1095. goto ERROR;
  1096. }
  1097. fnet_os_mutex_unlock();
  1098. return (result);
  1099. ERROR_SOCK:
  1100. fnet_socket_set_error(sock, error);
  1101. ERROR:
  1102. fnet_os_mutex_unlock();
  1103. return (SOCKET_ERROR);
  1104. }
  1105. /************************************************************************
  1106. * NAME: getsockopt
  1107. *
  1108. * DESCRIPTION: This function retrieves the current value for
  1109. * a socket option associated with a socket
  1110. *************************************************************************/
  1111. int getsockopt( SOCKET s, int level, int optname, char *optval, unsigned int *optlen )
  1112. {
  1113. fnet_socket_t *sock;
  1114. int error;
  1115. int result = FNET_OK;
  1116. fnet_os_mutex_lock();
  1117. if((sock = fnet_socket_desc_find(s)) != 0)
  1118. {
  1119. if(optval && optlen)
  1120. {
  1121. if(level != SOL_SOCKET)
  1122. {
  1123. if(sock->protocol_interface && sock->protocol_interface->socket_api->prot_getsockopt)
  1124. result = sock->protocol_interface->socket_api->prot_getsockopt(sock, level, optname, optval, optlen);
  1125. else
  1126. {
  1127. error = FNET_ERR_INVAL; /* Invalid argument.*/
  1128. goto ERROR_SOCK;
  1129. }
  1130. }
  1131. else
  1132. {
  1133. switch(optname) /* Socket options processing.*/
  1134. {
  1135. case SO_LINGER: /* Linger on close if data present.*/
  1136. if(*optlen < sizeof(struct linger))
  1137. {
  1138. error = FNET_ERR_INVAL;
  1139. goto ERROR_SOCK;
  1140. }
  1141. *optlen = sizeof(struct linger);
  1142. ((struct linger *)optval)->l_onoff
  1143. = (unsigned short)((sock->options.flags & SO_LINGER) > 0);
  1144. ((struct linger *)optval)->l_linger
  1145. = (unsigned short)((sock->options.linger_ticks * FNET_TIMER_PERIOD_MS) / 1000);
  1146. sock->options.linger_ticks = ((struct linger *)optval)->l_linger;
  1147. break;
  1148. case SO_KEEPALIVE: /* Keep connections alive.*/
  1149. case SO_DONTROUTE: /* Just use interface addresses.*/
  1150. #if FNET_CFG_TCP_URGENT
  1151. case SO_OOBINLINE: /* Leave received OOB data in line.*/
  1152. #endif
  1153. if(*optlen < sizeof(int))
  1154. {
  1155. error = FNET_ERR_INVAL;
  1156. goto ERROR_SOCK;
  1157. }
  1158. *optlen = sizeof(int);
  1159. *((int*)optval) = (int)((sock->options.flags & optname) > 0);
  1160. break;
  1161. case SO_ACCEPTCONN: /* Socket is listening. */
  1162. if(*optlen < sizeof(int))
  1163. {
  1164. error = FNET_ERR_INVAL;
  1165. goto ERROR_SOCK;
  1166. }
  1167. *optlen = sizeof(int);
  1168. *((int*)optval) = (int)(sock->state == SS_LISTENING);
  1169. break;
  1170. case SO_SNDBUF: /* Send buffer size.*/
  1171. case SO_RCVBUF: /* Receive buffer size.*/
  1172. if(*optlen < sizeof(unsigned long))
  1173. {
  1174. error = FNET_ERR_INVAL;
  1175. goto ERROR_SOCK;
  1176. }
  1177. *optlen = sizeof(unsigned long);
  1178. if(optname == SO_SNDBUF)
  1179. *((unsigned long*)optval)=sock->send_buffer.count_max;
  1180. else
  1181. *((unsigned long *)optval) = sock->receive_buffer.count_max;
  1182. break;
  1183. case SO_STATE: /* State of the socket.*/
  1184. if(*optlen < sizeof(fnet_socket_state_t))
  1185. {
  1186. error = FNET_ERR_INVAL;
  1187. goto ERROR_SOCK;
  1188. }
  1189. *optlen = sizeof(fnet_socket_state_t);
  1190. *((fnet_socket_state_t*)optval) = sock->state;
  1191. break;
  1192. case SO_RCVNUM: /* Use to determine the amount of data pending in the network's input buffer that can be read from socket.*/
  1193. case SO_SNDNUM: /* Use to determine the amount of data in the network's output buffer.*/
  1194. if(*optlen < sizeof(unsigned long))
  1195. {
  1196. error = FNET_ERR_INVAL;
  1197. goto ERROR_SOCK;
  1198. }
  1199. *optlen = sizeof(unsigned long);
  1200. if(optname == SO_RCVNUM)
  1201. *((unsigned long*)optval) = sock->receive_buffer.count;
  1202. else
  1203. *((unsigned long *)optval) = sock->send_buffer.count;
  1204. break;
  1205. case SO_ERROR: /* Socket error.*/
  1206. if(*optlen < sizeof(int))
  1207. {
  1208. error = FNET_ERR_INVAL;
  1209. goto ERROR_SOCK;
  1210. }
  1211. *optlen = sizeof(int);
  1212. *((int *)optval) = sock->options.error;
  1213. sock->options.error = FNET_OK; /* Reset error.*/
  1214. break;
  1215. case SO_TYPE:
  1216. if(*optlen < sizeof(int))
  1217. {
  1218. error = FNET_ERR_INVAL;
  1219. goto ERROR_SOCK;
  1220. }
  1221. *optlen = sizeof(int);
  1222. *((int *)optval) = (sock->protocol_interface ? sock->protocol_interface->type : 0);
  1223. break;
  1224. default:
  1225. error = FNET_ERR_NOPROTOOPT; /* The option is unknown or unsupported. */
  1226. goto ERROR_SOCK;
  1227. }/* case*/
  1228. }/* else */
  1229. }
  1230. else
  1231. {
  1232. error = FNET_ERR_INVAL; /* Invalid argument.*/
  1233. goto ERROR_SOCK;
  1234. }
  1235. }
  1236. else
  1237. {
  1238. fnet_error_set(FNET_ERR_BAD_DESC);/* Bad descriptor.*/
  1239. goto ERROR;
  1240. }
  1241. fnet_os_mutex_unlock();
  1242. return (result);
  1243. ERROR_SOCK:
  1244. fnet_socket_set_error(sock, error);
  1245. ERROR:
  1246. fnet_os_mutex_unlock();
  1247. return (SOCKET_ERROR);
  1248. }
  1249. /************************************************************************
  1250. * NAME: fnet_socket_buffer_release
  1251. *
  1252. * DESCRIPTION: Discards any buffers in the socket buffer
  1253. *************************************************************************/
  1254. void fnet_socket_buffer_release( fnet_socket_buffer_t *sb )
  1255. {
  1256. fnet_netbuf_t *nb_ptr;
  1257. fnet_netbuf_t *tmp_nb_ptr;
  1258. fnet_isr_lock();
  1259. if(sb && sb->net_buf_chain)
  1260. {
  1261. nb_ptr = sb->net_buf_chain;
  1262. while(nb_ptr != 0)
  1263. {
  1264. tmp_nb_ptr = nb_ptr->next_chain;
  1265. fnet_netbuf_free_chain(nb_ptr);
  1266. nb_ptr = tmp_nb_ptr;
  1267. }
  1268. sb->net_buf_chain = 0;
  1269. sb->count = 0;
  1270. }
  1271. fnet_isr_unlock();
  1272. }
  1273. /************************************************************************
  1274. * NAME: fnet_socket_buffer_append_record
  1275. *
  1276. * DESCRIPTION: Append the record to the end of the socket buffer.
  1277. *************************************************************************/
  1278. int fnet_socket_buffer_append_record( fnet_socket_buffer_t *sb, fnet_netbuf_t *nb )
  1279. {
  1280. fnet_isr_lock();
  1281. if((nb->total_length + sb->count) > sb->count_max)
  1282. {
  1283. fnet_isr_unlock();
  1284. return FNET_ERR;
  1285. }
  1286. sb->net_buf_chain = fnet_netbuf_concat(sb->net_buf_chain, nb);
  1287. sb->count += nb->total_length;
  1288. fnet_isr_unlock();
  1289. return FNET_OK;
  1290. }
  1291. /************************************************************************
  1292. * NAME: fnet_socket_buffer_append_address
  1293. *
  1294. * DESCRIPTION: Constract net_buf chain and add it to the queue.
  1295. * The chain…

Large files files are truncated, but you can click here to view the full file