Skip to content

Commit cc78249

Browse files
committed
nrf: Move the Characteristic class from ubluepy to the shared bleio module
1 parent fb422cc commit cc78249

File tree

14 files changed

+578
-343
lines changed

14 files changed

+578
-343
lines changed

ports/nrf/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ DRIVERS_SRC_C += $(addprefix modules/,\
131131
ubluepy/modubluepy.c \
132132
ubluepy/ubluepy_peripheral.c \
133133
ubluepy/ubluepy_service.c \
134-
ubluepy/ubluepy_characteristic.c \
135134
)
136135

137136
SRC_COMMON_HAL += \
@@ -163,6 +162,7 @@ ifneq ($(SD), )
163162
SRC_COMMON_HAL += \
164163
bleio/__init__.c \
165164
bleio/Adapter.c \
165+
bleio/Characteristic.c \
166166
bleio/Descriptor.c \
167167
bleio/Scanner.c \
168168
bleio/UUID.c
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2018 Artur Pacholec
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "ble_drv.h"
28+
#include "shared-module/bleio/Characteristic.h"
29+
30+
void data_callback(bleio_characteristic_obj_t *self, uint16_t length, uint8_t *data) {
31+
self->value_data = mp_obj_new_bytearray(length, data);
32+
}
33+
34+
void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) {
35+
ble_drv_attr_c_read(self, data_callback);
36+
}
37+
38+
void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
39+
ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(self->service);
40+
ubluepy_role_type_t role = service->p_periph->role;
41+
42+
if (role == UBLUEPY_ROLE_PERIPHERAL) {
43+
// TODO: Add indications
44+
if (self->props.notify) {
45+
ble_drv_attr_s_notify(self, bufinfo);
46+
} else {
47+
ble_drv_attr_s_write(self, bufinfo);
48+
}
49+
} else {
50+
ble_drv_attr_c_write(self, bufinfo);
51+
}
52+
53+
}

ports/nrf/common-hal/bleio/UUID.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H
2929
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H
3030

31-
#include "py/obj.h"
3231
#include "shared-bindings/bleio/UUIDType.h"
3332

3433
typedef struct {

ports/nrf/drivers/bluetooth/ble_drv.c

Lines changed: 70 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static bleio_scanner_obj_t *mp_adv_observer;
9898
static mp_obj_t mp_gattc_observer;
9999
static mp_obj_t mp_gattc_disc_service_observer;
100100
static mp_obj_t mp_gattc_disc_char_observer;
101-
static mp_obj_t mp_gattc_char_data_observer;
101+
static bleio_characteristic_obj_t *mp_gattc_char_data_observer;
102102

103103
#if (BLUETOOTH_SD == 140)
104104
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
@@ -270,38 +270,26 @@ bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) {
270270
bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) {
271271
SD_TEST_OR_ENABLE();
272272

273-
if (p_service_obj->p_uuid->type > BLE_UUID_TYPE_BLE) {
273+
ble_uuid_t uuid;
274+
uuid.type = BLE_UUID_TYPE_BLE;
275+
uuid.uuid = p_service_obj->p_uuid->value[0] | (p_service_obj->p_uuid->value[1] << 8);
274276

275-
ble_uuid_t uuid;
277+
if (p_service_obj->p_uuid->type == UUID_TYPE_128BIT) {
276278
uuid.type = p_service_obj->p_uuid->uuid_vs_idx;
277-
uuid.uuid = p_service_obj->p_uuid->value[0];
278-
uuid.uuid += p_service_obj->p_uuid->value[1] << 8;
279-
280-
if (sd_ble_gatts_service_add(p_service_obj->type,
281-
&uuid,
282-
&p_service_obj->handle) != 0) {
283-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
284-
translate("Can not add Service.")));
285-
}
286-
} else if (p_service_obj->p_uuid->type == BLE_UUID_TYPE_BLE) {
287-
BLE_DRIVER_LOG("adding service\n");
288-
289-
ble_uuid_t uuid;
290-
uuid.type = p_service_obj->p_uuid->type;
291-
uuid.uuid = p_service_obj->p_uuid->value[0];
292-
uuid.uuid += p_service_obj->p_uuid->value[1] << 8;
279+
}
293280

294-
if (sd_ble_gatts_service_add(p_service_obj->type,
295-
&uuid,
296-
&p_service_obj->handle) != 0) {
297-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
298-
translate("Can not add Service.")));
299-
}
281+
uint32_t err_code = sd_ble_gatts_service_add(p_service_obj->type,
282+
&uuid,
283+
&p_service_obj->handle);
284+
if (err_code != 0) {
285+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
286+
translate("Can not add Service. status: 0x%08lX"), err_code));
300287
}
288+
301289
return true;
302290
}
303291

