3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
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.
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.
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
37 #include <sys/ioctl.h>
38 #include <sys/socket.h>
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>
52 static volatile sig_atomic_t __io_canceled = 0;
54 static void sig_hup(int sig)
59 static void sig_term(int sig)
64 static char *cmtp_state[] = {
77 static char *cmtp_flagstostr(uint32_t flags)
79 static char str[100] = "";
83 if (flags & (1 << CMTP_LOOPBACK))
84 strcat(str, "loopback");
91 static int get_psm(bdaddr_t *src, bdaddr_t *dst, unsigned short *psm)
94 sdp_list_t *srch, *attrs, *rsp;
99 if (!(s = sdp_connect(src, dst, 0)))
102 sdp_uuid16_create(&svclass, CIP_SVCLASS_ID);
103 srch = sdp_list_append(NULL, &svclass);
105 attr = SDP_ATTR_PROTO_DESC_LIST;
106 attrs = sdp_list_append(NULL, &attr);
108 err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
115 for (; rsp; rsp = rsp->next) {
116 sdp_record_t *rec = (sdp_record_t *) rsp->data;
119 if (!sdp_get_access_protos(rec, &protos)) {
120 unsigned short p = sdp_get_proto_port(protos, L2CAP_UUID);
131 static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigned short psm, uint32_t flags)
133 struct cmtp_connadd_req req;
134 struct hci_dev_info di;
135 struct sockaddr_l2 addr;
136 struct l2cap_options opts;
140 hci_devinfo(dev_id, &di);
141 if (!(di.link_policy & HCI_LP_RSWITCH)) {
142 printf("Local device is not accepting role switch\n");
145 if ((sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) {
146 perror("Can't create L2CAP socket");
150 memset(&addr, 0, sizeof(addr));
151 addr.l2_family = AF_BLUETOOTH;
152 bacpy(&addr.l2_bdaddr, src);
154 if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
155 perror("Can't bind L2CAP socket");
160 memset(&opts, 0, sizeof(opts));
163 if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) {
164 perror("Can't get L2CAP options");
169 opts.imtu = CMTP_DEFAULT_MTU;
170 opts.omtu = CMTP_DEFAULT_MTU;
171 opts.flush_to = 0xffff;
173 if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) {
174 perror("Can't set L2CAP options");
179 memset(&addr, 0, sizeof(addr));
180 addr.l2_family = AF_BLUETOOTH;
181 bacpy(&addr.l2_bdaddr, dst);
182 addr.l2_psm = htobs(psm);
184 if (connect(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
185 perror("Can't connect L2CAP socket");
193 if (ioctl(ctl, CMTPCONNADD, &req) < 0) {
194 perror("Can't create connection");
201 static void cmd_show(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
203 struct cmtp_connlist_req req;
204 struct cmtp_conninfo ci[16];
211 if (ioctl(ctl, CMTPGETCONNLIST, &req) < 0) {
212 perror("Can't get connection list");
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) : "");
224 static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
226 inquiry_info *info = NULL;
229 int i, dev_id, num_rsp, length, flags;
233 ba2str(bdaddr, addr);
234 dev_id = hci_devid(addr);
236 dev_id = hci_get_route(NULL);
237 hci_devba(dev_id, &src);
241 length = 8; /* ~10 seconds */
245 printf("Searching ...\n");
247 num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags);
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);
255 printf("\tChecking service for %s\n", addr);
256 if (!get_psm(&src, &dst, &psm))
261 printf("\tConnecting to device %s\n", addr);
262 do_connect(ctl, dev_id, &src, &dst, psm, 0);
268 fprintf(stderr, "\tNo devices in range or visible\n");
272 static void cmd_create(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
282 str2ba(argv[1], &dst);
284 ba2str(bdaddr, addr);
285 dev_id = hci_devid(addr);
287 dev_id = hci_get_route(&dst);
288 hci_devba(dev_id, &src);
293 if (!get_psm(&src, &dst, &psm))
298 do_connect(ctl, dev_id, &src, &dst, psm, 0);
301 static void cmd_release(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
303 struct cmtp_conndel_req req;
304 struct cmtp_connlist_req cl;
305 struct cmtp_conninfo ci[16];
311 if (ioctl(ctl, CMTPGETCONNLIST, &cl) < 0) {
312 perror("Can't get connection list");
320 fprintf(stderr, "You have to specifiy the device address.\n");
324 bacpy(&req.bdaddr, &ci[0].bdaddr);
326 str2ba(argv[1], &req.bdaddr);
328 if (ioctl(ctl, CMTPCONNDEL, &req) < 0) {
329 perror("Can't release connection");
334 static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv)
336 struct cmtp_conndel_req req;
348 str2ba(argv[1], &dst);
350 ba2str(bdaddr, addr);
351 dev_id = hci_devid(addr);
353 dev_id = hci_get_route(&dst);
354 hci_devba(dev_id, &src);
359 printf("Connecting to %s in loopback mode\n", addr);
362 if (!get_psm(&src, &dst, &psm))
367 sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK));
369 printf("Press CTRL-C for hangup\n");
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);
377 sa.sa_handler = sig_term;
378 sigaction(SIGTERM, &sa, NULL);
379 sigaction(SIGINT, &sa, NULL);
381 sa.sa_handler = sig_hup;
382 sigaction(SIGHUP, &sa, NULL);
385 sigdelset(&sigs, SIGCHLD);
386 sigdelset(&sigs, SIGPIPE);
387 sigdelset(&sigs, SIGTERM);
388 sigdelset(&sigs, SIGINT);
389 sigdelset(&sigs, SIGHUP);
392 p.events = POLLERR | POLLHUP;
394 while (!__io_canceled) {
396 if (ppoll(&p, 1, NULL, &sigs) > 0)
400 bacpy(&req.bdaddr, &dst);
401 ioctl(ctl, CMTPCONNDEL, &req);
407 void (*func)(int ctl, bdaddr_t *bdaddr, int argc, char **argv);
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 }
419 static void usage(void)
423 printf("ciptool - Bluetooth Common ISDN Access Profile (CIP)\n\n");
426 "\tciptool [options] [command]\n"
430 "\t-i [hciX|bdaddr] Local HCI device or BD Address\n"
431 "\t-h, --help Display help\n"
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 : " ",
442 static struct option main_options[] = {
443 { "help", 0, 0, 'h' },
444 { "device", 1, 0, 'i' },
448 int main(int argc, char *argv[])
453 bacpy(&bdaddr, BDADDR_ANY);
455 while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
458 if (!strncmp(optarg, "hci", 3))
459 hci_devba(atoi(optarg + 3), &bdaddr);
461 str2ba(optarg, &bdaddr);
480 if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_CMTP)) < 0 ) {
481 perror("Can't open CMTP control socket");
485 for (i = 0; command[i].cmd; i++) {
486 if (strncmp(command[i].cmd, argv[0], 4) && strncmp(command[i].alt, argv[0], 4))
488 command[i].func(ctl, &bdaddr, argc, argv);