From 1763ffe2450fa07c74db225cc5ef3a6e2feb669b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 20 Nov 2018 23:04:58 -0500 Subject: [PATCH] More UUID work; use mp_raise for exceptions --- ports/nrf/common-hal/bleio/Adapter.c | 15 ++-- ports/nrf/common-hal/bleio/Characteristic.c | 20 ++--- ports/nrf/common-hal/bleio/Descriptor.c | 11 ++- ports/nrf/common-hal/bleio/Device.c | 90 +++++++------------ ports/nrf/common-hal/bleio/Scanner.c | 8 +- ports/nrf/common-hal/bleio/Service.c | 13 +-- ports/nrf/common-hal/bleio/UUID.c | 32 +++++-- ports/nrf/common-hal/bleio/UUID.h | 5 ++ .../common-hal/microcontroller/Processor.c | 5 +- py/runtime.c | 3 + py/runtime.h | 1 + shared-bindings/bleio/Address.c | 49 ++++++---- shared-bindings/bleio/Characteristic.c | 11 +-- shared-bindings/bleio/Descriptor.c | 14 +-- shared-bindings/bleio/Descriptor.h | 2 +- shared-bindings/bleio/Service.c | 11 +-- shared-bindings/bleio/UUID.c | 54 ++++++++--- shared-bindings/bleio/UUID.h | 3 +- 18 files changed, 186 insertions(+), 161 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index 985e262e49..318502e955 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -33,12 +33,12 @@ #include "nrfx_power.h" #include "nrf_nvic.h" #include "nrf_sdm.h" -#include "py/nlr.h" +#include "py/runtime.h" #include "shared-bindings/bleio/Adapter.h" STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AssertionError, - translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc)); + mp_raise_msg_varg(&mp_type_AssertionError, + translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc); } STATIC uint32_t ble_stack_enable(void) { @@ -121,8 +121,7 @@ void common_hal_bleio_adapter_set_enabled(bool enabled) { } if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to change softdevice state, error: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to change softdevice state")); } } @@ -131,8 +130,7 @@ bool common_hal_bleio_adapter_get_enabled(void) { const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to get softdevice state, error: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to get softdevice state")); } return is_enabled; @@ -151,8 +149,7 @@ void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { #endif if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to get local address, error: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to get local address")); } address->type = local_address.addr_type; diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 246c350057..002d145c7a 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -30,7 +30,7 @@ #include "ble_drv.h" #include "ble_gatts.h" #include "nrf_soc.h" -#include "py/nlr.h" +#include "py/runtime.h" #include "shared-module/bleio/Characteristic.h" static volatile bleio_characteristic_obj_t *m_read_characteristic; @@ -48,8 +48,7 @@ STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to write gatts value, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to write gatts value")); } } @@ -72,8 +71,7 @@ STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_i const uint32_t err_code = sd_ble_gatts_hvx(device->conn_handle, &hvx_params); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to notify attribute value, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to notify attribute value")); } m_tx_in_progress += 1; @@ -87,8 +85,7 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to read attribute value, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to read attribute value")); } while (m_read_characteristic != NULL) { @@ -115,15 +112,13 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in err_code = sd_mutex_acquire(m_write_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to acquire mutex")); } } err_code = sd_ble_gattc_write(device->conn_handle, &write_params); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to write attribute value, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to write attribute value")); } while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -134,8 +129,7 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in err_code = sd_mutex_release(m_write_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } } diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c index 9b61345fa8..c6b95832c4 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.c +++ b/ports/nrf/common-hal/bleio/Descriptor.c @@ -26,20 +26,23 @@ */ #include "common-hal/bleio/Descriptor.h" +#include "shared-bindings/bleio/UUID.h" void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid) { + // TODO: set handle ??? self->uuid = uuid; } void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print) { - mp_printf(print, "Descriptor(uuid: 0x" HEX2_FMT HEX2_FMT ")", - self->uuid->value[1], self->uuid->value[0]); + mp_printf(print, "Descriptor(uuid="); + common_hal_bleio_uuid_print(self->uuid, print); + mp_printf(print, ", handle=%0x", self->handle); } mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) { return self->handle; } -mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { - return self->uuid->value[0] | (self->uuid->value[1] << 8); +mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { + return MP_OBJ_FROM_PTR(self->uuid); } diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 2c000ae2e1..10592d65af 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -77,8 +77,7 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta #define ADD_FIELD(field, len) \ do { \ if (byte_pos + (len) > BLE_GAP_ADV_MAX_SIZE) { \ - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, \ - translate("Can not fit data into the advertisment packet"))); \ + mp_raise_ValueError(translate("Data too large for the advertisement packet")); \ } \ adv_data[byte_pos] = (field); \ byte_pos += (len); \ @@ -110,8 +109,7 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta ADD_FIELD(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE, BLE_AD_TYPE_FLAGS_DATA_SIZE); } else { if (byte_pos + raw_data->len > BLE_GAP_ADV_MAX_SIZE) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not fit data into the advertisment packet"))); + mp_raise_ValueError(translate("Data too large for the advertisement packet")); } memcpy(&adv_data[byte_pos], raw_data->buf, raw_data->len); @@ -130,12 +128,13 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta continue; } - if (service->uuid->type == UUID_TYPE_16BIT) { + switch (common_hal_bleio_uuid_get_size(service->uuid)) { + case 16: has_16bit_services = true; - } - - if (service->uuid->type == UUID_TYPE_128BIT) { + break; + case 128: has_128bit_services = true; + break; } } @@ -152,13 +151,12 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); uint8_t encoded_size = 0; - if ((service->uuid->type != UUID_TYPE_16BIT) || service->is_secondary) { + if (common_hal_bleio_uuid_get_size(service->uuid) != 16 || service->is_secondary) { continue; } ble_uuid_t uuid; - uuid.type = BLE_UUID_TYPE_BLE; - uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); if (err_code != NRF_SUCCESS) { @@ -185,13 +183,12 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); uint8_t encoded_size = 0; - if ((service->uuid->type != UUID_TYPE_128BIT) || service->is_secondary) { + if (common_hal_bleio_uuid_get_size(service->uuid) != 16 || service->is_secondary) { continue; } ble_uuid_t uuid; - uuid.type = service->uuid->uuid_vs_idx; - uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); if (err_code != NRF_SUCCESS) { @@ -262,14 +259,12 @@ STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to discover serivices, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to discover services")); } err_code = sd_mutex_acquire(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to acquire mutex")); } while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -280,8 +275,7 @@ STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } return m_discovery_successful; @@ -303,8 +297,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o err_code = sd_mutex_acquire(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to acquire mutex")); } while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -315,8 +308,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } return m_discovery_successful; @@ -324,7 +316,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_device_obj_t *device) { for (size_t i = 0; i < response->count; ++i) { - const ble_gattc_service_t *gattc_service = &response->services[i]; + ble_gattc_service_t *gattc_service = &response->services[i]; bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); service->base.type = &bleio_service_type; @@ -335,10 +327,7 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res service->handle = gattc_service->handle_range.start_handle; bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - uuid->type = (gattc_service->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; - uuid->value[0] = gattc_service->uuid.uuid & 0xFF; - uuid->value[1] = gattc_service->uuid.uuid >> 8; + bleio_uuid_construct_from_nrf_uuid(uuid, &gattc_service->uuid); service->uuid = uuid; mp_obj_list_append(device->service_list, service); @@ -350,23 +339,20 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res const uint32_t err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } } STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_device_obj_t *device) { for (size_t i = 0; i < response->count; ++i) { - const ble_gattc_char_t *gattc_char = &response->chars[i]; + ble_gattc_char_t *gattc_char = &response->chars[i]; bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); characteristic->base.type = &bleio_characteristic_type; bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); uuid->base.type = &bleio_uuid_type; - uuid->type = (gattc_char->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; - uuid->value[0] = gattc_char->uuid.uuid & 0xFF; - uuid->value[1] = gattc_char->uuid.uuid >> 8; + bleio_uuid_construct_from_nrf_uuid(uuid, &gattc_char->uuid); characteristic->uuid = uuid; characteristic->props.broadcast = gattc_char->char_props.broadcast; @@ -387,8 +373,7 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio const uint32_t err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } } @@ -399,8 +384,7 @@ STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t * #if (BLUETOOTH_SD == 140) err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to continue scanning, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to continue scanning")); } #endif return; @@ -432,8 +416,7 @@ STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t * #endif if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to connect, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to connect:")); } } @@ -491,14 +474,8 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *device_in) { } void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service) { - ble_uuid_t uuid = { - .type = BLE_UUID_TYPE_BLE, - .uuid = service->uuid->value[0] | (service->uuid->value[1] << 8) - }; - - if (service->uuid->type == UUID_TYPE_128BIT) { - uuid.type = service->uuid->uuid_vs_idx; - } + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; if (service->is_secondary) { @@ -509,8 +486,7 @@ void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_servi const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to add service, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to add service")); } const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); @@ -527,8 +503,7 @@ void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool const uint32_t err_code = set_advertisement_data(device, connectable, raw_data); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to start advertisment, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to start advertising")); } } @@ -545,8 +520,7 @@ void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device) { #endif if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to stop advertisment, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to stop advertising")); } } @@ -571,8 +545,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { #endif if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to start scanning, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to start scanning")); } while (device->conn_handle == BLE_CONN_HANDLE_INVALID) { @@ -588,8 +561,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { err_code = sd_mutex_new(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to create mutex, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to create mutex")); } } diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c index e56c1860c2..fd997a6d3c 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -30,7 +30,7 @@ #include "ble_drv.h" #include "ble_gap.h" #include "py/mphal.h" -#include "py/nlr.h" +#include "py/runtime.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" @@ -72,8 +72,7 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) { #if (BLUETOOTH_SD == 140) const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to continue scanning, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to continue scanning")); } #endif } @@ -99,8 +98,7 @@ void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout) #endif if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to start scanning, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to start scanning")); } if (timeout > 0) { diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 6866837a19..8ad81c015e 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -26,7 +26,7 @@ #include "ble_drv.h" #include "ble.h" -#include "py/nlr.h" +#include "py/runtime.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/Adapter.h" @@ -51,13 +51,8 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei char_md.p_cccd_md = &cccd_md; } - ble_uuid_t uuid = { - .type = BLE_UUID_TYPE_BLE, - .uuid = characteristic->uuid->uuid16; - }; - - if (characteristic->uuid->type == UUID_TYPE_128BIT) - uuid.type = characteristic->uuid->uuid_vs_idx; + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_uuid(characteristic->uuid, &uuid); ble_gatts_attr_md_t attr_md = { .vloc = BLE_GATTS_VLOC_STACK, @@ -79,7 +74,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei uint32_t err_code; err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); if (err_code != NRF_SUCCESS) { - mp_raise_OSError(translate("Could not add characteristic")); + mp_raise_OSError_msg(translate("Could not add characteristic")); } characteristic->user_desc_handle = handles.user_desc_handle; diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c index a54de5e31b..133ffe25bc 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -49,23 +49,45 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, ui common_hal_bleio_adapter_set_enabled(true); const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->uuid_vs_idx); if (err_code != NRF_SUCCESS) { - mp_raise_OSError(&mp_type_OSError, translate("Could not register Vendor-Specific UUID")); + mp_raise_OSError_msg(translate("Could not register Vendor-Specific UUID")); + } } } void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print) { if (self->uuid_vs_idx != 0) { - mp_printf(print, "UUID(uuid16: 0x%04x, Vendor-Specific index: " HEX2_FMT ")", + mp_printf(print, "UUID(uuid16=0x%04x, uuid128_handle=" HEX2_FMT ")", self->uuid16, self->uuid_vs_idx); } else { - mp_printf(print, "UUID16(0x%04x)", self->uuid16); + mp_printf(print, "UUID(0x%04x)", self->uuid16); } } -bool common_hal_bleio_uuid_get_vendor_specific(bleio_uuid_obj_t *self) { - return self->uuid_vs_idx != 0; +uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) { + return self->uuid_vs_idx != 0 ? 128 : 16; } uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) { return self->uuid16; } + +// Returns 0 if there is no handle, otherwise returns a non-zero index. +uint32_t common_hal_bleio_uuid_get_uuid128_handle(bleio_uuid_obj_t *self) { + return self->uuid_vs_idx; +} + + +void bleio_uuid_construct_from_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid) { + if (nrf_uuid->type == BLE_UUID_TYPE_UNKNOWN) { + mp_raise_RuntimeError(translate("Unexpected nrfx uuid type")); + } + + self->uuid16 = nrf_uuid->uuid; + self->uuid_vs_idx = nrf_uuid->type == BLE_UUID_TYPE_BLE ? 0 : nrf_uuid->type; +} + +// Fill in a ble_uuid_t from my values. +void bleio_uuid_convert_to_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid) { + nrf_uuid->uuid = self->uuid16; + nrf_uuid->type = self->uuid_vs_idx == 0 ? BLE_UUID_TYPE_BLE : self->uuid_vs_idx; +} diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/bleio/UUID.h index 77f8fc5d19..f0d32ede28 100644 --- a/ports/nrf/common-hal/bleio/UUID.h +++ b/ports/nrf/common-hal/bleio/UUID.h @@ -30,6 +30,8 @@ #include "py/obj.h" +#include "ble.h" + typedef struct { mp_obj_base_t base; // If non-zero, `uuid_vs_idx` is an index into the SoftDevice's table of registered vendor-specific UUID's. @@ -40,4 +42,7 @@ typedef struct { uint16_t uuid16; } bleio_uuid_obj_t; +void bleio_uuid_construct_from_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); +void bleio_uuid_convert_to_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); + #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index e4d9439c99..836020d159 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -45,10 +45,7 @@ float common_hal_mcu_processor_get_temperature(void) { if (sd_en) { uint32_t err_code = sd_temp_get(&temp); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not get temperature. status: 0x%02x"), (uint16_t)err_code)); - - return 0; + mp_raise_OSError_msg(translate("Cannot get temperature")); } } #endif diff --git a/py/runtime.c b/py/runtime.c index 3d7a97f58b..339978dadf 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1599,6 +1599,9 @@ NORETURN void mp_raise_OSError(int errno_) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_))); } +NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_OSError, msg); +} NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); diff --git a/py/runtime.h b/py/runtime.h index 9c7ffc02f5..54f6a3270b 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -158,6 +158,7 @@ NORETURN void mp_raise_RuntimeError(const compressed_string_t *msg); NORETURN void mp_raise_ImportError(const compressed_string_t *msg); NORETURN void mp_raise_IndexError(const compressed_string_t *msg); NORETURN void mp_raise_OSError(int errno_); +NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg); NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg); NORETURN void mp_raise_recursion_depth(void); diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index ec23ff2071..d4c24e4e2c 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -33,8 +33,12 @@ #include "shared-bindings/bleio/Address.h" #include "shared-module/bleio/Address.h" -#define ADDRESS_LONG_LEN 17 // XX:XX:XX:XX:XX:XX -#define ADDRESS_SHORT_LEN 12 // XXXXXXXXXXXX +#define ADDRESS_BYTE_LEN 12 + +STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { + return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4); +} + //| .. currentmodule:: bleio //| @@ -49,7 +53,7 @@ //| Create a new Address object encapsulating the address value. //| The value itself can be one of: //| -//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX' +//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX:XX' (12 hex digits) //| - a `bytes` or `bytearray` containing 6 bytes //| - another Address object //| @@ -85,26 +89,41 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t address = args[ARG_address].u_obj; if (MP_OBJ_IS_STR(address)) { - GET_STR_DATA_LEN(address, str_data, str_len); - const bool is_long = (str_len == ADDRESS_LONG_LEN); - const bool is_short = (str_len == ADDRESS_SHORT_LEN); + GET_STR_DATA_LEN(address, str, str_len); - if (is_long || is_short) { - size_t i = str_len - 1; - for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { - self->value[b] = unichar_xdigit_value(str_data[i]) | - unichar_xdigit_value(str_data[i - 1]) << 4; + size_t value_index = 0; + size_t str_index = str_len; + bool error = false; - i -= is_long ? 3 : 2; + // Loop until fewer than two characters left. + while (str_index >= 1 && value_index < sizeof(self->value)) { + if (str[str_index] == ':') { + // Skip colon separators. + str_index--; + continue; } - } else { - mp_raise_ValueError(translate("Wrong address length")); + + if (!unichar_isxdigit(str[str_index]) || + !unichar_isxdigit(str[str_index-1])) { + error = true; + break; + } + + self->value[value_index] = xdigit_8b_value(str[str_index], + str[str_index-1]); + value_index += 1; + str_index -= 2; + } + // Check for correct number of hex digits and no parsing errors. + if (error || value_index != ADDRESS_BYTE_LEN || str_index != -1) { + mp_raise_ValueError_varg(translate("Address is not %d bytes long or is in wrong format"), + ADDRESS_BYTE_LEN); } } else if (MP_OBJ_IS_TYPE(address, &mp_type_bytearray) || MP_OBJ_IS_TYPE(address, &mp_type_bytes)) { mp_buffer_info_t buf_info; mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); if (buf_info.len != BLEIO_ADDRESS_BYTES) { - mp_raise_ValueError(translate("Wrong number of bytes provided")); + mp_raise_ValueError_varg(translate("Address must be %d bytes long"), BLEIO_ADDRESS_BYTES); } for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 2dd1d4270c..4b4a4a9245 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -91,7 +91,7 @@ STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "Characteristic("); - common_hal_bleio_uuid_print(print, self->uuid); + common_hal_bleio_uuid_print(self->uuid, print); mp_printf(print, ")"); } @@ -115,16 +115,11 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t const mp_obj_t uuid = args[ARG_uuid].u_obj; - if (uuid == mp_const_none) { - return MP_OBJ_FROM_PTR(self); - } - - if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { - self->uuid = MP_OBJ_TO_PTR(uuid); - } else { + if (!MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { mp_raise_ValueError(translate("Expected a UUID")); } + self->uuid = MP_OBJ_TO_PTR(uuid); common_hal_bleio_characteristic_construct(self); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index df32a00e7c..d58bbd2756 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -61,7 +61,6 @@ enum { //| .. class:: Descriptor(uuid) //| //| Create a new descriptor object with the UUID uuid. -//| The value can be either of type `bleio.UUID` or any value allowed by the `bleio.UUID` constructor. //| .. attribute:: handle //| @@ -90,13 +89,11 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar const mp_obj_t uuid_arg = args[ARG_uuid].u_obj; - bleio_uuid_obj_t *uuid; - if (MP_OBJ_IS_TYPE(uuid_arg, &bleio_uuid_type)) { - uuid = MP_OBJ_TO_PTR(uuid_arg); - } else { - uuid = MP_OBJ_TO_PTR(bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_arg)); + if (!MP_OBJ_IS_TYPE(uuid_arg, &bleio_uuid_type)) { + mp_raise_ValueError(translate("Expected a UUID")); } + bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_arg); common_hal_bleio_descriptor_construct(self, uuid); return MP_OBJ_FROM_PTR(self); @@ -104,7 +101,6 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_bleio_descriptor_print(self, print); } @@ -124,9 +120,7 @@ const mp_obj_property_t bleio_descriptor_handle_obj = { STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); - const mp_obj_t uuid = mp_obj_new_int(common_hal_bleio_descriptor_get_uuid(self)); - - return bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid); + return common_hal_bleio_descriptor_get_uuid(self); } MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_uuid_obj, bleio_descriptor_get_uuid); diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h index 85310d304f..bef91061bd 100644 --- a/shared-bindings/bleio/Descriptor.h +++ b/shared-bindings/bleio/Descriptor.h @@ -35,6 +35,6 @@ extern const mp_obj_type_t bleio_descriptor_type; extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid); extern void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print); extern mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self); -extern mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); +extern mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 727350215f..275a61eeca 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -67,8 +67,8 @@ STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_pr bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "Service("); - common_hal_bleio_uuid_print(print, self->uuid); - mp_print(print, ")"); + common_hal_bleio_uuid_print(self->uuid, print); + mp_printf(print, ")"); } STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { @@ -112,9 +112,10 @@ STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t char bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in); - if (self->uuid->type == UUID_TYPE_128BIT) { - characteristic->uuid->type = UUID_TYPE_128BIT; - characteristic->uuid->uuid_vs_idx = self->uuid->uuid_vs_idx; + if (common_hal_bleio_uuid_get_uuid128_handle(self->uuid) != + common_hal_bleio_uuid_get_uuid128_handle(characteristic->uuid)) { + // The descriptor base UUID doesn't match the characteristic base UUID. + mp_raise_ValueError(translate("Characteristic UUID doesn't match Descriptor UUID")); } characteristic->service = self; diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 33d280304c..a326518e68 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -27,6 +27,7 @@ */ #include "py/objproperty.h" +#include "py/objstr.h" #include "py/runtime.h" #include "shared-bindings/bleio/UUID.h" @@ -63,6 +64,9 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { 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); + bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); + self->base.type = type; + mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); @@ -98,7 +102,7 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si while (str_index >= 1 && uuid128_index < UUID128_BYTE_LEN) { if (str[str_index] == '-') { // Skip hyphen separators. - str--; + str_index--; continue; } @@ -126,6 +130,8 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si } else { mp_raise_ValueError(translate("UUID value is not int or string")); } + // Unreachable. + return mp_const_none; } STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { @@ -138,42 +144,64 @@ STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print //| //| The 16-bit part of the UUID. (read-only) //| -STATIC void bleio_uuid_get_uuid16(mp_obj_t self_in) { +STATIC mp_obj_t bleio_uuid_get_uuid16(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self)); } MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid16_obj, bleio_uuid_get_uuid16); -const mp_obj_property_t bleio_uuid16_obj = { +const mp_obj_property_t bleio_uuid_uuid16_obj = { .base.type = &mp_type_property, .proxy = {(mp_obj_t)&bleio_uuid_get_uuid16_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; -//| .. attribute:: vendor_specific +//| .. attribute:: uuid128_handle //| -//| True if this UUID represents a 128-bit vendor-specific UUID. -//| False if this UUID represents a 16-bit Bluetooth SIG assigned UUID. (read-only) +//| An opaque handle representing the 128-bit UUID. (read-only) +//| Returns None if this is a 16-bit UUID. //| -STATIC mp_obj_t bleio_uuid_get_vendor_specific(mp_obj_t self_in) { +STATIC mp_obj_t bleio_uuid_get_uuid128_handle(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(common_hal_bleio_uuid_get_vendor_specific(self)); + uint32_t handle = common_hal_bleio_uuid_get_uuid128_handle(self); + return handle == 0 ? mp_const_none : MP_OBJ_NEW_SMALL_INT(handle); } -MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_vendor_specific_obj, bleio_uuid_get_vendor_specific); +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid128_handle_obj, bleio_uuid_get_uuid128_handle); -const mp_obj_property_t bleio_uuid_vendor_specific_obj = { +const mp_obj_property_t bleio_uuid_uuid128_handle_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&bleio_uuid_get_vendor_specific_obj, + .proxy = {(mp_obj_t)&bleio_uuid_get_uuid128_handle_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: size +//| +//| Returns 128 if this UUID represents a 128-bit vendor-specific UUID. +//| Returns 16 if this UUID represents a 16-bit Bluetooth SIG assigned UUID. (read-only) +//| 32-bit UUIDs are not currently supported. +//| +STATIC mp_obj_t bleio_uuid_get_size(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_size(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_size_obj, bleio_uuid_get_size); + +const mp_obj_property_t bleio_uuid_size_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_size_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid16_obj) }, - { MP_ROM_QSTR(MP_QSTR_vendor_specific), MP_ROM_PTR(&bleio_uuid_vendor_specific_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid_uuid16_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid128_handle), MP_ROM_PTR(&bleio_uuid_uuid128_handle_obj) }, + { MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&bleio_uuid_size_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table); diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h index e27058516e..79810dc973 100644 --- a/shared-bindings/bleio/UUID.h +++ b/shared-bindings/bleio/UUID.h @@ -33,7 +33,8 @@ extern const mp_obj_type_t bleio_uuid_type; extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, uint8_t uuid128[]); extern void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print); -extern bool common_hal_bleio_uuid_get_vendor_specific(bleio_uuid_obj_t *self); extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self); +extern uint32_t common_hal_bleio_uuid_get_uuid128_handle(bleio_uuid_obj_t *self); +extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H