Bluez相關的各種tools的使用
1. 安裝套件
sudo apt-get update
sudo apt-get install bluetooth bluez bluez-hcidump
其中 bluetooth 套件包含了底層的 hci (host controller interface) 和 sdp (service discovery protocol) 工具。而 bluez 則是官方藍牙軟體協定 (Official Linux Bluetooth protocol stack),屬於較上層。bluez 的網頁如下: http://www.bluez.org/
2.啟動驅動
sudo echo 0 > /sys/class/rfkill/rfkill0/state
sudo echo 1 > /sys/class/rfkill/rfkill0/state
sudo brcm_patchram_plus -d --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/vendor/firmware/bcm4356a2.hcd /dev/ttyS0 &
有些是用hciattach 請看該藍芽晶片說明
sudo hciconfig hci0 up
sudo hciconfig info
3. 查詢本機藍牙位址
用下面這個指令可以看到本機藍牙發射器的位址。
sudo hcitool dev
Devices:
hci0 00:1A:7D:DA:71:13
4. 掃描附近藍牙裝置
從這裡開始會分成兩部分來說明,一部份是 master 端,就是執行掃描的機器(例如 ubuntu);另一部分則是被掃描的 slave (RPi),會回應 master 的掃描訊號。
slave 端的指令:
sudo hciconfig hci0 piscan
master 端則是執行
sudo hcitool scan
若是找到 slave,在 master 端會顯示 slave 的位址 (所謂的 bdaddr) 和名稱。
5. 建立與尋找序列埠(SP)服務
我們可以用此指令,在 slave 端建立一個序列埠的服務。
sudo sdptool add --channel=3 --handle=1 SP
--channel 與 --handle 的參數可任選。在此我們選用3號頻道,並且給此服務一個編號1。
然後 master 就可用此指令查訊到附近有 SP 服務的機器:
sudo sdptool search SP
此外,sdptool 還可以讓我們瀏覽 (browse)本地或某一台機器上的所有服務,只要你給它位址 (bdaddr)。
sudo sdptool browse local
sudo sdptool browse <bdaddr>
6. 建立序列埠連線
SP 服務似乎已經準備好了,該如何建立真正的連線呢? 我們需要 rfcomm 這個工具。
首先,在 slave 端必須先建立一個監聽埠:
sudo rfcomm -i hci0 watch /dev/rfcomm0 3 <command>
此處的 3 是指SP服務中的 3號頻道,而 /dev/rfcomm0 此一節點會由 rfcomm 自動建立,我們無需使用 mknod -m 666 /dev/rfcomm0 c 216 0 此類指令來建立。
至於 command,是指建立連線時所要執行的命令,我們可以使用 minicom 或是再建立一個TTY 給遠端的藍牙,如下:
sudo rfcomm -i hci0 watch /dev/rfcomm0 3 minicom -D /dev/rfcomm0
sudo rfcomm -i hci0 watch /dev/rfcomm0 3 /sbin/agetty rfcomm0
接下來,在 master 端就可以用 rfcomm 來建立通訊的序列埠:
sudo rfcomm connect /dev/rfcomm0 <slave_bdaddr> 3 &
把這行放在背景執行,是因為我們一直需要這個埠 (/dev/rfcomm0) 。這埠的節點也是由 rfcomm 自動產生,不需使用 mknod。而這行指令返回時 (按下 Ctrl + C),埠也會消失 (這裡有一個 BUG,詳情請看下麵)。此外,3是指頻道,是由我們剛剛建立的服務而來。
最後,在埠建立完成後,master 就可以用 minicom 來和 slave 通訊了。
sudo minicom -D /dev/rfcomm0
7. 障礙排除:
A. Permission denied 與 Invalid exchange
有時 master 在執行 rfcomm connect 時無法成功,並會得到下列2種錯誤訊息:
Can't connect RFCOMM socket: Permission denied
Can't connect RFCOMM socket: Invalid exchange
這是一個 rfcomm 的小 bug,解法是清除 master 中,/var/lib/bluetooth/ 目錄下的所有檔案,就可以讓 rfcomm commect 順利成功。
sudo rm /var/lib/bluetooth/* -rf
B. Address already in use
master 在執行 rfcomm connect 時,有時會得到下列的錯誤訊息:
Can't create RFCOMM TTY: Address already in use
這也是一個已知的 bug (連結),原因是上一次 rfcomm 在 release com port (例如 /dev/rfcomm0) 的時候失敗,所以之前那個 com port 依舊存在。我們可以用選項 -a 來看看目前有多少埠存在。
sudo rfcomm -a
這些埠似乎已經變成了殭屍,用 rfcomm release 也清不掉。所以我們只能重啟系統,或是另外開一個埠,例如 /dev/rfcomm3 之類的。
C. 監看 hci
bluez 提供了一個監看 hci 動作的工具,用以下指令就可以使用:
sudo hcidump -X
不過因為它會不斷的丟出訊息,建議另開一個 TTY 來執行它並進行監看。當不知道障礙的成因,透過它或許能得到一些線索。
D. 確認 slave 的 pairing mode
從藍牙 v2.1 版之後引進了 Secure Simple Pairing mode (SSP) 來做裝置配對的工作。預設是打開,但是如果我們懷疑問題出在裝置配對,也懷疑 SSP 是否打開的話,可以執行以下直令來強制 slave 開啟 SSP mode。
sudo hciconfig hci0 sspmode 1
把1拿掉就可以查詢 SSP 的狀況。
sudo hciconfig hci0 sspmode
順道一提,倘若不使用SSP,master 可以用下面指令將 PIN 送給 slave:
sudo bluetooth-agent PIN <slave_bdaddr>
8命令介紹
8.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相關的文檔,可以找到具體的含義如下:
0x0000 Default
0x0008 psram
0x0001 psi
0x0002 psf
0x0004 psrom
0x0003 psi then psf
0x0007 psi, psf then psrom
0x0009 psram then psi
0x000b psram, psi then psf
0x000f psram, psi, psf then psrom
CSR的藍牙晶片中,PSKEY可能存儲在 rom flash eeprom ram等介質裡,這裡的數值指明了psset/get命令操作PSKEY時所針對的存儲介質及其優先順序,通常我們會用 –s 0x0 或 –s “default” 來使用該命令,0x0的含義與0xf一樣。
值得注意的是,哪個參數是有效的,還取決於哪一類的存儲介質實際存在於藍牙晶片中,此外,唯讀類的介質對寫操作類的命令也是無效的。
基本上來說,所修改的都是位於psram中的pskey,此外,pskey修改以後要起作用,還要一併使用 –r參數,或直接用warmreset命令將藍牙晶片進行warm reset。
8.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
8.3 其它
下面幾個,使用了,但是沒有太多研究
8.3.1 Hcidump
Hcidump不在bluez-utils包裡,而是在單獨的hcidump包裡。主要用來分析捕獲和分析HCI資料包,如果使用bluez過程中出了什 麼問題,用hcidump往往可以發現一些出錯的線索,原因。 參數很多,基本上hcidump –X –V 就可以幫你獲得詳細的經過格式解析的資料包。
1、 hcidump -Xt
終端下顯示相應HCI資訊。
1、 hcidump –Bw /data/bt1.cfa(android2.3下)/data/bt1.cfa為檔路徑
hcidump –w /data/bt1.cfa(android 4.0下)
用capture file viewer打開(frontline comprobe protocol analysis system 13.8)入下圖就可以分析相應的協議。
(2)、hcidump -tr bt_0.log
顯示bt hci log資訊
(3)、hcidump -r bt_0.log
(4)、hcidump –Rtw
8.3.2 Hcitool
主要用hcitool來scan遠端的設備,顯示裝置位址,名稱等。
例如:Hcitool scan, hcitool inq
hcitool常用方法
(1)、hcitool幫助命令
hcitool –h
(2)、hcitool dev 顯示本機MAC位址
[html] view plain copy
- hcitool dev
- Devices:
- hci0 00:16:53:96:22:53
(3)、hcitool inq
[html] view plain copy
root@android:/ # hcitool inq - hcitool inq
- Inquiring ...
- C4:6A:B7:21:79:C8 clock offset: 0x7e48 class: 0x5a020c
- 1C:66:AA:66:68:2E clock offset: 0x5e27 class: 0x5a020c
- AC:72:89:85:90:2A clock offset: 0x13ec class: 0x4a0100
- 68:17:29:78:37:4A clock offset: 0x5185 class: 0xff0104
- B0:C4:E7:65:A7:3A clock offset: 0x267e class: 0x5a020c<strong>
- </strong>
(4)、hcitool scan掃描周圍設備
(5)、hcitool name 8C:71:F8:AE:2A:C0(對應要獲取名字的BT mac地址)
(6)、hcitool info 8C:71:F8:AE:2A:C0(對應要獲取名字的BT mac地址)
(7)、hci clock
[html] view plain copy
1|root@android:/ # hcitool clock - hcitool clock
- Clock: 0x5ba67
- Accuracy: 0.00 msec<strong>
- </strong>
hcitool命令及參數
在打開藍牙設備以後,就可以使用hcitool工具集對藍牙進行控制,工具集參數 分為兩部分,一為正常的藍牙設備調試,二為低功耗即BLE設備, 工具參數如下:
$ hcitool
hcitool - HCI Tool ver
4.93
Usage:
hcitool [options] <command> [command parameters]
Options:
--help
Displayhelp
-i dev HCI device
Commands:
dev
Displaylocal devices
inq Inquire remote devices
scan
Scanfor remote devices
name
Getname from remote device
info
Getinformation from remote device
spinq Start periodic inquiry
epinq
Exitperiodic inquiry
cmd Submit arbitrary HCI commands
con
Displayactive connections
cc Create connection to remote device
dc Disconnect from remote device
sr
Switchmaster/slave role
cpt Change connection packet type
rssi
Displayconnection RSSI
lq
Displaylink quality
tpl
Displaytransmit power level
afh
DisplayAFH channel map
lp
Set/display link policy settings
lst
Set/display link supervision timeout
auth Request authentication
enc
Setconnection encryption
key Change connection link key
clkoff
Readclock offset
clock
Readlocal or remote clock
lescan Start LE scan
lewladd Add device to LE
White List
lewlrm
Removedevice from LE
White List
lewlsz
Readsize of LE
White List
lewlclr
ClearLE
Whitelist
lecc Create a LE Connection
ledc Disconnect a LE Connection
lecup LE Connection
Update
For more information on the usage of each command use:
hcitool <command> --help
命令 |
說明 |
調用方式 |
---|---|---|
參數 |
||
–help |
進入幫助 |
hcitool –help |
-i |
在host插有多個藍牙適配器的情況下,可以通過該參數來指定某控制某一適配器 |
hcitool -i [dbaddr] [command] |
命令 |
下面的命令是普通藍牙設備,不需要sudo |
|
dev |
同hciconfig一樣,顯示當前適配器設備,輸出格式為[hciid MAC] |
hcitool dev |
inq |
查詢可發現的遠端設備,與scan不同的是,除了能查詢出MAC以外,還可以查出遠端設備的時鐘偏移值“clock offset”與設備類型“class”,scan是不會輸出相關設備的類型,這可以讓我們區分設備是藍牙耳機,或藍牙滑鼠 |
hcitool inq |
hcitool inq [–length=N]設置最大查詢時間 |
||
hcitool inq [–numrsp=N]設置最大查詢數量 |
||
hcitool inq [–iac=lap]指定查詢的lac碼 |
||
hcitool inq [–flush]清除緩存 |
||
scan |
查詢可發現的遠端設備,與inq不同的是,除了能查詢出MAC以外,還可以輸出設備的名字【名字寫在標準的module中,若查詢不到該key對應的values則會輸出N/A】,可以通過設置參數來獲取設備的類型,資訊等 |
hcitool scan |
hcitool scan[–length=N]設置最大查詢時間 |
||
hcitool scan[–numrsp=N]設置最大查詢數量 |
||
hcitool scan[–iac=lap]指定查詢的lac碼 |
||
hcitool scan[–class]查詢設備類型 |
||
hcitool scan[–info]查詢設備資訊 |
||
hcitool scan[–oui]查詢設備唯一標識 |
||
hcitool scan[–flush]清除緩存 |
||
name |
通過指定MAC位址來獲取設備的名稱,該命令可以補全inq查詢時無法輸出設備名稱的問題. |
hcitool name [dbaddr] |
info |
通過指定MAC位址來獲取設備的相關資訊。 |
hcitool info [dbaddr] |
spinq |
開啟定期查詢,使設備被發現,沒有則無輸出 |
hcitool spinq |
epinq |
關閉定期查詢,沒有則無輸出 |
hcitool epinq |
cmd |
向遠端設備發送命令 |
hcitool cmd < ogf > < ocf > [parameters] |
con |
顯示當前連接資訊 |
hcitool con |
cc |
連接設備,可以設置資料類型,與主從關係 |
hcitool cc < bdaddr > |
hcitool cc [–ptype=pkt_types] < bdaddr > 可以設置接收資料的類型,資料類型包括[DM1, DM3, DM5,DH1,DH3,DH5, HV1, HV2, HV3],可以設置多個類型,類型中間以逗號分隔,預設接收所有類型資料 |
||
hcitool cc [–role=m/s] < bdaddr >可以設置設備的主從關係,M為master,S為slave,默認為s |
||
Example: |
hcitool cc –ptype=dm1,dh3,dh5 01:02:03:04:05:06 |
|
cc –role=m 01:02:03:04:05:06 |
||
dc |
斷開遠端設備連接 |
hcitool dc < bdaddr > [reason] |
sr |
設置設備的主從關係 |
hcitool sr < bdaddr > < role > |
cpt |
設置遠端設備資料類型 |
hcitool cpt < bdaddr > < packet_types >可以設置接收資料的類型,資料類型包括[DM1, DM3, DM5,DH1,DH3,DH5, HV1, HV2, HV3],可以設置多個類型,類型中間以逗號分隔 |
rssi |
顯示裝置的信號強度 |
hcitool rssi < bdaddr> |
lq |
顯示裝置的鏈路品質 |
hcitool lq < bdaddr> |
tpl |
顯示裝置的發射功率級別 |
hcitool tpl < bdaddr> [type] |
afh |
顯示裝置的AFH(適應性跳頻)的通道地圖 |
hcitool afh < bdaddr> |
lp |
設置或顯示裝置的鏈路 |
hcitool lp < bdaddr> [link policy] |
lst |
設置或顯示連接逾時時間,預設情況下連接逾時斷開連接為20s可以設置超時時間來縮短超時斷開連接的時間 |
hcitool lst < bdaddr> [new value in slots] |
auth |
請求設備配對認證 |
hcitool auth < bdaddr> |
enc |
設置連接加密,同樣可以關閉連接加密 |
hcitool enc < bdaddr> [encrypt enable] |
key |
更新與遠端設備的link key |
hcitool key < bdaddr> |
clkoff |
讀取遠端設備的時鐘偏移量,不過這個變數不太靠譜 |
hcitool clkoff < bdaddr> |
clock |
讀取本地時鐘或遠端設備的時鐘 |
hcitool clock [bdaddr] [which clock] |
BLE設備命令 |
以下命令需要root許可權才能執行 |
|
lescan |
搜索BLE設備 |
hcitool lescan |
hcitool lescan[–privacy]啟用隱私搜索 |
||
hcitool lescan [–passive]預設參數,設置被動掃描 |
||
hcitool lescan [–discovery=g/l] 設置搜索條件為綜合設備或限制設備 |
||
hcitool lescan [–duplicates]過濾重複的設備 |
||
lewladd |
將設備加入BLE白名單 |
hcitool lewladd [–random] < bdaddr>可聲明該設備的MAC位址為隨機位址,有的BLE設備可以被設置為隨機MAC位址以增加私密性,為以後也能連接到該MAC位元元址,需要聲明MAC位元元址是隨機,這樣才能用舊的MAC位址連接到設備 |
lewlrm |
將設備移除BLE白名單 |
hcitool lewlrm < bdaddr> |
lewlsz |
輸出白名單設備清單 |
hcitool lewlsz |
lewlclr |
清空白名單列表 |
hcitool lewlclr |
lecc |
連接BLE設備 |
hcitool lecc < bdaddr> |
hcitool lecc [–random] < bdaddr>隨機MAC位址連接 |
||
hcitool lecc –whitelist 連接所有白名單設備 |
||
ledc |
斷開BLE設備的連接。在通過lecc連結後,hci工具會隨機分配給該設備一個handle名,斷開連接時需要使用該handle,因為在藍牙4.0以後,一個藍牙適配器可以連接7個BLE設備 |
hcitool ledc < handle> [reason] |
lecup |
更新BLE設備的連接及狀態 |
hcitool lecup [Options] |
Options: |
||
-H, –handle < 0xXXXX>指定更新狀態的BLE設備Handle,在通過lecc連結後,hci工具會隨機分配給該設備一個handle名 |
||
-m, –min < interval> 設置設備藍牙的休眠時間與–max聯合使用,設置的區間為: 0x0006~0x0C80 |
||
-M, –max < interval> 設置實例【hcitool lecup –handle 71 –min 6 –max 100】 |
||
-l, –latency < range> 設置BLE資料傳輸速率,區間為: 0x0000~0x03E8 |
||
-t, –timeout < time> N * 10ms 設置設備超時等待時間,區間為 0x000A~0x0C80 |
||
備註: |
min/max參數區間為7.5ms到4s,誤差在1.25ms,timeout的區間為100ms到32s |
8.3.3 Sdptool
主要用來流覽遠端設備SDP服務,或者管理本地的SDPD維護的資料庫。
常用的應該就是查找遠端設備的服務了
例如:
sdptool browse 00:02:72:B0:00:26 流覽地址為00:02:72:B0:00:26的設備所提供的服務
sdptool search 0x1112 00:02:72:B0:00:26 查找位址為00:02:72:B0:00:26的設備上的Headset Audio Gateway服務。
./sdptool search 0x1112 00:02:72:B0:00:26
Class 0x1112
Inquiring ...
Searching for 0x1112 on 00:02:72:B0:00:26 ...
Service Name: Headset Audio Gateway
Service RecHandle: 0x1001d
Service Class ID List:
"Headset Audio Gateway" (0x1112)
"Generic Audio" (0x1203)
。。。
8.3.4 Hciconfig
這個就不用多說了,格式上很類似於ifconfig,用來設置HCI設備的參數
例如
hciconfig hci0 up 啟動hci0介面
hciconfig hci0 iscan 使能位於hci0介面的藍牙晶片的inquery scan模式(使得設備能被其它藍牙設備發現)
hcitool是為了對設備的連接進行管理,那麼對BLE資料進行精細化管理的話,就需要用到gattool,使用gattool對藍牙設備發送指令的操作上要比hcitool的cmd齊全很多,關於gattool的使用分為兩種,一種直接使用參數對藍牙設備進行控制,二就是使用-I參數進入gattool的interactive模式對藍牙設備進行控制。
首先,看一下gattool的參數:
# gattool -h
Usage:
gatttool [OPTION...]
Help Options:
-h, --help Show help options
--help-all Show all help options
--help-gatt Show all GATT commands
--help-params Show all Primary Services/Characteristics arguments
--help-char-read-write Show all Characteristics Value/Descriptor Read/Write arguments
Application Options:
-i, --adapter=hciX Specify local adapter interface
-b, --device=MAC Specify remote Bluetooth address
-t, --addr-type=[public | random] Set LE address type. Default: public
-m, --mtu=MTU Specify the MTU size
-p, --psm=PSM Specify the PSM for GATT/ATT over BR/EDR
-l, --sec-level=[low | medium | high] Set security level. Default: low
-I, --interactive Use interactive mode
具體含義如下:
-i 指定適配器
gatttool -i < hciX> -b < MAC Address>
-b 指定遠端設備,在連接多個設備的情況下需要指定控制某一設備
gatttool -b < bdaddr>
-t 指定設備的類型,是開放設備還是私密設備
gatttool -b < MAC Address> -t [public/random]
-m 設置數據包長度
-m MTU
-sec-leve 設置資料發送級別,預設情況下是low,需要高頻發射資料的情況下需要將級別設置為high,但相應的耗電會上升
gatttool -b < MAC Address> -l [low/medium/high]
-I 進入interactive模式
gatttool -b < MAC Address> -I
以下參數可以直接在interactive模式下使用,也可以在命令列直接使用
-primary 尋找BLE中可用的服務
gatttool -b < MAC Address> -primary
-characteristics 查看設備服務的特性,其中handle是特性的控制碼,char properties是特性的屬性值,char value handle是特性值的控制碼,uuid是特性的標識。
gatttool -b < MAC Address> -characteristics
-char-desc 配合查看服務特性使用,可以查看該設備所有服務特性的值,該數值型別為鍵值對
gatttool -b < MAC Address> -char-desc [-uuid 0x000]可以通過設置UUID來查看某一特性的值
-char-write 更新特性的值,該更新類似於鍵值對,一個uuid匹配一個value
gatttool -b -char-write -uuid [0x000] -value [0]
-char-write-req 讀取notifications裡的內容,可以設置listen來開啟監聽否則每次唯讀一次,監聽讀取notifications時需要向該handle寫入一個1,在命令列中16進制的表示為0100,若向該handle寫入0200的話則改為讀取indications的內容
gatttool -b < MAC Address> -char-write-req -handle=0xXXXX -value=0100 -listen
完整示例:
gatttool -i hci0 -b aa:bb:cc:dd -t random -char-write-req -a 0x0039 -n 0100 -listen
http://chaoyunotebook.blogspot.com/2015/10/ubuntu-raspberry-pi-serial-port.html
https://blog.csdn.net/xubin341719/article/details/38640725
https://blog.csdn.net/talkxin/article/details/50610984
留言列表