关键词:hciconfighcitool  hcidump
笔者:xubin341719(欢迎转载,请明确说明,请尊重版权,谢谢。)
欢迎指正错误,共同学习、共同进步!

Android blueZ HCI(一):hciconfig实现及经常用法
Android blueZ hci(二):hcitool hcidump经常用法

一、Hciconfig
1、adb shell 下。hciconfig 运行文件的位
/system/xbin/hciconfig


对应文件夹下Android.mk文件,生成hciconfig

#
# hciconfig
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
csr.c \
csr_h4.c \
hciconfig.c
………………
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:=hciconfig
include $(BUILD_EXECUTABLE)

2、hciconfig代码实现
idh.code\external\bluetooth\bluez\tools\hciconfig.c
main函数主要有两部分功能:main_options操作。命令的运行;
以下我们分两部分分析

int main(int argc, char *argv[])
{
int opt, ctl, i, cmd=0;
//(1)、hciconfig两个命main_options,help和all两个命令。
while ((opt=getopt_long(argc, argv, "ah", main_options, NULL)) != -1) {
switch(opt) {
case 'a':
all = 1;
break;
case 'h':
default:
usage();
exit(0);
}
}
//(2)、命令运行部分
argc -= optind;
argv += optind;
optind = 0; /* Open HCI socket */
if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
perror("Can't open HCI socket.");
exit(1);
} if (argc < 1) {
print_dev_list(ctl, 0);
exit(0);
} di.dev_id = atoi(argv[0] + 3);
argc--; argv++; if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) {
perror("Can't get device info");
exit(1);
} 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);
} while (argc > 0) {
for (i = 0; command[i].cmd; i++) {
if (strncmp(command[i].cmd, *argv, 5))
continue; if (command[i].opt) {
argc--; argv++;
} command[i].func(ctl, di.dev_id, *argv);
cmd = 1;
break;
}
argc--; argv++;
} if (!cmd)
print_dev_info(ctl, &di); close(ctl);
return 0;
}

(1)、hciconfig两个命main_options,help和all两个命令

int main(int argc, char *argv[])
{
int opt, ctl, i, cmd=0;
//1)、hciconfig两个命main_options,help和all两个命令。
while ((opt=getopt_long(argc, argv, "ah", main_options, NULL)) != -1) {//1)、main_options。
switch(opt) {
case 'a':
all = 1;
break;//2)、假设是all命令运行下去;
case 'h':
default:
usage();//3)、假设是help命令打印出命令用法。
exit(0);
}
}
………………
}

1)、main_options
while((opt=getopt_long(argc, argv, "ah", main_options, NULL)) != -1) {
getopt被用来解析命令行选项參数。getopt_long。解析命令參数支持长选项。即一对短横线、一个描写叙述性选项名称,还能够包括一个使用等号连接到选项的參数。

http://blog.csdn.net/slmmlk2011_2/article/details/7964218中有具体介绍。
即:hciconfig–all

main_options
static struct option main_options[] = {
{ "help", 0, 0, 'h' },
{ "all", 0, 0, 'a' },
{ 0, 0, 0, 0 }
};

2)、ops 解析出来数据,假设是a,打印出蓝牙相关信息

	case 'a':
all = 1;
break;

后面这部分和命令解析一起分析。

3)、假设是help命令,打印出命令用法。

		case 'h':
default:
usage();
exit(0);

假设是help 运行usage这个函数。以下分析这个函数
idh.code\external\bluetooth\bluez\tools\hciconfig.c

static void usage(void)
{
int i;
printf("hciconfig - HCI device configuration utility\n");
printf("Usage:\n"
"\thciconfig\n"
"\thciconfig [-a] hciX [command]\n");
printf("Commands:\n");
for (i=0; command[i].cmd; i++)
printf("\t%-10s %-8s\t%s\n", command[i].cmd,
command[i].opt ? command[i].opt : " ",
command[i].doc);
}

这个函数比較简单,就是不command[]结构体中的命令字符串打印出来:以下两个截图就一目了然了:

命令运行结果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHViaW4zNDE3MTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

