Skip to content

Commit 83cbbc9

Browse files
committed
Add BLE status to title bar
1 parent 3a2bcbc commit 83cbbc9

File tree

7 files changed

+103
-16
lines changed

7 files changed

+103
-16
lines changed

locale/circuitpython.pot

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,14 @@ msgstr ""
15391539
msgid "Odd parity is not supported"
15401540
msgstr ""
15411541

1542+
#: supervisor/shared/bluetooth/bluetooth.c
1543+
msgid "Off"
1544+
msgstr ""
1545+
1546+
#: supervisor/shared/bluetooth/bluetooth.c
1547+
msgid "Ok"
1548+
msgstr ""
1549+
15421550
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
15431551
#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c
15441552
msgid "Only 8 or 16 bit mono with "
@@ -1791,6 +1799,10 @@ msgstr ""
17911799
msgid "Received response was invalid"
17921800
msgstr ""
17931801

1802+
#: supervisor/shared/bluetooth/bluetooth.c
1803+
msgid "Reconnecting"
1804+
msgstr ""
1805+
17941806
#: shared-bindings/displayio/EPaperDisplay.c
17951807
msgid "Refresh too soon"
17961808
msgstr ""

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -449,15 +449,23 @@ bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_addre
449449
return sd_ble_gap_addr_set(&local_address) == NRF_SUCCESS;
450450
}
451451

452+
uint16_t bleio_adapter_get_name(char *buf, uint16_t len) {
453+
uint16_t full_len = 0;
454+
sd_ble_gap_device_name_get(NULL, &full_len);
455+
456+
uint32_t err_code = sd_ble_gap_device_name_get((uint8_t *)buf, &len);
457+
if (err_code != NRF_SUCCESS) {
458+
return 0;
459+
}
460+
return full_len;
461+
}
462+
452463
mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
453464
uint16_t len = 0;
454465
sd_ble_gap_device_name_get(NULL, &len);
455-
uint8_t buf[len];
456-
uint32_t err_code = sd_ble_gap_device_name_get(buf, &len);
457-
if (err_code != NRF_SUCCESS) {
458-
return NULL;
459-
}
460-
return mp_obj_new_str((char *)buf, len);
466+
char buf[len];
467+
bleio_adapter_get_name(buf, len);
468+
return mp_obj_new_str(buf, len);
461469
}
462470

463471
void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name) {

shared-bindings/_bleio/Adapter.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,10 @@ MP_PROPERTY_GETSET(bleio_adapter_address_obj,
158158
//| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``,
159159
//| to make it easy to distinguish multiple CircuitPython boards."""
160160
//|
161-
STATIC mp_obj_t bleio_adapter_get_name(mp_obj_t self) {
161+
STATIC mp_obj_t _bleio_adapter_get_name(mp_obj_t self) {
162162
return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_name(self));
163163
}
164-
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, bleio_adapter_get_name);
164+
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, _bleio_adapter_get_name);
165165

166166

167167
STATIC mp_obj_t bleio_adapter_set_name(mp_obj_t self, mp_obj_t new_name) {

shared-bindings/_bleio/Adapter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ extern bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
5050
extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self);
5151
extern bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_address_obj_t *address);
5252

53+
// Copies the adapter name into the given buffer up to len and returns the full length (may be more
54+
// than len if the buffer was too short.)
55+
uint16_t bleio_adapter_get_name(char *buf, uint16_t len);
5356
extern mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self);
5457
extern void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name);
5558

supervisor/shared/bluetooth/bluetooth.c

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@
3939

4040
#include "common-hal/_bleio/__init__.h"
4141

42+
#include "supervisor/serial.h"
4243
#include "supervisor/shared/status_leds.h"
4344
#include "supervisor/shared/tick.h"
45+
#include "supervisor/shared/title_bar.h"
46+
#include "supervisor/shared/translate/translate.h"
4447

4548
#include "py/mpstate.h"
4649

@@ -75,18 +78,13 @@ const uint8_t public_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags
7578
const uint8_t private_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags
7679
0x02, 0x0a, 0x00 // 3-5 TX power level 0
7780
};
78-
// This scan response advertises the full CIRCPYXXXX device name.
79-
uint8_t circuitpython_scan_response_data[] = {
80-
0x0a, 0x09, 0x43, 0x49, 0x52, 0x50, 0x59, 0x00, 0x00, 0x00, 0x00,
81-
#if CIRCUITPY_SERIAL_BLE
82-
0x11, 0x06, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x01, 0x00, 0xaf, 0xad
83-
#endif
84-
};
85-
81+
// This scan response advertises the full device name (if it fits.)
82+
uint8_t circuitpython_scan_response_data[31];
8683

8784
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
8885
STATIC bool boot_in_discovery_mode = false;
8986
STATIC bool advertising = false;
87+
STATIC bool _private_advertising = false;
9088
STATIC bool ble_started = false;
9189

9290
#define WORKFLOW_UNSET 0
@@ -96,6 +94,36 @@ STATIC bool ble_started = false;
9694
STATIC uint8_t workflow_state = WORKFLOW_UNSET;
9795
STATIC bool was_connected = false;
9896

97+
// To detect when the title bar changes.
98+
STATIC bool _last_connected = false;
99+
STATIC bool _last_advertising = false;
100+
101+
// Title bar status
102+
bool supervisor_bluetooth_status_dirty(void) {
103+
return _last_advertising != advertising ||
104+
_last_connected != was_connected;
105+
}
106+
107+
void supervisor_bluetooth_status(void) {
108+
serial_write("BLE:");
109+
if (advertising) {
110+
if (_private_advertising) {
111+
serial_write_compressed(translate("Reconnecting"));
112+
} else {
113+
const char *name = (char *)circuitpython_scan_response_data + 2;
114+
int len = MIN(strlen(name), sizeof(circuitpython_scan_response_data) - 2);
115+
serial_write_substring(name, len);
116+
}
117+
} else if (was_connected) {
118+
serial_write_compressed(translate("Ok"));
119+
} else {
120+
serial_write_compressed(translate("Off"));
121+
}
122+
123+
_last_connected = was_connected;
124+
_last_advertising = advertising;
125+
}
126+
99127
STATIC void supervisor_bluetooth_start_advertising(void) {
100128
if (workflow_state != WORKFLOW_ENABLED) {
101129
return;
@@ -118,6 +146,7 @@ STATIC void supervisor_bluetooth_start_advertising(void) {
118146
size_t adv_len = sizeof(private_advertising_data);
119147
const uint8_t *scan_response = NULL;
120148
size_t scan_response_len = 0;
149+
_private_advertising = true;
121150
// Advertise with less power when doing so publicly to reduce who can hear us. This will make it
122151
// harder for someone with bad intentions to pair from a distance.
123152
if (!bonded) {
@@ -126,6 +155,20 @@ STATIC void supervisor_bluetooth_start_advertising(void) {
126155
adv_len = sizeof(public_advertising_data);
127156
scan_response = circuitpython_scan_response_data;
128157
scan_response_len = sizeof(circuitpython_scan_response_data);
158+
uint16_t max_name_len = sizeof(circuitpython_scan_response_data) - 2;
159+
uint16_t name_len = bleio_adapter_get_name((char *)circuitpython_scan_response_data + 2,
160+
max_name_len);
161+
if (name_len > max_name_len) {
162+
circuitpython_scan_response_data[0] = max_name_len + 1;
163+
circuitpython_scan_response_data[1] = 0x8;
164+
} else {
165+
circuitpython_scan_response_data[0] = name_len + 1;
166+
circuitpython_scan_response_data[1] = 0x9;
167+
}
168+
scan_response_len = circuitpython_scan_response_data[0] + 1;
169+
assert(scan_response_len < 32);
170+
mp_printf(&mp_plat_print, "sr len %d\n", scan_response_len);
171+
_private_advertising = false;
129172
}
130173
uint32_t status = _common_hal_bleio_adapter_start_advertising(&common_hal_bleio_adapter_obj,
131174
true,
@@ -232,6 +275,9 @@ void supervisor_bluetooth_background(void) {
232275
supervisor_bluetooth_file_transfer_disconnected();
233276
#endif
234277
}
278+
if (was_connected != is_connected) {
279+
supervisor_title_bar_request_update(false);
280+
}
235281
was_connected = is_connected;
236282
if (!is_connected) {
237283
supervisor_bluetooth_start_advertising();
@@ -266,6 +312,7 @@ void supervisor_start_bluetooth(void) {
266312

267313
// Kick off advertisements
268314
supervisor_bluetooth_background();
315+
supervisor_title_bar_request_update(false);
269316

270317
#endif
271318
}

supervisor/shared/bluetooth/bluetooth.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,8 @@ void supervisor_stop_bluetooth(void);
3838
void supervisor_bluetooth_enable_workflow(void);
3939
void supervisor_bluetooth_disable_workflow(void);
4040

41+
// Title bar status
42+
bool supervisor_bluetooth_status_dirty(void);
43+
void supervisor_bluetooth_status(void);
44+
4145
#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H

supervisor/shared/title_bar.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
#if CIRCUITPY_WEB_WORKFLOW
3535
#include "supervisor/shared/web_workflow/web_workflow.h"
3636
#endif
37+
38+
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
39+
#include "supervisor/shared/bluetooth/bluetooth.h"
40+
#endif
41+
3742
static background_callback_t title_bar_background_cb;
3843

3944
static bool _forced_dirty = false;
@@ -55,6 +60,10 @@ void supervisor_title_bar_update(void) {
5560
supervisor_web_workflow_status();
5661
serial_write(" | ");
5762
#endif
63+
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
64+
supervisor_bluetooth_status();
65+
serial_write(" | ");
66+
#endif
5867
supervisor_execution_status();
5968
serial_write(" | ");
6069
serial_write(MICROPY_GIT_TAG);
@@ -75,6 +84,10 @@ static void title_bar_background(void *data) {
7584
dirty = dirty || supervisor_web_workflow_status_dirty();
7685
#endif
7786

87+
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
88+
dirty = dirty || supervisor_bluetooth_status_dirty();
89+
#endif
90+
7891
if (!dirty) {
7992
return;
8093
}

0 commit comments

Comments
 (0)