Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libbluetooth/bluetooth.c
34820 views
1
/*
2
* bluetooth.c
3
*/
4
5
/*-
6
* SPDX-License-Identifier: BSD-2-Clause
7
*
8
* Copyright (c) 2001-2009 Maksim Yevmenkin <[email protected]>
9
* All rights reserved.
10
*
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions
13
* are met:
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
* SUCH DAMAGE.
31
*
32
* $Id: bluetooth.c,v 1.3 2003/05/20 23:04:30 max Exp $
33
*/
34
#define L2CAP_SOCKET_CHECKED
35
#include <bluetooth.h>
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
40
#define _PATH_BT_HOSTS "/etc/bluetooth/hosts"
41
#define _PATH_BT_PROTOCOLS "/etc/bluetooth/protocols"
42
#define MAXALIASES 35
43
44
static FILE *hostf = NULL;
45
static int host_stayopen = 0;
46
static struct hostent host;
47
static bdaddr_t host_addr;
48
static char *host_addr_ptrs[2];
49
static char *host_aliases[MAXALIASES];
50
51
static FILE *protof = NULL;
52
static int proto_stayopen = 0;
53
static struct protoent proto;
54
static char *proto_aliases[MAXALIASES];
55
56
static char buf[BUFSIZ + 1];
57
58
static int bt_hex_byte (char const *str);
59
static int bt_hex_nibble (char nibble);
60
61
struct hostent *
62
bt_gethostbyname(char const *name)
63
{
64
struct hostent *p;
65
char **cp;
66
67
bt_sethostent(host_stayopen);
68
while ((p = bt_gethostent()) != NULL) {
69
if (strcasecmp(p->h_name, name) == 0)
70
break;
71
for (cp = p->h_aliases; *cp != NULL; cp++)
72
if (strcasecmp(*cp, name) == 0)
73
goto found;
74
}
75
found:
76
bt_endhostent();
77
78
return (p);
79
}
80
81
struct hostent *
82
bt_gethostbyaddr(char const *addr, int len, int type)
83
{
84
struct hostent *p;
85
86
if (type != AF_BLUETOOTH || len != sizeof(bdaddr_t)) {
87
h_errno = NO_RECOVERY;
88
return (NULL);
89
}
90
91
bt_sethostent(host_stayopen);
92
while ((p = bt_gethostent()) != NULL)
93
if (p->h_addrtype == type && bcmp(p->h_addr, addr, len) == 0)
94
break;
95
bt_endhostent();
96
97
return (p);
98
}
99
100
struct hostent *
101
bt_gethostent(void)
102
{
103
char *p, *cp, **q;
104
105
if (hostf == NULL)
106
hostf = fopen(_PATH_BT_HOSTS, "r");
107
108
if (hostf == NULL) {
109
h_errno = NETDB_INTERNAL;
110
return (NULL);
111
}
112
again:
113
if ((p = fgets(buf, sizeof(buf), hostf)) == NULL) {
114
h_errno = HOST_NOT_FOUND;
115
return (NULL);
116
}
117
if (*p == '#')
118
goto again;
119
if ((cp = strpbrk(p, "#\n")) == NULL)
120
goto again;
121
*cp = 0;
122
if ((cp = strpbrk(p, " \t")) == NULL)
123
goto again;
124
*cp++ = 0;
125
if (bt_aton(p, &host_addr) == 0)
126
goto again;
127
host_addr_ptrs[0] = (char *) &host_addr;
128
host_addr_ptrs[1] = NULL;
129
host.h_addr_list = host_addr_ptrs;
130
host.h_length = sizeof(host_addr);
131
host.h_addrtype = AF_BLUETOOTH;
132
while (*cp == ' ' || *cp == '\t')
133
cp++;
134
host.h_name = cp;
135
q = host.h_aliases = host_aliases;
136
if ((cp = strpbrk(cp, " \t")) != NULL)
137
*cp++ = 0;
138
while (cp != NULL && *cp != 0) {
139
if (*cp == ' ' || *cp == '\t') {
140
cp++;
141
continue;
142
}
143
if (q < &host_aliases[MAXALIASES - 1])
144
*q++ = cp;
145
if ((cp = strpbrk(cp, " \t")) != NULL)
146
*cp++ = 0;
147
}
148
*q = NULL;
149
h_errno = NETDB_SUCCESS;
150
151
return (&host);
152
}
153
154
void
155
bt_sethostent(int stayopen)
156
{
157
if (hostf == NULL)
158
hostf = fopen(_PATH_BT_HOSTS, "r");
159
else
160
rewind(hostf);
161
162
host_stayopen = stayopen;
163
}
164
165
void
166
bt_endhostent(void)
167
{
168
if (hostf != NULL && host_stayopen == 0) {
169
(void) fclose(hostf);
170
hostf = NULL;
171
}
172
}
173
174
struct protoent *
175
bt_getprotobyname(char const *name)
176
{
177
struct protoent *p;
178
char **cp;
179
180
bt_setprotoent(proto_stayopen);
181
while ((p = bt_getprotoent()) != NULL) {
182
if (strcmp(p->p_name, name) == 0)
183
break;
184
for (cp = p->p_aliases; *cp != NULL; cp++)
185
if (strcmp(*cp, name) == 0)
186
goto found;
187
}
188
found:
189
bt_endprotoent();
190
191
return (p);
192
}
193
194
struct protoent *
195
bt_getprotobynumber(int proto)
196
{
197
struct protoent *p;
198
199
bt_setprotoent(proto_stayopen);
200
while ((p = bt_getprotoent()) != NULL)
201
if (p->p_proto == proto)
202
break;
203
bt_endprotoent();
204
205
return (p);
206
}
207
208
struct protoent *
209
bt_getprotoent(void)
210
{
211
char *p, *cp, **q;
212
213
if (protof == NULL)
214
protof = fopen(_PATH_BT_PROTOCOLS, "r");
215
216
if (protof == NULL)
217
return (NULL);
218
again:
219
if ((p = fgets(buf, sizeof(buf), protof)) == NULL)
220
return (NULL);
221
if (*p == '#')
222
goto again;
223
if ((cp = strpbrk(p, "#\n")) == NULL)
224
goto again;
225
*cp = '\0';
226
proto.p_name = p;
227
if ((cp = strpbrk(p, " \t")) == NULL)
228
goto again;
229
*cp++ = '\0';
230
while (*cp == ' ' || *cp == '\t')
231
cp++;
232
if ((p = strpbrk(cp, " \t")) != NULL)
233
*p++ = '\0';
234
proto.p_proto = atoi(cp);
235
q = proto.p_aliases = proto_aliases;
236
if (p != NULL) {
237
cp = p;
238
while (cp != NULL && *cp != 0) {
239
if (*cp == ' ' || *cp == '\t') {
240
cp++;
241
continue;
242
}
243
if (q < &proto_aliases[MAXALIASES - 1])
244
*q++ = cp;
245
if ((cp = strpbrk(cp, " \t")) != NULL)
246
*cp++ = '\0';
247
}
248
}
249
*q = NULL;
250
251
return (&proto);
252
}
253
254
void
255
bt_setprotoent(int stayopen)
256
{
257
if (protof == NULL)
258
protof = fopen(_PATH_BT_PROTOCOLS, "r");
259
else
260
rewind(protof);
261
262
proto_stayopen = stayopen;
263
}
264
265
void
266
bt_endprotoent(void)
267
{
268
if (protof != NULL) {
269
(void) fclose(protof);
270
protof = NULL;
271
}
272
}
273
274
char const *
275
bt_ntoa(bdaddr_t const *ba, char *str)
276
{
277
static char buffer[24];
278
279
if (str == NULL)
280
str = buffer;
281
282
sprintf(str, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
283
ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]);
284
285
return (str);
286
}
287
288
int
289
bt_aton(char const *str, bdaddr_t *ba)
290
{
291
int i, b;
292
char *end = NULL;
293
294
memset(ba, 0, sizeof(*ba));
295
296
for (i = 5, end = strchr(str, ':');
297
i > 0 && *str != '\0' && end != NULL;
298
i --, str = end + 1, end = strchr(str, ':')) {
299
switch (end - str) {
300
case 1:
301
b = bt_hex_nibble(str[0]);
302
break;
303
304
case 2:
305
b = bt_hex_byte(str);
306
break;
307
308
default:
309
b = -1;
310
break;
311
}
312
313
if (b < 0)
314
return (0);
315
316
ba->b[i] = b;
317
}
318
319
if (i != 0 || end != NULL || *str == 0)
320
return (0);
321
322
switch (strlen(str)) {
323
case 1:
324
b = bt_hex_nibble(str[0]);
325
break;
326
327
case 2:
328
b = bt_hex_byte(str);
329
break;
330
331
default:
332
b = -1;
333
break;
334
}
335
336
if (b < 0)
337
return (0);
338
339
ba->b[i] = b;
340
341
return (1);
342
}
343
344
static int
345
bt_hex_byte(char const *str)
346
{
347
int n1, n2;
348
349
if ((n1 = bt_hex_nibble(str[0])) < 0)
350
return (-1);
351
352
if ((n2 = bt_hex_nibble(str[1])) < 0)
353
return (-1);
354
355
return ((((n1 & 0x0f) << 4) | (n2 & 0x0f)) & 0xff);
356
}
357
358
static int
359
bt_hex_nibble(char nibble)
360
{
361
if ('0' <= nibble && nibble <= '9')
362
return (nibble - '0');
363
364
if ('a' <= nibble && nibble <= 'f')
365
return (nibble - 'a' + 0xa);
366
367
if ('A' <= nibble && nibble <= 'F')
368
return (nibble - 'A' + 0xa);
369
370
return (-1);
371
}
372
373
374