gatt_client: wait until identity resolving complete for signed write, emit GATT_EVENT_QUERY_COMPLETE with ATT_ERROR_BONDING_INFORMATION_MISSING if not bonding information is available

This commit is contained in:
Matthias Ringwald 2019-05-01 18:18:27 +02:00
parent 51bd74d1a8
commit 793cf6ce5d
3 changed files with 30 additions and 5 deletions

View File

@ -64,7 +64,7 @@ static btstack_linked_list_t gatt_client_connections;
static btstack_linked_list_t gatt_client_value_listeners; static btstack_linked_list_t gatt_client_value_listeners;
static btstack_packet_callback_registration_t hci_event_callback_registration; static btstack_packet_callback_registration_t hci_event_callback_registration;
#ifdef ENABLE_GATT_CLIENT_PAIRING #if defined(ENABLE_GATT_CLIENT_PAIRING) || defined (ENABLE_LE_SIGNED_WRITE)
static btstack_packet_callback_registration_t sm_event_callback_registration; static btstack_packet_callback_registration_t sm_event_callback_registration;
#endif #endif
@ -94,7 +94,7 @@ void gatt_client_init(void){
hci_event_callback_registration.callback = &gatt_client_event_packet_handler; hci_event_callback_registration.callback = &gatt_client_event_packet_handler;
hci_add_event_handler(&hci_event_callback_registration); hci_add_event_handler(&hci_event_callback_registration);
#ifdef ENABLE_GATT_CLIENT_PAIRING #if defined(ENABLE_GATT_CLIENT_PAIRING) || defined (ENABLE_LE_SIGNED_WRITE)
// register for SM Events // register for SM Events
sm_event_callback_registration.callback = &gatt_client_event_packet_handler; sm_event_callback_registration.callback = &gatt_client_event_packet_handler;
sm_add_event_handler(&sm_event_callback_registration); sm_add_event_handler(&sm_event_callback_registration);
@ -1006,6 +1006,23 @@ static int gatt_client_run_for_peripheral( gatt_client_t * peripheral){
return 1; return 1;
#ifdef ENABLE_LE_SIGNED_WRITE #ifdef ENABLE_LE_SIGNED_WRITE
case P_W4_IDENTITY_RESOLVING:
log_info("P_W4_IDENTITY_RESOLVING - state %x", sm_identity_resolving_state(peripheral->con_handle));
switch (sm_identity_resolving_state(peripheral->con_handle)){
case IRK_LOOKUP_SUCCEEDED:
peripheral->le_device_index = sm_le_device_index(peripheral->con_handle);
peripheral->gatt_client_state = P_W4_CMAC_READY;
break;
case IRK_LOOKUP_FAILED:
gatt_client_handle_transaction_complete(peripheral);
emit_gatt_complete_event(peripheral, ATT_ERROR_BONDING_INFORMATION_MISSING);
return 0;
default:
return 0;
}
/* Fall through */
case P_W4_CMAC_READY: case P_W4_CMAC_READY:
if (sm_cmac_ready()){ if (sm_cmac_ready()){
sm_key_t csrk; sm_key_t csrk;
@ -1115,6 +1132,12 @@ static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t chann
} }
break; break;
#endif #endif
#ifdef ENABLE_LE_SIGNED_WRITE
// Identity Resolving completed (no code, gatt_client_run will continue)
case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED:
case SM_EVENT_IDENTITY_RESOLVING_FAILED:
break;
#endif
default: default:
break; break;
@ -1604,14 +1627,12 @@ static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t handle, uint16_t message_len, uint8_t * message){ uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t handle, uint16_t message_len, uint8_t * message){
gatt_client_t * peripheral = provide_context_for_conn_handle(con_handle); gatt_client_t * peripheral = provide_context_for_conn_handle(con_handle);
if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE; if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
peripheral->le_device_index = sm_le_device_index(con_handle);
if (peripheral->le_device_index < 0) return GATT_CLIENT_IN_WRONG_STATE; // device lookup not done / no stored bonding information
peripheral->callback = callback; peripheral->callback = callback;
peripheral->attribute_handle = handle; peripheral->attribute_handle = handle;
peripheral->attribute_length = message_len; peripheral->attribute_length = message_len;
peripheral->attribute_value = message; peripheral->attribute_value = message;
peripheral->gatt_client_state = P_W4_CMAC_READY; peripheral->gatt_client_state = P_W4_IDENTITY_RESOLVING;
gatt_client_run(); gatt_client_run();
return 0; return 0;

View File

@ -121,6 +121,7 @@ typedef enum {
P_W2_PREPARE_WRITE_SINGLE, P_W2_PREPARE_WRITE_SINGLE,
P_W4_PREPARE_WRITE_SINGLE_RESULT, P_W4_PREPARE_WRITE_SINGLE_RESULT,
P_W4_IDENTITY_RESOLVING,
P_W4_CMAC_READY, P_W4_CMAC_READY,
P_W4_CMAC_RESULT, P_W4_CMAC_RESULT,
P_W2_SEND_SIGNED_WRITE, P_W2_SEND_SIGNED_WRITE,

View File

@ -1111,6 +1111,9 @@ typedef enum {
#define ATT_ERROR_UNSUPPORTED_GROUP_TYPE 0x10 #define ATT_ERROR_UNSUPPORTED_GROUP_TYPE 0x10
#define ATT_ERROR_INSUFFICIENT_RESOURCES 0x11 #define ATT_ERROR_INSUFFICIENT_RESOURCES 0x11
// MARK: ATT Error Codes used internally by BTstack
#define ATT_ERROR_BONDING_INFORMATION_MISSING 0x70
// MARK: ATT Error Codes from Cycling Power Service spec // MARK: ATT Error Codes from Cycling Power Service spec
#define CYCLING_POWER_ERROR_CODE_INAPPROPRIATE_CONNECTION_PARAMETERS 0x80 #define CYCLING_POWER_ERROR_CODE_INAPPROPRIATE_CONNECTION_PARAMETERS 0x80
#define CYCLING_POWER_ERROR_CODE_PROCEDURE_ALREADY_IN_PROGRESS 0xFE #define CYCLING_POWER_ERROR_CODE_PROCEDURE_ALREADY_IN_PROGRESS 0xFE