hci.c revision 66f5420f4bf345b06f5b2f651d505b57afa6628c
195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky/*
295e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	HCIDump - HCI packet analyzer
395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	Copyright (C) 2000-2001 Maxim Krasnyansky <maxk@qualcomm.com>
495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	This program is free software; you can redistribute it and/or modify
695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	it under the terms of the GNU General Public License version 2 as
795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	published by the Free Software Foundation;
895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
1295e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM,
1395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
1495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
1695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	USE OR PERFORMANCE OF THIS SOFTWARE.
1795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
1895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS,
1995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED.
2095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky*/
2195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
2295e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky/*
2395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky * $Id$
2495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky */
2595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
2695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <stdio.h>
2795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <stdlib.h>
2895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <unistd.h>
2995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <errno.h>
3095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <string.h>
3195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
3295e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <sys/socket.h>
3395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <sys/types.h>
3495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <asm/types.h>
3595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
3695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <bluetooth/bluetooth.h>
3795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include <bluetooth/hci.h>
3895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
3995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky#include "parser.h"
4095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
4166f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyanskychar *event_map[] = {
4266f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Unknown",
4366f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Inquiry Complete",
4466f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Inquiry Result",
4566f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Connect Complete",
4666f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Connect Request",
4766f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Disconn Complete",
4866f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Auth Complete",
4966f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Remote Name Req Complete",
5066f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Encryp Change",
5166f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Change Connection Link Key Complete",
5266f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Master Link Key Complete",
5366f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Read Remote Supported Features",
5466f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Read Remote Ver Info Complete",
5566f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"QoS Setup Complete",
5666f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Command Complete",
5766f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Command Status",
5866f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Hardware Error",
5966f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Flush Occurred",
6066f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Role Change",
6166f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Number of Completed Packets",
6266f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Mode Change",
6366f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Return Link Keys",
6466f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"PIN Code Request",
6566f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Link Key Request",
6666f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Link Key Notification",
6766f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Loopback Command",
6866f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Data Buffer Overflow",
6966f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Max Slots Change",
7066f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Read Clock Offset Complete",
7166f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Connection Packet Type Changed",
7266f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"QoS Violation",
7366f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Page Scan Mode Change",
7466f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	"Page Scan Repetition Mode Change"
7566f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky};
7666f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky#define EVENTS_NUM	32
7766f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky
7895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyanskystatic inline void command_dump(void *ptr, int len)
7995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky{
8095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	hci_command_hdr *hdr = ptr;
8195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	__u16 opcode = __le16_to_cpu(hdr->opcode);
8295e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
8395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	ptr += HCI_COMMAND_HDR_SIZE;
8495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	len -= HCI_COMMAND_HDR_SIZE;
8595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
860acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky	printf("HCI Command: ogf 0x%x ocf 0x%x plen %d\n",
8795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		cmd_opcode_ogf(opcode), cmd_opcode_ocf(opcode), hdr->plen);
8895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	raw_dump(1, ptr, len);
8995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky}
9095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
9195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyanskystatic inline void event_dump(void *ptr, int len)
9295e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky{
9395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	hci_event_hdr *hdr = ptr;
9495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
9595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	ptr += HCI_EVENT_HDR_SIZE;
9695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	len -= HCI_EVENT_HDR_SIZE;
9795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
9866f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	if (hdr->evt <= EVENTS_NUM)
9966f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky		printf("HCI Event: %s(0x%2.2x) plen %d\n",
10066f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky			event_map[hdr->evt], hdr->evt, hdr->plen);
10166f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky	else
10266f5420f4bf345b06f5b2f651d505b57afa6628cMax Krasnyansky		printf("HCI Event: code 0x%2.2x plen %d\n", hdr->evt, hdr->plen);
10395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	raw_dump(1, ptr, len);
10495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky}
10595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
10695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyanskystatic inline void acl_dump(void *ptr, int len)
10795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky{
10895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	hci_acl_hdr *hdr = ptr;
10995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	__u16 handle = __le16_to_cpu(hdr->handle);
11095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	__u16 dlen = __le16_to_cpu(hdr->dlen);
1110acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky	__u8 flags = acl_flags(handle);
1120acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky
1130acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky	printf("ACL data: handle 0x%4.4x flags 0x%2.2x dlen %d\n",
1140acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky		acl_handle(handle), flags, dlen);
11595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
11695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	ptr += HCI_ACL_HDR_SIZE;
11795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	len -= HCI_ACL_HDR_SIZE;
1180acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky
1190acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky	if (flags & ACL_START) {
1200acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky		l2cap_dump(1, ptr, len, flags);
1210acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky	} else {
1220acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky		raw_dump(1, ptr, len);
1230acc29e48dbb65c22a7aa4e6d20ebe30275a763aMax Krasnyansky	}
12495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky}
12595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
12695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyanskyvoid hci_dump(int level, __u8 *data, int len)
12795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky{
12895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	unsigned char *ptr = data;
12995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	__u8 type;
13095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
13195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	type = *ptr++; len--;
13295e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
13395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	switch (type) {
13495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	case HCI_COMMAND_PKT:
13595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		command_dump(ptr, len);
13695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		break;
13795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
13895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	case HCI_EVENT_PKT:
13995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		event_dump(ptr, len);
14095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		break;
14195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
14295e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	case HCI_ACLDATA_PKT:
14395e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		acl_dump(ptr, len);
14495e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		break;
14595e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky
14695e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	default:
14795e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		printf("Unknown: type 0x%2.2x len %d\n", type, len);
14895e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		raw_dump(1, ptr, len);
14995e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky		break;
15095e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky	}
15195e558b9f6fd21e1b60b35ea86fcb502f333954aMax Krasnyansky}
152