1 #include <stdint.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "btstack_debug.h"
6 #include "bluetooth_gatt.h"
7 #include "mock_gatt_client.h"
8 #include "hci_event_builder.h"
9
10 //#include "CppUTest/TestHarness.h"
11 //#include "CppUTestExt/MockSupport.h"
12
13 static enum {
14 MOCK_QUERY_IDLE = 0,
15 MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID,
16 MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID,
17 MOCK_QUERY_DISCOVER_ALL_CHARACTERISTICS,
18 MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS,
19 MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION,
20 MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE,
21 MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE
22 } mock_gatt_client_state;
23
24 static uint16_t mock_gatt_client_att_handle_generator;
25
26 static uint8_t mock_gatt_client_att_error;
27 static uint8_t mock_gatt_client_uuid128[16];
28 static uint16_t mock_gatt_client_value_handle;
29 static uint16_t mock_gatt_client_start_handle;
30 static uint16_t mock_gatt_client_end_handle;
31
32 static gatt_client_t gatt_client;
33
34 static btstack_linked_list_t mock_gatt_client_services;
35
36 static mock_gatt_client_service_t * mock_gatt_client_last_service;
37 static mock_gatt_client_characteristic_t * mock_gatt_client_last_characteristic;
38
39 static uint8_t moc_att_error_code_discover_services;
40 static uint8_t moc_att_error_code_discover_characteristics;
41 static uint8_t moc_att_error_code_discover_characteristic_descriptors;
42 static uint8_t moc_att_error_code_read_value_characteristics;
43
44 static btstack_linked_list_t event_packet_handlers;
45
hci_add_event_handler(btstack_packet_callback_registration_t * callback_handler)46 void hci_add_event_handler(btstack_packet_callback_registration_t * callback_handler){
47 btstack_linked_list_add_tail(&event_packet_handlers, (btstack_linked_item_t*) callback_handler);
48 }
49
mock_hci_emit_event(uint8_t * packet,uint16_t size)50 void mock_hci_emit_event(uint8_t * packet, uint16_t size){
51 // dispatch to all event handlers
52 btstack_linked_list_iterator_t it;
53 btstack_linked_list_iterator_init(&it, &event_packet_handlers);
54 while (btstack_linked_list_iterator_has_next(&it)){
55 btstack_packet_callback_registration_t * entry = (btstack_packet_callback_registration_t*) btstack_linked_list_iterator_next(&it);
56 entry->callback(HCI_EVENT_PACKET, 0, packet, size);
57 }
58 }
59
hci_create_gap_connection_complete_event(const uint8_t * hci_event,uint8_t * gap_event)60 static void hci_create_gap_connection_complete_event(const uint8_t * hci_event, uint8_t * gap_event) {
61 gap_event[0] = HCI_EVENT_META_GAP;
62 gap_event[1] = 36 - 2;
63 gap_event[2] = GAP_SUBEVENT_LE_CONNECTION_COMPLETE;
64 switch (hci_event[2]){
65 case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
66 memcpy(&gap_event[3], &hci_event[3], 11);
67 memset(&gap_event[14], 0, 12);
68 memcpy(&gap_event[26], &hci_event[14], 7);
69 memset(&gap_event[33], 0xff, 3);
70 break;
71 case HCI_SUBEVENT_LE_ENHANCED_CONNECTION_COMPLETE_V1:
72 memcpy(&gap_event[3], &hci_event[3], 30);
73 memset(&gap_event[33], 0xff, 3);
74 break;
75 case HCI_SUBEVENT_LE_ENHANCED_CONNECTION_COMPLETE_V2:
76 memcpy(&gap_event[3], &hci_event[3], 33);
77 break;
78 default:
79 btstack_unreachable();
80 break;
81 }
82 }
83
mock_hci_emit_le_connection_complete(uint8_t address_type,const bd_addr_t address,hci_con_handle_t con_handle,uint8_t status)84 void mock_hci_emit_le_connection_complete(uint8_t address_type, const bd_addr_t address, hci_con_handle_t con_handle, uint8_t status){
85 uint8_t hci_event[21];
86 hci_event[0] = HCI_EVENT_LE_META;
87 hci_event[1] = sizeof(hci_event) - 2u;
88 hci_event[2] = HCI_SUBEVENT_LE_CONNECTION_COMPLETE;
89 hci_event[3] = status;
90 little_endian_store_16(hci_event, 4, con_handle);
91 hci_event[6] = 0; // TODO: role
92 hci_event[7] = address_type;
93 reverse_bd_addr(address, &hci_event[8]);
94 little_endian_store_16(hci_event, 14, 0); // interval
95 little_endian_store_16(hci_event, 16, 0); // latency
96 little_endian_store_16(hci_event, 18, 0); // supervision timeout
97 hci_event[20] = 0; // master clock accuracy
98 // emit GAP event, too
99 uint8_t gap_event[36];
100 hci_create_gap_connection_complete_event(hci_event, gap_event);
101 mock_hci_emit_event(gap_event, sizeof(gap_event));
102 }
103
mock_hci_emit_connection_encrypted(hci_con_handle_t con_handle,uint8_t encrypted)104 void mock_hci_emit_connection_encrypted(hci_con_handle_t con_handle, uint8_t encrypted){
105 uint8_t encryption_complete_event[6] = { HCI_EVENT_ENCRYPTION_CHANGE, 4, 0, 0, 0, 0};
106 little_endian_store_16(encryption_complete_event, 3, con_handle);
107 encryption_complete_event[5] = encrypted;
108 mock_hci_emit_event(encryption_complete_event, sizeof(encryption_complete_event));
109 }
110
mock_hci_emit_disconnection_complete(hci_con_handle_t con_handle,uint8_t reason)111 void mock_hci_emit_disconnection_complete(hci_con_handle_t con_handle, uint8_t reason){
112 uint8_t event[6];
113 event[0] = HCI_EVENT_DISCONNECTION_COMPLETE;
114 event[1] = sizeof(event) - 2u;
115 event[2] = 0; // status = OK
116 little_endian_store_16(event, 3, con_handle);
117 event[5] = reason;
118 mock_hci_emit_event(event, sizeof(event));
119 }
120
121
122 /**
123 * copied from gatt_client.c - START
124 */
gatt_client_deserialize_service(const uint8_t * packet,int offset,gatt_client_service_t * service)125 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){
126 service->start_group_handle = little_endian_read_16(packet, offset);
127 service->end_group_handle = little_endian_read_16(packet, offset + 2);
128 reverse_128(&packet[offset + 4], service->uuid128);
129 if (uuid_has_bluetooth_prefix(service->uuid128)){
130 service->uuid16 = big_endian_read_32(service->uuid128, 0);
131 } else {
132 service->uuid16 = 0;
133 }
134 }
135
gatt_client_deserialize_characteristic(const uint8_t * packet,int offset,gatt_client_characteristic_t * characteristic)136 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){
137 characteristic->start_handle = little_endian_read_16(packet, offset);
138 characteristic->value_handle = little_endian_read_16(packet, offset + 2);
139 characteristic->end_handle = little_endian_read_16(packet, offset + 4);
140 characteristic->properties = little_endian_read_16(packet, offset + 6);
141 reverse_128(&packet[offset+8], characteristic->uuid128);
142 if (uuid_has_bluetooth_prefix(characteristic->uuid128)){
143 characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0);
144 } else {
145 characteristic->uuid16 = 0;
146 }
147 }
148
gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet,int offset,gatt_client_characteristic_descriptor_t * descriptor)149 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){
150 descriptor->handle = little_endian_read_16(packet, offset);
151 reverse_128(&packet[offset+2], descriptor->uuid128);
152 if (uuid_has_bluetooth_prefix(descriptor->uuid128)){
153 descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0);
154 } else {
155 descriptor->uuid16 = 0;
156 }
157 }
158
emit_event_new(btstack_packet_handler_t callback,uint8_t * packet,uint16_t size)159 static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){
160 if (!callback) return;
161 (*callback)(HCI_EVENT_PACKET, 0, packet, size);
162 }
163
emit_gatt_complete_event(gatt_client_t * gatt_client,uint8_t att_status)164 static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){
165 // @format H122
166 uint8_t packet[9];
167 hci_event_builder_context_t context;
168 hci_event_builder_init(&context, packet, sizeof(packet), GATT_EVENT_QUERY_COMPLETE, 0);
169 hci_event_builder_add_con_handle(&context, gatt_client->con_handle);
170 hci_event_builder_add_16(&context, gatt_client->service_id);
171 hci_event_builder_add_16(&context, gatt_client->connection_id);
172 hci_event_builder_add_08(&context, att_status);
173 emit_event_new(gatt_client->callback, packet, hci_event_builder_get_length(&context));
174 }
175
emit_gatt_service_query_result_event(gatt_client_t * gatt_client,uint16_t start_group_handle,uint16_t end_group_handle,const uint8_t * uuid128)176 static void emit_gatt_service_query_result_event(gatt_client_t * gatt_client, uint16_t start_group_handle, uint16_t end_group_handle, const uint8_t * uuid128){
177 // @format H22X
178 uint8_t packet[28];
179 hci_event_builder_context_t context;
180 hci_event_builder_init(&context, packet, sizeof(packet), GATT_EVENT_SERVICE_QUERY_RESULT, 0);
181 hci_event_builder_add_con_handle(&context, gatt_client->con_handle);
182 hci_event_builder_add_16(&context, gatt_client->service_id);
183 hci_event_builder_add_16(&context, gatt_client->connection_id);
184 hci_event_builder_add_16(&context, start_group_handle);
185 hci_event_builder_add_16(&context, end_group_handle);
186 hci_event_builder_add_128(&context, uuid128);
187 emit_event_new(gatt_client->callback, packet, hci_event_builder_get_length(&context));
188 }
189
emit_gatt_characteristic_query_result_event(gatt_client_t * gatt_client,uint16_t start_handle,uint16_t value_handle,uint16_t end_handle,uint16_t properties,const uint8_t * uuid128)190 static void emit_gatt_characteristic_query_result_event(gatt_client_t * gatt_client, uint16_t start_handle, uint16_t value_handle, uint16_t end_handle,
191 uint16_t properties, const uint8_t * uuid128){
192 // @format H22Y
193 uint8_t packet[32];
194 hci_event_builder_context_t context;
195 hci_event_builder_init(&context, packet, sizeof(packet), GATT_EVENT_CHARACTERISTIC_QUERY_RESULT, 0);
196 hci_event_builder_add_con_handle(&context, gatt_client->con_handle);
197 hci_event_builder_add_16(&context, gatt_client->service_id);
198 hci_event_builder_add_16(&context, gatt_client->connection_id);
199 hci_event_builder_add_16(&context, start_handle);
200 hci_event_builder_add_16(&context, value_handle);
201 hci_event_builder_add_16(&context, end_handle);
202 hci_event_builder_add_16(&context, properties);
203 hci_event_builder_add_128(&context, uuid128);
204 emit_event_new(gatt_client->callback, packet, hci_event_builder_get_length(&context));
205 }
206
emit_gatt_all_characteristic_descriptors_result_event(gatt_client_t * gatt_client,uint16_t descriptor_handle,const uint8_t * uuid128)207 static void emit_gatt_all_characteristic_descriptors_result_event(
208 gatt_client_t * gatt_client, uint16_t descriptor_handle, const uint8_t * uuid128){
209 // @format HZ
210 uint8_t packet[22];
211 hci_event_builder_context_t context;
212 hci_event_builder_init(&context, packet, sizeof(packet), GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT, 0);
213 hci_event_builder_add_con_handle(&context, gatt_client->con_handle);
214 hci_event_builder_add_16(&context, gatt_client->service_id);
215 hci_event_builder_add_16(&context, gatt_client->connection_id);
216 hci_event_builder_add_16(&context, descriptor_handle);
217 hci_event_builder_add_128(&context, uuid128);
218 emit_event_new(gatt_client->callback, packet, hci_event_builder_get_length(&context));
219 }
220
221 static uint8_t event_packet[255];
setup_characteristic_value_packet(uint8_t type,hci_con_handle_t con_handle,uint16_t attribute_handle,uint8_t * value,uint16_t length)222 static uint8_t * setup_characteristic_value_packet(uint8_t type, hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t * value, uint16_t length){
223 // before the value inside the ATT PDU
224 event_packet[0] = type;
225 event_packet[1] = 10 + length;
226 little_endian_store_16(event_packet, 2, con_handle);
227 little_endian_store_16(event_packet, 4, 0);
228 little_endian_store_16(event_packet, 6, 0);
229 little_endian_store_16(event_packet, 8, attribute_handle);
230 little_endian_store_16(event_packet, 10, length);
231 memcpy(&event_packet[12], value, length);
232 return &event_packet[0];
233 }
234
mock_gatt_client_send_notification_with_handle(mock_gatt_client_characteristic_t * characteristic,uint16_t value_handle,const uint8_t * value_buffer,uint16_t value_len)235 void mock_gatt_client_send_notification_with_handle(mock_gatt_client_characteristic_t * characteristic, uint16_t value_handle, const uint8_t * value_buffer, uint16_t value_len){
236 btstack_assert(characteristic != NULL);
237 btstack_assert(characteristic->notification != NULL);
238 btstack_assert(characteristic->notification->callback != NULL);
239 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_NOTIFICATION, gatt_client.con_handle, value_handle, (uint8_t *) value_buffer, value_len);
240 emit_event_new(characteristic->notification->callback, packet, 2 + packet[1]);
241 }
242
mock_gatt_client_send_notification(mock_gatt_client_characteristic_t * characteristic,const uint8_t * value_buffer,uint16_t value_len)243 void mock_gatt_client_send_notification(mock_gatt_client_characteristic_t * characteristic, const uint8_t * value_buffer, uint16_t value_len){
244 mock_gatt_client_send_notification_with_handle(characteristic, characteristic->value_handle, value_buffer, value_len);
245 }
246
mock_gatt_client_send_indication_with_handle(mock_gatt_client_characteristic_t * characteristic,uint16_t value_handle,const uint8_t * value_buffer,uint16_t value_len)247 void mock_gatt_client_send_indication_with_handle(mock_gatt_client_characteristic_t * characteristic, uint16_t value_handle, const uint8_t * value_buffer, uint16_t value_len){
248 btstack_assert(characteristic != NULL);
249 btstack_assert(characteristic->notification != NULL);
250 btstack_assert(characteristic->notification->callback != NULL);
251 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_INDICATION, gatt_client.con_handle, value_handle, (uint8_t *) value_buffer, value_len);
252 emit_event_new(characteristic->notification->callback, packet, 2 + packet[1]);
253 }
254
mock_gatt_client_send_indication(mock_gatt_client_characteristic_t * characteristic,const uint8_t * value_buffer,uint16_t value_len)255 void mock_gatt_client_send_indication(mock_gatt_client_characteristic_t * characteristic, const uint8_t * value_buffer, uint16_t value_len){
256 mock_gatt_client_send_indication_with_handle(characteristic, characteristic->value_handle, value_buffer, value_len);
257 }
258
mock_gatt_client_send_characteristic_value(gatt_client_t * gatt_client,mock_gatt_client_characteristic_t * characteristic)259 static void mock_gatt_client_send_characteristic_value(gatt_client_t * gatt_client, mock_gatt_client_characteristic_t * characteristic){
260 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, gatt_client->con_handle, characteristic->value_handle, characteristic->value_buffer, characteristic->value_len);
261 emit_event_new(gatt_client->callback, packet, 2 + packet[1]);
262 }
263
264 /**
265 * copied from gatt_client.c - END
266 */
267
268
mock_gatt_client_get_characteristic_for_value_handle(uint16_t value_handle)269 static mock_gatt_client_characteristic_t * mock_gatt_client_get_characteristic_for_value_handle(uint16_t value_handle){
270 btstack_linked_list_iterator_t service_it;
271 btstack_linked_list_iterator_t characteristic_it;
272
273 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
274 while (btstack_linked_list_iterator_has_next(&service_it)){
275 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
276
277 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
278 while (btstack_linked_list_iterator_has_next(&characteristic_it)){
279 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
280 if (characteristic->value_handle != value_handle) continue;
281 return characteristic;
282 }
283 }
284 return NULL;
285 }
286
mock_gatt_client_get_characteristic_for_uuid16(uint16_t uuid16)287 static mock_gatt_client_characteristic_t * mock_gatt_client_get_characteristic_for_uuid16(uint16_t uuid16){
288 btstack_linked_list_iterator_t service_it;
289 btstack_linked_list_iterator_t characteristic_it;
290
291 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
292 while (btstack_linked_list_iterator_has_next(&service_it)){
293 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
294
295 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
296 while (btstack_linked_list_iterator_has_next(&characteristic_it)){
297 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
298 if (characteristic->uuid16 != uuid16) continue;
299 return characteristic;
300 }
301 }
302 return NULL;
303 }
304
mock_gatt_client_get_characteristic_descriptor_for_handle(uint16_t handle)305 static mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_get_characteristic_descriptor_for_handle(uint16_t handle){
306 btstack_linked_list_iterator_t service_it;
307 btstack_linked_list_iterator_t characteristic_it;
308
309 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
310 while (btstack_linked_list_iterator_has_next(&service_it)){
311 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
312
313 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
314 while (btstack_linked_list_iterator_has_next(&characteristic_it)){
315 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
316
317 btstack_linked_list_iterator_t desc_it;
318 btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors);
319 while (btstack_linked_list_iterator_has_next(&desc_it)){
320 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it);
321 if (desc->handle != handle) continue;
322 return desc;
323 }
324 }
325 }
326 return NULL;
327 }
328
gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t uuid16)329 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){
330 mock_gatt_client_state = MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID;
331 uuid_add_bluetooth_prefix(mock_gatt_client_uuid128, uuid16);
332 gatt_client.callback = callback;
333 gatt_client.con_handle = con_handle;
334 return ERROR_CODE_SUCCESS;
335 }
336
gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback,hci_con_handle_t con_handle,const uint8_t * uuid128)337 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){
338 mock_gatt_client_state = MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID;
339 memcpy(mock_gatt_client_uuid128, uuid128, 16);
340 gatt_client.callback = callback;
341 gatt_client.con_handle = con_handle;
342 return ERROR_CODE_SUCCESS;
343 }
344
gatt_client_discover_characteristics_for_handle_range_by_uuid16(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t start_handle,uint16_t end_handle,uint16_t uuid16)345 uint8_t gatt_client_discover_characteristics_for_handle_range_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16){
346 mock_gatt_client_state = MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID;
347 uuid_add_bluetooth_prefix(mock_gatt_client_uuid128, uuid16);
348 mock_gatt_client_start_handle = start_handle;
349 mock_gatt_client_end_handle = end_handle;
350
351 gatt_client.callback = callback;
352 gatt_client.con_handle = con_handle;
353 return ERROR_CODE_SUCCESS;
354 }
355
gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_service_t * service)356 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service){
357 mock_gatt_client_state = MOCK_QUERY_DISCOVER_ALL_CHARACTERISTICS;
358 mock_gatt_client_start_handle = service->start_group_handle;
359 mock_gatt_client_end_handle = service->end_group_handle;
360 gatt_client.callback = callback;
361 gatt_client.con_handle = con_handle;
362 return ERROR_CODE_SUCCESS;
363 }
364
gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_characteristic_t * characteristic)365 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
366 mock_gatt_client_state = MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS;
367 mock_gatt_client_value_handle = characteristic->value_handle;
368
369 gatt_client.callback = callback;
370 gatt_client.con_handle = con_handle;
371 return ERROR_CODE_SUCCESS;
372 }
373
gatt_client_listen_for_characteristic_value_updates(gatt_client_notification_t * notification,btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_characteristic_t * characteristic)374 void gatt_client_listen_for_characteristic_value_updates(gatt_client_notification_t * notification, btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
375 btstack_assert(notification != NULL);
376 btstack_assert(&callback != NULL);
377
378 notification->callback = callback;
379 notification->con_handle = con_handle;
380
381
382 if (characteristic == NULL){
383 // 'all characteristics': not used yet
384 btstack_assert(false);
385 } else {
386 mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle);
387 btstack_assert(mock_characteristic != NULL);
388
389 notification->attribute_handle = characteristic->value_handle;
390 mock_characteristic->notification = notification;
391 }
392 }
393
gatt_client_write_client_characteristic_configuration(btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_characteristic_t * characteristic,uint16_t configuration)394 uint8_t gatt_client_write_client_characteristic_configuration(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic, uint16_t configuration){
395 mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle);
396 btstack_assert(mock_characteristic != NULL);
397
398 if (mock_characteristic->notification_status_code != ERROR_CODE_SUCCESS){
399 return mock_characteristic->notification_status_code;
400 }
401
402 mock_gatt_client_state = MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
403
404 gatt_client.callback = callback;
405 gatt_client.con_handle = con_handle;
406 return ERROR_CODE_SUCCESS;
407 }
408
gatt_client_read_value_of_characteristics_by_uuid16(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t start_handle,uint16_t end_handle,uint16_t uuid16)409 uint8_t gatt_client_read_value_of_characteristics_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16){
410 mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE;
411
412 mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_uuid16(uuid16);
413 if (mock_characteristic != NULL){
414 mock_gatt_client_value_handle = mock_characteristic->value_handle;
415 gatt_client.callback = callback;
416 gatt_client.con_handle = con_handle;
417 }
418 return ERROR_CODE_SUCCESS;
419 }
420
gatt_client_read_value_of_characteristic_using_value_handle(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t value_handle)421 uint8_t gatt_client_read_value_of_characteristic_using_value_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle){
422 mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE;
423
424 mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(value_handle);
425 btstack_assert(mock_characteristic != NULL);
426
427 mock_gatt_client_value_handle = mock_characteristic->value_handle;
428 gatt_client.callback = callback;
429 gatt_client.con_handle = con_handle;
430 return ERROR_CODE_SUCCESS;
431 }
432
gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_characteristic_t * characteristic)433 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
434 btstack_assert(characteristic != NULL);
435 mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE;
436
437 mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle);
438 btstack_assert(mock_characteristic != NULL);
439
440 gatt_client.callback = callback;
441 gatt_client.con_handle = con_handle;
442 mock_gatt_client_value_handle = mock_characteristic->value_handle;
443 return ERROR_CODE_SUCCESS;
444 }
445
gatt_client_read_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t descriptor_handle)446 uint8_t gatt_client_read_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle){
447 mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE;
448 mock_gatt_client_value_handle = descriptor_handle;
449 return ERROR_CODE_SUCCESS;
450 }
451
gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification)452 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){
453 }
454
gatt_client_request_to_send_gatt_query(btstack_context_callback_registration_t * callback_registration,hci_con_handle_t con_handle)455 uint8_t gatt_client_request_to_send_gatt_query(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
456 // immediate callback, we don't have btstack runloop in most tests
457 (*callback_registration->callback)(callback_registration->context);
458 return ERROR_CODE_SUCCESS;
459 }
460
gatt_client_write_value_of_characteristic(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t value_handle,uint16_t value_length,uint8_t * value)461 uint8_t gatt_client_write_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t value_length, uint8_t * value){
462 mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(value_handle);
463 btstack_assert(mock_characteristic != NULL);
464
465 if (mock_characteristic->notification_status_code != ERROR_CODE_SUCCESS){
466 return mock_characteristic->notification_status_code;
467 }
468
469 mock_gatt_client_state = MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
470
471 gatt_client.callback = callback;
472 gatt_client.con_handle = con_handle;
473 return ERROR_CODE_SUCCESS;
474 }
475
mock_gatt_client_emit_complete(uint8_t status)476 void mock_gatt_client_emit_complete(uint8_t status){
477 mock_gatt_client_state = MOCK_QUERY_IDLE;
478 emit_gatt_complete_event(&gatt_client, status);
479 }
480
mock_gatt_client_run_once(void)481 void mock_gatt_client_run_once(void){
482 btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE);
483 mock_gatt_client_characteristic_t * characteristic;
484 mock_gatt_client_characteristic_descriptor_t * descriptor;
485
486 btstack_linked_list_iterator_t service_it;
487 btstack_linked_list_iterator_t characteristic_it;
488 btstack_linked_list_iterator_t descriptor_it;
489
490 switch (mock_gatt_client_state){
491 case MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID:
492 // emit GATT_EVENT_SERVICE_QUERY_RESULT for each matching service
493 if (moc_att_error_code_discover_services != ATT_ERROR_SUCCESS){
494 mock_gatt_client_emit_complete(moc_att_error_code_discover_services);
495 return;
496 }
497
498 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
499 while (btstack_linked_list_iterator_has_next(&service_it)){
500 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
501 if (memcmp(service->uuid128, mock_gatt_client_uuid128, 16) != 0) continue;
502 mock_gatt_client_last_service = service;
503 emit_gatt_service_query_result_event(&gatt_client, service->start_group_handle, service->end_group_handle, service->uuid128);
504 }
505 // emit GATT_EVENT_QUERY_COMPLETE
506 mock_gatt_client_emit_complete(ATT_ERROR_SUCCESS);
507 break;
508
509 case MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID:
510 case MOCK_QUERY_DISCOVER_ALL_CHARACTERISTICS:
511 // emit GATT_EVENT_CHARACTERISTIC_QUERY_RESULT for each matching characteristic
512 if (moc_att_error_code_discover_characteristics != ATT_ERROR_SUCCESS){
513 mock_gatt_client_emit_complete(moc_att_error_code_discover_characteristics);
514 return;
515 }
516
517 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
518 while (btstack_linked_list_iterator_has_next(&service_it)){
519 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
520
521 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
522 while (btstack_linked_list_iterator_has_next(&characteristic_it)){
523 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
524 if (characteristic->start_handle < mock_gatt_client_start_handle) continue;
525 if (characteristic->end_handle > mock_gatt_client_end_handle) continue;
526 if ((mock_gatt_client_state == MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID) && (memcmp(characteristic->uuid128, mock_gatt_client_uuid128, 16) != 0)) continue;
527
528 emit_gatt_characteristic_query_result_event(&gatt_client,
529 characteristic->start_handle, characteristic->value_handle, characteristic->end_handle,
530 characteristic->properties, characteristic->uuid128);
531 }
532 }
533
534 // emit GATT_EVENT_QUERY_COMPLETE
535 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
536 break;
537
538 case MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS:
539 characteristic = mock_gatt_client_get_characteristic_for_value_handle(mock_gatt_client_value_handle);
540 btstack_assert(characteristic != NULL);
541
542 if (moc_att_error_code_discover_characteristic_descriptors != ATT_ERROR_SUCCESS){
543 mock_gatt_client_emit_complete(moc_att_error_code_discover_characteristic_descriptors);
544 return;
545 }
546
547 btstack_linked_list_iterator_init(&descriptor_it, &characteristic->descriptors);
548 while (btstack_linked_list_iterator_has_next(&descriptor_it)){
549 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&descriptor_it);
550
551 emit_gatt_all_characteristic_descriptors_result_event(&gatt_client, desc->handle, desc->uuid128);
552 }
553
554 // emit GATT_EVENT_QUERY_COMPLETE
555 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
556 break;
557
558 case MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION:
559 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
560 break;
561
562 case MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE:
563 characteristic = mock_gatt_client_get_characteristic_for_value_handle(mock_gatt_client_value_handle);
564 if (moc_att_error_code_read_value_characteristics != ATT_ERROR_SUCCESS){
565 mock_gatt_client_emit_complete(moc_att_error_code_read_value_characteristics);
566 break;
567 }
568 if (characteristic != NULL){
569 mock_gatt_client_send_characteristic_value(&gatt_client, characteristic);
570 }
571 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
572 break;
573
574 case MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE:
575 descriptor = mock_gatt_client_get_characteristic_descriptor_for_handle(mock_gatt_client_value_handle);
576 btstack_assert(descriptor != NULL);
577 btstack_assert(descriptor->value_buffer != NULL);
578
579 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
580 break;
581
582 default:
583 btstack_assert(false);
584 break;
585 }
586 }
587
mock_gatt_client_run(void)588 void mock_gatt_client_run(void){
589 btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE);
590 while (mock_gatt_client_state != MOCK_QUERY_IDLE){
591 mock_gatt_client_run_once();
592 }
593 mock_gatt_client_att_error = ERROR_CODE_SUCCESS;
594 mock_gatt_client_state = MOCK_QUERY_IDLE;
595 }
596
mock_gatt_client_emit_dummy_event(void)597 void mock_gatt_client_emit_dummy_event(void){
598 // @format H1
599 uint8_t packet[2];
600 packet[0] = 0;
601 packet[1] = 0;
602 emit_event_new(gatt_client.callback, packet, sizeof(packet));
603 }
604
mock_gatt_client_reset_errors(void)605 static void mock_gatt_client_reset_errors(void){
606 moc_att_error_code_discover_services = ATT_ERROR_SUCCESS;
607 moc_att_error_code_discover_characteristics = ATT_ERROR_SUCCESS;
608 moc_att_error_code_discover_characteristic_descriptors = ATT_ERROR_SUCCESS;
609 moc_att_error_code_read_value_characteristics = ATT_ERROR_SUCCESS;
610 }
611
mock_gatt_client_reset(void)612 void mock_gatt_client_reset(void){
613 mock_gatt_client_att_error = 0;
614 mock_gatt_client_state = MOCK_QUERY_IDLE;
615 mock_gatt_client_att_handle_generator = 0;
616 mock_gatt_client_last_service = NULL;
617
618 mock_gatt_client_reset_errors();
619
620 btstack_linked_list_iterator_t service_it;
621 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
622 while (btstack_linked_list_iterator_has_next(&service_it)){
623 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
624 btstack_linked_list_remove(&mock_gatt_client_services, (btstack_linked_item_t *) service);
625
626 btstack_linked_list_iterator_t characteristic_it;
627 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
628 while (btstack_linked_list_iterator_has_next(&characteristic_it)){
629 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
630 btstack_linked_list_remove(&service->characteristics, (btstack_linked_item_t *) characteristic);
631
632 btstack_linked_list_iterator_t desc_it;
633 btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors);
634 while (btstack_linked_list_iterator_has_next(&desc_it)){
635 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it);
636 btstack_linked_list_remove(&characteristic->descriptors, (btstack_linked_item_t *) desc);
637 free(desc);
638 }
639 free(characteristic);
640 }
641 free(service);
642 }
643 }
644
mock_gatt_client_set_att_error_discover_primary_services(void)645 void mock_gatt_client_set_att_error_discover_primary_services(void){
646 moc_att_error_code_discover_services = ATT_ERROR_REQUEST_NOT_SUPPORTED;
647 }
mock_gatt_client_set_att_error_discover_characteristics(void)648 void mock_gatt_client_set_att_error_discover_characteristics(void){
649 moc_att_error_code_discover_characteristics = ATT_ERROR_REQUEST_NOT_SUPPORTED;
650 }
mock_gatt_client_set_att_error_discover_characteristic_descriptors(void)651 void mock_gatt_client_set_att_error_discover_characteristic_descriptors(void){
652 moc_att_error_code_discover_characteristic_descriptors = ATT_ERROR_REQUEST_NOT_SUPPORTED;
653 }
mock_gatt_client_set_att_error_read_value_characteristics(void)654 void mock_gatt_client_set_att_error_read_value_characteristics(void){
655 moc_att_error_code_read_value_characteristics = ATT_ERROR_REQUEST_NOT_SUPPORTED;
656 }
657
mock_gatt_client_enable_notification(mock_gatt_client_characteristic_t * characteristic,bool command_allowed)658 void mock_gatt_client_enable_notification(mock_gatt_client_characteristic_t * characteristic, bool command_allowed){
659 if (command_allowed){
660 characteristic->notification_status_code = ERROR_CODE_SUCCESS;
661 } else {
662 characteristic->notification_status_code = ERROR_CODE_COMMAND_DISALLOWED;
663 }
664 }
665
mock_gatt_client_dump_services(void)666 void mock_gatt_client_dump_services(void){
667 btstack_linked_list_iterator_t service_it;
668 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
669 while (btstack_linked_list_iterator_has_next(&service_it)){
670 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
671 printf("0x%02x: START SERVICE ", service->start_group_handle);
672 if (service->uuid16) {
673 printf("%04x\n", service->uuid16);
674 } else {
675 printf("%s\n", uuid128_to_str(service->uuid128));
676 }
677
678 btstack_linked_list_iterator_t characteristic_it;
679 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
680 while (btstack_linked_list_iterator_has_next(&characteristic_it)){
681 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
682 printf("0x%02x: START CHR ", characteristic->start_handle);
683 if (characteristic->uuid16) {
684 printf("%04x\n", characteristic->uuid16);
685 } else {
686 printf("%s\n", uuid128_to_str(characteristic->uuid128));
687 }
688 printf("0x%02x: VALUE HANDLE CHR\n", characteristic->value_handle);
689
690 btstack_linked_list_iterator_t desc_it;
691 btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors);
692 while (btstack_linked_list_iterator_has_next(&desc_it)){
693 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it);
694 printf("0x%02x: DESC 0x%02x\n", desc->handle, desc->uuid16);
695 }
696
697 printf("0x%02x: END CHR 0%02x\n", characteristic->end_handle, characteristic->uuid16);
698 }
699 printf("0x%02x: END SERVICE 0%02x\n", service->end_group_handle, service->uuid16);
700
701 }
702 }
703
mock_gatt_client_add_primary_service(void)704 static void mock_gatt_client_add_primary_service(void){
705 // set lsat group handle
706 // create new service
707 mock_gatt_client_last_service = (mock_gatt_client_service_t * )malloc(sizeof(mock_gatt_client_service_t));
708 memset(mock_gatt_client_last_service, 0, sizeof(mock_gatt_client_service_t));
709 mock_gatt_client_last_service->start_group_handle = mock_gatt_client_att_handle_generator++;
710 mock_gatt_client_last_service->end_group_handle = mock_gatt_client_last_service->start_group_handle;
711 btstack_linked_list_add_tail(&mock_gatt_client_services, (btstack_linked_item_t*)mock_gatt_client_last_service);
712 mock_gatt_client_last_characteristic = NULL;
713 }
714
mock_gatt_client_add_primary_service_uuid16(uint16_t service_uuid)715 mock_gatt_client_service_t * mock_gatt_client_add_primary_service_uuid16(uint16_t service_uuid){
716 mock_gatt_client_add_primary_service();
717 mock_gatt_client_last_service->uuid16 = service_uuid;
718 uuid_add_bluetooth_prefix(mock_gatt_client_last_service->uuid128, service_uuid);
719 return mock_gatt_client_last_service;
720 }
mock_gatt_client_add_primary_service_uuid128(const uint8_t * service_uuid)721 mock_gatt_client_service_t * mock_gatt_client_add_primary_service_uuid128(const uint8_t * service_uuid){
722 mock_gatt_client_add_primary_service();
723 (void) memcpy(mock_gatt_client_last_service->uuid128, service_uuid, 16);
724 return mock_gatt_client_last_service;
725 }
726
mock_gatt_client_add_characteristic(uint16_t properties)727 static void mock_gatt_client_add_characteristic(uint16_t properties){
728 btstack_assert(mock_gatt_client_last_service != NULL);
729 mock_gatt_client_last_characteristic = (mock_gatt_client_characteristic_t * )malloc(sizeof(mock_gatt_client_characteristic_t));
730 memset(mock_gatt_client_last_characteristic, 0, sizeof(mock_gatt_client_characteristic_t));
731 mock_gatt_client_last_characteristic->properties = properties;
732 mock_gatt_client_last_characteristic->start_handle = mock_gatt_client_att_handle_generator++;
733 mock_gatt_client_last_characteristic->value_handle = mock_gatt_client_att_handle_generator++;
734 mock_gatt_client_last_characteristic->end_handle = mock_gatt_client_last_characteristic->value_handle;
735 btstack_linked_list_add_tail(&mock_gatt_client_last_service->characteristics, (btstack_linked_item_t*)mock_gatt_client_last_characteristic);
736 mock_gatt_client_last_service->end_group_handle = mock_gatt_client_att_handle_generator - 1;
737 }
738
mock_gatt_client_add_characteristic_uuid16(uint16_t characteristic_uuid,uint16_t properties)739 mock_gatt_client_characteristic_t * mock_gatt_client_add_characteristic_uuid16(uint16_t characteristic_uuid, uint16_t properties){
740 mock_gatt_client_add_characteristic(properties);
741 mock_gatt_client_last_characteristic->uuid16 = characteristic_uuid;
742 uuid_add_bluetooth_prefix(mock_gatt_client_last_characteristic->uuid128, characteristic_uuid);
743 return mock_gatt_client_last_characteristic;
744 }
745
mock_gatt_client_add_characteristic_uuid128(const uint8_t * characteristic_uuid,uint16_t properties)746 mock_gatt_client_characteristic_t * mock_gatt_client_add_characteristic_uuid128(const uint8_t * characteristic_uuid, uint16_t properties){
747 mock_gatt_client_add_characteristic(properties);
748 (void) memcpy(mock_gatt_client_last_characteristic->uuid128, characteristic_uuid, 16);
749 return mock_gatt_client_last_characteristic;
750 }
751
mock_gatt_client_add_characteristic_descriptor(void)752 static mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_add_characteristic_descriptor(void){
753 btstack_assert(mock_gatt_client_last_characteristic != NULL);
754 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t * )malloc(sizeof(mock_gatt_client_characteristic_descriptor_t));
755 memset(desc, 0, sizeof(mock_gatt_client_characteristic_descriptor_t));
756 desc->handle = mock_gatt_client_att_handle_generator++;
757 btstack_linked_list_add_tail(&mock_gatt_client_last_characteristic->descriptors, (btstack_linked_item_t*)desc);
758 mock_gatt_client_last_characteristic->end_handle = mock_gatt_client_att_handle_generator - 1;
759 mock_gatt_client_last_service->end_group_handle = mock_gatt_client_att_handle_generator - 1;
760 return desc;
761 }
762
mock_gatt_client_add_characteristic_descriptor_uuid16(uint16_t descriptor_uuid)763 mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_add_characteristic_descriptor_uuid16(uint16_t descriptor_uuid){
764 mock_gatt_client_characteristic_descriptor_t * desc = mock_gatt_client_add_characteristic_descriptor();
765 desc->uuid16 = descriptor_uuid;
766 uuid_add_bluetooth_prefix(desc->uuid128, descriptor_uuid);
767 return desc;
768 }
769
mock_gatt_client_add_characteristic_descriptor_uuid128(const uint8_t * descriptor_uuid)770 mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_add_characteristic_descriptor_uuid128(const uint8_t * descriptor_uuid){
771 mock_gatt_client_characteristic_descriptor_t * desc = mock_gatt_client_add_characteristic_descriptor();
772 (void) memcpy(desc->uuid128, descriptor_uuid, 16);
773 return desc;
774 }
775
mock_gatt_client_set_descriptor_characteristic_value(mock_gatt_client_characteristic_descriptor_t * descriptor,uint8_t * value_buffer,uint16_t value_len)776 void mock_gatt_client_set_descriptor_characteristic_value(mock_gatt_client_characteristic_descriptor_t * descriptor, uint8_t * value_buffer, uint16_t value_len){
777 btstack_assert(descriptor != NULL);
778 descriptor->value_buffer = value_buffer;
779 descriptor->value_len = value_len;
780 }
781
mock_gatt_client_set_characteristic_value(mock_gatt_client_characteristic_t * characteristic,uint8_t * value_buffer,uint16_t value_len)782 void mock_gatt_client_set_characteristic_value(mock_gatt_client_characteristic_t * characteristic, uint8_t * value_buffer, uint16_t value_len){
783 btstack_assert(characteristic != NULL);
784 characteristic->value_buffer = value_buffer;
785 characteristic->value_len = value_len;
786 }
787
788 // simulate error
mock_gatt_client_simulate_att_error(uint8_t att_error)789 void mock_gatt_client_simulate_att_error(uint8_t att_error){
790 mock_gatt_client_att_error = att_error;
791 }
792