Android上成功實現了藍牙的一些Profile


前段時間做藍牙方面的開發,Google的Android只實現了Handset/Handfree和A2DP/AVRCP等Profile,而其 它常用的Profile如HID/DUN/SPP/OPP/FTP/PAN等卻沒有實現,並且Google方面關於何時實現也沒有一個時間表。

前段時間我實現了HID/DUN/SPP三個Profile,下一步實現OPP/FTP等Profile。具體的開發其實也簡單,我是參照A2DP的代碼進行的相關Profile的實現。

Android的Handset/Handfree的實現方式和A2DP/AVRCP的方式有很大的不同,Handset/Handfree是直接 在bluez的RFCOMM Socket上開發的,沒有利用bluez的audio plugin,而A2DP/AVRCP是在bluez的audio plugin基礎上開發的,所以大大降低了實現的難度。其實bluez的audio plugin上也有Handset/Handfree的實現,但不知道為什么Google沒有用它,而要在RFCOMM Socket上自己實現一個,這使得Handset/Handfree的實現顯得比較復雜。

HID要用到bluez的input plugin,Android已經把它編譯進去了,在system/lib/bluez-plugin/input.so下,與input.so一起的還 有audio.so庫,那是供A2DP/AVRCP用的。參照frameworks/base/core/jni /android_server_BluetoothA2dpService.cpp,自己寫一個HID用的的.cpp文件,其中跟A2DP一樣利用 DBUS調用input.so庫的CreateDevice/Connect/Disconnect等函數,具體源碼在external/bluez /utils/input/manager.c和external/bluez/utils/input/device.c中。完了之后,參照 frameworks/base/core/java/android/server/BluetoothA2dpService.java和 frameworks/base/core/java/android/bluetooth/BluetoothA2dp.java及 frameworks/base/core/java/android/bluetooth/IBluetoothA2dp.aidl,自己分別寫兩個 JAVA類及AIDL接口,余下的就是在packages/apps/Settings/src/com/android/settings /bluetooth目錄下的各個文件的修改了,比較省事的方法是搜一下A2DP,只要是A2DP要修改的地方照葫蘆畫瓢添加修改就是了。

DUN/SPP要用到bluez的serial plugin,因Android沒有編譯進去,所以要在external/bluez/utils/serial目錄下寫一個Android.mk,把它 編譯進去,生成system/lib/bluez-plugin/serial.so庫,其它的跟HID類似。

分類:  Androidbluetooth 標簽: bluetooth

Bluetooth FAQ on Android

2010年3月31日  zooyoo 沒有評論

URL: http://sites.google.com/a/android.com/opensource/projects/bluetooth-faq

This FAQ refers to the Android Open Source codebase, and is written for platform developers with root access on devices such as the Androd Developer Phone.

Q. How do I compile Android with Bluetooth support enabled?
A. Add this to your BoardConfig.mk:
BOARD_HAVE_BLUETOOTH := true

Q. Does the emulator support Bluetooth?
A. Sorry, not at this time. This would make a nice project if someone wants to take this on.

Q. Bluetooth doesn’t work on my device. How should I debug Bluetooth?
A. First step – read the logs (adb logcat)! In particular look for ERROR or WARNING level messages regarding Bluetooth.
Andoird uses Bluez, which comes with some very useful debugging tools. Here are some examples, in the rough order I use to debug BT.
hciconfig -a # print BT chipset address and features. Useful to check if you can communicate with your BT chipset.
hcidump -XVt # print live HCI UART traffic.
hcitool scan # scan for local devices. Useful to check if RX/TX works.
l2ping ADDRESS # ping another BT device. Useful to check if RX/TX works.
sdptool records ADDRESS # request the SDP records of another BT device.

Q. Where are the logs for the Bluetooth deamons hcid and hciattach?
A. Like all Android system daemons, the STDOUT and STDERR are sent to /dev/null by default. If you want to view these logs you can run the daemons under logwrapper which redirects there output to logcat. Edit init.rc and init.PLATFORM.rc to run these daemons under logwrapper.

Q. I compiled my own system.img for the Android Developer Phone, and hciconfig -a works, but hcitool scan does not. Whats going on?
A. You probably need to install the firmware for the Bluetooth chipset. Unfortunately this firmware is not yet in the open source codebase. However you can adb pull and then adb push it from a stock T-Mobile G1. The location is.
/etc/firmware/brf6300.bin

Q. What Bluetooth Core version does Android support?
A. Bluetooth 2.0 + EDR.

Q. What is the architecture of Bluetooth in Android?
A. We are based on Bluez version 3.36. The diagram below shows our 1.0 layout:

Q. When will Java Bluetooth API’s be released in an SDK?
A. We are not ready to announce a release target for Bluetooth API’s. We do understand there is demand for a Bluetooth API, and it is a top priority for the Android Bluetooth team.

Q. What is needed for Bluetooth 2.1 and Simple Pairing support?
A. We need to move to a Bluez 4.x version.

Profile Support

Q. What is the status of Headset and Handsfree?
A. Android 1.0 is qualified for both HFP and HSP (in the AG role) profiles. We are gladly taking bug fixes on any remaining issues. The one significant feature we lack is eSCO support.

