Skip to content

Commit c46d06f

Browse files
committed
Move 128-bit UUID string parsing to Python; simplify UUID API
1 parent 87c6f33 commit c46d06f

1 file changed

Lines changed: 23 additions & 83 deletions

File tree

shared-bindings/bleio/UUID.c

Lines changed: 23 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,13 @@
2626
* THE SOFTWARE.
2727
*/
2828

29+
#include <string.h>
30+
2931
#include "py/objproperty.h"
3032
#include "py/objstr.h"
3133
#include "py/runtime.h"
3234
#include "shared-bindings/bleio/UUID.h"
3335

34-
// Including hyphens.
35-
#define UUID128_STR_LEN 36
36-
// Number of bytes
37-
#define UUID128_BYTE_LEN 16
38-
39-
STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) {
40-
return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4);
41-
}
42-
43-
4436
//| .. currentmodule:: bleio
4537
//|
4638
//| :class:`UUID` -- BLE UUID
@@ -49,101 +41,49 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) {
4941
//| A 16-bit or 128-bit UUID. Can be used for services, characteristics, descriptors and more.
5042
//|
5143

52-
//| .. class:: UUID(value, *, base_uuid=None)
44+
//| .. class:: UUID(value)
5345
//|
5446
//| Create a new UUID or UUID object encapsulating the uuid value.
5547
//| The value can be one of:
5648
//|
5749
//| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID)
58-
//| - a `str` value in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', where the X's are hex digits.
59-
//| (128 bit UUID)
6050
//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID)
6151
//|
62-
//| :param int/str/buffer value: The uuid value to encapsulate
63-
//|
52+
//| :param int/buffer value: The uuid value to encapsulate
6453

6554
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) {
66-
mp_arg_check_num(n_args, n_kw, 1, 1, true);
55+
mp_arg_check_num(n_args, n_kw, 1, 1, false);
6756

6857
bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t);
6958
self->base.type = type;
7059

71-
mp_map_t kw_args;
72-
mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
73-
74-
enum { ARG_value, ARG_base_uuid };
75-
static const mp_arg_t allowed_args[] = {
76-
{ MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
77-
{ MP_QSTR_base_uuid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
78-
};
79-
80-
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
81-
mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
82-
83-
const mp_obj_t value = args[ARG_value].u_obj;
84-
const mp_obj_t base_uuid = args[ARG_base_uuid].u_obj;
60+
const mp_obj_t value = pos_args[0];
8561
uint8_t uuid128[16];
8662

87-
if (base_uuid != mp_const_none) {
88-
if (MP_OBJ_IS_TYPE(base_uuid, &bleio_uuid_type)) {
89-
if (!common_hal_bleio_uuid_get_uuid128(base_uuid, uuid128)) {
90-
mp_raise_ValueError(translate("base_uuid is not 128 bits"));
91-
}
92-
} else {
93-
mp_raise_ValueError(translate("base_uuid is not a UUID"));
94-
}
95-
}
96-
9763
if (MP_OBJ_IS_INT(value)) {
9864
mp_int_t uuid16 = mp_obj_get_int(value);
9965
if (uuid16 < 0 || uuid16 > 0xffff) {
10066
mp_raise_ValueError(translate("UUID integer value not in range 0 to 0xffff"));
10167
}
10268

103-
// If a base_uuid was supplied, merge the uuid16 into it. Otherwise
104-
// it's a 16-bit Bluetooth SIG UUID. NULL means no 128-bit value.
105-
common_hal_bleio_uuid_construct(self, uuid16, base_uuid == mp_const_none ? NULL : uuid128);
106-
107-
} else if (MP_OBJ_IS_STR(value)) {
108-
uint8_t uuid128[UUID128_BYTE_LEN];
109-
GET_STR_DATA_LEN(value, str, str_len);
110-
if (str_len == UUID128_STR_LEN &&
111-
str[8] == '-' && str[13] == '-' && str[18] == '-' && str[23] == '-') {
112-
int str_index = UUID128_STR_LEN - 1;
113-
size_t uuid128_index = 0;
114-
bool error = false;
115-
116-
// Loop until fewer than two characters left.
117-
while (str_index >= 1 && uuid128_index < UUID128_BYTE_LEN) {
118-
if (str[str_index] == '-') {
119-
// Skip hyphen separators.
120-
str_index--;
121-
continue;
122-
}
123-
124-
if (!unichar_isxdigit(str[str_index]) ||
125-
!unichar_isxdigit(str[str_index-1])) {
126-
error = true;
127-
break;
128-
}
129-
130-
uuid128[uuid128_index] = xdigit_8b_value(str[str_index],
131-
str[str_index-1]);
132-
uuid128_index += 1;
133-
str_index -= 2;
134-
}
135-
// Check for correct number of hex digits and no parsing errors.
136-
if (!error && uuid128_index == UUID128_BYTE_LEN && str_index == -1) {
137-
uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12];
138-
uuid128[12] = 0;
139-
uuid128[13] = 0;
140-
common_hal_bleio_uuid_construct(self, uuid16, uuid128);
141-
} else {
142-
mp_raise_ValueError(translate("UUID string must be of the form xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
143-
}
144-
}
69+
// NULL means no 128-bit value.
70+
common_hal_bleio_uuid_construct(self, uuid16, NULL);
71+
14572
} else {
146-
mp_raise_ValueError(translate("UUID value is not int or string"));
73+
mp_buffer_info_t bufinfo;
74+
if (!mp_get_buffer(value, &bufinfo, MP_BUFFER_READ)) {
75+
mp_raise_ValueError(translate("UUID value is not int or byte buffer"));
76+
}
77+
78+
if (bufinfo.len != 16) {
79+
mp_raise_ValueError(translate("Byte buffer must be 16 bytes."));
80+
}
81+
82+
memcpy(uuid128, bufinfo.buf, 16);
83+
uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12];
84+
uuid128[12] = 0;
85+
uuid128[13] = 0;
86+
common_hal_bleio_uuid_construct(self, uuid16, bufinfo.buf);
14787
}
14888

14989
return MP_OBJ_FROM_PTR(self);

0 commit comments

Comments
 (0)