2020年5月2日 星期六

BlueZ 的研讀紀錄(二): Device在哪裡 ?

由於沒有找到Device Name,依照我的習慣,先找找那些檔案是相關與Bluetooth的。

結果找到:

/usr/bin/hciattach
/usr/bin/hcidump
/usr/bin/hcitool
/use/bin/bluemoon
/usr/bin/bluetoothctl
/etc/bluetooth
/etc/dbus-1/system.d/bluetooth.conf
/etc/init.d/bluetooth
/etc/rc0.d/K01bluetooth
/etc/rc1.d/K01bluetooth
/etc/rc2.d/S01bluetooth
/etc/rc6.d/K01bluetooth


HCI這個名詞常常出現在Bluetooth的命令之中,所以先了解一下。

Bluetooth 基本上可以大致分為底層硬體的PHY (就是我們平常說的BT4.1, BT5.0) 與上層的應用Profile,目前已經有一堆Profile被定義:

1 A2DP : 藍牙立體聲音訊傳輸規範(Advanced Audio Distribution Profile )
2 ATT:(Attribute Profile)
3 AVRCP:音訊/影片遠端控制設定檔(Audio/Video Remote Control Profile)
4 BIP:基本圖像規範(Basic Imaging Profile)
5 BPP:基本列印規範(Basic Printing Profile)
6 CIP:ISDN規範(Common ISDN Access Profile)
7 CTP:無線電話規範(Cordless Telephony Profile)
8 DIP:裝置識別符號規範(Device ID Profile)
9 DUN:撥接網路規範(Dial-up Networking Profile)
10 FAX:傳真規範(Fax Profile)
11 FTP:檔案傳輸規範(File Transfer Profile)
12 GAVDP:影音傳送通用規範(Generic Audio/Video Distribution Profile)
13 GAP:通用存取規範(Generic Access Profile) – BLE 相關規範。
14 GATT:通用型連接規範(Generic Attribute Profile) – BLE 相關規範。
15 Generic Object Exchange Profile (GOEP)
16 Hard Copy Cable Replacement Profile (HCRP)
17 HDP:醫療設備規範(Health Device Profile )
18 HFP:手持裝置規範(Hands-Free Profile )
19 HID:人機介面規範(Human Interface Device Profile)
20 Headset Profile (HSP)
21 ICP:網內通訊規範(Intercom Profile )
22 LAP:網路訪問配置規範(LAN Access Profile)
23 MESH:MESH規範(Mesh Profile)
24 MAP:簡訊交換規範(Message Access Profile)
25 OBEX:泛用物件交換規範(OBject EXchange)
26 OPP:物件交換規範(Object Push Profile)
27 PAN:個人區域網路規範(Personal Area Networking Profile)
28 PBAP:電話簿存取規範(Phone Book Access Profile)
29 PXP:裝置接近規範(Proximity Profile)
30 SPP:序列埠規範(Serial Port Profile)
31 SDAP:服務搜尋規範(Service Discovery Application Profile)
32 SIM:SIM卡的遠端存取規範(SIM Access Profile, SAP, SIM or rSAP)
33 SYNCH:資訊同步規範(Synchronization Profile)
34 SyncML:格式化資訊同步規範(Synchronisation Mark-up Language Profile)
35 VDP:影像分享規範(Video Distribution Profile)
36 WAPB:基於藍芽點對點的WAP (Wireless Application Protocol Bearer) – 一個完全無用的協定。

HCI是Host Control Interface的簡寫。簡單來說,上層的這些Profile (軟體),利用HCI與底層的Bluetooth硬體,與另外一台裝置連接。如果裝置的雙方都有相同的Profile,就可以連接起來幹活了。

目前連接的方式(術語稱之為Transport)有UART、USB、SD、3-Wire UART四種。我們常見的接法就是主晶片使用UART連接Bluetooth晶片。這是最最簡單的接法,因為就等於使用 /dev/tty02 就可以完成通信了。

HCI 定義了四種封包,在主晶片與 BT模組之傳送資料:

1. Command : 0x01 使用 0x01 開頭的封包就是命令。
2. ACL:用於傳輸一般性資料具有基本的資料可靠性保證 (0x02)
3. SCO:用於語音資料的傳遞(x03)
4. Event:用於BT Module 回應 Host 的控制(0x04)

如果你找 INCLUDE FILE的定義,你會看到這樣的定義:

typedef  enum _HCI_PACKET_TYPE_ {
       HCI_COMMAND = 0x01,
       HCI_ACL = 0x02,
       HCI_SCL = 0x03,
       HCI_EVENT = 0x04
} HCI_PACKET_TYPE;