Q. What is the status of A2DP and AVRCP?
A. A2DP and AVRCP work is ongoing for the ‘cupcake’ release. We are using the Bluez audio plugin and Bluez SBC codec, with a custom audio path designed for the Android Audio sub-system. Qualificiation is not yet complete.

Q. What is the status of HID?
A. Some very early work is in cupcake – Bluez has an HID plugin which we compile:
external/bluez/utils/input/Android.mk
You can interact directly with this plugin using dbus-send and dbus-monitor. With a little study of the Bluez HID plugin API and some luck and you should be able to connect and use a HID keyboard or mouse. A lot of work remains to be done before we could officially claim HID is supported by the platform. For example we need to plumb the plugin API up in the Android Java framework. And the Android framework needs better support for HID input methods – new keymaps and mouse support. We do not yet have a release targetted for official HID support.

Q. What is the status for tethering – DUN and PAN.
A. Similar to HID, some very early work is in cupcake. Bluez has DUN and PAN daemons which we compile.
external/bluez/utils/dun/Android.mk
external/bluez/utils/pan/Android.mk
BNEP support is compiled into the kernel with cupcake. With a little experimentation running these daemons (dund or pand) and using pppd or iptables you can test tethering support. A lot of integration work remains before we could officially claim that DUN or PAN is supported by the platform. Like HID, we would need to plumb the DBUS API’s to these daemons up into the Android Java framework, and add code to setup the network paths via pppd and/or iptables. We do not yet have a release targetted for official DUN or PAN support.

分類:  Androidbluetooth 標簽: bluetooth

android1.0藍牙問題淺談1

2010年3月31日  zooyoo 沒有評論

cupcake和donut中bluez用的是3.35, eclair中用的是4.47

以下轉自:http://blog.sina.com.cn/s/blog_5dd76ed10100bqav.html

前段時間,研究android藍牙,有些困惑,在android開發者論壇發帖請教,結果沒人回復,無奈只好自己研究了一番。自問自答,希望對有相同困惑的朋友有所幫助,共同提高了,呵呵!android1.0藍牙問題淺談1

1/ android1.0平台嵌入的BlueZ stack是否支持A2DP? 根據代碼分析,其實用的bluez是3.35版本。

BlueZ stack是開源社區提供的一套協議棧,其本身的功能是相當豐富的。其主要分為兩部分:內核部分嵌在linux內核中,從linux2.4.6版本之后就 已經內嵌了bluez,之前的版本需要自己打補丁。內核部分主要在兩個文件夾下driver和net。還有一部分是用戶部分,主要包括lib和 utills工具集,從代碼中就可以看到A2DP/AVRCP/HSP等profile都是支持的。當然了,bluez雖然強大,但是並不支持obex協 議及之上的FTP/OPP/BIP/SP等profile, 我想這主要是考慮到OBEX的廣泛性,OBEX不僅是藍牙文件傳輸的基礎協議,也是IrDA的 基礎。所以,OBEX也有一個專門的開源協議棧,即OpenOBEX,如果需要支持FTP等profile,只需要將OpenOBEX及之上的 OpenFTp等移植近來即可。

2/Android1.0對bluez stack做了什么工作?如果bluez已經支持了A2DP,那么google為什么不支持?
眾所周知,Android平台是用JAVA寫的,那么在App FRAME和linux用戶空間之間需要JNI來實現兩部分之間的通信。BLUEZ內核部分在linux內核中,用戶部分(utils)在linux用戶 空間。android做的工作就是首先用C++對bluez封裝了一層FRAME,實現為COM接口的形式。然后在JNI之上,APP FRAME層用JAVA封裝了一層接口,用來調用COM接口。然后上層應用APPLICATION是用FRAME中的JAVA類接口。由於android 只是封裝了HSP/HFP,所以他並不支持A2DP/AVRCP等profile。

3/如果需要在android1.0平台上支持a2dp等協議,我該怎么辦?都有什么解決方案

A2DP解決方案如下:
1)自己封裝兩層接口,模仿HSP的做法
2)跟蹤google的藍牙策略。
分析:
由於google已經將A2DP的支持提上了日程,並聲稱在09年第一季度就會支持A2DP/AVRCP,所以如果我從現在開始自己封裝,鑒於人力/技術 等因素,很可能我還沒做完,google就已經支持了,而且我做完之后的代碼也不能作為開源代碼提供給android,所以工作白做。得不償失。
而且,由於bluez開源組織聲稱在即將推出的bluez4.x版本之后會對協議棧架構進行較大調整,產生后向兼容性問題。而google考慮到 android平台作為一個開源平台,其api穩定性是必須考慮的問題,所以其必然會采用4x版本(這也是google在android1.0 remove 藍牙API的原因之一)。這樣,自己開發的意義更是不復存在。

FTP/OPP解決方案:
1)移植OpenOBEX及之上的OpenFTP等。

分析:
由於google似乎並沒有公布其支持FTP的schedule,所以如果要支持文件傳輸這一藍牙最常用功能的話,我想只有自己想辦法了。~~

