bluetooth_conn.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /****************************************************************************
  2. * net/bluetooth/bluetooth_conn.c
  3. *
  4. * Copyright (C) 2018 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 the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. The name of the author may not be used to endorse or promote
  17. * products derived from this software without specific prior
  18. * written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  21. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  24. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  26. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  28. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. ****************************************************************************/
  33. /****************************************************************************
  34. * Included Files
  35. ****************************************************************************/
  36. #include <nuttx/config.h>
  37. #include <semaphore.h>
  38. #include <string.h>
  39. #include <assert.h>
  40. #include <errno.h>
  41. #include <debug.h>
  42. #include <netpacket/bluetooth.h>
  43. #include <arch/irq.h>
  44. #include <nuttx/mm/iob.h>
  45. #include <nuttx/net/netconfig.h>
  46. #include <nuttx/net/net.h>
  47. #include <nuttx/net/netdev.h>
  48. #include <nuttx/net/bluetooth.h>
  49. #include "devif/devif.h"
  50. #include "bluetooth/bluetooth.h"
  51. #ifdef CONFIG_NET_BLUETOOTH
  52. /****************************************************************************
  53. * Private Data
  54. ****************************************************************************/
  55. /* The array containing all packet socket connections. Protected via the
  56. * network lock.
  57. */
  58. static struct bluetooth_conn_s
  59. g_bluetooth_connections[CONFIG_NET_BLUETOOTH_NCONNS];
  60. /* A list of all free packet socket connections */
  61. static dq_queue_t g_free_bluetooth_connections;
  62. /* A list of all allocated packet socket connections */
  63. static dq_queue_t g_active_bluetooth_connections;
  64. static const bt_addr_t g_any_addr =
  65. {
  66. BT_ADDR_ANY
  67. };
  68. /****************************************************************************
  69. * Public Functions
  70. ****************************************************************************/
  71. /****************************************************************************
  72. * Name: bluetooth_conn_initialize
  73. *
  74. * Description:
  75. * Initialize the Bluetooth connection structure allocator. Called
  76. * once and only from bluetooth_initialize().
  77. *
  78. * Assumptions:
  79. * Called early in the initialization sequence
  80. *
  81. ****************************************************************************/
  82. void bluetooth_conn_initialize(void)
  83. {
  84. int i;
  85. /* Initialize the queues */
  86. dq_init(&g_free_bluetooth_connections);
  87. dq_init(&g_active_bluetooth_connections);
  88. for (i = 0; i < CONFIG_NET_BLUETOOTH_NCONNS; i++)
  89. {
  90. /* Link each pre-allocated connection structure into the free list. */
  91. dq_addlast(&g_bluetooth_connections[i].bc_node,
  92. &g_free_bluetooth_connections);
  93. }
  94. }
  95. /****************************************************************************
  96. * Name: bluetooth_conn_alloc()
  97. *
  98. * Description:
  99. * Allocate a new, uninitialized packet socket connection structure. This
  100. * is normally something done by the implementation of the socket() API
  101. *
  102. ****************************************************************************/
  103. FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void)
  104. {
  105. FAR struct bluetooth_conn_s *conn;
  106. /* The free list is protected by the network lock */
  107. net_lock();
  108. conn = (FAR struct bluetooth_conn_s *)
  109. dq_remfirst(&g_free_bluetooth_connections);
  110. if (conn)
  111. {
  112. /* Enqueue the connection into the active list */
  113. memset(conn, 0, sizeof(struct bluetooth_conn_s));
  114. dq_addlast(&conn->bc_node, &g_active_bluetooth_connections);
  115. }
  116. net_unlock();
  117. return conn;
  118. }
  119. /****************************************************************************
  120. * Name: bluetooth_conn_free()
  121. *
  122. * Description:
  123. * Free a packet socket connection structure that is no longer in use.
  124. * This should be done by the implementation of close().
  125. *
  126. ****************************************************************************/
  127. void bluetooth_conn_free(FAR struct bluetooth_conn_s *conn)
  128. {
  129. FAR struct bluetooth_container_s *container;
  130. FAR struct bluetooth_container_s *next;
  131. /* The free list is protected by the network lock. */
  132. DEBUGASSERT(conn->bc_crefs == 0);
  133. /* Remove the connection from the active list */
  134. net_lock();
  135. dq_rem(&conn->bc_node, &g_active_bluetooth_connections);
  136. /* Check if there any any frames attached to the container */
  137. for (container = conn->bc_rxhead; container != NULL; container = next)
  138. {
  139. /* Remove the frame from the list */
  140. next = container->bn_flink;
  141. container->bn_flink = NULL;
  142. /* Free the contained frame data (should be only one in chain) */
  143. if (container->bn_iob)
  144. {
  145. iob_free(container->bn_iob);
  146. }
  147. /* And free the container itself */
  148. bluetooth_container_free(container);
  149. }
  150. /* Free the connection */
  151. dq_addlast(&conn->bc_node, &g_free_bluetooth_connections);
  152. net_unlock();
  153. }
  154. /****************************************************************************
  155. * Name: bluetooth_conn_active()
  156. *
  157. * Description:
  158. * Find a connection structure that is the appropriate
  159. * connection to be used with the provided Bluetooth header
  160. *
  161. * Assumptions:
  162. * This function is called from network logic at with the network locked.
  163. *
  164. ****************************************************************************/
  165. FAR struct bluetooth_conn_s *
  166. bluetooth_conn_active(FAR const struct bluetooth_frame_meta_s *meta)
  167. {
  168. FAR struct bluetooth_conn_s *conn;
  169. DEBUGASSERT(meta != NULL);
  170. for (conn = (FAR struct bluetooth_conn_s *)g_active_bluetooth_connections.head;
  171. conn != NULL;
  172. conn = (FAR struct bluetooth_conn_s *)conn->bc_node.flink)
  173. {
  174. /* Does the destination address match the bound address of the socket. */
  175. if ((BLUETOOTH_ADDRCMP(&conn->bc_raddr, &meta->bm_raddr) ||
  176. BLUETOOTH_ADDRCMP(&conn->bc_raddr, &g_any_addr)) &&
  177. (meta->bm_channel == conn->bc_channel ||
  178. BT_CHANNEL_ANY == conn->bc_channel))
  179. {
  180. continue;
  181. }
  182. }
  183. return conn;
  184. }
  185. /****************************************************************************
  186. * Name: bluetooth_conn_next()
  187. *
  188. * Description:
  189. * Traverse the list of allocated packet connections
  190. *
  191. * Assumptions:
  192. * This function is called from network logic at with the network locked.
  193. *
  194. ****************************************************************************/
  195. FAR struct bluetooth_conn_s *
  196. bluetooth_conn_next(FAR struct bluetooth_conn_s *conn)
  197. {
  198. if (!conn)
  199. {
  200. return (FAR struct bluetooth_conn_s *)
  201. g_active_bluetooth_connections.head;
  202. }
  203. else
  204. {
  205. return (FAR struct bluetooth_conn_s *)conn->bc_node.flink;
  206. }
  207. }
  208. #endif /* CONFIG_NET_BLUETOOTH */