1 /* $NetBSD: btdevctl.c,v 1.7 2008/07/21 13:36:57 lukem Exp $ */
4 * Copyright (c) 2006 Itronix Inc.
7 * Written by Iain Hibbert for Itronix Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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 * 3. The name of Itronix Inc. may not be used to endorse
18 * or promote products derived from this software without specific
19 * prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 __COPYRIGHT("@(#) Copyright (c) 2006 The NetBSD Foundation, Inc.\
36 @(#) Copyright (c) 2006 Itronix, Inc.\
37 All rights reserved.");
38 __RCSID("$NetBSD: btdevctl.c,v 1.7 2008/07/21 13:36:57 lukem Exp $");
40 #include <prop/proplib.h>
41 #include <sys/ioctl.h>
43 #include <bluetooth.h>
51 #include <dev/bluetooth/btdev.h>
55 #define BTHUB_PATH "/dev/bthub"
57 int main(int, char *[]);
59 char *uppercase(const char *);
60 int bthub_pioctl(unsigned long, prop_dictionary_t
);
63 main(int argc
, char *argv
[])
65 prop_dictionary_t dev
;
67 bdaddr_t laddr
, raddr
;
68 const char *service
, *mode
;
69 int ch
, query
, verbose
, attach
, detach
, set
, none
;
71 bdaddr_copy(&laddr
, BDADDR_ANY
);
72 bdaddr_copy(&raddr
, BDADDR_ANY
);
82 while ((ch
= getopt(argc
, argv
, "Aa:Dd:hm:qs:v")) != -1) {
84 case 'A': /* Attach device */
88 case 'a': /* remote address */
89 if (!bt_aton(optarg
, &raddr
)) {
90 struct hostent
*he
= NULL
;
92 if ((he
= bt_gethostbyname(optarg
)) == NULL
)
93 errx(EXIT_FAILURE
, "%s: %s",
94 optarg
, hstrerror(h_errno
));
96 bdaddr_copy(&raddr
, (bdaddr_t
*)he
->h_addr
);
100 case 'D': /* Detach device */
104 case 'd': /* local device address */
105 if (!bt_devaddr(optarg
, &laddr
))
106 err(EXIT_FAILURE
, "%s", optarg
);
110 case 'm': /* link mode */
111 if (strcasecmp(optarg
, "none") == 0)
113 else if (strcasecmp(optarg
, BTDEVauth
) == 0)
115 else if (strcasecmp(optarg
, BTDEVencrypt
) == 0)
117 else if (strcasecmp(optarg
, BTDEVsecure
) == 0)
120 errx(EXIT_FAILURE
, "%s: unknown mode", optarg
);
128 case 's': /* service */
129 service
= uppercase(optarg
);
132 case 'v': /* verbose */
146 || (attach
== true && detach
== true)
147 || bdaddr_any(&laddr
)
148 || bdaddr_any(&raddr
)
152 if (attach
== false && detach
== false)
155 dev
= db_get(&laddr
, &raddr
, service
);
156 if (dev
== NULL
|| query
== true) {
158 printf("Performing SDP query for service '%s'..\n", service
);
160 dev
= cfg_query(&laddr
, &raddr
, service
);
162 errx(EXIT_FAILURE
, "%s/%s not found", bt_ntoa(&raddr
, NULL
), service
);
168 obj
= prop_string_create_cstring_nocopy(mode
);
169 if (obj
== NULL
|| !prop_dictionary_set(dev
, BTDEVmode
, obj
))
170 errx(EXIT_FAILURE
, "proplib failure (%s)", BTDEVmode
);
172 prop_object_release(obj
);
177 prop_dictionary_remove(dev
, BTDEVmode
);
181 if (set
== true && !db_set(dev
, &laddr
, &raddr
, service
))
182 errx(EXIT_FAILURE
, "service store failed");
184 /* add binary local-bdaddr */
185 obj
= prop_data_create_data(&laddr
, sizeof(laddr
));
186 if (obj
== NULL
|| !prop_dictionary_set(dev
, BTDEVladdr
, obj
))
187 errx(EXIT_FAILURE
, "proplib failure (%s)", BTDEVladdr
);
189 prop_object_release(obj
);
191 /* add binary remote-bdaddr */
192 obj
= prop_data_create_data(&raddr
, sizeof(raddr
));
193 if (obj
== NULL
|| !prop_dictionary_set(dev
, BTDEVraddr
, obj
))
194 errx(EXIT_FAILURE
, "proplib failure (%s)", BTDEVraddr
);
196 prop_object_release(obj
);
198 /* add service name */
199 obj
= prop_string_create_cstring(service
);
200 if (obj
== NULL
|| !prop_dictionary_set(dev
, BTDEVservice
, obj
))
201 errx(EXIT_FAILURE
, "proplib failure (%s)", BTDEVservice
);
203 prop_object_release(obj
);
209 bthub_pioctl(BTDEV_ATTACH
, dev
);
212 bthub_pioctl(BTDEV_DETACH
, dev
);
222 "usage: %s [-A | -D] [-qv] [-m mode] -a address -d device -s service\n"
224 "\t-A attach device\n"
225 "\t-a address remote device address\n"
226 "\t-D detach device\n"
227 "\t-d device local device address\n"
228 "\t-m mode link mode\n"
229 "\t-q force SDP query\n"
230 "\t-s service remote service\n"
238 uppercase(const char *arg
)
244 err(EXIT_FAILURE
, "strdup");
246 for (ptr
= str
; *ptr
; ptr
++)
247 *ptr
= (char)toupper((int)*ptr
);
253 bthub_pioctl(unsigned long cmd
, prop_dictionary_t dict
)
257 fd
= open(BTHUB_PATH
, O_WRONLY
, 0);
259 err(EXIT_FAILURE
, "%s", BTHUB_PATH
);
261 if (prop_dictionary_send_ioctl(dict
, fd
, cmd
))
262 err(EXIT_FAILURE
, "%s", BTHUB_PATH
);