Skip to content

Commit

Permalink
nimble/host: Add optional GAP event for unhandled HCI events
Browse files Browse the repository at this point in the history
This adds option to enabled additional GAP event which is called for a
HCI event that host doesn't know how to handle. It can be used to test
controller features that host doesn't yet support. It also removes
dedicated BLE_GAP_EVENT_VS_HCI as this is handled now by the same event.
  • Loading branch information
andrzej-kaczmarek committed Sep 23, 2023
1 parent 10f1270 commit ef29646
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 13 deletions.
16 changes: 10 additions & 6 deletions nimble/host/include/host/ble_gap.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ struct hci_conn_update;
/** GAP event: Subrate change */
#define BLE_GAP_EVENT_SUBRATE_CHANGE 28

/** GAP event: Vendor specific HCI event */
#define BLE_GAP_EVENT_VS_HCI 29
/** GAP event: Unhandled HCI event */
#define BLE_GAP_EVENT_UNHANDLED_HCI_EVENT 29

/** GAP event: BIG (Broadcast Isochronous Group) information report */
#define BLE_GAP_EVENT_BIGINFO_REPORT 30
Expand Down Expand Up @@ -1288,17 +1288,21 @@ struct ble_gap_event {
} subrate_change;
#endif

#if MYNEWT_VAL(BLE_HCI_VS)
#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT)
/**
* Represents a received vendor-specific HCI event
* Represents an HCI event received from controller that is not handled
* by the host. The event may be a regular event, LE meta event or
* vendor specific event which is denoted by included flags.
*
* Valid for the following event types:
* o BLE_GAP_EVENT_VS_HCI
* o BLE_GAP_EVENT_UNHANDLED_HCI_EVENT
*/
struct {
bool is_le_meta;
bool is_vs;
const void *ev;
uint8_t length;
} vs_hci;
} unhandled_hci;
#endif
};
};
Expand Down
13 changes: 8 additions & 5 deletions nimble/host/src/ble_gap.c
Original file line number Diff line number Diff line change
Expand Up @@ -6357,16 +6357,19 @@ ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu)
#endif
}

#if MYNEWT_VAL(BLE_HCI_VS)
#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT)
void
ble_gap_vs_hci_event(const void *buf, uint8_t len)
ble_gap_unhandled_hci_event(bool is_le_meta, bool is_vs, const void *buf,
uint8_t len)
{
struct ble_gap_event event;

memset(&event, 0, sizeof event);
event.type = BLE_GAP_EVENT_VS_HCI;
event.vs_hci.ev = buf;
event.vs_hci.length = len;
event.type = BLE_GAP_EVENT_UNHANDLED_HCI_EVENT;
event.unhandled_hci.is_le_meta = is_le_meta;
event.unhandled_hci.is_vs = is_vs;
event.unhandled_hci.ev = buf;
event.unhandled_hci.length = len;

ble_gap_event_listener_call(&event);
}
Expand Down
3 changes: 2 additions & 1 deletion nimble/host/src/ble_gap_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ void ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu);
void ble_gap_identity_event(uint16_t conn_handle, const ble_addr_t *peer_id_addr);
int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp);
void ble_gap_pairing_complete_event(uint16_t conn_handle, int status);
void ble_gap_vs_hci_event(const void *buf, uint8_t len);
void ble_gap_unhandled_hci_event(bool is_le_meta, bool is_vs, const void *buf,
uint8_t len);
int ble_gap_master_in_progress(void);

void ble_gap_preempt(void);
Expand Down
11 changes: 10 additions & 1 deletion nimble/host/src/ble_hs_hci_evt.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,9 @@ ble_hs_hci_evt_vs(uint8_t event_code, const void *data, unsigned int len)
return BLE_HS_ECONTROLLER;
}

ble_gap_vs_hci_event(data, len);
#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT)
ble_gap_unhandled_hci_event(false, true, data, len);
#endif

return 0;
}
Expand All @@ -315,6 +317,10 @@ ble_hs_hci_evt_le_meta(uint8_t event_code, const void *data, unsigned int len)
fn = ble_hs_hci_evt_le_dispatch_find(ev->subevent);
if (fn) {
return fn(ev->subevent, data, len);
} else {
#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT)
ble_gap_unhandled_hci_event(true, false, data, len);
#endif
}

return 0;
Expand Down Expand Up @@ -910,6 +916,9 @@ ble_hs_hci_evt_process(struct ble_hci_ev *ev)

entry = ble_hs_hci_evt_dispatch_find(ev->opcode);
if (entry == NULL) {
#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT)
ble_gap_unhandled_hci_event(false, false, ev->data, ev->length);
#endif
STATS_INC(ble_hs_stats, hci_unknown_event);
rc = BLE_HS_ENOTSUP;
} else {
Expand Down
7 changes: 7 additions & 0 deletions nimble/host/syscfg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,13 @@ syscfg.defs:
Sysinit stage for the NimBLE host.
value: 200

BLE_HS_GAP_UNHANDLED_HCI_EVENT:
description: >
Enables GAP event for received HCI events that are not handled by
host. This can be used to implement/test features that are not yet
supported by host.
value: 0

### Log settings.

BLE_HS_LOG_MOD:
Expand Down

0 comments on commit ef29646

Please sign in to comment.