diff --git a/app/ble/ble_service.c b/app/ble/ble_service.c index 620e12f..d5b991b 100644 --- a/app/ble/ble_service.c +++ b/app/ble/ble_service.c @@ -12,6 +12,7 @@ static volatile ble_service_state_e _ble_service_state = BLE_SERVICE_MODE_STOPPED; static nus_data_rx_fn_t _ble_service_nus_data_rx_cb = NULL; static ble_service_state_change_fn_t _ble_service_state_change_cb = NULL; +static uint32_t _pairing_passkey = 0; /* Connection handle to the connected device : only one simultaneous connection */ static uint16_t ble_device_conn_handle = BLE_HS_CONN_HANDLE_NONE; @@ -113,6 +114,7 @@ static bool ble_service_define_gatt(const struct ble_gatt_svc_def *gatt_svc); static bool ble_service_advertise(bool enable); static int ble_gap_event_cb(struct ble_gap_event *event, void *arg); static int ble_advertise_gap_event_cb(struct ble_gap_event *event, void *arg); +static int ble_conn_gap_event_cb(struct ble_gap_event *event, void *arg); static void print_conn_desc(const struct ble_gap_conn_desc *desc); // Raw because it doesn't handle payload fragmentation if mtu size is smaller than the payload size static bool ble_service_send_raw_custom_notification(uint16_t characteristic_handle, const uint8_t *data, uint16_t length); @@ -292,6 +294,11 @@ ble_service_state_e ble_service_get_state(void) return _ble_service_state; } +void ble_service_set_pairing_passkey(uint32_t passkey) +{ + _pairing_passkey = passkey; +} + bool ble_service_update_connection_parameters( uint16_t itvl_min, uint16_t itvl_max, @@ -367,10 +374,9 @@ void ble_service_register_nus_data_rx_cb(nus_data_rx_fn_t nus_data_rx_cb) void ble_service_set_battery_value(uint8_t value) { - if(value > 100) value = 100; - - _battery_level_value = value; + _battery_level_value = value > 100 ? 100 : value; } + /** * PRIVATE FUNCTION DEFINITION * Used for the internal workings of the service @@ -587,6 +593,10 @@ static int ble_gap_event_cb(struct ble_gap_event *event, void *arg) usable_mtu = USABLE_DEFAULT_MTU; ble_device_conn_handle = event->connect.conn_handle; + if((status = ble_gap_set_event_cb(event->connect.conn_handle, &(ble_conn_gap_event_cb), NULL)) != BLE_HS_ENOERR) + { + TLS_BT_APPL_TRACE_WARNING("%s, ble_gap_set_event_cb %s"NEW_LINE, __FUNCTION__, tls_bt_rc_2_str(status)); + } //We call the state change callback if registered if(_ble_service_state_change_cb)_ble_service_state_change_cb(_ble_service_state); } @@ -657,7 +667,7 @@ static int ble_gap_event_cb(struct ble_gap_event *event, void *arg) if(_ble_service_state_change_cb)_ble_service_state_change_cb(_ble_service_state); break; case BLE_GAP_EVENT_CONN_UPDATE: - TLS_BT_APPL_TRACE_DEBUG("Conn update status : %d"NEW_LINE, event->conn_update.status); + TLS_BT_APPL_TRACE_DEBUG("Conn update status : %s"NEW_LINE, tls_bt_rc_2_str(event->conn_update.status)); if((status = ble_gap_conn_find(event->connect.conn_handle, &desc)) == BLE_HS_ENOERR) { print_conn_desc(&desc); @@ -736,6 +746,136 @@ static int ble_advertise_gap_event_cb(struct ble_gap_event *event, void *arg) return BLE_HS_ENOERR; } +static int ble_conn_gap_event_cb(struct ble_gap_event *event, void *arg) +{ + int status = BLE_HS_ENOERR; + struct ble_gap_conn_desc desc; + + TLS_BT_APPL_TRACE_EVENT("%s : %s"NEW_LINE, __FUNCTION__, tls_bt_gap_evt_2_str(event->type)); + + switch(event->type) + { + case BLE_GAP_EVENT_PASSKEY_ACTION: + TLS_BT_APPL_TRACE_VERBOSE("conn_handle : %u"NEW_LINE + "action : %s"NEW_LINE, + event->passkey.conn_handle, + tls_bt_sm_ioact_2_str(event->passkey.params.action)); + + if(BLE_SM_IOACT_NUMCMP == event->passkey.params.action) + { + TLS_BT_APPL_TRACE_VERBOSE("numcmp : %u"NEW_LINE, + event->passkey.params.numcmp); + } + + struct ble_sm_io sm_io = { + .action = BLE_SM_IOACT_DISP, + .passkey = _pairing_passkey, + }; + + if((status = ble_sm_inject_io(event->passkey.conn_handle, &sm_io)) != BLE_HS_ENOERR) + { + TLS_BT_APPL_TRACE_ERROR("%s, ble_sm_inject_io %s"NEW_LINE, __FUNCTION__, tls_bt_rc_2_str(status)); + } + break; + case BLE_GAP_EVENT_CONN_UPDATE: + TLS_BT_APPL_TRACE_DEBUG("Conn update status : %s"NEW_LINE, tls_bt_rc_2_str(event->conn_update.status)); + if((status = ble_gap_conn_find(event->connect.conn_handle, &desc)) == BLE_HS_ENOERR) + { + print_conn_desc(&desc); + } + else + { + TLS_BT_APPL_TRACE_WARNING("%s, ble_gap_conn_find %s"NEW_LINE, __FUNCTION__, tls_bt_rc_2_str(status)); + } + break; + case BLE_GAP_EVENT_ENC_CHANGE: + TLS_BT_APPL_TRACE_DEBUG("Enc change status : (%u) -> %s"NEW_LINE, event->enc_change.status, tls_bt_rc_2_str(event->enc_change.status)); + break; + case BLE_GAP_EVENT_REPEAT_PAIRING: + { + // If this event is triggered, then we shall remove the device from the bonded device list + // and tell it to pair again. + uint16_t conn_handle = event->repeat_pairing.conn_handle; + TLS_BT_APPL_TRACE_VERBOSE("conn_handle : %u"NEW_LINE + "cur_key_size : %u"NEW_LINE + "cur_authenticated : %u"NEW_LINE + "cur_sc : %u"NEW_LINE + "new_key_size : %u"NEW_LINE + "new_authenticated : %u"NEW_LINE + "new_sc : %u"NEW_LINE + "new_bonding : %u"NEW_LINE, + event->repeat_pairing.conn_handle, + event->repeat_pairing.cur_key_size, + event->repeat_pairing.cur_authenticated, + event->repeat_pairing.cur_sc, + event->repeat_pairing.new_key_size, + event->repeat_pairing.new_authenticated, + event->repeat_pairing.new_sc, + event->repeat_pairing.new_bonding); + + if((status = ble_gap_conn_find(conn_handle, &desc)) != BLE_HS_ENOERR) + { + TLS_BT_APPL_TRACE_ERROR("%s, ble_gap_conn_find %s"NEW_LINE, __FUNCTION__, tls_bt_rc_2_str(status)); + return status; + } + + TLS_BT_APPL_TRACE_VERBOSE("sec_state_encrypted : %u"NEW_LINE + "sec_state_authenticated : %u"NEW_LINE + "sec_state_bonded : %u"NEW_LINE + "sec_state_key_size : %u"NEW_LINE + "our_id_addr(%u) : %02X:%02X:%02X:%02X:%02X:%02X"NEW_LINE + "our_ota_addr(%u) : %02X:%02X:%02X:%02X:%02X:%02X"NEW_LINE + "peer_id_addr(%u) : %02X:%02X:%02X:%02X:%02X:%02X"NEW_LINE + "peer_ota_addr(%u) : %02X:%02X:%02X:%02X:%02X:%02X"NEW_LINE, + desc.sec_state.encrypted, + desc.sec_state.authenticated, + desc.sec_state.bonded, + desc.sec_state.key_size, + desc.our_id_addr.type, + desc.our_id_addr.val[5], + desc.our_id_addr.val[4], + desc.our_id_addr.val[3], + desc.our_id_addr.val[2], + desc.our_id_addr.val[1], + desc.our_id_addr.val[0], + desc.our_ota_addr.type, + desc.our_ota_addr.val[5], + desc.our_ota_addr.val[4], + desc.our_ota_addr.val[3], + desc.our_ota_addr.val[2], + desc.our_ota_addr.val[1], + desc.our_ota_addr.val[0], + desc.peer_id_addr.type, + desc.peer_id_addr.val[5], + desc.peer_id_addr.val[4], + desc.peer_id_addr.val[3], + desc.peer_id_addr.val[2], + desc.peer_id_addr.val[1], + desc.peer_id_addr.val[0], + desc.peer_ota_addr.type, + desc.peer_ota_addr.val[5], + desc.peer_ota_addr.val[4], + desc.peer_ota_addr.val[3], + desc.peer_ota_addr.val[2], + desc.peer_ota_addr.val[1], + desc.peer_ota_addr.val[0]); + + if((status = ble_gap_unpair(&desc.peer_id_addr)) != BLE_HS_ENOERR) + { + TLS_BT_APPL_TRACE_ERROR("%s, ble_gap_unpair %s"NEW_LINE, __FUNCTION__, tls_bt_rc_2_str(status)); + return status; + } + + return BLE_GAP_REPEAT_PAIRING_RETRY; + } + break; + default: + TLS_BT_APPL_TRACE_WARNING("unhandled event !"NEW_LINE); + } + + return BLE_HS_ENOERR; +} + static int battery_level_char_access_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { int status = BLE_HS_ENOERR; diff --git a/app/ble/ble_service.h b/app/ble/ble_service.h index 1e80e2d..3d9c758 100644 --- a/app/ble/ble_service.h +++ b/app/ble/ble_service.h @@ -76,6 +76,13 @@ void ble_service_register_state_change_cb(ble_service_state_change_fn_t ble_serv */ ble_service_state_e ble_service_get_state(void); +/** + * @brief + * + * @param passkey + */ +void ble_service_set_pairing_passkey(uint32_t passkey); + /** * @brief Asks to update the current connection parameters * /!\ A connection should be already active before calling this function. @@ -123,6 +130,11 @@ bool ble_service_send_nus_data(const uint8_t *data, uint16_t length); */ void ble_service_register_nus_data_rx_cb(nus_data_rx_fn_t nus_data_rx_cb); +/** + * @brief Sets the battery level in percents sent by the BLE battery service + * + * @param value the battery level to set in percents + */ void ble_service_set_battery_value(uint8_t value); #endif //BLE_APP_H