Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | /** @file
* @brief Internal APIs for Bluetooth connection handling.
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
typedef enum __packed {
BT_CONN_DISCONNECTED,
BT_CONN_CONNECT_SCAN,
BT_CONN_CONNECT,
BT_CONN_CONNECTED,
BT_CONN_DISCONNECT,
} bt_conn_state_t;
/* bt_conn flags: the flags defined here represent connection parameters */
enum {
BT_CONN_AUTO_CONNECT,
BT_CONN_BR_LEGACY_SECURE, /* 16 digits legacy PIN tracker */
BT_CONN_USER, /* user I/O when pairing */
BT_CONN_BR_PAIRING, /* BR connection in pairing context */
BT_CONN_BR_NOBOND, /* SSP no bond pairing tracker */
BT_CONN_BR_PAIRING_INITIATOR, /* local host starts authentication */
BT_CONN_CLEANUP, /* Disconnected, pending cleanup */
BT_CONN_AUTO_PHY_UPDATE, /* Auto-update PHY */
BT_CONN_AUTO_DATA_LEN, /* Auto data len change in progress */
/* Total number of flags - must be at the end of the enum */
BT_CONN_NUM_FLAGS,
};
struct bt_conn_le {
bt_addr_le_t dst;
bt_addr_le_t init_addr;
bt_addr_le_t resp_addr;
u16_t interval;
u16_t interval_min;
u16_t interval_max;
u16_t latency;
u16_t timeout;
u8_t features[8];
struct bt_keys *keys;
/* Delayed work for connection update and timeout handling */
struct k_delayed_work update_work;
};
#if defined(CONFIG_BT_BREDR)
/* For now reserve space for 2 pages of LMP remote features */
#define LMP_MAX_PAGES 2
struct bt_conn_br {
bt_addr_t dst;
u8_t remote_io_capa;
u8_t remote_auth;
u8_t pairing_method;
/* remote LMP features pages per 8 bytes each */
u8_t features[LMP_MAX_PAGES][8];
struct bt_keys_link_key *link_key;
};
struct bt_conn_sco {
/* Reference to ACL Connection */
struct bt_conn *acl;
u16_t pkt_type;
};
#endif
typedef void (*bt_conn_tx_cb_t)(struct bt_conn *conn);
struct bt_conn_tx {
sys_snode_t node;
bt_conn_tx_cb_t cb;
};
struct bt_conn {
u16_t handle;
u8_t type;
u8_t role;
ATOMIC_DEFINE(flags, BT_CONN_NUM_FLAGS);
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
bt_security_t sec_level;
bt_security_t required_sec_level;
u8_t encrypt;
#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */
/* Connection error or reason for disconnect */
u8_t err;
bt_conn_state_t state;
u16_t rx_len;
struct net_buf *rx;
/* Sent but not acknowledged TX packets */
sys_slist_t tx_pending;
/* Acknowledged but not yet notified TX packets */
struct k_fifo tx_notify;
/* Queue for outgoing ACL data */
struct k_fifo tx_queue;
/* Active L2CAP channels */
sys_slist_t channels;
atomic_t ref;
union {
struct bt_conn_le le;
#if defined(CONFIG_BT_BREDR)
struct bt_conn_br br;
struct bt_conn_sco sco;
#endif
};
};
/* Process incoming data for a connection */
void bt_conn_recv(struct bt_conn *conn, struct net_buf *buf, u8_t flags);
/* Send data over a connection */
int bt_conn_send_cb(struct bt_conn *conn, struct net_buf *buf,
bt_conn_tx_cb_t cb);
static inline int bt_conn_send(struct bt_conn *conn, struct net_buf *buf)
{
return bt_conn_send_cb(conn, buf, NULL);
}
/* Add a new LE connection */
struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer);
/* Add a new BR/EDR connection */
struct bt_conn *bt_conn_add_br(const bt_addr_t *peer);
/* Add a new SCO connection */
struct bt_conn *bt_conn_add_sco(const bt_addr_t *peer, int link_type);
/* Cleanup SCO references */
void bt_sco_cleanup(struct bt_conn *sco_conn);
/* Look up an existing sco connection by BT address */
struct bt_conn *bt_conn_lookup_addr_sco(const bt_addr_t *peer);
/* Look up an existing connection by BT address */
struct bt_conn *bt_conn_lookup_addr_br(const bt_addr_t *peer);
void bt_conn_pin_code_req(struct bt_conn *conn);
u8_t bt_conn_get_io_capa(void);
u8_t bt_conn_ssp_get_auth(const struct bt_conn *conn);
void bt_conn_ssp_auth(struct bt_conn *conn, u32_t passkey);
void bt_conn_disconnect_all(void);
/* Look up an existing connection */
struct bt_conn *bt_conn_lookup_handle(u16_t handle);
/* Compare an address with bt_conn destination address */
int bt_conn_addr_le_cmp(const struct bt_conn *conn, const bt_addr_le_t *peer);
/* Helpers for identifying & looking up connections based on the the index to
* the connection list. This is useful for O(1) lookups, but can't be used
* e.g. as the handle since that's assigned to us by the controller.
*/
#define BT_CONN_ID_INVALID 0xff
u8_t bt_conn_get_id(struct bt_conn *conn);
struct bt_conn *bt_conn_lookup_id(u8_t id);
/* Look up a connection state. For BT_ADDR_LE_ANY, returns the first connection
* with the specific state
*/
struct bt_conn *bt_conn_lookup_state_le(const bt_addr_le_t *peer,
const bt_conn_state_t state);
/* Set connection object in certain state and perform action related to state */
void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state);
int bt_conn_le_conn_update(struct bt_conn *conn,
const struct bt_le_conn_param *param);
void notify_le_param_updated(struct bt_conn *conn);
bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param);
#if defined(CONFIG_BT_SMP)
/* rand and ediv should be in BT order */
int bt_conn_le_start_encryption(struct bt_conn *conn, u64_t rand,
u16_t ediv, const u8_t *ltk, size_t len);
/* Notify higher layers that RPA was resolved */
void bt_conn_identity_resolved(struct bt_conn *conn);
#endif /* CONFIG_BT_SMP */
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
/* Notify higher layers that connection security changed */
void bt_conn_security_changed(struct bt_conn *conn);
#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */
/* Prepare a PDU to be sent over a connection */
struct net_buf *bt_conn_create_pdu(struct net_buf_pool *pool, size_t reserve);
/* Initialize connection management */
int bt_conn_init(void);
/* Selects based on connecton type right semaphore for ACL packets */
struct k_sem *bt_conn_get_pkts(struct bt_conn *conn);
/* k_poll related helpers for the TX thread */
int bt_conn_prepare_events(struct k_poll_event events[]);
void bt_conn_process_tx(struct bt_conn *conn);
void bt_conn_notify_tx(struct bt_conn *conn);
|