Skip to content

Commit a76ad34

Browse files
committed
wip: implementing functionality
1 parent e6bd99a commit a76ad34

File tree

11 files changed

+209
-273
lines changed

11 files changed

+209
-273
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,12 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
240240
self->advertising_timeout_msecs = 0;
241241

242242
// Reset list of known attributes.
243+
// Indices into the list are handles. Handle 0x0000 designates an invalid handle,
244+
// so store None there to skip it.
243245
self->attributes = mp_obj_new_list(0, NULL);
246+
bleio_adapter_add_attribute(mp_const_none);
247+
self->last_added_service_handle = BLE_GATT_HANDLE_INVALID;
248+
self->last_added_characteristic_handle = BLE_GATT_HANDLE_INVALID;
244249
}
245250

246251
bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {
@@ -683,6 +688,25 @@ void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) {
683688
//FIX bonding_erase_storage();
684689
}
685690

691+
uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute) {
692+
// The handle is the index of this attribute in the attributes list.
693+
uint16_t handle = (uint16_t) adapter->attributes->len;
694+
mp_obj_list_append(adapter->attributes, attribute);
695+
return handle;
696+
}
697+
698+
mp_obj_t* bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle) {
699+
if (handle == 0 || handle >= adapter->attributes->len) {
700+
return mp_const_none;
701+
}
702+
return adapter->attributes->items[handle];
703+
}
704+
705+
uint16_t bleio_adapter_max_attribute_handle(bleio_adapter_obj_t *adapter) {
706+
return adapter->attributes->len - 1;
707+
}
708+
709+
686710
void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) {
687711
gc_collect_root((void**)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t));
688712
gc_collect_root((void**)bleio_connections, sizeof(bleio_connections) / sizeof(size_t));

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,15 @@ typedef struct _bleio_adapter_obj_t {
6868
// All the local attributes for this device. The index into the list
6969
// corresponds to the handle.
7070
mp_obj_list_t *attributes;
71+
// Handle for last added service. Characteristics can only be added immediately after
72+
// the service they belong to. This vets that.
73+
uint16_t last_added_service_handle;
74+
uint16_t last_added_characteristic_handle;
7175
} bleio_adapter_obj_t;
7276

77+
uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute);
78+
mp_obj_t* bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle);
79+
uint16_t bleio_adapter_max_attribute_handle(bleio_adapter_obj_t *adapter);
7380
void bleio_adapter_background(bleio_adapter_obj_t* adapter);
7481
void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter);
7582
void bleio_adapter_reset(bleio_adapter_obj_t* adapter);

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,24 @@
2525
*/
2626

2727
#include "shared-bindings/_bleio/Attribute.h"
28+
#include "shared-bindings/_bleio/Characteristic.h"
29+
#include "shared-bindings/_bleio/Descriptor.h"
30+
#include "shared-bindings/_bleio/Service.h"
2831

29-
// Return the type of the attribute
30-
bleio_attribute_type_uuid(mp_obj_t *attribute) {
31-
if mp_is_o
32+
// Return the type of the attribute.
33+
ble_attribute_type bleio_attribute_type_uuid(mp_obj_t *attribute) {
34+
if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
35+
return BLE_TYPE_CHARACTERISTIC;
36+
}
37+
if (MP_OBJ_IS_TYPE(attribute, &bleio_descriptor_type)) {
38+
return BLE_TYPE_DESCRIPTOR;
39+
}
40+
if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) {
41+
bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute);
42+
return service->is_secondary ? BLE_TYPE_SECONDARY_SERVICE : BLE_TYPE_PRIMARY_SERVICE;
43+
}
44+
return BLE_TYPE_UNKNOWN;
45+
}
3246

3347
// Convert a _bleio security mode to a ble_gap_conn_sec_mode_t setting.
3448
// void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) {

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
6+
* Copyright (c) 2020 Dan Halbert for Adafruit Industries
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -29,6 +29,15 @@
2929

