Skip to content

Commit

Permalink
Bluetooth: improved pairing process and host layer now successfully r…
Browse files Browse the repository at this point in the history
…eceives ACL packets
  • Loading branch information
robert authored and acassis committed Nov 10, 2024
1 parent 78aa263 commit 5e8f1ee
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 8 deletions.
1 change: 1 addition & 0 deletions arch/xtensa/src/esp32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,7 @@ config ESP32_BLE
default n
select ESP32_WIRELESS
select BLUETOOTH_TXCMD_PINNED_TO_CORE if SMP
select BLUETOOTH_CNTRL_HOST_FLOW_DISABLE
---help---
Enable BLE support

Expand Down
22 changes: 22 additions & 0 deletions include/nuttx/wireless/bluetooth/bt_hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
#define BT_HCI_OP_LE_SET_EVENT_MASK BT_OP(BT_OGF_LE, 0x0001)
#define BT_HCI_OP_LE_READ_BUFFER_SIZE BT_OP(BT_OGF_LE, 0x0002)
#define BT_HCI_OP_LE_READ_LOCAL_FEATURES BT_OP(BT_OGF_LE, 0x0003)
#define BT_HCI_OP_LE_REM_CONN_PARAM_REQ_RPLY BT_OP(BT_OGF_LE, 0x0020)

#define BT_HCI_OP_LE_SET_RAND_ADDR BT_OP(BT_OGF_LE, 0x0005)

Expand All @@ -149,6 +150,7 @@
#define BT_LE_ADV_SCAN_RSP 0x04

#define BT_HCI_OP_LE_SET_ADV_PARAMETERS BT_OP(BT_OGF_LE, 0x0006)
#define BT_HIC_OP_LE_READ_ADV_CHANNEL_TX_PWR BT_OP(BT_OGF_LE, 0x0007)
#define BT_HCI_OP_LE_SET_ADV_DATA BT_OP(BT_OGF_LE, 0x0008)
#define BT_HCI_OP_LE_SET_SCAN_RSP_DATA BT_OP(BT_OGF_LE, 0x0009)
#define BT_HCI_OP_LE_SET_ADV_ENABLE BT_OP(BT_OGF_LE, 0x000a)
Expand Down Expand Up @@ -510,6 +512,17 @@ begin_packed_struct struct bt_hci_cp_le_ltk_req_neg_reply_s
uint16_t handle;
} end_packed_struct;

begin_packed_struct struct bt_hci_cp_le_rem_conn_param_req_reply_s
{
uint16_t handle;
uint16_t min_interval;
uint16_t max_interval;
uint16_t latency;
uint16_t timeout;
uint16_t min_ce_len;
uint16_t max_ce_len;
} end_packed_struct;

/* Event definitions */

begin_packed_struct struct bt_hci_evt_disconn_complete_s
Expand Down Expand Up @@ -630,5 +643,14 @@ begin_packed_struct struct bt_hci_evt_le_ltk_request_s
uint16_t ediv;
} end_packed_struct;

begin_packed_struct struct bt_hci_evt_le_rem_conn_param_req_s
{
uint16_t handle;
uint16_t min_interval;
uint16_t max_interval;
uint16_t latency;
uint16_t timeout;
} end_packed_struct;

#endif /* CONFIG_WIRELESS_BLUETOOTH */
#endif /* __INCLUDE_NUTTX_WIRELESS_BLUETOOTH_BT_HCI_H */
9 changes: 9 additions & 0 deletions wireless/bluetooth/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ config BLUETOOTH_BUFFER_IRQRESERVE
interrupt level. This setting only needs to be non-zero if your
low-level Bluetooth driver needs to do such allocations.

config BLUETOOTH_CNTRL_HOST_FLOW_DISABLE
bool "Disable Controller to Host Flow Control"
default n
---help---
Controller to Host Flow Control prevents buffer overflow
between the Controller and the Host layers. When enabled, the Controller can
indicate to the Host when its buffers are nearly full, allowing the Host to
stop sending data until buffer space becomes available.

menu "Kernel Thread Configuration"

config BLUETOOTH_TXCMD_STACKSIZE
Expand Down
2 changes: 1 addition & 1 deletion wireless/bluetooth/bt_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ void bt_conn_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf)

sq_init(&fraglist);

wlinfo("conn handle %u buf len %u\n", conn->handle, buf->len);
wlwarn("conn handle %u buf len %u\n", conn->handle, buf->len);

