此文大部分內容來自官方的翻譯,加上了自己的一些蹩腳的理解。
一、簡介
ANCS是Apple Notification Center Service的簡稱,中文爲蘋果通知中心服務。
ANCS是蘋果讓周邊藍牙設備(手環、手錶等)可以通過低功耗藍牙訪問IOS設備(iphone、ipad等)上的各類通知提供的一種簡單方便的機制。
依賴
ANCS是基於BLE協議中的通用屬性協議(Generic Attribute Profile,GATT)協議實現的,他是GATT協議的一個子集。在ANCS協議中,IOS設備作爲gatt-server,而周邊設備作爲gatt client來連接和使用server提供的其他services。
端和字符編碼
除非特殊說明,IOS設備ANCS與ble設備進行通信的過程中都是採用的小端模式進行傳輸的,比如NC接收到的attribute length數據爲0x02 0x00,應該解析爲0x00 0x02,即長度爲2byte.
字符串的編碼採用了UTF-8編碼格式。
相關術語
NP(Notification Provider):消息提供者,指的是ANCS服務的產生者,即IOS設備。
NC(Notification Consumer):消息接受者,指的是ANCS服務的客戶端,即周邊BLE設備。
二、ANCS
蘋果通知中心服務的UUID爲7905F431-B5CE-4E99-A40F-4B1E122D00D0。
由於IOS的特性限制,一個蘋果設備上只能有一個ANCS存在,一個ANCS可以連接多個client。因爲ANCS並不能保證始終存在(be present?),NC需要訂閱服務變更特性(the Service Changed characteristic of the GATT service )以便任何時候都可以監聽準備發佈和取消發佈的ANCS。
服務特性
ANCS有三個特性:
-
Notification Source: UUID 9FBF120D-6301-42D9-8C58-25E699A21DBD
通知源,權限是可通知 -
Control Point: UUID 69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9
控制點,權限是可寫入,可響應 -
Data Source: UUID 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB
數據源,權限是可通知
所有的特性需要認證(NC設備連接上NP並且完成配對和綁定)才能過連接。
對於NC來說,通知源是必須訂閱的,其他兩個是可選擇的。
通知源
NC收到的通知源特性主要有三種事件:
- NP上新通知的到達
- NP上通知的修改
- NP上通知的刪除
當NC訂閱了通知源特性時,這些通知將會立刻被分發。因此NC在訂閱該特性時必須處於有能力接收和處理這些消息的狀態。
經過數據源特性分發的Gatt通知包含一下信息:
- EventID:這個字段指明瞭iOS通知添加、修改或移除三種事件中的一種。該字段的枚舉值可參考後面附錄的EventID Value表。
- EventFlags:一個位掩碼,這個位掩碼錶明瞭這個通知的一種特徵。例如,如果一個通知被認爲是重要的,那麼NC收到這個通知後,就想用明顯的方式提醒用戶。位掩碼的枚舉值在後面的EventFlags表中。
- CategoryID:通知的種類,分爲郵件,來電,未接來電,社交,娛樂等多種分類,短信和微信扣扣等消息全部在社交(social)。
- CategoryCount:給定類型中活躍的通知的數量。例如,郵箱中有兩封未讀的郵件,這個時候又來了一封新的郵件,那麼通知的郵件的數量將是3。
- NotificationUID:該通知的id,一個32位的數字來作爲通知的唯一標示(UID)。獲取更多該通知的信息時,這個數值在將作爲命令中的一個句柄寫入控制點特性(即告訴控制點我想要獲得那條通知的詳細信息)。
控制點和數據源
NC設備可能想要與IOS通知進行交互。它可能需要獲得通知的更多信息,其中包括它的內容以及在此基礎上進行一些操作,這些都要通過控制點和數據源特性來實現。
NC可以通過往控制點特性裏寫入命令來獲取關於通知的更多消息。如果命令寫入成功的話,NP會在數據源特性中通過通知流對該請求進行回覆。
獲取通知具體屬性的命令
獲取通知屬性命令使得NC可以得到某個特定通知的詳細屬性,比如短信的發送人,短信內容,時間等。
該命令包含了一下的信息:
- CommandID: 設爲零 (CommandIDGetNotificationAttributes),0x00
- NotificationUID: 想要獲得的通知的uid,32位數字是通知的唯一標示。
- AttributeIDs:NC想要獲得的屬性列表。有些屬性可能需要後面接一個16位的的參數,0xff 0xff。
byte[] getNotificationAttribute = {
//規定爲0
(byte) 0x00,
//UID,通知的id
uid[0], uid[1], uid[2], uid[3],
//title,Attribute 1,第一條屬性,通知的標題
(byte) 0x01, (byte) 0xff, (byte) 0xff,
//message,第二條屬性,標題的消息
(byte) 0x03, (byte) 0xff, (byte) 0xff
};
該響應包含一下內容:
- CommandID: 設爲0 (CommandIDGetNotificationAttributes)。
- NotificationUID: 32位的UID。
- AttributeList:由屬性ID、16位長度、屬性所組成的一個列表。一個屬性始終是字符串,並且它的長度由16位長度所決定,而不是以空(NULL)結束。如果所請求的屬性是空的,或者是錯過了iOS通知,那麼長度設爲0。
如果響應的長度大於GATT所規定的最大傳輸單元(Maximum Transmission Unit, MTU),則NP會它分成多段傳送。NC必須將響應的數據段重新組包。當收到所有請求屬性的內容時,則表示響應完成。
獲得應用屬性
獲取應用屬性命令允許NC指定獲取NP上某個已安裝的應用程序的屬性。
獲取應用屬性命令包含下面信息:
- CommandID:必須設置爲1(CommandIDGetAppAttributes)。
- AppIdentifier:客戶端想要獲取信息的應用程序的字符串標誌。字符串必須以空(NULL)結束。
- AttributeIDs:想要NC先要獲取的屬性列表。
響應一個獲取應用屬性命令的數據包含下面信息:
- CommandID:設置爲1(CommandIDGetAppAttributes)。
- AppIdentifier:應用的字符串標識。字符串以空(NULL)結束。
- AttributeList:由屬性ID、16位長度、屬性所組成的一個列表。一個屬性始終是字符串,並且它的長度由16位長度所決定,而不是以空(NULL)結束。如果所請求的屬性是空的,或者錯過了應用應用程序,那麼長度設爲0。
如果響應數據的長度大於GATT所規定的最大傳輸單元(Maximum Transmission Unit, MTU),則NP會它分成多端傳送。NC必須將響應的數據段重新組包。當收到所有請求屬性的內容時,則表示響應完成。
**執行通知動作
它允許NC向指定的iOS通知執行一條預定動作。
一條執行通知動作包含下面信息:
- CommandID:必須設置爲2(CommandIDPerformNotificationAction)。
- NotificationUID:32位的數值。其值爲要執行動作的的iOS通知的UID。
- ActionID:NC對指定iOS通知要執行的動作。
當發送這個命令到控制點特徵後,無論發送成功或失敗,數據源特徵上都不會產生數據。也就是說這是一個無需響應的命令。
通知動作
從iOS8開始,NP發送的iOS通知起始可以間接的告訴NC可執行哪些動作。接着,NC就可以針對指定的iOS通知,請求NP執行一個動作。
通知源特徵上生成的GATT通知包含一個叫做Eventflags的數據域,NC根據這個數據域就可得知對一條iOS通知可以執行哪些操作:
- EventFlagPositiveAction:積極動作(Positive Action),與iOS通知相關。
- EventFlagNegativeAction:消極動作(Negative Action),與iOS通知相關。
實際的動作都是由NP執行的,這就表示:NC可執行動作都是由NP所決定的,而且根據iOS通知的不同而不同。舉個例子,當NC收到來電通知時,執行積極動作可以接聽,執行消極動作就拒接,而對於消息(官方是social)類型的通知而言,則只有消極操作,也就是說,在手錶等從設備上面只能查看消息,而無法回覆。
NC不能預先去假設或嘗試猜測一條iOS通知確切的可執行的動作。因爲這些動作都是基於特定通知的,只有NP知道,而對NC無用的;同時還有其它的因素,如ANCS版本的變化等。這樣,NP才能保證積極動作和消極動作的結果都與用戶沒多大關係。
iOS 8系統中,NC通過發送獲取通知屬性命令,可獲取到某條iOS通知可執行動作的簡潔描述:
- NotificationAttributeIDPositiveActionLabel:這條標籤用於描述某條iOS通知可執行的積極動作。
- NotificationAttributeIDNegativeActionLavel:這條標籤用於描述某條iOS通知可執行的消極動作。
三、生命週期
一個ANCS的服務週期開始於NC訂閱NP上的Notification Source characteristic,結束於NC取消該訂閱或者斷開連接。因爲ANCS不是一種完全同步的服務,它沒有追蹤不同週期中的狀態,因此所有的標示以及NC、NP之間的數據交換隻在某一個週期中是有效的。
當一個週期結束後,NC應該刪除其在本週期內採集和存儲的所有的標示以及數據。一個新的週期開始的時候,NP會可能的把所有存在的通知下發給NC。
四、錯誤碼
當往 Control Point characteristic中寫入控制命令時,NC有時會受到ANCS錯誤碼:
Unknown command (0xA0): 命令無法識別.
Invalid command (0xA1): 命令格式錯誤.
Invalid parameter (0xA2): 參數錯誤,例如notification uid並不存在對應的notification對象.
Action failed (0xA3): 動作沒有被執行。
如果NP回覆了一個錯誤碼,那麼Data Source characteristic中將不再產生任何迴應的命令的數據。
五、示例圖
以下兩個圖展示了NP和NC之間的兩種交互的過程的例子。Figure 2-7顯示了NC上想要開啓ANCS的基本流程;Figure 2-8 展示了NC獲得IOS通知更多信息的基本流程。
Figure 2-7 Service setup example
Figure 2-8 Notification attribute retrieval example