3030
#include "shared-module/_bleio/Attribute.h"
3131

32+
// Types returned by attribute table lookups. These are UUIDs.
33+
enum ble_attribute_type {
34+
BLE_TYPE_UNKNOWN = 0x0000,
35+
BLE_TYPE_PRIMARY_SERVICE = 0x2800,
36+
BLE_TYPE_SECONDARY_SERVICE = 0x2801,
37+
BLE_TYPE_CHARACTERISTIC = 0x2803,
38+
BLE_TYPE_DESCRIPTOR = 0x2900
39+
};
40+
3241
// typedef struct
3342
// {
3443
// uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */

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

Lines changed: 29 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -34,58 +34,10 @@
3434

3535
#include "common-hal/_bleio/Adapter.h"
3636

37-
// STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) {
38-
// uint16_t cccd;
39-
// // ble_gatts_value_t value = {
40-
// // .p_value = (uint8_t*) &cccd,
41-
// // .len = 2,
42-
// // };
43-
44-
// // const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, cccd_handle, &value);
45-
46-
// // if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) {
47-
// // // CCCD is not set, so say that neither Notify nor Indicate is enabled.
48-
// // cccd = 0;
49-
// // } else {
50-
// // check_nrf_error(err_code);
51-
// // }
52-
53-
// return cccd;
54-
// }
55-
56-
57-
// STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, uint16_t hvx_type) {
58-
// uint16_t hvx_len = bufinfo->len;
59-
60-
// ble_gatts_hvx_params_t hvx_params = {
61-
// .handle = handle,
62-
// .type = hvx_type,
63-
// .offset = 0,
64-
// .p_len = &hvx_len,
65-
// .p_data = bufinfo->buf,
66-
// };
67-
68-
// while (1) {
69-
// const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
70-
// if (err_code == NRF_SUCCESS) {
71-
// break;
72-
// }
73-
// // TX buffer is full
74-
// // We could wait for an event indicating the write is complete, but just retrying is easier.
75-
// if (err_code == NRF_ERROR_RESOURCES) {
76-
// RUN_BACKGROUND_TASKS;
77-
// continue;
78-
// }
79-
80-
// // Some real error has occurred.
81-
// check_nrf_error(err_code);
82-
// }
83-
// }
84-
8537
void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) {
8638
self->service = service;
8739
self->uuid = uuid;
88-
//FIX self->handle = BLE_GATT_HANDLE_INVALID;
40+
self->handle = BLE_GATT_HANDLE_INVALID;
8941
self->props = props;
9042
self->read_perm = read_perm;
9143
self->write_perm = write_perm;
@@ -153,30 +105,23 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
153105
// Always write the value locally even if no connections are active.
154106
// conn_handle is ignored for non-system attributes, so we use BLE_CONN_HANDLE_INVALID.
155107
common_hal_bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo);
156-
// Check to see if we need to notify or indicate any active connections.
157-
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
158-
bleio_connection_internal_t *connection = &bleio_connections[i];
159-
uint16_t conn_handle = connection->conn_handle;
160-
if (conn_handle == BLE_CONN_HANDLE_INVALID) {
161-
continue;
162-
}
163-
164-
//FIX
165-
// uint16_t cccd = 0;
108+
// Notify or indicate all active connections.
109+
uint16_t cccd = 0;
110+
111+
const bool notify = self->props & CHAR_PROP_NOTIFY;
112+
const bool indicate = self->props & CHAR_PROP_INDICATE;
113+
// Read the CCCD value, if there is one.
114+
if ((notify | indicate) && self->cccd_handle != BLE_GATT_HANDLE_INVALID) {
115+
common_hal_bleio_gatts_read(self->cccd_handle, conn_handle, &cccd, sizeof(cccd));
116+
}
166117

