Compare commits

...

4 Commits

Author SHA1 Message Date
anschrammh
0f376fd528 Now setting a default passkey when starting the BLE service/server 2023-04-18 23:15:10 +02:00
anschrammh
166581caeb Added the tls_bt_sm_ioact_2_str utility function 2023-04-18 23:15:09 +02:00
anschrammh
9269e279ef Updated the nimble stack configuration to prompt the user to enter a passkey when trying to pair it's phone with the host 2023-04-18 23:15:08 +02:00
anschrammh
b37dab16d5 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.
2023-04-18 23:13:47 +02:00
6 changed files with 178 additions and 7 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

View File

@ -667,6 +667,7 @@ int _bluetooth(const shell_cmd_t *pcmd, int argc, char *const argv[])
{
gadget_bridge_parser_register_event_callback(&(parser_event_cb));
ble_service_register_nus_data_rx_cb(&(nus_data_rx_cb));
ble_service_set_pairing_passkey(123456);
}
}
else if(strcmp(argv[1], "disable") == 0)

View File

@ -178,6 +178,23 @@ const char *tls_bt_access_opt_2_str(uint8_t op)
}
}
const char *tls_bt_sm_ioact_2_str(uint8_t ioact)
{
switch(ioact)
{
CASE_RETURN_STR(BLE_SM_IOACT_NONE)
CASE_RETURN_STR(BLE_SM_IOACT_OOB)
CASE_RETURN_STR(BLE_SM_IOACT_INPUT)
CASE_RETURN_STR(BLE_SM_IOACT_DISP)
CASE_RETURN_STR(BLE_SM_IOACT_NUMCMP)
CASE_RETURN_STR(BLE_SM_IOACT_OOB_SC)
CASE_RETURN_STR(BLE_SM_IOACT_MAX_PLUS_ONE)
default:
return "unknown io action type";
}
}
static void async_evt_func(struct ble_npl_event *ev)
{
ble_async_t *bat = (ble_async_t *)ev->arg;

View File

@ -56,6 +56,7 @@ const char *tls_bt_gap_evt_2_str(uint32_t event);
const char *tls_bt_rc_2_str(uint32_t event);
const char *tls_bt_addr_type_2_str(uint8_t addr_type);
const char *tls_bt_access_opt_2_str(uint8_t op);
const char *tls_bt_sm_ioact_2_str(uint8_t ioact);
extern int tls_bt_util_init(void);
extern int tls_bt_util_deinit(void);

View File

@ -302,7 +302,7 @@
#endif
#ifndef MYNEWT_VAL_LOG_LEVEL
#define MYNEWT_VAL_LOG_LEVEL (0)//(2)
#define MYNEWT_VAL_LOG_LEVEL (2)
#endif
/*** @apache-mynewt-core/sys/mfg */
@ -723,7 +723,7 @@
#endif
#ifndef MYNEWT_VAL_BLE_SM_MITM
#define MYNEWT_VAL_BLE_SM_MITM (1)//(0)
#define MYNEWT_VAL_BLE_SM_MITM (0)
#endif
#ifndef MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG
@ -731,7 +731,7 @@
#endif
#ifndef MYNEWT_VAL_BLE_SM_OUR_KEY_DIST
#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0x03) //(0x00)
#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0x00)
#endif
#ifndef MYNEWT_VAL_BLE_SM_SC