Skip to content

Commit dc76306

Browse files
committed
Enable a BLE workflow
nRF CircuitPython boards will now provide the file transfer service defined here: https://github.com/adafruit/Adafruit_CircuitPython_BLE_File_Transfer USB capable boards will only advertise if previously bonded to a device or if the reset button is pressed during the fast blue flashes on start up. When pressed, the board will restart again but the blue period will not flash. Boards without USB will always advertise. When previously bonded, the advertisement is private so that no other peers can connect. If advertising publicly, the tx power is lowered to reduce the likelihood of bonding from a distance. This PR also fixes issues with loading identities of bonded peers so that our address can now be resolved and we can resolve others' addresses when scanning.
1 parent b81573d commit dc76306

34 files changed

+1203
-411
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ jobs:
139139
run: |
140140
echo "Uploading dev release to PyPi"
141141
python setup.py sdist
142-
twine upload dist/*
142+
[ -z "$TWINE_USERNAME" ] || twine upload dist/*
143143
144144
mpy-cross-mac:
145145
runs-on: macos-10.15

devices/ble_hci/common-hal/_bleio/Adapter.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,11 @@ STATIC void check_data_fit(size_t data_len, bool connectable) {
645645
// return true;
646646
// }
647647

648-
uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len, mp_int_t tx_power) {
648+
uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
649+
bool connectable, bool anonymous, uint32_t timeout, float interval,
650+
const uint8_t *advertising_data, uint16_t advertising_data_len,
651+
const uint8_t *scan_response_data, uint16_t scan_response_data_len,
652+
mp_int_t tx_power, const bleio_address_obj_t *directed_to) {
649653
check_enabled(self);
650654

651655
if (self->now_advertising) {
@@ -769,7 +773,11 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
769773
return 0;
770774
}
771775

772-
void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo, mp_int_t tx_power) {
776+
void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
777+
bool connectable, bool anonymous, uint32_t timeout, mp_float_t interval,
778+
mp_buffer_info_t *advertising_data_bufinfo,
779+
mp_buffer_info_t *scan_response_data_bufinfo,
780+
mp_int_t tx_power, const bleio_address_obj_t *directed_to) {
773781
check_enabled(self);
774782

775783
// interval value has already been validated.
@@ -803,7 +811,7 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
803811
advertising_data_bufinfo->len,
804812
scan_response_data_bufinfo->buf,
805813
scan_response_data_bufinfo->len,
806-
tx_power);
814+
tx_power, directed_to);
807815

808816
if (result) {
809817
mp_raise_bleio_BluetoothError(translate("Already advertising"));

devices/ble_hci/common-hal/_bleio/PacketBuffer.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self
148148
return ret;
149149
}
150150

151-
mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t *header, size_t header_len) {
151+
mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self,
152+
const uint8_t *data, size_t len, uint8_t *header, size_t header_len) {
152153
if (self->outgoing[0] == NULL) {
153154
mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic"));
154155
}

locale/circuitpython.pot

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -595,10 +595,6 @@ msgstr ""
595595
msgid "Buffer must be at least length 1"
596596
msgstr ""
597597

598-
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
599-
msgid "Buffer too large and unable to allocate"
600-
msgstr ""
601-
602598
#: shared-bindings/_bleio/PacketBuffer.c
603599
#, c-format
604600
msgid "Buffer too short by %d bytes"
@@ -873,6 +869,10 @@ msgstr ""
873869
msgid "Data chunk must follow fmt chunk"
874870
msgstr ""
875871

872+
#: ports/nrf/common-hal/_bleio/Adapter.c
873+
msgid "Data not supported with directed advertising"
874+
msgstr ""
875+
876876
#: ports/nrf/common-hal/_bleio/Adapter.c
877877
msgid "Data too large for advertisement packet"
878878
msgstr ""
@@ -1667,7 +1667,6 @@ msgstr ""
16671667
msgid "Not a valid IP string"
16681668
msgstr ""
16691669

1670-
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
16711670
#: ports/nrf/common-hal/_bleio/__init__.c
16721671
#: shared-bindings/_bleio/CharacteristicBuffer.c
16731672
msgid "Not connected"
@@ -1710,6 +1709,10 @@ msgid ""
17101709
"Only Windows format, uncompressed BMP supported: given header size is %d"
17111710
msgstr ""
17121711

1712+
#: shared-bindings/_bleio/Adapter.c
1713+
msgid "Only connectable advertisements can be directed"
1714+
msgstr ""
1715+
17131716
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
17141717
msgid "Only edge detection is available on this hardware"
17151718
msgstr ""

main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,11 @@ int __attribute__((used)) main(void) {
696696

697697
stack_init();
698698

699+
#if CIRCUITPY_BLEIO
700+
// Early init so that a reset press can cause BLE public advertising.
701+
supervisor_bluetooth_init();
702+
#endif
703+
699704
// Create a new filesystem only if we're not in a safe mode.
700705
// A power brownout here could make it appear as if there's
701706
// no SPI flash filesystem, and we might erase the existing one.

ports/nrf/bluetooth/ble_drv.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include "py/mpstate.h"
4040

4141
#include "supervisor/shared/bluetooth.h"
42-
#include "supervisor/bluetooth.h"
4342

4443
nrf_nvic_state_t nrf_nvic_state = { 0 };
4544

@@ -56,6 +55,14 @@ void ble_drv_reset() {
5655
}
5756

5857
void ble_drv_add_event_handler_entry(ble_drv_evt_handler_entry_t *entry, ble_drv_evt_handler_t func, void *param) {
58+
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
59+
while (it != NULL) {
60+
// If event handler and its corresponding param are already on the list, don't add again.
61+
if ((it->func == func) && (it->param == param)) {
62+
return;
63+
}
64+
it = it->next;
65+
}
5966
entry->next = MP_STATE_VM(ble_drv_evt_handler_entries);
6067
entry->param = param;
6168
entry->func = func;
@@ -85,6 +92,8 @@ void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param) {
8592
if ((it->func == func) && (it->param == param)) {
8693
// Splice out the matching handler.
8794
*prev = it->next;
95+
// Clear next of the removed node so it's clearly not in a list.
96+
it->next = NULL;
8897
return;
8998
}
9099
prev = &(it->next);
@@ -138,21 +147,26 @@ void SD_EVT_IRQHandler(void) {
138147

139148
ble_evt_t *event = (ble_evt_t *)m_ble_evt_buf;
140149
#if CIRCUITPY_VERBOSE_BLE
141-
mp_printf(&mp_plat_print, "BLE event: 0x%04x\n", event->header.evt_id);
142-
#endif
143-
144-
if (supervisor_bluetooth_hook(event)) {
145-
continue;
150+
size_t eid = event->header.evt_id;
151+
if (eid != 0x1d) {
152+
if (BLE_GAP_EVT_BASE <= eid && eid <= BLE_GAP_EVT_LAST) {
153+
mp_printf(&mp_plat_print, "BLE GAP event: %d\n", eid - BLE_GAP_EVT_BASE);
154+
} else {
155+
mp_printf(&mp_plat_print, "BLE event: 0x%04x\n", event->header.evt_id);
156+
}
146157
}
158+
#endif
147159

148160
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
149161
bool done = false;
150162
while (it != NULL) {
151163
#if CIRCUITPY_VERBOSE_BLE
152-
// mp_printf(&mp_plat_print, " calling handler: 0x%08lx, param: 0x%08lx\n", it->func-1, it->param);
164+
// mp_printf(&mp_plat_print, " calling handler: 0x%08lx, param: 0x%08lx\n", it->func - 1, it->param);
153165
#endif
166+
// Capture next before calling the function in case it removes itself from the list.
167+
ble_drv_evt_handler_entry_t *next = it->next;
154168
done = it->func(event, it->param) || done;
155-
it = it->next;
169+
it = next;
156170
}
157171
#if CIRCUITPY_VERBOSE_BLE
158172
if (event->header.evt_id == BLE_GATTS_EVT_WRITE) {

0 commit comments

Comments
 (0)