1/* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24#ifdef HAVE_CONFIG_H 25#include <config.h> 26#endif 27 28#define _GNU_SOURCE 29#include <stdio.h> 30#include <errno.h> 31#include <stdlib.h> 32#include <unistd.h> 33#include <string.h> 34#include <getopt.h> 35#include <signal.h> 36#include <sys/poll.h> 37#include <sys/ioctl.h> 38#include <sys/socket.h> 39 40#include <bluetooth/bluetooth.h> 41#include <bluetooth/hci.h> 42#include <bluetooth/hci_lib.h> 43#include <bluetooth/l2cap.h> 44#include <bluetooth/sdp.h> 45#include <bluetooth/sdp_lib.h> 46#include <bluetooth/cmtp.h> 47 48#ifdef NEED_PPOLL 49#include "ppoll.h" 50#endif 51 52static volatile sig_atomic_t __io_canceled = 0; 53 54static void sig_hup(int sig) 55{ 56 return; 57} 58 59static void sig_term(int sig) 60{ 61 __io_canceled = 1; 62} 63 64static char *cmtp_state[] = { 65 "unknown", 66 "connected", 67 "open", 68 "bound", 69 "listening", 70 "connecting", 71 "connecting", 72 "config", 73 "disconnecting", 74 "closed" 75}; 76 77static char *cmtp_flagstostr(uint32_t flags) 78{ 79 static char str[100] = ""; 80 81 strcat(str, "["); 82 83 if (flags & (1 << CMTP_LOOPBACK)) 84 strcat(str, "loopback"); 85 86 strcat(str, "]"); 87 88 return str; 89} 90 91static int get_psm(bdaddr_t *src, bdaddr_t *dst, unsigned short *psm) 92{ 93 sdp_session_t *s; 94 sdp_list_t *srch, *attrs, *rsp; 95 uuid_t svclass; 96 uint16_t attr; 97 int err; 98 99 if (!(s = sdp_connect(src, dst, 0))) 100 return -1; 101 102 sdp_uuid16_create(&svclass, CIP_SVCLASS_ID); 103 srch = sdp_list_append(NULL, &svclass); 104 105 attr = SDP_ATTR_PROTO_DESC_LIST; 106 attrs = sdp_list_append(NULL, &attr); 107 108 err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); 109 110 sdp_close(s); 111 112 if (err) 113 return 0; 114 115 for (; rsp; rsp = rsp->next) { 116 sdp_record_t *rec = (sdp_record_t *) rsp->data; 117 sdp_list_t *protos; 118 119 if (!sdp_get_access_protos(rec, &protos)) { 120 unsigned short p = sdp_get_proto_port(protos, L2CAP_UUID); 121 if (p > 0) { 122 *psm = p; 123 return 1; 124 } 125 } 126 } 127 128 return 0; 129} 130 131static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigned short psm, uint32_t flags) 132{ 133 struct cmtp_connadd_req req; 134 struct hci_dev_info di; 135 struct sockaddr_l2 addr; 136 struct l2cap_options opts; 137 socklen_t size; 138 int sk; 139 140 hci_devinfo(dev_id, &di); 141 if (!(di.link_policy & HCI_LP_RSWITCH)) { 142 printf("Local device is not accepting role switch\n"); 143 } 144 145 if ((sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { 146 perror("Can't create L2CAP socket"); 147 exit(1); 148 } 149 150 memset(&addr, 0, sizeof(addr)); 151 addr.l2_family = AF_BLUETOOTH; 152 bacpy(&addr.l2_bdaddr, src); 153 154 if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 155 perror("Can't bind L2CAP socket"); 156 close(sk); 157 exit(1); 158 } 159 160 memset(&opts, 0, sizeof(opts)); 161 size = sizeof(opts); 162 163 if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) { 164 perror("Can't get L2CAP options"); 165 close(sk); 166 exit(1); 167 } 168 169 opts.imtu = CMTP_DEFAULT_MTU; 170 opts.omtu = CMTP_DEFAULT_MTU; 171 opts.flush_to = 0xffff; 172 173 if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { 174 perror("Can't set L2CAP options"); 175 close(sk); 176 exit(1); 177 } 178 179 memset(&addr, 0, sizeof(addr)); 180 addr.l2_family = AF_BLUETOOTH; 181 bacpy(&addr.l2_bdaddr, dst); 182 addr.l2_psm = htobs(psm); 183 184 if (connect(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 185 perror("Can't connect L2CAP socket"); 186 close(sk); 187 exit(1); 188 } 189 190 req.sock = sk; 191 req.flags = flags; 192 193 if (ioctl(ctl, CMTPCONNADD, &req) < 0) { 194 perror("Can't create connection"); 195 exit(1); 196 } 197 198 return sk; 199} 200 201static void cmd_show(int ctl, bdaddr_t *bdaddr, int argc, char **argv) 202{ 203 struct cmtp_connlist_req req; 204 struct cmtp_conninfo ci[16]; 205 char addr[18]; 206 unsigned int i; 207 208 req.cnum = 16; 209 req.ci = ci; 210 211 if (ioctl(ctl, CMTPGETCONNLIST, &req) < 0) { 212 perror("Can't get connection list"); 213 exit(1); 214 } 215 216 for (i = 0; i < req.cnum; i++) { 217 ba2str(&ci[i].bdaddr, addr); 218 printf("%d %s %s %s\n", ci[i].num, addr, 219 cmtp_state[ci[i].state], 220 ci[i].flags ? cmtp_flagstostr(ci[i].flags) : ""); 221 } 222} 223 224static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv) 225{ 226 inquiry_info *info = NULL; 227 bdaddr_t src, dst; 228 unsigned short psm; 229 int i, dev_id, num_rsp, length, flags; 230 char addr[18]; 231 uint8_t class[3]; 232 233 ba2str(bdaddr, addr); 234 dev_id = hci_devid(addr); 235 if (dev_id < 0) { 236 dev_id = hci_get_route(NULL); 237 hci_devba(dev_id, &src); 238 } else 239 bacpy(&src, bdaddr); 240 241 length = 8; /* ~10 seconds */ 242 num_rsp = 0; 243 flags = 0; 244 245 printf("Searching ...\n"); 246 247 num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); 248 249 for (i = 0; i < num_rsp; i++) { 250 memcpy(class, (info+i)->dev_class, 3); 251 if ((class[1] == 2) && ((class[0] / 4) == 5)) { 252 bacpy(&dst, &(info+i)->bdaddr); 253 ba2str(&dst, addr); 254 255 printf("\tChecking service for %s\n", addr); 256 if (!get_psm(&src, &dst, &psm)) 257 continue; 258 259 bt_free(info); 260 261 printf("\tConnecting to device %s\n", addr); 262 do_connect(ctl, dev_id, &src, &dst, psm, 0); 263 return; 264 } 265 } 266 267 bt_free(info); 268 fprintf(stderr, "\tNo devices in range or visible\n"); 269 exit(1); 270} 271 272static void cmd_create(int ctl, bdaddr_t *bdaddr, int argc, char **argv) 273{ 274 bdaddr_t src, dst; 275 unsigned short psm; 276 int dev_id; 277 char addr[18]; 278 279 if (argc < 2) 280 return; 281 282 str2ba(argv[1], &dst); 283 284 ba2str(bdaddr, addr); 285 dev_id = hci_devid(addr); 286 if (dev_id < 0) { 287 dev_id = hci_get_route(&dst); 288 hci_devba(dev_id, &src); 289 } else 290 bacpy(&src, bdaddr); 291 292 if (argc < 3) { 293 if (!get_psm(&src, &dst, &psm)) 294 psm = 4099; 295 } else 296 psm = atoi(argv[2]); 297 298 do_connect(ctl, dev_id, &src, &dst, psm, 0); 299} 300 301static void cmd_release(int ctl, bdaddr_t *bdaddr, int argc, char **argv) 302{ 303 struct cmtp_conndel_req req; 304 struct cmtp_connlist_req cl; 305 struct cmtp_conninfo ci[16]; 306 307 if (argc < 2) { 308 cl.cnum = 16; 309 cl.ci = ci; 310 311 if (ioctl(ctl, CMTPGETCONNLIST, &cl) < 0) { 312 perror("Can't get connection list"); 313 exit(1); 314 } 315 316 if (cl.cnum == 0) 317 return; 318 319 if (cl.cnum != 1) { 320 fprintf(stderr, "You have to specifiy the device address.\n"); 321 exit(1); 322 } 323 324 bacpy(&req.bdaddr, &ci[0].bdaddr); 325 } else 326 str2ba(argv[1], &req.bdaddr); 327 328 if (ioctl(ctl, CMTPCONNDEL, &req) < 0) { 329 perror("Can't release connection"); 330 exit(1); 331 } 332} 333 334static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) 335{ 336 struct cmtp_conndel_req req; 337 struct sigaction sa; 338 struct pollfd p; 339 sigset_t sigs; 340 bdaddr_t src, dst; 341 unsigned short psm; 342 int dev_id, sk; 343 char addr[18]; 344 345 if (argc < 2) 346 return; 347 348 str2ba(argv[1], &dst); 349 350 ba2str(bdaddr, addr); 351 dev_id = hci_devid(addr); 352 if (dev_id < 0) { 353 dev_id = hci_get_route(&dst); 354 hci_devba(dev_id, &src); 355 } else 356 bacpy(&src, bdaddr); 357 358 ba2str(&dst, addr); 359 printf("Connecting to %s in loopback mode\n", addr); 360 361 if (argc < 3) { 362 if (!get_psm(&src, &dst, &psm)) 363 psm = 4099; 364 } else 365 psm = atoi(argv[2]); 366 367 sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK)); 368 369 printf("Press CTRL-C for hangup\n"); 370 371 memset(&sa, 0, sizeof(sa)); 372 sa.sa_flags = SA_NOCLDSTOP; 373 sa.sa_handler = SIG_IGN; 374 sigaction(SIGCHLD, &sa, NULL); 375 sigaction(SIGPIPE, &sa, NULL); 376 377 sa.sa_handler = sig_term; 378 sigaction(SIGTERM, &sa, NULL); 379 sigaction(SIGINT, &sa, NULL); 380 381 sa.sa_handler = sig_hup; 382 sigaction(SIGHUP, &sa, NULL); 383 384 sigfillset(&sigs); 385 sigdelset(&sigs, SIGCHLD); 386 sigdelset(&sigs, SIGPIPE); 387 sigdelset(&sigs, SIGTERM); 388 sigdelset(&sigs, SIGINT); 389 sigdelset(&sigs, SIGHUP); 390 391 p.fd = sk; 392 p.events = POLLERR | POLLHUP; 393 394 while (!__io_canceled) { 395 p.revents = 0; 396 if (ppoll(&p, 1, NULL, &sigs) > 0) 397 break; 398 } 399 400 bacpy(&req.bdaddr, &dst); 401 ioctl(ctl, CMTPCONNDEL, &req); 402} 403 404static struct { 405 char *cmd; 406 char *alt; 407 void (*func)(int ctl, bdaddr_t *bdaddr, int argc, char **argv); 408 char *opt; 409 char *doc; 410} command[] = { 411 { "show", "list", cmd_show, 0, "Show remote connections" }, 412 { "search", "scan", cmd_search, 0, "Search for a remote device" }, 413 { "connect", "create", cmd_create, "<bdaddr>", "Connect a remote device" }, 414 { "release", "disconnect", cmd_release, "[bdaddr]", "Disconnect the remote device" }, 415 { "loopback", "test", cmd_loopback, "<bdaddr>", "Loopback test of a device" }, 416 { NULL, NULL, NULL, 0, 0 } 417}; 418 419static void usage(void) 420{ 421 int i; 422 423 printf("ciptool - Bluetooth Common ISDN Access Profile (CIP)\n\n"); 424 425 printf("Usage:\n" 426 "\tciptool [options] [command]\n" 427 "\n"); 428 429 printf("Options:\n" 430 "\t-i [hciX|bdaddr] Local HCI device or BD Address\n" 431 "\t-h, --help Display help\n" 432 "\n"); 433 434 printf("Commands:\n"); 435 for (i = 0; command[i].cmd; i++) 436 printf("\t%-8s %-10s\t%s\n", command[i].cmd, 437 command[i].opt ? command[i].opt : " ", 438 command[i].doc); 439 printf("\n"); 440} 441 442static struct option main_options[] = { 443 { "help", 0, 0, 'h' }, 444 { "device", 1, 0, 'i' }, 445 { 0, 0, 0, 0 } 446}; 447 448int main(int argc, char *argv[]) 449{ 450 bdaddr_t bdaddr; 451 int i, opt, ctl; 452 453 bacpy(&bdaddr, BDADDR_ANY); 454 455 while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { 456 switch(opt) { 457 case 'i': 458 if (!strncmp(optarg, "hci", 3)) 459 hci_devba(atoi(optarg + 3), &bdaddr); 460 else 461 str2ba(optarg, &bdaddr); 462 break; 463 case 'h': 464 usage(); 465 exit(0); 466 default: 467 exit(0); 468 } 469 } 470 471 argc -= optind; 472 argv += optind; 473 optind = 0; 474 475 if (argc < 1) { 476 usage(); 477 return 0; 478 } 479 480 if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_CMTP)) < 0 ) { 481 perror("Can't open CMTP control socket"); 482 exit(1); 483 } 484 485 for (i = 0; command[i].cmd; i++) { 486 if (strncmp(command[i].cmd, argv[0], 4) && strncmp(command[i].alt, argv[0], 4)) 487 continue; 488 command[i].func(ctl, &bdaddr, argc, argv); 489 close(ctl); 490 exit(0); 491 } 492 493 usage(); 494 495 close(ctl); 496 497 return 0; 498} 499