Skip to content

Commit b2c32cf

Browse files
authored
Merge pull request #8645 from dhalbert/esp32s3-ble-fixes
ESP32-S3 BLE fixes
2 parents 28c2094 + 567c273 commit b2c32cf

File tree

7 files changed

+57
-20
lines changed

7 files changed

+57
-20
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,15 +284,21 @@ STATIC void _new_connection(uint16_t conn_handle) {
284284
esp_ble_tx_power_set(conn_handle, ESP_PWR_LVL_N0);
285285

286286

287-
// Find an empty connection. One must always be available because the SD has the same
287+
// Find an empty connection. One should always be available because the SD has the same
288288
// total connection limit.
289-
bleio_connection_internal_t *connection;
289+
bleio_connection_internal_t *connection = NULL;
290290
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
291291
connection = &bleio_connections[i];
292292
if (connection->conn_handle == BLEIO_HANDLE_INVALID) {
293293
break;
294294
}
295295
}
296+
297+
// Shouldn't happen, but just return if no connection available.
298+
if (!connection) {
299+
return;
300+
}
301+
296302
connection->conn_handle = conn_handle;
297303
connection->connection_obj = mp_const_none;
298304
connection->pair_status = PAIR_NOT_PAIRED;

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,25 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
5050
self->props = props;
5151
self->read_perm = read_perm;
5252
self->write_perm = write_perm;
53-
common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo);
53+
54+
if (initial_value_bufinfo != NULL) {
55+
// Copy the initial value if it's on the heap. Otherwise it's internal and we may not be able
56+
// to allocate.
57+
self->current_value_len = initial_value_bufinfo->len;
58+
if (gc_alloc_possible()) {
59+
if (gc_nbytes(initial_value_bufinfo->buf) > 0) {
60+
uint8_t *initial_value = m_malloc(self->current_value_len);
61+
self->current_value_alloc = self->current_value_len;
62+
memcpy(initial_value, initial_value_bufinfo->buf, self->current_value_len);
63+
self->current_value = initial_value;
64+
} else {
65+
self->current_value_alloc = 0;
66+
self->current_value = initial_value_bufinfo->buf;
67+
}
68+
} else {
69+
self->current_value = initial_value_bufinfo->buf;
70+
}
71+
}
5472