分類:  Androidbluetooth 標簽: bluetooth

ARM平台上藍牙協議棧Bluez的移植使用和配置(轉)

2010年3月30日  zooyoo 沒有評論

作者:劉旭暉 Raymond轉載請注明出處

Email:colorant@163.com

BLOG:http://blog.csdn.net/colorant/

主頁:http://rgbbones.googlepages.com/

Bluez作為當前最成熟的開源藍牙協議棧,在Linux的各大發行版中已經得到了廣泛的應用。在桌面環境下,使用Bluez應該已經沒有太大的問 題,本文的主要目的是介紹在嵌入式平台上,搭建和配置Bluez的各個Profile運行所需做的工作,討論可能遇到的問題,介紹一些工具的使用和工作原 理。因為本人的能力和測試時間有限,可能下文中有些理解、分析不一定准確,歡迎聯系指正。

1         相關說明

1.1        網站資源

Bluez的官方網址:http://www.bluez.org/ 這里提供最新的源碼下載,最近服務器崩潰了一次,有些東西沒了。。。。

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之類的懷疑,還有編程接口之類的問題,就發到這里吧。

1.2        工作環境

個人感覺,使用Bluez最大的問題就是文檔的欠缺,除了Wiki上的有限資料以外,很難找到其它有用的文檔。

由於Bluez的代碼實現更新變化得很快,網上的許多文檔介紹的都是早期版本的使用,再有的文章多數是基於成熟的Linux發行版,來討論藍牙設備的配置和使用,對於嵌入系統開發,自己編譯,搭建和配置相關環境的文章很少。此外和具體藍牙芯片相關的資料也很難找到。

這里我不打算也沒有能力寫一個完整的指南,只能基於前段時間在自己的板子上所做的工作,總結一下相關的步驟和所遇到的各類問題以及這期間所掌握的各種相關知識。希望能給有類似開發需求的朋友一些有益的幫助,下面是這篇文章所基於的工作環境:

?       硬件平台:基於ARM的嵌入式板子

?       藍牙芯片:CSR BC4 ROM 版本芯片,不帶eeprom

?       軟件環境:Linux 2.6.21 ,自制文件系統

?       Bluez版本:bluez-libs 3.22  bluez-utils 3.22

2         編譯

2.1        內核

相信多數人使用的都是2.6的內核了,在2.6的內核中要支持Bluez,只要你的內核版本不是太舊,無需打Patch,直接配置好就OK了,內核 里面的代碼相對比較穩定了。當然,Bluez對一些Bluetooth協議棧新特性的支持,還是需要更新kernel代碼的。你應該確認你使用的 kernel版本是否以及包含了對應的支持。

內核的配置,基本上把 networking下 — Bluetooth subsystem support 里的以下幾項全部選上即可:

L2CAP protocol support

SCO links support

RFCOMM protocol support

RFCOMM TTY support

BNEP protocol support

HIDP protocol support

此外,在Bluetooth device drivers里選上你所需要支持的Bluetooth設備。我使用的CSR的chip是我們直接build在板子上,通過串口和cpu通訊的,芯片默認使用BCSP作為通訊協議,所以我選擇了:

HCI UART driver

BCSP protocol support

如果你是通過usb接口使用藍牙適配器,需要選擇

HCI USB driver

2.2        Bluez Lib / Utils

Bluez Lib的編譯比較簡單,而Bluez-Utils所依賴的庫就比較多了,大體包括 dbus alsa hal gstreamer openobex xml等等,仔細觀察./configure 的輸出,將所需要的包先安裝或者build好。

值得注意的一點是:

如果你需要打開所有的功能模塊的支持,需要在 ./configure 參數中添加 –enable-all  –enable-audio –enable-input –enable-network –enable-serial 等,在3.22版本中 –enable-all 居然不包括 audio等相關模塊的service的編譯,不知道是否是因為還保留了daemon和service等不同方案的緣故。不過,這至少與他的 configure –help 對於 –enable-all 的描述是不符合的。

3         藍牙硬件初始化及基礎服務啟動

如果在PC環境下,使用Ubuntu,調用 /etc/init.d/bluetooth start 應該就能完成這一步的工作了。下面敘述一下在我的嵌入式環境下,如何手動完成這一步驟。

3.1        何謂硬件初始化

硬件初始化,指的是配置藍牙芯片,將其置於一個能夠正常通訊的狀態。

對於CSR的芯片來說,就是通過設置PSKEY,設置其晶振頻率,UART波特率等等一些關鍵參數。 如果使用的是USB形式的適配器,因為其EEPROM存儲了相關的默認參數,這一步很可能不需要做,而我使用的是不帶EEPROM的ROM版本芯片,如何 正確完成初始化工作着實讓我折騰了一陣。

對於其它芯片,沒有太多研究,不過,據我有限的了解,TI的芯片在hciattach時也需要完成一些額外的初始化工作,其它如ST的芯片則可能需要下載firmware。

3.2        硬件初始化步驟

通常藍牙芯片的初始化和協議綁定可以通過 hciattach 來完成(通過配置bluez的啟動腳本,可以不需要使用hciattach,標准發行版應該都是不用hciattach,如何配置,還沒有研究 。。。 8 )

Hciattach 需要的參數主要包括 TTY節點,設備類型,波特率等。多數類型的設備的初始化工作,在選擇了正確的設備類型參數后,都由hciattach在init_uart函數中調用具體的初始化函數所完成。

很遺憾的是,因為要重新設置晶振頻率和波特率,並同步BCSP協議,這種方式好像處理不了我所使用的芯片(不排除我沒有找到正確的解決方案的可能 性),我最終的解決辦法是在hciattach之前,使用Bluez-utils里的BCCMD工具先完成這些PSKEY的設置工作。

具體命令是:

bccmd -t bcsp -d /dev/ttyS1 psload -r csr.psr

在這時,由於HCI接口還沒有啟動,所以只能使用BCSP協議來進行通訊,我的設備是暴露在ttyS1下,你的可能不一樣,-r參數指明在psload完成 PSKEY的批量加載操作之后,對芯片進行Warmreset,否則這些參數的修改不會起作用。

Csr.psr的內容取決與你的芯片,我的大致如下:

// PSKEY_ANA_FREQ

&01fe = 9C40 // 相當於40M的晶振

// PSKEY_UART_BAUD_RATE

&01be = 0EBF // 921600的波特率

// PSKEY_UART_SEQ_WINSIZE

&0407 = 0006

// BDADDR

&0001 = 1122 3344 5566 7788

。。。

這里有個問題,你會發現,通過bccmd -t bcsp psset 命令理論上應該是可以單步設置每一個PSKEY的,但是從我實踐看來,單步的操作在兩次對bccmd的調用過程中,上一次對PSKEY的修改,都會在下一 次調用之前被復位,從代碼上看估計和BCSP協議的同步過程有關。

3.2.1          關於PSKEY的獲取

如何獲得正確的完整的PSKEY參數,大概會有幾個途徑:

?       通過CSR的網站下載boot_strap包,這是CSR自己的BCHS協議棧所使用的初始化代碼,在里面找到你所需要的pskey值。

?       下載CSR的bluesuite工具,里面包含了一個叫pstool的工具,可以用它來讀寫CSR的Casira開發板或其它BT設備的PSKEY設置,試驗並找出你能用的參數。

?       找CSR或模組廠商支持 8 )

不過,基本上來說,如果只是要讓芯片通過串口能夠和Bluez協議棧正常通訊上,只需要設置PSKEY_ANA_FREQ 和 PSKEY_UART_BAUD_RATE 這兩個PSKEY就可以了。

3.3        Daemon進程的啟動

早先的版本里,Bluez的Daemon很多,但是最近的版本,很多daemon都轉為service的形式來做了,3.22 里面包括了以下這幾個Service,其它profile貌似還保留着daemon的形式。

bluetoothd-service-serial

bluetoothd-service-network

bluetoothd-service-audio

bluetoothd-service-input

這幾個Service的啟動依賴於hcid的啟動以及相關的配置文件

主要配置文件位於:/etc/bluetooth/

此外,通常還需要啟動SDP來提供服務查詢,另外,Bluez本身還依賴於Dbus daemon的運行。

所以,整體上來說,我的手動啟動Bluez的全過程如下:(其中內核代碼是以模塊形式編譯的)

insmod bluetooth.ko

insmod hci_uart.ko

insmod l2cap.ko

insmod rfcomm.ko

insmod sco.ko

insmod hidp.ko

/etc/rc2.d/S20dbus start

bccmd -t bcsp -d /dev/ttyS1 psload -r csr.psr

hciattach -s 921600 /dev/ttyS1 bcsp 921600

hciconfig hci0 up

sdpd

hcid –d

4         Paring配對

4.1        Passkey_agent

在正常使用一個藍牙設備前,通常都需要對該設備進行配對綁定的操作。

Bluez的配對機制貌似也修改了幾次,2.x版本中通過pin_helper來處理pin code的應答,3.22版本里使用的配對機制,其API是基於Dbus來實現的,需要向dbus注冊一個agent,PC的發行版通常都會有一些基於各 種圖形庫的passkey_agent,對於嵌入式系統,這部分代碼可以想象,應該是要按照相應的API自己實現一個,為了測試,我直接使用了 bluez-utils/daemon 目錄下的passkey-agent

這是一個命令行下的可以使用預先設定的pin code進行配對的程序

為了使用它,我的文件系統里 /etc/Bluetooth/hcid.conf 中 option一節類似如下 :

# 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

pairing multi;

# Do the same as “hciconfig hci0 down” when SetMode(“off”)

# is called.

offmode devdown;

# Default PIN code for incoming connections

passkey “1234″;

}

4.2        關於自動配對和請求的發起

配對的發起,這里主要是從請求的發起者是誰的角度來說。

通常可能不需要關心配對請求是由本地還是由遠端發起的,使用passkey_agent都能夠正確處理。

不過如果在hcid.conf中將 Security Manager mode 設置為 auto,則Bluez會將passkey后面的字符串作為默認的Pin code,自動答復遠端發起的配對請求。這是在沒有使用passkey_agent的情況下的一種配對方式。

