ARM平台上蓝牙协议栈Bluez的移植使用和配置

♥arm♥ 同时被 2 个专栏收录
20 篇文章 1 订阅

版权所有,转载请注明出处http://blog.csdn.net/gatieme/article/details/48751743
参考
http://blog.csdn.net/lizzywu/article/details/7662110
http://blog.csdn.net/colorant/article/details/2590654

前言


blue简介

蓝牙(Bluetooth),或称为蓝芽,是一种新式的无线传送协议,最初由爱立信创制,后来由蓝牙特别兴趣组订定技术标准。据说因为此技术尚在萌芽的阶段,故将Bluetooth以“蓝牙”的中文译名在台湾地区进行商业的注册,不过根据英文本身的意义直译,还是“蓝牙”较为贴切。

蓝牙用于在不同的设备之间进行无线连接,例如连接计算机和外围设施,如:打印机、键盘等,又或让个人数字助理(PDA)与其它附近的PDA或计算机进行通信。目前市面上具备蓝牙技术的手机选择非常丰富,可以连接到计算机、PDA甚至连接到免提听筒。

蓝牙技术最初由爱立信创制。1999年5月20日,索尼爱立信、IBM、英特尔、诺基亚及东芝等业界龙头创立蓝牙特别兴趣组,制订蓝牙技术标准。“蓝牙”这名称来自10世纪的丹麦国王哈拉尔德(Harald Gormsson)的外号。出身海盗家庭的哈拉尔德统一了北欧四分五裂的国家,成为维京王国的国王。由于他喜欢吃蓝莓,牙齿常常被染成蓝色,而获得“蓝牙”的绰号,当时蓝莓因为颜色怪异的缘故被认为是不适合食用的东西,因此这位爱尝新的国王也成为创新与勇于尝试的象征。1998年,爱立信公司希望无线通信技术能统一标准而取名“蓝牙”。

Bluetooth用于连接个人周边的外围设备,比如无线耳机、打印机、扫描仪、手机、计算机等等,在这些设备之间交换文件和数据,替代低速串行线的工作,常用用途包括

* 文件共享、传输
* 语音传输
* 远程打印
* RS-232串行口线替代

因为Bluetooth的功能十分实用、一经提出,立刻有一种一呼百应的感觉,随着成本的下降,蓝牙的用途也越来越广(当然了,这个过程也不是一帆风顺的了),大量的中低端手机也开始装备上了这项技术,以其更丰富、完善的协议栈,略高的传输速率,以及相对于红外线来说摆脱了必须毫无障碍的束缚,几乎完全取代了原来商务手机上普遍装备的红外接口。

蓝牙来到中国,把“牙”替换成了更有东方美感的“芽”字。

蓝牙实际上并不是一种简单的协议,相反,十分复杂

从网络结构和组网方式讲,蓝牙在10米区域内形成一个网络,其中可以有1个主设备,7个从设备,一共8个激活的设备,当然睡觉的设备还可以有很多,不打呼噜就行了。对于更多的设备,可以使用ad hoc的方式互联,学网络的同学们看到这个来精神了吧,不过我可不打算讲了。

从应用来看,BT支持语音通信和串行线模拟,并且通过Profile来支持各种周边智能设备的应用,比如耳机、打印机……并且定义了一套服务发现和调用机制,还是瞒有意思的。

蓝牙最有意思的模过于第2层互联和应用层的Profile了,至于底层的跳频什么的倒是新意不大。另外就是,虽然蓝牙使用的频率和微波炉烹饪的频率毫无二致,但发射功率还是很小的,基本不足以把我们这么大块的肉弄熟。

Linux下的蓝牙协议栈


Linux 下有若干个蓝牙协议栈,目前生存状况比较健康的是bluez和affix,后者大概是Nokia支持的吧,前者则是目前蓝牙的Linux官方版本,集成在 Linux内核之中,也就是说,如果你有一个比较新的2.6内核,那么,你多半已经支持蓝牙了,而如果还不支持的话,重新编译一下也就好了。

不要觉得Linux的协议栈比不上Windows里面的,事实是,这里风景独好,bluez协议栈支持的硬件设备远远多于windows系统支持的。如果你和我一样只用Linux,那么,买了蓝牙适配器之后,大概就可以把臃肿的驱动光盘丢进垃圾桶,然后心情愉快的使用蓝牙了,跟我来吧,

内核的协议栈支持主要包含这么几个部分:

  • HCI. 这个是最底层的了,称为 Host Control Interface. 之所以称为 HCI 是源于蓝牙的应用模型的。蓝牙是连接智能外设的无线接口,接口的一侧是设备,另一侧就是主机 (Host) 了,采用类似记法的还有 USB, IEEE1394,所以,从设计初衷来看,这几个东东都是针对差不多的市场的,当然,各有所长了。一个蓝牙适配器是否能被驱动起来,就看 HCI 的支持性了。最常见的蓝牙适配器就是笔者持有的这类 USB 接口的了,对于大部分标准的蓝牙设备,它的驱动模块是: hci-usb,对于我们的 2.6 内核,插入这个适配器,该模块就被自动加载了。

  • L2CAP之上有两个协议被较广地使用着:RFCOMM和BNEP,前者用于取代传统的串行口,包括串行口上的各种应用,比如,传真和拨号上网、打印机、文件图片等数据传输;后者则可以提供一个以太网接口,更适于计算机组网。自然地,对于手机和计算机之间,RFCOMM 总是更常被用到。