304-
bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) {
292+
bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic) {
305293
ble_gatts_char_md_t char_md;
306294
ble_gatts_attr_md_t cccd_md;
307295
ble_gatts_attr_t attr_char_value;
@@ -310,24 +298,19 @@ bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) {
310298

311299
memset(&char_md, 0, sizeof(char_md));
312300

313-
char_md.char_props.broadcast = (p_char_obj->props & UBLUEPY_PROP_BROADCAST) ? 1 : 0;
314-
char_md.char_props.read = (p_char_obj->props & UBLUEPY_PROP_READ) ? 1 : 0;
315-
char_md.char_props.write_wo_resp = (p_char_obj->props & UBLUEPY_PROP_WRITE_WO_RESP) ? 1 : 0;
316-
char_md.char_props.write = (p_char_obj->props & UBLUEPY_PROP_WRITE) ? 1 : 0;
317-
char_md.char_props.notify = (p_char_obj->props & UBLUEPY_PROP_NOTIFY) ? 1 : 0;
318-
char_md.char_props.indicate = (p_char_obj->props & UBLUEPY_PROP_INDICATE) ? 1 : 0;
319-
#if 0
320-
char_md.char_props.auth_signed_wr = (p_char_obj->props & UBLUEPY_PROP_NOTIFY) ? 1 : 0;
321-
#endif
322-
301+
char_md.char_props.broadcast = characteristic->props.broadcast;
302+
char_md.char_props.read = characteristic->props.read;
303+
char_md.char_props.write_wo_resp = characteristic->props.write_wo_resp;
304+
char_md.char_props.write = characteristic->props.write;
305+
char_md.char_props.notify = characteristic->props.notify;
306+
char_md.char_props.indicate = characteristic->props.indicate;
323307

324308
char_md.p_char_user_desc = NULL;
325309
char_md.p_char_pf = NULL;
326310
char_md.p_user_desc_md = NULL;
327311
char_md.p_sccd_md = NULL;
328312

329-
// if cccd
330-
if (p_char_obj->attrs & UBLUEPY_ATTR_CCCD) {
313+
if (characteristic->props.notify || characteristic->props.notify) {
331314
memset(&cccd_md, 0, sizeof(cccd_md));
332315
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
333316
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
@@ -337,9 +320,12 @@ bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) {
337320
char_md.p_cccd_md = NULL;
338321
}
339322

340-
uuid.type = p_char_obj->p_uuid->type;
341-
uuid.uuid = p_char_obj->p_uuid->value[0];
342-
uuid.uuid += p_char_obj->p_uuid->value[1] << 8;
323+
uuid.type = BLE_UUID_TYPE_BLE;
324+
if (characteristic->uuid->type == UUID_TYPE_128BIT)
325+
uuid.type = characteristic->uuid->uuid_vs_idx;
326+
327+
uuid.uuid = characteristic->uuid->value[0];
328+
uuid.uuid += characteristic->uuid->value[1] << 8;
343329

344330
memset(&attr_md, 0, sizeof(attr_md));
345331

@@ -365,19 +351,20 @@ bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) {
365351

366352
ble_gatts_char_handles_t handles;
367353

368-
if (sd_ble_gatts_characteristic_add(p_char_obj->service_handle,
369-
&char_md,
370-
&attr_char_value,
371-
&handles) != 0) {
354+
uint32_t err_code = sd_ble_gatts_characteristic_add(characteristic->service_handle,
355+
&char_md,
356+
&attr_char_value,
357+
&handles);
358+
if (err_code != 0) {
372359
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
373-
translate("Can not add Characteristic.")));
360+
translate("Can not add Characteristic. status: 0x%08lX"), err_code));
374361
}
375362

376363
// apply handles to object instance
377-
p_char_obj->handle = handles.value_handle;
378-
p_char_obj->user_desc_handle = handles.user_desc_handle;
379-
p_char_obj->cccd_handle = handles.cccd_handle;
380-
p_char_obj->sccd_handle = handles.sccd_handle;
364+
characteristic->handle = handles.value_handle;
365+
characteristic->user_desc_handle = handles.user_desc_handle;
366+
characteristic->cccd_handle = handles.cccd_handle;
367+
characteristic->sccd_handle = handles.sccd_handle;
381368

382369
return true;
383370
}
@@ -652,33 +639,38 @@ void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, ui
652639

653640
}
654641

655-
void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) {
642+
void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
643+
ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service);
644+
uint16_t conn_handle = service->p_periph->conn_handle;
656645
ble_gatts_value_t gatts_value;
646+
657647
memset(&gatts_value, 0, sizeof(gatts_value));
658648

