10f7fd6c1SMilanka Ringwald #include <stdint.h> 20f7fd6c1SMilanka Ringwald #include <stdio.h> 30f7fd6c1SMilanka Ringwald #include <string.h> 40f7fd6c1SMilanka Ringwald 5af770404SMilanka Ringwald #include "btstack_debug.h" 67e693ad3SMilanka Ringwald #include "bluetooth_gatt.h" 70f7fd6c1SMilanka Ringwald #include "mock_gatt_client.h" 80f7fd6c1SMilanka Ringwald 90f7fd6c1SMilanka Ringwald #include "CppUTest/TestHarness.h" 100f7fd6c1SMilanka Ringwald #include "CppUTestExt/MockSupport.h" 110f7fd6c1SMilanka Ringwald 12af770404SMilanka Ringwald static enum { 13af770404SMilanka Ringwald MOCK_QUERY_IDLE = 0, 14d41a8f51SMilanka Ringwald MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID16, 15d41a8f51SMilanka Ringwald MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID16, 1676cdba3eSMilanka Ringwald MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS, 1776cdba3eSMilanka Ringwald MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION, 187e693ad3SMilanka Ringwald MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE, 197e693ad3SMilanka Ringwald MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE 20af770404SMilanka Ringwald } mock_gatt_client_state; 21af770404SMilanka Ringwald 2276cdba3eSMilanka Ringwald static uint16_t mock_gatt_client_att_handle_generator; 2376cdba3eSMilanka Ringwald 24af770404SMilanka Ringwald static uint8_t mock_gatt_client_att_error; 25af770404SMilanka Ringwald static uint16_t mock_gatt_client_uuid; 2676cdba3eSMilanka Ringwald static uint16_t mock_gatt_client_value_handle; 2776cdba3eSMilanka Ringwald static uint16_t mock_gatt_client_start_handle; 2876cdba3eSMilanka Ringwald static uint16_t mock_gatt_client_end_handle; 2976cdba3eSMilanka Ringwald 30af770404SMilanka Ringwald static gatt_client_t gatt_client; 310f7fd6c1SMilanka Ringwald 327da2c1baSMilanka Ringwald static btstack_linked_list_t mock_gatt_client_services; 337da2c1baSMilanka Ringwald 347da2c1baSMilanka Ringwald static mock_gatt_client_service_t * mock_gatt_client_last_service; 357da2c1baSMilanka Ringwald static mock_gatt_client_characteristic_t * mock_gatt_client_last_characteristic; 367da2c1baSMilanka Ringwald 37ec1a0daeSMilanka Ringwald static uint8_t moc_att_error_code_discover_services; 38ec1a0daeSMilanka Ringwald static uint8_t moc_att_error_code_discover_characteristics; 39ec1a0daeSMilanka Ringwald static uint8_t moc_att_error_code_discover_characteristic_descriptors; 407e693ad3SMilanka Ringwald static bool mock_gatt_client_wrong_con_handle; 417e693ad3SMilanka Ringwald static bool mock_gatt_client_wrong_value_handle; 42ec1a0daeSMilanka Ringwald 437e693ad3SMilanka Ringwald static void mock_gatt_client_reset_errors(void){ 44ec1a0daeSMilanka Ringwald moc_att_error_code_discover_services = ATT_ERROR_SUCCESS; 45ec1a0daeSMilanka Ringwald moc_att_error_code_discover_characteristics = ATT_ERROR_SUCCESS; 46ec1a0daeSMilanka Ringwald moc_att_error_code_discover_characteristic_descriptors = ATT_ERROR_SUCCESS; 477e693ad3SMilanka Ringwald 487e693ad3SMilanka Ringwald mock_gatt_client_wrong_con_handle = false; 497e693ad3SMilanka Ringwald mock_gatt_client_wrong_value_handle = false; 50ec1a0daeSMilanka Ringwald } 51ec1a0daeSMilanka Ringwald 520f7fd6c1SMilanka Ringwald void mock_gatt_client_reset(void){ 53af770404SMilanka Ringwald mock_gatt_client_att_error = 0; 54af770404SMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_IDLE; 5576cdba3eSMilanka Ringwald mock_gatt_client_att_handle_generator = 0; 5676cdba3eSMilanka Ringwald mock_gatt_client_last_service = NULL; 577da2c1baSMilanka Ringwald 587e693ad3SMilanka Ringwald mock_gatt_client_reset_errors(); 59ec1a0daeSMilanka Ringwald 607da2c1baSMilanka Ringwald btstack_linked_list_iterator_t service_it; 617da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 627da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){ 637da2c1baSMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 647da2c1baSMilanka Ringwald btstack_linked_list_remove(&mock_gatt_client_services, (btstack_linked_item_t *) service); 657da2c1baSMilanka Ringwald 667da2c1baSMilanka Ringwald btstack_linked_list_iterator_t characteristic_it; 677da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 687da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 697da2c1baSMilanka Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 707da2c1baSMilanka Ringwald btstack_linked_list_remove(&service->characteristics, (btstack_linked_item_t *) characteristic); 717da2c1baSMilanka Ringwald 727da2c1baSMilanka Ringwald btstack_linked_list_iterator_t desc_it; 737da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors); 747da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&desc_it)){ 757da2c1baSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it); 767da2c1baSMilanka Ringwald btstack_linked_list_remove(&characteristic->descriptors, (btstack_linked_item_t *) desc); 777da2c1baSMilanka Ringwald free(desc); 787da2c1baSMilanka Ringwald } 797da2c1baSMilanka Ringwald free(characteristic); 807da2c1baSMilanka Ringwald } 817da2c1baSMilanka Ringwald free(service); 827da2c1baSMilanka Ringwald } 830f7fd6c1SMilanka Ringwald } 84af770404SMilanka Ringwald 85ec1a0daeSMilanka Ringwald void mock_gatt_client_set_att_error_discover_primary_services(void){ 86ec1a0daeSMilanka Ringwald moc_att_error_code_discover_services = ATT_ERROR_REQUEST_NOT_SUPPORTED; 87ec1a0daeSMilanka Ringwald } 88ec1a0daeSMilanka Ringwald void mock_gatt_client_set_att_error_discover_characteristics(void){ 89ec1a0daeSMilanka Ringwald moc_att_error_code_discover_characteristics = ATT_ERROR_REQUEST_NOT_SUPPORTED; 90ec1a0daeSMilanka Ringwald } 91ec1a0daeSMilanka Ringwald void mock_gatt_client_set_att_error_discover_characteristic_descriptors(void){ 92ec1a0daeSMilanka Ringwald moc_att_error_code_discover_characteristic_descriptors = ATT_ERROR_REQUEST_NOT_SUPPORTED; 93ec1a0daeSMilanka Ringwald } 94ec1a0daeSMilanka Ringwald 957e693ad3SMilanka Ringwald void mock_gatt_client_simulate_invalid_con_handle(void){ 967e693ad3SMilanka Ringwald mock_gatt_client_wrong_con_handle = true; 977e693ad3SMilanka Ringwald } 987e693ad3SMilanka Ringwald void mock_gatt_client_simulate_invalid_value_handle(void){ 997e693ad3SMilanka Ringwald mock_gatt_client_wrong_value_handle = true; 1007e693ad3SMilanka Ringwald } 1017e693ad3SMilanka Ringwald 1027e693ad3SMilanka Ringwald void mock_gatt_client_enable_notification(mock_gatt_client_characteristic_t * characteristic, bool command_allowed){ 1037e693ad3SMilanka Ringwald if (command_allowed){ 1047e693ad3SMilanka Ringwald characteristic->notification_status_code = ERROR_CODE_SUCCESS; 1057e693ad3SMilanka Ringwald } else { 1067e693ad3SMilanka Ringwald characteristic->notification_status_code = ERROR_CODE_COMMAND_DISALLOWED; 1077e693ad3SMilanka Ringwald } 1087e693ad3SMilanka Ringwald } 1097e693ad3SMilanka Ringwald 11076cdba3eSMilanka Ringwald void mock_gatt_client_dump_services(void){ 11176cdba3eSMilanka Ringwald btstack_linked_list_iterator_t service_it; 11276cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 11376cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){ 11476cdba3eSMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 11576cdba3eSMilanka Ringwald printf("0x%02x: START SERVICE 0%02x\n", service->start_group_handle, service->uuid16); 11676cdba3eSMilanka Ringwald 11776cdba3eSMilanka Ringwald btstack_linked_list_iterator_t characteristic_it; 11876cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 11976cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 12076cdba3eSMilanka Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 12176cdba3eSMilanka Ringwald printf("0x%02x: START CHR 0%02x\n", characteristic->start_handle, characteristic->uuid16); 12276cdba3eSMilanka Ringwald printf("0x%02x: VALUE HANDLE CHR 0%02x\n", characteristic->value_handle, characteristic->uuid16); 12376cdba3eSMilanka Ringwald 12476cdba3eSMilanka Ringwald btstack_linked_list_iterator_t desc_it; 12576cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors); 12676cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&desc_it)){ 12776cdba3eSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it); 12876cdba3eSMilanka Ringwald printf("0x%02x: DESC 0x%02x\n", desc->handle, desc->uuid16); 12976cdba3eSMilanka Ringwald } 13076cdba3eSMilanka Ringwald 13176cdba3eSMilanka Ringwald printf("0x%02x: END CHR 0%02x\n", characteristic->end_handle, characteristic->uuid16); 13276cdba3eSMilanka Ringwald 13376cdba3eSMilanka Ringwald } 13476cdba3eSMilanka Ringwald printf("0x%02x: END SERVICE 0%02x\n", service->end_group_handle, service->uuid16); 13576cdba3eSMilanka Ringwald 13676cdba3eSMilanka Ringwald } 13776cdba3eSMilanka Ringwald } 13876cdba3eSMilanka Ringwald 13976cdba3eSMilanka Ringwald mock_gatt_client_service_t * mock_gatt_client_add_primary_service_uuid16(uint16_t service_uuid){ 14076cdba3eSMilanka Ringwald // set lsat group handle 14176cdba3eSMilanka Ringwald // create new service 1427da2c1baSMilanka Ringwald mock_gatt_client_last_service = (mock_gatt_client_service_t * )malloc(sizeof(mock_gatt_client_service_t)); 1437da2c1baSMilanka Ringwald memset(mock_gatt_client_last_service, 0, sizeof(mock_gatt_client_service_t)); 1447da2c1baSMilanka Ringwald mock_gatt_client_last_service->uuid16 = service_uuid; 14576cdba3eSMilanka Ringwald mock_gatt_client_last_service->start_group_handle = mock_gatt_client_att_handle_generator++; 1466ad61799SMilanka Ringwald mock_gatt_client_last_service->end_group_handle = mock_gatt_client_last_service->start_group_handle; 1475b92fca9SMilanka Ringwald btstack_linked_list_add_tail(&mock_gatt_client_services, (btstack_linked_item_t*)mock_gatt_client_last_service); 14876cdba3eSMilanka Ringwald mock_gatt_client_last_characteristic = NULL; 14976cdba3eSMilanka Ringwald return mock_gatt_client_last_service; 1500f7fd6c1SMilanka Ringwald } 151af770404SMilanka Ringwald 15276cdba3eSMilanka Ringwald mock_gatt_client_characteristic_t * mock_gatt_client_add_characteristic_uuid16(uint16_t characteristic_uuid, uint16_t properties){ 1537da2c1baSMilanka Ringwald btstack_assert(mock_gatt_client_last_service != NULL); 1547da2c1baSMilanka Ringwald mock_gatt_client_last_characteristic = (mock_gatt_client_characteristic_t * )malloc(sizeof(mock_gatt_client_characteristic_t)); 1557da2c1baSMilanka Ringwald memset(mock_gatt_client_last_characteristic, 0, sizeof(mock_gatt_client_characteristic_t)); 1567da2c1baSMilanka Ringwald mock_gatt_client_last_characteristic->uuid16 = characteristic_uuid; 15776cdba3eSMilanka Ringwald mock_gatt_client_last_characteristic->properties = properties; 15876cdba3eSMilanka Ringwald mock_gatt_client_last_characteristic->start_handle = mock_gatt_client_att_handle_generator++; 15976cdba3eSMilanka Ringwald mock_gatt_client_last_characteristic->value_handle = mock_gatt_client_att_handle_generator++; 16076cdba3eSMilanka Ringwald mock_gatt_client_last_characteristic->end_handle = mock_gatt_client_last_characteristic->value_handle; 1615b92fca9SMilanka Ringwald btstack_linked_list_add_tail(&mock_gatt_client_last_service->characteristics, (btstack_linked_item_t*)mock_gatt_client_last_characteristic); 16276cdba3eSMilanka Ringwald mock_gatt_client_last_service->end_group_handle = mock_gatt_client_att_handle_generator - 1; 16376cdba3eSMilanka Ringwald return mock_gatt_client_last_characteristic; 1640f7fd6c1SMilanka Ringwald } 165af770404SMilanka Ringwald 16676cdba3eSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_add_characteristic_descriptor_uuid16(uint16_t descriptor_uuid){ 16776cdba3eSMilanka Ringwald btstack_assert(mock_gatt_client_last_characteristic != NULL); 1687da2c1baSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t * )malloc(sizeof(mock_gatt_client_characteristic_descriptor_t)); 1697da2c1baSMilanka Ringwald memset(desc, 0, sizeof(mock_gatt_client_characteristic_descriptor_t)); 1707da2c1baSMilanka Ringwald desc->uuid16 = descriptor_uuid; 17176cdba3eSMilanka Ringwald desc->handle = mock_gatt_client_att_handle_generator++; 1725b92fca9SMilanka Ringwald btstack_linked_list_add_tail(&mock_gatt_client_last_characteristic->descriptors, (btstack_linked_item_t*)desc); 17376cdba3eSMilanka Ringwald mock_gatt_client_last_characteristic->end_handle = mock_gatt_client_att_handle_generator - 1; 17476cdba3eSMilanka Ringwald mock_gatt_client_last_service->end_group_handle = mock_gatt_client_att_handle_generator - 1; 17576cdba3eSMilanka Ringwald return desc; 1760f7fd6c1SMilanka Ringwald } 1770f7fd6c1SMilanka Ringwald 17876cdba3eSMilanka Ringwald static mock_gatt_client_characteristic_t * mock_gatt_client_get_characteristic_for_value_handle(uint16_t value_handle){ 17976cdba3eSMilanka Ringwald btstack_linked_list_iterator_t service_it; 18076cdba3eSMilanka Ringwald btstack_linked_list_iterator_t characteristic_it; 18176cdba3eSMilanka Ringwald 18276cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 18376cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){ 18476cdba3eSMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 18576cdba3eSMilanka Ringwald 18676cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 18776cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 18876cdba3eSMilanka Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 18976cdba3eSMilanka Ringwald if (characteristic->value_handle != value_handle) continue; 19076cdba3eSMilanka Ringwald return characteristic; 19176cdba3eSMilanka Ringwald } 19276cdba3eSMilanka Ringwald } 19376cdba3eSMilanka Ringwald return NULL; 19476cdba3eSMilanka Ringwald } 19576cdba3eSMilanka Ringwald 19676cdba3eSMilanka Ringwald static mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_get_characteristic_descriptor_for_handle(uint16_t handle){ 19776cdba3eSMilanka Ringwald btstack_linked_list_iterator_t service_it; 19876cdba3eSMilanka Ringwald btstack_linked_list_iterator_t characteristic_it; 19976cdba3eSMilanka Ringwald 20076cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 20176cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){ 20276cdba3eSMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 20376cdba3eSMilanka Ringwald 20476cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 20576cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 20676cdba3eSMilanka Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 20776cdba3eSMilanka Ringwald 20876cdba3eSMilanka Ringwald btstack_linked_list_iterator_t desc_it; 20976cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors); 21076cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&desc_it)){ 21176cdba3eSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it); 21276cdba3eSMilanka Ringwald if (desc->handle != handle) continue; 21376cdba3eSMilanka Ringwald return desc; 21476cdba3eSMilanka Ringwald } 21576cdba3eSMilanka Ringwald } 21676cdba3eSMilanka Ringwald } 21776cdba3eSMilanka Ringwald return NULL; 21876cdba3eSMilanka Ringwald } 21976cdba3eSMilanka Ringwald 22076cdba3eSMilanka Ringwald 2217e693ad3SMilanka Ringwald void mock_gatt_client_set_descriptor_characteristic_value(mock_gatt_client_characteristic_descriptor_t * descriptor, uint8_t * value_buffer, uint16_t value_len){ 22276cdba3eSMilanka Ringwald btstack_assert(descriptor != NULL); 22376cdba3eSMilanka Ringwald descriptor->value_buffer = value_buffer; 22476cdba3eSMilanka Ringwald descriptor->value_len = value_len; 22576cdba3eSMilanka Ringwald } 2267da2c1baSMilanka Ringwald 2277e693ad3SMilanka Ringwald void mock_gatt_client_set_characteristic_value(mock_gatt_client_characteristic_t * characteristic, uint8_t * value_buffer, uint16_t value_len){ 2287e693ad3SMilanka Ringwald btstack_assert(characteristic != NULL); 2297e693ad3SMilanka Ringwald characteristic->value_buffer = value_buffer; 2307e693ad3SMilanka Ringwald characteristic->value_len = value_len; 2317e693ad3SMilanka Ringwald } 2327e693ad3SMilanka Ringwald 2337e693ad3SMilanka Ringwald // simulate error 234af770404SMilanka Ringwald void mock_gatt_client_simulate_att_error(uint8_t att_error){ 235af770404SMilanka Ringwald mock_gatt_client_att_error = att_error; 2360f7fd6c1SMilanka Ringwald } 2370f7fd6c1SMilanka Ringwald 2380f7fd6c1SMilanka Ringwald uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){ 239d41a8f51SMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID16; 240af770404SMilanka Ringwald mock_gatt_client_uuid = uuid16; 241af770404SMilanka Ringwald 242af770404SMilanka Ringwald gatt_client.callback = callback; 243af770404SMilanka Ringwald gatt_client.con_handle = con_handle; 2440f7fd6c1SMilanka Ringwald return ERROR_CODE_SUCCESS; 2450f7fd6c1SMilanka Ringwald } 2460f7fd6c1SMilanka Ringwald 2470f7fd6c1SMilanka Ringwald 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){ 248d41a8f51SMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID16; 2497da2c1baSMilanka Ringwald mock_gatt_client_uuid = uuid16; 25076cdba3eSMilanka Ringwald mock_gatt_client_start_handle = start_handle; 25176cdba3eSMilanka Ringwald mock_gatt_client_end_handle = end_handle; 2527da2c1baSMilanka Ringwald 2537da2c1baSMilanka Ringwald gatt_client.callback = callback; 2547da2c1baSMilanka Ringwald gatt_client.con_handle = con_handle; 2550f7fd6c1SMilanka Ringwald return ERROR_CODE_SUCCESS; 2560f7fd6c1SMilanka Ringwald } 2570f7fd6c1SMilanka Ringwald 2580f7fd6c1SMilanka Ringwald uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){ 25976cdba3eSMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS; 26076cdba3eSMilanka Ringwald mock_gatt_client_value_handle = characteristic->value_handle; 26176cdba3eSMilanka Ringwald 26276cdba3eSMilanka Ringwald gatt_client.callback = callback; 26376cdba3eSMilanka Ringwald gatt_client.con_handle = con_handle; 26476cdba3eSMilanka Ringwald return ERROR_CODE_SUCCESS; 26576cdba3eSMilanka Ringwald } 26676cdba3eSMilanka Ringwald 2677e693ad3SMilanka Ringwald 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){ 2687e693ad3SMilanka Ringwald btstack_assert(notification != NULL); 2697e693ad3SMilanka Ringwald btstack_assert(&callback != NULL); 2707e693ad3SMilanka Ringwald 2717e693ad3SMilanka Ringwald notification->callback = callback; 2727e693ad3SMilanka Ringwald notification->con_handle = con_handle; 2737e693ad3SMilanka Ringwald 2747e693ad3SMilanka Ringwald 2757e693ad3SMilanka Ringwald if (characteristic == NULL){ 2767e693ad3SMilanka Ringwald // 'all characteristics': not used yet 2777e693ad3SMilanka Ringwald btstack_assert(false); 2787e693ad3SMilanka Ringwald } else { 2797e693ad3SMilanka Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle); 2807e693ad3SMilanka Ringwald btstack_assert(mock_characteristic != NULL); 2817e693ad3SMilanka Ringwald 2827e693ad3SMilanka Ringwald notification->attribute_handle = characteristic->value_handle; 2837e693ad3SMilanka Ringwald mock_characteristic->notification = notification; 2847e693ad3SMilanka Ringwald } 2857e693ad3SMilanka Ringwald } 2867e693ad3SMilanka Ringwald 28776cdba3eSMilanka Ringwald 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){ 2887e693ad3SMilanka Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle); 2897e693ad3SMilanka Ringwald btstack_assert(mock_characteristic != NULL); 2907e693ad3SMilanka Ringwald 2917e693ad3SMilanka Ringwald if (mock_characteristic->notification_status_code != ERROR_CODE_SUCCESS){ 2927e693ad3SMilanka Ringwald return mock_characteristic->notification_status_code; 2937e693ad3SMilanka Ringwald } 2947e693ad3SMilanka Ringwald 29576cdba3eSMilanka Ringwald mock_gatt_client_state = MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 29676cdba3eSMilanka Ringwald mock_gatt_client_uuid = characteristic->uuid16; 29776cdba3eSMilanka Ringwald 29876cdba3eSMilanka Ringwald gatt_client.callback = callback; 29976cdba3eSMilanka Ringwald gatt_client.con_handle = con_handle; 30076cdba3eSMilanka Ringwald return ERROR_CODE_SUCCESS; 30176cdba3eSMilanka Ringwald } 30276cdba3eSMilanka Ringwald 30376cdba3eSMilanka Ringwald 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){ 30476cdba3eSMilanka Ringwald mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE; 3057e693ad3SMilanka Ringwald 3067e693ad3SMilanka Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(value_handle); 3077e693ad3SMilanka Ringwald btstack_assert(mock_characteristic != NULL); 3087e693ad3SMilanka Ringwald 3097e693ad3SMilanka Ringwald mock_gatt_client_value_handle = mock_characteristic->value_handle; 3107e693ad3SMilanka Ringwald gatt_client.callback = callback; 3117e693ad3SMilanka Ringwald gatt_client.con_handle = con_handle; 312af770404SMilanka Ringwald return ERROR_CODE_SUCCESS; 313af770404SMilanka Ringwald } 314af770404SMilanka Ringwald 315af770404SMilanka Ringwald uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){ 31624152f08SMilanka Ringwald btstack_assert(characteristic != NULL); 31724152f08SMilanka Ringwald mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE; 31824152f08SMilanka Ringwald 3197e693ad3SMilanka Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle); 32024152f08SMilanka Ringwald btstack_assert(mock_characteristic != NULL); 32124152f08SMilanka Ringwald 3227e693ad3SMilanka Ringwald gatt_client.callback = callback; 3237e693ad3SMilanka Ringwald gatt_client.con_handle = con_handle; 32424152f08SMilanka Ringwald mock_gatt_client_value_handle = mock_characteristic->value_handle; 3250f7fd6c1SMilanka Ringwald return ERROR_CODE_SUCCESS; 3260f7fd6c1SMilanka Ringwald } 3270f7fd6c1SMilanka Ringwald 3287e693ad3SMilanka Ringwald 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){ 3297e693ad3SMilanka Ringwald mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE; 3307e693ad3SMilanka Ringwald mock_gatt_client_value_handle = descriptor_handle; 3317e693ad3SMilanka Ringwald return ERROR_CODE_SUCCESS; 3327e693ad3SMilanka Ringwald } 3337e693ad3SMilanka Ringwald 334af770404SMilanka Ringwald void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){ 335af770404SMilanka Ringwald } 336af770404SMilanka Ringwald 337*86d0910fSMilanka Ringwald uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service){ 338*86d0910fSMilanka Ringwald btstack_assert(false); 339*86d0910fSMilanka Ringwald return ERROR_CODE_SUCCESS; 340*86d0910fSMilanka Ringwald } 341*86d0910fSMilanka Ringwald 342*86d0910fSMilanka Ringwald uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){ 343*86d0910fSMilanka Ringwald btstack_assert(false); 344*86d0910fSMilanka Ringwald return ERROR_CODE_SUCCESS; 345*86d0910fSMilanka Ringwald } 346*86d0910fSMilanka Ringwald 347*86d0910fSMilanka Ringwald 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){ 348*86d0910fSMilanka Ringwald btstack_assert(false); 349*86d0910fSMilanka Ringwald return ERROR_CODE_SUCCESS; 350*86d0910fSMilanka Ringwald } 351*86d0910fSMilanka Ringwald 352af770404SMilanka Ringwald /** 353af770404SMilanka Ringwald * copied from gatt_client.c - START 354af770404SMilanka Ringwald */ 3550f7fd6c1SMilanka Ringwald void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){ 3560f7fd6c1SMilanka Ringwald service->start_group_handle = little_endian_read_16(packet, offset); 3570f7fd6c1SMilanka Ringwald service->end_group_handle = little_endian_read_16(packet, offset + 2); 3580f7fd6c1SMilanka Ringwald reverse_128(&packet[offset + 4], service->uuid128); 3590f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(service->uuid128)){ 3600f7fd6c1SMilanka Ringwald service->uuid16 = big_endian_read_32(service->uuid128, 0); 3610f7fd6c1SMilanka Ringwald } else { 3620f7fd6c1SMilanka Ringwald service->uuid16 = 0; 3630f7fd6c1SMilanka Ringwald } 3640f7fd6c1SMilanka Ringwald } 3650f7fd6c1SMilanka Ringwald 3660f7fd6c1SMilanka Ringwald void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){ 3670f7fd6c1SMilanka Ringwald characteristic->start_handle = little_endian_read_16(packet, offset); 3680f7fd6c1SMilanka Ringwald characteristic->value_handle = little_endian_read_16(packet, offset + 2); 3690f7fd6c1SMilanka Ringwald characteristic->end_handle = little_endian_read_16(packet, offset + 4); 3700f7fd6c1SMilanka Ringwald characteristic->properties = little_endian_read_16(packet, offset + 6); 3710f7fd6c1SMilanka Ringwald reverse_128(&packet[offset+8], characteristic->uuid128); 3720f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(characteristic->uuid128)){ 3730f7fd6c1SMilanka Ringwald characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0); 3740f7fd6c1SMilanka Ringwald } else { 3750f7fd6c1SMilanka Ringwald characteristic->uuid16 = 0; 3760f7fd6c1SMilanka Ringwald } 3770f7fd6c1SMilanka Ringwald } 3780f7fd6c1SMilanka Ringwald 3790f7fd6c1SMilanka Ringwald void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){ 3800f7fd6c1SMilanka Ringwald descriptor->handle = little_endian_read_16(packet, offset); 3810f7fd6c1SMilanka Ringwald reverse_128(&packet[offset+2], descriptor->uuid128); 3820f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(descriptor->uuid128)){ 3830f7fd6c1SMilanka Ringwald descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0); 3840f7fd6c1SMilanka Ringwald } else { 3850f7fd6c1SMilanka Ringwald descriptor->uuid16 = 0; 3860f7fd6c1SMilanka Ringwald } 3870f7fd6c1SMilanka Ringwald } 3880f7fd6c1SMilanka Ringwald 3897e693ad3SMilanka Ringwald static void emit_event(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){ 390af770404SMilanka Ringwald if (!callback) return; 3917e693ad3SMilanka Ringwald if (mock_gatt_client_wrong_con_handle){ 3927e693ad3SMilanka Ringwald little_endian_store_16(packet, 2, 0xFFFF); 3937e693ad3SMilanka Ringwald } 394af770404SMilanka Ringwald (*callback)(HCI_EVENT_PACKET, 0, packet, size); 3950f7fd6c1SMilanka Ringwald } 3960f7fd6c1SMilanka Ringwald 397af770404SMilanka Ringwald static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){ 398af770404SMilanka Ringwald // @format H1 399af770404SMilanka Ringwald uint8_t packet[5]; 400af770404SMilanka Ringwald packet[0] = GATT_EVENT_QUERY_COMPLETE; 401af770404SMilanka Ringwald packet[1] = 3; 402af770404SMilanka Ringwald little_endian_store_16(packet, 2, gatt_client->con_handle); 403af770404SMilanka Ringwald packet[4] = att_status; 4047e693ad3SMilanka Ringwald emit_event(gatt_client->callback, packet, sizeof(packet)); 4050f7fd6c1SMilanka Ringwald } 4060f7fd6c1SMilanka Ringwald 4077da2c1baSMilanka Ringwald 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){ 4087da2c1baSMilanka Ringwald // @format HX 4097da2c1baSMilanka Ringwald uint8_t packet[24]; 4107da2c1baSMilanka Ringwald packet[0] = GATT_EVENT_SERVICE_QUERY_RESULT; 4117da2c1baSMilanka Ringwald packet[1] = sizeof(packet) - 2u; 4127da2c1baSMilanka Ringwald little_endian_store_16(packet, 2, gatt_client->con_handle); 4137da2c1baSMilanka Ringwald /// 4147da2c1baSMilanka Ringwald little_endian_store_16(packet, 4, start_group_handle); 4157da2c1baSMilanka Ringwald little_endian_store_16(packet, 6, end_group_handle); 4167da2c1baSMilanka Ringwald reverse_128(uuid128, &packet[8]); 4177e693ad3SMilanka Ringwald emit_event(gatt_client->callback, packet, sizeof(packet)); 4187da2c1baSMilanka Ringwald } 4197da2c1baSMilanka Ringwald 4207da2c1baSMilanka Ringwald 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, 4217da2c1baSMilanka Ringwald uint16_t properties, const uint8_t * uuid128){ 4227da2c1baSMilanka Ringwald // @format HY 4237da2c1baSMilanka Ringwald uint8_t packet[28]; 4247da2c1baSMilanka Ringwald packet[0] = GATT_EVENT_CHARACTERISTIC_QUERY_RESULT; 4257da2c1baSMilanka Ringwald packet[1] = sizeof(packet) - 2u; 4267da2c1baSMilanka Ringwald little_endian_store_16(packet, 2, gatt_client->con_handle); 4277da2c1baSMilanka Ringwald /// 4287da2c1baSMilanka Ringwald little_endian_store_16(packet, 4, start_handle); 4297da2c1baSMilanka Ringwald little_endian_store_16(packet, 6, value_handle); 4307da2c1baSMilanka Ringwald little_endian_store_16(packet, 8, end_handle); 4317da2c1baSMilanka Ringwald little_endian_store_16(packet, 10, properties); 4327da2c1baSMilanka Ringwald reverse_128(uuid128, &packet[12]); 4337e693ad3SMilanka Ringwald emit_event(gatt_client->callback, packet, sizeof(packet)); 4347da2c1baSMilanka Ringwald } 4357da2c1baSMilanka Ringwald 43676cdba3eSMilanka Ringwald static void emit_gatt_all_characteristic_descriptors_result_event( 43776cdba3eSMilanka Ringwald gatt_client_t * gatt_client, uint16_t descriptor_handle, const uint8_t * uuid128){ 43876cdba3eSMilanka Ringwald // @format HZ 43976cdba3eSMilanka Ringwald uint8_t packet[22]; 44076cdba3eSMilanka Ringwald packet[0] = GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT; 44176cdba3eSMilanka Ringwald packet[1] = sizeof(packet) - 2u; 44276cdba3eSMilanka Ringwald little_endian_store_16(packet, 2, gatt_client->con_handle); 44376cdba3eSMilanka Ringwald /// 44476cdba3eSMilanka Ringwald little_endian_store_16(packet, 4, descriptor_handle); 44576cdba3eSMilanka Ringwald reverse_128(uuid128, &packet[6]); 4467e693ad3SMilanka Ringwald emit_event(gatt_client->callback, packet, sizeof(packet)); 44776cdba3eSMilanka Ringwald } 44876cdba3eSMilanka Ringwald 4497e693ad3SMilanka Ringwald static uint8_t event_packet[255]; 45076cdba3eSMilanka Ringwald 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){ 45176cdba3eSMilanka Ringwald // before the value inside the ATT PDU 4527e693ad3SMilanka Ringwald event_packet[0] = type; 4537e693ad3SMilanka Ringwald event_packet[1] = 6 + length; 4547e693ad3SMilanka Ringwald little_endian_store_16(event_packet, 2, con_handle); 4557e693ad3SMilanka Ringwald little_endian_store_16(event_packet, 4, attribute_handle); 4567e693ad3SMilanka Ringwald little_endian_store_16(event_packet, 6, length); 4577e693ad3SMilanka Ringwald memcpy(&event_packet[8], value, length); 4587e693ad3SMilanka Ringwald return &event_packet[0]; 45976cdba3eSMilanka Ringwald } 46076cdba3eSMilanka Ringwald 4617e693ad3SMilanka Ringwald void mock_gatt_client_send_notification_with_handle(mock_gatt_client_characteristic_t * characteristic, uint16_t value_handle, uint8_t * value_buffer, uint16_t value_len){ 4627e693ad3SMilanka Ringwald btstack_assert(characteristic != NULL); 4637e693ad3SMilanka Ringwald btstack_assert(characteristic->notification != NULL); 4647e693ad3SMilanka Ringwald btstack_assert(characteristic->notification->callback != NULL); 4657e693ad3SMilanka Ringwald uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_NOTIFICATION, gatt_client.con_handle, value_handle, value_buffer, value_len); 4667e693ad3SMilanka Ringwald emit_event(characteristic->notification->callback, packet, 2 + packet[1]); 4677e693ad3SMilanka Ringwald } 4687e693ad3SMilanka Ringwald 4697e693ad3SMilanka Ringwald void mock_gatt_client_send_notification(mock_gatt_client_characteristic_t * characteristic, uint8_t * value_buffer, uint16_t value_len){ 4707e693ad3SMilanka Ringwald mock_gatt_client_send_notification_with_handle(characteristic, characteristic->value_handle, value_buffer, value_len); 4717e693ad3SMilanka Ringwald } 4727e693ad3SMilanka Ringwald 4737e693ad3SMilanka Ringwald static void mock_gatt_client_send_characteristic_value(gatt_client_t * gatt_client, mock_gatt_client_characteristic_t * characteristic){ 4747e693ad3SMilanka Ringwald 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); 4757e693ad3SMilanka Ringwald emit_event(gatt_client->callback, packet, 2 + packet[1]); 47676cdba3eSMilanka Ringwald } 47776cdba3eSMilanka Ringwald 478af770404SMilanka Ringwald /** 479af770404SMilanka Ringwald * copied from gatt_client.c - END 480af770404SMilanka Ringwald */ 4810f7fd6c1SMilanka Ringwald 4827e693ad3SMilanka Ringwald void mock_gatt_client_emit_complete(uint8_t status){ 4837da2c1baSMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_IDLE; 4847da2c1baSMilanka Ringwald emit_gatt_complete_event(&gatt_client, status); 4857da2c1baSMilanka Ringwald } 4860f7fd6c1SMilanka Ringwald 4877e693ad3SMilanka Ringwald void mock_gatt_client_run_once(void){ 488af770404SMilanka Ringwald btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE); 48976cdba3eSMilanka Ringwald mock_gatt_client_characteristic_t * characteristic; 49076cdba3eSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * descriptor; 49176cdba3eSMilanka Ringwald 4927da2c1baSMilanka Ringwald btstack_linked_list_iterator_t service_it; 4937da2c1baSMilanka Ringwald btstack_linked_list_iterator_t characteristic_it; 49476cdba3eSMilanka Ringwald btstack_linked_list_iterator_t descriptor_it; 49576cdba3eSMilanka Ringwald 4967da2c1baSMilanka Ringwald uint8_t uuid128[16]; 4977da2c1baSMilanka Ringwald 498af770404SMilanka Ringwald switch (mock_gatt_client_state){ 499d41a8f51SMilanka Ringwald case MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID16: 500af770404SMilanka Ringwald // emit GATT_EVENT_SERVICE_QUERY_RESULT for each matching service 501ec1a0daeSMilanka Ringwald if (moc_att_error_code_discover_services != ATT_ERROR_SUCCESS){ 502ec1a0daeSMilanka Ringwald mock_gatt_client_emit_complete(moc_att_error_code_discover_services); 503ec1a0daeSMilanka Ringwald return; 504ec1a0daeSMilanka Ringwald } 505ec1a0daeSMilanka Ringwald 5067da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 5077da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){ 5087da2c1baSMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 5097da2c1baSMilanka Ringwald if (service->uuid16 != mock_gatt_client_uuid) continue; 5107da2c1baSMilanka Ringwald mock_gatt_client_last_service = service; 5117da2c1baSMilanka Ringwald uuid_add_bluetooth_prefix(uuid128, service->uuid16); 51276cdba3eSMilanka Ringwald emit_gatt_service_query_result_event(&gatt_client, service->start_group_handle, service->end_group_handle, uuid128); 5137da2c1baSMilanka Ringwald } 5147da2c1baSMilanka Ringwald // emit GATT_EVENT_QUERY_COMPLETE 5157da2c1baSMilanka Ringwald mock_gatt_client_emit_complete(ATT_ERROR_SUCCESS); 5167da2c1baSMilanka Ringwald break; 5177da2c1baSMilanka Ringwald 518d41a8f51SMilanka Ringwald case MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID16: 5197da2c1baSMilanka Ringwald // emit GATT_EVENT_CHARACTERISTIC_QUERY_RESULT for each matching characteristic 520ec1a0daeSMilanka Ringwald if (moc_att_error_code_discover_characteristics != ATT_ERROR_SUCCESS){ 521ec1a0daeSMilanka Ringwald mock_gatt_client_emit_complete(moc_att_error_code_discover_characteristics); 522ec1a0daeSMilanka Ringwald return; 523ec1a0daeSMilanka Ringwald } 524ec1a0daeSMilanka Ringwald 5257da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services); 5267da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){ 5277da2c1baSMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it); 5287da2c1baSMilanka Ringwald 5297da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics); 5307da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){ 5317da2c1baSMilanka Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it); 5327da2c1baSMilanka Ringwald if (characteristic->uuid16 != mock_gatt_client_uuid) continue; 53376cdba3eSMilanka Ringwald if (characteristic->start_handle < mock_gatt_client_start_handle) continue; 53476cdba3eSMilanka Ringwald if (characteristic->end_handle > mock_gatt_client_end_handle) continue; 53576cdba3eSMilanka Ringwald 5367da2c1baSMilanka Ringwald uuid_add_bluetooth_prefix(uuid128, characteristic->uuid16); 53776cdba3eSMilanka Ringwald emit_gatt_characteristic_query_result_event(&gatt_client, 53876cdba3eSMilanka Ringwald characteristic->start_handle, characteristic->value_handle, characteristic->end_handle, 53976cdba3eSMilanka Ringwald characteristic->properties, uuid128); 5407da2c1baSMilanka Ringwald } 5417da2c1baSMilanka Ringwald } 5427da2c1baSMilanka Ringwald 5437da2c1baSMilanka Ringwald // emit GATT_EVENT_QUERY_COMPLETE 5447da2c1baSMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 545af770404SMilanka Ringwald break; 54676cdba3eSMilanka Ringwald 54776cdba3eSMilanka Ringwald case MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS: 54876cdba3eSMilanka Ringwald characteristic = mock_gatt_client_get_characteristic_for_value_handle(mock_gatt_client_value_handle); 54976cdba3eSMilanka Ringwald btstack_assert(characteristic != NULL); 55076cdba3eSMilanka Ringwald 551ec1a0daeSMilanka Ringwald if (moc_att_error_code_discover_characteristic_descriptors != ATT_ERROR_SUCCESS){ 552ec1a0daeSMilanka Ringwald mock_gatt_client_emit_complete(moc_att_error_code_discover_characteristic_descriptors); 553ec1a0daeSMilanka Ringwald return; 554ec1a0daeSMilanka Ringwald } 555ec1a0daeSMilanka Ringwald 55676cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&descriptor_it, &characteristic->descriptors); 55776cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&descriptor_it)){ 55876cdba3eSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&descriptor_it); 55976cdba3eSMilanka Ringwald 56076cdba3eSMilanka Ringwald uuid_add_bluetooth_prefix(uuid128, desc->uuid16); 56176cdba3eSMilanka Ringwald emit_gatt_all_characteristic_descriptors_result_event(&gatt_client, desc->handle, uuid128); 56276cdba3eSMilanka Ringwald } 56376cdba3eSMilanka Ringwald 56476cdba3eSMilanka Ringwald // emit GATT_EVENT_QUERY_COMPLETE 56576cdba3eSMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 56676cdba3eSMilanka Ringwald break; 56776cdba3eSMilanka Ringwald 56876cdba3eSMilanka Ringwald case MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: 56976cdba3eSMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 57076cdba3eSMilanka Ringwald break; 57176cdba3eSMilanka Ringwald 57276cdba3eSMilanka Ringwald case MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE: 5737e693ad3SMilanka Ringwald characteristic = mock_gatt_client_get_characteristic_for_value_handle(mock_gatt_client_value_handle); 5747e693ad3SMilanka Ringwald btstack_assert(characteristic != NULL); 5757e693ad3SMilanka Ringwald 5767e693ad3SMilanka Ringwald mock_gatt_client_send_characteristic_value(&gatt_client, characteristic); 5777e693ad3SMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 5787e693ad3SMilanka Ringwald break; 5797e693ad3SMilanka Ringwald 5807e693ad3SMilanka Ringwald case MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE: 58176cdba3eSMilanka Ringwald descriptor = mock_gatt_client_get_characteristic_descriptor_for_handle(mock_gatt_client_value_handle); 58276cdba3eSMilanka Ringwald btstack_assert(descriptor != NULL); 58376cdba3eSMilanka Ringwald btstack_assert(descriptor->value_buffer != NULL); 58476cdba3eSMilanka Ringwald 58576cdba3eSMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 58676cdba3eSMilanka Ringwald break; 58776cdba3eSMilanka Ringwald 588af770404SMilanka Ringwald default: 589af770404SMilanka Ringwald btstack_assert(false); 590af770404SMilanka Ringwald break; 5910f7fd6c1SMilanka Ringwald } 5927da2c1baSMilanka Ringwald } 5937e693ad3SMilanka Ringwald 5947e693ad3SMilanka Ringwald void mock_gatt_client_run(void){ 5957e693ad3SMilanka Ringwald btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE); 5967e693ad3SMilanka Ringwald while (mock_gatt_client_state != MOCK_QUERY_IDLE){ 5977e693ad3SMilanka Ringwald mock_gatt_client_run_once(); 5987e693ad3SMilanka Ringwald } 5997da2c1baSMilanka Ringwald mock_gatt_client_att_error = ERROR_CODE_SUCCESS; 600af770404SMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_IDLE; 6010f7fd6c1SMilanka Ringwald } 6027e693ad3SMilanka Ringwald 6037e693ad3SMilanka Ringwald void mock_gatt_client_emit_dummy_event(void){ 6047e693ad3SMilanka Ringwald // @format H1 6057e693ad3SMilanka Ringwald uint8_t packet[2]; 6067e693ad3SMilanka Ringwald packet[0] = 0; 6077e693ad3SMilanka Ringwald packet[1] = 0; 6087e693ad3SMilanka Ringwald emit_event(gatt_client.callback, packet, sizeof(packet)); 6097e693ad3SMilanka Ringwald } 610