截止到这里就是内核提供的几乎所有蓝牙协议栈了,不过,仅有这些,蓝牙还不足以为我所用,只有有了用户态的协议栈和工具相配合,才有幸福的蓝牙生活 :)
用户空间中的蓝牙协议栈与相关工具

接着刚才的协议栈,这次势在用户空间实现的了:

  • 在最上层,蓝牙定义了很多的Profile,每个Profile对应着一种应用,比如打印、耳机(Headset)、文件传输、Fax/Modem拨号功能等。其中,文件交换对应着Obex协议,这是一个基于蓝牙、红外(IrDA)、串口等介质的文件(对象)交换协议,这几种介质被列到一起一点也不会让人感到意外,毕竟前两个都是用来在某种意义上取代串口的。当然,有些Profile,比如一些人机交互设备 (键盘鼠标之类的) 的profile 是在内核中实现的。

  • 实际上,我们还有一个重要的协议没有介绍,这就是SDP — 服务发现协议,这个协议可以认为和RFCOMM处于统一层次,因为它并不承载于RFCOMM之上,不过,这个协议却十分特殊而重要,通过它,我们才能识别出某一蓝牙设备提供了哪些服务(Profile),从而为我所用。

嗯,协议栈已经有了,那我们怎么使用蓝牙呢? 回忆一下怎么把大象放到冰箱里吧:

    * 打开冰箱门
    * 把大象放进冰箱
    * 关上冰箱门

就是这么简单,一个蓝牙服务也是这么容易

  • 找到蓝牙设备,这是HCI层负责的,使用 bluez-utils 包提供的 hcitool 来找到蓝牙设备;
  • 找到服务,RFCOMM 是通过不同的频道 (channel) 来提供不同的Profile的,所以,我们需要找到我们要用的服务在设备上的哪个频道上,这是通过同一个软件包里的 sdptool 来完成的,没错,就是 SDP,服务发现协议。
  • 连接恰当的服务,使用

蓝牙的特点就是如上所属的那些了,而用户态的工具所要完成的任务就是:

    * 发现服务
    * 使用服务

bluez简介


Bluez作为当前最成熟的开源蓝牙协议栈,它是一个基于GNU General Public License (GPL)发布的开源项目,已成为linux官方的蓝牙协议栈(从Linux2.4.6开始便成为Linux 内核的一部分),在Linux的各大发行版中已经得到了广泛的应用。在桌面环境下,使用Bluez应该已经没有太大的问题,但是arm上仍然需要我们移植以及配置bluez,本文的主要目的是介绍在嵌入式arm平台上,移植和配置Bluez的。

因为本人的能力和测试时间有限,可能下文中有些理解、分析不一定准确,欢迎联系指正。

BlueZ支持蓝牙核心层和协议,它灵活、高效,以模块化方式实现,具有以下特点:
n        完整的模块化实现
n        均衡的多处理安全
n        支持多线程数据处理
n        支持多个蓝牙设备
n        硬件抽象
n        向所有层提供标准socket接口
n        提供设备和服务级安全保证

BlueZ包含多个相互独立的模块:
n        Linux内核蓝牙子系统核心
n        L2CAP 和 SCO 音频内核层
n        RFCOMM, BNEP, CMTP 和 HIDP内核实现
n        HCI UART, USB, PCMCIA 和虚拟设备驱动
n        通用蓝牙和SDP库和守候进程
n        配置和测试小工具
n        协议解码和分析工具

BlueZ内核模块,程序开发库和小工具能在支持Linux的多种硬件架构系统上运行,既支持单核也支持多核处理器。BlueZ主要支持以下系统平台:
n        Intel and AMD x86
n        AMD64 and EM64T (x86-64)
n        SUN SPARC 32/64bit
n        PowerPC 32/64bit
n        Intel StrongARM and XScale
n        Hitachi/Renesas SH processors
n        Motorola DragonBall
现在市面上的很多Linux发行版都支持BlueZ,基本上任何一个Linux系统都兼容BlueZ,如:
n        Debian GNU/Linux
n        Ubuntu Linux
n        Fedora Core / Red Hat Linux
n        OpenSuSE / SuSE Linux
n        Mandrake Linux

网络资源


Bluez的官方网址:http://www.bluez.org/ 这里提供最新的源码下载
BlueZ的源代码可以从http://www.bluez.org/download/下载

其中Linux 2.4 and 2.6 系列内核已经包含BlueZ内核模块源程序,因此要使用BlueZ只需下载最新稳定的Linux内核源码就行了。而从前面的网址可以下载一些库和工具程序的源代码,也可以通过源码仓库http://www.bluez.org/development/git/来下载源码。

Bluez的Wiki:http://wiki.bluez.org/wiki/ 这里提供Bluez相关的Howto等文档资源
相关邮件列表:
https://lists.sourceforge.net/lists/listinfo/bluez-users 关于如何使用和配置Bluez,多数是在讨论PC环境下的问题。。。。
https://lists.sourceforge.net/lists/listinfo/bluez-devel Bluez开发者活动的地方,有什么Bug之类的怀疑,还有编程接口之类的问题,就发到这里吧。
bluez官网

开发环境


硬件平台:realarm
蓝牙芯片:CSR BC4 ROM 版本芯片,不带eeprom
软件环境:linux 2.6.35.7 ,自制文件系统
Bluez版本:bluez-libs-3.36
交叉编译环境:Ubuntu14.04-LTS,arm-linux-gcc 4.4.3

蓝牙协议栈bluez移植


配置内核支持Bluetooth


相信多数人使用的都是2.6的内核了,在2.6的内核中要支持Bluez,只要你的内核版本不是太旧,无需打Patch,直接配置好就OK了,内核里面的代码相对比较稳定了。当然,Bluez对一些Bluetooth协议栈新特性的支持,还是需要更新kernel代码的。你应该确认你使用的kernel版本是否以及包含了对应的支持。

内核的配置,基本上把 networking下 — Bluetooth subsystem support 里的以下几项全部选上即可:
内核配置

make menuconfig
[*] Networking support  --->                
<*>   Bluetooth subsystem support  --->    //蓝牙子系统必须选择
<*>   L2CAP protocol suppor       //逻辑链路控制和适配协议。
<*>   SCO links support           //蓝牙语音和耳机支持
<*>   RFCOMM protocol suppor      //面向流的传输协议,支持拨号网络等
[*]   RFCOMM TTY support          //
<*>   BNEP protocol support       //蓝牙网络封装协议,自组网支持
[*]   Multicast filter support    //蓝牙多播,支持支持BNEP
[*]   Protocol filter support //蓝牙多播,支持支持支持BNEP
<*>   HIDP protocol support       //基本支持协议
Bluetooth device drivers  --->
<*> HCI USB driver              //USB蓝牙模块支持
<M>HCI UART driver              //基于串口,CF卡或PCMCIA的蓝牙
<*> HCI BlueFRITZ! USB driver
<*> HCI VHCI (Virtual HCI device) driver

此外,在Bluetooth device drivers里选上你所需要支持的Bluetooth设备。我使用的CSR的chip是我们直接build在板子上,通过串口和cpu通讯的,芯片默认使用BCSP作为通讯协议,所以我选择了HCI UART driverBCSP protocol support
如果你是通过usb接口使用蓝牙适配器,需要选择HCI USB driver
然后我们执行make zIamge生成内核镜像,烧写如板子中,这块我们不详细讲,不是我们今天内容的重点。

交叉编译并移植蓝牙协议栈bluez


移植过蓝牙协议栈的人,肯定会觉得,Bluez协议栈的编译是最麻烦的一件事情。其实,如果你能理清楚bluez-utils所依赖的一些库,你就能很快的cross-compile交叉编译出一套能在开发板上跑起来的程序。关键是如何去理清楚协议,我总结出来的方法是,倒着推,你不知道bluez-utils依赖那些库,那就先直接编译bluez-utils,根据编译显示的错误,分析错误,找出来它所依赖的库,这样一步一步的分析下去,你就可以把蓝牙协议栈交叉编译出来。如果你不会分析错误或则不想去分析,可以,那你就直接把错误粘贴到网上,让搜索引擎给你找。

首先是我们所需要编译的库文件

bluez-libs-3.36.tar.gz
expat-2.1.0.tar.gz
dbus-1.10.0.tar.gz 
glib-2.26.1.tar.gz
bluez-utils-3.36.tar.gz
libusb-1.0.9.tar.bz2

下面我将bluez的库全部编译在了我电脑上/opt/arm/bluez目录下,大家可以根据自己的需要自己修改–prefix来指定路径

编译blue-lib


下载地址:http://www.bluez.org/download/

tar zxvf bluez-lib-3.36.tar.gz
./configure --prefix=/opt/arm/bluez --host=arm-linux --target=arm-linux CC=arm-linux-gcc
make 
make install

make install时注意由于arm-linux-gcc的PATH是在~/.bashrc中
sudo以后相当于root账户,这样我们PATH中配置的arm-linux-gcc就没有了
因此可能会报一些编译器链接的错误,比如
../libtool: line 6619: arm-linux-ranlib: command not found
我们可以有多种解决方案
① 将arm-linux-gcc的环境变量添加在全局的配置文件中
② 手动添加PATH或者直接source /home/gatieme/.bashrc

编译expat


官方地址:http://www.libexpat.org/
下载地址:http://sourceforge.net/projects/expat/
这个库是后面的dbus依赖的,你也可以用expat来代替libxml2,官方网站上说dbus必须依赖于他们中的一个。官方网站上说dbus必须依赖于他们中的一个,我这里用的是expat-2.1.0.tar.gz

