3030#include "ble_drv.h"
3131#include "ble_gatts.h"
3232#include "nrf_soc.h"
33+
3334#include "py/runtime.h"
35+ #include "common-hal/bleio/__init__.h"
3436#include "shared-module/bleio/Characteristic.h"
3537
36- static volatile bleio_characteristic_obj_t * m_read_characteristic ;
37- static volatile uint8_t m_tx_in_progress ;
38- static nrf_mutex_t * m_write_mutex ;
38+
39+ STATIC volatile bleio_characteristic_obj_t * m_read_characteristic ;
40+ STATIC volatile uint8_t m_tx_in_progress ;
41+ STATIC nrf_mutex_t * m_write_mutex ;
42+
3943
4044STATIC void gatts_write (bleio_characteristic_obj_t * characteristic , mp_buffer_info_t * bufinfo ) {
41- bleio_device_obj_t * device = characteristic -> service -> device ;
42- const uint16_t conn_handle = device -> conn_handle ;
45+ const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle (characteristic -> service -> device );
4346
4447 ble_gatts_value_t gatts_value = {
4548 .p_value = bufinfo -> buf ,
@@ -48,17 +51,17 @@ STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in
4851
4952 const uint32_t err_code = sd_ble_gatts_value_set (conn_handle , characteristic -> handle , & gatts_value );
5053 if (err_code != NRF_SUCCESS ) {
51- mp_raise_OSError_msg (translate ("Failed to write gatts value" ) );
54+ mp_raise_OSError_msg_varg (translate ("Failed to write gatts value, err 0x%04x" ), err_code );
5255 }
5356}
5457
5558STATIC void gatts_notify (bleio_characteristic_obj_t * characteristic , mp_buffer_info_t * bufinfo ) {
56- bleio_device_obj_t * device = characteristic -> service -> device ;
5759 uint16_t hvx_len = bufinfo -> len ;
5860
5961 ble_gatts_hvx_params_t hvx_params = {
6062 .handle = characteristic -> handle ,
6163 .type = BLE_GATT_HVX_NOTIFICATION ,
64+ .offset = 0 ,
6265 .p_len = & hvx_len ,
6366 .p_data = bufinfo -> buf ,
6467 };
@@ -69,25 +72,26 @@ STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_i
6972#endif
7073 }
7174
72- const uint32_t err_code = sd_ble_gatts_hvx (device -> conn_handle , & hvx_params );
75+ const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle (characteristic -> service -> device );
76+ const uint32_t err_code = sd_ble_gatts_hvx (conn_handle , & hvx_params );
7377 if (err_code != NRF_SUCCESS ) {
74- mp_raise_OSError_msg (translate ("Failed to notify attribute value" ) );
78+ mp_raise_OSError_msg_varg (translate ("Failed to notify attribute value, err %0x04x" ), err_code );
7579 }
7680
7781 m_tx_in_progress += 1 ;
7882}
7983
8084STATIC void gattc_read (bleio_characteristic_obj_t * characteristic ) {
81- bleio_service_obj_t * service = characteristic -> service ;
82- bleio_device_obj_t * device = service -> device ;
85+ const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle (characteristic -> service -> device );
8386
8487 m_read_characteristic = characteristic ;
8588
86- const uint32_t err_code = sd_ble_gattc_read (device -> conn_handle , characteristic -> handle , 0 );
89+ const uint32_t err_code = sd_ble_gattc_read (conn_handle , characteristic -> handle , 0 );
8790 if (err_code != NRF_SUCCESS ) {
88- mp_raise_OSError_msg (translate ("Failed to read attribute value" ) );
91+ mp_raise_OSError_msg_varg (translate ("Failed to read attribute value, err %0x04x" ), err_code );
8992 }
9093
94+ //
9195 while (m_read_characteristic != NULL ) {
9296#ifdef MICROPY_VM_HOOK_LOOP
9397 MICROPY_VM_HOOK_LOOP
@@ -96,7 +100,7 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) {
96100}
97101
98102STATIC void gattc_write (bleio_characteristic_obj_t * characteristic , mp_buffer_info_t * bufinfo ) {
99- bleio_device_obj_t * device = characteristic -> service -> device ;
103+ const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle ( characteristic -> service -> device ) ;
100104 uint32_t err_code ;
101105
102106 ble_gattc_write_params_t write_params = {
@@ -112,13 +116,13 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in
112116
113117 err_code = sd_mutex_acquire (m_write_mutex );
114118 if (err_code != NRF_SUCCESS ) {
115- mp_raise_OSError_msg (translate ("Failed to acquire mutex" ) );
119+ mp_raise_OSError_msg_varg (translate ("Failed to acquire mutex, err 0x%04x" ), err_code );
116120 }
117121 }
118122
119- err_code = sd_ble_gattc_write (device -> conn_handle , & write_params );
123+ err_code = sd_ble_gattc_write (conn_handle , & write_params );
120124 if (err_code != NRF_SUCCESS ) {
121- mp_raise_OSError_msg (translate ("Failed to write attribute value" ) );
125+ mp_raise_OSError_msg_varg (translate ("Failed to write attribute value, err 0x%04x" ), err_code );
122126 }
123127
124128 while (sd_mutex_acquire (m_write_mutex ) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN ) {
@@ -129,33 +133,28 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in
129133
130134 err_code = sd_mutex_release (m_write_mutex );
131135 if (err_code != NRF_SUCCESS ) {
132- mp_raise_OSError_msg (translate ("Failed to release mutex" ) );
136+ mp_raise_OSError_msg_varg (translate ("Failed to release mutex, err 0x%04x" ), err_code );
133137 }
134138}
135139
136140STATIC void on_ble_evt (ble_evt_t * ble_evt , void * param ) {
137141 switch (ble_evt -> header .evt_id ) {
138- #if (BLE_API_VERSION == 4 )
139142 case BLE_GATTS_EVT_HVN_TX_COMPLETE :
140143 m_tx_in_progress -= ble_evt -> evt .gatts_evt .params .hvn_tx_complete .count ;
141144 break ;
142- #else
143- case BLE_EVT_TX_COMPLETE :
144- m_tx_in_progress -= ble_evt -> evt .common_evt .params .tx_complete .count ;
145- break ;
146- #endif
147145
148146 case BLE_GATTC_EVT_READ_RSP :
149147 {
150148 ble_gattc_evt_read_rsp_t * response = & ble_evt -> evt .gattc_evt .params .read_rsp ;
151149 m_read_characteristic -> value_data = mp_obj_new_bytearray (response -> len , response -> data );
150+ // Flag to busy-wait loop that we've read the characteristic.
152151 m_read_characteristic = NULL ;
153152 break ;
154153 }
155154
156155 case BLE_GATTC_EVT_WRITE_RSP :
156+ // Someone else can write now.
157157 sd_mutex_release (m_write_mutex );
158- // m_write_done = true;
159158 break ;
160159 }
161160}
@@ -165,21 +164,34 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self)
165164}
166165
167166void common_hal_bleio_characteristic_read_value (bleio_characteristic_obj_t * self ) {
168- gattc_read (self );
167+ switch (common_hal_bleio_device_get_gatt_role (self -> service -> device )) {
168+ case GATT_ROLE_CLIENT :
169+ gattc_read (self );
170+ break ;
171+
172+ default :
173+ mp_raise_RuntimeError (translate ("bad GATT role" ));
174+ break ;
175+ }
169176}
170177
171178void common_hal_bleio_characteristic_write_value (bleio_characteristic_obj_t * self , mp_buffer_info_t * bufinfo ) {
172- const bleio_device_obj_t * device = self -> service -> device ;
173-
174- if (device -> is_peripheral ) {
175- // TODO: Add indications
179+ switch (common_hal_bleio_device_get_gatt_role (self -> service -> device )) {
180+ case GATT_ROLE_SERVER :
176181 if (self -> props .notify ) {
177182 gatts_notify (self , bufinfo );
178183 } else {
179184 gatts_write (self , bufinfo );
180185 }
181- } else {
186+ break ;
187+
188+ case GATT_ROLE_CLIENT :
189+ // TODO: Add indications
182190 gattc_write (self , bufinfo );
183- }
191+ break ;
184192
193+ default :
194+ mp_raise_RuntimeError (translate ("bad GATT role" ));
195+ break ;
196+ }
185197}
0 commit comments