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