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

📄 csr.c

📁 Linux下蓝牙探测工具
💻 C
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2004-2007  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 <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include "parser.h"#define CSR_U8(frm)  (get_u8(frm))#define CSR_U16(frm) (btohs(htons(get_u16(frm))))#define CSR_U32(frm) ((CSR_U16(frm) << 16) + CSR_U16(frm))#define CSR_S16(frm) (btohs(htons(get_u16(frm))))static char *type2str(uint16_t type){	switch (type) {	case 0x0000:		return "Get req";	case 0x0001:		return "Get rsp";	case 0x0002:		return "Set req";	default:		return "Reserved";	}}static inline void valueless_dump(int level, char *str, struct frame *frm){	p_indent(level, frm);	printf("%s\n", str);}static inline void complex_dump(int level, char *str, struct frame *frm){	p_indent(level, frm);	printf("%s\n", str);	raw_dump(level, frm);}static inline void bool_dump(int level, char *str, struct frame *frm){	uint16_t value;	value = CSR_U16(frm);	p_indent(level, frm);	printf("%s: value %s (%d)\n", str, value ? "TRUE" : "FALSE", value);}static inline void int8_dump(int level, char *str, struct frame *frm){	int16_t value;	value = CSR_S16(frm);	p_indent(level, frm);	printf("%s: value %d (0x%2.2x)\n", str, value, value);}static inline void int16_dump(int level, char *str, struct frame *frm){	int16_t value;	value = CSR_S16(frm);	p_indent(level, frm);	printf("%s: value %d (0x%2.2x)\n", str, value, value);}static inline void uint16_dump(int level, char *str, struct frame *frm){	uint16_t value;	value = CSR_U16(frm);	p_indent(level, frm);	printf("%s: value %d (0x%4.4x)\n", str, value, value);}static inline void uint32_dump(int level, char *str, struct frame *frm){	uint32_t value;	value = CSR_U32(frm);	p_indent(level, frm);	printf("%s: value %d (0x%4.4x)\n", str, value, value);}static inline void bdaddr_dump(int level, char *str, struct frame *frm){	char addr[18];	p_ba2str(frm->ptr, addr);	p_indent(level, frm);	printf("%s: bdaddr %s\n", str, addr);}static inline void features_dump(int level, char *str, struct frame *frm){	unsigned char features[8];	int i;	memcpy(features, frm->ptr, 8);	p_indent(level, frm);	printf("%s: features", str);	for (i = 0; i < 8; i++)		printf(" 0x%02x", features[i]);	printf("\n");}static inline void commands_dump(int level, char *str, struct frame *frm){	unsigned char commands[64];	int i;	memcpy(commands, frm->ptr, frm->len);	p_indent(level, frm);	printf("%s: commands", str);	for (i = 0; i < frm->len; i++)		printf(" 0x%02x", commands[i]);	printf("\n");}static inline void handle_length_dump(int level, char *str, struct frame *frm){	uint16_t handle, length;	handle = CSR_U16(frm);	length = CSR_U16(frm);	p_indent(level, frm);	printf("%s: handle %d length %d\n", str, handle, length);}static inline void handle_clock_dump(int level, char *str, struct frame *frm){	uint16_t handle;	uint32_t clock;	handle = CSR_U16(frm);	clock  = CSR_U32(frm);	p_indent(level, frm);	printf("%s: handle %d clock 0x%4.4x\n", str, handle, clock);}static inline void radiotest_dump(int level, char *str, struct frame *frm){	uint16_t testid;	testid = CSR_U16(frm);	p_indent(level, frm);	printf("%s: test id %d\n", str, testid);	raw_dump(level, frm);}static inline void psmemtype_dump(int level, char *str, struct frame *frm){	uint16_t store, type;	store = CSR_U16(frm);	type  = CSR_U16(frm);	p_indent(level, frm);	printf("%s: store 0x%4.4x type %d\n", str, store, type);}static inline void psnext_dump(int level, char *str, struct frame *frm){	uint16_t key, stores, next;	key    = CSR_U16(frm);	stores = CSR_U16(frm);	next   = CSR_U16(frm);	p_indent(level, frm);	printf("%s: key 0x%4.4x stores 0x%4.4x next 0x%4.4x\n", str, key, stores, next);}static inline void pssize_dump(int level, char *str, struct frame *frm){	uint16_t key, length;	key    = CSR_U16(frm);	length = CSR_U16(frm);	p_indent(level, frm);	printf("%s: key 0x%4.4x %s 0x%4.4x\n", str, key,				frm->in ? "len" : "stores", length);}static inline void psstores_dump(int level, char *str, struct frame *frm){	uint16_t key, stores;	key    = CSR_U16(frm);	stores = CSR_U16(frm);	p_indent(level, frm);	printf("%s: key 0x%4.4x stores 0x%4.4x\n", str, key, stores);}static inline void pskey_dump(int level, struct frame *frm){	uint16_t key, length, stores;	key    = CSR_U16(frm);	length = CSR_U16(frm);	stores = CSR_U16(frm);	p_indent(level, frm);	printf("PSKEY: key 0x%4.4x len %d stores 0x%4.4x\n", key, length, stores);	switch (key) {	case 0x0001:		bdaddr_dump(level + 1, "BDADDR", frm);		break;	case 0x0002:		uint16_dump(level + 1, "COUNTRYCODE", frm);		break;	case 0x0003:		uint32_dump(level + 1, "CLASSOFDEVICE", frm);		break;	case 0x0004:		uint16_dump(level + 1, "DEVICE_DRIFT", frm);		break;	case 0x0005:		uint16_dump(level + 1, "DEVICE_JITTER", frm);		break;	case 0x000d:		uint16_dump(level + 1, "MAX_ACLS", frm);		break;	case 0x000e:		uint16_dump(level + 1, "MAX_SCOS", frm);		break;	case 0x000f:		uint16_dump(level + 1, "MAX_REMOTE_MASTERS", frm);		break;	case 0x00da:		uint16_dump(level + 1, "ENC_KEY_LMIN", frm);		break;	case 0x00db:		uint16_dump(level + 1, "ENC_KEY_LMAX", frm);		break;	case 0x00ef:		features_dump(level + 1, "LOCAL_SUPPORTED_FEATURES", frm);		break;	case 0x0106:		commands_dump(level + 1, "LOCAL_SUPPORTED_COMMANDS", frm);		break;	case 0x010d:		uint16_dump(level + 1, "HCI_LMP_LOCAL_VERSION", frm);		break;	case 0x010e:		uint16_dump(level + 1, "LMP_REMOTE_VERSION", frm);		break;	case 0x01a5:		bool_dump(level + 1, "HOSTIO_USE_HCI_EXTN", frm);		break;	case 0x01ab:		bool_dump(level + 1, "HOSTIO_MAP_SCO_PCM", frm);		break;	case 0x01be:		uint16_dump(level + 1, "UART_BAUDRATE", frm);		break;	case 0x01f6:		uint16_dump(level + 1, "ANA_FTRIM", frm);		break;	case 0x01f9:		uint16_dump(level + 1, "HOST_INTERFACE", frm);		break;	case 0x01fe:		uint16_dump(level + 1, "ANA_FREQ", frm);		break;	case 0x02be:		uint16_dump(level + 1, "USB_VENDOR_ID", frm);		break;	case 0x02bf:		uint16_dump(level + 1, "USB_PRODUCT_ID", frm);		break;	case 0x02cb:		uint16_dump(level + 1, "USB_DFU_PRODUCT_ID", frm);		break;	case 0x03cd:		int16_dump(level + 1, "INITIAL_BOOTMODE", frm);		break;	default:		raw_dump(level + 1, frm);		break;	}}static inline void bccmd_dump(int level, struct frame *frm){	uint16_t type, length, seqno, varid, status;	type   = CSR_U16(frm);	length = CSR_U16(frm);	seqno  = CSR_U16(frm);	varid  = CSR_U16(frm);	status = CSR_U16(frm);	p_indent(level, frm);	printf("BCCMD: %s: len %d seqno %d varid 0x%4.4x status %d\n",			type2str(type), length, seqno, varid, status);	if (!(parser.flags & DUMP_VERBOSE)) {		raw_dump(level + 1, frm);		return;	}	switch (varid) {	case 0x000b:		valueless_dump(level + 1, "PS_CLR_ALL", frm);		break;	case 0x000c:		valueless_dump(level + 1, "PS_FACTORY_SET", frm);		break;	case 0x082d:		uint16_dump(level + 1, "PS_CLR_ALL_STORES", frm);		break;	case 0x2801:		uint16_dump(level + 1, "BC01_STATUS", frm);		break;	case 0x2819:		uint16_dump(level + 1, "BUILDID", frm);		break;	case 0x281a:		uint16_dump(level + 1, "CHIPVER", frm);		break;	case 0x281b:		uint16_dump(level + 1, "CHIPREV", frm);		break;	case 0x2825:		uint16_dump(level + 1, "INTERFACE_VERSION", frm);		break;	case 0x282a:		uint16_dump(level + 1, "RAND", frm);		break;	case 0x282c:		uint16_dump(level + 1, "MAX_CRYPT_KEY_LENGTH", frm);		break;	case 0x2833:		uint16_dump(level + 1, "E2_APP_SIZE", frm);		break;	case 0x2836:		uint16_dump(level + 1, "CHIPANAREV", frm);		break;	case 0x2838:		uint16_dump(level + 1, "BUILDID_LOADER", frm);		break;	case 0x2c00:		uint32_dump(level + 1, "BT_CLOCK", frm);		break;	case 0x3005:		psnext_dump(level + 1, "PS_NEXT", frm);		break;	case 0x3006:		pssize_dump(level + 1, "PS_SIZE", frm);		break;	case 0x3008:		handle_length_dump(level + 1, "CRYPT_KEY_LENGTH", frm);		break;	case 0x3009:		handle_clock_dump(level + 1, "PICONET_INSTANCE", frm);		break;	case 0x300a:		complex_dump(level + 1, "GET_CLR_EVT", frm);		break;	case 0x300b:		complex_dump(level + 1, "GET_NEXT_BUILDDEF", frm);		break;	case 0x300e:		complex_dump(level + 1, "E2_DEVICE", frm);		break;	case 0x300f:		complex_dump(level + 1, "E2_APP_DATA", frm);		break;	case 0x3012:		psmemtype_dump(level + 1, "PS_MEMORY_TYPE", frm);		break;	case 0x301c:		complex_dump(level + 1, "READ_BUILD_NAME", frm);		break;	case 0x4001:		valueless_dump(level + 1, "COLD_RESET", frm);		break;	case 0x4002:		valueless_dump(level + 1, "WARM_RESET", frm);		break;	case 0x4003:		valueless_dump(level + 1, "COLD_HALT", frm);		break;	case 0x4004:		valueless_dump(level + 1, "WARM_HALT", frm);		break;	case 0x4005:		valueless_dump(level + 1, "INIT_BT_STACK", frm);		break;	case 0x4006:		valueless_dump(level + 1, "ACTIVATE_BT_STACK", frm);		break;	case 0x4007:		valueless_dump(level + 1, "ENABLE_TX", frm);		break;	case 0x4008:		valueless_dump(level + 1, "DISABLE_TX", frm);		break;	case 0x4009:		valueless_dump(level + 1, "RECAL", frm);		break;	case 0x400d:		valueless_dump(level + 1, "PS_FACTORY_RESTORE", frm);		break;	case 0x400e:		valueless_dump(level + 1, "PS_FACTORY_RESTORE_ALL", frm);		break;	case 0x400f:		valueless_dump(level + 1, "PS_DEFRAG_RESET", frm);		break;	case 0x4011:		valueless_dump(level + 1, "HOPPING_ON", frm);		break;	case 0x4012:		valueless_dump(level + 1, "CANCEL_PAGE", frm);		break;	case 0x4818:		uint16_dump(level + 1, "PS_CLR", frm);		break;	case 0x481c:		uint16_dump(level + 1, "MAP_SCO_PCM", frm);		break;	case 0x482e:		uint16_dump(level + 1, "SINGLE_CHAN", frm);		break;	case 0x5004:		radiotest_dump(level + 1, "RADIOTEST", frm);		break;	case 0x500c:		psstores_dump(level + 1, "PS_CLR_STORES", frm);		break;	case 0x6000:		valueless_dump(level + 1, "NO_VARIABLE", frm);		break;	case 0x6802:		uint16_dump(level + 1, "CONFIG_UART", frm);		break;	case 0x6805:		uint16_dump(level + 1, "PANIC_ARG", frm);		break;	case 0x6806:		uint16_dump(level + 1, "FAULT_ARG", frm);		break;	case 0x6827:		int8_dump(level + 1, "MAX_TX_POWER", frm);		break;	case 0x682b:		int8_dump(level + 1, "DEFAULT_TX_POWER", frm);		break;	case 0x7003:		pskey_dump(level + 1, frm);		break;	default:		raw_dump(level + 1, frm);		break;	}}static char *cid2str(uint8_t cid){	switch (cid & 0x3f) {	case 0:		return "BCSP Internal";	case 1:		return "BCSP Link";	case 2:		return "BCCMD";	case 3:		return "HQ";	case 4:		return "Device Mgt";	case 5:		return "HCI Cmd/Evt";	case 6:		return "HCI ACL";	case 7:		return "HCI SCO";	case 8:		return "L2CAP";	case 9:		return "RFCOMM";	case 10:		return "SDP";	case 11:		return "Debug";	case 12:		return "DFU";	case 13:		return "VM";	case 14:		return "Unused";	case 15:		return "Reserved";	default:		return "Unknown";	}}static char *frag2str(uint8_t frag){	switch (frag & 0xc0) {	case 0x00:		return " middle fragment";	case 0x40:		return " first fragment";	case 0x80:		return " last fragment";	default:		return "";	}}void csr_dump(int level, struct frame *frm){	uint8_t desc, cid, type;	uint16_t handle, master, addr;	desc = CSR_U8(frm);	cid = desc & 0x3f;	switch (cid) {	case 2:		bccmd_dump(level, frm);		break;	case 20:		type = CSR_U8(frm);		if (!p_filter(FILT_LMP)) {			switch (type) {			case 0x0f:				frm->handle =  ((uint8_t *) frm->ptr)[17];				frm->master = 0;				frm->len--;				lmp_dump(level, frm);				return;			case 0x10:				frm->handle = ((uint8_t *) frm->ptr)[17];				frm->master = 1;				frm->len--;				lmp_dump(level, frm);				return;			case 0x12:				handle = CSR_U16(frm);				master = CSR_U16(frm);				addr = CSR_U16(frm);				p_indent(level, frm);				printf("FHS: handle %d addr %d (%s)\n", handle,					addr, master ? "master" : "slave");				if (!master) {					char addr[18];					p_ba2str((bdaddr_t *) frm->ptr, addr);					p_indent(level + 1, frm);					printf("bdaddr %s class "						"0x%2.2x%2.2x%2.2x\n", addr,						((uint8_t *) frm->ptr)[8],						((uint8_t *) frm->ptr)[7],						((uint8_t *) frm->ptr)[6]);				}				return;			case 0x7b:				p_indent(level, frm);				printf("LMP(r): duplicate (same SEQN)\n");				return;			}		}		p_indent(level, frm);		printf("CSR: Debug (type 0x%2.2x)\n", type);		raw_dump(level, frm);		break;	default:		p_indent(level, frm);		printf("CSR: %s (channel %d)%s\n", cid2str(cid), cid, frag2str(desc));		raw_dump(level, frm);		break;	}}

⌨️ 快捷键说明

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