xref: /btstack/example/gatt_device_information_query.c (revision 087a95b88599c99c210f7df5b431a291b36c5192)
177aad125SMilanka Ringwald /*
277aad125SMilanka Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
377aad125SMilanka Ringwald  *
477aad125SMilanka Ringwald  * Redistribution and use in source and binary forms, with or without
577aad125SMilanka Ringwald  * modification, are permitted provided that the following conditions
677aad125SMilanka Ringwald  * are met:
777aad125SMilanka Ringwald  *
877aad125SMilanka Ringwald  * 1. Redistributions of source code must retain the above copyright
977aad125SMilanka Ringwald  *    notice, this list of conditions and the following disclaimer.
1077aad125SMilanka Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
1177aad125SMilanka Ringwald  *    notice, this list of conditions and the following disclaimer in the
1277aad125SMilanka Ringwald  *    documentation and/or other materials provided with the distribution.
1377aad125SMilanka Ringwald  * 3. Neither the name of the copyright holders nor the names of
1477aad125SMilanka Ringwald  *    contributors may be used to endorse or promote products derived
1577aad125SMilanka Ringwald  *    from this software without specific prior written permission.
1677aad125SMilanka Ringwald  * 4. Any redistribution, use, or modification is done solely for
1777aad125SMilanka Ringwald  *    personal benefit and not for any commercial purpose or for
1877aad125SMilanka Ringwald  *    monetary gain.
1977aad125SMilanka Ringwald  *
2077aad125SMilanka Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
2177aad125SMilanka Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2277aad125SMilanka Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2377aad125SMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
2477aad125SMilanka Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2577aad125SMilanka Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2677aad125SMilanka Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2777aad125SMilanka Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2877aad125SMilanka Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2977aad125SMilanka Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
3077aad125SMilanka Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3177aad125SMilanka Ringwald  * SUCH DAMAGE.
3277aad125SMilanka Ringwald  *
3377aad125SMilanka Ringwald  * Please inquire about commercial licensing options at
3477aad125SMilanka Ringwald  * [email protected]
3577aad125SMilanka Ringwald  *
3677aad125SMilanka Ringwald  */
3777aad125SMilanka Ringwald 
3877aad125SMilanka Ringwald #define BTSTACK_FILE__ "gatt_device_information_query.c"
3977aad125SMilanka Ringwald 
4077aad125SMilanka Ringwald // *****************************************************************************
4177aad125SMilanka Ringwald /* EXAMPLE_START(gatt_device_information_query): GATT Device Information Client
4277aad125SMilanka Ringwald  *
4377aad125SMilanka Ringwald  */
4477aad125SMilanka Ringwald 
4577aad125SMilanka Ringwald #include <stdint.h>
4677aad125SMilanka Ringwald #include <stdio.h>
4777aad125SMilanka Ringwald #include <stdlib.h>
4877aad125SMilanka Ringwald #include <string.h>
4977aad125SMilanka Ringwald 
5077aad125SMilanka Ringwald #include "btstack.h"
5177aad125SMilanka Ringwald 
5277aad125SMilanka Ringwald // gatt_device_information_query.gatt contains the declaration of the provided GATT Services + Characteristics
5377aad125SMilanka Ringwald // gatt_device_information_query.h    contains the binary representation of gatt_device_information_query.gatt
5477aad125SMilanka Ringwald // it is generated by the build system by calling: $BTSTACK_ROOT/tool/compile_gatt.py gatt_device_information_query.gatt gatt_device_information_query.h
5577aad125SMilanka Ringwald // it needs to be regenerated when the GATT Database declared in gatt_device_information_query.gatt file is modified
5677aad125SMilanka Ringwald #include "gatt_device_information_query.h"
5777aad125SMilanka Ringwald 
5877aad125SMilanka Ringwald typedef struct advertising_report {
5977aad125SMilanka Ringwald     uint8_t   type;
6077aad125SMilanka Ringwald     uint8_t   event_type;
6177aad125SMilanka Ringwald     uint8_t   address_type;
6277aad125SMilanka Ringwald     bd_addr_t address;
6377aad125SMilanka Ringwald     uint8_t   rssi;
6477aad125SMilanka Ringwald     uint8_t   length;
6577aad125SMilanka Ringwald     const uint8_t * data;
6677aad125SMilanka Ringwald } advertising_report_t;
6777aad125SMilanka Ringwald 
6877aad125SMilanka Ringwald static enum {
6977aad125SMilanka Ringwald     APP_STATE_IDLE,
7077aad125SMilanka Ringwald     APP_STATE_W4_SCAN_RESULT,
7177aad125SMilanka Ringwald     APP_STATE_W4_CONNECT,
7277aad125SMilanka Ringwald     APP_STATE_CONNECTED
7377aad125SMilanka Ringwald } app_state;
7477aad125SMilanka Ringwald 
7577aad125SMilanka Ringwald static int blacklist_index = 0;
7677aad125SMilanka Ringwald static bd_addr_t blacklist[20];
7777aad125SMilanka Ringwald static advertising_report_t report;
7877aad125SMilanka Ringwald 
7977aad125SMilanka Ringwald static hci_con_handle_t connection_handle;
8077aad125SMilanka Ringwald 
8177aad125SMilanka Ringwald static bd_addr_t cmdline_addr;
8277aad125SMilanka Ringwald static int cmdline_addr_found = 0;
8377aad125SMilanka Ringwald 
8477aad125SMilanka Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration;
8577aad125SMilanka Ringwald 
8677aad125SMilanka Ringwald static int blacklist_size(void){
8777aad125SMilanka Ringwald     return sizeof(blacklist) / sizeof(bd_addr_t);
8877aad125SMilanka Ringwald }
8977aad125SMilanka Ringwald 
9077aad125SMilanka Ringwald static int blacklist_contains(bd_addr_t addr){
9177aad125SMilanka Ringwald     int i;
9277aad125SMilanka Ringwald     for (i=0; i<blacklist_size(); i++){
9377aad125SMilanka Ringwald         if (bd_addr_cmp(addr, blacklist[i]) == 0) return 1;
9477aad125SMilanka Ringwald     }
9577aad125SMilanka Ringwald     return 0;
9677aad125SMilanka Ringwald }
9777aad125SMilanka Ringwald 
9877aad125SMilanka Ringwald static void add_to_blacklist(bd_addr_t addr){
9977aad125SMilanka Ringwald     printf("%s added to blacklist (no device information service found).\n", bd_addr_to_str(addr));
10077aad125SMilanka Ringwald     bd_addr_copy(blacklist[blacklist_index], addr);
10177aad125SMilanka Ringwald     blacklist_index = (blacklist_index + 1) % blacklist_size();
10277aad125SMilanka Ringwald }
10377aad125SMilanka Ringwald 
10477aad125SMilanka Ringwald static void dump_advertising_report(uint8_t *packet){
10577aad125SMilanka Ringwald     bd_addr_t address;
10677aad125SMilanka Ringwald     gap_event_advertising_report_get_address(packet, address);
10777aad125SMilanka Ringwald 
10877aad125SMilanka Ringwald     printf("    * adv. event: evt-type %u, addr-type %u, addr %s, rssi %u, length adv %u, data: ",
10977aad125SMilanka Ringwald         gap_event_advertising_report_get_advertising_event_type(packet),
11077aad125SMilanka Ringwald         gap_event_advertising_report_get_address_type(packet),
11177aad125SMilanka Ringwald         bd_addr_to_str(address),
11277aad125SMilanka Ringwald         gap_event_advertising_report_get_rssi(packet),
11377aad125SMilanka Ringwald         gap_event_advertising_report_get_data_length(packet));
11477aad125SMilanka Ringwald     printf_hexdump(gap_event_advertising_report_get_data(packet), gap_event_advertising_report_get_data_length(packet));
11577aad125SMilanka Ringwald 
11677aad125SMilanka Ringwald }
11777aad125SMilanka Ringwald 
11877aad125SMilanka Ringwald static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
11977aad125SMilanka Ringwald     UNUSED(packet_type);
12077aad125SMilanka Ringwald     UNUSED(channel);
12177aad125SMilanka Ringwald     UNUSED(size);
12277aad125SMilanka Ringwald 
123*087a95b8SMilanka Ringwald     uint8_t att_status = 0;
12477aad125SMilanka Ringwald 
12577aad125SMilanka Ringwald     if (hci_event_packet_get_type(packet) != HCI_EVENT_GATTSERVICE_META){
12677aad125SMilanka Ringwald         return;
12777aad125SMilanka Ringwald     }
12877aad125SMilanka Ringwald 
12977aad125SMilanka Ringwald     switch (hci_event_gattservice_meta_get_subevent_code(packet)){
130*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_MANUFACTURER_NAME:
131*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_manufacturer_name_get_att_status(packet);
132*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
133*087a95b8SMilanka Ringwald                 printf("Manufacturer Name read failed, ATT Error 0x%02x\n", att_status);
134*087a95b8SMilanka Ringwald             } else {
135*087a95b8SMilanka Ringwald                 printf("Manufacturer Name: %s\n", gattservice_subevent_device_information_manufacturer_name_get_value(packet));
136*087a95b8SMilanka Ringwald             }
137*087a95b8SMilanka Ringwald             break;
138*087a95b8SMilanka Ringwald 
139*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_MODEL_NUMBER:
140*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_model_number_get_att_status(packet);
141*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
142*087a95b8SMilanka Ringwald                 printf("Model Number read failed, ATT Error 0x%02x\n", att_status);
143*087a95b8SMilanka Ringwald             } else {
144*087a95b8SMilanka Ringwald                 printf("Model Number:     %s\n", gattservice_subevent_device_information_model_number_get_value(packet));
145*087a95b8SMilanka Ringwald             }
146*087a95b8SMilanka Ringwald             break;
147*087a95b8SMilanka Ringwald 
148*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SERIAL_NUMBER:
149*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_serial_number_get_att_status(packet);
150*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
151*087a95b8SMilanka Ringwald                 printf("Serial Number read failed, ATT Error 0x%02x\n", att_status);
152*087a95b8SMilanka Ringwald             } else {
153*087a95b8SMilanka Ringwald                 printf("Serial Number:    %s\n", gattservice_subevent_device_information_serial_number_get_value(packet));
154*087a95b8SMilanka Ringwald             }
155*087a95b8SMilanka Ringwald             break;
156*087a95b8SMilanka Ringwald 
157*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_HARDWARE_REVISION:
158*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_hardware_revision_get_att_status(packet);
159*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
160*087a95b8SMilanka Ringwald                 printf("Hardware Revision read failed, ATT Error 0x%02x\n", att_status);
161*087a95b8SMilanka Ringwald             } else {
162*087a95b8SMilanka Ringwald                 printf("Hardware Revision: %s\n", gattservice_subevent_device_information_hardware_revision_get_value(packet));
163*087a95b8SMilanka Ringwald             }
164*087a95b8SMilanka Ringwald             break;
165*087a95b8SMilanka Ringwald 
166*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_FIRMWARE_REVISION:
167*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_firmware_revision_get_att_status(packet);
168*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
169*087a95b8SMilanka Ringwald                 printf("Firmware Revision read failed, ATT Error 0x%02x\n", att_status);
170*087a95b8SMilanka Ringwald             } else {
171*087a95b8SMilanka Ringwald                 printf("Firmware Revision: %s\n", gattservice_subevent_device_information_firmware_revision_get_value(packet));
172*087a95b8SMilanka Ringwald             }
173*087a95b8SMilanka Ringwald             break;
174*087a95b8SMilanka Ringwald 
175*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SOFTWARE_REVISION:
176*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_software_revision_get_att_status(packet);
177*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
178*087a95b8SMilanka Ringwald                 printf("Software Revision read failed, ATT Error 0x%02x\n", att_status);
179*087a95b8SMilanka Ringwald             } else {
180*087a95b8SMilanka Ringwald                 printf("Software Revision: %s\n", gattservice_subevent_device_information_software_revision_get_value(packet));
181*087a95b8SMilanka Ringwald             }
182*087a95b8SMilanka Ringwald             break;
183*087a95b8SMilanka Ringwald 
184*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SYSTEM_ID:
185*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_system_id_get_att_status(packet);
186*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
187*087a95b8SMilanka Ringwald                 printf("System ID read failed, ATT Error 0x%02x\n", att_status);
188*087a95b8SMilanka Ringwald             } else {
189*087a95b8SMilanka Ringwald                 uint32_t manufacturer_identifier_low  = gattservice_subevent_device_information_system_id_get_manufacturer_id_low(packet);
190*087a95b8SMilanka Ringwald                 uint8_t  manufacturer_identifier_high = gattservice_subevent_device_information_system_id_get_manufacturer_id_high(packet);
191*087a95b8SMilanka Ringwald 
192*087a95b8SMilanka Ringwald                 printf("Manufacturer ID:  0x%02x%08x\n",  manufacturer_identifier_high, manufacturer_identifier_low);
193*087a95b8SMilanka Ringwald                 printf("Organizationally Unique ID:  0x%06x\n", gattservice_subevent_device_information_system_id_get_organizationally_unique_id(packet));
194*087a95b8SMilanka Ringwald             }
195*087a95b8SMilanka Ringwald             break;
196*087a95b8SMilanka Ringwald 
197*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_IEEE_REGULATORY_CERTIFICATION:
198*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_ieee_regulatory_certification_get_att_status(packet);
199*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
200*087a95b8SMilanka Ringwald                 printf("IEEE Regulatory Certification read failed, ATT Error 0x%02x\n", att_status);
201*087a95b8SMilanka Ringwald             } else {
202*087a95b8SMilanka Ringwald                 printf("value_a:          0x%04x\n", gattservice_subevent_device_information_ieee_regulatory_certification_get_value_a(packet));
203*087a95b8SMilanka Ringwald                 printf("value_b:          0x%04x\n", gattservice_subevent_device_information_ieee_regulatory_certification_get_value_b(packet));
204*087a95b8SMilanka Ringwald             }
205*087a95b8SMilanka Ringwald             break;
206*087a95b8SMilanka Ringwald 
207*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_PNP_ID:
208*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_pnp_id_get_att_status(packet);
209*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
210*087a95b8SMilanka Ringwald                 printf("PNP ID read failed, ATT Error 0x%02x\n", att_status);
211*087a95b8SMilanka Ringwald             } else {
212*087a95b8SMilanka Ringwald                 printf("Vendor Source ID: 0x%02x\n", gattservice_subevent_device_information_pnp_id_get_vendor_source_id(packet));
213*087a95b8SMilanka Ringwald                 printf("Vendor  ID:       0x%04x\n", gattservice_subevent_device_information_pnp_id_get_vendor_id(packet));
214*087a95b8SMilanka Ringwald                 printf("Product ID:       0x%04x\n", gattservice_subevent_device_information_pnp_id_get_product_id(packet));
215*087a95b8SMilanka Ringwald                 printf("Product Version:  0x%04x\n", gattservice_subevent_device_information_pnp_id_get_product_version(packet));
216*087a95b8SMilanka Ringwald             }
217*087a95b8SMilanka Ringwald             break;
218*087a95b8SMilanka Ringwald 
219*087a95b8SMilanka Ringwald         case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_DONE:
220*087a95b8SMilanka Ringwald             att_status = gattservice_subevent_device_information_serial_number_get_att_status(packet);
221*087a95b8SMilanka Ringwald             if (att_status != ATT_ERROR_SUCCESS){
222*087a95b8SMilanka Ringwald                 printf("Query failed, ATT Error 0x%02x\n", att_status);
223*087a95b8SMilanka Ringwald             } else {
224*087a95b8SMilanka Ringwald                 printf("Query done\n");
225*087a95b8SMilanka Ringwald             }
22677aad125SMilanka Ringwald 
22777aad125SMilanka Ringwald         default:
22877aad125SMilanka Ringwald             break;
22977aad125SMilanka Ringwald     }
23077aad125SMilanka Ringwald }
23177aad125SMilanka Ringwald 
23277aad125SMilanka Ringwald static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
23377aad125SMilanka Ringwald     UNUSED(channel);
23477aad125SMilanka Ringwald     UNUSED(size);
23577aad125SMilanka Ringwald 
23677aad125SMilanka Ringwald     uint8_t status;
23777aad125SMilanka Ringwald     bd_addr_t address;
23877aad125SMilanka Ringwald 
23977aad125SMilanka Ringwald     if (packet_type != HCI_EVENT_PACKET){
24077aad125SMilanka Ringwald         return;
24177aad125SMilanka Ringwald     }
24277aad125SMilanka Ringwald 
24377aad125SMilanka Ringwald     switch (hci_event_packet_get_type(packet)) {
24477aad125SMilanka Ringwald         case BTSTACK_EVENT_STATE:
24577aad125SMilanka Ringwald             // BTstack activated, get started
24677aad125SMilanka Ringwald             if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
24777aad125SMilanka Ringwald             if (cmdline_addr_found){
24877aad125SMilanka Ringwald                 printf("Connect to %s\n", bd_addr_to_str(cmdline_addr));
24977aad125SMilanka Ringwald                 app_state = APP_STATE_W4_CONNECT;
25077aad125SMilanka Ringwald                 gap_connect(cmdline_addr, 0);
25177aad125SMilanka Ringwald                 break;
25277aad125SMilanka Ringwald             }
25377aad125SMilanka Ringwald             printf("Start scanning!\n");
25477aad125SMilanka Ringwald             app_state = APP_STATE_W4_SCAN_RESULT;
25577aad125SMilanka Ringwald             gap_set_scan_parameters(0,0x0030, 0x0030);
25677aad125SMilanka Ringwald             gap_start_scan();
25777aad125SMilanka Ringwald             break;
25877aad125SMilanka Ringwald 
25977aad125SMilanka Ringwald         case GAP_EVENT_ADVERTISING_REPORT:
26077aad125SMilanka Ringwald             if (app_state != APP_STATE_W4_SCAN_RESULT) return;
26177aad125SMilanka Ringwald 
26277aad125SMilanka Ringwald             gap_event_advertising_report_get_address(packet, address);
26377aad125SMilanka Ringwald             if (blacklist_contains(address)) {
26477aad125SMilanka Ringwald                 break;
26577aad125SMilanka Ringwald             }
26677aad125SMilanka Ringwald             dump_advertising_report(packet);
26777aad125SMilanka Ringwald 
26877aad125SMilanka Ringwald             // stop scanning, and connect to the device
26977aad125SMilanka Ringwald             app_state = APP_STATE_W4_CONNECT;
27077aad125SMilanka Ringwald             gap_stop_scan();
27177aad125SMilanka Ringwald             printf("Stop scan. Connect to device with addr %s.\n", bd_addr_to_str(report.address));
27277aad125SMilanka Ringwald             gap_connect(report.address,report.address_type);
27377aad125SMilanka Ringwald             break;
27477aad125SMilanka Ringwald 
27577aad125SMilanka Ringwald         case HCI_EVENT_LE_META:
27677aad125SMilanka Ringwald             // wait for connection complete
27777aad125SMilanka Ringwald             if (hci_event_le_meta_get_subevent_code(packet) !=  HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
27877aad125SMilanka Ringwald             if (app_state != APP_STATE_W4_CONNECT) return;
27977aad125SMilanka Ringwald             connection_handle = hci_subevent_le_connection_complete_get_connection_handle(packet);
28077aad125SMilanka Ringwald 
28177aad125SMilanka Ringwald             status = device_information_service_client_query(connection_handle, handle_gatt_client_event);
28277aad125SMilanka Ringwald             btstack_assert(status == ERROR_CODE_SUCCESS);
28377aad125SMilanka Ringwald 
28477aad125SMilanka Ringwald             app_state = APP_STATE_CONNECTED;
285*087a95b8SMilanka Ringwald             printf("Device Information connected.\n");
28677aad125SMilanka Ringwald             break;
28777aad125SMilanka Ringwald 
28877aad125SMilanka Ringwald         case HCI_EVENT_DISCONNECTION_COMPLETE:
28977aad125SMilanka Ringwald             connection_handle = HCI_CON_HANDLE_INVALID;
29077aad125SMilanka Ringwald 
29177aad125SMilanka Ringwald             if (cmdline_addr_found){
29277aad125SMilanka Ringwald                 printf("Disconnected %s\n", bd_addr_to_str(cmdline_addr));
29377aad125SMilanka Ringwald                 return;
29477aad125SMilanka Ringwald             }
29577aad125SMilanka Ringwald 
29677aad125SMilanka Ringwald             printf("Disconnected %s\n", bd_addr_to_str(report.address));
29777aad125SMilanka Ringwald             printf("Restart scan.\n");
29877aad125SMilanka Ringwald             app_state = APP_STATE_W4_SCAN_RESULT;
29977aad125SMilanka Ringwald             gap_start_scan();
30077aad125SMilanka Ringwald             break;
30177aad125SMilanka Ringwald         default:
30277aad125SMilanka Ringwald             break;
30377aad125SMilanka Ringwald     }
30477aad125SMilanka Ringwald }
30577aad125SMilanka Ringwald 
30677aad125SMilanka Ringwald int btstack_main(int argc, const char * argv[]);
30777aad125SMilanka Ringwald int btstack_main(int argc, const char * argv[]){
30877aad125SMilanka Ringwald 
30977aad125SMilanka Ringwald     // parse address if command line arguments are provided
31077aad125SMilanka Ringwald     int arg = 1;
31177aad125SMilanka Ringwald     cmdline_addr_found = 0;
31277aad125SMilanka Ringwald 
31377aad125SMilanka Ringwald     while (arg < argc) {
31477aad125SMilanka Ringwald         if(!strcmp(argv[arg], "-a") || !strcmp(argv[arg], "--address")){
31577aad125SMilanka Ringwald             arg++;
31677aad125SMilanka Ringwald             cmdline_addr_found = sscanf_bd_addr(argv[arg], cmdline_addr);
31777aad125SMilanka Ringwald             arg++;
31877aad125SMilanka Ringwald             if (!cmdline_addr_found) exit(1);
31977aad125SMilanka Ringwald             continue;
32077aad125SMilanka Ringwald         }
32177aad125SMilanka Ringwald         fprintf(stderr, "\nUsage: %s [-a|--address aa:bb:cc:dd:ee:ff]\n", argv[0]);
32277aad125SMilanka Ringwald         fprintf(stderr, "If no argument is provided, GATT browser will start scanning and connect to the first found device.\nTo connect to a specific device use argument [-a].\n\n");
32377aad125SMilanka Ringwald         return 0;
32477aad125SMilanka Ringwald     }
32577aad125SMilanka Ringwald     (void)argv;
32677aad125SMilanka Ringwald 
32777aad125SMilanka Ringwald     l2cap_init();
32877aad125SMilanka Ringwald 
32977aad125SMilanka Ringwald     // setup ATT server - only needed if LE Peripheral does ATT queries on its own, e.g. Android phones
33077aad125SMilanka Ringwald     att_server_init(profile_data, NULL, NULL);
33177aad125SMilanka Ringwald 
33277aad125SMilanka Ringwald     // GATT Client setup
33377aad125SMilanka Ringwald     gatt_client_init();
33477aad125SMilanka Ringwald     device_information_service_client_init();
33577aad125SMilanka Ringwald 
33677aad125SMilanka Ringwald     sm_init();
33777aad125SMilanka Ringwald     sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT);
33877aad125SMilanka Ringwald 
33977aad125SMilanka Ringwald     hci_event_callback_registration.callback = &hci_event_handler;
34077aad125SMilanka Ringwald     hci_add_event_handler(&hci_event_callback_registration);
34177aad125SMilanka Ringwald 
34277aad125SMilanka Ringwald     app_state = APP_STATE_IDLE;
34377aad125SMilanka Ringwald 
34477aad125SMilanka Ringwald     // turn on!
34577aad125SMilanka Ringwald     hci_power_control(HCI_POWER_ON);
34677aad125SMilanka Ringwald 
34777aad125SMilanka Ringwald     return 0;
34877aad125SMilanka Ringwald }
34977aad125SMilanka Ringwald 
35077aad125SMilanka Ringwald /* EXAMPLE_END */
35177aad125SMilanka Ringwald 
35277aad125SMilanka Ringwald 
353