3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
6 * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
41 #include <sys/types.h>
42 #include <sys/socket.h>
44 #include <bluetooth/bluetooth.h>
45 #include <bluetooth/hci.h>
46 #include <bluetooth/hci_lib.h>
47 #include <bluetooth/l2cap.h>
48 #include <bluetooth/bnep.h>
49 #include <bluetooth/hidp.h>
58 static uint16_t role = BNEP_SVC_PANU; /* Local role (ie service) */
59 static uint16_t service = BNEP_SVC_NAP; /* Remote service */
61 static int detach = 1;
63 static int use_sdp = 1;
65 static int link_mode = 0;
67 static int search_duration = 10;
75 static char netdev[16] = "bnep%d";
76 static char *pidfile = NULL;
77 static char *devupcmd = NULL;
78 static char *devdowncmd = NULL;
80 static bdaddr_t src_addr = *BDADDR_ANY;
81 static int src_dev = -1;
83 static volatile int terminate;
85 static void do_kill(char *dst);
102 static void run_script(char *script, char *dev, char *dst, int sk, int nsk)
110 if (access(script, R_OK | X_OK))
122 memset(&sa, 0, sizeof(sa));
123 sa.sa_handler = SIG_DFL;
124 sigaction(SIGCHLD, &sa, NULL);
125 sigaction(SIGPIPE, &sa, NULL);
137 /* Wait for disconnect or error condition on the socket */
138 static int w4_hup(int sk, struct script_arg *down_cmd)
145 sigdelset(&sigs, SIGCHLD);
146 sigdelset(&sigs, SIGPIPE);
147 sigdelset(&sigs, SIGTERM);
148 sigdelset(&sigs, SIGINT);
149 sigdelset(&sigs, SIGHUP);
153 pf.events = POLLERR | POLLHUP;
155 n = ppoll(&pf, 1, NULL, &sigs);
158 if (errno == EINTR || errno == EAGAIN)
161 syslog(LOG_ERR, "Poll failed. %s(%d)",
162 strerror(errno), errno);
169 socklen_t olen = sizeof(err);
171 getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &olen);
173 syslog(LOG_INFO, "%s disconnected%s%s", netdev,
174 err ? " : " : "", err ? strerror(err) : "");
177 run_script(devdowncmd,
178 down_cmd->dev, down_cmd->dst,
179 down_cmd->sk, down_cmd->nsk);
190 static int do_listen(void)
192 struct l2cap_options l2o;
193 struct sockaddr_l2 l2a;
198 bnep_sdp_register(&src_addr, role);
200 /* Create L2CAP socket and bind it to PSM BNEP */
201 sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
203 syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)",
204 strerror(errno), errno);
208 memset(&l2a, 0, sizeof(l2a));
209 l2a.l2_family = AF_BLUETOOTH;
210 bacpy(&l2a.l2_bdaddr, &src_addr);
211 l2a.l2_psm = htobs(BNEP_PSM);
213 if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) {
214 syslog(LOG_ERR, "Bind failed. %s(%d)",
215 strerror(errno), errno);
219 /* Setup L2CAP options according to BNEP spec */
220 memset(&l2o, 0, sizeof(l2o));
222 if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) {
223 syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)",
224 strerror(errno), errno);
228 l2o.imtu = l2o.omtu = BNEP_MTU;
229 if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) {
230 syslog(LOG_ERR, "Failed to set L2CAP options. %s(%d)",
231 strerror(errno), errno);
237 if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) {
238 syslog(LOG_ERR, "Failed to set link mode. %s(%d)",
239 strerror(errno), errno);
246 socklen_t alen = sizeof(l2a);
250 nsk = accept(sk, (struct sockaddr *) &l2a, &alen);
252 syslog(LOG_ERR, "Accept failed. %s(%d)",
253 strerror(errno), errno);
261 syslog(LOG_ERR, "Fork failed. %s(%d)",
262 strerror(errno), errno);
268 strncpy(devname, netdev, 16);
271 if (!bnep_accept_connection(nsk, role, devname)) {
273 struct script_arg down_cmd;
275 ba2str(&l2a.l2_bdaddr, str);
277 syslog(LOG_INFO, "New connection from %s at %s",
280 run_script(devupcmd, devname, str, sk, nsk);
282 memset(&down_cmd, 0, sizeof(struct script_arg));
283 strncpy(down_cmd.dev, devname, strlen(devname) + 1);
284 strncpy(down_cmd.dst, str, strlen(str) + 1);
287 w4_hup(nsk, &down_cmd);
289 syslog(LOG_ERR, "Connection failed. %s(%d)",
290 strerror(errno), errno);
298 bnep_sdp_unregister();
303 /* Connect and initiate BNEP session
305 * -1 - critical error (exit persist mode)
306 * 1 - non critical error
309 static int create_connection(char *dst, bdaddr_t *bdaddr)
311 struct l2cap_options l2o;
312 struct sockaddr_l2 l2a;
315 struct script_arg down_cmd;
317 syslog(LOG_INFO, "Connecting to %s", dst);
319 sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
321 syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)",
322 strerror(errno), errno);
326 /* Setup L2CAP options according to BNEP spec */
327 memset(&l2o, 0, sizeof(l2o));
329 getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen);
330 l2o.imtu = l2o.omtu = BNEP_MTU;
331 setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o));
333 memset(&l2a, 0, sizeof(l2a));
334 l2a.l2_family = AF_BLUETOOTH;
335 bacpy(&l2a.l2_bdaddr, &src_addr);
337 if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)))
338 syslog(LOG_ERR, "Bind failed. %s(%d)",
339 strerror(errno), errno);
341 memset(&l2a, 0, sizeof(l2a));
342 l2a.l2_family = AF_BLUETOOTH;
343 bacpy(&l2a.l2_bdaddr, bdaddr);
344 l2a.l2_psm = htobs(BNEP_PSM);
346 if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) &&
347 !bnep_create_connection(sk, role, service, netdev)) {
349 syslog(LOG_INFO, "%s connected", netdev);
351 run_script(devupcmd, netdev, dst, sk, -1);
353 if (persist || devdowncmd) {
354 memset(&down_cmd, 0, sizeof(struct script_arg));
355 strncpy(down_cmd.dev, netdev, strlen(netdev) + 1);
356 strncpy(down_cmd.dst, dst, strlen(dst) + 1);
359 w4_hup(sk, &down_cmd);
361 if (terminate && cleanup) {
362 syslog(LOG_INFO, "Disconnecting from %s.", dst);
369 syslog(LOG_ERR, "Connect to %s failed. %s(%d)",
370 dst, strerror(errno), errno);
378 /* Succesesful connection, validate cache */
379 strcpy(cache.dst, dst);
380 bacpy(&cache.bdaddr, bdaddr);
381 cache.valid = use_cache;
389 /* Search and connect
391 * -1 - critical error (exit persist mode)
392 * 1 - non critical error
395 static int do_connect(void)
406 if (cache.valid > 0) {
407 /* Use cached bdaddr */
408 r = create_connection(cache.dst, &cache.bdaddr);
416 syslog(LOG_INFO, "Inquiring");
418 /* FIXME: Should we use non general LAP here ? */
421 n = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0);
423 syslog(LOG_ERR, "Inquiry failed. %s(%d)",
424 strerror(errno), errno);
428 for (i = 0; i < n; i++) {
430 ba2str(&ii[i].bdaddr, dst);
433 syslog(LOG_INFO, "Searching for %s on %s",
434 bnep_svc2str(service), dst);
436 if (bnep_sdp_search(&src_addr, &ii[i].bdaddr, service) <= 0)
440 r = create_connection(dst, &ii[i].bdaddr);
447 } while (!terminate && persist);
452 static void do_show(void)
454 bnep_show_connections();
457 static void do_kill(char *dst)
460 bdaddr_t *ba = strtoba(dst);
461 bnep_kill_connection((void *) ba);
464 bnep_kill_all_connections();
468 static void sig_hup(int sig)
473 static void sig_term(int sig)
478 static int write_pidfile(void)
485 fd = open(pidfile, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, 0644);
487 /* Try to open the file for read. */
488 fd = open(pidfile, O_RDONLY);
490 syslog(LOG_ERR, "Could not read old pidfile: %s(%d)",
491 strerror(errno), errno);
495 /* We're already running; send a SIGHUP (we presume that they
496 * are calling ifup for a reason, so they probably want to
497 * rescan) and then exit cleanly and let things go on in the
498 * background. Muck with the filename so that we don't go
499 * deleting the pid file for the already-running instance.
503 syslog(LOG_ERR, "Could not fdopen old pidfile: %s(%d)",
504 strerror(errno), errno);
510 if (fscanf(f, "%d", &pid) != 1)
515 /* Try to kill it. */
516 if (kill(pid, SIGHUP) == -1) {
517 /* No such pid; remove the bogus pid file. */
518 syslog(LOG_INFO, "Removing stale pidfile");
522 /* Got it. Don't mess with the pid file on
524 syslog(LOG_INFO, "Signalling existing process %d and exiting\n", pid);
534 syslog(LOG_ERR, "Could not fdopen new pidfile: %s(%d)",
535 strerror(errno), errno);
541 fprintf(f, "%d\n", getpid());
547 static struct option main_lopts[] = {
548 { "help", 0, 0, 'h' },
549 { "listen", 0, 0, 's' },
550 { "connect", 1, 0, 'c' },
551 { "search", 2, 0, 'Q' },
552 { "kill", 1, 0, 'k' },
553 { "killall", 0, 0, 'K' },
554 { "role", 1, 0, 'r' },
555 { "service", 1, 0, 'd' },
556 { "ethernet", 1, 0, 'e' },
557 { "device", 1, 0, 'i' },
558 { "nosdp", 0, 0, 'D' },
559 { "list", 0, 0, 'l' },
560 { "show", 0, 0, 'l' },
561 { "nodetach", 0, 0, 'n' },
562 { "persist", 2, 0, 'p' },
563 { "auth", 0, 0, 'A' },
564 { "encrypt", 0, 0, 'E' },
565 { "secure", 0, 0, 'S' },
566 { "master", 0, 0, 'M' },
567 { "cache", 0, 0, 'C' },
568 { "pidfile", 1, 0, 'P' },
569 { "devup", 1, 0, 'u' },
570 { "devdown", 1, 0, 'o' },
571 { "autozap", 0, 0, 'z' },
575 static const char *main_sopts = "hsc:k:Kr:d:e:i:lnp::DQ::AESMC::P:u:o:z";
577 static const char *main_help =
578 "Bluetooth PAN daemon version %s\n"
582 "\t--show --list -l Show active PAN connections\n"
583 "\t--listen -s Listen for PAN connections\n"
584 "\t--connect -c <bdaddr> Create PAN connection\n"
585 "\t--autozap -z Disconnect automatically on exit\n"
586 "\t--search -Q[duration] Search and connect\n"
587 "\t--kill -k <bdaddr> Kill PAN connection\n"
588 "\t--killall -K Kill all PAN connections\n"
589 "\t--role -r <role> Local PAN role (PANU, NAP, GN)\n"
590 "\t--service -d <role> Remote PAN service (PANU, NAP, GN)\n"
591 "\t--ethernet -e <name> Network interface name\n"
592 "\t--device -i <bdaddr> Source bdaddr\n"
593 "\t--nosdp -D Disable SDP\n"
594 "\t--auth -A Enable authentication\n"
595 "\t--encrypt -E Enable encryption\n"
596 "\t--secure -S Secure connection\n"
597 "\t--master -M Become the master of a piconet\n"
598 "\t--nodetach -n Do not become a daemon\n"
599 "\t--persist -p[interval] Persist mode\n"
600 "\t--cache -C[valid] Cache addresses\n"
601 "\t--pidfile -P <pidfile> Create PID file\n"
602 "\t--devup -u <script> Script to run when interface comes up\n"
603 "\t--devdown -o <script> Script to run when interface comes down\n";
605 int main(int argc, char *argv[])
607 char *dst = NULL, *src = NULL;
612 while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) {
625 dst = strdup(optarg);
631 search_duration = atoi(optarg);
637 dst = strdup(optarg);
646 src = strdup(optarg);
650 bnep_str2svc(optarg, &role);
654 bnep_str2svc(optarg, &service);
662 link_mode |= L2CAP_LM_AUTH;
666 link_mode |= L2CAP_LM_ENCRYPT;
670 link_mode |= L2CAP_LM_SECURE;
674 link_mode |= L2CAP_LM_MASTER;
678 strncpy(netdev, optarg, 16);
688 persist = atoi(optarg);
695 use_cache = atoi(optarg);
701 pidfile = strdup(optarg);
705 devupcmd = strdup(optarg);
709 devdowncmd = strdup(optarg);
718 printf(main_help, VERSION);
732 /* Check non daemon modes first */
745 printf(main_help, VERSION);
750 /* Initialize signals */
751 memset(&sa, 0, sizeof(sa));
752 sa.sa_flags = SA_NOCLDSTOP;
753 sa.sa_handler = SIG_IGN;
754 sigaction(SIGCHLD, &sa, NULL);
755 sigaction(SIGPIPE, &sa, NULL);
757 sa.sa_handler = sig_hup;
758 sigaction(SIGHUP, &sa, NULL);
760 sa.sa_handler = sig_term;
761 sigaction(SIGTERM, &sa, NULL);
762 sigaction(SIGINT, &sa, NULL);
764 if (detach && daemon(0, 0)) {
765 perror("Can't start daemon");
769 openlog("pand", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
770 syslog(LOG_INFO, "Bluetooth PAN daemon version %s", VERSION);
773 src_dev = hci_devid(src);
774 if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) {
775 syslog(LOG_ERR, "Invalid source. %s(%d)",
776 strerror(errno), errno);
782 if (pidfile && write_pidfile()) {
788 /* Disable cache invalidation */
791 strncpy(cache.dst, dst, sizeof(cache.dst) - 1);
792 str2ba(dst, &cache.bdaddr);