extmod/modbluetooth: Add support for passkey authentication.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
pull/6662/head
Jim Mussared 2020-11-26 23:49:45 +11:00 zatwierdzone przez Damien George
rodzic 4bcbbfdb6c
commit e4f27cbee7
3 zmienionych plików z 71 dodań i 0 usunięć

Wyświetl plik

@ -689,6 +689,14 @@ STATIC mp_obj_t bluetooth_ble_gap_pair(mp_obj_t self_in, mp_obj_t conn_handle_in
return bluetooth_handle_errno(mp_bluetooth_gap_pair(conn_handle)); return bluetooth_handle_errno(mp_bluetooth_gap_pair(conn_handle));
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(bluetooth_ble_gap_pair_obj, bluetooth_ble_gap_pair); STATIC MP_DEFINE_CONST_FUN_OBJ_2(bluetooth_ble_gap_pair_obj, bluetooth_ble_gap_pair);
STATIC mp_obj_t bluetooth_ble_gap_passkey(size_t n_args, const mp_obj_t *args) {
uint16_t conn_handle = mp_obj_get_int(args[1]);
uint8_t action = mp_obj_get_int(args[2]);
mp_int_t passkey = mp_obj_get_int(args[3]);
return bluetooth_handle_errno(mp_bluetooth_gap_passkey(conn_handle, action, passkey));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_passkey_obj, 4, 4, bluetooth_ble_gap_passkey);
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING #endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -894,6 +902,7 @@ STATIC const mp_rom_map_elem_t bluetooth_ble_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_gap_disconnect), MP_ROM_PTR(&bluetooth_ble_gap_disconnect_obj) }, { MP_ROM_QSTR(MP_QSTR_gap_disconnect), MP_ROM_PTR(&bluetooth_ble_gap_disconnect_obj) },
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING #if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
{ MP_ROM_QSTR(MP_QSTR_gap_pair), MP_ROM_PTR(&bluetooth_ble_gap_pair_obj) }, { MP_ROM_QSTR(MP_QSTR_gap_pair), MP_ROM_PTR(&bluetooth_ble_gap_pair_obj) },
{ MP_ROM_QSTR(MP_QSTR_gap_passkey), MP_ROM_PTR(&bluetooth_ble_gap_passkey_obj) },
#endif #endif
// GATT Server (i.e. peripheral/advertiser role) // GATT Server (i.e. peripheral/advertiser role)
{ MP_ROM_QSTR(MP_QSTR_gatts_register_services), MP_ROM_PTR(&bluetooth_ble_gatts_register_services_obj) }, { MP_ROM_QSTR(MP_QSTR_gatts_register_services), MP_ROM_PTR(&bluetooth_ble_gatts_register_services_obj) },
@ -1167,6 +1176,11 @@ bool mp_bluetooth_gap_on_set_secret(uint8_t type, const uint8_t *key, size_t key
mp_obj_t result = invoke_irq_handler(MP_BLUETOOTH_IRQ_SET_SECRET, args, 1, 0, NULL_ADDR, NULL_UUID, data, data_len, 2); mp_obj_t result = invoke_irq_handler(MP_BLUETOOTH_IRQ_SET_SECRET, args, 1, 0, NULL_ADDR, NULL_UUID, data, data_len, 2);
return mp_obj_is_true(result); return mp_obj_is_true(result);
} }
void mp_bluetooth_gap_on_passkey_action(uint16_t conn_handle, uint8_t action, mp_int_t passkey) {
mp_int_t args[] = { conn_handle, action, passkey };
invoke_irq_handler(MP_BLUETOOTH_IRQ_PASSKEY_ACTION, args, 2, 1, NULL_ADDR, NULL_UUID, NULL_DATA, NULL_DATA_LEN, 0);
}
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING #endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
void mp_bluetooth_gatts_on_write(uint16_t conn_handle, uint16_t value_handle) { void mp_bluetooth_gatts_on_write(uint16_t conn_handle, uint16_t value_handle) {

Wyświetl plik

@ -148,6 +148,7 @@
#define MP_BLUETOOTH_IRQ_ENCRYPTION_UPDATE (28) #define MP_BLUETOOTH_IRQ_ENCRYPTION_UPDATE (28)
#define MP_BLUETOOTH_IRQ_GET_SECRET (29) #define MP_BLUETOOTH_IRQ_GET_SECRET (29)
#define MP_BLUETOOTH_IRQ_SET_SECRET (30) #define MP_BLUETOOTH_IRQ_SET_SECRET (30)
#define MP_BLUETOOTH_IRQ_PASSKEY_ACTION (31)
#define MP_BLUETOOTH_ADDRESS_MODE_PUBLIC (0) #define MP_BLUETOOTH_ADDRESS_MODE_PUBLIC (0)
#define MP_BLUETOOTH_ADDRESS_MODE_RANDOM (1) #define MP_BLUETOOTH_ADDRESS_MODE_RANDOM (1)
@ -167,6 +168,12 @@
#define MP_BLUETOOTH_PASSKEY_ACTION_DISPLAY (3) #define MP_BLUETOOTH_PASSKEY_ACTION_DISPLAY (3)
#define MP_BLUETOOTH_PASSKEY_ACTION_NUMERIC_COMPARISON (4) #define MP_BLUETOOTH_PASSKEY_ACTION_NUMERIC_COMPARISON (4)
// These match NimBLE BLE_SM_IOACT_.
#define MP_BLUETOOTH_PASSKEY_ACTION_NONE (0)
#define MP_BLUETOOTH_PASSKEY_ACTION_INPUT (2)
#define MP_BLUETOOTH_PASSKEY_ACTION_DISPLAY (3)
#define MP_BLUETOOTH_PASSKEY_ACTION_NUMERIC_COMPARISON (4)
/* /*
These aren't included in the module for space reasons, but can be used These aren't included in the module for space reasons, but can be used
in your Python code if necessary. in your Python code if necessary.
@ -202,6 +209,7 @@ _IRQ_CONNECTION_UPDATE = const(27)
_IRQ_ENCRYPTION_UPDATE = const(28) _IRQ_ENCRYPTION_UPDATE = const(28)
_IRQ_GET_SECRET = const(29) _IRQ_GET_SECRET = const(29)
_IRQ_SET_SECRET = const(30) _IRQ_SET_SECRET = const(30)
_IRQ_PASSKEY_ACTION = const(31)
_FLAG_BROADCAST = const(0x0001) _FLAG_BROADCAST = const(0x0001)
_FLAG_READ = const(0x0002) _FLAG_READ = const(0x0002)
@ -231,6 +239,11 @@ _IO_CAPABILITY_DISPLAY_YESNO = const(1)
_IO_CAPABILITY_KEYBOARD_ONLY = const(2) _IO_CAPABILITY_KEYBOARD_ONLY = const(2)
_IO_CAPABILITY_NO_INPUT_OUTPUT = const(3) _IO_CAPABILITY_NO_INPUT_OUTPUT = const(3)
_IO_CAPABILITY_KEYBOARD_DISPLAY = const(4) _IO_CAPABILITY_KEYBOARD_DISPLAY = const(4)
_PASSKEY_ACTION_NONE = const(0)
_PASSKEY_ACTION_INPUT = const(2)
_PASSKEY_ACTION_DISPLAY = const(3)
_PASSKEY_ACTION_NUMERIC_COMPARISON = const(4)
*/ */
// bluetooth.UUID type. // bluetooth.UUID type.
@ -332,6 +345,9 @@ int mp_bluetooth_set_preferred_mtu(uint16_t mtu);
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING #if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
// Initiate pairing on the specified connection. // Initiate pairing on the specified connection.
int mp_bluetooth_gap_pair(uint16_t conn_handle); int mp_bluetooth_gap_pair(uint16_t conn_handle);
// Respond to a pairing request.
int mp_bluetooth_gap_passkey(uint16_t conn_handle, uint8_t action, mp_int_t passkey);
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING #endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
#if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE #if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE
@ -387,8 +403,12 @@ void mp_bluetooth_gatts_on_encryption_update(uint16_t conn_handle, bool encrypte
// Call this when you need the application to manage persistent key data. // Call this when you need the application to manage persistent key data.
// For get, if key is NULL, then the implementation must return the index'th matching key. Otherwise it should return a specific key. // For get, if key is NULL, then the implementation must return the index'th matching key. Otherwise it should return a specific key.
// For set, if value is NULL, then delete. // For set, if value is NULL, then delete.
// The "type" is stack-specific, but could also be used to implement versioning.
bool mp_bluetooth_gap_on_get_secret(uint8_t type, uint8_t index, const uint8_t *key, size_t key_len, const uint8_t **value, size_t *value_len); bool mp_bluetooth_gap_on_get_secret(uint8_t type, uint8_t index, const uint8_t *key, size_t key_len, const uint8_t **value, size_t *value_len);
bool mp_bluetooth_gap_on_set_secret(uint8_t type, const uint8_t *key, size_t key_len, const uint8_t *value, size_t value_len); bool mp_bluetooth_gap_on_set_secret(uint8_t type, const uint8_t *key, size_t key_len, const uint8_t *value, size_t value_len);
// Call this when a passkey verification needs to be processed.
void mp_bluetooth_gap_on_passkey_action(uint16_t conn_handle, uint8_t action, mp_int_t passkey);
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING #endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
// Call this when a characteristic is written to. // Call this when a characteristic is written to.

Wyświetl plik

@ -347,6 +347,16 @@ STATIC int gap_event_cb(struct ble_gap_event *event, void *arg) {
return BLE_GAP_REPEAT_PAIRING_RETRY; return BLE_GAP_REPEAT_PAIRING_RETRY;
} }
case BLE_GAP_EVENT_PASSKEY_ACTION: {
DEBUG_printf("gap_event_cb: passkey action: conn_handle=%d action=%d num=" UINT_FMT "\n", event->passkey.conn_handle, event->passkey.params.action, (mp_uint_t)event->passkey.params.numcmp);
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
mp_bluetooth_gap_on_passkey_action(event->passkey.conn_handle, event->passkey.params.action, event->passkey.params.numcmp);
#endif
return 0;
}
default: default:
DEBUG_printf("gap_event_cb: unknown type %d\n", event->type); DEBUG_printf("gap_event_cb: unknown type %d\n", event->type);
break; break;
@ -886,6 +896,33 @@ int mp_bluetooth_gap_pair(uint16_t conn_handle) {
DEBUG_printf("mp_bluetooth_gap_pair: conn_handle=%d\n", conn_handle); DEBUG_printf("mp_bluetooth_gap_pair: conn_handle=%d\n", conn_handle);
return ble_hs_err_to_errno(ble_gap_security_initiate(conn_handle)); return ble_hs_err_to_errno(ble_gap_security_initiate(conn_handle));
} }
int mp_bluetooth_gap_passkey(uint16_t conn_handle, uint8_t action, mp_int_t passkey) {
struct ble_sm_io io = {0};
switch (action) {
case MP_BLUETOOTH_PASSKEY_ACTION_INPUT: {
io.passkey = passkey;
break;
}
case MP_BLUETOOTH_PASSKEY_ACTION_DISPLAY: {
io.passkey = passkey;
break;
}
case MP_BLUETOOTH_PASSKEY_ACTION_NUMERIC_COMPARISON: {
io.numcmp_accept = passkey != 0;
break;
}
default: {
return MP_EINVAL;
}
}
io.action = action;
DEBUG_printf("mp_bluetooth_gap_passkey: injecting IO: conn_handle=%d, action=%d, passkey=" UINT_FMT ", numcmp_accept=%d\n", conn_handle, io.action, (mp_uint_t)io.passkey, io.numcmp_accept);
return ble_hs_err_to_errno(ble_sm_inject_io(conn_handle, &io));
}
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING #endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
#if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE #if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE