1 /** @file 2 * @brief Internal APIs for Bluetooth SCO handling. 3 */ 4 /* 5 * Copyright 2024 NXP 6 * 7 * SPDX-License-Identifier: Apache-2.0 8 */ 9 10 /** @brief Life-span states of SCO channel. Used only by internal APIs 11 * dealing with setting channel to proper state depending on operational 12 * context. 13 */ 14 enum bt_sco_state { 15 /** Channel disconnected */ 16 BT_SCO_STATE_DISCONNECTED, 17 /** Channel is pending ACL encryption before connecting */ 18 BT_SCO_STATE_ENCRYPT_PENDING, 19 /** Channel in connecting state */ 20 BT_SCO_STATE_CONNECTING, 21 /** Channel ready for upper layer traffic on it */ 22 BT_SCO_STATE_CONNECTED, 23 /** Channel in disconnecting state */ 24 BT_SCO_STATE_DISCONNECTING, 25 }; 26 27 struct bt_sco_chan; 28 struct bt_sco_chan_ops { 29 /** @brief Channel connected callback 30 * 31 * If this callback is provided it will be called whenever the 32 * connection completes. 33 * 34 * @param chan The channel that has been connected 35 */ 36 void (*connected)(struct bt_sco_chan *chan); 37 38 /** @brief Channel disconnected callback 39 * 40 * If this callback is provided it will be called whenever the 41 * channel is disconnected, including when a connection gets 42 * rejected or when setting security fails. 43 * 44 * @param chan The channel that has been Disconnected 45 * @param reason BT_HCI_ERR_* reason for the disconnection. 46 */ 47 void (*disconnected)(struct bt_sco_chan *chan, uint8_t reason); 48 }; 49 50 struct bt_sco_chan { 51 struct bt_conn *sco; 52 /** Channel operations reference */ 53 const struct bt_sco_chan_ops *ops; 54 55 enum bt_sco_state state; 56 }; 57 58 /** @brief Initiate an SCO connection to a remote device. 59 * 60 * Allows initiate new SCO link to remote peer using its address. 61 * 62 * The caller gets a new reference to the connection object which must be 63 * released with bt_conn_unref() once done using the object. 64 * 65 * @param peer Remote address. 66 * @param chan sco chan object. 67 * 68 * @return Valid connection object on success or NULL otherwise. 69 */ 70 struct bt_conn *bt_conn_create_sco(const bt_addr_t *peer, struct bt_sco_chan *chan); 71 72 /** @brief SCO Accept Info Structure */ 73 struct bt_sco_accept_info { 74 /** The ACL connection that is requesting authorization */ 75 struct bt_conn *acl; 76 77 /** class code of peer device */ 78 uint8_t dev_class[3]; 79 80 /** link type */ 81 uint8_t link_type; 82 }; 83 84 /** @brief SCO Server structure. */ 85 struct bt_sco_server { 86 /** Required minimum security level. 87 * Only available when @kconfig{CONFIG_BT_SMP} is enabled. 88 */ 89 bt_security_t sec_level; 90 /** @brief Server accept callback 91 * 92 * This callback is called whenever a new incoming connection requires 93 * authorization. 94 * 95 * @param info The SCO accept information structure 96 * @param chan Pointer to receive the allocated channel 97 * 98 * @return 0 in case of success or negative value in case of error. 99 */ 100 int (*accept)(const struct bt_sco_accept_info *info, 101 struct bt_sco_chan **chan); 102 }; 103 104 /** @brief Register SCO server. 105 * 106 * Register SCO server, each new connection is authorized using the accept() 107 * callback which in case of success shall allocate the channel structure 108 * to be used by the new connection. 109 * 110 * @param server Server structure. 111 * 112 * @return 0 in case of success or negative value in case of error. 113 */ 114 int bt_sco_server_register(struct bt_sco_server *server); 115 116 /** @brief Unregister SCO server. 117 * 118 * Unregister previously registered SCO server. 119 * 120 * @param server Server structure. 121 * 122 * @return 0 in case of success or negative value in case of error. 123 */ 124 int bt_sco_server_unregister(struct bt_sco_server *server); 125 126 /** @brief sco channel connected. 127 * 128 * sco channel connected 129 * 130 * @param sco SCO connection object. 131 */ 132 void bt_sco_connected(struct bt_conn *sco); 133 134 /** @brief sco channel disconnected. 135 * 136 * sco channel disconnected 137 * 138 * @param sco SCO connection object. 139 */ 140 void bt_sco_disconnected(struct bt_conn *sco); 141 142 uint8_t bt_esco_conn_req(struct bt_hci_evt_conn_request *evt); 143 144 #if defined(CONFIG_BT_CONN_LOG_LEVEL_DBG) 145 void bt_sco_chan_set_state_debug(struct bt_sco_chan *chan, 146 enum bt_sco_state state, 147 const char *func, int line); 148 #define bt_sco_chan_set_state(_chan, _state) \ 149 bt_sco_chan_set_state_debug(_chan, _state, __func__, __LINE__) 150 #else 151 void bt_sco_chan_set_state(struct bt_sco_chan *chan, enum bt_sco_state state); 152 #endif /* CONFIG_BT_CONN_LOG_LEVEL_DBG */ 153 154 /** @brief SCO connection callback structure. 155 * 156 * This structure is used for tracking the state of a SCO connection. 157 * It is registered with the help of the bt_sco_conn_cb_register() API. 158 * It's permissible to register multiple instances of this @ref bt_sco_conn_cb 159 * type, in case different modules of an application are interested in 160 * tracking the connection state. If a callback is not of interest for 161 * an instance, it may be set to NULL and will as a consequence not be 162 * used for that instance. 163 */ 164 struct bt_sco_conn_cb { 165 /** @brief A new SCO connection has been established. 166 * 167 * This callback notifies the application of a new connection. 168 * In case the err parameter is non-zero it means that the 169 * connection establishment failed. 170 * 171 * @param conn New SCO connection object. 172 * @param err HCI error. Zero for success, non-zero otherwise. 173 */ 174 void (*connected)(struct bt_conn *conn, uint8_t err); 175 176 /** @brief A SCO connection has been disconnected. 177 * 178 * This callback notifies the application that a SCO connection 179 * has been disconnected. 180 * When this callback is called the stack still has one reference to 181 * the connection object. 182 * 183 * @param conn SCO connection object. 184 * @param reason BT_HCI_ERR_* reason for the disconnection. 185 */ 186 void (*disconnected)(struct bt_conn *conn, uint8_t reason); 187 188 /** @internal Internally used field for list handling */ 189 sys_snode_t _node; 190 }; 191 192 /** @brief Register SCO connection callbacks. 193 * 194 * Register callbacks to monitor the state of SCO connections. 195 * 196 * @param cb Callback struct. Must point to memory that remains valid. 197 * 198 * @retval 0 Success. 199 * @retval -EINVAL If @p cb is NULL. 200 * @retval -EEXIST if @p cb was already registered. 201 */ 202 int bt_sco_conn_cb_register(struct bt_sco_conn_cb *cb); 203 204 /** 205 * @brief Unregister SCO connection callbacks. 206 * 207 * Unregister the state of SCO connections callbacks. 208 * 209 * @param cb Callback struct point to memory that remains valid. 210 * 211 * @retval 0 Success. 212 * @retval -EINVAL If @p cb is NULL. 213 * @retval -ENOENT if @p cb was not registered. 214 */ 215 int bt_sco_conn_cb_unregister(struct bt_sco_conn_cb *cb); 216 217 /** 218 * @brief Register a callback structure for connection events. 219 * 220 * @param _name Name of callback structure. 221 */ 222 #define BT_SCO_CONN_CB_DEFINE(_name) \ 223 static const STRUCT_SECTION_ITERABLE(bt_sco_conn_cb, _CONCAT(bt_sco_conn_cb_, _name)) 224