在這種情況下,Bluez可以處理遠端的配對請求,但是對於本地發起的配對請求,將無法正確處理,我沒有仔細的分析原因,或許是代碼特意設計成這種 工作方式。所以在無法明確知道誰將會主動先發起配對請求的情況下,使用Atuo模式,可能就會出現有些時候設備能綁定有些時候不能綁定的現象。

通常如果是由本地設備搜索發現的新設備,配對綁定的操作應該也是由本地發起。

另外可以觀察到,對遠端一個非PC類的藍牙設備,如藍牙耳機,如果上次綁定過,在耳機啟動時會主動發起連接請求,如果本地的link key丟失了,也就會再走一次綁定的流程,這種情況下配對請求就是由遠端設備發起的。

5         A2DP

A2DP藍牙立體聲應該是藍牙最常見的Profile之一。

2.x版本的Bluez,對A2DP的支持是通過BTSCO來實現的,3.22的版本通過bluetoothd-service-audio來支持。

對Bluez A2DP profile的支持,還依賴於Alsa或Gstreamer。

5.1        配置

測試A2DP的時候,我使用的是aplay,同時在相關的配置文件里面寫死了藍牙耳機的地址

主要的配置文件包括:

/etc/asound.conf :

pcm.bluetooth{

type bluetooth

device 00:02:5B:00:C1:A0

profile “hifi”

}

/etc/bluetooth/audio.conf :

[General]

# disable=Sink

SCORouting=PCM

[Headset]

DisableHFP=true

[A2DP]

SourceCount=2

配置好這些以后,使用 aplay -D bluetooth sample.wav 進行測試。

值得注意的是,使用Aplay打開藍牙設備進行播放,需要有如下兩個Alsa的plugin:

/usr/lib/alsa-lib/libasound_module_pcm_bluetooth.so

/usr/lib/alsa-lib/libasound_module_ctl_bluetooth.so

這兩個so文件可以在bluez-utils 里面找到。需要注意他們和libasound 的版本匹配。

5.2        問題

在測試中發現,如果連接的耳機是由PC上的藍牙適配器提供的AV耳機服務,那么配對可以完成,但是連接會失敗,真正的耳機則沒有這個問題,不知道是 否是因為以上的方法還存在缺陷?嘗試使用由DBUS發起命令的形式來連接PC的AV耳機服務,也是一樣的問題。是否連接PC模擬的AV耳機服務,首先要切 換設備的role?

沒有測試Ctl接口

如何動態選擇不同的耳機,而不是寫死在腳本里?(這個想來估計是要自己基於Alsa的API編程處理,aplay無法直接完成測試)

播放大文件會出現under run錯誤,需要測試是由與波特率設置不夠高造成,還是SBC編碼效率不夠,還是這個版本里存在的bug。

6         DUN的使用

Dun profile運行於rfcomm之上,主要是通過藍牙接口暴露一個Modem的接口,用於提供撥號上網服務。

在這里所討論的不是提供撥號上網服務本身,而是使用外部設備所提供的這個服務,進行網絡連接。

6.1        系統配置

通常為了使用DUN,或者任何一個其它類型的Modem,我們會通過PPP協議來撥號和建立網絡連接。

首先需要內核的支持,可以簡單的把 device drivers -> Network device support 下面的PPP相關的內容全部選上。

其次,要編譯應用層的PPP包,我的測試是基於ppp-2.4.4

主要的兩個ppp配置文件:

/etc/ppp/peers/gprs:

/dev/rfcomm0

115200

defaultroute

usepeerdns

nodetach

noauth

local

debug

connect “/usr/sbin/chat -v -f /etc/ppp/chat-gprs”

/etc/ppp/chat-gprs:

TIMEOUT 10

ABORT ‘BUSY’

ABORT ‘NO ANSWER’

ABORT ‘ERROR’

“” ‘ATZ’

SAY ‘Init….\n’

OK ‘AT+CGDCONT=1,”IP”,”CMWAP”‘

ABORT ‘NO CARRIER’

SAY ‘Dialing….\n’

OK ‘ATD*99***1#’

CONNECT ”

前面一個配置文件基本就是那樣了,后面一個,這兩句要根據你的SIM卡的實際情況來處理:

OK ‘AT+CGDCONT=1,”IP”,”CMWAP”‘

OK ‘ATD*99***1#’

這里我設置的是使用中國移動的CMWAP。

此外,使用CMWAP還需要設置你的瀏覽器的代理服務器:10.0.0.172 端口9201

6.2        連接步驟

首先是要查找提供dun服務的設備,將服務提供在哪個channel通道上。這可以通過sdptool來查看,在我的設備上查詢的結果是在channel 1上:

~ # ./sdptool browse 00:08:C6:77:A0:6C

Browsing 00:08:C6:77:A0:6C …

Service Name: Dial-upnetworking

Service RecHandle: 0×10000

Service Class ID List:

“Dialup Networking” (0×1103)

“Generic Networking” (0×1201)

Protocol Descriptor List:

