summaryrefslogtreecommitdiff
path: root/extmod
diff options
context:
space:
mode:
Diffstat (limited to 'extmod')
-rw-r--r--extmod/btstack/modbluetooth_btstack.c33
-rw-r--r--extmod/modbluetooth.c12
-rw-r--r--extmod/modbluetooth.h4
-rw-r--r--extmod/nimble/modbluetooth_nimble.c22
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;