diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index c03333c10..2e0fbc4ba 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -158,6 +158,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_VS_HCI 29 #define BLE_GAP_EVENT_BIGINFO_REPORT 30 #define BLE_GAP_EVENT_REATTEMPT_COUNT 31 +#define BLE_GAP_EVENT_AUTHORIZE 32 /*** Reason codes for the subscribe GAP event. */ @@ -188,6 +189,10 @@ struct hci_conn_update; /** @} */ +/* Response values for gatt read/write authorization event */ +#define BLE_GAP_AUTHORIZE_ACCEPT 1 +#define BLE_GAP_AUTHORIZE_REJECT 2 + /** Connection security state */ struct ble_gap_sec_state { /** If connection is encrypted */ @@ -1166,6 +1171,31 @@ struct ble_gap_event { } vs_hci; #endif + /** + * GATT Authorization Event. Ask the user to authorize a GATT + * read/write operation. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_AUTHORIZE + * + * Valid responses from user: + * o BLE_GAP_AUTHORIZE_ACCEPT + * o BLE_GAP_AUTHORIZE_REJECT + */ + struct { + /* Connection Handle */ + uint16_t conn_handle; + + /* Attribute handle of the attribute being accessed. */ + uint16_t attr_handle; + + /* Weather the operation is a read or write operation. */ + int is_read; + + /* User's response */ + int out_response; + } authorize; + #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) /** * Represents a event mentioning connection reattempt diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index d167b2adc..ca486a375 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -371,6 +371,11 @@ ble_att_svr_check_perms(uint16_t conn_handle, int is_read, if (author) { /* XXX: Prompt user for authorization. */ + rc = ble_gap_authorize_event(conn_handle, entry->ha_handle_id, is_read); + if (rc == BLE_GAP_AUTHORIZE_REJECT) { + *out_att_err = BLE_ATT_ERR_INSUFFICIENT_AUTHOR; + return BLE_HS_ATT_ERR(*out_att_err); + } } return 0; diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index b582805f2..4fb803c9e 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -7127,6 +7127,32 @@ ble_gap_vs_hci_event(const void *buf, uint8_t len) } #endif +int +ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle, + int is_read) +{ +#if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) + struct ble_gap_event event; + + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_AUTHORIZE; + event.authorize.conn_handle = conn_handle; + event.authorize.attr_handle = attr_handle; + event.authorize.is_read = is_read; + + ble_gap_call_conn_event_cb(&event, conn_handle); + + /* Make sure reject is sent back if the application + * sets response to anything but accept. + */ + if (event.authorize.out_response != BLE_GAP_AUTHORIZE_ACCEPT) { + return BLE_GAP_AUTHORIZE_REJECT; + } + return event.authorize.out_response; +#endif + return BLE_GAP_AUTHORIZE_REJECT; +} + /***************************************************************************** * $preempt * *****************************************************************************/ diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 34a5f952b..d15f633ef 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -142,6 +142,7 @@ 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); +int ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle, int is_read); int ble_gap_master_in_progress(void); void ble_gap_preempt(void);