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

 

原作链接:http://lib.csdn.net/article/embeddeddevelopment/11277

作者:gatieme

 

blue简介

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

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

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

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

  • * 文件共享、传输
    * 语音传输
    * 远程打印
    * RS-232串行口线替代
  • 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),从而为我所用。

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

        * 打开冰箱门
        * 把大象放进冰箱
        * 关上冰箱门
  • 1
  • 2
  • 3
  • 就是这么简单,一个蓝牙服务也是这么容易

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

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

        * 发现服务
        * 使用服务
  • 1
  • 2
  • 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 此外,在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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 下面我将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
  • 1
  • 2
  • 3
  • 4
  • 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
  • 1
  • 2
  • 3
  • 4
  • 编译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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 出现的问题 
    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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 出现的问题

    安装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
  • 1
  • 2
  • 3
  • 4
  • 编译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
  • 1
  • 2
  • 3
  • 4
  • 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/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 测试

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


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

    蓝牙配置文件


    蓝牙配置文件

    蓝牙采用/etc/bluetooth/下的hcid.conf 和 rfcomm.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";                                                      
    }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 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";                                   
    #}    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 蓝牙命令


    命令什么的,由于我们的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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 启动 HCI 设备hciconfig

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

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

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

    寻找蓝芽设备hcitool

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

    hcitool scan
  • 1
  • 这里写图片描述 
    我们发现蓝牙已经扫描发现额我的华为手机,名字为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
  • 1
  • 可以看到,执行完 obex_test 之后,进入一个交互状态,首先建立连接,然后传送文件 (本地文件名是 test.jpg,存在手机上叫 get.jpg最后,退出。这个过程需要看着点手机屏幕,可能要你确认是否连接,文件存放在哪里,当然,这个和手机有关。

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

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

    obex_test -b FF:FF:FF:00:00:00 9
  • 1
  • 现在,计算机进入了接收模式,在手机侧发送文件到计算机就可以了。 
    使用 obexftp 上传下载

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

    看看有哪些目录:

    obexftp -b 04:02:1F:A2:B2:AF -B 9 -l
  • 1
  • 下载文件,我们把它一个啊a.mp3取下来

    obexftp -b 04:02:1F:A2:B2:AF -B 9 -c audio -g a.mp3
  • 1
  • 利用蓝芽手机拨号

    我们说过,蓝芽的一个几本功能就是模仿串口,串口的重要作用之一 (可能是最重要的了) 就是拨号,传统的 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";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 这样,在启动 bluetooth 服务的时候,就已经自动连接上了,而不需要使用rfcomm (1) 命令自己费力气了。现在,可以使用任意一个喜欢的串口程序 (minicom, gtkterm 等等) 来对 /dev/rfcomm0 进行拨号了

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

    AT
    OK
  • 1
  • 2
  • 试着播一下号

    ATD1824950512;
  • 1
  • 这个是随便写的号码,大家找认识的号码播哦 (故意少写了两位,省得万一试到人家头上,呵呵)。 
    拨号就是这么简单,理论上讲,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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 查看hci设备,hciconfig

    这里写图片描述

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

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

    hciconfig usbdev1.4 up
  • 1
  • 激活蓝牙设备

    扫描可连接的蓝牙设备


    扫描设备

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


    sdptool brower 00:13:EF:A0:00:AF
  • 1
  • 增加自动配对设置

    通过修改 /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";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 首次连接需要创建设备结点

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

    rfcomm create dev #它将创建于/dev/rfcomm0 设备结点
  • 1
  • 其实,它等同于如下命令系列

    mknod /dev/rfcomm0 c 216 1
    chmod 666 /dev/rfcomm0
    rfcomm bind /dev/rfcomm0 00:13:EF:A0:00:AF 1
  • 1
  • 2
  • 3
  • 或者直接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
  • 1
  • 增加蓝牙串口绑定

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

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

    如果希望解除蓝牙绑定 
    格式:sudo rfcomm release /dev/rfcomm0 蓝牙设备地址 通道 
    这样就可以绑定了,比如我需要用手机拨号上网的功能,看到它的Channel 1 是RFCOMM 的Dialup 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
  • 1
  • 连接蓝牙耳机


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

    扫描耳机,得到bdaddress


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

    hcitool scan
  • 1
  • 配置工作

    modprobe snd_bt_sco
    hciconfig hci0 void 0x0060
    btsco bdaddress (这里的bdaddress就是扫描出来的结果)
  • 1
  • 2
  • 3
  • 建立连接后,设备被映射成/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 &
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 以上是针对板子作为host来发起配对请求的,如果是希望自己的板子做slave的话 
    3.设置rfcomm后台监听:

    rfcomm listen /dev/rfcomm0 1 &
  • 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声卡设备的接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值