static struct {
char *cmd;//命令。比方hciconfig up;
void (*func)(int ctl, int hdev, char *opt);//命令运行函数。
char *opt;//
char *doc;//命令描写叙述
} command[] = {
{ "up", cmd_up, 0, "Open and initialize HCI device" },
{ "down", cmd_down, 0, "Close HCI device" },
{ "reset", cmd_reset, 0, "Reset HCI device" },
………………
}

这部分以:{ "up",           cmd_up,            0,               "Open and initialize HCIdevice" },为例说明

使用up命令时。会调用到,cmd_up这个函数:
idh.code\external\bluetooth\bluez\tools\hciconfig.c

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);
}
}

(2)、命令运行部分

Main()
{
………………
argc -= optind;
argv += optind;
optind = 0; /* Open HCI socket *///1)、打开HCI socket通信
if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {/
perror("Can't open HCI socket.");
exit(1);
} if (argc < 1) {
print_dev_list(ctl, 0);
exit(0);
} di.dev_id = atoi(argv[0] + 3);
argc--; argv++;
//2)、通过ioctl获取HCI驱动信息
if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) {
perror("Can't get device info");
exit(1);
}
//3)、hci_test_bit bacmp
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);
}
//4)命令运行
while (argc > 0) {
for (i = 0; command[i].cmd; i++) {
if (strncmp(command[i].cmd, *argv, 5))
continue; if (command[i].opt) {
argc--; argv++;
} command[i].func(ctl, di.dev_id, *argv);
cmd = 1;
break;
}
argc--; argv++;
} if (!cmd)//没有对应的命令打印出
print_dev_info(ctl, &di);
//5)、关闭ctl,完毕操作
close(ctl);
return 0;
}

1)、打开HCI socket通信

/* Open HCI socket  */
if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
int socket(int domain, int type, int protocol);

參数说明:
  domain:
指明所使用的协议族,通常为PF_INET,表示TCP/IP协议。
  type:參数指定socket的类型,基本上有三种:数据流套接字、数据报套接字、原始套接字
  protocol:通常赋值"0"。

程序中蓝牙建立:

damain:使用AF_BLUETOOTH;
idh.code\3rdparty\bluetooth\Trout_BT\special\android\kernel\include\net\bluetooth\bluetooth.h
#define AF_BLUETOOTH 31
type: SOC_SEQPACKET,以Packet为单位读取。SOC_RAW:原始socket
enum sock_type {
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
SOCK_DCCP = 6,
SOCK_PACKET = 10,
};
protocol:使用对应建立的Socket的protocol,不同类型的入L2CAP、HCI、SCO……
#define BTPROTO_L2CAP 0
#define BTPROTO_HCI 1
#define BTPROTO_SCO 2
#define BTPROTO_RFCOMM 3
#define BTPROTO_BNEP 4
#define BTPROTO_CMTP 5
#define BTPROTO_HIDP 6
#define BTPROTO_AVDTP 7

2)、通过ioctl获取HCI驱动信息,写入struct hci_dev_info di结构体

if(ioctl(ctl, HCIGETDEVINFO, (void *) &di))
idh.code\3rdparty\bluetooth\Trout_BT\special\android\kernel\include\net\bluetooth\hci.h相关命令的定义

#define HCIGETDEVLIST	_IOR('H', 210, int)
#define HCIGETDEVINFO _IOR('H', 211, int)
#define HCIGETCONNLIST _IOR('H', 212, int)
#define HCIGETCONNINFO _IOR('H', 213, int)
#define HCIGETAUTHINFO _IOR('H', 215, int)
di对应的数据结构
static struct hci_dev_info di;
struct hci_dev_info {
__u16 dev_id;
char name[8];
bdaddr_t bdaddr;
__u32 flags;
__u8 type;
__u8 features[8];
__u32 pkt_type;
__u32 link_policy;
__u32 link_mode;
__u16 acl_mtu;
__u16 acl_pkts;
__u16 sco_mtu;
__u16 sco_pkts;
struct hci_dev_stats stat;
};

3)、hci_test_bit bacmp

	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);
}

推断di中相关參数。

hci_test_bit检測*addr的第nr位是否为1(*addr右起最低位为第0位)

static inline int hci_test_bit(int nr, void *addr)
{
return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
}

