1. 程式人生 > >BLE 5協議棧-屬性協議層(ATT)

BLE 5協議棧-屬性協議層(ATT)

組類型 onf xxxx 偏移量 read error 框架 request 有效

文章轉載自:http://www.sunyouqun.com/2017/04/page/2/

屬性協議(Attribute Protocol)簡稱ATT。

ATT層定義了屬性實體的概念,包括UUID、句柄和屬性值等,也規定了屬性的讀、寫、通知等操作方法和細節,這些與屬性操作相關的內容稱為屬性協議。ATT層規定了ATT_MTU值,如果屬性值很長,超過了ATT_MTU限制,將使用特殊的讀寫方法進行操作。

基於ATT層,可以構建出通用屬性操作規範。

1. 屬性

在藍牙協議中, 屬性是指一個數據實體,它包含標識符,句柄,數據內容,訪問權限,安全問題等。

屬性協議規定了屬性的發現和讀寫訪問的方法。

1.1 類型

屬性類型由一個UUID(Universally Unique Identifier)表示。UUID是指從時間尺度和空間尺度都具有唯一性的一串128-bit的數字,該數字串在全球範圍內不會重復,並且在未來也不會出現重復。

一個典型的16字節UUID格式為XXXX-XX-XX-XX-XXXXXX。

藍牙協議設定了一個藍牙基礎UUID: 00000000 – 0000 – 1000 – 8000 – 00805F9B34FB。

利用該基礎UUID,可以使用16-bit或32-bit的UUID來代替128-bit的UUID,當傳遞到對端設備,再還原成128-bit的UUID。

假如16-bit的UUID為YYYY,則還原後的128-bit的UUID為:0000YYYY – 0000 – 1000 – 8000 – 00805F9B34FB。

假如32-bit的UUID為YYYYYYYY,則還原後的128-bit的UUID為:YYYYYYYY – 0000 – 1000 – 8000 – 00805F9B34FB。

ATT層支持使用16-bit和128-bit兩種UUID,32-bit的UUID在使用前必須轉換成128-bit。

1.2 句柄

屬性句柄猶如指向屬性實體的指針,對端設備通過句柄來訪問該屬性。

屬性句柄是一個2字節數,有效範圍為0x0001-0xFFFF。

屬性句柄為有序排列,後面的句柄值會大於前面的句柄,通常下一個屬性的句柄值是上一個屬性的句柄加1。

1.3 分組

多個屬性可以合成一組,一組屬性包含的參數為:開始句柄、結束句柄。

1.4 值

屬性值可以是一個數字或一個字符串。屬性值的長度信息不包含在PDU中,所以需要從PDU的長度間接推算出屬性值的長度信息。

屬性值通常在一個PDU中發送,如果屬性值太長,也可以分成多個PDU進行發送。

1.5 權限

屬性的讀寫權限由ATT層之上的協議層規定,有效的讀寫權限包括:可讀、可寫、讀寫。

在讀寫屬性之前,客戶端設備還需要具有足夠的安全權限,包括:

  • 加密權限:需要加密、無需加密
  • 認證權限:需要認證、無需認證
  • 授權權限:需要授權、無需授權

如果權限不足,將觸發錯誤處理機制。

1.6 控制點屬性

控制點屬性是一類特殊屬性,它不可讀,只能寫。

1.7 協議方法

對屬性的操作稱為協議方法,包括:命令(Command),請求(Request),響應(Response),通知(Notification),指示(Indication)和確認(Confirmation),某些屬性PDU還涉及授權簽名方法。

1.8 交換MTU Size

ATT_MTU表示ATT層間傳輸的數據包的最大長度。兩端設備可以通過Exchange MTU Request/Response進行交換MTU。

1.9 長包屬性

對於讀屬性的數據包,最大長度為(ATT_MTU-1)個字節。其中減去的1表示1字節的操作碼。