5573
if (gc_alloc_possible()) {
5674
self->descriptor_list = mp_obj_new_list(0, NULL);

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

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ int bleio_connection_event_cb(struct ble_gap_event *event, void *connection_in)
6363
connection->pair_status = PAIR_NOT_PAIRED;
6464

6565
#if CIRCUITPY_VERBOSE_BLE
66-
mp_printf(&mp_plat_print, "disconnected %02x\n", event->disconnect.reason);
66+
mp_printf(&mp_plat_print, "event->disconnect.reason: 0x%x\n", event->disconnect.reason);
6767
#endif
6868
if (connection->connection_obj != mp_const_none) {
6969
bleio_connection_obj_t *obj = connection->connection_obj;
@@ -128,6 +128,7 @@ bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self) {
128128
}
129129

130130
void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) {
131+
// Second argument is an HCI reason, not an HS error code.
131132
ble_gap_terminate(self->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
132133
}
133134

@@ -162,9 +163,9 @@ STATIC int _discovered_service_cb(uint16_t conn_handle,
162163
void *arg) {
163164
bleio_connection_internal_t *self = (bleio_connection_internal_t *)arg;
164165

165-
if (error->status != BLE_ERR_SUCCESS) {
166+
if (error->status != 0) {
166167
// Keep the first error in case it's due to memory.
167-
if (_last_discovery_status == BLE_ERR_SUCCESS) {
168+
if (_last_discovery_status == 0) {
168169
_last_discovery_status = error->status;
169170
xTaskNotifyGive(discovery_task);
170171
}
@@ -173,7 +174,7 @@ STATIC int _discovered_service_cb(uint16_t conn_handle,
173174

174175
// If any of these memory allocations fail, we set _last_discovery_status
175176
// and let the process continue.
176-
if (_last_discovery_status != BLE_ERR_SUCCESS) {
177+
if (_last_discovery_status != 0) {
177178
return 0;
178179
}
179180
bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
@@ -202,16 +203,17 @@ STATIC int _discovered_characteristic_cb(uint16_t conn_handle,
202203
void *arg) {
203204
bleio_service_obj_t *service = (bleio_service_obj_t *)arg;
204205

205-
if (error->status != BLE_ERR_SUCCESS) {
206+
if (error->status != 0) {
206207
// Keep the first error in case it's due to memory.
207-
if (_last_discovery_status == BLE_ERR_SUCCESS) {
208+
if (_last_discovery_status == 0) {
208209
_last_discovery_status = error->status;
209210
xTaskNotifyGive(discovery_task);
210211
}
212+
return 0;
211213
}
212214
// If any of these memory allocations fail, we set _last_discovery_status
213215
// and let the process continue.
214-
if (_last_discovery_status != BLE_ERR_SUCCESS) {
216+
if (_last_discovery_status != 0) {
215217
return 0;
216218
}
217219

@@ -232,11 +234,14 @@ STATIC int _discovered_characteristic_cb(uint16_t conn_handle,
232234
((chr->properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) != 0 ? CHAR_PROP_WRITE_NO_RESPONSE : 0);
233235

234236
// Call common_hal_bleio_characteristic_construct() to initialize some fields and set up evt handler.
237+
mp_buffer_info_t mp_const_empty_bytes_bufinfo;
238+
mp_get_buffer_raise(mp_const_empty_bytes, &mp_const_empty_bytes_bufinfo, MP_BUFFER_READ);
239+
235240
common_hal_bleio_characteristic_construct(
236241
characteristic, service, chr->val_handle, uuid,
237242
props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
238243
0, false, // max_length, fixed_length: values don't matter for gattc
239-
mp_const_empty_bytes,
244+
&mp_const_empty_bytes_bufinfo,
240245
NULL);
241246
// Set def_handle directly since it is only used in discovery.
242247
characteristic->def_handle = chr->def_handle;
@@ -253,16 +258,17 @@ STATIC int _discovered_descriptor_cb(uint16_t conn_handle,
253258
void *arg) {
254259
bleio_characteristic_obj_t *characteristic = (bleio_characteristic_obj_t *)arg;
255260

256-
if (error->status != BLE_ERR_SUCCESS) {
261+
if (error->status != 0) {
257262
// Keep the first error in case it's due to memory.
258-
if (_last_discovery_status == BLE_ERR_SUCCESS) {
263+
if (_last_discovery_status == 0) {
259264
_last_discovery_status = error->status;
260265
}
261266
xTaskNotifyGive(discovery_task);
267+
return 0;
262268
}
263269
// If any of these memory allocations fail, we set _last_discovery_status
264270
// and let the process continue.
265-
if (_last_discovery_status != BLE_ERR_SUCCESS) {
271+
if (_last_discovery_status != 0) {
266272
return 0;
267273
}
268274

@@ -306,7 +312,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
306312

307313
discovery_task = xTaskGetCurrentTaskHandle();
308314
if (service_uuids_whitelist == mp_const_none) {
309-
_last_discovery_status = BLE_ERR_SUCCESS;
315+
_last_discovery_status = 0;
310316
CHECK_NIMBLE_ERROR(ble_gattc_disc_all_svcs(self->conn_handle, _discovered_service_cb, self));
311317

312318
// Wait for sync.
@@ -324,7 +330,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
324330
}
325331
bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
326332

327-
_last_discovery_status = BLE_ERR_SUCCESS;
333+
_last_discovery_status = 0;
328334
// Make sure we start with a clean notification state
329335
ulTaskNotifyValueClear(discovery_task, 0xffffffff);
330336
CHECK_NIMBLE_ERROR(ble_gattc_disc_svc_by_uuid(self->conn_handle, &uuid->nimble_ble_uuid.u,
@@ -340,7 +346,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
340346
for (size_t i = 0; i < self->remote_service_list->len; i++) {
341347
bleio_service_obj_t *service = MP_OBJ_TO_PTR(self->remote_service_list->items[i]);
342348

343-
_last_discovery_status = BLE_ERR_SUCCESS;
349+
_last_discovery_status = 0;
344350
CHECK_NIMBLE_ERROR(ble_gattc_disc_all_chrs(self->conn_handle,
345351
service->start_handle,
346352
service->end_handle,
@@ -375,7 +381,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
375381
continue;
376382
}
377383

378-
_last_discovery_status = BLE_ERR_SUCCESS;
384+
_last_discovery_status = 0;
379385
CHECK_NIMBLE_ERROR(ble_gattc_disc_all_dscs(self->conn_handle, characteristic->handle,
380386
end_handle,
381387
_discovered_descriptor_cb, characteristic));

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ void check_nimble_error(int rc, const char *file, size_t line) {
112112
}
113113

114114
void check_ble_error(int error_code, const char *file, size_t line) {
115-
if (error_code == BLE_ERR_SUCCESS) {
115+
// 0 means success. For BLE_HS_* codes, there is no defined "SUCCESS" value.
116+
if (error_code == 0) {
116117
return;
117118
}
118119
switch (error_code) {

ports/espressif/mpconfigport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
#ifndef MICROPY_INCLUDED_ESPRESSIF_MPCONFIGPORT_H
2929
#define MICROPY_INCLUDED_ESPRESSIF_MPCONFIGPORT_H
3030

31+
// Enable for debugging.
32+
// #define CIRCUITPY_VERBOSE_BLE (1)
33+
3134
#define MICROPY_NLR_THUMB (0)
3235

3336
#define MICROPY_USE_INTERNAL_PRINTF (0)

py/circuitpy_mpconfig.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,9 @@ void background_callback_run_all(void);
470470
#error "boot counter requires CIRCUITPY_NVM enabled"
471471
#endif
472472

473+
#ifndef CIRCUITPY_VERBOSE_BLE
473474
#define CIRCUITPY_VERBOSE_BLE 0
475+
#endif
474476

475477
// Display the Blinka logo in the REPL on displayio displays.
476478
#ifndef CIRCUITPY_REPL_LOGO

shared-bindings/_bleio/Adapter.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ STATIC mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args
353353
prefix_bufinfo.len = 0;
354354
if (args[ARG_prefixes].u_obj != MP_OBJ_NULL) {
355355
mp_get_buffer_raise(args[ARG_prefixes].u_obj, &prefix_bufinfo, MP_BUFFER_READ);
356-
if (gc_nbytes(prefix_bufinfo.buf) == 0) {
356+
// An empty buffer may not be on the heap, but that doesn't matter.
357+
if (prefix_bufinfo.len > 0 && gc_nbytes(prefix_bufinfo.buf) == 0) {
357358
mp_raise_ValueError(MP_ERROR_TEXT("Prefix buffer must be on the heap"));
358359
}
359360
}

0 commit comments

Comments
 (0)