“L2CAP” (0×0100)

“RFCOMM” (0×0003)

Channel: 1

Profile Descriptor List:

“Dialup Networking” (0×1103)

Version: 0×0100

其次,如果rfcomm所需設備節點不存在,將其創建:

mknod -m 666 /dev/rfcomm0 c 216 0

然后就是撥號了,如果該設備之前沒有綁定,這過程中會自動發起綁定操作:

pppd debug dump call gprs &

完成以后就可以看到 ppp0這樣一個網絡接口了。

~ # ifconfig

ppp0      Link encap:Point-to-Point Protocol

inet addr:10.154.76.82  P-t-P:192.200.1.21  Mask:255.255.255.255

UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1

RX packets:4 errors:0 dropped:0 overruns:0 frame:0

TX packets:6 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:3

RX bytes:64 (64.0 B)  TX bytes:101 (101.0 B)

7         Bluez相關的各種tools的使用

在這一段折騰Bluez的時間里,越來越發現Bluez相關的許多工具做得還是挺好用的,主要在Bluez-utils/tools 目錄下。只是有一點讓我很遺憾,除了man以外很難找到更多的幫助文檔,而man文檔本身對一些功能的描述也不是很詳細。

其中有些選項,如果你不了解藍牙協議棧,或者沒有查閱過相關藍牙芯片的一些文檔,很難搞明白是什么意思,甚至有些選項的具體參數值的設定,如果不讀源碼你都無從得知有哪些備選值。。。。

能力有限,下面所寫的只是我所用過的有限的幾個工具的一些使用經驗,希望能有所幫助。

7.1        Bccmd

Bccmd是用來和CSR的芯片進行BCCMD(Bluecore command protocol)通訊的一個工具。BCCMD並非藍牙協議棧的標准,而是CSR芯片的專屬協議

Bccmd的調用格式為:bccmd [-t <transport>] [-d <device>] <command> [<args>]

Tansport類型包括 HCI USB BCSP H4等,常用的估計就是HCI和BCSP兩種。需要注意一下他們的使用場合:

HCI是一個抽象的標准的藍牙通訊接口,在基於HCI協議調用BCCMD時,需要在Bluez已經建立好hci接口的基礎上使用。

BCSP(Bluecore Serial Protocol)是CSR自己制定的傳輸層協議,主要目的是用來加強在沒有使用CTS、RTS進行流量控制的情況下進行可靠的數據傳輸的能力。其概念是 相對H3 , H4而言,( 具體分析,請參考下面雜項一章中相應的小節 )

BCCMD的主要用途就是用來讀寫pskey,這里以 psset 這個command來介紹一下格式:

Psset 格式如下: psset [-r] [-s <stores>] <key> <value>

其它都好理解,關鍵是-s參數之后跟的store具體的含義。這個參數可以是數值也可以是字符串

查詢CSR的BCCMD相關的文檔,可以找到具體的含義如下:

0×0000 Default

0×0008 psram

0×0001 psi

0×0002 psf

0×0004 psrom

0×0003 psi then psf

0×0007 psi, psf then psrom

0×0009 psram then psi

0x000b psram, psi then psf

0x000f psram, psi, psf then psrom

CSR的藍牙芯片中,PSKEY可能存儲在 rom flash eeprom ram等介質里,這里的數值指明了psset/get命令操作PSKEY時所針對的存儲介質及其優先順序,通常我們會用 –s 0×0 或 –s “default” 來使用該命令,0×0的含義與0xf一樣。

值得注意的是,哪個參數是有效的,還取決於哪一類的存儲介質實際存在於藍牙芯片中,此外,只讀類的介質對寫操作類的命令也是無效的。

基本上來說,所修改的都是位於psram中的pskey,此外,pskey修改以后要起作用,還要一並使用 –r參數,或直接用warmreset命令將藍牙芯片進行warm reset。

7.2        Hciattach

Hciattach主要用來初始化藍牙設備,它的命令格式如下:

hciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]

其中最重要的參數就是 type和speed,type決定了要初始化的設備的型號,可以使用 hciattach –l 來列出所支持的設備型號。

並不是所有的參數對所有的設備都是適用的,有些設備會忽略一些參數設置,例如:查看hciattach的代碼就可以看到,多數設備都忽略bdaddr參數。

Hciattach命令內部的工作步驟是:首先打開制定的tty設備,然后做一些通用的設置,如flow等,然后設置波特率為 initial_speed,然后根據type調用各自的初始化代碼,最后將波特率重新設置為speed。所以調用hciattach時,要根據你的實際 情況,設置好initial_speed和speed。

對於type BCSP來說,它的初始化代碼只做了一件事,就是完成BCSP協議的同步操作,它並不對藍牙芯片做任何的pskey的設置。同步操作的具體流程和規范可以參考CSR的相關文檔: BCSP Link Establishment Protocol

7.3        其它

下面幾個,使用了,但是沒有太多研究

7.3.1          Hcidump

Hcidump不在bluez-utils包里,而是在單獨的hcidump包里。主要用來分析捕獲和分析HCI數據包,如果使用bluez過程中 出了什么問題,用hcidump往往可以發現一些出錯的線索,原因。 參數很多,基本上hcidump –X –V 就可以幫你獲得詳細的經過格式解析的數據包。

