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