tar zxvf expat-2.1.0.tar.gz
./configure --prefix=/opt/arm/bluez --host=arm-linux --target=arm-linux     CC=arm-linux-gcc
make 
make install

编译dbus


下载地址 :http://dbus.freedesktop.org/releases/dbus/

tar zxvf dbus-1.10.0
echo ac_cv_have_abstract_sockets=yes>arm-linux.cache
./configure --prefix=/opt/arm/bluez --host=arm-linux --target=arm-linux     CC="arm-linux-gcc -I/opt/arm/bluez/include -L/opt/arm/bluez/lib" --cache-file=arm-linux.cache --with-x=no
make 
make install

出现的问题
checking for accept4… yes
checking abstract socket namespace… no
checking for pkg-config… (cached) /usr/local/bin/pkg-config
checking pkg-config is at least version 0.9.0… yes
checking for XML_ParserCreate_MM in -lexpat… no
configure: error: Could not find expat.h, check config.log for failed attempts
解决方案:
export LDFLAGS=-Wl,-L/usr/local/lib,-lexpat
export CPPFLAGS=-I/usr/local/include

编译glib


下载地址 http://ftp.gnome.org/pub/gnome/sources/glib/

tar  -zxjf  glib-2.26.1.tar.gz
echo ac_cv_type_long_long=yes>arm-linux.cache
echo glib_cv_stack_grows=no>>arm-linux.cache
echo glib_cv_uscore=no>>arm-linux.cache
echo ac_cv_func_posix_getpwuid_r=yes>>arm-linux.cache
echo ac_cv_func_posix_getgrgid_r=yes>>arm-linux.cache
#注意:">"和">>"的区别

./configure --prefix=/opt/arm/bluez --host=arm-linux --target=arm-linux     CC="arm-linux-gcc -I/opt/arm/bluez/include -L/opt/arm/bluez/lib" --cache-file=arm-linux.cache
make 
make install

出现的问题

安装glib 时出现glib msgfmt.. no (这个问题极易出现在Ubuntu 上)
解决方案:apt-get install gettest

安装glib 时出现 error: Could not find a glib-genmarshal in your PATH,
解决方案:先在主机安装 apt-get install libglib2.0-dev一

configure: error: cannot run test program while cross compiling
就检查依赖关系,然后修改arm-linux.cache文件
向arm-linux.cache文件中写入配置信息,我们在编译前通过echo向该文件中写入的配置,就是为了解决这些问题

configure: error: Could not find a glib-genmarshal in your PATH
安装libglib2.0-dev
sudo apt-get install libglib2.0-dev

编译libusb


这个库不需要什么依赖,直接解压,配置,编译然后安装即可。

tar jf  libusb-1.0.9.tar.bz2
./configure --prefix=/opt/arm/bluez --host=arm-linux --target=arm-linux CC="arm-linux-gcc -I/opt/arm/bluez/include -L/opt/arm/bluez/lib"
make 
make install

编译bluez-utils


下载地址:http://www.bluez.org/download/
如果你需要打开所有的功能模块的支持,需要在 ./configure 参数中添加 –enable-all –enable-audio –enable-input –enable-network –enable-serial 等,在3.36版本中 –enable-all 居然不包括 audio等相关模块的service的编译,不知道是否是因为还保留了daemon和service等不同方案的缘故。不过,这至少与他的configure –help 对于 –enable-all 的描述是不符合的。

tar zxvf bluez-utils-3.36.tar.gz
./configure --prefix=/opt/arm/bluez --host=arm-linux --target=arm-linux     CC="arm-linux-gcc -I/opt/arm/bluez/include -L/opt/arm/bluez/lib" --disable-audio
make 
make install

bluez-utils ./configure 时出现:BLUEZ no Bluetooth library is required
解决方案:sudo apt-get install libbluetooth-dev

bluez-utils ./configure 时出现:configure: error: D-Bus library is required
解决方案:sudo apt-get install libdbus-1-dev libdbus-glib-1-dev

bluez-utils 编译 make 时出现bluez libgmodule-2.0.so could not read symbols: File in wrong 等
解决方案: 查看 glib 配置时的 arm-linux.cache 和环境变量的配置,问题极有可能出现在这里

移植bluez


在自己配置 ./configure –prefix=/opt/arm/bluez 时 说明自己的库会被安装在/opt/arm/bluez 下

