1
2 // *****************************************************************************
3 //
4 // test Battery Service Client
5 //
6 // *****************************************************************************
7
8
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "CppUTest/TestHarness.h"
15 #include "CppUTest/CommandLineTestRunner.h"
16 #include "CppUTestExt/MockSupport.h"
17
18 #include "bluetooth.h"
19 #include "bluetooth_gatt.h"
20 #include "btstack_debug.h"
21 #include "btstack_event.h"
22 #include "btstack_memory.h"
23 #include "btstack_util.h"
24 #include "hci.h"
25
26 #include "ble/gatt-service/device_information_service_client.h"
27 #include "mock_gatt_client.h"
28
29 static const hci_con_handle_t con_handle = 0x01;
30 static bool connected;
31
32 // temp btstack run loop mock
33
34 static btstack_timer_source_t * btstack_timer = NULL;
35
36 static bool manufacturer_name = false;
37 static bool model_number = false;
38 static bool serial_number = false;
39 static bool hardware_revision = false;
40 static bool firmware_revision = false;
41 static bool software_revision = false;
42 static bool system_id = false;
43 static bool ieee_regulatory_certification = false;
44 static bool pnp_id = false;
45
46 static bool mock_wrong_hci_event_packet_type = false;
47
48 extern "C" void device_information_service_client_set_invalid_state(void);
49
btstack_run_lopo_deinit(void)50 void btstack_run_lopo_deinit(void){
51 btstack_timer = NULL;
52 }
53
btstack_run_loop_add_timer(btstack_timer_source_t * timer)54 void btstack_run_loop_add_timer(btstack_timer_source_t * timer){
55 btstack_timer = timer;
56 }
57
btstack_run_loop_remove_timer(btstack_timer_source_t * timer)58 int btstack_run_loop_remove_timer(btstack_timer_source_t * timer){
59 btstack_timer = NULL;
60 return 1;
61 }
62
btstack_run_loop_set_timer(btstack_timer_source_t * timer,uint32_t timeout_in_ms)63 void btstack_run_loop_set_timer(btstack_timer_source_t * timer, uint32_t timeout_in_ms){
64 }
65
btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer,void (* process)(btstack_timer_source_t * _timer))66 void btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer, void (*process)(btstack_timer_source_t * _timer)){
67 timer->process = process;
68 }
69
btstack_run_loop_set_timer_context(btstack_timer_source_t * timer,void * context)70 void btstack_run_loop_set_timer_context(btstack_timer_source_t * timer, void * context){
71 timer->context = context;
72 }
73
btstack_run_loop_get_timer_context(btstack_timer_source_t * timer)74 void * btstack_run_loop_get_timer_context(btstack_timer_source_t * timer){
75 return timer->context;
76 }
77
mock_btstack_run_loop_trigger_timer(void)78 void mock_btstack_run_loop_trigger_timer(void){
79 btstack_assert(btstack_timer != NULL);
80 (*btstack_timer->process)(btstack_timer);
81 }
82
83 // simulate btstack_memory_battery_service_client_get
84
85 static bool mock_btstack_memory_battery_service_client_no_memory;
86 static battery_service_client_t * mock_btstack_memory_battery_service_client_last_alloc;
87
btstack_memory_init(void)88 void btstack_memory_init(void){
89 mock_btstack_memory_battery_service_client_no_memory = false;
90 mock_btstack_memory_battery_service_client_last_alloc = NULL;
91 }
92
mock_btstack_memory_battery_service_client_simulate_no_memory(void)93 void mock_btstack_memory_battery_service_client_simulate_no_memory(void){
94 mock_btstack_memory_battery_service_client_no_memory = true;
95 }
96
mock_btstack_memory_battery_service_client_get_last_alloc(void)97 battery_service_client_t * mock_btstack_memory_battery_service_client_get_last_alloc(void){
98 btstack_assert(mock_btstack_memory_battery_service_client_last_alloc != NULL);
99 return mock_btstack_memory_battery_service_client_last_alloc;
100 }
101
btstack_memory_battery_service_client_get(void)102 battery_service_client_t * btstack_memory_battery_service_client_get(void){
103 if (mock_btstack_memory_battery_service_client_no_memory){
104 return NULL;
105 }
106 mock_btstack_memory_battery_service_client_last_alloc = (battery_service_client_t *) malloc(sizeof(battery_service_client_t));
107 memset(mock_btstack_memory_battery_service_client_last_alloc, 0, sizeof(battery_service_client_t));
108 return mock_btstack_memory_battery_service_client_last_alloc;
109 }
110
btstack_memory_battery_service_client_free(battery_service_client_t * battery_service_client)111 void btstack_memory_battery_service_client_free(battery_service_client_t *battery_service_client){
112 free(battery_service_client);
113 }
114
gatt_client_event_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)115 static void gatt_client_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
116 UNUSED(packet_type);
117 UNUSED(channel);
118 UNUSED(size);
119
120 uint8_t status;
121 // uint8_t att_status;
122
123 if (hci_event_packet_get_type(packet) != HCI_EVENT_GATTSERVICE_META){
124 return;
125 }
126
127 switch (hci_event_gattservice_meta_get_subevent_code(packet)){
128 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_DONE:
129 status = gattservice_subevent_device_information_done_get_att_status(packet);
130 switch (status){
131 case ATT_ERROR_SUCCESS:
132 connected = true;
133 break;
134 default:
135 connected = false;
136 break;
137 }
138 break;
139 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_MANUFACTURER_NAME:
140 manufacturer_name = true;
141 break;
142 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_MODEL_NUMBER:
143 model_number = true;
144 break;
145 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SERIAL_NUMBER:
146 serial_number = true;
147 break;
148 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_HARDWARE_REVISION:
149 hardware_revision = true;
150 break;
151 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_FIRMWARE_REVISION:
152 firmware_revision = true;
153 break;
154 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SOFTWARE_REVISION:
155 software_revision = true;
156 break;
157 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SYSTEM_ID:
158 system_id = true;
159 break;
160 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_IEEE_REGULATORY_CERTIFICATION:
161 ieee_regulatory_certification = true;
162 break;
163 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_PNP_ID:
164 pnp_id = true;
165 break;
166
167 default:
168 break;
169 }
170 }
171
TEST_GROUP(DEVICE_INFORMATION_SERVICE_CLIENT)172 TEST_GROUP(DEVICE_INFORMATION_SERVICE_CLIENT){
173 mock_gatt_client_service_t * service;
174 mock_gatt_client_characteristic_t * characteristic;
175
176 void setup(void){
177 mock_wrong_hci_event_packet_type = false;
178 manufacturer_name = false;
179 model_number = false;
180 serial_number = false;
181 hardware_revision = false;
182 firmware_revision = false;
183 software_revision = false;
184 system_id = false;
185 ieee_regulatory_certification = false;
186 pnp_id = false;
187
188 device_information_service_client_init();
189 mock_gatt_client_reset();
190 }
191
192 void setup_service(bool add_characteristic){
193 uint8_t buffer[] = {0x01, 0x02};
194 service = mock_gatt_client_add_primary_service_uuid16(ORG_BLUETOOTH_SERVICE_DEVICE_INFORMATION);
195
196 if (!add_characteristic) return;
197 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_MANUFACTURER_NAME_STRING, ATT_PROPERTY_READ);
198 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer));
199 }
200
201 void setup_full_service(void){
202 static uint8_t buffer[] = {0x01, 0x02};
203 static uint8_t system_id_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
204 static uint8_t ieee_buffer[] = {0x01, 0x02, 0x03, 0x04};
205 static uint8_t pnp_id_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
206
207 service = mock_gatt_client_add_primary_service_uuid16(ORG_BLUETOOTH_SERVICE_DEVICE_INFORMATION);
208
209 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_MANUFACTURER_NAME_STRING, ATT_PROPERTY_READ);
210 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer));
211
212 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_MODEL_NUMBER_STRING , ATT_PROPERTY_READ);
213 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer));
214
215 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_SERIAL_NUMBER_STRING , ATT_PROPERTY_READ);
216 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer));
217
218 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_HARDWARE_REVISION_STRING, ATT_PROPERTY_READ);
219 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer));
220
221 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_FIRMWARE_REVISION_STRING, ATT_PROPERTY_READ);
222 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer));
223
224 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_SOFTWARE_REVISION_STRING, ATT_PROPERTY_READ);
225 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer));
226
227 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_SYSTEM_ID, ATT_PROPERTY_READ);
228 mock_gatt_client_set_characteristic_value(characteristic, system_id_buffer, sizeof(system_id_buffer));
229
230 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST, ATT_PROPERTY_READ);
231 mock_gatt_client_set_characteristic_value(characteristic, ieee_buffer, sizeof(ieee_buffer));
232
233 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID, ATT_PROPERTY_READ);
234 mock_gatt_client_set_characteristic_value(characteristic, pnp_id_buffer, sizeof(pnp_id_buffer));
235 }
236
237 void teardown(void){
238 device_information_service_client_deinit();
239 }
240 };
241
242
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,double_query)243 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, double_query){
244 uint8_t status;
245
246 status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
247 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
248
249 status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
250 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
251
252 status = device_information_service_client_query(HCI_CON_HANDLE_INVALID, &gatt_client_event_handler);
253 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
254 }
255
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,query_no_service)256 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_no_service){
257 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
258 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
259
260 mock_gatt_client_run();
261 CHECK_EQUAL(false, connected);
262 }
263
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,query_service_no_caharacteristic)264 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_no_caharacteristic){
265 setup_service(false);
266
267 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
268 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
269
270 mock_gatt_client_run();
271 CHECK_EQUAL(false, connected);
272 }
273
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,query_service_att_error)274 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_att_error){
275 setup_service(false);
276 mock_gatt_client_set_att_error_discover_primary_services();
277
278 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
279 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
280
281 mock_gatt_client_run();
282 CHECK_EQUAL(false, connected);
283 }
284
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,query_service_one_chr)285 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_one_chr){
286 setup_service(true);
287
288 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
289 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
290
291 mock_gatt_client_run();
292 CHECK_EQUAL(true, connected);
293 }
294
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,query_service_one_chr_att_error)295 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_one_chr_att_error){
296 setup_service(true);
297 mock_gatt_client_set_att_error_read_value_characteristics();
298 // mock_gatt_client_dump_services();
299
300 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
301 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
302
303 mock_gatt_client_run();
304 CHECK_EQUAL(true, connected);
305 }
306
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,query_service_full_setup_no_error)307 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_full_setup_no_error){
308 setup_full_service();
309
310 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
311 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
312
313 mock_gatt_client_run();
314 CHECK_EQUAL(true, connected);
315
316 CHECK_EQUAL(true, manufacturer_name);
317 CHECK_EQUAL(true, model_number);
318 CHECK_EQUAL(true, serial_number);
319 CHECK_EQUAL(true, hardware_revision);
320 CHECK_EQUAL(true, firmware_revision);
321 CHECK_EQUAL(true, software_revision);
322
323 CHECK_EQUAL(true, system_id);
324 CHECK_EQUAL(true, ieee_regulatory_certification);
325 CHECK_EQUAL(true, pnp_id);
326 }
327
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,unhandled_gatt_event_when_connected)328 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, unhandled_gatt_event_when_connected){
329 setup_service(true);
330 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
331 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
332 mock_gatt_client_run();
333 CHECK_EQUAL(true, connected);
334
335 mock_gatt_client_emit_dummy_event();
336 CHECK_EQUAL(true, connected);
337 }
338
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,unhandled_gatt_event_when_not_connected)339 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, unhandled_gatt_event_when_not_connected){
340 setup_service(true);
341 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
342 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
343
344 CHECK_EQUAL(false, connected);
345
346 mock_gatt_client_emit_dummy_event();
347 CHECK_EQUAL(false, connected);
348
349 mock_gatt_client_run();
350 CHECK_EQUAL(true, connected);
351 }
352
353
TEST(DEVICE_INFORMATION_SERVICE_CLIENT,client_in_wrong_state)354 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, client_in_wrong_state){
355 setup_service(true);
356 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
357 CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
358
359 device_information_service_client_set_invalid_state();
360 mock_gatt_client_run();
361 CHECK_EQUAL(false, connected);
362 }
363
main(int argc,const char * argv[])364 int main (int argc, const char * argv[]){
365 return CommandLineTestRunner::RunAllTests(argc, argv);
366 }
367