Modify flora license version.
[platform/core/messaging/msg-service.git] / utils / MsgVMessage.cpp
1 /*
2 * Copyright 2012-2013  Samsung Electronics Co., Ltd
3 *
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *    http://floralicense.org/license/
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <VMessage.h>
17 #include <VCard.h>
18 #include <time.h>
19
20 #include "MsgMmsTypes.h"
21
22 #include "MsgDebug.h"
23 #include "MsgUtilFile.h"
24 #include "MsgCppTypes.h"
25 #include "MsgVMessage.h"
26
27
28 /*==================================================================================================
29                                      DEFINES
30 ==================================================================================================*/
31 #define INSERT_VMSG_OBJ pObject = (VObject*)calloc(1, sizeof(VObject)); \
32                                       if ( !pObject )\
33 {\
34    vmsg_free_vtree_memory( pMessage );\
35    return false;\
36 }\
37 if (pMessage->pTop == NULL)\
38 {\
39    pMessage->pTop = pObject;\
40 }\
41 else\
42 {\
43    pMessage->pCur->pSibling = pObject;\
44 }\
45 pMessage->pCur = pObject;
46
47
48 #define INSERT_VBODY_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));        \
49                                       if ( !pObject )\
50 {\
51    vmsg_free_vtree_memory( pMessage );\
52    return false;\
53 }\
54 if (pBody->pTop == NULL)\
55 {\
56    pBody->pTop = pObject;\
57 }\
58 else\
59 {\
60    pBody->pCur->pSibling = pObject;\
61 }\
62 pBody->pCur = pObject;
63
64
65 #define INSERT_VCARD_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));        \
66                                       if ( !pObject )\
67 {\
68    vmsg_free_vtree_memory( pMessage );\
69    return false;\
70 }\
71 if (pCard->pTop == NULL)\
72 {\
73    pCard->pTop = pObject;\
74 }\
75 else\
76 {\
77    pCard->pCur->pSibling = pObject;\
78 }\
79 pCard->pCur = pObject;
80
81
82 #define INSERT_PARAM  param = (VParam*)calloc(1, sizeof(VParam));\
83                              if (!param)\
84 {\
85    vmsg_free_vtree_memory( pMessage );\
86    if (pObject != NULL)\
87    {\
88       free(pObject);\
89       pObject = NULL;\
90    }\
91    return false;\
92 }
93
94
95 /*==================================================================================================
96                                      FUNCTION IMPLEMENTATION
97 ==================================================================================================*/
98 char* MsgVMessageAddRecord(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S* pMsg)
99 {
100         MSG_BEGIN();
101
102         VObject*                pObject = NULL;
103         VParam*         param = NULL;
104         VTree *         pBody = NULL;
105         VTree *         pCard = NULL;
106         VTree *         pCurrent= NULL;
107         struct tm       display_time;
108         char*           encoded_data = NULL;
109         int                     err = MSG_SUCCESS;
110
111         VTree* pMessage = NULL;
112         if (pMessage == NULL) {
113                 pMessage = (VTree *)malloc(sizeof(VTree));
114                 if (!pMessage) {
115                         return NULL;
116                 }
117                 pMessage->treeType = VMESSAGE;
118                 pMessage->pTop = NULL;
119                 pMessage->pCur = NULL;
120                 pMessage->pNext = NULL;
121
122         }
123                 pCurrent = pMessage;
124
125         //Insert VObject (X-MESSAGE-TYPE) to VMessage tree
126         INSERT_VMSG_OBJ;
127
128         pObject->property = VMSG_TYPE_MSGTYPE;
129
130         if(pMsg->msgType.subType == MSG_NORMAL_SMS)
131                 pObject->pszValue[0] = strdup("SMS");
132 #if 0
133         else if(pMsg->msgType.mainType == MSG_MMS_TYPE && pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
134                 pObject->pszValue[0] = strdup("MMS NOTIFICATION");
135 #endif
136
137         else if(pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_SENDREQ_MMS || pMsg->msgType.subType == MSG_SENDCONF_MMS))
138                 pObject->pszValue[0] = strdup("MMS SEND");
139
140         else if(pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_RETRIEVE_AUTOCONF_MMS || pMsg->msgType.subType == MSG_RETRIEVE_MANUALCONF_MMS))
141                 pObject->pszValue[0] = strdup("MMS RETRIEVED");
142
143         else
144                 goto __CATCH_FAIL__;
145
146         pObject->valueCount = 1;
147
148
149         //Insert VObject (X-IRMC-BOX) to VMessate tree
150         INSERT_VMSG_OBJ;
151
152         pObject->property = VMSG_TYPE_MSGBOX;
153
154         switch(pMsg->folderId)
155         {
156                 case MSG_INBOX_ID:
157                         pObject->pszValue[0] = strdup("INBOX");
158                         break;
159                 case MSG_OUTBOX_ID:
160                         pObject->pszValue[0] = strdup("OUTBOX");
161                         break;
162                 case MSG_SENTBOX_ID:
163                         pObject->pszValue[0] = strdup("SENTBOX");
164                         break;
165                 case MSG_DRAFT_ID:
166                         pObject->pszValue[0] = strdup("DRAFTBOX");
167                         break;
168                 default:
169                         // Discard User Defined or Spam folder's messages.
170                         goto __CATCH_FAIL__;
171         }
172         pObject->valueCount = 1;
173
174
175         //Insert VObject (X-SS-DT) to VMessage tree
176         INSERT_VMSG_OBJ;
177
178         pObject->property = VMSG_TYPE_DATE;
179         localtime_r(&(pMsg->displayTime), &display_time);
180         pObject->pszValue[0] = _convert_tm_to_vdata_str(&display_time);
181         pObject->valueCount = 1;
182
183
184         //Insert Vobject read status to VMessage tree
185         INSERT_VMSG_OBJ;
186
187         pObject->property = VMSG_TYPE_STATUS;
188
189         if(pMsg->bRead)
190                 pObject->pszValue[0] = strdup("READ");
191         else
192                 pObject->pszValue[0] = strdup("UNREAD");
193
194         pObject->valueCount = 1;
195
196
197         //Insert VBody  tree for message body;
198         pBody = (VTree*)calloc(1, sizeof(VTree));
199         if ( !pBody )
200                 goto __CATCH_FAIL__;
201         pBody->treeType = VBODY;
202         pBody->pTop = NULL;
203         pBody->pCur = NULL;
204         pBody->pNext = NULL;
205         pCurrent->pNext = pBody;
206         pCurrent = pBody;
207
208 if(strlen(pMsg->subject) > 0)
209 {
210         //Insert Subject object
211         INSERT_VBODY_OBJ;
212         pObject->property = VMSG_TYPE_SUBJECT;
213         pObject->pszValue[0] = strdup(pMsg->subject);
214         pObject->valueCount = 1;
215 }
216         //Insert VBody object
217         INSERT_VBODY_OBJ;
218         pObject->property = VMSG_TYPE_BODY;
219
220         if(pMsg->msgType.mainType == MSG_SMS_TYPE)
221         {
222                 if(pMsg->msgType.subType == MSG_NORMAL_SMS)
223                 {
224                         if (pMsg->bTextSms == false)
225                         {
226                                 char* pFileData = NULL;
227                                 AutoPtr<char> buf(&pFileData);
228
229                                 int             fileSize = 0;
230                                 char*   msgText = NULL;
231
232                                 if (MsgOpenAndReadFile(pMsg->msgData, &pFileData, &fileSize) == false)
233                                         goto __CATCH_FAIL__;
234
235                                 msgText = (char *)calloc(1, fileSize);
236                                 memcpy(msgText, pFileData, fileSize);
237                                 pObject->numOfBiData = fileSize;
238                                 pObject->pszValue[0] = msgText;
239                         }
240                         else
241                         {
242                                 pObject->numOfBiData = pMsg->dataSize;
243                                 pObject->pszValue[0] = strdup(pMsg->msgText);
244                         }
245                         pObject->valueCount = 1;
246                 }
247                 else
248                         goto __CATCH_FAIL__;
249         }
250
251         else if(pMsg->msgType.mainType == MSG_MMS_TYPE)
252         {
253                 //Insert VBody for mms raw data;
254                 char* pFileData = NULL;
255
256                 int             fileSize = 0;
257                 char*   msgText = NULL;
258                 char            filePath[MSG_FILEPATH_LEN_MAX] = {0, };
259
260                 if(pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
261                         pFileData = MsgOpenAndReadMmsFile(pMsg->msgData, 0, -1, &fileSize);
262
263                 else
264                 {
265                         err = MsgStoGetMmsRawFilePath(pDbHandle, pMsg->msgId, filePath);
266
267                         if (err != MSG_SUCCESS)
268                                 goto __CATCH_FAIL__;
269
270                         pFileData = MsgOpenAndReadMmsFile(filePath, 0, -1, &fileSize);
271                 }
272                 MSG_DEBUG("FILE SIZE IS %d", fileSize);
273                 msgText = (char *)calloc(1, fileSize);
274                 if(pFileData)
275                         memcpy(msgText, pFileData, fileSize);
276                 pObject->numOfBiData = fileSize;
277                 pObject->pszValue[0] = msgText;
278                 pObject->valueCount = 1;
279
280                 if (pFileData) {
281                         free(pFileData);
282                         pFileData = NULL;
283                 }
284         }
285
286         // Insert parameter for base64 encoding
287         MSG_DEBUG("before to start INSERT_PARAM");
288         INSERT_PARAM;
289         pObject->pParam = param;
290         param->parameter = VMSG_PARAM_ENCODING;
291         param->paramValue = VMSG_ENC_PARAM_BASE64;
292
293         // Add VCard tree for recipient address information.
294         for(int i = 0; i < pMsg->nAddressCnt; ++i)
295         {
296                 pCard = (VTree*)calloc(1, sizeof(VTree));
297                 if ( !pCard )
298                         goto __CATCH_FAIL__;
299
300                 pCard->treeType = VCARD;
301                 pCard->pTop = NULL;
302                 pCard->pCur = NULL;
303                 pCard->pNext = NULL;
304                 pCurrent->pNext = pCard;
305                 pCurrent = pCard;
306
307                 INSERT_VCARD_OBJ;
308                 pObject->property = VCARD_TYPE_TEL;
309                 pObject->pszValue       [0] = strdup(pMsg->addressList[i].addressVal);
310                 pObject->valueCount = 1;
311         }
312         MSG_DEBUG("before to start vmsg_encode");
313         encoded_data = vmsg_encode(pMessage);
314
315         vmsg_free_vtree_memory(pMessage);
316         MSG_END();
317         return encoded_data;
318
319 __CATCH_FAIL__ :
320         vmsg_free_vtree_memory( pMessage );
321
322         return NULL;
323 }
324
325
326 char* _convert_tm_to_vdata_str(const struct tm * tm)
327 {
328         char str[17] = {0, };
329
330         snprintf(str, 17, "%04d%02d%02dT%02d%02d%02dZ",
331                 tm->tm_year + 1900,
332                 tm->tm_mon +1,
333                 tm->tm_mday,
334                 tm->tm_hour,
335                 tm->tm_min,
336                 tm->tm_sec);
337
338         return strdup(str);
339 }
340
341
342 bool _convert_vdata_str_to_tm(const char* szText, struct tm * tm)
343 {
344
345    if (szText == NULL) return false;
346    if (strlen(szText) < 15) return false;
347    if (szText[8] != 'T') return false;
348
349    char szBuff[8]={0};
350    memset(tm, 0, sizeof(struct tm));
351
352    // year, month, day
353    memcpy(szBuff, &(szText[0]), 4);
354    szBuff[4] = '\0';
355    tm->tm_year = atol(szBuff) - 1900;
356    if ((tm->tm_year > 137) || (tm->tm_year < 0))
357       tm->tm_year = 0;
358
359    memcpy(szBuff, &(szText[4]), 2);
360    szBuff[2] = '\0';
361    tm->tm_mon = atol(szBuff)-1;
362    if ((tm->tm_mon > 11) || (tm->tm_mon < 0))
363       tm->tm_mon = 11;
364
365    memcpy(szBuff, &(szText[6]), 2);
366    szBuff[2] = '\0';
367    tm->tm_mday = atol(szBuff);
368    if ((tm->tm_mday > 31) || (tm->tm_mday < 1))
369       tm->tm_mday = 31;
370
371    // hour, minute, second
372    memcpy(szBuff, &(szText[9]), 2);
373    szBuff[2] = '\0';
374    tm->tm_hour = atol(szBuff);
375    if ((tm->tm_hour > 23) || (tm->tm_hour < 0))
376       tm->tm_hour = 23;
377
378    memcpy(szBuff, &(szText[11]), 2);
379    szBuff[2] = '\0';
380    tm->tm_min = atol(szBuff);
381    if ((tm->tm_min > 59) || (tm->tm_min < 0))
382       tm->tm_min = 59;
383
384    memcpy(szBuff, &(szText[13]), 2);
385    szBuff[2] = '\0';
386    tm->tm_sec = atol(szBuff);
387    if ((tm->tm_sec > 59) || (tm->tm_sec < 0))
388       tm->tm_sec = 59;
389
390    return true;
391 }
392
393 char *MsgVMessageEncode(MSG_MESSAGE_INFO_S *pMsg)
394 {
395         MSG_BEGIN();
396
397         MsgDbHandler dbHandle;
398         VObject *pObject = NULL;
399         VParam *param = NULL;
400         VTree *pBody = NULL;
401         VTree *pCard = NULL;
402         VTree *pCurrent= NULL;
403         VTree *pMessage = NULL;
404
405         struct tm       display_time;
406         char *encoded_data = NULL;
407         int err = MSG_SUCCESS;
408
409         if (pMessage == NULL) {
410                 pMessage = (VTree *)malloc(sizeof(VTree));
411                 if (!pMessage) {
412                         return NULL;
413                 }
414                 pMessage->treeType = VMESSAGE;
415                 pMessage->pTop = NULL;
416                 pMessage->pCur = NULL;
417                 pMessage->pNext = NULL;
418
419         }
420                 pCurrent = pMessage;
421
422         //Insert VObject (X-MESSAGE-TYPE) to VMessage tree
423         INSERT_VMSG_OBJ;
424
425         pObject->property = VMSG_TYPE_MSGTYPE;
426
427         if(pMsg->msgType.subType == MSG_NORMAL_SMS)
428                 pObject->pszValue[0] = strdup("SMS");
429 #if 0
430         else if(pMsg->msgType.mainType == MSG_MMS_TYPE && pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
431                 pObject->pszValue[0] = strdup("MMS NOTIFICATION");
432 #endif
433
434         else if(pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_SENDREQ_MMS || pMsg->msgType.subType == MSG_SENDCONF_MMS))
435                 pObject->pszValue[0] = strdup("MMS SEND");
436
437         else if(pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_RETRIEVE_AUTOCONF_MMS || pMsg->msgType.subType == MSG_RETRIEVE_MANUALCONF_MMS))
438                 pObject->pszValue[0] = strdup("MMS RETRIEVED");
439
440         else
441                 goto __CATCH_FAIL__;
442
443         pObject->valueCount = 1;
444
445
446         //Insert VObject (X-IRMC-BOX) to VMessate tree
447         INSERT_VMSG_OBJ;
448
449         pObject->property = VMSG_TYPE_MSGBOX;
450
451         switch(pMsg->folderId)
452         {
453                 case MSG_INBOX_ID:
454                         pObject->pszValue[0] = strdup("INBOX");
455                         break;
456                 case MSG_OUTBOX_ID:
457                         pObject->pszValue[0] = strdup("OUTBOX");
458                         break;
459                 case MSG_SENTBOX_ID:
460                         pObject->pszValue[0] = strdup("SENTBOX");
461                         break;
462                 case MSG_DRAFT_ID:
463                         pObject->pszValue[0] = strdup("DRAFTBOX");
464                         break;
465                 default:
466                         // Discard User Defined or Spam folder's messages.
467                         goto __CATCH_FAIL__;
468         }
469         pObject->valueCount = 1;
470
471
472         //Insert VObject (X-SS-DT) to VMessage tree
473         INSERT_VMSG_OBJ;
474
475         pObject->property = VMSG_TYPE_DATE;
476         localtime_r(&(pMsg->displayTime), &display_time);
477         pObject->pszValue[0] = _convert_tm_to_vdata_str(&display_time);
478         pObject->valueCount = 1;
479
480
481         //Insert Vobject read status to VMessage tree
482         INSERT_VMSG_OBJ;
483
484         pObject->property = VMSG_TYPE_STATUS;
485
486         if(pMsg->bRead)
487                 pObject->pszValue[0] = strdup("READ");
488         else
489                 pObject->pszValue[0] = strdup("UNREAD");
490
491         pObject->valueCount = 1;
492
493
494         //Insert VBody  tree for message body;
495         pBody = (VTree*)calloc(1, sizeof(VTree));
496         if ( !pBody )
497                 goto __CATCH_FAIL__;
498         pBody->treeType = VBODY;
499         pBody->pTop = NULL;
500         pBody->pCur = NULL;
501         pBody->pNext = NULL;
502         pCurrent->pNext = pBody;
503         pCurrent = pBody;
504
505 if(strlen(pMsg->subject) > 0)
506 {
507         //Insert Subject object
508         INSERT_VBODY_OBJ;
509         pObject->property = VMSG_TYPE_SUBJECT;
510         pObject->pszValue[0] = strdup(pMsg->subject);
511         pObject->valueCount = 1;
512 }
513         //Insert VBody object
514         INSERT_VBODY_OBJ;
515         pObject->property = VMSG_TYPE_BODY;
516
517         if(pMsg->msgType.mainType == MSG_SMS_TYPE)
518         {
519                 if(pMsg->msgType.subType == MSG_NORMAL_SMS)
520                 {
521                         if (pMsg->bTextSms == false)
522                         {
523                                 char* pFileData = NULL;
524                                 AutoPtr<char> buf(&pFileData);
525
526                                 int             fileSize = 0;
527                                 char*   msgText = NULL;
528
529                                 if (MsgOpenAndReadFile(pMsg->msgData, &pFileData, &fileSize) == false)
530                                         goto __CATCH_FAIL__;
531
532                                 msgText = (char *)calloc(1, fileSize);
533                                 memcpy(msgText, pFileData, fileSize);
534                                 pObject->numOfBiData = fileSize;
535                                 pObject->pszValue[0] = msgText;
536                         }
537                         else
538                         {
539                                 pObject->numOfBiData = pMsg->dataSize;
540                                 pObject->pszValue[0] = strdup(pMsg->msgText);
541                         }
542                         pObject->valueCount = 1;
543                 }
544                 else
545                         goto __CATCH_FAIL__;
546         }
547
548         else if(pMsg->msgType.mainType == MSG_MMS_TYPE)
549         {
550                 //Insert VBody for mms raw data;
551                 char* pFileData = NULL;
552
553                 int             fileSize = 0;
554                 char*   msgText = NULL;
555                 char            filePath[MSG_FILEPATH_LEN_MAX] = {0, };
556
557                 if(pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
558                         pFileData = MsgOpenAndReadMmsFile(pMsg->msgData, 0, -1, &fileSize);
559
560                 else
561                 {
562                         err = MsgStoGetMmsRawFilePath(&dbHandle, pMsg->msgId, filePath);
563
564                         if (err != MSG_SUCCESS)
565                                 goto __CATCH_FAIL__;
566
567                         pFileData = MsgOpenAndReadMmsFile(filePath, 0, -1, &fileSize);
568                 }
569                 MSG_DEBUG("FILE SIZE IS %d", fileSize);
570                 msgText = (char *)calloc(1, fileSize);
571                 if(pFileData)
572                         memcpy(msgText, pFileData, fileSize);
573                 pObject->numOfBiData = fileSize;
574                 pObject->pszValue[0] = msgText;
575                 pObject->valueCount = 1;
576
577                 if (pFileData) {
578                         free(pFileData);
579                         pFileData = NULL;
580                 }
581         }
582
583         // Insert parameter for base64 encoding
584         MSG_DEBUG("before to start INSERT_PARAM");
585         INSERT_PARAM;
586         pObject->pParam = param;
587         param->parameter = VMSG_PARAM_ENCODING;
588         param->paramValue = VMSG_ENC_PARAM_BASE64;
589
590         // Add VCard tree for recipient address information.
591         for(int i = 0; i < pMsg->nAddressCnt; ++i)
592         {
593                 pCard = (VTree*)calloc(1, sizeof(VTree));
594                 if ( !pCard )
595                         goto __CATCH_FAIL__;
596
597                 pCard->treeType = VCARD;
598                 pCard->pTop = NULL;
599                 pCard->pCur = NULL;
600                 pCard->pNext = NULL;
601                 pCurrent->pNext = pCard;
602                 pCurrent = pCard;
603
604                 INSERT_VCARD_OBJ;
605                 pObject->property = VCARD_TYPE_TEL;
606                 pObject->pszValue       [0] = strdup(pMsg->addressList[i].addressVal);
607                 pObject->valueCount = 1;
608         }
609         MSG_DEBUG("before to start vmsg_encode");
610         encoded_data = vmsg_encode(pMessage);
611
612         vmsg_free_vtree_memory(pMessage);
613         MSG_END();
614         return encoded_data;
615
616 __CATCH_FAIL__ :
617         vmsg_free_vtree_memory( pMessage );
618
619         return NULL;
620 }