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, 14 MOCK_QUERY_DISCOVER_CHARACTERISTICS, 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(&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(&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(&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; 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; 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(false); 249 return ERROR_CODE_SUCCESS; 250 } 251 252 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){ 253 btstack_assert(false); 254 } 255 256 /** 257 * copied from gatt_client.c - START 258 */ 259 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){ 260 service->start_group_handle = little_endian_read_16(packet, offset); 261 service->end_group_handle = little_endian_read_16(packet, offset + 2); 262 reverse_128(&packet[offset + 4], service->uuid128); 263 if (uuid_has_bluetooth_prefix(service->uuid128)){ 264 service->uuid16 = big_endian_read_32(service->uuid128, 0); 265 } else { 266 service->uuid16 = 0; 267 } 268 } 269 270 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){ 271 characteristic->start_handle = little_endian_read_16(packet, offset); 272 characteristic->value_handle = little_endian_read_16(packet, offset + 2); 273 characteristic->end_handle = little_endian_read_16(packet, offset + 4); 274 characteristic->properties = little_endian_read_16(packet, offset + 6); 275 reverse_128(&packet[offset+8], characteristic->uuid128); 276 if (uuid_has_bluetooth_prefix(characteristic->uuid128)){ 277 characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0); 278 } else { 279 characteristic->uuid16 = 0; 280 } 281 } 282 283 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){ 284 descriptor->handle = little_endian_read_16(packet, offset); 285 reverse_128(&packet[offset+2], descriptor->uuid128); 286 if (uuid_has_bluetooth_prefix(descriptor->uuid128)){ 287 descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0); 288 } else { 289 descriptor->uuid16 = 0; 290 } 291 } 292 293 static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){ 294 if (!callback) return; 295 (*callback)(HCI_EVENT_PACKET, 0, packet, size); 296 } 297 298 static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){ 299 // @format H1 300 uint8_t packet[5]; 301 packet[0] = GATT_EVENT_QUERY_COMPLETE; 302 packet[1] = 3; 303 little_endian_store_16(packet, 2, gatt_client->con_handle); 304 packet[4] = att_status; 305 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 306 } 307 308 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){ 309 // @format HX 310 uint8_t packet[24]; 311 packet[0] = GATT_EVENT_SERVICE_QUERY_RESULT; 312 packet[1] = sizeof(packet) - 2u; 313 little_endian_store_16(packet, 2, gatt_client->con_handle); 314 /// 315 little_endian_store_16(packet, 4, start_group_handle); 316 little_endian_store_16(packet, 6, end_group_handle); 317 reverse_128(uuid128, &packet[8]); 318 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 319 } 320 321 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, 322 uint16_t properties, const uint8_t * uuid128){ 323 // @format HY 324 uint8_t packet[28]; 325 packet[0] = GATT_EVENT_CHARACTERISTIC_QUERY_RESULT; 326 packet[1] = sizeof(packet) - 2u; 327 little_endian_store_16(packet, 2, gatt_client->con_handle); 328 /// 329 little_endian_store_16(packet, 4, start_handle); 330 little_endian_store_16(packet, 6, value_handle); 331 little_endian_store_16(packet, 8, end_handle); 332 little_endian_store_16(packet, 10, properties); 333 reverse_128(uuid128, &packet[12]); 334 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 335 } 336 337 static void emit_gatt_all_characteristic_descriptors_result_event( 338 gatt_client_t * gatt_client, uint16_t descriptor_handle, const uint8_t * uuid128){ 339 // @format HZ 340 uint8_t packet[22]; 341 packet[0] = GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT; 342 packet[1] = sizeof(packet) - 2u; 343 little_endian_store_16(packet, 2, gatt_client->con_handle); 344 /// 345 little_endian_store_16(packet, 4, descriptor_handle); 346 reverse_128(uuid128, &packet[6]); 347 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 348 } 349 350 351 static const int characteristic_value_event_header_size = 8; 352 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){ 353 // before the value inside the ATT PDU 354 uint8_t * packet = value - characteristic_value_event_header_size; 355 packet[0] = type; 356 packet[1] = characteristic_value_event_header_size - 2 + length; 357 little_endian_store_16(packet, 2, con_handle); 358 little_endian_store_16(packet, 4, attribute_handle); 359 little_endian_store_16(packet, 6, length); 360 return packet; 361 } 362 363 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes 364 static void report_gatt_characteristic_value(gatt_client_t * gatt_client, uint16_t attribute_handle, uint8_t * value, uint16_t length){ 365 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, gatt_client->con_handle, attribute_handle, value, length); 366 emit_event_new(gatt_client->callback, packet, characteristic_value_event_header_size + length); 367 } 368 369 /** 370 * copied from gatt_client.c - END 371 */ 372 373 static void mock_gatt_client_emit_complete(uint8_t status){ 374 mock_gatt_client_state = MOCK_QUERY_IDLE; 375 emit_gatt_complete_event(&gatt_client, status); 376 } 377 378 void mock_gatt_client_run(void){ 379 btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE); 380 mock_gatt_client_characteristic_t * characteristic; 381 mock_gatt_client_characteristic_descriptor_t * descriptor; 382 383 btstack_linked_list_iterator_t service_it; 384 btstack_linked_list_iterator_t characteristic_it; 385 btstack_linked_list_iterator_t descriptor_it; 386 387 uint8_t uuid128[16]; 388 389 while (mock_gatt_client_state != MOCK_QUERY_IDLE){ 390 switch (mock_gatt_client_state){ 391 case MOCK_QUERY_DISCOVER_PRIMARY_SERVICES: 392 // emit GATT_EVENT_SERVICE_QUERY_RESULT for each matching service 393 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 394 while (btstack_linked_list_iterator_has_next(&service_it)){ 395 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 396 if (service->uuid16 != mock_gatt_client_uuid) continue; 397 mock_gatt_client_last_service = service; 398 uuid_add_bluetooth_prefix(uuid128, service->uuid16); 399 emit_gatt_service_query_result_event(&gatt_client, service->start_group_handle, service->end_group_handle, uuid128); 400 } 401 // emit GATT_EVENT_QUERY_COMPLETE 402 mock_gatt_client_emit_complete(ATT_ERROR_SUCCESS); 403 break; 404 405 case MOCK_QUERY_DISCOVER_CHARACTERISTICS: 406 // emit GATT_EVENT_CHARACTERISTIC_QUERY_RESULT for each matching characteristic 407 btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 408 while (btstack_linked_list_iterator_has_next(&service_it)){ 409 mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 410 411 btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 412 while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 413 mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 414 if (characteristic->uuid16 != mock_gatt_client_uuid) continue; 415 if (characteristic->start_handle < mock_gatt_client_start_handle) continue; 416 if (characteristic->end_handle > mock_gatt_client_end_handle) continue; 417 418 uuid_add_bluetooth_prefix(uuid128, characteristic->uuid16); 419 emit_gatt_characteristic_query_result_event(&gatt_client, 420 characteristic->start_handle, characteristic->value_handle, characteristic->end_handle, 421 characteristic->properties, uuid128); 422 } 423 } 424 425 // emit GATT_EVENT_QUERY_COMPLETE 426 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 427 break; 428 429 case MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS: 430 characteristic = mock_gatt_client_get_characteristic_for_value_handle(mock_gatt_client_value_handle); 431 btstack_assert(characteristic != NULL); 432 433 btstack_linked_list_iterator_init(&descriptor_it, &characteristic->descriptors); 434 while (btstack_linked_list_iterator_has_next(&descriptor_it)){ 435 mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&descriptor_it); 436 437 uuid_add_bluetooth_prefix(uuid128, desc->uuid16); 438 emit_gatt_all_characteristic_descriptors_result_event(&gatt_client, desc->handle, uuid128); 439 } 440 441 442 // emit GATT_EVENT_QUERY_COMPLETE 443 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 444 break; 445 446 case MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: 447 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 448 break; 449 450 case MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE: 451 descriptor = mock_gatt_client_get_characteristic_descriptor_for_handle(mock_gatt_client_value_handle); 452 btstack_assert(descriptor != NULL); 453 btstack_assert(descriptor->value_buffer != NULL); 454 455 report_gatt_characteristic_value(&gatt_client, descriptor->handle, descriptor->value_buffer, descriptor->value_len); 456 mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 457 break; 458 459 default: 460 btstack_assert(false); 461 break; 462 } 463 } 464 mock_gatt_client_att_error = ERROR_CODE_SUCCESS; 465 mock_gatt_client_state = MOCK_QUERY_IDLE; 466 }