OSDN Git Service

Remove obsolete LOCAL_MODULE_TAGS
[android-x86/external-bluetooth-bluez.git] / tools / btmgmt.c
1 /*
2  *  BlueZ - Bluetooth protocol stack for Linux
3  *
4  *  Copyright (C) 2011  Intel Corporation. All rights reserved.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/socket.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <poll.h>
38 #include <getopt.h>
39 #include <stdbool.h>
40 #include <wordexp.h>
41 #include <ctype.h>
42
43 #include <readline/readline.h>
44 #include <readline/history.h>
45
46 #include "lib/bluetooth.h"
47 #include "lib/hci.h"
48 #include "lib/hci_lib.h"
49 #include "lib/sdp.h"
50 #include "lib/sdp_lib.h"
51
52 #include "src/uuid-helper.h"
53 #include "lib/mgmt.h"
54
55 #include "client/display.h"
56 #include "src/shared/mainloop.h"
57 #include "src/shared/io.h"
58 #include "src/shared/util.h"
59 #include "src/shared/mgmt.h"
60
61 #define SCAN_TYPE_BREDR (1 << BDADDR_BREDR)
62 #define SCAN_TYPE_LE ((1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM))
63 #define SCAN_TYPE_DUAL (SCAN_TYPE_BREDR | SCAN_TYPE_LE)
64
65 static struct mgmt *mgmt = NULL;
66 static uint16_t mgmt_index = MGMT_INDEX_NONE;
67
68 static bool discovery = false;
69 static bool resolve_names = true;
70 static bool interactive = false;
71
72 static char *saved_prompt = NULL;
73 static int saved_point = 0;
74
75 static struct {
76         uint16_t index;
77         uint16_t req;
78         struct mgmt_addr_info addr;
79 } prompt = {
80         .index = MGMT_INDEX_NONE,
81 };
82
83 static int pending_index = 0;
84
85 #ifndef MIN
86 #define MIN(x, y) ((x) < (y) ? (x) : (y))
87 #endif
88
89 #define PROMPT_ON       COLOR_BLUE "[mgmt]" COLOR_OFF "# "
90
91 static void update_prompt(uint16_t index)
92 {
93         char str[32];
94
95         if (index == MGMT_INDEX_NONE)
96                 snprintf(str, sizeof(str), "%s# ",
97                                         COLOR_BLUE "[mgmt]" COLOR_OFF);
98         else
99                 snprintf(str, sizeof(str),
100                                 COLOR_BLUE "[hci%u]" COLOR_OFF "# ", index);
101
102         if (saved_prompt) {
103                 free(saved_prompt);
104                 saved_prompt = strdup(str);
105                 return;
106         }
107
108         rl_set_prompt(str);
109 }
110
111 static void noninteractive_quit(int status)
112 {
113         if (interactive)
114                 return;
115
116         if (status == EXIT_SUCCESS)
117                 mainloop_exit_success();
118         else
119                 mainloop_exit_failure();
120 }
121
122 #define print(fmt, arg...) do { \
123         if (interactive) \
124                 rl_printf(fmt "\n", ## arg); \
125         else \
126                 printf(fmt "\n", ## arg); \
127 } while (0)
128
129 #define error(fmt, arg...) do { \
130         if (interactive) \
131                 rl_printf(COLOR_RED fmt "\n" COLOR_OFF, ## arg); \
132         else \
133                 fprintf(stderr, fmt "\n", ## arg); \
134 } while (0)
135
136 static size_t hex2bin(const char *hexstr, uint8_t *buf, size_t buflen)
137 {
138         size_t i, len;
139
140         len = MIN((strlen(hexstr) / 2), buflen);
141         memset(buf, 0, len);
142
143         for (i = 0; i < len; i++)
144                 sscanf(hexstr + (i * 2), "%02hhX", &buf[i]);
145
146         return len;
147 }
148
149 static size_t bin2hex(const uint8_t *buf, size_t buflen, char *str,
150                                                                 size_t strlen)
151 {
152         size_t i;
153
154         for (i = 0; i < buflen && i < (strlen / 2); i++)
155                 sprintf(str + (i * 2), "%02x", buf[i]);
156
157         return i;
158 }
159
160 static void print_eir(const uint8_t *eir, uint16_t eir_len)
161 {
162         uint16_t parsed = 0;
163         char str[33];
164
165         while (parsed < eir_len - 1) {
166                 uint8_t field_len = eir[0];
167
168                 if (field_len == 0)
169                         break;
170
171                 parsed += field_len + 1;
172
173                 if (parsed > eir_len)
174                         break;
175
176                 switch (eir[1]) {
177                 case 0x01:
178                         print("Flags: 0x%02x", eir[2]);
179                         break;
180                 case 0x0d:
181                         print("Class of Device: 0x%02x%02x%02x",
182                                                 eir[4], eir[3], eir[2]);
183                         break;
184                 case 0x0e:
185                         bin2hex(eir + 2, 16, str, sizeof(str));
186                         print("SSP Hash C-192: %s", str);
187                         break;
188                 case 0x0f:
189                         bin2hex(eir + 2, 16, str, sizeof(str));
190                         print("SSP Rand R-192: %s", str);
191                         break;
192                 case 0x1b:
193                         ba2str((bdaddr_t *) (eir + 2), str);
194                         print("LE Device Address: %s (%s)", str,
195                                         eir[8] ? "random" : "public");
196                         break;
197                 case 0x1c:
198                         print("LE Role: 0x%02x", eir[2]);
199                         break;
200                 case 0x1d:
201                         bin2hex(eir + 2, 16, str, sizeof(str));
202                         print("SSP Hash C-256: %s", str);
203                         break;
204                 case 0x1e:
205                         bin2hex(eir + 2, 16, str, sizeof(str));
206                         print("SSP Rand R-256: %s", str);
207                         break;
208                 case 0x22:
209                         bin2hex(eir + 2, 16, str, sizeof(str));
210                         print("LE SC Confirmation Value: %s", str);
211                         break;
212                 case 0x23:
213                         bin2hex(eir + 2, 16, str, sizeof(str));
214                         print("LE SC Random Value: %s", str);
215                         break;
216                 default:
217                         print("Type %u: %u byte%s", eir[1], field_len - 1,
218                                         (field_len - 1) == 1 ? "" : "s");
219                         break;
220                 }
221
222                 eir += field_len + 1;
223         }
224 }
225
226 static bool load_identity(const char *path, struct mgmt_irk_info *irk)
227 {
228         char *addr, *key;
229         unsigned int type;
230         int n;
231         FILE *fp;
232
233         fp = fopen(path, "r");
234         if (!fp) {
235                 error("Failed to open identity file: %s", strerror(errno));
236                 return false;
237         }
238
239         n = fscanf(fp, "%m[0-9a-f:] (type %u) %m[0-9a-f]", &addr, &type, &key);
240
241         fclose(fp);
242
243         if (n != 3)
244                 return false;
245
246         str2ba(addr, &irk->addr.bdaddr);
247         hex2bin(key, irk->val, sizeof(irk->val));
248
249         free(addr);
250         free(key);
251
252         switch (type) {
253         case 0:
254                 irk->addr.type = BDADDR_LE_PUBLIC;
255                 break;
256         case 1:
257                 irk->addr.type = BDADDR_LE_RANDOM;
258                 break;
259         default:
260                 error("Invalid address type %u", type);
261                 return false;
262         }
263
264         return true;
265 }
266
267 static void controller_error(uint16_t index, uint16_t len,
268                                 const void *param, void *user_data)
269 {
270         const struct mgmt_ev_controller_error *ev = param;
271
272         if (len < sizeof(*ev)) {
273                 error("Too short (%u bytes) controller error event", len);
274                 return;
275         }
276
277         print("hci%u error 0x%02x", index, ev->error_code);
278 }
279
280 static void index_added(uint16_t index, uint16_t len,
281                                 const void *param, void *user_data)
282 {
283         print("hci%u added", index);
284 }
285
286 static void index_removed(uint16_t index, uint16_t len,
287                                 const void *param, void *user_data)
288 {
289         print("hci%u removed", index);
290 }
291
292 static void unconf_index_added(uint16_t index, uint16_t len,
293                                 const void *param, void *user_data)
294 {
295         print("hci%u added (unconfigured)", index);
296 }
297
298 static void unconf_index_removed(uint16_t index, uint16_t len,
299                                 const void *param, void *user_data)
300 {
301         print("hci%u removed (unconfigured)", index);
302 }
303
304 static void ext_index_added(uint16_t index, uint16_t len,
305                                 const void *param, void *user_data)
306 {
307         const struct mgmt_ev_ext_index_added *ev = param;
308
309         print("hci%u added (type %u bus %u)", index, ev->type, ev->bus);
310 }
311
312 static void ext_index_removed(uint16_t index, uint16_t len,
313                                 const void *param, void *user_data)
314 {
315         const struct mgmt_ev_ext_index_removed *ev = param;
316
317         print("hci%u removed (type %u bus %u)", index, ev->type, ev->bus);
318 }
319
320 static const char *options_str[] = {
321                                 "external",
322                                 "public-address",
323 };
324
325 static const char *options2str(uint32_t options)
326 {
327         static char str[256];
328         unsigned i;
329         int off;
330
331         off = 0;
332         str[0] = '\0';
333
334         for (i = 0; i < NELEM(options_str); i++) {
335                 if ((options & (1 << i)) != 0)
336                         off += snprintf(str + off, sizeof(str) - off, "%s ",
337                                                         options_str[i]);
338         }
339
340         return str;
341 }
342
343 static void new_config_options(uint16_t index, uint16_t len,
344                                         const void *param, void *user_data)
345 {
346         const uint32_t *ev = param;
347
348         if (len < sizeof(*ev)) {
349                 error("Too short new_config_options event (%u)", len);
350                 return;
351         }
352
353         print("hci%u new_config_options: %s", index, options2str(get_le32(ev)));
354 }
355
356 static const char *settings_str[] = {
357                                 "powered",
358                                 "connectable",
359                                 "fast-connectable",
360                                 "discoverable",
361                                 "bondable",
362                                 "link-security",
363                                 "ssp",
364                                 "br/edr",
365                                 "hs",
366                                 "le",
367                                 "advertising",
368                                 "secure-conn",
369                                 "debug-keys",
370                                 "privacy",
371                                 "configuration",
372                                 "static-addr",
373 };
374
375 static const char *settings2str(uint32_t settings)
376 {
377         static char str[256];
378         unsigned i;
379         int off;
380
381         off = 0;
382         str[0] = '\0';
383
384         for (i = 0; i < NELEM(settings_str); i++) {
385                 if ((settings & (1 << i)) != 0)
386                         off += snprintf(str + off, sizeof(str) - off, "%s ",
387                                                         settings_str[i]);
388         }
389
390         return str;
391 }
392
393 static void new_settings(uint16_t index, uint16_t len,
394                                         const void *param, void *user_data)
395 {
396         const uint32_t *ev = param;
397
398         if (len < sizeof(*ev)) {
399                 error("Too short new_settings event (%u)", len);
400                 return;
401         }
402
403         print("hci%u new_settings: %s", index, settings2str(get_le32(ev)));
404 }
405
406 static void discovering(uint16_t index, uint16_t len, const void *param,
407                                                         void *user_data)
408 {
409         const struct mgmt_ev_discovering *ev = param;
410
411         if (len < sizeof(*ev)) {
412                 error("Too short (%u bytes) discovering event", len);
413                 return;
414         }
415
416         print("hci%u type %u discovering %s", index, ev->type,
417                                         ev->discovering ? "on" : "off");
418
419         if (ev->discovering == 0 && discovery)
420                 return noninteractive_quit(EXIT_SUCCESS);
421 }
422
423 static void new_link_key(uint16_t index, uint16_t len, const void *param,
424                                                         void *user_data)
425 {
426         const struct mgmt_ev_new_link_key *ev = param;
427         char addr[18];
428
429         if (len != sizeof(*ev)) {
430                 error("Invalid new_link_key length (%u bytes)", len);
431                 return;
432         }
433
434         ba2str(&ev->key.addr.bdaddr, addr);
435         print("hci%u new_link_key %s type 0x%02x pin_len %d store_hint %u",
436                 index, addr, ev->key.type, ev->key.pin_len, ev->store_hint);
437 }
438
439 static const char *typestr(uint8_t type)
440 {
441         static const char *str[] = { "BR/EDR", "LE Public", "LE Random" };
442
443         if (type <= BDADDR_LE_RANDOM)
444                 return str[type];
445
446         return "(unknown)";
447 }
448
449 static void connected(uint16_t index, uint16_t len, const void *param,
450                                                         void *user_data)
451 {
452         const struct mgmt_ev_device_connected *ev = param;
453         uint16_t eir_len;
454         char addr[18];
455
456         if (len < sizeof(*ev)) {
457                 error("Invalid connected event length (%u bytes)", len);
458                 return;
459         }
460
461         eir_len = get_le16(&ev->eir_len);
462         if (len != sizeof(*ev) + eir_len) {
463                 error("Invalid connected event length (%u != eir_len %u)",
464                                                                 len, eir_len);
465                 return;
466         }
467
468         ba2str(&ev->addr.bdaddr, addr);
469         print("hci%u %s type %s connected eir_len %u", index, addr,
470                                         typestr(ev->addr.type), eir_len);
471 }
472
473 static void release_prompt(void)
474 {
475         if (!interactive)
476                 return;
477
478         memset(&prompt, 0, sizeof(prompt));
479         prompt.index = MGMT_INDEX_NONE;
480
481         if (!saved_prompt)
482                 return;
483
484         /* This will cause rl_expand_prompt to re-run over the last prompt,
485          * but our prompt doesn't expand anyway.
486          */
487         rl_set_prompt(saved_prompt);
488         rl_replace_line("", 0);
489         rl_point = saved_point;
490         rl_redisplay();
491
492         free(saved_prompt);
493         saved_prompt = NULL;
494 }
495
496 static void disconnected(uint16_t index, uint16_t len, const void *param,
497                                                         void *user_data)
498 {
499         const struct mgmt_ev_device_disconnected *ev = param;
500         char addr[18];
501         uint8_t reason;
502
503         if (len < sizeof(struct mgmt_addr_info)) {
504                 error("Invalid disconnected event length (%u bytes)", len);
505                 return;
506         }
507
508         if (!memcmp(&ev->addr, &prompt.addr, sizeof(ev->addr)))
509                 release_prompt();
510
511         if (len < sizeof(*ev))
512                 reason = MGMT_DEV_DISCONN_UNKNOWN;
513         else
514                 reason = ev->reason;
515
516         ba2str(&ev->addr.bdaddr, addr);
517         print("hci%u %s type %s disconnected with reason %u",
518                         index, addr, typestr(ev->addr.type), reason);
519 }
520
521 static void conn_failed(uint16_t index, uint16_t len, const void *param,
522                                                         void *user_data)
523 {
524         const struct mgmt_ev_connect_failed *ev = param;
525         char addr[18];
526
527         if (len != sizeof(*ev)) {
528                 error("Invalid connect_failed event length (%u bytes)", len);
529                 return;
530         }
531
532         ba2str(&ev->addr.bdaddr, addr);
533         print("hci%u %s type %s connect failed (status 0x%02x, %s)",
534                         index, addr, typestr(ev->addr.type), ev->status,
535                         mgmt_errstr(ev->status));
536 }
537
538 static void auth_failed(uint16_t index, uint16_t len, const void *param,
539                                                         void *user_data)
540 {
541         const struct mgmt_ev_auth_failed *ev = param;
542         char addr[18];
543
544         if (len != sizeof(*ev)) {
545                 error("Invalid auth_failed event length (%u bytes)", len);
546                 return;
547         }
548
549         if (!memcmp(&ev->addr, &prompt.addr, sizeof(ev->addr)))
550                 release_prompt();
551
552         ba2str(&ev->addr.bdaddr, addr);
553         print("hci%u %s auth failed with status 0x%02x (%s)",
554                         index, addr, ev->status, mgmt_errstr(ev->status));
555 }
556
557 static void class_of_dev_changed(uint16_t index, uint16_t len,
558                                         const void *param, void *user_data)
559 {
560         const struct mgmt_ev_class_of_dev_changed *ev = param;
561
562         if (len != sizeof(*ev)) {
563                 error("Invalid class_of_dev_changed length (%u bytes)", len);
564                 return;
565         }
566
567         print("hci%u class of device changed: 0x%02x%02x%02x", index,
568                         ev->dev_class[2], ev->dev_class[1], ev->dev_class[0]);
569 }
570
571 static void local_name_changed(uint16_t index, uint16_t len, const void *param,
572                                                         void *user_data)
573 {
574         const struct mgmt_ev_local_name_changed *ev = param;
575
576         if (len != sizeof(*ev)) {
577                 error("Invalid local_name_changed length (%u bytes)", len);
578                 return;
579         }
580
581         print("hci%u name changed: %s", index, ev->name);
582 }
583
584 static void confirm_name_rsp(uint8_t status, uint16_t len,
585                                         const void *param, void *user_data)
586 {
587         const struct mgmt_rp_confirm_name *rp = param;
588         char addr[18];
589
590         if (len == 0 && status != 0) {
591                 error("confirm_name failed with status 0x%02x (%s)", status,
592                                                         mgmt_errstr(status));
593                 return;
594         }
595
596         if (len != sizeof(*rp)) {
597                 error("confirm_name rsp length %u instead of %zu",
598                                                         len, sizeof(*rp));
599                 return;
600         }
601
602         ba2str(&rp->addr.bdaddr, addr);
603
604         if (status != 0)
605                 error("confirm_name for %s failed: 0x%02x (%s)",
606                         addr, status, mgmt_errstr(status));
607         else
608                 print("confirm_name succeeded for %s", addr);
609 }
610
611 static char *eir_get_name(const uint8_t *eir, uint16_t eir_len)
612 {
613         uint8_t parsed = 0;
614
615         if (eir_len < 2)
616                 return NULL;
617
618         while (parsed < eir_len - 1) {
619                 uint8_t field_len = eir[0];
620
621                 if (field_len == 0)
622                         break;
623
624                 parsed += field_len + 1;
625
626                 if (parsed > eir_len)
627                         break;
628
629                 /* Check for short of complete name */
630                 if (eir[1] == 0x09 || eir[1] == 0x08)
631                         return strndup((char *) &eir[2], field_len - 1);
632
633                 eir += field_len + 1;
634         }
635
636         return NULL;
637 }
638
639 static unsigned int eir_get_flags(const uint8_t *eir, uint16_t eir_len)
640 {
641         uint8_t parsed = 0;
642
643         if (eir_len < 2)
644                 return 0;
645
646         while (parsed < eir_len - 1) {
647                 uint8_t field_len = eir[0];
648
649                 if (field_len == 0)
650                         break;
651
652                 parsed += field_len + 1;
653
654                 if (parsed > eir_len)
655                         break;
656
657                 /* Check for flags */
658                 if (eir[1] == 0x01)
659                         return eir[2];
660
661                 eir += field_len + 1;
662         }
663
664         return 0;
665 }
666
667 static void device_found(uint16_t index, uint16_t len, const void *param,
668                                                         void *user_data)
669 {
670         const struct mgmt_ev_device_found *ev = param;
671         struct mgmt *mgmt = user_data;
672         uint16_t eir_len;
673         uint32_t flags;
674
675         if (len < sizeof(*ev)) {
676                 error("Too short device_found length (%u bytes)", len);
677                 return;
678         }
679
680         flags = btohl(ev->flags);
681
682         eir_len = get_le16(&ev->eir_len);
683         if (len != sizeof(*ev) + eir_len) {
684                 error("dev_found: expected %zu bytes, got %u bytes",
685                                                 sizeof(*ev) + eir_len, len);
686                 return;
687         }
688
689         if (discovery) {
690                 char addr[18], *name;
691
692                 ba2str(&ev->addr.bdaddr, addr);
693                 print("hci%u dev_found: %s type %s rssi %d "
694                         "flags 0x%04x ", index, addr,
695                         typestr(ev->addr.type), ev->rssi, flags);
696
697                 if (ev->addr.type != BDADDR_BREDR)
698                         print("AD flags 0x%02x ",
699                                         eir_get_flags(ev->eir, eir_len));
700
701                 name = eir_get_name(ev->eir, eir_len);
702                 if (name)
703                         print("name %s", name);
704                 else
705                         print("eir_len %u", eir_len);
706
707                 free(name);
708         }
709
710         if (discovery && (flags & MGMT_DEV_FOUND_CONFIRM_NAME)) {
711                 struct mgmt_cp_confirm_name cp;
712
713                 memset(&cp, 0, sizeof(cp));
714                 memcpy(&cp.addr, &ev->addr, sizeof(cp.addr));
715                 if (resolve_names)
716                         cp.name_known = 0;
717                 else
718                         cp.name_known = 1;
719
720                 mgmt_reply(mgmt, MGMT_OP_CONFIRM_NAME, index, sizeof(cp), &cp,
721                                                 confirm_name_rsp, NULL, NULL);
722         }
723 }
724
725 static void pin_rsp(uint8_t status, uint16_t len, const void *param,
726                                                         void *user_data)
727 {
728         if (status != 0) {
729                 error("PIN Code reply failed with status 0x%02x (%s)",
730                                                 status, mgmt_errstr(status));
731                 return noninteractive_quit(EXIT_FAILURE);
732         }
733
734         print("PIN Reply successful");
735 }
736
737 static int mgmt_pin_reply(struct mgmt *mgmt, uint16_t index,
738                                         const struct mgmt_addr_info *addr,
739                                         const char *pin, size_t len)
740 {
741         struct mgmt_cp_pin_code_reply cp;
742
743         memset(&cp, 0, sizeof(cp));
744         memcpy(&cp.addr, addr, sizeof(cp.addr));
745         cp.pin_len = len;
746         memcpy(cp.pin_code, pin, len);
747
748         return mgmt_reply(mgmt, MGMT_OP_PIN_CODE_REPLY, index, sizeof(cp), &cp,
749                                                         pin_rsp, NULL, NULL);
750 }
751
752 static void pin_neg_rsp(uint8_t status, uint16_t len, const void *param,
753                                                         void *user_data)
754 {
755         if (status != 0) {
756                 error("PIN Neg reply failed with status 0x%02x (%s)",
757                                                 status, mgmt_errstr(status));
758                 return noninteractive_quit(EXIT_FAILURE);
759         }
760
761         print("PIN Negative Reply successful");
762 }
763
764 static int mgmt_pin_neg_reply(struct mgmt *mgmt, uint16_t index,
765                                         const struct mgmt_addr_info *addr)
766 {
767         struct mgmt_cp_pin_code_neg_reply cp;
768
769         memset(&cp, 0, sizeof(cp));
770         memcpy(&cp.addr, addr, sizeof(cp.addr));
771
772         return mgmt_reply(mgmt, MGMT_OP_PIN_CODE_NEG_REPLY, index,
773                                 sizeof(cp), &cp, pin_neg_rsp, NULL, NULL);
774 }
775
776 static void confirm_rsp(uint8_t status, uint16_t len, const void *param,
777                                                         void *user_data)
778 {
779         if (status != 0) {
780                 error("User Confirm reply failed. status 0x%02x (%s)",
781                                                 status, mgmt_errstr(status));
782                 return noninteractive_quit(EXIT_FAILURE);
783         }
784
785         print("User Confirm Reply successful");
786 }
787
788 static int mgmt_confirm_reply(struct mgmt *mgmt, uint16_t index,
789                                         const struct mgmt_addr_info *addr)
790 {
791         struct mgmt_cp_user_confirm_reply cp;
792
793         memset(&cp, 0, sizeof(cp));
794         memcpy(&cp.addr, addr, sizeof(*addr));
795
796         return mgmt_reply(mgmt, MGMT_OP_USER_CONFIRM_REPLY, index,
797                                 sizeof(cp), &cp, confirm_rsp, NULL, NULL);
798 }
799
800 static void confirm_neg_rsp(uint8_t status, uint16_t len, const void *param,
801                                                         void *user_data)
802 {
803         if (status != 0) {
804                 error("Confirm Neg reply failed. status 0x%02x (%s)",
805                                                 status, mgmt_errstr(status));
806                 return noninteractive_quit(EXIT_FAILURE);
807         }
808
809         print("User Confirm Negative Reply successful");
810 }
811
812 static int mgmt_confirm_neg_reply(struct mgmt *mgmt, uint16_t index,
813                                         const struct mgmt_addr_info *addr)
814 {
815         struct mgmt_cp_user_confirm_reply cp;
816
817         memset(&cp, 0, sizeof(cp));
818         memcpy(&cp.addr, addr, sizeof(*addr));
819
820         return mgmt_reply(mgmt, MGMT_OP_USER_CONFIRM_NEG_REPLY, index,
821                                 sizeof(cp), &cp, confirm_neg_rsp, NULL, NULL);
822 }
823
824 static void passkey_rsp(uint8_t status, uint16_t len, const void *param,
825                                                         void *user_data)
826 {
827         if (status != 0) {
828                 error("User Passkey reply failed. status 0x%02x (%s)",
829                                                 status, mgmt_errstr(status));
830                 return noninteractive_quit(EXIT_FAILURE);
831         }
832
833         print("User Passkey Reply successful");
834 }
835
836 static int mgmt_passkey_reply(struct mgmt *mgmt, uint16_t index,
837                                         const struct mgmt_addr_info *addr,
838                                         uint32_t passkey)
839 {
840         struct mgmt_cp_user_passkey_reply cp;
841
842         memset(&cp, 0, sizeof(cp));
843         memcpy(&cp.addr, addr, sizeof(*addr));
844         put_le32(passkey, &cp.passkey);
845
846         return mgmt_reply(mgmt, MGMT_OP_USER_PASSKEY_REPLY, index,
847                                 sizeof(cp), &cp, passkey_rsp, NULL, NULL);
848 }
849
850 static void passkey_neg_rsp(uint8_t status, uint16_t len, const void *param,
851                                                         void *user_data)
852 {
853         if (status != 0) {
854                 error("Passkey Neg reply failed. status 0x%02x (%s)",
855                                                 status, mgmt_errstr(status));
856                 return noninteractive_quit(EXIT_FAILURE);
857         }
858
859         print("User Passkey Negative Reply successful");
860 }
861
862 static int mgmt_passkey_neg_reply(struct mgmt *mgmt, uint16_t index,
863                                         const struct mgmt_addr_info *addr)
864 {
865         struct mgmt_cp_user_passkey_reply cp;
866
867         memset(&cp, 0, sizeof(cp));
868         memcpy(&cp.addr, addr, sizeof(*addr));
869
870         return mgmt_reply(mgmt, MGMT_OP_USER_PASSKEY_NEG_REPLY, index,
871                                 sizeof(cp), &cp, passkey_neg_rsp, NULL, NULL);
872 }
873
874 static bool prompt_input(const char *input)
875 {
876         size_t len;
877
878         if (!prompt.req)
879                 return false;
880
881         len = strlen(input);
882
883         switch (prompt.req) {
884         case MGMT_EV_PIN_CODE_REQUEST:
885                 if (len)
886                         mgmt_pin_reply(mgmt, prompt.index, &prompt.addr,
887                                                                 input, len);
888                 else
889                         mgmt_pin_neg_reply(mgmt, prompt.index, &prompt.addr);
890                 break;
891         case MGMT_EV_USER_PASSKEY_REQUEST:
892                 if (strlen(input) > 0)
893                         mgmt_passkey_reply(mgmt, prompt.index, &prompt.addr,
894                                                                 atoi(input));
895                 else
896                         mgmt_passkey_neg_reply(mgmt, prompt.index,
897                                                                 &prompt.addr);
898                 break;
899         case MGMT_EV_USER_CONFIRM_REQUEST:
900                 if (input[0] == 'y' || input[0] == 'Y')
901                         mgmt_confirm_reply(mgmt, prompt.index, &prompt.addr);
902                 else
903                         mgmt_confirm_neg_reply(mgmt, prompt.index,
904                                                                 &prompt.addr);
905                 break;
906         }
907
908         release_prompt();
909
910         return true;
911 }
912
913 static void interactive_prompt(const char *msg)
914 {
915         if (saved_prompt)
916                 return;
917
918         saved_prompt = strdup(rl_prompt);
919         if (!saved_prompt)
920                 return;
921
922         saved_point = rl_point;
923
924         rl_set_prompt("");
925         rl_redisplay();
926
927         rl_set_prompt(msg);
928
929         rl_replace_line("", 0);
930         rl_redisplay();
931 }
932
933 static size_t get_input(char *buf, size_t buf_len)
934 {
935         size_t len;
936
937         if (!fgets(buf, buf_len, stdin))
938                 return 0;
939
940         len = strlen(buf);
941
942         /* Remove trailing white-space */
943         while (len && isspace(buf[len - 1]))
944                 buf[--len] = '\0';
945
946         return len;
947 }
948
949 static void ask(uint16_t index, uint16_t req, const struct mgmt_addr_info *addr,
950                                                 const char *fmt, ...)
951 {
952         char msg[256], buf[18];
953         va_list ap;
954         int off;
955
956         prompt.index = index;
957         prompt.req = req;
958         memcpy(&prompt.addr, addr, sizeof(*addr));
959
960         va_start(ap, fmt);
961         off = vsnprintf(msg, sizeof(msg), fmt, ap);
962         va_end(ap);
963
964         snprintf(msg + off, sizeof(msg) - off, " %s ",
965                                         COLOR_BOLDGRAY ">>" COLOR_OFF);
966
967         if (interactive) {
968                 interactive_prompt(msg);
969                 va_end(ap);
970                 return;
971         }
972
973         printf("%s", msg);
974         fflush(stdout);
975
976         memset(buf, 0, sizeof(buf));
977         get_input(buf, sizeof(buf));
978         prompt_input(buf);
979 }
980
981 static void request_pin(uint16_t index, uint16_t len, const void *param,
982                                                         void *user_data)
983 {
984         const struct mgmt_ev_pin_code_request *ev = param;
985         char addr[18];
986
987         if (len != sizeof(*ev)) {
988                 error("Invalid pin_code request length (%u bytes)", len);
989                 return;
990         }
991
992         ba2str(&ev->addr.bdaddr, addr);
993         print("hci%u %s request PIN", index, addr);
994
995         ask(index, MGMT_EV_PIN_CODE_REQUEST, &ev->addr,
996                                 "PIN Request (press enter to reject)");
997 }
998
999 static void user_confirm(uint16_t index, uint16_t len, const void *param,
1000                                                         void *user_data)
1001 {
1002         const struct mgmt_ev_user_confirm_request *ev = param;
1003         uint32_t val;
1004         char addr[18];
1005
1006         if (len != sizeof(*ev)) {
1007                 error("Invalid user_confirm request length (%u)", len);
1008                 return;
1009         }
1010
1011         ba2str(&ev->addr.bdaddr, addr);
1012         val = get_le32(&ev->value);
1013
1014         print("hci%u %s User Confirm %06u hint %u", index, addr,
1015                                                         val, ev->confirm_hint);
1016
1017         if (ev->confirm_hint)
1018                 ask(index, MGMT_EV_USER_CONFIRM_REQUEST, &ev->addr,
1019                                 "Accept pairing with %s (yes/no)", addr);
1020         else
1021                 ask(index, MGMT_EV_USER_CONFIRM_REQUEST, &ev->addr,
1022                         "Confirm value %06u for %s (yes/no)", val, addr);
1023 }
1024
1025 static void request_passkey(uint16_t index, uint16_t len, const void *param,
1026                                                         void *user_data)
1027 {
1028         const struct mgmt_ev_user_passkey_request *ev = param;
1029         char addr[18];
1030
1031         if (len != sizeof(*ev)) {
1032                 error("Invalid passkey request length (%u bytes)", len);
1033                 return;
1034         }
1035
1036         ba2str(&ev->addr.bdaddr, addr);
1037         print("hci%u %s request passkey", index, addr);
1038
1039         ask(index, MGMT_EV_USER_PASSKEY_REQUEST, &ev->addr,
1040                         "Passkey Request (press enter to reject)");
1041 }
1042
1043 static void passkey_notify(uint16_t index, uint16_t len, const void *param,
1044                                                         void *user_data)
1045 {
1046         const struct mgmt_ev_passkey_notify *ev = param;
1047         char addr[18];
1048
1049         if (len != sizeof(*ev)) {
1050                 error("Invalid passkey request length (%u bytes)", len);
1051                 return;
1052         }
1053
1054         ba2str(&ev->addr.bdaddr, addr);
1055         print("hci%u %s request passkey", index, addr);
1056
1057         print("Passkey Notify: %06u (entered %u)", get_le32(&ev->passkey),
1058                                                                 ev->entered);
1059 }
1060
1061 static void local_oob_data_updated(uint16_t index, uint16_t len,
1062                                         const void *param, void *user_data)
1063 {
1064         const struct mgmt_ev_local_oob_data_updated *ev = param;
1065         uint16_t eir_len;
1066
1067         if (len < sizeof(*ev)) {
1068                 error("Too small (%u bytes) local_oob_updated event", len);
1069                 return;
1070         }
1071
1072         eir_len = le16_to_cpu(ev->eir_len);
1073         if (len != sizeof(*ev) + eir_len) {
1074                 error("local_oob_updated: expected %zu bytes, got %u bytes",
1075                                                 sizeof(*ev) + eir_len, len);
1076                 return;
1077         }
1078
1079         print("hci%u oob data updated: type %u len %u", index,
1080                                                 ev->type, eir_len);
1081 }
1082
1083 static void advertising_added(uint16_t index, uint16_t len,
1084                                         const void *param, void *user_data)
1085 {
1086         const struct mgmt_ev_advertising_added *ev = param;
1087
1088         if (len < sizeof(*ev)) {
1089                 error("Too small (%u bytes) advertising_added event", len);
1090                 return;
1091         }
1092
1093         print("hci%u advertising_added: instance %u", index, ev->instance);
1094 }
1095
1096 static void advertising_removed(uint16_t index, uint16_t len,
1097                                         const void *param, void *user_data)
1098 {
1099         const struct mgmt_ev_advertising_removed *ev = param;
1100
1101         if (len < sizeof(*ev)) {
1102                 error("Too small (%u bytes) advertising_removed event", len);
1103                 return;
1104         }
1105
1106         print("hci%u advertising_removed: instance %u", index, ev->instance);
1107 }
1108
1109 static void version_rsp(uint8_t status, uint16_t len, const void *param,
1110                                                         void *user_data)
1111 {
1112         const struct mgmt_rp_read_version *rp = param;
1113
1114         if (status != 0) {
1115                 error("Reading mgmt version failed with status 0x%02x (%s)",
1116                                                 status, mgmt_errstr(status));
1117                 goto done;
1118         }
1119
1120         if (len < sizeof(*rp)) {
1121                 error("Too small version reply (%u bytes)", len);
1122                 goto done;
1123         }
1124
1125         print("MGMT Version %u, revision %u", rp->version,
1126                                                 get_le16(&rp->revision));
1127
1128 done:
1129         noninteractive_quit(EXIT_SUCCESS);
1130 }
1131
1132 static void cmd_version(struct mgmt *mgmt, uint16_t index, int argc,
1133                                                                 char **argv)
1134 {
1135         if (mgmt_send(mgmt, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE,
1136                                 0, NULL, version_rsp, NULL, NULL) == 0) {
1137                 error("Unable to send read_version cmd");
1138                 return noninteractive_quit(EXIT_FAILURE);
1139         }
1140 }
1141
1142 static void commands_rsp(uint8_t status, uint16_t len, const void *param,
1143                                                         void *user_data)
1144 {
1145         const struct mgmt_rp_read_commands *rp = param;
1146         uint16_t num_commands, num_events;
1147         const uint16_t *opcode;
1148         size_t expected_len;
1149         int i;
1150
1151         if (status != 0) {
1152                 error("Read Supported Commands failed: status 0x%02x (%s)",
1153                                                 status, mgmt_errstr(status));
1154                 goto done;
1155         }
1156
1157         if (len < sizeof(*rp)) {
1158                 error("Too small commands reply (%u bytes)", len);
1159                 goto done;
1160         }
1161
1162         num_commands = get_le16(&rp->num_commands);
1163         num_events = get_le16(&rp->num_events);
1164
1165         expected_len = sizeof(*rp) + num_commands * sizeof(uint16_t) +
1166                                                 num_events * sizeof(uint16_t);
1167
1168         if (len < expected_len) {
1169                 error("Too small commands reply (%u != %zu)",
1170                                                         len, expected_len);
1171                 goto done;
1172         }
1173
1174         opcode = rp->opcodes;
1175
1176         print("%u commands:", num_commands);
1177         for (i = 0; i < num_commands; i++) {
1178                 uint16_t op = get_le16(opcode++);
1179                 print("\t%s (0x%04x)", mgmt_opstr(op), op);
1180         }
1181
1182         print("%u events:", num_events);
1183         for (i = 0; i < num_events; i++) {
1184                 uint16_t ev = get_le16(opcode++);
1185                 print("\t%s (0x%04x)", mgmt_evstr(ev), ev);
1186         }
1187
1188 done:
1189         noninteractive_quit(EXIT_SUCCESS);
1190 }
1191
1192 static void cmd_commands(struct mgmt *mgmt, uint16_t index, int argc,
1193                                                                 char **argv)
1194 {
1195         if (mgmt_send(mgmt, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE,
1196                                 0, NULL, commands_rsp, NULL, NULL) == 0) {
1197                 error("Unable to send read_commands cmd");
1198                 return noninteractive_quit(EXIT_FAILURE);
1199         }
1200 }
1201
1202 static void config_info_rsp(uint8_t status, uint16_t len, const void *param,
1203                                                         void *user_data)
1204 {
1205         const struct mgmt_rp_read_config_info *rp = param;
1206         uint16_t index = PTR_TO_UINT(user_data);
1207         uint32_t supported_options, missing_options;
1208
1209         if (status != 0) {
1210                 error("Reading hci%u config failed with status 0x%02x (%s)",
1211                                         index, status, mgmt_errstr(status));
1212                 goto done;
1213         }
1214
1215         if (len < sizeof(*rp)) {
1216                 error("Too small info reply (%u bytes)", len);
1217                 goto done;
1218         }
1219
1220         print("hci%u:\tUnconfigured controller", index);
1221
1222         print("\tmanufacturer %u", le16_to_cpu(rp->manufacturer));
1223
1224         supported_options = le32_to_cpu(rp->supported_options);
1225         print("\tsupported options: %s", options2str(supported_options));
1226
1227         missing_options = le32_to_cpu(rp->missing_options);
1228         print("\tmissing options: %s", options2str(missing_options));
1229
1230 done:
1231         pending_index--;
1232
1233         if (pending_index > 0)
1234                 return;
1235
1236         noninteractive_quit(EXIT_SUCCESS);
1237 }
1238
1239 static void unconf_index_rsp(uint8_t status, uint16_t len, const void *param,
1240                                                         void *user_data)
1241 {
1242         const struct mgmt_rp_read_unconf_index_list *rp = param;
1243         uint16_t count;
1244         unsigned int i;
1245
1246         if (status != 0) {
1247                 error("Reading index list failed with status 0x%02x (%s)",
1248                                                 status, mgmt_errstr(status));
1249                 return noninteractive_quit(EXIT_FAILURE);
1250         }
1251
1252         if (len < sizeof(*rp)) {
1253                 error("Too small index list reply (%u bytes)", len);
1254                 return noninteractive_quit(EXIT_FAILURE);
1255         }
1256
1257         count = le16_to_cpu(rp->num_controllers);
1258
1259         if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
1260                 error("Index count (%u) doesn't match reply length (%u)",
1261                                                                 count, len);
1262                 return noninteractive_quit(EXIT_FAILURE);
1263         }
1264
1265         print("Unconfigured index list with %u item%s",
1266                                         count, count != 1 ? "s" : "");
1267
1268         for (i = 0; i < count; i++) {
1269                 uint16_t index = le16_to_cpu(rp->index[i]);
1270
1271                 if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, index, 0, NULL,
1272                                 config_info_rsp, UINT_TO_PTR(index), NULL)) {
1273                         error("Unable to send read_config_info cmd");
1274                         return noninteractive_quit(EXIT_FAILURE);
1275                 }
1276
1277                 pending_index++;
1278         }
1279
1280         if (!count)
1281                 noninteractive_quit(EXIT_SUCCESS);
1282 }
1283
1284 static void cmd_config(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
1285 {
1286         if (index == MGMT_INDEX_NONE) {
1287                 if (!mgmt_send(mgmt, MGMT_OP_READ_UNCONF_INDEX_LIST,
1288                                         MGMT_INDEX_NONE, 0, NULL,
1289                                         unconf_index_rsp, mgmt, NULL)) {
1290                         error("Unable to send unconf_index_list cmd");
1291                         return noninteractive_quit(EXIT_FAILURE);
1292                 }
1293
1294                 return;
1295         }
1296
1297         if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, index, 0, NULL,
1298                                 config_info_rsp, UINT_TO_PTR(index), NULL)) {
1299                 error("Unable to send read_config_info cmd");
1300                 return noninteractive_quit(EXIT_FAILURE);
1301         }
1302 }
1303
1304 static void config_options_rsp(uint8_t status, uint16_t len, const void *param,
1305                                                         void *user_data)
1306 {
1307         const struct mgmt_rp_read_config_info *rp = param;
1308         uint16_t index = PTR_TO_UINT(user_data);
1309         uint32_t supported_options, missing_options;
1310
1311         if (status != 0) {
1312                 error("Reading hci%u config failed with status 0x%02x (%s)",
1313                                         index, status, mgmt_errstr(status));
1314                 goto done;
1315         }
1316
1317         if (len < sizeof(*rp)) {
1318                 error("Too small info reply (%u bytes)", len);
1319                 goto done;
1320         }
1321
1322         print("hci%u:\tConfiguration options", index);
1323
1324         supported_options = le32_to_cpu(rp->supported_options);
1325         print("\tsupported options: %s", options2str(supported_options));
1326
1327         missing_options = le32_to_cpu(rp->missing_options);
1328         print("\tmissing options: %s", options2str(missing_options));
1329
1330 done:
1331         pending_index--;
1332
1333         if (pending_index > 0)
1334                 return;
1335
1336         noninteractive_quit(EXIT_SUCCESS);
1337 }
1338
1339 static void info_rsp(uint8_t status, uint16_t len, const void *param,
1340                                                         void *user_data)
1341 {
1342         const struct mgmt_rp_read_info *rp = param;
1343         uint16_t index = PTR_TO_UINT(user_data);
1344         uint32_t supported_settings, current_settings;
1345         char addr[18];
1346
1347         if (status != 0) {
1348                 error("Reading hci%u info failed with status 0x%02x (%s)",
1349                                         index, status, mgmt_errstr(status));
1350                 goto done;
1351         }
1352
1353         if (len < sizeof(*rp)) {
1354                 error("Too small info reply (%u bytes)", len);
1355                 goto done;
1356         }
1357
1358         print("hci%u:\tPrimary controller", index);
1359
1360         ba2str(&rp->bdaddr, addr);
1361         print("\taddr %s version %u manufacturer %u class 0x%02x%02x%02x",
1362                         addr, rp->version, le16_to_cpu(rp->manufacturer),
1363                         rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
1364
1365         supported_settings = le32_to_cpu(rp->supported_settings);
1366         print("\tsupported settings: %s", settings2str(supported_settings));
1367
1368         current_settings = le32_to_cpu(rp->current_settings);
1369         print("\tcurrent settings: %s", settings2str(current_settings));
1370
1371         print("\tname %s", rp->name);
1372         print("\tshort name %s", rp->short_name);
1373
1374         if (supported_settings & MGMT_SETTING_CONFIGURATION) {
1375                 if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO,
1376                                         index, 0, NULL, config_options_rsp,
1377                                         UINT_TO_PTR(index), NULL)) {
1378                         error("Unable to send read_config cmd");
1379                         goto done;
1380                 }
1381                 return;
1382         }
1383
1384 done:
1385         pending_index--;
1386
1387         if (pending_index > 0)
1388                 return;
1389
1390         noninteractive_quit(EXIT_SUCCESS);
1391 }
1392
1393 static void ext_info_rsp(uint8_t status, uint16_t len, const void *param,
1394                                                         void *user_data)
1395 {
1396         const struct mgmt_rp_read_ext_info *rp = param;
1397         uint16_t index = PTR_TO_UINT(user_data);
1398         uint32_t supported_settings, current_settings;
1399         char addr[18];
1400
1401         if (status != 0) {
1402                 error("Reading hci%u info failed with status 0x%02x (%s)",
1403                                         index, status, mgmt_errstr(status));
1404                 goto done;
1405         }
1406
1407         if (len < sizeof(*rp)) {
1408                 error("Too small info reply (%u bytes)", len);
1409                 goto done;
1410         }
1411
1412         print("hci%u:\tPrimary controller", index);
1413
1414         ba2str(&rp->bdaddr, addr);
1415         print("\taddr %s version %u manufacturer %u",
1416                         addr, rp->version, le16_to_cpu(rp->manufacturer));
1417
1418         supported_settings = le32_to_cpu(rp->supported_settings);
1419         print("\tsupported settings: %s", settings2str(supported_settings));
1420
1421         current_settings = le32_to_cpu(rp->current_settings);
1422         print("\tcurrent settings: %s", settings2str(current_settings));
1423
1424         if (supported_settings & MGMT_SETTING_CONFIGURATION) {
1425                 if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO,
1426                                         index, 0, NULL, config_options_rsp,
1427                                         UINT_TO_PTR(index), NULL)) {
1428                         error("Unable to send read_config cmd");
1429                         goto done;
1430                 }
1431                 return;
1432         }
1433
1434 done:
1435         pending_index--;
1436
1437         if (pending_index > 0)
1438                 return;
1439
1440         noninteractive_quit(EXIT_SUCCESS);
1441 }
1442
1443 static void index_rsp(uint8_t status, uint16_t len, const void *param,
1444                                                         void *user_data)
1445 {
1446         const struct mgmt_rp_read_index_list *rp = param;
1447         struct mgmt *mgmt = user_data;
1448         uint16_t count;
1449         unsigned int i;
1450
1451         if (status != 0) {
1452                 error("Reading index list failed with status 0x%02x (%s)",
1453                                                 status, mgmt_errstr(status));
1454                 return noninteractive_quit(EXIT_FAILURE);
1455         }
1456
1457         if (len < sizeof(*rp)) {
1458                 error("Too small index list reply (%u bytes)", len);
1459                 return noninteractive_quit(EXIT_FAILURE);
1460         }
1461
1462         count = le16_to_cpu(rp->num_controllers);
1463
1464         if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
1465                 error("Index count (%u) doesn't match reply length (%u)",
1466                                                                 count, len);
1467                 return noninteractive_quit(EXIT_FAILURE);
1468         }
1469
1470         print("Index list with %u item%s", count, count != 1 ? "s" : "");
1471
1472         for (i = 0; i < count; i++) {
1473                 uint16_t index = le16_to_cpu(rp->index[i]);
1474
1475                 if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
1476                                         info_rsp, UINT_TO_PTR(index), NULL)) {
1477                         error("Unable to send read_info cmd");
1478                         return noninteractive_quit(EXIT_FAILURE);
1479                 }
1480
1481                 pending_index++;
1482         }
1483
1484         if (!count)
1485                 noninteractive_quit(EXIT_SUCCESS);
1486 }
1487
1488 static void cmd_info(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
1489 {
1490         if (index == MGMT_INDEX_NONE) {
1491                 if (!mgmt_send(mgmt, MGMT_OP_READ_INDEX_LIST,
1492                                         MGMT_INDEX_NONE, 0, NULL,
1493                                         index_rsp, mgmt, NULL)) {
1494                         error("Unable to send index_list cmd");
1495                         return noninteractive_quit(EXIT_FAILURE);
1496                 }
1497
1498                 return;
1499         }
1500
1501         if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL, info_rsp,
1502                                                 UINT_TO_PTR(index), NULL)) {
1503                 error("Unable to send read_info cmd");
1504                 return noninteractive_quit(EXIT_FAILURE);
1505         }
1506 }
1507
1508 static void ext_index_rsp(uint8_t status, uint16_t len, const void *param,
1509                                                         void *user_data)
1510 {
1511         const struct mgmt_rp_read_ext_index_list *rp = param;
1512         uint16_t count, index_filter = PTR_TO_UINT(user_data);
1513         unsigned int i;
1514
1515         if (status != 0) {
1516                 error("Reading ext index list failed with status 0x%02x (%s)",
1517                                                 status, mgmt_errstr(status));
1518                 return noninteractive_quit(EXIT_FAILURE);
1519         }
1520
1521         if (len < sizeof(*rp)) {
1522                 error("Too small ext index list reply (%u bytes)", len);
1523                 return noninteractive_quit(EXIT_FAILURE);
1524         }
1525
1526         count = get_le16(&rp->num_controllers);
1527
1528         if (len < sizeof(*rp) + count * (sizeof(uint16_t) + sizeof(uint8_t))) {
1529                 error("Index count (%u) doesn't match reply length (%u)",
1530                                                                 count, len);
1531                 return noninteractive_quit(EXIT_FAILURE);
1532         }
1533
1534         print("Extended index list with %u item%s",
1535                                         count, count != 1 ? "s" : "");
1536
1537         for (i = 0; i < count; i++) {
1538                 uint16_t index = le16_to_cpu(rp->entry[i].index);
1539                 char *busstr = hci_bustostr(rp->entry[i].bus);
1540
1541                 if (index_filter != MGMT_INDEX_NONE && index_filter != index)
1542                         continue;
1543
1544                 switch (rp->entry[i].type) {
1545                 case 0x00:
1546                         print("Primary controller (hci%u,%s)", index, busstr);
1547                         if (!mgmt_send(mgmt, MGMT_OP_READ_EXT_INFO,
1548                                                 index, 0, NULL, ext_info_rsp,
1549                                                 UINT_TO_PTR(index), NULL)) {
1550                                 error("Unable to send read_ext_info cmd");
1551                                 return noninteractive_quit(EXIT_FAILURE);
1552                         }
1553                         pending_index++;
1554                         break;
1555                 case 0x01:
1556                         print("Unconfigured controller (hci%u,%s)",
1557                                                                 index, busstr);
1558                         if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO,
1559                                                 index, 0, NULL, config_info_rsp,
1560                                                 UINT_TO_PTR(index), NULL)) {
1561                                 error("Unable to send read_config cmd");
1562                                 return noninteractive_quit(EXIT_FAILURE);
1563                         }
1564                         pending_index++;
1565                         break;
1566                 case 0x02:
1567                         print("AMP controller (hci%u,%s)", index, busstr);
1568                         break;
1569                 default:
1570                         print("Type %u controller (hci%u,%s)",
1571                                         rp->entry[i].type, index, busstr);
1572                         break;
1573                 }
1574         }
1575
1576         print("");
1577
1578         if (!count)
1579                 noninteractive_quit(EXIT_SUCCESS);
1580 }
1581
1582 static void cmd_extinfo(struct mgmt *mgmt, uint16_t index,
1583                                                 int argc, char **argv)
1584 {
1585         if (!mgmt_send(mgmt, MGMT_OP_READ_EXT_INDEX_LIST,
1586                                 MGMT_INDEX_NONE, 0, NULL,
1587                                 ext_index_rsp, UINT_TO_PTR(index), NULL)) {
1588                 error("Unable to send ext_index_list cmd");
1589                 return noninteractive_quit(EXIT_FAILURE);
1590         }
1591 }
1592
1593 static void auto_power_enable_rsp(uint8_t status, uint16_t len,
1594                                         const void *param, void *user_data)
1595 {
1596         uint16_t index = PTR_TO_UINT(user_data);
1597
1598         print("Successfully enabled controller with index %u", index);
1599
1600         noninteractive_quit(EXIT_SUCCESS);
1601 }
1602
1603 static void auto_power_info_rsp(uint8_t status, uint16_t len,
1604                                         const void *param, void *user_data)
1605 {
1606         const struct mgmt_rp_read_info *rp = param;
1607         uint16_t index = PTR_TO_UINT(user_data);
1608         uint32_t supported_settings, current_settings, missing_settings;
1609         uint8_t val = 0x01;
1610
1611         if (status) {
1612                 error("Reading info failed with status 0x%02x (%s)",
1613                                                 status, mgmt_errstr(status));
1614                 return noninteractive_quit(EXIT_FAILURE);
1615         }
1616
1617         supported_settings = le32_to_cpu(rp->supported_settings);
1618         current_settings = le32_to_cpu(rp->current_settings);
1619         missing_settings = current_settings ^ supported_settings;
1620
1621         if (missing_settings & MGMT_SETTING_BREDR)
1622                 mgmt_send(mgmt, MGMT_OP_SET_BREDR, index, sizeof(val), &val,
1623                                                         NULL, NULL, NULL);
1624
1625         if (missing_settings & MGMT_SETTING_SSP)
1626                 mgmt_send(mgmt, MGMT_OP_SET_SSP, index, sizeof(val), &val,
1627                                                         NULL, NULL, NULL);
1628
1629         if (missing_settings & MGMT_SETTING_LE)
1630                 mgmt_send(mgmt, MGMT_OP_SET_LE, index, sizeof(val), &val,
1631                                                         NULL, NULL, NULL);
1632
1633         if (missing_settings & MGMT_SETTING_SECURE_CONN)
1634                 mgmt_send(mgmt, MGMT_OP_SET_SECURE_CONN, index,
1635                                                         sizeof(val), &val,
1636                                                         NULL, NULL, NULL);
1637
1638         if (missing_settings & MGMT_SETTING_BONDABLE)
1639                 mgmt_send(mgmt, MGMT_OP_SET_BONDABLE, index, sizeof(val), &val,
1640                                                         NULL, NULL, NULL);
1641
1642         if (current_settings & MGMT_SETTING_POWERED)
1643                 return noninteractive_quit(EXIT_SUCCESS);
1644
1645         if (!mgmt_send(mgmt, MGMT_OP_SET_POWERED, index, sizeof(val), &val,
1646                                                 auto_power_enable_rsp,
1647                                                 UINT_TO_PTR(index), NULL)) {
1648                 error("Unable to send set powerd cmd");
1649                 return noninteractive_quit(EXIT_FAILURE);
1650         }
1651 }
1652
1653 static void auto_power_index_evt(uint16_t index, uint16_t len,
1654                                         const void *param, void *user_data)
1655 {
1656         uint16_t index_filter = PTR_TO_UINT(user_data);
1657
1658         if (index != index_filter)
1659                 return;
1660
1661         print("New controller with index %u", index);
1662
1663         if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
1664                                                 auto_power_info_rsp,
1665                                                 UINT_TO_PTR(index), NULL)) {
1666                 error("Unable to send read info cmd");
1667                 return noninteractive_quit(EXIT_FAILURE);
1668         }
1669 }
1670
1671 static void auto_power_index_rsp(uint8_t status, uint16_t len,
1672                                         const void *param, void *user_data)
1673 {
1674         const struct mgmt_rp_read_index_list *rp = param;
1675         uint16_t index = PTR_TO_UINT(user_data);
1676         uint16_t i, count;
1677         bool found = false;
1678
1679         if (status) {
1680                 error("Reading index list failed with status 0x%02x (%s)",
1681                                                 status, mgmt_errstr(status));
1682                 return noninteractive_quit(EXIT_FAILURE);
1683         }
1684
1685         count = le16_to_cpu(rp->num_controllers);
1686         for (i = 0; i < count; i++) {
1687                 if (le16_to_cpu(rp->index[i]) == index)
1688                         found = true;
1689         }
1690
1691         if (!found) {
1692                 print("Waiting for index %u to appear", index);
1693
1694                 mgmt_register(mgmt, MGMT_EV_INDEX_ADDED, index,
1695                                                 auto_power_index_evt,
1696                                                 UINT_TO_PTR(index), NULL);
1697                 return;
1698         }
1699
1700         print("Found controller with index %u", index);
1701
1702         if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
1703                                                 auto_power_info_rsp,
1704                                                 UINT_TO_PTR(index), NULL)) {
1705                 error("Unable to send read info cmd");
1706                 return noninteractive_quit(EXIT_FAILURE);
1707         }
1708 }
1709
1710 static void cmd_auto_power(struct mgmt *mgmt, uint16_t index,
1711                                                 int argc, char **argv)
1712 {
1713         if (index == MGMT_INDEX_NONE)
1714                 index = 0;
1715
1716         if (!mgmt_send(mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
1717                                                 auto_power_index_rsp,
1718                                                 UINT_TO_PTR(index), NULL)) {
1719                 error("Unable to send read index list cmd");
1720                 return noninteractive_quit(EXIT_FAILURE);
1721         }
1722 }
1723
1724 /* Wrapper to get the index and opcode to the response callback */
1725 struct command_data {
1726         uint16_t id;
1727         uint16_t op;
1728         void (*callback) (uint16_t id, uint16_t op, uint8_t status,
1729                                         uint16_t len, const void *param);
1730 };
1731
1732 static void cmd_rsp(uint8_t status, uint16_t len, const void *param,
1733                                                         void *user_data)
1734 {
1735         struct command_data *data = user_data;
1736
1737         data->callback(data->op, data->id, status, len, param);
1738 }
1739
1740 static unsigned int send_cmd(struct mgmt *mgmt, uint16_t op, uint16_t id,
1741                                 uint16_t len, const void *param,
1742                                 void (*cb)(uint16_t id, uint16_t op,
1743                                                 uint8_t status, uint16_t len,
1744                                                 const void *param))
1745 {
1746         struct command_data *data;
1747         unsigned int send_id;
1748
1749         data = new0(struct command_data, 1);
1750         if (!data)
1751                 return 0;
1752
1753         data->id = id;
1754         data->op = op;
1755         data->callback = cb;
1756
1757         send_id = mgmt_send(mgmt, op, id, len, param, cmd_rsp, data, free);
1758         if (send_id == 0)
1759                 free(data);
1760
1761         return send_id;
1762 }
1763
1764 static void setting_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
1765                                                         const void *param)
1766 {
1767         const uint32_t *rp = param;
1768
1769         if (status != 0) {
1770                 error("%s for hci%u failed with status 0x%02x (%s)",
1771                         mgmt_opstr(op), id, status, mgmt_errstr(status));
1772                 goto done;
1773         }
1774
1775         if (len < sizeof(*rp)) {
1776                 error("Too small %s response (%u bytes)",
1777                                                         mgmt_opstr(op), len);
1778                 goto done;
1779         }
1780
1781         print("hci%u %s complete, settings: %s", id, mgmt_opstr(op),
1782                                                 settings2str(get_le32(rp)));
1783
1784 done:
1785         noninteractive_quit(EXIT_SUCCESS);
1786 }
1787
1788 static void cmd_setting(struct mgmt *mgmt, uint16_t index, uint16_t op,
1789                                                         int argc, char **argv)
1790 {
1791         uint8_t val;
1792
1793         if (argc < 2) {
1794                 print("Specify \"on\" or \"off\"");
1795                 return noninteractive_quit(EXIT_FAILURE);
1796         }
1797
1798         if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
1799                 val = 1;
1800         else if (strcasecmp(argv[1], "off") == 0)
1801                 val = 0;
1802         else
1803                 val = atoi(argv[1]);
1804
1805         if (index == MGMT_INDEX_NONE)
1806                 index = 0;
1807
1808         if (send_cmd(mgmt, op, index, sizeof(val), &val, setting_rsp) == 0) {
1809                 error("Unable to send %s cmd", mgmt_opstr(op));
1810                 return noninteractive_quit(EXIT_FAILURE);
1811         }
1812 }
1813
1814 static void cmd_power(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
1815 {
1816         cmd_setting(mgmt, index, MGMT_OP_SET_POWERED, argc, argv);
1817 }
1818
1819 static void cmd_discov(struct mgmt *mgmt, uint16_t index, int argc,
1820                                                                 char **argv)
1821 {
1822         struct mgmt_cp_set_discoverable cp;
1823
1824         if (argc < 2) {
1825                 print("Usage: %s <yes/no/limited> [timeout]", argv[0]);
1826                 return noninteractive_quit(EXIT_FAILURE);
1827         }
1828
1829         memset(&cp, 0, sizeof(cp));
1830
1831         if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
1832                 cp.val = 1;
1833         else if (strcasecmp(argv[1], "off") == 0)
1834                 cp.val = 0;
1835         else if (strcasecmp(argv[1], "limited") == 0)
1836                 cp.val = 2;
1837         else
1838                 cp.val = atoi(argv[1]);
1839
1840         if (argc > 2)
1841                 cp.timeout = htobs(atoi(argv[2]));
1842
1843         if (index == MGMT_INDEX_NONE)
1844                 index = 0;
1845
1846         if (send_cmd(mgmt, MGMT_OP_SET_DISCOVERABLE, index, sizeof(cp), &cp,
1847                                                         setting_rsp) == 0) {
1848                 error("Unable to send set_discoverable cmd");
1849                 return noninteractive_quit(EXIT_FAILURE);
1850         }
1851 }
1852
1853 static void cmd_connectable(struct mgmt *mgmt, uint16_t index, int argc,
1854                                                                 char **argv)
1855 {
1856         cmd_setting(mgmt, index, MGMT_OP_SET_CONNECTABLE, argc, argv);
1857 }
1858
1859 static void cmd_fast_conn(struct mgmt *mgmt, uint16_t index, int argc,
1860                                                                 char **argv)
1861 {
1862         cmd_setting(mgmt, index, MGMT_OP_SET_FAST_CONNECTABLE, argc, argv);
1863 }
1864
1865 static void cmd_bondable(struct mgmt *mgmt, uint16_t index, int argc,
1866                                                                 char **argv)
1867 {
1868         cmd_setting(mgmt, index, MGMT_OP_SET_BONDABLE, argc, argv);
1869 }
1870
1871 static void cmd_linksec(struct mgmt *mgmt, uint16_t index, int argc,
1872                                                                 char **argv)
1873 {
1874         cmd_setting(mgmt, index, MGMT_OP_SET_LINK_SECURITY, argc, argv);
1875 }
1876
1877 static void cmd_ssp(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
1878 {
1879         cmd_setting(mgmt, index, MGMT_OP_SET_SSP, argc, argv);
1880 }
1881
1882 static void cmd_sc(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
1883 {
1884         uint8_t val;
1885
1886         if (argc < 2) {
1887                 print("Specify \"on\" or \"off\" or \"only\"");
1888                 return noninteractive_quit(EXIT_FAILURE);
1889         }
1890
1891         if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
1892                 val = 1;
1893         else if (strcasecmp(argv[1], "off") == 0)
1894                 val = 0;
1895         else if (strcasecmp(argv[1], "only") == 0)
1896                 val = 2;
1897         else
1898                 val = atoi(argv[1]);
1899
1900         if (index == MGMT_INDEX_NONE)
1901                 index = 0;
1902
1903         if (send_cmd(mgmt, MGMT_OP_SET_SECURE_CONN, index,
1904                                         sizeof(val), &val, setting_rsp) == 0) {
1905                 error("Unable to send set_secure_conn cmd");
1906                 return noninteractive_quit(EXIT_FAILURE);
1907         }
1908 }
1909
1910 static void cmd_hs(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
1911 {
1912         cmd_setting(mgmt, index, MGMT_OP_SET_HS, argc, argv);
1913 }
1914
1915 static void cmd_le(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
1916 {
1917         cmd_setting(mgmt, index, MGMT_OP_SET_LE, argc, argv);
1918 }
1919
1920 static void cmd_advertising(struct mgmt *mgmt, uint16_t index, int argc,
1921                                                                 char **argv)
1922 {
1923         cmd_setting(mgmt, index, MGMT_OP_SET_ADVERTISING, argc, argv);
1924 }
1925
1926 static void cmd_bredr(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
1927 {
1928         cmd_setting(mgmt, index, MGMT_OP_SET_BREDR, argc, argv);
1929 }
1930
1931 static void cmd_privacy(struct mgmt *mgmt, uint16_t index, int argc,
1932                                                                 char **argv)
1933 {
1934         struct mgmt_cp_set_privacy cp;
1935
1936         if (argc < 2) {
1937                 print("Specify \"on\" or \"off\"");
1938                 return noninteractive_quit(EXIT_FAILURE);
1939         }
1940
1941         if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
1942                 cp.privacy = 0x01;
1943         else if (strcasecmp(argv[1], "off") == 0)
1944                 cp.privacy = 0x00;
1945         else
1946                 cp.privacy = atoi(argv[1]);
1947
1948         if (index == MGMT_INDEX_NONE)
1949                 index = 0;
1950
1951         if (argc > 2) {
1952                 if (hex2bin(argv[2], cp.irk,
1953                                         sizeof(cp.irk)) != sizeof(cp.irk)) {
1954                         error("Invalid key format");
1955                         return noninteractive_quit(EXIT_FAILURE);
1956                 }
1957         } else {
1958                 int fd;
1959
1960                 fd = open("/dev/urandom", O_RDONLY);
1961                 if (fd < 0) {
1962                         error("open(/dev/urandom): %s", strerror(errno));
1963                         return noninteractive_quit(EXIT_FAILURE);
1964                 }
1965
1966                 if (read(fd, cp.irk, sizeof(cp.irk)) != sizeof(cp.irk)) {
1967                         error("Reading from urandom failed");
1968                         close(fd);
1969                         return noninteractive_quit(EXIT_FAILURE);
1970                 }
1971
1972                 close(fd);
1973         }
1974
1975         if (send_cmd(mgmt, MGMT_OP_SET_PRIVACY, index, sizeof(cp), &cp,
1976                                                         setting_rsp) == 0) {
1977                 error("Unable to send Set Privacy command");
1978                 return noninteractive_quit(EXIT_FAILURE);
1979         }
1980 }
1981
1982 static void class_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
1983                                                         const void *param)
1984 {
1985         const struct mgmt_ev_class_of_dev_changed *rp = param;
1986
1987         if (len == 0 && status != 0) {
1988                 error("%s failed, status 0x%02x (%s)",
1989                                 mgmt_opstr(op), status, mgmt_errstr(status));
1990                 return noninteractive_quit(EXIT_FAILURE);
1991         }
1992
1993         if (len != sizeof(*rp)) {
1994                 error("Unexpected %s len %u", mgmt_opstr(op), len);
1995                 return noninteractive_quit(EXIT_FAILURE);
1996         }
1997
1998         print("%s succeeded. Class 0x%02x%02x%02x", mgmt_opstr(op),
1999                 rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
2000
2001         noninteractive_quit(EXIT_SUCCESS);
2002 }
2003
2004 static void cmd_class(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2005 {
2006         uint8_t class[2];
2007
2008         if (argc < 3) {
2009                 print("Usage: %s <major> <minor>", argv[0]);
2010                 return noninteractive_quit(EXIT_FAILURE);
2011         }
2012
2013         class[0] = atoi(argv[1]);
2014         class[1] = atoi(argv[2]);
2015
2016         if (index == MGMT_INDEX_NONE)
2017                 index = 0;
2018
2019         if (send_cmd(mgmt, MGMT_OP_SET_DEV_CLASS, index, sizeof(class), class,
2020                                                         class_rsp) == 0) {
2021                 error("Unable to send set_dev_class cmd");
2022                 return noninteractive_quit(EXIT_FAILURE);
2023         }
2024 }
2025
2026 static void disconnect_rsp(uint8_t status, uint16_t len, const void *param,
2027                                                         void *user_data)
2028 {
2029         const struct mgmt_rp_disconnect *rp = param;
2030         char addr[18];
2031
2032         if (len == 0 && status != 0) {
2033                 error("Disconnect failed with status 0x%02x (%s)",
2034                                                 status, mgmt_errstr(status));
2035                 return noninteractive_quit(EXIT_FAILURE);
2036         }
2037
2038         if (len != sizeof(*rp)) {
2039                 error("Invalid disconnect response length (%u)", len);
2040                 return noninteractive_quit(EXIT_FAILURE);
2041         }
2042
2043         ba2str(&rp->addr.bdaddr, addr);
2044
2045         if (status == 0)
2046                 print("%s disconnected", addr);
2047         else
2048                 error("Disconnecting %s failed with status 0x%02x (%s)",
2049                                 addr, status, mgmt_errstr(status));
2050
2051         noninteractive_quit(EXIT_SUCCESS);
2052 }
2053
2054 static void disconnect_usage(void)
2055 {
2056         print("Usage: disconnect [-t type] <remote address>");
2057 }
2058
2059 static struct option disconnect_options[] = {
2060         { "help",       0, 0, 'h' },
2061         { "type",       1, 0, 't' },
2062         { 0, 0, 0, 0 }
2063 };
2064
2065 static void cmd_disconnect(struct mgmt *mgmt, uint16_t index, int argc,
2066                                                                 char **argv)
2067 {
2068         struct mgmt_cp_disconnect cp;
2069         uint8_t type = BDADDR_BREDR;
2070         int opt;
2071
2072         while ((opt = getopt_long(argc, argv, "+t:h", disconnect_options,
2073                                                                 NULL)) != -1) {
2074                 switch (opt) {
2075                 case 't':
2076                         type = strtol(optarg, NULL, 0);
2077                         break;
2078                 case 'h':
2079                         disconnect_usage();
2080                         optind = 0;
2081                         return noninteractive_quit(EXIT_SUCCESS);
2082                 default:
2083                         disconnect_usage();
2084                         optind = 0;
2085                         return noninteractive_quit(EXIT_FAILURE);
2086                 }
2087         }
2088
2089         argc -= optind;
2090         argv += optind;
2091         optind = 0;
2092
2093         if (argc < 1) {
2094                 disconnect_usage();
2095                 return noninteractive_quit(EXIT_FAILURE);
2096         }
2097
2098         if (index == MGMT_INDEX_NONE)
2099                 index = 0;
2100
2101         memset(&cp, 0, sizeof(cp));
2102         str2ba(argv[0], &cp.addr.bdaddr);
2103         cp.addr.type = type;
2104
2105         if (mgmt_send(mgmt, MGMT_OP_DISCONNECT, index, sizeof(cp), &cp,
2106                                         disconnect_rsp, NULL, NULL) == 0) {
2107                 error("Unable to send disconnect cmd");
2108                 return noninteractive_quit(EXIT_FAILURE);
2109         }
2110 }
2111
2112 static void con_rsp(uint8_t status, uint16_t len, const void *param,
2113                                                         void *user_data)
2114 {
2115         const struct mgmt_rp_get_connections *rp = param;
2116         uint16_t count, i;
2117
2118         if (len < sizeof(*rp)) {
2119                 error("Too small (%u bytes) get_connections rsp", len);
2120                 return noninteractive_quit(EXIT_FAILURE);
2121         }
2122
2123         count = get_le16(&rp->conn_count);
2124         if (len != sizeof(*rp) + count * sizeof(struct mgmt_addr_info)) {
2125                 error("Invalid get_connections length (count=%u, len=%u)",
2126                                                                 count, len);
2127                 return noninteractive_quit(EXIT_FAILURE);
2128         }
2129
2130         for (i = 0; i < count; i++) {
2131                 char addr[18];
2132
2133                 ba2str(&rp->addr[i].bdaddr, addr);
2134
2135                 print("%s type %s", addr, typestr(rp->addr[i].type));
2136         }
2137
2138         noninteractive_quit(EXIT_SUCCESS);
2139 }
2140
2141 static void cmd_con(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2142 {
2143         if (index == MGMT_INDEX_NONE)
2144                 index = 0;
2145
2146         if (mgmt_send(mgmt, MGMT_OP_GET_CONNECTIONS, index, 0, NULL,
2147                                                 con_rsp, NULL, NULL) == 0) {
2148                 error("Unable to send get_connections cmd");
2149                 return noninteractive_quit(EXIT_FAILURE);
2150         }
2151 }
2152
2153 static void find_service_rsp(uint8_t status, uint16_t len, const void *param,
2154                                                         void *user_data)
2155 {
2156         if (status != 0) {
2157                 error("Start Service Discovery failed: status 0x%02x (%s)",
2158                                                 status, mgmt_errstr(status));
2159                 return noninteractive_quit(EXIT_FAILURE);
2160         }
2161
2162         print("Service discovery started");
2163         discovery = true;
2164 }
2165
2166 static void find_service_usage(void)
2167 {
2168         print("Usage: find-service [-u UUID] [-r RSSI_Threshold] [-l|-b]");
2169 }
2170
2171 static struct option find_service_options[] = {
2172         { "help",       no_argument, 0, 'h' },
2173         { "le-only",    no_argument, 0, 'l' },
2174         { "bredr-only", no_argument, 0, 'b' },
2175         { "uuid",       required_argument, 0, 'u' },
2176         { "rssi",       required_argument, 0, 'r' },
2177         { 0, 0, 0, 0 }
2178 };
2179
2180 static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
2181 {
2182         if (uuid->type == SDP_UUID16)
2183                 sdp_uuid16_to_uuid128(uuid128, uuid);
2184         else if (uuid->type == SDP_UUID32)
2185                 sdp_uuid32_to_uuid128(uuid128, uuid);
2186         else
2187                 memcpy(uuid128, uuid, sizeof(*uuid));
2188 }
2189
2190 #define MAX_UUIDS 4
2191
2192 static void cmd_find_service(struct mgmt *mgmt, uint16_t index, int argc,
2193                              char **argv)
2194 {
2195         struct mgmt_cp_start_service_discovery *cp;
2196         uint8_t buf[sizeof(*cp) + 16 * MAX_UUIDS];
2197         uuid_t uuid;
2198         uint128_t uint128;
2199         uuid_t uuid128;
2200         uint8_t type = SCAN_TYPE_DUAL;
2201         int8_t rssi;
2202         uint16_t count;
2203         int opt;
2204
2205         if (index == MGMT_INDEX_NONE)
2206                 index = 0;
2207
2208         rssi = 127;
2209         count = 0;
2210
2211         if (argc == 1) {
2212                 find_service_usage();
2213                 return noninteractive_quit(EXIT_FAILURE);
2214         }
2215
2216         while ((opt = getopt_long(argc, argv, "+lbu:r:p:h",
2217                                         find_service_options, NULL)) != -1) {
2218                 switch (opt) {
2219                 case 'l':
2220                         type &= ~SCAN_TYPE_BREDR;
2221                         type |= SCAN_TYPE_LE;
2222                         break;
2223                 case 'b':
2224                         type |= SCAN_TYPE_BREDR;
2225                         type &= ~SCAN_TYPE_LE;
2226                         break;
2227                 case 'u':
2228                         if (count == MAX_UUIDS) {
2229                                 print("Max %u UUIDs supported", MAX_UUIDS);
2230                                 optind = 0;
2231                                 return noninteractive_quit(EXIT_FAILURE);
2232                         }
2233
2234                         if (bt_string2uuid(&uuid, optarg) < 0) {
2235                                 print("Invalid UUID: %s", optarg);
2236                                 optind = 0;
2237                                 return noninteractive_quit(EXIT_FAILURE);
2238                         }
2239                         cp = (void *) buf;
2240                         uuid_to_uuid128(&uuid128, &uuid);
2241                         ntoh128((uint128_t *) uuid128.value.uuid128.data,
2242                                 &uint128);
2243                         htob128(&uint128, (uint128_t *) cp->uuids[count++]);
2244                         break;
2245                 case 'r':
2246                         rssi = atoi(optarg);
2247                         break;
2248                 case 'h':
2249                         find_service_usage();
2250                         optind = 0;
2251                         return noninteractive_quit(EXIT_SUCCESS);
2252                 default:
2253                         find_service_usage();
2254                         optind = 0;
2255                         return noninteractive_quit(EXIT_FAILURE);
2256                 }
2257         }
2258
2259         argc -= optind;
2260         argv += optind;
2261         optind = 0;
2262
2263         if (argc > 0) {
2264                 find_service_usage();
2265                 return noninteractive_quit(EXIT_FAILURE);
2266         }
2267
2268         cp = (void *) buf;
2269         cp->type = type;
2270         cp->rssi = rssi;
2271         cp->uuid_count = cpu_to_le16(count);
2272
2273         if (mgmt_send(mgmt, MGMT_OP_START_SERVICE_DISCOVERY, index,
2274                                 sizeof(*cp) + count * 16, cp,
2275                                 find_service_rsp, NULL, NULL) == 0) {
2276                 error("Unable to send start_service_discovery cmd");
2277                 return noninteractive_quit(EXIT_FAILURE);
2278         }
2279 }
2280
2281 static void find_rsp(uint8_t status, uint16_t len, const void *param,
2282                                                         void *user_data)
2283 {
2284         if (status != 0) {
2285                 error("Unable to start discovery. status 0x%02x (%s)",
2286                                                 status, mgmt_errstr(status));
2287                 return noninteractive_quit(EXIT_FAILURE);
2288         }
2289
2290         print("Discovery started");
2291         discovery = true;
2292 }
2293
2294 static void find_usage(void)
2295 {
2296         print("Usage: find [-l|-b]>");
2297 }
2298
2299 static struct option find_options[] = {
2300         { "help",       0, 0, 'h' },
2301         { "le-only",    1, 0, 'l' },
2302         { "bredr-only", 1, 0, 'b' },
2303         { "limited",    1, 0, 'L' },
2304         { 0, 0, 0, 0 }
2305 };
2306
2307 static void cmd_find(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2308 {
2309         struct mgmt_cp_start_discovery cp;
2310         uint8_t op = MGMT_OP_START_DISCOVERY;
2311         uint8_t type = SCAN_TYPE_DUAL;
2312         int opt;
2313
2314         if (index == MGMT_INDEX_NONE)
2315                 index = 0;
2316
2317         while ((opt = getopt_long(argc, argv, "+lbLh", find_options,
2318                                                                 NULL)) != -1) {
2319                 switch (opt) {
2320                 case 'l':
2321                         type &= ~SCAN_TYPE_BREDR;
2322                         type |= SCAN_TYPE_LE;
2323                         break;
2324                 case 'b':
2325                         type |= SCAN_TYPE_BREDR;
2326                         type &= ~SCAN_TYPE_LE;
2327                         break;
2328                 case 'L':
2329                         op = MGMT_OP_START_LIMITED_DISCOVERY;
2330                         break;
2331                 case 'h':
2332                         find_usage();
2333                         optind = 0;
2334                         return noninteractive_quit(EXIT_SUCCESS);
2335                 default:
2336                         find_usage();
2337                         optind = 0;
2338                         return noninteractive_quit(EXIT_FAILURE);
2339                 }
2340         }
2341
2342         argc -= optind;
2343         argv += optind;
2344         optind = 0;
2345
2346         memset(&cp, 0, sizeof(cp));
2347         cp.type = type;
2348
2349         if (mgmt_send(mgmt, op, index, sizeof(cp), &cp, find_rsp,
2350                                                         NULL, NULL) == 0) {
2351                 error("Unable to send start_discovery cmd");
2352                 return noninteractive_quit(EXIT_FAILURE);
2353         }
2354 }
2355
2356 static void stop_find_rsp(uint8_t status, uint16_t len, const void *param,
2357                                                         void *user_data)
2358 {
2359         if (status != 0) {
2360                 fprintf(stderr,
2361                         "Stop Discovery failed: status 0x%02x (%s)\n",
2362                                                 status, mgmt_errstr(status));
2363                 return noninteractive_quit(EXIT_SUCCESS);
2364         }
2365
2366         printf("Discovery stopped\n");
2367         discovery = false;
2368
2369         noninteractive_quit(EXIT_SUCCESS);
2370 }
2371
2372 static void stop_find_usage(void)
2373 {
2374         printf("Usage: btmgmt stop-find [-l|-b]>\n");
2375 }
2376
2377 static struct option stop_find_options[] = {
2378         { "help",       0, 0, 'h' },
2379         { "le-only",    1, 0, 'l' },
2380         { "bredr-only", 1, 0, 'b' },
2381         { 0, 0, 0, 0 }
2382 };
2383
2384 static void cmd_stop_find(struct mgmt *mgmt, uint16_t index, int argc,
2385                           char **argv)
2386 {
2387         struct mgmt_cp_stop_discovery cp;
2388         uint8_t type = SCAN_TYPE_DUAL;
2389         int opt;
2390
2391         if (index == MGMT_INDEX_NONE)
2392                 index = 0;
2393
2394         while ((opt = getopt_long(argc, argv, "+lbh", stop_find_options,
2395                                                                 NULL)) != -1) {
2396                 switch (opt) {
2397                 case 'l':
2398                         type &= ~SCAN_TYPE_BREDR;
2399                         type |= SCAN_TYPE_LE;
2400                         break;
2401                 case 'b':
2402                         type |= SCAN_TYPE_BREDR;
2403                         type &= ~SCAN_TYPE_LE;
2404                         break;
2405                 case 'h':
2406                 default:
2407                         stop_find_usage();
2408                         optind = 0;
2409                         exit(EXIT_SUCCESS);
2410                 }
2411         }
2412
2413         argc -= optind;
2414         argv += optind;
2415         optind = 0;
2416
2417         memset(&cp, 0, sizeof(cp));
2418         cp.type = type;
2419
2420         if (mgmt_send(mgmt, MGMT_OP_STOP_DISCOVERY, index, sizeof(cp), &cp,
2421                                              stop_find_rsp, NULL, NULL) == 0) {
2422                 fprintf(stderr, "Unable to send stop_discovery cmd\n");
2423                 exit(EXIT_FAILURE);
2424         }
2425 }
2426
2427 static void name_rsp(uint8_t status, uint16_t len, const void *param,
2428                                                         void *user_data)
2429 {
2430         if (status != 0)
2431                 error("Unable to set local name with status 0x%02x (%s)",
2432                                                 status, mgmt_errstr(status));
2433
2434         noninteractive_quit(EXIT_SUCCESS);
2435 }
2436
2437 static void cmd_name(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2438 {
2439         struct mgmt_cp_set_local_name cp;
2440
2441         if (argc < 2) {
2442                 print("Usage: %s <name> [shortname]", argv[0]);
2443                 return noninteractive_quit(EXIT_FAILURE);
2444         }
2445
2446         if (index == MGMT_INDEX_NONE)
2447                 index = 0;
2448
2449         memset(&cp, 0, sizeof(cp));
2450         strncpy((char *) cp.name, argv[1], HCI_MAX_NAME_LENGTH);
2451         if (argc > 2)
2452                 strncpy((char *) cp.short_name, argv[2],
2453                                         MGMT_MAX_SHORT_NAME_LENGTH);
2454
2455         if (mgmt_send(mgmt, MGMT_OP_SET_LOCAL_NAME, index, sizeof(cp), &cp,
2456                                                 name_rsp, NULL, NULL) == 0) {
2457                 error("Unable to send set_name cmd");
2458                 return noninteractive_quit(EXIT_FAILURE);
2459         }
2460 }
2461
2462 static void pair_rsp(uint8_t status, uint16_t len, const void *param,
2463                                                         void *user_data)
2464 {
2465         const struct mgmt_rp_pair_device *rp = param;
2466         char addr[18];
2467
2468         if (len == 0 && status != 0) {
2469                 error("Pairing failed with status 0x%02x (%s)",
2470                                                 status, mgmt_errstr(status));
2471                 return noninteractive_quit(EXIT_FAILURE);
2472         }
2473
2474         if (len != sizeof(*rp)) {
2475                 error("Unexpected pair_rsp len %u", len);
2476                 return noninteractive_quit(EXIT_FAILURE);
2477         }
2478
2479         if (!memcmp(&rp->addr, &prompt.addr, sizeof(rp->addr)))
2480                 release_prompt();
2481
2482         ba2str(&rp->addr.bdaddr, addr);
2483
2484         if (status)
2485                 error("Pairing with %s (%s) failed. status 0x%02x (%s)",
2486                         addr, typestr(rp->addr.type), status,
2487                         mgmt_errstr(status));
2488         else
2489                 print("Paired with %s (%s)", addr, typestr(rp->addr.type));
2490
2491         noninteractive_quit(EXIT_SUCCESS);
2492 }
2493
2494 static void pair_usage(void)
2495 {
2496         print("Usage: pair [-c cap] [-t type] <remote address>");
2497 }
2498
2499 static struct option pair_options[] = {
2500         { "help",       0, 0, 'h' },
2501         { "capability", 1, 0, 'c' },
2502         { "type",       1, 0, 't' },
2503         { 0, 0, 0, 0 }
2504 };
2505
2506 static void cmd_pair(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2507 {
2508         struct mgmt_cp_pair_device cp;
2509         uint8_t cap = 0x01;
2510         uint8_t type = BDADDR_BREDR;
2511         char addr[18];
2512         int opt;
2513
2514         while ((opt = getopt_long(argc, argv, "+c:t:h", pair_options,
2515                                                                 NULL)) != -1) {
2516                 switch (opt) {
2517                 case 'c':
2518                         cap = strtol(optarg, NULL, 0);
2519                         break;
2520                 case 't':
2521                         type = strtol(optarg, NULL, 0);
2522                         break;
2523                 case 'h':
2524                         pair_usage();
2525                         optind = 0;
2526                         return noninteractive_quit(EXIT_SUCCESS);
2527                 default:
2528                         pair_usage();
2529                         optind = 0;
2530                         return noninteractive_quit(EXIT_FAILURE);
2531                 }
2532         }
2533
2534         argc -= optind;
2535         argv += optind;
2536         optind = 0;
2537
2538         if (argc < 1) {
2539                 pair_usage();
2540                 return noninteractive_quit(EXIT_FAILURE);
2541         }
2542
2543         if (index == MGMT_INDEX_NONE)
2544                 index = 0;
2545
2546         memset(&cp, 0, sizeof(cp));
2547         str2ba(argv[0], &cp.addr.bdaddr);
2548         cp.addr.type = type;
2549         cp.io_cap = cap;
2550
2551         ba2str(&cp.addr.bdaddr, addr);
2552         print("Pairing with %s (%s)", addr, typestr(cp.addr.type));
2553
2554         if (mgmt_send(mgmt, MGMT_OP_PAIR_DEVICE, index, sizeof(cp), &cp,
2555                                                 pair_rsp, NULL, NULL) == 0) {
2556                 error("Unable to send pair_device cmd");
2557                 return noninteractive_quit(EXIT_FAILURE);
2558         }
2559 }
2560
2561 static void cancel_pair_rsp(uint8_t status, uint16_t len, const void *param,
2562                                                         void *user_data)
2563 {
2564         const struct mgmt_addr_info *rp = param;
2565         char addr[18];
2566
2567         if (len == 0 && status != 0) {
2568                 error("Cancel Pairing failed with 0x%02x (%s)",
2569                                                 status, mgmt_errstr(status));
2570                 return noninteractive_quit(EXIT_FAILURE);
2571         }
2572
2573         if (len != sizeof(*rp)) {
2574                 error("Unexpected cancel_pair_rsp len %u", len);
2575                 return noninteractive_quit(EXIT_FAILURE);
2576         }
2577
2578         ba2str(&rp->bdaddr, addr);
2579
2580         if (status)
2581                 error("Cancel Pairing with %s (%s) failed. 0x%02x (%s)",
2582                         addr, typestr(rp->type), status,
2583                         mgmt_errstr(status));
2584         else
2585                 print("Pairing Cancelled with %s", addr);
2586
2587         noninteractive_quit(EXIT_SUCCESS);
2588 }
2589
2590 static void cancel_pair_usage(void)
2591 {
2592         print("Usage: cancelpair [-t type] <remote address>");
2593 }
2594
2595 static struct option cancel_pair_options[] = {
2596         { "help",       0, 0, 'h' },
2597         { "type",       1, 0, 't' },
2598         { 0, 0, 0, 0 }
2599 };
2600
2601 static void cmd_cancel_pair(struct mgmt *mgmt, uint16_t index, int argc,
2602                                                                 char **argv)
2603 {
2604         struct mgmt_addr_info cp;
2605         uint8_t type = BDADDR_BREDR;
2606         int opt;
2607
2608         while ((opt = getopt_long(argc, argv, "+t:h", cancel_pair_options,
2609                                                                 NULL)) != -1) {
2610                 switch (opt) {
2611                 case 't':
2612                         type = strtol(optarg, NULL, 0);
2613                         break;
2614                 case 'h':
2615                         cancel_pair_usage();
2616                         optind = 0;
2617                         return noninteractive_quit(EXIT_SUCCESS);
2618                 default:
2619                         cancel_pair_usage();
2620                         optind = 0;
2621                         return noninteractive_quit(EXIT_FAILURE);
2622                 }
2623         }
2624
2625         argc -= optind;
2626         argv += optind;
2627         optind = 0;
2628
2629         if (argc < 1) {
2630                 cancel_pair_usage();
2631                 return noninteractive_quit(EXIT_FAILURE);
2632         }
2633
2634         if (index == MGMT_INDEX_NONE)
2635                 index = 0;
2636
2637         memset(&cp, 0, sizeof(cp));
2638         str2ba(argv[0], &cp.bdaddr);
2639         cp.type = type;
2640
2641         if (mgmt_reply(mgmt, MGMT_OP_CANCEL_PAIR_DEVICE, index, sizeof(cp), &cp,
2642                                         cancel_pair_rsp, NULL, NULL) == 0) {
2643                 error("Unable to send cancel_pair_device cmd");
2644                 return noninteractive_quit(EXIT_FAILURE);
2645         }
2646 }
2647
2648 static void unpair_rsp(uint8_t status, uint16_t len, const void *param,
2649                                                         void *user_data)
2650 {
2651         const struct mgmt_rp_unpair_device *rp = param;
2652         char addr[18];
2653
2654         if (len == 0 && status != 0) {
2655                 error("Unpair device failed. status 0x%02x (%s)",
2656                                                 status, mgmt_errstr(status));
2657                 return noninteractive_quit(EXIT_FAILURE);
2658         }
2659
2660         if (len != sizeof(*rp)) {
2661                 error("Unexpected unpair_device_rsp len %u", len);
2662                 return noninteractive_quit(EXIT_FAILURE);
2663         }
2664
2665         ba2str(&rp->addr.bdaddr, addr);
2666
2667         if (status)
2668                 error("Unpairing %s failed. status 0x%02x (%s)",
2669                                 addr, status, mgmt_errstr(status));
2670         else
2671                 print("%s unpaired", addr);
2672
2673         noninteractive_quit(EXIT_SUCCESS);
2674 }
2675
2676 static void unpair_usage(void)
2677 {
2678         print("Usage: unpair [-t type] <remote address>");
2679 }
2680
2681 static struct option unpair_options[] = {
2682         { "help",       0, 0, 'h' },
2683         { "type",       1, 0, 't' },
2684         { 0, 0, 0, 0 }
2685 };
2686
2687 static void cmd_unpair(struct mgmt *mgmt, uint16_t index, int argc,
2688                                                                 char **argv)
2689 {
2690         struct mgmt_cp_unpair_device cp;
2691         uint8_t type = BDADDR_BREDR;
2692         int opt;
2693
2694         while ((opt = getopt_long(argc, argv, "+t:h", unpair_options,
2695                                                                 NULL)) != -1) {
2696                 switch (opt) {
2697                 case 't':
2698                         type = strtol(optarg, NULL, 0);
2699                         break;
2700                 case 'h':
2701                         unpair_usage();
2702                         optind = 0;
2703                         return noninteractive_quit(EXIT_SUCCESS);
2704                 default:
2705                         unpair_usage();
2706                         optind = 0;
2707                         return noninteractive_quit(EXIT_FAILURE);
2708                 }
2709         }
2710
2711         argc -= optind;
2712         argv += optind;
2713         optind = 0;
2714
2715         if (argc < 1) {
2716                 unpair_usage();
2717                 return noninteractive_quit(EXIT_FAILURE);
2718         }
2719
2720         if (index == MGMT_INDEX_NONE)
2721                 index = 0;
2722
2723         memset(&cp, 0, sizeof(cp));
2724         str2ba(argv[0], &cp.addr.bdaddr);
2725         cp.addr.type = type;
2726         cp.disconnect = 1;
2727
2728         if (mgmt_send(mgmt, MGMT_OP_UNPAIR_DEVICE, index, sizeof(cp), &cp,
2729                                                 unpair_rsp, NULL, NULL) == 0) {
2730                 error("Unable to send unpair_device cmd");
2731                 return noninteractive_quit(EXIT_FAILURE);
2732         }
2733 }
2734
2735 static void keys_rsp(uint8_t status, uint16_t len, const void *param,
2736                                                         void *user_data)
2737 {
2738         if (status != 0)
2739                 error("Load keys failed with status 0x%02x (%s)",
2740                                                 status, mgmt_errstr(status));
2741         else
2742                 print("Keys successfully loaded");
2743
2744         noninteractive_quit(EXIT_SUCCESS);
2745 }
2746
2747 static void cmd_keys(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2748 {
2749         struct mgmt_cp_load_link_keys cp;
2750
2751         if (index == MGMT_INDEX_NONE)
2752                 index = 0;
2753
2754         memset(&cp, 0, sizeof(cp));
2755
2756         if (mgmt_send(mgmt, MGMT_OP_LOAD_LINK_KEYS, index, sizeof(cp), &cp,
2757                                                 keys_rsp, NULL, NULL) == 0) {
2758                 error("Unable to send load_keys cmd");
2759                 return noninteractive_quit(EXIT_FAILURE);
2760         }
2761 }
2762
2763 static void ltks_rsp(uint8_t status, uint16_t len, const void *param,
2764                                                         void *user_data)
2765 {
2766         if (status != 0)
2767                 error("Load keys failed with status 0x%02x (%s)",
2768                                                 status, mgmt_errstr(status));
2769         else
2770                 print("Long term keys successfully loaded");
2771
2772         noninteractive_quit(EXIT_SUCCESS);
2773 }
2774
2775 static void cmd_ltks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2776 {
2777         struct mgmt_cp_load_long_term_keys cp;
2778
2779         if (index == MGMT_INDEX_NONE)
2780                 index = 0;
2781
2782         memset(&cp, 0, sizeof(cp));
2783
2784         if (mgmt_send(mgmt, MGMT_OP_LOAD_LONG_TERM_KEYS, index, sizeof(cp), &cp,
2785                                                 ltks_rsp, NULL, NULL) == 0) {
2786                 error("Unable to send load_ltks cmd");
2787                 return noninteractive_quit(EXIT_SUCCESS);
2788         }
2789 }
2790
2791 static void irks_rsp(uint8_t status, uint16_t len, const void *param,
2792                                                         void *user_data)
2793 {
2794         if (status != 0)
2795                 error("Load IRKs failed with status 0x%02x (%s)",
2796                                                 status, mgmt_errstr(status));
2797         else
2798                 print("Identity Resolving Keys successfully loaded");
2799
2800         noninteractive_quit(EXIT_SUCCESS);
2801 }
2802
2803 static void irks_usage(void)
2804 {
2805         print("Usage: irks [--local]");
2806 }
2807
2808 static struct option irks_options[] = {
2809         { "help",       0, 0, 'h' },
2810         { "local",      1, 0, 'l' },
2811         { "file",       1, 0, 'f' },
2812         { 0, 0, 0, 0 }
2813 };
2814
2815 #define MAX_IRKS 4
2816
2817 static void cmd_irks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2818 {
2819         struct mgmt_cp_load_irks *cp;
2820         uint8_t buf[sizeof(*cp) + 23 * MAX_IRKS];
2821         uint16_t count, local_index;
2822         char path[PATH_MAX];
2823         int opt;
2824
2825         if (index == MGMT_INDEX_NONE)
2826                 index = 0;
2827
2828         cp = (void *) buf;
2829         count = 0;
2830
2831         while ((opt = getopt_long(argc, argv, "+l:f:h",
2832                                         irks_options, NULL)) != -1) {
2833                 switch (opt) {
2834                 case 'l':
2835                         if (count >= MAX_IRKS) {
2836                                 error("Number of IRKs exceeded");
2837                                 optind = 0;
2838                                 return noninteractive_quit(EXIT_FAILURE);
2839                         }
2840                         if (strlen(optarg) > 3 &&
2841                                         strncasecmp(optarg, "hci", 3) == 0)
2842                                 local_index = atoi(optarg + 3);
2843                         else
2844                                 local_index = atoi(optarg);
2845                         snprintf(path, sizeof(path),
2846                                 "/sys/kernel/debug/bluetooth/hci%u/identity",
2847                                 local_index);
2848                         if (!load_identity(path, &cp->irks[count])) {
2849                                 error("Unable to load identity");
2850                                 optind = 0;
2851                                 return noninteractive_quit(EXIT_FAILURE);
2852                         }
2853                         count++;
2854                         break;
2855                 case 'f':
2856                         if (count >= MAX_IRKS) {
2857                                 error("Number of IRKs exceeded");
2858                                 optind = 0;
2859                                 return noninteractive_quit(EXIT_FAILURE);
2860                         }
2861                         if (!load_identity(optarg, &cp->irks[count])) {
2862                                 error("Unable to load identities");
2863                                 optind = 0;
2864                                 return noninteractive_quit(EXIT_FAILURE);
2865                         }
2866                         count++;
2867                         break;
2868                 case 'h':
2869                         irks_usage();
2870                         optind = 0;
2871                         return noninteractive_quit(EXIT_SUCCESS);
2872                 default:
2873                         irks_usage();
2874                         optind = 0;
2875                         return noninteractive_quit(EXIT_FAILURE);
2876                 }
2877         }
2878
2879         argc -= optind;
2880         argv += optind;
2881         optind = 0;
2882
2883         if (argc > 0) {
2884                 irks_usage();
2885                 return noninteractive_quit(EXIT_FAILURE);
2886         }
2887
2888         cp->irk_count = cpu_to_le16(count);
2889
2890         if (mgmt_send(mgmt, MGMT_OP_LOAD_IRKS, index,
2891                                         sizeof(*cp) + count * 23, cp,
2892                                         irks_rsp, NULL, NULL) == 0) {
2893                 error("Unable to send load_irks cmd");
2894                 return noninteractive_quit(EXIT_FAILURE);
2895         }
2896 }
2897
2898 static void block_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
2899                                                         const void *param)
2900 {
2901         const struct mgmt_addr_info *rp = param;
2902         char addr[18];
2903
2904         if (len == 0 && status != 0) {
2905                 error("%s failed, status 0x%02x (%s)",
2906                                 mgmt_opstr(op), status, mgmt_errstr(status));
2907                 return noninteractive_quit(EXIT_FAILURE);
2908         }
2909
2910         if (len != sizeof(*rp)) {
2911                 error("Unexpected %s len %u", mgmt_opstr(op), len);
2912                 return noninteractive_quit(EXIT_FAILURE);
2913         }
2914
2915         ba2str(&rp->bdaddr, addr);
2916
2917         if (status)
2918                 error("%s %s (%s) failed. status 0x%02x (%s)",
2919                                 mgmt_opstr(op), addr, typestr(rp->type),
2920                                 status, mgmt_errstr(status));
2921         else
2922                 print("%s %s succeeded", mgmt_opstr(op), addr);
2923
2924         noninteractive_quit(EXIT_SUCCESS);
2925 }
2926
2927 static void block_usage(void)
2928 {
2929         print("Usage: block [-t type] <remote address>");
2930 }
2931
2932 static struct option block_options[] = {
2933         { "help",       0, 0, 'h' },
2934         { "type",       1, 0, 't' },
2935         { 0, 0, 0, 0 }
2936 };
2937
2938 static void cmd_block(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
2939 {
2940         struct mgmt_cp_block_device cp;
2941         uint8_t type = BDADDR_BREDR;
2942         int opt;
2943
2944         while ((opt = getopt_long(argc, argv, "+t:h", block_options,
2945                                                         NULL)) != -1) {
2946                 switch (opt) {
2947                 case 't':
2948                         type = strtol(optarg, NULL, 0);
2949                         break;
2950                 case 'h':
2951                         block_usage();
2952                         optind = 0;
2953                         return noninteractive_quit(EXIT_SUCCESS);
2954                 default:
2955                         block_usage();
2956                         optind = 0;
2957                         return noninteractive_quit(EXIT_FAILURE);
2958                 }
2959         }
2960
2961         argc -= optind;
2962         argv += optind;
2963         optind = 0;
2964
2965         if (argc < 1) {
2966                 block_usage();
2967                 return noninteractive_quit(EXIT_FAILURE);
2968         }
2969
2970         if (index == MGMT_INDEX_NONE)
2971                 index = 0;
2972
2973         memset(&cp, 0, sizeof(cp));
2974         str2ba(argv[0], &cp.addr.bdaddr);
2975         cp.addr.type = type;
2976
2977         if (send_cmd(mgmt, MGMT_OP_BLOCK_DEVICE, index, sizeof(cp), &cp,
2978                                                         block_rsp) == 0) {
2979                 error("Unable to send block_device cmd");
2980                 return noninteractive_quit(EXIT_FAILURE);
2981         }
2982 }
2983
2984 static void unblock_usage(void)
2985 {
2986         print("Usage: unblock [-t type] <remote address>");
2987 }
2988
2989 static void cmd_unblock(struct mgmt *mgmt, uint16_t index, int argc,
2990                                                                 char **argv)
2991 {
2992         struct mgmt_cp_unblock_device cp;
2993         uint8_t type = BDADDR_BREDR;
2994         int opt;
2995
2996         while ((opt = getopt_long(argc, argv, "+t:h", block_options,
2997                                                         NULL)) != -1) {
2998                 switch (opt) {
2999                 case 't':
3000                         type = strtol(optarg, NULL, 0);
3001                         break;
3002                 case 'h':
3003                         unblock_usage();
3004                         optind = 0;
3005                         return noninteractive_quit(EXIT_SUCCESS);
3006                 default:
3007                         unblock_usage();
3008                         optind = 0;
3009                         return noninteractive_quit(EXIT_FAILURE);
3010                 }
3011         }
3012
3013         argc -= optind;
3014         argv += optind;
3015         optind = 0;
3016
3017         if (argc < 1) {
3018                 unblock_usage();
3019                 return noninteractive_quit(EXIT_FAILURE);
3020         }
3021
3022         if (index == MGMT_INDEX_NONE)
3023                 index = 0;
3024
3025         memset(&cp, 0, sizeof(cp));
3026         str2ba(argv[0], &cp.addr.bdaddr);
3027         cp.addr.type = type;
3028
3029         if (send_cmd(mgmt, MGMT_OP_UNBLOCK_DEVICE, index, sizeof(cp), &cp,
3030                                                         block_rsp) == 0) {
3031                 error("Unable to send unblock_device cmd");
3032                 return noninteractive_quit(EXIT_FAILURE);
3033         }
3034 }
3035
3036 static void cmd_add_uuid(struct mgmt *mgmt, uint16_t index, int argc,
3037                                                         char **argv)
3038 {
3039         struct mgmt_cp_add_uuid cp;
3040         uint128_t uint128;
3041         uuid_t uuid, uuid128;
3042
3043         if (argc < 3) {
3044                 print("UUID and service hint needed");
3045                 return noninteractive_quit(EXIT_FAILURE);
3046         }
3047
3048         if (index == MGMT_INDEX_NONE)
3049                 index = 0;
3050
3051         if (bt_string2uuid(&uuid, argv[1]) < 0) {
3052                 print("Invalid UUID: %s", argv[1]);
3053                 return noninteractive_quit(EXIT_FAILURE);
3054         }
3055
3056         memset(&cp, 0, sizeof(cp));
3057
3058         uuid_to_uuid128(&uuid128, &uuid);
3059         ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
3060         htob128(&uint128, (uint128_t *) cp.uuid);
3061
3062         cp.svc_hint = atoi(argv[2]);
3063
3064         if (send_cmd(mgmt, MGMT_OP_ADD_UUID, index, sizeof(cp), &cp,
3065                                                         class_rsp) == 0) {
3066                 error("Unable to send add_uuid cmd");
3067                 return noninteractive_quit(EXIT_FAILURE);
3068         }
3069 }
3070
3071 static void cmd_remove_uuid(struct mgmt *mgmt, uint16_t index, int argc,
3072                                                                 char **argv)
3073 {
3074         struct mgmt_cp_remove_uuid cp;
3075         uint128_t uint128;
3076         uuid_t uuid, uuid128;
3077
3078         if (argc < 2) {
3079                 print("UUID needed");
3080                 return noninteractive_quit(EXIT_FAILURE);
3081         }
3082
3083         if (index == MGMT_INDEX_NONE)
3084                 index = 0;
3085
3086         if (bt_string2uuid(&uuid, argv[1]) < 0) {
3087                 print("Invalid UUID: %s", argv[1]);
3088                 return noninteractive_quit(EXIT_FAILURE);
3089         }
3090
3091         memset(&cp, 0, sizeof(cp));
3092
3093         uuid_to_uuid128(&uuid128, &uuid);
3094         ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
3095         htob128(&uint128, (uint128_t *) cp.uuid);
3096
3097         if (send_cmd(mgmt, MGMT_OP_REMOVE_UUID, index, sizeof(cp), &cp,
3098                                                         class_rsp) == 0) {
3099                 error("Unable to send remove_uuid cmd");
3100                 return noninteractive_quit(EXIT_FAILURE);
3101         }
3102 }
3103
3104 static void cmd_clr_uuids(struct mgmt *mgmt, uint16_t index, int argc,
3105                                                                 char **argv)
3106 {
3107         char *uuid_any = "00000000-0000-0000-0000-000000000000";
3108         char *rm_argv[] = { "rm-uuid", uuid_any, NULL };
3109
3110         cmd_remove_uuid(mgmt, index, 2, rm_argv);
3111 }
3112
3113 static void local_oob_rsp(uint8_t status, uint16_t len, const void *param,
3114                                                         void *user_data)
3115 {
3116         const struct mgmt_rp_read_local_oob_data *rp = param;
3117         char str[33];
3118
3119         if (status != 0) {
3120                 error("Read Local OOB Data failed with status 0x%02x (%s)",
3121                                                 status, mgmt_errstr(status));
3122                 return noninteractive_quit(EXIT_FAILURE);
3123         }
3124
3125         if (len < sizeof(*rp)) {
3126                 error("Too small (%u bytes) read_local_oob rsp", len);
3127                 return noninteractive_quit(EXIT_FAILURE);
3128         }
3129
3130         bin2hex(rp->hash192, 16, str, sizeof(str));
3131         print("Hash C from P-192: %s", str);
3132
3133         bin2hex(rp->rand192, 16, str, sizeof(str));
3134         print("Randomizer R with P-192: %s", str);
3135
3136         if (len < sizeof(*rp))
3137                 return noninteractive_quit(EXIT_SUCCESS);
3138
3139         bin2hex(rp->hash256, 16, str, sizeof(str));
3140         print("Hash C from P-256: %s", str);
3141
3142         bin2hex(rp->rand256, 16, str, sizeof(str));
3143         print("Randomizer R with P-256: %s", str);
3144
3145         noninteractive_quit(EXIT_SUCCESS);
3146 }
3147
3148 static void cmd_local_oob(struct mgmt *mgmt, uint16_t index,
3149                                                 int argc, char **argv)
3150 {
3151         if (index == MGMT_INDEX_NONE)
3152                 index = 0;
3153
3154         if (mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_DATA, index, 0, NULL,
3155                                         local_oob_rsp, NULL, NULL) == 0) {
3156                 error("Unable to send read_local_oob cmd");
3157                 return noninteractive_quit(EXIT_FAILURE);
3158         }
3159 }
3160
3161 static void remote_oob_rsp(uint8_t status, uint16_t len, const void *param,
3162                                                         void *user_data)
3163 {
3164         const struct mgmt_addr_info *rp = param;
3165         char addr[18];
3166
3167         if (status != 0) {
3168                 error("Add Remote OOB Data failed: 0x%02x (%s)",
3169                                                 status, mgmt_errstr(status));
3170                 return;
3171         }
3172
3173         if (len < sizeof(*rp)) {
3174                 error("Too small (%u bytes) add_remote_oob rsp", len);
3175                 return;
3176         }
3177
3178         ba2str(&rp->bdaddr, addr);
3179         print("Remote OOB data added for %s (%u)", addr, rp->type);
3180 }
3181
3182 static void remote_oob_usage(void)
3183 {
3184         print("Usage: remote-oob [-t <addr_type>] "
3185                 "[-r <rand192>] [-h <hash192>] [-R <rand256>] [-H <hash256>] "
3186                 "<addr>");
3187 }
3188
3189 static struct option remote_oob_opt[] = {
3190         { "help",       0, 0, 'h' },
3191         { "type",       1, 0, 't' },
3192         { 0, 0, 0, 0 }
3193 };
3194
3195 static void cmd_remote_oob(struct mgmt *mgmt, uint16_t index,
3196                                                 int argc, char **argv)
3197 {
3198         struct mgmt_cp_add_remote_oob_data cp;
3199         int opt;
3200
3201         memset(&cp, 0, sizeof(cp));
3202         cp.addr.type = BDADDR_BREDR;
3203
3204         while ((opt = getopt_long(argc, argv, "+t:r:R:h:H:",
3205                                         remote_oob_opt, NULL)) != -1) {
3206                 switch (opt) {
3207                 case 't':
3208                         cp.addr.type = strtol(optarg, NULL, 0);
3209                         break;
3210                 case 'r':
3211                         hex2bin(optarg, cp.rand192, 16);
3212                         break;
3213                 case 'h':
3214                         hex2bin(optarg, cp.hash192, 16);
3215                         break;
3216                 case 'R':
3217                         hex2bin(optarg, cp.rand256, 16);
3218                         break;
3219                 case 'H':
3220                         hex2bin(optarg, cp.hash256, 16);
3221                         break;
3222                 default:
3223                         remote_oob_usage();
3224                         return noninteractive_quit(EXIT_FAILURE);
3225                 }
3226         }
3227
3228         argc -= optind;
3229         argv += optind;
3230         optind = 0;
3231
3232         if (argc < 1) {
3233                 remote_oob_usage();
3234                 return noninteractive_quit(EXIT_FAILURE);
3235         }
3236
3237         if (index == MGMT_INDEX_NONE)
3238                 index = 0;
3239
3240         str2ba(argv[0], &cp.addr.bdaddr);
3241
3242         print("Adding OOB data for %s (%s)", argv[0], typestr(cp.addr.type));
3243
3244         if (mgmt_send(mgmt, MGMT_OP_ADD_REMOTE_OOB_DATA, index,
3245                                 sizeof(cp), &cp, remote_oob_rsp,
3246                                 NULL, NULL) == 0) {
3247                 error("Unable to send add_remote_oob cmd");
3248                 return noninteractive_quit(EXIT_FAILURE);
3249         }
3250 }
3251
3252 static void did_rsp(uint8_t status, uint16_t len, const void *param,
3253                                                         void *user_data)
3254 {
3255         if (status != 0)
3256                 error("Set Device ID failed with status 0x%02x (%s)",
3257                                                 status, mgmt_errstr(status));
3258         else
3259                 print("Device ID successfully set");
3260
3261         noninteractive_quit(EXIT_SUCCESS);
3262 }
3263
3264 static void did_usage(void)
3265 {
3266         print("Usage: did <source>:<vendor>:<product>:<version>");
3267         print("       possible source values: bluetooth, usb");
3268 }
3269
3270 static void cmd_did(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
3271 {
3272         struct mgmt_cp_set_device_id cp;
3273         uint16_t vendor, product, version , source;
3274         int result;
3275
3276         if (argc < 2) {
3277                 did_usage();
3278                 return noninteractive_quit(EXIT_FAILURE);
3279         }
3280
3281         result = sscanf(argv[1], "bluetooth:%4hx:%4hx:%4hx", &vendor, &product,
3282                                                                 &version);
3283         if (result == 3) {
3284                 source = 0x0001;
3285                 goto done;
3286         }
3287
3288         result = sscanf(argv[1], "usb:%4hx:%4hx:%4hx", &vendor, &product,
3289                                                                 &version);
3290         if (result == 3) {
3291                 source = 0x0002;
3292                 goto done;
3293         }
3294
3295         did_usage();
3296         return noninteractive_quit(EXIT_FAILURE);
3297
3298 done:
3299         if (index == MGMT_INDEX_NONE)
3300                 index = 0;
3301
3302         cp.source = htobs(source);
3303         cp.vendor = htobs(vendor);
3304         cp.product = htobs(product);
3305         cp.version = htobs(version);
3306
3307         if (mgmt_send(mgmt, MGMT_OP_SET_DEVICE_ID, index, sizeof(cp), &cp,
3308                                                 did_rsp, NULL, NULL) == 0) {
3309                 error("Unable to send set_device_id cmd");
3310                 return noninteractive_quit(EXIT_FAILURE);
3311         }
3312 }
3313
3314 static void static_addr_rsp(uint8_t status, uint16_t len, const void *param,
3315                                                         void *user_data)
3316 {
3317         if (status != 0)
3318                 error("Set static address failed with status 0x%02x (%s)",
3319                                                 status, mgmt_errstr(status));
3320         else
3321                 print("Static address successfully set");
3322
3323         noninteractive_quit(EXIT_SUCCESS);
3324 }
3325
3326 static void static_addr_usage(void)
3327 {
3328         print("Usage: static-addr <address>");
3329 }
3330
3331 static void cmd_static_addr(struct mgmt *mgmt, uint16_t index,
3332                                                         int argc, char **argv)
3333 {
3334         struct mgmt_cp_set_static_address cp;
3335
3336         if (argc < 2) {
3337                 static_addr_usage();
3338                 return noninteractive_quit(EXIT_FAILURE);
3339         }
3340
3341         if (index == MGMT_INDEX_NONE)
3342                 index = 0;
3343
3344         str2ba(argv[1], &cp.bdaddr);
3345
3346         if (mgmt_send(mgmt, MGMT_OP_SET_STATIC_ADDRESS, index, sizeof(cp), &cp,
3347                                         static_addr_rsp, NULL, NULL) == 0) {
3348                 error("Unable to send set_static_address cmd");
3349                 return noninteractive_quit(EXIT_FAILURE);
3350         }
3351 }
3352
3353 static void options_rsp(uint16_t op, uint16_t id, uint8_t status,
3354                                         uint16_t len, const void *param)
3355 {
3356         const uint32_t *rp = param;
3357
3358         if (status != 0) {
3359                 error("%s for hci%u failed with status 0x%02x (%s)",
3360                         mgmt_opstr(op), id, status, mgmt_errstr(status));
3361                 return noninteractive_quit(EXIT_FAILURE);
3362         }
3363
3364         if (len < sizeof(*rp)) {
3365                 error("Too small %s response (%u bytes)",
3366                                                         mgmt_opstr(op), len);
3367                 return noninteractive_quit(EXIT_FAILURE);
3368         }
3369
3370         print("hci%u %s complete, options: %s", id, mgmt_opstr(op),
3371                                                 options2str(get_le32(rp)));
3372
3373         noninteractive_quit(EXIT_SUCCESS);
3374 }
3375
3376 static void cmd_public_addr(struct mgmt *mgmt, uint16_t index,
3377                                                 int argc, char **argv)
3378 {
3379         struct mgmt_cp_set_public_address cp;
3380
3381         if (argc < 2) {
3382                 print("Usage: public-addr <address>");
3383                 return noninteractive_quit(EXIT_FAILURE);
3384         }
3385
3386         if (index == MGMT_INDEX_NONE)
3387                 index = 0;
3388
3389         str2ba(argv[1], &cp.bdaddr);
3390
3391         if (send_cmd(mgmt, MGMT_OP_SET_PUBLIC_ADDRESS, index, sizeof(cp), &cp,
3392                                                         options_rsp) == 0) {
3393                 error("Unable to send Set Public Address cmd");
3394                 return noninteractive_quit(EXIT_FAILURE);
3395         }
3396 }
3397
3398 static void cmd_ext_config(struct mgmt *mgmt, uint16_t index,
3399                                                 int argc, char **argv)
3400 {
3401         struct mgmt_cp_set_external_config cp;
3402
3403         if (argc < 2) {
3404                 print("Specify \"on\" or \"off\"");
3405                 return noninteractive_quit(EXIT_FAILURE);
3406         }
3407
3408         if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
3409                 cp.config = 0x01;
3410         else if (strcasecmp(argv[1], "off") == 0)
3411                 cp.config = 0x00;
3412         else
3413                 cp.config = atoi(argv[1]);
3414
3415         if (index == MGMT_INDEX_NONE)
3416                 index = 0;
3417
3418         if (send_cmd(mgmt, MGMT_OP_SET_EXTERNAL_CONFIG, index, sizeof(cp), &cp,
3419                                                         options_rsp) == 0) {
3420                 error("Unable to send Set External Config cmd");
3421                 return noninteractive_quit(EXIT_FAILURE);
3422         }
3423 }
3424
3425 static void cmd_debug_keys(struct mgmt *mgmt, uint16_t index,
3426                                                 int argc, char **argv)
3427 {
3428         cmd_setting(mgmt, index, MGMT_OP_SET_DEBUG_KEYS, argc, argv);
3429 }
3430
3431 static void conn_info_rsp(uint8_t status, uint16_t len, const void *param,
3432                                                         void *user_data)
3433 {
3434         const struct mgmt_rp_get_conn_info *rp = param; char addr[18];
3435
3436         if (len == 0 && status != 0) {
3437                 error("Get Conn Info failed, status 0x%02x (%s)",
3438                                                 status, mgmt_errstr(status));
3439                 return noninteractive_quit(EXIT_FAILURE);
3440         }
3441
3442         if (len < sizeof(*rp)) {
3443                 error("Unexpected Get Conn Info len %u", len);
3444                 return noninteractive_quit(EXIT_FAILURE);
3445         }
3446
3447         ba2str(&rp->addr.bdaddr, addr);
3448
3449         if (status) {
3450                 error("Get Conn Info for %s (%s) failed. status 0x%02x (%s)",
3451                                                 addr, typestr(rp->addr.type),
3452                                                 status, mgmt_errstr(status));
3453         } else {
3454                 print("Connection Information for %s (%s)",
3455                                                 addr, typestr(rp->addr.type));
3456                 print("\tRSSI %d\tTX power %d\tmaximum TX power %d",
3457                                 rp->rssi, rp->tx_power, rp->max_tx_power);
3458         }
3459
3460         noninteractive_quit(EXIT_SUCCESS);
3461 }
3462
3463 static void conn_info_usage(void)
3464 {
3465         print("Usage: conn-info [-t type] <remote address>");
3466 }
3467
3468 static struct option conn_info_options[] = {
3469         { "help",       0, 0, 'h' },
3470         { "type",       1, 0, 't' },
3471         { 0, 0, 0, 0 }
3472 };
3473
3474 static void cmd_conn_info(struct mgmt *mgmt, uint16_t index,
3475                                                 int argc, char **argv)
3476 {
3477         struct mgmt_cp_get_conn_info cp;
3478         uint8_t type = BDADDR_BREDR;
3479         int opt;
3480
3481         while ((opt = getopt_long(argc, argv, "+t:h", conn_info_options,
3482                                                                 NULL)) != -1) {
3483                 switch (opt) {
3484                 case 't':
3485                         type = strtol(optarg, NULL, 0);
3486                         break;
3487                 case 'h':
3488                         conn_info_usage();
3489                         return noninteractive_quit(EXIT_SUCCESS);
3490                 default:
3491                         conn_info_usage();
3492                         return noninteractive_quit(EXIT_FAILURE);
3493                 }
3494         }
3495
3496         argc -= optind;
3497         argv += optind;
3498         optind = 0;
3499
3500         if (argc < 1) {
3501                 conn_info_usage();
3502                 return noninteractive_quit(EXIT_FAILURE);
3503         }
3504
3505         if (index == MGMT_INDEX_NONE)
3506                 index = 0;
3507
3508         memset(&cp, 0, sizeof(cp));
3509         str2ba(argv[0], &cp.addr.bdaddr);
3510         cp.addr.type = type;
3511
3512         if (mgmt_send(mgmt, MGMT_OP_GET_CONN_INFO, index, sizeof(cp), &cp,
3513                                         conn_info_rsp, NULL, NULL) == 0) {
3514                 error("Unable to send get_conn_info cmd");
3515                 return noninteractive_quit(EXIT_FAILURE);
3516         }
3517 }
3518
3519 static void io_cap_rsp(uint8_t status, uint16_t len, const void *param,
3520                                                         void *user_data)
3521 {
3522         if (status != 0)
3523                 error("Could not set IO Capability with status 0x%02x (%s)",
3524                                                 status, mgmt_errstr(status));
3525         else
3526                 print("IO Capabilities successfully set");
3527
3528         noninteractive_quit(EXIT_SUCCESS);
3529 }
3530
3531 static void io_cap_usage(void)
3532 {
3533         print("Usage: io-cap <cap>");
3534 }
3535
3536 static void cmd_io_cap(struct mgmt *mgmt, uint16_t index,
3537                                                 int argc, char **argv)
3538 {
3539         struct mgmt_cp_set_io_capability cp;
3540         uint8_t cap;
3541
3542         if (argc < 2) {
3543                 io_cap_usage();
3544                 return noninteractive_quit(EXIT_FAILURE);
3545         }
3546
3547         if (index == MGMT_INDEX_NONE)
3548                 index = 0;
3549
3550         cap = strtol(argv[1], NULL, 0);
3551         memset(&cp, 0, sizeof(cp));
3552         cp.io_capability = cap;
3553
3554         if (mgmt_send(mgmt, MGMT_OP_SET_IO_CAPABILITY, index, sizeof(cp), &cp,
3555                                         io_cap_rsp, NULL, NULL) == 0) {
3556                 error("Unable to send set-io-cap cmd");
3557                 return noninteractive_quit(EXIT_FAILURE);
3558         }
3559 }
3560
3561 static void scan_params_rsp(uint8_t status, uint16_t len, const void *param,
3562                                                         void *user_data)
3563 {
3564         if (status != 0)
3565                 error("Set scan parameters failed with status 0x%02x (%s)",
3566                                                 status, mgmt_errstr(status));
3567         else
3568                 print("Scan parameters successfully set");
3569
3570         noninteractive_quit(EXIT_SUCCESS);
3571 }
3572
3573 static void scan_params_usage(void)
3574 {
3575         print("Usage: scan-params <interval> <window>");
3576 }
3577
3578 static void cmd_scan_params(struct mgmt *mgmt, uint16_t index,
3579                                                         int argc, char **argv)
3580 {
3581         struct mgmt_cp_set_scan_params cp;
3582
3583         if (argc < 3) {
3584                 scan_params_usage();
3585                 return noninteractive_quit(EXIT_FAILURE);
3586         }
3587
3588         if (index == MGMT_INDEX_NONE)
3589                 index = 0;
3590
3591         cp.interval = strtol(argv[1], NULL, 0);
3592         cp.window = strtol(argv[2], NULL, 0);
3593
3594         if (mgmt_send(mgmt, MGMT_OP_SET_SCAN_PARAMS, index, sizeof(cp), &cp,
3595                                         scan_params_rsp, NULL, NULL) == 0) {
3596                 error("Unable to send set_scan_params cmd");
3597                 return noninteractive_quit(EXIT_FAILURE);
3598         }
3599 }
3600
3601 static void clock_info_rsp(uint8_t status, uint16_t len, const void *param,
3602                                                         void *user_data)
3603 {
3604         const struct mgmt_rp_get_clock_info *rp = param;
3605
3606         if (len < sizeof(*rp)) {
3607                 error("Unexpected Get Clock Info len %u", len);
3608                 return noninteractive_quit(EXIT_FAILURE);
3609         }
3610
3611         if (status) {
3612                 error("Get Clock Info failed with status 0x%02x (%s)",
3613                                                 status, mgmt_errstr(status));
3614                 return noninteractive_quit(EXIT_FAILURE);
3615         }
3616
3617         print("Local Clock:   %u", le32_to_cpu(rp->local_clock));
3618         print("Piconet Clock: %u", le32_to_cpu(rp->piconet_clock));
3619         print("Accurary:      %u", le16_to_cpu(rp->accuracy));
3620
3621         noninteractive_quit(EXIT_SUCCESS);
3622 }
3623
3624 static void cmd_clock_info(struct mgmt *mgmt, uint16_t index,
3625                                                         int argc, char **argv)
3626 {
3627         struct mgmt_cp_get_clock_info cp;
3628
3629         if (index == MGMT_INDEX_NONE)
3630                 index = 0;
3631
3632         memset(&cp, 0, sizeof(cp));
3633
3634         if (argc > 1)
3635                 str2ba(argv[1], &cp.addr.bdaddr);
3636
3637         if (mgmt_send(mgmt, MGMT_OP_GET_CLOCK_INFO, index, sizeof(cp), &cp,
3638                                         clock_info_rsp, NULL, NULL) == 0) {
3639                 error("Unable to send get_clock_info cmd");
3640                 return noninteractive_quit(EXIT_FAILURE);
3641         }
3642 }
3643
3644 static void add_device_rsp(uint8_t status, uint16_t len, const void *param,
3645                                                         void *user_data)
3646 {
3647         if (status != 0)
3648                 error("Add device failed with status 0x%02x (%s)",
3649                                                 status, mgmt_errstr(status));
3650         noninteractive_quit(EXIT_SUCCESS);
3651 }
3652
3653 static void add_device_usage(void)
3654 {
3655         print("Usage: add-device [-a action] [-t type] <address>");
3656 }
3657
3658 static struct option add_device_options[] = {
3659         { "help",       0, 0, 'h' },
3660         { "action",     1, 0, 'a' },
3661         { "type",       1, 0, 't' },
3662         { 0, 0, 0, 0 }
3663 };
3664
3665 static void cmd_add_device(struct mgmt *mgmt, uint16_t index,
3666                                                 int argc, char **argv)
3667 {
3668         struct mgmt_cp_add_device cp;
3669         uint8_t action = 0x00;
3670         uint8_t type = BDADDR_BREDR;
3671         char addr[18];
3672         int opt;
3673
3674         while ((opt = getopt_long(argc, argv, "+a:t:h", add_device_options,
3675                                                                 NULL)) != -1) {
3676                 switch (opt) {
3677                 case 'a':
3678                         action = strtol(optarg, NULL, 0);
3679                         break;
3680                 case 't':
3681                         type = strtol(optarg, NULL, 0);
3682                         break;
3683                 case 'h':
3684                         add_device_usage();
3685                         return noninteractive_quit(EXIT_SUCCESS);
3686                 default:
3687                         add_device_usage();
3688                         return noninteractive_quit(EXIT_FAILURE);
3689                 }
3690         }
3691
3692         argc -= optind;
3693         argv += optind;
3694         optind = 0;
3695
3696         if (argc < 1) {
3697                 add_device_usage();
3698                 return noninteractive_quit(EXIT_FAILURE);
3699         }
3700
3701         if (index == MGMT_INDEX_NONE)
3702                 index = 0;
3703
3704         memset(&cp, 0, sizeof(cp));
3705         str2ba(argv[0], &cp.addr.bdaddr);
3706         cp.addr.type = type;
3707         cp.action = action;
3708
3709         ba2str(&cp.addr.bdaddr, addr);
3710         print("Adding device with %s (%s)", addr, typestr(cp.addr.type));
3711
3712         if (mgmt_send(mgmt, MGMT_OP_ADD_DEVICE, index, sizeof(cp), &cp,
3713                                         add_device_rsp, NULL, NULL) == 0) {
3714                 error("Unable to send add device command");
3715                 return noninteractive_quit(EXIT_FAILURE);
3716         }
3717 }
3718
3719 static void remove_device_rsp(uint8_t status, uint16_t len, const void *param,
3720                                                         void *user_data)
3721 {
3722         if (status != 0)
3723                 error("Remove device failed with status 0x%02x (%s)",
3724                                                 status, mgmt_errstr(status));
3725         noninteractive_quit(EXIT_SUCCESS);
3726 }
3727
3728 static void del_device_usage(void)
3729 {
3730         print("Usage: del-device [-t type] <address>");
3731 }
3732
3733 static struct option del_device_options[] = {
3734         { "help",       0, 0, 'h' },
3735         { "type",       1, 0, 't' },
3736         { 0, 0, 0, 0 }
3737 };
3738
3739 static void cmd_del_device(struct mgmt *mgmt, uint16_t index,
3740                                                 int argc, char **argv)
3741 {
3742         struct mgmt_cp_remove_device cp;
3743         uint8_t type = BDADDR_BREDR;
3744         char addr[18];
3745         int opt;
3746
3747         while ((opt = getopt_long(argc, argv, "+t:h", del_device_options,
3748                                                                 NULL)) != -1) {
3749                 switch (opt) {
3750                 case 't':
3751                         type = strtol(optarg, NULL, 0);
3752                         break;
3753                 case 'h':
3754                         del_device_usage();
3755                         return noninteractive_quit(EXIT_SUCCESS);
3756                 default:
3757                         del_device_usage();
3758                         return noninteractive_quit(EXIT_FAILURE);
3759                 }
3760         }
3761
3762         argc -= optind;
3763         argv += optind;
3764         optind = 0;
3765
3766         if (argc < 1) {
3767                 del_device_usage();
3768                 return noninteractive_quit(EXIT_FAILURE);
3769         }
3770
3771         if (index == MGMT_INDEX_NONE)
3772                 index = 0;
3773
3774         memset(&cp, 0, sizeof(cp));
3775         str2ba(argv[0], &cp.addr.bdaddr);
3776         cp.addr.type = type;
3777
3778         ba2str(&cp.addr.bdaddr, addr);
3779         print("Removing device with %s (%s)", addr, typestr(cp.addr.type));
3780
3781         if (mgmt_send(mgmt, MGMT_OP_REMOVE_DEVICE, index, sizeof(cp), &cp,
3782                                         remove_device_rsp, NULL, NULL) == 0) {
3783                 error("Unable to send remove device command");
3784                 return noninteractive_quit(EXIT_FAILURE);
3785         }
3786 }
3787
3788 static void cmd_clr_devices(struct mgmt *mgmt, uint16_t index,
3789                                                 int argc, char **argv)
3790 {
3791         char *bdaddr_any = "00:00:00:00:00:00";
3792         char *rm_argv[] = { "del-device", bdaddr_any, NULL };
3793
3794         cmd_del_device(mgmt, index, 2, rm_argv);
3795 }
3796
3797 static void local_oob_ext_rsp(uint8_t status, uint16_t len, const void *param,
3798                                                         void *user_data)
3799 {
3800         const struct mgmt_rp_read_local_oob_ext_data *rp = param;
3801         uint16_t eir_len;
3802
3803         if (status != 0) {
3804                 error("Read Local OOB Ext Data failed with status 0x%02x (%s)",
3805                                                 status, mgmt_errstr(status));
3806                 return noninteractive_quit(EXIT_FAILURE);
3807         }
3808
3809         if (len < sizeof(*rp)) {
3810                 error("Too small (%u bytes) read_local_oob_ext rsp", len);
3811                 return noninteractive_quit(EXIT_FAILURE);
3812         }
3813
3814         eir_len = le16_to_cpu(rp->eir_len);
3815         if (len != sizeof(*rp) + eir_len) {
3816                 error("local_oob_ext: expected %zu bytes, got %u bytes",
3817                                                 sizeof(*rp) + eir_len, len);
3818                 return noninteractive_quit(EXIT_FAILURE);
3819         }
3820
3821         print_eir(rp->eir, eir_len);
3822
3823         noninteractive_quit(EXIT_SUCCESS);
3824 }
3825
3826 static void cmd_bredr_oob(struct mgmt *mgmt, uint16_t index,
3827                                                 int argc, char **argv)
3828 {
3829         struct mgmt_cp_read_local_oob_ext_data cp;
3830
3831         if (index == MGMT_INDEX_NONE)
3832                 index = 0;
3833
3834         cp.type = SCAN_TYPE_BREDR;
3835
3836         if (!mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
3837                                         index, sizeof(cp), &cp,
3838                                         local_oob_ext_rsp, NULL, NULL)) {
3839                 error("Unable to send read_local_oob_ext cmd");
3840                 return noninteractive_quit(EXIT_FAILURE);
3841         }
3842 }
3843
3844 static void cmd_le_oob(struct mgmt *mgmt, uint16_t index,
3845                                                 int argc, char **argv)
3846 {
3847         struct mgmt_cp_read_local_oob_ext_data cp;
3848
3849         if (index == MGMT_INDEX_NONE)
3850                 index = 0;
3851
3852         cp.type = SCAN_TYPE_LE;
3853
3854         if (!mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
3855                                         index, sizeof(cp), &cp,
3856                                         local_oob_ext_rsp, NULL, NULL)) {
3857                 error("Unable to send read_local_oob_ext cmd");
3858                 return noninteractive_quit(EXIT_FAILURE);
3859         }
3860 }
3861
3862 static const char *adv_flags_str[] = {
3863                                 "connectable",
3864                                 "general-discoverable",
3865                                 "limited-discoverable",
3866                                 "managed-flags",
3867                                 "tx-power",
3868                                 "scan-rsp-appearance",
3869                                 "scan-rsp-local-name",
3870 };
3871
3872 static const char *adv_flags2str(uint32_t flags)
3873 {
3874         static char str[256];
3875         unsigned i;
3876         int off;
3877
3878         off = 0;
3879         str[0] = '\0';
3880
3881         for (i = 0; i < NELEM(adv_flags_str); i++) {
3882                 if ((flags & (1 << i)) != 0)
3883                         off += snprintf(str + off, sizeof(str) - off, "%s ",
3884                                                         adv_flags_str[i]);
3885         }
3886
3887         return str;
3888 }
3889
3890 static void adv_features_rsp(uint8_t status, uint16_t len, const void *param,
3891                                                         void *user_data)
3892 {
3893         const struct mgmt_rp_read_adv_features *rp = param;
3894         uint32_t supported_flags;
3895
3896         if (status != 0) {
3897                 error("Reading adv features failed with status 0x%02x (%s)",
3898                                                 status, mgmt_errstr(status));
3899                 return noninteractive_quit(EXIT_FAILURE);
3900         }
3901
3902         if (len < sizeof(*rp)) {
3903                 error("Too small adv features reply (%u bytes)", len);
3904                 return noninteractive_quit(EXIT_FAILURE);
3905         }
3906
3907         if (len < sizeof(*rp) + rp->num_instances * sizeof(uint8_t)) {
3908                 error("Instances count (%u) doesn't match reply length (%u)",
3909                                                         rp->num_instances, len);
3910                 return noninteractive_quit(EXIT_FAILURE);
3911         }
3912
3913         supported_flags = le32_to_cpu(rp->supported_flags);
3914         print("Supported flags: %s", adv_flags2str(supported_flags));
3915         print("Max advertising data len: %u", rp->max_adv_data_len);
3916         print("Max scan response data len: %u", rp->max_scan_rsp_len);
3917         print("Max instances: %u", rp->max_instances);
3918
3919         print("Instances list with %u item%s", rp->num_instances,
3920                                         rp->num_instances != 1 ? "s" : "");
3921
3922         return noninteractive_quit(EXIT_SUCCESS);
3923 }
3924
3925 static void cmd_advinfo(struct mgmt *mgmt, uint16_t index,
3926                                                 int argc, char **argv)
3927 {
3928         if (index == MGMT_INDEX_NONE)
3929                 index = 0;
3930
3931         if (!mgmt_send(mgmt, MGMT_OP_READ_ADV_FEATURES, index, 0, NULL,
3932                                         adv_features_rsp, NULL, NULL)) {
3933                 error("Unable to send advertising features command");
3934                 return noninteractive_quit(EXIT_FAILURE);
3935         }
3936 }
3937
3938 static void adv_size_info_rsp(uint8_t status, uint16_t len, const void *param,
3939                                                         void *user_data)
3940 {
3941         const struct mgmt_rp_get_adv_size_info *rp = param;
3942         uint32_t flags;
3943
3944         if (status != 0) {
3945                 error("Reading adv size info failed with status 0x%02x (%s)",
3946                                                 status, mgmt_errstr(status));
3947                 return noninteractive_quit(EXIT_FAILURE);
3948         }
3949
3950         if (len < sizeof(*rp)) {
3951                 error("Too small adv size info reply (%u bytes)", len);
3952                 return noninteractive_quit(EXIT_FAILURE);
3953         }
3954
3955         flags = le32_to_cpu(rp->flags);
3956         print("Instance: %u", rp->instance);
3957         print("Flags: %s", adv_flags2str(flags));
3958         print("Max advertising data len: %u", rp->max_adv_data_len);
3959         print("Max scan response data len: %u", rp->max_scan_rsp_len);
3960
3961         return noninteractive_quit(EXIT_SUCCESS);
3962 }
3963
3964 static void advsize_usage(void)
3965 {
3966         print("Usage: advsize [options] <instance_id>\nOptions:\n"
3967                 "\t -c, --connectable         \"connectable\" flag\n"
3968                 "\t -g, --general-discov      \"general-discoverable\" flag\n"
3969                 "\t -l, --limited-discov      \"limited-discoverable\" flag\n"
3970                 "\t -m, --managed-flags       \"managed-flags\" flag\n"
3971                 "\t -p, --tx-power            \"tx-power\" flag\n"\
3972                 "\t -a, --appearance          \"appearance\" flag\n"\
3973                 "\t -n, --local-name          \"local-name\" flag");
3974 }
3975
3976 static struct option advsize_options[] = {
3977         { "help",               0, 0, 'h' },
3978         { "connectable",        0, 0, 'c' },
3979         { "general-discov",     0, 0, 'g' },
3980         { "limited-discov",     0, 0, 'l' },
3981         { "managed-flags",      0, 0, 'm' },
3982         { "tx-power",           0, 0, 'p' },
3983         { "appearance",         0, 0, 'a' },
3984         { "local-name",         0, 0, 'n' },
3985         { 0, 0, 0, 0}
3986 };
3987
3988 static void cmd_advsize(struct mgmt *mgmt, uint16_t index,
3989                                                 int argc, char **argv)
3990 {
3991         struct mgmt_cp_get_adv_size_info cp;
3992         uint8_t instance;
3993         uint32_t flags = 0;
3994         int opt;
3995
3996         while ((opt = getopt_long(argc, argv, "+cglmphna",
3997                                                 advsize_options, NULL)) != -1) {
3998                 switch (opt) {
3999                 case 'c':
4000                         flags |= MGMT_ADV_FLAG_CONNECTABLE;
4001                         break;
4002                 case 'g':
4003                         flags |= MGMT_ADV_FLAG_DISCOV;
4004                         break;
4005                 case 'l':
4006                         flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
4007                         break;
4008                 case 'm':
4009                         flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
4010                         break;
4011                 case 'p':
4012                         flags |= MGMT_ADV_FLAG_TX_POWER;
4013                         break;
4014                 case 'a':
4015                         flags |= MGMT_ADV_FLAG_APPEARANCE;
4016                         break;
4017                 case 'n':
4018                         flags |= MGMT_ADV_FLAG_LOCAL_NAME;
4019                         break;
4020                 default:
4021                         advsize_usage();
4022                         return noninteractive_quit(EXIT_FAILURE);
4023                 }
4024         }
4025
4026         argc -= optind;
4027         argv += optind;
4028         optind = 0;
4029
4030         if (argc != 1) {
4031                 advsize_usage();
4032                 return noninteractive_quit(EXIT_FAILURE);
4033         }
4034
4035         instance = strtol(argv[0], NULL, 0);
4036
4037         if (index == MGMT_INDEX_NONE)
4038                 index = 0;
4039
4040         memset(&cp, 0, sizeof(cp));
4041
4042         cp.instance = instance;
4043         cp.flags = cpu_to_le32(flags);
4044
4045         if (!mgmt_send(mgmt, MGMT_OP_GET_ADV_SIZE_INFO, index, sizeof(cp), &cp,
4046                                         adv_size_info_rsp, NULL, NULL)) {
4047                 error("Unable to send advertising size info command");
4048                 return noninteractive_quit(EXIT_FAILURE);
4049         }
4050 }
4051
4052 static void add_adv_rsp(uint8_t status, uint16_t len, const void *param,
4053                                                                 void *user_data)
4054 {
4055         const struct mgmt_rp_add_advertising *rp = param;
4056
4057         if (status != 0) {
4058                 error("Add Advertising failed with status 0x%02x (%s)",
4059                                                 status, mgmt_errstr(status));
4060                 return noninteractive_quit(EXIT_FAILURE);
4061         }
4062
4063         if (len != sizeof(*rp)) {
4064                 error("Invalid Add Advertising response length (%u)", len);
4065                 return noninteractive_quit(EXIT_FAILURE);
4066         }
4067
4068         print("Instance added: %u", rp->instance);
4069
4070         return noninteractive_quit(EXIT_SUCCESS);
4071 }
4072
4073 static void add_adv_usage(void)
4074 {
4075         print("Usage: add-adv [options] <instance_id>\nOptions:\n"
4076                 "\t -u, --uuid <uuid>         Service UUID\n"
4077                 "\t -d, --adv-data <data>     Advertising Data bytes\n"
4078                 "\t -s, --scan-rsp <data>     Scan Response Data bytes\n"
4079                 "\t -t, --timeout <timeout>   Timeout in seconds\n"
4080                 "\t -D, --duration <duration> Duration in seconds\n"
4081                 "\t -c, --connectable         \"connectable\" flag\n"
4082                 "\t -g, --general-discov      \"general-discoverable\" flag\n"
4083                 "\t -l, --limited-discov      \"limited-discoverable\" flag\n"
4084                 "\t -n, --scan-rsp-local-name \"local-name\" flag\n"
4085                 "\t -a, --scan-rsp-appearance \"appearance\" flag\n"
4086                 "\t -m, --managed-flags       \"managed-flags\" flag\n"
4087                 "\t -p, --tx-power            \"tx-power\" flag\n"
4088                 "e.g.:\n"
4089                 "\tadd-adv -u 180d -u 180f -d 080954657374204C45 1");
4090 }
4091
4092 static struct option add_adv_options[] = {
4093         { "help",               0, 0, 'h' },
4094         { "uuid",               1, 0, 'u' },
4095         { "adv-data",           1, 0, 'd' },
4096         { "scan-rsp",           1, 0, 's' },
4097         { "timeout",            1, 0, 't' },
4098         { "duration",           1, 0, 'D' },
4099         { "connectable",        0, 0, 'c' },
4100         { "general-discov",     0, 0, 'g' },
4101         { "limited-discov",     0, 0, 'l' },
4102         { "managed-flags",      0, 0, 'm' },
4103         { "tx-power",           0, 0, 'p' },
4104         { 0, 0, 0, 0}
4105 };
4106
4107 static bool parse_bytes(char *optarg, uint8_t **bytes, size_t *len)
4108 {
4109         unsigned i;
4110
4111         if (!optarg) {
4112                 add_adv_usage();
4113                 return false;
4114         }
4115
4116         *len = strlen(optarg);
4117
4118         if (*len % 2) {
4119                 error("Malformed data");
4120                 return false;
4121         }
4122
4123         *len /= 2;
4124         if (*len > UINT8_MAX) {
4125                 error("Data too long");
4126                 return false;
4127         }
4128
4129         *bytes = malloc(*len);
4130         if (!*bytes) {
4131                 error("Failed to allocate memory");
4132                 return false;
4133         }
4134
4135         for (i = 0; i < *len; i++) {
4136                 if (sscanf(optarg + (i * 2), "%2hhx", *bytes + i) != 1) {
4137                         error("Invalid data");
4138                         free(*bytes);
4139                         *bytes = NULL;
4140                         return false;
4141                 }
4142         }
4143
4144         return true;
4145 }
4146
4147 #define MAX_AD_UUID_BYTES 32
4148
4149 static void cmd_add_adv(struct mgmt *mgmt, uint16_t index,
4150                                                         int argc, char **argv)
4151 {
4152         struct mgmt_cp_add_advertising *cp = NULL;
4153         int opt;
4154         uint8_t *adv_data = NULL, *scan_rsp = NULL;
4155         size_t adv_len = 0, scan_rsp_len = 0;
4156         size_t cp_len;
4157         uint8_t uuids[MAX_AD_UUID_BYTES];
4158         size_t uuid_bytes = 0;
4159         uint8_t uuid_type = 0;
4160         uint16_t timeout = 0, duration = 0;
4161         uint8_t instance;
4162         uuid_t uuid;
4163         bool success = false;
4164         bool quit = true;
4165         uint32_t flags = 0;
4166
4167         while ((opt = getopt_long(argc, argv, "+u:d:s:t:D:cglmphna",
4168                                                 add_adv_options, NULL)) != -1) {
4169                 switch (opt) {
4170                 case 'u':
4171                         if (bt_string2uuid(&uuid, optarg) < 0) {
4172                                 print("Invalid UUID: %s", optarg);
4173                                 goto done;
4174                         }
4175
4176                         if (uuid_type && uuid_type != uuid.type) {
4177                                 print("UUID types must be consistent");
4178                                 goto done;
4179                         }
4180
4181                         if (uuid.type == SDP_UUID16) {
4182                                 if (uuid_bytes + 2 >= MAX_AD_UUID_BYTES) {
4183                                         print("Too many UUIDs");
4184                                         goto done;
4185                                 }
4186
4187                                 put_le16(uuid.value.uuid16, uuids + uuid_bytes);
4188                                 uuid_bytes += 2;
4189                         } else if (uuid.type == SDP_UUID128) {
4190                                 if (uuid_bytes + 16 >= MAX_AD_UUID_BYTES) {
4191                                         print("Too many UUIDs");
4192                                         goto done;
4193                                 }
4194
4195                                 bswap_128(uuid.value.uuid128.data,
4196                                                         uuids + uuid_bytes);
4197                                 uuid_bytes += 16;
4198                         } else {
4199                                 printf("Unsupported UUID type");
4200                                 goto done;
4201                         }
4202
4203                         if (!uuid_type)
4204                                 uuid_type = uuid.type;
4205
4206                         break;
4207                 case 'd':
4208                         if (adv_len) {
4209                                 print("Only one adv-data option allowed");
4210                                 goto done;
4211                         }
4212
4213                         if (!parse_bytes(optarg, &adv_data, &adv_len))
4214                                 goto done;
4215                         break;
4216                 case 's':
4217                         if (scan_rsp_len) {
4218                                 print("Only one scan-rsp option allowed");
4219                                 goto done;
4220                         }
4221
4222                         if (!parse_bytes(optarg, &scan_rsp, &scan_rsp_len))
4223                                 goto done;
4224                         break;
4225                 case 't':
4226                         timeout = strtol(optarg, NULL, 0);
4227                         break;
4228                 case 'D':
4229                         duration = strtol(optarg, NULL, 0);
4230                         break;
4231                 case 'c':
4232                         flags |= MGMT_ADV_FLAG_CONNECTABLE;
4233                         break;
4234                 case 'g':
4235                         flags |= MGMT_ADV_FLAG_DISCOV;
4236                         break;
4237                 case 'l':
4238                         flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
4239                         break;
4240                 case 'm':
4241                         flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
4242                         break;
4243                 case 'p':
4244                         flags |= MGMT_ADV_FLAG_TX_POWER;
4245                         break;
4246                 case 'n':
4247                         flags |= MGMT_ADV_FLAG_LOCAL_NAME;
4248                         break;
4249                 case 'a':
4250                         flags |= MGMT_ADV_FLAG_APPEARANCE;
4251                         break;
4252                 case 'h':
4253                         success = true;
4254                 default:
4255                         add_adv_usage();
4256                         goto done;
4257                 }
4258         }
4259
4260         argc -= optind;
4261         argv += optind;
4262         optind = 0;
4263
4264         if (argc != 1) {
4265                 add_adv_usage();
4266                 goto done;
4267         }
4268
4269         if (uuid_bytes)
4270                 uuid_bytes += 2;
4271
4272         instance = strtol(argv[0], NULL, 0);
4273
4274         if (index == MGMT_INDEX_NONE)
4275                 index = 0;
4276
4277         cp_len = sizeof(*cp) + uuid_bytes + adv_len + scan_rsp_len;
4278         cp = malloc0(cp_len);
4279         if (!cp)
4280                 goto done;
4281
4282         cp->instance = instance;
4283         put_le32(flags, &cp->flags);
4284         put_le16(timeout, &cp->timeout);
4285         put_le16(duration, &cp->duration);
4286         cp->adv_data_len = adv_len + uuid_bytes;
4287         cp->scan_rsp_len = scan_rsp_len;
4288
4289         if (uuid_bytes) {
4290                 cp->data[0] = uuid_bytes - 1;
4291                 cp->data[1] = uuid_type == SDP_UUID16 ? 0x03 : 0x07;
4292                 memcpy(cp->data + 2, uuids, uuid_bytes - 2);
4293         }
4294
4295         memcpy(cp->data + uuid_bytes, adv_data, adv_len);
4296         memcpy(cp->data + uuid_bytes + adv_len, scan_rsp, scan_rsp_len);
4297
4298         if (!mgmt_send(mgmt, MGMT_OP_ADD_ADVERTISING, index, cp_len, cp,
4299                                                 add_adv_rsp, NULL, NULL)) {
4300                 error("Unable to send \"Add Advertising\" command");
4301                 goto done;
4302         }
4303
4304         quit = false;
4305
4306 done:
4307         free(adv_data);
4308         free(scan_rsp);
4309         free(cp);
4310
4311         if (quit)
4312                 noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
4313 }
4314
4315 static void rm_adv_rsp(uint8_t status, uint16_t len, const void *param,
4316                                                                 void *user_data)
4317 {
4318         const struct mgmt_rp_remove_advertising *rp = param;
4319
4320         if (status != 0) {
4321                 error("Remove Advertising failed with status 0x%02x (%s)",
4322                                                 status, mgmt_errstr(status));
4323                 return noninteractive_quit(EXIT_FAILURE);
4324         }
4325
4326         if (len != sizeof(*rp)) {
4327                 error("Invalid Remove Advertising response length (%u)", len);
4328                 return noninteractive_quit(EXIT_FAILURE);
4329         }
4330
4331         print("Instance removed: %u", rp->instance);
4332
4333         return noninteractive_quit(EXIT_SUCCESS);
4334 }
4335
4336 static void rm_adv_usage(void)
4337 {
4338         print("Usage: rm-adv <instance_id>");
4339 }
4340
4341 static void cmd_rm_adv(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
4342 {
4343         struct mgmt_cp_remove_advertising cp;
4344         uint8_t instance;
4345
4346         if (argc != 2) {
4347                 rm_adv_usage();
4348                 return noninteractive_quit(EXIT_FAILURE);
4349         }
4350
4351         instance = strtol(argv[1], NULL, 0);
4352
4353         if (index == MGMT_INDEX_NONE)
4354                 index = 0;
4355
4356         memset(&cp, 0, sizeof(cp));
4357
4358         cp.instance = instance;
4359
4360         if (!mgmt_send(mgmt, MGMT_OP_REMOVE_ADVERTISING, index, sizeof(cp), &cp,
4361                                                 rm_adv_rsp, NULL, NULL)) {
4362                 error("Unable to send \"Remove Advertising\" command");
4363                 return noninteractive_quit(EXIT_FAILURE);
4364         }
4365 }
4366
4367 static void cmd_clr_adv(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
4368 {
4369         char *all_instances = "0";
4370         char *rm_argv[] = { "rm-adv", all_instances, NULL };
4371
4372         cmd_rm_adv(mgmt, index, 2, rm_argv);
4373 }
4374
4375 static void appearance_rsp(uint8_t status, uint16_t len, const void *param,
4376                                                         void *user_data)
4377 {
4378         if (status != 0)
4379                 error("Could not set Appearance with status 0x%02x (%s)",
4380                                                 status, mgmt_errstr(status));
4381         else
4382                 print("Appearance successfully set");
4383
4384         noninteractive_quit(EXIT_SUCCESS);
4385 }
4386
4387 static void cmd_appearance(struct mgmt *mgmt, uint16_t index, int argc,
4388                                                                 char **argv)
4389 {
4390         struct mgmt_cp_set_appearance cp;
4391
4392         if (argc < 2) {
4393                 print("Usage: appearance <appearance>");
4394                 return noninteractive_quit(EXIT_FAILURE);
4395         }
4396
4397         if (index == MGMT_INDEX_NONE)
4398                 index = 0;
4399
4400         cp.appearance = cpu_to_le16(strtol(argv[1], NULL, 0));
4401
4402         if (mgmt_send(mgmt, MGMT_OP_SET_APPEARANCE, index, sizeof(cp), &cp,
4403                                         appearance_rsp, NULL, NULL) == 0) {
4404                 error("Unable to send appearance cmd");
4405                 return noninteractive_quit(EXIT_FAILURE);
4406         }
4407 }
4408
4409 struct cmd_info {
4410         char *cmd;
4411         void (*func)(struct mgmt *mgmt, uint16_t index, int argc, char **argv);
4412         char *doc;
4413         char * (*gen) (const char *text, int state);
4414         void (*disp) (char **matches, int num_matches, int max_length);
4415 };
4416
4417 static struct cmd_info all_cmd[] = {
4418         { "version",    cmd_version,    "Get the MGMT Version"          },
4419         { "commands",   cmd_commands,   "List supported commands"       },
4420         { "config",     cmd_config,     "Show configuration info"       },
4421         { "info",       cmd_info,       "Show controller info"          },
4422         { "extinfo",    cmd_extinfo,    "Show extended controller info" },
4423         { "auto-power", cmd_auto_power, "Power all available features"  },
4424         { "power",      cmd_power,      "Toggle powered state"          },
4425         { "discov",     cmd_discov,     "Toggle discoverable state"     },
4426         { "connectable",cmd_connectable,"Toggle connectable state"      },
4427         { "fast-conn",  cmd_fast_conn,  "Toggle fast connectable state" },
4428         { "bondable",   cmd_bondable,   "Toggle bondable state"         },
4429         { "pairable",   cmd_bondable,   "Toggle bondable state"         },
4430         { "linksec",    cmd_linksec,    "Toggle link level security"    },
4431         { "ssp",        cmd_ssp,        "Toggle SSP mode"               },
4432         { "sc",         cmd_sc,         "Toogle SC support"             },
4433         { "hs",         cmd_hs,         "Toggle HS support"             },
4434         { "le",         cmd_le,         "Toggle LE support"             },
4435         { "advertising",cmd_advertising,"Toggle LE advertising",        },
4436         { "bredr",      cmd_bredr,      "Toggle BR/EDR support",        },
4437         { "privacy",    cmd_privacy,    "Toggle privacy support"        },
4438         { "class",      cmd_class,      "Set device major/minor class"  },
4439         { "disconnect", cmd_disconnect, "Disconnect device"             },
4440         { "con",        cmd_con,        "List connections"              },
4441         { "find",       cmd_find,       "Discover nearby devices"       },
4442         { "find-service", cmd_find_service, "Discover nearby service"   },
4443         { "stop-find",  cmd_stop_find,  "Stop discovery"                },
4444         { "name",       cmd_name,       "Set local name"                },
4445         { "pair",       cmd_pair,       "Pair with a remote device"     },
4446         { "cancelpair", cmd_cancel_pair,"Cancel pairing"                },
4447         { "unpair",     cmd_unpair,     "Unpair device"                 },
4448         { "keys",       cmd_keys,       "Load Link Keys"                },
4449         { "ltks",       cmd_ltks,       "Load Long Term Keys"           },
4450         { "irks",       cmd_irks,       "Load Identity Resolving Keys"  },
4451         { "block",      cmd_block,      "Block Device"                  },
4452         { "unblock",    cmd_unblock,    "Unblock Device"                },
4453         { "add-uuid",   cmd_add_uuid,   "Add UUID"                      },
4454         { "rm-uuid",    cmd_remove_uuid,"Remove UUID"                   },
4455         { "clr-uuids",  cmd_clr_uuids,  "Clear UUIDs"                   },
4456         { "local-oob",  cmd_local_oob,  "Local OOB data"                },
4457         { "remote-oob", cmd_remote_oob, "Remote OOB data"               },
4458         { "did",        cmd_did,        "Set Device ID"                 },
4459         { "static-addr",cmd_static_addr,"Set static address"            },
4460         { "public-addr",cmd_public_addr,"Set public address"            },
4461         { "ext-config", cmd_ext_config, "External configuration"        },
4462         { "debug-keys", cmd_debug_keys, "Toogle debug keys"             },
4463         { "conn-info",  cmd_conn_info,  "Get connection information"    },
4464         { "io-cap",     cmd_io_cap,     "Set IO Capability"             },
4465         { "scan-params",cmd_scan_params,"Set Scan Parameters"           },
4466         { "get-clock",  cmd_clock_info, "Get Clock Information"         },
4467         { "add-device", cmd_add_device, "Add Device"                    },
4468         { "del-device", cmd_del_device, "Remove Device"                 },
4469         { "clr-devices",cmd_clr_devices,"Clear Devices"                 },
4470         { "bredr-oob",  cmd_bredr_oob,  "Local OOB data (BR/EDR)"       },
4471         { "le-oob",     cmd_le_oob,     "Local OOB data (LE)"           },
4472         { "advinfo",    cmd_advinfo,    "Show advertising features"     },
4473         { "advsize",    cmd_advsize,    "Show advertising size info"    },
4474         { "add-adv",    cmd_add_adv,    "Add advertising instance"      },
4475         { "rm-adv",     cmd_rm_adv,     "Remove advertising instance"   },
4476         { "clr-adv",    cmd_clr_adv,    "Clear advertising instances"   },
4477         { "appearance", cmd_appearance, "Set appearance"                },
4478 };
4479
4480 static void cmd_quit(struct mgmt *mgmt, uint16_t index,
4481                                                 int argc, char **argv)
4482 {
4483         mainloop_exit_success();
4484 }
4485
4486 static void register_mgmt_callbacks(struct mgmt *mgmt, uint16_t index)
4487 {
4488         mgmt_register(mgmt, MGMT_EV_CONTROLLER_ERROR, index, controller_error,
4489                                                                 NULL, NULL);
4490         mgmt_register(mgmt, MGMT_EV_INDEX_ADDED, index, index_added,
4491                                                                 NULL, NULL);
4492         mgmt_register(mgmt, MGMT_EV_INDEX_REMOVED, index, index_removed,
4493                                                                 NULL, NULL);
4494         mgmt_register(mgmt, MGMT_EV_NEW_SETTINGS, index, new_settings,
4495                                                                 NULL, NULL);
4496         mgmt_register(mgmt, MGMT_EV_DISCOVERING, index, discovering,
4497                                                                 NULL, NULL);
4498         mgmt_register(mgmt, MGMT_EV_NEW_LINK_KEY, index, new_link_key,
4499                                                                 NULL, NULL);
4500         mgmt_register(mgmt, MGMT_EV_DEVICE_CONNECTED, index, connected,
4501                                                                 NULL, NULL);
4502         mgmt_register(mgmt, MGMT_EV_DEVICE_DISCONNECTED, index, disconnected,
4503                                                                 NULL, NULL);
4504         mgmt_register(mgmt, MGMT_EV_CONNECT_FAILED, index, conn_failed,
4505                                                                 NULL, NULL);
4506         mgmt_register(mgmt, MGMT_EV_AUTH_FAILED, index, auth_failed,
4507                                                                 NULL, NULL);
4508         mgmt_register(mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED, index,
4509                                         class_of_dev_changed, NULL, NULL);
4510         mgmt_register(mgmt, MGMT_EV_LOCAL_NAME_CHANGED, index,
4511                                         local_name_changed, NULL, NULL);
4512         mgmt_register(mgmt, MGMT_EV_DEVICE_FOUND, index, device_found,
4513                                                                 mgmt, NULL);
4514         mgmt_register(mgmt, MGMT_EV_PIN_CODE_REQUEST, index, request_pin,
4515                                                                 mgmt, NULL);
4516         mgmt_register(mgmt, MGMT_EV_USER_CONFIRM_REQUEST, index, user_confirm,
4517                                                                 mgmt, NULL);
4518         mgmt_register(mgmt, MGMT_EV_USER_PASSKEY_REQUEST, index,
4519                                                 request_passkey, mgmt, NULL);
4520         mgmt_register(mgmt, MGMT_EV_PASSKEY_NOTIFY, index,
4521                                                 passkey_notify, mgmt, NULL);
4522         mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_ADDED, index,
4523                                         unconf_index_added, NULL, NULL);
4524         mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_REMOVED, index,
4525                                         unconf_index_removed, NULL, NULL);
4526         mgmt_register(mgmt, MGMT_EV_NEW_CONFIG_OPTIONS, index,
4527                                         new_config_options, NULL, NULL);
4528         mgmt_register(mgmt, MGMT_EV_EXT_INDEX_ADDED, index,
4529                                         ext_index_added, NULL, NULL);
4530         mgmt_register(mgmt, MGMT_EV_EXT_INDEX_REMOVED, index,
4531                                         ext_index_removed, NULL, NULL);
4532         mgmt_register(mgmt, MGMT_EV_LOCAL_OOB_DATA_UPDATED, index,
4533                                         local_oob_data_updated, NULL, NULL);
4534         mgmt_register(mgmt, MGMT_EV_ADVERTISING_ADDED, index,
4535                                                 advertising_added, NULL, NULL);
4536         mgmt_register(mgmt, MGMT_EV_ADVERTISING_REMOVED, index,
4537                                         advertising_removed, NULL, NULL);
4538 }
4539
4540 static void cmd_select(struct mgmt *mgmt, uint16_t index,
4541                                                 int argc, char **argv)
4542 {
4543         if (argc != 2) {
4544                 error("Usage: select <index>");
4545                 return;
4546         }
4547
4548         mgmt_cancel_all(mgmt);
4549         mgmt_unregister_all(mgmt);
4550
4551         if (!strcmp(argv[1], "none") || !strcmp(argv[1], "any") ||
4552                                                 !strcmp(argv[1], "all"))
4553                 mgmt_index = MGMT_INDEX_NONE;
4554         else if (!strncmp(argv[1], "hci", 3))
4555                 mgmt_index = atoi(&argv[1][3]);
4556         else
4557                 mgmt_index = atoi(argv[1]);
4558
4559         register_mgmt_callbacks(mgmt, mgmt_index);
4560
4561         print("Selected index %u", mgmt_index);
4562
4563         update_prompt(mgmt_index);
4564 }
4565
4566 static struct cmd_info interactive_cmd[] = {
4567         { "select",     cmd_select,     "Select a different index"      },
4568         { "quit",       cmd_quit,       "Exit program"                  },
4569         { "exit",       cmd_quit,       "Exit program"                  },
4570         { "help",       NULL,           "List supported commands"       },
4571 };
4572
4573 static char *cmd_generator(const char *text, int state)
4574 {
4575         static size_t i, j, len;
4576         const char *cmd;
4577
4578         if (!state) {
4579                 i = 0;
4580                 j = 0;
4581                 len = strlen(text);
4582         }
4583
4584         while (i < NELEM(all_cmd)) {
4585                 cmd = all_cmd[i++].cmd;
4586
4587                 if (!strncmp(cmd, text, len))
4588                         return strdup(cmd);
4589         }
4590
4591         while (j < NELEM(interactive_cmd)) {
4592                 cmd = interactive_cmd[j++].cmd;
4593
4594                 if (!strncmp(cmd, text, len))
4595                         return strdup(cmd);
4596         }
4597
4598         return NULL;
4599 }
4600
4601 static char **cmd_completion(const char *text, int start, int end)
4602 {
4603         char **matches = NULL;
4604
4605         if (start > 0) {
4606                 unsigned int i;
4607
4608                 for (i = 0; i < NELEM(all_cmd); i++) {
4609                         struct cmd_info *c = &all_cmd[i];
4610
4611                         if (strncmp(c->cmd, rl_line_buffer, start - 1))
4612                                 continue;
4613
4614                         if (!c->gen)
4615                                 continue;
4616
4617                         rl_completion_display_matches_hook = c->disp;
4618                         matches = rl_completion_matches(text, c->gen);
4619                         break;
4620                 }
4621         } else {
4622                 rl_completion_display_matches_hook = NULL;
4623                 matches = rl_completion_matches(text, cmd_generator);
4624         }
4625
4626         if (!matches)
4627                 rl_attempted_completion_over = 1;
4628
4629         return matches;
4630 }
4631
4632 static struct cmd_info *find_cmd(const char *cmd, struct cmd_info table[],
4633                                                         size_t cmd_count)
4634 {
4635         size_t i;
4636
4637         for (i = 0; i < cmd_count; i++) {
4638                 if (!strcmp(table[i].cmd, cmd))
4639                         return &table[i];
4640         }
4641
4642         return NULL;
4643 }
4644
4645 static void rl_handler(char *input)
4646 {
4647         struct cmd_info *c;
4648         wordexp_t w;
4649         char *cmd, **argv;
4650         size_t argc, i;
4651
4652         if (!input) {
4653                 rl_insert_text("quit");
4654                 rl_redisplay();
4655                 rl_crlf();
4656                 mainloop_quit();
4657                 return;
4658         }
4659
4660         if (!strlen(input))
4661                 goto done;
4662
4663         if (prompt_input(input))
4664                 goto done;
4665
4666         add_history(input);
4667
4668         if (wordexp(input, &w, WRDE_NOCMD))
4669                 goto done;
4670
4671         if (w.we_wordc == 0)
4672                 goto free_we;
4673
4674         cmd = w.we_wordv[0];
4675         argv = w.we_wordv;
4676         argc = w.we_wordc;
4677
4678         c = find_cmd(cmd, all_cmd, NELEM(all_cmd));
4679         if (!c && interactive)
4680                 c = find_cmd(cmd, interactive_cmd, NELEM(interactive_cmd));
4681
4682         if (c && c->func) {
4683                 c->func(mgmt, mgmt_index, argc, argv);
4684                 goto free_we;
4685         }
4686
4687         if (strcmp(cmd, "help")) {
4688                 print("Invalid command");
4689                 goto free_we;
4690         }
4691
4692         print("Available commands:");
4693
4694         for (i = 0; i < NELEM(all_cmd); i++) {
4695                 c = &all_cmd[i];
4696                 if (c->doc)
4697                         print("  %s %-*s %s", c->cmd,
4698                                 (int)(25 - strlen(c->cmd)), "", c->doc ? : "");
4699         }
4700
4701         if (!interactive)
4702                 goto free_we;
4703
4704         for (i = 0; i < NELEM(interactive_cmd); i++) {
4705                 c = &interactive_cmd[i];
4706                 if (c->doc)
4707                         print("  %s %-*s %s", c->cmd,
4708                                 (int)(25 - strlen(c->cmd)), "", c->doc ? : "");
4709         }
4710
4711 free_we:
4712         wordfree(&w);
4713 done:
4714         free(input);
4715 }
4716
4717 static void usage(void)
4718 {
4719         unsigned int i;
4720
4721         printf("btmgmt ver %s\n", VERSION);
4722         printf("Usage:\n"
4723                 "\tbtmgmt [options] <command> [command parameters]\n");
4724
4725         printf("Options:\n"
4726                 "\t--index <id>\tSpecify adapter index\n"
4727                 "\t--verbose\tEnable extra logging\n"
4728                 "\t--help\tDisplay help\n");
4729
4730         printf("Commands:\n");
4731         for (i = 0; i < NELEM(all_cmd); i++)
4732                 printf("\t%-15s\t%s\n", all_cmd[i].cmd, all_cmd[i].doc);
4733
4734         printf("\n"
4735                 "For more information on the usage of each command use:\n"
4736                 "\tbtmgmt <command> --help\n" );
4737 }
4738
4739 static struct option main_options[] = {
4740         { "index",      1, 0, 'i' },
4741         { "verbose",    0, 0, 'v' },
4742         { "help",       0, 0, 'h' },
4743         { 0, 0, 0, 0 }
4744 };
4745
4746 static bool prompt_read(struct io *io, void *user_data)
4747 {
4748         rl_callback_read_char();
4749         return true;
4750 }
4751
4752 static struct io *setup_stdin(void)
4753 {
4754         struct io *io;
4755
4756         io = io_new(STDIN_FILENO);
4757         if (!io)
4758                 return io;
4759
4760         io_set_read_handler(io, prompt_read, NULL, NULL);
4761
4762         return io;
4763 }
4764
4765 static void mgmt_debug(const char *str, void *user_data)
4766 {
4767         const char *prefix = user_data;
4768
4769         print("%s%s", prefix, str);
4770 }
4771
4772 int main(int argc, char *argv[])
4773 {
4774         struct io *input;
4775         uint16_t index = MGMT_INDEX_NONE;
4776         int status, opt;
4777
4778         while ((opt = getopt_long(argc, argv, "+hi:",
4779                                                 main_options, NULL)) != -1) {
4780                 switch (opt) {
4781                 case 'i':
4782                         if (strlen(optarg) > 3 &&
4783                                         strncasecmp(optarg, "hci", 3) == 0)
4784                                 index = atoi(optarg + 3);
4785                         else
4786                                 index = atoi(optarg);
4787                         break;
4788                 case 'h':
4789                 default:
4790                         usage();
4791                         return 0;
4792                 }
4793         }
4794
4795         argc -= optind;
4796         argv += optind;
4797         optind = 0;
4798
4799         mainloop_init();
4800
4801         mgmt = mgmt_new_default();
4802         if (!mgmt) {
4803                 fprintf(stderr, "Unable to open mgmt_socket\n");
4804                 return EXIT_FAILURE;
4805         }
4806
4807         if (getenv("MGMT_DEBUG"))
4808                 mgmt_set_debug(mgmt, mgmt_debug, "mgmt: ", NULL);
4809
4810         if (argc > 0) {
4811                 struct cmd_info *c;
4812
4813                 c = find_cmd(argv[0], all_cmd, NELEM(all_cmd));
4814                 if (!c) {
4815                         fprintf(stderr, "Unknown command: %s\n", argv[0]);
4816                         mgmt_unref(mgmt);
4817                         return EXIT_FAILURE;
4818                 }
4819
4820                 c->func(mgmt, index, argc, argv);
4821         }
4822
4823         register_mgmt_callbacks(mgmt, index);
4824
4825         /* Interactive mode */
4826         if (!argc)
4827                 input = setup_stdin();
4828         else
4829                 input = NULL;
4830
4831         if (input) {
4832                 interactive = true;
4833
4834                 rl_attempted_completion_function = cmd_completion;
4835
4836                 rl_erase_empty_line = 1;
4837                 rl_callback_handler_install(NULL, rl_handler);
4838
4839                 update_prompt(index);
4840                 rl_redisplay();
4841         }
4842
4843         mgmt_index = index;
4844
4845         status = mainloop_run();
4846
4847         if (input) {
4848                 io_destroy(input);
4849
4850                 rl_message("");
4851                 rl_callback_handler_remove();
4852         }
4853
4854         mgmt_cancel_all(mgmt);
4855         mgmt_unregister_all(mgmt);
4856         mgmt_unref(mgmt);
4857
4858         return status;
4859 }