Now handling pairing by asking to enter a passkey on the phone side. This

passkey is then verified with the code entered on the host side. Also
handling the repeat pairing event by reperforming the pairing process.
This commit is contained in:
anschrammh 2023-04-18 23:03:08 +02:00
parent 7c78142f88
commit b37dab16d5
2 changed files with 156 additions and 4 deletions

View File

@ -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;

View File

@ -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