From 28ca05ccdcf674ad128f357ac8f54a1931560331 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 27 Jul 2019 13:20:59 -0400 Subject: allow discovery from central or peripheral --- ports/nrf/boards/make-pins.py | 208 ------------ ports/nrf/common-hal/bleio/Central.c | 335 +------------------- ports/nrf/common-hal/bleio/Central.h | 4 +- ports/nrf/common-hal/bleio/Characteristic.c | 66 ++-- ports/nrf/common-hal/bleio/CharacteristicBuffer.c | 2 +- ports/nrf/common-hal/bleio/Peripheral.c | 15 +- ports/nrf/common-hal/bleio/Peripheral.h | 6 +- ports/nrf/common-hal/bleio/Service.c | 5 + ports/nrf/common-hal/bleio/Service.h | 2 + ports/nrf/common-hal/bleio/__init__.c | 365 +++++++++++++++++++++- ports/nrf/common-hal/bleio/__init__.h | 8 +- ports/nrf/nrfx_config.h | 1 + ports/nrf/peripherals/nrf/timers.c | 2 +- shared-bindings/bleio/Central.c | 77 +++-- shared-bindings/bleio/Central.h | 2 +- shared-bindings/bleio/Peripheral.c | 72 ++++- shared-bindings/bleio/Peripheral.h | 2 +- shared-bindings/bleio/Service.c | 22 ++ shared-bindings/bleio/Service.h | 1 + shared-bindings/bleio/__init__.h | 11 + shared-module/bleio/__init__.h | 6 - 21 files changed, 564 insertions(+), 648 deletions(-) delete mode 100644 ports/nrf/boards/make-pins.py diff --git a/ports/nrf/boards/make-pins.py b/ports/nrf/boards/make-pins.py deleted file mode 100644 index d1cfd5b70..000000000 --- a/ports/nrf/boards/make-pins.py +++ /dev/null @@ -1,208 +0,0 @@ -#!/usr/bin/env python -"""Creates the pin file for the nRF5.""" - -from __future__ import print_function - -import argparse -import sys -import csv - - -def parse_port_pin(name_str): - """Parses a string and returns a (port-num, pin-num) tuple.""" - if len(name_str) < 4: - raise ValueError("Expecting pin name to be at least 5 charcters.") - if name_str[0] != 'P': - raise ValueError("Expecting pin name to start with P") - if name_str[1] not in ('0', '1'): - raise ValueError("Expecting pin port to be in 0 or 1") - port = ord(name_str[1]) - ord('0') - pin_str = name_str[3:] - if not pin_str.isdigit(): - raise ValueError("Expecting numeric pin number.") - return (port, int(pin_str)) - - -class Pin(object): - """Holds the information associated with a pin.""" - - def __init__(self, port, pin): - self.port = port - self.pin = pin - self.adc_channel = '0' - self.board_pin = False - - def cpu_pin_name(self): - return 'P{:d}_{:02d}'.format(self.port, self.pin) - - def is_board_pin(self): - return self.board_pin - - def set_is_board_pin(self): - self.board_pin = True - - def parse_adc(self, adc_str): - if (adc_str[:3] != 'AIN'): - return - self.adc_channel = 'SAADC_CH_PSELP_PSELP_AnalogInput%d' % int(adc_str[3]) - - def print(self): - print('const pin_obj_t pin_{:s} = PIN({:s}, {:d}, {:d}, {:s});'.format( - self.cpu_pin_name(), self.cpu_pin_name(), - self.port, self.pin, self.adc_channel)) - - def print_header(self, hdr_file): - hdr_file.write('extern const pin_obj_t pin_{:s};\n'. - format(self.cpu_pin_name())) - - -class NamedPin(object): - - def __init__(self, name, pin): - self._name = name - self._pin = pin - - def pin(self): - return self._pin - - def name(self): - return self._name - - -class Pins(object): - - def __init__(self): - self.cpu_pins = [] # list of NamedPin objects - self.board_pins = [] # list of NamedPin objects - - def find_pin(self, port_num, pin_num): - for named_pin in self.cpu_pins: - pin = named_pin.pin() - if pin.port == port_num and pin.pin == pin_num: - return pin - - def parse_af_file(self, filename): - with open(filename, 'r') as csvfile: - rows = csv.reader(csvfile) - for row in rows: - try: - (port_num, pin_num) = parse_port_pin(row[0]) - except: - continue - pin = Pin(port_num, pin_num) - if len(row) > 1: - pin.parse_adc(row[1]) - self.cpu_pins.append(NamedPin(pin.cpu_pin_name(), pin)) - - def parse_board_file(self, filename): - with open(filename, 'r') as csvfile: - rows = csv.reader(csvfile) - for row in rows: - try: - (port_num, pin_num) = parse_port_pin(row[1]) - except: - continue - pin = self.find_pin(port_num, pin_num) - if pin: - pin.set_is_board_pin() - self.board_pins.append(NamedPin(row[0], pin)) - - def print_named(self, label, named_pins): - print('') - print('STATIC const mp_rom_map_elem_t {:s}_table[] = {{'.format(label)) - for named_pin in named_pins: - pin = named_pin.pin() - if pin.is_board_pin(): - print(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}) }},'.format(named_pin.name(), pin.cpu_pin_name())) - print('};') - print('MP_DEFINE_CONST_DICT({:s}, {:s}_table);'.format(label, label)) - - def print(self): - for named_pin in self.cpu_pins: - pin = named_pin.pin() - if pin.is_board_pin(): - pin.print() - self.print_named('mcu_pin_globals', self.cpu_pins) - self.print_named('board_module_globals', self.board_pins) - - def print_header(self, hdr_filename): - with open(hdr_filename, 'wt') as hdr_file: - for named_pin in self.cpu_pins: - pin = named_pin.pin() - if pin.is_board_pin(): - pin.print_header(hdr_file) - - def print_qstr(self, qstr_filename): - with open(qstr_filename, 'wt') as qstr_file: - qstr_set = set([]) - for named_pin in self.cpu_pins: - pin = named_pin.pin() - if pin.is_board_pin(): - qstr_set |= set([named_pin.name()]) - for named_pin in self.board_pins: - qstr_set |= set([named_pin.name()]) - for qstr in sorted(qstr_set): - print('Q({})'.format(qstr), file=qstr_file) - - -def main(): - parser = argparse.ArgumentParser( - prog="make-pins.py", - usage="%(prog)s [options] [command]", - description="Generate board specific pin file" - ) - parser.add_argument( - "-a", "--af", - dest="af_filename", - help="Specifies the alternate function file for the chip", - default="nrf_af.csv" - ) - parser.add_argument( - "-b", "--board", - dest="board_filename", - help="Specifies the board file", - ) - parser.add_argument( - "-p", "--prefix", - dest="prefix_filename", - help="Specifies beginning portion of generated pins file", - default="nrf52_prefix.c" - ) - parser.add_argument( - "-q", "--qstr", - dest="qstr_filename", - help="Specifies name of generated qstr header file", - default="build/pins_qstr.h" - ) - parser.add_argument( - "-r", "--hdr", - dest="hdr_filename", - help="Specifies name of generated pin header file", - default="build/pins.h" - ) - args = parser.parse_args(sys.argv[1:]) - - pins = Pins() - - print('// This file was automatically generated by make-pins.py') - print('//') - if args.af_filename: - print('// --af {:s}'.format(args.af_filename)) - pins.parse_af_file(args.af_filename) - - if args.board_filename: - print('// --board {:s}'.format(args.board_filename)) - pins.parse_board_file(args.board_filename) - - if args.prefix_filename: - print('// --prefix {:s}'.format(args.prefix_filename)) - print('') - with open(args.prefix_filename, 'r') as prefix_file: - print(prefix_file.read()) - pins.print() - pins.print_header(args.hdr_filename) - pins.print_qstr(args.qstr_filename) - - -if __name__ == "__main__": - main() diff --git a/ports/nrf/common-hal/bleio/Central.c b/ports/nrf/common-hal/bleio/Central.c index d90737411..c42a2084a 100644 --- a/ports/nrf/common-hal/bleio/Central.c +++ b/ports/nrf/common-hal/bleio/Central.c @@ -35,216 +35,8 @@ #include "py/objstr.h" #include "py/runtime.h" #include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Central.h" -#include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/UUID.h" - -static bleio_service_obj_t *m_char_discovery_service; -static bleio_characteristic_obj_t *m_desc_discovery_characteristic; - -static volatile bool m_discovery_in_process; -static volatile bool m_discovery_successful; - -// service_uuid may be NULL, to discover all services. -STATIC bool discover_next_services(bleio_central_obj_t *self, uint16_t start_handle, ble_uuid_t *service_uuid) { - m_discovery_successful = false; - m_discovery_in_process = true; - - uint32_t err_code = sd_ble_gattc_primary_services_discover(self->conn_handle, start_handle, service_uuid); - - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to discover services")); - } - - // Wait for a discovery event. - while (m_discovery_in_process) { - MICROPY_VM_HOOK_LOOP; - } - return m_discovery_successful; -} - -STATIC bool discover_next_characteristics(bleio_central_obj_t *self, bleio_service_obj_t *service, uint16_t start_handle) { - m_char_discovery_service = service; - - ble_gattc_handle_range_t handle_range; - handle_range.start_handle = start_handle; - handle_range.end_handle = service->end_handle; - - m_discovery_successful = false; - m_discovery_in_process = true; - - uint32_t err_code = sd_ble_gattc_characteristics_discover(self->conn_handle, &handle_range); - if (err_code != NRF_SUCCESS) { - return false; - } - - // Wait for a discovery event. - while (m_discovery_in_process) { - MICROPY_VM_HOOK_LOOP; - } - return m_discovery_successful; -} - -STATIC bool discover_next_descriptors(bleio_central_obj_t *self, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) { - m_desc_discovery_characteristic = characteristic; - - ble_gattc_handle_range_t handle_range; - handle_range.start_handle = start_handle; - handle_range.end_handle = end_handle; - - m_discovery_successful = false; - m_discovery_in_process = true; - - uint32_t err_code = sd_ble_gattc_descriptors_discover(self->conn_handle, &handle_range); - if (err_code != NRF_SUCCESS) { - return false; - } - - // Wait for a discovery event. - while (m_discovery_in_process) { - MICROPY_VM_HOOK_LOOP; - } - return m_discovery_successful; -} - -STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_central_obj_t *central) { - for (size_t i = 0; i < response->count; ++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; - - // Initialize several fields at once. - common_hal_bleio_service_construct(service, NULL, mp_obj_new_list(0, NULL), false); - - service->device = MP_OBJ_FROM_PTR(central); - service->start_handle = gattc_service->handle_range.start_handle; - service->end_handle = gattc_service->handle_range.end_handle; - service->handle = gattc_service->handle_range.start_handle; - - if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) { - // Known service UUID. - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); - service->uuid = uuid; - service->device = MP_OBJ_FROM_PTR(central); - } else { - // The discovery response contained a 128-bit UUID that has not yet been registered with the - // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. - // For now, just set the UUID to NULL. - service->uuid = NULL; - } - - mp_obj_list_append(central->service_list, service); - } - - if (response->count > 0) { - m_discovery_successful = true; - } - m_discovery_in_process = false; -} - -STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_central_obj_t *central) { - for (size_t i = 0; i < response->count; ++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; - - characteristic->descriptor_list = mp_obj_new_list(0, NULL); - - bleio_uuid_obj_t *uuid = NULL; - - if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { - // Known characteristic UUID. - uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); - } else { - // The discovery response contained a 128-bit UUID that has not yet been registered with the - // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. - // For now, just leave the UUID as NULL. - } - - bleio_characteristic_properties_t props; - - props.broadcast = gattc_char->char_props.broadcast; - props.indicate = gattc_char->char_props.indicate; - props.notify = gattc_char->char_props.notify; - props.read = gattc_char->char_props.read; - props.write = gattc_char->char_props.write; - props.write_no_response = gattc_char->char_props.write_wo_resp; - - // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. - common_hal_bleio_characteristic_construct(characteristic, uuid, props, mp_obj_new_list(0, NULL)); - characteristic->handle = gattc_char->handle_value; - characteristic->service = m_char_discovery_service; - - mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); - } - - if (response->count > 0) { - m_discovery_successful = true; - } - m_discovery_in_process = false; -} - -STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio_central_obj_t *central) { - for (size_t i = 0; i < response->count; ++i) { - ble_gattc_desc_t *gattc_desc = &response->descs[i]; - - // Remember handles for certain well-known descriptors. - switch (gattc_desc->uuid.uuid) { - case DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION: - m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle; - break; - - case DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION: - m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle; - break; - - case DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION: - m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle; - break; - - default: - // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors, - // so ignore those. - // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors - break; - } - - bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); - descriptor->base.type = &bleio_descriptor_type; - - bleio_uuid_obj_t *uuid = NULL; - - if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) { - // Known descriptor UUID. - uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid); - } else { - // The discovery response contained a 128-bit UUID that has not yet been registered with the - // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. - // For now, just leave the UUID as NULL. - } - - common_hal_bleio_descriptor_construct(descriptor, uuid); - descriptor->handle = gattc_desc->handle; - descriptor->characteristic = m_desc_discovery_characteristic; - - mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); - } - - if (response->count > 0) { - m_discovery_successful = true; - } - m_discovery_in_process = false; -} +#include "common-hal/bleio/__init__.h" STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) { bleio_central_obj_t *central = (bleio_central_obj_t*)central_in; @@ -262,20 +54,6 @@ STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) { case BLE_GAP_EVT_DISCONNECTED: central->conn_handle = BLE_CONN_HANDLE_INVALID; - m_discovery_successful = false; - m_discovery_in_process = false; - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, central); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, central); - break; - - case BLE_GATTC_EVT_DESC_DISC_RSP: - on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, central); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: @@ -288,7 +66,6 @@ STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) { sd_ble_gap_conn_param_update(central->conn_handle, &request->conn_params); break; } - default: // For debugging. // mp_printf(&mp_plat_print, "Unhandled central event: 0x%04x\n", ble_evt->header.evt_id); @@ -299,12 +76,11 @@ STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) { void common_hal_bleio_central_construct(bleio_central_obj_t *self) { common_hal_bleio_adapter_set_enabled(true); - self->service_list = mp_obj_new_list(0, NULL); - self->gatt_role = GATT_ROLE_CLIENT; + self->remote_services_list = mp_obj_new_list(0, NULL); self->conn_handle = BLE_CONN_HANDLE_INVALID; } -void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids) { +void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout) { common_hal_bleio_adapter_set_enabled(true); ble_drv_add_event_handler(central_on_ble_evt, self); @@ -345,109 +121,6 @@ void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_o if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { mp_raise_OSError_msg(translate("Failed to connect: timeout")); } - - // Connection successful. - // Now discover services on the remote peripheral. - - if (service_uuids == mp_const_none) { - - // List of service UUID's not given, so discover all available services. - - uint16_t next_service_start_handle = BLE_GATT_HANDLE_START; - - while (discover_next_services(self, next_service_start_handle, MP_OBJ_NULL)) { - // discover_next_services() appends to service_list. - - // Get the most recently discovered service, and then ask for services - // whose handles start after the last attribute handle inside that service. - const bleio_service_obj_t *service = - MP_OBJ_TO_PTR(self->service_list->items[self->service_list->len - 1]); - next_service_start_handle = service->end_handle + 1; - } - } else { - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(service_uuids, &iter_buf); - mp_obj_t uuid_obj; - while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { - mp_raise_ValueError(translate("non-UUID found in service_uuids")); - } - bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); - - ble_uuid_t nrf_uuid; - bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid); - - // Service might or might not be discovered; that's ok. Caller has to check - // Central.remote_services to find out. - // We only need to call this once for each service to discover. - discover_next_services(self, BLE_GATT_HANDLE_START, &nrf_uuid); - } - } - - - for (size_t service_idx = 0; service_idx < self->service_list->len; ++service_idx) { - bleio_service_obj_t *service = MP_OBJ_TO_PTR(self->service_list->items[service_idx]); - - // Skip the service if it had an unknown (unregistered) UUID. - if (service->uuid == NULL) { - continue; - } - - uint16_t next_char_start_handle = service->start_handle; - - // Stop when we go past the end of the range of handles for this service or - // discovery call returns nothing. - // discover_next_characteristics() appends to the characteristic_list. - while (next_char_start_handle <= service->end_handle && - discover_next_characteristics(self, service, next_char_start_handle)) { - - - // Get the most recently discovered characteristic, and then ask for characteristics - // whose handles start after the last attribute handle inside that characteristic. - const bleio_characteristic_obj_t *characteristic = - MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]); - next_char_start_handle = characteristic->handle + 1; - } - - // Got characteristics for this service. Now discover descriptors for each characteristic. - size_t char_list_len = service->characteristic_list->len; - for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) { - bleio_characteristic_obj_t *characteristic = - MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]); - const bool last_characteristic = char_idx == char_list_len - 1; - bleio_characteristic_obj_t *next_characteristic = last_characteristic - ? NULL - : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]); - - // Skip the characteristic if it had an unknown (unregistered) UUID. - if (characteristic->uuid == NULL) { - continue; - } - - uint16_t next_desc_start_handle = characteristic->handle + 1; - - // Don't run past the end of this service or the beginning of the next characteristic. - uint16_t next_desc_end_handle = next_characteristic == NULL - ? service->end_handle - : next_characteristic->handle - 1; - - // Stop when we go past the end of the range of handles for this service or - // discovery call returns nothing. - // discover_next_descriptors() appends to the descriptor_list. - while (next_desc_start_handle <= service->end_handle && - next_desc_start_handle < next_desc_end_handle && - discover_next_descriptors(self, characteristic, - next_desc_start_handle, next_desc_end_handle)) { - - // Get the most recently discovered descriptor, and then ask for descriptors - // whose handles start after that descriptor's handle. - const bleio_descriptor_obj_t *descriptor = - MP_OBJ_TO_PTR(characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1]); - next_desc_start_handle = descriptor->handle + 1; - } - } - - } } void common_hal_bleio_central_disconnect(bleio_central_obj_t *self) { @@ -459,5 +132,5 @@ bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) { } mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) { - return self->service_list; + return self->remote_services_list; } diff --git a/ports/nrf/common-hal/bleio/Central.h b/ports/nrf/common-hal/bleio/Central.h index ac1670088..8b0d811bd 100644 --- a/ports/nrf/common-hal/bleio/Central.h +++ b/ports/nrf/common-hal/bleio/Central.h @@ -36,10 +36,10 @@ typedef struct { mp_obj_base_t base; - gatt_role_t gatt_role; volatile bool waiting_to_connect; volatile uint16_t conn_handle; - mp_obj_list_t *service_list; + // Services discovered after connecting to a remote peripheral. + mp_obj_list_t *remote_services_list; } bleio_central_obj_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 17417a5e6..e9f0225cf 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -33,8 +33,10 @@ #include "nrf_soc.h" #include "py/runtime.h" -#include "common-hal/bleio/__init__.h" -#include "common-hal/bleio/Characteristic.h" + +#include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Service.h" STATIC volatile bleio_characteristic_obj_t *m_read_characteristic; @@ -225,53 +227,39 @@ mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_charact } mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) { - switch (common_hal_bleio_device_get_gatt_role(self->service->device)) { - case GATT_ROLE_CLIENT: + if (common_hal_bleio_service_get_is_remote(self->service)) { gattc_read(self); - break; - - case GATT_ROLE_SERVER: + } else { gatts_read(self); - break; - - default: - mp_raise_RuntimeError(translate("bad GATT role")); - break; } return self->value_data; } void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { - bool sent = false; - uint16_t cccd = 0; + if (common_hal_bleio_service_get_is_remote(self->service)) { + gattc_write(self, bufinfo); + } else { + bool sent = false; + uint16_t cccd = 0; - switch (common_hal_bleio_device_get_gatt_role(self->service->device)) { - case GATT_ROLE_SERVER: - if (self->props.notify || self->props.indicate) { + if (self->props.notify || self->props.indicate) { cccd = get_cccd(self); - } - // It's possible that both notify and indicate are set. - if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { - gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION); - sent = true; - } - if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) { - gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION); - sent = true; - } - if (!sent) { - gatts_write(self, bufinfo); - } - break; + } - case GATT_ROLE_CLIENT: - gattc_write(self, bufinfo); - break; + // It's possible that both notify and indicate are set. + if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { + gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION); + sent = true; + } + if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) { + gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION); + sent = true; + } - default: - mp_raise_RuntimeError(translate("bad GATT role")); - break; + if (!sent) { + gatts_write(self, bufinfo); + } } } @@ -289,8 +277,8 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, mp_raise_ValueError(translate("No CCCD for this Characteristic")); } - if (common_hal_bleio_device_get_gatt_role(self->service->device) != GATT_ROLE_CLIENT) { - mp_raise_ValueError(translate("Can't set CCCD for local Characteristic")); + if (!common_hal_bleio_service_get_is_remote(self->service)) { + mp_raise_ValueError(translate("Can't set CCCD on local Characteristic")); } uint16_t cccd_value = diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c index 59eaaf02b..a6d834d7d 100644 --- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c +++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c @@ -37,7 +37,7 @@ #include "tick.h" -#include "common-hal/bleio/__init__.h" +#include "shared-bindings/bleio/__init__.h" #include "common-hal/bleio/CharacteristicBuffer.h" STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) { diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index 608bd1342..930000534 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -120,20 +120,21 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { } } -void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name) { +void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *services_list, mp_obj_t name) { common_hal_bleio_adapter_set_enabled(true); - self->service_list = service_list; + self->services_list = services_list; + // Used only for discovery when acting as a client. + self->remote_services_list = mp_obj_new_list(0, NULL); self->name = name; - self->gatt_role = GATT_ROLE_SERVER; self->conn_handle = BLE_CONN_HANDLE_INVALID; self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; // Add all the services. - for (size_t service_idx = 0; service_idx < service_list->len; ++service_idx) { - bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[service_idx]); + for (size_t service_idx = 0; service_idx < services_list->len; ++service_idx) { + bleio_service_obj_t *service = MP_OBJ_TO_PTR(services_list->items[service_idx]); service->device = MP_OBJ_FROM_PTR(self); @@ -156,8 +157,8 @@ void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_ } -mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self) { - return self->service_list; +mp_obj_list_t *common_hal_bleio_peripheral_get_services_list(bleio_peripheral_obj_t *self) { + return self->services_list; } bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) { diff --git a/ports/nrf/common-hal/bleio/Peripheral.h b/ports/nrf/common-hal/bleio/Peripheral.h index 2a1251715..3127a527f 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.h +++ b/ports/nrf/common-hal/bleio/Peripheral.h @@ -41,9 +41,11 @@ typedef struct { mp_obj_base_t base; mp_obj_t name; - gatt_role_t gatt_role; volatile uint16_t conn_handle; - mp_obj_list_t *service_list; + // Services provided by this peripheral. + mp_obj_list_t *services_list; + // Remote services discovered when this peripheral is acting as a client. + mp_obj_list_t *remote_services_list; // The advertising data and scan response buffers are held by us, not by the SD, so we must // maintain them and not change it. If we need to change the contents during advertising, // there are tricks to get the SD to notice (see DevZone - TBS). diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index b6fcde827..02c2ac1f9 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -39,6 +39,7 @@ void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_ob self->handle = 0xFFFF; self->uuid = uuid; self->characteristic_list = characteristic_list; + self->is_remote = false; self->is_secondary = is_secondary; for (size_t characteristic_idx = 0; characteristic_idx < characteristic_list->len; ++characteristic_idx) { @@ -57,6 +58,10 @@ mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_ob return self->characteristic_list; } +bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) { + return self->is_remote; +} + bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) { return self->is_secondary; } diff --git a/ports/nrf/common-hal/bleio/Service.h b/ports/nrf/common-hal/bleio/Service.h index 583593fb8..03ac2bca8 100644 --- a/ports/nrf/common-hal/bleio/Service.h +++ b/ports/nrf/common-hal/bleio/Service.h @@ -35,6 +35,8 @@ typedef struct { mp_obj_base_t base; // Handle for this service. uint16_t handle; + // True if created during discovery. + bool is_remote; bool is_secondary; bleio_uuid_obj_t *uuid; // May be a Peripheral, Central, etc. diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index 2dba5780c..a24898b0a 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -26,12 +26,24 @@ * THE SOFTWARE. */ +#include "py/runtime.h" #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Central.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/Peripheral.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" + #include "common-hal/bleio/__init__.h" +static volatile bool m_discovery_in_process; +static volatile bool m_discovery_successful; + +static bleio_service_obj_t *m_char_discovery_service; +static bleio_characteristic_obj_t *m_desc_discovery_characteristic; + // Turn off BLE on a reset or reload. void bleio_reset() { if (common_hal_bleio_adapter_get_enabled()) { @@ -47,22 +59,359 @@ const super_adapter_obj_t common_hal_bleio_adapter_obj = { }, }; -gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device) { +uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) { if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { - return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; + return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { - return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; + return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; } else { - return GATT_ROLE_NONE; + return 0; } } -uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) { +mp_obj_list_t *common_hal_bleio_device_get_remote_services_list(mp_obj_t device) { if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { - return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; + return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->remote_services_list; } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { - return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; + return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->remote_services_list; } else { - return 0; + return NULL; + } +} + +// service_uuid may be NULL, to discover all services. +STATIC bool discover_next_services(mp_obj_t device, uint16_t start_handle, ble_uuid_t *service_uuid) { + m_discovery_successful = false; + m_discovery_in_process = true; + + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device); + uint32_t err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, service_uuid); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg(translate("Failed to discover services")); + } + + // Wait for a discovery event. + while (m_discovery_in_process) { + MICROPY_VM_HOOK_LOOP; + } + return m_discovery_successful; +} + +STATIC bool discover_next_characteristics(mp_obj_t device, bleio_service_obj_t *service, uint16_t start_handle) { + m_char_discovery_service = service; + + ble_gattc_handle_range_t handle_range; + handle_range.start_handle = start_handle; + handle_range.end_handle = service->end_handle; + + m_discovery_successful = false; + m_discovery_in_process = true; + + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device); + uint32_t err_code = sd_ble_gattc_characteristics_discover(conn_handle, &handle_range); + if (err_code != NRF_SUCCESS) { + return false; + } + + // Wait for a discovery event. + while (m_discovery_in_process) { + MICROPY_VM_HOOK_LOOP; + } + return m_discovery_successful; +} + +STATIC bool discover_next_descriptors(mp_obj_t device, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) { + m_desc_discovery_characteristic = characteristic; + + ble_gattc_handle_range_t handle_range; + handle_range.start_handle = start_handle; + handle_range.end_handle = end_handle; + + m_discovery_successful = false; + m_discovery_in_process = true; + + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device); + uint32_t err_code = sd_ble_gattc_descriptors_discover(conn_handle, &handle_range); + if (err_code != NRF_SUCCESS) { + return false; + } + + // Wait for a discovery event. + while (m_discovery_in_process) { + MICROPY_VM_HOOK_LOOP; + } + return m_discovery_successful; +} + +STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, mp_obj_t device) { + for (size_t i = 0; i < response->count; ++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; + + // Initialize several fields at once. + common_hal_bleio_service_construct(service, NULL, mp_obj_new_list(0, NULL), false); + + service->device = device; + service->is_remote = true; + service->start_handle = gattc_service->handle_range.start_handle; + service->end_handle = gattc_service->handle_range.end_handle; + service->handle = gattc_service->handle_range.start_handle; + + if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) { + // Known service UUID. + bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); + service->uuid = uuid; + } else { + // The discovery response contained a 128-bit UUID that has not yet been registered with the + // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. + // For now, just set the UUID to NULL. + service->uuid = NULL; + } + + mp_obj_list_append(common_hal_bleio_device_get_remote_services_list(device), service); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + m_discovery_in_process = false; +} + +STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_obj_t device) { + for (size_t i = 0; i < response->count; ++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; + + characteristic->descriptor_list = mp_obj_new_list(0, NULL); + + bleio_uuid_obj_t *uuid = NULL; + + if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { + // Known characteristic UUID. + uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); + } else { + // The discovery response contained a 128-bit UUID that has not yet been registered with the + // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. + // For now, just leave the UUID as NULL. + } + + bleio_characteristic_properties_t props; + + props.broadcast = gattc_char->char_props.broadcast; + props.indicate = gattc_char->char_props.indicate; + props.notify = gattc_char->char_props.notify; + props.read = gattc_char->char_props.read; + props.write = gattc_char->char_props.write; + props.write_no_response = gattc_char->char_props.write_wo_resp; + + // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. + common_hal_bleio_characteristic_construct(characteristic, uuid, props, mp_obj_new_list(0, NULL)); + characteristic->handle = gattc_char->handle_value; + characteristic->service = m_char_discovery_service; + + mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); + } + + if (response->count > 0) { + m_discovery_successful = true; } + m_discovery_in_process = false; +} + +STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_obj_t device) { + for (size_t i = 0; i < response->count; ++i) { + ble_gattc_desc_t *gattc_desc = &response->descs[i]; + + // Remember handles for certain well-known descriptors. + switch (gattc_desc->uuid.uuid) { + case DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION: + m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle; + break; + + case DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION: + m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle; + break; + + case DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION: + m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle; + break; + + default: + // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors, + // so ignore those. + // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors + break; + } + + bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); + descriptor->base.type = &bleio_descriptor_type; + + bleio_uuid_obj_t *uuid = NULL; + + if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) { + // Known descriptor UUID. + uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid); + } else { + // The discovery response contained a 128-bit UUID that has not yet been registered with the + // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. + // For now, just leave the UUID as NULL. + } + + common_hal_bleio_descriptor_construct(descriptor, uuid); + descriptor->handle = gattc_desc->handle; + descriptor->characteristic = m_desc_discovery_characteristic; + + mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + m_discovery_in_process = false; +} + +STATIC void discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t device) { + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_DISCONNECTED: + m_discovery_successful = false; + m_discovery_in_process = false; + break; + + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, device); + break; + + case BLE_GATTC_EVT_CHAR_DISC_RSP: + on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, device); + break; + + case BLE_GATTC_EVT_DESC_DISC_RSP: + on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, device); + break; + + default: + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id); + break; + } +} + + +void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist) { + mp_obj_list_t *remote_services_list = common_hal_bleio_device_get_remote_services_list(device); + + ble_drv_add_event_handler(discovery_on_ble_evt, device); + + if (service_uuids_whitelist == mp_const_none) { + // List of service UUID's not given, so discover all available services. + + uint16_t next_service_start_handle = BLE_GATT_HANDLE_START; + + while (discover_next_services(device, next_service_start_handle, MP_OBJ_NULL)) { + // discover_next_services() appends to remote_services_list. + + // Get the most recently discovered service, and then ask for services + // whose handles start after the last attribute handle inside that service. + const bleio_service_obj_t *service = + MP_OBJ_TO_PTR(remote_services_list->items[remote_services_list->len - 1]); + next_service_start_handle = service->end_handle + 1; + } + } else { + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf); + mp_obj_t uuid_obj; + while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + mp_raise_ValueError(translate("non-UUID found in service_uuids_whitelist")); + } + bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); + + ble_uuid_t nrf_uuid; + bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid); + + // Service might or might not be discovered; that's ok. Caller has to check + // Central.remote_services to find out. + // We only need to call this once for each service to discover. + discover_next_services(device, BLE_GATT_HANDLE_START, &nrf_uuid); + } + } + + + for (size_t service_idx = 0; service_idx < remote_services_list->len; ++service_idx) { + bleio_service_obj_t *service = MP_OBJ_TO_PTR(remote_services_list->items[service_idx]); + + // Skip the service if it had an unknown (unregistered) UUID. + if (service->uuid == NULL) { + continue; + } + + uint16_t next_char_start_handle = service->start_handle; + + // Stop when we go past the end of the range of handles for this service or + // discovery call returns nothing. + // discover_next_characteristics() appends to the characteristic_list. + while (next_char_start_handle <= service->end_handle && + discover_next_characteristics(device, service, next_char_start_handle)) { + + + // Get the most recently discovered characteristic, and then ask for characteristics + // whose handles start after the last attribute handle inside that characteristic. + const bleio_characteristic_obj_t *characteristic = + MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]); + next_char_start_handle = characteristic->handle + 1; + } + + // Got characteristics for this service. Now discover descriptors for each characteristic. + size_t char_list_len = service->characteristic_list->len; + for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) { + bleio_characteristic_obj_t *characteristic = + MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]); + const bool last_characteristic = char_idx == char_list_len - 1; + bleio_characteristic_obj_t *next_characteristic = last_characteristic + ? NULL + : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]); + + // Skip the characteristic if it had an unknown (unregistered) UUID. + if (characteristic->uuid == NULL) { + continue; + } + + uint16_t next_desc_start_handle = characteristic->handle + 1; + + // Don't run past the end of this service or the beginning of the next characteristic. + uint16_t next_desc_end_handle = next_characteristic == NULL + ? service->end_handle + : next_characteristic->handle - 1; + + // Stop when we go past the end of the range of handles for this service or + // discovery call returns nothing. + // discover_next_descriptors() appends to the descriptor_list. + while (next_desc_start_handle <= service->end_handle && + next_desc_start_handle < next_desc_end_handle && + discover_next_descriptors(device, characteristic, + next_desc_start_handle, next_desc_end_handle)) { + + // Get the most recently discovered descriptor, and then ask for descriptors + // whose handles start after that descriptor's handle. + const bleio_descriptor_obj_t *descriptor = + MP_OBJ_TO_PTR(characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1]); + next_desc_start_handle = descriptor->handle + 1; + } + } + } + + // This event handler is no longer needed. + ble_drv_remove_event_handler(discovery_on_ble_evt, device); + } diff --git a/ports/nrf/common-hal/bleio/__init__.h b/ports/nrf/common-hal/bleio/__init__.h index 0c46b631f..c0bba3799 100644 --- a/ports/nrf/common-hal/bleio/__init__.h +++ b/ports/nrf/common-hal/bleio/__init__.h @@ -27,16 +27,10 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H -#include "shared-bindings/bleio/__init__.h" -#include "shared-bindings/bleio/Adapter.h" - -#include "shared-module/bleio/__init__.h" +void bleio_reset(void); // We assume variable length data. // 20 bytes max (23 - 3). #define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3) -gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device); -uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); - #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index a2b48065d..8fa6721e2 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -78,6 +78,7 @@ // TIMERS #define NRFX_TIMER_ENABLED 1 // Don't enable TIMER0: it's used by the SoftDevice. +#define NRFX_TIMER0_ENABLED 0 #define NRFX_TIMER1_ENABLED 1 #define NRFX_TIMER2_ENABLED 1 diff --git a/ports/nrf/peripherals/nrf/timers.c b/ports/nrf/peripherals/nrf/timers.c index 7f7a003d3..88f3dd468 100644 --- a/ports/nrf/peripherals/nrf/timers.c +++ b/ports/nrf/peripherals/nrf/timers.c @@ -36,7 +36,7 @@ STATIC nrfx_timer_t nrfx_timers[] = { #if NRFX_CHECK(NRFX_TIMER0_ENABLED) - // Note that TIMER0 is reserved for use by the SoftDevice, so it should not usually be enabled. + #error NRFX_TIMER0_ENABLED should not be on: TIMER0 is used by the SoftDevice NRFX_TIMER_INSTANCE(0), #endif #if NRFX_CHECK(NRFX_TIMER1_ENABLED) diff --git a/shared-bindings/bleio/Central.c b/shared-bindings/bleio/Central.c index fc00bce5c..70b270c65 100644 --- a/shared-bindings/bleio/Central.c +++ b/shared-bindings/bleio/Central.c @@ -34,6 +34,7 @@ #include "py/objproperty.h" #include "py/objstr.h" #include "py/runtime.h" +#include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/Characteristic.h" @@ -56,12 +57,16 @@ //| //| my_entry = None //| for entry in entries: -//| if entry.name is not None and entry.name == 'MyPeripheral': +//| if entry.name is not None and entry.name == 'InterestingPeripheral': //| my_entry = entry //| break //| -//| central = bleio.Central(my_entry.address) -//| central.connect(10.0) # timeout after 10 seconds +//| if not my_entry: +//| raise Exception("'InterestingPeripheral' not found") +//| +//| central = bleio.Central() +//| central.connect(my_entry.address, 10) # timeout after 10 seconds +//| central.discover_remote_services() //| //| .. class:: Central() @@ -79,24 +84,11 @@ STATIC mp_obj_t bleio_central_make_new(const mp_obj_type_t *type, size_t n_args, return MP_OBJ_FROM_PTR(self); } -//| .. method:: connect(address, timeout, *, service_uuids=None) -//| Attempts a connection to the remote peripheral. If the connection is successful, -//| Do BLE discovery for the listed services, to find their handles and characteristics. -//| The attribute `remote_services` will contain a list of all discovered services. +//| .. method:: connect(address, timeout, *, service_uuids_whitelist=None) +//| Attempts a connection to the remote peripheral. //| //| :param bleio.Address address: The address of the peripheral to connect to //| :param float/int timeout: Try to connect for timeout seconds. -//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services -//| provided by the peripheral that you want to use. -//| The peripheral may provide more services, but services not listed are ignored. -//| If a service in service_uuids is not found during discovery, it will not -//| appear in `remote_services`. -//| -//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow. -//| -//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you -//| you must have already created a :py:class:~`UUID` object for that UUID in order for the -//| service or characteristic to be discovered. (This restriction may be lifted in the future.) //| STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -105,7 +97,6 @@ STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args static const mp_arg_t allowed_args[] = { { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_service_uuids_whitelist, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -119,7 +110,7 @@ STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); // common_hal_bleio_central_connect() will validate that services is an iterable or None. - common_hal_bleio_central_connect(self, address, timeout, args[ARG_service_uuids_whitelist].u_obj); + common_hal_bleio_central_connect(self, address, timeout); return mp_const_none; } @@ -139,6 +130,47 @@ STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_disconnect); +//| .. method:: discover_remote_services(service_uuids_whitelist=None) +//| Do BLE discovery for all services or for the given service UUIDS, +//| to find their handles and characteristics. +//| The attribute `remote_services` will contain a list of all discovered services. +//| `Central.connected` must be True. +//| +//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services +//| provided by the peripheral that you want to use. +//| The peripheral may provide more services, but services not listed are ignored. +//| If a service in service_uuids_whitelist is not found during discovery, it will not +//| appear in `remote_services`. +//| +//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow. +//| +//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you +//| you must have already created a :py:class:~`UUID` object for that UUID in order for the +//| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered +//| for use. (This restriction may be lifted in the future.) +//| +STATIC mp_obj_t bleio_central_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_service_uuids_whitelist }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_service_uuids_whitelist, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (!common_hal_bleio_central_get_connected(self)) { + mp_raise_ValueError(translate("Not connected")); + } + + common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), + args[ARG_service_uuids_whitelist].u_obj); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_discover_remote_services_obj, 1, bleio_central_discover_remote_services); + //| .. attribute:: connected //| //| True if connected to a remove peripheral. @@ -181,8 +213,9 @@ const mp_obj_property_t bleio_central_remote_services_obj = { STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = { // Methods - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) }, - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_central_discover_remote_services_obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_central_connected_obj) }, diff --git a/shared-bindings/bleio/Central.h b/shared-bindings/bleio/Central.h index 0e84037f9..1d7fb6248 100644 --- a/shared-bindings/bleio/Central.h +++ b/shared-bindings/bleio/Central.h @@ -34,7 +34,7 @@ extern const mp_obj_type_t bleio_central_type; extern void common_hal_bleio_central_construct(bleio_central_obj_t *self); -extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids); +extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout); extern void common_hal_bleio_central_disconnect(bleio_central_obj_t *self); extern bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self); extern mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self); diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c index 1302c9652..69bc72d92 100644 --- a/shared-bindings/bleio/Peripheral.c +++ b/shared-bindings/bleio/Peripheral.c @@ -35,6 +35,7 @@ #include "py/objstr.h" #include "py/runtime.h" +#include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Peripheral.h" @@ -107,15 +108,15 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar self->base.type = &bleio_peripheral_type; // Copy the services list and validate its items. - mp_obj_t service_list_obj = mp_obj_new_list(0, NULL); - mp_obj_list_t *service_list = MP_OBJ_FROM_PTR(service_list_obj); + mp_obj_t services_list_obj = mp_obj_new_list(0, NULL); + mp_obj_list_t *services_list = MP_OBJ_FROM_PTR(services_list_obj); mp_obj_t service; while ((service = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (!MP_OBJ_IS_TYPE(service, &bleio_service_type)) { mp_raise_ValueError(translate("non-Service found in services")); } - mp_obj_list_append(service_list, service); + mp_obj_list_append(services_list, service); } const mp_obj_t name = args[ARG_name].u_obj; @@ -128,7 +129,7 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar mp_raise_ValueError(translate("name must be a string")); } - common_hal_bleio_peripheral_construct(self, service_list, name_str); + common_hal_bleio_peripheral_construct(self, services_list, name_str); return MP_OBJ_FROM_PTR(self); } @@ -158,8 +159,8 @@ const mp_obj_property_t bleio_peripheral_connected_obj = { STATIC mp_obj_t bleio_peripheral_get_services(mp_obj_t self_in) { bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); // Return list as a tuple so user won't be able to change it. - mp_obj_list_t *service_list = common_hal_bleio_peripheral_get_service_list(self); - return mp_obj_new_tuple(service_list->len, service_list->items); + mp_obj_list_t *services_list = common_hal_bleio_peripheral_get_services_list(self); + return mp_obj_new_tuple(services_list->len, services_list->items); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_services_obj, bleio_peripheral_get_services); @@ -265,16 +266,63 @@ STATIC mp_obj_t bleio_peripheral_disconnect(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_disconnect_obj, bleio_peripheral_disconnect); +//| .. method:: discover_remote_services(service_uuids_whitelist=None) +//| Do BLE discovery for all services or for the given service UUIDS, +//| to find their handles and characteristics. +//| The attribute `remote_services` will contain a list of all discovered services. +//| `Peripheral.connected` must be True. +//| +//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services +//| provided by the peripheral that you want to use. +//| The peripheral may provide more services, but services not listed are ignored. +//| If a service in service_uuids_whitelist is not found during discovery, it will not +//| appear in `remote_services`. +//| +//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow. +//| +//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you +//| you must have already created a :py:class:~`UUID` object for that UUID in order for the +//| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered +//| for use. (This restriction may be lifted in the future.) +//| +//| Thought it is unusual for a peripheral to act as a BLE client, it can do so, and +//| needs to be able to do discovery on its peer (a central). +//| Examples include a peripheral accessing a central that provides Current Time Service, +//| Apple Notification Center Service, or Battery Service. +//| +STATIC mp_obj_t bleio_peripheral_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_service_uuids_whitelist }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_service_uuids_whitelist, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (!common_hal_bleio_peripheral_get_connected(self)) { + mp_raise_ValueError(translate("Not connected")); + } + + common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), + args[ARG_service_uuids_whitelist].u_obj); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_discover_remote_services_obj, 1, bleio_peripheral_discover_remote_services); + STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = { // Methods - { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) }, - { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) }, - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_peripheral_discover_remote_services_obj) }, // Properties - { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) }, - { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) }, - { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) }, + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_peripheral_locals_dict, bleio_peripheral_locals_dict_table); diff --git a/shared-bindings/bleio/Peripheral.h b/shared-bindings/bleio/Peripheral.h index 846250a5f..7dad0bccd 100644 --- a/shared-bindings/bleio/Peripheral.h +++ b/shared-bindings/bleio/Peripheral.h @@ -33,7 +33,7 @@ extern const mp_obj_type_t bleio_peripheral_type; extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name); -extern mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self); +extern mp_obj_list_t *common_hal_bleio_peripheral_get_services_list(bleio_peripheral_obj_t *self); extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self); extern mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self); extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo); diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index db0606991..b4aeab2bd 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -43,12 +43,16 @@ //| .. class:: Service(uuid, characteristics, *, secondary=False) //| //| Create a new Service object identified by the specified UUID. +//| //| To mark the service as secondary, pass `True` as :py:data:`secondary`. //| //| :param bleio.UUID uuid: The uuid of the service //| :param iterable characteristics: the Characteristic objects for this service //| :param bool secondary: If the service is a secondary one //| +//| A Service may be remote (:py:data:`remote` is ``True``), but a remote Service +//| cannot be constructed directly. It is created by `Central.discover_remote_services()` +//| or `Peripheral.discover_remote_services()`. STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_uuid, ARG_characteristics, ARG_secondary }; @@ -119,6 +123,24 @@ const mp_obj_property_t bleio_service_characteristics_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: remote +//| +//| True if this is a service provided by a remote device. (read-only) +//| +STATIC mp_obj_t bleio_service_get_remote(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_bleio_service_get_is_remote(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_remote_obj, bleio_service_get_remote); + +const mp_obj_property_t bleio_service_remote_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_remote_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + //| .. attribute:: secondary //| //| True if this is a secondary service. (read-only) diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h index f646c81a9..716c2e8a9 100644 --- a/shared-bindings/bleio/Service.h +++ b/shared-bindings/bleio/Service.h @@ -35,6 +35,7 @@ const mp_obj_type_t bleio_service_type; extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, mp_obj_list_t *characteristic_list, bool is_secondary); extern bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self); extern mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self); +extern bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self); extern bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self); extern void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self); diff --git a/shared-bindings/bleio/__init__.h b/shared-bindings/bleio/__init__.h index 4aa6dd45b..dd6e55204 100644 --- a/shared-bindings/bleio/__init__.h +++ b/shared-bindings/bleio/__init__.h @@ -29,8 +29,19 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H +#include "py/objlist.h" + +#include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/Adapter.h" + +#include "shared-module/bleio/__init__.h" #include "common-hal/bleio/Adapter.h" extern const super_adapter_obj_t common_hal_bleio_adapter_obj; +extern uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); +extern mp_obj_list_t *common_hal_bleio_device_get_remote_services_list(mp_obj_t device); +extern void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist); + + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H diff --git a/shared-module/bleio/__init__.h b/shared-module/bleio/__init__.h index 07d148594..f8f0e0660 100644 --- a/shared-module/bleio/__init__.h +++ b/shared-module/bleio/__init__.h @@ -27,12 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H -typedef enum { - GATT_ROLE_NONE, - GATT_ROLE_SERVER, - GATT_ROLE_CLIENT, -} gatt_role_t; - extern void bleio_reset(void); #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H -- cgit v1.2.3 From 83129b8c63e58596add0d111360701aab51ce62b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 30 Jul 2019 14:26:26 -0400 Subject: BLE: peripheral client pairing (not yet bonding); fix time doc formatting --- ports/nrf/common-hal/bleio/Characteristic.c | 2 +- ports/nrf/common-hal/bleio/Peripheral.c | 89 +++++++++++++++++++++++++++-- ports/nrf/common-hal/bleio/Peripheral.h | 8 ++- shared-bindings/bleio/Peripheral.c | 44 ++++++++++++-- shared-bindings/bleio/Peripheral.h | 4 +- shared-bindings/time/__init__.c | 21 +++---- 6 files changed, 146 insertions(+), 22 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index e9f0225cf..b318ae81c 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -203,8 +203,8 @@ STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) { break; } - // For debugging. default: + // For debugging. // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id); break; } diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index 930000534..c45041ad0 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -52,6 +52,19 @@ #define BLE_ADV_AD_TYPE_FIELD_SIZE 1 #define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 +static const ble_gap_sec_params_t pairing_sec_params = { + .bond = 0, // TODO: add bonding + .mitm = 0, + .lesc = 0, + .keypress = 0, + .oob = 0, + .io_caps = BLE_GAP_IO_CAPS_NONE, + .min_key_size = 7, + .max_key_size = 16, + .kdist_own = { .enc = 1, .id = 1}, + .kdist_peer = { .enc = 1, .id = 1}, +}; + STATIC void check_data_fit(size_t data_len) { if (data_len > BLE_GAP_ADV_SET_DATA_SIZE_MAX) { mp_raise_ValueError(translate("Data too large for advertisement packet")); @@ -61,6 +74,9 @@ STATIC void check_data_fit(size_t data_len) { STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in; + // For debugging. + // mp_printf(&mp_plat_print, "Peripheral event: 0x%04x\n", ble_evt->header.evt_id); + switch (ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: { // Central has connected. @@ -89,10 +105,6 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { // Someday may handle timeouts or limit reached. break; - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); - break; - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: { ble_gap_evt_conn_param_update_request_t *request = &ble_evt->evt.gap_evt.params.conn_param_update_request; @@ -113,6 +125,50 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); break; + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &pairing_sec_params, NULL); + break; + + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + // TODO for LESC pairing: + // sd_ble_gap_lesc_dhkey_reply(...); + break; + + case BLE_GAP_EVT_AUTH_STATUS: { + // Pairing process completed + ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status; + if (BLE_GAP_SEC_STATUS_SUCCESS == status->auth_status) { + mp_printf(&mp_plat_print, "Pairing succeeded, status: 0x%04x\n", status->auth_status); + self->pair_status = PAIR_PAIRED; + } else { + mp_printf(&mp_plat_print, "Pairing failed, status: 0x%04x\n", status->auth_status); + self->pair_status = PAIR_NOT_PAIRED; + } + break; + } + + case BLE_GAP_EVT_CONN_SEC_UPDATE: { + ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec; + mp_printf(&mp_plat_print, "sm: %d, lv: %d\n", conn_sec->sec_mode.sm, conn_sec->sec_mode.lv); + if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) { + // Security setup did not succeed: + // mode 0, level 0 means no access + // mode 1, level 1 means open link + // mode >=1 and/or level >=1 means encryption is set up + self->pair_status = PAIR_NOT_PAIRED; + mp_printf(&mp_plat_print, "PAIR_NOT_PAIRED\n"); + } else { + // TODO: see Bluefruit lib + // if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) { + // sd_ble_gatts_sys_attr_set(_conn_hdl, NULL, 0, 0); + // } + self->pair_status = PAIR_PAIRED; + mp_printf(&mp_plat_print, "PAIR_PAIRED\n"); + } + break; + } + + default: // For debugging. // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id); @@ -130,6 +186,7 @@ void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_ self->conn_handle = BLE_CONN_HANDLE_INVALID; self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; + self->pair_status = PAIR_NOT_PAIRED; // Add all the services. @@ -157,7 +214,7 @@ void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_ } -mp_obj_list_t *common_hal_bleio_peripheral_get_services_list(bleio_peripheral_obj_t *self) { +mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self) { return self->services_list; } @@ -248,3 +305,25 @@ void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self) void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *self) { sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); } + +mp_obj_list_t *common_hal_bleio_peripheral_get_remote_services(bleio_peripheral_obj_t *self) { + return self->remote_services_list; +} + +void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *self) { + self->pair_status = PAIR_WAITING; + + uint32_t err_code = sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to start pairing, error 0x%04x"), err_code); + } + + while (self->pair_status == PAIR_WAITING) { + MICROPY_VM_HOOK_LOOP; + } + + if (self->pair_status == PAIR_NOT_PAIRED) { + mp_raise_OSError_msg(translate("Failed to pair")); + } +} diff --git a/ports/nrf/common-hal/bleio/Peripheral.h b/ports/nrf/common-hal/bleio/Peripheral.h index 3127a527f..e4a664b01 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.h +++ b/ports/nrf/common-hal/bleio/Peripheral.h @@ -38,6 +38,12 @@ #include "shared-module/bleio/__init__.h" #include "shared-module/bleio/Address.h" +typedef enum { + PAIR_NOT_PAIRED, + PAIR_WAITING, + PAIR_PAIRED, +} pair_status_t; + typedef struct { mp_obj_base_t base; mp_obj_t name; @@ -52,7 +58,7 @@ typedef struct { uint8_t* advertising_data; uint8_t* scan_response_data; uint8_t adv_handle; - + pair_status_t pair_status; } bleio_peripheral_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c index 69bc72d92..981ea2246 100644 --- a/shared-bindings/bleio/Peripheral.c +++ b/shared-bindings/bleio/Peripheral.c @@ -159,7 +159,7 @@ const mp_obj_property_t bleio_peripheral_connected_obj = { STATIC mp_obj_t bleio_peripheral_get_services(mp_obj_t self_in) { bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); // Return list as a tuple so user won't be able to change it. - mp_obj_list_t *services_list = common_hal_bleio_peripheral_get_services_list(self); + mp_obj_list_t *services_list = common_hal_bleio_peripheral_get_services(self); return mp_obj_new_tuple(services_list->len, services_list->items); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_services_obj, bleio_peripheral_get_services); @@ -312,17 +312,53 @@ STATIC mp_obj_t bleio_peripheral_discover_remote_services(mp_uint_t n_args, cons } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_discover_remote_services_obj, 1, bleio_peripheral_discover_remote_services); +//| .. attribute:: remote_services (read-only) +//| +//| A tuple of services provided by the remote central. +//| If discovery did not occur, an empty tuple will be returned. +//| +STATIC mp_obj_t bleio_peripheral_get_remote_services(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // Return list as a tuple so user won't be able to change it. + mp_obj_list_t *service_list = common_hal_bleio_peripheral_get_remote_services(self); + return mp_obj_new_tuple(service_list->len, service_list->items); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_remote_services_obj, bleio_peripheral_get_remote_services); + +//| .. method:: pair() +//| +//| Request pairing with connected central. +STATIC mp_obj_t bleio_peripheral_pair(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_peripheral_pair(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_pair_obj, bleio_peripheral_pair); + +const mp_obj_property_t bleio_peripheral_remote_services_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_peripheral_get_remote_services_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + + STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) }, { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) }, { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) }, { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_peripheral_discover_remote_services_obj) }, + { MP_ROM_QSTR(MP_QSTR_pair) , MP_ROM_PTR(&bleio_peripheral_pair_obj) }, // Properties - { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) }, - { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) }, - { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) }, + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_peripheral_remote_services_obj) }, + { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_peripheral_locals_dict, bleio_peripheral_locals_dict_table); diff --git a/shared-bindings/bleio/Peripheral.h b/shared-bindings/bleio/Peripheral.h index 7dad0bccd..d9b72b2c3 100644 --- a/shared-bindings/bleio/Peripheral.h +++ b/shared-bindings/bleio/Peripheral.h @@ -33,11 +33,13 @@ extern const mp_obj_type_t bleio_peripheral_type; extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name); -extern mp_obj_list_t *common_hal_bleio_peripheral_get_services_list(bleio_peripheral_obj_t *self); +extern mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self); extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self); extern mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self); extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo); extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device); extern void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *device); +extern mp_obj_list_t *common_hal_bleio_peripheral_get_remote_services(bleio_peripheral_obj_t *self); +extern void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *device); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 70c01c2d8..f34cb9c46 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -99,16 +99,17 @@ mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp //| //| Structure used to capture a date and time. Note that it takes a tuple! //| -//| :param Tuple[tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst] time_tuple: Tuple of time info. -//| * the year, 2017 for example -//| * the month, range [1, 12] -//| * the day of the month, range [1, 31] -//| * the hour, range [0, 23] -//| * the minute, range [0, 59] -//| * the second, range [0, 61] -//| * the day of the week, range [0, 6], Monday is 0 -//| * the day of the year, range [1, 366], -1 indicates not known -//| * 1 when in daylight savings, 0 when not, -1 if unknown. +//| :param tuple time_tuple: Tuple of time info: ``(tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)`` +//| +//| * ``tm_year``: the year, 2017 for example +//| * ``tm_month``: the month, range [1, 12] +//| * ``tm_mday``: the day of the month, range [1, 31] +//| * ``tm_hour``: the hour, range [0, 23] +//| * ``tm_minute``: the minute, range [0, 59] +//| * ``tm_sec``: the second, range [0, 61] +//| * ``tm_wday``: the day of the week, range [0, 6], Monday is 0 +//| * ``tm_yday``: the day of the year, range [1, 366], -1 indicates not known +//| * ``tm_isdst``: 1 when in daylight savings, 0 when not, -1 if unknown. //| const mp_obj_namedtuple_type_t struct_time_type_obj = { .base = { -- cgit v1.2.3 From 91d791afd091ba38bb61689e88a7fc03b9679e00 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 31 Jul 2019 00:30:24 -0400 Subject: cleanup adapter.address; add uniquish suffix to BLE device name --- ports/nrf/common-hal/bleio/Adapter.c | 41 ++++++++++++++++++++++++++++-------- py/objstr.c | 6 ++++++ py/objstr.h | 3 +++ shared-bindings/bleio/Adapter.c | 36 +++++++++++++++++++++---------- shared-bindings/bleio/Adapter.h | 3 ++- shared-bindings/bleio/Address.c | 19 ++++++----------- shared-bindings/bleio/Peripheral.c | 21 +++++++----------- supervisor/shared/usb/usb.c | 5 ++--- 8 files changed, 85 insertions(+), 49 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index 9d0912930..936dfcb9b 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -34,10 +34,11 @@ #include "nrfx_power.h" #include "nrf_nvic.h" #include "nrf_sdm.h" +#include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/bleio/Adapter.h" - #include "supervisor/usb.h" +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/Address.h" STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { mp_raise_msg_varg(&mp_type_AssertionError, @@ -132,20 +133,42 @@ bool common_hal_bleio_adapter_get_enabled(void) { return is_enabled; } -void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { - ble_gap_addr_t local_address; +void get_address(ble_gap_addr_t *address) { uint32_t err_code; common_hal_bleio_adapter_set_enabled(true); - err_code = sd_ble_gap_addr_get(&local_address); + err_code = sd_ble_gap_addr_get(address); if (err_code != NRF_SUCCESS) { mp_raise_OSError_msg(translate("Failed to get local address")); } +} + +bleio_address_obj_t *common_hal_bleio_adapter_get_address(void) { + common_hal_bleio_adapter_set_enabled(true); + + ble_gap_addr_t local_address; + get_address(&local_address); + + bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); + address->base.type = &bleio_address_type; + + common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type); + return address; +} + +mp_obj_t common_hal_bleio_adapter_get_default_name(void) { + common_hal_bleio_adapter_set_enabled(true); + + ble_gap_addr_t local_address; + get_address(&local_address); + + char name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 }; - address->type = local_address.addr_type; + name[sizeof(name) - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf]; + name[sizeof(name) - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf]; + name[sizeof(name) - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf]; + name[sizeof(name) - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf]; - mp_buffer_info_t buf_info; - mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); - memcpy(address->bytes, buf_info.buf, NUM_BLEIO_ADDRESS_BYTES); + return mp_obj_new_str(name, sizeof(name)); } diff --git a/py/objstr.c b/py/objstr.c index ebd11d5cc..afe11f00f 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -41,6 +41,12 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in); +const char nibble_to_hex_upper[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F'}; + +const char nibble_to_hex_lower[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + /******************************************************************************/ /* str */ diff --git a/py/objstr.h b/py/objstr.h index 0efe62a80..61a11d0bd 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -77,6 +77,9 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s mp_obj_t index, bool is_slice); const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction); +const char nibble_to_hex_upper[16]; +const char nibble_to_hex_lower[16]; + MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj); diff --git a/shared-bindings/bleio/Adapter.c b/shared-bindings/bleio/Adapter.c index 7b8df5103..2bb7f3465 100644 --- a/shared-bindings/bleio/Adapter.c +++ b/shared-bindings/bleio/Adapter.c @@ -53,12 +53,6 @@ //| //| State of the BLE adapter. //| - -//| .. attribute:: adapter.address -//| -//| MAC address of the BLE adapter. (read-only) -//| - STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) { return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled()); } @@ -80,13 +74,13 @@ const mp_obj_property_t bleio_adapter_enabled_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: adapter.address +//| +//| MAC address of the BLE adapter. (read-only) +//| STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) { - mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, mp_const_none); - bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj); - - common_hal_bleio_adapter_get_address(address); + return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address()); - return obj; } MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address); @@ -97,9 +91,29 @@ const mp_obj_property_t bleio_adapter_address_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: adapter.default_name +//| +//| default_name of the BLE adapter. (read-only) +//| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``, +//| to make it easy to distinguish multiple CircuitPython boards. +//| +STATIC mp_obj_t bleio_adapter_get_default_name(mp_obj_t self) { + return common_hal_bleio_adapter_get_default_name(); + +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_default_name_obj, bleio_adapter_get_default_name); + +const mp_obj_property_t bleio_adapter_default_name_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_adapter_get_default_name_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + STATIC const mp_rom_map_elem_t bleio_adapter_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&bleio_adapter_enabled_obj) }, { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_adapter_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_default_name), MP_ROM_PTR(&bleio_adapter_default_name_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_adapter_locals_dict, bleio_adapter_locals_dict_table); diff --git a/shared-bindings/bleio/Adapter.h b/shared-bindings/bleio/Adapter.h index de9d1d6db..72382616c 100644 --- a/shared-bindings/bleio/Adapter.h +++ b/shared-bindings/bleio/Adapter.h @@ -34,6 +34,7 @@ const mp_obj_type_t bleio_adapter_type; extern bool common_hal_bleio_adapter_get_enabled(void); extern void common_hal_bleio_adapter_set_enabled(bool enabled); -extern void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address); +extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(void); +extern mp_obj_t common_hal_bleio_adapter_get_default_name(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index 37f01042c..475fc9427 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -147,18 +147,13 @@ STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_o STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (kind == PRINT_STR) { - mp_buffer_info_t buf_info; - mp_obj_t address_bytes = common_hal_bleio_address_get_address_bytes(self); - mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ); - - const uint8_t *buf = (uint8_t *) buf_info.buf; - mp_printf(print, - "%02x:%02x:%02x:%02x:%02x:%02x", - buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]); - } else { - mp_printf(print, "
"); - } + mp_buffer_info_t buf_info; + mp_obj_t address_bytes = common_hal_bleio_address_get_address_bytes(self); + mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ); + + const uint8_t *buf = (uint8_t *) buf_info.buf; + mp_printf(print, "
", + buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]); } //| .. data:: PUBLIC diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c index 981ea2246..6cd077999 100644 --- a/shared-bindings/bleio/Peripheral.c +++ b/shared-bindings/bleio/Peripheral.c @@ -45,8 +45,6 @@ #include "common-hal/bleio/Peripheral.h" -static const char default_name[] = "CIRCUITPY"; - #define ADV_INTERVAL_DEFAULT (1.0f) #define ADV_INTERVAL_MIN (0.0020f) #define ADV_INTERVAL_MIN_STRING "0.0020" @@ -81,14 +79,14 @@ static const char default_name[] = "CIRCUITPY"; //| # Wait for connection. //| pass //| -//| .. class:: Peripheral(services=(), \*, name='CIRCUITPY') +//| .. class:: Peripheral(services=(), \*, name=None) //| //| Create a new Peripheral object. //| //| :param iterable services: the Service objects representing services available from this peripheral, if any. //| A non-connectable peripheral will have no services. -//| :param str name: The name used when advertising this peripheral. Use ``None`` when a name is not needed, -//| such as when the peripheral is a beacon +//| :param str name: The name used when advertising this peripheral. If name is None, +//| bleio.adapter.default_name will be used. //| STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_services, ARG_name }; @@ -119,22 +117,19 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar mp_obj_list_append(services_list, service); } - const mp_obj_t name = args[ARG_name].u_obj; - mp_obj_t name_str; + mp_obj_t name = args[ARG_name].u_obj; if (name == MP_OBJ_NULL || name == mp_const_none) { - name_str = mp_obj_new_str(default_name, strlen(default_name)); - } else if (MP_OBJ_IS_STR(name)) { - name_str = name; - } else { + name = common_hal_bleio_adapter_get_default_name(); + } else if (!MP_OBJ_IS_STR(name)) { mp_raise_ValueError(translate("name must be a string")); } - common_hal_bleio_peripheral_construct(self, services_list, name_str); + common_hal_bleio_peripheral_construct(self, services_list, name); return MP_OBJ_FROM_PTR(self); } -//| .. attribute:: connected +//| .. attribute:: connected (read-only) //| //| True if connected to a BLE Central device. //| diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 0678a3a3f..c1d70c5b0 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -25,6 +25,7 @@ */ #include "tick.h" +#include "py/objstr.h" #include "shared-bindings/microcontroller/Processor.h" #include "shared-module/usb_midi/__init__.h" #include "supervisor/port.h" @@ -43,13 +44,11 @@ void load_serial_number(void) { uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; common_hal_mcu_processor_get_uid(raw_id); - static const char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F'}; for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) { for (int j = 0; j < 2; j++) { uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf; // Strings are UTF-16-LE encoded. - usb_serial_number[1 + i * 2 + j] = nibble_to_hex[nibble]; + usb_serial_number[1 + i * 2 + j] = nibble_to_hex_upper[nibble]; } } } -- cgit v1.2.3 From 28b7cbfca624d3e6a59c7ec231ee6da6ebcf0d80 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 2 Aug 2019 07:44:02 -0500 Subject: nrf: Mark interrupt vectors as used --- ports/nrf/device/nrf52/startup_nrf52840.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/device/nrf52/startup_nrf52840.c b/ports/nrf/device/nrf52/startup_nrf52840.c index 30634a1b5..8e1c36012 100644 --- a/ports/nrf/device/nrf52/startup_nrf52840.c +++ b/ports/nrf/device/nrf52/startup_nrf52840.c @@ -116,7 +116,7 @@ void CRYPTOCELL_IRQHandler (void) __attribute__ ((weak, alias("Default_Han void SPIM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); -const func __Vectors[] __attribute__ ((section(".isr_vector"))) = { +const func __Vectors[] __attribute__ ((used, section(".isr_vector"))) = { (func)&_estack, Reset_Handler, NMI_Handler, -- cgit v1.2.3 From 7ce3776b8086abbe0d01056651904a59bf4f8bec Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 2 Aug 2019 17:56:44 -0400 Subject: WIP: rework of Characteristic properties; enhance Descriptor; not tested --- ports/nrf/common-hal/bleio/Attribute.c | 60 ++++++++ ports/nrf/common-hal/bleio/Attribute.h | 32 +++++ ports/nrf/common-hal/bleio/Central.h | 1 - ports/nrf/common-hal/bleio/Characteristic.c | 21 +-- ports/nrf/common-hal/bleio/Characteristic.h | 6 +- ports/nrf/common-hal/bleio/Descriptor.c | 6 +- ports/nrf/common-hal/bleio/Descriptor.h | 7 +- ports/nrf/common-hal/bleio/Peripheral.c | 4 +- ports/nrf/common-hal/bleio/Peripheral.h | 1 - ports/nrf/common-hal/bleio/Service.c | 74 +++++++--- ports/nrf/common-hal/bleio/__init__.c | 29 ++-- py/circuitpy_defns.mk | 11 +- py/obj.h | 1 + py/objlist.c | 5 + shared-bindings/bleio/Address.c | 12 +- shared-bindings/bleio/Attribute.c | 93 +++++++++++++ shared-bindings/bleio/Attribute.h | 38 +++++ shared-bindings/bleio/Characteristic.c | 207 ++++++++++------------------ shared-bindings/bleio/Characteristic.h | 3 +- shared-bindings/bleio/Descriptor.c | 90 ++---------- shared-bindings/bleio/Descriptor.h | 21 +-- shared-bindings/bleio/__init__.c | 38 +++-- shared-bindings/bleio/__init__.h | 1 - shared-module/bleio/Attribute.c | 46 +++++++ shared-module/bleio/Attribute.h | 41 ++++++ shared-module/bleio/Characteristic.h | 21 +-- shared-module/bleio/__init__.h | 32 ----- 27 files changed, 546 insertions(+), 355 deletions(-) create mode 100644 ports/nrf/common-hal/bleio/Attribute.c create mode 100644 ports/nrf/common-hal/bleio/Attribute.h create mode 100644 shared-bindings/bleio/Attribute.c create mode 100644 shared-bindings/bleio/Attribute.h create mode 100644 shared-module/bleio/Attribute.c create mode 100644 shared-module/bleio/Attribute.h delete mode 100644 shared-module/bleio/__init__.h diff --git a/ports/nrf/common-hal/bleio/Attribute.c b/ports/nrf/common-hal/bleio/Attribute.c new file mode 100644 index 000000000..bffe68254 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Attribute.c @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/bleio/Attribute.h" + +// Convert a bleio security mode to a ble_gap_conn_sec_mode_t setting. +void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) { + switch (security_mode) { + case SEC_MODE_NO_ACCESS: + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(perm); + break; + + case SEC_MODE_OPEN: + BLE_GAP_CONN_SEC_MODE_SET_OPEN(perm); + break; + + case SEC_MODE_ENC_NO_MITM: + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(perm); + break; + + case SEC_MODE_ENC_WITH_MITM: + BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(perm); + break; + + case SEC_MODE_LESC_ENC_WITH_MITM: + BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(perm); + break; + + case SEC_MODE_SIGNED_NO_MITM: + BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(perm); + break; + + case SEC_MODE_SIGNED_WITH_MITM: + BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(perm); + break; + } +} diff --git a/ports/nrf/common-hal/bleio/Attribute.h b/ports/nrf/common-hal/bleio/Attribute.h new file mode 100644 index 000000000..44c2fdfa1 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Attribute.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H + +// Nothing yet. + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H diff --git a/ports/nrf/common-hal/bleio/Central.h b/ports/nrf/common-hal/bleio/Central.h index 8b0d811bd..b7a9050b8 100644 --- a/ports/nrf/common-hal/bleio/Central.h +++ b/ports/nrf/common-hal/bleio/Central.h @@ -31,7 +31,6 @@ #include #include "py/objlist.h" -#include "shared-module/bleio/__init__.h" #include "shared-module/bleio/Address.h" typedef struct { diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index b318ae81c..41fcdd1f1 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -164,7 +164,8 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in check_connected(conn_handle); ble_gattc_write_params_t write_params = { - .write_op = characteristic->props.write_no_response ? BLE_GATT_OP_WRITE_CMD : BLE_GATT_OP_WRITE_REQ, + .write_op = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) + ? BLE_GATT_OP_WRITE_CMD: BLE_GATT_OP_WRITE_REQ, .handle = characteristic->handle, .p_value = bufinfo->buf, .len = bufinfo->len, @@ -211,12 +212,14 @@ STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) { } -void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list) { +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t security_mode, mp_obj_t descriptors) { self->service = mp_const_none; self->uuid = uuid; self->value_data = mp_const_none; self->props = props; - self->descriptor_list = descriptor_list; + self->security_mode = security_mode; + self->descriptor_list = mp_obj_new_list_from_iter(descriptors); + self->handle = BLE_GATT_HANDLE_INVALID; ble_drv_add_event_handler(characteristic_on_ble_evt, self); @@ -238,21 +241,23 @@ mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *s void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { if (common_hal_bleio_service_get_is_remote(self->service)) { - gattc_write(self, bufinfo); + gattc_write(self, bufinfo); } else { bool sent = false; uint16_t cccd = 0; - if (self->props.notify || self->props.indicate) { - cccd = get_cccd(self); + const bool notify = self->props & CHAR_PROP_NOTIFY; + const bool indicate = self->props & CHAR_PROP_INDICATE; + if (notify | indicate) { + cccd = get_cccd(self); } // It's possible that both notify and indicate are set. - if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { + if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION); sent = true; } - if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) { + if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) { gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION); sent = true; } diff --git a/ports/nrf/common-hal/bleio/Characteristic.h b/ports/nrf/common-hal/bleio/Characteristic.h index 7cb227596..8c8309f09 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.h +++ b/ports/nrf/common-hal/bleio/Characteristic.h @@ -28,17 +28,19 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H +#include "shared-bindings/bleio/Attribute.h" +#include "shared-module/bleio/Characteristic.h" #include "common-hal/bleio/Service.h" #include "common-hal/bleio/UUID.h" -#include "shared-module/bleio/Characteristic.h" typedef struct { mp_obj_base_t base; bleio_service_obj_t *service; bleio_uuid_obj_t *uuid; - volatile mp_obj_t value_data; + mp_obj_t value_data; uint16_t handle; bleio_characteristic_properties_t props; + bleio_attribute_security_mode_t security_mode; mp_obj_list_t *descriptor_list; uint16_t user_desc_handle; uint16_t cccd_handle; diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c index 005af6eaa..ad62b2535 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.c +++ b/ports/nrf/common-hal/bleio/Descriptor.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2019 Dan Halbert for Adafruit Industries * Copyright (c) 2018 Artur Pacholec * Copyright (c) 2016 Glenn Ruben Bakke * @@ -33,10 +33,6 @@ void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_u self->uuid = uuid; } -mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) { - return self->handle; -} - bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { return self->uuid; } diff --git a/ports/nrf/common-hal/bleio/Descriptor.h b/ports/nrf/common-hal/bleio/Descriptor.h index b7af6a42f..ad94a0bb9 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.h +++ b/ports/nrf/common-hal/bleio/Descriptor.h @@ -30,14 +30,17 @@ #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H #include "py/obj.h" -#include "common-hal/bleio/Characteristic.h" + +#include "shared-bindings/bleio/Characteristic.h" #include "common-hal/bleio/UUID.h" typedef struct { mp_obj_base_t base; - uint16_t handle; bleio_characteristic_obj_t *characteristic; bleio_uuid_obj_t *uuid; + mp_obj_t value_data; + uint16_t handle; + bleio_attribute_security_mode_t security_mode; } bleio_descriptor_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index c45041ad0..905b26835 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -138,10 +138,10 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { // Pairing process completed ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status; if (BLE_GAP_SEC_STATUS_SUCCESS == status->auth_status) { - mp_printf(&mp_plat_print, "Pairing succeeded, status: 0x%04x\n", status->auth_status); + // mp_printf(&mp_plat_print, "Pairing succeeded, status: 0x%04x\n", status->auth_status); self->pair_status = PAIR_PAIRED; } else { - mp_printf(&mp_plat_print, "Pairing failed, status: 0x%04x\n", status->auth_status); + // mp_printf(&mp_plat_print, "Pairing failed, status: 0x%04x\n", status->auth_status); self->pair_status = PAIR_NOT_PAIRED; } break; diff --git a/ports/nrf/common-hal/bleio/Peripheral.h b/ports/nrf/common-hal/bleio/Peripheral.h index e4a664b01..e75a1641a 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.h +++ b/ports/nrf/common-hal/bleio/Peripheral.h @@ -35,7 +35,6 @@ #include "py/obj.h" #include "py/objlist.h" -#include "shared-module/bleio/__init__.h" #include "shared-module/bleio/Address.h" typedef enum { diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 02c2ac1f9..cdcbad7c4 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -29,8 +29,8 @@ #include "ble.h" #include "py/runtime.h" #include "common-hal/bleio/__init__.h" -#include "common-hal/bleio/Characteristic.h" #include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/Adapter.h" @@ -74,12 +74,12 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) MP_OBJ_TO_PTR(self->characteristic_list->items[characteristic_idx]); ble_gatts_char_md_t char_md = { - .char_props.broadcast = characteristic->props.broadcast, - .char_props.read = characteristic->props.read, - .char_props.write_wo_resp = characteristic->props.write_no_response, - .char_props.write = characteristic->props.write, - .char_props.notify = characteristic->props.notify, - .char_props.indicate = characteristic->props.indicate, + .char_props.broadcast = (bool) characteristic->props & CHAR_PROP_BROADCAST, + .char_props.read = (bool) characteristic->props & CHAR_PROP_READ, + .char_props.write_wo_resp = (bool) characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE, + .char_props.write = (bool) characteristic->props & CHAR_PROP_WRITE, + .char_props.notify = (bool) characteristic->props & CHAR_PROP_NOTIFY, + .char_props.indicate = (bool) characteristic->props & CHAR_PROP_INDICATE, }; ble_gatts_attr_md_t cccd_md = { @@ -93,28 +93,28 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) char_md.p_cccd_md = &cccd_md; } - ble_uuid_t uuid; - bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &uuid); + ble_uuid_t char_uuid; + bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &char_uuid); - ble_gatts_attr_md_t attr_md = { + ble_gatts_attr_md_t char_attr_md = { .vloc = BLE_GATTS_VLOC_STACK, .vlen = 1, }; - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_attr_md.write_perm); - ble_gatts_attr_t attr_char_value = { - .p_uuid = &uuid, - .p_attr_md = &attr_md, + ble_gatts_attr_t char_attr = { + .p_uuid = &char_uuid, + .p_attr_md = &char_attr_md, .init_len = sizeof(uint8_t), .max_len = GATT_MAX_DATA_LENGTH, }; - ble_gatts_char_handles_t handles; + ble_gatts_char_handles_t char_handles; uint32_t err_code; - err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); + err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles); if (err_code != NRF_SUCCESS) { mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code); } @@ -123,9 +123,41 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) mp_raise_ValueError(translate("Characteristic already in use by another Service.")); } - characteristic->user_desc_handle = handles.user_desc_handle; - characteristic->cccd_handle = handles.cccd_handle; - characteristic->sccd_handle = handles.sccd_handle; - characteristic->handle = handles.value_handle; + characteristic->user_desc_handle = char_handles.user_desc_handle; + characteristic->cccd_handle = char_handles.cccd_handle; + characteristic->sccd_handle = char_handles.sccd_handle; + characteristic->handle = char_handles.value_handle; + + // Add the descriptors for this characteristic. + for (size_t descriptor_idx = 0; descriptor_idx < characteristic->descriptor_list->len; ++descriptor_idx) { + bleio_descriptor_obj_t *descriptor = + MP_OBJ_TO_PTR(characteristic->descriptor_list->items[descriptor_idx]); + + ble_uuid_t desc_uuid; + bleio_uuid_convert_to_nrf_ble_uuid(descriptor->uuid, &desc_uuid); + + ble_gatts_attr_md_t desc_attr_md = { + // Data passed is not in a permanent location and should be copied. + .vloc = BLE_GATTS_VLOC_STACK, + .vlen = 1, + }; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.write_perm); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(descriptor->value_data, &bufinfo, MP_BUFFER_READ); + + ble_gatts_attr_t desc_attr = { + .p_uuid = &desc_uuid, + .p_attr_md = &desc_attr_md, + .init_len = bufinfo.len, + .p_value = bufinfo.buf, + .init_offs = 0, + .max_len = GATT_MAX_DATA_LENGTH, + }; + + err_code = sd_ble_gatts_descriptor_add(characteristic->handle, &desc_attr, &descriptor->handle); + } } } diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index a24898b0a..303e70797 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -204,17 +204,16 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_ob // For now, just leave the UUID as NULL. } - bleio_characteristic_properties_t props; - - props.broadcast = gattc_char->char_props.broadcast; - props.indicate = gattc_char->char_props.indicate; - props.notify = gattc_char->char_props.notify; - props.read = gattc_char->char_props.read; - props.write = gattc_char->char_props.write; - props.write_no_response = gattc_char->char_props.write_wo_resp; + bleio_characteristic_properties_t props = + (gattc_char->char_props.broadcast ? CHAR_PROP_BROADCAST : 0) | + (gattc_char->char_props.indicate ? CHAR_PROP_INDICATE : 0) | + (gattc_char->char_props.notify ? CHAR_PROP_NOTIFY : 0) | + (gattc_char->char_props.read ? CHAR_PROP_READ : 0) | + (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) | + (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0); // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. - common_hal_bleio_characteristic_construct(characteristic, uuid, props, mp_obj_new_list(0, NULL)); + common_hal_bleio_characteristic_construct(characteristic, uuid, props, SEC_MODE_OPEN, mp_const_empty_tuple); characteristic->handle = gattc_char->handle_value; characteristic->service = m_char_discovery_service; @@ -233,15 +232,15 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_ob // Remember handles for certain well-known descriptors. switch (gattc_desc->uuid.uuid) { - case DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION: + case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG: m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle; break; - case DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION: + case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG: m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle; break; - case DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION: + case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC: m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle; break; @@ -268,7 +267,8 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_ob // For now, just leave the UUID as NULL. } - common_hal_bleio_descriptor_construct(descriptor, uuid); + // TODO: can we find out security mode? + common_hal_bleio_descriptor_construct(descriptor, uuid, SEC_MODE_OPEN); descriptor->handle = gattc_desc->handle; descriptor->characteristic = m_desc_discovery_characteristic; @@ -313,6 +313,9 @@ void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t ble_drv_add_event_handler(discovery_on_ble_evt, device); + // Start over with an empty list. + mp_obj_list_clear(MP_OBJ_FROM_PTR(common_hal_bleio_device_get_remote_services_list(device))); + if (service_uuids_whitelist == mp_const_none) { // List of service UUID's not given, so discover all available services. diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index bdefc18cc..5e5ebeaa8 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -227,6 +227,7 @@ $(filter $(SRC_PATTERNS), \ audioio/AudioOut.c \ bleio/__init__.c \ bleio/Adapter.c \ + bleio/Attribute.c \ bleio/Central.c \ bleio/Characteristic.c \ bleio/CharacteristicBuffer.c \ @@ -276,6 +277,9 @@ $(filter $(SRC_PATTERNS), \ # All possible sources are listed here, and are filtered by SRC_PATTERNS. SRC_BINDINGS_ENUMS = \ $(filter $(SRC_PATTERNS), \ + bleio/Address.c \ + bleio/Attribute.c \ + bleio/ScanEntry.c \ digitalio/Direction.c \ digitalio/DriveMode.c \ digitalio/Pull.c \ @@ -289,12 +293,6 @@ SRC_BINDINGS_ENUMS += \ help.c \ util.c -SRC_BINDINGS_ENUMS += \ -$(filter $(SRC_PATTERNS), \ - bleio/Address.c \ - bleio/ScanEntry.c \ -) - # All possible sources are listed here, and are filtered by SRC_PATTERNS. SRC_SHARED_MODULE = \ $(filter $(SRC_PATTERNS), \ @@ -314,6 +312,7 @@ $(filter $(SRC_PATTERNS), \ bitbangio/__init__.c \ board/__init__.c \ bleio/Address.c \ + bleio/Attribute.c \ bleio/ScanEntry.c \ busio/OneWire.c \ displayio/Bitmap.c \ diff --git a/py/obj.h b/py/obj.h index 6eead377d..c719c2945 100644 --- a/py/obj.h +++ b/py/obj.h @@ -668,6 +668,7 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed, const mp_obj_t *closed); mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items); +mp_obj_t mp_obj_new_list_from_iter(mp_obj_t iterable); mp_obj_t mp_obj_new_dict(size_t n_args); mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items); mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step); diff --git a/py/objlist.c b/py/objlist.c index 558c4c611..ea38e64e5 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -68,6 +68,11 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) { return list; } +mp_obj_t mp_obj_new_list_from_iter(mp_obj_t iterable) { + mp_obj_t list = mp_obj_new_list(0, NULL); + return list_extend_from_iter(list, iterable); +} + STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; mp_arg_check_num(n_args, kw_args, 0, 1, false); diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index 475fc9427..d77cfa404 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -174,13 +174,13 @@ STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_pr //| A randomly generated address that changes on every connection. //| STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_address_bytes_obj) }, - { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_address_bytes_obj) }, + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) }, // These match the BLE_GAP_ADDR_TYPES values used by the nRF library. - { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_OBJ_NEW_SMALL_INT(0) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_OBJ_NEW_SMALL_INT(1) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(2) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(3) }, + { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_INT(0) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_INT(1) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_INT(2) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_INT(3) }, }; diff --git a/shared-bindings/bleio/Attribute.c b/shared-bindings/bleio/Attribute.c new file mode 100644 index 000000000..f640cc05c --- /dev/null +++ b/shared-bindings/bleio/Attribute.c @@ -0,0 +1,93 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/UUID.h" + +// + +//| .. currentmodule:: bleio +//| +//| :class:`Attribute` -- BLE Attribute +//| ========================================================= +//| +//| Definitions associated with all BLE attributes: characteristics, descriptors, etc. +//| `Attribute` is, notionally, a superclass of `Characteristic` and `Descriptor`, +//| but is not defined as a Python superclass of those classes. +//| +//| .. class:: Attribute() +//| +//| You cannot create an instance of `Attribute`. +//| + +STATIC const mp_rom_map_elem_t bleio_attribute_locals_dict_table[] = { + +//| .. data:: NO_ACCESS +//| +//| security mode: access not allowed +//| +//| .. data:: OPEN +//| +//| security_mode: no security (link is not encrypted) +//| +//| .. data:: ENCRYPT_NO_MITM +//| +//| security_mode: unauthenticated encryption, without man-in-the-middle protection +//| +//| .. data:: ENCRYPT_WITH_MITM +//| +//| security_mode: authenticated encryption, with man-in-the-middle protection +//| +//| .. data:: LESC_ENCRYPT_WITH_MITM +//| +//| security_mode: LESC encryption, with man-in-the-middle protection +//| +//| .. data:: SIGNED_NO_MITM +//| +//| security_mode: unauthenticated data signing, without man-in-the-middle protection +//| +//| .. data:: SIGNED_WITH_MITM +//| +//| security_mode: authenticated data signing, without man-in-the-middle protection +//| + { MP_ROM_QSTR(MP_QSTR_NO_ACCESS), MP_ROM_INT(SEC_MODE_NO_ACCESS) }, + { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(SEC_MODE_OPEN) }, + { MP_ROM_QSTR(MP_QSTR_ENCRYPT_NO_MITM), MP_ROM_INT(SEC_MODE_ENC_NO_MITM) }, + { MP_ROM_QSTR(MP_QSTR_ENCRYPT_WITH_MITM), MP_ROM_INT(SEC_MODE_ENC_WITH_MITM) }, + { MP_ROM_QSTR(MP_QSTR_LESC_ENCRYPT_WITH_MITM), MP_ROM_INT(SEC_MODE_LESC_ENC_WITH_MITM) }, + { MP_ROM_QSTR(MP_QSTR_SIGNED_NO_MITM), MP_ROM_INT(SEC_MODE_SIGNED_NO_MITM) }, + { MP_ROM_QSTR(MP_QSTR_SIGNED_WITH_MITM), MP_ROM_INT(SEC_MODE_SIGNED_WITH_MITM) }, + +}; +STATIC MP_DEFINE_CONST_DICT(bleio_attribute_locals_dict, bleio_attribute_locals_dict_table); + +const mp_obj_type_t bleio_attribute_type = { + { &mp_type_type }, + .name = MP_QSTR_Attribute, + .locals_dict = (mp_obj_dict_t*)&bleio_attribute_locals_dict, +}; diff --git a/shared-bindings/bleio/Attribute.h b/shared-bindings/bleio/Attribute.h new file mode 100644 index 000000000..06a6eb5a9 --- /dev/null +++ b/shared-bindings/bleio/Attribute.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H + +#include "py/obj.h" + +#include "shared-module/bleio/Attribute.h" + +extern const mp_obj_type_t bleio_attribute_type; + +extern void common_hal_bleio_attribute_security_mode_check_valid(bleio_attribute_security_mode_t security_mode); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 3bf0476ab..09ed48ef9 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -28,6 +28,7 @@ #include "py/objproperty.h" #include "py/runtime.h" +#include "shared-bindings/bleio/Attribute.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/UUID.h" @@ -40,30 +41,25 @@ //| and writing of the characteristic's value. //| //| -//| .. class:: Characteristic(uuid, *, broadcast=False, indicate=False, notify=False, read=False, write=False, write_no_response=False) +//| .. class:: Characteristic(uuid, *, properties=0, security_mode=`Attribute.OPEN`, descriptors=None) //| //| Create a new Characteristic object identified by the specified UUID. //| //| :param bleio.UUID uuid: The uuid of the characteristic -//| :param bool broadcast: Allowed in advertising packets -//| :param bool indicate: Server will indicate to the client when the value is set and wait for a response -//| :param bool notify: Server will notify the client when the value is set -//| :param bool read: Clients may read this characteristic -//| :param bool write: Clients may write this characteristic; a response will be sent back -//| :param bool write_no_response: Clients may write this characteristic; no response will be sent back +//| :param int properties: bitmask of these values bitwise-or'd together: `BROADCAST`, `INDICATE`, +//| `NOTIFY`, `READ`, `WRITE`, `WRITE_NO_RESPONSE` +//| :param int security_mode: one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`, +//| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`, +//| `Attribute.SIGNED_NO_MITM`, `Attribute.SIGNED_WITH_MITM`. +//| :param iterable descriptors: BLE descriptors for this characteristic. //| STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { - ARG_uuid, ARG_broadcast, ARG_indicate, ARG_notify, ARG_read, ARG_write, ARG_write_no_response, - }; + enum { ARG_uuid, ARG_properties, ARG_security_mode, ARG_descriptors }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_broadcast, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_indicate, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_notify, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_read, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_write, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_write_no_response, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_properties, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 0 } }, + { MP_QSTR_security_mode, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, + { MP_QSTR_descriptors, MP_ARG_KW_ONLY| MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -76,129 +72,41 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t } bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); - bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); - self->base.type = &bleio_characteristic_type; - - bleio_characteristic_properties_t properties; - - properties.broadcast = args[ARG_broadcast].u_bool; - properties.indicate = args[ARG_indicate].u_bool; - properties.notify = args[ARG_notify].u_bool; - properties.read = args[ARG_read].u_bool; - properties.write = args[ARG_write].u_bool; - properties.write_no_response = args[ARG_write_no_response].u_bool; - - // Initialize, with an empty descriptor list. - common_hal_bleio_characteristic_construct(self, uuid, properties, mp_obj_new_list(0, NULL)); - - return MP_OBJ_FROM_PTR(self); -} - -//| .. attribute:: broadcast -//| -//| A `bool` specifying if the characteristic allows broadcasting its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).broadcast); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast); - -const mp_obj_property_t bleio_characteristic_broadcast_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_broadcast_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -//| .. attribute:: indicate -//| -//| A `bool` specifying if the characteristic allows indicating its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).indicate); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_indicate); - - -const mp_obj_property_t bleio_characteristic_indicate_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_indicate_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -//| .. attribute:: notify -//| -//| A `bool` specifying if the characteristic allows notifying its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).notify); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify); - -const mp_obj_property_t bleio_characteristic_notify_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_notify_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; + const bleio_characteristic_properties_t properties = args[ARG_properties].u_int; + if (properties & ~CHAR_PROP_ALL) { + mp_raise_ValueError(translate("Invalid properties")); + } -//| .. attribute:: read -//| -//| A `bool` specifying if the characteristic allows reading its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + const bleio_attribute_security_mode_t security_mode = args[ARG_security_mode].u_int; + common_hal_bleio_attribute_security_mode_check_valid(security_mode); - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).read); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read); + mp_obj_t descriptors = args[ARG_descriptors].u_obj; + if (descriptors == mp_const_none) { + descriptors = mp_const_empty_tuple; + } -const mp_obj_property_t bleio_characteristic_read_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_read_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; + bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); + self->base.type = &bleio_characteristic_type; -//| .. attribute:: write -//| -//| A `bool` specifying if the characteristic allows writing to its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_bleio_characteristic_construct(self, uuid, properties, security_mode, descriptors); - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write); + return MP_OBJ_FROM_PTR(self); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_write); -const mp_obj_property_t bleio_characteristic_write_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_write_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -//| .. attribute:: write_no_response +//| .. attribute:: properties //| -//| A `bool` specifying if the characteristic allows writing to its value without response. (read-only) +//| An int bitmask representing which properties are set. //| -STATIC mp_obj_t bleio_characteristic_get_write_no_response(mp_obj_t self_in) { +STATIC mp_obj_t bleio_characteristic_get_properties(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write_no_response); + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_get_properties(self)); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_no_response_obj, bleio_characteristic_get_write_no_response); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_properties_obj, bleio_characteristic_get_properties); -const mp_obj_property_t bleio_characteristic_write_no_response_obj = { +const mp_obj_property_t bleio_characteristic_properties_obj = { .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_write_no_response_obj, + .proxy = { (mp_obj_t)&bleio_characteristic_get_properties_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; @@ -301,16 +209,43 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_set_cccd_obj, 1, bleio_ch STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_broadcast), MP_ROM_PTR(&bleio_characteristic_broadcast_obj) }, - { MP_ROM_QSTR(MP_QSTR_descriptors), MP_ROM_PTR(&bleio_characteristic_descriptors_obj) }, - { MP_ROM_QSTR(MP_QSTR_indicate), MP_ROM_PTR(&bleio_characteristic_indicate_obj) }, - { MP_ROM_QSTR(MP_QSTR_notify), MP_ROM_PTR(&bleio_characteristic_notify_obj) }, - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_obj) }, - { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) }, - { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_characteristic_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_no_response), MP_ROM_PTR(&bleio_characteristic_write_no_response_obj) }, + { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_get_properties) }, + { MP_ROM_QSTR(MP_QSTR_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) }, + + // Bitmask constants to represent properties +//| .. data:: BROADCAST +//| +//| property: allowed in advertising packets +//| +//| .. data:: INDICATE +//| +//| property: server will indicate to the client when the value is set and wait for a response +//| +//| .. data:: NOTIFY +//| +//| property: server will notify the client when the value is set +//| +//| .. data:: READ +//| +//| property: clients may read this characteristic +//| +//| .. data:: WRITE +//| +//| property: clients may write this characteristic; a response will be sent back +//| +//| .. data:: WRITE_NO_RESPONSE +//| +//| property: clients may write this characteristic; no response will be sent back +//| + { MP_ROM_QSTR(MP_QSTR_BROADCAST), MP_ROM_INT(CHAR_PROP_BROADCAST) }, + { MP_ROM_QSTR(MP_QSTR_INDICATE), MP_ROM_INT(CHAR_PROP_INDICATE) }, + { MP_ROM_QSTR(MP_QSTR_NOTIFY), MP_ROM_INT(CHAR_PROP_NOTIFY) }, + { MP_ROM_QSTR(MP_QSTR_READ), MP_ROM_INT(CHAR_PROP_READ) }, + { MP_ROM_QSTR(MP_QSTR_WRITE), MP_ROM_INT(CHAR_PROP_WRITE) }, + { MP_ROM_QSTR(MP_QSTR_WRITE_NO_RESPONSE), MP_ROM_INT(CHAR_PROP_WRITE_NO_RESPONSE) }, + }; STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table); @@ -330,5 +265,5 @@ const mp_obj_type_t bleio_characteristic_type = { .name = MP_QSTR_Characteristic, .make_new = bleio_characteristic_make_new, .print = bleio_characteristic_print, - .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict + .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict, }; diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h index d450c42b4..379f9b4bf 100644 --- a/shared-bindings/bleio/Characteristic.h +++ b/shared-bindings/bleio/Characteristic.h @@ -28,12 +28,13 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H +#include "shared-bindings/bleio/Attribute.h" #include "shared-module/bleio/Characteristic.h" #include "common-hal/bleio/Characteristic.h" extern const mp_obj_type_t bleio_characteristic_type; -extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list); +extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t security_mode, mp_obj_t descriptors); extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self); extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self); diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index f2e5aa01d..b709f3aa7 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -28,6 +28,7 @@ #include "py/objproperty.h" #include "py/runtime.h" +#include "shared-bindings/bleio/Attribute.h" #include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/UUID.h" @@ -41,23 +42,15 @@ //| information about the characteristic. //| -//| .. class:: Descriptor(uuid) +//| .. class:: Descriptor(uuid, security_mode=`Attribute.OPEN`) //| -//| Create a new descriptor object with the UUID uuid. +//| Create a new descriptor object with the UUID uuid and the given value, if any. -//| .. attribute:: handle -//| -//| The descriptor handle. (read-only) -//| - -//| .. attribute:: uuid -//| -//| The descriptor uuid. (read-only) -//| STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_uuid }; + enum { ARG_uuid, ARG_security_mode }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_security_mode, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -69,28 +62,22 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar mp_raise_ValueError(translate("Expected a UUID")); } + const bleio_attribute_security_mode_t security_mode = args[ARG_security_mode].u_int; + common_hal_bleio_attribute_security_mode_check_valid(security_mode); + bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t); self->base.type = type; bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_arg); - common_hal_bleio_descriptor_construct(self, uuid); - return MP_OBJ_FROM_PTR(self); -} + common_hal_bleio_descriptor_construct(self, uuid, security_mode); -STATIC mp_obj_t bleio_descriptor_get_handle(mp_obj_t self_in) { - bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_int(common_hal_bleio_descriptor_get_handle(self)); + return MP_OBJ_FROM_PTR(self); } -MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_handle_obj, bleio_descriptor_get_handle); - -const mp_obj_property_t bleio_descriptor_handle_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&bleio_descriptor_get_handle_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; +//| .. attribute:: uuid +//| +//| The descriptor uuid. (read-only) +//| STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -108,54 +95,7 @@ const mp_obj_property_t bleio_descriptor_uuid_obj = { STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = { // Properties - { MP_ROM_QSTR(MP_QSTR_handle), MP_ROM_PTR(&bleio_descriptor_handle_obj) }, { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) }, - - // Static variables - { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES), - MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES) }, - - { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION), - MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION) }, - - { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION), - MP_ROM_INT(DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION) }, - - { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION), - MP_ROM_INT(DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION) }, - - { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT), - MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT) }, - - { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT), - MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT) }, - - { MP_ROM_QSTR(MP_QSTR_VALID_RANGE), - MP_ROM_INT(DESCRIPTOR_UUID_VALID_RANGE) }, - - { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE), - MP_ROM_INT(DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE) }, - - { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE), - MP_ROM_INT(DESCRIPTOR_UUID_REPORT_REFERENCE) }, - - { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS), - MP_ROM_INT(DESCRIPTOR_UUID_NUMBER_OF_DIGITALS) }, - - { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING), - MP_ROM_INT(DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING) }, - - { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION), - MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION) }, - - { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ), - MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT) }, - - { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING), - MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING) }, - - { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING), - MP_ROM_INT(DESCRIPTOR_UUID_TIME_TRIGGER_SETTING) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table); diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h index fd11ea08c..a7daee574 100644 --- a/shared-bindings/bleio/Descriptor.h +++ b/shared-bindings/bleio/Descriptor.h @@ -28,31 +28,14 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H +#include "shared-module/bleio/Attribute.h" #include "common-hal/bleio/Descriptor.h" #include "common-hal/bleio/UUID.h" -enum { - DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES = 0x2900, - DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION = 0x2901, - DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION = 0x2902, - DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION = 0x2903, - DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT = 0x2904, - DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT = 0x2905, - DESCRIPTOR_UUID_VALID_RANGE = 0x2906, - DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE = 0x2907, - DESCRIPTOR_UUID_REPORT_REFERENCE = 0x2908, - DESCRIPTOR_UUID_NUMBER_OF_DIGITALS = 0x2909, - DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING = 0x290A, - DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION = 0x290B, - DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT = 0x290C, - DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING = 0x290D, - DESCRIPTOR_UUID_TIME_TRIGGER_SETTING = 0x290E, -}; - 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 mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self); extern mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); +extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t security_mode); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index ba3bae6c7..7a6f96436 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -31,21 +31,26 @@ #include "shared-bindings/bleio/Central.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/CharacteristicBuffer.h" -// #include "shared-bindings/bleio/Descriptor.h" +#include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/Peripheral.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" -//| :mod:`bleio` --- Bluetooth Low Energy functionality +//| :mod:`bleio` --- Bluetooth Low Energy (BLE) communication //| ================================================================ //| //| .. module:: bleio //| :synopsis: Bluetooth Low Energy functionality //| :platform: nRF //| -//| The `bleio` module contains methods for managing the BLE adapter. +//| The `bleio` module provides necessary low-level functionality for communicating +//| using Bluetooth Low Energy (BLE). We recommend you use `bleio` in conjunction +//| with the `adafruit_ble `_ +//| CircuitPython library, which builds on `bleio`, and +//| provides higher-level convenience functionality, including predefined beacons, clients, +//| servers. //| //| Libraries //| @@ -72,20 +77,23 @@ //| STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, - { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, - { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) }, - { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, - { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) }, -// { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, - { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_type) }, - { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, - { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, - { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, - { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, + { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, + { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) }, + { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, + { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) }, + { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, + { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_type) }, + { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, + { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, + { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, + { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, // Properties - { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, + { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, + + // constants + { MP_ROM_QSTR(MP_QSTR_SEC), MP_ROM_PTR(&bleio_uuid_type) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); diff --git a/shared-bindings/bleio/__init__.h b/shared-bindings/bleio/__init__.h index dd6e55204..626b188a9 100644 --- a/shared-bindings/bleio/__init__.h +++ b/shared-bindings/bleio/__init__.h @@ -34,7 +34,6 @@ #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" -#include "shared-module/bleio/__init__.h" #include "common-hal/bleio/Adapter.h" extern const super_adapter_obj_t common_hal_bleio_adapter_obj; diff --git a/shared-module/bleio/Attribute.c b/shared-module/bleio/Attribute.c new file mode 100644 index 000000000..ac854ec6b --- /dev/null +++ b/shared-module/bleio/Attribute.c @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/runtime.h" +#include "shared-bindings/bleio/Attribute.h" + +void common_hal_bleio_attribute_security_mode_check_valid(bleio_attribute_security_mode_t security_mode) { + switch (security_mode) { + case SEC_MODE_NO_ACCESS: + case SEC_MODE_OPEN: + case SEC_MODE_ENC_NO_MITM: + case SEC_MODE_ENC_WITH_MITM: + case SEC_MODE_LESC_ENC_WITH_MITM: + case SEC_MODE_SIGNED_NO_MITM: + case SEC_MODE_SIGNED_WITH_MITM: + break; + default: + mp_raise_ValueError(translate("Invalid security_mode")); + break; + } +} diff --git a/shared-module/bleio/Attribute.h b/shared-module/bleio/Attribute.h new file mode 100644 index 000000000..62615f1b5 --- /dev/null +++ b/shared-module/bleio/Attribute.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H + +// BLE security modes: 0x +typedef enum { + SEC_MODE_NO_ACCESS = 0x00, + SEC_MODE_OPEN = 0x11, + SEC_MODE_ENC_NO_MITM = 0x21, + SEC_MODE_ENC_WITH_MITM = 0x31, + SEC_MODE_LESC_ENC_WITH_MITM = 0x41, + SEC_MODE_SIGNED_NO_MITM = 0x12, + SEC_MODE_SIGNED_WITH_MITM = 0x22, +} bleio_attribute_security_mode_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h index 27b43588f..409a57c76 100644 --- a/shared-module/bleio/Characteristic.h +++ b/shared-module/bleio/Characteristic.h @@ -27,14 +27,17 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H -// Flags for each characteristic property. Common across ports. -typedef struct { - bool broadcast : 1; - bool read : 1; - bool write_no_response : 1; - bool write : 1; - bool notify : 1; - bool indicate : 1; -} bleio_characteristic_properties_t; +typedef enum { + CHAR_PROP_NONE = 0, + CHAR_PROP_BROADCAST = 1u << 0, + CHAR_PROP_INDICATE = 1u << 1, + CHAR_PROP_NOTIFY = 1u << 2, + CHAR_PROP_READ = 1u << 3, + CHAR_PROP_WRITE = 1u << 4, + CHAR_PROP_WRITE_NO_RESPONSE = 1u << 5, + CHAR_PROP_ALL = (CHAR_PROP_BROADCAST | CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY | + CHAR_PROP_READ | CHAR_PROP_WRITE | CHAR_PROP_WRITE_NO_RESPONSE) +} bleio_characteristic_properties_enum_t; +typedef uint8_t bleio_characteristic_properties_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H diff --git a/shared-module/bleio/__init__.h b/shared-module/bleio/__init__.h deleted file mode 100644 index f8f0e0660..000000000 --- a/shared-module/bleio/__init__.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Dan Halbert for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H -#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H - -extern void bleio_reset(void); - -#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H -- cgit v1.2.3 From 4bae29b9254416d192e498a9e9df049097cab660 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 2 Aug 2019 07:48:12 -0500 Subject: nrf: enable link-time optimization Testing performed: installed freshly built .uf2 on a Particle Xenon. Checked that circuitpython still starts. Checked that the size of all .uf2 files for nrf builds are plausible. Aside from memory savings, the performance of Python code (pystone) increased by about +14%. However, this adds about 12-16 seconds to each nrf build. Timings & Sizes (build system: i5-3320M, -j5 parallelism on 4 threads): Before: $ make -j5 BOARD=particle_xenon 765004 bytes free in flash out of 1048576 bytes ( 1024.0 kb ). 232076 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ). 68.54user 11.83system 0:34.34elapsed 234%CPU pystones before: 570 After: $ make -j5 BOARD=particle_xenon 804284 bytes free in flash out of 1048576 bytes ( 1024.0 kb ). 232072 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ). 71.06user 11.77system 0:46.91elapsed 176%CPU pystones after: 650 Timings on travis: Before: Build feather_nrf52840_express for pl took 55.79s and succeeded Build feather_nrf52840_express for zh_Latn_pinyin took 3.18s and succeeded After: Build feather_nrf52840_express for pl took 62.72s and succeeded Build feather_nrf52840_express for zh_Latn_pinyin took 19.10s Closes: #1396 --- ports/nrf/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 9da2c498d..fad127514 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -95,8 +95,7 @@ ifeq ($(DEBUG), 1) CFLAGS += -fno-inline -fno-ipa-sra else CFLAGS += -Os -DNDEBUG - # TODO: Test with -flto - ### CFLAGS += -flto + CFLAGS += -flto -flto-partition=none endif -- cgit v1.2.3 From d74c8b9425d38fe2dce56e044b128ab5693f5f06 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 6 Aug 2019 22:55:25 -0400 Subject: WIP: more Descriptor work; refactor gattc/gatts read/write --- ports/nrf/common-hal/bleio/Characteristic.c | 199 +++++++++------------------- ports/nrf/common-hal/bleio/Characteristic.h | 6 +- ports/nrf/common-hal/bleio/Descriptor.c | 84 +++++++++++- ports/nrf/common-hal/bleio/Descriptor.h | 6 +- ports/nrf/common-hal/bleio/Service.c | 3 +- ports/nrf/common-hal/bleio/__init__.c | 89 ++++++++++++- shared-bindings/bleio/Address.c | 16 ++- shared-bindings/bleio/Attribute.c | 4 +- shared-bindings/bleio/Characteristic.c | 62 +++++++-- shared-bindings/bleio/Characteristic.h | 3 +- shared-bindings/bleio/Descriptor.c | 46 +++++-- shared-bindings/bleio/Descriptor.h | 6 +- shared-bindings/bleio/Service.c | 3 + shared-bindings/bleio/__init__.c | 1 + shared-bindings/bleio/__init__.h | 6 + 15 files changed, 362 insertions(+), 172 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 41fcdd1f1..e0ddf1e81 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -25,30 +25,23 @@ * THE SOFTWARE. */ -#include -#include - -#include "ble_drv.h" -#include "ble_gatts.h" -#include "nrf_soc.h" - #include "py/runtime.h" #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/Service.h" -STATIC volatile bleio_characteristic_obj_t *m_read_characteristic; +static volatile bleio_characteristic_obj_t *m_read_characteristic; -STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) { - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); +STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) { uint16_t cccd; ble_gatts_value_t value = { .p_value = (uint8_t*) &cccd, .len = 2, }; - const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, characteristic->cccd_handle, &value); + const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, cccd_handle, &value); if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) { @@ -61,64 +54,39 @@ STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) { return cccd; } -STATIC void gatts_read(bleio_characteristic_obj_t *characteristic) { - // This might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because - // we can still read and write the local value. - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - - mp_buffer_info_t bufinfo; - ble_gatts_value_t gatts_value = { - .p_value = NULL, - .len = 0, - }; - - // Read once to find out what size buffer we need, then read again to fill buffer. - - uint32_t err_code = sd_ble_gatts_value_get(conn_handle, characteristic->handle, &gatts_value); - if (err_code == NRF_SUCCESS) { - characteristic->value_data = mp_obj_new_bytearray_of_zeros(gatts_value.len); - mp_get_buffer_raise(characteristic->value_data, &bufinfo, MP_BUFFER_WRITE); - gatts_value.p_value = bufinfo.buf; - - // Read again, with the correct size of buffer. - err_code = sd_ble_gatts_value_get(conn_handle, characteristic->handle, &gatts_value); - } - - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code); - } -} - +STATIC void characteristic_on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { -STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - // This might be BLE_CONN_HANDLE_INVALID if we're not conected, but that's OK, because - // we can still read and write the local value. - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); + // More events may be handled later, so keep this as a switch. - ble_gatts_value_t gatts_value = { - .p_value = bufinfo->buf, - .len = bufinfo->len, - }; + case BLE_GATTC_EVT_READ_RSP: { + ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; + if (m_read_characteristic) { + m_read_characteristic->value = mp_obj_new_bytearray(response->len, response->data); + } + // Indicate to busy-wait loop that we've read the attribute value. + m_read_characteristic = NULL; + break; + } - const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value); - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code); + default: + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id); + break; } } -STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo, uint16_t hvx_type) { +STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, uint16_t hvx_type) { uint16_t hvx_len = bufinfo->len; ble_gatts_hvx_params_t hvx_params = { - .handle = characteristic->handle, + .handle = handle, .type = hvx_type, .offset = 0, .p_len = &hvx_len, .p_data = bufinfo->buf, }; - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - while (1) { const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params); if (err_code == NRF_SUCCESS) { @@ -134,21 +102,17 @@ STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp // Some real error has occurred. mp_raise_OSError_msg_varg(translate("Failed to notify or indicate attribute value, err 0x%04x"), err_code); } - -} - -STATIC void check_connected(uint16_t conn_handle) { - if (conn_handle == BLE_CONN_HANDLE_INVALID) { - mp_raise_OSError_msg(translate("Not connected")); - } } -STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { +STATIC void characteristic_gattc_read(bleio_characteristic_obj_t *characteristic) { const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - check_connected(conn_handle); + common_hal_bleio_check_connected(conn_handle); + // Set to NULL in event loop after event. m_read_characteristic = characteristic; + ble_drv_add_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic); + const uint32_t err_code = sd_ble_gattc_read(conn_handle, characteristic->handle, 0); if (err_code != NRF_SUCCESS) { mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code); @@ -157,91 +121,54 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { while (m_read_characteristic != NULL) { MICROPY_VM_HOOK_LOOP; } -} - -STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - check_connected(conn_handle); - - ble_gattc_write_params_t write_params = { - .write_op = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) - ? BLE_GATT_OP_WRITE_CMD: BLE_GATT_OP_WRITE_REQ, - .handle = characteristic->handle, - .p_value = bufinfo->buf, - .len = bufinfo->len, - }; - - while (1) { - uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); - if (err_code == NRF_SUCCESS) { - break; - } - - // Write with response will return NRF_ERROR_BUSY if the response has not been received. - // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending. - if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) { - // We could wait for an event indicating the write is complete, but just retrying is easier. - MICROPY_VM_HOOK_LOOP; - continue; - } - - // Some real error occurred. - mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code); - } + ble_drv_remove_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic); } -STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) { - switch (ble_evt->header.evt_id) { - - // More events may be handled later, so keep this as a switch. - - case BLE_GATTC_EVT_READ_RSP: { - ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; - m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data); - // Indicate to busy-wait loop that we've read the characteristic. - m_read_characteristic = NULL; - break; - } - - default: - // For debugging. - // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id); - break; - } - -} - -void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t security_mode, mp_obj_t descriptors) { - self->service = mp_const_none; +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_obj_list_t *descriptor_list) { + self->service = MP_OBJ_NULL; self->uuid = uuid; - self->value_data = mp_const_none; - self->props = props; - self->security_mode = security_mode; - self->descriptor_list = mp_obj_new_list_from_iter(descriptors); - + self->value = mp_const_none; self->handle = BLE_GATT_HANDLE_INVALID; - - ble_drv_add_event_handler(characteristic_on_ble_evt, self); + self->props = props; + self->read_perm = read_perm; + self->write_perm = write_perm; + self->descriptor_list = descriptor_list; + + for (size_t descriptor_idx = 0; descriptor_idx < descriptor_list->len; ++descriptor_idx) { + bleio_descriptor_obj_t *descriptor = + MP_OBJ_TO_PTR(descriptor_list->items[descriptor_idx]); + descriptor->characteristic = self; + } } mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) { return self->descriptor_list; } +bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self) { + return self->service; +} + mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); if (common_hal_bleio_service_get_is_remote(self->service)) { - gattc_read(self); + // self->value is set by evt handler. + characteristic_gattc_read(self); } else { - gatts_read(self); + self->value = common_hal_bleio_gatts_read(self->handle, conn_handle); } - return self->value_data; + return self->value; } void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); + if (common_hal_bleio_service_get_is_remote(self->service)) { - gattc_write(self, bufinfo); + // Last argument is true if write-no-reponse desired. + common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, + (self->props & CHAR_PROP_WRITE_NO_RESPONSE)); } else { bool sent = false; uint16_t cccd = 0; @@ -249,26 +176,25 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, const bool notify = self->props & CHAR_PROP_NOTIFY; const bool indicate = self->props & CHAR_PROP_INDICATE; if (notify | indicate) { - cccd = get_cccd(self); + cccd = characteristic_get_cccd(self->cccd_handle, conn_handle); } // It's possible that both notify and indicate are set. if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { - gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION); + characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION); sent = true; } if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) { - gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION); + characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION); sent = true; } if (!sent) { - gatts_write(self, bufinfo); + common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); } } } - bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) { return self->uuid; } @@ -286,14 +212,13 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, mp_raise_ValueError(translate("Can't set CCCD on local Characteristic")); } + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); + common_hal_bleio_check_connected(conn_handle); + uint16_t cccd_value = (notify ? BLE_GATT_HVX_NOTIFICATION : 0) | (indicate ? BLE_GATT_HVX_INDICATION : 0); - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); - check_connected(conn_handle); - - ble_gattc_write_params_t write_params = { .write_op = BLE_GATT_OP_WRITE_REQ, .handle = self->cccd_handle, diff --git a/ports/nrf/common-hal/bleio/Characteristic.h b/ports/nrf/common-hal/bleio/Characteristic.h index 8c8309f09..46f46eee5 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.h +++ b/ports/nrf/common-hal/bleio/Characteristic.h @@ -35,12 +35,14 @@ typedef struct { mp_obj_base_t base; + // Will be MP_OBJ_NULL before being assigned to a Service. bleio_service_obj_t *service; bleio_uuid_obj_t *uuid; - mp_obj_t value_data; + mp_obj_t value; uint16_t handle; bleio_characteristic_properties_t props; - bleio_attribute_security_mode_t security_mode; + bleio_attribute_security_mode_t read_perm; + bleio_attribute_security_mode_t write_perm; mp_obj_list_t *descriptor_list; uint16_t user_desc_handle; uint16_t cccd_handle; diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c index ad62b2535..d6473a64f 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.c +++ b/ports/nrf/common-hal/bleio/Descriptor.c @@ -26,13 +26,93 @@ * THE SOFTWARE. */ -#include "common-hal/bleio/Descriptor.h" +#include "py/runtime.h" + +#include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/Descriptor.h" +#include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" -void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid) { +static volatile bleio_descriptor_obj_t *m_read_descriptor; + +void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm) { + self->characteristic = MP_OBJ_NULL; self->uuid = uuid; + self->value = mp_const_none; + self->handle = BLE_CONN_HANDLE_INVALID; + self->read_perm = read_perm; + self->write_perm = write_perm; } bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { return self->uuid; } + +mp_obj_t common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self) { + return self->characteristic; +} + +STATIC void descriptor_on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { + + // More events may be handled later, so keep this as a switch. + + case BLE_GATTC_EVT_READ_RSP: { + ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; + if (m_read_descriptor) { + m_read_descriptor->value = mp_obj_new_bytearray(response->len, response->data); + } + // Indicate to busy-wait loop that we've read the attribute value. + m_read_descriptor = NULL; + break; + } + + default: + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled descriptor event: 0x%04x\n", ble_evt->header.evt_id); + break; + } +} + +STATIC void descriptor_gattc_read(bleio_descriptor_obj_t *descriptor) { + const uint16_t conn_handle = + common_hal_bleio_device_get_conn_handle(descriptor->characteristic->service->device); + common_hal_bleio_check_connected(conn_handle); + + // Set to NULL in event loop after event. + m_read_descriptor = descriptor; + + ble_drv_add_event_handler(descriptor_on_gattc_read_rsp_evt, descriptor); + + const uint32_t err_code = sd_ble_gattc_read(conn_handle, descriptor->handle, 0); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code); + } + + while (m_read_descriptor != NULL) { + MICROPY_VM_HOOK_LOOP; + } + + ble_drv_remove_event_handler(descriptor_on_gattc_read_rsp_evt, descriptor); +} + +mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self) { + if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { + descriptor_gattc_read(self); + } else { + self->value = common_hal_bleio_gatts_read( + self->handle, common_hal_bleio_device_get_conn_handle(self->characteristic->service->device)); + } + + return self->value; +} + +void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->characteristic->service->device); + if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { + // false means WRITE_REQ, not write-no-response + common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, false); + } else { + common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); + } +} diff --git a/ports/nrf/common-hal/bleio/Descriptor.h b/ports/nrf/common-hal/bleio/Descriptor.h index ad94a0bb9..2fae8cba6 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.h +++ b/ports/nrf/common-hal/bleio/Descriptor.h @@ -36,11 +36,13 @@ typedef struct { mp_obj_base_t base; + // Will be MP_OBJ_NULL before being assigned to a Characteristic. bleio_characteristic_obj_t *characteristic; bleio_uuid_obj_t *uuid; - mp_obj_t value_data; + mp_obj_t value; uint16_t handle; - bleio_attribute_security_mode_t security_mode; + bleio_attribute_security_mode_t read_perm; + bleio_attribute_security_mode_t write_perm; } bleio_descriptor_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index cdcbad7c4..6d2d9d74f 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -47,7 +47,6 @@ void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_ob MP_OBJ_TO_PTR(characteristic_list->items[characteristic_idx]); characteristic->service = self; } - } bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) { @@ -146,7 +145,7 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.write_perm); mp_buffer_info_t bufinfo; - mp_get_buffer_raise(descriptor->value_data, &bufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(descriptor->value, &bufinfo, MP_BUFFER_READ); ble_gatts_attr_t desc_attr = { .p_uuid = &desc_uuid, diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index 303e70797..9879a9ff4 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -59,13 +59,19 @@ const super_adapter_obj_t common_hal_bleio_adapter_obj = { }, }; +void common_hal_bleio_check_connected(uint16_t conn_handle) { + if (conn_handle == BLE_CONN_HANDLE_INVALID) { + mp_raise_OSError_msg(translate("Not connected")); + } +} + uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) { if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; } else { - return 0; + return BLE_CONN_HANDLE_INVALID; } } @@ -213,7 +219,7 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_ob (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0); // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. - common_hal_bleio_characteristic_construct(characteristic, uuid, props, SEC_MODE_OPEN, mp_const_empty_tuple); + common_hal_bleio_characteristic_construct(characteristic, uuid, props, SEC_MODE_OPEN, SEC_MODE_OPEN, mp_const_empty_tuple); characteristic->handle = gattc_char->handle_value; characteristic->service = m_char_discovery_service; @@ -267,8 +273,7 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_ob // For now, just leave the UUID as NULL. } - // TODO: can we find out security mode? - common_hal_bleio_descriptor_construct(descriptor, uuid, SEC_MODE_OPEN); + common_hal_bleio_descriptor_construct(descriptor, uuid, SEC_MODE_OPEN, SEC_MODE_OPEN); descriptor->handle = gattc_desc->handle; descriptor->characteristic = m_desc_discovery_characteristic; @@ -418,3 +423,79 @@ void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t ble_drv_remove_event_handler(discovery_on_ble_evt, device); } + +// GATTS read of a Characteristic or Descriptor. +mp_obj_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle) { + // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because + // we can still read and write the local value. + + mp_buffer_info_t bufinfo; + ble_gatts_value_t gatts_value = { + .p_value = NULL, + .len = 0, + }; + + // Read once to find out what size buffer we need, then read again to fill buffer. + + mp_obj_t value = mp_const_none; + uint32_t err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value); + if (err_code == NRF_SUCCESS) { + value = mp_obj_new_bytearray_of_zeros(gatts_value.len); + mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_WRITE); + gatts_value.p_value = bufinfo.buf; + + // Read again, with the correct size of buffer. + err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value); + } + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code); + } + + return value; +} + +void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) { + // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because + // we can still read and write the local value. + + ble_gatts_value_t gatts_value = { + .p_value = bufinfo->buf, + .len = bufinfo->len, + }; + + const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code); + } +} + +void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response) { + common_hal_bleio_check_connected(conn_handle); + + ble_gattc_write_params_t write_params = { + .write_op = write_no_response ? BLE_GATT_OP_WRITE_CMD: BLE_GATT_OP_WRITE_REQ, + .handle = handle, + .p_value = bufinfo->buf, + .len = bufinfo->len, + }; + + while (1) { + uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); + if (err_code == NRF_SUCCESS) { + break; + } + + // Write with response will return NRF_ERROR_BUSY if the response has not been received. + // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending. + if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) { + // We could wait for an event indicating the write is complete, but just retrying is easier. + MICROPY_VM_HOOK_LOOP; + continue; + } + + // Some real error occurred. + mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code); + } + +} diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index d77cfa404..baeb6d7c0 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -83,7 +83,21 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, //| .. attribute:: address_bytes //| -//| The bytes that make up the device address (read-only) +//| The bytes that make up the device address (read-only). +//| +//| Note that the ``bytes`` object returned is in little-endian order: +//| The least significant byte is ``address_bytes[0]``. So the address will +//| appear to be reversed if you print the raw ``bytes`` object. If you print +//| or use `str()` on the :py:class:`~bleio.Attribute` object itself, the address will be printed +//| in the expected order. For example: +//| +//| .. code-block:: pycon +//| +//| >>> import bleio +//| >>> bleio.adapter.address +//|
+//| >>> bleio.adapter.address.address_bytes +//| b'5\xa8\xed\xf5\x1d\xc8' //| STATIC mp_obj_t bleio_address_get_address_bytes(mp_obj_t self_in) { bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/bleio/Attribute.c b/shared-bindings/bleio/Attribute.c index f640cc05c..ef6b17253 100644 --- a/shared-bindings/bleio/Attribute.c +++ b/shared-bindings/bleio/Attribute.c @@ -37,12 +37,12 @@ //| ========================================================= //| //| Definitions associated with all BLE attributes: characteristics, descriptors, etc. -//| `Attribute` is, notionally, a superclass of `Characteristic` and `Descriptor`, +//| :py:class:`~bleio.Attribute` is, notionally, a superclass of `Characteristic` and `Descriptor`, //| but is not defined as a Python superclass of those classes. //| //| .. class:: Attribute() //| -//| You cannot create an instance of `Attribute`. +//| You cannot create an instance of :py:class:`~bleio.Attribute`. //| STATIC const mp_rom_map_elem_t bleio_attribute_locals_dict_table[] = { diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 09ed48ef9..45bec6c28 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -30,6 +30,7 @@ #include "py/runtime.h" #include "shared-bindings/bleio/Attribute.h" #include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/UUID.h" //| .. currentmodule:: bleio @@ -41,24 +42,28 @@ //| and writing of the characteristic's value. //| //| -//| .. class:: Characteristic(uuid, *, properties=0, security_mode=`Attribute.OPEN`, descriptors=None) +//| .. class:: Characteristic(uuid, *, properties=0, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, descriptors=None) //| //| Create a new Characteristic object identified by the specified UUID. //| //| :param bleio.UUID uuid: The uuid of the characteristic //| :param int properties: bitmask of these values bitwise-or'd together: `BROADCAST`, `INDICATE`, //| `NOTIFY`, `READ`, `WRITE`, `WRITE_NO_RESPONSE` -//| :param int security_mode: one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`, +//| :param int read_perm: Specifies whether the characteristic can be read by a client, and if so, which +//| security mode is required. Must be one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`, //| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`, -//| `Attribute.SIGNED_NO_MITM`, `Attribute.SIGNED_WITH_MITM`. +//| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`. +//| :param int write_perm: Specifies whether the characteristic can be written by a client, and if so, which +//| security mode is required. Values allowed are the same as `read_perm`. //| :param iterable descriptors: BLE descriptors for this characteristic. //| STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_uuid, ARG_properties, ARG_security_mode, ARG_descriptors }; + enum { ARG_uuid, ARG_properties, ARG_read_perm, ARG_write_perm, ARG_descriptors }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_properties, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 0 } }, - { MP_QSTR_security_mode, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, + { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, + { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, { MP_QSTR_descriptors, MP_ARG_KW_ONLY| MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; @@ -77,8 +82,11 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t mp_raise_ValueError(translate("Invalid properties")); } - const bleio_attribute_security_mode_t security_mode = args[ARG_security_mode].u_int; - common_hal_bleio_attribute_security_mode_check_valid(security_mode); + const bleio_attribute_security_mode_t read_perm = args[ARG_read_perm].u_int; + common_hal_bleio_attribute_security_mode_check_valid(read_perm); + + const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int; + common_hal_bleio_attribute_security_mode_check_valid(write_perm); mp_obj_t descriptors = args[ARG_descriptors].u_obj; if (descriptors == mp_const_none) { @@ -88,7 +96,27 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); self->base.type = &bleio_characteristic_type; - common_hal_bleio_characteristic_construct(self, uuid, properties, security_mode, descriptors); + // If descriptors is not an iterable, an exception will be thrown. + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(args[ARG_descriptors].u_obj, &iter_buf); + +// Copy the descriptors list and validate its items. + mp_obj_t desc_list_obj = mp_obj_new_list(0, NULL); + mp_obj_list_t *desc_list = MP_OBJ_TO_PTR(desc_list_obj); + + mp_obj_t descriptor_obj; + while ((descriptor_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + if (!MP_OBJ_IS_TYPE(descriptor_obj, &bleio_descriptor_type)) { + mp_raise_ValueError(translate("descriptors includes an object that is not a Descriptors")); + } + bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(descriptor_obj); + if (common_hal_bleio_descriptor_get_characteristic(descriptor) != mp_const_none) { + mp_raise_ValueError(translate("Descriptor is already attached to a Characteristic")); + } + mp_obj_list_append(desc_list_obj, descriptor_obj); + } + + common_hal_bleio_characteristic_construct(self, uuid, properties, read_perm, write_perm, desc_list); return MP_OBJ_FROM_PTR(self); } @@ -182,6 +210,24 @@ const mp_obj_property_t bleio_characteristic_descriptors_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: service (read-only) +//| +//| The Service this Characteristic is a part of. None if not yet assigned to a Service. +//| +STATIC mp_obj_t bleio_characteristic_get_service(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_characteristic_get_service(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_service_obj, bleio_characteristic_get_service); + +const mp_obj_property_t bleio_characteristic_service_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_service_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + //| .. method:: set_cccd(*, notify=False, indicate=False) //| //| Set the remote characteristic's CCCD to enable or disable notification and indication. diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h index 379f9b4bf..1d532d748 100644 --- a/shared-bindings/bleio/Characteristic.h +++ b/shared-bindings/bleio/Characteristic.h @@ -34,12 +34,13 @@ extern const mp_obj_type_t bleio_characteristic_type; -extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t security_mode, mp_obj_t descriptors); +extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_obj_list_t *descriptor_list); extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self); extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self); extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self); extern mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self); +extern bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self); extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index b709f3aa7..1ab8c9ecd 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -42,15 +42,24 @@ //| information about the characteristic. //| -//| .. class:: Descriptor(uuid, security_mode=`Attribute.OPEN`) +//| .. class:: Descriptor(uuid, *, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`) +//| +//| Create a new descriptor object with the UUID uuid +//| +//| :param bleio.UUID uuid: The uuid of the descriptor +//| :param int read_perm: Specifies whether the descriptor can be read by a client, and if so, which +//| security mode is required. Must be one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`, +//| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`, +//| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`. +//| :param int write_perm: Specifies whether the descriptor can be written by a client, and if so, which +//| security mode is required. Values allowed are the same as `read_perm`. //| -//| Create a new descriptor object with the UUID uuid and the given value, if any. - STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_uuid, ARG_security_mode }; + enum { ARG_uuid, ARG_read_perm, ARG_write_perm }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_security_mode, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, + { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, + { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -62,14 +71,17 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar mp_raise_ValueError(translate("Expected a UUID")); } - const bleio_attribute_security_mode_t security_mode = args[ARG_security_mode].u_int; - common_hal_bleio_attribute_security_mode_check_valid(security_mode); + const bleio_attribute_security_mode_t read_perm = args[ARG_read_perm].u_int; + common_hal_bleio_attribute_security_mode_check_valid(read_perm); + + const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int; + common_hal_bleio_attribute_security_mode_check_valid(write_perm); bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t); self->base.type = type; bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_arg); - common_hal_bleio_descriptor_construct(self, uuid, security_mode); + common_hal_bleio_descriptor_construct(self, uuid, read_perm, write_perm); return MP_OBJ_FROM_PTR(self); } @@ -93,6 +105,24 @@ const mp_obj_property_t bleio_descriptor_uuid_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| .. attribute:: characteristic (read-only) +//| +//| The Characteristic this Descriptor is a part of. None if not yet assigned to a Characteristic. +//| +STATIC mp_obj_t bleio_descriptor_get_characteristic(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_descriptor_get_characteristic(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_characteristic_obj, bleio_descriptor_get_characteristic); + +const mp_obj_property_t bleio_descriptor_characteristic_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_descriptor_get_characteristic_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) }, diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h index a7daee574..eefce03d1 100644 --- a/shared-bindings/bleio/Descriptor.h +++ b/shared-bindings/bleio/Descriptor.h @@ -34,8 +34,8 @@ extern const mp_obj_type_t bleio_descriptor_type; -extern mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self); -extern mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); -extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t security_mode); +extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm); +extern bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); +extern mp_obj_t common_hal_bleio_descriptor_get_characteristic(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 b4aeab2bd..6961b0b52 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -96,6 +96,9 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, // The descriptor base UUID doesn't match the characteristic base UUID. mp_raise_ValueError(translate("Characteristic UUID doesn't match Service UUID")); } + if (common_hal_bleio_characteristic_get_service(characteristic) != MP_OBJ_NULL) { + mp_raise_ValueError(translate("Characteristic is already attached to a Service")); + } mp_obj_list_append(char_list_obj, characteristic_obj); } diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 7a6f96436..0009cf113 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -59,6 +59,7 @@ //| //| Address //| Adapter +//| Attribute //| Central //| Characteristic //| CharacteristicBuffer diff --git a/shared-bindings/bleio/__init__.h b/shared-bindings/bleio/__init__.h index 626b188a9..6a4c804f5 100644 --- a/shared-bindings/bleio/__init__.h +++ b/shared-bindings/bleio/__init__.h @@ -38,9 +38,15 @@ extern const super_adapter_obj_t common_hal_bleio_adapter_obj; +extern void common_hal_bleio_check_connected(uint16_t conn_handle); + extern uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); extern mp_obj_list_t *common_hal_bleio_device_get_remote_services_list(mp_obj_t device); extern void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist); +extern mp_obj_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle); +extern void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo); +extern void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H -- cgit v1.2.3 From d047b73a9cd0f17f9e11d60f3004ada473b2c803 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 7 Aug 2019 11:10:21 -0400 Subject: fix newly-introduced bugs; UART client/server working again --- ports/nrf/common-hal/bleio/Service.c | 12 ++++++------ ports/nrf/common-hal/bleio/__init__.c | 5 ++--- shared-bindings/bleio/Characteristic.c | 12 ++++++------ shared-bindings/bleio/__init__.c | 2 ++ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 6d2d9d74f..0ac0107f5 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -73,12 +73,12 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) MP_OBJ_TO_PTR(self->characteristic_list->items[characteristic_idx]); ble_gatts_char_md_t char_md = { - .char_props.broadcast = (bool) characteristic->props & CHAR_PROP_BROADCAST, - .char_props.read = (bool) characteristic->props & CHAR_PROP_READ, - .char_props.write_wo_resp = (bool) characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE, - .char_props.write = (bool) characteristic->props & CHAR_PROP_WRITE, - .char_props.notify = (bool) characteristic->props & CHAR_PROP_NOTIFY, - .char_props.indicate = (bool) characteristic->props & CHAR_PROP_INDICATE, + .char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0, + .char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0, + .char_props.write_wo_resp = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) ? 1 : 0, + .char_props.write = (characteristic->props & CHAR_PROP_WRITE) ? 1 : 0, + .char_props.notify = (characteristic->props & CHAR_PROP_NOTIFY) ? 1 : 0, + .char_props.indicate = (characteristic->props & CHAR_PROP_INDICATE) ? 1 : 0, }; ble_gatts_attr_md_t cccd_md = { diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index 9879a9ff4..d09b6f5af 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -195,8 +195,6 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_ob bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); characteristic->base.type = &bleio_characteristic_type; - characteristic->descriptor_list = mp_obj_new_list(0, NULL); - bleio_uuid_obj_t *uuid = NULL; if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { @@ -219,7 +217,8 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_ob (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0); // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. - common_hal_bleio_characteristic_construct(characteristic, uuid, props, SEC_MODE_OPEN, SEC_MODE_OPEN, mp_const_empty_tuple); + common_hal_bleio_characteristic_construct( + characteristic, uuid, props, SEC_MODE_OPEN, SEC_MODE_OPEN, mp_obj_new_list(0, NULL)); characteristic->handle = gattc_char->handle_value; characteristic->service = m_char_discovery_service; diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 45bec6c28..4adc897eb 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -96,16 +96,16 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); self->base.type = &bleio_characteristic_type; - // If descriptors is not an iterable, an exception will be thrown. - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(args[ARG_descriptors].u_obj, &iter_buf); - -// Copy the descriptors list and validate its items. + // Copy the descriptors list and validate its items. mp_obj_t desc_list_obj = mp_obj_new_list(0, NULL); mp_obj_list_t *desc_list = MP_OBJ_TO_PTR(desc_list_obj); + // If descriptors is not an iterable, an exception will be thrown. + mp_obj_iter_buf_t iter_buf; + mp_obj_t descriptors_iter = mp_getiter(descriptors, &iter_buf); + mp_obj_t descriptor_obj; - while ((descriptor_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + while ((descriptor_obj = mp_iternext(descriptors_iter)) != MP_OBJ_STOP_ITERATION) { if (!MP_OBJ_IS_TYPE(descriptor_obj, &bleio_descriptor_type)) { mp_raise_ValueError(translate("descriptors includes an object that is not a Descriptors")); } diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 0009cf113..05be48ddc 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -28,6 +28,7 @@ #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Address.h" +#include "shared-bindings/bleio/Attribute.h" #include "shared-bindings/bleio/Central.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/CharacteristicBuffer.h" @@ -80,6 +81,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, + { MP_ROM_QSTR(MP_QSTR_Attribute), MP_ROM_PTR(&bleio_attribute_type) }, { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) }, -- cgit v1.2.3 From 1570ef2dd493dbf813e14ac853ce8d4e069fb6c4 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 7 Aug 2019 23:49:09 -0400 Subject: specifying attribute length; fix up value setting --- ports/nrf/common-hal/bleio/Characteristic.c | 92 ++++++++++++++++++----------- ports/nrf/common-hal/bleio/Characteristic.h | 2 + ports/nrf/common-hal/bleio/Descriptor.c | 53 ++++++++++++----- ports/nrf/common-hal/bleio/Descriptor.h | 2 + ports/nrf/common-hal/bleio/Peripheral.c | 3 - ports/nrf/common-hal/bleio/Service.c | 37 +++++++----- ports/nrf/common-hal/bleio/__init__.c | 7 ++- shared-bindings/bleio/Characteristic.c | 26 +++++--- shared-bindings/bleio/Characteristic.h | 2 +- shared-bindings/bleio/Descriptor.c | 45 +++++++++++++- shared-bindings/bleio/Descriptor.h | 6 +- 11 files changed, 193 insertions(+), 82 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index e0ddf1e81..f8b6ce06c 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -43,7 +43,6 @@ STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_hand const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, cccd_handle, &value); - if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) { // CCCD is not set, so say that neither Notify nor Indicate is enabled. cccd = 0; @@ -125,16 +124,24 @@ STATIC void characteristic_gattc_read(bleio_characteristic_obj_t *characteristic ble_drv_remove_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic); } -void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_obj_list_t *descriptor_list) { +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_obj_list_t *descriptor_list) { self->service = MP_OBJ_NULL; self->uuid = uuid; - self->value = mp_const_none; + self->value = mp_const_empty_bytes; self->handle = BLE_GATT_HANDLE_INVALID; self->props = props; self->read_perm = read_perm; self->write_perm = write_perm; self->descriptor_list = descriptor_list; + const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX; + if (max_length < 0 || max_length > max_length_max) { + mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"), + max_length_max, fixed_length ? "True" : "False"); + } + self->max_length = max_length; + self->fixed_length = fixed_length; + for (size_t descriptor_idx = 0; descriptor_idx < descriptor_list->len; ++descriptor_idx) { bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(descriptor_list->items[descriptor_idx]); @@ -151,48 +158,63 @@ bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_character } mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) { - uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); - if (common_hal_bleio_service_get_is_remote(self->service)) { - // self->value is set by evt handler. - characteristic_gattc_read(self); - } else { - self->value = common_hal_bleio_gatts_read(self->handle, conn_handle); + // Do GATT operations only if this characteristic has been added to a registered service. + if (self->handle != BLE_GATT_HANDLE_INVALID) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); + if (common_hal_bleio_service_get_is_remote(self->service)) { + // self->value is set by evt handler. + characteristic_gattc_read(self); + } else { + self->value = common_hal_bleio_gatts_read(self->handle, conn_handle); + } } return self->value; } void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { - uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); - - if (common_hal_bleio_service_get_is_remote(self->service)) { - // Last argument is true if write-no-reponse desired. - common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, - (self->props & CHAR_PROP_WRITE_NO_RESPONSE)); - } else { - bool sent = false; - uint16_t cccd = 0; - - const bool notify = self->props & CHAR_PROP_NOTIFY; - const bool indicate = self->props & CHAR_PROP_INDICATE; - if (notify | indicate) { - cccd = characteristic_get_cccd(self->cccd_handle, conn_handle); - } + // Do GATT operations only if this characteristic has been added to a registered service. + if (self->handle != BLE_GATT_HANDLE_INVALID) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); + + if (common_hal_bleio_service_get_is_remote(self->service)) { + // Last argument is true if write-no-reponse desired. + common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, + (self->props & CHAR_PROP_WRITE_NO_RESPONSE)); + } else { + if (self->fixed_length && bufinfo->len != self->max_length) { + mp_raise_ValueError(translate("Value length required fixed length")); + } + if (bufinfo->len > self->max_length) { + mp_raise_ValueError(translate("Value length > max_length")); + } - // It's possible that both notify and indicate are set. - if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { - characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION); - sent = true; - } - if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) { - characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION); - sent = true; - } + bool sent = false; + uint16_t cccd = 0; + + const bool notify = self->props & CHAR_PROP_NOTIFY; + const bool indicate = self->props & CHAR_PROP_INDICATE; + if (notify | indicate) { + cccd = characteristic_get_cccd(self->cccd_handle, conn_handle); + } + + // It's possible that both notify and indicate are set. + if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { + characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION); + sent = true; + } + if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) { + characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION); + sent = true; + } - if (!sent) { - common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); + if (!sent) { + common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); + } } } + + self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); } bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) { diff --git a/ports/nrf/common-hal/bleio/Characteristic.h b/ports/nrf/common-hal/bleio/Characteristic.h index 46f46eee5..fb6a4c6ce 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.h +++ b/ports/nrf/common-hal/bleio/Characteristic.h @@ -39,6 +39,8 @@ typedef struct { bleio_service_obj_t *service; bleio_uuid_obj_t *uuid; mp_obj_t value; + uint16_t max_length; + bool fixed_length; uint16_t handle; bleio_characteristic_properties_t props; bleio_attribute_security_mode_t read_perm; diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c index d6473a64f..2a2019277 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.c +++ b/ports/nrf/common-hal/bleio/Descriptor.c @@ -35,20 +35,28 @@ static volatile bleio_descriptor_obj_t *m_read_descriptor; -void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm) { +void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length) { self->characteristic = MP_OBJ_NULL; self->uuid = uuid; - self->value = mp_const_none; - self->handle = BLE_CONN_HANDLE_INVALID; + self->value = mp_const_empty_bytes; + self->handle = BLE_GATT_HANDLE_INVALID; self->read_perm = read_perm; self->write_perm = write_perm; + + const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX; + if (max_length < 0 || max_length > max_length_max) { + mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"), + max_length_max, fixed_length ? "True" : "False"); + } + self->max_length = max_length; + self->fixed_length = fixed_length; } bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { return self->uuid; } -mp_obj_t common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self) { +bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self) { return self->characteristic; } @@ -97,22 +105,37 @@ STATIC void descriptor_gattc_read(bleio_descriptor_obj_t *descriptor) { } mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self) { - if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { - descriptor_gattc_read(self); - } else { - self->value = common_hal_bleio_gatts_read( - self->handle, common_hal_bleio_device_get_conn_handle(self->characteristic->service->device)); + // Do GATT operations only if this descriptor has been registered + if (self->handle != BLE_GATT_HANDLE_INVALID) { + if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { + descriptor_gattc_read(self); + } else { + self->value = common_hal_bleio_gatts_read( + self->handle, common_hal_bleio_device_get_conn_handle(self->characteristic->service->device)); + } } return self->value; } void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) { - uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->characteristic->service->device); - if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { - // false means WRITE_REQ, not write-no-response - common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, false); - } else { - common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); + // Do GATT operations only if this descriptor has been registered. + if (self->handle != BLE_GATT_HANDLE_INVALID) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->characteristic->service->device); + if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { + // false means WRITE_REQ, not write-no-response + common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, false); + } else { + if (self->fixed_length && bufinfo->len != self->max_length) { + mp_raise_ValueError(translate("Value length != required fixed length")); + } + if (bufinfo->len > self->max_length) { + mp_raise_ValueError(translate("Value length > max_length")); + } + + common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); + } } + + self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); } diff --git a/ports/nrf/common-hal/bleio/Descriptor.h b/ports/nrf/common-hal/bleio/Descriptor.h index 2fae8cba6..6db4d7be3 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.h +++ b/ports/nrf/common-hal/bleio/Descriptor.h @@ -40,6 +40,8 @@ typedef struct { bleio_characteristic_obj_t *characteristic; bleio_uuid_obj_t *uuid; mp_obj_t value; + uint16_t max_length; + bool fixed_length; uint16_t handle; bleio_attribute_security_mode_t read_perm; bleio_attribute_security_mode_t write_perm; diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index 905b26835..640b93180 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -149,21 +149,18 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { case BLE_GAP_EVT_CONN_SEC_UPDATE: { ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec; - mp_printf(&mp_plat_print, "sm: %d, lv: %d\n", conn_sec->sec_mode.sm, conn_sec->sec_mode.lv); if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) { // Security setup did not succeed: // mode 0, level 0 means no access // mode 1, level 1 means open link // mode >=1 and/or level >=1 means encryption is set up self->pair_status = PAIR_NOT_PAIRED; - mp_printf(&mp_plat_print, "PAIR_NOT_PAIRED\n"); } else { // TODO: see Bluefruit lib // if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) { // sd_ble_gatts_sys_attr_set(_conn_hdl, NULL, 0, 0); // } self->pair_status = PAIR_PAIRED; - mp_printf(&mp_plat_print, "PAIR_PAIRED\n"); } break; } diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 0ac0107f5..a7a3a6db0 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -72,6 +72,10 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(self->characteristic_list->items[characteristic_idx]); + if (characteristic->handle != BLE_GATT_HANDLE_INVALID) { + mp_raise_ValueError(translate("Characteristic already in use by another Service.")); + } + ble_gatts_char_md_t char_md = { .char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0, .char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0, @@ -97,17 +101,22 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) ble_gatts_attr_md_t char_attr_md = { .vloc = BLE_GATTS_VLOC_STACK, - .vlen = 1, + .vlen = !characteristic->fixed_length, }; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_attr_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_attr_md.write_perm); + mp_buffer_info_t char_value_bufinfo; + mp_get_buffer_raise(characteristic->value, &char_value_bufinfo, MP_BUFFER_READ); + ble_gatts_attr_t char_attr = { .p_uuid = &char_uuid, .p_attr_md = &char_attr_md, - .init_len = sizeof(uint8_t), - .max_len = GATT_MAX_DATA_LENGTH, + .init_len = char_value_bufinfo.len, + .p_value = char_value_bufinfo.buf, + .init_offs = 0, + .max_len = characteristic->max_length, }; ble_gatts_char_handles_t char_handles; @@ -118,10 +127,6 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code); } - if (characteristic->handle != BLE_GATT_HANDLE_INVALID) { - mp_raise_ValueError(translate("Characteristic already in use by another Service.")); - } - characteristic->user_desc_handle = char_handles.user_desc_handle; characteristic->cccd_handle = char_handles.cccd_handle; characteristic->sccd_handle = char_handles.sccd_handle; @@ -138,25 +143,27 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) ble_gatts_attr_md_t desc_attr_md = { // Data passed is not in a permanent location and should be copied. .vloc = BLE_GATTS_VLOC_STACK, - .vlen = 1, + .vlen = !descriptor->fixed_length, }; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.write_perm); - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(descriptor->value, &bufinfo, MP_BUFFER_READ); + mp_buffer_info_t desc_value_bufinfo; + mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ); ble_gatts_attr_t desc_attr = { .p_uuid = &desc_uuid, .p_attr_md = &desc_attr_md, - .init_len = bufinfo.len, - .p_value = bufinfo.buf, + .init_len = desc_value_bufinfo.len, + .p_value = desc_value_bufinfo.buf, .init_offs = 0, - .max_len = GATT_MAX_DATA_LENGTH, + .max_len = descriptor->max_length, }; err_code = sd_ble_gatts_descriptor_add(characteristic->handle, &desc_attr, &descriptor->handle); - } - } + + } // loop over descriptors + + } // loop over characteristics } diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index d09b6f5af..2d144f8b5 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -218,7 +218,9 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_ob // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. common_hal_bleio_characteristic_construct( - characteristic, uuid, props, SEC_MODE_OPEN, SEC_MODE_OPEN, mp_obj_new_list(0, NULL)); + characteristic, uuid, props, SEC_MODE_OPEN, SEC_MODE_OPEN, + GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc + mp_obj_new_list(0, NULL)); characteristic->handle = gattc_char->handle_value; characteristic->service = m_char_discovery_service; @@ -272,7 +274,8 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_ob // For now, just leave the UUID as NULL. } - common_hal_bleio_descriptor_construct(descriptor, uuid, SEC_MODE_OPEN, SEC_MODE_OPEN); + common_hal_bleio_descriptor_construct(descriptor, uuid, SEC_MODE_OPEN, SEC_MODE_OPEN, + GATT_MAX_DATA_LENGTH, false); descriptor->handle = gattc_desc->handle; descriptor->characteristic = m_desc_discovery_characteristic; diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 4adc897eb..7bcfc6b6d 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -42,7 +42,7 @@ //| and writing of the characteristic's value. //| //| -//| .. class:: Characteristic(uuid, *, properties=0, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, descriptors=None) +//| .. class:: Characteristic(uuid, *, properties=0, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, max_length=20, fixed_length=False, descriptors=None) //| //| Create a new Characteristic object identified by the specified UUID. //| @@ -55,15 +55,22 @@ //| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`. //| :param int write_perm: Specifies whether the characteristic can be written by a client, and if so, which //| security mode is required. Values allowed are the same as `read_perm`. +//| :param int max_length: Maximum length in bytes of the characteristic value. The maximum allowed is +//| is 512, or possibly 510 if `fixed_length` is False. The default, 20, is the maximum +//| number of data bytes that fit in a single BLE 4.x ATT packet. +//| :param bool fixed_length: True if the characteristic value is of fixed length. //| :param iterable descriptors: BLE descriptors for this characteristic. //| STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_uuid, ARG_properties, ARG_read_perm, ARG_write_perm, ARG_descriptors }; + enum { ARG_uuid, ARG_properties, ARG_read_perm, ARG_write_perm, + ARG_max_length, ARG_fixed_length, ARG_descriptors }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_properties, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 0 } }, - { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, - { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, + { MP_QSTR_properties, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN} }, + { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN} }, + { MP_QSTR_max_length, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 20} }, + { MP_QSTR_fixed_length, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_descriptors, MP_ARG_KW_ONLY| MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; @@ -110,13 +117,18 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t mp_raise_ValueError(translate("descriptors includes an object that is not a Descriptors")); } bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(descriptor_obj); - if (common_hal_bleio_descriptor_get_characteristic(descriptor) != mp_const_none) { + if (common_hal_bleio_descriptor_get_characteristic(descriptor) != MP_OBJ_NULL) { mp_raise_ValueError(translate("Descriptor is already attached to a Characteristic")); } mp_obj_list_append(desc_list_obj, descriptor_obj); } - common_hal_bleio_characteristic_construct(self, uuid, properties, read_perm, write_perm, desc_list); + // Range checking on max_length arg is done by the common_hal layer, because + // it may vary depending on underlying BLE implementation. + common_hal_bleio_characteristic_construct(self, uuid, properties, + read_perm, write_perm, + args[ARG_max_length].u_int, args[ARG_fixed_length].u_bool, + desc_list); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h index 1d532d748..87942c8e9 100644 --- a/shared-bindings/bleio/Characteristic.h +++ b/shared-bindings/bleio/Characteristic.h @@ -34,7 +34,7 @@ extern const mp_obj_type_t bleio_characteristic_type; -extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_obj_list_t *descriptor_list); +extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_obj_list_t *descriptor_list); extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self); extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self); diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index 1ab8c9ecd..2d4c8df9f 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -53,13 +53,19 @@ //| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`. //| :param int write_perm: Specifies whether the descriptor can be written by a client, and if so, which //| security mode is required. Values allowed are the same as `read_perm`. +//| :param int max_length: Maximum length in bytes of the characteristic value. The maximum allowed is +//| is 512, or possibly 510 if `fixed_length` is False. The default, 20, is the maximum +//| number of data bytes that fit in a single BLE 4.x ATT packet. +//| :param bool fixed_length: True if the characteristic value is of fixed length. //| STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_uuid, ARG_read_perm, ARG_write_perm }; + enum { ARG_uuid, ARG_read_perm, ARG_write_perm, ARG_max_length, ARG_fixed_length }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, + { MP_QSTR_max_length, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 20} }, + { MP_QSTR_fixed_length, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -81,7 +87,10 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar self->base.type = type; bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_arg); - common_hal_bleio_descriptor_construct(self, uuid, read_perm, write_perm); + // Range checking on max_length arg is done by the common_hal layer, because + // it may vary depending on underlying BLE implementation. + common_hal_bleio_descriptor_construct(self, uuid, read_perm, write_perm, + args[ARG_max_length].u_int, args[ARG_fixed_length].u_bool); return MP_OBJ_FROM_PTR(self); } @@ -123,9 +132,41 @@ const mp_obj_property_t bleio_descriptor_characteristic_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: value +//| +//| The value of this descriptor. +//| +STATIC mp_obj_t bleio_descriptor_get_value(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_descriptor_get_value(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_value_obj, bleio_descriptor_get_value); + +STATIC mp_obj_t bleio_descriptor_set_value(mp_obj_t self_in, mp_obj_t value_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ); + + common_hal_bleio_descriptor_set_value(self, &bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_descriptor_set_value_obj, bleio_descriptor_set_value); + +const mp_obj_property_t bleio_descriptor_value_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_descriptor_get_value_obj, + (mp_obj_t)&bleio_descriptor_set_value_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) }, + { MP_ROM_QSTR(MP_QSTR_characteristic), MP_ROM_PTR(&bleio_descriptor_characteristic_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_descriptor_value_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table); diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h index eefce03d1..430c0d0b6 100644 --- a/shared-bindings/bleio/Descriptor.h +++ b/shared-bindings/bleio/Descriptor.h @@ -34,8 +34,10 @@ 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, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm); +extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length); extern bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); -extern mp_obj_t common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self); +extern bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self); +extern mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self); +extern void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H -- cgit v1.2.3 From af29fc3ea8440445c9ae32eee1090c544bd848e9 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 15 Aug 2019 21:54:52 -0400 Subject: make translate and fix sphinx issues --- locale/ID.po | 72 ++++++++++++++++++++++++------ locale/circuitpython.pot | 72 ++++++++++++++++++++++++------ locale/de_DE.po | 72 ++++++++++++++++++++++++------ locale/en_US.po | 72 ++++++++++++++++++++++++------ locale/en_x_pirate.po | 72 ++++++++++++++++++++++++------ locale/es.po | 75 +++++++++++++++++++++++++------ locale/fil.po | 72 ++++++++++++++++++++++++------ locale/fr.po | 75 +++++++++++++++++++++++++------ locale/it_IT.po | 72 ++++++++++++++++++++++++------ locale/pl.po | 75 +++++++++++++++++++++++++------ locale/pt_BR.po | 72 ++++++++++++++++++++++++------ locale/zh_Latn_pinyin.po | 80 ++++++++++++++++++++++++++++------ shared-bindings/bleio/Attribute.c | 3 +- shared-bindings/bleio/Characteristic.c | 8 ++-- shared-bindings/bleio/Descriptor.c | 4 +- 15 files changed, 731 insertions(+), 165 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index e8fdf3595..438dca55f 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-05 17:52-0700\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -364,7 +364,7 @@ msgid "Can not use dotstar with %s" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -433,6 +433,10 @@ msgstr "" msgid "Characteristic already in use by another Service." msgstr "" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -508,6 +512,10 @@ msgstr "" msgid "Data too large for advertisement packet" msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "" @@ -602,7 +610,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy msgid "Failed to discover services" msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" @@ -622,17 +630,22 @@ msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, fuzzy, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" @@ -662,6 +675,11 @@ msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, fuzzy, c-format msgid "Failed to start scanning, err 0x%04x" @@ -677,12 +695,12 @@ msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" @@ -828,10 +846,18 @@ msgstr "Pin-pin tidak valid" msgid "Invalid polarity" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "" @@ -950,8 +976,9 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c #, fuzzy msgid "Not connected" msgstr "Tidak dapat menyambungkan ke AP" @@ -1289,6 +1316,19 @@ msgstr "" msgid "Unsupported pull value." msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "" @@ -1388,10 +1428,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "mode compile buruk" @@ -1709,6 +1745,10 @@ msgstr "" msgid "default 'except' must be last" msgstr "'except' standar harus terakhir" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2048,6 +2088,12 @@ msgstr "" msgid "math domain error" msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "" @@ -2147,8 +2193,8 @@ msgstr "" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a2e66cc5d..8cfbcfe85 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-05 17:52-0700\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -359,7 +359,7 @@ msgid "Can not use dotstar with %s" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -423,6 +423,10 @@ msgstr "" msgid "Characteristic already in use by another Service." msgstr "" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -497,6 +501,10 @@ msgstr "" msgid "Data too large for advertisement packet" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "" @@ -590,7 +598,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c msgid "Failed to discover services" msgstr "" @@ -607,17 +615,22 @@ msgstr "" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "" @@ -647,6 +660,11 @@ msgstr "" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, c-format msgid "Failed to start scanning, err 0x%04x" @@ -662,12 +680,12 @@ msgstr "" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "" @@ -813,10 +831,18 @@ msgstr "" msgid "Invalid polarity" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "" @@ -935,8 +961,9 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c msgid "Not connected" msgstr "" @@ -1265,6 +1292,19 @@ msgstr "" msgid "Unsupported pull value." msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "" @@ -1355,10 +1395,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1675,6 +1711,10 @@ msgstr "" msgid "default 'except' must be last" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2014,6 +2054,12 @@ msgstr "" msgid "math domain error" msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "" @@ -2112,8 +2158,8 @@ msgstr "" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c diff --git a/locale/de_DE.po b/locale/de_DE.po index 3037a5369..7551b1e6d 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-05 17:52-0700\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Pascal Deneaux\n" "Language-Team: Sebastian Plamauer, Pascal Deneaux\n" @@ -363,7 +363,7 @@ msgid "Can not use dotstar with %s" msgstr "Kann dotstar nicht mit %s verwenden" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -427,6 +427,10 @@ msgstr "Characteristic UUID stimmt nicht mit der Service-UUID überein" msgid "Characteristic already in use by another Service." msgstr "Characteristic wird bereits von einem anderen Dienst verwendet." +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "Schreiben von CharacteristicBuffer ist nicht vorgesehen" @@ -501,6 +505,10 @@ msgstr "" msgid "Data too large for advertisement packet" msgstr "Zu vielen Daten für das advertisement packet" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "Die Zielkapazität ist kleiner als destination_length." @@ -594,7 +602,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c msgid "Failed to discover services" msgstr "Es konnten keine Dienste gefunden werden" @@ -611,17 +619,22 @@ msgstr "Fehler beim Abrufen des Softdevice-Status" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Kann CCCD value nicht lesen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "gatts value konnte nicht gelesen werden. Status: 0x%04x" @@ -651,6 +664,11 @@ msgstr "Kann advertisement nicht starten. Status: 0x%04x" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, c-format msgid "Failed to start scanning, err 0x%04x" @@ -666,12 +684,12 @@ msgstr "Kann advertisement nicht stoppen. Status: 0x%04x" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "gatts value konnte nicht geschrieben werden. Status: 0x%04x" @@ -819,10 +837,18 @@ msgstr "Ungültige Pins" msgid "Invalid polarity" msgstr "Ungültige Polarität" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "Ungültiger Ausführungsmodus" +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "Ungültige Anzahl von Stimmen" @@ -948,8 +974,9 @@ msgstr "Kein Speicherplatz auf Gerät" msgid "No such file/directory" msgstr "Keine solche Datei/Verzeichnis" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c msgid "Not connected" msgstr "Nicht verbunden" @@ -1296,6 +1323,19 @@ msgstr "Nicht unterstützte Operation" msgid "Unsupported pull value." msgstr "Nicht unterstützter Pull-Wert" +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "Viper-Funktionen unterstützen derzeit nicht mehr als 4 Argumente" @@ -1395,10 +1435,6 @@ msgstr "Array/Bytes auf der rechten Seite erforderlich" msgid "attributes not supported yet" msgstr "Attribute werden noch nicht unterstützt" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1715,6 +1751,10 @@ msgstr "" msgid "default 'except' must be last" msgstr "Die Standart-Ausnahmebehandlung muss als letztes sein" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2061,6 +2101,12 @@ msgstr "map buffer zu klein" msgid "math domain error" msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "maximale Rekursionstiefe überschritten" @@ -2159,8 +2205,8 @@ msgstr "" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c diff --git a/locale/en_US.po b/locale/en_US.po index 6d15af4dd..fd176c869 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-05 17:52-0700\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -359,7 +359,7 @@ msgid "Can not use dotstar with %s" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -423,6 +423,10 @@ msgstr "" msgid "Characteristic already in use by another Service." msgstr "" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -497,6 +501,10 @@ msgstr "" msgid "Data too large for advertisement packet" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "" @@ -590,7 +598,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c msgid "Failed to discover services" msgstr "" @@ -607,17 +615,22 @@ msgstr "" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "" @@ -647,6 +660,11 @@ msgstr "" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, c-format msgid "Failed to start scanning, err 0x%04x" @@ -662,12 +680,12 @@ msgstr "" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "" @@ -813,10 +831,18 @@ msgstr "" msgid "Invalid polarity" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "" @@ -935,8 +961,9 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c msgid "Not connected" msgstr "" @@ -1265,6 +1292,19 @@ msgstr "" msgid "Unsupported pull value." msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "" @@ -1355,10 +1395,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1675,6 +1711,10 @@ msgstr "" msgid "default 'except' must be last" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2014,6 +2054,12 @@ msgstr "" msgid "math domain error" msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "" @@ -2112,8 +2158,8 @@ msgstr "" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index 57bb45380..f0aa99293 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-05 17:52-0700\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: @sommersoft, @MrCertainly\n" @@ -363,7 +363,7 @@ msgid "Can not use dotstar with %s" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -427,6 +427,10 @@ msgstr "" msgid "Characteristic already in use by another Service." msgstr "" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -501,6 +505,10 @@ msgstr "" msgid "Data too large for advertisement packet" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "" @@ -594,7 +602,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c msgid "Failed to discover services" msgstr "" @@ -611,17 +619,22 @@ msgstr "" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "" @@ -651,6 +664,11 @@ msgstr "" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, c-format msgid "Failed to start scanning, err 0x%04x" @@ -666,12 +684,12 @@ msgstr "" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "" @@ -817,10 +835,18 @@ msgstr "" msgid "Invalid polarity" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "" @@ -939,8 +965,9 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c msgid "Not connected" msgstr "" @@ -1269,6 +1296,19 @@ msgstr "" msgid "Unsupported pull value." msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "" @@ -1359,10 +1399,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1679,6 +1715,10 @@ msgstr "" msgid "default 'except' must be last" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2018,6 +2058,12 @@ msgstr "" msgid "math domain error" msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "" @@ -2116,8 +2162,8 @@ msgstr "" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c diff --git a/locale/es.po b/locale/es.po index a3ffe5799..c90be4e02 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-31 16:30-0500\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -367,7 +367,7 @@ msgid "Can not use dotstar with %s" msgstr "No se puede usar dotstar con %s" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -431,6 +431,10 @@ msgstr "Características UUID no concide con el Service UUID" msgid "Characteristic already in use by another Service." msgstr "Características ya esta en uso por otro Serivice" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "CharateristicBuffer escritura no proporcionada" @@ -505,6 +509,10 @@ msgstr "Trozo de datos debe seguir fmt chunk" msgid "Data too large for advertisement packet" msgstr "Data es muy grande para el paquete de advertisement." +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "Capacidad de destino es mas pequeña que destination_length." @@ -598,7 +606,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "No se puede iniciar el escaneo. err: 0x%02x" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy msgid "Failed to discover services" msgstr "No se puede descubrir servicios" @@ -616,17 +624,22 @@ msgstr "No se puede obtener el estado del softdevice" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "Error al notificar o indicar el valor del atributo, err 0x%04x" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "No se puede leer el valor del atributo. err 0x%02x" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "Error al leer valor del atributo, err 0x%04" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "No se puede escribir el valor del atributo. status: 0x%02x" @@ -656,6 +669,11 @@ msgstr "No se puede inicar el anuncio. err: 0x%04x" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, c-format msgid "Failed to start scanning, err 0x%04x" @@ -671,12 +689,12 @@ msgstr "No se puede detener el anuncio. err: 0x%04x" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "No se puede escribir el valor del atributo. err: 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "No se puede escribir el valor del atributo. err: 0x%04x" @@ -824,10 +842,18 @@ msgstr "pines inválidos" msgid "Invalid polarity" msgstr "Polaridad inválida" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "Modo de ejecución inválido." +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "Cuenta de voces inválida" @@ -950,8 +976,9 @@ msgstr "No queda espacio en el dispositivo" msgid "No such file/directory" msgstr "No existe el archivo/directorio" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c msgid "Not connected" msgstr "No conectado" @@ -1306,6 +1333,19 @@ msgstr "Operación no soportada" msgid "Unsupported pull value." msgstr "valor pull no soportado." +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "funciones Viper actualmente no soportan más de 4 argumentos." @@ -1404,10 +1444,6 @@ msgstr "array/bytes requeridos en el lado derecho" msgid "attributes not supported yet" msgstr "atributos aún no soportados" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "mal GATT role" - #: py/builtinevex.c msgid "bad compile mode" msgstr "modo de compilación erroneo" @@ -1729,6 +1765,10 @@ msgstr "números decimales no soportados" msgid "default 'except' must be last" msgstr "'except' por defecto deberia estar de último" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2073,6 +2113,12 @@ msgstr "map buffer muy pequeño" msgid "math domain error" msgstr "error de dominio matemático" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "profundidad máxima de recursión excedida" @@ -2171,8 +2217,8 @@ msgstr "no hay tal atributo" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2866,6 +2912,9 @@ msgstr "paso cero" #~ msgstr "" #~ "Usa esptool para borrar la flash y vuelve a cargar Python en su lugar" +#~ msgid "bad GATT role" +#~ msgstr "mal GATT role" + #~ msgid "buffer too long" #~ msgstr "buffer demasiado largo" diff --git a/locale/fil.po b/locale/fil.po index f83429882..d2535cc38 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-31 16:30-0500\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -366,7 +366,7 @@ msgid "Can not use dotstar with %s" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -431,6 +431,10 @@ msgstr "" msgid "Characteristic already in use by another Service." msgstr "" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -508,6 +512,10 @@ msgstr "Dapat sunurin ng Data chunk ang fmt chunk" msgid "Data too large for advertisement packet" msgstr "Hindi makasya ang data sa loob ng advertisement packet" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "" @@ -605,7 +613,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy msgid "Failed to discover services" msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX" @@ -625,17 +633,22 @@ msgstr "Nabigo sa pagkuha ng softdevice state, error: 0x%08lX" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, fuzzy, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "Hindi maisulat ang gatts value, status: 0x%08lX" @@ -665,6 +678,11 @@ msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, fuzzy, c-format msgid "Failed to start scanning, err 0x%04x" @@ -680,12 +698,12 @@ msgstr "Hindi mahinto ang advertisement, status: 0x%08lX" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Hindi maisulat ang attribute value, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "Hindi maisulat ang gatts value, status: 0x%08lX" @@ -833,10 +851,18 @@ msgstr "Mali ang pins" msgid "Invalid polarity" msgstr "Mali ang polarity" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "Mali ang run mode." +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "Maling bilang ng voice" @@ -959,8 +985,9 @@ msgstr "" msgid "No such file/directory" msgstr "Walang file/directory" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c #, fuzzy msgid "Not connected" msgstr "Hindi maka connect sa AP" @@ -1310,6 +1337,19 @@ msgstr "Hindi sinusuportahang operasyon" msgid "Unsupported pull value." msgstr "Hindi suportado ang pull value." +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "" @@ -1408,10 +1448,6 @@ msgstr "array/bytes kinakailangan sa kanang bahagi" msgid "attributes not supported yet" msgstr "attributes hindi sinusuportahan" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "masamang mode ng compile" @@ -1735,6 +1771,10 @@ msgstr "decimal numbers hindi sinusuportahan" msgid "default 'except' must be last" msgstr "default 'except' ay dapat sa huli" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2084,6 +2124,12 @@ msgstr "masyadong maliit ang buffer map" msgid "math domain error" msgstr "may pagkakamali sa math domain" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "lumagpas ang maximum recursion depth" @@ -2183,8 +2229,8 @@ msgstr "walang ganoon na attribute" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c diff --git a/locale/fr.po b/locale/fr.po index 07355526f..999d8c4f0 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-31 16:30-0500\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2019-04-14 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -371,7 +371,7 @@ msgid "Can not use dotstar with %s" msgstr "Impossible d'utiliser 'dotstar' avec %s" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -437,6 +437,10 @@ msgstr "L'UUID de 'Characteristic' ne correspond pas à l'UUID du Service" msgid "Characteristic already in use by another Service." msgstr "'Characteristic' déjà en utilisation par un autre service" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "Ecriture sur 'CharacteristicBuffer' non fournie" @@ -513,6 +517,10 @@ msgstr "Un bloc de données doit suivre un bloc de format" msgid "Data too large for advertisement packet" msgstr "Données trop volumineuses pour un paquet de diffusion" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "La capacité de destination est plus petite que 'destination_length'." @@ -609,7 +617,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "Impossible de poursuivre le scan, err 0x%04x" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy msgid "Failed to discover services" msgstr "Echec de la découverte de services" @@ -630,17 +638,22 @@ msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "" "Impossible de notifier ou d'indiquer la valeur de l'attribut, err 0x%04x" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, fuzzy, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Impossible de lire la valeur 'CCCD', err 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "Impossible de lire la valeur de l'attribut, err 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "Impossible de lire la valeur de 'gatts', err 0x%04x" @@ -670,6 +683,11 @@ msgstr "Impossible de commencer à diffuser, err 0x%04x" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, fuzzy, c-format msgid "Failed to start scanning, err 0x%04x" @@ -685,12 +703,12 @@ msgstr "Echec de l'arrêt de diffusion, err 0x%04x" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Impossible d'écrire la valeur de l'attribut, err 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "Impossible d'écrire la valeur de 'gatts', err 0x%04x" @@ -841,10 +859,18 @@ msgstr "Broches invalides" msgid "Invalid polarity" msgstr "Polarité invalide" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "Mode de lancement invalide." +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c #, fuzzy msgid "Invalid voice count" @@ -968,8 +994,9 @@ msgstr "Il n'y a plus d'espace libre sur le périphérique" msgid "No such file/directory" msgstr "Fichier/dossier introuvable" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c #, fuzzy msgid "Not connected" msgstr "Non connecté" @@ -1335,6 +1362,19 @@ msgstr "Opération non supportée" msgid "Unsupported pull value." msgstr "Valeur de tirage 'pull' non supportée." +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "" @@ -1433,10 +1473,6 @@ msgstr "tableau/octets requis à droite" msgid "attributes not supported yet" msgstr "attribut pas encore supporté" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "mauvais rôle GATT" - #: py/builtinevex.c msgid "bad compile mode" msgstr "mauvais mode de compilation" @@ -1771,6 +1807,10 @@ msgstr "nombres décimaux non supportés" msgid "default 'except' must be last" msgstr "l''except' par défaut doit être en dernier" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2117,6 +2157,12 @@ msgstr "tampon trop petit" msgid "math domain error" msgstr "erreur de domaine math" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "profondeur maximale de récursivité dépassée" @@ -2217,8 +2263,8 @@ msgstr "pas de tel attribut" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2917,6 +2963,9 @@ msgstr "'step' nul" #~ msgstr "" #~ "Utilisez 'esptool' pour effacer la flash et recharger Python à la place" +#~ msgid "bad GATT role" +#~ msgstr "mauvais rôle GATT" + #~ msgid "buffer too long" #~ msgstr "tampon trop long" diff --git a/locale/it_IT.po b/locale/it_IT.po index 4360cd221..411c9125a 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-31 16:30-0500\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -366,7 +366,7 @@ msgid "Can not use dotstar with %s" msgstr "dotstar non può essere usato con %s" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -432,6 +432,10 @@ msgstr "caratteristico UUID non assomiglia servizio UUID" msgid "Characteristic already in use by another Service." msgstr "caratteristico già usato da un altro servizio" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "CharacteristicBuffer scritura non dato" @@ -509,6 +513,10 @@ msgstr "" msgid "Data too large for advertisement packet" msgstr "Impossibile inserire dati nel pacchetto di advertisement." +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "La capacità di destinazione è più piccola di destination_length." @@ -605,7 +613,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "Impossible iniziare la scansione. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy msgid "Failed to discover services" msgstr "Impossibile fermare advertisement. status: 0x%02x" @@ -624,17 +632,22 @@ msgstr "Impossibile fermare advertisement. status: 0x%02x" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "Notificamento o indicazione di attribute value fallito, err 0x%04x" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, fuzzy, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "Tentative leggere attribute value fallito, err 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" @@ -664,6 +677,11 @@ msgstr "Impossibile avviare advertisement. status: 0x%02x" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, fuzzy, c-format msgid "Failed to start scanning, err 0x%04x" @@ -679,12 +697,12 @@ msgstr "Impossibile fermare advertisement. status: 0x%02x" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" @@ -834,10 +852,18 @@ msgstr "Pin non validi" msgid "Invalid polarity" msgstr "Polarità non valida" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "Modalità di esecuzione non valida." +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c #, fuzzy msgid "Invalid voice count" @@ -958,8 +984,9 @@ msgstr "Non che spazio sul dispositivo" msgid "No such file/directory" msgstr "Nessun file/directory esistente" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c #, fuzzy msgid "Not connected" msgstr "Impossible connettersi all'AP" @@ -1309,6 +1336,19 @@ msgstr "Operazione non supportata" msgid "Unsupported pull value." msgstr "Valore di pull non supportato." +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "Le funzioni Viper non supportano più di 4 argomenti al momento" @@ -1402,10 +1442,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "attributi non ancora supportati" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1728,6 +1764,10 @@ msgstr "numeri decimali non supportati" msgid "default 'except' must be last" msgstr "'except' predefinito deve essere ultimo" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2077,6 +2117,12 @@ msgstr "map buffer troppo piccolo" msgid "math domain error" msgstr "errore di dominio matematico" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "profondità massima di ricorsione superata" @@ -2177,8 +2223,8 @@ msgstr "attributo inesistente" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c diff --git a/locale/pl.po b/locale/pl.po index 0a38aa914..caa5df76d 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-05 17:52-0700\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski \n" "Language-Team: pl\n" @@ -362,7 +362,7 @@ msgid "Can not use dotstar with %s" msgstr "Nie można używać dotstar z %s" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -426,6 +426,10 @@ msgstr "UUID charakterystyki inny niż UUID serwisu" msgid "Characteristic already in use by another Service." msgstr "Charakterystyka w użyciu w innym serwisie" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "Pisanie do CharacteristicBuffer niewspierane" @@ -500,6 +504,10 @@ msgstr "Fragment danych musi następować po fragmencie fmt" msgid "Data too large for advertisement packet" msgstr "Zbyt dużo danych pakietu rozgłoszeniowego" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "Pojemność celu mniejsza od destination_length." @@ -593,7 +601,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "Nie udała się kontynuacja skanowania, błąd 0x%04x" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c msgid "Failed to discover services" msgstr "Nie udało się odkryć serwisów" @@ -610,17 +618,22 @@ msgstr "Nie udało się odczytać stanu softdevice" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "Nie udało się powiadomić o wartości atrybutu, błąd 0x%04x" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Nie udało się odczytać CCCD, błąd 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "Nie udało się odczytać wartości atrybutu, błąd 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "Nie udało się odczytać gatts, błąd 0x%04x" @@ -650,6 +663,11 @@ msgstr "Nie udało się rozpocząć rozgłaszania, błąd 0x%04x" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, c-format msgid "Failed to start scanning, err 0x%04x" @@ -665,12 +683,12 @@ msgstr "Nie udało się zatrzymać rozgłaszania, błąd 0x%04x" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Nie udało się zapisać atrybutu, błąd 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "Nie udało się zapisać gatts, błąd 0x%04x" @@ -818,10 +836,18 @@ msgstr "Złe nóżki" msgid "Invalid polarity" msgstr "Zła polaryzacja" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "Zły tryb uruchomienia" +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "Zła liczba głosów" @@ -945,8 +971,9 @@ msgstr "Brak miejsca" msgid "No such file/directory" msgstr "Brak pliku/katalogu" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c msgid "Not connected" msgstr "Nie podłączono" @@ -1285,6 +1312,19 @@ msgstr "Zła operacja" msgid "Unsupported pull value." msgstr "Zła wartość podciągnięcia." +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "Funkcje Viper nie obsługują obecnie więcej niż 4 argumentów" @@ -1379,10 +1419,6 @@ msgstr "tablica/bytes wymagane po prawej stronie" msgid "attributes not supported yet" msgstr "atrybuty nie są jeszcze obsługiwane" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "zła rola GATT" - #: py/builtinevex.c msgid "bad compile mode" msgstr "zły tryb kompilacji" @@ -1699,6 +1735,10 @@ msgstr "liczby dziesiętne nieobsługiwane" msgid "default 'except' must be last" msgstr "domyślny 'except' musi być ostatni" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2039,6 +2079,12 @@ msgstr "bufor mapy zbyt mały" msgid "math domain error" msgstr "błąd domeny" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "przekroczono dozwoloną głębokość rekurencji" @@ -2137,8 +2183,8 @@ msgstr "nie ma takiego atrybutu" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2708,6 +2754,9 @@ msgstr "zerowy krok" #~ msgid "UUID integer value not in range 0 to 0xffff" #~ msgstr "Wartość UUID poza zakresem 0 do 0xffff" +#~ msgid "bad GATT role" +#~ msgstr "zła rola GATT" + #~ msgid "interval not in range 0.0020 to 10.24" #~ msgstr "przedział poza zakresem 0.0020 do 10.24" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index defeb3e44..79a83d2f6 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-31 16:30-0500\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -363,7 +363,7 @@ msgid "Can not use dotstar with %s" msgstr "" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c @@ -428,6 +428,10 @@ msgstr "" msgid "Characteristic already in use by another Service." msgstr "" +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -504,6 +508,10 @@ msgstr "Pedaço de dados deve seguir o pedaço de cortes" msgid "Data too large for advertisement packet" msgstr "Não é possível ajustar dados no pacote de anúncios." +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "" @@ -600,7 +608,7 @@ msgstr "" msgid "Failed to continue scanning, err 0x%04x" msgstr "Não é possível iniciar o anúncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy msgid "Failed to discover services" msgstr "Não pode parar propaganda. status: 0x%02x" @@ -619,17 +627,22 @@ msgstr "Não pode parar propaganda. status: 0x%02x" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, fuzzy, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Não é possível ler o valor do atributo. status: 0x%02x" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" @@ -659,6 +672,11 @@ msgstr "Não é possível iniciar o anúncio. status: 0x%02x" msgid "Failed to start connecting, error 0x%04x" msgstr "" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, fuzzy, c-format msgid "Failed to start scanning, err 0x%04x" @@ -674,12 +692,12 @@ msgstr "Não pode parar propaganda. status: 0x%02x" msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, fuzzy, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" @@ -827,10 +845,18 @@ msgstr "Pinos inválidos" msgid "Invalid polarity" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c #, fuzzy msgid "Invalid voice count" @@ -950,8 +976,9 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c #, fuzzy msgid "Not connected" msgstr "Não é possível conectar-se ao AP" @@ -1286,6 +1313,19 @@ msgstr "" msgid "Unsupported pull value." msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "" @@ -1376,10 +1416,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "atributos ainda não suportados" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1699,6 +1735,10 @@ msgstr "" msgid "default 'except' must be last" msgstr "" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2039,6 +2079,12 @@ msgstr "" msgid "math domain error" msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "" @@ -2138,8 +2184,8 @@ msgstr "" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index c0537202c..a42f8bae4 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-05 17:52-0700\n" +"POT-Creation-Date: 2019-08-15 21:44-0400\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -363,8 +363,8 @@ msgid "Can not use dotstar with %s" msgstr "Wúfǎ yǔ dotstar yīqǐ shǐyòng %s" #: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" -msgstr "Wúfǎ wéi běndì tèzhēng shèzhì CCCD" +msgid "Can't set CCCD on local Characteristic" +msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c msgid "Cannot delete values" @@ -427,6 +427,10 @@ msgstr "Zìfú UUID bù fúhé fúwù UUID" msgid "Characteristic already in use by another Service." msgstr "Qítā fúwù bùmén yǐ shǐyòng de gōngnéng." +#: shared-bindings/bleio/Service.c +msgid "Characteristic is already attached to a Service" +msgstr "" + #: shared-bindings/bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "Wèi tígōng zìfú huǎncún xiě rù" @@ -501,6 +505,10 @@ msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài" msgid "Data too large for advertisement packet" msgstr "Guǎnggào bāo de shùjù tài dà" +#: shared-bindings/bleio/Characteristic.c +msgid "Descriptor is already attached to a Characteristic" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." msgstr "Mùbiāo róngliàng xiǎoyú mùdì de_chángdù." @@ -594,7 +602,7 @@ msgstr "Liánjiē shībài: Chāoshí" msgid "Failed to continue scanning, err 0x%04x" msgstr "Jìxù sǎomiáo shībài, err 0x%04x" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/bleio/__init__.c msgid "Failed to discover services" msgstr "Fāxiàn fúwù shībài" @@ -611,17 +619,22 @@ msgstr "Wúfǎ huòdé ruǎnjiàn shèbèi zhuàngtài" msgid "Failed to notify or indicate attribute value, err 0x%04x" msgstr "Wúfǎ tōngzhī huò xiǎnshì shǔxìng zhí, err 0x%04x" +#: ports/nrf/common-hal/bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + #: ports/nrf/common-hal/bleio/Characteristic.c #, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Dòu qǔ CCCD zhí, err 0x%04x shībài" #: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c #, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "Dòu qǔ shǔxìng zhí shībài, err 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "Wúfǎ dòu qǔ gatts zhí, err 0x%04x" @@ -651,6 +664,11 @@ msgstr "Qǐdòng guǎnggào shībài, err 0x%04x" msgid "Failed to start connecting, error 0x%04x" msgstr "Wúfǎ kāishǐ liánjiē, cuòwù 0x%04x" +#: ports/nrf/common-hal/bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + #: ports/nrf/common-hal/bleio/Scanner.c #, c-format msgid "Failed to start scanning, err 0x%04x" @@ -666,12 +684,12 @@ msgstr "Wúfǎ tíngzhǐ guǎnggào, err 0x%04x" msgid "Failed to write CCCD, err 0x%04x" msgstr "Wúfǎ xiě rù CCCD, cuòwù 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Xiě rù shǔxìng zhí shībài, err 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "Xiě rù gatts zhí,err 0x%04x shībài" @@ -819,10 +837,18 @@ msgstr "Wúxiào de yǐn jiǎo" msgid "Invalid polarity" msgstr "Wúxiào liǎng jí zhí" +#: shared-bindings/bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "Wúxiào de yùnxíng móshì." +#: shared-module/bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + #: shared-bindings/audiocore/Mixer.c msgid "Invalid voice count" msgstr "Wúxiào de yǔyīn jìshù" @@ -945,8 +971,9 @@ msgstr "Shèbèi shàng méiyǒu kònggé" msgid "No such file/directory" msgstr "Méiyǒu cǐ lèi wénjiàn/mùlù" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c #: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/bleio/Peripheral.c msgid "Not connected" msgstr "Wèi liánjiē" @@ -1292,6 +1319,19 @@ msgstr "Bù zhīchí de cāozuò" msgid "Unsupported pull value." msgstr "Bù zhīchí de lādòng zhí." +#: ports/nrf/common-hal/bleio/Characteristic.c +msgid "Value length required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" msgstr "Viper hánshù mùqián bù zhīchí chāoguò 4 gè cānshù" @@ -1389,10 +1429,6 @@ msgstr "yòu cè xūyào shùzǔ/zì jié" msgid "attributes not supported yet" msgstr "shǔxìng shàngwèi zhīchí" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "zǒng xiédìng de bùliáng juésè" - #: py/builtinevex.c msgid "bad compile mode" msgstr "biānyì móshì cuòwù" @@ -1711,6 +1747,10 @@ msgstr "bù zhīchí xiǎoshù shù" msgid "default 'except' must be last" msgstr "mòrèn 'except' bìxū shì zuìhòu yīgè" +#: shared-bindings/bleio/Characteristic.c +msgid "descriptors includes an object that is not a Descriptors" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" @@ -2052,6 +2092,12 @@ msgstr "dìtú huǎnchōng qū tài xiǎo" msgid "math domain error" msgstr "shùxué yù cuòwù" +#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "chāochū zuìdà dìguī shēndù" @@ -2151,8 +2197,8 @@ msgstr "méiyǒu cǐ shǔxìng" msgid "non-Service found in services" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2674,6 +2720,9 @@ msgstr "líng bù" #~ msgid "Can't connect in Peripheral mode" #~ msgstr "Wúfǎ zài biānyuán móshì zhōng liánjiē" +#~ msgid "Can't set CCCD for local Characteristic" +#~ msgstr "Wúfǎ wéi běndì tèzhēng shèzhì CCCD" + #~ msgid "Data too large for the advertisement packet" #~ msgstr "Guǎnggào bāo de shùjù tài dà" @@ -2734,6 +2783,9 @@ msgstr "líng bù" #~ msgid "UUID integer value not in range 0 to 0xffff" #~ msgstr "UUID zhěngshù zhí bùzài fànwéi 0 zhì 0xffff" +#~ msgid "bad GATT role" +#~ msgstr "zǒng xiédìng de bùliáng juésè" + #~ msgid "expected a DigitalInOut" #~ msgstr "qídài de DigitalInOut" diff --git a/shared-bindings/bleio/Attribute.c b/shared-bindings/bleio/Attribute.c index ef6b17253..cbbc07b9e 100644 --- a/shared-bindings/bleio/Attribute.c +++ b/shared-bindings/bleio/Attribute.c @@ -37,7 +37,8 @@ //| ========================================================= //| //| Definitions associated with all BLE attributes: characteristics, descriptors, etc. -//| :py:class:`~bleio.Attribute` is, notionally, a superclass of `Characteristic` and `Descriptor`, +//| :py:class:`~bleio.Attribute` is, notionally, a superclass of +//| :py:class:`~Characteristic` and :py:class:`~Descriptor`, //| but is not defined as a Python superclass of those classes. //| //| .. class:: Attribute() diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 7bcfc6b6d..c9e0f3757 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -54,9 +54,9 @@ //| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`, //| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`. //| :param int write_perm: Specifies whether the characteristic can be written by a client, and if so, which -//| security mode is required. Values allowed are the same as `read_perm`. +//| security mode is required. Values allowed are the same as ``read_perm``. //| :param int max_length: Maximum length in bytes of the characteristic value. The maximum allowed is -//| is 512, or possibly 510 if `fixed_length` is False. The default, 20, is the maximum +//| is 512, or possibly 510 if ``fixed_length`` is False. The default, 20, is the maximum //| number of data bytes that fit in a single BLE 4.x ATT packet. //| :param bool fixed_length: True if the characteristic value is of fixed length. //| :param iterable descriptors: BLE descriptors for this characteristic. @@ -173,9 +173,7 @@ const mp_obj_property_t bleio_characteristic_uuid_obj = { //| .. attribute:: value //| -//| The value of this characteristic. The value can be written to if the `write` property allows it. -//| If the `read` property allows it, the value can be read. If the `notify` property is set, writing -//| to the value will generate a BLE notification. +//| The value of this characteristic. //| STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index 2d4c8df9f..95477336e 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -52,9 +52,9 @@ //| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`, //| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`. //| :param int write_perm: Specifies whether the descriptor can be written by a client, and if so, which -//| security mode is required. Values allowed are the same as `read_perm`. +//| security mode is required. Values allowed are the same as ``read_perm``. //| :param int max_length: Maximum length in bytes of the characteristic value. The maximum allowed is -//| is 512, or possibly 510 if `fixed_length` is False. The default, 20, is the maximum +//| is 512, or possibly 510 if ``fixed_length`` is False. The default, 20, is the maximum //| number of data bytes that fit in a single BLE 4.x ATT packet. //| :param bool fixed_length: True if the characteristic value is of fixed length. //| -- cgit v1.2.3 From 49d8ea648dad6bc202f0cae27ab58760535de3d0 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 16 Aug 2019 07:29:52 -0500 Subject: update tinyusb This fixes a problem with USB MIDI messages 0xc and 0xd and Closes: #2057 --- lib/tinyusb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tinyusb b/lib/tinyusb index 1ee9ef4f2..96d96a94b 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 1ee9ef4f2b7c6acfab6c398a4f57ca22036958f7 +Subproject commit 96d96a94b887bc1b648a175c28b377dba76a9068 -- cgit v1.2.3 From 630c92392abef67b0e6f81c98316dea93d3b2376 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 16 Aug 2019 15:18:53 -0400 Subject: address review comments; avoid calling common_hal_bleio_device... routines from shared-bindings --- ports/nrf/common-hal/bleio/Attribute.c | 14 +++++----- ports/nrf/common-hal/bleio/Central.c | 11 +++++++- ports/nrf/common-hal/bleio/Peripheral.c | 11 +++++--- ports/nrf/common-hal/bleio/__init__.c | 4 +-- shared-bindings/bleio/Attribute.c | 14 +++++----- shared-bindings/bleio/Central.c | 45 ++++++++------------------------- shared-bindings/bleio/Central.h | 3 ++- shared-bindings/bleio/Characteristic.c | 4 +-- shared-bindings/bleio/Descriptor.c | 4 +-- shared-bindings/bleio/Peripheral.c | 41 ++++++------------------------ shared-bindings/bleio/Peripheral.h | 3 ++- shared-bindings/bleio/__init__.c | 3 --- shared-module/bleio/Attribute.c | 14 +++++----- shared-module/bleio/Attribute.h | 14 +++++----- 14 files changed, 74 insertions(+), 111 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Attribute.c b/ports/nrf/common-hal/bleio/Attribute.c index bffe68254..fd1e7538d 100644 --- a/ports/nrf/common-hal/bleio/Attribute.c +++ b/ports/nrf/common-hal/bleio/Attribute.c @@ -29,31 +29,31 @@ // Convert a bleio security mode to a ble_gap_conn_sec_mode_t setting. void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) { switch (security_mode) { - case SEC_MODE_NO_ACCESS: + case SECURITY_MODE_NO_ACCESS: BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(perm); break; - case SEC_MODE_OPEN: + case SECURITY_MODE_OPEN: BLE_GAP_CONN_SEC_MODE_SET_OPEN(perm); break; - case SEC_MODE_ENC_NO_MITM: + case SECURITY_MODE_ENC_NO_MITM: BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(perm); break; - case SEC_MODE_ENC_WITH_MITM: + case SECURITY_MODE_ENC_WITH_MITM: BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(perm); break; - case SEC_MODE_LESC_ENC_WITH_MITM: + case SECURITY_MODE_LESC_ENC_WITH_MITM: BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(perm); break; - case SEC_MODE_SIGNED_NO_MITM: + case SECURITY_MODE_SIGNED_NO_MITM: BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(perm); break; - case SEC_MODE_SIGNED_WITH_MITM: + case SECURITY_MODE_SIGNED_WITH_MITM: BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(perm); break; } diff --git a/ports/nrf/common-hal/bleio/Central.c b/ports/nrf/common-hal/bleio/Central.c index c42a2084a..d771437d6 100644 --- a/ports/nrf/common-hal/bleio/Central.c +++ b/ports/nrf/common-hal/bleio/Central.c @@ -34,9 +34,9 @@ #include "nrf_soc.h" #include "py/objstr.h" #include "py/runtime.h" +#include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Central.h" -#include "common-hal/bleio/__init__.h" STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) { bleio_central_obj_t *central = (bleio_central_obj_t*)central_in; @@ -131,6 +131,15 @@ bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) { return self->conn_handle != BLE_CONN_HANDLE_INVALID; } +mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist) { + common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist); + // Convert to a tuple and then clear the list so the callee will take ownership. + mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_services_list->len, + self->remote_services_list->items); + mp_obj_list_clear(self->remote_services_list); + return services_tuple; +} + mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) { return self->remote_services_list; } diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index 640b93180..ed35516fc 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -36,12 +36,12 @@ #include "py/objlist.h" #include "py/objstr.h" #include "py/runtime.h" +#include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Peripheral.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" -#include "common-hal/bleio/Service.h" #define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) #define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) @@ -303,8 +303,13 @@ void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *self) { sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); } -mp_obj_list_t *common_hal_bleio_peripheral_get_remote_services(bleio_peripheral_obj_t *self) { - return self->remote_services_list; +mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist) { + common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist); + // Convert to a tuple and then clear the list so the callee will take ownership. + mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_services_list->len, + self->remote_services_list->items); + mp_obj_list_clear(self->remote_services_list); + return services_tuple; } void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *self) { diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index 2d144f8b5..2e26ac07d 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -218,7 +218,7 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_ob // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. common_hal_bleio_characteristic_construct( - characteristic, uuid, props, SEC_MODE_OPEN, SEC_MODE_OPEN, + characteristic, uuid, props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc mp_obj_new_list(0, NULL)); characteristic->handle = gattc_char->handle_value; @@ -274,7 +274,7 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_ob // For now, just leave the UUID as NULL. } - common_hal_bleio_descriptor_construct(descriptor, uuid, SEC_MODE_OPEN, SEC_MODE_OPEN, + common_hal_bleio_descriptor_construct(descriptor, uuid, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, GATT_MAX_DATA_LENGTH, false); descriptor->handle = gattc_desc->handle; descriptor->characteristic = m_desc_discovery_characteristic; diff --git a/shared-bindings/bleio/Attribute.c b/shared-bindings/bleio/Attribute.c index cbbc07b9e..2cc9ef6d0 100644 --- a/shared-bindings/bleio/Attribute.c +++ b/shared-bindings/bleio/Attribute.c @@ -76,13 +76,13 @@ STATIC const mp_rom_map_elem_t bleio_attribute_locals_dict_table[] = { //| //| security_mode: authenticated data signing, without man-in-the-middle protection //| - { MP_ROM_QSTR(MP_QSTR_NO_ACCESS), MP_ROM_INT(SEC_MODE_NO_ACCESS) }, - { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(SEC_MODE_OPEN) }, - { MP_ROM_QSTR(MP_QSTR_ENCRYPT_NO_MITM), MP_ROM_INT(SEC_MODE_ENC_NO_MITM) }, - { MP_ROM_QSTR(MP_QSTR_ENCRYPT_WITH_MITM), MP_ROM_INT(SEC_MODE_ENC_WITH_MITM) }, - { MP_ROM_QSTR(MP_QSTR_LESC_ENCRYPT_WITH_MITM), MP_ROM_INT(SEC_MODE_LESC_ENC_WITH_MITM) }, - { MP_ROM_QSTR(MP_QSTR_SIGNED_NO_MITM), MP_ROM_INT(SEC_MODE_SIGNED_NO_MITM) }, - { MP_ROM_QSTR(MP_QSTR_SIGNED_WITH_MITM), MP_ROM_INT(SEC_MODE_SIGNED_WITH_MITM) }, + { MP_ROM_QSTR(MP_QSTR_NO_ACCESS), MP_ROM_INT(SECURITY_MODE_NO_ACCESS) }, + { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(SECURITY_MODE_OPEN) }, + { MP_ROM_QSTR(MP_QSTR_ENCRYPT_NO_MITM), MP_ROM_INT(SECURITY_MODE_ENC_NO_MITM) }, + { MP_ROM_QSTR(MP_QSTR_ENCRYPT_WITH_MITM), MP_ROM_INT(SECURITY_MODE_ENC_WITH_MITM) }, + { MP_ROM_QSTR(MP_QSTR_LESC_ENCRYPT_WITH_MITM), MP_ROM_INT(SECURITY_MODE_LESC_ENC_WITH_MITM) }, + { MP_ROM_QSTR(MP_QSTR_SIGNED_NO_MITM), MP_ROM_INT(SECURITY_MODE_SIGNED_NO_MITM) }, + { MP_ROM_QSTR(MP_QSTR_SIGNED_WITH_MITM), MP_ROM_INT(SECURITY_MODE_SIGNED_WITH_MITM) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_attribute_locals_dict, bleio_attribute_locals_dict_table); diff --git a/shared-bindings/bleio/Central.c b/shared-bindings/bleio/Central.c index 70b270c65..1fc455d8d 100644 --- a/shared-bindings/bleio/Central.c +++ b/shared-bindings/bleio/Central.c @@ -34,7 +34,6 @@ #include "py/objproperty.h" #include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/Characteristic.h" @@ -66,7 +65,7 @@ //| //| central = bleio.Central() //| central.connect(my_entry.address, 10) # timeout after 10 seconds -//| central.discover_remote_services() +//| remote_services = central.discover_remote_services() //| //| .. class:: Central() @@ -132,15 +131,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_dis //| .. method:: discover_remote_services(service_uuids_whitelist=None) //| Do BLE discovery for all services or for the given service UUIDS, -//| to find their handles and characteristics. -//| The attribute `remote_services` will contain a list of all discovered services. -//| `Central.connected` must be True. +//| to find their handles and characteristics, and return the discovered services. +//| `Peripheral.connected` must be True. //| //| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services //| provided by the peripheral that you want to use. -//| The peripheral may provide more services, but services not listed are ignored. -//| If a service in service_uuids_whitelist is not found during discovery, it will not -//| appear in `remote_services`. +//| The peripheral may provide more services, but services not listed are ignored +//| and will not be returned. //| //| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow. //| @@ -149,6 +146,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_dis //| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered //| for use. (This restriction may be lifted in the future.) //| +//| :return: A tuple of services provided by the remote peripheral. +//| STATIC mp_obj_t bleio_central_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -164,10 +163,9 @@ STATIC mp_obj_t bleio_central_discover_remote_services(mp_uint_t n_args, const m mp_raise_ValueError(translate("Not connected")); } - common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), - args[ARG_service_uuids_whitelist].u_obj); - - return mp_const_none; + return MP_OBJ_FROM_PTR(common_hal_bleio_central_discover_remote_services( + MP_OBJ_FROM_PTR(self), + args[ARG_service_uuids_whitelist].u_obj)); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_discover_remote_services_obj, 1, bleio_central_discover_remote_services); @@ -189,28 +187,6 @@ const mp_obj_property_t bleio_central_connected_obj = { (mp_obj_t)&mp_const_none_obj }, }; - -//| .. attribute:: remote_services (read-only) -//| -//| A tuple of services provided by the remote peripheral. -//| If the Central is not connected, an empty tuple will be returned. -//| -STATIC mp_obj_t bleio_central_get_remote_services(mp_obj_t self_in) { - bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // Return list as a tuple so user won't be able to change it. - mp_obj_list_t *service_list = common_hal_bleio_central_get_remote_services(self); - return mp_obj_new_tuple(service_list->len, service_list->items); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_remote_services_obj, bleio_central_get_remote_services); - -const mp_obj_property_t bleio_central_remote_services_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_central_get_remote_services_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) }, @@ -219,7 +195,6 @@ STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_central_connected_obj) }, - { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_central_remote_services_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table); diff --git a/shared-bindings/bleio/Central.h b/shared-bindings/bleio/Central.h index 1d7fb6248..cbc437087 100644 --- a/shared-bindings/bleio/Central.h +++ b/shared-bindings/bleio/Central.h @@ -28,6 +28,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H +#include "py/objtuple.h" #include "common-hal/bleio/Central.h" #include "common-hal/bleio/Service.h" @@ -37,6 +38,6 @@ extern void common_hal_bleio_central_construct(bleio_central_obj_t *self); extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout); extern void common_hal_bleio_central_disconnect(bleio_central_obj_t *self); extern bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self); -extern mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self); +extern mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index c9e0f3757..4894ad114 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -67,8 +67,8 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_properties, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN} }, - { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN} }, + { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN} }, + { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN} }, { MP_QSTR_max_length, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 20} }, { MP_QSTR_fixed_length, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_descriptors, MP_ARG_KW_ONLY| MP_ARG_OBJ, {.u_obj = mp_const_none} }, diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index 95477336e..d7c2a85c7 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -62,8 +62,8 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar enum { ARG_uuid, ARG_read_perm, ARG_write_perm, ARG_max_length, ARG_fixed_length }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, - { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SEC_MODE_OPEN } }, + { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN } }, + { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN } }, { MP_QSTR_max_length, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 20} }, { MP_QSTR_fixed_length, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, }; diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c index b42ca3784..630e6ed36 100644 --- a/shared-bindings/bleio/Peripheral.c +++ b/shared-bindings/bleio/Peripheral.c @@ -35,7 +35,6 @@ #include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Peripheral.h" @@ -263,15 +262,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_disconnect_obj, bleio_peripher //| .. method:: discover_remote_services(service_uuids_whitelist=None) //| Do BLE discovery for all services or for the given service UUIDS, -//| to find their handles and characteristics. -//| The attribute `remote_services` will contain a list of all discovered services. +//| to find their handles and characteristics, and return the discovered services. //| `Peripheral.connected` must be True. //| //| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services //| provided by the peripheral that you want to use. -//| The peripheral may provide more services, but services not listed are ignored. -//| If a service in service_uuids_whitelist is not found during discovery, it will not -//| appear in `remote_services`. +//| The peripheral may provide more services, but services not listed are ignored +//| and will not be returned. //| //| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow. //| @@ -285,6 +282,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_disconnect_obj, bleio_peripher //| Examples include a peripheral accessing a central that provides Current Time Service, //| Apple Notification Center Service, or Battery Service. //| +//| :return: A tuple of services provided by the remote central. +//| STATIC mp_obj_t bleio_peripheral_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -300,27 +299,12 @@ STATIC mp_obj_t bleio_peripheral_discover_remote_services(mp_uint_t n_args, cons mp_raise_ValueError(translate("Not connected")); } - common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), - args[ARG_service_uuids_whitelist].u_obj); - - return mp_const_none; + return MP_OBJ_FROM_PTR(common_hal_bleio_peripheral_discover_remote_services( + MP_OBJ_FROM_PTR(self), + args[ARG_service_uuids_whitelist].u_obj)); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_discover_remote_services_obj, 1, bleio_peripheral_discover_remote_services); -//| .. attribute:: remote_services (read-only) -//| -//| A tuple of services provided by the remote central. -//| If discovery did not occur, an empty tuple will be returned. -//| -STATIC mp_obj_t bleio_peripheral_get_remote_services(mp_obj_t self_in) { - bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // Return list as a tuple so user won't be able to change it. - mp_obj_list_t *service_list = common_hal_bleio_peripheral_get_remote_services(self); - return mp_obj_new_tuple(service_list->len, service_list->items); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_remote_services_obj, bleio_peripheral_get_remote_services); - //| .. method:: pair() //| //| Request pairing with connected central. @@ -333,14 +317,6 @@ STATIC mp_obj_t bleio_peripheral_pair(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_pair_obj, bleio_peripheral_pair); -const mp_obj_property_t bleio_peripheral_remote_services_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_peripheral_get_remote_services_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - - STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) }, @@ -352,7 +328,6 @@ STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) }, { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) }, - { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_peripheral_remote_services_obj) }, { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) }, }; diff --git a/shared-bindings/bleio/Peripheral.h b/shared-bindings/bleio/Peripheral.h index d9b72b2c3..597b65ce2 100644 --- a/shared-bindings/bleio/Peripheral.h +++ b/shared-bindings/bleio/Peripheral.h @@ -28,6 +28,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H +#include "py/objtuple.h" #include "common-hal/bleio/Peripheral.h" extern const mp_obj_type_t bleio_peripheral_type; @@ -39,7 +40,7 @@ extern mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *sel extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo); extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device); extern void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *device); -extern mp_obj_list_t *common_hal_bleio_peripheral_get_remote_services(bleio_peripheral_obj_t *self); +extern mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist); extern void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *device); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 05be48ddc..739f461a5 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -94,9 +94,6 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, - - // constants - { MP_ROM_QSTR(MP_QSTR_SEC), MP_ROM_PTR(&bleio_uuid_type) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); diff --git a/shared-module/bleio/Attribute.c b/shared-module/bleio/Attribute.c index ac854ec6b..2275003c9 100644 --- a/shared-module/bleio/Attribute.c +++ b/shared-module/bleio/Attribute.c @@ -31,13 +31,13 @@ void common_hal_bleio_attribute_security_mode_check_valid(bleio_attribute_security_mode_t security_mode) { switch (security_mode) { - case SEC_MODE_NO_ACCESS: - case SEC_MODE_OPEN: - case SEC_MODE_ENC_NO_MITM: - case SEC_MODE_ENC_WITH_MITM: - case SEC_MODE_LESC_ENC_WITH_MITM: - case SEC_MODE_SIGNED_NO_MITM: - case SEC_MODE_SIGNED_WITH_MITM: + case SECURITY_MODE_NO_ACCESS: + case SECURITY_MODE_OPEN: + case SECURITY_MODE_ENC_NO_MITM: + case SECURITY_MODE_ENC_WITH_MITM: + case SECURITY_MODE_LESC_ENC_WITH_MITM: + case SECURITY_MODE_SIGNED_NO_MITM: + case SECURITY_MODE_SIGNED_WITH_MITM: break; default: mp_raise_ValueError(translate("Invalid security_mode")); diff --git a/shared-module/bleio/Attribute.h b/shared-module/bleio/Attribute.h index 62615f1b5..a498a14a5 100644 --- a/shared-module/bleio/Attribute.h +++ b/shared-module/bleio/Attribute.h @@ -29,13 +29,13 @@ // BLE security modes: 0x typedef enum { - SEC_MODE_NO_ACCESS = 0x00, - SEC_MODE_OPEN = 0x11, - SEC_MODE_ENC_NO_MITM = 0x21, - SEC_MODE_ENC_WITH_MITM = 0x31, - SEC_MODE_LESC_ENC_WITH_MITM = 0x41, - SEC_MODE_SIGNED_NO_MITM = 0x12, - SEC_MODE_SIGNED_WITH_MITM = 0x22, + SECURITY_MODE_NO_ACCESS = 0x00, + SECURITY_MODE_OPEN = 0x11, + SECURITY_MODE_ENC_NO_MITM = 0x21, + SECURITY_MODE_ENC_WITH_MITM = 0x31, + SECURITY_MODE_LESC_ENC_WITH_MITM = 0x41, + SECURITY_MODE_SIGNED_NO_MITM = 0x12, + SECURITY_MODE_SIGNED_WITH_MITM = 0x22, } bleio_attribute_security_mode_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H -- cgit v1.2.3 From 9d164965c9fe04f3485b6ee213507548cac403d0 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 17 Aug 2019 20:49:05 -0500 Subject: localtime: don't hard-fault on argument type errors; handle localtime(float) It turns out `mp_obj_int_get_checked` is not appropriate to call when the argument is not of int or long type--the "checked" refers to guarding against overflow/underflow, not type checking. For compatibility with CPython, handle float arguments. Closes: #2069 --- shared-bindings/time/__init__.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index f34cb9c46..420bedf1c 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -236,7 +236,12 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { return rtc_get_time_source_time(); } - mp_int_t secs = mp_obj_int_get_checked(args[0]); + mp_obj_t arg = args[0]; + if(mp_obj_is_float(arg)) + arg = mp_obj_new_int_from_float(mp_obj_get_float(arg)); + + mp_int_t secs = mp_obj_get_int(arg); + if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); -- cgit v1.2.3 From f384d2dd8004e1becac6183243caef4b4bbedf56 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 18 Aug 2019 08:11:14 -0500 Subject: shared-bindings/time: style --- shared-bindings/time/__init__.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 420bedf1c..2654de09a 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -237,13 +237,15 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { } mp_obj_t arg = args[0]; - if(mp_obj_is_float(arg)) + if (mp_obj_is_float(arg)) { arg = mp_obj_new_int_from_float(mp_obj_get_float(arg)); + } mp_int_t secs = mp_obj_get_int(arg); - if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) + if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) { mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); + } timeutils_struct_time_t tm; timeutils_seconds_since_epoch_to_struct_time(secs, &tm); @@ -275,8 +277,9 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) { mp_raise_TypeError(translate("function takes exactly 9 arguments")); } - if (mp_obj_get_int(elem[0]) < 2000) + if (mp_obj_get_int(elem[0]) < 2000) { mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); + } mp_uint_t secs = timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])); -- cgit v1.2.3