📄 capi.c
字号:
/* * * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2004-2005 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 <sys/types.h>#include <netinet/in.h>#include <bluetooth/bluetooth.h>#include "parser.h"#define CAPI_U8(frm) (get_u8(frm))#define CAPI_U16(frm) (btohs(htons(get_u16(frm))))#define CAPI_U32(frm) (btohl(htonl(get_u32(frm))))static char *cmd2str(uint8_t cmd){ switch (cmd) { case 0x01: return "ALERT"; case 0x02: return "CONNECT"; case 0x03: return "CONNECT_ACTIVE"; case 0x04: return "DISCONNECT"; case 0x05: return "LISTEN"; case 0x08: return "INFO"; case 0x20: return "INTEROPERABILITY"; case 0x41: return "SELECT_B_PROTOCOL"; case 0x80: return "FACILITY"; case 0x82: return "CONNECT_B3"; case 0x83: return "CONNECT_B3_ACTIVE"; case 0x84: return "DISCONNECT_B3"; case 0x86: return "DATA_B3"; case 0x87: return "RESET_B3"; case 0x88: return "CONNECT_B3_T90_ACTIVE"; case 0xff: return "MANUFACTURER"; default: return "UNKNOWN"; }}static char *subcmd2str(uint8_t subcmd){ switch (subcmd) { case 0x80: return "REQ"; case 0x81: return "CONF"; case 0x82: return "IND"; case 0x83: return "RESP"; default: return "UNKN"; }}static char *interopsel2str(uint16_t sel){ switch (sel) { case 0x0000: return "USB Device Management"; case 0x0001: return "Bluetooth Device Management"; default: return "Unknown"; }}static char *func2str(uint16_t func){ switch (func) { case 0: return "Register"; case 1: return "Release"; case 2: return "Get_Profile"; case 3: return "Get_Manufacturer"; case 4: return "Get_Version"; case 5: return "Get_Serial_Number"; case 6: return "Manufacturer"; case 7: return "Echo_Loopback"; default: return "Unknown"; }}static char *facilitysel2str(uint16_t sel){ switch (sel) { case 0x0000: return "Handset"; case 0x0001: return "DTMF"; case 0x0002: return "V.42 bis"; case 0x0003: return "Supplementary Services"; case 0x0004: return "Power management wakeup"; case 0x0005: return "Line Interconnect"; case 0x0006: return "DTMF"; default: return "Unknown"; }}static char *info2str(uint16_t info){ switch (info) { case 0x0000: return "No error"; case 0x0001: return "NCPI not supported by current protocol, NCPI ignored"; case 0x0002: return "Flags not supported by current protocol, flags ignored"; case 0x2001: return "Message not supported in current state"; case 0x2002: return "Incorrect Controller/PLCI/NCCI"; case 0x2003: return "No PLCI available"; case 0x2004: return "No NCCI available"; case 0x2005: return "No Listen resources available"; case 0x2007: return "Illegal message parameter coding"; case 0x2008: return "No interconnection resources available"; case 0x3001: return "B1 protocol not supported"; case 0x3002: return "B2 protocol not supported"; case 0x3003: return "B3 protocol not supported"; case 0x3004: return "B1 protocol parameter not supported"; case 0x3005: return "B2 protocol parameter not supported"; case 0x3006: return "B3 protocol parameter not supported"; case 0x3007: return "B protocol combination not supported"; case 0x3008: return "NCPI not supported"; case 0x3009: return "CIP Value unknown"; case 0x300A: return "Flags not supported (reserved bits)"; case 0x300B: return "Facility not supported"; case 0x300C: return "Data length not supported by current protocol"; case 0x300D: return "Reset procedure not supported by current protocol"; case 0x300F: return "Unsupported interoperability"; case 0x3011: return "Facility specific function not supported"; case 0x3301: return "Protocol error, Layer 1"; case 0x3302: return "Protocol error, Layer 2"; case 0x3303: return "Protocol error, Layer 3"; case 0x3304: return "Another application got that call"; case 0x3305: return "Cleared by Call Control Supervision"; case 0x3400: /* The cause value received from the network in a cause * information element (Octet 4) is indicated in the field 00 */ return "Disconnect cause from the network in accordance with Q.850/ETS 300 102-1"; default: return "Unknown"; }}static void profile(int level, struct frame *frm){ uint16_t nctr, nchn; uint32_t value; nctr = CAPI_U16(frm); nchn = CAPI_U16(frm); if (nchn > 0) { p_indent(level, frm); printf("Controller: %d\n", nctr); p_indent(level, frm); printf("Number of B-channels: %d\n", nchn); value = CAPI_U32(frm); p_indent(level, frm); printf("Global options: 0x%04x\n", value); value = CAPI_U32(frm); p_indent(level, frm); printf("B1 protocol support: 0x%08x\n", value); value = CAPI_U32(frm); p_indent(level, frm); printf("B2 protocol support: 0x%08x\n", value); value = CAPI_U32(frm); p_indent(level, frm); printf("B3 protocol support: 0x%08x\n", value); frm->ptr += 24; frm->len -= 24; p_indent(level, frm); printf("Manufacturer-specific information:\n"); hex_dump(level, frm, 20); } else { p_indent(level, frm); printf("Number of controllers: %d\n", nctr); }}static void cmd_common(int level, uint8_t subcmd, struct frame *frm){ uint32_t val; uint16_t info, ncci; uint8_t ctr, plci; val = CAPI_U32(frm); ctr = val & 0xff; plci = (val & 0xff00) >> 8; ncci = (val & 0xffff0000) >> 16; p_indent(level, frm); printf("Controller: %d %s\n", ctr & 0x7f, ctr & 0x80 ? "Ext." : "Int."); if (plci > 0) { p_indent(level, frm); printf("PLCI: 0x%02x\n", plci); } if (ncci > 0) { p_indent(level, frm); printf("NCCI: 0x%04x\n", ncci); } if (subcmd == 0x81) { info = CAPI_U16(frm); p_indent(level, frm); printf("Info: 0x%04x (%s)\n", info, info2str(info)); }}static void cmd_alert(int level, uint8_t subcmd, struct frame *frm){ uint8_t len; cmd_common(level, subcmd, frm); if (subcmd == 0x80) { len = CAPI_U8(frm); if (len > 0) { p_indent(level, frm); printf("Additional info:\n"); hex_dump(level, frm, len); } }}static void cmd_connect(int level, uint8_t subcmd, struct frame *frm){ uint16_t cip; uint8_t len; cmd_common(level, subcmd, frm); if (subcmd == 0x81) return; cip = CAPI_U16(frm); p_indent(level, frm); printf("CIP value: 0x%04x\n", cip); len = CAPI_U8(frm); frm->ptr += len; frm->len -= len; len = CAPI_U8(frm); frm->ptr += len; frm->len -= len; len = CAPI_U8(frm); frm->ptr += len; frm->len -= len; len = CAPI_U8(frm); frm->ptr += len; frm->len -= len; raw_dump(level, frm);}static void cmd_disconnect(int level, uint8_t subcmd, struct frame *frm){ uint16_t reason; uint8_t len; cmd_common(level, subcmd, frm); if (subcmd == 0x80) { len = CAPI_U8(frm); if (len > 0) { p_indent(level, frm); printf("Additional info:\n"); hex_dump(level, frm, len); } } if (subcmd == 0x82) { reason = CAPI_U16(frm); p_indent(level, frm); printf("Reason: 0x%04x (%s)\n", reason, info2str(reason)); }}static void cmd_connect_active(int level, uint8_t subcmd, struct frame *frm){ uint8_t len; cmd_common(level, subcmd, frm); if (subcmd == 0x82) { len = CAPI_U8(frm); if (len > 0) { p_indent(level, frm); printf("Connected number:\n"); hex_dump(level, frm, len); } len = CAPI_U8(frm); if (len > 0) { p_indent(level, frm); printf("Connected subaddress:\n"); hex_dump(level, frm, len); } len = CAPI_U8(frm); if (len > 0) { p_indent(level, frm); printf("LLC:\n"); hex_dump(level, frm, len); } }}static void cmd_listen(int level, uint8_t subcmd, struct frame *frm){ uint32_t mask; uint8_t len; cmd_common(level, subcmd, frm); if (subcmd == 0x80) { mask = CAPI_U32(frm); p_indent(level, frm); printf("Info mask: 0x%08x\n", mask); mask = CAPI_U32(frm); p_indent(level, frm); printf("CIP mask: 0x%08x", mask); mask = CAPI_U32(frm); if (mask > 0) printf(" 0x%08x\n", mask); else printf("\n"); len = CAPI_U8(frm); if (len > 0) { p_indent(level, frm);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -