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
6554STATIC 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