IAP2 通过蓝牙
前言
iAP2協議,是蘋果MFi技術中的一種,是一個非常完整、經典的通訊協議。兩個設備互相使用數據包來通信,考慮到了通訊的完整性、正確性和效率。
作為數據包通信學習,是一個非常好的案例。
正文
配件可以使用iAP2協議來訪問高級設備功能。其中一項功能是通過iOS外部附件框架與第三方iOS應用程序進行安全通信的能力。
iOS External Accessory Framework:
About External Accessories
在Accessory Interface Specification R39.pdf中,第57章,是關于iAP2的協議描述。
iAP2是iAP1的完全替代者,不向后兼容(backward compatible)。
iAP縮寫表示的是Interface Accessory Protocol.
57.1 iAP2 Connection
一個iAP2連接是由一個iAP2傳輸通道(iAP2 Link)和一個或多個iAP2會話組成。
57.2 iAP Link
每一個iAP2連接都是從附件和設備之間通過支持的傳輸建立一個通道開始的。鏈接協議提供了一個與傳輸無關的機制,用于可靠和有序地發布屬于一個或多個iAP2會話的數據包。該協議也可基于每個連接進行配置,并可在任何特定的傳輸方式或附件使用情況下進行優化以獲得最佳性能。這些協議的功能是為了實現以下這些目標:
-
對收到的數據包進行ACK確認。
-
重傳只需要重新發送序列中未被確認的數據包。
-
對iAP2會話的明確和有效支持。
支持iAP2的傳輸方式:
-
Bluetooth
-
UART
-
USB Device Mode
-
USB Host Mode
-
Apple Lightning Audio
支持上面這些傳輸方式的設備,都可以和配件建立iAP2的連接。一些傳輸方式對不同的功能會更加合適,所以在配件設計過程中,選擇合適的傳輸方式是最優先的事。
57.2.1 Packet Structure
每個通信數據包應以一個固定大小的9字節的頭開始,包括校驗和。頭后面數據是一個可選的可變長度的數據有效載荷。頭部和有效載荷都有各自的校驗和。如果沒有有效載荷數據,就沒有有效載荷校驗和。
Table 57-1 iAP2 Link Packet Structure
Start of Packet MSB (0xFF)
Start of Packet LSB (0x5A)
Packet Length MSB
Packet Length LSB
Control Byte
Packet Sequence Number
Packet Acknowledgement Number
Session Identifier
Header Checksum
…
Payload Data
…
Payload Checksum
57.2.1.1 Start of Packet
每個iAP2鏈接數據包的前兩個字節總是FF 5A。如果在傳輸流中檢測到這些字節,那么配件和設備都應嘗試將后面的字節解析為有效的數據包。
57.2.1.2 Packet Length
接下來的兩個字節表示以字節為單位的數據包長度,并且總是以無符號的16位大端整數表示。一個沒有有效載荷數據的鏈接數據包的長度固定是9字節(從數據包的開始到頭校驗和)。否則,數據包長度是從數據包開始到最后一個字節的有效載荷數據,包括有效載荷校驗和。例如,一個有1個字節的有效載荷數據的鏈接數據包,其數據包長度為11字節。數據包的最大有效載荷數據大小為65525字節;具有這種有效載荷的數據包的包長為65535字節。
57.2.1.3 Control Byte
控制字節中的位表明數據包中存在的內容。
-
SYN, EAK, 和 RST 位是相互排斥的。
-
ACK位可與SYN位結合。
-
EAK位總是與ACK位一起設置。
-
RST位從不與任何其他位一起設置。
-
SLP位從不與任何其他位一起設置。
-
所有未分配的位應被設置為0。
當SYN、EAK或RST的任何位被設置時,iAP2會話有效載荷不能出現。反之,帶有iAP2會話有效載荷的鏈接數據包總是設置ACK位。
Table 57-2 iAP2 Link Control Byte Bits
Bit
Name
Meaning
7
SYN
Link Synchronization Payload is present
6
ACK
Packet Acknowledgement Number is valid, and iAP2 Session Payload may be present
5
EAK
Extended Acknowledgement Payload is present
4
RST
Link Reset
3
SLP
Device Sleep
下面的內容將會使用這些描述表示帶有某種control byte的link packet。
57.2.1.4 Packet Sequence Number
每個鏈接數據包都包含一個數據包序列號,用來唯一識別傳輸中的該數據包。當首次創建鏈路時,設備和附件都應在發送其第一個SYN/SYN+ACK包之前隨機選擇一個初始序列號。每次發送帶有iAP2會話或鏈路同步有效載荷數據的數據包時,序列號都會增加1,否則,在發送數據包時序列號不會增加。以前發送的數據包的重新傳輸應保留相同的數據包序列號。序列號在達到255時包回0。The sequence number wraps back to 0 upon reaching 255.
注:設備和配件應該各自使用自己的包序列號。
57.2.1.5 Packet Acknowledgement Number
只有當控制字節中的ACK位被設置時,數據包確認號碼才有意義。如果沒有設置ACK,則發送方應將數據包確認號設置為0,而接收方應將其忽略。
如果設置了ACK,此數據包是接收方向發送方回復一個數據包用來確認,里面包含的數據包確認號表示的是收到的上一個按順序接受的數據包號碼。例如,如果配件收到的數據包序列號是1、2、3和5,那么配件發送的下一個數據包里的數據包確認號將是3,因為5是不按順序收到的。
57.2.1.6 Session Identifier
會話標識符只有在控制字節中的ACK位被設置且存在iAP2會話有效載荷時才有意義。如果滿足這兩個條件,會話標識符將是一個非零數字,指定iAP2連接中的一個特定會話。否則,會話標識符應被設置為0。
57.2.1.7 Header Checksum
頭部校驗和的計算方法是將以下所有數據包的字節相加。如果報頭校驗和的值與根據校驗和計算的值不一致,接收方應從下一個檢測到的數據包開始序列重新開始數據包解析工作。
· Start of Packet MSB
· Start of Packet LSB
· Packet Length MSB
· Packet Length LSB
· Control Byte
· Packet Sequence Number
· Packet Acknowledgement Number
· Session Identifier
57.2.1.8 Payload Data
這一部分是可選的,它的存在應與控制字節中的位的狀態相匹配。可能的最大有效載荷大小為65,525字節。
57.2.1.9 Payload Checksum
當且僅當有效載荷數據存在時,有效載荷校驗字節才會出現。如果存在有效載荷數據,則對有效載荷數據的所有字節進行校驗。如果有效載荷校驗和中的值與根據校驗和計算的值不一致,接收方應從下一個檢測到的數據包開始序列重新開始數據包解析。
57.2.1.10 Checksum Calculation
iAP2使用的校驗和字節是為每個發送的數據包計算的。其目的是讓所有被校驗的(無符號8位)字節和校驗(無符號8位)字節的總和,忽略任何無符號8位溢出,等于0x00。這允許一個快速的方法來驗證數據包的正確傳輸。校驗字節的計算方法是:取被校驗的(無符號8位)字節之和的最小有效字節,然后取補碼。
下面是代碼示例:
uint8_t
checksum_calculation(uint8_t *buffer, uint16_t start, uint16_t length)
{
uint16_t i;
}
57.2.2 Link Synchronization Payload
關于包頭后面的負載數據:鏈路同步有效載荷(Link Synchronization Payload / LSP)用于建立鏈路,并在設備和接入點之間同步包序號。它還包含可協商的鏈接參數。
Table 57-3 Link Synchronization Payload (Version 1)
Link Version (0x01)
Maximum Number of Outstanding Packets
Maximum Received Packet Length MSB
Maximum Received Packet Length LSB
Retransmission Timeout MSB
Retransmission Timeout LSB
Cumulative Acknowledgement Timeout MSB
Cumulative Acknowledgement Timeout LSB
Maximum Number of Retransmissions
Maximum Cumulative Acknowledgements
iAP2 Session 1: Session Identifier
iAP2 Session 1: Session Type
iAP2 Session 1: Session Version
…
iAP2 Session N: Session Identifier
iAP2 Session N: Session Type
iAP2 Session N: Session Version
57.2.2.1 Link Version
-
正在建立的鏈接的版本。所有數據包的有效載荷都可能根據鏈路版本的不同而不同。
-
目前鏈路版本的唯一有效值是1。
-
這是一個可協商的參數。
-
附件和設備都應同意相同的值。
57.2.2.2 Maximum Number of Outstanding Packets
-
在沒有收到對方ACK的情況下,可以發送的未決數據包的最大數目
-
有效值為1到127。
-
這不是一個可協商的參數。
-
配件和設備可以提出并使用不同的值。
-
在不等待設備確認的情況下,配件發送的數據包數量不得超過設備建議的最大未決數據包數量,反之亦然。
57.2.2.3 Maximum Received Packet Length
-
以字節為單位的可以接手的最大可能的包長。
-
有效值為24至65535。
-
這不是一個可協商的參數。
-
配件和設備可以提出并使用不同的值。
57.2.2.4 Retransmission Timeout
-
沒有收到ACK時重發一個包的超時時間,單位為毫秒。這應該被設置為一個與數據包在鏈路傳輸上的傳輸時間相近的值。
-
有效值為20毫秒至65535毫秒。
-
這是一個可協商的參數。
-
配件和設備都應同意相同的值。
57.2.2.5 Cumulative Acknowledgement Timeout
-
以毫秒為單位的超時值,當不在接受到新的數據包時,要發送ACK數據確認包。
-
有效值為10毫秒至等待重傳超時時間的一半。
-
這是一個可協商的參數。
-
配件和設備都應同意相同的值。
57.2.2.6 Maximum Number of Retransmissions
-
在鏈路被認為是斷開之前嘗試的最大數據包重傳數量。
-
有效值為1到30。
-
這是一個可協商的參數。
-
配件和設備都應同意相同的值。
57.2.2.7 Maximum Cumulative Acknowledgements
-
當按序列接收到的最大數量的數據包時,就要發送ACK確認數據包。
-
有效值為0-127或最大未處理數據包數量,以較小者為準。
-
這是一個可協商的參數。
-
配件和設備都應同意相同的值。
57.2.2.8 ZeroACK/ZeroRetransmit Link Configurations
從iOS 8.3開始,配件可以選擇協商一個ZeroACK/ZeroRetransmit鏈路配置,而不期待重傳的數據包或數據包確認。建議使用的條件是,底層傳輸有自己的可靠傳輸機制,并且配件可以完全利用這些機制。這種類型的iAP2連接方式,可用的傳輸層是USB主機模式、USB設備模式和藍牙RFCOMM傳輸。
設備仍將使用數據包序列號檢測掉落的鏈接數據包并重置iAP2鏈接。
如果在典型的使用過程中經常發生丟包,附件不應使用這種鏈路配置,并應準備在復位發生時重新建立鏈路,而不丟失狀態或影響用戶功能。
-
當設備檢測到丟包時,將向附件發送RST,鏈路層協商將以附件的SYN包重新開始。
-
當附件使用數據包序列號檢測到一個丟棄的數據包時,附件應發送一個SYN數據包以重新啟動鏈路協商
為了協商零應答/零重傳的鏈路配置,以下可協商的鏈路參數應設置為0:
-
重傳超時
-
累計確認超時
-
最大重傳次數
-
最大累計確認次數
一些設備和/或iOS版本可能會拒絕協商零ACK/零重傳鏈接配置的嘗試。如果配件聲稱與這些設備/iOS版本兼容,則應保留協商帶有確認和重傳的鏈接的能力。配件應發送一個SYN數據包,而不是SYN+ACK,來更新參數以繼續協商。
配件應通過管理其iAP2會話的通訊,來解決在鏈路層缺乏流量控制(flow control)的情況。例如,在開始文件傳輸前,應通過發送StopMediaLibraryUpdate來暫停MediaLibraryUpdate消息,并在適當時恢復其他活動。同樣的注意事項也適用于外部配件協議消息。
Accessories shall account for the lack of flow control at the link layer by managing their iAP2 session traffic.
57.2.2.9 iAP2 Sessions
-
配件將使用iAP2會話與設備進行通信。
-
會話標識符對每個定義的會話都是唯一的。0不是一個有效的會話標識符。
-
會話類型和版本應是有效的。
-
這是一個可協商的參數。
-
配件和設備都應同意相同的值。
57.2.3 iAP2 Session Payload
iAP2會話有效載荷在后面有專門說明。只要存在iAP2會話有效載荷,控制字節中的ACK位應被設置。
57.2.4 Extended Acknowledgement Payload
Extended Acknowledgement Payload用于確認不按順序收到的數據包。
該有效載荷具有以下屬性:
-
控制字節中的EAK和ACK位都應被設置。
-
數據包確認號包含依次收到的最后一個數據包的序列號。
-
有效載荷數據部分包含一個或多個不按順序收到的數據包的序列號。它們不是這些數據包的確認。確認將在以后的數據包中單獨發送,并在ACK字段中標明適當的號碼。
Table 57-4 EAK Packet Payload (Link v1)
1st Out of Sequence Acknowledgement Number
…
Nth Out of Sequence Acknowledgement Number
57.2.5 Reset
控制字節中的RST位被設備用來重置一個連接。這種鏈接數據包沒有有效載荷,只能由設備發送。
57.2.6 Sleep
本節僅適用于集成以下Lightning連接器的配件:
· Lightning (C78-USBH)
· Lightning (C79-USBH)
· Lightning (C79-UART)
· Lightning (C79-LA)
· Lightning (C78-STROBE-USBH)
· Lightning (C78-STROBE-UART)
· Lightning (C78-STROBE-LA)
控制字節中的SLP位被設備用來表示它即將進入睡眠狀態。這種鏈接數據包沒有有效載荷,只能由設備發送。
一旦進入睡眠狀態,設備將停止供應附屬電源。如果設備退出睡眠狀態,它將再次開始供應配件電源。
如果配件能夠暫停和恢復鏈路層,配件應在附件電源恢復后等待500毫秒,然后重新初始化鏈路。在這段時間內,配件可能會收到來自設備的ACK信號,該信號是鏈路層恢復的信號,并用于同步序列號(設備發出的最后一個包的序列號)和ACK號(設備收到的最后一個包的序號)。
如果配件不能暫停和恢復鏈路層,在重新初始化鏈路前,配件應在電源恢復后等待80毫秒。
57.2.7 Operation
57.2.7.1 Record
所有鏈接的實施都應在鏈接的特定記錄中存儲以下變量。這些變量將在描述iAP2鏈接操作的后續章節中被提及。
Table 57-5 iAP2 Link Operation Record Variables
Variable
Description
SentACKTimer
A timer keeping track of the elapsed time (ms) since the last ACK packet was sent
NextSentPSN
The Packet Sequence Number of the next packet to be sent
OldestSentUnacknowledgedPSN
The Packet Sequence Number of the oldest unacknowledged packet
InitialSentPSN
The Packet Sequence Number used for the very first packet sent
LastReceivedInSequencePSN
The Packet Sequence Number of the last packet received correctly and in sequence
InitialReceivedPSN
The Packet Sequence Number of the very first packet received
ReceivedOutOfSequencePSNs[n]
An array of Packet Sequence Numbers received and acknowledged out of sequence
57.2.7.2 Initialization
一旦傳輸連接已經建立,配件應確認設備是否支持iAP2,以1赫茲(每秒一次)發送以下字節序列,直到收到設備的響應:
FF 55 02 00 EE 10.
如果設備支持iAP2, 配件會受到同樣的字節序列。
如果設備只支持iAP1,配件會收到下面的某個數據序列:
55 04 00 02 04 EE 08
55 02 00 00 FE
FF 55 04 00 02 04 EE 08
FF 55 02 00 00 FE
如果配件收到上面的數據序列之一,需要發送下面的字節序列給設備,來表示不兼容:
FF 55 0E 00 13 FF FF FF FF FF FF FF FF FF FF FF FF EB
配件應將設備返回的應答作為最終應答,不允許重傳或重試。
57.2.7.3 Synchronization
該鏈接的一個顯著特點是支持在任何類型的傳輸上自動協商傳輸參數。這允許鏈接根據設備和配件的能力進行擴展。鏈接初始化有3個主要目的:
-
確定設備和配件雙方都能接受的鏈路配置參數。
-
搜索配置參數中的錯誤。
-
如果不能達成協議,就終止鏈接。
當底層傳輸連接已建立,iAP協議也兼容時,就會啟動一個鏈接。這時,配件先發送一個SYN數據包,里面的鏈接同步數據負載包含了鏈接所需的參數,以及隨機生成的數據包序列號。設備將以SYN+ACK數據包回應,確認收到附件的SYN數據包、它自己想要的連接參數和它隨機產生的數據包序列號。
如果設備和配件對所有可協商的連接參數提出了相同的值,附件應發送一個來自設備的最新SYN+ACK的最終ACK包,并且連接被認為已經建立。否則,SYN+ACK包將繼續交換,最多10次,直到所有可協商的連接參數都達成一致。如果發生10次交換而沒有就可協商的連接參數達成協議,設備將停止響應配件發送的任何進一步的數據包。
有時,設備將無法立即響應從配件收到的SYN數據包。配件可以用相同的有效負載數據和相同的數據包序列號重新發送SYN數據包。附件可以每秒繼續這樣做,直到設備發送SYN+ACK響應,確認先前發送的數據包序列號。一旦收到設備的響應,附件應忽略任何隨后進入的具有相同數據包序列號的SYN+ACK數據包。
如果配件的最終鏈路同步有效負載數據中含有無效的非協商數據,設備將發送一個RST數據包以重置鏈路。
在同步過程中,假定以下默認鏈路配置參數,直到同步完成之前,以下默認鏈路配置參數。
在同步過程中,在同步完成之前,假定使用以下的默認鏈路配置參數:
Table 57-6 Default link parameters during synchronization
Parameter
Default Value
Maximum Number of Outstanding Packets
1
Maximum Received Packet Length
128 bytes
Retransmission Timeout
1000 ms
Cumulative Ack Timeout
10 ms
Maximum Number of Retransmissions
30
Maximum Cumulative Acknowledgements
0
下表包含了一些使用iAP2協議的傳輸方式所推薦的鏈接配置參數。
這些值只是作為開發的初始值,針對某個特定配件使用的話,需要經過相應的核實才行。
Table 57-7 Recommended link parameters for USB Host Mode transport (Full Speed)
Parameter
Recommended Value
Maximum Number of Outstanding Packets
5
Maximum Received Packet Length
4096 bytes
Retransmission Timeout
2000 ms
Cumulative Ack Timeout
22 ms
Maximum Number of Retransmissions
30
Maximum Cumulative Acknowledgements
3
Table 57-8 Recommended link parameters for USB Device Mode transport (Full Speed)
這個和上面一樣。
Table 57-9 Recommended link parameters for Bluetooth transport
Parameter
Recommended Value
Maximum Number of Outstanding Packets
5
Maximum Received Packet Length
2048 bytes
Retransmission Timeout
1500 ms
Cumulative Ack Timeout
73 ms
Maximum Number of Retransmissions
30
Maximum Cumulative Acknowledgements
3
Table 57-10 Recommended link parameters for 115.2 kbps UART transport
Parameter
Recommended Value
Maximum Number of Outstanding Packets
4
Maximum Received Packet Length
256 bytes
Retransmission Timeout
1000 ms
Cumulative Ack Timeout
133 ms
Maximum Number of Retransmissions
30
Maximum Cumulative Acknowledgements
2
57.2.7.4 Acknowledgements
為了保證數據包派發成功,鏈路協議同時使用了數據包的接收確認和重傳。每個帶有有效負載數據的數據包和SYN數據包在被接收方收到并認可后,需要接收方回復ACK。回復的ACK數據包不需要另一方再回復ACK。損壞的數據包被丟棄,不需要回復ACK。當數據包在重傳超時規定的時間內未被接收方確認時,發送方將重傳數據包。
有兩種類型的數據包確認方式(ACK)。累積確認用于確認收到的所有按順序接收到的數據包,指定的是某個最新發送的符合順序的數據包。擴展確認允許接收方確認不按順序的數據包。使用的確認類型只是根據數據包到達順序而定。在可能的情況下,鏈路實現應使用累積確認,并僅在數據包被非按順序接收時使用擴展確認。
一旦收到一個或多個不按順序的數據包,接收方應立即生成并發送擴展確認。
如果相應的ACK在傳輸中丟失,同一個有效載荷數據可能被多次接收。發生這種情況時,接收方應重新發送有效負載數據的ACK。
57.2.7.5 Retransmissions
數據包在底層傳輸時,可能會丟失或損壞。這樣就可能被數據包丟棄。如前所提的數據包的回復ACK機制,要求接收方正確收到一個有效數據包時,要回復一個ACK的數據包。
為了檢測丟失的數據包,發送方應為每個發出的數據包啟用一個重傳超時時間。這個定時器的時間是根據協商確定的。當收到一個數據包的確認時,該數據包的定時器被取消。如果定時器在收到確認之前過期,則數據包被重傳,定時器被重新啟動。可以重傳的最大次數,是根據鏈接同步期間協商而定的。
57.2.7.6 Flow Control
iAP2鏈路使用了流控機制,根據未收到確認的數據包個數,和鏈路配置參數里的最大未決數據包個數。該參數由雙方在創建鏈路時指定,并應根據各自分配給鏈路的緩沖區的數量和大小來設置。一旦設定,該參數在連接時保持不變。
該鏈路采用了序列號窗口的概念,用于可接受的數據包序列號。窗口的左邊緣是最后一個確認的數據包序列號加1。窗口的右邊緣等于最后一個序列內確認的數據包序列號加最大未決數據包數量。鏈路發送者發送數據包,直到達到接收者的最大未處理數據包數量。一旦達到限制,發送方只能收到一個確認包,再發送一個新數據包。
當一個收到的數據包的數據包序列號落在窗口內,它就被確認。分兩種情況。如果數據包序列號等于左邊緣(即它是下一個預期的數據包序列號),則以累積確認(ACK)確認該數據包,并且接受窗口的左邊緣和右邊緣遞增一個。如果收到的數據包的序列號在窗口內,但不在序列內,則用擴展確認(EAK)來確認。窗口不作調整,并記錄收到的不符合順序的數據包。收到的鏈路數據包序列號在窗口之外的數據包應被丟棄;并表明鏈路不穩定,可能需要重置。
當發送方收到擴展確認(EAK)時,發送方不應在發送接收窗口之外的數據包。如果一個數據包沒有被確認,但所有后續的數據包都被收到并確認,就可能發生這種情況。這一要求將把窗口的左邊緣固定在未被確認的數據包的序列號上。隨著其他數據包的發送,下一個數據包序列號將接近并最終超過右邊緣。這時,沒有更多的數據包可以被發送,直到未被確認的數據包被確認。
57.2.7.7 Reset
設備可以在任何時候向配件發送一個RST數據包。收到RST數據包后,附件應在收到RST數據包后1秒內向設備發送SYN數據包,然后進行同步處理。
配件應終止底層傳輸連接,然后再重新連接。如果UART傳輸處于活動狀態,只有手動的斷開再接入配合和設備的Lightning連接器才可以。當必須重連時,表明協商的鏈接參數設置不合理,一般情況下不應該發生這種情況。
總結
- 上一篇: android lame wav 转 m
- 下一篇: 风口的猪-中国牛市(动态规划)----百