diff options
Diffstat (limited to 'extmod')
-rw-r--r-- | extmod/btstack/modbluetooth_btstack.c | 33 | ||||
-rw-r--r-- | extmod/modbluetooth.c | 12 | ||||
-rw-r--r-- | extmod/modbluetooth.h | 4 | ||||
-rw-r--r-- | extmod/nimble/modbluetooth_nimble.c | 22 |
4 files changed, 67 insertions, 4 deletions
diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c index f0b6187a2..772fe4bed 100644 --- a/extmod/btstack/modbluetooth_btstack.c +++ b/extmod/btstack/modbluetooth_btstack.c @@ -37,10 +37,20 @@ #define DEBUG_EVENT_printf(...) //printf(__VA_ARGS__) +#ifndef MICROPY_PY_BLUETOOTH_DEFAULT_GAP_NAME +#define MICROPY_PY_BLUETOOTH_DEFAULT_GAP_NAME "MPY BTSTACK" +#endif + // How long to wait for a controller to init/deinit. // Some controllers can take up to 5-6 seconds in normal operation. STATIC const uint32_t BTSTACK_INIT_DEINIT_TIMEOUT_MS = 15000; +// We need to know the attribute handle for the GAP device name (see GAP_DEVICE_NAME_UUID) +// so it can be put into the gatts_db before registering the services, and accessed +// efficiently when requesting an attribute in att_read_callback. Because this is the +// first characteristic of the first service, it always has a handle value of 3. +STATIC const uint16_t BTSTACK_GAP_DEVICE_NAME_HANDLE = 3; + volatile int mp_bluetooth_btstack_state = MP_BLUETOOTH_BTSTACK_STATE_OFF; STATIC btstack_packet_callback_registration_t hci_event_callback_registration; @@ -250,6 +260,12 @@ int mp_bluetooth_init(void) { MP_STATE_PORT(bluetooth_btstack_root_pointers) = m_new0(mp_bluetooth_btstack_root_pointers_t, 1); mp_bluetooth_gatts_db_create(&MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db); + // Set the default GAP device name. + const char *gap_name = MICROPY_PY_BLUETOOTH_DEFAULT_GAP_NAME; + size_t gap_len = strlen(gap_name); + mp_bluetooth_gatts_db_create_entry(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, BTSTACK_GAP_DEVICE_NAME_HANDLE, gap_len); + mp_bluetooth_gap_set_device_name((const uint8_t *)gap_name, gap_len); + mp_bluetooth_btstack_port_init(); mp_bluetooth_btstack_state = MP_BLUETOOTH_BTSTACK_STATE_STARTING; @@ -344,6 +360,19 @@ void mp_bluetooth_get_device_addr(uint8_t *addr) { mp_hal_get_mac(MP_HAL_MAC_BDADDR, addr); } +size_t mp_bluetooth_gap_get_device_name(const uint8_t **buf) { + uint8_t *value = NULL; + size_t value_len = 0; + mp_bluetooth_gatts_db_read(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, BTSTACK_GAP_DEVICE_NAME_HANDLE, &value, &value_len); + *buf = value; + return value_len; +} + +int mp_bluetooth_gap_set_device_name(const uint8_t *buf, size_t len) { + mp_bluetooth_gatts_db_write(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, BTSTACK_GAP_DEVICE_NAME_HANDLE, buf, len); + return 0; +} + int mp_bluetooth_gap_advertise_start(bool connectable, int32_t interval_us, const uint8_t *adv_data, size_t adv_data_len, const uint8_t *sr_data, size_t sr_data_len) { DEBUG_EVENT_printf("mp_bluetooth_gap_advertise_start\n"); uint16_t adv_int_min = interval_us / 625; @@ -396,7 +425,9 @@ int mp_bluetooth_gatts_register_service_begin(bool append) { att_db_util_init(); att_db_util_add_service_uuid16(GAP_SERVICE_UUID); - att_db_util_add_characteristic_uuid16(GAP_DEVICE_NAME_UUID, ATT_PROPERTY_READ, ATT_SECURITY_NONE, ATT_SECURITY_NONE, (uint8_t *)"MPY BTSTACK", 11); + uint16_t handle = att_db_util_add_characteristic_uuid16(GAP_DEVICE_NAME_UUID, ATT_PROPERTY_READ | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_NONE, ATT_SECURITY_NONE, NULL, 0); + assert(handle == BTSTACK_GAP_DEVICE_NAME_HANDLE); + (void)handle; att_db_util_add_service_uuid16(0x1801); att_db_util_add_characteristic_uuid16(0x2a05, ATT_PROPERTY_READ, ATT_SECURITY_NONE, ATT_SECURITY_NONE, NULL, 0); diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 7a3d1ac12..7e6abb549 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -295,6 +295,11 @@ STATIC mp_obj_t bluetooth_ble_config(size_t n_args, const mp_obj_t *args, mp_map } switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_gap_name: { + const uint8_t *buf; + size_t len = mp_bluetooth_gap_get_device_name(&buf); + return mp_obj_new_bytes(buf, len); + } case MP_QSTR_mac: { uint8_t addr[6]; mp_bluetooth_get_device_addr(addr); @@ -315,6 +320,13 @@ STATIC mp_obj_t bluetooth_ble_config(size_t n_args, const mp_obj_t *args, mp_map if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { mp_map_elem_t *e = &kwargs->table[i]; switch (mp_obj_str_get_qstr(e->key)) { + case MP_QSTR_gap_name: { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(e->value, &bufinfo, MP_BUFFER_READ); + int ret = mp_bluetooth_gap_set_device_name(bufinfo.buf, bufinfo.len); + bluetooth_handle_errno(ret); + break; + } case MP_QSTR_rxbuf: { // Determine new buffer sizes mp_int_t ringbuf_alloc = mp_obj_get_int(e->value); diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h index 96c9c4b9a..4e658a7a0 100644 --- a/extmod/modbluetooth.h +++ b/extmod/modbluetooth.h @@ -171,6 +171,10 @@ bool mp_bluetooth_is_active(void); // Gets the MAC addr of this device in big-endian format. void mp_bluetooth_get_device_addr(uint8_t *addr); +// Get or set the GAP device name that will be used by service 0x1800, characteristic 0x2a00. +size_t mp_bluetooth_gap_get_device_name(const uint8_t **buf); +int mp_bluetooth_gap_set_device_name(const uint8_t *buf, size_t len); + // Start advertisement. Will re-start advertisement when already enabled. // Returns errno on failure. int mp_bluetooth_gap_advertise_start(bool connectable, int32_t interval_us, const uint8_t *adv_data, size_t adv_data_len, const uint8_t *sr_data, size_t sr_data_len); diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c index 9498e998b..69067e077 100644 --- a/extmod/nimble/modbluetooth_nimble.c +++ b/extmod/nimble/modbluetooth_nimble.c @@ -40,8 +40,8 @@ #include "nimble/nimble_port.h" #include "services/gap/ble_svc_gap.h" -#ifndef MICROPY_PY_BLUETOOTH_DEFAULT_NAME -#define MICROPY_PY_BLUETOOTH_DEFAULT_NAME "PYBD" +#ifndef MICROPY_PY_BLUETOOTH_DEFAULT_GAP_NAME +#define MICROPY_PY_BLUETOOTH_DEFAULT_GAP_NAME "MPY NIMBLE" #endif #define DEBUG_EVENT_printf(...) //printf(__VA_ARGS__) @@ -191,7 +191,7 @@ STATIC void sync_cb(void) { assert(rc == 0); } - ble_svc_gap_device_name_set(MICROPY_PY_BLUETOOTH_DEFAULT_NAME); + ble_svc_gap_device_name_set(MICROPY_PY_BLUETOOTH_DEFAULT_GAP_NAME); mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_ACTIVE; } @@ -352,6 +352,22 @@ void mp_bluetooth_get_device_addr(uint8_t *addr) { #endif } +size_t mp_bluetooth_gap_get_device_name(const uint8_t **buf) { + const char *name = ble_svc_gap_device_name(); + *buf = (const uint8_t *)name; + return strlen(name); +} + +int mp_bluetooth_gap_set_device_name(const uint8_t *buf, size_t len) { + char tmp_buf[MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH) + 1]; + if (len + 1 > sizeof(tmp_buf)) { + return MP_EINVAL; + } + memcpy(tmp_buf, buf, len); + tmp_buf[len] = '\0'; + return ble_hs_err_to_errno(ble_svc_gap_device_name_set(tmp_buf)); +} + int mp_bluetooth_gap_advertise_start(bool connectable, int32_t interval_us, const uint8_t *adv_data, size_t adv_data_len, const uint8_t *sr_data, size_t sr_data_len) { if (!mp_bluetooth_is_active()) { return ERRNO_BLUETOOTH_NOT_ACTIVE; |