29
29
30
30
#include "shared-bindings/_bleio/__init__.h"
31
31
#include "shared-bindings/_bleio/Characteristic.h"
32
+ #include "shared-bindings/_bleio/CharacteristicBuffer.h"
32
33
#include "shared-bindings/_bleio/Descriptor.h"
34
+ #include "shared-bindings/_bleio/PacketBuffer.h"
33
35
#include "shared-bindings/_bleio/Service.h"
34
36
35
37
#include "common-hal/_bleio/Adapter.h"
@@ -47,8 +49,12 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
47
49
self -> props = props ;
48
50
self -> read_perm = read_perm ;
49
51
self -> write_perm = write_perm ;
50
- self -> descriptor_linked_list = mp_obj_new_list (0 , NULL );
51
- self -> watchers_list = mp_obj_new_list (0 , NULL );
52
+ self -> descriptor_list = mp_obj_new_list (0 , NULL );
53
+ self -> observer = mp_const_none ;
54
+ self -> user_desc = NULL ;
55
+ self -> cccd = NULL ;
56
+ self -> sccd = NULL ;
57
+ self -> value = mp_obj_new_bytes (initial_value_bufinfo -> buf , initial_value_bufinfo -> len );
52
58
53
59
const mp_int_t max_length_max = 512 ;
54
60
if (max_length < 0 || max_length > max_length_max ) {
@@ -62,14 +68,10 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
62
68
} else {
63
69
common_hal_bleio_service_add_characteristic (self -> service , self , initial_value_bufinfo );
64
70
}
65
-
66
- if (initial_value_bufinfo != NULL ) {
67
- common_hal_bleio_characteristic_set_value (self , initial_value_bufinfo );
68
- }
69
71
}
70
72
71
- bleio_descriptor_obj_t * common_hal_bleio_characteristic_get_descriptor_linked_list (bleio_characteristic_obj_t * self ) {
72
- return self -> descriptor_linked_list ;
73
+ mp_obj_tuple_t * common_hal_bleio_characteristic_get_descriptors (bleio_characteristic_obj_t * self ) {
74
+ return mp_obj_new_tuple ( self -> descriptor_list -> len , self -> descriptor_list -> items ) ;
73
75
}
74
76
75
77
bleio_service_obj_t * common_hal_bleio_characteristic_get_service (bleio_characteristic_obj_t * self ) {
@@ -79,13 +81,19 @@ bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_character
79
81
size_t common_hal_bleio_characteristic_get_value (bleio_characteristic_obj_t * self , uint8_t * buf , size_t len ) {
80
82
// Do GATT operations only if this characteristic has been added to a registered service.
81
83
if (self -> handle != BLE_GATT_HANDLE_INVALID ) {
82
- uint16_t conn_handle = bleio_connection_get_conn_handle (self -> service -> connection );
84
+ //FIX uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
83
85
if (common_hal_bleio_service_get_is_remote (self -> service )) {
84
- // self->value is set by evt handler.
85
- return common_hal_bleio_gattc_read (self -> handle , conn_handle , buf , len );
86
+ //FIX read remote chars
87
+ //uint8_t rsp[MAX(len, 512)];
88
+ //FIX improve att_read_req to write into our requested buffer.
89
+ // return att_read_req(conn_handle, self->handle, rsp);
90
+ return 0 ; //FIX
86
91
} else {
87
- // conn_handle is ignored for non-system attributes.
88
- return common_hal_bleio_gatts_read (self -> handle , conn_handle , buf , len );
92
+ mp_buffer_info_t bufinfo ;
93
+ if (!mp_get_buffer (self -> value , & bufinfo , MP_BUFFER_READ )) {
94
+ return 0 ;
95
+ }
96
+ memcpy (buf , bufinfo .buf , MIN (len , bufinfo .len ));
89
97
}
90
98
}
91
99
@@ -102,32 +110,40 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
102
110
103
111
// Do GATT operations only if this characteristic has been added to a registered service.
104
112
if (self -> handle != BLE_GATT_HANDLE_INVALID ) {
105
-
106
113
if (common_hal_bleio_service_get_is_remote (self -> service )) {
107
- uint16_t conn_handle = bleio_connection_get_conn_handle (self -> service -> connection );
108
- // Last argument is true if write-no-reponse desired.
109
- common_hal_bleio_gattc_write (self -> handle , conn_handle , bufinfo ,
110
- (self -> props & CHAR_PROP_WRITE_NO_RESPONSE ));
114
+ //FIX uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
115
+ if (self -> props & CHAR_PROP_WRITE ) {
116
+ //FIX writing remote chars
117
+ //uint8_t rsp[sizeof(bt_att_error_rsp)];
118
+ //att_write_req(conn_handle, self->handle, bufinfo->buf, bufinfo->len, rsp);
119
+ } else if (self -> props & CHAR_PROP_WRITE_NO_RESPONSE ) {
120
+ //att_write_cmd(conn_handle, self->handle, bufinfo->buff, bufinfo->len);
121
+ } else {
122
+ mp_raise_bleio_BluetoothError (translate ("Characteristic not writable" ));
123
+ }
111
124
} else {
112
125
// Always write the value locally even if no connections are active.
113
- // conn_handle is ignored for non-system attributes, so we use BLE_CONN_HANDLE_INVALID.
114
- common_hal_bleio_gatts_write (self -> handle , BLE_CONN_HANDLE_INVALID , bufinfo );
126
+ bleio_characteristic_set_local_value (self , bufinfo );
115
127
// Notify or indicate all active connections.
116
- uint16_t cccd = 0 ;
128
+
129
+ uint16_t cccd_value = 0 ;
130
+ mp_buffer_info_t cccd_bufinfo = {
131
+ .buf = & cccd_value ,
132
+ .len = sizeof (cccd_value ),
133
+ };
117
134
118
135
const bool notify = self -> props & CHAR_PROP_NOTIFY ;
119
136
const bool indicate = self -> props & CHAR_PROP_INDICATE ;
120
137
// Read the CCCD value, if there is one.
121
- if ((notify | indicate ) && self -> cccd_handle != BLE_GATT_HANDLE_INVALID ) {
122
- common_hal_bleio_gatts_read (self -> cccd_handle , BLE_CONN_HANDLE_INVALID ,
123
- (uint8_t * ) & cccd , sizeof (cccd ));
138
+ if ((notify | indicate ) && self -> cccd != NULL ) {
139
+ common_hal_bleio_descriptor_get_value (self -> cccd , cccd_bufinfo .buf , cccd_bufinfo .len );
124
140
}
125
141
126
142
// It's possible that both notify and indicate are set.
127
- if (notify && (cccd & CCCD_NOTIFY )) {
143
+ if (notify && (cccd_value & CCCD_NOTIFY )) {
128
144
att_notify (self -> handle , bufinfo -> buf , MIN (bufinfo -> len , self -> max_length ));
129
145
}
130
- if (indicate && (cccd & CCCD_INDICATE )) {
146
+ if (indicate && (cccd_value & CCCD_INDICATE )) {
131
147
att_indicate (self -> handle , bufinfo -> buf , MIN (bufinfo -> len , self -> max_length ));
132
148
133
149
}
@@ -153,13 +169,12 @@ void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *
153
169
// Include this descriptor in the service handle's range.
154
170
self -> service -> end_handle = descriptor -> handle ;
155
171
156
- // Link together all the descriptors for this characteristic.
157
- descriptor -> next = self -> descriptor_linked_list ;
158
- self -> descriptor_linked_list = descriptor ;
172
+ mp_obj_list_append (MP_OBJ_FROM_PTR (self -> descriptor_list ),
173
+ MP_OBJ_FROM_PTR (descriptor ));
159
174
}
160
175
161
176
void common_hal_bleio_characteristic_set_cccd (bleio_characteristic_obj_t * self , bool notify , bool indicate ) {
162
- if (self -> cccd_handle == BLE_GATT_HANDLE_INVALID ) {
177
+ if (self -> cccd == NULL ) {
163
178
mp_raise_bleio_BluetoothError (translate ("No CCCD for this Characteristic" ));
164
179
}
165
180
@@ -174,48 +189,38 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self,
174
189
(notify ? CCCD_NOTIFY : 0 ) |
175
190
(indicate ? CCCD_INDICATE : 0 );
176
191
192
+ //FIX do remote
177
193
(void ) cccd_value ;
178
- //FIX call att_something to set remote CCCD
179
- // ble_gattc_write_params_t write_params = {
180
- // .write_op = BLE_GATT_OP_WRITE_REQ,
181
- // .handle = self->cccd_handle,
182
- // .p_value = (uint8_t *) &cccd_value,
183
- // .len = 2,
184
- // };
185
-
186
- // while (1) {
187
- // uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
188
- // if (err_code == NRF_SUCCESS) {
189
- // break;
190
- // }
191
-
192
- // // Write with response will return NRF_ERROR_BUSY if the response has not been received.
193
- // // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
194
- // if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
195
- // // We could wait for an event indicating the write is complete, but just retrying is easier.
196
- // RUN_BACKGROUND_TASKS;
197
- // continue;
198
- // }
199
-
200
- // // Some real error occurred.
201
- // check_nrf_error(err_code);
194
+ // uint8_t rsp[sizeof(bt_att_error_rsp)];
195
+ // if (att_write_req(conn_handle, self->cccd->handle, &cccd_value, sizeof(cccd_value)) == 0) {
196
+ // mp_raise_bleio_BluetoothError(translate("Could not write CCCD"));
202
197
// }
203
-
204
198
}
205
199
206
200
bool bleio_characteristic_set_local_value (bleio_characteristic_obj_t * self , mp_buffer_info_t * bufinfo ) {
207
201
if (self -> fixed_length && bufinfo -> len != self -> max_length ) {
208
202
return false;
209
203
}
210
204
if (bufinfo -> len > self -> max_length ) {
211
- bool
205
+ return false;
212
206
}
213
207
214
- mp_buffer_info_t char_bufinfo ;
215
- if (!mp_get_buffer (characteristic -> value , & bufinfo , MP_BUFFER_WRITE )) {
208
+ self -> value = mp_obj_new_bytes (bufinfo -> buf , bufinfo -> len );
209
+
210
+ if (MP_OBJ_IS_TYPE (self -> observer , & bleio_characteristic_buffer_type )) {
211
+ bleio_characteristic_buffer_update (MP_OBJ_FROM_PTR (self -> observer ), bufinfo );
212
+ } else if (MP_OBJ_IS_TYPE (self -> observer , & bleio_packet_buffer_type )) {
213
+ bleio_packet_buffer_update (MP_OBJ_FROM_PTR (self -> observer ), bufinfo );
214
+ } else {
216
215
return false;
217
216
}
218
- memcpy (& char_bufinfo -> buf , bufinfo -> buf , bufinfo -> len );
217
+ return true;
218
+ }
219
+
220
+ void bleio_characteristic_set_observer (bleio_characteristic_obj_t * self , mp_obj_t observer ) {
221
+ self -> observer = observer ;
222
+ }
219
223
220
- for (size_t i ; i < characteristic -> set_callbacks .
224
+ void bleio_characteristic_clear_observer (bleio_characteristic_obj_t * self ) {
225
+ self -> observer = mp_const_none ;
221
226
}
0 commit comments