extmod/modbluetooth: Allow setting char/desc enc/auth options.
This widens the characteristic/descriptor flags to 16-bit, to allow setting encryption/authentication requirements. Sets the required flags for NimBLE and btstack implementations. The BLE.FLAG_* constants will eventually be deprecated in favour of copy and paste Python constants (like the IRQs). Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
parent
7a9aa49595
commit
1697ff335d
|
@ -12,14 +12,19 @@ _IRQ_CENTRAL_CONNECT = const(1)
|
|||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_WRITE = const(3)
|
||||
|
||||
_FLAG_READ = const(0x0002)
|
||||
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
|
||||
_FLAG_WRITE = const(0x0008)
|
||||
_FLAG_NOTIFY = const(0x0010)
|
||||
|
||||
_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
|
||||
_UART_TX = (
|
||||
bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"),
|
||||
bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,
|
||||
_FLAG_READ | _FLAG_NOTIFY,
|
||||
)
|
||||
_UART_RX = (
|
||||
bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),
|
||||
bluetooth.FLAG_WRITE | bluetooth.FLAG_WRITE_NO_RESPONSE,
|
||||
_FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,
|
||||
)
|
||||
_UART_SERVICE = (
|
||||
_UART_UUID,
|
||||
|
|
|
@ -15,12 +15,16 @@ _IRQ_CENTRAL_CONNECT = const(1)
|
|||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_INDICATE_DONE = const(20)
|
||||
|
||||
_FLAG_READ = const(0x0002)
|
||||
_FLAG_NOTIFY = const(0x0010)
|
||||
_FLAG_INDICATE = const(0x0020)
|
||||
|
||||
# org.bluetooth.service.environmental_sensing
|
||||
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
|
||||
# org.bluetooth.characteristic.temperature
|
||||
_TEMP_CHAR = (
|
||||
bluetooth.UUID(0x2A6E),
|
||||
bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY | bluetooth.FLAG_INDICATE,
|
||||
_FLAG_READ | _FLAG_NOTIFY | _FLAG_INDICATE,
|
||||
)
|
||||
_ENV_SENSE_SERVICE = (
|
||||
_ENV_SENSE_UUID,
|
||||
|
|
|
@ -9,14 +9,17 @@ _IRQ_CENTRAL_CONNECT = const(1)
|
|||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_WRITE = const(3)
|
||||
|
||||
_FLAG_WRITE = const(0x0008)
|
||||
_FLAG_NOTIFY = const(0x0010)
|
||||
|
||||
_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
|
||||
_UART_TX = (
|
||||
bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"),
|
||||
bluetooth.FLAG_NOTIFY,
|
||||
_FLAG_NOTIFY,
|
||||
)
|
||||
_UART_RX = (
|
||||
bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),
|
||||
bluetooth.FLAG_WRITE,
|
||||
_FLAG_WRITE,
|
||||
)
|
||||
_UART_SERVICE = (
|
||||
_UART_UUID,
|
||||
|
|
|
@ -893,7 +893,30 @@ STATIC inline uint16_t get_uuid16(const mp_obj_bluetooth_uuid_t *uuid) {
|
|||
return (uuid->data[1] << 8) | uuid->data[0];
|
||||
}
|
||||
|
||||
int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, mp_obj_bluetooth_uuid_t **characteristic_uuids, uint8_t *characteristic_flags, mp_obj_bluetooth_uuid_t **descriptor_uuids, uint8_t *descriptor_flags, uint8_t *num_descriptors, uint16_t *handles, size_t num_characteristics) {
|
||||
// Map MP_BLUETOOTH_CHARACTERISTIC_FLAG_ values to btstack read/write permission values.
|
||||
STATIC void get_characteristic_permissions(uint16_t flags, uint16_t *read_permission, uint16_t *write_permission) {
|
||||
if (flags & MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ_ENCRYPTED) {
|
||||
*read_permission = ATT_SECURITY_ENCRYPTED;
|
||||
} else if (flags & MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ_AUTHENTICATED) {
|
||||
*read_permission = ATT_SECURITY_AUTHENTICATED;
|
||||
} else if (flags & MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ_AUTHORIZED) {
|
||||
*read_permission = ATT_SECURITY_AUTHORIZED;
|
||||
} else {
|
||||
*read_permission = ATT_SECURITY_NONE;
|
||||
}
|
||||
|
||||
if (flags & MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE_ENCRYPTED) {
|
||||
*write_permission = ATT_SECURITY_ENCRYPTED;
|
||||
} else if (flags & MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE_AUTHENTICATED) {
|
||||
*write_permission = ATT_SECURITY_AUTHENTICATED;
|
||||
} else if (flags & MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE_AUTHORIZED) {
|
||||
*write_permission = ATT_SECURITY_AUTHORIZED;
|
||||
} else {
|
||||
*write_permission = ATT_SECURITY_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, mp_obj_bluetooth_uuid_t **characteristic_uuids, uint16_t *characteristic_flags, mp_obj_bluetooth_uuid_t **descriptor_uuids, uint16_t *descriptor_flags, uint8_t *num_descriptors, uint16_t *handles, size_t num_characteristics) {
|
||||
DEBUG_printf("mp_bluetooth_gatts_register_service\n");
|
||||
// Note: btstack expects BE UUIDs (which it immediately convertes to LE).
|
||||
// So we have to convert all our modbluetooth LE UUIDs to BE just for the att_db_util_add_* methods (using get_uuid16 above, and reverse_128 from btstackutil.h).
|
||||
|
@ -916,9 +939,9 @@ int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, m
|
|||
static uint8_t cccb_buf[2] = {0};
|
||||
|
||||
for (size_t i = 0; i < num_characteristics; ++i) {
|
||||
uint16_t props = characteristic_flags[i] | ATT_PROPERTY_DYNAMIC;
|
||||
uint16_t read_permission = ATT_SECURITY_NONE;
|
||||
uint16_t write_permission = ATT_SECURITY_NONE;
|
||||
uint16_t props = (characteristic_flags[i] & 0x7f) | ATT_PROPERTY_DYNAMIC;
|
||||
uint16_t read_permission, write_permission;
|
||||
get_characteristic_permissions(characteristic_flags[i], &read_permission, &write_permission);
|
||||
if (characteristic_uuids[i]->type == MP_BLUETOOTH_UUID_TYPE_16) {
|
||||
handles[handle_index] = att_db_util_add_characteristic_uuid16(get_uuid16(characteristic_uuids[i]), props, read_permission, write_permission, NULL, 0);
|
||||
} else if (characteristic_uuids[i]->type == MP_BLUETOOTH_UUID_TYPE_128) {
|
||||
|
@ -942,9 +965,8 @@ int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, m
|
|||
++handle_index;
|
||||
|
||||
for (size_t j = 0; j < num_descriptors[i]; ++j) {
|
||||
props = descriptor_flags[descriptor_index] | ATT_PROPERTY_DYNAMIC;
|
||||
read_permission = ATT_SECURITY_NONE;
|
||||
write_permission = ATT_SECURITY_NONE;
|
||||
props = (descriptor_flags[descriptor_index] & 0x7f) | ATT_PROPERTY_DYNAMIC;
|
||||
get_characteristic_permissions(descriptor_flags[descriptor_index], &read_permission, &write_permission);
|
||||
|
||||
if (descriptor_uuids[descriptor_index]->type == MP_BLUETOOTH_UUID_TYPE_16) {
|
||||
handles[handle_index] = att_db_util_add_descriptor_uuid16(get_uuid16(descriptor_uuids[descriptor_index]), props, read_permission, write_permission, NULL, 0);
|
||||
|
|
|
@ -461,11 +461,11 @@ STATIC int bluetooth_gatts_register_service(mp_obj_t uuid_in, mp_obj_t character
|
|||
|
||||
// Lists of characteristic uuids and flags.
|
||||
mp_obj_bluetooth_uuid_t **characteristic_uuids = m_new(mp_obj_bluetooth_uuid_t *, len);
|
||||
uint8_t *characteristic_flags = m_new(uint8_t, len);
|
||||
uint16_t *characteristic_flags = m_new(uint16_t, len);
|
||||
|
||||
// Flattened list of descriptor uuids and flags. Grows (realloc) as more descriptors are encountered.
|
||||
mp_obj_bluetooth_uuid_t **descriptor_uuids = NULL;
|
||||
uint8_t *descriptor_flags = NULL;
|
||||
uint16_t *descriptor_flags = NULL;
|
||||
// How many descriptors in the flattened list per characteristic.
|
||||
uint8_t *num_descriptors = m_new(uint8_t, len);
|
||||
|
||||
|
@ -506,7 +506,7 @@ STATIC int bluetooth_gatts_register_service(mp_obj_t uuid_in, mp_obj_t character
|
|||
|
||||
// Grow the flattened uuids and flags arrays with this many more descriptors.
|
||||
descriptor_uuids = m_renew(mp_obj_bluetooth_uuid_t *, descriptor_uuids, descriptor_index, descriptor_index + num_descriptors[characteristic_index]);
|
||||
descriptor_flags = m_renew(uint8_t, descriptor_flags, descriptor_index, descriptor_index + num_descriptors[characteristic_index]);
|
||||
descriptor_flags = m_renew(uint16_t, descriptor_flags, descriptor_index, descriptor_index + num_descriptors[characteristic_index]);
|
||||
|
||||
// Also grow the handles array.
|
||||
*handles = m_renew(uint16_t, *handles, *num_handles, *num_handles + num_descriptors[characteristic_index]);
|
||||
|
@ -894,6 +894,8 @@ STATIC const mp_rom_map_elem_t mp_module_bluetooth_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluetooth) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_BLE), MP_ROM_PTR(&mp_type_bluetooth_ble) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&mp_type_bluetooth_uuid) },
|
||||
|
||||
// TODO: Deprecate these flags (recommend copying the constants from modbluetooth.h instead).
|
||||
{ MP_ROM_QSTR(MP_QSTR_FLAG_READ), MP_ROM_INT(MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FLAG_WRITE), MP_ROM_INT(MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FLAG_NOTIFY), MP_ROM_INT(MP_BLUETOOTH_CHARACTERISTIC_FLAG_NOTIFY) },
|
||||
|
|
|
@ -71,12 +71,28 @@
|
|||
// Advertisement packet lengths
|
||||
#define MP_BLUETOOTH_GAP_ADV_MAX_LEN (32)
|
||||
|
||||
// Basic characteristic/descriptor flags.
|
||||
// These match the spec values for these flags so can be passed directly to the stack.
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ (1 << 1)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE_NO_RESPONSE (1 << 2)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE (1 << 3)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_NOTIFY (1 << 4)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_INDICATE (1 << 5)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_BROADCAST (0x0001)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ (0x0002)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE_NO_RESPONSE (0x0004)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE (0x0008)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_NOTIFY (0x0010)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_INDICATE (0x0020)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_AUTHENTICATED_SIGNED_WRITE (0x0040)
|
||||
|
||||
// TODO: NimBLE and BlueKitchen disagree on this one.
|
||||
// #define MP_BLUETOOTH_CHARACTERISTIC_FLAG_RELIABLE_WRITE (0x0080)
|
||||
|
||||
// Extended flags for security and privacy.
|
||||
// These match NimBLE but might require mapping in the bindings for other stacks.
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_AUX_WRITE (0x0100)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ_ENCRYPTED (0x0200)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ_AUTHENTICATED (0x0400)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_READ_AUTHORIZED (0x0800)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE_ENCRYPTED (0x1000)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE_AUTHENTICATED (0x2000)
|
||||
#define MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE_AUTHORIZED (0x4000)
|
||||
|
||||
// For mp_bluetooth_gattc_write, the mode parameter
|
||||
#define MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE (0)
|
||||
|
@ -153,6 +169,22 @@ _IRQ_L2CAP_DISCONNECT = const(24)
|
|||
_IRQ_L2CAP_RECV = const(25)
|
||||
_IRQ_L2CAP_SEND_READY = const(26)
|
||||
_IRQ_GATTS_CONN_UPDATE = const(27)
|
||||
|
||||
_FLAG_BROADCAST = const(0x0001)
|
||||
_FLAG_READ = const(0x0002)
|
||||
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
|
||||
_FLAG_WRITE = const(0x0008)
|
||||
_FLAG_NOTIFY = const(0x0010)
|
||||
_FLAG_INDICATE = const(0x0020)
|
||||
_FLAG_AUTHENTICATED_SIGNED_WRITE = const(0x0040)
|
||||
|
||||
_FLAG_AUX_WRITE = const(0x0100)
|
||||
_FLAG_READ_ENCRYPTED = const(0x0200)
|
||||
_FLAG_READ_AUTHENTICATED = const(0x0400)
|
||||
_FLAG_READ_AUTHORIZED = const(0x0800)
|
||||
_FLAG_WRITE_ENCRYPTED = const(0x1000)
|
||||
_FLAG_WRITE_AUTHENTICATED = const(0x2000)
|
||||
_FLAG_WRITE_AUTHORIZED = const(0x4000)
|
||||
*/
|
||||
|
||||
// bluetooth.UUID type.
|
||||
|
@ -214,7 +246,7 @@ void mp_bluetooth_gap_advertise_stop(void);
|
|||
int mp_bluetooth_gatts_register_service_begin(bool append);
|
||||
// Add a service with the given list of characteristics to the queue to be registered.
|
||||
// The value_handles won't be valid until after mp_bluetooth_register_service_end is called.
|
||||
int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, mp_obj_bluetooth_uuid_t **characteristic_uuids, uint8_t *characteristic_flags, mp_obj_bluetooth_uuid_t **descriptor_uuids, uint8_t *descriptor_flags, uint8_t *num_descriptors, uint16_t *handles, size_t num_characteristics);
|
||||
int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, mp_obj_bluetooth_uuid_t **characteristic_uuids, uint16_t *characteristic_flags, mp_obj_bluetooth_uuid_t **descriptor_uuids, uint16_t *descriptor_flags, uint8_t *num_descriptors, uint16_t *handles, size_t num_characteristics);
|
||||
// Register any queued services.
|
||||
int mp_bluetooth_gatts_register_service_end(void);
|
||||
|
||||
|
|
|
@ -685,7 +685,7 @@ int mp_bluetooth_gatts_register_service_end(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, mp_obj_bluetooth_uuid_t **characteristic_uuids, uint8_t *characteristic_flags, mp_obj_bluetooth_uuid_t **descriptor_uuids, uint8_t *descriptor_flags, uint8_t *num_descriptors, uint16_t *handles, size_t num_characteristics) {
|
||||
int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, mp_obj_bluetooth_uuid_t **characteristic_uuids, uint16_t *characteristic_flags, mp_obj_bluetooth_uuid_t **descriptor_uuids, uint16_t *descriptor_flags, uint8_t *num_descriptors, uint16_t *handles, size_t num_characteristics) {
|
||||
if (MP_STATE_PORT(bluetooth_nimble_root_pointers)->n_services == MP_BLUETOOTH_NIMBLE_MAX_SERVICES) {
|
||||
return MP_E2BIG;
|
||||
}
|
||||
|
@ -697,6 +697,7 @@ int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, m
|
|||
characteristics[i].uuid = create_nimble_uuid(characteristic_uuids[i], NULL);
|
||||
characteristics[i].access_cb = characteristic_access_cb;
|
||||
characteristics[i].arg = NULL;
|
||||
// NimBLE flags match the MP_BLUETOOTH_CHARACTERISTIC_FLAG_ ones exactly (including the security/privacy options).
|
||||
characteristics[i].flags = characteristic_flags[i];
|
||||
characteristics[i].min_key_size = 0;
|
||||
characteristics[i].val_handle = &handles[handle_index];
|
||||
|
@ -710,7 +711,8 @@ int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, m
|
|||
for (size_t j = 0; j < num_descriptors[i]; ++j) {
|
||||
descriptors[j].uuid = create_nimble_uuid(descriptor_uuids[descriptor_index], NULL);
|
||||
descriptors[j].access_cb = characteristic_access_cb;
|
||||
descriptors[j].att_flags = descriptor_flags[descriptor_index];
|
||||
// NimBLE doesn't support security/privacy options on descriptors.
|
||||
descriptors[j].att_flags = (uint8_t)descriptor_flags[descriptor_index];
|
||||
descriptors[j].min_key_size = 0;
|
||||
// Unlike characteristic, Nimble doesn't provide an automatic way to remember the handle, so use the arg.
|
||||
descriptors[j].arg = &handles[handle_index];
|
||||
|
|
Loading…
Reference in New Issue