xref: /btstack/test/mock/mock_gatt_client.c (revision af7704047a77c37e3dd80d6ce23c3e600fb3cf47)
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 }