對於寫屬性的數據包,最大長度為(ATT_MTU-3)個字節。其中減去的3表示1字節的操作碼和2字節的屬性句柄。

如果數據包超過這個長度,則稱為長包屬性。

讀長包屬性,需要使用Read Blob Request,寫長包屬性,需要使用Prepare Write Request和Execute Write Request。

如果使用普通Read操作讀長包屬性,僅能讀取前(ATT_MTU – 1)個字節,使用普通Write操作寫長包屬性,僅能寫前(ATT_MTU-3)個字節。

無論普通屬性還是長包屬性,屬性值的最大長度均為512字節。

1.10 原子操作

一個請求或一個命令,稱為一個原子操作。一個原子操作結束後,才能進行新的原子操作。

讀寫長包屬性無法在一個原子操作內完成。

2. 屬性PDU

2.1 屬性角色

在ATT層協議框架內,擁有一組屬性的設備稱為服務端(Server),讀寫該屬性值的設備稱為客戶端(Client)。

2.2 分類

屬性PDU有六類:

屬性PDU方向觸發響應
Command Client -> Server
Request Client -> Server Response
Response Server -> Client
Notification Server -> Client
Indication Server -> Client Confirmation
Confirmation Client -> Server

屬性PDU格式如下:

字段OpcodeParameterAuthentication Signature
長度 1 octet 0 – (ATT_MTU-X) octets 0 or 12 octets

其中Opcode的第0-5位表示該屬性的具體類型,第6位表示命令標誌位,如果該位為1,表示該操作碼對應一個命令,最後1位表示認證簽名(Authentication Signature)標誌位,如果該位為1,表示該PDU的最後一個字段中包含12字節的認證簽名。

Parameter字段中包含了參數,其長度為0支ATT_MTU-x,如果認證簽名位為1,則此處x等於13,否則等於1。

只有寫命令才需要認證簽名,其他命令不需要。此外,如果鏈路已經進行加密,則屬性PDU中也無需額外添加認證簽名。

2.3 操作順序

對於Request和Indication屬性,需要接收端返回響應。在發出Request和Indication後,收到響應之前,不能發出新的Request和Indication。

對於其他無需響應的屬性,則可以在自由發送,但是不保證接收端一定能夠收到和執行。

可以在Request和Response之間,或Indication和Confirmation之間發送其他無需響應的屬性。

2.4 事務

一個Request-Response對,或Indication-Confirmation對,稱為一個事務。

對於客戶端設備而言,發出Request或收到Indication表示事務的開始,收到Response或返回Confirmation表示事務的結束。

對於服務端設備而言,發出Indication或收到Confirmation表示事務的開始,收到Confirmation或返回Response表示事務的結束。

3. 屬性協議PDU

屬性協議規定了多種Request-Response對,請求屬性由客戶端設備發出,響應屬性由服務端設備發出。

3.1 錯誤處理

OpcodePDU
0x01 Error Response

如果屬性PDU的操作碼無效,或屬性句柄無效,將返回錯誤響應PDU。在PDU的Parameter字段中,包含了錯誤編碼。

3.2 交換MTU

OpcodePDU
0x02 Exchange MTU Request
0x03 Exchange MTU Response

客戶端設備向服務端設備發送交換MTU請求,提供客戶端設備的MTU值。服務端設備獲知客戶端的MTU值,並返回自己的MTU值。兩端設備都將設置較小的MTU值作為新的MTU值。

如果兩端設備沒有交換MTU,則使用默認的MTU值(BLE下為23)處理屬性事務。

3.3 查找信息

PDUOpcode
0x04 Find Information Request
0x05 Find Information Response
0x06 Find By Type Value Request
0x07 Find By Type Value Response

查找信息請求,包含兩個參數:起始屬性句柄和結束屬性句柄,用於獲取服務端設備屬性句柄處於該參數區間內的屬性。

查找信息響應,包含指定句柄區間內的屬性UUID。如果區間內有多個屬性,則返回多個響應。

