xref: /btstack/test/gatt-service-client/device_information_service_client_test.cpp (revision 4a9eead824c50b40e12b6f72611a74a3f57a47f6)
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 
253 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_no_service){
254     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
255     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
256 
257     mock_gatt_client_run();
258     CHECK_EQUAL(false, connected);
259 }
260 
261 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_no_caharacteristic){
262     setup_service(false);
263 
264     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
265     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
266 
267     mock_gatt_client_run();
268     CHECK_EQUAL(false, connected);
269 }
270 
271 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_att_error){
272     setup_service(false);
273     mock_gatt_client_set_att_error_discover_primary_services();
274 
275     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
276     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
277 
278     mock_gatt_client_run();
279     CHECK_EQUAL(false, connected);
280 }
281 
282 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_one_chr){
283     setup_service(true);
284 
285     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
286     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
287 
288     mock_gatt_client_run();
289     CHECK_EQUAL(true, connected);
290 }
291 
292 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_one_chr_att_error){
293     setup_service(true);
294     mock_gatt_client_set_att_error_read_value_characteristics();
295     // mock_gatt_client_dump_services();
296 
297     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
298     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
299 
300     mock_gatt_client_run();
301     CHECK_EQUAL(true, connected);
302 }
303 
304 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_full_setup_no_error){
305     setup_full_service();
306 
307     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
308     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
309 
310     mock_gatt_client_run();
311     CHECK_EQUAL(true, connected);
312 
313     CHECK_EQUAL(true, manufacturer_name);
314     CHECK_EQUAL(true, model_number);
315     CHECK_EQUAL(true, serial_number);
316     CHECK_EQUAL(true, hardware_revision);
317     CHECK_EQUAL(true, firmware_revision);
318     CHECK_EQUAL(true, software_revision);
319 
320     CHECK_EQUAL(true, system_id);
321     CHECK_EQUAL(true, ieee_regulatory_certification);
322     CHECK_EQUAL(true, pnp_id);
323 }
324 
325 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, unhandled_gatt_event_when_connected){
326     setup_service(true);
327     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
328     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
329     mock_gatt_client_run();
330     CHECK_EQUAL(true, connected);
331 
332     mock_gatt_client_emit_dummy_event();
333     CHECK_EQUAL(true, connected);
334 }
335 
336 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, unhandled_gatt_event_when_not_connected){
337     setup_service(true);
338     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
339     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
340 
341     CHECK_EQUAL(false, connected);
342 
343     mock_gatt_client_emit_dummy_event();
344     CHECK_EQUAL(false, connected);
345 
346     mock_gatt_client_run();
347     CHECK_EQUAL(true, connected);
348 }
349 
350 
351 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, client_in_wrong_state){
352     setup_service(true);
353     uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler);
354     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
355 
356     device_information_service_client_set_invalid_state();
357     mock_gatt_client_run();
358     CHECK_EQUAL(false, connected);
359 }
360 
361 int main (int argc, const char * argv[]){
362     return CommandLineTestRunner::RunAllTests(argc, argv);
363 }
364