659-
gatts_value.len = len;
649+
gatts_value.len = bufinfo->len;
660650
gatts_value.offset = 0;
661-
gatts_value.p_value = p_data;
651+
gatts_value.p_value = bufinfo->buf;
662652

663-
uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value);
653+
uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value);
664654

665655
if (err_code != 0) {
666656
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
667657
translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code));
668658
}
669659
}
670660

671-
void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) {
672-
uint16_t hvx_len = len;
661+
void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
662+
ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service);
663+
uint16_t conn_handle = service->p_periph->conn_handle;
673664
ble_gatts_hvx_params_t hvx_params;
665+
uint16_t hvx_len = bufinfo->len;
674666

675667
memset(&hvx_params, 0, sizeof(hvx_params));
676668

677-
hvx_params.handle = handle;
669+
hvx_params.handle = characteristic->handle;
678670
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
679671
hvx_params.offset = 0;
680672
hvx_params.p_len = &hvx_len;
681-
hvx_params.p_data = p_data;
673+
hvx_params.p_data = bufinfo->buf;
682674

683675
while (m_tx_in_progress) {
684676
;
@@ -713,13 +705,13 @@ void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_c
713705
}
714706

715707

716-
void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, ble_drv_gattc_char_data_callback_t cb) {
717-
718-
mp_gattc_char_data_observer = obj;
708+
void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb) {
709+
ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service);
710+
mp_gattc_char_data_observer = characteristic;
719711
gattc_char_data_handle = cb;
720712

721-
uint32_t err_code = sd_ble_gattc_read(conn_handle,
722-
handle,
713+
const uint32_t err_code = sd_ble_gattc_read(service->p_periph->conn_handle,
714+
characteristic->handle,
723715
0);
724716
if (err_code != 0) {
725717
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
@@ -731,26 +723,26 @@ void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, bl
731723
}
732724
}
733725

734-
void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response) {
726+
void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
727+
ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service);
728+
uint16_t conn_handle = service->p_periph->conn_handle;
735729

736730
ble_gattc_write_params_t write_params;
731+
write_params.write_op = BLE_GATT_OP_WRITE_REQ;
737732

738-
if (w_response) {
739-
write_params.write_op = BLE_GATT_OP_WRITE_REQ;
740-
} else {
733+
if (characteristic->props.write_wo_resp) {
741734
write_params.write_op = BLE_GATT_OP_WRITE_CMD;
742735
}
743736

744737
write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL;
745-
write_params.handle = handle;
738+
write_params.handle = characteristic->handle;
746739
write_params.offset = 0;
747-
write_params.len = len;
748-
write_params.p_value = p_data;
740+
write_params.len = bufinfo->len;
741+
write_params.p_value = bufinfo->buf;
749742

750-
m_write_done = !w_response;
743+
m_write_done = (write_params.write_op == BLE_GATT_OP_WRITE_CMD);
751744

752745
uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
753-
754746
if (err_code != 0) {
755747
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
756748
translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code));
@@ -1053,15 +1045,12 @@ static void ble_evt_handler(ble_evt_t * p_ble_evt) {
10531045
char_data.decl_handle = p_char->handle_decl;
10541046
char_data.value_handle = p_char->handle_value;
10551047

1056-
char_data.props |= (p_char->char_props.broadcast) ? UBLUEPY_PROP_BROADCAST : 0;
1057-
char_data.props |= (p_char->char_props.read) ? UBLUEPY_PROP_READ : 0;
1058-
char_data.props |= (p_char->char_props.write_wo_resp) ? UBLUEPY_PROP_WRITE_WO_RESP : 0;
1059-
char_data.props |= (p_char->char_props.write) ? UBLUEPY_PROP_WRITE : 0;
1060-
char_data.props |= (p_char->char_props.notify) ? UBLUEPY_PROP_NOTIFY : 0;
1061-
char_data.props |= (p_char->char_props.indicate) ? UBLUEPY_PROP_INDICATE : 0;
1062-
#if 0
1063-
char_data.props |= (p_char->char_props.auth_signed_wr) ? UBLUEPY_PROP_NOTIFY : 0;
1064-
#endif
1048+
char_data.props.broadcast = p_char->char_props.broadcast;
1049+
char_data.props.read = p_char->char_props.read;
1050+
char_data.props.write_wo_resp = p_char->char_props.write_wo_resp;
1051+
char_data.props.write = p_char->char_props.write;
1052+
char_data.props.notify = p_char->char_props.notify;
1053+
char_data.props.indicate = p_char->char_props.indicate;
10651054

10661055
disc_add_char_handler(mp_gattc_disc_char_observer, &char_data);
10671056
}

0 commit comments

Comments
 (0)