Bluetooth: Add support for outgoing BR/EDR connections
This allows to create outgoing BR/EDR connection and cancel pending connection before it succeed. Change-Id: I5c08bb2e89f79c09fa7930f860d6080d902186a1 Signed-off-by: Szymon Janc <ext.szymon.janc@tieto.com>
This commit is contained in:
parent
cd8d4eb2b7
commit
8d154104b6
2 changed files with 124 additions and 0 deletions
|
@ -379,6 +379,41 @@ int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin);
|
||||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||||
#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */
|
#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||||
|
/** Connection parameters for BR/EDR connections */
|
||||||
|
struct bt_br_conn_param {
|
||||||
|
bool allow_role_switch;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Helper to declare BR/EDR connection parameters inline
|
||||||
|
*
|
||||||
|
* @param role_switch True if role switch is allowed
|
||||||
|
*/
|
||||||
|
#define BT_BR_CONN_PARAM(role_switch) \
|
||||||
|
(&(struct bt_br_conn_param) { \
|
||||||
|
.allow_role_switch = (role_switch), \
|
||||||
|
})
|
||||||
|
|
||||||
|
/** Default BR/EDR connection parameters:
|
||||||
|
* Role switch allowed
|
||||||
|
*/
|
||||||
|
#define BT_BR_CONN_PARAM_DEFAULT BT_BR_CONN_PARAM(true)
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief Initiate an BR/EDR connection to a remote device.
|
||||||
|
*
|
||||||
|
* Allows initiate new BR/EDR link to remote peer using its address.
|
||||||
|
* Returns a new reference that the the caller is responsible for managing.
|
||||||
|
*
|
||||||
|
* @param peer Remote address.
|
||||||
|
* @param param Initial connection parameters.
|
||||||
|
*
|
||||||
|
* @return Valid connection object on success or NULL otherwise.
|
||||||
|
*/
|
||||||
|
struct bt_conn *bt_conn_create_br(const bt_addr_t *peer,
|
||||||
|
const struct bt_br_conn_param *param);
|
||||||
|
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -578,6 +578,58 @@ struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||||
|
struct bt_conn *bt_conn_create_br(const bt_addr_t *peer,
|
||||||
|
const struct bt_br_conn_param *param)
|
||||||
|
{
|
||||||
|
struct bt_hci_cp_connect *cp;
|
||||||
|
struct bt_conn *conn;
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
conn = bt_conn_lookup_addr_br(peer);
|
||||||
|
if (conn) {
|
||||||
|
switch (conn->state) {
|
||||||
|
return conn;
|
||||||
|
case BT_CONN_CONNECT:
|
||||||
|
case BT_CONN_CONNECTED:
|
||||||
|
return conn;
|
||||||
|
default:
|
||||||
|
bt_conn_unref(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = bt_conn_add_br(peer);
|
||||||
|
if (!conn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = bt_hci_cmd_create(BT_HCI_OP_CONNECT, sizeof(*cp));
|
||||||
|
if (!buf) {
|
||||||
|
bt_conn_unref(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = net_buf_add(buf, sizeof(*cp));
|
||||||
|
|
||||||
|
memset(cp, 0, sizeof(*cp));
|
||||||
|
|
||||||
|
memcpy(&cp->bdaddr, peer, sizeof(cp->bdaddr));
|
||||||
|
cp->packet_type = sys_cpu_to_le16(0xcc18); /* DM1 DH1 DM3 DH5 DM5 DH5 */
|
||||||
|
cp->pscan_rep_mode = 0x02; /* R2 */
|
||||||
|
cp->allow_role_switch = param->allow_role_switch ? 0x01 : 0x00;
|
||||||
|
cp->clock_offset = 0x0000; /* TODO used cached clock offset */
|
||||||
|
|
||||||
|
if (bt_hci_cmd_send_sync(BT_HCI_OP_CONNECT, buf, NULL) < 0) {
|
||||||
|
bt_conn_unref(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_conn_set_state(conn, BT_CONN_CONNECT);
|
||||||
|
conn->role = BT_CONN_ROLE_MASTER;
|
||||||
|
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
struct bt_conn *bt_conn_lookup_addr_br(const bt_addr_t *peer)
|
struct bt_conn *bt_conn_lookup_addr_br(const bt_addr_t *peer)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -978,6 +1030,37 @@ static int bt_hci_connect_le_cancel(struct bt_conn *conn)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||||
|
static int bt_hci_connect_br_cancel(struct bt_conn *conn)
|
||||||
|
{
|
||||||
|
struct bt_hci_cp_connect_cancel *cp;
|
||||||
|
struct bt_hci_rp_connect_cancel *rp;
|
||||||
|
struct net_buf *buf, *rsp;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
buf = bt_hci_cmd_create(BT_HCI_OP_CONNECT_CANCEL, sizeof(*cp));
|
||||||
|
if (!buf) {
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = net_buf_add(buf, sizeof(*cp));
|
||||||
|
memcpy(&cp->bdaddr, &conn->br.dst, sizeof(cp->bdaddr));
|
||||||
|
|
||||||
|
err = bt_hci_cmd_send_sync(BT_HCI_OP_CONNECT_CANCEL, buf, &rsp);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp = (void *)rsp->data;
|
||||||
|
|
||||||
|
err = rp->status ? -EIO : 0;
|
||||||
|
|
||||||
|
net_buf_unref(rsp);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int bt_conn_le_param_update(struct bt_conn *conn,
|
int bt_conn_le_param_update(struct bt_conn *conn,
|
||||||
const struct bt_le_conn_param *param)
|
const struct bt_le_conn_param *param)
|
||||||
{
|
{
|
||||||
|
@ -1003,6 +1086,12 @@ int bt_conn_disconnect(struct bt_conn *conn, uint8_t reason)
|
||||||
bt_le_scan_update(false);
|
bt_le_scan_update(false);
|
||||||
return 0;
|
return 0;
|
||||||
case BT_CONN_CONNECT:
|
case BT_CONN_CONNECT:
|
||||||
|
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||||
|
if (conn->type == BT_CONN_TYPE_BR) {
|
||||||
|
return bt_hci_connect_br_cancel(conn);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||||
|
|
||||||
return bt_hci_connect_le_cancel(conn);
|
return bt_hci_connect_le_cancel(conn);
|
||||||
case BT_CONN_CONNECTED:
|
case BT_CONN_CONNECTED:
|
||||||
return bt_hci_disconnect(conn, reason);
|
return bt_hci_disconnect(conn, reason);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue