Skip to content

Commit ac95106

Browse files
committed
service discovery works; need to work on char and descriptor discovery
1 parent a995a5c commit ac95106

File tree

11 files changed

+53
-23
lines changed

11 files changed

+53
-23
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *
149149
}
150150

151151
descriptor->handle = bleio_adapter_add_attribute(&common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(descriptor));
152+
// Include this desriptor in the service handles range.
153+
self->service->end_handle = descriptor->handle;
152154

153155
// Link together all the descriptors for this characteristic.
154156
descriptor->next = self->descriptor_list;

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uu
4242
vm_used_ble = true;
4343

4444
self->handle = bleio_adapter_add_attribute(&common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(self));
45+
self->start_handle = self->handle;
46+
self->end_handle = self->handle;
4547
if (self->handle == BLE_GATT_HANDLE_INVALID) {
4648
return 1;
4749
}
@@ -90,10 +92,12 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
9092
}
9193
characteristic->decl_handle = bleio_adapter_add_attribute(
9294
&common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(characteristic));
93-
// This is the value handle
95+
// This is the value handle.
9496
characteristic->handle = bleio_adapter_add_attribute(
9597
&common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(characteristic));
9698

99+
self->end_handle = characteristic->handle;
100+
97101
if (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) {
98102
// We need a CCCD.
99103
bleio_descriptor_obj_t *cccd = m_new_obj(bleio_descriptor_obj_t);
@@ -107,6 +111,8 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
107111
cccd->handle = cccd_handle;
108112
characteristic->cccd_handle = cccd_handle;
109113
common_hal_bleio_characteristic_add_descriptor(characteristic, cccd);
114+
115+
self->end_handle = cccd_handle;
110116
}
111117

112118
// #if CIRCUITPY_VERBOSE_BLE

devices/ble_hci/common-hal/_bleio/Service.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ typedef struct bleio_service_obj {
4343
// A local service doesn't know the connection.
4444
mp_obj_t connection;
4545
mp_obj_list_t *characteristic_list;
46-
// Range of attribute handles of this remote service.
46+
// Range of attribute handles of this service.
4747
uint16_t start_handle;
4848
uint16_t end_handle;
4949
struct bleio_service_obj* next;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
#include "shared-bindings/_bleio/UUID.h"
3939
#include "supervisor/shared/bluetooth.h"
4040

41+
bool vm_used_ble;
42+
4143
void check_hci_error(hci_result_t result) {
4244
switch (result) {
4345
case HCI_OK:
@@ -110,6 +112,8 @@ void check_hci_error(hci_result_t result) {
110112

111113
// Turn off BLE on a reset or reload.
112114
void bleio_reset() {
115+
bleio_hci_reset();
116+
113117
if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
114118
return;
115119
}

devices/ble_hci/common-hal/_bleio/__init__.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@ void check_gatt_status(uint16_t gatt_status);
5757
void check_sec_status(uint8_t sec_status);
5858

5959
// Track if the user code modified the BLE state to know if we need to undo it on reload.
60-
bool vm_used_ble;
60+
extern bool vm_used_ble;
6161

6262
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H

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

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ STATIC void check_and_save_expected_rsp(uint16_t conn_handle, uint8_t opcode, ui
116116
}
117117
}
118118

119-
void att_init(void) {
119+
void bleio_att_reset(void) {
120120
max_mtu = BT_ATT_DEFAULT_LE_MTU;
121121
timeout = 5000;
122122
long_write_handle = BLE_GATT_HANDLE_INVALID;
@@ -884,6 +884,8 @@ void process_read_by_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen,
884884
struct bt_att_read_group_req *req = (struct bt_att_read_group_req *) data;
885885
uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8);
886886

887+
// We only support returning services for BT_ATT_OP_READ_GROUP_REQ, which is typically used
888+
// for service discovery.
887889
if (dlen != sizeof(struct bt_att_read_group_req) + sizeof(type_uuid) ||
888890
(type_uuid != BLE_TYPE_PRIMARY_SERVICE &&
889891
type_uuid != BLE_TYPE_SECONDARY_SERVICE)) {
@@ -897,7 +899,7 @@ void process_read_by_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen,
897899
} rsp_t;
898900

899901
uint8_t rsp_bytes[mtu];
900-
rsp_t *rsp = (rsp_t *) &rsp_bytes;
902+
rsp_t *rsp = (rsp_t *) rsp_bytes;
901903
rsp->h.code = BT_ATT_OP_READ_GROUP_RSP;
902904
rsp->r.len = 0;
903905

@@ -907,13 +909,22 @@ void process_read_by_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen,
907909
bool no_data = true;
908910

909911
// All the data chunks must have uuid's that are the same size.
910-
// Keep track fo the first one to make sure.
912+
// Keep track of the first one to make sure.
911913
size_t sizeof_first_service_uuid = 0;
914+
915+
// Size of a single bt_att_group_data chunk. Start with the intial size, and
916+
// add the uuid size in the loop below.
917+
size_t data_length = sizeof(struct bt_att_group_data);
918+
912919
const uint16_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
913920
for (uint16_t handle = req->start_handle;
914921
handle <= max_attribute_handle && handle <= req->end_handle;
915922
handle++) {
916-
no_data = false;
923+
924+
if (rsp_length + data_length > mtu) {
925+
// The next possible bt_att_group_data chunk won't fit. The response is full.
926+
break;
927+
}
917928

918929
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
919930
if (type_uuid != bleio_attribute_type_uuid(attribute_obj)) {
@@ -925,33 +936,28 @@ void process_read_by_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen,
925936

926937
// Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute
927938
// in this transmission.
928-
const uint8_t sizeof_service_uuid = common_hal_bleio_uuid_get_size(service->uuid) / 8;
939+
const uint32_t sizeof_service_uuid = common_hal_bleio_uuid_get_size(service->uuid) / 8;
929940
if (sizeof_first_service_uuid == 0) {
930941
sizeof_first_service_uuid = sizeof_service_uuid;
942+
data_length += sizeof_service_uuid;
931943
} else if (sizeof_first_service_uuid != sizeof_service_uuid) {
932-
// Mismatched sizes. Transmit just what we have so far in this batch.
944+
// Mismatched sizes, which can't be in the same batch.
945+
// Transmit just what we have so far in this batch.
933946
break;
934947
}
935948

936-
// Size of bt_att_group_data chunk with uuid.
937-
const uint16_t data_length = sizeof(struct bt_att_group_data) + sizeof_service_uuid;
938-
939-
if (rsp_length + data_length > mtu) {
940-
// No room for another bt_att_group_data chunk.
941-
break;
942-
}
943949

944950
// Pass the length of ONE bt_att_group_data chunk. There may be multiple ones in this transmission.
945951
rsp->r.len = data_length;
946952

947-
uint8_t group_data_bytes[data_length];
948-
struct bt_att_group_data *group_data = (struct bt_att_group_data *) group_data_bytes;
953+
struct bt_att_group_data *group_data = (struct bt_att_group_data *) &rsp_bytes[rsp_length];
949954

950955
group_data->start_handle = service->start_handle;
951956
group_data->end_handle = service->end_handle;
952957
common_hal_bleio_uuid_pack_into(service->uuid, group_data->value);
953958

954959
rsp_length += data_length;
960+
no_data = false;
955961
}
956962

957963
if (no_data) {

devices/ble_hci/common-hal/_bleio/att.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "hci_include/att.h"
3131
#include "hci_include/att_internal.h"
3232

33+
void bleio_att_reset(void);
34+
3335
//FIX BLEDevice att_central(void);
3436
//FIX BLERemoteDevice* att_device(uint8_t address_type, const uint8_t address[6]);
3537
//FIX void att_set_event_handler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler);

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,20 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
272272
}
273273
}
274274

275-
void hci_init(void) {
275+
void bleio_hci_reset(void) {
276276
rx_idx = 0;
277277
pending_pkt = 0;
278278
hci_poll_in_progress = false;
279+
280+
bleio_att_reset();
279281
}
280282

281283
hci_result_t hci_poll_for_incoming_pkt_timeout(uint32_t timeout_msecs) {
282284
uint64_t start = supervisor_ticks_ms64();
283285

284-
hci_result_t result;
286+
hci_result_t result = HCI_OK;
285287

286-
while (supervisor_ticks_ms64() -start < timeout_msecs) {
288+
while (supervisor_ticks_ms64() - start < timeout_msecs) {
287289
result = hci_poll_for_incoming_pkt();
288290
RUN_BACKGROUND_TASKS;
289291
}

devices/ble_hci/common-hal/_bleio/hci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ typedef int hci_result_t;
3939
#define HCI_WRITE_ERROR (-5)
4040
#define HCI_ATT_ERROR (-6)
4141

42-
void hci_init(void);
42+
void bleio_hci_reset(void);
4343

4444
hci_result_t hci_disconnect(uint16_t handle);
4545

main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
105105
static size_t PLACE_IN_DTCM_BSS(_pystack[CIRCUITPY_PYSTACK_SIZE / sizeof(size_t)]);
106106
#endif
107107

108+
static void reset_devices(void) {
109+
#if CIRCUITPY_BLEIO_HCI
110+
bleio_reset();
111+
#endif
112+
}
113+
108114
void start_mp(supervisor_allocation* heap) {
109115
reset_status_led();
110116
autoreload_stop();
@@ -459,6 +465,8 @@ int __attribute__((used)) main(void) {
459465

460466
// Reset everything and prep MicroPython to run boot.py.
461467
reset_port();
468+
// Port-independent devices, like CIRCUITPY_BLEIO_HCI.
469+
reset_devices();
462470
reset_board();
463471

464472
// Turn on autoreload by default but before boot.py in case it wants to change it.

0 commit comments

Comments
 (0)