Bluetooth: HFP HF: SCO: Handle synchronous_conn_complete

Handle the synchronous connection complete event received from the
controller and update the event details received.

> HCI Event: Synchronous Connect Complete (0x2c) plen 17
        Status: Success (0x00)
        Handle: 266
        Address: 48:9D:24:1F:4D:1D (BlackBerry RTS)
        Link type: eSCO (0x02)
        Transmission interval: 0x06
        Retransmission window: 0x02
        RX packet length: 30
        TX packet length: 30
        Air mode: CVSD (0x02)

Change-Id: I4bcd0488f798b112af504245e80180a70b32a882
Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
This commit is contained in:
Sathish Narasimman 2017-02-15 15:08:25 +05:30 committed by Johan Hedberg
commit befc6510f1
4 changed files with 74 additions and 0 deletions

View file

@ -1074,6 +1074,19 @@ struct bt_hci_evt_remote_ext_features {
uint8_t features[8];
} __packed;
#define BT_HCI_EVT_SYNC_CONN_COMPLETE 0x2c
struct bt_hci_evt_sync_conn_complete {
uint8_t status;
uint16_t handle;
bt_addr_t bdaddr;
uint8_t link_type;
uint8_t tx_interval;
uint8_t retansmission_window;
uint16_t rx_pkt_length;
uint16_t tx_pkt_length;
uint8_t air_mode;
} __packed;
#define BT_HCI_EVT_EXTENDED_INQUIRY_RESULT 0x2f
struct bt_hci_evt_extended_inquiry_result {
uint8_t num_reports;

View file

@ -266,6 +266,27 @@ struct bt_conn *bt_conn_create_br(const bt_addr_t *peer,
return conn;
}
struct bt_conn *bt_conn_lookup_addr_sco(const bt_addr_t *peer)
{
int i;
for (i = 0; i < ARRAY_SIZE(sco_conns); i++) {
if (!atomic_get(&sco_conns[i].ref)) {
continue;
}
if (sco_conns[i].type != BT_CONN_TYPE_SCO) {
continue;
}
if (!bt_addr_cmp(peer, &sco_conns[i].sco.conn->br.dst)) {
return bt_conn_ref(&sco_conns[i]);
}
}
return NULL;
}
struct bt_conn *bt_conn_lookup_addr_br(const bt_addr_t *peer)
{
int i;
@ -1207,6 +1228,10 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
/* Actions needed for entering the new state */
switch (conn->state) {
case BT_CONN_CONNECTED:
if (conn->type == BT_CONN_TYPE_SCO) {
/* TODO: Notify sco connected */
break;
}
k_fifo_init(&conn->tx_queue);
k_poll_signal(&conn_change, 0);
@ -1254,6 +1279,9 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
case BT_CONN_CONNECT_SCAN:
break;
case BT_CONN_CONNECT:
if (conn->type == BT_CONN_TYPE_SCO) {
break;
}
/*
* Timer is needed only for LE. For other link types controller
* will handle connection timeout.

View file

@ -127,6 +127,9 @@ 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);
/* 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);

View file

@ -1113,6 +1113,33 @@ static void update_sec_level_br(struct bt_conn *conn)
}
}
static void synchronous_conn_complete(struct net_buf *buf)
{
struct bt_hci_evt_sync_conn_complete *evt = (void *)buf->data;
struct bt_conn *sco_conn;
uint16_t handle = sys_le16_to_cpu(evt->handle);
BT_DBG("status 0x%02x, handle %u, type 0x%02x", evt->status, handle,
evt->link_type);
sco_conn = bt_conn_lookup_addr_sco(&evt->bdaddr);
if (!sco_conn) {
BT_ERR("Unable to find conn for %s", bt_addr_str(&evt->bdaddr));
return;
}
if (evt->status) {
sco_conn->err = evt->status;
bt_conn_set_state(sco_conn, BT_CONN_DISCONNECTED);
bt_conn_unref(sco_conn);
return;
}
sco_conn->handle = handle;
bt_conn_set_state(sco_conn, BT_CONN_CONNECTED);
bt_conn_unref(sco_conn);
}
static void conn_complete(struct net_buf *buf)
{
struct bt_hci_evt_conn_complete *evt = (void *)buf->data;
@ -2691,6 +2718,9 @@ static void hci_event(struct net_buf *buf)
case BT_HCI_EVT_ROLE_CHANGE:
role_change(buf);
break;
case BT_HCI_EVT_SYNC_CONN_COMPLETE:
synchronous_conn_complete(buf);
break;
#endif
#if defined(CONFIG_BLUETOOTH_CONN)
case BT_HCI_EVT_DISCONN_COMPLETE: