2 * BlueZ - Bluetooth protocol stack for Linux
4 * Copyright (C) 2011 Intel Corporation. All rights reserved.
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.
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.
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
31 #include <sys/types.h>
32 #include <sys/socket.h>
37 #include <bluetooth/bluetooth.h>
38 #include <bluetooth/hci.h>
39 #include <bluetooth/hci_lib.h>
40 #include <bluetooth/sdp.h>
41 #include <bluetooth/sdp_lib.h>
42 #include <bluetooth/mgmt.h>
45 #include "glib-helper.h"
47 static bool monitor = false;
48 static bool discovery = false;
49 static bool resolve_names = true;
51 typedef void (*cmd_cb)(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
52 void *rsp, uint16_t len, void *user_data);
54 static struct pending_cmd {
59 struct pending_cmd *next;
62 static int mgmt_send_cmd(int mgmt_sk, uint16_t op, uint16_t id, void *data,
63 size_t len, cmd_cb func, void *user_data)
66 struct pending_cmd *cmd;
67 struct mgmt_hdr *hdr = (void *) buf;
69 if (len + MGMT_HDR_SIZE > sizeof(buf))
72 cmd = calloc(1, sizeof(struct pending_cmd));
79 cmd->user_data = user_data;
81 memset(buf, 0, sizeof(buf));
82 hdr->opcode = htobs(op);
83 hdr->index = htobs(id);
84 hdr->len = htobs(len);
85 memcpy(buf + MGMT_HDR_SIZE, data, len);
87 if (write(mgmt_sk, buf, MGMT_HDR_SIZE + len) < 0) {
88 fprintf(stderr, "Unable to write to socket: %s\n",
100 static int mgmt_open(void)
102 struct sockaddr_hci addr;
105 sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
107 fprintf(stderr, "socket: %s\n", strerror(errno));
111 memset(&addr, 0, sizeof(addr));
112 addr.hci_family = AF_BLUETOOTH;
113 addr.hci_dev = HCI_DEV_NONE;
114 addr.hci_channel = HCI_CHANNEL_CONTROL;
116 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
117 fprintf(stderr, "bind: %s\n", strerror(errno));
125 static void mgmt_check_pending(int mgmt_sk, uint16_t op, uint16_t index,
126 uint16_t status, void *data, uint16_t len)
128 struct pending_cmd *c, *prev;
130 for (c = pending, prev = NULL; c != NULL; prev = c, c = c->next) {
139 prev->next = c->next;
141 c->cb(mgmt_sk, op, index, status, data, len, c->user_data);
148 static int mgmt_cmd_complete(int mgmt_sk, uint16_t index,
149 struct mgmt_ev_cmd_complete *ev, uint16_t len)
153 if (len < sizeof(*ev)) {
154 fprintf(stderr, "Too short (%u bytes) cmd complete event\n",
159 op = bt_get_le16(&ev->opcode);
164 printf("%s complete, opcode 0x%04x len %u\n", mgmt_opstr(op),
167 mgmt_check_pending(mgmt_sk, op, index, ev->status, ev->data, len);
172 static int mgmt_cmd_status(int mgmt_sk, uint16_t index,
173 struct mgmt_ev_cmd_status *ev, uint16_t len)
177 if (len < sizeof(*ev)) {
178 fprintf(stderr, "Too short (%u bytes) cmd status event\n",
183 opcode = bt_get_le16(&ev->opcode);
186 printf("cmd status, opcode 0x%04x status 0x%02x (%s)\n",
187 opcode, ev->status, mgmt_errstr(ev->status));
190 mgmt_check_pending(mgmt_sk, opcode, index, ev->status,
196 static int mgmt_controller_error(uint16_t index,
197 struct mgmt_ev_controller_error *ev,
200 if (len < sizeof(*ev)) {
202 "Too short (%u bytes) controller error event\n", len);
207 printf("hci%u error 0x%02x\n", index, ev->error_code);
212 static int mgmt_index_added(int mgmt_sk, uint16_t index)
215 printf("hci%u added\n", index);
219 static int mgmt_index_removed(int mgmt_sk, uint16_t index)
222 printf("hci%u removed\n", index);
226 static const char *settings_str[] = {
239 static void print_settings(uint32_t settings)
243 for (i = 0; i < NELEM(settings_str); i++) {
244 if ((settings & (1 << i)) != 0)
245 printf("%s ", settings_str[i]);
249 static int mgmt_new_settings(int mgmt_sk, uint16_t index,
250 uint32_t *ev, uint16_t len)
252 if (len < sizeof(*ev)) {
253 fprintf(stderr, "Too short new_settings event (%u)\n", len);
258 printf("hci%u new_settings: ", index);
259 print_settings(bt_get_le32(ev));
266 static int mgmt_discovering(int mgmt_sk, uint16_t index,
267 struct mgmt_ev_discovering *ev, uint16_t len)
269 if (len < sizeof(*ev)) {
270 fprintf(stderr, "Too short (%u bytes) discovering event\n",
275 if (ev->discovering == 0 && discovery)
279 printf("hci%u type %u discovering %s\n", index,
280 ev->type, ev->discovering ? "on" : "off");
285 static int mgmt_new_link_key(int mgmt_sk, uint16_t index,
286 struct mgmt_ev_new_link_key *ev, uint16_t len)
289 if (len != sizeof(*ev)) {
290 fprintf(stderr, "Invalid new_link_key length (%u bytes)\n",
297 ba2str(&ev->key.addr.bdaddr, addr);
298 printf("hci%u new_link_key %s type 0x%02x pin_len %d "
299 "store_hint %u\n", index, addr, ev->key.type,
300 ev->key.pin_len, ev->store_hint);
306 static const char *typestr(uint8_t type)
308 const char *str[] = { "BR/EDR", "LE Public", "LE Random" };
310 if (type <= BDADDR_LE_RANDOM)
316 static int mgmt_connected(int mgmt_sk, uint16_t index,
317 struct mgmt_ev_device_connected *ev,
322 if (len < sizeof(*ev)) {
324 "Invalid connected event length (%u bytes)\n", len);
328 eir_len = bt_get_le16(&ev->eir_len);
329 if (len != sizeof(*ev) + eir_len) {
330 fprintf(stderr, "Invalid connected event length "
331 "(%u bytes, eir_len %u bytes)\n", len, eir_len);
337 ba2str(&ev->addr.bdaddr, addr);
338 printf("hci%u %s type %s connected eir_len %u\n", index, addr,
339 typestr(ev->addr.type), eir_len);
345 static int mgmt_disconnected(int mgmt_sk, uint16_t index,
346 struct mgmt_addr_info *ev, uint16_t len)
348 if (len != sizeof(*ev)) {
350 "Invalid disconnected event length (%u bytes)\n", len);
356 ba2str(&ev->bdaddr, addr);
357 printf("hci%u %s type %s disconnected\n", index, addr,
364 static int mgmt_conn_failed(int mgmt_sk, uint16_t index,
365 struct mgmt_ev_connect_failed *ev,
368 if (len != sizeof(*ev)) {
370 "Invalid connect_failed event length (%u bytes)\n", len);
376 ba2str(&ev->addr.bdaddr, addr);
377 printf("hci%u %s type %s connect failed (status 0x%02x, %s)\n",
378 index, addr, typestr(ev->addr.type), ev->status,
379 mgmt_errstr(ev->status));
385 static int mgmt_auth_failed(int mgmt_sk, uint16_t index,
386 struct mgmt_ev_auth_failed *ev,
389 if (len != sizeof(*ev)) {
391 "Invalid auth_failed event length (%u bytes)\n", len);
397 ba2str(&ev->addr.bdaddr, addr);
398 printf("hci%u %s auth failed with status 0x%02x (%s)\n",
399 index, addr, ev->status, mgmt_errstr(ev->status));
405 static int mgmt_name_changed(int mgmt_sk, uint16_t index,
406 struct mgmt_ev_local_name_changed *ev,
409 if (len != sizeof(*ev)) {
411 "Invalid local_name_changed length (%u bytes)\n", len);
416 printf("hci%u name changed: %s\n", index, ev->name);
421 static void confirm_name_rsp(int mgmt_sk, uint16_t op, uint16_t id,
422 uint8_t status, void *rsp, uint16_t len,
425 struct mgmt_rp_confirm_name *rp = rsp;
428 if (len == 0 && status != 0) {
430 "hci%u confirm_name failed with status 0x%02x (%s)\n",
431 id, status, mgmt_errstr(status));
435 if (len != sizeof(*rp)) {
437 "hci%u confirm_name rsp length %u instead of %zu\n",
438 id, len, sizeof(*rp));
442 ba2str(&rp->addr.bdaddr, addr);
446 "hci%u confirm_name for %s failed: 0x%02x (%s)\n",
447 id, addr, status, mgmt_errstr(status));
449 printf("hci%u confirm_name succeeded for %s\n", id, addr);
452 static int mgmt_device_found(int mgmt_sk, uint16_t index,
453 struct mgmt_ev_device_found *ev, uint16_t len)
458 if (len < sizeof(*ev)) {
460 "Too short device_found length (%u bytes)\n", len);
464 flags = btohs(ev->flags);
466 eir_len = bt_get_le16(&ev->eir_len);
467 if (len != sizeof(*ev) + eir_len) {
468 fprintf(stderr, "dev_found: expected %zu bytes, got %u bytes",
469 sizeof(*ev) + eir_len, len);
473 if (monitor || discovery) {
475 ba2str(&ev->addr.bdaddr, addr);
476 printf("hci%u dev_found: %s type %s rssi %d "
477 "flags 0x%04x eir_len %u\n", index, addr,
478 typestr(ev->addr.type), ev->rssi, flags, eir_len);
481 if (discovery && (flags & MGMT_DEV_FOUND_CONFIRM_NAME)) {
482 struct mgmt_cp_confirm_name cp;
484 memset(&cp, 0, sizeof(cp));
485 memcpy(&cp.addr, &ev->addr, sizeof(cp.addr));
491 mgmt_send_cmd(mgmt_sk, MGMT_OP_CONFIRM_NAME, index,
492 &cp, sizeof(cp), confirm_name_rsp,
499 static void pin_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
500 void *rsp, uint16_t len, void *user_data)
504 "hci%u PIN Code reply failed with status 0x%02x (%s)",
505 id, status, mgmt_errstr(status));
509 printf("hci%u PIN Reply successful\n", id);
512 static int mgmt_pin_reply(int mgmt_sk, uint16_t index,
513 struct mgmt_addr_info *addr,
514 const char *pin, size_t len)
516 struct mgmt_cp_pin_code_reply cp;
518 memset(&cp, 0, sizeof(cp));
519 memcpy(&cp.addr, addr, sizeof(cp.addr));
521 memcpy(cp.pin_code, pin, len);
523 return mgmt_send_cmd(mgmt_sk, MGMT_OP_PIN_CODE_REPLY, index,
524 &cp, sizeof(cp), pin_rsp, NULL);
527 static void pin_neg_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
528 void *rsp, uint16_t len, void *user_data)
532 "hci%u PIN Neg reply failed with status 0x%02x (%s)",
533 id, status, mgmt_errstr(status));
537 printf("hci%u PIN Negative Reply successful\n", id);
540 static int mgmt_pin_neg_reply(int mgmt_sk, uint16_t index,
541 struct mgmt_addr_info *addr)
543 struct mgmt_cp_pin_code_neg_reply cp;
545 memset(&cp, 0, sizeof(cp));
546 memcpy(&cp.addr, addr, sizeof(cp.addr));
548 return mgmt_send_cmd(mgmt_sk, MGMT_OP_PIN_CODE_NEG_REPLY, index,
549 &cp, sizeof(cp), pin_neg_rsp, NULL);
552 static int mgmt_request_pin(int mgmt_sk, uint16_t index,
553 struct mgmt_ev_pin_code_request *ev,
559 if (len != sizeof(*ev)) {
561 "Invalid pin_code request length (%u bytes)\n", len);
567 ba2str(&ev->addr.bdaddr, addr);
568 printf("hci%u %s request PIN\n", index, addr);
571 printf("PIN Request (press enter to reject) >> ");
574 memset(pin, 0, sizeof(pin));
576 if (fgets(pin, sizeof(pin), stdin) == NULL || pin[0] == '\n')
577 return mgmt_pin_neg_reply(mgmt_sk, index, &ev->addr);
579 pin_len = strlen(pin);
580 if (pin[pin_len - 1] == '\n') {
581 pin[pin_len - 1] = '\0';
585 return mgmt_pin_reply(mgmt_sk, index, &ev->addr, pin, pin_len);
588 static void confirm_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
589 void *rsp, uint16_t len, void *user_data)
593 "hci%u User Confirm reply failed. status 0x%02x (%s)",
594 id, status, mgmt_errstr(status));
598 printf("hci%u User Confirm Reply successful\n", id);
601 static int mgmt_confirm_reply(int mgmt_sk, uint16_t index, bdaddr_t *bdaddr)
603 struct mgmt_cp_user_confirm_reply cp;
605 memset(&cp, 0, sizeof(cp));
606 bacpy(&cp.addr.bdaddr, bdaddr);
608 return mgmt_send_cmd(mgmt_sk, MGMT_OP_USER_CONFIRM_REPLY, index,
609 &cp, sizeof(cp), confirm_rsp, NULL);
612 static void confirm_neg_rsp(int mgmt_sk, uint16_t op, uint16_t id,
613 uint8_t status, void *rsp, uint16_t len,
618 "hci%u Confirm Neg reply failed. status 0x%02x (%s)",
619 id, status, mgmt_errstr(status));
623 printf("hci%u User Confirm Negative Reply successful\n", id);
626 static int mgmt_confirm_neg_reply(int mgmt_sk, uint16_t index,
629 struct mgmt_cp_user_confirm_reply cp;
631 memset(&cp, 0, sizeof(cp));
632 bacpy(&cp.addr.bdaddr, bdaddr);
634 return mgmt_send_cmd(mgmt_sk, MGMT_OP_USER_CONFIRM_NEG_REPLY, index,
635 &cp, sizeof(cp), confirm_neg_rsp, NULL);
639 static int mgmt_user_confirm(int mgmt_sk, uint16_t index,
640 struct mgmt_ev_user_confirm_request *ev,
648 if (len != sizeof(*ev)) {
650 "Invalid user_confirm request length (%u)\n", len);
654 ba2str(&ev->addr.bdaddr, addr);
655 val = bt_get_le32(&ev->value);
658 printf("hci%u %s User Confirm %06u hint %u\n", index, addr,
659 val, ev->confirm_hint);
661 if (ev->confirm_hint)
662 printf("Accept pairing with %s (yes/no) >> ", addr);
664 printf("Confirm value %06u for %s (yes/no) >> ", val, addr);
668 memset(rsp, 0, sizeof(rsp));
670 if (fgets(rsp, sizeof(rsp), stdin) == NULL || rsp[0] == '\n')
671 return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->addr.bdaddr);
673 rsp_len = strlen(rsp);
674 if (rsp[rsp_len - 1] == '\n') {
675 rsp[rsp_len - 1] = '\0';
679 if (rsp[0] == 'y' || rsp[0] == 'Y')
680 return mgmt_confirm_reply(mgmt_sk, index, &ev->addr.bdaddr);
682 return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->addr.bdaddr);
685 static int mgmt_handle_event(int mgmt_sk, uint16_t ev, uint16_t index,
686 void *data, uint16_t len)
689 printf("event: %s\n", mgmt_evstr(ev));
692 case MGMT_EV_CMD_COMPLETE:
693 return mgmt_cmd_complete(mgmt_sk, index, data, len);
694 case MGMT_EV_CMD_STATUS:
695 return mgmt_cmd_status(mgmt_sk, index, data, len);
696 case MGMT_EV_CONTROLLER_ERROR:
697 return mgmt_controller_error(index, data, len);
698 case MGMT_EV_INDEX_ADDED:
699 return mgmt_index_added(mgmt_sk, index);
700 case MGMT_EV_INDEX_REMOVED:
701 return mgmt_index_removed(mgmt_sk, index);
702 case MGMT_EV_NEW_SETTINGS:
703 return mgmt_new_settings(mgmt_sk, index, data, len);
704 case MGMT_EV_DISCOVERING:
705 return mgmt_discovering(mgmt_sk, index, data, len);
706 case MGMT_EV_NEW_LINK_KEY:
707 return mgmt_new_link_key(mgmt_sk, index, data, len);
708 case MGMT_EV_DEVICE_CONNECTED:
709 return mgmt_connected(mgmt_sk, index, data, len);
710 case MGMT_EV_DEVICE_DISCONNECTED:
711 return mgmt_disconnected(mgmt_sk, index, data, len);
712 case MGMT_EV_CONNECT_FAILED:
713 return mgmt_conn_failed(mgmt_sk, index, data, len);
714 case MGMT_EV_AUTH_FAILED:
715 return mgmt_auth_failed(mgmt_sk, index, data, len);
716 case MGMT_EV_LOCAL_NAME_CHANGED:
717 return mgmt_name_changed(mgmt_sk, index, data, len);
718 case MGMT_EV_DEVICE_FOUND:
719 return mgmt_device_found(mgmt_sk, index, data, len);
720 case MGMT_EV_PIN_CODE_REQUEST:
721 return mgmt_request_pin(mgmt_sk, index, data, len);
722 case MGMT_EV_USER_CONFIRM_REQUEST:
723 return mgmt_user_confirm(mgmt_sk, index, data, len);
726 printf("Unhandled event 0x%04x (%s)\n", ev, mgmt_evstr(ev));
731 static int mgmt_process_data(int mgmt_sk)
734 struct mgmt_hdr *hdr = (void *) buf;
735 uint16_t len, ev, index;
738 ret = read(mgmt_sk, buf, sizeof(buf));
740 fprintf(stderr, "read: %s\n", strerror(errno));
744 if (ret < MGMT_HDR_SIZE) {
745 fprintf(stderr, "Too small mgmt packet (%zd bytes)\n", ret);
749 ev = bt_get_le16(&hdr->opcode);
750 index = bt_get_le16(&hdr->index);
751 len = bt_get_le16(&hdr->len);
754 printf("event 0x%04x len 0x%04x index 0x%04x\n", ev, len, index);
756 if (ret != MGMT_HDR_SIZE + len) {
757 fprintf(stderr, "Packet length mismatch. ret %zd len %u",
762 mgmt_handle_event(mgmt_sk, ev, index, buf + MGMT_HDR_SIZE, len);
767 static void cmd_monitor(int mgmt_sk, uint16_t index, int argc, char **argv)
769 printf("Monitoring mgmt events...\n");
773 static void version_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
774 void *rsp, uint16_t len, void *user_data)
776 struct mgmt_rp_read_version *rp = rsp;
779 fprintf(stderr, "Reading mgmt version failed with status"
780 " 0x%02x (%s)\n", status, mgmt_errstr(status));
784 if (len < sizeof(*rp)) {
785 fprintf(stderr, "Too small version reply (%u bytes)\n", len);
789 printf("MGMT Version %u, revision %u\n", rp->version,
790 bt_get_le16(&rp->revision));
795 static void cmd_version(int mgmt_sk, uint16_t index, int argc, char **argv)
797 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE,
798 NULL, 0, version_rsp, NULL) < 0) {
799 fprintf(stderr, "Unable to send read_version cmd\n");
804 static void commands_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
805 void *rsp, uint16_t len, void *user_data)
807 struct mgmt_rp_read_commands *rp = rsp;
808 uint16_t num_commands, num_events, *opcode;
813 fprintf(stderr, "Reading supported commands failed with status"
814 " 0x%02x (%s)\n", status, mgmt_errstr(status));
818 if (len < sizeof(*rp)) {
819 fprintf(stderr, "Too small commands reply (%u bytes)\n", len);
823 num_commands = bt_get_le16(&rp->num_commands);
824 num_events = bt_get_le16(&rp->num_events);
826 expected_len = sizeof(*rp) + num_commands * sizeof(uint16_t) +
827 num_events * sizeof(uint16_t);
829 if (len < expected_len) {
830 fprintf(stderr, "Too small commands reply (%u != %zu)\n",
835 opcode = rp->opcodes;
837 printf("%u commands:\n", num_commands);
838 for (i = 0; i < num_commands; i++) {
839 uint16_t op = bt_get_le16(opcode++);
840 printf("\t%s (0x%04x)\n", mgmt_opstr(op), op);
843 printf("%u events:\n", num_events);
844 for (i = 0; i < num_events; i++) {
845 uint16_t ev = bt_get_le16(opcode++);
846 printf("\t%s (0x%04x)\n", mgmt_evstr(ev), ev);
852 static void cmd_commands(int mgmt_sk, uint16_t index, int argc, char **argv)
854 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE,
855 NULL, 0, commands_rsp, NULL) < 0) {
856 fprintf(stderr, "Unable to send read_commands cmd\n");
861 static void info_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
862 void *rsp, uint16_t len, void *user_data)
864 struct mgmt_rp_read_info *rp = rsp;
869 "Reading hci%u info failed with status 0x%02x (%s)\n",
870 id, status, mgmt_errstr(status));
874 if (len < sizeof(*rp)) {
875 fprintf(stderr, "Too small info reply (%u bytes)\n", len);
879 ba2str(&rp->bdaddr, addr);
880 printf("hci%u:\taddr %s version %u manufacturer %u"
881 " class 0x%02x%02x%02x\n",
882 id, addr, rp->version, bt_get_le16(&rp->manufacturer),
883 rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
885 printf("\tsupported settings: ");
886 print_settings(bt_get_le32(&rp->supported_settings));
888 printf("\n\tcurrent settings: ");
889 print_settings(bt_get_le32(&rp->current_settings));
891 printf("\n\tname %s\n", rp->name);
892 printf("\tshort name %s\n", rp->short_name);
898 static void index_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
899 void *rsp, uint16_t len, void *user_data)
901 struct mgmt_rp_read_index_list *rp = rsp;
907 "Reading index list failed with status 0x%02x (%s)\n",
908 status, mgmt_errstr(status));
912 if (len < sizeof(*rp)) {
913 fprintf(stderr, "Too small index list reply (%u bytes)\n",
918 count = bt_get_le16(&rp->num_controllers);
920 if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
922 "Index count (%u) doesn't match reply length (%u)\n",
928 printf("Index list with %u item%s\n",
929 count, count > 1 ? "s" : "");
934 if (monitor && count > 0)
937 for (i = 0; i < count; i++) {
940 index = bt_get_le16(&rp->index[i]);
943 printf("hci%u ", index);
945 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INFO, index, NULL,
946 0, info_rsp, NULL) < 0) {
947 fprintf(stderr, "Unable to send read_info cmd\n");
952 if (monitor && count > 0)
956 static void cmd_info(int mgmt_sk, uint16_t index, int argc, char **argv)
958 if (index == MGMT_INDEX_NONE) {
959 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INDEX_LIST,
960 MGMT_INDEX_NONE, NULL, 0,
961 index_rsp, NULL) < 0) {
962 fprintf(stderr, "Unable to send index_list cmd\n");
969 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INFO, index, NULL,
970 0, info_rsp, NULL) < 0) {
971 fprintf(stderr, "Unable to send read_info cmd\n");
976 static void setting_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
977 void *rsp, uint16_t len, void *user_data)
983 "%s for hci%u failed with status 0x%02x (%s)\n",
984 mgmt_opstr(op), id, status, mgmt_errstr(status));
988 if (len < sizeof(*rp)) {
989 fprintf(stderr, "Too small %s response (%u bytes)\n",
990 mgmt_opstr(op), len);
994 printf("hci%u %s complete, settings: ", id, mgmt_opstr(op));
995 print_settings(bt_get_le32(rp));
1001 static void cmd_setting(int mgmt_sk, uint16_t index, uint16_t op,
1002 int argc, char **argv)
1007 printf("Specify \"on\" or \"off\"\n");
1011 if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
1013 else if (strcasecmp(argv[1], "off") == 0)
1016 val = atoi(argv[1]);
1018 if (index == MGMT_INDEX_NONE)
1021 if (mgmt_send_cmd(mgmt_sk, op, index, &val, sizeof(val),
1022 setting_rsp, NULL) < 0) {
1023 fprintf(stderr, "Unable to send %s cmd\n", mgmt_opstr(op));
1028 static void cmd_power(int mgmt_sk, uint16_t index, int argc, char **argv)
1030 cmd_setting(mgmt_sk, index, MGMT_OP_SET_POWERED, argc, argv);
1033 static void cmd_discov(int mgmt_sk, uint16_t index, int argc, char **argv)
1035 struct mgmt_cp_set_discoverable cp;
1038 printf("Usage: btmgmt %s <yes/no> [timeout]\n", argv[0]);
1042 memset(&cp, 0, sizeof(cp));
1044 if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
1046 else if (strcasecmp(argv[1], "off") == 0)
1049 cp.val = atoi(argv[1]);
1052 cp.timeout = htobs(atoi(argv[2]));
1054 if (index == MGMT_INDEX_NONE)
1057 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DISCOVERABLE, index,
1058 &cp, sizeof(cp), setting_rsp, NULL) < 0) {
1059 fprintf(stderr, "Unable to send set_discoverable cmd\n");
1064 static void cmd_connectable(int mgmt_sk, uint16_t index, int argc, char **argv)
1066 cmd_setting(mgmt_sk, index, MGMT_OP_SET_CONNECTABLE, argc, argv);
1069 static void cmd_pairable(int mgmt_sk, uint16_t index, int argc, char **argv)
1071 cmd_setting(mgmt_sk, index, MGMT_OP_SET_PAIRABLE, argc, argv);
1074 static void cmd_linksec(int mgmt_sk, uint16_t index, int argc, char **argv)
1076 cmd_setting(mgmt_sk, index, MGMT_OP_SET_LINK_SECURITY, argc, argv);
1079 static void cmd_ssp(int mgmt_sk, uint16_t index, int argc, char **argv)
1081 cmd_setting(mgmt_sk, index, MGMT_OP_SET_SSP, argc, argv);
1084 static void cmd_hs(int mgmt_sk, uint16_t index, int argc, char **argv)
1086 cmd_setting(mgmt_sk, index, MGMT_OP_SET_HS, argc, argv);
1089 static void cmd_le(int mgmt_sk, uint16_t index, int argc, char **argv)
1091 cmd_setting(mgmt_sk, index, MGMT_OP_SET_LE, argc, argv);
1094 static void class_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1095 void *rsp, uint16_t len, void *user_data)
1097 struct mgmt_ev_class_of_dev_changed *rp = rsp;
1099 if (len == 0 && status != 0) {
1100 fprintf(stderr, "%s failed, status 0x%02x (%s)\n",
1101 mgmt_opstr(op), status, mgmt_errstr(status));
1105 if (len != sizeof(*rp)) {
1106 fprintf(stderr, "Unexpected %s len %u\n", mgmt_opstr(op), len);
1110 printf("%s succeeded. Class 0x%02x%02x%02x\n", mgmt_opstr(op),
1111 rp->class_of_dev[2], rp->class_of_dev[1], rp->class_of_dev[0]);
1116 static void cmd_class(int mgmt_sk, uint16_t index, int argc, char **argv)
1121 printf("Usage: btmgmt %s <major> <minor>\n", argv[0]);
1125 class[0] = atoi(argv[1]);
1126 class[1] = atoi(argv[2]);
1128 if (index == MGMT_INDEX_NONE)
1131 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DEV_CLASS, index,
1132 class, sizeof(class), class_rsp, NULL) < 0) {
1133 fprintf(stderr, "Unable to send set_dev_class cmd\n");
1138 static void disconnect_rsp(int mgmt_sk, uint16_t op, uint16_t id,
1139 uint8_t status, void *rsp, uint16_t len,
1142 struct mgmt_rp_disconnect *rp = rsp;
1145 if (len == 0 && status != 0) {
1146 fprintf(stderr, "Disconnect failed with status 0x%02x (%s)\n",
1147 status, mgmt_errstr(status));
1151 if (len != sizeof(*rp)) {
1152 fprintf(stderr, "Invalid disconnect response length (%u)\n",
1157 ba2str(&rp->addr.bdaddr, addr);
1160 printf("%s disconnected\n", addr);
1164 "Disconnecting %s failed with status 0x%02x (%s)\n",
1165 addr, status, mgmt_errstr(status));
1170 static void cmd_disconnect(int mgmt_sk, uint16_t index, int argc, char **argv)
1172 struct mgmt_cp_disconnect cp;
1175 printf("Usage: btmgmt %s <address>\n", argv[0]);
1179 str2ba(argv[1], &cp.addr.bdaddr);
1181 if (index == MGMT_INDEX_NONE)
1184 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_DISCONNECT, index,
1185 &cp, sizeof(cp), disconnect_rsp, NULL) < 0) {
1186 fprintf(stderr, "Unable to send disconnect cmd\n");
1191 static void con_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1192 void *rsp, uint16_t len, void *user_data)
1194 struct mgmt_rp_get_connections *rp = rsp;
1197 if (len < sizeof(*rp)) {
1198 fprintf(stderr, "Too small (%u bytes) get_connections rsp\n",
1203 count = bt_get_le16(&rp->conn_count);
1204 if (len != sizeof(*rp) + count * sizeof(struct mgmt_addr_info)) {
1205 fprintf(stderr, "Invalid get_connections length "
1206 " (count=%u, len=%u)\n", count, len);
1210 for (i = 0; i < count; i++) {
1213 ba2str(&rp->addr[i].bdaddr, addr);
1215 printf("%s type %s\n", addr, typestr(rp->addr[i].type));
1221 static void cmd_con(int mgmt_sk, uint16_t index, int argc, char **argv)
1223 if (index == MGMT_INDEX_NONE)
1226 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_GET_CONNECTIONS, index, NULL, 0,
1227 con_rsp, NULL) < 0) {
1228 fprintf(stderr, "Unable to send get_connections cmd\n");
1233 static void find_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1234 void *rsp, uint16_t len, void *user_data)
1238 "Unable to start discovery. status 0x%02x (%s)\n",
1239 status, mgmt_errstr(status));
1243 printf("Discovery started\n");
1247 static void find_usage(void)
1249 printf("Usage: btmgmt find [-l|-b]>\n");
1252 static struct option find_options[] = {
1253 { "help", 0, 0, 'h' },
1254 { "le-only", 1, 0, 'l' },
1255 { "bredr-only", 1, 0, 'b' },
1259 static void cmd_find(int mgmt_sk, uint16_t index, int argc, char **argv)
1261 struct mgmt_cp_start_discovery cp;
1265 if (index == MGMT_INDEX_NONE)
1269 hci_set_bit(BDADDR_BREDR, &type);
1270 hci_set_bit(BDADDR_LE_PUBLIC, &type);
1271 hci_set_bit(BDADDR_LE_RANDOM, &type);
1273 while ((opt = getopt_long(argc, argv, "+lbh", find_options,
1277 hci_clear_bit(BDADDR_BREDR, &type);
1278 hci_set_bit(BDADDR_LE_PUBLIC, &type);
1279 hci_set_bit(BDADDR_LE_RANDOM, &type);
1282 hci_set_bit(BDADDR_BREDR, &type);
1283 hci_clear_bit(BDADDR_LE_PUBLIC, &type);
1284 hci_clear_bit(BDADDR_LE_RANDOM, &type);
1297 memset(&cp, 0, sizeof(cp));
1300 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_START_DISCOVERY, index,
1301 &cp, sizeof(cp), find_rsp, NULL) < 0) {
1302 fprintf(stderr, "Unable to send start_discovery cmd\n");
1307 static void name_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1308 void *rsp, uint16_t len, void *user_data)
1311 fprintf(stderr, "Unable to set local name. status 0x%02x (%s)",
1312 status, mgmt_errstr(status));
1319 static void cmd_name(int mgmt_sk, uint16_t index, int argc, char **argv)
1321 struct mgmt_cp_set_local_name cp;
1324 printf("Usage: btmgmt %s <name> [shortname]\n", argv[0]);
1328 if (index == MGMT_INDEX_NONE)
1331 memset(&cp, 0, sizeof(cp));
1332 strncpy((char *) cp.name, argv[1], HCI_MAX_NAME_LENGTH);
1334 strncpy((char *) cp.short_name, argv[2],
1335 MGMT_MAX_SHORT_NAME_LENGTH);
1337 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_LOCAL_NAME, index,
1338 &cp, sizeof(cp), name_rsp, NULL) < 0) {
1339 fprintf(stderr, "Unable to send set_name cmd\n");
1344 static void pair_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1345 void *rsp, uint16_t len, void *user_data)
1347 struct mgmt_rp_pair_device *rp = rsp;
1350 if (len == 0 && status != 0) {
1351 fprintf(stderr, "Pairing failed with status 0x%02x (%s)\n",
1352 status, mgmt_errstr(status));
1356 if (len != sizeof(*rp)) {
1357 fprintf(stderr, "Unexpected pair_rsp len %u\n", len);
1361 ba2str(&rp->addr.bdaddr, addr);
1365 "Pairing with %s (%s) failed. status 0x%02x (%s)\n",
1366 addr, typestr(rp->addr.type), status,
1367 mgmt_errstr(status));
1371 printf("Paired with %s\n", addr);
1376 static void pair_usage(void)
1378 printf("Usage: btmgmt pair [-c cap] [-t type] <remote address>\n");
1381 static struct option pair_options[] = {
1382 { "help", 0, 0, 'h' },
1383 { "capability", 1, 0, 'c' },
1384 { "type", 1, 0, 't' },
1388 static void cmd_pair(int mgmt_sk, uint16_t index, int argc, char **argv)
1390 struct mgmt_cp_pair_device cp;
1392 uint8_t type = BDADDR_BREDR;
1395 while ((opt = getopt_long(argc, argv, "+c:t:h", pair_options,
1399 cap = strtol(optarg, NULL, 0);
1402 type = strtol(optarg, NULL, 0);
1420 if (index == MGMT_INDEX_NONE)
1423 memset(&cp, 0, sizeof(cp));
1424 str2ba(argv[0], &cp.addr.bdaddr);
1425 cp.addr.type = type;
1428 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_PAIR_DEVICE, index, &cp, sizeof(cp),
1429 pair_rsp, NULL) < 0) {
1430 fprintf(stderr, "Unable to send pair_device cmd\n");
1435 static void unpair_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1436 void *rsp, uint16_t len, void *user_data)
1438 struct mgmt_rp_unpair_device *rp = rsp;
1441 if (len == 0 && status != 0) {
1442 fprintf(stderr, "Unpair device failed. status 0x%02x (%s)\n",
1443 status, mgmt_errstr(status));
1447 if (len != sizeof(*rp)) {
1448 fprintf(stderr, "Unexpected unpair_device_rsp len %u\n", len);
1452 ba2str(&rp->addr.bdaddr, addr);
1456 "Unpairing %s failed. status 0x%02x (%s)\n",
1457 addr, status, mgmt_errstr(status));
1461 printf("%s unpaired\n", addr);
1466 static void cmd_unpair(int mgmt_sk, uint16_t index, int argc, char **argv)
1468 struct mgmt_cp_unpair_device cp;
1471 printf("Usage: btmgmt %s <remote address>\n", argv[0]);
1475 if (index == MGMT_INDEX_NONE)
1478 memset(&cp, 0, sizeof(cp));
1479 str2ba(argv[1], &cp.addr.bdaddr);
1482 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_UNPAIR_DEVICE, index, &cp,
1483 sizeof(cp), unpair_rsp, NULL) < 0) {
1484 fprintf(stderr, "Unable to send unpair_device cmd\n");
1489 static void keys_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1490 void *rsp, uint16_t len, void *user_data)
1493 fprintf(stderr, "Load keys failed with status 0x%02x (%s)\n",
1494 status, mgmt_errstr(status));
1498 printf("Keys successfully loaded\n");
1503 static void cmd_keys(int mgmt_sk, uint16_t index, int argc, char **argv)
1505 struct mgmt_cp_load_link_keys cp;
1507 if (index == MGMT_INDEX_NONE)
1510 memset(&cp, 0, sizeof(cp));
1512 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_LOAD_LINK_KEYS, index,
1513 &cp, sizeof(cp), keys_rsp, NULL) < 0) {
1514 fprintf(stderr, "Unable to send load_keys cmd\n");
1519 static void block_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1520 void *rsp, uint16_t len, void *user_data)
1522 struct mgmt_addr_info *rp = rsp;
1525 if (len == 0 && status != 0) {
1526 fprintf(stderr, "%s failed, status 0x%02x (%s)\n",
1527 mgmt_opstr(op), status, mgmt_errstr(status));
1531 if (len != sizeof(*rp)) {
1532 fprintf(stderr, "Unexpected %s len %u\n", mgmt_opstr(op), len);
1536 ba2str(&rp->bdaddr, addr);
1539 fprintf(stderr, "%s %s (%s) failed. status 0x%02x (%s)\n",
1540 mgmt_opstr(op), addr, typestr(rp->type),
1541 status, mgmt_errstr(status));
1545 printf("%s %s succeeded\n", mgmt_opstr(op), addr);
1550 static void block_usage(void)
1552 printf("Usage: btmgmt block [-t type] <remote address>\n");
1555 static struct option block_options[] = {
1556 { "help", 0, 0, 'h' },
1557 { "type", 1, 0, 't' },
1561 static void cmd_block(int mgmt_sk, uint16_t index, int argc, char **argv)
1563 struct mgmt_cp_block_device cp;
1564 uint8_t type = BDADDR_BREDR;
1567 while ((opt = getopt_long(argc, argv, "+t:h", block_options,
1571 type = strtol(optarg, NULL, 0);
1589 if (index == MGMT_INDEX_NONE)
1592 memset(&cp, 0, sizeof(cp));
1593 str2ba(argv[0], &cp.addr.bdaddr);
1594 cp.addr.type = type;
1596 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_BLOCK_DEVICE, index,
1597 &cp, sizeof(cp), block_rsp, NULL) < 0) {
1598 fprintf(stderr, "Unable to send block_device cmd\n");
1603 static void unblock_usage(void)
1605 printf("Usage: btmgmt unblock [-t type] <remote address>\n");
1608 static void cmd_unblock(int mgmt_sk, uint16_t index, int argc, char **argv)
1610 struct mgmt_cp_unblock_device cp;
1611 uint8_t type = BDADDR_BREDR;
1614 while ((opt = getopt_long(argc, argv, "+t:h", block_options,
1618 type = strtol(optarg, NULL, 0);
1636 if (index == MGMT_INDEX_NONE)
1639 memset(&cp, 0, sizeof(cp));
1640 str2ba(argv[0], &cp.addr.bdaddr);
1641 cp.addr.type = type;
1643 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_UNBLOCK_DEVICE, index,
1644 &cp, sizeof(cp), block_rsp, NULL) < 0) {
1645 fprintf(stderr, "Unable to send unblock_device cmd\n");
1650 static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
1652 if (uuid->type == SDP_UUID16)
1653 sdp_uuid16_to_uuid128(uuid128, uuid);
1654 else if (uuid->type == SDP_UUID32)
1655 sdp_uuid32_to_uuid128(uuid128, uuid);
1657 memcpy(uuid128, uuid, sizeof(*uuid));
1660 static void cmd_add_uuid(int mgmt_sk, uint16_t index, int argc, char **argv)
1662 struct mgmt_cp_add_uuid cp;
1664 uuid_t uuid, uuid128;
1667 printf("UUID and service hint needed\n");
1671 if (index == MGMT_INDEX_NONE)
1674 if (bt_string2uuid(&uuid, argv[1]) < 0) {
1675 printf("Invalid UUID: %s\n", argv[1]);
1679 memset(&cp, 0, sizeof(cp));
1681 uuid_to_uuid128(&uuid128, &uuid);
1682 ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
1683 htob128(&uint128, (uint128_t *) cp.uuid);
1685 cp.svc_hint = atoi(argv[2]);
1687 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_ADD_UUID, index,
1688 &cp, sizeof(cp), class_rsp, NULL) < 0) {
1689 fprintf(stderr, "Unable to send add_uuid cmd\n");
1694 static void cmd_remove_uuid(int mgmt_sk, uint16_t index, int argc, char **argv)
1696 struct mgmt_cp_remove_uuid cp;
1698 uuid_t uuid, uuid128;
1701 printf("UUID needed\n");
1705 if (index == MGMT_INDEX_NONE)
1708 if (bt_string2uuid(&uuid, argv[1]) < 0) {
1709 printf("Invalid UUID: %s\n", argv[1]);
1713 memset(&cp, 0, sizeof(cp));
1715 uuid_to_uuid128(&uuid128, &uuid);
1716 ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
1717 htob128(&uint128, (uint128_t *) cp.uuid);
1719 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_REMOVE_UUID, index,
1720 &cp, sizeof(cp), class_rsp, NULL) < 0) {
1721 fprintf(stderr, "Unable to send remove_uuid cmd\n");
1726 static void cmd_clr_uuids(int mgmt_sk, uint16_t index, int argc, char **argv)
1728 char *uuid_any = "00000000-0000-0000-0000-000000000000";
1729 char *rm_argv[] = { "rm-uuid", uuid_any, NULL };
1731 cmd_remove_uuid(mgmt_sk, index, 2, rm_argv);
1734 static void did_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
1735 void *rsp, uint16_t len, void *user_data)
1738 fprintf(stderr, "Set Device ID failed with status 0x%02x (%s)\n",
1739 status, mgmt_errstr(status));
1743 printf("Device ID successfully set\n");
1748 static void did_usage(void)
1750 printf("Usage: btmgmt did <source>:<vendor>:<product>:<version>\n");
1751 printf(" possible source values: bluetooth, usb\n");
1754 static void cmd_did(int mgmt_sk, uint16_t index, int argc, char **argv)
1756 struct mgmt_cp_set_device_id cp;
1757 uint16_t vendor, product, version , source;
1765 result = sscanf(argv[1], "bluetooth:%4hx:%4hx:%4hx", &vendor, &product,
1772 result = sscanf(argv[1], "usb:%4hx:%4hx:%4hx", &vendor, &product,
1783 if (index == MGMT_INDEX_NONE)
1786 cp.source = htobs(source);
1787 cp.vendor = htobs(vendor);
1788 cp.product = htobs(product);
1789 cp.version = htobs(version);
1791 if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DEVICE_ID, index,
1792 &cp, sizeof(cp), did_rsp, NULL) < 0) {
1793 fprintf(stderr, "Unable to send set_dev_class cmd\n");
1800 void (*func)(int mgmt_sk, uint16_t index, int argc, char **argv);
1803 { "monitor", cmd_monitor, "Monitor events" },
1804 { "version", cmd_version, "Get the MGMT Version" },
1805 { "commands", cmd_commands, "List supported commands" },
1806 { "info", cmd_info, "Show controller info" },
1807 { "power", cmd_power, "Toggle powered state" },
1808 { "discov", cmd_discov, "Toggle discoverable state" },
1809 { "connectable",cmd_connectable,"Toggle connectable state" },
1810 { "pairable", cmd_pairable, "Toggle pairable state" },
1811 { "linksec", cmd_linksec, "Toggle link level security" },
1812 { "ssp", cmd_ssp, "Toggle SSP mode" },
1813 { "hs", cmd_hs, "Toggle HS Support" },
1814 { "le", cmd_le, "Toggle LE Support" },
1815 { "class", cmd_class, "Set device major/minor class" },
1816 { "disconnect", cmd_disconnect, "Disconnect device" },
1817 { "con", cmd_con, "List connections" },
1818 { "find", cmd_find, "Discover nearby devices" },
1819 { "name", cmd_name, "Set local name" },
1820 { "pair", cmd_pair, "Pair with a remote device" },
1821 { "unpair", cmd_unpair, "Unpair device" },
1822 { "keys", cmd_keys, "Load Keys" },
1823 { "block", cmd_block, "Block Device" },
1824 { "unblock", cmd_unblock, "Unblock Device" },
1825 { "add-uuid", cmd_add_uuid, "Add UUID" },
1826 { "rm-uuid", cmd_add_uuid, "Remove UUID" },
1827 { "clr-uuids", cmd_clr_uuids, "Clear UUIDs", },
1828 { "did", cmd_did, "Set Device ID", },
1832 static void usage(void)
1836 printf("btmgmt ver %s\n", VERSION);
1838 "\tbtmgmt [options] <command> [command parameters]\n");
1841 "\t--index <id>\tSpecify adapter index\n"
1842 "\t--verbose\tEnable extra logging\n"
1843 "\t--help\tDisplay help\n");
1845 printf("Commands:\n");
1846 for (i = 0; command[i].cmd; i++)
1847 printf("\t%-15s\t%s\n", command[i].cmd, command[i].doc);
1850 "For more information on the usage of each command use:\n"
1851 "\tbtmgmt <command> --help\n" );
1854 static struct option main_options[] = {
1855 { "index", 1, 0, 'i' },
1856 { "verbose", 0, 0, 'v' },
1857 { "help", 0, 0, 'h' },
1861 int main(int argc, char *argv[])
1863 int opt, i, mgmt_sk;
1864 uint16_t index = MGMT_INDEX_NONE;
1865 struct pollfd pollfd;
1867 while ((opt = getopt_long(argc, argv, "+hvi:",
1868 main_options, NULL)) != -1) {
1871 if (strlen(optarg) > 3 &&
1872 strncasecmp(optarg, "hci", 3) == 0)
1873 index = atoi(&optarg[4]);
1875 index = atoi(optarg);
1896 mgmt_sk = mgmt_open();
1898 fprintf(stderr, "Unable to open mgmt socket\n");
1902 for (i = 0; command[i].cmd; i++) {
1903 if (strcmp(command[i].cmd, argv[0]) != 0)
1906 command[i].func(mgmt_sk, index, argc, argv);
1910 if (command[i].cmd == NULL) {
1911 fprintf(stderr, "Unknown command: %s\n", argv[0]);
1916 pollfd.fd = mgmt_sk;
1917 pollfd.events = POLLIN;
1920 while (poll(&pollfd, 1, -1) >= 0) {
1921 if (pollfd.revents & (POLLHUP | POLLERR | POLLNVAL))
1924 if (pollfd.revents & POLLIN)
1925 mgmt_process_data(mgmt_sk);