1 #include <stdint.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 #include "btstack_debug.h" 6 #include "mock_gatt_client.h" 7 8 #include "CppUTest/TestHarness.h" 9 #include "CppUTestExt/MockSupport.h" 10 11 static enum { 12 MOCK_QUERY_IDLE = 0, 13 MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID16, 14 MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID16, 15 MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS, 16 MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION, 17 MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE 18 } mock_gatt_client_state; 19 20 static uint16_t mock_gatt_client_att_handle_generator; 21 22 static uint8_t mock_gatt_client_att_error; 23 static uint16_t mock_gatt_client_uuid; 24 static uint16_t mock_gatt_client_value_handle; 25 static uint16_t mock_gatt_client_start_handle; 26 static uint16_t mock_gatt_client_end_handle; 27 28 static gatt_client_t gatt_client; 29 30 static btstack_linked_list_t mock_gatt_client_services; 31 32 static mock_gatt_client_service_t * mock_gatt_client_last_service; 33 static mock_gatt_client_characteristic_t * mock_gatt_client_last_characteristic; 34 35 void mock_gatt_client_reset(void){ 36 mock_gatt_client_att_error = 0; 37 mock_gatt_client_state = MOCK_QUERY_IDLE; 38 mock_gatt_client_att_handle_generator = 0; 39 mock_gatt_client_last_service = NULL; 40 41 btstack_linked_list_iterator_t service_it; 42 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 43 while (btstack_linked_list_iterator_has_next(&service_it)){ 44 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 45 btstack_linked_list_remove(&mock_gatt_client_services, (btstack_linked_item_t *) service); 46 47 btstack_linked_list_iterator_t characteristic_it; 48 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 49 while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 50 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 51 btstack_linked_list_remove(&service->characteristics, (btstack_linked_item_t *) characteristic); 52 53 btstack_linked_list_iterator_t desc_it; 54 btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors); 55 while (btstack_linked_list_iterator_has_next(&desc_it)){ 56 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it); 57 btstack_linked_list_remove(&characteristic->descriptors, (btstack_linked_item_t *) desc); 58 free(desc); 59 } 60 free(characteristic); 61 } 62 free(service); 63 } 64 } 65 66 void mock_gatt_client_dump_services(void){ 67 btstack_linked_list_iterator_t service_it; 68 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 69 while (btstack_linked_list_iterator_has_next(&service_it)){ 70 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 71 printf("0x%02x: START SERVICE 0%02x\n", service->start_group_handle, service->uuid16); 72 73 btstack_linked_list_iterator_t characteristic_it; 74 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 75 while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 76 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 77 printf("0x%02x: START CHR 0%02x\n", characteristic->start_handle, characteristic->uuid16); 78 printf("0x%02x: VALUE HANDLE CHR 0%02x\n", characteristic->value_handle, characteristic->uuid16); 79 80 btstack_linked_list_iterator_t desc_it; 81 btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors); 82 while (btstack_linked_list_iterator_has_next(&desc_it)){ 83 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it); 84 printf("0x%02x: DESC 0x%02x\n", desc->handle, desc->uuid16); 85 } 86 87 printf("0x%02x: END CHR 0%02x\n", characteristic->end_handle, characteristic->uuid16); 88 89 } 90 printf("0x%02x: END SERVICE 0%02x\n", service->end_group_handle, service->uuid16); 91 92 } 93 } 94 95 mock_gatt_client_service_t * mock_gatt_client_add_primary_service_uuid16(uint16_t service_uuid){ 96 // set lsat group handle 97 // create new service 98 mock_gatt_client_last_service = (mock_gatt_client_service_t * )malloc(sizeof(mock_gatt_client_service_t)); 99 memset(mock_gatt_client_last_service, 0, sizeof(mock_gatt_client_service_t)); 100 mock_gatt_client_last_service->uuid16 = service_uuid; 101 mock_gatt_client_last_service->start_group_handle = mock_gatt_client_att_handle_generator++; 102 mock_gatt_client_last_service->end_group_handle = 0xffff; 103 btstack_linked_list_add_tail(&mock_gatt_client_services, (btstack_linked_item_t*)mock_gatt_client_last_service); 104 mock_gatt_client_last_characteristic = NULL; 105 return mock_gatt_client_last_service; 106 } 107 108 mock_gatt_client_characteristic_t * mock_gatt_client_add_characteristic_uuid16(uint16_t characteristic_uuid, uint16_t properties){ 109 btstack_assert(mock_gatt_client_last_service != NULL); 110 mock_gatt_client_last_characteristic = (mock_gatt_client_characteristic_t * )malloc(sizeof(mock_gatt_client_characteristic_t)); 111 memset(mock_gatt_client_last_characteristic, 0, sizeof(mock_gatt_client_characteristic_t)); 112 mock_gatt_client_last_characteristic->uuid16 = characteristic_uuid; 113 mock_gatt_client_last_characteristic->properties = properties; 114 mock_gatt_client_last_characteristic->start_handle = mock_gatt_client_att_handle_generator++; 115 mock_gatt_client_last_characteristic->value_handle = mock_gatt_client_att_handle_generator++; 116 mock_gatt_client_last_characteristic->end_handle = mock_gatt_client_last_characteristic->value_handle; 117 btstack_linked_list_add_tail(&mock_gatt_client_last_service->characteristics, (btstack_linked_item_t*)mock_gatt_client_last_characteristic); 118 mock_gatt_client_last_service->end_group_handle = mock_gatt_client_att_handle_generator - 1; 119 return mock_gatt_client_last_characteristic; 120 } 121 122 mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_add_characteristic_descriptor_uuid16(uint16_t descriptor_uuid){ 123 btstack_assert(mock_gatt_client_last_characteristic != NULL); 124 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t * )malloc(sizeof(mock_gatt_client_characteristic_descriptor_t)); 125 memset(desc, 0, sizeof(mock_gatt_client_characteristic_descriptor_t)); 126 desc->uuid16 = descriptor_uuid; 127 desc->handle = mock_gatt_client_att_handle_generator++; 128 btstack_linked_list_add_tail(&mock_gatt_client_last_characteristic->descriptors, (btstack_linked_item_t*)desc); 129 mock_gatt_client_last_characteristic->end_handle = mock_gatt_client_att_handle_generator - 1; 130 mock_gatt_client_last_service->end_group_handle = mock_gatt_client_att_handle_generator - 1; 131 return desc; 132 } 133 134 static mock_gatt_client_characteristic_t * mock_gatt_client_get_characteristic_for_value_handle(uint16_t value_handle){ 135 btstack_linked_list_iterator_t service_it; 136 btstack_linked_list_iterator_t characteristic_it; 137 138 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 139 while (btstack_linked_list_iterator_has_next(&service_it)){ 140 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 141 142 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 143 while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 144 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 145 if (characteristic->value_handle != value_handle) continue; 146 return characteristic; 147 } 148 } 149 return NULL; 150 } 151 152 static mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_get_characteristic_descriptor_for_handle(uint16_t handle){ 153 btstack_linked_list_iterator_t service_it; 154 btstack_linked_list_iterator_t characteristic_it; 155 156 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 157 while (btstack_linked_list_iterator_has_next(&service_it)){ 158 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 159 160 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 161 while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 162 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 163 164 btstack_linked_list_iterator_t desc_it; 165 btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors); 166 while (btstack_linked_list_iterator_has_next(&desc_it)){ 167 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it); 168 if (desc->handle != handle) continue; 169 return desc; 170 } 171 } 172 } 173 return NULL; 174 } 175 176 177 void mock_gatt_client_set_characteristic_value(mock_gatt_client_characteristic_descriptor_t * descriptor, uint8_t * value_buffer, uint16_t value_len){ 178 btstack_assert(descriptor != NULL); 179 descriptor->value_buffer = value_buffer; 180 descriptor->value_len = value_len; 181 } 182 183 // simulate erro 184 void mock_gatt_client_simulate_att_error(uint8_t att_error){ 185 mock_gatt_client_att_error = att_error; 186 } 187 188 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){ 189 mock_gatt_client_state = MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID16; 190 mock_gatt_client_uuid = uuid16; 191 192 gatt_client.callback = callback; 193 gatt_client.con_handle = con_handle; 194 return ERROR_CODE_SUCCESS; 195 } 196 197 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){ 198 mock_gatt_client_state = MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID16; 199 mock_gatt_client_uuid = uuid16; 200 mock_gatt_client_start_handle = start_handle; 201 mock_gatt_client_end_handle = end_handle; 202 203 gatt_client.callback = callback; 204 gatt_client.con_handle = con_handle; 205 return ERROR_CODE_SUCCESS; 206 } 207 208 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){ 209 mock_gatt_client_state = MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS; 210 mock_gatt_client_value_handle = characteristic->value_handle; 211 212 gatt_client.callback = callback; 213 gatt_client.con_handle = con_handle; 214 return ERROR_CODE_SUCCESS; 215 } 216 217 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){ 218 mock_gatt_client_state = MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 219 mock_gatt_client_uuid = characteristic->uuid16; 220 221 gatt_client.callback = callback; 222 gatt_client.con_handle = con_handle; 223 return ERROR_CODE_SUCCESS; 224 } 225 226 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){ 227 notification->callback = callback; 228 notification->con_handle = con_handle; 229 230 if (characteristic == NULL){ 231 // 'all characteristics': not used yet 232 btstack_assert(false); 233 } else { 234 notification->attribute_handle = characteristic->value_handle; 235 } 236 237 // finc our characteristic and set point to notification 238 } 239 240 241 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){ 242 mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE; 243 mock_gatt_client_value_handle = value_handle; 244 return ERROR_CODE_SUCCESS; 245 } 246 247 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){ 248 btstack_assert(characteristic != NULL); 249 mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE; 250 mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle); 251 252 btstack_assert(mock_characteristic != NULL); 253 254 mock_gatt_client_value_handle = mock_characteristic->value_handle; 255 return ERROR_CODE_SUCCESS; 256 } 257 258 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){ 259 } 260 261 /** 262 * copied from gatt_client.c - START 263 */ 264 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){ 265 service->start_group_handle = little_endian_read_16(packet, offset); 266 service->end_group_handle = little_endian_read_16(packet, offset + 2); 267 reverse_128(&packet[offset + 4], service->uuid128); 268 if (uuid_has_bluetooth_prefix(service->uuid128)){ 269 service->uuid16 = big_endian_read_32(service->uuid128, 0); 270 } else { 271 service->uuid16 = 0; 272 } 273 } 274 275 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){ 276 characteristic->start_handle = little_endian_read_16(packet, offset); 277 characteristic->value_handle = little_endian_read_16(packet, offset + 2); 278 characteristic->end_handle = little_endian_read_16(packet, offset + 4); 279 characteristic->properties = little_endian_read_16(packet, offset + 6); 280 reverse_128(&packet[offset+8], characteristic->uuid128); 281 if (uuid_has_bluetooth_prefix(characteristic->uuid128)){ 282 characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0); 283 } else { 284 characteristic->uuid16 = 0; 285 } 286 } 287 288 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){ 289 descriptor->handle = little_endian_read_16(packet, offset); 290 reverse_128(&packet[offset+2], descriptor->uuid128); 291 if (uuid_has_bluetooth_prefix(descriptor->uuid128)){ 292 descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0); 293 } else { 294 descriptor->uuid16 = 0; 295 } 296 } 297 298 static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){ 299 if (!callback) return; 300 (*callback)(HCI_EVENT_PACKET, 0, packet, size); 301 } 302 303 static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){ 304 // @format H1 305 uint8_t packet[5]; 306 packet[0] = GATT_EVENT_QUERY_COMPLETE; 307 packet[1] = 3; 308 little_endian_store_16(packet, 2, gatt_client->con_handle); 309 packet[4] = att_status; 310 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 311 } 312 313 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){ 314 // @format HX 315 uint8_t packet[24]; 316 packet[0] = GATT_EVENT_SERVICE_QUERY_RESULT; 317 packet[1] = sizeof(packet) - 2u; 318 little_endian_store_16(packet, 2, gatt_client->con_handle); 319 /// 320 little_endian_store_16(packet, 4, start_group_handle); 321 little_endian_store_16(packet, 6, end_group_handle); 322 reverse_128(uuid128, &packet[8]); 323 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 324 } 325 326 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, 327 uint16_t properties, const uint8_t * uuid128){ 328 // @format HY 329 uint8_t packet[28]; 330 packet[0] = GATT_EVENT_CHARACTERISTIC_QUERY_RESULT; 331 packet[1] = sizeof(packet) - 2u; 332 little_endian_store_16(packet, 2, gatt_client->con_handle); 333 /// 334 little_endian_store_16(packet, 4, start_handle); 335 little_endian_store_16(packet, 6, value_handle); 336 little_endian_store_16(packet, 8, end_handle); 337 little_endian_store_16(packet, 10, properties); 338 reverse_128(uuid128, &packet[12]); 339 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 340 } 341 342 static void emit_gatt_all_characteristic_descriptors_result_event( 343 gatt_client_t * gatt_client, uint16_t descriptor_handle, const uint8_t * uuid128){ 344 // @format HZ 345 uint8_t packet[22]; 346 packet[0] = GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT; 347 packet[1] = sizeof(packet) - 2u; 348 little_endian_store_16(packet, 2, gatt_client->con_handle); 349 /// 350 little_endian_store_16(packet, 4, descriptor_handle); 351 reverse_128(uuid128, &packet[6]); 352 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 353 } 354 355 356 static const int characteristic_value_event_header_size = 8; 357 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){ 358 // before the value inside the ATT PDU 359 uint8_t * packet = value - characteristic_value_event_header_size; 360 packet[0] = type; 361 packet[1] = characteristic_value_event_header_size - 2 + length; 362 little_endian_store_16(packet, 2, con_handle); 363 little_endian_store_16(packet, 4, attribute_handle); 364 little_endian_store_16(packet, 6, length); 365 return packet; 366 } 367 368 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes 369 static void report_gatt_characteristic_value(gatt_client_t * gatt_client, uint16_t attribute_handle, uint8_t * value, uint16_t length){ 370 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, gatt_client->con_handle, attribute_handle, value, length); 371 emit_event_new(gatt_client->callback, packet, characteristic_value_event_header_size + length); 372 } 373 374 /** 375 * copied from gatt_client.c - END 376 */ 377 378 static void mock_gatt_client_emit_complete(uint8_t status){ 379 mock_gatt_client_state = MOCK_QUERY_IDLE; 380 emit_gatt_complete_event(&gatt_client, status); 381 } 382 383 void mock_gatt_client_run(void){ 384 btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE); 385 mock_gatt_client_characteristic_t * characteristic; 386 mock_gatt_client_characteristic_descriptor_t * descriptor; 387 388 btstack_linked_list_iterator_t service_it; 389 btstack_linked_list_iterator_t characteristic_it; 390 btstack_linked_list_iterator_t descriptor_it; 391 392 uint8_t uuid128[16]; 393 394 while (mock_gatt_client_state != MOCK_QUERY_IDLE){ 395 switch (mock_gatt_client_state){ 396 case MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID16: 397 // emit GATT_EVENT_SERVICE_QUERY_RESULT for each matching service 398 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 399 while (btstack_linked_list_iterator_has_next(&service_it)){ 400 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 401 if (service->uuid16 != mock_gatt_client_uuid) continue; 402 mock_gatt_client_last_service = service; 403 uuid_add_bluetooth_prefix(uuid128, service->uuid16); 404 emit_gatt_service_query_result_event(&gatt_client, service->start_group_handle, service->end_group_handle, uuid128); 405 } 406 // emit GATT_EVENT_QUERY_COMPLETE 407 mock_gatt_client_emit_complete(ATT_ERROR_SUCCESS); 408 break; 409 410 case MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID16: 411 // emit GATT_EVENT_CHARACTERISTIC_QUERY_RESULT for each matching characteristic 412 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 413 while (btstack_linked_list_iterator_has_next(&service_it)){ 414 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 415 416 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 417 while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 418 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 419 if (characteristic->uuid16 != mock_gatt_client_uuid) continue; 420 if (characteristic->start_handle < mock_gatt_client_start_handle) continue; 421 if (characteristic->end_handle > mock_gatt_client_end_handle) continue; 422 423 uuid_add_bluetooth_prefix(uuid128, characteristic->uuid16); 424 emit_gatt_characteristic_query_result_event(&gatt_client, 425 characteristic->start_handle, characteristic->value_handle, characteristic->end_handle, 426 characteristic->properties, uuid128); 427 } 428 } 429 430 // emit GATT_EVENT_QUERY_COMPLETE 431 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 432 break; 433 434 case MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS: 435 characteristic = mock_gatt_client_get_characteristic_for_value_handle(mock_gatt_client_value_handle); 436 btstack_assert(characteristic != NULL); 437 438 btstack_linked_list_iterator_init(&descriptor_it, &characteristic->descriptors); 439 while (btstack_linked_list_iterator_has_next(&descriptor_it)){ 440 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&descriptor_it); 441 442 uuid_add_bluetooth_prefix(uuid128, desc->uuid16); 443 emit_gatt_all_characteristic_descriptors_result_event(&gatt_client, desc->handle, uuid128); 444 } 445 446 // emit GATT_EVENT_QUERY_COMPLETE 447 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 448 break; 449 450 case MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: 451 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 452 break; 453 454 case MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE: 455 descriptor = mock_gatt_client_get_characteristic_descriptor_for_handle(mock_gatt_client_value_handle); 456 btstack_assert(descriptor != NULL); 457 btstack_assert(descriptor->value_buffer != NULL); 458 459 report_gatt_characteristic_value(&gatt_client, descriptor->handle, descriptor->value_buffer, descriptor->value_len); 460 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 461 break; 462 463 default: 464 btstack_assert(false); 465 break; 466 } 467 } 468 mock_gatt_client_att_error = ERROR_CODE_SUCCESS; 469 mock_gatt_client_state = MOCK_QUERY_IDLE; 470 }