3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
21 * @brief This file is the source file of implementation of San Parser
31 #include <sync_agent.h>
33 #include "wbxml/wbxml.h"
34 #include "wbxml/wbxml_tree.h"
35 #include "framework/san-parser/pm_sanparser.h"
37 #ifndef OMADS_AGENT_LOG
39 #define LOG_TAG "OMA_DS_COMMON"
42 static san_content_type_s contentTypeSupported[] = {
45 {0x06, "text/x-vcalendar"},
46 {0x07, "text/x-vcard"},
47 {0x0305, "text/calendar"},
48 {0x0306, "application/vnd.omads-email+xml"},
49 {0x0307, "application/vnd.omads-file+xml"},
50 {0x0308, "application/vnd.omads-folder+xml"},
51 {0x0309, "text/vcard"}
54 san_package_s *san_package_12_parser(const char *msg_body, unsigned int msg_size)
58 unsigned int idLength = (uint8_t) msg_body[23];
59 retvm_if(msg_size < (25 + idLength), NULL, "[sanPackage12Parser] SAN package size is smaller than its minimal size specified in the spec, related to [Header] part.");
61 san_package_s *san = (san_package_s *) calloc(1, sizeof(san_package_s));
62 retvm_if(san == NULL, NULL, "[sanPackage12Parser] SAN package memory allocation fail. [Container]");
64 /* MSG BODY WITHOUT DIGEST */
65 san->msg_body_without_digest = (char *)calloc(msg_size - 16, sizeof(char));
66 if (san->msg_body_without_digest == NULL) {
67 _DEBUG_ERROR("[sanPackage12Parser] SAN package memory allocation fail. [Msg body]");
70 memcpy(san->msg_body_without_digest, msg_body + 16, msg_size - 16);
71 san->msg_body_without_digest_length = msg_size - 16;
74 san->digest = (char *)calloc(16, sizeof(char));
75 if (san->digest == NULL) {
76 _DEBUG_ERROR("[sanPackage12Parser] SAN package memory allocation fail. [Digest]");
79 memcpy(san->digest, msg_body, 16);
82 unsigned int version = ((uint8_t) msg_body[16]) << 2;
83 version = version | ((uint8_t) msg_body[17]) >> 6;
86 _DEBUG_ERROR("[sanPackage12Parser] Not supported SAN version %d.", version);
89 san->version = version;
92 san->ui_mode = (((uint8_t) msg_body[17]) & 0x30) >> 4;
95 san->initiator = (((uint8_t) msg_body[17]) & 0x08) >> 3;
98 /*san->sessionID = ((uint8_t)msgBody[21]) << 8;
99 san->sessionID = san->sessionID | (uint8_t)msgBody[22];*/
100 san->session_id = atoi(g_strdup_printf("%02X%02X", msg_body[21], msg_body[22]));
101 _DEBUG_INFO("session id : %d \n", san->session_id);
105 san->server_id = (char *)calloc(idLength + 1, sizeof(char));
106 if (san->server_id == NULL) {
107 _DEBUG_ERROR("[sanPackage12Parser] SAN package memory allocation fail. [Server ID]");
110 memcpy(san->server_id, msg_body + 24, idLength);
113 san->cnt_sync_alerts = ((uint8_t) msg_body[24 + idLength]) >> 4;
115 if (san->cnt_sync_alerts == 0) {
116 if (msg_size > 24 + idLength + 1) {
117 _DEBUG_INFO("[sanPackage12Parser] There are remaining bytes at the end of the package. (w/o alerts info)");
120 /* If number of sync alerts equals 0, should sync all data store in the client */
125 san->sync_alerts = (san_sync_alert_s *) calloc(san->cnt_sync_alerts, sizeof(san_sync_alert_s));
126 if (san->sync_alerts == NULL) {
127 _DEBUG_ERROR("[sanPackage12Parser] SAN package memory allocation fail. [syncAlerts]");
131 msg_body += 25 + idLength;
132 unsigned int alertLength = 25 + idLength;
135 for (i = 0; i < san->cnt_sync_alerts; i++) {
137 idLength = (uint8_t) msg_body[4];
138 if (msg_size < (alertLength + 5 + idLength)) {
139 _DEBUG_ERROR("[sanPackage12Parser] SAN package size is smaller than");
140 _DEBUG_ERROR("[sanPackage12Parser] its minimal size specified in the spec, related to [Alerts] part.");
143 alertLength = alertLength + 5 + idLength;
146 san_sync_type_e alert_type = (((uint8_t) msg_body[0]) >> 4) + 200;
147 if (alert_type < 206 || alert_type > 210) {
148 _DEBUG_ERROR("[sanPackage12Parser] SAN doesn't support the sync type %d.", alert_type);
152 unsigned int contentType = ((uint8_t) msg_body[1]) << 16;
153 contentType = contentType | ((uint8_t) msg_body[2]) << 8;
154 contentType = contentType | ((uint8_t) msg_body[3]);
157 char *alert_ct = NULL;
160 int cnt = (int)sizeof(contentTypeSupported) / sizeof(san_content_type_s);
161 bool isContentSupported = false;
163 for (j = 0; j < cnt; j++) {
164 if (contentType == contentTypeSupported[j].type) {
165 alert_ct = contentTypeSupported[j].strType;
166 isContentSupported = true;
171 if (!isContentSupported) {
172 _DEBUG_ERROR("[sanPackage12Parser] SAN doesn't support the content type %d.", contentType);
177 char *alert_uri = NULL;
180 alert_uri = (char *)calloc(idLength + 1, sizeof(char));
181 if (alert_uri == NULL) {
182 _DEBUG_ERROR("[sanPackage12Parser] SAN package memory allocation fail. [Server URI]");
185 memcpy(alert_uri, msg_body + 5, idLength);
187 msg_body += 5 + idLength;
189 san->sync_alerts[i].sync_type = alert_type;
190 san->sync_alerts[i].content_type = alert_ct;
191 san->sync_alerts[i].server_uri = alert_uri;
195 if (msg_size > alertLength) {
196 _DEBUG_INFO("[sanPackage12Parser] There are remaining bytes at the end of the package. (with alerts info)");
204 sanPackageParserFree(san);
211 san_package_s *san_package_11_parser(const char *msg_body, unsigned int msg_size)
215 san_package_s *san = (san_package_s *) calloc(1, sizeof(san_package_s));
217 _DEBUG_ERROR("[sanPackage11Parser] SAN package memory allocation fail. [Container]");
223 WBXMLTree *wbxml_tree = NULL;
224 WBXMLError wbxml_err = wbxml_tree_from_wbxml((unsigned char *)msg_body, msg_size, WBXML_LANG_UNKNOWN, WBXML_CHARSET_UNKNOWN, &wbxml_tree);
226 if (wbxml_err != WBXML_OK) {
227 _DEBUG_ERROR("[sanPackage11Parser] Libwbxml2 failed to parse WBXML STREAM to WBXML TREE, error code : %s", wbxml_errors_string(wbxml_err));
231 WBXMLTreeNode *synchdr_node;
232 if ((synchdr_node = wbxml_tree_node_elt_get_from_name(wbxml_tree->root, "SyncHdr", TRUE)) == NULL) {
233 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [SyncHdr]");
236 WBXMLTreeNode *child_node = NULL;
237 const char *child_node_name = NULL;
239 for (child_node = synchdr_node->children; child_node != NULL; child_node = child_node->next) {
240 child_node_name = (const char *)wbxml_tag_get_xml_name(child_node->name);
242 if ((strcmp(child_node_name, "VerDTD") == 0) || (strcmp(child_node_name, "VerProto") == 0)) {
243 char *version = NULL;
244 if (child_node->children != NULL && child_node->children->type == WBXML_TREE_TEXT_NODE && child_node->children->content != NULL) {
246 version = (char *)wbxml_buffer_get_cstr(child_node->children->content);
248 if (strcmp(version, "1.1") && strcmp(version, "SyncML/1.1")) {
249 _DEBUG_ERROR("[sanPackage11Parser] Not supported SAN version %s.", version);
254 } else if (strcmp(child_node_name, "SessionID") == 0) {
255 char *sessionID = NULL;
256 if (child_node->children != NULL && child_node->children->type == WBXML_TREE_TEXT_NODE && child_node->children->content != NULL) {
258 sessionID = (char *)wbxml_buffer_get_cstr(child_node->children->content);
260 if (sessionID == NULL) {
261 _DEBUG_ERROR("[sanPackage11Parser] NULL sessionID detected. sessionID MUST NOT be NULL.");
264 san->session_id = atoi(sessionID);
266 } else if (strcmp(child_node_name, "Source") == 0) {
267 char *serverID = NULL;
268 unsigned serverIDlen = 0;
269 WBXMLTreeNode *serverid_node;
270 if ((serverid_node = wbxml_tree_node_elt_get_from_name(child_node, "LocURI", TRUE)) == NULL) {
271 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [LocURI]");
275 if (serverid_node->children != NULL && serverid_node->children->type == WBXML_TREE_TEXT_NODE && serverid_node->children->content != NULL) {
277 serverID = (char *)wbxml_buffer_get_cstr(serverid_node->children->content);
278 serverIDlen = wbxml_buffer_len(serverid_node->children->content);
279 if (serverID == NULL) {
280 _DEBUG_ERROR("[sanPackage11Parser] NULL serverID detected. serverID MUST NOT be NULL.");
284 san->server_id = (char *)calloc(serverIDlen, sizeof(char));
285 if (san->server_id == NULL) {
286 _DEBUG_ERROR("[sanPackage11Parser] SAN package memory allocation fail. [Server ID]");
289 memcpy(san->server_id, serverID, serverIDlen);
291 } else if (strcmp(child_node_name, "Cred") == 0) {
293 san->cred = (san_cred_s *) calloc(1, sizeof(san_cred_s));
294 if (san->cred == NULL) {
295 _DEBUG_ERROR("[sanPackage11Parser] SAN package memory allocation fail. [cred]");
299 char *credFormat = NULL;
300 unsigned credFormatLen = 0;
301 WBXMLTreeNode *credformat_node;
302 if ((credformat_node = wbxml_tree_node_elt_get_from_name(child_node, "Format", TRUE)) == NULL) {
303 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [Format]");
307 if (credformat_node->children != NULL && credformat_node->children->type == WBXML_TREE_TEXT_NODE && credformat_node->children->content != NULL) {
309 credFormat = (char *)wbxml_buffer_get_cstr(credformat_node->children->content);
310 credFormatLen = wbxml_buffer_len(credformat_node->children->content);
311 if (credFormat == NULL) {
312 _DEBUG_ERROR("[sanPackage11Parser] NULL credFormat detected. credFormat MUST NOT be NULL.");
316 san->cred->cred_format = (char *)calloc(credFormatLen, sizeof(char));
317 if (san->cred->cred_format == NULL) {
318 _DEBUG_ERROR("[sanPackage11Parser] SAN package memory allocation fail. [credFormat]");
321 memcpy(san->cred->cred_format, credFormat, credFormatLen);
324 char *credAuth = NULL;
325 unsigned credAuthLen = 0;
326 WBXMLTreeNode *credauth_node;
327 if ((credauth_node = wbxml_tree_node_elt_get_from_name(child_node, "Type", TRUE)) == NULL) {
328 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [Type]");
332 if (credauth_node->children != NULL && credauth_node->children->type == WBXML_TREE_TEXT_NODE && credauth_node->children->content != NULL) {
334 credAuth = (char *)wbxml_buffer_get_cstr(credauth_node->children->content);
335 credAuthLen = wbxml_buffer_len(credauth_node->children->content);
336 if (credAuth == NULL) {
337 _DEBUG_ERROR("[sanPackage11Parser] NULL credAuth detected. credAuth MUST NOT be NULL.");
341 san->cred->cred_auth = (char *)calloc(credAuthLen, sizeof(char));
342 if (san->cred->cred_auth == NULL) {
343 _DEBUG_ERROR("[sanPackage11Parser] SAN package memory allocation fail. [credAuth]");
346 memcpy(san->cred->cred_auth, credAuth, credAuthLen);
349 char *credData = NULL;
350 unsigned credDataLen = 0;
351 WBXMLTreeNode *creddata_node;
352 if ((creddata_node = wbxml_tree_node_elt_get_from_name(child_node, "Data", TRUE)) == NULL) {
353 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [Data]");
357 if (creddata_node->children != NULL && creddata_node->children->type == WBXML_TREE_TEXT_NODE && creddata_node->children->content != NULL) {
359 credData = (char *)wbxml_buffer_get_cstr(creddata_node->children->content);
360 credDataLen = wbxml_buffer_len(creddata_node->children->content);
361 if (credData == NULL) {
362 _DEBUG_ERROR("[sanPackage11Parser] NULL credData detected. credData MUST NOT be NULL.");
366 san->cred->cred_data = (char *)calloc(credDataLen, sizeof(char));
367 if (san->cred->cred_data == NULL) {
368 _DEBUG_ERROR("[sanPackage11Parser] SAN package memory allocation fail. [credData]");
371 memcpy(san->cred->cred_data, credData, credDataLen);
378 WBXMLTreeNode *syncbody_node;
379 if ((syncbody_node = wbxml_tree_node_elt_get_from_name(wbxml_tree->root, "SyncBody", TRUE)) == NULL) {
380 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [SyncBody]");
384 WBXMLList *alertnode_list = wbxml_tree_node_get_all_children(syncbody_node);
385 unsigned int alertnode_list_len = wbxml_list_len(alertnode_list);
387 child_node = (WBXMLTreeNode *) wbxml_list_get(alertnode_list, alertnode_list_len - 1);
388 child_node_name = (const char *)wbxml_tag_get_xml_name(child_node->name);
389 if (strcmp(child_node_name, "Final") == 0)
390 san->cnt_sync_alerts = alertnode_list_len - 1;
392 if (san->cnt_sync_alerts == 0) {
393 /* If number of sync alerts equals 0, should sync all data store in the client */
396 san->sync_alerts = (san_sync_alert_s *) calloc(san->cnt_sync_alerts, sizeof(san_sync_alert_s));
397 if (san->sync_alerts == NULL) {
398 _DEBUG_ERROR("[sanPackage11Parser] SAN package memory allocation fail. [syncAlerts]");
402 unsigned int indexNode;
403 for (indexNode = 0; indexNode < san->cnt_sync_alerts; indexNode++) {
405 WBXMLTreeNode *alert_node = (WBXMLTreeNode *) wbxml_list_get(alertnode_list, indexNode);
407 char *alertData = NULL;
408 WBXMLTreeNode *alertdata_node;
409 if ((alertdata_node = wbxml_tree_node_elt_get_from_name(alert_node, "Data", TRUE)) == NULL) {
410 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [Data]");
414 if (alertdata_node->children != NULL && alertdata_node->children->type == WBXML_TREE_TEXT_NODE && alertdata_node->children->content != NULL) {
416 alertData = (char *)wbxml_buffer_get_cstr(alertdata_node->children->content);
417 if (alertData == NULL) {
418 _DEBUG_ERROR("[sanPackage11Parser] NULL alertData detected. alertData MUST NOT be NULL.");
422 if (atoi(alertData) < 206 || atoi(alertData) > 210) {
423 _DEBUG_ERROR("[sanPackage11Parser] SAN doesn't support the sync type %d.", atoi(alertData));
427 san->sync_alerts[indexNode].sync_type = atoi(alertData);
430 char *alertURI = NULL;
431 unsigned alertURIlen = 0;
432 WBXMLTreeNode *alerturi_node;
433 if ((alerturi_node = wbxml_tree_node_elt_get_from_name(alert_node, "LocURI", TRUE)) == NULL) {
434 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [LocURI]");
438 if (alerturi_node->children != NULL && alerturi_node->children->type == WBXML_TREE_TEXT_NODE && alerturi_node->children->content != NULL) {
440 alertURI = (char *)wbxml_buffer_get_cstr(alerturi_node->children->content);
441 alertURIlen = wbxml_buffer_len(alerturi_node->children->content);
442 if (alertURI == NULL) {
443 _DEBUG_ERROR("[sanPackage11Parser] NULL alertURI detected. alertURI MUST NOT be NULL.");
447 san->sync_alerts[indexNode].server_uri = (char *)calloc(alertURIlen, sizeof(char));
448 if (san->sync_alerts[indexNode].server_uri == NULL) {
449 _DEBUG_ERROR("[sanPackage11Parser] SAN package memory allocation fail. [serverURI]");
452 memcpy(san->sync_alerts[indexNode].server_uri, alertURI, alertURIlen);
455 char *alertContentType = NULL;
456 unsigned alertContentTypeLen = 0;
457 WBXMLTreeNode *alertcontenttype_node;
458 if ((alertcontenttype_node = wbxml_tree_node_elt_get_from_name(alert_node, "Type", TRUE)) == NULL) {
459 _DEBUG_ERROR("[sanPackage11Parser] NULL from wbxml_tree_node_elt_get_from_name. [Type]");
463 if (alertcontenttype_node->children != NULL && alertcontenttype_node->children->type == WBXML_TREE_TEXT_NODE && alertcontenttype_node->children->content != NULL) {
465 alertContentType = (char *)wbxml_buffer_get_cstr(alertcontenttype_node->children->content);
466 alertContentTypeLen = wbxml_buffer_len(alertcontenttype_node->children->content);
468 if (alertContentType == NULL) {
469 _DEBUG_ERROR("[sanPackage11Parser] NULL alertContentType detected. alertContentType MUST NOT be NULL.");
474 int cnt = (int)sizeof(contentTypeSupported) / sizeof(san_content_type_s);
475 bool isContentSupported = false;
477 for (j = 0; j < cnt; j++) {
478 if (contentTypeSupported[j].strType == NULL)
480 if (strcmp(alertContentType, contentTypeSupported[j].strType) == 0) {
481 san->sync_alerts[indexNode].content_type = contentTypeSupported[j].strType;
482 isContentSupported = true;
487 if (!isContentSupported) {
488 _DEBUG_ERROR("[sanPackage11Parser] SAN doesn't support the content type %s.", alertContentType);
495 wbxml_tree_destroy(wbxml_tree);
502 sanPackageParserFree(san);
509 void sanPackageParserFree(void *point)
513 san_package_s *san = (san_package_s *) point;
515 if (san->msg_body_without_digest != NULL)
516 free(san->msg_body_without_digest);
517 if (san->digest != NULL)
519 if (san->cred != NULL) {
520 if (san->cred->cred_format != NULL)
521 free(san->cred->cred_format);
522 if (san->cred->cred_auth != NULL)
523 free(san->cred->cred_auth);
524 if (san->cred->cred_data != NULL)
525 free(san->cred->cred_data);
528 if (san->server_id != NULL)
529 free(san->server_id);
530 if (san->sync_alerts != NULL) {
532 for (i = 0; i < san->cnt_sync_alerts; i++) {
533 if (san->sync_alerts[i].server_uri != NULL) {
534 free(san->sync_alerts[i].server_uri);
537 free(san->sync_alerts);
545 void sanPrintMsg(san_package_s * san)
551 _DEBUG_INFO("Printing SAN package ============================\n\n");
553 _DEBUG_INFO("MsgBody without Digest :\n\t");
554 for (i = 0; i < san->msg_body_without_digest_length; i++) {
555 _DEBUG_INFO("%02x ", san->msg_body_without_digest[i]);
556 if ((i + 1) % 16 == 0)
561 _DEBUG_INFO("Digest : %s\n", san->digest);
562 if (san->cred != NULL) {
563 if (san->cred->cred_format != NULL)
564 _DEBUG_INFO("Cred Format : %s\n", san->cred->cred_format);
565 if (san->cred->cred_auth != NULL)
566 _DEBUG_INFO("Cred Type : %s\n", san->cred->cred_auth);
567 if (san->cred->cred_data != NULL)
568 _DEBUG_INFO("Cred Data : %s\n", san->cred->cred_data);
570 _DEBUG_INFO("Version : %d\n", san->version);
571 _DEBUG_INFO("UI mode : %d\n", san->ui_mode);
572 _DEBUG_INFO("Initiator : %d\n", san->initiator);
573 _DEBUG_INFO("Session ID : %u\n", san->session_id);
574 _DEBUG_INFO("Server ID : %s\n", san->server_id);
575 _DEBUG_INFO("No. of Sync : %u\n", san->cnt_sync_alerts);
577 for (i = 0; i < san->cnt_sync_alerts; i++) {
578 _DEBUG_INFO("\n\t=== Sync No. %d ============\n", i + 1);
579 _DEBUG_INFO("\tSync type : %d\n", san->sync_alerts[i].sync_type);
580 _DEBUG_INFO("\tContent type : %s\n", san->sync_alerts[i].content_type);
581 _DEBUG_INFO("\tServer URI : %s\n", san->sync_alerts[i].server_uri);
587 int parse_ip_push_msg(char *data, san_package_s ** san_package, char **id)
591 retvm_if(data == NULL, 0, "data is NULL");
595 char *decoded_body = NULL;
596 unsigned int decoded_size;
598 *id = strtok(data, "|");
599 pay = strtok(NULL, "|");
600 body = strtok(NULL, "|");
602 _DEBUG_INFO("id = %s", *id);
603 _DEBUG_INFO("pay = %s", pay);
604 _DEBUG_INFO("after = %s", body);
606 decoded_body = (char *)g_base64_decode(body, &decoded_size);
608 _DEBUG_INFO("decoded_body = %s", decoded_body);
609 _DEBUG_INFO("decoded_size = %d", decoded_size);
611 *san_package = san_package_12_parser(decoded_body, decoded_size);
613 if ((*san_package) != NULL) {
614 _DEBUG_INFO("serverId = %s", (*san_package)->server_id);
615 _DEBUG_INFO("sessionID = %d", (*san_package)->session_id);
616 _DEBUG_INFO("cntSyncAlerts = %d", (*san_package)->cnt_sync_alerts);
618 for (i = 0; i < (*san_package)->cnt_sync_alerts; i++) {
619 _DEBUG_INFO("syncAlerts = %d", (*san_package)->sync_alerts[i].sync_type);
622 _DEBUG_ERROR("pSanPackage is NULL");