天天看點

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

版權所有,轉載請注明出處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,那麼,買了藍牙擴充卡之後,大概就可以把臃腫的驅動CD光牒丢進垃圾桶,然後心情愉快的使用藍牙了,跟我來吧,

核心的協定棧支援主要包含這麼幾個部分:

  • 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之類的懷疑,還有程式設計接口之類的問題,就發到這裡吧。

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧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 裡的以下幾項全部選上即可:

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意
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 driver

BCSP 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,就是為了使用

是騾子是馬拉出來遛遛

但是我們不得不說寫題外話,我們必須了解藍牙的機制,以及藍牙指令以及配置檔案等資訊

藍牙配置檔案

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧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";                                                      
}  
           

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 的話

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

插入 USB 擴充卡後,你的 hcid 就已經在運作了,看看相關資訊吧

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

這個過程是自動的,當然,你也可以用 hciconfig (8) 來手工控制。

尋找藍芽裝置

hcitool

HCI 已經啟動了,現在就可以用它來尋找藍芽裝置了,當然,一定要先開啟藍芽裝置的藍芽功能,這個不是廢話,手機的藍芽是預設關閉的,隻有在手動控制之下才會發送信号,允許被掃描到,不過裝置的個體差異性太大了,這裡就沒法介紹了,我假設你已經自己摸索或參照說明書打開了裝置的藍芽電源,現在,找找看吧

hcitool scan
           
ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

我們發現藍牙已經掃描發現額我的華為手機,名字為

gatieme

協定檢視工具

sdptool

利用 SDP 協定,我們還可以檢視每個裝置都有功能,能提供什麼服務,每種基于 RFCOMM 的服務都使用某種協定,占據一個“頻道 (channel)”,這是我們使用服務時的一個重要參數

使用

sdptool brower [address]

可以檢視我們的裝置所支援的協定和功能

下面是例子,先看看自己本機的資訊

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

好了,再看看我的手機

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

利用藍牙發送檔案

利用藍芽傳送檔案使用的都是前面提到的 Obex 協定,這裡介紹幾個用法。

與手機互相推送檔案

這是使用手機或計算機提供的”OBEX Object Push” (0x1105)服務,由另一方向其推送檔案。使用的工具是 openobex-apps 包裡的 obex_test工具

首先是向手機推送,對于我的手機,推送服務在頻道8:

可以看到,執行完 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 的結果)。

看看有哪些目錄:

下載下傳檔案,我們把它一個啊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平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

說明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

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

激活我們的藍牙裝置hciconfig hci0 up

前面已經說過我們的藍牙擴充卡的裝置名為usbdev1.4,是以采用如下指令激活

hciconfig usbdev1.4 up
           
ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

掃描可連接配接的藍牙裝置

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

檢視裝置支援的協定和功能

增加自動配對設定

通過修改 /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";
}
           

首次連接配接需要建立裝置結點

注意隻需要在第一次連接配接時設定裝置結點

使用如下指令可直接建立裝置結點

其實,它等同于如下指令系列

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消息資訊

為了減少麻煩,把所有支援的藍牙服務都加上.

增加藍牙序列槽綁定

利用實用工具rfcomm可以把遵循RFCOMM的服務bind到一個類似的序列槽裝置上。在綁定之前,必須確定/dev下有rfcomm*的裝置,如果沒有,就參照前面自己建立

#rfcomm bind /dev/rfcomm0 藍牙裝置位址 通道,這個指令可選

此時我們輸入

rfcomm0

會發現

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

如果希望解除藍牙綁定

格式:sudo rfcomm release /dev/rfcomm0 藍牙裝置位址 通道

這樣就可以綁定了,比如我需要用手機撥号上網的功能,看到它的

Channel 1

RFCOMM

Dialup Networking

功能,則即将

00:13:EF:A0:00:AF

裝置的

Channel 1

服務綁定到

/dev/rfcomm0

上,這樣,就相當于建立了一個虛拟的串行連接配接到一個可以撥号的無線

modem

上了,打開

minicom

,設定序列槽為

/dev/rfcomm0

,波特率

19200

8N1

,鍵入

atz

,傳回OK。用

ppp

就可以撥号上網了,第一次連接配接時手機會彈出個輸入框問PIN code,以後就不用了。同樣我們也使用類似方法使用手機的GPS功能

另外,sdpd程式是本裝置提供給對外的看到的服務,可以通過sdptool add –channel=X SP來增加對外的服務

連接配接藍牙裝置

連接配接藍牙耳機

前面的工作和連接配接藍牙裝置相同,都需要激活藍牙,然後我們開始掃描

掃描耳機,得到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: [email protected]
# 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裝置

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

通過/dev/rfcomm0讀取GPS資訊

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

連接配接總結

作為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

下,也就是說我們得在闆子上同樣将配置檔案或者庫放到這個目錄下,配置檔案才能讀取。

ARM平台上藍牙協定棧Bluez的移植使用和配置前言藍牙協定棧bluez移植配置并連接配接藍牙裝置注意

但是我們也可以使用其他的方式,

-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聲霸卡裝置的接口。

繼續閱讀