1 // Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <stdlib.h>
16 #include <string.h>
17 #include "esp_log.h"
18 #include "ble_ancs.h"
19 
20 #define BLE_ANCS_TAG  "BLE_ANCS"
21 
22 /*
23 | EventID(1 Byte) | EventFlags(1 Byte) | CategoryID(1 Byte) | CategoryCount(1 Byte) | NotificationUID(4 Bytes) |
24 
25 A GATT notification delivered through the Notification Source characteristic contains the following information:
26 * EventID: This field informs the accessory whether the given iOS notification was added, modified, or removed. The enumerated values for this field are defined
27             in EventID Values.
28 * EventFlags: A bitmask whose set bits inform an NC of specificities with the iOS notification. For example, if an iOS notification is considered “important”,
29               the NC may want to display a more aggressive user interface (UI) to make sure the user is properly alerted. The enumerated bits for this field
30               are defined in EventFlags.
31 * CategoryID: A numerical value providing a category in which the iOS notification can be classified. The NP will make a best effort to provide an accurate category
32               for each iOS notification. The enumerated values for this field are defined in CategoryID Values.
33 * CategoryCount: The current number of active iOS notifications in the given category. For example, if two unread emails are sitting in a user’s email inbox, and a new
34                  email is pushed to the user’s iOS device, the value of CategoryCount is 3.
35 * NotificationUID: A 32-bit numerical value that is the unique identifier (UID) for the iOS notification. This value can be used as a handle in commands sent to the
36                    Control Point characteristic to interact with the iOS notification.
37 */
38 
EventID_to_String(uint8_t EventID)39 char *EventID_to_String(uint8_t EventID)
40 {
41     char *str = NULL;
42     switch (EventID)
43     {
44         case EventIDNotificationAdded:
45             str = "New message";
46             break;
47         case EventIDNotificationModified:
48             str = "Modified message";
49             break;
50         case EventIDNotificationRemoved:
51             str = "Removed message";
52             break;
53         default:
54             str = "unknown EventID";
55             break;
56     }
57     return str;
58 }
59 
CategoryID_to_String(uint8_t CategoryID)60 char *CategoryID_to_String(uint8_t CategoryID)
61 {
62     char *Cidstr = NULL;
63     switch(CategoryID) {
64         case CategoryIDOther:
65             Cidstr = "Other";
66             break;
67         case CategoryIDIncomingCall:
68             Cidstr = "IncomingCall";
69             break;
70         case CategoryIDMissedCall:
71             Cidstr = "MissedCall";
72             break;
73         case CategoryIDVoicemail:
74             Cidstr = "Voicemail";
75             break;
76         case CategoryIDSocial:
77             Cidstr = "Social";
78             break;
79         case CategoryIDSchedule:
80             Cidstr = "Schedule";
81             break;
82         case CategoryIDEmail:
83             Cidstr = "Email";
84             break;
85         case CategoryIDNews:
86             Cidstr = "News";
87             break;
88         case CategoryIDHealthAndFitness:
89             Cidstr = "HealthAndFitness";
90             break;
91         case CategoryIDBusinessAndFinance:
92             Cidstr = "BusinessAndFinance";
93             break;
94         case CategoryIDLocation:
95             Cidstr = "Location";
96             break;
97         case CategoryIDEntertainment:
98             Cidstr = "Entertainment";
99             break;
100         default:
101             Cidstr = "Unknown CategoryID";
102             break;
103     }
104     return Cidstr;
105 }
106 
107 /*
108 | EventID(1 Byte) | EventFlags(1 Byte) | CategoryID(1 Byte) | CategoryCount(1 Byte) | NotificationUID(4 Bytes) |
109 */
110 
esp_receive_apple_notification_source(uint8_t * message,uint16_t message_len)111 void esp_receive_apple_notification_source(uint8_t *message, uint16_t message_len)
112 {
113     if (!message || message_len < 5) {
114         return;
115     }
116 
117     uint8_t EventID    = message[0];
118     char    *EventIDS  = EventID_to_String(EventID);
119     uint8_t EventFlags = message[1];
120     uint8_t CategoryID = message[2];
121     char    *Cidstr    = CategoryID_to_String(CategoryID);
122     uint8_t CategoryCount = message[3];
123     uint32_t NotificationUID = (message[4]) | (message[5]<< 8) | (message[6]<< 16) | (message[7] << 24);
124     ESP_LOGI(BLE_ANCS_TAG, "EventID:%s EventFlags:0x%x CategoryID:%s CategoryCount:%d NotificationUID:%d", EventIDS, EventFlags, Cidstr, CategoryCount, NotificationUID);
125 }
126 
esp_receive_apple_data_source(uint8_t * message,uint16_t message_len)127 void esp_receive_apple_data_source(uint8_t *message, uint16_t message_len)
128 {
129     //esp_log_buffer_hex("data source", message, message_len);
130     if (!message || message_len == 0) {
131         return;
132     }
133     uint8_t Command_id = message[0];
134     switch (Command_id)
135     {
136         case CommandIDGetNotificationAttributes: {
137             uint32_t NotificationUID = (message[1]) | (message[2]<< 8) | (message[3]<< 16) | (message[4] << 24);
138             uint32_t remian_attr_len = message_len - 5;
139             uint8_t *attrs = &message[5];
140             ESP_LOGI(BLE_ANCS_TAG, "recevice Notification Attributes response Command_id %d NotificationUID %d", Command_id, NotificationUID);
141             while(remian_attr_len > 0) {
142                 uint8_t AttributeID = attrs[0];
143                 uint16_t len = attrs[1] | (attrs[2] << 8);
144                 if(len > (remian_attr_len -3)) {
145                     ESP_LOGE(BLE_ANCS_TAG, "data error");
146                     break;
147                 }
148                 switch (AttributeID)
149                 {
150                     case NotificationAttributeIDAppIdentifier:
151                         esp_log_buffer_char("Identifier", &attrs[3], len);
152                         break;
153                     case NotificationAttributeIDTitle:
154                         esp_log_buffer_char("Title", &attrs[3], len);
155                         break;
156                     case NotificationAttributeIDSubtitle:
157                         esp_log_buffer_char("Subtitle", &attrs[3], len);
158                         break;
159                     case NotificationAttributeIDMessage:
160                         esp_log_buffer_char("Message", &attrs[3], len);
161                         break;
162                     case NotificationAttributeIDMessageSize:
163                         esp_log_buffer_char("MessageSize", &attrs[3], len);
164                         break;
165                     case NotificationAttributeIDDate:
166                         //yyyyMMdd'T'HHmmSS
167                         esp_log_buffer_char("Date", &attrs[3], len);
168                         break;
169                     case NotificationAttributeIDPositiveActionLabel:
170                         esp_log_buffer_hex("PActionLabel", &attrs[3], len);
171                         break;
172                     case NotificationAttributeIDNegativeActionLabel:
173                         esp_log_buffer_hex("NActionLabel", &attrs[3], len);
174                         break;
175                     default:
176                         esp_log_buffer_hex("unknownAttributeID", &attrs[3], len);
177                         break;
178                 }
179 
180                 attrs += (1 + 2 + len);
181                 remian_attr_len -= (1 + 2 + len);
182             }
183 
184             break;
185         }
186         case CommandIDGetAppAttributes:
187             ESP_LOGI(BLE_ANCS_TAG, "recevice APP Attributes response");
188             break;
189         case CommandIDPerformNotificationAction:
190             ESP_LOGI(BLE_ANCS_TAG, "recevice Perform Notification Action");
191             break;
192         default:
193             ESP_LOGI(BLE_ANCS_TAG, "unknown Command ID");
194             break;
195     }
196 }
197 
Errcode_to_String(uint16_t status)198 char *Errcode_to_String(uint16_t status)
199 {
200     char *Errstr = NULL;
201     switch (status) {
202         case Unknown_command:
203             Errstr = "Unknown_command";
204             break;
205         case Invalid_command:
206             Errstr = "Invalid_command";
207             break;
208         case Invalid_parameter:
209             Errstr = "Invalid_parameter";
210             break;
211         case Action_failed:
212             Errstr = "Action_failed";
213             break;
214         default:
215             Errstr = "unknown_failed";
216             break;
217     }
218     return Errstr;
219 
220 }
221