10f7fd6c1SMilanka Ringwald #include <stdint.h> 20f7fd6c1SMilanka Ringwald #include <stdio.h> 30f7fd6c1SMilanka Ringwald #include <string.h> 40f7fd6c1SMilanka Ringwald 5*af770404SMilanka Ringwald #include "btstack_debug.h" 60f7fd6c1SMilanka Ringwald #include "mock_gatt_client.h" 70f7fd6c1SMilanka Ringwald 80f7fd6c1SMilanka Ringwald #include "CppUTest/TestHarness.h" 90f7fd6c1SMilanka Ringwald #include "CppUTestExt/MockSupport.h" 100f7fd6c1SMilanka Ringwald 11*af770404SMilanka Ringwald static enum { 12*af770404SMilanka Ringwald MOCK_QUERY_IDLE = 0, 13*af770404SMilanka Ringwald MOCK_QUERY_DISCOVER_PRIMARY_SERVICES, 14*af770404SMilanka Ringwald } mock_gatt_client_state; 15*af770404SMilanka Ringwald 16*af770404SMilanka Ringwald static uint8_t mock_gatt_client_att_error; 17*af770404SMilanka Ringwald static uint16_t mock_gatt_client_uuid; 18*af770404SMilanka Ringwald static gatt_client_t gatt_client; 190f7fd6c1SMilanka Ringwald 200f7fd6c1SMilanka Ringwald void mock_gatt_client_reset(void){ 21*af770404SMilanka Ringwald mock_gatt_client_att_error = 0; 22*af770404SMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_IDLE; 230f7fd6c1SMilanka Ringwald } 24*af770404SMilanka Ringwald 250f7fd6c1SMilanka Ringwald void mock_gatt_client_add_primary_service(uint16_t service_uuid){ 260f7fd6c1SMilanka Ringwald } 27*af770404SMilanka Ringwald 280f7fd6c1SMilanka Ringwald void mock_gatt_client_add_characteristic(uint16_t characteristic_uuid){ 290f7fd6c1SMilanka Ringwald } 30*af770404SMilanka Ringwald 310f7fd6c1SMilanka Ringwald void mock_gatt_client_add_characteristic_descriptor(uint16_t descriptor_uuid){ 320f7fd6c1SMilanka Ringwald } 330f7fd6c1SMilanka Ringwald 34*af770404SMilanka Ringwald // simulate erro 35*af770404SMilanka Ringwald void mock_gatt_client_simulate_att_error(uint8_t att_error){ 36*af770404SMilanka Ringwald mock_gatt_client_att_error = att_error; 370f7fd6c1SMilanka Ringwald } 380f7fd6c1SMilanka Ringwald 390f7fd6c1SMilanka Ringwald uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){ 40*af770404SMilanka Ringwald printf("gatt_client_discover_primary_services_by_uuid16 callback %p\n", callback); 41*af770404SMilanka Ringwald 42*af770404SMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_PRIMARY_SERVICES; 43*af770404SMilanka Ringwald mock_gatt_client_uuid = uuid16; 44*af770404SMilanka Ringwald 45*af770404SMilanka Ringwald gatt_client.callback = callback; 46*af770404SMilanka Ringwald gatt_client.con_handle = con_handle; 470f7fd6c1SMilanka Ringwald return ERROR_CODE_SUCCESS; 480f7fd6c1SMilanka Ringwald } 490f7fd6c1SMilanka Ringwald 500f7fd6c1SMilanka 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){ 51*af770404SMilanka Ringwald btstack_assert(false); 520f7fd6c1SMilanka Ringwald return ERROR_CODE_SUCCESS; 530f7fd6c1SMilanka Ringwald } 540f7fd6c1SMilanka Ringwald 550f7fd6c1SMilanka Ringwald uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){ 56*af770404SMilanka Ringwald btstack_assert(false); 57*af770404SMilanka Ringwald return ERROR_CODE_SUCCESS; 58*af770404SMilanka Ringwald } 59*af770404SMilanka Ringwald 60*af770404SMilanka 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){ 61*af770404SMilanka Ringwald btstack_assert(false); 620f7fd6c1SMilanka Ringwald return ERROR_CODE_SUCCESS; 630f7fd6c1SMilanka Ringwald } 640f7fd6c1SMilanka Ringwald 650f7fd6c1SMilanka 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){ 66*af770404SMilanka Ringwald btstack_assert(false); 670f7fd6c1SMilanka Ringwald return ERROR_CODE_SUCCESS; 680f7fd6c1SMilanka Ringwald } 690f7fd6c1SMilanka Ringwald 700f7fd6c1SMilanka 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){ 71*af770404SMilanka Ringwald btstack_assert(false); 720f7fd6c1SMilanka Ringwald return ERROR_CODE_SUCCESS; 730f7fd6c1SMilanka Ringwald } 740f7fd6c1SMilanka Ringwald 750f7fd6c1SMilanka 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){ 76*af770404SMilanka Ringwald btstack_assert(false); 770f7fd6c1SMilanka Ringwald } 780f7fd6c1SMilanka Ringwald 79*af770404SMilanka Ringwald void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){ 80*af770404SMilanka Ringwald btstack_assert(false); 81*af770404SMilanka Ringwald } 82*af770404SMilanka Ringwald 83*af770404SMilanka Ringwald /** 84*af770404SMilanka Ringwald * copied from gatt_client.c - START 85*af770404SMilanka Ringwald */ 860f7fd6c1SMilanka Ringwald void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){ 870f7fd6c1SMilanka Ringwald service->start_group_handle = little_endian_read_16(packet, offset); 880f7fd6c1SMilanka Ringwald service->end_group_handle = little_endian_read_16(packet, offset + 2); 890f7fd6c1SMilanka Ringwald reverse_128(&packet[offset + 4], service->uuid128); 900f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(service->uuid128)){ 910f7fd6c1SMilanka Ringwald service->uuid16 = big_endian_read_32(service->uuid128, 0); 920f7fd6c1SMilanka Ringwald } else { 930f7fd6c1SMilanka Ringwald service->uuid16 = 0; 940f7fd6c1SMilanka Ringwald } 950f7fd6c1SMilanka Ringwald } 960f7fd6c1SMilanka Ringwald 970f7fd6c1SMilanka Ringwald void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){ 980f7fd6c1SMilanka Ringwald characteristic->start_handle = little_endian_read_16(packet, offset); 990f7fd6c1SMilanka Ringwald characteristic->value_handle = little_endian_read_16(packet, offset + 2); 1000f7fd6c1SMilanka Ringwald characteristic->end_handle = little_endian_read_16(packet, offset + 4); 1010f7fd6c1SMilanka Ringwald characteristic->properties = little_endian_read_16(packet, offset + 6); 1020f7fd6c1SMilanka Ringwald reverse_128(&packet[offset+8], characteristic->uuid128); 1030f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(characteristic->uuid128)){ 1040f7fd6c1SMilanka Ringwald characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0); 1050f7fd6c1SMilanka Ringwald } else { 1060f7fd6c1SMilanka Ringwald characteristic->uuid16 = 0; 1070f7fd6c1SMilanka Ringwald } 1080f7fd6c1SMilanka Ringwald } 1090f7fd6c1SMilanka Ringwald 1100f7fd6c1SMilanka Ringwald void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){ 1110f7fd6c1SMilanka Ringwald descriptor->handle = little_endian_read_16(packet, offset); 1120f7fd6c1SMilanka Ringwald reverse_128(&packet[offset+2], descriptor->uuid128); 1130f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(descriptor->uuid128)){ 1140f7fd6c1SMilanka Ringwald descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0); 1150f7fd6c1SMilanka Ringwald } else { 1160f7fd6c1SMilanka Ringwald descriptor->uuid16 = 0; 1170f7fd6c1SMilanka Ringwald } 1180f7fd6c1SMilanka Ringwald } 1190f7fd6c1SMilanka Ringwald 120*af770404SMilanka Ringwald static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){ 121*af770404SMilanka Ringwald if (!callback) return; 122*af770404SMilanka Ringwald (*callback)(HCI_EVENT_PACKET, 0, packet, size); 1230f7fd6c1SMilanka Ringwald } 1240f7fd6c1SMilanka Ringwald 125*af770404SMilanka Ringwald static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){ 126*af770404SMilanka Ringwald // @format H1 127*af770404SMilanka Ringwald uint8_t packet[5]; 128*af770404SMilanka Ringwald packet[0] = GATT_EVENT_QUERY_COMPLETE; 129*af770404SMilanka Ringwald packet[1] = 3; 130*af770404SMilanka Ringwald little_endian_store_16(packet, 2, gatt_client->con_handle); 131*af770404SMilanka Ringwald packet[4] = att_status; 132*af770404SMilanka Ringwald emit_event_new(gatt_client->callback, packet, sizeof(packet)); 1330f7fd6c1SMilanka Ringwald } 1340f7fd6c1SMilanka Ringwald 135*af770404SMilanka Ringwald /** 136*af770404SMilanka Ringwald * copied from gatt_client.c - END 137*af770404SMilanka Ringwald */ 1380f7fd6c1SMilanka Ringwald 139*af770404SMilanka Ringwald // magic 1400f7fd6c1SMilanka Ringwald 141*af770404SMilanka Ringwald void mock_gatt_client_run(void){ 142*af770404SMilanka Ringwald btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE); 143*af770404SMilanka Ringwald switch (mock_gatt_client_state){ 144*af770404SMilanka Ringwald case MOCK_QUERY_DISCOVER_PRIMARY_SERVICES: 145*af770404SMilanka Ringwald // emit GATT_EVENT_SERVICE_QUERY_RESULT for each matching service 146*af770404SMilanka Ringwald // TODO: 147*af770404SMilanka Ringwald // emit GATT_EVENT_QUERY_COMPLETE with status mock_gatt_client_att_error 148*af770404SMilanka Ringwald emit_gatt_complete_event(&gatt_client, ERROR_CODE_SUCCESS); 149*af770404SMilanka Ringwald // reset status 150*af770404SMilanka Ringwald mock_gatt_client_att_error = ERROR_CODE_SUCCESS; 151*af770404SMilanka Ringwald break; 152*af770404SMilanka Ringwald default: 153*af770404SMilanka Ringwald btstack_assert(false); 154*af770404SMilanka Ringwald break; 1550f7fd6c1SMilanka Ringwald } 156*af770404SMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_IDLE; 1570f7fd6c1SMilanka Ringwald }