⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hciconfig.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * *  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 max_page, features[8];	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);	tmp = lmp_featurestostr(di.features, "\t\t", 63);	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]);	printf("%s\n", tmp);	bt_free(tmp);	for (i = 1; i <= max_page; i++) {		if (hci_read_local_ext_features(dd, 1, &max_page, 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;		case 3:			strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -