Skip to content

Commit da48ab0

Browse files
committed
add generic services
1 parent 1c8e11b commit da48ab0

File tree

2 files changed

+128
-16
lines changed

2 files changed

+128
-16
lines changed

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

Lines changed: 122 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,114 @@
7474

7575
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
7676

77+
STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
78+
// Create Generic Access UUID, Service, and Characteristics.
79+
80+
// Generic Access Service setup.
81+
82+
bleio_uuid_obj_t *generic_access_service_uuid = m_new_obj(bleio_uuid_obj_t);
83+
generic_access_service_uuid->base.type = &bleio_uuid_type;
84+
common_hal_bleio_uuid_construct(generic_access_service_uuid, 0x1800, NULL);
85+
86+
bleio_uuid_obj_t *device_name_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
87+
device_name_characteristic_uuid->base.type = &bleio_uuid_type;
88+
common_hal_bleio_uuid_construct(device_name_characteristic_uuid, 0x2A00, NULL);
89+
90+
bleio_uuid_obj_t *appearance_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
91+
appearance_characteristic_uuid->base.type = &bleio_uuid_type;
92+
common_hal_bleio_uuid_construct(appearance_characteristic_uuid, 0x2A01, NULL);
93+
94+
// Not implemented:
95+
// Peripheral Preferred Connection Parameters
96+
// Central Address Resolution
97+
98+
bleio_service_obj_t *generic_access_service = m_new_obj(bleio_service_obj_t);
99+
generic_access_service->base.type = &bleio_service_type;
100+
common_hal_bleio_service_construct(generic_access_service, generic_access_service_uuid, false);
101+
102+
adapter->device_name_characteristic = m_new_obj(bleio_characteristic_obj_t);
103+
adapter->device_name_characteristic->base.type = &bleio_characteristic_type;
104+
105+
char generic_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 'n', 'n', 'n', 'n' };
106+
mp_buffer_info_t generic_name_bufinfo = {
107+
.buf = generic_name,
108+
.len = sizeof(generic_name),
109+
};
110+
111+
// Will be added to service by constructor.
112+
common_hal_bleio_characteristic_construct(
113+
adapter->device_name_characteristic,
114+
generic_access_service,
115+
BLE_GATT_HANDLE_INVALID,
116+
device_name_characteristic_uuid,
117+
CHAR_PROP_READ,
118+
SECURITY_MODE_OPEN,
119+
SECURITY_MODE_NO_ACCESS,
120+
248, // max length, from Bluetooth spec
121+
false, // not fixed length
122+
&generic_name_bufinfo
123+
);
124+
125+
uint16_t zero_16 = 0;
126+
mp_buffer_info_t zero_16_value = {
127+
.buf = &zero_16,
128+
.len = sizeof(zero_16),
129+
};
130+
131+
adapter->appearance_characteristic = m_new_obj(bleio_characteristic_obj_t);
132+
adapter->appearance_characteristic->base.type = &bleio_characteristic_type;
133+
134+
common_hal_bleio_characteristic_construct(
135+
adapter->appearance_characteristic,
136+
generic_access_service,
137+
BLE_GATT_HANDLE_INVALID,
138+
appearance_characteristic_uuid,
139+
CHAR_PROP_READ,
140+
SECURITY_MODE_OPEN,
141+
SECURITY_MODE_NO_ACCESS,
142+
2, // max length, from Bluetooth spec
143+
true, // fixed length
144+
&zero_16_value
145+
);
146+
147+
// Generic Attribute Service setup.
148+
149+
bleio_uuid_obj_t *generic_attribute_service_uuid = m_new_obj(bleio_uuid_obj_t);
150+
generic_attribute_service_uuid->base.type = &bleio_uuid_type;
151+
common_hal_bleio_uuid_construct(generic_attribute_service_uuid, 0x1801, NULL);
152+
153+
bleio_uuid_obj_t *service_changed_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
154+
service_changed_characteristic_uuid->base.type = &bleio_uuid_type;
155+
common_hal_bleio_uuid_construct(service_changed_characteristic_uuid, 0x2A05, NULL);
156+
157+
bleio_service_obj_t *generic_attribute_service = m_new_obj(bleio_service_obj_t);
158+
generic_attribute_service->base.type = &bleio_service_type;
159+
common_hal_bleio_service_construct(generic_attribute_service, generic_attribute_service_uuid, false);
160+
161+
adapter->service_changed_characteristic = m_new_obj(bleio_characteristic_obj_t);
162+
adapter->service_changed_characteristic->base.type = &bleio_characteristic_type;
163+
164+
uint32_t zero_32 = 0;
165+
mp_buffer_info_t zero_32_value = {
166+
.buf = &zero_32,
167+
.len = sizeof(zero_32),
168+
};
169+
170+
common_hal_bleio_characteristic_construct(
171+
adapter->service_changed_characteristic,
172+
generic_attribute_service,
173+
BLE_GATT_HANDLE_INVALID,
174+
service_changed_characteristic_uuid,
175+
CHAR_PROP_INDICATE,
176+
SECURITY_MODE_OPEN,
177+
SECURITY_MODE_NO_ACCESS,
178+
4, // max length, from Bluetooth spec
179+
true, // fixed length
180+
&zero_32_value
181+
);
182+
}
183+
184+
77185
STATIC void check_enabled(bleio_adapter_obj_t *adapter) {
78186
if (!common_hal_bleio_adapter_get_enabled(adapter)) {
79187
mp_raise_bleio_BluetoothError(translate("Adapter not enabled"));
@@ -163,10 +271,13 @@ STATIC void check_enabled(bleio_adapter_obj_t *adapter) {
163271
// return true;
164272
// }
165273

166-
char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 , 0};
274+
char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0};
275+
276+
// Get various values and limits set by the adapter.
277+
// Set event mask.
278+
STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) {
167279

168-
STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) {
169-
uint8_t len = sizeof(default_ble_name) - 1;
280+
const size_t len = sizeof(default_ble_name);
170281

171282
bt_addr_t addr;
172283
check_hci_error(hci_read_bd_addr(&addr));
@@ -175,14 +286,7 @@ STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) {
175286
default_ble_name[len - 3] = nibble_to_hex_lower[addr.val[1] & 0xf];
176287
default_ble_name[len - 2] = nibble_to_hex_lower[addr.val[0] >> 4 & 0xf];
177288
default_ble_name[len - 1] = nibble_to_hex_lower[addr.val[0] & 0xf];
178-
default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
179-
180-
common_hal_bleio_adapter_set_name(self, (char*) default_ble_name);
181-
}
182-
183-
// Get various values and limits set by the adapter.
184-
// Set event mask.
185-
STATIC void bleio_adapter_setup(bleio_adapter_obj_t *self) {
289+
self->name = mp_obj_new_str(default_ble_name, len);
186290

187291
// Get version information.
188292
if (hci_read_local_version(&self->hci_version, &self->hci_revision, &self->lmp_version,
@@ -246,8 +350,8 @@ void common_hal_bleio_adapter_hci_uart_init(bleio_adapter_obj_t *self, busio_uar
246350
self->enabled = false;
247351

248352
common_hal_bleio_adapter_set_enabled(self, true);
249-
bleio_adapter_setup(self);
250-
bleio_adapter_reset_name(self);
353+
bleio_adapter_hci_init(self);
354+
common_hal_bleio_adapter_set_name(self, default_ble_name);
251355
}
252356

253357
void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled) {
@@ -281,8 +385,7 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
281385
// so store None there to skip it.
282386
self->attributes = mp_obj_new_list(0, NULL);
283387
bleio_adapter_add_attribute(self, mp_const_none);
284-
self->last_added_service_handle = BLE_GATT_HANDLE_INVALID;
285-
self->last_added_characteristic_handle = BLE_GATT_HANDLE_INVALID;
388+
add_generic_services(self);
286389
}
287390
}
288391

@@ -309,6 +412,9 @@ mp_obj_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
309412

310413
void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name) {
311414
self->name = mp_obj_new_str(name, strlen(name));
415+
mp_buffer_info_t bufinfo;
416+
mp_get_buffer_raise(self->name, &bufinfo, MP_BUFFER_READ);
417+
bleio_characteristic_set_local_value(self->device_name_characteristic, &bufinfo);
312418
}
313419

