Move 128-bit UUID string parsing to Python; simplify UUID API
This commit is contained in:
parent
87c6f33bcc
commit
c46d06f34c
@ -26,21 +26,13 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "py/objproperty.h"
|
#include "py/objproperty.h"
|
||||||
#include "py/objstr.h"
|
#include "py/objstr.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "shared-bindings/bleio/UUID.h"
|
#include "shared-bindings/bleio/UUID.h"
|
||||||
|
|
||||||
// Including hyphens.
|
|
||||||
#define UUID128_STR_LEN 36
|
|
||||||
// Number of bytes
|
|
||||||
#define UUID128_BYTE_LEN 16
|
|
||||||
|
|
||||||
STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) {
|
|
||||||
return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//| .. currentmodule:: bleio
|
//| .. currentmodule:: bleio
|
||||||
//|
|
//|
|
||||||
//| :class:`UUID` -- BLE UUID
|
//| :class:`UUID` -- BLE UUID
|
||||||
@ -49,101 +41,49 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) {
|
|||||||
//| A 16-bit or 128-bit UUID. Can be used for services, characteristics, descriptors and more.
|
//| A 16-bit or 128-bit UUID. Can be used for services, characteristics, descriptors and more.
|
||||||
//|
|
//|
|
||||||
|
|
||||||
//| .. class:: UUID(value, *, base_uuid=None)
|
//| .. class:: UUID(value)
|
||||||
//|
|
//|
|
||||||
//| Create a new UUID or UUID object encapsulating the uuid value.
|
//| Create a new UUID or UUID object encapsulating the uuid value.
|
||||||
//| The value can be one of:
|
//| The value can be one of:
|
||||||
//|
|
//|
|
||||||
//| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID)
|
//| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID)
|
||||||
//| - a `str` value in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', where the X's are hex digits.
|
|
||||||
//| (128 bit UUID)
|
|
||||||
//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID)
|
//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID)
|
||||||
//|
|
//|
|
||||||
//| :param int/str/buffer value: The uuid value to encapsulate
|
//| :param int/buffer value: The uuid value to encapsulate
|
||||||
//|
|
|
||||||
|
|
||||||
STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 1, 1, true);
|
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||||
|
|
||||||
bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t);
|
bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t);
|
||||||
self->base.type = type;
|
self->base.type = type;
|
||||||
|
|
||||||
mp_map_t kw_args;
|
const mp_obj_t value = pos_args[0];
|
||||||
mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
|
|
||||||
|
|
||||||
enum { ARG_value, ARG_base_uuid };
|
|
||||||
static const mp_arg_t allowed_args[] = {
|
|
||||||
{ MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
|
||||||
{ MP_QSTR_base_uuid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
|
||||||
};
|
|
||||||
|
|
||||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
|
||||||
mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
|
||||||
|
|
||||||
const mp_obj_t value = args[ARG_value].u_obj;
|
|
||||||
const mp_obj_t base_uuid = args[ARG_base_uuid].u_obj;
|
|
||||||
uint8_t uuid128[16];
|
uint8_t uuid128[16];
|
||||||
|
|
||||||
if (base_uuid != mp_const_none) {
|
|
||||||
if (MP_OBJ_IS_TYPE(base_uuid, &bleio_uuid_type)) {
|
|
||||||
if (!common_hal_bleio_uuid_get_uuid128(base_uuid, uuid128)) {
|
|
||||||
mp_raise_ValueError(translate("base_uuid is not 128 bits"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mp_raise_ValueError(translate("base_uuid is not a UUID"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MP_OBJ_IS_INT(value)) {
|
if (MP_OBJ_IS_INT(value)) {
|
||||||
mp_int_t uuid16 = mp_obj_get_int(value);
|
mp_int_t uuid16 = mp_obj_get_int(value);
|
||||||
if (uuid16 < 0 || uuid16 > 0xffff) {
|
if (uuid16 < 0 || uuid16 > 0xffff) {
|
||||||
mp_raise_ValueError(translate("UUID integer value not in range 0 to 0xffff"));
|
mp_raise_ValueError(translate("UUID integer value not in range 0 to 0xffff"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a base_uuid was supplied, merge the uuid16 into it. Otherwise
|
// NULL means no 128-bit value.
|
||||||
// it's a 16-bit Bluetooth SIG UUID. NULL means no 128-bit value.
|
common_hal_bleio_uuid_construct(self, uuid16, NULL);
|
||||||
common_hal_bleio_uuid_construct(self, uuid16, base_uuid == mp_const_none ? NULL : uuid128);
|
|
||||||
|
|
||||||
} else if (MP_OBJ_IS_STR(value)) {
|
|
||||||
uint8_t uuid128[UUID128_BYTE_LEN];
|
|
||||||
GET_STR_DATA_LEN(value, str, str_len);
|
|
||||||
if (str_len == UUID128_STR_LEN &&
|
|
||||||
str[8] == '-' && str[13] == '-' && str[18] == '-' && str[23] == '-') {
|
|
||||||
int str_index = UUID128_STR_LEN - 1;
|
|
||||||
size_t uuid128_index = 0;
|
|
||||||
bool error = false;
|
|
||||||
|
|
||||||
// Loop until fewer than two characters left.
|
|
||||||
while (str_index >= 1 && uuid128_index < UUID128_BYTE_LEN) {
|
|
||||||
if (str[str_index] == '-') {
|
|
||||||
// Skip hyphen separators.
|
|
||||||
str_index--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!unichar_isxdigit(str[str_index]) ||
|
|
||||||
!unichar_isxdigit(str[str_index-1])) {
|
|
||||||
error = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uuid128[uuid128_index] = xdigit_8b_value(str[str_index],
|
|
||||||
str[str_index-1]);
|
|
||||||
uuid128_index += 1;
|
|
||||||
str_index -= 2;
|
|
||||||
}
|
|
||||||
// Check for correct number of hex digits and no parsing errors.
|
|
||||||
if (!error && uuid128_index == UUID128_BYTE_LEN && str_index == -1) {
|
|
||||||
uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12];
|
|
||||||
uuid128[12] = 0;
|
|
||||||
uuid128[13] = 0;
|
|
||||||
common_hal_bleio_uuid_construct(self, uuid16, uuid128);
|
|
||||||
} else {
|
|
||||||
mp_raise_ValueError(translate("UUID string must be of the form xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mp_raise_ValueError(translate("UUID value is not int or string"));
|
mp_buffer_info_t bufinfo;
|
||||||
|
if (!mp_get_buffer(value, &bufinfo, MP_BUFFER_READ)) {
|
||||||
|
mp_raise_ValueError(translate("UUID value is not int or byte buffer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufinfo.len != 16) {
|
||||||
|
mp_raise_ValueError(translate("Byte buffer must be 16 bytes."));
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(uuid128, bufinfo.buf, 16);
|
||||||
|
uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12];
|
||||||
|
uuid128[12] = 0;
|
||||||
|
uuid128[13] = 0;
|
||||||
|
common_hal_bleio_uuid_construct(self, uuid16, bufinfo.buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(self);
|
return MP_OBJ_FROM_PTR(self);
|
||||||
|
Loading…
Reference in New Issue
Block a user