#copy /opt/arm/bluez/sbin/* 到你的文件系统/sbin
cp bluez/sbin/*   /sbin/
#copy /opt/arm/bluez/bin/ 下的 hcitool,rfcomm,sdptool 到你的文件系统 /bin
cp bluez/bin/*    /bin/
#copy /opt/arm/bluez/lib/* 到文件系统的/lib下 
#copy /opt/arm/bluez/etc/bluetooth/* 到你的文件系统 /etc
cp bluez/etc/bluetooth  /etc/

测试

hciconfig hci0 up  启用蓝牙
hciconfig hci0 iscan配置开发板蓝牙可被查找
hcitool scan 查找蓝牙
Scanning ...
        04:02:1F:A2:B2:AF       gatieme                       #  这个是我的手机
        00:13:EF:A0:00:AF       GPFILE Morr2           #  这个是我的蓝牙耳机

配置并连接蓝牙设备


我们移植了bluez,就是为了使用是骡子是马拉出来遛遛 但是我们不得不说写题外话,我们必须了解蓝牙的机制,以及蓝牙命令以及配置文件等信息

蓝牙配置文件


蓝牙配置文件

蓝牙采用/etc/bluetooth/下的hcid.confrfcomm.conf 来进行配置。

hcid.conf配置文件

其中hcid.conf有关配对信息。其中security user;表示每次配对询问用户对方PIN,而auto则直接采用passkey中的PIN码。

如果修改了此文件则需要重启bluetooth服务。

重启蓝牙请使用如下命令
service bluetooth restart
或者
/etc/init.d/bluetooth restart

#
# HCI daemon configuration file.
#

# HCId options
options {
        # Automatically initialize new devices
        autoinit yes;

        # Security Manager mode
        #   none - Security manager disabled
        #   auto - Use local PIN for incoming connections
        #   user - Always ask user for a PIN
        #
        security user;

        # Pairing mode
        #   none  - Pairing disabled
        #   multi - Allow pairing with already paired devices
        #   once  - Pair once and deny successive attempts
        pairing multi;

        # Default PIN code for incoming connections                           
        passkey "BlueZ";                                                      
}  

rfcomm.conf配置文件

这个文件用来配置我们连接的蓝牙设备,包括是否在初始化的时候,自动连接设备rfcomm0,以及设备的地址,使用频道1,设备的名字等等配置信息。

#                                                                             
# RFCOMM configuration file.                                                  
#                                                                             

#rfcomm0 {                                                                    
#       # Automatically bind the device at startup                            
#       bind no;                                                              
#                                                                             
#       # Bluetooth address of the device                                     
#       device 11:22:33:44:55:66;                                             
#                                                                             
#       # RFCOMM channel for the connection                                   
#       channel 1;                                                            
#                                                                             
#       # Description of the connection                                       
#       comment "Example Bluetooth device";                                   
#}    

蓝牙命令


命令什么的,由于我们的arm并没有那么全的命令支持,那么我们就在本机上测试这些命令吧

操作系统自带HCI工具主要来自bluez-util.

sbin/hciattach : attach serial devices via UART HCI to BlueZ stack
sbin/hcid     :Bluetooth Host Controller Interface Daemon
sbin/hciemu    :HCI emulator 
sbin/hciconfig :  configure Bluetooth devices
sbin/hcidump  : Parse HCI data
bin/hcitool   : configure Bluetooth connections
bin/sdptool    : control and interrogate SDP servers

启动 HCI 设备hciconfig

首先,我们需要启动 hcid,让 HCI 层的通信可以进行,对于 Debian 用户来说,你需要安装 bluez-utils 包,并启动 hcid。如果你运行了 bluetooth 服务,并在 /etc/init.d/bluetooth 之中设置启动了 HCID 的话

    HIDD_ENABLED=1

这里写图片描述
插入 USB 适配器后,你的 hcid 就已经在运行了,看看相关信息吧

hcitonfig -a

这里写图片描述
这个过程是自动的,当然,你也可以用 hciconfig (8) 来手工控制。

寻找蓝芽设备hcitool

HCI 已经启动了,现在就可以用它来寻找蓝芽设备了,当然,一定要先开启蓝芽设备的蓝芽功能,这个不是废话,手机的蓝芽是默认关闭的,只有在手动控制之下才会发送信号,允许被扫描到,不过设备的个体差异性太大了,这里就没法介绍了,我假设你已经自己摸索或参照说明书打开了设备的蓝芽电源,现在,找找看吧

hcitool scan

这里写图片描述
我们发现蓝牙已经扫描发现额我的华为手机,名字为gatieme

协议查看工具sdptool

利用 SDP 协议,我们还可以查看每个设备都有功能,能提供什么服务,每种基于 RFCOMM 的服务都使用某种协议,占据一个“频道 (channel)”,这是我们使用服务时的一个重要参数
使用sdptool brower [address] 可以查看我们的设备所支持的协议和功能
下面是例子,先看看自己本机的信息
这里写图片描述
好了,再看看我的手机
这里写图片描述

利用蓝牙发送文件

利用蓝芽传送文件使用的都是前面提到的 Obex 协议,这里介绍几个用法。
与手机互相推送文件
这是使用手机或计算机提供的”OBEX Object Push” (0x1105)服务,由另一方向其推送文件。使用的工具是 openobex-apps 包里的 obex_test工具

首先是向手机推送,对于我的手机,推送服务在频道8:

obex_test -b  04:02:1F:A2:B2:AF

可以看到,执行完 obex_test 之后,进入一个交互状态,首先建立连接,然后传送文件 (本地文件名是 test.jpg,存在手机上叫 get.jpg最后,退出。这个过程需要看着点手机屏幕,可能要你确认是否连接,文件存放在哪里,当然,这个和手机有关。

现在也可以看看手机向计算机推送,首先应该让手机进入接收状态,如果本地没有启动 Object PUSH 服务,己把它加上:

sdptool add OPUSH

现在进入接收状态,注意要使用计算机 (local) 的地址和频道号:

obex_test -b FF:FF:FF:00:00:00 9

现在,计算机进入了接收模式,在手机侧发送文件到计算机就可以了。
使用 obexftp 上传下载

使用”OBEX File Transfer” (0x1106)服务的 obexftp 是一个方便的工具,我们可以查看手机上的内容,并进行上传下载,对于我的手机,对应的频道是 9 (参考上面的 sdptool browse 的结果)。

看看有哪些目录:

obexftp -b 04:02:1F:A2:B2:AF -B 9 -l

下载文件,我们把它一个啊a.mp3取下来

obexftp -b 04:02:1F:A2:B2:AF -B 9 -c audio -g a.mp3

利用蓝芽手机拨号

我们说过,蓝芽的一个几本功能就是模仿串口,串口的重要作用之一 (可能是最重要的了) 就是拨号,传统的 DTE 也就是 Modem 嘛。实际上,通过 rfcomm,蓝芽连接可以反映在 /dev/rfcomm0 这样的字符设备上,像串口一样操作。当然,我们最好先定义 /etc/bluetooth/rfcomm.conf,里面根据手机的设备号和频道号写上

rfcomm0 {
       # Automatically bind the device at startup
    bind yes;

       # Bluetooth address of the device
    device 04:02:1F:A2:B2:AF;

       # RFCOMM channel for the connection
    channel 1;

       # Description of the connection
    comment "GatieMe";
}

这样,在启动 bluetooth 服务的时候,就已经自动连接上了,而不需要使用rfcomm (1) 命令自己费力气了。现在,可以使用任意一个喜欢的串口程序 (minicom, gtkterm 等等) 来对 /dev/rfcomm0 进行拨号了

输入 AT 命令的第一个命令:

AT
OK

试着播一下号

ATD1824950512;

这个是随便写的号码,大家找认识的号码播哦 (故意少写了两位,省得万一试到人家头上,呵呵)。
拨号就是这么简单,理论上讲,GPRS 连接应该也可以实现,不过,没有笔者开通业务,就算了,留给读者自己研究吧,呵呵。

连接蓝牙设备如手机

在Linux使用蓝牙最方便是使用bluez-util自带向个命令来测试。
我们这里采用市面最容易找到的蓝牙耳机来做测试,通过蓝牙适配器来进行通信。
mincom进入arm板,首先我们插入我们的蓝牙适配器,出现如下提示
蓝牙适配器的识别

说明arm板已经已经识别了我们的蓝牙适配器,设备名字为/dev/usbdev1.4
然后lsusb,查看我们的USB设备

检测USB设备,lsusb

#lsusb
Bus 001 Device 004: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 003: ID 0e0f:0002
Bus 001 Device 001: ID 0000:0000
Bus 002 Device 001: ID 0000:0000

查看hci设备,hciconfig

这里写图片描述

激活我们的蓝牙设备hciconfig hci0 up

前面已经说过我们的蓝牙适配器的设备名为usbdev1.4,因此采用如下命令激活

hciconfig usbdev1.4 up

激活蓝牙设备

扫描可连接的蓝牙设备


扫描设备

查看设备支持的协议和功能


sdptool brower 00:13:EF:A0:00:AF

增加自动配对设置

通过修改 /etc/bluetooth/rfcomm.conf可增加可扫描蓝牙地址
增加一个新的蓝牙设备,在启动时默认不练连接,设备地址为00:13:EF:A0:00:AF,使用频道1,设备名称为GPFILE Morr2

rfcomm0{
        bind no;
        device 00:13:EF:A0:00:AF;
        channel 1;
        comment "GPFILE Morr2";
}

首次连接需要创建设备结点

注意只需要在第一次连接时设置设备结点
使用如下命令可直接创建设备结点

rfcomm create dev #它将创建于/dev/rfcomm0 设备结点

其实,它等同于如下命令系列

mknod /dev/rfcomm0 c 216 1
chmod 666 /dev/rfcomm0
rfcomm bind /dev/rfcomm0 00:13:EF:A0:00:AF 1

或者直接mknod -m 666 /dev/rfcommX c 216 1
其中rfcomm用于绑定下面会我们会提到

增加SDP消息信息

为了减少麻烦,把所有支持的蓝牙服务都加上.

sdptool add --channel=1 DID SP DUN LAN FAX OPUSH FTP HS HF SAP NAP GN PANU HID CIP CTP A2SRC A2SNK SYNCML NOKID PCSUITE SR1

增加蓝牙串口绑定

利用实用工具rfcomm可以把遵循RFCOMM的服务bind到一个类似的串口设备上。在绑定之前,必须确保/dev下有rfcomm*的设备,如果没有,就参照前面自己建立

rfcomm bind /dev/rfcomm0 00:13:EF:A0:00:AF 1

#rfcomm bind /dev/rfcomm0 蓝牙设备地址 通道,这个命令可选
此时我们输入rfcomm0会发现
蓝牙绑定信息

如果希望解除蓝牙绑定
格式:sudo rfcomm release /dev/rfcomm0 蓝牙设备地址 通道
这样就可以绑定了,比如我需要用手机拨号上网的功能,看到它的Channel 1RFCOMMDialup Networking 功能,则即将00:13:EF:A0:00:AF 设备的Channel 1 服务绑定到/dev/rfcomm0 上,这样,就相当于建立了一个虚拟的串行连接到一个可以拨号的无线modem上了,打开minicom ,设置串口为 /dev/rfcomm0,波特率192008N1,键入atz,返回OK。用ppp就可以拨号上网了,第一次连接时手机会弹出个输入框问PIN code,以后就不用了。同样我们也使用类似方法使用手机的GPS功能
另外,sdpd程序是本设备提供给对外的看到的服务,可以通过sdptool add –channel=X SP来增加对外的服务

连接蓝牙设备

hcitool cc 00:13:EF:A0:00:AF

连接蓝牙耳机


前面的工作和连接蓝牙设备相同,都需要激活蓝牙,然后我们开始扫描

扫描耳机,得到bdaddress


如果连接蓝牙耳机的话,可能需要更多的配置。
在之前的版本bluez2.X中我们可以直接使用btsco,后来更名为plugz(bluetooth-alsa),但是这个项目已经很久没有维护了,当然对于我们来说PulseAudio可能是更好的选择

hcitool scan

配置工作

modprobe snd_bt_sco
hciconfig hci0 void 0x0060
btsco bdaddress (这里的bdaddress就是扫描出来的结果)

建立连接后,设备被映射成/dev/dsp1

连接串口设备


当然对于我们也可以直接使用串口协议rfcomm进行连接,其他一些配置信息同上,我们在rfcomm.conf中填写配置信息,然后使用rfcomm connect即可连接

下面是我为了板子连接蓝牙GPS所设置的脚本,大家可以看下

#########################################################################
# File Name: bluetooth-gps.sh
# Author: GatieMe
# mail: gatieme@163.com
# Created Time: 2015年10月19日 星期二 14时36分31秒
#########################################################################
#!/bin/bash

hciconfig 1-1.4 up  #  激活蓝牙
#hciconfig 1-1.4 piscan # 设置蓝牙可见性
#hcitool scan       #  扫描蓝牙设备
address=00:1C:EF:00:48:48
chanle=1
# 
mknod -m 666 /dev/rfcomm0  c 216 1  # 创建设备结点
#rfcomm bind /dev/rfcomm0 00:10:22:01:00:44 $chanle
# 如果在rfcomm中填写了设备信息,可直接使用rfcomm create dev创建
#sdptool add --channel=$ch DID SP DUN LAN FAX OPUSH FTP HS HF SAP NAP GN PANU HID CIP CTP A2SRC A2SNK SYNCML NOKID PCSUITE SR1

# 连接蓝牙GPS设备,我的设备地址为00:1C:EF:00:48:48,频道1
rfcomm connect 0 $address $chanle &
#以上命令等同于rfcomm connect /dev/rfcomm0 00:1C:EF:00:48:48 1 &

以上是针对板子作为host来发起配对请求的,如果是希望自己的板子做slave的话
3.设置rfcomm后台监听:

rfcomm listen /dev/rfcomm0 1 &

以上两种情况任何一种连接ok,就可以操作rfcomm0口来进行正常串口通讯了.

蓝牙连接上了GPS设备
这里写图片描述

通过/dev/rfcomm0读取GPS信息

这里写代码片

连接总结


作为host


  • 首先配置蓝牙初始化信息hcid.conf
  • 在rfcomm.conf中配置设备信息(如果希望手动创建设备,此步可以跳过)
  • 查询要连接设备的信息sdptool browse XX:XX:XX:XX:XX
  • 设置连接rfcomm connect 0 XX:XX:XX:XX:XX 1&

作为slave


  • 首先配置蓝牙初始化信息hcid.conf
  • 在rfcomm.conf中配置设备信息(如果希望手动创建设备,此步可以跳过)
  • 设备SDP , sdptool add --channel=x SP x就是未使用的channel号.
  • 设置后台监听rfcomm listen /dev/rfcomm0 1&

注意


配置文件的读取问题

之前在编译的时候,没有配置配置文件的路径,导致在板子上配置信息不能读取,是因为我们在编译时有个–sysconfdir这个选项没有设置,默认的路径是我们安装路径的/etc下,对于我们编译的库来说就是/opt/arm/bluez/etc下,也就是说我们得在板子上同样将配置文件或者库放到这个目录下,配置文件才能读取。

这里写图片描述

但是我们也可以使用其他的方式,-f 参数来制定配置文件的信息

比如hcid.conf配置文件就使用hcid -f /etc/bluetooth/hcidconf

而rfcomm.conf配置文件就使用rfcomm -f /etc/bluetooth/rfcomm.conf

这样强制制定配置文件的路径也是可以的。

bluez库的架构


我们看到我们编了一堆包,但是其实,所有的操作都只是为了编译bluez-util 这个包。
bluez的协议层模块和驱动,都已经内置在内核中了,我们移植的只是bluez应用层提供的一些工具包和API,或者说就是命令。是为了我们更好的使用bluetooth。

bluez-lib提供了基本的函数API,也就是库
而dbus和glib等提供了一些其他工具包需要的函数API
也就是说前面编译的包都是bluez-util的依赖库,是为了让我们顺序的编译好工具命令

在bluez4.X和最新版bluez5.X中,已经将bluez-lib和bluez-util合并成了一个包,方便我们交叉编译。

其实不仅bluez的架构是这样的,我们linux下使用的很多协议或者库,都是这样的,最基本的物理层或者协议和驱动都在内核中,而我们平台移植就只需要移植一套工具包就可以,最简单的例子就是alsa声卡设备的接口。

打赏
文章很值,打赏犒劳作者一下
相关推荐
摘 要:基于对Linux 下蓝牙协议BlueZ 源代码的分析,给出BlueZ的组织结构和特点。分析蓝牙USB 传输驱动机制和数据处理过程, 给出实现蓝牙设备驱动的重要数据结构和流程,并总结Linux 下开发蓝牙USB 设备驱动的一般方法和关键技术。 关键词:Linux 系统;蓝牙协议;设备驱动 USB Device Driver for Linux Bluetooth Stack LIANG Jun-xue, YU Bin (Institute of Electronic Technology, PLA Information Engineering University, Zhengzhou 450004) 【Abstract】This paper depicts the structure and characteristics of BlueZ based on analyzing the source code of Linux bluetooth stack BlueZ. It analyzes the implementation of bluetooth USB transport driver scheme and data processing procedure in detail, and gives the key data structure and implementation of bluetooth device driver. It summarizes the approach of developing Linux bluetooth USB device driver and the key technology. 【Key words】Linux system; bluetooth stack; device driver 计 算 机 工 程 Computer Engineering 第 34 卷 第 9 期 Vol.34 No.9 2008 年 5 月 May 2008 ·开发研究与设计技术· 文章编号:1000—3428(2008)09—0273—03 文献标识码:A 中图分类号:TP391 1 概述 蓝牙技术是开放式通信规范,而 Linux 是开放源码的操 作系统。廉价设备与免费软件的结合,促进了蓝牙技术和 Linux 的发展与融合。 Linux最早的蓝牙协议是由Axis Communication Inc在 1999 年发布的 OpenBT 协议。 随后, IBM 发布了 BlueDrekar 协议,但没有公开其源码。Qualcomm Incorporated 在 2001 年发布的 BlueZ 协议被接纳为 2.4.6 内核的一部分。此外, Rappore Technology 及 Nokia 的 Affix Bluetooth Stack 都是 Linux 系统下的蓝牙协议,应用在不同的设备和领域中。 BlueZ 是 Linux 的官方蓝牙协议,也是目前应用最广 泛的协议,几乎支持所有已通过认证的蓝牙设备。对于基 于主机的蓝牙应用,目前常见的硬件接口有 UART, USB 和 PC 卡等,USB 作为 PC 的标准外设接口,具有连接方便、兼 容性好和支持高速设备等特点,已广泛应用于蓝牙设备。 目前对 Linux 下 USB 设备驱动的研究已较为广泛而深 入[1-4] ,但对 Linux 下的蓝牙设备驱动还没有专门的研究。本 文在分析 USB 设备驱动和蓝牙协议的基础上,总结了 Linux 下开发蓝牙 USB 驱动程序的一般方法,并深入剖析了 其关键技术。 2 Linux 蓝牙协议 BlueZ 简介 BlueZ 目前已成为一个开放性的源码工程。它可以很好 地在 Linux 支持的各种体系的硬件平台下运行,包括各种单 处理器平台、多处理器平台及超线程系统。 BlueZ 由多个独立的模块组成,内核空间主要包括设备 驱动层、蓝牙核心及 HCI 层、L2CAP 与 SCO 音频层、 RFCOMM, BNEP, CMTP 与 HIDP 层、通用蓝牙 SDP 库和后 台服务及面向所有层的标准套接字接口;在用户空间提供了 蓝牙配置、测试及协议分析等工具。其组织结构如图 1 所示, BlueZ 没有实现专门的 SDP 层,而是将其实现为运行在后台 的蓝牙服务库例程(图 1 没有描述该后台服务)。 RFOMM 层支 持标准的套接口,并提供了串行仿真 TTY 接口,这使串行端 口应用程序和协议可以不加更改地运行在蓝牙设备上,例如 通过点对点协议 PPP 可实现基于 TCP/IP 协议簇的所有网络
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页

打赏

CHENG Jian

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值