4)、命令运行,这部分是命令实现的部分

	while (argc > 0) {
for (i = 0; command[i].cmd; i++) {
if (strncmp(command[i].cmd, *argv, 5))//通过for循环比較第二个參数
continue; if (command[i].opt) {
argc--; argv++;
} command[i].func(ctl, di.dev_id, *argv);//假设參数对应,就运行对应的命令函数
cmd = 1;
break;
}
argc--; argv++;
}
if (!cmd)//没有对应的命令打印出
print_dev_info(ctl, &di);

a、如:if (strncmp(command[i].cmd, *argv, 5))// 通过for循环比較第二个參数
| 如命令:hciconfighci0 commands
argv 的值就为:commands字符串,假设5个字符相等。

b、假设对应。就运行对应的命令函数

command[i].func(ctl, di.dev_id, *argv);

c、假设是commands命令:对应command[]结构体中的数组

	{ "commands",	cmd_commands,	0,		"Display supported commands" },

command[i].func = cmd_commands
对应commands 的实现函数cmd_commands函数的实现:

static void cmd_commands(int ctl, int hdev, char *opt)
{
uint8_t cmds[64];
char *str;
int i, n, 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 (hci_read_local_commands(dd, cmds, 1000) < 0) {
fprintf(stderr, "Can't read support commands on hci%d: %s (%d)\n",
hdev, strerror(errno), errno);
exit(1);
} print_dev_hdr(&di);
for (i = 0; i < 64; i++) {
if (!cmds[i])
continue; printf("%s Octet %-2d = 0x%02x (Bit",
i ? "\t\t ": "\tCommands:", i, cmds[i]);
for (n = 0; n < 8; n++)
if (cmds[i] & (1 << n))
printf(" %d", n);
printf(")\n");
} str = hci_commandstostr(cmds, "\t", 71);
printf("%s\n", str);
bt_free(str); hci_close_dev(dd);
}
这个是针对每一个命令实现的具体函数。
//5)、关闭ctl,完毕操作
close(ctl);
return 0;

3、hciconfig命令经常用法:
(1)、帮助命令:查看hciconfig支持的命令和用法
hciconfig –h或者hciconfig  --hlep

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHViaW4zNDE3MTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
(2)、查看蓝牙相关信息

hciconfig –a

root@android:/ # hciconfig -a
hciconfig -a
hci0: Type: BR/EDR Bus: UART//蓝牙的接口类型。这个是UART的。还有USB、PCI…………
BD Address: 00:16:53:96:22:53 ACL MTU: 1021:8 SCO MTU: 120:10//蓝牙地址
UP RUNNING PSCAN//命令状态
RX bytes:2846 acl:0 sco:0 events:67 errors:0
TX bytes:2034 acl:0 sco:0 commands:80 errors:0
Features: 0xff 0xff 0x8d 0xfe 0x9b 0xbf 0x79 0x83
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3//支持数据包
Link policy: RSWITCH HOLD SNIFF PARK
Link mode: SLAVE ACCEPT//连接的类型。是主设备、从设备
Name: 'sp8825c1'//蓝牙名称
Class: 0x5a020c//蓝牙的类型
Service Classes: Networking, Capturing, Object Transfer, Telephony//支持的类型
Device Class: Phone, Smart phone
HCI Version: 2.1 (0x4) Revision: 0x1250//HCI版本号
LMP Version: 2.1 (0x4) Subversion: 0x1250//LMP版本号
Manufacturer: Ericsson Technology Licensing (0)//作者

(3)、启动蓝牙
hciconfig hci0 up
(4)、关闭蓝牙
hciconfig hci0 down
(5)、查看hci命令
hciconfighci0 commands 

