Skip to content

Commit 63aeb11

Browse files
committed
Improve ESP BLE and turn on BLE workflow
The BLE workflow will broadcast publicly when the web workflow isn't activated.
1 parent c6da0a4 commit 63aeb11

File tree

25 files changed

+242
-81
lines changed

25 files changed

+242
-81
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
[submodule "ports/espressif/esp-idf"]
144144
path = ports/espressif/esp-idf
145145
url = https://github.com/adafruit/esp-idf.git
146-
branch = circuitpython-v5.1.3
146+
branch = circuitpython-v5.2.2
147147
[submodule "ports/espressif/esp-protocols"]
148148
path = ports/espressif/esp-protocols
149149
url = https://github.com/espressif/esp-protocols.git

locale/circuitpython.pot

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ msgstr ""
113113
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
114114
#: ports/raspberrypi/common-hal/usb_host/Port.c
115115
#: shared-bindings/digitalio/DigitalInOut.c
116-
#: shared-bindings/microcontroller/Pin.c
116+
#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c
117117
msgid "%q in use"
118118
msgstr ""
119119

@@ -1114,10 +1114,12 @@ msgstr ""
11141114
msgid "Input/output error"
11151115
msgstr ""
11161116

1117+
#: ports/espressif/common-hal/_bleio/__init__.c
11171118
#: ports/nordic/common-hal/_bleio/__init__.c
11181119
msgid "Insufficient authentication"
11191120
msgstr ""
11201121

1122+
#: ports/espressif/common-hal/_bleio/__init__.c
11211123
#: ports/nordic/common-hal/_bleio/__init__.c
11221124
msgid "Insufficient encryption"
11231125
msgstr ""
@@ -1154,6 +1156,7 @@ msgstr ""
11541156
#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c
11551157
#: ports/atmel-samd/common-hal/countio/Counter.c
11561158
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
1159+
#: ports/atmel-samd/common-hal/max3421e/Max3421E.c
11571160
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
11581161
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
11591162
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
@@ -1285,6 +1288,10 @@ msgstr ""
12851288
msgid "MAC address was invalid"
12861289
msgstr ""
12871290

1291+
#: ports/espressif/common-hal/_bleio/Characteristic.c
1292+
msgid "MITM security not supported"
1293+
msgstr ""
1294+
12881295
#: shared-bindings/is31fl3741/IS31FL3741.c
12891296
msgid "Mapping must be a tuple"
12901297
msgstr ""
@@ -2139,6 +2146,7 @@ msgstr ""
21392146
msgid "Unknown BLE error: %d"
21402147
msgstr ""
21412148

2149+
#: ports/espressif/common-hal/max3421e/Max3421E.c
21422150
#: ports/raspberrypi/common-hal/wifi/__init__.c
21432151
#, c-format
21442152
msgid "Unknown error code %d"
@@ -3810,7 +3818,7 @@ msgstr ""
38103818
msgid "pop from empty %q"
38113819
msgstr ""
38123820

3813-
#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c
3821+
#: shared-bindings/socketpool/Socket.c
38143822
msgid "port must be >= 0"
38153823
msgstr ""
38163824

main.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,10 +1006,6 @@ int __attribute__((used)) main(void) {
10061006
supervisor_status_bar_init();
10071007
#endif
10081008

1009-
#if CIRCUITPY_BLEIO
1010-
// Early init so that a reset press can cause BLE public advertising.
1011-
supervisor_bluetooth_init();
1012-
#endif
10131009

10141010
#if !INTERNAL_FLASH_FILESYSTEM
10151011
// Set up anything that might need to get done before we try to use SPI flash
@@ -1027,6 +1023,12 @@ int __attribute__((used)) main(void) {
10271023
set_safe_mode(SAFE_MODE_NO_CIRCUITPY);
10281024
}
10291025

1026+
#if CIRCUITPY_BLEIO
1027+
// Early init so that a reset press can cause BLE public advertising. Need the filesystem to
1028+
// read settings.toml.
1029+
supervisor_bluetooth_init();
1030+
#endif
1031+
10301032
#if CIRCUITPY_ALARM
10311033
// Record which alarm woke us up, if any.
10321034
// common_hal_alarm_record_wake_alarm() should return a static, non-heap object

ports/espressif/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,13 @@ LDFLAGS += \
229229
-Tesp32c6.rom.newlib.ld \
230230
-Tesp32c6.rom.coexist.ld \
231231
-Tesp32c6.rom.heap.ld \
232+
-Tesp32c6.rom.systimer.ld \
232233
-Tesp32c6.rom.wdt.ld
233234
else ifeq ($(IDF_TARGET),esp32h2)
234235
LDFLAGS += \
235236
-Tesp32h2.rom.heap.ld \
236237
-Tesp32h2.rom.newlib.ld \
238+
-Tesp32h2.rom.systimer.ld \
237239
-Tesp32h2.rom.wdt.ld
238240
else ifeq ($(IDF_TARGET),esp32s2)
239241
LDFLAGS += \

ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#define MICROPY_HW_BOARD_NAME "Adafruit Feather ESP32-C6 4MB Flash No PSRAM"
1212
#define MICROPY_HW_MCU_NAME "ESP32C6"
1313

14-
#define MICROPY_HW_NEOPIXEL (&pin_GPIO9)
14+
// Don't use the neopixel for status because we can't use it at the same time as
15+
// the boot button.
16+
// #define MICROPY_HW_NEOPIXEL (&pin_GPIO9)
1517

1618
#define MICROPY_HW_LED_STATUS (&pin_GPIO15)
1719

ports/espressif/common-hal/_bleio/Adapter.c

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "common-hal/_bleio/Connection.h"
4040

4141
#include "esp_bt.h"
42+
#include "esp_mac.h"
4243
#include "esp_nimble_hci.h"
4344
#include "nvs_flash.h"
4445

@@ -48,11 +49,6 @@
4849

4950
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
5051

51-
// static void bluetooth_adapter_background(void *data) {
52-
// supervisor_bluetooth_background();
53-
// bleio_background();
54-
// }
55-
5652
bool ble_active = false;
5753

5854
static void nimble_host_task(void *param) {
@@ -63,7 +59,7 @@ static void nimble_host_task(void *param) {
6359
static TaskHandle_t cp_task = NULL;
6460

6561
static void _on_sync(void) {
66-
int rc = ble_hs_util_ensure_addr(0);
62+
int rc = ble_hs_util_ensure_addr(false);
6763
assert(rc == 0);
6864

6965
xTaskNotifyGive(cp_task);
@@ -72,6 +68,8 @@ static void _on_sync(void) {
7268
// All examples have this. It'd make sense in a header.
7369
void ble_store_config_init(void);
7470

71+
char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0};
72+
7573
void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled) {
7674
const bool is_enabled = common_hal_bleio_adapter_get_enabled(self);
7775

@@ -81,15 +79,6 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
8179
}
8280

8381
if (enabled) {
84-
esp_err_t err = nvs_flash_init();
85-
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
86-
// NVS partition was truncated and needs to be erased
87-
// Retry nvs_flash_init
88-
ESP_ERROR_CHECK(nvs_flash_erase());
89-
err = nvs_flash_init();
90-
}
91-
ESP_ERROR_CHECK(err);
92-
9382
CHECK_ESP_RESULT(nimble_port_init());
9483

9584
// ble_hs_cfg.reset_cb = blecent_on_reset;
@@ -104,8 +93,8 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
10493
ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC;
10594
ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC;
10695

107-
ble_hs_cfg.sm_mitm = 1;
108-
ble_hs_cfg.sm_sc = 1;
96+
ble_hs_cfg.sm_mitm = 0;
97+
ble_hs_cfg.sm_sc = 0;
10998
/* Stores the IRK */
11099
ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;
111100
ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;
@@ -122,7 +111,17 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
122111
} else
123112
#endif
124113
{
125-
ble_svc_gap_device_name_set("CIRCUITPY");
114+
uint8_t mac[6];
115+
esp_read_mac(mac, ESP_MAC_BT);
116+
mp_int_t len = sizeof(default_ble_name) - 1;
117+
default_ble_name[len - 6] = nibble_to_hex_lower[mac[3] >> 4 & 0xf];
118+
default_ble_name[len - 5] = nibble_to_hex_lower[mac[3] & 0xf];
119+
default_ble_name[len - 4] = nibble_to_hex_lower[mac[4] >> 4 & 0xf];
120+
default_ble_name[len - 3] = nibble_to_hex_lower[mac[4] & 0xf];
121+
default_ble_name[len - 2] = nibble_to_hex_lower[mac[5] >> 4 & 0xf];
122+
default_ble_name[len - 1] = nibble_to_hex_lower[mac[5] & 0xf];
123+
default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
124+
ble_svc_gap_device_name_set(default_ble_name);
126125
}
127126

128127
// Clear all of the internal connection objects.
@@ -180,6 +179,14 @@ bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_addre
180179
return result == 0;
181180
}
182181

182+
uint16_t bleio_adapter_get_name(char *buf, uint16_t len) {
183+
const char *name = ble_svc_gap_device_name();
184+
uint16_t full_len = strlen(name);
185+
memcpy(buf, name, MIN(full_len, len));
186+
187+
return full_len;
188+
}
189+
183190
mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
184191
const char *name = ble_svc_gap_device_name();
185192

@@ -487,6 +494,7 @@ static int _advertising_event(struct ble_gap_event *event, void *self_in) {
487494
#endif
488495
break;
489496
}
497+
background_callback_add_core(&bleio_background_callback);
490498
return 0;
491499
}
492500

@@ -499,6 +507,8 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
499507
if (ble_gap_adv_active() && !self->user_advertising) {
500508
return BLE_HS_EBUSY;
501509
}
510+
// Override anonymous because it isn't working with the ESP-IDF.
511+
anonymous = false;
502512

503513
uint32_t rc;
504514

@@ -521,12 +531,19 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
521531
bool extended = advertising_data_len > BLE_ADV_LEGACY_DATA_MAX_LEN ||
522532
scan_response_data_len > BLE_ADV_LEGACY_DATA_MAX_LEN;
523533

534+
bool scannable = scan_response_data_len > 0;
535+
bool legacy_pdu = !extended && !anonymous;
536+
if (legacy_pdu && connectable) {
537+
// Connectable legacy advertisements are always scannable too.
538+
scannable = true;
539+
}
540+
524541
struct ble_gap_ext_adv_params adv_params = {
525542
.connectable = connectable,
526-
.scannable = scan_response_data_len > 0,
543+
.scannable = scannable,
527544
.directed = directed_to != NULL,
528545
.high_duty_directed = high_duty_directed,
529-
.legacy_pdu = !extended,
546+
.legacy_pdu = legacy_pdu,
530547
.anonymous = anonymous,
531548
.include_tx_power = extended,
532549
.scan_req_notif = false,
@@ -712,14 +729,46 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
712729
return self->connection_objs;
713730
}
714731

732+
#define NIMBLE_NVS_PEER_SEC_KEY "peer_sec"
733+
#define NIMBLE_NVS_OUR_SEC_KEY "our_sec"
734+
#define NIMBLE_NVS_CCCD_SEC_KEY "cccd_sec"
735+
#define NIMBLE_NVS_PEER_RECORDS_KEY "p_dev_rec"
736+
#define NIMBLE_NVS_NAMESPACE "nimble_bond"
737+
738+
// Implement bonding control ourselves when the adapter isn't enabled so that it
739+
// can run when BLE is off.
715740
void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) {
716-
ble_store_clear();
741+
if (common_hal_bleio_adapter_get_enabled(self)) {
742+
ble_store_clear();
743+
} else {
744+
nvs_handle_t nimble_handle;
745+
esp_err_t err = nvs_open(NIMBLE_NVS_NAMESPACE, NVS_READWRITE, &nimble_handle);
746+
if (err != ESP_OK) {
747+
return;
748+
}
749+
nvs_erase_all(nimble_handle);
750+
nvs_commit(nimble_handle);
751+
nvs_close(nimble_handle);
752+
}
717753
}
718754

719755
bool common_hal_bleio_adapter_is_bonded_to_central(bleio_adapter_obj_t *self) {
720-
int count;
721-
ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
722-
return count > 0;
756+
if (common_hal_bleio_adapter_get_enabled(self)) {
757+
int count;
758+
ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
759+
return count > 0;
760+
}
761+
nvs_handle_t nimble_handle;
762+
esp_err_t err = nvs_open(NIMBLE_NVS_NAMESPACE, NVS_READONLY, &nimble_handle);
763+
if (err != ESP_OK) {
764+
return false;
765+
}
766+
err = nvs_find_key(nimble_handle, "peer_sec_1", NULL);
767+
nvs_close(nimble_handle);
768+
if (err == ESP_OK) {
769+
return true;
770+
}
771+
return false;
723772
}
724773

