xref: /btstack/test/gatt-service-client/device_information_service_client_test.cpp (revision 6897da5c53aac5b1f90f41b5b15d0bd43d61dfff)
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 
50 void btstack_run_lopo_deinit(void){
51         btstack_timer = NULL;
52 }
53 
54 void btstack_run_loop_add_timer(btstack_timer_source_t * timer){
55     btstack_timer = timer;
56 }
57 
58 int btstack_run_loop_remove_timer(btstack_timer_source_t * timer){
59     btstack_timer = NULL;
60     return 1;
61 }
62 
63 void btstack_run_loop_set_timer(btstack_timer_source_t * timer, uint32_t timeout_in_ms){
64 }
65 
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 
70 void btstack_run_loop_set_timer_context(btstack_timer_source_t * timer, void * context){
71     timer->context = context;
72 }
73 
74 void * btstack_run_loop_get_timer_context(btstack_timer_source_t * timer){
75     return timer->context;
76 }
77 
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 
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 
93 void mock_btstack_memory_battery_service_client_simulate_no_memory(void){
94     mock_btstack_memory_battery_service_client_no_memory = true;
95 }
96 
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 
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 
111 void btstack_memory_battery_service_client_free(battery_service_client_t *battery_service_client){
112     free(battery_service_client);
113 }
114 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
364 int main (int argc, const char * argv[]){
365     return CommandLineTestRunner::RunAllTests(argc, argv);
366 }
367