diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 80c5ecb98..bf554a314 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -159,13 +159,13 @@ struct hci_conn_update; #define BLE_GAP_EVENT_TEST_UPDATE 30 #define BLE_GAP_EVENT_DATA_LEN_CHG 31 -/* Deprecate EVENT_LINK_ESTAB */ -#define BLE_GAP_EVENT_LINK_ESTAB BLE_GAP_EVENT_CONNECT -#define BLE_GAP_EVENT_AUTHORIZE 32 -#define BLE_GAP_EVENT_EATT 33 -#define BLE_GAP_EVENT_PER_SUBEV_DATA_REQ 34 -#define BLE_GAP_EVENT_PER_SUBEV_RESP 35 -#define BLE_GAP_EVENT_PERIODIC_TRANSFER_V2 36 +//TODO : Deprecate the EVENT_LINK_ESTAB going ahead +#define BLE_GAP_EVENT_LINK_ESTAB 32 +#define BLE_GAP_EVENT_AUTHORIZE 33 +#define BLE_GAP_EVENT_EATT 34 +#define BLE_GAP_EVENT_PER_SUBEV_DATA_REQ 35 +#define BLE_GAP_EVENT_PER_SUBEV_RESP 36 +#define BLE_GAP_EVENT_PERIODIC_TRANSFER_V2 37 /* DTM events */ #define BLE_GAP_DTM_TX_START_EVT 0 @@ -634,6 +634,44 @@ struct ble_gap_event { #endif } connect; + /** + * Represents a successful Link establishment attempt. Sometimes, in noisy environment, + * even if BLE_GAP_EVENT_CONNECT is posted, the link syncronization procedure may fail + * and link gets disconnected with reason 0x3E. Application can wait for below event to ensure + * the link syncronization is completed. Valid for the following event + * types: + * o BLE_GAP_EVENT_LINK_ESTAB + */ + + struct { + /** + * The final status of the link establishment; + * o 0: the connection was successfully established. + * o BLE host error code: the connection attempt failed for + * the specified reason. + */ + int status; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + /* + * Adv_Handle is used to identify an advertising set. + * If the connection is established from periodic advertising with responses + * and Role is 0x00 then the Advertising_Handle parameter shall be set + * according to the periodic advertising train the connection was established from + */ + uint8_t adv_handle; + /* + * Sync_Handle identifying the periodic advertising train + * If the connection is established from periodic advertising with responses + * and Role is 0x01, then the Sync_Handle parameter shall be set according + * to the periodic advertising train the connection was established from + */ + uint16_t sync_handle; +#endif + } link_estab; + /** * Represents a terminated connection. Valid for the following event * types: diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index d47dda032..a200480c8 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1034,6 +1034,17 @@ ble_gap_master_connect_failure(int status) event.connect.adv_handle = pawr_adv_handle; #endif rc = state.cb(&event, state.cb_arg); + +//TODO Remove duplication of event fields + event.type = BLE_GAP_EVENT_LINK_ESTAB; + event.link_estab.status = status; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.link_estab.sync_handle = pawr_sync_handle; + event.link_estab.adv_handle = pawr_adv_handle; +#endif + rc = state.cb(&event, state.cb_arg); + } else { rc = 0; } @@ -1063,6 +1074,23 @@ ble_gap_master_connect_cancelled(void) #if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) event.connect.sync_handle = pawr_sync_handle; event.connect.adv_handle = pawr_adv_handle; +#endif + state.cb(&event, state.cb_arg); + +//TODO Remove duplication of event fields + event.type = BLE_GAP_EVENT_LINK_ESTAB; + event.link_estab.conn_handle = BLE_HS_CONN_HANDLE_NONE; + if (state.conn.cancel) { + /* Connect procedure successfully cancelled. */ + event.link_estab.status = BLE_HS_EAPP; + } else { + /* Connect procedure timed out. */ + event.link_estab.status = BLE_HS_ETIMEOUT; + } + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.link_estab.sync_handle = pawr_sync_handle; + event.link_estab.adv_handle = pawr_adv_handle; #endif state.cb(&event, state.cb_arg); } @@ -2276,11 +2304,12 @@ ble_gap_rx_periodic_adv_response(const struct ble_gap_periodic_adv_response resp void ble_gap_rx_conn_comp_failed(const struct ble_gap_conn_complete *evt) { - struct ble_gap_event event; + struct ble_gap_event event, event_link_estab; ble_gap_event_fn *cb; void *cb_arg; memset(&event, 0x0, sizeof event); + memset(&event_link_estab, 0x0, sizeof event); event.type = BLE_GAP_EVENT_CONNECT; event.connect.conn_handle = evt->connection_handle; @@ -2289,13 +2318,23 @@ ble_gap_rx_conn_comp_failed(const struct ble_gap_conn_complete *evt) event.connect.sync_handle = evt->sync_handle; event.connect.adv_handle = evt->adv_handle; +//TODO Remove duplication of event fields + event_link_estab.type = BLE_GAP_EVENT_LINK_ESTAB; + event_link_estab.link_estab.conn_handle = evt->connection_handle; + event_link_estab.link_estab.status = BLE_ERR_CONN_ESTABLISHMENT; + + event_link_estab.link_estab.sync_handle = evt->sync_handle; + event_link_estab.link_estab.adv_handle = evt->adv_handle; + ble_gap_master_reset_state(); ble_gap_slave_extract_cb(evt->adv_handle, &cb, &cb_arg); if (cb != NULL) { cb(&event, cb_arg); + cb(&event_link_estab, cb_arg); } ble_gap_event_listener_call(&event); + ble_gap_event_listener_call(&event_link_estab); } #endif @@ -2535,6 +2574,19 @@ ble_gap_event_connect_call(uint16_t conn_handle, int status) ble_gap_event_listener_call(&event); ble_gap_call_conn_event_cb(&event, handle); +//TODO : Remove duplication of event + event.type = BLE_GAP_EVENT_LINK_ESTAB; + event.link_estab.status = status; + event.link_estab.conn_handle = handle; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.link_estab.sync_handle = pawr_sync_handle; + event.link_estab.adv_handle = pawr_adv_handle; +#endif + + ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, handle); + ble_hs_hci_util_set_data_len(le16toh(conn_handle), BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX, BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX); }