7.3.2          Hcitool

主要用hcitool來scan遠端的設備,顯示設備地址,名稱等。

例如:Hcitool scan, hcitool inq

7.3.3          Sdptool

主要用來瀏覽遠端設備SDP服務,或者管理本地的SDPD維護的數據庫。

常用的應該就是查找遠端設備的服務了

例如:

sdptool browse 00:02:72:B0:00:26 瀏覽地址為00:02:72:B0:00:26的設備所提供的服務

sdptool search 0×1112 00:02:72:B0:00:26 查找地址為00:02:72:B0:00:26的設備上的Headset Audio Gateway服務。

./sdptool search 0×1112 00:02:72:B0:00:26

Class 0×1112

Inquiring …

Searching for 0×1112 on 00:02:72:B0:00:26 …

Service Name: Headset Audio Gateway

Service RecHandle: 0x1001d

Service Class ID List:

“Headset Audio Gateway” (0×1112)

“Generic Audio” (0×1203)

。。。

7.3.4          Hciconfig

這個就不用多說了,格式上很類似於ifconfig,用來設置HCI設備的參數

例如

hciconfig hci0 up 啟動hci0接口

hciconfig hci0 iscan 使能位於hci0接口的藍牙芯片的inquery scan模式(使得設備能被其它藍牙設備發現)

8         雜項

8.1        使用Dbus-send進行測試

由於Bluez使用dbus進行進程間通訊,所以我們可以使用dbus-send命令直接發送命令進行一些查詢,試驗的工作。

Bluez每個Daemon或service所支持的Dbus接口API描述文本,可以在各自的目錄下找到,例如Audio的API寫在 audio/audio-api.txt中。

以Audio為例,可以參考 http://wiki.bluez.org/wiki/HOWTO/AudioDevices 中的描述

8.2        HCI、H4、USB、BCSP 之間的關系

個人理解,嚴格的說HCI和其它幾種protocol並不是可以對比的同一層次的東西。

HCI protocol 並不考慮在實際傳輸載體以及其中的糾錯等問題,只是一個抽象的傳輸層或叫做接口。USB,H3,H4等才是具體的transport layer(此外還有SD Transport layer)。HCI數據包需要附着在這些具體的Transport Layer的協議包中。

以BCSP為例,4種類型的HCI數據包各自使用了一個BCSP通道,做為這些通道的payload封裝在BCSP的協議包里,需要通過TTY的 lldsic層走一次,並由hci_uart模塊做相應的封裝工作。而BCSP還通過其它通道支持其它的一些自定的Protocol。BCSP作為一個具 體的傳輸層協議,還支持了校驗,同步等功能。

H4機制類似,SD和USB transport好像區別比較大一點。具體可以參考 Bluetooth Specification Volume 4.

8.3        BCSP數據包結構

HCI數據包的結構,在bluetooth的spec里面有詳細定義,不過,CSR自己的BCSP,BCCMD等一系列協議,又添加了一堆的東西, 其中,HCI數據包是作為BCSP的payload,而BCCMD又是作為HCI的payload,所以測試過程中,發覺要分析清楚bluez通過 kernel最后到底往藍牙芯片的串口發送了什么數據,特別是想要自己手工構建一串數據,着實要看上一堆spec,拼湊起來才能完成。

要具體學習分析一串命令,最好的辦法,我能想到的就是修改bccmd的代碼,將它傳給串口的每一個字符串都打印出來,這樣對照這spec看,事半功倍。

例如下面這條,是使用我修改后的bccmd指令。所做的操作是讀取串口波特率的pskey:

./bccmd.dbg -t bcsp -d /dev/ttyS1 psget -s 0×0 0x01be

cmd : 00 fc 13 c2 00 00 09 00 01 00 03 70 00 00 be 01 01 00 00 00 00 00

c0 d1 65 01 c8 00 fc 13 c2 00 00 09 00 01 00 03 70 00 00 be 01 01 00 00 00 00 69 a6 c0

在這里 HCI的數據包是第一行,具體解釋一下:

頭4個字節是HCI Head,其中

00 fc :整體代表這是一個制造商自定義的命令。

13 :HCI命令長度為0×13。

C2 :包的內容是唯一的一個BCCMD數據包。

后面是BCCMD的Head

00 00 :這是一個GetReq命令

09 00 :BCCMD的命令9個word長度,及18字節

01 00 :seqno, 包的順序標記 包1

03 70 :varid 7003, 表示這是對PSKEY的操作

00 00 :狀態標志

再下來是BCCMD的payload

be 01 :0x01be 波特率PSKEY的index

01 00 :該PSKEY的長度為1

00 00 :strore 為 00

00 00 :該PSKEY的值,這里是發送讀命令,所以填0

第二行的數據是將HCI包封裝在了BCSP數據包里:

前面部分:c0 d1 65 01 c8 :

C0 :是BCSP數據包的分割符

D1 :類型為可靠鏈接數據流,有CRC校驗