725774
void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) {

ports/espressif/common-hal/_bleio/Characteristic.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
#include "common-hal/_bleio/Adapter.h"
1919
#include "common-hal/_bleio/Service.h"
20-
// #include "common-hal/_bleio/bonding.h"
2120

2221

2322
static int characteristic_on_ble_gap_evt(struct ble_gap_event *event, void *param);
@@ -57,6 +56,22 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
5756
if ((props & CHAR_PROP_WRITE_NO_RESPONSE) != 0) {
5857
self->flags |= BLE_GATT_CHR_F_WRITE_NO_RSP;
5958
}
59+
if (read_perm == SECURITY_MODE_ENC_WITH_MITM || write_perm == SECURITY_MODE_ENC_WITH_MITM ||
60+
read_perm == SECURITY_MODE_SIGNED_WITH_MITM || write_perm == SECURITY_MODE_SIGNED_WITH_MITM) {
61+
mp_raise_NotImplementedError(MP_ERROR_TEXT("MITM security not supported"));
62+
}
63+
if (read_perm == SECURITY_MODE_ENC_NO_MITM) {
64+
self->flags |= BLE_GATT_CHR_F_READ_ENC;
65+
}
66+
if (read_perm == SECURITY_MODE_SIGNED_NO_MITM) {
67+
self->flags |= BLE_GATT_CHR_F_READ_AUTHEN;
68+
}
69+
if (write_perm == SECURITY_MODE_ENC_NO_MITM) {
70+
self->flags |= BLE_GATT_CHR_F_WRITE_ENC;
71+
}
72+
if (write_perm == SECURITY_MODE_SIGNED_NO_MITM) {
73+
self->flags |= BLE_GATT_CHR_F_WRITE_AUTHEN;
74+
}
6075

6176
if (initial_value_bufinfo != NULL) {
6277
// Copy the initial value if it's on the heap. Otherwise it's internal and we may not be able
@@ -72,6 +87,12 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
7287
self->current_value = initial_value_bufinfo->buf;
7388
assert(self->current_value_len == max_length);
7489
}
90+
} else {
91+
self->current_value = port_malloc(max_length, false);
92+
if (self->current_value != NULL) {
93+
self->current_value_alloc = max_length;
94+
self->current_value_len = 0;
95+
}
7596
}
7697

7798
if (gc_alloc_possible()) {
@@ -294,6 +315,7 @@ int bleio_characteristic_access_cb(uint16_t conn_handle, uint16_t attr_handle,
294315
bleio_packet_buffer_extend(MP_OBJ_FROM_PTR(self->observer), conn_handle, self->current_value, self->current_value_len);
295316
}
296317
}
318+
background_callback_add_core(&bleio_background_callback);
297319
return rc;
298320
}
299321
return BLE_ATT_ERR_UNLIKELY;

ports/espressif/common-hal/_bleio/Connection.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,18 @@ int bleio_connection_event_cb(struct ble_gap_event *event, void *connection_in)
9191
case BLE_GAP_EVENT_NOTIFY_TX:
9292
MP_FALLTHROUGH;
9393
case BLE_GAP_EVENT_SUBSCRIBE:
94-
return ble_event_run_handlers(event);
94+
int status = ble_event_run_handlers(event);
95+
background_callback_add_core(&bleio_background_callback);
96+
return status;
9597

9698
default:
9799
#if CIRCUITPY_VERBOSE_BLE
98100
mp_printf(&mp_plat_print, "Unhandled connection event: %d\n", event->type);
99101
#endif
100-
return 0;
102+
break;
101103
}
104+
105+
background_callback_add_core(&bleio_background_callback);
102106
return 0;
103107
}
104108

ports/espressif/common-hal/_bleio/PacketBuffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void _common_hal_bleio_packet_buffer_construct(
157157
bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
158158
uint32_t *incoming_buffer, size_t incoming_buffer_size,
159159
uint32_t *outgoing_buffer1, uint32_t *outgoing_buffer2, size_t max_packet_size,
160-
void *static_handler_entry) {
160+
ble_event_handler_t *static_handler_entry) {
161161
self->characteristic = characteristic;
162162
self->client = self->characteristic->service->is_remote;
163163
self->max_packet_size = max_packet_size;

0 commit comments

Comments
 (0)