xref: /btstack/example/gap_le_advertisements.c (revision edd159b3a19b50d3ca5904b7fc7d2688749b8529)
1bcf00d8fSMatthias Ringwald /*
2bcf00d8fSMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3bcf00d8fSMatthias Ringwald  *
4bcf00d8fSMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5bcf00d8fSMatthias Ringwald  * modification, are permitted provided that the following conditions
6bcf00d8fSMatthias Ringwald  * are met:
7bcf00d8fSMatthias Ringwald  *
8bcf00d8fSMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9bcf00d8fSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10bcf00d8fSMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11bcf00d8fSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12bcf00d8fSMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13bcf00d8fSMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14bcf00d8fSMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15bcf00d8fSMatthias Ringwald  *    from this software without specific prior written permission.
16bcf00d8fSMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17bcf00d8fSMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18bcf00d8fSMatthias Ringwald  *    monetary gain.
19bcf00d8fSMatthias Ringwald  *
20bcf00d8fSMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21bcf00d8fSMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22bcf00d8fSMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
232fca4dadSMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
242fca4dadSMilanka Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25bcf00d8fSMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26bcf00d8fSMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27bcf00d8fSMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28bcf00d8fSMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29bcf00d8fSMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30bcf00d8fSMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31bcf00d8fSMatthias Ringwald  * SUCH DAMAGE.
32bcf00d8fSMatthias Ringwald  *
33bcf00d8fSMatthias Ringwald  * Please inquire about commercial licensing options at
34bcf00d8fSMatthias Ringwald  * [email protected]
35bcf00d8fSMatthias Ringwald  *
36bcf00d8fSMatthias Ringwald  */
37ab2c6ae4SMatthias Ringwald 
38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "gap_le_advertisements.c"
39bcf00d8fSMatthias Ringwald 
40bcf00d8fSMatthias Ringwald 
41bcf00d8fSMatthias Ringwald // *****************************************************************************
42ec8ae085SMilanka Ringwald /* EXAMPLE_START(gap_le_advertisements): GAP LE Advertisements Scanner
43bcf00d8fSMatthias Ringwald  *
44bcf00d8fSMatthias Ringwald  * @text This example shows how to scan and parse advertisements.
45bcf00d8fSMatthias Ringwald  *
46bcf00d8fSMatthias Ringwald  */
47bcf00d8fSMatthias Ringwald  // *****************************************************************************
48bcf00d8fSMatthias Ringwald 
49bcf00d8fSMatthias Ringwald 
50bcf00d8fSMatthias Ringwald #include <stdint.h>
51de1762f7SMatthias Ringwald #include <inttypes.h>
52bcf00d8fSMatthias Ringwald #include <stdio.h>
53bcf00d8fSMatthias Ringwald #include <stdlib.h>
54bcf00d8fSMatthias Ringwald #include <string.h>
55bcf00d8fSMatthias Ringwald 
560e2df43fSMatthias Ringwald #include "btstack.h"
57bcf00d8fSMatthias Ringwald 
58bcf00d8fSMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration;
59bcf00d8fSMatthias Ringwald 
60bcf00d8fSMatthias Ringwald /* @section GAP LE setup for receiving advertisements
61bcf00d8fSMatthias Ringwald  *
62bcf00d8fSMatthias Ringwald  * @text GAP LE advertisements are received as custom HCI events of the
63045013feSMatthias Ringwald  * GAP_EVENT_ADVERTISING_REPORT type. To receive them, you'll need to register
64bcf00d8fSMatthias Ringwald  * the HCI packet handler, as shown in Listing GAPLEAdvSetup.
65bcf00d8fSMatthias Ringwald  */
66bcf00d8fSMatthias Ringwald 
67bcf00d8fSMatthias Ringwald /* LISTING_START(GAPLEAdvSetup): Setting up GAP LE client for receiving advertisements */
68bcf00d8fSMatthias Ringwald static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
69bcf00d8fSMatthias Ringwald 
gap_le_advertisements_setup(void)70bcf00d8fSMatthias Ringwald static void gap_le_advertisements_setup(void){
71bfb465b0SMatthias Ringwald     // Active scanning, 100% (scan interval = scan window)
72bfb465b0SMatthias Ringwald     gap_set_scan_parameters(1,48,48);
7349999da9SMatthias Ringwald     gap_start_scan();
74a4fe6467SMatthias Ringwald 
75a4fe6467SMatthias Ringwald     hci_event_callback_registration.callback = &packet_handler;
76a4fe6467SMatthias Ringwald     hci_add_event_handler(&hci_event_callback_registration);
77bcf00d8fSMatthias Ringwald }
78bcf00d8fSMatthias Ringwald 
79bcf00d8fSMatthias Ringwald /* LISTING_END */
80bcf00d8fSMatthias Ringwald 
81bcf00d8fSMatthias Ringwald /* @section GAP LE Advertising Data Dumper
82bcf00d8fSMatthias Ringwald  *
83bcf00d8fSMatthias Ringwald  * @text Here, we use the definition of advertising data types and flags as specified in
84bcf00d8fSMatthias Ringwald  * [Assigned Numbers GAP](https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile)
85bcf00d8fSMatthias Ringwald  * and [Supplement to the Bluetooth Core Specification, v4](https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=282152).
86bcf00d8fSMatthias Ringwald  */
87bcf00d8fSMatthias Ringwald 
88bcf00d8fSMatthias Ringwald /* LISTING_START(GAPLEAdvDataTypesAndFlags): Advertising data types and flags */
89e3c4fe2fSMatthias Ringwald static const char * ad_types[] = {
90bcf00d8fSMatthias Ringwald     "",
91bcf00d8fSMatthias Ringwald     "Flags",
92bcf00d8fSMatthias Ringwald     "Incomplete List of 16-bit Service Class UUIDs",
93bcf00d8fSMatthias Ringwald     "Complete List of 16-bit Service Class UUIDs",
94bcf00d8fSMatthias Ringwald     "Incomplete List of 32-bit Service Class UUIDs",
95bcf00d8fSMatthias Ringwald     "Complete List of 32-bit Service Class UUIDs",
96bcf00d8fSMatthias Ringwald     "Incomplete List of 128-bit Service Class UUIDs",
97bcf00d8fSMatthias Ringwald     "Complete List of 128-bit Service Class UUIDs",
98bcf00d8fSMatthias Ringwald     "Shortened Local Name",
99bcf00d8fSMatthias Ringwald     "Complete Local Name",
100bcf00d8fSMatthias Ringwald     "Tx Power Level",
101bcf00d8fSMatthias Ringwald     "",
102bcf00d8fSMatthias Ringwald     "",
103bcf00d8fSMatthias Ringwald     "Class of Device",
104bcf00d8fSMatthias Ringwald     "Simple Pairing Hash C",
105bcf00d8fSMatthias Ringwald     "Simple Pairing Randomizer R",
106bcf00d8fSMatthias Ringwald     "Device ID",
107bcf00d8fSMatthias Ringwald     "Security Manager TK Value",
108bcf00d8fSMatthias Ringwald     "Slave Connection Interval Range",
109bcf00d8fSMatthias Ringwald     "",
110bcf00d8fSMatthias Ringwald     "List of 16-bit Service Solicitation UUIDs",
111bcf00d8fSMatthias Ringwald     "List of 128-bit Service Solicitation UUIDs",
112bcf00d8fSMatthias Ringwald     "Service Data",
113bcf00d8fSMatthias Ringwald     "Public Target Address",
114bcf00d8fSMatthias Ringwald     "Random Target Address",
115bcf00d8fSMatthias Ringwald     "Appearance",
116bcf00d8fSMatthias Ringwald     "Advertising Interval"
117bcf00d8fSMatthias Ringwald };
118bcf00d8fSMatthias Ringwald 
119e3c4fe2fSMatthias Ringwald static const char * flags[] = {
120bcf00d8fSMatthias Ringwald     "LE Limited Discoverable Mode",
121bcf00d8fSMatthias Ringwald     "LE General Discoverable Mode",
122bcf00d8fSMatthias Ringwald     "BR/EDR Not Supported",
123bcf00d8fSMatthias Ringwald     "Simultaneous LE and BR/EDR to Same Device Capable (Controller)",
124bcf00d8fSMatthias Ringwald     "Simultaneous LE and BR/EDR to Same Device Capable (Host)",
125bcf00d8fSMatthias Ringwald     "Reserved",
126bcf00d8fSMatthias Ringwald     "Reserved",
127bcf00d8fSMatthias Ringwald     "Reserved"
128bcf00d8fSMatthias Ringwald };
129bcf00d8fSMatthias Ringwald /* LISTING_END */
130bcf00d8fSMatthias Ringwald 
131bcf00d8fSMatthias Ringwald /* @text BTstack offers an iterator for parsing sequence of advertising data (AD) structures,
132bcf00d8fSMatthias Ringwald  * see [BLE advertisements parser API](../appendix/apis/#ble-advertisements-parser-api).
133bcf00d8fSMatthias Ringwald  * After initializing the iterator, each AD structure is dumped according to its type.
134bcf00d8fSMatthias Ringwald  */
135bcf00d8fSMatthias Ringwald 
136bcf00d8fSMatthias Ringwald /* LISTING_START(GAPLEAdvDataParsing): Parsing advertising data */
dump_advertisement_data(const uint8_t * adv_data,uint8_t adv_size)1373ee82ab1SMilanka Ringwald static void dump_advertisement_data(const uint8_t * adv_data, uint8_t adv_size){
138bcf00d8fSMatthias Ringwald     ad_context_t context;
139bcf00d8fSMatthias Ringwald     bd_addr_t address;
140bcf00d8fSMatthias Ringwald     uint8_t uuid_128[16];
1413ee82ab1SMilanka Ringwald     for (ad_iterator_init(&context, adv_size, (uint8_t *)adv_data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){
142bcf00d8fSMatthias Ringwald         uint8_t data_type    = ad_iterator_get_data_type(&context);
143bcf00d8fSMatthias Ringwald         uint8_t size         = ad_iterator_get_data_len(&context);
14418a2fc6fSMatthias Ringwald         const uint8_t * data = ad_iterator_get_data(&context);
145bcf00d8fSMatthias Ringwald 
146bcf00d8fSMatthias Ringwald         if (data_type > 0 && data_type < 0x1B){
147bcf00d8fSMatthias Ringwald             printf("    %s: ", ad_types[data_type]);
148bcf00d8fSMatthias Ringwald         }
149bcf00d8fSMatthias Ringwald         int i;
150bcf00d8fSMatthias Ringwald         // Assigned Numbers GAP
151bcf00d8fSMatthias Ringwald 
152bcf00d8fSMatthias Ringwald         switch (data_type){
1531d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_FLAGS:
154bcf00d8fSMatthias Ringwald                 // show only first octet, ignore rest
155bcf00d8fSMatthias Ringwald                 for (i=0; i<8;i++){
156bcf00d8fSMatthias Ringwald                     if (data[0] & (1<<i)){
157bcf00d8fSMatthias Ringwald                         printf("%s; ", flags[i]);
158bcf00d8fSMatthias Ringwald                     }
159bcf00d8fSMatthias Ringwald                 }
160bcf00d8fSMatthias Ringwald                 break;
1611d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS:
1621d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS:
1631d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS:
164bcf00d8fSMatthias Ringwald                 for (i=0; i<size;i+=2){
165*edd159b3SMatthias Ringwald                     printf("%04X ", little_endian_read_16(data, i));
166bcf00d8fSMatthias Ringwald                 }
167bcf00d8fSMatthias Ringwald                 break;
1681d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS:
1691d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS:
1701d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS:
171bcf00d8fSMatthias Ringwald                 for (i=0; i<size;i+=4){
172de1762f7SMatthias Ringwald                     printf("%04"PRIX32, little_endian_read_32(data, i));
173bcf00d8fSMatthias Ringwald                 }
174bcf00d8fSMatthias Ringwald                 break;
1751d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS:
1761d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS:
1771d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS:
178bcf00d8fSMatthias Ringwald                 reverse_128(data, uuid_128);
179bcf00d8fSMatthias Ringwald                 printf("%s", uuid128_to_str(uuid_128));
180bcf00d8fSMatthias Ringwald                 break;
1811d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_SHORTENED_LOCAL_NAME:
1821d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME:
183bcf00d8fSMatthias Ringwald                 for (i=0; i<size;i++){
184bcf00d8fSMatthias Ringwald                     printf("%c", (char)(data[i]));
185bcf00d8fSMatthias Ringwald                 }
186bcf00d8fSMatthias Ringwald                 break;
1871d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_TX_POWER_LEVEL:
188bcf00d8fSMatthias Ringwald                 printf("%d dBm", *(int8_t*)data);
189bcf00d8fSMatthias Ringwald                 break;
1901d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE:
191bcf00d8fSMatthias Ringwald                 printf("Connection Interval Min = %u ms, Max = %u ms", little_endian_read_16(data, 0) * 5/4, little_endian_read_16(data, 2) * 5/4);
192bcf00d8fSMatthias Ringwald                 break;
1931d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_SERVICE_DATA:
194*edd159b3SMatthias Ringwald                 for (i=0; i<size;i+=2){
195*edd159b3SMatthias Ringwald                     printf("%02X ", data[i]);
196*edd159b3SMatthias Ringwald                 }
197bcf00d8fSMatthias Ringwald                 break;
1981d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_PUBLIC_TARGET_ADDRESS:
1991d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_RANDOM_TARGET_ADDRESS:
200bcf00d8fSMatthias Ringwald                 reverse_bd_addr(data, address);
201bcf00d8fSMatthias Ringwald                 printf("%s", bd_addr_to_str(address));
202bcf00d8fSMatthias Ringwald                 break;
2031d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_APPEARANCE:
204bcf00d8fSMatthias Ringwald                 // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
205bcf00d8fSMatthias Ringwald                 printf("%02X", little_endian_read_16(data, 0) );
206bcf00d8fSMatthias Ringwald                 break;
2071d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_ADVERTISING_INTERVAL:
208bcf00d8fSMatthias Ringwald                 printf("%u ms", little_endian_read_16(data, 0) * 5/8 );
209bcf00d8fSMatthias Ringwald                 break;
2101d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_3D_INFORMATION_DATA:
211*edd159b3SMatthias Ringwald                 for (i=0; i<size;i+=2){
212*edd159b3SMatthias Ringwald                     printf("%02X ", data[i]);
213*edd159b3SMatthias Ringwald                 }
214bcf00d8fSMatthias Ringwald                 break;
2151d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA: // Manufacturer Specific Data
2161d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_CLASS_OF_DEVICE:
2171d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_SIMPLE_PAIRING_HASH_C:
2181d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_SIMPLE_PAIRING_RANDOMIZER_R:
2191d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_DEVICE_ID:
2201d0cde9dSMatthias Ringwald             case BLUETOOTH_DATA_TYPE_SECURITY_MANAGER_OUT_OF_BAND_FLAGS:
221bcf00d8fSMatthias Ringwald             default:
2221d0cde9dSMatthias Ringwald                 printf("    Advertising Data Type 0x%2x not handled yet", data_type);
223bcf00d8fSMatthias Ringwald                 break;
224bcf00d8fSMatthias Ringwald         }
225bcf00d8fSMatthias Ringwald         printf("\n");
226bcf00d8fSMatthias Ringwald     }
227bcf00d8fSMatthias Ringwald     printf("\n");
228bcf00d8fSMatthias Ringwald }
229bcf00d8fSMatthias Ringwald /* LISTING_END */
230bcf00d8fSMatthias Ringwald 
231bcf00d8fSMatthias Ringwald /* @section HCI packet handler
232bcf00d8fSMatthias Ringwald  *
233bcf00d8fSMatthias Ringwald  * @text The HCI packet handler has to start the scanning,
234bcf00d8fSMatthias Ringwald  * and to handle received advertisements. Advertisements are received
235045013feSMatthias Ringwald  * as HCI event packets of the GAP_EVENT_ADVERTISING_REPORT type,
236bcf00d8fSMatthias Ringwald  * see Listing GAPLEAdvPacketHandler.
237bcf00d8fSMatthias Ringwald  */
238bcf00d8fSMatthias Ringwald 
239bcf00d8fSMatthias Ringwald /* LISTING_START(GAPLEAdvPacketHandler): Scanning and receiving advertisements */
240bcf00d8fSMatthias Ringwald 
packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)241bcf00d8fSMatthias Ringwald static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
2429ec2630cSMatthias Ringwald     UNUSED(channel);
2439ec2630cSMatthias Ringwald     UNUSED(size);
2449ec2630cSMatthias Ringwald 
245bcf00d8fSMatthias Ringwald     if (packet_type != HCI_EVENT_PACKET) return;
246bcf00d8fSMatthias Ringwald 
247bcf00d8fSMatthias Ringwald     bd_addr_t address;
248b1847fffSMatthias Ringwald     uint8_t address_type;
249b1847fffSMatthias Ringwald     uint8_t event_type;
250b1847fffSMatthias Ringwald     int8_t rssi;
251b1847fffSMatthias Ringwald     uint8_t length;
252b1847fffSMatthias Ringwald     const uint8_t * data;
253bcf00d8fSMatthias Ringwald 
254b1847fffSMatthias Ringwald     switch (hci_event_packet_get_type(packet)) {
255b1847fffSMatthias Ringwald         case GAP_EVENT_ADVERTISING_REPORT:
256b1847fffSMatthias Ringwald             gap_event_advertising_report_get_address(packet, address);
257b1847fffSMatthias Ringwald             event_type = gap_event_advertising_report_get_advertising_event_type(packet);
258b1847fffSMatthias Ringwald             address_type = gap_event_advertising_report_get_address_type(packet);
259b1847fffSMatthias Ringwald             rssi = gap_event_advertising_report_get_rssi(packet);
260b1847fffSMatthias Ringwald             length = gap_event_advertising_report_get_data_length(packet);
261b1847fffSMatthias Ringwald             data = gap_event_advertising_report_get_data(packet);
262b1847fffSMatthias Ringwald             printf("Advertisement (legacy) event: evt-type %u, addr-type %u, addr %s, rssi %d, data[%u] ", event_type,
263bcf00d8fSMatthias Ringwald                address_type, bd_addr_to_str(address), rssi, length);
264bcf00d8fSMatthias Ringwald             printf_hexdump(data, length);
265bcf00d8fSMatthias Ringwald             dump_advertisement_data(data, length);
266bcf00d8fSMatthias Ringwald             break;
267b1847fffSMatthias Ringwald #ifdef ENABLE_LE_EXTENDED_ADVERTISING
268b1847fffSMatthias Ringwald         case GAP_EVENT_EXTENDED_ADVERTISING_REPORT:
269b1847fffSMatthias Ringwald             gap_event_extended_advertising_report_get_address(packet, address);
270b1847fffSMatthias Ringwald             event_type = gap_event_extended_advertising_report_get_advertising_event_type(packet);
271b1847fffSMatthias Ringwald             address_type = gap_event_extended_advertising_report_get_address_type(packet);
272b1847fffSMatthias Ringwald             rssi = gap_event_extended_advertising_report_get_rssi(packet);
273b1847fffSMatthias Ringwald             length = gap_event_extended_advertising_report_get_data_length(packet);
274b1847fffSMatthias Ringwald             data = gap_event_extended_advertising_report_get_data(packet);
275b1847fffSMatthias Ringwald             printf("Advertisement (extended) event: evt-type %u, addr-type %u, addr %s, rssi %d, data[%u] ", event_type,
276b1847fffSMatthias Ringwald                address_type, bd_addr_to_str(address), rssi, length);
277b1847fffSMatthias Ringwald             printf_hexdump(data, length);
278b1847fffSMatthias Ringwald             dump_advertisement_data(data, length);
279b1847fffSMatthias Ringwald             break;
280b1847fffSMatthias Ringwald #endif
281bcf00d8fSMatthias Ringwald         default:
282bcf00d8fSMatthias Ringwald             break;
283bcf00d8fSMatthias Ringwald     }
284bcf00d8fSMatthias Ringwald }
285bcf00d8fSMatthias Ringwald /* LISTING_END */
286bcf00d8fSMatthias Ringwald 
287bcf00d8fSMatthias Ringwald int btstack_main(void);
btstack_main(void)288bcf00d8fSMatthias Ringwald int btstack_main(void)
289bcf00d8fSMatthias Ringwald {
290bcf00d8fSMatthias Ringwald     gap_le_advertisements_setup();
291bcf00d8fSMatthias Ringwald 
292bcf00d8fSMatthias Ringwald     // turn on!
293bcf00d8fSMatthias Ringwald     hci_power_control(HCI_POWER_ON);
294bcf00d8fSMatthias Ringwald 
295bcf00d8fSMatthias Ringwald     return 0;
296bcf00d8fSMatthias Ringwald }
297bcf00d8fSMatthias Ringwald 
298bcf00d8fSMatthias Ringwald /* EXAMPLE_END */
299