65 01 :channel 5 ( HCI CMD ), 長度為0×16

C8 :包頭的校驗

后面部分:69 a6 c0:

69 a6 :整個BCSP包的CRC校驗

C0 :分隔符

其它命令類似的分析可得。

如果只是希望看到HCI命令本身,也可以用hcidump來看。這是上面的讀pskey操作通過HCI接口操作的dump:

< HCI Command: Vendor (0x3f|0×0000) plen 19

BCCMD: Get req: len 9 seqno 1 varid 0×7003 status 0

PSKEY: key 0x01be len 1 stores 0×0000

UART_BAUDRATE: value 0 (0×0000)

8.4        Hid / Serial / HF / OBEX

這幾個比較常用的profile,還沒測試哪。。。。。。誰給我買個藍牙鼠標玩玩?!

8.5        總的遺留問題

整體上,PC上實現的自動識別,自動啟動服務的一整套腳本,還沒有仔細研究。

分類:  bluetooth 標簽: bluetoothbluez

Android Bluetooth Class summary

2010年3月24日  zooyoo 沒有評論

Setting app related

BluetoothSettings is the Settings screen for Bluetooth configuration and connection management.

BluetoothDevicePreference is the preference type used to display each remote Bluetooth device in the Bluetooth Settings screen.

BluetoothDiscoverableEnabler is a helper to manage the “Discoverable” checkbox. It sets/unsets discoverability and keeps track of how much time until the the discoverability is automatically turned off.

BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox preference. It is turns on/off Bluetooth and ensures the summary of the preference reflects the current state.

BluetoothEventRedirector receives broadcasts and callbacks from the Bluetooth API and dispatches the event on the UI thread to the right class in the Settings.

BluetoothNamePreference is the preference type for editing the device’s Bluetooth name. It asks the user for a name, and persists it via the Bluetooth API.

BluetoothPinDialog asks the user to enter a PIN for pairing with a remote Bluetooth device. It is an activity that appears as a dialog.

BluetoothPinRequest is a receiver for any Bluetooth pairing PIN request. It checks if the Bluetooth Settings is currently visible and brings up the PIN entry dialog. Otherwise it puts a Notification in the status bar, which can be clicked to bring up the PIN entry dialog.

ConnectSpecificProfilesActivity presents the user with all of the profiles for a particular device, and allows him to choose which should be connected (or disconnected).

LocalBluetoothDevice represents a remote Bluetooth device. It contains attributes of the device (such as the address, name, RSSI, etc.) and functionality that can be performed on the device (connect, pair, disconnect, etc.).

LocalBluetoothDeviceManager manages the set of remote Bluetooth devices.

LocalBluetoothManager provides a simplified interface on top of a subset of the Bluetooth API.

LocalBluetoothProfileManager is an abstract class defining the basic functionality related to a profile.

SettingsBtStatus is a helper class that contains constants for various status codes.

Framework realted

AtCommandHandler is handler interface for AtParser.

AtCommandResult represent the final response to an AT command line, and also  intermediate responses to a single command within a chained AT command line.

AtParser object accepts a new command line to parse via its process() method. It breaks each command line into one or more commands. Each command is parsed for name, type, and (optional) arguments, and an appropriate external handler method is called through the AtCommandHandler interface.

BluetoothCmeError: Constants for extended AT error codes specified by the Handsfree profile.

BluetoothAtPhonebook is helper for managing phonebook presentation over AT commands

BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP Service via IPC. Currently this class provides methods to connect to A2DP audio sinks.

BluetoothA2dpService

BluetoothAudioGateway listen’s for incoming RFCOMM connection for the headset / handsfree service.  This class is planned for deletion, in favor of a generic Rfcomm class.

BluetoothClass is static helper methods and constants to decode the device class bit vector returned by the Bluetooth API.

BluetoothDevice manages the local Bluetooth device. Scan for devices, create bondings, power up and down the adapter.

BluetoothDeviceService

BluetoothError: constant error codes

BluetoothEventLoop

BluetoothHeadset is public API for controlling the Bluetooth Headset Service. This includes both Bluetooth Headset and Handsfree (v1.5) profiles. The Headset service will  attempt a handsfree connection first, and fall back to headset.

BluetoothHandsfree: Bluetooth headset manager for the Phone app.

BluetoothHeadsetService extends Service, provides Bluetooth Headset and Handsfree profile, as a service in the Phone application.

BluetoothIntent contains constant intens for bluetooth.

Database is A low-level API to the Service Discovery Protocol (SDP) Database.

HeadsetBase is the base RFCOMM (service) connection for a headset or handsfree device.

RfcommSocket implements an API to the Bluetooth RFCOMM layer. An RFCOMM socket  is similar to a normal socket in that it takes an address and a port number. The difference is of course that the address is a Bluetooth-device address, and the port number is an RFCOMM channel.

ScoSocket: Simple SCO Socket. Currently in Android, there is no support for sending data over a SCO socket – this is managed by the hardware link to the Bluetooth Chip. This class is instead intended for management of the SCO socket lifetime,  and is tailored for use with the headset / handsfree profiles.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM