xref: /btstack/test/mesh/sniffer.c (revision bc6a318f2177319997f3b7da7b6f161b4ec94fed)
1 /*
2  * Copyright (C) 2014 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 MATTHIAS
24  * RINGWALD 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__ "gap_le_advertisements.c"
39 
40 
41 // *****************************************************************************
42 /* EXAMPLE_START(gap_le_advertisements): GAP LE Advertisements Dumper
43  *
44  * @text This example shows how to scan and parse advertisements.
45  *
46  */
47  // *****************************************************************************
48 
49 
50 #include <stdint.h>
51 #include <inttypes.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 
56 #include "btstack.h"
57 
58 static btstack_packet_callback_registration_t hci_event_callback_registration;
59 
60 #define NUM_NODES 2
61 
62 static const char * nodes_string[NUM_NODES] = {
63     "5C:F3:70:60:7B:87",
64     "00:1B:DC:07:32:EF",
65 };
66 static bd_addr_t nodes_addr[NUM_NODES];
67 
68 /* @section GAP LE setup for receiving advertisements
69  *
70  * @text GAP LE advertisements are received as custom HCI events of the
71  * GAP_EVENT_ADVERTISING_REPORT type. To receive them, you'll need to register
72  * the HCI packet handler, as shown in Listing GAPLEAdvSetup.
73  */
74 
75 static char * ad_types[] = {
76     "",
77     "Flags",
78     "Incomplete List of 16-bit Service Class UUIDs",
79     "Complete List of 16-bit Service Class UUIDs",
80     "Incomplete List of 32-bit Service Class UUIDs",
81     "Complete List of 32-bit Service Class UUIDs",
82     "Incomplete List of 128-bit Service Class UUIDs",
83     "Complete List of 128-bit Service Class UUIDs",
84     "Shortened Local Name",
85     "Complete Local Name",
86     "Tx Power Level",
87     "",
88     "",
89     "Class of Device",
90     "Simple Pairing Hash C",
91     "Simple Pairing Randomizer R",
92     "Device ID",
93     "Security Manager TK Value",
94     "Slave Connection Interval Range",
95     "",
96     "List of 16-bit Service Solicitation UUIDs",
97     "List of 128-bit Service Solicitation UUIDs",
98     "Service Data",
99     "Public Target Address",
100     "Random Target Address",
101     "Appearance",
102     "Advertising Interval"
103 };
104 
105 static char * flags[] = {
106     "LE Limited Discoverable Mode",
107     "LE General Discoverable Mode",
108     "BR/EDR Not Supported",
109     "Simultaneous LE and BR/EDR to Same Device Capable (Controller)",
110     "Simultaneous LE and BR/EDR to Same Device Capable (Host)",
111     "Reserved",
112     "Reserved",
113     "Reserved"
114 };
115 
116 /* LISTING_START(GAPLEAdvSetup): Setting up GAP LE client for receiving advertisements */
117 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
118 
sniffer_setup(void)119 static void sniffer_setup(void){
120     hci_event_callback_registration.callback = &packet_handler;
121     hci_add_event_handler(&hci_event_callback_registration);
122     // Active scanning, 100% (scan interval = scan window)
123     gap_set_scan_parameters(1,48,48);
124     //
125     int i;
126     for (i=0;i<NUM_NODES;i++){
127         sscanf_bd_addr(nodes_string[i], nodes_addr[i]);
128         printf("Listening for %s\n", bd_addr_to_str(nodes_addr[i]));
129     }
130 }
131 
addr_from_list(bd_addr_t addr)132 static int addr_from_list(bd_addr_t addr){
133     int i;
134     for (i=0;i<NUM_NODES;i++){
135         if (memcmp(addr, nodes_addr[i], 6) == 0) return 1;
136     }
137     return 0;
138 }
139 
140 /* LISTING_END */
141 
142 
143 /* LISTING_START(GAPLEAdvDataParsing): Parsing advertising data */
dump_advertisement_data(const uint8_t * adv_data,uint8_t adv_size)144 static void dump_advertisement_data(const uint8_t * adv_data, uint8_t adv_size){
145     ad_context_t context;
146     bd_addr_t address;
147     uint8_t uuid_128[16];
148     for (ad_iterator_init(&context, adv_size, (uint8_t *)adv_data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){
149         uint8_t data_type    = ad_iterator_get_data_type(&context);
150         uint8_t size         = ad_iterator_get_data_len(&context);
151         const uint8_t * data = ad_iterator_get_data(&context);
152 
153         if (data_type > 0 && data_type < 0x1B){
154             printf("    %s: ", ad_types[data_type]);
155         }
156         int i;
157         // Assigned Numbers GAP
158 
159         switch (data_type){
160             case BLUETOOTH_DATA_TYPE_FLAGS:
161                 // show only first octet, ignore rest
162                 for (i=0; i<8;i++){
163                     if (data[0] & (1<<i)){
164                         printf("%s; ", flags[i]);
165                     }
166 
167                 }
168                 break;
169             case BLUETOOTH_DATA_TYPE_INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS:
170             case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS:
171             case BLUETOOTH_DATA_TYPE_LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS:
172                 for (i=0; i<size;i+=2){
173                     printf("%02X ", little_endian_read_16(data, i));
174                 }
175                 break;
176             case BLUETOOTH_DATA_TYPE_INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS:
177             case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS:
178             case BLUETOOTH_DATA_TYPE_LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS:
179                 for (i=0; i<size;i+=4){
180                     printf("%04"PRIX32, little_endian_read_32(data, i));
181                 }
182                 break;
183             case BLUETOOTH_DATA_TYPE_INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS:
184             case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS:
185             case BLUETOOTH_DATA_TYPE_LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS:
186                 reverse_128(data, uuid_128);
187                 printf("%s", uuid128_to_str(uuid_128));
188                 break;
189             case BLUETOOTH_DATA_TYPE_SHORTENED_LOCAL_NAME:
190             case BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME:
191                 for (i=0; i<size;i++){
192                     printf("%c", (char)(data[i]));
193                 }
194                 break;
195             case BLUETOOTH_DATA_TYPE_TX_POWER_LEVEL:
196                 printf("%d dBm", *(int8_t*)data);
197                 break;
198             case BLUETOOTH_DATA_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE:
199                 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);
200                 break;
201             case BLUETOOTH_DATA_TYPE_SERVICE_DATA:
202                 printf_hexdump(data, size);
203                 break;
204             case BLUETOOTH_DATA_TYPE_PUBLIC_TARGET_ADDRESS:
205             case BLUETOOTH_DATA_TYPE_RANDOM_TARGET_ADDRESS:
206                 reverse_bd_addr(data, address);
207                 printf("%s", bd_addr_to_str(address));
208                 break;
209             case BLUETOOTH_DATA_TYPE_APPEARANCE:
210                 // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
211                 printf("%02X", little_endian_read_16(data, 0) );
212                 break;
213             case BLUETOOTH_DATA_TYPE_ADVERTISING_INTERVAL:
214                 printf("%u ms", little_endian_read_16(data, 0) * 5/8 );
215                 break;
216             case BLUETOOTH_DATA_TYPE_3D_INFORMATION_DATA:
217                 printf_hexdump(data, size);
218                 break;
219             case BLUETOOTH_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA: // Manufacturer Specific Data
220                 break;
221             case BLUETOOTH_DATA_TYPE_CLASS_OF_DEVICE:
222             case BLUETOOTH_DATA_TYPE_SIMPLE_PAIRING_HASH_C:
223             case BLUETOOTH_DATA_TYPE_SIMPLE_PAIRING_RANDOMIZER_R:
224             case BLUETOOTH_DATA_TYPE_DEVICE_ID:
225             case BLUETOOTH_DATA_TYPE_SECURITY_MANAGER_OUT_OF_BAND_FLAGS:
226             default:
227                 printf("Advertising Data Type 0x%2x not handled yet", data_type);
228                 break;
229         }
230         printf("\n");
231     }
232     printf("\n");
233 }
234 /* LISTING_END */
235 
236 /* @section HCI packet handler
237  *
238  * @text The HCI packet handler has to start the scanning,
239  * and to handle received advertisements. Advertisements are received
240  * as HCI event packets of the GAP_EVENT_ADVERTISING_REPORT type,
241  * see Listing GAPLEAdvPacketHandler.
242  */
243 
244 /* LISTING_START(GAPLEAdvPacketHandler): Scanning and receiving advertisements */
245 
packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)246 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
247     UNUSED(channel);
248     UNUSED(size);
249 
250     if (packet_type != HCI_EVENT_PACKET) return;
251 
252     switch (hci_event_packet_get_type(packet)) {
253         case BTSTACK_EVENT_STATE:
254             // BTstack activated, get started
255             if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){
256                 printf("Start scaning!\n");
257                 gap_set_scan_parameters(0,0x0030, 0x0030);
258                 gap_start_scan();
259             }
260             break;
261         case GAP_EVENT_ADVERTISING_REPORT:{
262             bd_addr_t address;
263             gap_event_advertising_report_get_address(packet, address);
264             // check if in list
265             if (!addr_from_list(address)) break;
266 
267             uint8_t event_type = gap_event_advertising_report_get_advertising_event_type(packet);
268             uint8_t address_type = gap_event_advertising_report_get_address_type(packet);
269             int8_t rssi = gap_event_advertising_report_get_rssi(packet);
270             uint8_t length = gap_event_advertising_report_get_data_length(packet);
271             const uint8_t * data = gap_event_advertising_report_get_data(packet);
272 
273             printf("Advertisement event: evt-type %u, addr-type %u, addr %s, rssi %d, data[%u] ", event_type,
274                address_type, bd_addr_to_str(address), rssi, length);
275             printf_hexdump(data, length);
276             dump_advertisement_data(data, length);
277             break;
278         }
279         default:
280             break;
281     }
282 }
283 /* LISTING_END */
284 
285 int btstack_main(void);
btstack_main(void)286 int btstack_main(void)
287 {
288     sniffer_setup();
289 
290     // turn on!
291     hci_power_control(HCI_POWER_ON);
292 
293     return 0;
294 }
295 
296 /* EXAMPLE_END */
297