xref: /btstack/src/ble/gatt-service/device_information_service_client.c (revision 6897da5c53aac5b1f90f41b5b15d0bd43d61dfff)
1 /*
2  * Copyright (C) 2021 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define BTSTACK_FILE__ "device_information_service_client.c"
39 
40 #include "btstack_config.h"
41 
42 #include <stdint.h>
43 #include <string.h>
44 
45 #ifdef ENABLE_TESTING_SUPPORT
46 #include <stdio.h>
47 #endif
48 
49 #include "ble/gatt-service/device_information_service_client.h"
50 
51 #include "ble/core.h"
52 #include "ble/gatt_client.h"
53 #include "bluetooth_gatt.h"
54 #include "btstack_debug.h"
55 #include "btstack_event.h"
56 #include "gap.h"
57 
58 #define DEVICE_INFORMATION_MAX_STRING_LEN 32
59 
60 
61 typedef enum {
62     DEVICE_INFORMATION_SERVICE_CLIENT_STATE_IDLE,
63     DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE,
64     DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT,
65 #ifdef ENABLE_TESTING_SUPPORT
66     DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS,
67     DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT,
68 #endif
69     DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_READ_VALUE_OF_CHARACTERISTIC,
70     DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_VALUE
71 } device_information_service_client_state_t;
72 
73 typedef struct {
74     hci_con_handle_t con_handle;
75     device_information_service_client_state_t  state;
76     btstack_packet_handler_t client_handler;
77 
78     // service
79     uint16_t start_handle;
80     uint16_t end_handle;
81     uint8_t  num_instances;
82 
83     // index of next characteristic to query
84     uint8_t characteristic_index;
85 } device_information_service_client_t;
86 
87 static device_information_service_client_t device_information_service_client;
88 
89 static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
90 static void device_information_service_emit_string_value(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len);
91 static void device_information_service_emit_system_id(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len);
92 static void device_information_service_emit_certification_data_list(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len);
93 static void device_information_service_emit_pnp_id(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len);
94 
95 // list of uuids and how they are reported as events
96 static const struct device_information_characteristic {
97     uint16_t uuid;
98     uint8_t  subevent;
99     void (*handle_value)(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len);
100 } device_information_characteristics[] = {
101     {ORG_BLUETOOTH_CHARACTERISTIC_MANUFACTURER_NAME_STRING, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_MANUFACTURER_NAME, device_information_service_emit_string_value},
102     {ORG_BLUETOOTH_CHARACTERISTIC_MODEL_NUMBER_STRING, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_MODEL_NUMBER, device_information_service_emit_string_value},
103     {ORG_BLUETOOTH_CHARACTERISTIC_SERIAL_NUMBER_STRING, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SERIAL_NUMBER, device_information_service_emit_string_value},
104     {ORG_BLUETOOTH_CHARACTERISTIC_HARDWARE_REVISION_STRING, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_HARDWARE_REVISION, device_information_service_emit_string_value},
105     {ORG_BLUETOOTH_CHARACTERISTIC_FIRMWARE_REVISION_STRING, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_FIRMWARE_REVISION, device_information_service_emit_string_value},
106     {ORG_BLUETOOTH_CHARACTERISTIC_SOFTWARE_REVISION_STRING, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SOFTWARE_REVISION, device_information_service_emit_string_value},
107 
108     {ORG_BLUETOOTH_CHARACTERISTIC_SYSTEM_ID, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SYSTEM_ID, device_information_service_emit_system_id},
109     {ORG_BLUETOOTH_CHARACTERISTIC_IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_IEEE_REGULATORY_CERTIFICATION, device_information_service_emit_certification_data_list},
110     {ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_PNP_ID, device_information_service_emit_pnp_id}
111 };
112 
113 #ifdef ENABLE_TESTING_SUPPORT
114 static struct device_information_characteristic_handles{
115     uint16_t uuid;
116     uint16_t value_handle;
117 } device_information_characteristic_handles[] = {
118     {ORG_BLUETOOTH_CHARACTERISTIC_MANUFACTURER_NAME_STRING, 0},
119     {ORG_BLUETOOTH_CHARACTERISTIC_MODEL_NUMBER_STRING, 0},
120     {ORG_BLUETOOTH_CHARACTERISTIC_SERIAL_NUMBER_STRING, 0},
121     {ORG_BLUETOOTH_CHARACTERISTIC_HARDWARE_REVISION_STRING, 0},
122     {ORG_BLUETOOTH_CHARACTERISTIC_FIRMWARE_REVISION_STRING, 0},
123     {ORG_BLUETOOTH_CHARACTERISTIC_SOFTWARE_REVISION_STRING, 0},
124     {ORG_BLUETOOTH_CHARACTERISTIC_SYSTEM_ID, 0},
125     {ORG_BLUETOOTH_CHARACTERISTIC_IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST, 0},
126     {ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID, 0}
127 };
128 
129 static void device_information_service_update_handle_for_uuid(uint16_t uuid, uint16_t value_handle){
130     uint8_t i;
131     for (i = 0; i < 9; i++){
132         if (device_information_characteristic_handles[i].uuid == uuid){
133             device_information_characteristic_handles[i].value_handle = value_handle;
134             return;
135         }
136     }
137 }
138 #endif
139 
140 
141 static const uint8_t num_information_fields = sizeof(device_information_characteristics)/sizeof(struct device_information_characteristic);
142 
143 #ifdef ENABLE_TESTING_SUPPORT
144 static char * device_information_characteristic_name(uint16_t uuid){
145     switch (uuid){
146         case ORG_BLUETOOTH_CHARACTERISTIC_MANUFACTURER_NAME_STRING:
147             return "MANUFACTURER_NAME_STRING";
148 
149         case ORG_BLUETOOTH_CHARACTERISTIC_MODEL_NUMBER_STRING:
150             return "MODEL_NUMBER_STRING";
151 
152         case ORG_BLUETOOTH_CHARACTERISTIC_SERIAL_NUMBER_STRING:
153             return "SERIAL_NUMBER_STRING";
154 
155         case ORG_BLUETOOTH_CHARACTERISTIC_HARDWARE_REVISION_STRING:
156             return "HARDWARE_REVISION_STRING";
157 
158         case ORG_BLUETOOTH_CHARACTERISTIC_FIRMWARE_REVISION_STRING:
159             return "FIRMWARE_REVISION_STRING";
160 
161         case ORG_BLUETOOTH_CHARACTERISTIC_SOFTWARE_REVISION_STRING:
162             return "SOFTWARE_REVISION_STRING";
163 
164         case ORG_BLUETOOTH_CHARACTERISTIC_SYSTEM_ID:
165             return "SYSTEM_ID";
166 
167         case ORG_BLUETOOTH_CHARACTERISTIC_IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST:
168             return "IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST";
169 
170         case ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID:
171             return "PNP_ID";
172         default:
173             return "UKNOWN";
174     }
175 }
176 #endif
177 static device_information_service_client_t * device_information_service_client_get_client(void){
178     return &device_information_service_client;
179 }
180 
181 static device_information_service_client_t * device_information_service_get_client_for_con_handle(hci_con_handle_t con_handle){
182     if (device_information_service_client.con_handle == con_handle){
183         return &device_information_service_client;
184     }
185     return NULL;
186 }
187 
188 static void device_information_service_finalize_client(device_information_service_client_t * client){
189     client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_IDLE;
190     client->con_handle = HCI_CON_HANDLE_INVALID;
191     client->client_handler = NULL;
192     client->num_instances = 0;
193     client->start_handle = 0;
194     client->end_handle = 0;
195 }
196 
197 static void device_information_service_emit_query_done_and_finalize_client(device_information_service_client_t * client, uint8_t status){
198     hci_con_handle_t con_handle = client->con_handle;
199     btstack_packet_handler_t callback = client->client_handler;
200 
201     device_information_service_finalize_client(client);
202 
203     uint8_t event[6];
204     int pos = 0;
205     event[pos++] = HCI_EVENT_GATTSERVICE_META;
206     event[pos++] = sizeof(event) - 2;
207     event[pos++] = GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_DONE;
208     little_endian_store_16(event, pos, con_handle);
209     pos += 2;
210     event[pos++] = status;
211     (*callback)(HCI_EVENT_PACKET, 0, event, pos);
212 }
213 
214 static void device_information_service_emit_string_value(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len){
215     uint8_t event[6 + DEVICE_INFORMATION_MAX_STRING_LEN + 1];
216     int pos = 0;
217 
218     event[pos++] = HCI_EVENT_GATTSERVICE_META;
219     pos++;
220     event[pos++] = subevent;
221     little_endian_store_16(event, pos, client->con_handle);
222     pos += 2;
223     event[pos++] = att_status;
224 
225     uint16_t bytes_to_copy = btstack_min(value_len, DEVICE_INFORMATION_MAX_STRING_LEN);
226     memcpy((char*)&event[pos], value, bytes_to_copy);
227     pos += bytes_to_copy;
228     event[pos++] = 0;
229 
230     event[1] = pos - 2;
231     (*client->client_handler)(HCI_EVENT_PACKET, 0, event, pos);
232 }
233 
234 static void device_information_service_emit_system_id(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len){
235     if (value_len != 8) return;
236 
237     uint8_t event[14];
238     uint16_t pos = 0;
239     event[pos++] = HCI_EVENT_GATTSERVICE_META;
240     event[pos++] = sizeof(event) - 2;
241     event[pos++] = subevent;
242     little_endian_store_16(event, pos, client->con_handle);
243     pos += 2;
244     event[pos++] = att_status;
245     memcpy(event+pos, value, 8);
246     pos += 8;
247 
248     (*client->client_handler)(HCI_EVENT_PACKET, 0, event, pos);
249 }
250 
251 static void device_information_service_emit_certification_data_list(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len){
252     if (value_len != 4) return;
253 
254     uint8_t event[10];
255     int pos = 0;
256     event[pos++] = HCI_EVENT_GATTSERVICE_META;
257     event[pos++] = sizeof(event) - 2;
258     event[pos++] = subevent;
259     little_endian_store_16(event, pos, client->con_handle);
260     pos += 2;
261     event[pos++] = att_status;
262     memcpy(event + pos, value, 4);
263     pos += 4;
264 
265     (*client->client_handler)(HCI_EVENT_PACKET, 0, event, pos);
266 }
267 
268 static void device_information_service_emit_pnp_id(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len){
269     if (value_len != 7) return;
270 
271     uint8_t event[13];
272     uint16_t pos = 0;
273     event[pos++] = HCI_EVENT_GATTSERVICE_META;
274     event[pos++] = sizeof(event) - 2;
275     event[pos++] = subevent;
276     little_endian_store_16(event, pos, client->con_handle);
277     pos += 2;
278     event[pos++] = att_status;
279     memcpy(event + pos, value, 7);
280     pos += 7;
281 
282     (*client->client_handler)(HCI_EVENT_PACKET, 0, event, pos);
283 }
284 
285 
286 static void device_information_service_run_for_client(device_information_service_client_t * client){
287     uint8_t att_status;
288 
289     switch (client->state){
290         case DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE:
291             client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT;
292             att_status = gatt_client_discover_primary_services_by_uuid16(handle_gatt_client_event, client->con_handle, ORG_BLUETOOTH_SERVICE_DEVICE_INFORMATION);
293             // TODO handle status
294             UNUSED(att_status);
295             break;
296 #ifdef ENABLE_TESTING_SUPPORT
297         case DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS:
298             client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT;
299             gatt_client_discover_characteristics_for_handle_range_by_uuid16(
300                 &handle_gatt_client_event,
301                 client->con_handle, client->start_handle, client->end_handle,
302                 device_information_characteristics[client->characteristic_index].uuid);
303             break;
304 #endif
305 
306         case DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_READ_VALUE_OF_CHARACTERISTIC:
307             client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_VALUE;
308 
309 #ifdef ENABLE_TESTING_SUPPORT
310             att_status = gatt_client_read_value_of_characteristic_using_value_handle(
311                 handle_gatt_client_event,
312                 client->con_handle,
313                 device_information_characteristic_handles[client->characteristic_index].value_handle);
314 #else
315             att_status = gatt_client_read_value_of_characteristics_by_uuid16(
316                 handle_gatt_client_event,
317                 client->con_handle, client->start_handle, client->end_handle,
318                 device_information_characteristics[client->characteristic_index].uuid);
319 #endif
320             // TODO handle status
321             UNUSED(att_status);
322             break;
323 
324         default:
325             break;
326     }
327 }
328 
329 static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
330     UNUSED(packet_type);
331     UNUSED(channel);
332     UNUSED(size);
333 
334     uint8_t att_status;
335     device_information_service_client_t * client = NULL;
336     gatt_client_service_t service;
337 
338 #ifdef ENABLE_TESTING_SUPPORT
339     gatt_client_characteristic_t characteristic;
340 #endif
341 
342     switch(hci_event_packet_get_type(packet)){
343 
344         case GATT_EVENT_SERVICE_QUERY_RESULT:
345             client = device_information_service_get_client_for_con_handle(gatt_event_service_query_result_get_handle(packet));
346             btstack_assert(client != NULL);
347 
348             gatt_event_service_query_result_get_service(packet, &service);
349             client->start_handle = service.start_group_handle;
350             client->end_handle = service.end_group_handle;
351 
352             client->characteristic_index = 0;
353             if (client->start_handle < client->end_handle){
354                 client->num_instances++;
355             }
356 #ifdef ENABLE_TESTING_SUPPORT
357             printf("Device Information Service: start handle 0x%04X, end handle 0x%04X, num_instances %d\n", client->start_handle, client->end_handle, client->num_instances);
358 #endif
359             break;
360 
361 #ifdef ENABLE_TESTING_SUPPORT
362         case GATT_EVENT_CHARACTERISTIC_QUERY_RESULT:
363             client = device_information_service_get_client_for_con_handle(gatt_event_characteristic_query_result_get_handle(packet));
364             btstack_assert(client != NULL);
365             gatt_event_characteristic_query_result_get_characteristic(packet, &characteristic);
366 
367             device_information_service_update_handle_for_uuid(characteristic.uuid16, characteristic.value_handle);
368             printf("Device Information Characteristic %s:  \n    Attribute Handle 0x%04X, Properties 0x%02X, Handle 0x%04X, UUID 0x%04X\n",
369                 device_information_characteristic_name(characteristic.uuid16),
370                 characteristic.start_handle,
371                 characteristic.properties,
372                 characteristic.value_handle, characteristic.uuid16);
373             break;
374 #endif
375         case GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT:
376             client = device_information_service_get_client_for_con_handle(gatt_event_characteristic_value_query_result_get_handle(packet));
377             btstack_assert(client != NULL);
378 
379 
380             (device_information_characteristics[client->characteristic_index].handle_value(
381                 client, device_information_characteristics[client->characteristic_index].subevent,
382                 ATT_ERROR_SUCCESS,
383                 gatt_event_characteristic_value_query_result_get_value(packet),
384                 gatt_event_characteristic_value_query_result_get_value_length(packet)));
385             break;
386 
387         case GATT_EVENT_QUERY_COMPLETE:
388             client = device_information_service_get_client_for_con_handle(gatt_event_query_complete_get_handle(packet));
389             btstack_assert(client != NULL);
390 
391             att_status = gatt_event_query_complete_get_att_status(packet);
392             switch (client->state){
393                 case DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT:
394                     if (att_status != ATT_ERROR_SUCCESS){
395                         device_information_service_emit_query_done_and_finalize_client(client, att_status);
396                         return;
397                     }
398 
399                     if (client->num_instances != 1){
400                         device_information_service_emit_query_done_and_finalize_client(client, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
401                         return;
402                     }
403                     client->characteristic_index = 0;
404 
405 #ifdef ENABLE_TESTING_SUPPORT
406                     client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS;
407 #else
408                     client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_READ_VALUE_OF_CHARACTERISTIC;
409 #endif
410                     break;
411 
412 #ifdef ENABLE_TESTING_SUPPORT
413                     case DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT:
414                         // check if there is another characteristic to query
415                         if ((client->characteristic_index + 1) < num_information_fields){
416                             client->characteristic_index++;
417                             client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS;
418                             break;
419                         }
420                         client->characteristic_index = 0;
421                         client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_READ_VALUE_OF_CHARACTERISTIC;
422                         break;
423 #endif
424                 case DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_VALUE:
425                     // check if there is another characteristic to query
426                     if ((client->characteristic_index + 1) < num_information_fields){
427                         client->characteristic_index++;
428                         client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_READ_VALUE_OF_CHARACTERISTIC;
429                         break;
430                     }
431                     // we are done with quering all characteristics
432                     device_information_service_emit_query_done_and_finalize_client(client, ERROR_CODE_SUCCESS);
433                     return;
434 
435                 default:
436                     break;
437             }
438             break;
439         default:
440             break;
441     }
442 
443     if (client != NULL){
444         device_information_service_run_for_client(client);
445     }
446 
447 }
448 
449 uint8_t device_information_service_client_query(hci_con_handle_t con_handle, btstack_packet_handler_t packet_handler){
450     btstack_assert(packet_handler != NULL);
451     device_information_service_client_t * client = device_information_service_get_client_for_con_handle(con_handle);
452 
453     if (client != NULL){
454         return ERROR_CODE_COMMAND_DISALLOWED;
455     }
456 
457     client = device_information_service_client_get_client();
458 
459     if (client->con_handle != HCI_CON_HANDLE_INVALID) {
460         return ERROR_CODE_COMMAND_DISALLOWED;
461     }
462 
463     client->con_handle = con_handle;
464     client->client_handler = packet_handler;
465     client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE;
466 
467     device_information_service_run_for_client(client);
468     return ERROR_CODE_SUCCESS;
469 }
470 
471 
472 void device_information_service_client_init(void){
473     device_information_service_client_t * client = device_information_service_client_get_client();
474     device_information_service_finalize_client(client);
475 }
476 
477 void device_information_service_client_deinit(void){}
478 
479 // unit test only
480 #if defined __cplusplus
481 extern "C"
482 #endif
483 void device_information_service_client_set_invalid_state(void);
484 void device_information_service_client_set_invalid_state(void){
485     device_information_service_client_t * client =  device_information_service_client_get_client();
486     client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_IDLE;
487 }
488