ieee802154_sockif.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. /****************************************************************************
  2. * net/socket/ieee802154_sockif.c
  3. *
  4. * Copyright (C) 2017 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <sys/types.h>
  40. #include <sys/socket.h>
  41. #include <stdbool.h>
  42. #include <string.h>
  43. #include <assert.h>
  44. #include <errno.h>
  45. #include <debug.h>
  46. #include <socket/socket.h>
  47. #include <netpacket/ieee802154.h>
  48. #include <nuttx/net/net.h>
  49. #include <nuttx/net/radiodev.h>
  50. #include "ieee802154/ieee802154.h"
  51. #ifdef CONFIG_NET_IEEE802154
  52. /****************************************************************************
  53. * Private Function Prototypes
  54. ****************************************************************************/
  55. static int ieee802154_setup(FAR struct socket *psock, int protocol);
  56. static sockcaps_t ieee802154_sockcaps(FAR struct socket *psock);
  57. static void ieee802154_addref(FAR struct socket *psock);
  58. static int ieee802154_bind(FAR struct socket *psock,
  59. FAR const struct sockaddr *addr, socklen_t addrlen);
  60. static int ieee802154_getsockname(FAR struct socket *psock,
  61. FAR struct sockaddr *addr, FAR socklen_t *addrlen);
  62. static int ieee802154_getpeername(FAR struct socket *psock,
  63. FAR struct sockaddr *addr, FAR socklen_t *addrlen);
  64. static int ieee802154_listen(FAR struct socket *psock, int backlog);
  65. static int ieee802154_connect(FAR struct socket *psock,
  66. FAR const struct sockaddr *addr, socklen_t addrlen);
  67. static int ieee802154_accept(FAR struct socket *psock,
  68. FAR struct sockaddr *addr, FAR socklen_t *addrlen,
  69. FAR struct socket *newsock);
  70. #ifndef CONFIG_DISABLE_POLL
  71. static int ieee802154_poll_local(FAR struct socket *psock,
  72. FAR struct pollfd *fds, bool setup);
  73. #endif
  74. static ssize_t ieee802154_send(FAR struct socket *psock,
  75. FAR const void *buf, size_t len, int flags);
  76. static ssize_t ieee802154_sendto(FAR struct socket *psock,
  77. FAR const void *buf, size_t len, int flags,
  78. FAR const struct sockaddr *to, socklen_t tolen);
  79. static int ieee802154_close(FAR struct socket *psock);
  80. /****************************************************************************
  81. * Public Data
  82. ****************************************************************************/
  83. const struct sock_intf_s g_ieee802154_sockif =
  84. {
  85. ieee802154_setup, /* si_setup */
  86. ieee802154_sockcaps, /* si_sockcaps */
  87. ieee802154_addref, /* si_addref */
  88. ieee802154_bind, /* si_bind */
  89. ieee802154_getsockname, /* si_getsockname */
  90. ieee802154_getpeername, /* si_getpeername */
  91. ieee802154_listen, /* si_listen */
  92. ieee802154_connect, /* si_connect */
  93. ieee802154_accept, /* si_accept */
  94. #ifndef CONFIG_DISABLE_POLL
  95. ieee802154_poll_local, /* si_poll */
  96. #endif
  97. ieee802154_send, /* si_send */
  98. ieee802154_sendto, /* si_sendto */
  99. #ifdef CONFIG_NET_SENDFILE
  100. NULL, /* si_sendfile */
  101. #endif
  102. ieee802154_recvfrom, /* si_recvfrom */
  103. ieee802154_close /* si_close */
  104. };
  105. /****************************************************************************
  106. * Private Functions
  107. ****************************************************************************/
  108. /****************************************************************************
  109. * Name: ieee802154_sockif_alloc
  110. *
  111. * Description:
  112. * Allocate and attach a PF_IEEE802154 connection structure.
  113. *
  114. * Assumptions:
  115. * The network is locked
  116. *
  117. ****************************************************************************/
  118. static int ieee802154_sockif_alloc(FAR struct socket *psock)
  119. {
  120. /* Allocate the packet socket connection structure and save in the new
  121. * socket instance.
  122. */
  123. FAR struct ieee802154_conn_s *conn = ieee802154_conn_alloc();
  124. if (conn == NULL)
  125. {
  126. /* Failed to reserve a connection structure */
  127. return -ENOMEM;
  128. }
  129. /* Set the reference count on the connection structure. This reference
  130. * count will be incremented only if the socket is dup'ed
  131. */
  132. DEBUGASSERT(conn->crefs == 0);
  133. conn->crefs = 1;
  134. /* Save the pre-allocated connection in the socket structure */
  135. psock->s_conn = conn;
  136. return OK;
  137. }
  138. /****************************************************************************
  139. * Name: ieee802154_setup
  140. *
  141. * Description:
  142. * Called for socket() to verify that the provided socket type and
  143. * protocol are usable by this address family. Perform any family-
  144. * specific socket fields.
  145. *
  146. * Input Parameters:
  147. * psock A pointer to a user allocated socket structure to be
  148. * initialized.
  149. * protocol (see sys/socket.h)
  150. *
  151. * Returned Value:
  152. * Zero (OK) is returned on success. Otherwise, a negated errno value is
  153. * returned.
  154. *
  155. ****************************************************************************/
  156. static int ieee802154_setup(FAR struct socket *psock, int protocol)
  157. {
  158. /* Allocate the appropriate connection structure. This reserves the
  159. * the connection structure is is unallocated at this point. It will
  160. * not actually be initialized until the socket is connected.
  161. *
  162. * Only SOCK_DGRAM is supported (since the MAC header is stripped)
  163. */
  164. if (psock->s_type == SOCK_DGRAM)
  165. {
  166. return ieee802154_sockif_alloc(psock);
  167. }
  168. else
  169. {
  170. return -EPROTONOSUPPORT;
  171. }
  172. }
  173. /****************************************************************************
  174. * Name: ieee802154_sockcaps
  175. *
  176. * Description:
  177. * Return the bit encoded capabilities of this socket.
  178. *
  179. * Input Parameters:
  180. * psock - Socket structure of the socket whose capabilities are being
  181. * queried.
  182. *
  183. * Returned Value:
  184. * The set of socket cababilities is returned.
  185. *
  186. ****************************************************************************/
  187. static sockcaps_t ieee802154_sockcaps(FAR struct socket *psock)
  188. {
  189. return 0;
  190. }
  191. /****************************************************************************
  192. * Name: ieee802154_addref
  193. *
  194. * Description:
  195. * Increment the refernce count on the underlying connection structure.
  196. *
  197. * Input Parameters:
  198. * psock - Socket structure of the socket whose reference count will be
  199. * incremented.
  200. *
  201. * Returned Value:
  202. * None
  203. *
  204. ****************************************************************************/
  205. static void ieee802154_addref(FAR struct socket *psock)
  206. {
  207. FAR struct ieee802154_conn_s *conn;
  208. DEBUGASSERT(psock != NULL && psock->s_conn != NULL &&
  209. psock->s_type == SOCK_DGRAM);
  210. conn = (FAR struct ieee802154_conn_s *)psock->s_conn;
  211. DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
  212. conn->crefs++;
  213. }
  214. /****************************************************************************
  215. * Name: ieee802154_connect
  216. *
  217. * Description:
  218. * ieee802154_connect() connects the local socket referred to by the structure
  219. * 'psock' to the address specified by 'addr'. The addrlen argument
  220. * specifies the size of 'addr'. The format of the address in 'addr' is
  221. * determined by the address space of the socket 'psock'.
  222. *
  223. * If the socket 'psock' is of type SOCK_DGRAM then 'addr' is the address
  224. * to which datagrams are sent by default, and the only address from which
  225. * datagrams are received. If the socket is of type SOCK_STREAM or
  226. * SOCK_SEQPACKET, this call attempts to make a connection to the socket
  227. * that is bound to the address specified by 'addr'.
  228. *
  229. * Generally, connection-based protocol sockets may successfully
  230. * ieee802154_connect() only once; connectionless protocol sockets may use
  231. * ieee802154_connect() multiple times to change their association.
  232. * Connectionless sockets may dissolve the association by connecting to
  233. * an address with the sa_family member of sockaddr set to AF_UNSPEC.
  234. *
  235. * Input Parameters:
  236. * psock Pointer to a socket structure initialized by psock_socket()
  237. * addr Server address (form depends on type of socket)
  238. * addrlen Length of actual 'addr'
  239. *
  240. * Returned Value:
  241. * 0 on success; a negated errno value on failue. See connect() for the
  242. * list of appropriate errno values to be returned.
  243. *
  244. ****************************************************************************/
  245. static int ieee802154_connect(FAR struct socket *psock,
  246. FAR const struct sockaddr *addr,
  247. socklen_t addrlen)
  248. {
  249. FAR struct ieee802154_conn_s *conn;
  250. FAR struct sockaddr_ieee802154_s *ieeeaddr;
  251. int ret;
  252. DEBUGASSERT(psock != NULL || addr != NULL);
  253. conn = (FAR struct ieee802154_conn_s *)psock->s_conn;
  254. DEBUGASSERT(conn != NULL);
  255. /* Verify the address family */
  256. if (addr->sa_family == AF_IEEE802154)
  257. {
  258. /* Save the "connection" address */
  259. ieeeaddr = (FAR struct sockaddr_ieee802154_s *)addr;
  260. memcpy(&conn->raddr, &ieeeaddr->sa_addr,
  261. sizeof(struct ieee802154_saddr_s));
  262. /* Mark the socket as connected. */
  263. psock->s_flags |= _SF_CONNECTED;
  264. ret = OK;
  265. }
  266. else
  267. {
  268. /* The specified address is not a valid address for the address family
  269. * of the specified socket.
  270. */
  271. ret = -EAFNOSUPPORT;
  272. }
  273. return ret;
  274. }
  275. /****************************************************************************
  276. * Name: ieee802154_accept
  277. *
  278. * Description:
  279. * The ieee802154_accept function is used with connection-based socket types
  280. * (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
  281. * connection request on the queue of pending connections, creates a new
  282. * connected socket with mostly the same properties as 'sockfd', and
  283. * allocates a new socket descriptor for the socket, which is returned. The
  284. * newly created socket is no longer in the listening state. The original
  285. * socket 'sockfd' is unaffected by this call. Per file descriptor flags
  286. * are not inherited across an ieee802154_accept.
  287. *
  288. * The 'sockfd' argument is a socket descriptor that has been created with
  289. * socket(), bound to a local address with bind(), and is listening for
  290. * connections after a call to listen().
  291. *
  292. * On return, the 'addr' structure is filled in with the address of the
  293. * connecting entity. The 'addrlen' argument initially contains the size
  294. * of the structure pointed to by 'addr'; on return it will contain the
  295. * actual length of the address returned.
  296. *
  297. * If no pending connections are present on the queue, and the socket is
  298. * not marked as non-blocking, ieee802154_accept blocks the caller until a
  299. * connection is present. If the socket is marked non-blocking and no
  300. * pending connections are present on the queue, ieee802154_accept returns
  301. * EAGAIN.
  302. *
  303. * Input Parameters:
  304. * psock Reference to the listening socket structure
  305. * addr Receives the address of the connecting client
  306. * addrlen Input: allocated size of 'addr', Return: returned size of 'addr'
  307. * newsock Location to return the accepted socket information.
  308. *
  309. * Returned Value:
  310. * Returns 0 (OK) on success. On failure, it returns a negated errno
  311. * value. See accept() for a desrciption of the approriate error value.
  312. *
  313. * Assumptions:
  314. * The network is locked.
  315. *
  316. ****************************************************************************/
  317. static int ieee802154_accept(FAR struct socket *psock,
  318. FAR struct sockaddr *addr,
  319. FAR socklen_t *addrlen,
  320. FAR struct socket *newsock)
  321. {
  322. return -EAFNOSUPPORT;
  323. }
  324. /****************************************************************************
  325. * Name: ieee802154_bind
  326. *
  327. * Description:
  328. * ieee802154_bind() gives the socket 'psock' the local address 'addr'.
  329. * 'addr' is 'addrlen' bytes long. Traditionally, this is called
  330. * "assigning a name to a socket." When a socket is created with
  331. * socket(), it exists in a name space (address family) but has no name
  332. * assigned.
  333. *
  334. * Input Parameters:
  335. * psock Socket structure of the socket to bind
  336. * addr Socket local address
  337. * addrlen Length of 'addr'
  338. *
  339. * Returned Value:
  340. * 0 on success; A negated errno value is returned on failure. See
  341. * bind() for a list a appropriate error values.
  342. *
  343. ****************************************************************************/
  344. static int ieee802154_bind(FAR struct socket *psock,
  345. FAR const struct sockaddr *addr, socklen_t addrlen)
  346. {
  347. FAR const struct sockaddr_ieee802154_s *iaddr;
  348. FAR struct radio_driver_s *radio;
  349. FAR struct ieee802154_conn_s *conn;
  350. DEBUGASSERT(psock != NULL && addr != NULL);
  351. /* Verify that a valid address has been provided */
  352. if (addr->sa_family != AF_IEEE802154 ||
  353. addrlen < sizeof(struct sockaddr_ieee802154_s))
  354. {
  355. nerr("ERROR: Invalid family: %u or address length: %d < %d\n",
  356. addr->sa_family, addrlen, sizeof(struct sockaddr_ieee802154_s));
  357. return -EBADF;
  358. }
  359. /* Bind a PF_IEEE802154 socket to an network device. */
  360. if (psock->s_type != SOCK_DGRAM)
  361. {
  362. nerr("ERROR: Invalid socket type: %u\n", psock->s_type);
  363. return -EBADF;
  364. }
  365. /* Verify that the socket is not already bound. */
  366. if (_SS_ISBOUND(psock->s_flags))
  367. {
  368. nerr("ERROR: Already bound\n");
  369. return -EINVAL;
  370. }
  371. iaddr = (FAR const struct sockaddr_ieee802154_s *)addr;
  372. /* Very that some address was provided.
  373. *
  374. * REVISIT: Currently and explict address must be assigned. Should we
  375. * support some moral equivalent to INADDR_ANY?
  376. */
  377. if (iaddr->sa_addr.s_mode == IEEE802154_ADDRMODE_NONE)
  378. {
  379. nerr("ERROR: No address provided\n");
  380. return -EADDRNOTAVAIL;
  381. }
  382. conn = (FAR struct ieee802154_conn_s *)psock->s_conn;
  383. /* Find the device associated with the requested address */
  384. radio = ieee802154_find_device(conn, &iaddr->sa_addr);
  385. if (radio == NULL)
  386. {
  387. nerr("ERROR: No radio at this address\n");
  388. return -ENODEV;
  389. }
  390. /* Save the address as the socket's local address */
  391. memcpy(&conn->laddr, &iaddr->sa_addr, sizeof(struct ieee802154_saddr_s));
  392. /* Mark the socket bound */
  393. psock->s_flags |= _SF_BOUND;
  394. return OK;
  395. }
  396. /****************************************************************************
  397. * Name: ieee802154_getsockname
  398. *
  399. * Description:
  400. * The ieee802154_getsockname() function retrieves the locally-bound name of the
  401. * specified packet socket, stores this address in the sockaddr structure
  402. * pointed to by the 'addr' argument, and stores the length of this
  403. * address in the object pointed to by the 'addrlen' argument.
  404. *
  405. * If the actual length of the address is greater than the length of the
  406. * supplied sockaddr structure, the stored address will be truncated.
  407. *
  408. * If the socket has not been bound to a local name, the value stored in
  409. * the object pointed to by address is unspecified.
  410. *
  411. * Input Parameters:
  412. * psock Socket structure of the socket to be queried
  413. * addr sockaddr structure to receive data [out]
  414. * addrlen Length of sockaddr structure [in/out]
  415. *
  416. * Returned Value:
  417. * On success, 0 is returned, the 'addr' argument points to the address
  418. * of the socket, and the 'addrlen' argument points to the length of the
  419. * address. Otherwise, a negated errno value is returned. See
  420. * getsockname() for the list of appropriate error numbers.
  421. *
  422. ****************************************************************************/
  423. static int ieee802154_getsockname(FAR struct socket *psock,
  424. FAR struct sockaddr *addr, FAR
  425. socklen_t *addrlen)
  426. {
  427. FAR struct ieee802154_conn_s *conn;
  428. FAR struct sockaddr_ieee802154_s tmp;
  429. socklen_t copylen;
  430. DEBUGASSERT(psock != NULL && addr != NULL && addrlen != NULL);
  431. conn = (FAR struct ieee802154_conn_s *)psock->s_conn;
  432. DEBUGASSERT(conn != NULL);
  433. /* Create a copy of the full address on the stack */
  434. tmp.sa_family = AF_IEEE802154;
  435. memcpy(&tmp.sa_addr, &conn->laddr, sizeof(struct ieee802154_saddr_s));
  436. /* Copy to the user buffer, truncating if necessary */
  437. copylen = sizeof(struct sockaddr_ieee802154_s);
  438. if (copylen > *addrlen)
  439. {
  440. copylen = *addrlen;
  441. }
  442. memcpy(addr, &tmp, copylen);
  443. /* Return the actual size transferred */
  444. *addrlen = copylen;
  445. return OK;
  446. }
  447. /****************************************************************************
  448. * Name: ieee802154_getpeername
  449. *
  450. * Description:
  451. * The ieee802154_getpeername() function retrieves the remote-connectd name of the
  452. * specified packet socket, stores this address in the sockaddr structure
  453. * pointed to by the 'addr' argument, and stores the length of this
  454. * address in the object pointed to by the 'addrlen' argument.
  455. *
  456. * If the actual length of the address is greater than the length of the
  457. * supplied sockaddr structure, the stored address will be truncated.
  458. *
  459. * If the socket has not been bound to a local name, the value stored in
  460. * the object pointed to by address is unspecified.
  461. *
  462. * Parameters:
  463. * psock Socket structure of the socket to be queried
  464. * addr sockaddr structure to receive data [out]
  465. * addrlen Length of sockaddr structure [in/out]
  466. *
  467. * Returned Value:
  468. * On success, 0 is returned, the 'addr' argument points to the address
  469. * of the socket, and the 'addrlen' argument points to the length of the
  470. * address. Otherwise, a negated errno value is returned. See
  471. * getpeername() for the list of appropriate error numbers.
  472. *
  473. ****************************************************************************/
  474. static int ieee802154_getpeername(FAR struct socket *psock,
  475. FAR struct sockaddr *addr, FAR
  476. socklen_t *addrlen)
  477. {
  478. FAR struct ieee802154_conn_s *conn;
  479. FAR struct sockaddr_ieee802154_s tmp;
  480. socklen_t copylen;
  481. DEBUGASSERT(psock != NULL && addr != NULL && addrlen != NULL);
  482. conn = (FAR struct ieee802154_conn_s *)psock->s_conn;
  483. DEBUGASSERT(conn != NULL);
  484. /* Create a copy of the full address on the stack */
  485. tmp.sa_family = PF_IEEE802154;
  486. memcpy(&tmp.sa_addr, &conn->raddr, sizeof(struct ieee802154_saddr_s));
  487. /* Copy to the user buffer, truncating if necessary */
  488. copylen = sizeof(struct sockaddr_ieee802154_s);
  489. if (copylen > *addrlen)
  490. {
  491. copylen = *addrlen;
  492. }
  493. memcpy(addr, &tmp, copylen);
  494. /* Return the actual size transferred */
  495. *addrlen = copylen;
  496. return OK;
  497. }
  498. /****************************************************************************
  499. * Name: ieee802154_listen
  500. *
  501. * Description:
  502. * To accept connections, a socket is first created with psock_socket(), a
  503. * willingness to accept incoming connections and a queue limit for
  504. * incoming connections are specified with psock_listen(), and then the
  505. * connections are accepted with psock_accept(). For the case of
  506. * PF_IEEE802154 sockets, psock_listen() calls this function. The listen()
  507. * call does not apply only to PF_IEEE802154 sockets.
  508. *
  509. * Input Parameters:
  510. * psock Reference to an internal, boound socket structure.
  511. * backlog The maximum length the queue of pending connections may grow.
  512. * If a connection request arrives with the queue full, the client
  513. * may receive an error with an indication of ECONNREFUSED or,
  514. * if the underlying protocol supports retransmission, the request
  515. * may be ignored so that retries succeed.
  516. *
  517. * Returned Value:
  518. * On success, zero is returned. On error, a negated errno value is
  519. * returned. See list() for the set of appropriate error values.
  520. *
  521. ****************************************************************************/
  522. int ieee802154_listen(FAR struct socket *psock, int backlog)
  523. {
  524. return -EOPNOTSUPP;
  525. }
  526. /****************************************************************************
  527. * Name: ieee802154_poll
  528. *
  529. * Description:
  530. * The standard poll() operation redirects operations on socket descriptors
  531. * to net_poll which, indiectly, calls to function.
  532. *
  533. * Input Parameters:
  534. * psock - An instance of the internal socket structure.
  535. * fds - The structure describing the events to be monitored, OR NULL if
  536. * this is a request to stop monitoring events.
  537. * setup - true: Setup up the poll; false: Teardown the poll
  538. *
  539. * Returned Value:
  540. * 0: Success; Negated errno on failure
  541. *
  542. ****************************************************************************/
  543. #ifndef CONFIG_DISABLE_POLL
  544. static int ieee802154_poll_local(FAR struct socket *psock,
  545. FAR struct pollfd *fds, bool setup)
  546. {
  547. /* We should need to support some kind of write ahead buffering for this
  548. * feature.
  549. */
  550. #warning Missing logic
  551. return -ENOSYS;
  552. }
  553. #endif /* !CONFIG_DISABLE_POLL */
  554. /****************************************************************************
  555. * Name: ieee802154_send
  556. *
  557. * Description:
  558. * Socket send() method for the PF_IEEE802154 socket.
  559. *
  560. * Input Parameters:
  561. * psock An instance of the internal socket structure.
  562. * buf Data to send
  563. * len Length of data to send
  564. * flags Send flags
  565. *
  566. * Returned Value:
  567. * On success, returns the number of characters sent. On error, a negated
  568. * errno value is returned (see send() for the list of appropriate error
  569. * values.
  570. *
  571. ****************************************************************************/
  572. static ssize_t ieee802154_send(FAR struct socket *psock, FAR const void *buf,
  573. size_t len, int flags)
  574. {
  575. struct sockaddr_ieee802154_s to;
  576. FAR struct ieee802154_conn_s *conn;
  577. ssize_t ret;
  578. DEBUGASSERT(psock != NULL || buf != NULL);
  579. conn = (FAR struct ieee802154_conn_s *)psock->s_conn;
  580. DEBUGASSERT(conn != NULL);
  581. /* Only SOCK_DGRAM is supported (because the MAC header is stripped) */
  582. if (psock->s_type == SOCK_DGRAM)
  583. {
  584. /* send() may be used only if the socket has been connected. */
  585. if (!_SS_ISCONNECTED(psock->s_flags) ||
  586. conn->raddr.s_mode == IEEE802154_ADDRMODE_NONE)
  587. {
  588. ret = -ENOTCONN;
  589. }
  590. else
  591. {
  592. to.sa_family = AF_IEEE802154;
  593. memcpy(&to.sa_addr, &conn->raddr,
  594. sizeof(struct ieee802154_saddr_s));
  595. /* Then perform the send() as sendto() */
  596. ret = psock_ieee802154_sendto(psock, buf, len, flags,
  597. (FAR const struct sockaddr *)&to,
  598. sizeof(struct sockaddr_ieee802154_s));
  599. }
  600. }
  601. else
  602. {
  603. /* EDESTADDRREQ. Signifies that the socket is not connection-mode and
  604. * no peer address is set.
  605. */
  606. ret = -EDESTADDRREQ;
  607. }
  608. return ret;
  609. }
  610. /****************************************************************************
  611. * Name: ieee802154_sendto
  612. *
  613. * Description:
  614. * Implements the sendto() operation for the case of the PF_IEEE802154
  615. * socket.
  616. *
  617. * Input Parameters:
  618. * psock A pointer to a NuttX-specific, internal socket structure
  619. * buf Data to send
  620. * len Length of data to send
  621. * flags Send flags
  622. * to Address of recipient
  623. * tolen The length of the address structure
  624. *
  625. * Returned Value:
  626. * On success, returns the number of characters sent. On error, a negated
  627. * errno value is returned (see send_to() for the list of appropriate error
  628. * values.
  629. *
  630. ****************************************************************************/
  631. static ssize_t ieee802154_sendto(FAR struct socket *psock, FAR const void *buf,
  632. size_t len, int flags,
  633. FAR const struct sockaddr *to, socklen_t tolen)
  634. {
  635. ssize_t ret;
  636. /* Only SOCK_DGRAM is supported (because the MAC header is stripped) */
  637. if (psock->s_type == SOCK_DGRAM)
  638. {
  639. /* Raw packet send */
  640. ret = psock_ieee802154_sendto(psock, buf, len, flags, to, tolen);
  641. }
  642. else
  643. {
  644. /* EDESTADDRREQ. Signifies that the socket is not connection-mode and
  645. * no peer address is set.
  646. */
  647. ret = -EDESTADDRREQ;
  648. }
  649. return ret;
  650. }
  651. /****************************************************************************
  652. * Name: ieee802154_close
  653. *
  654. * Description:
  655. * Performs the close operation on a PF_IEEE802154 socket instance
  656. *
  657. * Input Parameters:
  658. * psock Socket instance
  659. *
  660. * Returned Value:
  661. * 0 on success; a negated errno value is returned on any failure.
  662. *
  663. * Assumptions:
  664. *
  665. ****************************************************************************/
  666. static int ieee802154_close(FAR struct socket *psock)
  667. {
  668. /* Perform some pre-close operations for the PF_IEEE802154 address type */
  669. switch (psock->s_type)
  670. {
  671. case SOCK_DGRAM:
  672. {
  673. FAR struct ieee802154_conn_s *conn = psock->s_conn;
  674. /* Is this the last reference to the connection structure (there
  675. * could be more if the socket was dup'ed).
  676. */
  677. if (conn->crefs <= 1)
  678. {
  679. /* Yes... free the connection structure */
  680. conn->crefs = 0; /* No more references on the connection */
  681. ieee802154_conn_free(psock->s_conn); /* Free network resources */
  682. }
  683. else
  684. {
  685. /* No.. Just decrement the reference count */
  686. conn->crefs--;
  687. }
  688. return OK;
  689. }
  690. default:
  691. return -EBADF;
  692. }
  693. }
  694. /****************************************************************************
  695. * Public Functions
  696. ****************************************************************************/
  697. #endif /* CONFIG_NET_IEEE802154 */