314420

@@ -637,7 +743,7 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
637743
check_hci_error(hci_le_set_advertising_data(advertising_data_len, full_data));
638744
memset(full_data, 0, sizeof(full_data));
639745
if (scan_response_data_len > 0) {
640-
memcpy(full_data, advertising_data, MIN(sizeof(full_data), scan_response_data_len));
746+
memcpy(full_data, scan_response_data, MIN(sizeof(full_data), scan_response_data_len));
641747
check_hci_error(hci_le_set_scan_response_data(scan_response_data_len, full_data));
642748
}
643749

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "py/obj.h"
3333
#include "py/objtuple.h"
3434

35+
#include "shared-bindings/_bleio/Characteristic.h"
3536
#include "shared-bindings/_bleio/Connection.h"
3637
#include "shared-bindings/_bleio/ScanResults.h"
3738
#include "shared-bindings/busio/UART.h"
@@ -67,6 +68,11 @@ typedef struct _bleio_adapter_obj_t {
6768
uint64_t advertising_start_ticks;
6869
uint64_t advertising_timeout_msecs; // If zero, do not check.
6970

71+
// Generic services characteristics.
72+
bleio_characteristic_obj_t *device_name_characteristic;
73+
bleio_characteristic_obj_t *appearance_characteristic;
74+
bleio_characteristic_obj_t * service_changed_characteristic;
75+
7076
uint16_t max_acl_buffer_len;
7177
uint16_t max_acl_num_buffers;
7278
uint16_t max_adv_data_len;

0 commit comments

Comments
 (0)