這些定義可以在 /include/net/bluetooth/hci.h 當中看到。如果沒有,可以先到BlueZ官網,下載最新版的SOURCE CODE,hci.h 在 ./lib 的目錄下面。

下面就先看一下HCI_COMMAND與HCI_EVENT在傳些甚麼東西:

HCI_COMMAND

先看一下HCI_COMMAND Packet Format,用C struct 可以這樣表示:

_HCI_PACKET_ {
  union
   {
      unsigned short int code; // 16 bit
      struct {
         unsigned int ocf :10;
         unsigned int ogf : 6;
      } op;
   }
   unsigned char Size;     // parameter total length
   unsgined char* body; // context of parameters
} HCI_PACKET;



CI 命令封包(Command Packet) 是由一個16 bits 的操作碼(Opcode)開始, 操作碼由兩部份組成 分別是 OGF (OpCode Group Field, 6 bits) 與 OCF (OpCode Command Field, 10 bits),

OGF 目前定義了 6 個 Group
  1. 連結控制命令(Link Control Command), OGF =: 0x01
  2. 連結方式命令(Link Policy Command), OGF =: 0x02
  3. 控制器與基頻命令(Controller & Baseband Command), OGF =: 0x03
  4. 資訊參數(Informational Parameters), OGF =: 0x04
  5. 狀態參數(Status Parameters), OGF =: 0x05
  6. 測試命令(Testing Command), OGF =: 0x06
OGF: 0x3F (111111B)是保留給Vendor-Specific 測試使用, OGF:0x3E (111110B)則是保留給 Bluetooth Logo Test。

當OGF與OCF 都為0 時則是一個 NOP 命令,在流量控制中可能會需要使用到。

接在Opcode 後的就是SIZE,這是說明BODY的總長度,所以BODY依照不同命令會有不同的長度。

要注意的是HCI的功能是透過UART,讓主晶片的CPU可以與藍芽晶片溝通。舉例而言,要對一個BT Module下達進入測試模式(Enable Device Under Test Mode)時,就可以使用 OGF =: 0x06。Protocol的細節可以參考藍芽Core Specification Section 7.6.3 Part E, Volume 2。

每當一個Command 下達給BT晶片之後,晶片會回應一個HCI Command Complete Event 給Host端表示完成命令的接收。

HCI_EVENT

HCI_EVENT是BT晶片用來回應 HCI Command 的封包,基本結構如下:



HCI_EVENT Packet Format

其實都是差不多的結構:

typedef struct {
uint16_t handle; /* Handle & Flags (PB, BC) */
uint16_t dlen;
}


就是先送 Event Code、接上參數長度,然後依照這個長度,讀出所有的參數。大致上懂了HCI 的功能之後,接下來就可以回來玩玩這些已經寫好的命令。

首先先試試 hciconfig:

root@luke-G50:/etc/bluetooth# hciconfig <Enter>
hci0:   Type: BR/EDR  Bus: USB
        BD Address: D0:53:49:00:FB:6A  ACL MTU: 1022:8  SCO MTU: 183:5
        DOWN
        RX bytes:574 acl:0 sco:0 events:30 errors:0
        TX bytes:368 acl:0 sco:0 commands:30 errors:0


果然看到一些資訊,而且與上面說的這些理論值,可以對應得起來。由於顯示為DOWN,所以試試能不能UP:

root@luke-G50:/etc/bluetooth# hciconfig hci0 up
Can't init device hci0: Operation not possible due to RF-kill (132)

因為硬體沒有開嗎? 於是由DESKTOP上面開啟Bluetooth。這裡有個疑問? 難道沒有命令可以打開Bluetooth硬體嗎? 這還要研究一下,總之hciconfig 無法開啟硬體就是了。接下來就有以下的畫面:

root@luke-G50:/etc/bluetooth# hciconfig hci0 up
root@luke-G50:/etc/bluetooth# hciconfig hci0
hci0:   Type: BR/EDR  Bus: USB
        BD Address: D0:53:49:00:FB:6A  ACL MTU: 1022:8  SCO MTU: 183:5
        UP RUNNING PSCAN ISCAN
        RX bytes:1190 acl:0 sco:0 events:67 errors:0
        TX bytes:1076 acl:0 sco:0 commands:67 errors:0


所以 Bluetooth DEVICE在哪裡? 原來是 hci0 。

這台PC是透過USB與藍芽晶片連接的。 其中藍牙晶片支援基礎率/增強資料率(BR/EDR),但是另外的BLE (低耗能)則沒有支持。

Mac Address D0-53-49 屬於光寶(Liteon Technology Corporation),BT模組應該是光寶製作的。





沒有留言:

張貼留言