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_gatt_client_state; 15 16 static uint8_t mock_gatt_client_att_error; 17 static uint16_t mock_gatt_client_uuid; 18 static gatt_client_t gatt_client; 19 20 void mock_gatt_client_reset(void){ 21 mock_gatt_client_att_error = 0; 22 mock_gatt_client_state = MOCK_QUERY_IDLE; 23 } 24 25 void mock_gatt_client_add_primary_service(uint16_t service_uuid){ 26 } 27 28 void mock_gatt_client_add_characteristic(uint16_t characteristic_uuid){ 29 } 30 31 void mock_gatt_client_add_characteristic_descriptor(uint16_t descriptor_uuid){ 32 } 33 34 // simulate erro 35 void mock_gatt_client_simulate_att_error(uint8_t att_error){ 36 mock_gatt_client_att_error = att_error; 37 } 38 39 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){ 40 printf("gatt_client_discover_primary_services_by_uuid16 callback %p\n", callback); 41 42 mock_gatt_client_state = MOCK_QUERY_DISCOVER_PRIMARY_SERVICES; 43 mock_gatt_client_uuid = uuid16; 44 45 gatt_client.callback = callback; 46 gatt_client.con_handle = con_handle; 47 return ERROR_CODE_SUCCESS; 48 } 49 50 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 btstack_assert(false); 52 return ERROR_CODE_SUCCESS; 53 } 54 55 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){ 56 btstack_assert(false); 57 return ERROR_CODE_SUCCESS; 58 } 59 60 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 btstack_assert(false); 62 return ERROR_CODE_SUCCESS; 63 } 64 65 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 btstack_assert(false); 67 return ERROR_CODE_SUCCESS; 68 } 69 70 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 btstack_assert(false); 72 return ERROR_CODE_SUCCESS; 73 } 74 75 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 btstack_assert(false); 77 } 78 79 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){ 80 btstack_assert(false); 81 } 82 83 /** 84 * copied from gatt_client.c - START 85 */ 86 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){ 87 service->start_group_handle = little_endian_read_16(packet, offset); 88 service->end_group_handle = little_endian_read_16(packet, offset + 2); 89 reverse_128(&packet[offset + 4], service->uuid128); 90 if (uuid_has_bluetooth_prefix(service->uuid128)){ 91 service->uuid16 = big_endian_read_32(service->uuid128, 0); 92 } else { 93 service->uuid16 = 0; 94 } 95 } 96 97 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){ 98 characteristic->start_handle = little_endian_read_16(packet, offset); 99 characteristic->value_handle = little_endian_read_16(packet, offset + 2); 100 characteristic->end_handle = little_endian_read_16(packet, offset + 4); 101 characteristic->properties = little_endian_read_16(packet, offset + 6); 102 reverse_128(&packet[offset+8], characteristic->uuid128); 103 if (uuid_has_bluetooth_prefix(characteristic->uuid128)){ 104 characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0); 105 } else { 106 characteristic->uuid16 = 0; 107 } 108 } 109 110 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){ 111 descriptor->handle = little_endian_read_16(packet, offset); 112 reverse_128(&packet[offset+2], descriptor->uuid128); 113 if (uuid_has_bluetooth_prefix(descriptor->uuid128)){ 114 descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0); 115 } else { 116 descriptor->uuid16 = 0; 117 } 118 } 119 120 static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){ 121 if (!callback) return; 122 (*callback)(HCI_EVENT_PACKET, 0, packet, size); 123 } 124 125 static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){ 126 // @format H1 127 uint8_t packet[5]; 128 packet[0] = GATT_EVENT_QUERY_COMPLETE; 129 packet[1] = 3; 130 little_endian_store_16(packet, 2, gatt_client->con_handle); 131 packet[4] = att_status; 132 emit_event_new(gatt_client->callback, packet, sizeof(packet)); 133 } 134 135 /** 136 * copied from gatt_client.c - END 137 */ 138 139 // magic 140 141 void mock_gatt_client_run(void){ 142 btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE); 143 switch (mock_gatt_client_state){ 144 case MOCK_QUERY_DISCOVER_PRIMARY_SERVICES: 145 // emit GATT_EVENT_SERVICE_QUERY_RESULT for each matching service 146 // TODO: 147 // emit GATT_EVENT_QUERY_COMPLETE with status mock_gatt_client_att_error 148 emit_gatt_complete_event(&gatt_client, ERROR_CODE_SUCCESS); 149 // reset status 150 mock_gatt_client_att_error = ERROR_CODE_SUCCESS; 151 break; 152 default: 153 btstack_assert(false); 154 break; 155 } 156 mock_gatt_client_state = MOCK_QUERY_IDLE; 157 }