167-
// const bool notify = self->props & CHAR_PROP_NOTIFY;
168-
// const bool indicate = self->props & CHAR_PROP_INDICATE;
169-
// if (notify | indicate) {
170-
// cccd = characteristic_get_cccd(self->cccd_handle, conn_handle);
171-
// }
118+
// It's possible that both notify and indicate are set.
119+
if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
120+
att_notify(self->handle, bufinfo->buf, MIN(bufinfo->len, self->max_length));
121+
}
122+
if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
123+
att_indicate(self->handle, bufinfo->buf, MIN(bufinfo->len, self->max_length));
172124

173-
// // It's possible that both notify and indicate are set.
174-
// if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
175-
// characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION);
176-
// }
177-
// if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
178-
// characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION);
179-
// }
180125
}
181126
}
182127
}
@@ -191,35 +136,16 @@ bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties
191136
}
192137

193138
void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor) {
194-
//FIX
195-
// ble_uuid_t desc_uuid;
196-
// bleio_uuid_convert_to_nrf_ble_uuid(descriptor->uuid, &desc_uuid);
197-
198-
// ble_gatts_attr_md_t desc_attr_md = {
199-
// // Data passed is not in a permanent location and should be copied.
200-
// .vloc = BLE_GATTS_VLOC_STACK,
201-
// .vlen = !descriptor->fixed_length,
202-
// };
203-
204-
// bleio_attribute_gatts_set_security_mode(&desc_attr_md.read_perm, descriptor->read_perm);
205-
// bleio_attribute_gatts_set_security_mode(&desc_attr_md.write_perm, descriptor->write_perm);
206-
207-
// mp_buffer_info_t desc_value_bufinfo;
208-
// mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ);
209-
210-
// ble_gatts_attr_t desc_attr = {
211-
// .p_uuid = &desc_uuid,
212-
// .p_attr_md = &desc_attr_md,
213-
// .init_len = desc_value_bufinfo.len,
214-
// .p_value = desc_value_bufinfo.buf,
215-
// .init_offs = 0,
216-
// .max_len = descriptor->max_length,
217-
// };
139+
if (self->handle != common_hal_bleio_adapter_obj->last_added_characteristic_handle) {
140+
mp_raise_bleio_BluetoothError(
141+
translate("Descriptor can only be added to most recently added characteristic"));
142+
}
218143

219-
// check_nrf_error(sd_ble_gatts_descriptor_add(self->handle, &desc_attr, &descriptor->handle));
144+
descriptor->handle = bleio_adapter_add_attribute(common_hal_bleio_adapter_obj, descriptor);
220145

221-
// descriptor->next = self->descriptor_list;
222-
// self->descriptor_list = descriptor;
146+
// Link together all the descriptors for this characteristic.
147+
descriptor->next = self->descriptor_list;
148+
self->descriptor_list = descriptor;
223149
}
224150

225151
void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) {
@@ -234,11 +160,12 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self,
234160
const uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
235161
common_hal_bleio_check_connected(conn_handle);
236162

237-
//FIX
238-
// uint16_t cccd_value =
239-
// (notify ? BLE_GATT_HVX_NOTIFICATION : 0) |
240-
// (indicate ? BLE_GATT_HVX_INDICATION : 0);
163+
uint16_t cccd_value =
164+
(notify ? BLE_GATT_HVX_NOTIFICATION : 0) |
165+
(indicate ? BLE_GATT_HVX_INDICATION : 0);
241166

167+
(void) cccd_value;
168+
//FIX call att_something to set remote CCCD
242169
// ble_gattc_write_params_t write_params = {
243170
// .write_op = BLE_GATT_OP_WRITE_REQ,
244171
// .handle = self->cccd_handle,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef struct _bleio_characteristic_obj {
4343
uint16_t max_length;
4444
bool fixed_length;
4545
uint16_t handle;
46+
uint16_t value_handle; // Should be handle+1.
4647
bleio_characteristic_properties_t props;
4748
bleio_attribute_security_mode_t read_perm;
4849
bleio_attribute_security_mode_t write_perm;

0 commit comments

Comments
 (0)