diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c index 839519dc33..8c7b8f67eb 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.c +++ b/devices/ble_hci/common-hal/_bleio/Adapter.c @@ -49,6 +49,10 @@ #include "shared-bindings/_bleio/ScanEntry.h" #include "shared-bindings/time/__init__.h" +#if CIRCUITPY_DOTENV +#include "shared-module/dotenv/__init__.h" +#endif + #define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) #define SEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000000) / (RESOLUTION)) #define UNITS_TO_SEC(TIME, RESOLUTION) (((TIME)*(RESOLUTION)) / 1000000) @@ -278,17 +282,27 @@ char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0 // Get various values and limits set by the adapter. // Set event mask. STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) { + mp_int_t name_len = 0; - const size_t len = sizeof(default_ble_name); + #if CIRCUITPY_DOTENV + char ble_name[32]; + name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1); + if (name_len > 0) { + self->name = mp_obj_new_str(ble_name, (size_t)name_len); + } + #endif - bt_addr_t addr; - hci_check_error(hci_read_bd_addr(&addr)); + if (name_len <= 0) { + name_len = sizeof(default_ble_name); + bt_addr_t addr; + hci_check_error(hci_read_bd_addr(&addr)); - default_ble_name[len - 4] = nibble_to_hex_lower[addr.val[1] >> 4 & 0xf]; - default_ble_name[len - 3] = nibble_to_hex_lower[addr.val[1] & 0xf]; - default_ble_name[len - 2] = nibble_to_hex_lower[addr.val[0] >> 4 & 0xf]; - default_ble_name[len - 1] = nibble_to_hex_lower[addr.val[0] & 0xf]; - self->name = mp_obj_new_str(default_ble_name, len); + default_ble_name[name_len - 4] = nibble_to_hex_lower[addr.val[1] >> 4 & 0xf]; + default_ble_name[name_len - 3] = nibble_to_hex_lower[addr.val[1] & 0xf]; + default_ble_name[name_len - 2] = nibble_to_hex_lower[addr.val[0] >> 4 & 0xf]; + default_ble_name[name_len - 1] = nibble_to_hex_lower[addr.val[0] & 0xf]; + self->name = mp_obj_new_str(default_ble_name, (uint8_t)name_len); + } // Get version information. if (hci_read_local_version(&self->hci_version, &self->hci_revision, &self->lmp_version, diff --git a/docs/environment.rst b/docs/environment.rst index 2e5d81fca8..4d12009848 100644 --- a/docs/environment.rst +++ b/docs/environment.rst @@ -31,9 +31,17 @@ CircuitPython behavior CircuitPython will also read the environment to configure its behavior. Other keys are ignored by CircuitPython. Here are the keys it uses: +CIRCUITPY_BLE_NAME +~~~~~~~~~~~~~~~~~~ +Default BLE name the board advertises as, including for the BLE workflow. + +CIRCUITPY_WEB_API_PASSWORD +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Password required to make modifications to the board from the Web Workflow. + CIRCUITPY_WIFI_PASSWORD ~~~~~~~~~~~~~~~~~~~~~~~ -Wi-Fi password used to auto connect to CIRCUITPY_WIFI_SSID +Wi-Fi password used to auto connect to CIRCUITPY_WIFI_SSID. CIRCUITPY_WIFI_SSID ~~~~~~~~~~~~~~~~~~~ diff --git a/docs/workflows.md b/docs/workflows.md index b011acd01c..2196d1111a 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -45,6 +45,10 @@ using a rotating key rather than a static one. Non-bonded devices won't be able connection, the central device can discover two default services. One for file transfer and one for CircuitPython specifically that includes serial characteristics. +To change the default BLE advertising name without (or before) running user code, the desired name +can be put in the `/.env` file. The key is `CIRCUITPY_BLE_NAME`. It's limited to approximately +30 characters depending on the port's settings and will be truncated if longer. + ### File Transfer API CircuitPython uses [an open File Transfer API](https://github.com/adafruit/Adafruit_CircuitPython_BLE_File_Transfer) diff --git a/ports/espressif/common-hal/_bleio/Adapter.c b/ports/espressif/common-hal/_bleio/Adapter.c index 943e44e7cd..5eaf6e9cf4 100644 --- a/ports/espressif/common-hal/_bleio/Adapter.c +++ b/ports/espressif/common-hal/_bleio/Adapter.c @@ -59,6 +59,10 @@ #include "esp_bt.h" #include "esp_nimble_hci.h" +#if CIRCUITPY_DOTENV +#include "shared-module/dotenv/__init__.h" +#endif + bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; // static void bluetooth_adapter_background(void *data) { @@ -96,7 +100,23 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable // ble_hs_cfg.reset_cb = blecent_on_reset; ble_hs_cfg.sync_cb = _on_sync; // ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + #if CIRCUITPY_DOTENV + mp_int_t name_len = 0; + char ble_name[32]; + name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1); + if (name_len > 0) { + if (name_len > MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH) { + name_len = MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH; + } + ble_name[name_len] = '\0'; + ble_svc_gap_device_name_set(ble_name); + } else { + ble_svc_gap_device_name_set("CIRCUITPY"); + } + #else ble_svc_gap_device_name_set("CIRCUITPY"); + #endif // Clear all of the internal connection objects. for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c index 288cf2f217..5cebf2fa0f 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -52,6 +52,10 @@ #include "shared-bindings/_bleio/ScanEntry.h" #include "shared-bindings/time/__init__.h" +#if CIRCUITPY_DOTENV +#include "shared-module/dotenv/__init__.h" +#endif + #define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) #define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) #define BLE_SLAVE_LATENCY 0 @@ -329,18 +333,30 @@ STATIC void get_address(bleio_adapter_obj_t *self, ble_gap_addr_t *address) { char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0, 0}; STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) { - uint8_t len = sizeof(default_ble_name) - 1; - - ble_gap_addr_t local_address; - get_address(self, &local_address); - - default_ble_name[len - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf]; - default_ble_name[len - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf]; - default_ble_name[len - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf]; - default_ble_name[len - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf]; + // setup the default name + ble_gap_addr_t addr; // local_address + get_address(self, &addr); + mp_int_t len = sizeof(default_ble_name) - 1; + default_ble_name[len - 4] = nibble_to_hex_lower[addr.addr[1] >> 4 & 0xf]; + default_ble_name[len - 3] = nibble_to_hex_lower[addr.addr[1] & 0xf]; + default_ble_name[len - 2] = nibble_to_hex_lower[addr.addr[0] >> 4 & 0xf]; + default_ble_name[len - 1] = nibble_to_hex_lower[addr.addr[0] & 0xf]; default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings - common_hal_bleio_adapter_set_name(self, (char *)default_ble_name); + mp_int_t name_len = 0; + + #if CIRCUITPY_DOTENV + char ble_name[32]; + name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1); + if (name_len > 0) { + ble_name[name_len] = '\0'; + common_hal_bleio_adapter_set_name(self, (char *)ble_name); + } + #endif + + if (name_len <= 0) { + common_hal_bleio_adapter_set_name(self, (char *)default_ble_name); + } } static void bluetooth_adapter_background(void *data) { @@ -448,7 +464,11 @@ void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *na ble_gap_conn_sec_mode_t sec; sec.lv = 0; sec.sm = 0; - sd_ble_gap_device_name_set(&sec, (const uint8_t *)name, strlen(name)); + uint16_t len = strlen(name); + if (len > BLE_GAP_DEVNAME_MAX_LEN) { + len = BLE_GAP_DEVNAME_MAX_LEN; + } + sd_ble_gap_device_name_set(&sec, (const uint8_t *)name, len); } STATIC uint32_t _update_identities(bool is_central) {