if (conn->state != BT_CONN_CONNECTED)
{
Expand Down
68 changes: 61 additions & 7 deletions wireless/bluetooth/bt_hcicore.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,11 +741,6 @@ static void le_conn_complete(FAR struct bt_buf_s *buf)

bt_l2cap_connected(conn);

if (evt->role == BT_HCI_ROLE_SLAVE)
{
bt_l2cap_update_conn_param(conn);
}

bt_connected(conn);
bt_conn_release(conn);
bt_le_scan_update();
Expand Down Expand Up @@ -907,6 +902,34 @@ static void le_ltk_request(FAR struct bt_buf_s *buf)
bt_conn_release(conn);
}

static int le_param_request(FAR struct bt_buf_s *buf)
{
FAR struct bt_buf_s *reply_buf;
FAR struct bt_hci_cp_le_rem_conn_param_req_reply_s *params_reply;
FAR struct bt_hci_evt_le_rem_conn_param_req_s *params_request;

reply_buf = bt_hci_cmd_create(BT_HCI_OP_LE_REM_CONN_PARAM_REQ_RPLY,
sizeof(*params_reply));
if (!reply_buf)
{
return -ENOBUFS;
}

params_request = (FAR void *)buf->data;

params_reply = bt_buf_extend(reply_buf, sizeof(*params_reply));
memset(params_reply, 0, sizeof(*params_reply));
params_reply->handle = BT_HOST2LE16(params_request->handle);
params_reply->min_interval = BT_HOST2LE16(params_request->min_interval);
params_reply->max_interval = BT_HOST2LE16(params_request->max_interval);
params_reply->latency = BT_HOST2LE16(params_request->latency);
params_reply->timeout = BT_HOST2LE16(params_request->timeout);
params_reply->max_ce_len = BT_HOST2LE16(0xffff);

return bt_hci_cmd_send_sync(BT_HCI_OP_LE_REM_CONN_PARAM_REQ_RPLY,
reply_buf, NULL);
}

static void hci_le_meta_event(FAR struct bt_buf_s *buf)
{
FAR struct bt_hci_evt_le_meta_event_s *evt = (FAR void *)buf->data;
Expand All @@ -923,10 +946,17 @@ static void hci_le_meta_event(FAR struct bt_buf_s *buf)
le_adv_report(buf);
break;

case BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE:
break;

case BT_HCI_EVT_LE_LTK_REQUEST:
le_ltk_request(buf);
break;

case BT_HCI_EVT_LE_CONN_PARAM_REQ:
le_param_request(buf);
break;

default:
wlinfo("Unhandled LE event %04x\n", evt->subevent);
break;
Expand Down Expand Up @@ -1335,6 +1365,8 @@ static int hci_initialize(void)
ev = bt_buf_extend(buf, sizeof(*ev));
memset(ev, 0, sizeof(*ev));

ev->events[0] |= 0x04; /* Connection Complete */
ev->events[0] |= 0x08; /* Connection Request */
ev->events[0] |= 0x10; /* Disconnection Complete */
ev->events[1] |= 0x08; /* Read Remote Version Information Complete */
ev->events[1] |= 0x20; /* Command Complete */
Expand All @@ -1352,6 +1384,25 @@ static int hci_initialize(void)

bt_hci_cmd_send_sync(BT_HCI_OP_SET_EVENT_MASK, buf, NULL);

buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_EVENT_MASK, sizeof(*ev));
if (buf == NULL)
{
wlerr("ERROR: Failed to create buffer\n");
return -ENOBUFS;
}

ev = bt_buf_extend(buf, sizeof(*ev));
memset(ev, 0, sizeof(*ev));

ev->events[0] |= 0xff;

ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL);
if (ret < 0)
{
wlerr("ERROR: bt_hci_cmd_send_sync failed: %d\n", ret);
return ret;
}

buf = bt_hci_cmd_create(BT_HCI_OP_HOST_BUFFER_SIZE, sizeof(*hbs));
if (buf == NULL)
{
Expand Down Expand Up @@ -1381,7 +1432,11 @@ static int hci_initialize(void)
}

enable = bt_buf_extend(buf, sizeof(*enable));
*enable = 0x01;
#ifdef CONFIG_BLUETOOTH_CNTRL_HOST_FLOW_DISABLE
*enable = 0;
#else
*enable = 1;
#endif

ret = bt_hci_cmd_send_sync(BT_HCI_OP_SET_CTL_TO_HOST_FLOW, buf, NULL);
if (ret < 0)
Expand Down Expand Up @@ -2119,7 +2174,6 @@ int bt_start_advertising(uint8_t type, FAR const struct bt_eir_s *ad,
int bt_stop_advertising(void)
{
FAR struct bt_buf_s *buf;

if (!g_btdev.adv_enable)
{
wlwarn("WARNING: Already advertising\n");
Expand Down

0 comments on commit 5e8f1ee

Please sign in to comment.