4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JuHak Park <juhaki.park@samsung.com>,
7 * JuneHyuk Lee <junhyuk7.lee@samsung.com>,
8 * SunBong Ha <sunbong.ha@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
28 * For any sort of issue you concern as to this software,
\r
29 * you may use following point of contact.
\r
30 * All resources contributed on this software
\r
31 * are orinigally written by S-Core Inc., a member of Samsung Group.
\r
33 * SeongWon Shim <seongwon.shim@samsung.com>
\r
39 * @brief This file is the source file of implementation of San Parser
\r
44 #include <stdbool.h>
\r
46 #include <inttypes.h>
\r
48 #include "wbxml/wbxml.h"
\r
49 #include "wbxml/wbxml_tree.h"
\r
51 #include "Framework/SAN_parser/PM_SanParser.h"
\r
52 #include "agent-framework/Utility/fw_log.h"
\r
54 #define LOG_TAG "OMA_DS_COMMON"
\r
56 static SanContentType contentTypeSupported[] = {
\r
58 {0x03, "text/plain"},
\r
59 {0x06, "text/x-vcalendar"},
\r
60 {0x07, "text/x-vcard"},
\r
61 {0x0305, "text/calendar"},
\r
62 {0x0306, "application/vnd.omads-email+xml"},
\r
63 {0x0307, "application/vnd.omads-file+xml"},
\r
64 {0x0308, "application/vnd.omads-folder+xml"},
\r
65 {0x0309, "text/vcard"}
\r
68 SanPackage *sanPackage12Parser(const char *msgBody, unsigned int msgSize)
\r
70 unsigned int idLength = (uint8_t)msgBody[23];
\r
71 if (msgSize < (25 + idLength)) {
\r
72 FW_LOGV("[sanPackage12Parser] SAN package size is smaller than");
\r
73 FW_LOGV("[sanPackage12Parser] its minimal size specified in the spec, related to [Header] part.");
\r
77 SanPackage *san = (SanPackage *)calloc(1, sizeof(SanPackage));
\r
79 FW_LOGV("[sanPackage12Parser] SAN package memory allocation fail. [Container]");
\r
83 /* MSG BODY WITHOUT DIGEST*/
\r
84 san->msgBodyWithoutDigest = (char *)calloc(msgSize - 16, sizeof(char));
\r
85 if (!san->msgBodyWithoutDigest) {
\r
86 FW_LOGV("[sanPackage12Parser] SAN package memory allocation fail. [Msg body]");
\r
89 memcpy(san->msgBodyWithoutDigest, msgBody + 16, msgSize - 16);
\r
90 san->msgBodyWithoutDigestLength = msgSize - 16;
\r
93 san->digest = (char *)calloc(16, sizeof(char));
\r
95 FW_LOGV("[sanPackage12Parser] SAN package memory allocation fail. [Digest]");
\r
98 memcpy(san->digest, msgBody, 16);
\r
101 unsigned int version = ((uint8_t)msgBody[16]) << 2;
\r
102 version = version | ((uint8_t)msgBody[17]) >> 6;
\r
104 if (version != 12) {
\r
105 FW_LOGV("[sanPackage12Parser] Not supported SAN version %d.", version);
\r
108 san->version = version;
\r
111 san->uiMode = (((uint8_t)msgBody[17]) & 0x30) >> 4;
\r
114 san->initiator = (((uint8_t)msgBody[17]) & 0x08) >> 3;
\r
117 /*san->sessionID = ((uint8_t)msgBody[21]) << 8;
\r
118 san->sessionID = san->sessionID | (uint8_t)msgBody[22];*/
\r
119 san->sessionID = atoi(g_strdup_printf("%02X%02X", msgBody[21], msgBody[22]));
\r
120 FW_LOGV("session id : %d \n", san->sessionID);
\r
124 san->serverID = (char *)calloc(idLength + 1, sizeof(char));
\r
125 if (!san->serverID) {
\r
126 FW_LOGV("[sanPackage12Parser] SAN package memory allocation fail. [Server ID]");
\r
129 memcpy(san->serverID, msgBody + 24, idLength);
\r
132 san->cntSyncAlerts = ((uint8_t)msgBody[24 + idLength]) >> 4;
\r
134 if (san->cntSyncAlerts == 0) {
\r
135 if (msgSize > 24 + idLength + 1) {
\r
136 FW_LOGV("[sanPackage12Parser] There are remaining bytes at the end of the package. (w/o alerts info)");
\r
139 /* If number of sync alerts equals 0, should sync all data store in the client*/
\r
143 san->syncAlerts = (SanSyncAlert *)calloc(san->cntSyncAlerts, sizeof(SanSyncAlert));
\r
145 msgBody += 25 + idLength;
\r
146 unsigned int alertLength = 25 + idLength;
\r
149 for (i = 0; i < san->cntSyncAlerts; i++) {
\r
151 idLength = (uint8_t)msgBody[4];
\r
152 if (msgSize < (alertLength + 5 + idLength)) {
\r
153 FW_LOGV("[sanPackage12Parser] SAN package size is smaller than");
\r
154 FW_LOGV("[sanPackage12Parser] its minimal size specified in the spec, related to [Alerts] part.");
\r
157 alertLength = alertLength + 5 + idLength;
\r
160 SanSyncType alert_type = (((uint8_t)msgBody[0]) >> 4) + 200;
\r
161 if (alert_type < 206 || alert_type > 210) {
\r
162 FW_LOGV("[sanPackage12Parser] SAN doesn't support the sync type %d.", alert_type);
\r
166 unsigned int contentType = ((uint8_t)msgBody[1]) << 16;
\r
167 contentType = contentType | ((uint8_t)msgBody[2]) << 8;
\r
168 contentType = contentType | ((uint8_t)msgBody[3]);
\r
171 char *alert_ct = NULL;
\r
174 int cnt = (int)sizeof(contentTypeSupported)/sizeof(SanContentType);
\r
175 bool isContentSupported = false;
\r
177 for (j = 0 ; j < cnt ; j++) {
\r
178 if (contentType == contentTypeSupported[j].type) {
\r
179 alert_ct = contentTypeSupported[j].strType;
\r
180 isContentSupported = true;
\r
185 if (!isContentSupported) {
\r
186 FW_LOGV("[sanPackage12Parser] SAN doesn't support the content type %d.", contentType);
\r
191 char *alert_uri = NULL;
\r
194 alert_uri = (char *)calloc(idLength + 1, sizeof(char));
\r
196 FW_LOGV("[sanPackage12Parser] SAN package memory allocation fail. [Server URI]");
\r
199 memcpy(alert_uri, msgBody + 5, idLength);
\r
201 msgBody += 5 + idLength;
\r
203 san->syncAlerts[i].syncType = alert_type;
\r
204 san->syncAlerts[i].contentType = alert_ct;
\r
205 san->syncAlerts[i].serverURI = alert_uri;
\r
209 if (msgSize > alertLength) {
\r
210 FW_LOGV("[sanPackage12Parser] There are remaining bytes at the end of the package. (with alerts info)");
\r
216 sanPackageParserFree(san);
\r
221 WBXMLTreeNode *__get_node_elt_from_name(WBXMLTreeNode *node, const char *name, WB_BOOL recurs)
\r
223 WBXMLTreeNode *current_node = NULL;
\r
224 WBXMLTreeNode *recurs_node = NULL;
\r
226 if ((node == NULL) || (name == NULL))
\r
229 /* Let's go through the tree */
\r
230 current_node = node;
\r
232 while (current_node != NULL) {
\r
233 /* Is this a normal node? */
\r
234 if (current_node->type == WBXML_TREE_ELEMENT_NODE) {
\r
235 /* Is this the Node we searched ? */
\r
236 if (WBXML_STRCMP(wbxml_tag_get_xml_name(current_node->name), name) == 0) {
\r
237 return current_node;
\r
240 /* Sould we start a recursive search? */
\r
241 if (recurs && current_node->children) {
\r
242 recurs_node = __get_node_elt_from_name(current_node->children, name, TRUE);
\r
243 /* Is this the Node we searched ? */
\r
245 return recurs_node;
\r
250 /* Go to next Sibbling Node */
\r
251 current_node = current_node->next;
\r
254 /* A node with the specified name could not be found. */
\r
258 SanPackage *sanPackage11Parser(const char *msgBody, unsigned int msgSize)
\r
260 SanPackage *san = (SanPackage *)calloc(1, sizeof(SanPackage));
\r
262 FW_LOGV("[sanPackage11Parser] SAN package memory allocation fail. [Container]");
\r
266 WBXMLTree *wbxml_tree = NULL;
\r
267 WBXMLError wbxml_err = wbxml_tree_from_wbxml((unsigned char *)msgBody, msgSize, WBXML_LANG_UNKNOWN, WBXML_CHARSET_UNKNOWN, &wbxml_tree);
\r
269 if (wbxml_err != WBXML_OK) {
\r
270 FW_LOGV("[sanPackage11Parser] Libwbxml2 failed to parse WBXML STREAM to WBXML TREE, error code : %s", wbxml_errors_string(wbxml_err));
\r
274 WBXMLTreeNode *synchdr_node;
\r
275 if ((synchdr_node = __get_node_elt_from_name(wbxml_tree->root, "SyncHdr", TRUE)) == NULL) {
\r
276 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [SyncHdr]");
\r
279 WBXMLTreeNode *child_node = NULL;
\r
280 const char *child_node_name = NULL;
\r
282 for (child_node = synchdr_node->children ; child_node != NULL ; child_node = child_node->next) {
\r
283 child_node_name = (const char *)wbxml_tag_get_xml_name(child_node->name);
\r
285 if ((strcmp(child_node_name, "VerDTD") == 0) || (strcmp(child_node_name, "VerProto") == 0)) {
\r
286 char *version = NULL;
\r
287 if (child_node->children != NULL &&
\r
288 child_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
289 child_node->children->content != NULL) {
\r
291 version = (char *)wbxml_buffer_get_cstr(child_node->children->content);
\r
293 if (strcmp(version, "1.1") && strcmp(version, "SyncML/1.1")) {
\r
294 FW_LOGV("[sanPackage11Parser] Not supported SAN version %s.", version);
\r
299 } else if (strcmp(child_node_name, "SessionID") == 0) {
\r
300 char *sessionID = NULL;
\r
301 if (child_node->children != NULL &&
\r
302 child_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
303 child_node->children->content != NULL) {
\r
305 sessionID = (char *)wbxml_buffer_get_cstr(child_node->children->content);
\r
308 FW_LOGV("[sanPackage11Parser] NULL sessionID detected. sessionID MUST NOT be NULL.");
\r
311 san->sessionID = atoi(sessionID);
\r
313 } else if (strcmp(child_node_name, "Source") == 0) {
\r
314 char *serverID = NULL;
\r
315 unsigned serverIDlen = 0;
\r
316 WBXMLTreeNode *serverid_node;
\r
317 if ((serverid_node = __get_node_elt_from_name(child_node, "LocURI", TRUE)) == NULL) {
\r
318 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [LocURI]");
\r
322 if (serverid_node->children != NULL &&
\r
323 serverid_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
324 serverid_node->children->content != NULL) {
\r
326 serverID = (char *)wbxml_buffer_get_cstr(serverid_node->children->content);
\r
327 serverIDlen = wbxml_buffer_len(serverid_node->children->content);
\r
329 FW_LOGV("[sanPackage11Parser] NULL serverID detected. serverID MUST NOT be NULL.");
\r
333 san->serverID = (char *)calloc(serverIDlen, sizeof(char));
\r
334 if (!san->serverID) {
\r
335 FW_LOGV("[sanPackage11Parser] SAN package memory allocation fail. [Server ID]");
\r
338 memcpy(san->serverID, serverID, serverIDlen);
\r
340 } else if (strcmp(child_node_name, "Cred") == 0) {
\r
342 san->cred = (SanCred *)calloc(1, sizeof(SanCred));
\r
344 char *credFormat = NULL;
\r
345 unsigned credFormatLen = 0;
\r
346 WBXMLTreeNode *credformat_node;
\r
347 if ((credformat_node = __get_node_elt_from_name(child_node, "Format", TRUE)) == NULL) {
\r
348 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [Format]");
\r
352 if (credformat_node->children != NULL &&
\r
353 credformat_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
354 credformat_node->children->content != NULL) {
\r
356 credFormat = (char *)wbxml_buffer_get_cstr(credformat_node->children->content);
\r
357 credFormatLen = wbxml_buffer_len(credformat_node->children->content);
\r
359 FW_LOGV("[sanPackage11Parser] NULL credFormat detected. credFormat MUST NOT be NULL.");
\r
363 san->cred->credFormat = (char *)calloc(credFormatLen, sizeof(char));
\r
364 if (!san->cred->credFormat) {
\r
365 FW_LOGV("[sanPackage11Parser] SAN package memory allocation fail. [credFormat]");
\r
368 memcpy(san->cred->credFormat, credFormat, credFormatLen);
\r
371 char *credAuth = NULL;
\r
372 unsigned credAuthLen = 0;
\r
373 WBXMLTreeNode *credauth_node;
\r
374 if ((credauth_node = __get_node_elt_from_name(child_node, "Type", TRUE)) == NULL) {
\r
375 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [Type]");
\r
379 if (credauth_node->children != NULL &&
\r
380 credauth_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
381 credauth_node->children->content != NULL) {
\r
383 credAuth = (char *)wbxml_buffer_get_cstr(credauth_node->children->content);
\r
384 credAuthLen = wbxml_buffer_len(credauth_node->children->content);
\r
386 FW_LOGV("[sanPackage11Parser] NULL credAuth detected. credAuth MUST NOT be NULL.");
\r
390 san->cred->credAuth = (char *)calloc(credAuthLen, sizeof(char));
\r
391 if (!san->cred->credAuth) {
\r
392 FW_LOGV("[sanPackage11Parser] SAN package memory allocation fail. [credAuth]");
\r
395 memcpy(san->cred->credAuth, credAuth, credAuthLen);
\r
398 char *credData = NULL;
\r
399 unsigned credDataLen = 0;
\r
400 WBXMLTreeNode *creddata_node;
\r
401 if ((creddata_node = __get_node_elt_from_name(child_node, "Data", TRUE)) == NULL) {
\r
402 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [Data]");
\r
406 if (creddata_node->children != NULL &&
\r
407 creddata_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
408 creddata_node->children->content != NULL) {
\r
410 credData = (char *)wbxml_buffer_get_cstr(creddata_node->children->content);
\r
411 credDataLen = wbxml_buffer_len(creddata_node->children->content);
\r
413 FW_LOGV("[sanPackage11Parser] NULL credData detected. credData MUST NOT be NULL.");
\r
417 san->cred->credData = (char *)calloc(credDataLen, sizeof(char));
\r
418 if (!san->cred->credData) {
\r
419 FW_LOGV("[sanPackage11Parser] SAN package memory allocation fail. [credData]");
\r
422 memcpy(san->cred->credData, credData, credDataLen);
\r
429 WBXMLTreeNode *syncbody_node;
\r
430 if ((syncbody_node = __get_node_elt_from_name(wbxml_tree->root, "SyncBody", TRUE)) == NULL) {
\r
431 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [SyncBody]");
\r
435 WBXMLList *alertnode_list = wbxml_tree_node_get_all_children(syncbody_node);
\r
436 unsigned int alertnode_list_len = wbxml_list_len(alertnode_list);
\r
438 child_node = (WBXMLTreeNode *)wbxml_list_get(alertnode_list, alertnode_list_len - 1);
\r
439 child_node_name = (const char *)wbxml_tag_get_xml_name(child_node->name);
\r
440 if (strcmp(child_node_name, "Final") == 0)
\r
441 san->cntSyncAlerts = alertnode_list_len - 1;
\r
443 if (san->cntSyncAlerts == 0) {
\r
444 /* If number of sync alerts equals 0, should sync all data store in the client*/
\r
447 san->syncAlerts = (SanSyncAlert *)calloc(san->cntSyncAlerts, sizeof(SanSyncAlert));
\r
449 unsigned int indexNode;
\r
450 for (indexNode = 0; indexNode < san->cntSyncAlerts; indexNode++) {
\r
452 WBXMLTreeNode* alert_node = (WBXMLTreeNode *)wbxml_list_get(alertnode_list, indexNode);
\r
454 char *alertData = NULL;
\r
455 WBXMLTreeNode *alertdata_node;
\r
456 if ((alertdata_node = __get_node_elt_from_name(alert_node, "Data", TRUE)) == NULL) {
\r
457 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [Data]");
\r
461 if (alertdata_node->children != NULL &&
\r
462 alertdata_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
463 alertdata_node->children->content != NULL) {
\r
465 alertData = (char *)wbxml_buffer_get_cstr(alertdata_node->children->content);
\r
467 FW_LOGV("[sanPackage11Parser] NULL alertData detected. alertData MUST NOT be NULL.");
\r
471 if (atoi(alertData) < 206 || atoi(alertData) > 210) {
\r
472 FW_LOGV("[sanPackage11Parser] SAN doesn't support the sync type %d.", atoi(alertData));
\r
476 san->syncAlerts[indexNode].syncType = atoi(alertData);
\r
479 char *alertURI = NULL;
\r
480 unsigned alertURIlen = 0;
\r
481 WBXMLTreeNode *alerturi_node;
\r
482 if ((alerturi_node = __get_node_elt_from_name(alert_node, "LocURI", TRUE)) == NULL) {
\r
483 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [LocURI]");
\r
487 if (alerturi_node->children != NULL &&
\r
488 alerturi_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
489 alerturi_node->children->content != NULL) {
\r
491 alertURI = (char *)wbxml_buffer_get_cstr(alerturi_node->children->content);
\r
492 alertURIlen = wbxml_buffer_len(alerturi_node->children->content);
\r
494 FW_LOGV("[sanPackage11Parser] NULL alertURI detected. alertURI MUST NOT be NULL.");
\r
498 san->syncAlerts[indexNode].serverURI = (char *)calloc(alertURIlen, sizeof(char));
\r
499 if (!san->syncAlerts[indexNode].serverURI) {
\r
500 FW_LOGV("[sanPackage11Parser] SAN package memory allocation fail. [serverURI]");
\r
503 memcpy(san->syncAlerts[indexNode].serverURI, alertURI, alertURIlen);
\r
506 char *alertContentType = NULL;
\r
507 unsigned alertContentTypeLen = 0;
\r
508 WBXMLTreeNode *alertcontenttype_node;
\r
509 if ((alertcontenttype_node = __get_node_elt_from_name(alert_node, "Type", TRUE)) == NULL) {
\r
510 FW_LOGV("[sanPackage11Parser] NULL from __get_node_elt_from_name. [Type]");
\r
514 if (alertcontenttype_node->children != NULL &&
\r
515 alertcontenttype_node->children->type == WBXML_TREE_TEXT_NODE &&
\r
516 alertcontenttype_node->children->content != NULL) {
\r
518 alertContentType = (char *)wbxml_buffer_get_cstr(alertcontenttype_node->children->content);
\r
519 alertContentTypeLen = wbxml_buffer_len(alertcontenttype_node->children->content);
\r
521 if (!alertContentType) {
\r
522 FW_LOGV("[sanPackage11Parser] NULL alertContentType detected. alertContentType MUST NOT be NULL.");
\r
527 int cnt = (int)sizeof(contentTypeSupported)/sizeof(SanContentType);
\r
528 bool isContentSupported = false;
\r
530 for (j = 0 ; j < cnt ; j++) {
\r
531 if (contentTypeSupported[j].strType == NULL)
\r
533 if (strcmp(alertContentType, contentTypeSupported[j].strType) == 0) {
\r
534 san->syncAlerts[indexNode].contentType = contentTypeSupported[j].strType;
\r
535 isContentSupported = true;
\r
540 if (!isContentSupported) {
\r
541 FW_LOGV("[sanPackage11Parser] SAN doesn't support the content type %s.", alertContentType);
\r
550 wbxml_tree_destroy(wbxml_tree);
\r
553 sanPackageParserFree(san);
\r
559 void sanPackageParserFree(void *point)
\r
561 SanPackage *san = (SanPackage *)point;
\r
563 if (san->msgBodyWithoutDigest)
\r
564 free(san->msgBodyWithoutDigest);
\r
568 if (san->cred->credFormat)
\r
569 free(san->cred->credFormat);
\r
570 if (san->cred->credAuth)
\r
571 free(san->cred->credAuth);
\r
572 if (san->cred->credData)
\r
573 free(san->cred->credData);
\r
577 free(san->serverID);
\r
578 if (san->syncAlerts) {
\r
580 for (i = 0 ; i < san->cntSyncAlerts ; i++) {
\r
581 if (san->syncAlerts[i].serverURI) {
\r
582 free(san->syncAlerts[i].serverURI);
\r
585 free(san->syncAlerts);
\r
591 void sanPrintMsg(SanPackage *san)
\r
595 FW_LOGV("Printing SAN package ============================\n\n");
\r
597 FW_LOGV("MsgBody without Digest :\n\t");
\r
598 for (i = 0 ; i < san->msgBodyWithoutDigestLength ; i++) {
\r
599 printf("%02x ", san->msgBodyWithoutDigest[i]);
\r
600 if ((i + 1) % 16 == 0) printf("\n\t");
\r
604 FW_LOGV("Digest : %s\n", san->digest);
\r
606 if (san->cred->credFormat)
\r
607 printf("Cred Format : %s\n", san->cred->credFormat);
\r
608 if (san->cred->credAuth)
\r
609 printf("Cred Type : %s\n", san->cred->credAuth);
\r
610 if (san->cred->credData)
\r
611 printf("Cred Data : %s\n", san->cred->credData);
\r
613 FW_LOGV("Version : %d\n", san->version);
\r
614 FW_LOGV("UI mode : %d\n", san->uiMode);
\r
615 FW_LOGV("Initiator : %d\n", san->initiator);
\r
616 FW_LOGV("Session ID : %u\n", san->sessionID);
\r
617 FW_LOGV("Server ID : %s\n", san->serverID);
\r
618 FW_LOGV("No. of Sync : %u\n", san->cntSyncAlerts);
\r
620 for (i = 0 ; i < san->cntSyncAlerts ; i++) {
\r
621 FW_LOGV("\n\t=== Sync No. %d ============\n", i+1);
\r
622 FW_LOGV("\tSync type : %d\n", san->syncAlerts[i].syncType);
\r
623 FW_LOGV("\tContent type : %s\n", san->syncAlerts[i].contentType);
\r
624 FW_LOGV("\tServer URI : %s\n", san->syncAlerts[i].serverURI);
\r