Add BLE status to title bar

This commit is contained in:
Scott Shawcroft 2022-08-03 14:35:28 -07:00
parent 3a2bcbc5c7
commit 83cbbc9946
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
7 changed files with 103 additions and 16 deletions

View File

@ -1539,6 +1539,14 @@ msgstr ""
msgid "Odd parity is not supported"
msgstr ""
#: supervisor/shared/bluetooth/bluetooth.c
msgid "Off"
msgstr ""
#: supervisor/shared/bluetooth/bluetooth.c
msgid "Ok"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c
msgid "Only 8 or 16 bit mono with "
@ -1791,6 +1799,10 @@ msgstr ""
msgid "Received response was invalid"
msgstr ""
#: supervisor/shared/bluetooth/bluetooth.c
msgid "Reconnecting"
msgstr ""
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""

View File

@ -449,15 +449,23 @@ bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_addre
return sd_ble_gap_addr_set(&local_address) == NRF_SUCCESS;
}
uint16_t bleio_adapter_get_name(char *buf, uint16_t len) {
uint16_t full_len = 0;
sd_ble_gap_device_name_get(NULL, &full_len);
uint32_t err_code = sd_ble_gap_device_name_get((uint8_t *)buf, &len);
if (err_code != NRF_SUCCESS) {
return 0;
}
return full_len;
}
mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
uint16_t len = 0;
sd_ble_gap_device_name_get(NULL, &len);
uint8_t buf[len];
uint32_t err_code = sd_ble_gap_device_name_get(buf, &len);
if (err_code != NRF_SUCCESS) {
return NULL;
}
return mp_obj_new_str((char *)buf, len);
char buf[len];
bleio_adapter_get_name(buf, len);
return mp_obj_new_str(buf, len);
}
void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name) {

View File

@ -158,10 +158,10 @@ MP_PROPERTY_GETSET(bleio_adapter_address_obj,
//| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``,
//| to make it easy to distinguish multiple CircuitPython boards."""
//|
STATIC mp_obj_t bleio_adapter_get_name(mp_obj_t self) {
STATIC mp_obj_t _bleio_adapter_get_name(mp_obj_t self) {
return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_name(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, bleio_adapter_get_name);
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, _bleio_adapter_get_name);
STATIC mp_obj_t bleio_adapter_set_name(mp_obj_t self, mp_obj_t new_name) {

View File

@ -50,6 +50,9 @@ extern bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self);
extern bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_address_obj_t *address);
// Copies the adapter name into the given buffer up to len and returns the full length (may be more
// than len if the buffer was too short.)
uint16_t bleio_adapter_get_name(char *buf, uint16_t len);
extern mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self);
extern void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name);

View File

@ -39,8 +39,11 @@
#include "common-hal/_bleio/__init__.h"
#include "supervisor/serial.h"
#include "supervisor/shared/status_leds.h"
#include "supervisor/shared/tick.h"
#include "supervisor/shared/title_bar.h"
#include "supervisor/shared/translate/translate.h"
#include "py/mpstate.h"
@ -75,18 +78,13 @@ const uint8_t public_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags
const uint8_t private_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags
0x02, 0x0a, 0x00 // 3-5 TX power level 0
};
// This scan response advertises the full CIRCPYXXXX device name.
uint8_t circuitpython_scan_response_data[] = {
0x0a, 0x09, 0x43, 0x49, 0x52, 0x50, 0x59, 0x00, 0x00, 0x00, 0x00,
#if CIRCUITPY_SERIAL_BLE
0x11, 0x06, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x01, 0x00, 0xaf, 0xad
#endif
};
// This scan response advertises the full device name (if it fits.)
uint8_t circuitpython_scan_response_data[31];
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
STATIC bool boot_in_discovery_mode = false;
STATIC bool advertising = false;
STATIC bool _private_advertising = false;
STATIC bool ble_started = false;
#define WORKFLOW_UNSET 0
@ -96,6 +94,36 @@ STATIC bool ble_started = false;
STATIC uint8_t workflow_state = WORKFLOW_UNSET;
STATIC bool was_connected = false;
// To detect when the title bar changes.
STATIC bool _last_connected = false;
STATIC bool _last_advertising = false;
// Title bar status
bool supervisor_bluetooth_status_dirty(void) {
return _last_advertising != advertising ||
_last_connected != was_connected;
}
void supervisor_bluetooth_status(void) {
serial_write("BLE:");
if (advertising) {
if (_private_advertising) {
serial_write_compressed(translate("Reconnecting"));
} else {
const char *name = (char *)circuitpython_scan_response_data + 2;
int len = MIN(strlen(name), sizeof(circuitpython_scan_response_data) - 2);
serial_write_substring(name, len);
}
} else if (was_connected) {
serial_write_compressed(translate("Ok"));
} else {
serial_write_compressed(translate("Off"));
}
_last_connected = was_connected;
_last_advertising = advertising;
}
STATIC void supervisor_bluetooth_start_advertising(void) {
if (workflow_state != WORKFLOW_ENABLED) {
return;
@ -118,6 +146,7 @@ STATIC void supervisor_bluetooth_start_advertising(void) {
size_t adv_len = sizeof(private_advertising_data);
const uint8_t *scan_response = NULL;
size_t scan_response_len = 0;
_private_advertising = true;
// Advertise with less power when doing so publicly to reduce who can hear us. This will make it
// harder for someone with bad intentions to pair from a distance.
if (!bonded) {
@ -126,6 +155,20 @@ STATIC void supervisor_bluetooth_start_advertising(void) {
adv_len = sizeof(public_advertising_data);
scan_response = circuitpython_scan_response_data;
scan_response_len = sizeof(circuitpython_scan_response_data);
uint16_t max_name_len = sizeof(circuitpython_scan_response_data) - 2;
uint16_t name_len = bleio_adapter_get_name((char *)circuitpython_scan_response_data + 2,
max_name_len);
if (name_len > max_name_len) {
circuitpython_scan_response_data[0] = max_name_len + 1;
circuitpython_scan_response_data[1] = 0x8;
} else {
circuitpython_scan_response_data[0] = name_len + 1;
circuitpython_scan_response_data[1] = 0x9;
}
scan_response_len = circuitpython_scan_response_data[0] + 1;
assert(scan_response_len < 32);
mp_printf(&mp_plat_print, "sr len %d\n", scan_response_len);
_private_advertising = false;
}
uint32_t status = _common_hal_bleio_adapter_start_advertising(&common_hal_bleio_adapter_obj,
true,
@ -232,6 +275,9 @@ void supervisor_bluetooth_background(void) {
supervisor_bluetooth_file_transfer_disconnected();
#endif
}
if (was_connected != is_connected) {
supervisor_title_bar_request_update(false);
}
was_connected = is_connected;
if (!is_connected) {
supervisor_bluetooth_start_advertising();
@ -266,6 +312,7 @@ void supervisor_start_bluetooth(void) {
// Kick off advertisements
supervisor_bluetooth_background();
supervisor_title_bar_request_update(false);
#endif
}

View File

@ -38,4 +38,8 @@ void supervisor_stop_bluetooth(void);
void supervisor_bluetooth_enable_workflow(void);
void supervisor_bluetooth_disable_workflow(void);
// Title bar status
bool supervisor_bluetooth_status_dirty(void);
void supervisor_bluetooth_status(void);
#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H

View File

@ -34,6 +34,11 @@
#if CIRCUITPY_WEB_WORKFLOW
#include "supervisor/shared/web_workflow/web_workflow.h"
#endif
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
#include "supervisor/shared/bluetooth/bluetooth.h"
#endif
static background_callback_t title_bar_background_cb;
static bool _forced_dirty = false;
@ -55,6 +60,10 @@ void supervisor_title_bar_update(void) {
supervisor_web_workflow_status();
serial_write(" | ");
#endif
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
supervisor_bluetooth_status();
serial_write(" | ");
#endif
supervisor_execution_status();
serial_write(" | ");
serial_write(MICROPY_GIT_TAG);
@ -75,6 +84,10 @@ static void title_bar_background(void *data) {
dirty = dirty || supervisor_web_workflow_status_dirty();
#endif
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
dirty = dirty || supervisor_bluetooth_status_dirty();
#endif
if (!dirty) {
return;
}