?? hciconfig.c
字號:
/* * * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> * Copyright (C) 2002-2008 Marcel Holtmann <marcel@holtmann.org> * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <errno.h>#include <ctype.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <sys/param.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include "textfile.h"#include "csr.h"static struct hci_dev_info di;static int all;static void print_dev_hdr(struct hci_dev_info *di);static void print_dev_info(int ctl, struct hci_dev_info *di);static void print_dev_list(int ctl, int flags){ struct hci_dev_list_req *dl; struct hci_dev_req *dr; int i; if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) { perror("Can't allocate memory"); exit(1); } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) { perror("Can't get device list"); exit(1); } for (i = 0; i< dl->dev_num; i++) { di.dev_id = (dr+i)->dev_id; if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) continue; if (hci_test_bit(HCI_RAW, &di.flags) && !bacmp(&di.bdaddr, BDADDR_ANY)) { int dd = hci_open_dev(di.dev_id); hci_read_bd_addr(dd, &di.bdaddr, 1000); hci_close_dev(dd); } print_dev_info(ctl, &di); }}static void print_pkt_type(struct hci_dev_info *di){ printf("\tPacket type: %s\n", hci_ptypetostr(di->pkt_type));}static void print_link_policy(struct hci_dev_info *di){ printf("\tLink policy: %s\n", hci_lptostr(di->link_policy));}static void print_link_mode(struct hci_dev_info *di){ printf("\tLink mode: %s\n", hci_lmtostr(di->link_mode));}static void print_dev_features(struct hci_dev_info *di, int format){ printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", di->features[0], di->features[1], di->features[2], di->features[3], di->features[4], di->features[5], di->features[6], di->features[7]); if (format) { char *tmp = lmp_featurestostr(di->features, "\t\t", 63); printf("%s\n", tmp); bt_free(tmp); }}static void cmd_rstat(int ctl, int hdev, char *opt){ /* Reset HCI device stat counters */ if (ioctl(ctl, HCIDEVRESTAT, hdev) < 0) { fprintf(stderr, "Can't reset stats counters hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); }}static void cmd_scan(int ctl, int hdev, char *opt){ struct hci_dev_req dr; dr.dev_id = hdev; dr.dev_opt = SCAN_DISABLED; if (!strcmp(opt, "iscan")) dr.dev_opt = SCAN_INQUIRY; else if (!strcmp(opt, "pscan")) dr.dev_opt = SCAN_PAGE; else if (!strcmp(opt, "piscan")) dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); }}static void cmd_iac(int ctl, int hdev, char *opt){ int s = hci_open_dev(hdev); if (s < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } if (opt) { int l = strtoul(opt, 0, 16); uint8_t lap[3]; if (!strcasecmp(opt, "giac")) { l = 0x9e8b33; } else if (!strcasecmp(opt, "liac")) { l = 0x9e8b00; } else if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } lap[0] = (l & 0xff); lap[1] = (l >> 8) & 0xff; lap[2] = (l >> 16) & 0xff; if (hci_write_current_iac_lap(s, 1, lap, 1000) < 0) { printf("Failed to set IAC on hci%d: %s\n", hdev, strerror(errno)); exit(1); } } else { uint8_t lap[3 * MAX_IAC_LAP]; int i, j; uint8_t n; if (hci_read_current_iac_lap(s, &n, lap, 1000) < 0) { printf("Failed to read IAC from hci%d: %s\n", hdev, strerror(errno)); exit(1); } print_dev_hdr(&di); printf("\tIAC: "); for (i = 0; i < n; i++) { printf("0x"); for (j = 3; j--; ) printf("%02x", lap[j + 3 * i]); if (i < n - 1) printf(", "); } printf("\n"); } close(s);}static void cmd_auth(int ctl, int hdev, char *opt){ struct hci_dev_req dr; dr.dev_id = hdev; if (!strcmp(opt, "auth")) dr.dev_opt = AUTH_ENABLED; else dr.dev_opt = AUTH_DISABLED; if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set auth on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); }}static void cmd_encrypt(int ctl, int hdev, char *opt){ struct hci_dev_req dr; dr.dev_id = hdev; if (!strcmp(opt, "encrypt")) dr.dev_opt = ENCRYPT_P2P; else dr.dev_opt = ENCRYPT_DISABLED; if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set encrypt on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); }}static void cmd_up(int ctl, int hdev, char *opt){ /* Start HCI device */ if (ioctl(ctl, HCIDEVUP, hdev) < 0) { if (errno == EALREADY) return; fprintf(stderr, "Can't init device hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); }}static void cmd_down(int ctl, int hdev, char *opt){ /* Stop HCI device */ if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) { fprintf(stderr, "Can't down device hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); }}static void cmd_reset(int ctl, int hdev, char *opt){ /* Reset HCI device */#if 0 if (ioctl(ctl, HCIDEVRESET, hdev) < 0 ){ fprintf(stderr, "Reset failed for device hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); }#endif cmd_down(ctl, hdev, "down"); cmd_up(ctl, hdev, "up");}static void cmd_ptype(int ctl, int hdev, char *opt){ struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtoptype(opt, &dr.dev_opt)) { if (ioctl(ctl, HCISETPTYPE, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set pkttype on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } } else { print_dev_hdr(&di); print_pkt_type(&di); }}static void cmd_lp(int ctl, int hdev, char *opt){ struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtolp(opt, &dr.dev_opt)) { if (ioctl(ctl, HCISETLINKPOL, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set link policy on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } } else { print_dev_hdr(&di); print_link_policy(&di); }}static void cmd_lm(int ctl, int hdev, char *opt){ struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtolm(opt, &dr.dev_opt)) { if (ioctl(ctl, HCISETLINKMODE, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set default link mode on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } } else { print_dev_hdr(&di); print_link_mode(&di); }}static void cmd_aclmtu(int ctl, int hdev, char *opt){ struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; if (!opt) return; if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16)); if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n", hdev, strerror(errno), errno); exit(1); }}static void cmd_scomtu(int ctl, int hdev, char *opt){ struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; if (!opt) return; if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16)); if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); }}static void cmd_features(int ctl, int hdev, char *opt){ uint8_t features[8], max_page = 0; char *tmp; int i, dd; if (!(di.features[7] & LMP_EXT_FEAT)) { print_dev_hdr(&di); print_dev_features(&di, 1); return; } dd = hci_open_dev(hdev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } if (hci_read_local_ext_features(dd, 0, &max_page, features, 1000) < 0) { fprintf(stderr, "Can't read extended features hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } print_dev_hdr(&di); printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", (max_page > 0) ? " page 0" : "", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); tmp = lmp_featurestostr(di.features, "\t\t", 63); printf("%s\n", tmp); bt_free(tmp); for (i = 1; i <= max_page; i++) { if (hci_read_local_ext_features(dd, i, NULL, features, 1000) < 0) continue; printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i, features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); } hci_close_dev(dd);}static void cmd_name(int ctl, int hdev, char *opt){ int dd; dd = hci_open_dev(hdev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } if (opt) { if (hci_write_local_name(dd, opt, 2000) < 0) { fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } } else { char name[249]; int i; if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) { fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } for (i = 0; i < 248 && name[i]; i++) { if ((unsigned char) name[i] < 32 || name[i] == 127) name[i] = '.'; } name[248] = '\0'; print_dev_hdr(&di); printf("\tName: '%s'\n", name); } hci_close_dev(dd);}/* * see http://www.bluetooth.org/assigned-numbers/baseband.htm --- all * strings are reproduced verbatim */static char *get_minor_device_name(int major, int minor){ switch (major) { case 0: /* misc */ return ""; case 1: /* computer */ switch(minor) { case 0: return "Uncategorized"; case 1: return "Desktop workstation"; case 2: return "Server"; case 3: return "Laptop"; case 4: return "Handheld"; case 5: return "Palm"; case 6: return "Wearable"; } break; case 2: /* phone */ switch(minor) { case 0: return "Uncategorized"; case 1: return "Cellular"; case 2: return "Cordless"; case 3: return "Smart phone"; case 4: return "Wired modem or voice gateway"; case 5: return "Common ISDN Access"; case 6: return "Sim Card Reader"; } break; case 3: /* lan access */ if (minor == 0) return "Uncategorized"; switch(minor / 8) { case 0: return "Fully available"; case 1: return "1-17% utilized"; case 2: return "17-33% utilized"; case 3: return "33-50% utilized"; case 4: return "50-67% utilized"; case 5: return "67-83% utilized"; case 6: return "83-99% utilized"; case 7: return "No service available"; } break; case 4: /* audio/video */ switch(minor) { case 0: return "Uncategorized"; case 1: return "Device conforms to the Headset profile"; case 2: return "Hands-free"; /* 3 is reserved */ case 4: return "Microphone"; case 5: return "Loudspeaker"; case 6: return "Headphones"; case 7: return "Portable Audio"; case 8: return "Car Audio"; case 9: return "Set-top box"; case 10: return "HiFi Audio Device"; case 11: return "VCR"; case 12: return "Video Camera"; case 13: return "Camcorder"; case 14: return "Video Monitor"; case 15: return "Video Display and Loudspeaker"; case 16: return "Video Conferencing"; /* 17 is reserved */ case 18: return "Gaming/Toy"; } break; case 5: /* peripheral */ { static char cls_str[48]; cls_str[0] = '\0'; switch(minor & 48) { case 16: strncpy(cls_str, "Keyboard", sizeof(cls_str)); break; case 32: strncpy(cls_str, "Pointing device", sizeof(cls_str)); break; case 48: strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str)); break; } if((minor & 15) && (strlen(cls_str) > 0)) strcat(cls_str, "/"); switch(minor & 15) { case 0: break; case 1: strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str)); break; case 2: strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str)); break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -