蘋果通知中心服務ANCS協議分析

蘋果ANCS官網ANCS spec:
https://developer.apple.com/library/content/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Introduction/Introduction.html#//apple_ref/doc/uid/TP40013460-CH2-SW1

此文大部分內容來自官方的翻譯,加上了自己的一些蹩腳的理解。

一、簡介

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章