4 * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $Id: bluetooth.c,v 1.3 2003/05/20 23:04:30 max Exp $
32 #include <bluetooth.h>
37 #define _PATH_BT_HOSTS "/etc/bluetooth/hosts"
38 #define _PATH_BT_PROTOCOLS "/etc/bluetooth/protocols"
41 static FILE *hostf
= NULL
;
42 static int host_stayopen
= 0;
43 static struct hostent host
;
44 static bdaddr_t host_addr
;
45 static char *host_addr_ptrs
[2];
46 static char *host_aliases
[MAXALIASES
];
48 static FILE *protof
= NULL
;
49 static int proto_stayopen
= 0;
50 static struct protoent proto
;
51 static char *proto_aliases
[MAXALIASES
];
53 static char buf
[BUFSIZ
+ 1];
55 static int bt_hex_byte (char const *str
);
56 static int bt_hex_nibble (char nibble
);
59 bt_gethostbyname(char const *name
)
64 bt_sethostent(host_stayopen
);
65 while ((p
= bt_gethostent()) != NULL
) {
66 if (strcasecmp(p
->h_name
, name
) == 0)
68 for (cp
= p
->h_aliases
; *cp
!= 0; cp
++)
69 if (strcasecmp(*cp
, name
) == 0)
79 bt_gethostbyaddr(char const *addr
, int len
, int type
)
83 if (type
!= AF_BLUETOOTH
|| len
!= sizeof(bdaddr_t
)) {
84 h_errno
= NO_RECOVERY
;
88 bt_sethostent(host_stayopen
);
89 while ((p
= bt_gethostent()) != NULL
)
90 if (p
->h_addrtype
== type
&& bcmp(p
->h_addr
, addr
, len
) == 0)
103 hostf
= fopen(_PATH_BT_HOSTS
, "r");
106 h_errno
= NETDB_INTERNAL
;
110 if ((p
= fgets(buf
, sizeof(buf
), hostf
)) == NULL
) {
111 h_errno
= HOST_NOT_FOUND
;
116 if ((cp
= strpbrk(p
, "#\n")) == NULL
)
119 if ((cp
= strpbrk(p
, " \t")) == NULL
)
122 if (bt_aton(p
, &host_addr
) == 0)
124 host_addr_ptrs
[0] = (char *) &host_addr
;
125 host_addr_ptrs
[1] = NULL
;
126 host
.h_addr_list
= host_addr_ptrs
;
127 host
.h_length
= sizeof(host_addr
);
128 host
.h_addrtype
= AF_BLUETOOTH
;
129 while (*cp
== ' ' || *cp
== '\t')
132 q
= host
.h_aliases
= host_aliases
;
133 if ((cp
= strpbrk(cp
, " \t")) != NULL
)
135 while (cp
!= NULL
&& *cp
!= 0) {
136 if (*cp
== ' ' || *cp
== '\t') {
140 if (q
< &host_aliases
[MAXALIASES
- 1])
142 if ((cp
= strpbrk(cp
, " \t")) != NULL
)
146 h_errno
= NETDB_SUCCESS
;
152 bt_sethostent(int stayopen
)
155 hostf
= fopen(_PATH_BT_HOSTS
, "r");
159 host_stayopen
= stayopen
;
165 if (hostf
!= NULL
&& host_stayopen
== 0) {
166 (void) fclose(hostf
);
172 bt_getprotobyname(char const *name
)
177 bt_setprotoent(proto_stayopen
);
178 while ((p
= bt_getprotoent()) != NULL
) {
179 if (strcmp(p
->p_name
, name
) == 0)
181 for (cp
= p
->p_aliases
; *cp
!= 0; cp
++)
182 if (strcmp(*cp
, name
) == 0)
192 bt_getprotobynumber(int proto
)
196 bt_setprotoent(proto_stayopen
);
197 while ((p
= bt_getprotoent()) != NULL
)
198 if (p
->p_proto
== proto
)
211 protof
= fopen(_PATH_BT_PROTOCOLS
, "r");
216 if ((p
= fgets(buf
, sizeof(buf
), protof
)) == NULL
)
220 if ((cp
= strpbrk(p
, "#\n")) == NULL
)
224 if ((cp
= strpbrk(p
, " \t")) == NULL
)
227 while (*cp
== ' ' || *cp
== '\t')
229 if ((p
= strpbrk(cp
, " \t")) != NULL
)
231 proto
.p_proto
= atoi(cp
);
232 q
= proto
.p_aliases
= proto_aliases
;
235 while (cp
!= NULL
&& *cp
!= 0) {
236 if (*cp
== ' ' || *cp
== '\t') {
240 if (q
< &proto_aliases
[MAXALIASES
- 1])
242 if ((cp
= strpbrk(cp
, " \t")) != NULL
)
252 bt_setprotoent(int stayopen
)
255 protof
= fopen(_PATH_BT_PROTOCOLS
, "r");
259 proto_stayopen
= stayopen
;
265 if (protof
!= NULL
) {
266 (void) fclose(protof
);
272 bt_ntoa(bdaddr_t
const *ba
, char *str
)
274 static char buffer
[24];
279 sprintf(str
, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
280 ba
->b
[5], ba
->b
[4], ba
->b
[3], ba
->b
[2], ba
->b
[1], ba
->b
[0]);
286 bt_aton(char const *str
, bdaddr_t
*ba
)
291 memset(ba
, 0, sizeof(*ba
));
293 for (i
= 5, end
= strchr(str
, ':');
294 i
> 0 && *str
!= '\0' && end
!= NULL
;
295 i
--, str
= end
+ 1, end
= strchr(str
, ':')) {
298 b
= bt_hex_nibble(str
[0]);
302 b
= bt_hex_byte(str
);
316 if (i
!= 0 || end
!= NULL
|| *str
== 0)
319 switch (strlen(str
)) {
321 b
= bt_hex_nibble(str
[0]);
325 b
= bt_hex_byte(str
);
342 bt_hex_byte(char const *str
)
346 if ((n1
= bt_hex_nibble(str
[0])) < 0)
349 if ((n2
= bt_hex_nibble(str
[1])) < 0)
352 return ((((n1
& 0x0f) << 4) | (n2
& 0x0f)) & 0xff);
356 bt_hex_nibble(char nibble
)
358 if ('0' <= nibble
&& nibble
<= '9')
359 return (nibble
- '0');
361 if ('a' <= nibble
&& nibble
<= 'f')
362 return (nibble
- 'a' + 0xa);
364 if ('A' <= nibble
&& nibble
<= 'F')
365 return (nibble
- 'A' + 0xa);