(6)、显示OOB数据
Hciconfig hci0 oobdata

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Android blueZ HCI(一个):hciconfig实施和经常使用的更多相关文章

  1. S5PV210之Sate210-F DIY硬件,移植uboot,kernel,android 活动现在已经进入实施阶段吗,欢迎广大网友参与 !

    大家一起来diy 超低价四核的exynos4412或者Cortex A8S5pv210开源开发板 商业版Sate210已经完成了好久了.Sate4412 也已经出来.但是这两个接口非常全,主要是针对企 ...

  2. Android发展的一个重要方面Makefile分析

    Android发展的一个重要方面Makefile分析 随着移动互联网的发展,移动开发也越来越吃香了.眼下最火的莫过于android.android是什么就不用说了,android自从开源以来,就受到非 ...

  3. 二维码合成,将苹果和安卓(ios和android)合成一个二维码,让用户扫描一个二维码就可以分别下载苹果和安卓的应用

    因为公司推广的原因,没有合适的将苹果和安卓(ios和android)合成一个二维码的工具. 因为这个不难,主要是根据浏览器的UA进行判断,所以就自己开发了一个网站 网站名称叫:好推二维码  https ...

  4. Android 如何判断一个应用在运行(转)

    Android 如何判断一个应用在运行  在一个应用中,或一个Service .Receiver中判断一个应用是否正在运行,以便进行一些相关的处理. 这个时候我们需要得到一个ActivityManag ...

  5. android studio 导入一个已有的android studio project作为lib使用

    android studio 导入一个已有的android studio project作为lib使用 新项目来了. 需要搭建框架. android studio对我来说还是很陌生,之前一个项目在同事 ...

  6. Android Studio新建一个HelloWorld 程序(App)

    Android Studio新建一个HelloWorld程序(App) 新建 或者直接启动程序(注:如果已有程序,此方法会直接打开最近一次关闭从程序) 更改App名 选择App运行平台 选择模板 更改 ...

  7. android 自己创建一个凝视模板

    android  自己创建一个凝视模板 作为一名程序猿 不仅要有一个写代码的能力,养成一个良好的编写习惯也是非常重要的. 今天给大家具体介绍一下怎样创建凝视模板,给每一个类和方法都自己手动去凝视信息也 ...

  8. Android下实现一个简单的计算器源码

    下面的内容是关于Android下实现一个简单的计算器的内容. import android.app.Activity; import android.os.Bundle;import android. ...

  9. [android] android下创建一个sqlite数据库

    Sqlite数据库是开源的c语言写的数据库,android和iphone都使用的这个,首先需要创建数据库,然后创建表和字段,android提供了一个api叫SQLiteOpenHelper数据库的打开 ...

随机推荐

  1. IfSpeed 带宽计算

    http://www.360doc.com/content/11/0304/22/2614615_98214710.shtml http://www.cisco.com/support/zh/477/ ...

  2. Hadoop基本原理之一:MapReduce 分类: A1_HADOOP 2014-08-17 19:26 1113人阅读 评论(0) 收藏

    1.为什么需要Hadoop 目前,一块硬盘容量约为1TB,读取速度约为100M/S,因此完成一块硬盘的读取需时约2.5小时(写入时间更长).若把数据放在同一硬盘上,且全部数据均需要同一个程序进行处理, ...

  3. 用Ajax图片上传、预览、修改图片

    首选图片的上传和下载并不是很难,但要注意细节. 一,给出前端图片上传的html代码 1.图片上传的控件 <img src="/${res}/images/default.png&quo ...

  4. iOS开发Block的介绍以及Block的循环引用问题

    1:block的循环引用问题最主要记住两点: 如果[block内部]使用[外部声明的强引用]访问[对象A], 那么[block内部]会自动产生一个[强引用]指向[对象A] 如果[block内部]使用[ ...

  5. AngularJS之基本指令(init、repeat)

    <h3>ng-init初始化变量</h3> <div ng-init="name='aurora';age='18'"> <p ng-bi ...

  6. [tmux] Manage terminal workspaces using session naming

    It's a lot easier to manage your tmux session when they have sensible names. We'll cover: How to cre ...

  7. 【hdu 2955】Robberies

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  8. Qt5.4.2编译 qtpropertybrowser-2.51(从4修改到5的除错过程)

    qtpropertybrowser是一个洛基亚时代的一个产物,其实它就是QtDesigner侧栏那种样子而已.网上大部分的都只适用于Qt4,今天头脑发热想用Qt5编译一下,发觉一大堆错误,因为Qt4有 ...

  9. 【hdu 1527】取石子游戏

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

  10. 【hdu 2897】邂逅明下

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...