Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bluetooth/hccontrol/adv_data.c
104817 views
1
/*-
2
* adv_data.c
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
6
* Copyright (c) 2020 Marc Veldman <[email protected]>
7
* All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
* SUCH DAMAGE.
29
*
30
* $Id$
31
*/
32
33
#include <sys/types.h>
34
#include <stdio.h>
35
#include <string.h>
36
#include <uuid.h>
37
#define L2CAP_SOCKET_CHECKED
38
#include <bluetooth.h>
39
#include "hccontrol.h"
40
41
static char* const adv_data2str(int len, uint8_t* data, char* buffer,
42
int size);
43
static char* const adv_name2str(int len, uint8_t* advdata, char* buffer,
44
int size);
45
static char* const adv_uuid2str(int datalen, uint8_t* data, char* buffer,
46
int size);
47
48
void dump_adv_data(int len, uint8_t* advdata)
49
{
50
int n=0;
51
fprintf(stdout, "\tADV Data: ");
52
for (n = 0; n < len+1; n++) {
53
fprintf(stdout, "%02x ", advdata[n]);
54
}
55
fprintf(stdout, "\n");
56
}
57
58
void print_adv_data(int len, uint8_t* advdata)
59
{
60
int n=0;
61
while(n < len)
62
{
63
char buffer[2048];
64
uint8_t datalen = advdata[n];
65
uint8_t datatype = advdata[++n];
66
/* Skip type */
67
++n;
68
datalen--;
69
switch (datatype) {
70
case 0x01:
71
fprintf(stdout,
72
"\tFlags: %s\n",
73
adv_data2str(
74
datalen,
75
&advdata[n],
76
buffer,
77
sizeof(buffer)));
78
break;
79
case 0x02:
80
fprintf(stdout,
81
"\tIncomplete list of service"
82
" class UUIDs (16-bit): %s\n",
83
adv_data2str(
84
datalen,
85
&advdata[n],
86
buffer,
87
sizeof(buffer)));
88
break;
89
case 0x03:
90
fprintf(stdout,
91
"\tComplete list of service "
92
"class UUIDs (16-bit): %s\n",
93
adv_data2str(
94
datalen,
95
&advdata[n],
96
buffer,
97
sizeof(buffer)));
98
break;
99
case 0x07:
100
fprintf(stdout,
101
"\tComplete list of service "
102
"class UUIDs (128 bit): %s\n",
103
adv_uuid2str(
104
datalen,
105
&advdata[n],
106
buffer,
107
sizeof(buffer)));
108
break;
109
case 0x08:
110
fprintf(stdout,
111
"\tShortened local name: %s\n",
112
adv_name2str(
113
datalen,
114
&advdata[n],
115
buffer,
116
sizeof(buffer)));
117
break;
118
case 0x09:
119
fprintf(stdout,
120
"\tComplete local name: %s\n",
121
adv_name2str(
122
datalen,
123
&advdata[n],
124
buffer,
125
sizeof(buffer)));
126
break;
127
case 0x0a:
128
fprintf(stdout,
129
"\tTx Power level: %d dBm\n",
130
(int8_t)advdata[n]);
131
break;
132
case 0x0d:
133
fprintf(stdout,
134
"\tClass of device: %s\n",
135
adv_data2str(
136
datalen,
137
&advdata[n],
138
buffer,
139
sizeof(buffer)));
140
break;
141
case 0x16:
142
fprintf(stdout,
143
"\tService data: %s\n",
144
adv_data2str(
145
datalen,
146
&advdata[n],
147
buffer,
148
sizeof(buffer)));
149
break;
150
case 0x19:
151
fprintf(stdout,
152
"\tAppearance: %s\n",
153
adv_data2str(
154
datalen,
155
&advdata[n],
156
buffer,
157
sizeof(buffer)));
158
break;
159
case 0xff:
160
fprintf(stdout,
161
"\tManufacturer: %s\n",
162
hci_manufacturer2str(
163
advdata[n]|advdata[n+1]<<8));
164
fprintf(stdout,
165
"\tManufacturer specific data: %s\n",
166
adv_data2str(
167
datalen-2,
168
&advdata[n+2],
169
buffer,
170
sizeof(buffer)));
171
break;
172
default:
173
fprintf(stdout,
174
"\tUNKNOWN datatype: %02x data %s\n",
175
datatype,
176
adv_data2str(
177
datalen,
178
&advdata[n],
179
buffer,
180
sizeof(buffer)));
181
}
182
n += datalen;
183
}
184
}
185
186
static char* const adv_data2str(int datalen, uint8_t* data, char* buffer,
187
int size)
188
{
189
int i = 0;
190
char tmpbuf[5];
191
192
if (buffer == NULL)
193
return NULL;
194
195
memset(buffer, 0, size);
196
197
while(i < datalen) {
198
(void)snprintf(tmpbuf, sizeof(tmpbuf), "%02x ", data[i]);
199
/* Check if buffer is full */
200
if (strlcat(buffer, tmpbuf, size) > size)
201
break;
202
i++;
203
}
204
return buffer;
205
}
206
207
static char* const adv_name2str(int datalen, uint8_t* data, char* buffer,
208
int size)
209
{
210
if (buffer == NULL)
211
return NULL;
212
213
memset(buffer, 0, size);
214
215
(void)strlcpy(buffer, (char*)data, datalen+1);
216
return buffer;
217
}
218
219
static char* const adv_uuid2str(int datalen, uint8_t* data, char* buffer,
220
int size)
221
{
222
int i;
223
uuid_t uuid;
224
uint32_t ustatus;
225
char* tmpstr;
226
227
if (buffer == NULL)
228
return NULL;
229
230
memset(buffer, 0, size);
231
if (datalen < 16)
232
return buffer;
233
uuid.time_low = le32dec(data+12);
234
uuid.time_mid = le16dec(data+10);
235
uuid.time_hi_and_version = le16dec(data+8);
236
uuid.clock_seq_hi_and_reserved = data[7];
237
uuid.clock_seq_low = data[6];
238
for(i = 0; i < _UUID_NODE_LEN; i++){
239
uuid.node[i] = data[5 - i];
240
}
241
uuid_to_string(&uuid, &tmpstr, &ustatus);
242
if(ustatus == uuid_s_ok) {
243
strlcpy(buffer, tmpstr, size);
244
}
245
free(tmpstr);
246
247
return buffer;
248
}
249
250