按類型值查找請求,是在查找信息請求的基礎上,加上了屬性類型和屬性值兩個參數,這樣能夠更加精確的找到目標屬性。

按類型值查找響應,包含了滿足條件的屬性句柄列表。

3.4 讀屬性

OpcodePDU
0x08 Read By Type Request
0x09 Read By Type Response
0x0A Read Request
0x0B Read Response
0x0C Read Blob Request
0x0D Read Blob Response
0x0E Read Multiple Request
0x0F Read Multiple Response
0x10 Read by Group Type Request
0x11 Read by Group Type Response

按類型讀請求,包含三個參數:起始屬性句柄、結束屬性句柄和屬性類型。

按類型讀響應,包含了滿足條件的屬性的“句柄-值”對的列表。

讀請求,包含一個參數:屬性句柄。

讀響應,返回滿足條件的屬性值。

讀片段(blob)請求,用於讀取一個長包屬性的值,它包含兩個參數:屬性句柄和偏移量。以不同的偏移量作為參數,多次執行該請求可以讀取長包屬性的完整值。

讀片段響應,包含了長包屬性值的指定偏移量片段。

讀多次請求,用於讀取多個給定句柄的屬性值,它包含一個參數:句柄列表。

讀多次響應,包含了多個指定句柄的屬性值。

按組類型讀請求,用於讀取指定組類型的屬性值,組類型是由ATT層之上的協議層設定的。它包含三個參數:起始屬性句柄、結束屬性句柄和屬性組類型。

按組類型讀響應,包含了滿足條件的屬性值列表。

3.5 寫屬性

OpcodePDU
0x12 Write Request
0x13 Write Response
0x14 Write Command
0x15 Signed Write Command

寫請求,將待寫數值寫入指定的屬性值,包含兩個參數:屬性句柄和數值。

寫響應,表示寫請求執行成功,不含任何參數。

寫命令,將待寫數值寫入指定的屬性值,包含兩個參數:屬性句柄和數值。它不會觸發一個寫響應。

簽名的寫命令,與上面的寫命令類似,指示包含了額外的參數:認證簽名。典型應用是寫控制點屬性。

3.6 隊列寫屬性

隊列寫是指利用一個先進先出的隊列,緩存多個屬性值的寫操作,然後在一個原子操作中完成所有的值寫入操作。

隊列寫專門用於長包屬性的寫操作,現將一個長數據分成多個部分並記錄偏移量,然後通過隊列緩存,等數據發送完畢,再按照收到的順序,一次性將整個長數據寫入屬性值。

OpcodePDU
0x16 Prepare Write Request
0x17 Prepare Write Response
0x18 Execute Write Request
0x19 Execute Write Response

準備寫請求,用於發送一個長數據片段,它包含三個參數:屬性句柄、偏移量和待寫入數據。

準備寫響應,收到準備寫請求以後,緩存收到的數據。

執行寫請求,對前面緩存的數據執行寫操作,它包含一個參數:標誌位。如果標誌位為1,則執行寫操作,如果為0,則取消前面的緩存數據。

執行寫響應,根據執行寫請求的標誌位,執行或取消寫操作。

3.7 通知屬性

OpcodePDU
0x1B Handle Value Notification
0x1D Handle Value Indication
0x1E Handle Value Confirmation

發送數值通知,它包含兩個參數:屬性句柄和屬性值。它不需要客戶端收到後返回響應。

發送數值指示,它包含兩個參數:屬性句柄和屬性值。它需要客戶端收到後返回確認。

發送數值確認,它不包含參數,客戶端發出該確認消息表示收到了數值指示。

4. 權限

通知和指示與讀寫操作類似,也可以設置安全權限。

每個屬性可以設置單獨的權限。

權限不足將阻止操作,並觸發錯誤響應。

權限問題與ATT之上的協議層有較大聯系。

(完)

BLE 5協議棧-屬性協議層(ATT)