文章總列表

假日藍芽工程師, ATT protocol

前言
搞定從Raspberry Pi讀心跳之後(by notification),下一步就是弄清楚BLE通信協定。這篇文章希望可以提供一些範例,解釋GATT/ATT是怎麼運作的。希望他能幫助社會大眾了解BLE是怎麼玩的。

ATT (Attribute)
所有BLE裝置都要支援ATT (Attribute, 屬性)協定。看起來很厲害,其實只是一個資料結構:

    struct {
        u16 uuid; // Universally Unique Identifier
        u8 *data; // variable length data
    } att[65536];

這個通訊協定就是一張表格,一個陣列。陣列允許random access,只要給個index就可以了。在BLE的術語理,這個index叫handle。表格每個單元還包括16bit的UUID作為metadata,解釋這筆資料是什麼。另外資料並不是直接嵌在表格,而是放一個指標,允許可變長度的資料。

上篇文章,我用了gatttool和心跳表打交道。這個工具就是透過RPi的藍芽dongle和心跳表的ATT layer打交道。參考gatttool的說明功能表就可以看出ATT protocol的功能:


在工具裡,執行"char-desc"可以把藍芽裝置所有的handle和對應的UUID讀出。對應的pseudo code看起來很像這樣:

    for handle in range(1, 65535):
        if att[handle] is effective:
            print "handler=%d, uuid=%d", i, att[i].uuid

我實際上在RPi執行的結果如下:



要在8051/ARM實作ATT protocol不會很難,就是一個存資料的資料結構而已。這邊有兩點值得再注意:
  1. UUID代表Universal Unique IDentifier,這個ID和資料放在一起,功能是描述這筆資料是什麼,也就是俗稱的metadata。一般去google找"Bluetooth BLE NNNN"就找得到UUID的意義。
  2. ATT protocol對資料長度沒有限制,實際的規範定義在上層GATT裡
以handle[0x3]當例子,這筆的UUID = 0x2A00代表裝置名稱。下面的截圖讀到0x48, 0x52, 0x4D,對照ASCII表格就查得到是"HRM"。這個字串和我在手機上看到的是一致的。




我的心跳表
要分析BLE裝置支援的功能,gatttool真的是滿好用的。我做了一些功課讀出每個handle並且找出意義。下面看得到ATT表格看起來是同樣功能的東西會集中在一起。這裡面也有一些有趣的參數,比如handle[0x1F]指出他是"Cambridge Silicon R"(CSR)的解決方案;handle[0x1b]指出開發工具的版本是"uEnergy SDK 1.4.3"。

* Generic Access Service
handle: 0x0001, uuid: 2800          1800, Generic access
handle: 0x0002, uuid: 2803          0a 0003 2a00
handle: 0x0003, uuid: 2a00          Device Name, "HRM"
handle: 0x0004, uuid: 2803          02 05 2a01
handle: 0x0005, uuid: 2a01          Appearance, 0x340=832, Generic Heart Rate Sensor
handle: 0x0006, uuid: 2803          02 07 2a04, Peripheral preferred connection parameter 
handle: 0x0007, uuid: 2a04          000a 0010 0064 04e2
    min-connection-interval = 0xA * 1.25ms = 12.5ms
    max-connection-interval = 0x10 * 1.25ms = 20ms
    Slave latency = 0x64 * interval = 100*interval = 1.25s ~ 2s
    Connection Superviser Timeout = 0x4E2 * interval = 1250 * interval = 15.625s ~ 25s

* Generic Attributes
handle: 0x0008, uuid: 2800          1801, Generic attributes

* Heart Rate
handle: 0x0009, uuid: 2800          180D, Heart Rate
handle: 0x000a, uuid: 2803          10 000b 2a37
handle: 0x000b, uuid: 2a37          Heart rate measurement, only notify (*)
handle: 0x000c, uuid: 2902          Control channel
handle: 0x000d, uuid: 2803          02 000e 2a38
handle: 0x000e, uuid: 2a38          01, chest
handle: 0x000f, uuid: 2803          08 0010 2a39
handle: 0x0010, uuid: 2a39          Heart rate control point

* Battery Service
handle: 0x0011, uuid: 2800          180F, Battery Service
handle: 0x0012, uuid: 2803          12 0013 2a19
handle: 0x0013, uuid: 2a19          Battery level, 0~100
handle: 0x0014, uuid: 2902          Control channel


* Device Information
handle: 0x0015, uuid: 2800          180A, Device Information
handle: 0x0016, uuid: 2803          02 0017 2a25
handle: 0x0017, uuid: 2a25          Serial Num, 34 36 58 41 36 37 39 57 44 4e 44 52 43 58 37 50 00 
handle: 0x0018, uuid: 2803          02 0019 2a27
handle: 0x0019, uuid: 2a27          Hw Revision String, 41 30 34 55, “@04U"
handle: 0x001a, uuid: 2803          02 001b 2a26
handle: 0x001b, uuid: 2a26          FW Rev String, “uEnergy SDK 1.4.3”
handle: 0x001c, uuid: 2803          02 001d 2a28
handle: 0x001d, uuid: 2a28          SW Rev String, “1.4.3.1”
handle: 0x001e, uuid: 2803          02 001f 2a29
handle: 0x001f, uuid: 2a29          Manufacturer, “Cambridge Silicon R"
handle: 0x0020, uuid: 2803          02 0021 2a50
handle: 0x0021, uuid: 2a50          PnP ID, 01 000a 014c 0100, vendor-id-src, vendor-id, product-id, product-rev


下一步: GATT
根據這張表格,要搞懂GATT的意義應該會比較容易一點

留言

Unknown寫道…
很有幫助 感謝~~~
感謝你的文章
收益良多!!
lihgong寫道…
@Cappella, 感謝comment, 我很高興這篇文章有幫助

這個網誌中的熱門文章

STM32 UART + DMA,使用HAL實作TX/RX,以及不定長度接收

幼犬書桌椅選擇心得 升降桌 兒童桌椅

CANON G3000 廢墨瓶改裝