RSA sync with private
[platform/core/messaging/msg-service.git] / plugin / mms_plugin / MmsPluginMessage.cpp
1 /*
2 * Copyright 2012  Samsung Electronics Co., Ltd
3 *
4 * Licensed under the Flora License, Version 1.0 (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://www.tizenopensource.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
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <time.h>
21 #include <ctype.h>
22
23 #include "MsgTypes.h"
24 #include "MsgCppTypes.h"
25 #include "MsgException.h"
26 #include "MsgStorageTypes.h"
27 #include "MsgSettingTypes.h"
28 #include "MmsPluginMessage.h"
29 #include "MmsPluginMIME.h"
30 #include "MmsPluginAvCodec.h"
31 #include "MsgUtilFile.h"
32 #include "MsgDebug.h"
33 #include "MmsPluginCodec.h"
34 #include "MmsPluginStorage.h"
35 #include "MsgMmsMessage.h"
36 #include "MsgGconfWrapper.h"
37 #include "MmsPluginUtil.h"
38 #include "MmsPluginSMILValidate.h"
39
40
41 bool MmsInitMsgAttrib(MmsAttrib *pAttrib)
42 {
43         MSG_DEBUG("MmsInitMsgAttrib");
44
45         pAttrib->bAskDeliveryReport = false;
46
47         pAttrib->bAskReadReply = false;
48         pAttrib->bRead = false;
49         pAttrib->bReportAllowed = false;
50         pAttrib->readReportAllowedType = MMS_RECEIVE_READ_REPORT_ALLOWED;
51         pAttrib->readReportSendStatus = MMS_RECEIVE_READ_REPORT_NO_SEND;
52         pAttrib->bReadReportSent = false;
53
54         pAttrib->bHideAddress = false;
55         pAttrib->date = 0;
56         pAttrib->bUseDeliveryCustomTime = false;
57         pAttrib->deliveryTime.type = MMS_TIMETYPE_RELATIVE;
58         pAttrib->deliveryTime.time = 0;
59         pAttrib->bUseExpiryCustomTime = false;
60         pAttrib->expiryTime.type = MMS_TIMETYPE_RELATIVE;
61         pAttrib->expiryTime.time = 0;
62         memset(&pAttrib->expiryTime, 0, sizeof(MmsTimeStruct));
63         pAttrib->msgClass = MMS_MSGCLASS_PERSONAL;
64         pAttrib->msgStatus = MSG_DELIVERY_REPORT_NONE;
65         pAttrib->priority = MMS_PRIORITY_NORMAL;
66         pAttrib->responseStatus = MMS_RESPSTATUS_ERROR;
67         pAttrib->retrieveStatus = MMS_RETRSTATUS_ERROR;
68         pAttrib->contentType = MIME_UNKNOWN;
69         pAttrib->msgSize = 0;
70         pAttrib->bLeaveCopy = true;
71
72         pAttrib->specialMsgType = MMS_SPECIAL_MSG_TYPE_NONE;
73 #ifdef __SUPPORT_DRM__
74         pAttrib->drmType = MSG_DRM_TYPE_NONE;
75         pAttrib->roWaitingTimerMax = 0;
76         pAttrib->pszDrmData = NULL;
77 #endif
78         pAttrib->version = MMS_VERSION;
79
80         memset(pAttrib->szFrom, 0, MSG_LOCALE_ADDR_LEN + 10);
81         memset(pAttrib->szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
82         memset(pAttrib->szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
83         memset(pAttrib->szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
84         pAttrib->szTo = NULL;
85         pAttrib->szCc = NULL;
86         pAttrib->szBcc = NULL;
87
88         pAttrib->pMultiStatus = NULL;
89
90         pAttrib->replyCharge.chargeType = MMS_REPLY_NONE;
91         memset(&pAttrib->replyCharge.deadLine , 0, sizeof(MmsTimeStruct));
92         pAttrib->replyCharge.chargeSize = 0;
93         memset(pAttrib->replyCharge.szChargeID, 0, MMS_MSG_ID_LEN);
94
95         return true;
96 }
97
98 bool MmsInitMsgType(MsgType *pMsgType)
99 {
100         MSG_DEBUG("MmsInitMsgType");
101         pMsgType->offset = 0;
102         pMsgType->size = 0;
103         pMsgType->contentSize = 0;
104         pMsgType->disposition = -1;
105         pMsgType->encoding = -1;
106         pMsgType->type = MIME_UNKNOWN;
107         pMsgType->section = -1;
108
109         pMsgType->szOrgFilePath[0] = '\0';
110         pMsgType->szContentID[0] = '\0';
111         pMsgType->szContentLocation[0] = '\0';
112
113         pMsgType->szContentRepPos[0] = '\0';
114         pMsgType->szContentRepSize[0] = '\0';
115         pMsgType->szContentRepIndex[0] = '\0';
116
117         MmsInitMsgContentParam(&pMsgType->param);
118 #ifdef __SUPPORT_DRM__
119         __MsgInitMsgDRMInfo(&pMsgType->drmInfo);
120 #endif
121
122         return true;
123 }
124
125 bool MmsInitMsgBody(MsgBody *pMsgBody)
126 {
127         MSG_DEBUG("MmsInitMsgBody");
128         pMsgBody->offset = 0;
129         pMsgBody->size = 0;
130         pMsgBody->body.pText = NULL;
131
132         MmsInitMsgType(&pMsgBody->presentationType);
133         pMsgBody->pPresentationBody = NULL;
134
135         memset(pMsgBody->szOrgFilePath, 0, MSG_FILEPATH_LEN_MAX);
136
137         return true;
138 }
139
140 bool MmsInitMsgContentParam(MsgContentParam *pMsgContentParam)
141 {
142         MSG_DEBUG("MmsInitMsgContentParam");
143         pMsgContentParam->charset = MSG_CHARSET_UNKNOWN;
144         pMsgContentParam->type = MIME_UNKNOWN;
145         pMsgContentParam->szBoundary[0] = '\0';
146         pMsgContentParam->szFileName[0] = '\0';
147         pMsgContentParam->szName[0] = '\0';
148         pMsgContentParam->szStart[0] = '\0';
149         pMsgContentParam->szStartInfo[0] = '\0';
150         pMsgContentParam->pPresentation = NULL;
151         pMsgContentParam->reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN; // only used as parameter of Content-Type: multipart/report; report-type
152 #ifdef FEATURE_JAVA_MMS
153         pMsgContentParam->szApplicationID = NULL;
154         pMsgContentParam->szReplyToApplicationID = NULL;
155 #endif
156         return true;
157 }
158
159 bool MmsSetMsgAddressList(MmsAttrib *pAttrib, const MSG_MESSAGE_INFO_S * pMsgInfo)
160 {
161         MSG_DEBUG("MmsSetMsgAddressList");
162         pAttrib->szTo = MmsComposeAddress(pMsgInfo, MSG_RECIPIENTS_TYPE_TO);
163         MSG_DEBUG("To address: %s", pAttrib->szTo);
164         pAttrib->szCc = MmsComposeAddress(pMsgInfo, MSG_RECIPIENTS_TYPE_CC);
165         MSG_DEBUG("Cc address: %s", pAttrib->szCc);
166         pAttrib->szBcc = MmsComposeAddress(pMsgInfo, MSG_RECIPIENTS_TYPE_BCC);
167         MSG_DEBUG("Bcc address: %s", pAttrib->szBcc);
168
169         return true;
170 }
171
172 void MmsSetMsgMultiStatus(MmsAttrib *pAttrib, const MSG_MESSAGE_INFO_S *pMsgInfo)
173 {
174         int     nAddressCnt = 0;
175
176         nAddressCnt = pMsgInfo->nAddressCnt;
177
178         for (int i = 0; i < nAddressCnt; ++i) {
179                 pAttrib->pMultiStatus = (MmsMsgMultiStatus *)malloc(sizeof(MmsMsgMultiStatus));
180
181                 memset(pAttrib->pMultiStatus->szTo, 0, MAX_ADDRESS_VAL_LEN + 1);
182                 strncpy(pAttrib->pMultiStatus->szTo, pMsgInfo->addressList[i].addressVal, MAX_ADDRESS_VAL_LEN);
183
184                 MSG_DEBUG("### pMultistatus->szTo = %s ####", pAttrib->pMultiStatus->szTo);
185                 pAttrib->pMultiStatus->bDeliveryReportIsRead = false;
186                 pAttrib->pMultiStatus->bDeliveyrReportIsLast = false;
187                 pAttrib->pMultiStatus->msgStatus = MMS_MSGSTATUS_NONE;
188                 pAttrib->pMultiStatus->handledTime = 0;
189                 pAttrib->pMultiStatus->bReadReplyIsRead = false;
190                 pAttrib->pMultiStatus->bReadReplyIsLast = false;
191                 pAttrib->pMultiStatus->readStatus = MMS_READSTATUS_NONE;
192                 pAttrib->pMultiStatus->readTime = 0;
193
194                 pAttrib->pMultiStatus = pAttrib->pMultiStatus->pNext;
195         }
196 }
197
198 char *MmsComposeAddress(const MSG_MESSAGE_INFO_S *pMsgInfo, int recipientType)
199 {
200         MSG_DEBUG("MmsComposeAddress");
201         int     addrLen = 0;
202         int     nAddressCnt = 0;
203         int nRecpCnt = 0;
204         char pString[MSG_LOCALE_NAME_LEN + MSG_ADDR_LEN + 3] = {0, };
205         char *szCompose;
206
207         nAddressCnt = pMsgInfo->nAddressCnt;
208
209         // Calculate allocated buffer size
210         for (int i = 0; i < nAddressCnt; ++i) {
211                 MSG_DEBUG("recipientType: %d, address value: %s", pMsgInfo->addressList[i].recipientType, pMsgInfo->addressList[i].addressVal);
212                 if (pMsgInfo->addressList[i].recipientType == recipientType) {
213                         if (pMsgInfo->addressList[i].addressType == MSG_ADDRESS_TYPE_PLMN) {
214                                 addrLen += strlen(MsgGetString(MSG_ADDR_TYPE, MSG_ADDR_TYPE_PHONE));
215                                 addrLen += strlen(pMsgInfo->addressList[i].addressVal);
216                         } else if (pMsgInfo->addressList[i].addressType == MSG_ADDRESS_TYPE_EMAIL) {
217                                 addrLen += strlen(pMsgInfo->addressList[i].addressVal);
218                         } else
219                                 ; // Need to consider IPV4, IPV6, and Alias formatted address
220
221                         nRecpCnt++;
222                 }
223         }
224
225         if (nRecpCnt > 1)
226                 addrLen = addrLen + nRecpCnt - 1;
227         szCompose = (char *)calloc(addrLen + 1, 1);
228
229         // Address String copy
230         for (int i = 0; i < nAddressCnt; ++i) {
231                 if (pMsgInfo->addressList[i].recipientType == recipientType) {
232                         if (strlen(szCompose) > 0)
233                                 strcat(szCompose, MSG_STR_ADDR_DELIMETER);
234
235                         memset(pString, 0x00, (MSG_LOCALE_NAME_LEN + MSG_ADDR_LEN + 3) * sizeof(char));
236                         if (pMsgInfo->addressList[i].addressType == MSG_ADDRESS_TYPE_PLMN) {
237                                 snprintf(pString, MSG_LOCALE_NAME_LEN + MSG_ADDR_LEN + 3, "%s%s", pMsgInfo->addressList[i].addressVal, MsgGetString(MSG_ADDR_TYPE, MSG_ADDR_TYPE_PHONE));
238                                 MSG_DEBUG("%s", pString);
239                         } else if (pMsgInfo->addressList[i].addressType == MSG_ADDRESS_TYPE_EMAIL) {
240                                 snprintf(pString, MSG_LOCALE_NAME_LEN + MSG_ADDR_LEN + 3, "%s", pMsgInfo->addressList[i].addressVal);
241                         } else
242                                 ; // Need to consider IPV4, IPV6, and Alias formatted address
243
244                         strcat(szCompose, pString);
245                 }
246         }
247
248         return szCompose;
249 }
250
251
252 bool MmsGetMsgBodyfromMsgInfo(const MSG_MESSAGE_INFO_S *pMsgInfo, MMS_MESSAGE_DATA_S *pMsgBody, char *pFileData)
253 {
254         MSG_DEBUG("MmsGetMsgBodyfromMsgInfo");
255         memset(pMsgBody, 0, sizeof(MMS_MESSAGE_DATA_S));
256
257         if (pMsgInfo->bTextSms == false) {       //if  the message body was stored in file.
258                 _MsgMmsDeserializeMessageData(pMsgBody, pFileData);
259         }
260
261         return true;
262 }
263
264 int MmsGetSmilRawData(MMS_MESSAGE_DATA_S *pMsgBody, char **pRawdata)
265 {
266         MSG_BEGIN();
267
268         if (MsgReadSmilFile(pMsgBody->szSmilFilePath, pRawdata) < 0)
269                 return false;
270
271         MsgDeleteSmilFile(pMsgBody->szSmilFilePath);
272
273         MSG_END();
274
275         return true;
276 }
277
278
279 bool MmsInsertPresentation(MmsMsg *pMsg, MsgContentType mimeType, char *pData, int size)
280 {
281         MSG_DEBUG("MmsInsertPresentation");
282
283         if (pMsg == NULL) {
284                 MSG_DEBUG("pMsg is NULL");
285                 return false;
286         }
287
288         if (pMsg->msgBody.pPresentationBody != NULL)
289                 goto __CATCH;
290
291         memset(&pMsg->msgBody.presentationType, 0, sizeof(MsgType));
292         pMsg->msgBody.pPresentationBody = (MsgBody *)malloc(sizeof(MsgBody));
293         if (pMsg->msgBody.pPresentationBody == NULL)
294                 goto __CATCH;
295
296         MmsInitMsgBody(pMsg->msgBody.pPresentationBody);
297
298         pMsg->msgBody.pPresentationBody->body.pText = (char *)malloc(size + 1);
299         if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
300                 goto __CATCH;
301
302         pMsg->msgBody.pPresentationBody->size = size;
303         pMsg->msgBody.presentationType.type = mimeType;
304         pMsg->msgBody.presentationType.param.charset = MSG_CHARSET_UTF8;
305         snprintf(pMsg->msgBody.presentationType.szContentID, MSG_MSG_ID_LEN + 1, "<_S_>");
306
307         snprintf(pMsg->msgType.param.szStart, MSG_MSG_ID_LEN + 1, "%s", pMsg->msgBody.presentationType.szContentID);
308         pMsg->msgType.param.type = mimeType;
309
310         memset(pMsg->msgBody.pPresentationBody->body.pText, 0, size + 1);
311         strncpy(pMsg->msgBody.pPresentationBody->body.pText, pData, size);
312
313         return true;
314
315 __CATCH:
316
317         if (pMsg->msgBody.pPresentationBody != NULL) {
318                 if (pMsg->msgBody.pPresentationBody->body.pText != NULL) {
319                         free(pMsg->msgBody.pPresentationBody->body.pText);
320                         pMsg->msgBody.pPresentationBody->body.pText = NULL;
321                 }
322
323                 free(pMsg->msgBody.pPresentationBody);
324                 pMsg->msgBody.pPresentationBody = NULL;
325         }
326
327         return false;
328 }
329
330
331 bool MmsInsertPartFromFile(MmsMsg *pMsg, char *szTitleName, char *szOrgFilePath, char *szContentID)
332 {
333         MSG_DEBUG("MmsInsertPartFromFile");
334
335         MsgMultipart *pMultipart = NULL;
336         MsgMultipart *pLastPart = NULL;
337         int nFileSize;
338         MsgContentType mimeType = MIME_UNKNOWN;
339         char *pExt = NULL;
340
341         pExt = strrchr(szOrgFilePath, '.');
342
343         if (pExt == NULL || pExt[0] == '\0' || strrchr(pExt, '/'))
344                 mimeType = MIME_UNKNOWN;
345         else {
346                 if (strcasecmp(pExt, ".dcf") == 0)
347                         mimeType = MIME_APPLICATION_VND_OMA_DRM_CONTENT;
348                 else {
349                         if (MmsGetTypeByFileName((int *)&mimeType, szOrgFilePath) == false)
350                                 goto __CATCH;
351                 }
352         }
353
354         if (mimeType == MIME_UNKNOWN)
355                 mimeType = MIME_APPLICATION_OCTET_STREAM;
356
357         if (MmsIsMultipart(pMsg->msgType.type) == true) {
358                 /* Insert as a multipart */
359                 if (MsgGetFileSize(szOrgFilePath, &nFileSize) == false) {
360                         MSG_DEBUG("MsgGetFileSize: failed");
361                         goto __CATCH;
362                 }
363
364                 pMultipart = MmsMakeMultipart(mimeType, szTitleName, szOrgFilePath, NULL, 0, nFileSize, szContentID);
365                 if (pMultipart == NULL)
366                         goto __CATCH;
367
368                 if (pMsg->mmsAttrib.contentType == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
369                         pMsg->mmsAttrib.contentType == MIME_MULTIPART_MIXED)
370                         pMultipart->type.disposition = MSG_DISPOSITION_ATTACHMENT;
371
372                 if (pMsg->msgBody.body.pMultipart == NULL) {
373                         pMsg->msgBody.body.pMultipart = pMultipart;
374                 } else {
375                         pLastPart = pMsg->msgBody.body.pMultipart;
376                         while (pLastPart->pNext) {
377                                 pLastPart = pLastPart->pNext;
378                         }
379
380                         pLastPart->pNext = pMultipart;
381                 }
382
383                 pMsg->msgBody.size += pMultipart->pBody->size;
384                 pMsg->msgType.contentSize += pMultipart->pBody->size;
385         } else {
386                 /* Single part - Insert as a message body */
387                 if (pMsg->mmsAttrib.contentType != mimeType || pMsg->msgType.type != mimeType)
388                         goto __CATCH;
389
390                 strncpy(pMsg->msgType.param.szName, szTitleName, MSG_LOCALE_FILENAME_LEN_MAX);
391
392                 if (MmsIsText(pMsg->msgType.type) == true) {
393                         pMsg->msgType.param.charset = MSG_CHARSET_UTF8;
394                 }
395
396                 strncpy(pMsg->msgBody.szOrgFilePath, szOrgFilePath, MSG_FILEPATH_LEN_MAX - 1);
397                 if (MsgGetFileSize(szOrgFilePath, &nFileSize) == false) {
398                         MSG_DEBUG("MsgGetFileSize: failed");
399                         goto __CATCH;
400                 }
401
402                 pMsg->msgBody.offset = 0;
403                 pMsg->msgBody.size = nFileSize;
404                 pMsg->msgType.contentSize = nFileSize;
405         }
406
407         pMsg->nPartCount++;
408
409         return true;
410
411 __CATCH:
412         return false;
413
414 }
415
416 bool MmsIsMultipart(int type)
417 {
418         MSG_DEBUG("MmsIsMultipart");
419         if (type == MIME_MULTIPART_RELATED ||
420                 type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
421                 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED ||
422                 type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
423                 type == MIME_MULTIPART_MIXED ||
424                 type == MIME_MULTIPART_REPORT) {
425                 return true;
426         } else {
427                 return false;
428         }
429 }
430
431 bool MmsIsText(int type)
432 {
433         if (type == MIME_TEXT_PLAIN ||
434                 type == MIME_TEXT_HTML ||
435                 type == MIME_TEXT_VND_WAP_WML ||
436                 type == MIME_TEXT_X_VCARD ||
437                 type == MIME_TEXT_X_VCALENDAR ||
438                 type == MIME_TEXT_X_VNOTE ||
439                 type == MIME_APPLICATION_SMIL ||
440                 type == MIME_TEXT_X_IMELODY) {
441                 MSG_DEBUG("MmsIsText true.");
442                 return true;
443         } else {
444                 MSG_DEBUG("MmsIsText false.");
445                 return false;
446         }
447 }
448
449 bool MmsIsVitemContent (int type, char *pszName)
450 {
451         switch (type) {
452
453 /*
454 *       To make Encoding information right.
455 *               case MIME_TEXT_X_VCARD :
456 *               case MIME_TEXT_X_VCALENDAR :
457 *               case MIME_TEXT_X_VNOTE :        // vnt
458 *               {
459 *                       MSG_DEBUG("MmsIsVitemContent true.");
460 *                       return true;
461 *               }
462 *
463 */
464         case MIME_TEXT_X_VCARD:
465         case MIME_TEXT_X_VCALENDAR:
466         case MIME_TEXT_X_VNOTE: // vnt
467         case MIME_TEXT_PLAIN:           // vbm - It SHOULD be distinguished from a normal text file.
468                 {
469                         char *pszExt = NULL;
470
471                         if (!pszName)
472                                 break;
473
474                         // search file extension.
475                         if ((pszExt = strrchr(pszName, '.')) == NULL)
476                                 break;
477
478                         if (!strcasecmp(pszExt, ".vbm")) {
479                                 MSG_DEBUG("MmsIsVitemContent true.");
480                                 return true;
481                         }
482                 }
483                 break;
484
485         default:
486                 break;
487         }
488
489         MSG_DEBUG("MmsIsVitemContent false.");
490         return false;
491 }
492
493
494
495 MsgMultipart *MmsAllocMultipart(void)
496 {
497         MsgMultipart *pMultipart = NULL;
498
499         pMultipart = (MsgMultipart *)malloc(sizeof(MsgMultipart));
500
501         if (pMultipart == NULL)
502                 goto __CATCH;
503
504         pMultipart->pBody = (MsgBody *)malloc(sizeof(MsgBody));
505
506         if (pMultipart->pBody == NULL)
507                 goto __CATCH;
508
509         MmsInitMsgType(&pMultipart->type);
510         MmsInitMsgBody(pMultipart->pBody);
511
512         pMultipart->pNext = NULL;
513
514         return pMultipart;
515
516 __CATCH:
517
518         if (pMultipart) {
519                 if (pMultipart->pBody) {
520                         free(pMultipart->pBody);
521                         pMultipart->pBody = NULL;
522                 }
523
524                 free(pMultipart);
525                 pMultipart = NULL;
526         }
527
528         return NULL;
529 }
530
531
532
533 MsgMultipart *MmsMakeMultipart(MsgContentType mimeType, char *szTitleName, char *szOrgFilePath, void *pData, int offset, int size, char *szContentID)
534 {
535         MsgMultipart *pMultipart = NULL;
536
537         if ((pMultipart = MmsAllocMultipart()) == NULL)
538                 goto __CATCH;
539
540         pMultipart->type.type = mimeType;
541
542         if (szTitleName && szTitleName[0]) {
543                 memset(pMultipart->type.param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
544                 strncpy(pMultipart->type.param.szName, szTitleName, MSG_LOCALE_FILENAME_LEN_MAX);
545         }
546
547         if (szContentID && szContentID[0]) {
548                 memset(pMultipart->type.szContentID, 0, MSG_MSG_ID_LEN + 1);
549                 snprintf(pMultipart->type.szContentID, MSG_MSG_ID_LEN + 1, "<%s>", szContentID);
550
551                 memset(pMultipart->type.szContentLocation, 0, MSG_MSG_ID_LEN + 1);
552                 snprintf(pMultipart->type.szContentLocation, MSG_MSG_ID_LEN + 1, "%s", szContentID);
553         }
554
555         if (MmsIsText(mimeType) == true) {
556                 if (!MmsIsVitemContent (mimeType, pMultipart->type.param.szName)) {
557                         pMultipart->type.param.charset = MSG_CHARSET_UTF8;
558                 }
559                 pMultipart->type.encoding = MSG_ENCODING_8BIT;
560         } else {
561                 pMultipart->type.encoding = MSG_ENCODING_BINARY;
562         }
563
564         if (szOrgFilePath == NULL) {
565                 if (pData != NULL) {
566                         if (MmsIsText(mimeType) == true) {
567                                 pMultipart->pBody->body.pText = (char *)malloc(size + 1);
568                                 if (pMultipart->pBody->body.pText == NULL)
569                                         goto __CATCH;
570
571                                 memset(pMultipart->pBody->body.pText, 0, size + 1);
572                         } else {
573                                 pMultipart->pBody->body.pBinary = malloc(size);
574                                 if (pMultipart->pBody->body.pBinary == NULL)
575                                         goto __CATCH;
576
577                                 memset(pMultipart->pBody->body.pBinary, 0, size);
578                         }
579
580                         memcpy(pMultipart->pBody->body.pBinary, pData, size);
581                         pMultipart->pBody->size = size;
582                 }
583         } else {
584                 if (szOrgFilePath)
585                         strncpy(pMultipart->pBody->szOrgFilePath, szOrgFilePath, MSG_FILEPATH_LEN_MAX - 1);
586
587                 pMultipart->pBody->offset = offset;
588                 pMultipart->pBody->size = size;
589         }
590
591         return pMultipart;
592
593 __CATCH:
594
595         if (pMultipart) {
596                 if (pMultipart->pBody) {
597                         if (pMultipart->pBody->body.pText) {
598                                 free(pMultipart->pBody->body.pText);
599                                 pMultipart->pBody->body.pText = NULL;
600                         }
601                         free(pMultipart->pBody);
602                         pMultipart->pBody = NULL;
603                 }
604                 free(pMultipart);
605                 pMultipart = NULL;
606         }
607
608         return NULL;
609 }
610
611
612 bool MmsGetTypeByFileName(int *type, char *szFileName)
613 {
614         char *pExt   = NULL;
615         AvCodecType AvType = AV_CODEC_NONE;
616
617         /* AVMS unknown or text/image file format identify type from file extention  */
618
619         pExt = strrchr(szFileName, '.');
620         if (pExt == NULL || pExt[0] == '\0')
621                 goto __CATCH;
622
623         pExt++;
624
625         if (strcasecmp(pExt, "mp4") == 0 || strcasecmp(pExt, "mpeg4") == 0 ||
626                 strcasecmp(pExt, "3gp") == 0 || strcasecmp(pExt, "3gpp") == 0) {
627                 /* Audio / Video format. If file exists already, AvGetFileCodecType() can identify the format  */
628                 if (szFileName[0] != '/')
629                         goto __CATCH;
630
631                 AvType = AvGetFileCodecType(szFileName);
632
633                 switch (AvType) {
634                 case AV_DEC_AUDIO_MPEG4:
635                         *type = MIME_AUDIO_MP4;//*type = MIME_AUDIO_3GPP;
636                         break;
637
638                 case AV_DEC_VIDEO_MPEG4:
639                         *type = MIME_VIDEO_MP4;
640                         break;
641
642                 default:
643                         *type = MIME_VIDEO_3GPP;
644                         break;
645                 }
646                 return true;
647         }
648
649         if (strcasecmp(pExt, "amr") == 0) {
650                 *type = MIME_AUDIO_AMR;
651                 return true;
652         } else if ((strcasecmp(pExt, "mid") == 0) || (strcasecmp(pExt, "midi") == 0)) {
653                 *type = MIME_AUDIO_MIDI;
654                 return true;
655         } else if (strcasecmp(pExt, "imy") == 0) {
656                 *type = MIME_TEXT_X_IMELODY;
657                 return true;
658         }
659
660         *type = MimeGetMimeFromExtInt((const char *)pExt);
661
662         return true;
663
664 __CATCH:
665
666         *type = MIME_UNKNOWN;
667         return false;
668
669 }
670
671 bool MmsComposeMessage(MmsMsg *pMmsMsg, MSG_MESSAGE_INFO_S *pMsgInfo, MSG_SENDINGOPT_INFO_S *pSendOptInfo, MMS_MESSAGE_DATA_S *pMsgData, char *pFileData)
672 {
673         MSG_BEGIN();
674
675         char *pRawData = NULL;
676         AutoPtr<char> buf(&pRawData);
677
678         struct tm *timeInfo = NULL;
679         time_t RawTime = 0;
680         time_t nTimeInSecs = 0;
681
682         msg_error_t     err = MSG_SUCCESS;
683
684         // Initialize mmsMsg structure
685         MmsInitMsgAttrib(&pMmsMsg->mmsAttrib);
686         MmsInitMsgType(&pMmsMsg->msgType);
687         MmsInitMsgBody(&pMmsMsg->msgBody);
688
689         // setting mmsMsg structure
690         pMmsMsg->mailbox = pMsgInfo->folderId;
691         pMmsMsg->msgID = pMsgInfo->msgId;
692
693         memset(pMmsMsg->szTrID, 0, MMS_TR_ID_LEN + 1);
694         memset(pMmsMsg->szContentLocation, 0, MMS_LOCATION_LEN + 1);
695         memset(pMmsMsg->szMsgID, 0, MMS_MSG_ID_LEN + 1);
696         memset(pMmsMsg->szForwardMsgID, 0, MMS_MSG_ID_LEN + 1);
697
698         pMmsMsg->mmsAttrib.dataType = MMS_DATATYPE_DRAFT;
699
700         MSG_DEBUG("## delivery = %d ##", pSendOptInfo->bDeliverReq);
701         MSG_DEBUG("## read = %d ##", pSendOptInfo->option.mmsSendOptInfo.bReadReq);
702         MSG_DEBUG("## priority = %d ##", pSendOptInfo->option.mmsSendOptInfo.priority);
703         MSG_DEBUG("## expiryTime = %d ##", pSendOptInfo->option.mmsSendOptInfo.expiryTime.time);
704
705         if (pSendOptInfo->bSetting == false) {
706                 unsigned int expiryTime;
707                 MSG_MMS_DELIVERY_TIME_T deliveryTime;
708
709                 pMmsMsg->mmsAttrib.priority = (MmsPriority)MsgSettingGetInt(MMS_SEND_PRIORITY);
710
711                 MsgSettingGetBool(MMS_SEND_DELIVERY_REPORT, &pMmsMsg->mmsAttrib.bAskDeliveryReport);
712                 MsgSettingGetBool(MMS_SEND_READ_REPLY, &pMmsMsg->mmsAttrib.bAskReadReply);
713                 MsgSettingGetBool(MSG_KEEP_COPY, &pMmsMsg->mmsAttrib.bLeaveCopy);
714
715                 expiryTime = (unsigned int)MsgSettingGetInt(MMS_SEND_EXPIRY_TIME);
716
717                 if (expiryTime == 0)
718                         pMmsMsg->mmsAttrib.expiryTime.type = MMS_TIMETYPE_NONE;
719                 else {
720                         pMmsMsg->mmsAttrib.expiryTime.type = MMS_TIMETYPE_RELATIVE;
721                         pMmsMsg->mmsAttrib.expiryTime.time = expiryTime;
722                 }
723
724                 deliveryTime = (MSG_MMS_DELIVERY_TIME_T)MsgSettingGetInt(MMS_SEND_DELIVERY_TIME);
725
726                 if (deliveryTime == MSG_DELIVERY_TIME_CUSTOM) {
727                         pMmsMsg->mmsAttrib.bUseDeliveryCustomTime = true;
728
729                         pMmsMsg->mmsAttrib.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
730                         pMmsMsg->mmsAttrib.deliveryTime.time = (unsigned int)MsgSettingGetInt(MMS_SEND_CUSTOM_DELIVERY);
731                 } else {
732                         pMmsMsg->mmsAttrib.bUseDeliveryCustomTime = false;
733
734                         pMmsMsg->mmsAttrib.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
735                         pMmsMsg->mmsAttrib.deliveryTime.time = (unsigned int)deliveryTime;
736                 }
737         } else {
738                 pMmsMsg->mmsAttrib.priority = (MmsPriority)pSendOptInfo->option.mmsSendOptInfo.priority;
739                 pMmsMsg->mmsAttrib.bAskDeliveryReport = pSendOptInfo->bDeliverReq;
740                 pMmsMsg->mmsAttrib.bAskReadReply = pSendOptInfo->option.mmsSendOptInfo.bReadReq;
741                 pMmsMsg->mmsAttrib.expiryTime.type = pSendOptInfo->option.mmsSendOptInfo.expiryTime.type;
742                 pMmsMsg->mmsAttrib.bLeaveCopy = pSendOptInfo->bKeepCopy;
743
744                 if (pMmsMsg->mmsAttrib.expiryTime.type != MMS_TIMETYPE_NONE)
745                         pMmsMsg->mmsAttrib.expiryTime.time = pSendOptInfo->option.mmsSendOptInfo.expiryTime.time;
746
747                 pMmsMsg->mmsAttrib.bUseDeliveryCustomTime = pSendOptInfo->option.mmsSendOptInfo.bUseDeliveryCustomTime;
748                 pMmsMsg->mmsAttrib.deliveryTime.type = pSendOptInfo->option.mmsSendOptInfo.deliveryTime.type;
749                 pMmsMsg->mmsAttrib.deliveryTime.time = pSendOptInfo->option.mmsSendOptInfo.deliveryTime.time;
750         }
751
752         MSG_DEBUG("pSendOptInfo->bSetting = %d", pSendOptInfo->bSetting);
753         MSG_DEBUG("pMmsMsg->mmsAttrib.bLeaveCopy = %d", pMmsMsg->mmsAttrib.bLeaveCopy);
754         MSG_DEBUG("pMmsMsg->mmsAttrib.bUseDeliveryCustomTime = %d", pMmsMsg->mmsAttrib.bUseDeliveryCustomTime);
755         MSG_DEBUG("pMmsMsg->mmsAttrib.deliveryTime.type = %d", pMmsMsg->mmsAttrib.deliveryTime.type);
756         MSG_DEBUG("pMmsMsg->mmsAttrib.deliveryTime.time = %d", pMmsMsg->mmsAttrib.deliveryTime.time);
757
758         /* MMS-1.3-con-739 */
759         pMmsMsg->mmsAttrib.msgClass = (MmsMsgClass)MsgSettingGetInt(MMS_SEND_MSG_CLASS);
760         /* MMS-1.3-con-739 */
761 #ifdef MMS_13_CON_742_ENABLED
762         /* MMS-1.3-con-742 */
763         pMmsMsg->mmsAttrib.deliveryTime.time = (unsigned int)MsgSettingGetInt(MMS_SEND_DELIVERY_TIME);
764         /* MMS-1.3-con-742 */
765 #endif
766
767         MSG_DEBUG("@@@ pMmsMsg->mmsAttrib.bAskDeliveryReport = %d @@@", pMmsMsg->mmsAttrib.bAskDeliveryReport);
768         MSG_DEBUG("@@@ pMmsMsg->mmsAttrib.bAskReadReply = %d @@@", pMmsMsg->mmsAttrib.bAskReadReply);
769         MSG_DEBUG("@@@ pMmsMsg->mmsAttrib.priority = %d @@@", pMmsMsg->mmsAttrib.priority);
770
771         // setting date
772         time(&RawTime);
773         timeInfo = localtime(&RawTime);
774         nTimeInSecs = mktime(timeInfo);
775         pMmsMsg->mmsAttrib.date = nTimeInSecs;  // todo: need to subtract timeline value to make GMT+0 time
776
777         //setting subject
778         strcpy(pMmsMsg->mmsAttrib.szSubject, pMsgInfo->subject);
779
780         //setting adddress
781         MmsSetMsgAddressList(&pMmsMsg->mmsAttrib, pMsgInfo);
782         MmsGetMsgBodyfromMsgInfo(pMsgInfo, pMsgData, pFileData);
783
784         int pageCnt = _MsgMmsGetPageCount(pMsgData);
785
786         if (pageCnt == 0) {     // Multipart mixed
787                 pMmsMsg->mmsAttrib.contentType = MIME_APPLICATION_VND_WAP_MULTIPART_MIXED;
788                 pMmsMsg->msgType.type = MIME_APPLICATION_VND_WAP_MULTIPART_MIXED;
789                 MmsMakePreviewInfo(pMsgInfo->msgId, pMsgData);
790         } else {        // Multipart related
791
792                 int RawDataSize = 0;
793
794                 time_t RawTime = 0;
795                 time(&RawTime);
796                 snprintf(pMsgData->szSmilFilePath, MSG_FILEPATH_LEN_MAX, "%lu", RawTime);
797
798                 MsgMMSCreateSMIL(pMsgData);
799
800                 RawDataSize = MmsGetSmilRawData(pMsgData, &pRawData);
801                 if (RawDataSize < 0) {
802                         MSG_DEBUG("Smil file size is less than 0");
803                         return false;
804                 }
805                 MSG_DEBUG("%s", pRawData);
806                 if (pRawData)
807                         MmsInsertPresentation(pMmsMsg, MIME_APPLICATION_SMIL, pRawData, strlen(pRawData));
808
809                 pMmsMsg->mmsAttrib.contentType = MIME_APPLICATION_VND_WAP_MULTIPART_RELATED;
810                 pMmsMsg->msgType.type = MIME_APPLICATION_VND_WAP_MULTIPART_RELATED;
811
812                 for (int i = 0; i < pageCnt; ++i) {
813                         MMS_PAGE_S *pPage = _MsgMmsGetPage(pMsgData, i);
814                         int mediaCnt = pPage->mediaCnt;
815                         MSG_DEBUG("PAGE %d's media Cnt: %d", i+1, mediaCnt);
816
817                         for (int j = 0; j < mediaCnt; ++j) {
818                                 MMS_MEDIA_S *pMedia = _MsgMmsGetMedia(pPage, j);
819
820                                 switch (pMedia->mediatype) {
821                                 case MMS_SMIL_MEDIA_IMG:
822                                 case MMS_SMIL_MEDIA_VIDEO:
823                                 case MMS_SMIL_MEDIA_AUDIO:
824                                 case MMS_SMIL_MEDIA_TEXT:
825                                         if (pMedia->szFilePath[0] != 0) {
826                                                 if (!MmsInsertPartFromFile(pMmsMsg, pMedia->szFileName, pMedia->szFilePath, pMedia->szContentID))
827                                                         return false;
828                                         }
829                                         break;
830
831                                 default:
832                                         break;
833                                 }
834                         }
835                 }
836
837                 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, };;
838                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%d.mms", pMsgInfo->msgId);
839
840                 MmsPluginStorage *pStorage = MmsPluginStorage::instance();
841                 err = pStorage->getMsgText(pMsgData, pMsgInfo->msgText);
842                 MmsMakePreviewInfo(pMsgInfo->msgId, pMsgData);
843         }
844
845 #ifdef FEATURE_JAVA_MMS
846         MSG_DEBUG("msgAppId: valid:%d appId:%s replyToAppId:%s", pMsgData->msgAppId.valid, pMsgData->msgAppId.appId, pMsgData->msgAppId.replyToAppId);
847         if (pMsgData->msgAppId.valid) { // check if msgAppId.valid is true, both appId and replytoappId must have a meaning data
848                 if (pMsgData->msgAppId.appId[0] != 0) {
849                         pMmsMsg->msgType.param.szApplicationID = (char *)malloc(strlen(pMsgData->msgAppId.appId) + 1);
850                         if (pMmsMsg->msgType.param.szApplicationID == NULL) {
851                                 MSG_DEBUG("Error: out of Memory");
852                                 return false;
853                         }
854                         memset(pMmsMsg->msgType.param.szApplicationID, 0, strlen(pMsgData->msgAppId.appId) + 1);
855
856                         strcpy(pMmsMsg->msgType.param.szApplicationID, pMsgData->msgAppId.appId);
857                 }
858
859                 if (pMsgData->msgAppId.replyToAppId[0] != 0) {
860                         pMmsMsg->msgType.param.szReplyToApplicationID = (char *)malloc(strlen(pMsgData->msgAppId.replyToAppId) + 1);
861                         if (pMmsMsg->msgType.param.szReplyToApplicationID == NULL) {
862                                 MSG_DEBUG("Error: out of Memory");
863                                 return false;
864                         }
865                         memset(pMmsMsg->msgType.param.szReplyToApplicationID, 0, strlen(pMsgData->msgAppId.replyToAppId) + 1);
866
867                         strcpy(pMmsMsg->msgType.param.szReplyToApplicationID, pMsgData->msgAppId.replyToAppId);
868                 }
869         }
870 #endif
871
872         //Processing Attachment List
873         for (int i = 0; i < _MsgMmsGetAttachCount(pMsgData); ++i) {
874                 MMS_ATTACH_S *pMedia = _MsgMmsGetAttachment(pMsgData, i);
875                 if (pMedia->szFilePath[0] != 0) {
876                         if (!MmsInsertPartFromFile(pMmsMsg, pMedia->szFileName, pMedia->szFilePath, NULL)) {
877                                 free(pMedia);
878                                 return false;
879                         }
880                 }
881         }
882
883         return true;
884 }
885
886 void MmsComposeNotiMessage(MmsMsg *pMmsMsg, msg_message_id_t msgID)
887 {
888         MSG_BEGIN();
889
890         struct tm *timeInfo = NULL;
891         time_t RawTime = 0;
892         time_t nTimeInSecs = 0;
893
894         MmsInitMsgAttrib(&pMmsMsg->mmsAttrib);
895         MmsInitMsgType(&pMmsMsg->msgType);
896         MmsInitMsgBody(&pMmsMsg->msgBody);
897
898         pMmsMsg->msgID = msgID;
899
900         pMmsMsg->mmsAttrib.version = mmsHeader.version;
901
902         // setting date
903         time(&RawTime);
904         timeInfo = localtime(&RawTime);
905         nTimeInSecs = mktime(timeInfo);
906         pMmsMsg->mmsAttrib.date = nTimeInSecs;
907
908         pMmsMsg->mmsAttrib.bReportAllowed = mmsHeader.reportAllowed;
909         pMmsMsg->mmsAttrib.bAskDeliveryReport = mmsHeader.deliveryReport;
910
911         MSG_DEBUG("######## Version = %d ########", pMmsMsg->mmsAttrib.version);
912
913         strncpy(pMmsMsg->szTrID, mmsHeader.szTrID, MMS_TR_ID_LEN);
914         strncpy(pMmsMsg->szMsgID, mmsHeader.szMsgID, MMS_MSG_ID_LEN);
915         pMmsMsg->szForwardMsgID[0] = '\0';
916
917         if (mmsHeader.pFrom) {
918                 MmsAddrUtilRemovePlmnString(mmsHeader.pFrom->szAddr );
919                 strncpy(pMmsMsg->mmsAttrib.szFrom, mmsHeader.pFrom->szAddr, MSG_LOCALE_ADDR_LEN + 9);
920         }
921
922         strncpy(pMmsMsg->mmsAttrib.szSubject, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN);
923         strncpy(pMmsMsg->szContentLocation, mmsHeader.szContentLocation, MMS_LOCATION_LEN);
924
925         pMmsMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
926         pMmsMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
927         pMmsMsg->mmsAttrib.expiryTime.type = mmsHeader.expiryTime.type;
928         pMmsMsg->mmsAttrib.expiryTime.time = mmsHeader.expiryTime.time;
929         pMmsMsg->mmsAttrib.dataType = MMS_DATATYPE_NOTIFY;
930         pMmsMsg->mmsAttrib.bRead = false;
931         pMmsMsg->mailbox = MSG_INBOX_ID;
932
933         pMmsMsg->mmsAttrib.replyCharge.chargeType = mmsHeader.replyCharge.chargeType;
934         pMmsMsg->mmsAttrib.replyCharge.deadLine.type = mmsHeader.replyCharge.deadLine.type;
935         pMmsMsg->mmsAttrib.replyCharge.deadLine.time = mmsHeader.replyCharge.deadLine.time;
936         pMmsMsg->mmsAttrib.replyCharge.chargeSize = mmsHeader.replyCharge.chargeSize;
937
938         strncpy(pMmsMsg->mmsAttrib.replyCharge.szChargeID, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN);
939
940         MSG_END();
941 }
942
943 bool MmsGetMmsMessageBody(MmsMsg *pMmsMsg, char *retrievedFilePath)
944 {
945         FILE *pFile     = NULL;
946         MsgMultipart *pMultipart = NULL;
947         int attachmax = MSG_ATTACH_MAX;
948         int nSize = 0;
949
950         /*      read from MMS raw file  */
951         if (retrievedFilePath)
952                 strncpy(pMmsMsg->szFileName, retrievedFilePath + strlen(MSG_DATA_PATH), strlen(retrievedFilePath + strlen(MSG_DATA_PATH)));
953         else
954                 goto __CATCH;
955
956         pFile = MsgOpenFile(retrievedFilePath, "rb");
957
958         if (pFile == NULL) {
959                 MSG_DEBUG( "_MmsReadMsgBody: invalid mailbox\n");
960                 goto __CATCH;
961         }
962
963         if (MsgGetFileSize(retrievedFilePath, &nSize) == false) {
964                 MSG_DEBUG("MsgGetFileSize: failed");
965                 goto __CATCH;
966         }
967
968         _MmsRegisterDecodeBuffer(gszMmsLoadBuf1,
969                                                           gszMmsLoadBuf2,
970                                                           MSG_MMS_DECODE_BUFFER_MAX);
971
972         if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
973                 MSG_DEBUG( "_MmsReadMsgBody: MmsBinaryDecodeMsgHeader fail...\n");
974                 goto __CATCH;
975         }
976
977         if (MmsBinaryDecodeMsgBody(pFile, retrievedFilePath, nSize) == false) {
978                 MSG_DEBUG( "_MmsReadMsgBody: MmsBinaryDecodeMsgBody fail\n");
979                 goto __CATCH;
980         }
981
982         /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
983
984         pMmsMsg->mmsAttrib.contentType = (MsgContentType)mmsHeader.msgType.type;
985
986         memcpy(&(pMmsMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
987         memcpy(&(pMmsMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
988
989         MSG_DEBUG("#############################");
990         MSG_DEBUG("## pMmsMsg->msgType.type = %d ##", pMmsMsg->msgType.type);
991         MSG_DEBUG("## pMmsMsg->msgType.szContentID = %s ##", pMmsMsg->msgType.szContentID);
992         MSG_DEBUG("## pMmsMsg->msgType.szContentLocation = %s ##", pMmsMsg->msgType.szContentLocation);
993         MSG_DEBUG("#############################");
994
995         if (pMmsMsg->msgBody.pPresentationBody) {
996                 if(MsgFseek(pFile, pMmsMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
997                         goto __CATCH;
998
999                 pMmsMsg->msgBody.pPresentationBody->body.pText = (char *)malloc(pMmsMsg->msgBody.pPresentationBody->size + 1);
1000                 if (pMmsMsg->msgBody.pPresentationBody->body.pText == NULL)
1001                         goto __CATCH;
1002
1003                 memset(pMmsMsg->msgBody.pPresentationBody->body.pText, 0, pMmsMsg->msgBody.pPresentationBody->size + 1);
1004                 ULONG nRead = 0;
1005                 nRead = MsgReadFile(pMmsMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMmsMsg->msgBody.pPresentationBody->size, pFile);
1006
1007                 if (nRead == 0)
1008                         goto __CATCH;
1009         }
1010
1011         MsgCloseFile(pFile);
1012         pFile = NULL;
1013
1014         /* nPartCount */
1015         pMmsMsg->nPartCount = 0;
1016
1017         if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
1018                 pMultipart = pMmsMsg->msgBody.body.pMultipart;
1019                 while (pMultipart) {
1020                         pMmsMsg->nPartCount++;
1021
1022                         if (pMultipart->type.type == MIME_TEXT_PLAIN)
1023                                 attachmax++;
1024
1025                         if ((mmsHeader.msgType.type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED) ||
1026                                 (mmsHeader.msgType.type == MIME_MULTIPART_MIXED)) {
1027                                 if ((pMmsMsg->nPartCount >= attachmax ) && (pMultipart->pNext != NULL)) {
1028                                         _MsgFreeBody(pMultipart->pNext->pBody, pMultipart->pNext->type.type);
1029
1030                                         free(pMultipart->pNext->pBody);
1031                                         pMultipart->pNext->pBody = NULL;
1032
1033                                         free(pMultipart->pNext);
1034
1035                                         pMultipart->pNext = NULL;
1036                                         break;
1037                                 }
1038                         }
1039                         pMultipart = pMultipart->pNext;
1040                 }
1041         } else {
1042                 if (pMmsMsg->msgBody.size > 0)
1043                         pMmsMsg->nPartCount++;
1044         }
1045
1046         //call before processing urgent event.
1047         _MmsInitHeader();
1048         _MmsUnregisterDecodeBuffer();
1049
1050         return true;
1051
1052 __CATCH:
1053
1054         _MmsInitHeader();
1055         _MmsUnregisterDecodeBuffer();
1056
1057         if (pFile != NULL) {
1058                 MsgCloseFile(pFile);
1059                 pFile = NULL;
1060         }
1061
1062         _MsgFreeBody(&pMmsMsg->msgBody, pMmsMsg->msgType.type);
1063         MSG_DEBUG("_MmsReadMsgBody:    E  N  D    ( fail )    ******************** \n");
1064
1065         return false;
1066 }
1067
1068 #ifdef MMS_DELIEVERY_IND_ENABLED
1069 MmsMsgMultiStatus *MmsComposeDeliveryIndMessage(MmsMsg *pMmsMsg, msg_message_id_t msgId)
1070 {
1071         MmsMsgMultiStatus *pStatus = NULL;
1072         MmsMsgMultiStatus *pLastStatus = NULL;
1073         bool bFound = false;
1074
1075         MmsInitMsgAttrib(&pMmsMsg->mmsAttrib);
1076         MmsInitMsgType(&pMmsMsg->msgType);
1077         MmsInitMsgBody(&pMmsMsg->msgBody);
1078
1079         pMmsMsg->mmsAttrib.version = mmsHeader.version;
1080
1081         pMmsMsg->mmsAttrib.pMultiStatus = MmsGetMultiStatus(msgId);
1082
1083         pStatus = pMmsMsg->mmsAttrib.pMultiStatus;
1084
1085         MSG_DEBUG("### pStatus->szTo = %s ###", pStatus->szTo);
1086
1087         while (pStatus && !bFound) {
1088                 MSG_DEBUG("### MmsAddrUtilCompareAddr ###");
1089                 MSG_DEBUG("### mmsHeader.pTo->szAddr = %s ###", mmsHeader.pTo->szAddr);
1090                 if (MmsAddrUtilCompareAddr(pStatus->szTo, mmsHeader.pTo->szAddr)) {
1091                         bFound = true;
1092                         break;
1093                 }
1094
1095                 pStatus = pStatus->pNext;
1096         }
1097
1098         if (bFound == false) {
1099                 MSG_DEBUG("### bFound == false ###");
1100                 /* Queue the delivery report  --------------------------- */
1101
1102                 pStatus = (MmsMsgMultiStatus *)malloc(sizeof(MmsMsgMultiStatus));
1103                 memset(pStatus, 0, sizeof(MmsMsgMultiStatus));
1104
1105                 pStatus->readStatus = MMS_READSTATUS_NONE;
1106
1107                 memset(pStatus->szTo, 0, MSG_ADDR_LEN + 1);
1108                 strncpy(pStatus->szTo, mmsHeader.pTo->szAddr, MSG_ADDR_LEN);
1109
1110                 if (pMmsMsg->mmsAttrib.pMultiStatus == NULL) {
1111                         /* first delivery report */
1112                         pMmsMsg->mmsAttrib.pMultiStatus = pStatus;
1113                 } else {
1114                         pLastStatus = pMmsMsg->mmsAttrib.pMultiStatus;
1115                         while (pLastStatus->pNext) {
1116                                 pLastStatus = pLastStatus->pNext;
1117                         }
1118
1119                         pLastStatus->pNext = pStatus;
1120                         pLastStatus = pStatus;
1121                 }
1122         }
1123
1124         pStatus->handledTime = mmsHeader.date;
1125         pStatus->msgStatus = mmsHeader.msgStatus;
1126         pStatus->bDeliveryReportIsRead = false;
1127
1128         _MmsDataUpdateLastStatus(pMmsMsg);
1129
1130         pStatus->bDeliveyrReportIsLast = true;
1131
1132         return pStatus;
1133 }
1134 #endif
1135
1136 void MmsComposeReadReportMessage(MmsMsg *pMmsMsg, const MSG_MESSAGE_INFO_S *pMsgInfo, msg_message_id_t selectedMsgId)
1137 {
1138         struct tm *timeInfo = NULL;
1139         time_t RawTime = 0;
1140         time_t nTimeInSecs = 0;
1141
1142         MmsInitMsgAttrib(&pMmsMsg->mmsAttrib);
1143         MmsInitMsgType(&pMmsMsg->msgType);
1144         MmsInitMsgBody(&pMmsMsg->msgBody);
1145
1146         // setting mmsMsg structure
1147         pMmsMsg->mailbox = pMsgInfo->folderId;
1148         pMmsMsg->msgID = pMsgInfo->msgId;
1149
1150         memset(pMmsMsg->szTrID, 0, MMS_TR_ID_LEN + 1);
1151         memset(pMmsMsg->szContentLocation, 0, MMS_LOCATION_LEN + 1);
1152         memset(pMmsMsg->szForwardMsgID, 0, MMS_MSG_ID_LEN + 1);
1153
1154         pMmsMsg->mmsAttrib.dataType = MMS_DATATYPE_DRAFT;
1155
1156         // setting date
1157         time(&RawTime);
1158         timeInfo = localtime(&RawTime);
1159         nTimeInSecs = mktime(timeInfo);
1160         pMmsMsg->mmsAttrib.date = nTimeInSecs;
1161
1162         // setting szMsgId
1163         MmsPluginStorage::instance()->getMmsMessageId(selectedMsgId, pMmsMsg);
1164
1165         //setting subject
1166         strcpy(pMmsMsg->mmsAttrib.szSubject, pMsgInfo->subject);
1167
1168         //setting adddress
1169         MmsSetMsgAddressList(&pMmsMsg->mmsAttrib, pMsgInfo);
1170
1171         if (pMmsMsg->mmsAttrib.szTo)
1172                 strncpy(pMmsMsg->mmsAttrib.szFrom, pMmsMsg->mmsAttrib.szTo, strlen(pMmsMsg->mmsAttrib.szTo));
1173 }
1174
1175 int MmsSearchMsgId(char *toNumber, char *szMsgID)
1176 {
1177         MSG_BEGIN();
1178
1179         int msgId;
1180
1181         msgId = MmsPluginStorage::instance()->searchMsgId(toNumber, szMsgID);
1182
1183         if (msgId < 0)
1184                 return 0;
1185
1186         MSG_END();
1187
1188         return msgId;
1189 }
1190
1191 MmsMsgMultiStatus *MmsGetMultiStatus(msg_message_id_t msgId)
1192 {
1193         MmsMsgMultiStatus *pMultiStatus;
1194
1195         pMultiStatus = MmsPluginStorage::instance()->getMultiStatus(msgId);
1196
1197         MSG_DEBUG("### szTo = %s ###", pMultiStatus->szTo);
1198
1199         MSG_END();
1200
1201         return pMultiStatus;
1202 }
1203
1204 bool MmsCheckAdditionalMedia(MMS_MESSAGE_DATA_S *pMsgData, MsgType *partHeader)
1205 {
1206         if (_MsgMmsFindMatchedMedia(pMsgData, partHeader->param.szFileName))
1207                 return false;
1208         else
1209                 return true;
1210 }
1211
1212 /*PIM objects SHALL be supported as attachments to an MM*/
1213 bool MmsRemovePims(MMS_MESSAGE_DATA_S *pMsgData)
1214 {
1215         GList *cur_page = NULL;
1216         GList *cur_media = NULL;
1217
1218         if (pMsgData == NULL)
1219                 return false;
1220
1221         cur_page = pMsgData->pagelist;
1222
1223         while(cur_page) {
1224                 MMS_PAGE_S *page = (MMS_PAGE_S *)cur_page->data;
1225                 if (page) {
1226                         cur_media = page->medialist;
1227
1228                         while(cur_media) {
1229                                 MMS_MEDIA_S *pMedia = (MMS_MEDIA_S *)cur_media->data;
1230                                 if (pMedia) {
1231                                         int tempType;
1232                                         MsgGetTypeByFileName(&tempType, pMedia->szFilePath);
1233                                         if (tempType == MIME_TEXT_X_VCALENDAR || tempType == MIME_TEXT_X_VCARD) {
1234                                                 page->medialist = g_list_remove_all(page->medialist, pMedia);
1235                                                 page->mediaCnt = g_list_length(page->medialist);
1236                                                 cur_media = page->medialist;
1237                                                 free(pMedia);
1238                                         } else {
1239                                                 cur_media =  g_list_next(cur_media);
1240                                         }
1241                                 } else {
1242                                         cur_media =  g_list_next(cur_media);
1243                                 }
1244                         } //cur_media while for remove pims file in list
1245
1246                         if (page->medialist == NULL) {//remove empty page
1247                                 pMsgData->pagelist = g_list_remove_all(pMsgData->pagelist, page);
1248                                 pMsgData->pageCnt = g_list_length(pMsgData->pagelist);
1249                                 cur_page = pMsgData->pagelist;
1250                                 free(page);
1251                         } else {
1252                                 cur_page =  g_list_next(cur_page);
1253                         }
1254                 }
1255         }//cur_page while
1256
1257
1258         return true;
1259 }
1260
1261
1262 #ifdef __SUPPORT_DRM__
1263 bool __MsgInitMsgDRMInfo(MsgDRMInfo *pMsgDrmInfo)
1264 {
1265         pMsgDrmInfo->contentType = MIME_UNKNOWN;
1266         pMsgDrmInfo->drmType = MSG_DRM_TYPE_NONE;
1267
1268         pMsgDrmInfo->szContentName = NULL;
1269         pMsgDrmInfo->szContentURI = NULL;
1270         pMsgDrmInfo->szContentDescription = NULL;
1271         pMsgDrmInfo->szContentVendor = NULL;
1272         pMsgDrmInfo->szRightIssuer = NULL;
1273         pMsgDrmInfo->szDrm2FullPath = NULL;
1274         pMsgDrmInfo->roWaitingTimerMax = 0;
1275         pMsgDrmInfo->bFwdLock = false;
1276         pMsgDrmInfo->bNoScreen = false;
1277         pMsgDrmInfo->bNoRingTone = false;
1278         pMsgDrmInfo->pszContentType = NULL;
1279
1280         return true;
1281 }
1282 #endif
1283
1284 msg_error_t MmsMakePreviewInfo(int msgId, MMS_MESSAGE_DATA_S *pMmsMsg)
1285 {
1286         MMS_PAGE_S *pPage = NULL;
1287         MMS_MEDIA_S *pMedia = NULL;
1288
1289         if (pMmsMsg == NULL)
1290                 return MSG_ERR_NULL_POINTER;
1291
1292         if (pMmsMsg->pageCnt > 0) {
1293
1294                 MmsPluginStorage::instance()->insertPreviewInfo(msgId, MSG_MMS_ITEM_TYPE_PAGE, (char *)"pagecount", pMmsMsg->pageCnt);
1295
1296                 pPage = _MsgMmsGetPage(pMmsMsg, 0);
1297                 for (int j = 0; j < pPage->mediaCnt; j++) {
1298
1299                         pMedia = _MsgMmsGetMedia(pPage, j);
1300                         MSG_DEBUG("pMedia's Name: %s", pMedia->szFilePath);
1301
1302                         if (pMedia->mediatype == MMS_SMIL_MEDIA_IMG || pMedia->mediatype == MMS_SMIL_MEDIA_VIDEO) {
1303                                 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, };
1304                                 char thumbPath[MSG_FILEPATH_LEN_MAX+1] = {0, };
1305
1306                                 memset(szFileName, 0x00, MSG_FILENAME_LEN_MAX+1);
1307                                 memset(thumbPath, 0x00, MSG_FILEPATH_LEN_MAX);
1308
1309                                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%d.mms",msgId);
1310                                 snprintf(thumbPath, MSG_FILEPATH_LEN_MAX, MSG_THUMBNAIL_PATH"/%s.jpg", szFileName);
1311
1312                                 if (pMedia->mediatype == MMS_SMIL_MEDIA_IMG) {
1313                                         if (makeImageThumbnail(pMedia->szFilePath, thumbPath) == true) {
1314                                                 MmsPluginStorage::instance()->insertPreviewInfo(msgId, MSG_MMS_ITEM_TYPE_IMG, thumbPath);
1315                                         } else {
1316                                                 MSG_DEBUG("Fail of generating thumbnail: %s to %s", pMedia->szFilePath, thumbPath);
1317                                         }
1318                                 } else {
1319                                         if (makeVideoThumbnail(pMedia->szFilePath, thumbPath) == true) {;
1320                                                 MmsPluginStorage::instance()->insertPreviewInfo(msgId, MSG_MMS_ITEM_TYPE_VIDEO, thumbPath);
1321                                         } else {
1322                                                 MSG_DEBUG("Fail of generating thumbnail: %s to %s", pMedia->szFilePath, thumbPath);
1323                                         }
1324                                 }
1325
1326                         } else if (pMedia->mediatype == MMS_SMIL_MEDIA_AUDIO) {
1327                                 MmsPluginStorage::instance()->insertPreviewInfo(msgId, MSG_MMS_ITEM_TYPE_AUDIO, pMedia->szFileName);
1328                         }
1329                 }
1330         } else {
1331                 MSG_DEBUG("There is no page");
1332         }
1333
1334         int attachCnt = _MsgMmsGetAttachCount(pMmsMsg);
1335         if (attachCnt > 0) {
1336                 MMS_ATTACH_S *pAttach = _MsgMmsGetAttachment(pMmsMsg, 0);
1337                 MmsPluginStorage::instance()->insertPreviewInfo(msgId, MSG_MMS_ITEM_TYPE_ATTACH, pAttach->szFileName, attachCnt);
1338         } else {
1339                 MSG_DEBUG("There is no attachment");
1340         }
1341
1342         return MSG_SUCCESS;
1343 }