RSA sync with private
[platform/core/messaging/msg-service.git] / plugin / mms_plugin / MmsPluginInternal.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 <stdlib.h>
18 #include <errno.h>
19 #include <sys/stat.h>
20
21 #include "MsgDebug.h"
22 #include "MsgUtilFile.h"
23 #include "MsgException.h"
24 #include "MsgMmsMessage.h"
25 #include "MsgTransportTypes.h"
26 #include "MsgGconfWrapper.h"
27 #include "MsgSoundPlayer.h"
28 #include "MsgStorageHandler.h"
29 #include "MmsPluginTypes.h"
30 #include "MmsPluginCodec.h"
31 #include "MmsPluginSetup.h"
32 #include "MmsPluginInternal.h"
33 #include "MmsPluginStorage.h"
34 #include "MmsPluginHttp.h"
35 #include "MmsPluginCodec.h"
36
37 #include "MsgNotificationWrapper.h"
38 #include "MmsPluginSmil.h"
39
40 MmsSetup gMmsSetup;
41
42 /*==================================================================================================
43                                      IMPLEMENTATION OF MmsPluginInternal - Member Functions
44 ==================================================================================================*/
45 MmsPluginInternal *MmsPluginInternal::pInstance = NULL;
46
47
48 MmsPluginInternal::MmsPluginInternal()
49 {
50
51 }
52
53 MmsPluginInternal::~MmsPluginInternal()
54 {
55
56 }
57
58 MmsPluginInternal *MmsPluginInternal::instance()
59 {
60         if (!pInstance)
61                 pInstance = new MmsPluginInternal();
62
63         return pInstance;
64 }
65
66 void MmsPluginInternal::processReceivedInd(MSG_MESSAGE_INFO_S *pMsgInfo, MSG_REQUEST_INFO_S *pRequest, bool *bReject)
67 {
68         MSG_DEBUG("processReceivedInd \r\n");
69
70         FILE *pFile = NULL;
71         char fileName[MSG_FILENAME_LEN_MAX] = {0,};
72
73         if (pMsgInfo->bTextSms == true) {
74                 char fullPath[MAX_FULL_PATH_SIZE+1] = {0,};
75
76                 if(MsgCreateFileName(fileName) == false)
77                         THROW(MsgException::FILE_ERROR, "MsgCreateFileName error");
78
79                 MSG_DEBUG(" File name = %s", fileName);
80
81                 if(MsgWriteIpcFile(fileName, pMsgInfo->msgText, pMsgInfo->dataSize) == false)
82                         THROW(MsgException::FILE_ERROR, "MsgWriteIpcFile error");
83
84                 snprintf(fullPath, MAX_FULL_PATH_SIZE+1, MSG_IPC_DATA_PATH"%s", fileName);
85
86                 memset(pMsgInfo->msgData, 0x00, sizeof(pMsgInfo->msgData));
87                 memcpy(pMsgInfo->msgData, fullPath, strlen(fullPath));
88                 pMsgInfo->bTextSms = false;
89         }
90
91         MSG_DEBUG("MMS File Path = %s", pMsgInfo->msgData);
92
93         _MmsInitHeader();
94         _MmsRegisterDecodeBuffer(gszMmsLoadBuf1,  gszMmsLoadBuf2, MSG_MMS_DECODE_BUFFER_MAX);
95
96         if ((pFile = MsgOpenFile(pMsgInfo->msgData, "rb+")) == NULL) {
97                 MSG_DEBUG("File Open Error: %s", pMsgInfo->msgData);
98         } else {
99                 //Decode Header
100                 if (!MmsBinaryDecodeMsgHeader(pFile, pMsgInfo->dataSize))
101                         MSG_DEBUG("Decoding Header Failed \r\n");
102
103                 MsgDeleteFile(pMsgInfo->msgData + strlen(MSG_IPC_DATA_PATH));
104
105                 switch (mmsHeader.type) {
106                 case MMS_MSGTYPE_NOTIFICATION_IND:
107                         MSG_DEBUG("MmsProcessNewMsgInd: process noti.ind\n");
108                         // For Set Value pMsgInfo
109                         if (processNotiInd(pMsgInfo, pRequest) == false)
110                                 *bReject = true;
111                         else
112                                 *bReject = false;
113                         break;
114
115                 case MMS_MSGTYPE_DELIVERY_IND:
116                         MSG_DEBUG("MmsProcessNewMsgInd: process delivery.ind\n");
117                         // For Set Value pMsgInfo
118                         processDeliveryInd(pMsgInfo);
119                         break;
120
121                 case MMS_MSGTYPE_READORG_IND:
122                         MSG_DEBUG("MmsProcessNewMsgInd: process readorig.ind\n");
123                         processReadOrgInd(pMsgInfo);
124                         break;
125                 default:
126                         break;
127                 }
128
129                 MsgCloseFile(pFile);
130         }
131         //Check Msg Type & Process(Save ...)
132 }
133
134 bool MmsPluginInternal::processNotiInd(MSG_MESSAGE_INFO_S *pMsgInfo, MSG_REQUEST_INFO_S *pRequest)
135 {
136         MSG_DEBUG("MmsProcessNotiInd");
137         msg_error_t     err = MSG_SUCCESS;
138
139         MSG_MMS_HOME_RETRIEVE_TYPE_T retrieveType;
140         bool bReportAllowed;
141
142         MmsAttrib attrib;
143
144         MmsInitMsgAttrib(&attrib);
145
146         pMsgInfo->msgType.mainType = MSG_MMS_TYPE;
147         pMsgInfo->msgType.subType = MSG_NOTIFICATIONIND_MMS;
148         pMsgInfo->priority = mmsHeader.priority;
149         strncpy(pMsgInfo->subject, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN);
150
151         MSG_DEBUG("pMsgInfo->subject [%s]", pMsgInfo->subject);
152
153         if (strlen(pMsgInfo->subject) < 1)
154                 snprintf(pMsgInfo->subject, MAX_SUBJECT_LEN, "MMS Notification Message.");
155
156         attrib.expiryTime = mmsHeader.expiryTime;
157
158         MmsPluginStorage *pStorage = MmsPluginStorage::instance();
159         err = pStorage->updateMmsAttrib(pMsgInfo->msgId, &attrib, pMsgInfo->msgType.subType);
160
161         if (mmsHeader.pFrom) {
162                 MmsAddrUtilRemovePlmnString(mmsHeader.pFrom->szAddr);
163                 // From
164                 strncpy(pMsgInfo->addressList[0].addressVal, mmsHeader.pFrom->szAddr, MAX_ADDRESS_VAL_LEN);
165         }
166
167         int roamState = 0;
168
169         roamState = MsgSettingGetInt(VCONFKEY_TELEPHONY_SVC_ROAM);
170         MsgSettingGetBool(MMS_SEND_REPORT_ALLOWED, &bReportAllowed);
171
172         if (checkRejectNotiInd(roamState, bReportAllowed, pMsgInfo->msgData)) {
173                 MSG_DEBUG("MMS Message Rejected......");
174
175                 pMsgInfo->dataSize = strlen(pMsgInfo->msgData);
176                 pMsgInfo->bTextSms = true;
177                 memcpy(&pRequest->msgInfo, pMsgInfo, sizeof(MSG_MESSAGE_INFO_S));
178
179                 pRequest->msgInfo.msgType.subType = MSG_NOTIFYRESPIND_MMS;
180
181                 return false;
182         }
183
184         if (roamState == VCONFKEY_TELEPHONY_SVC_ROAM_OFF) {
185                 retrieveType = (MSG_MMS_HOME_RETRIEVE_TYPE_T)MsgSettingGetInt(MMS_RECV_HOME_NETWORK);
186                 MSG_DEBUG("$$$$$$$$$$ MMS_RECV_HOME_NETWORK = %d $$$$$$$$$$$$$", retrieveType);
187         } else {
188                 retrieveType = (MSG_MMS_HOME_RETRIEVE_TYPE_T)MsgSettingGetInt(MMS_RECV_ABROAD_NETWORK);
189                 MSG_DEBUG("$$$$$$$$$$ MMS_RECV_ABROAD_NETWORK = %d $$$$$$$$$$$$$", retrieveType);
190
191                 if (retrieveType == MSG_ABROAD_RESTRICTED) {
192                         MSG_DEBUG("MMS Receiving Setting Restricted was selected.");
193                         // m-notify-resp-ind encoding process
194                         memset(pMsgInfo->msgData, 0, MAX_MSG_DATA_LEN + 1);
195
196                         encodeNotifyRespInd(mmsHeader.szTrID, MSG_DELIVERY_REPORT_DEFERRED, bReportAllowed, pMsgInfo->msgData);
197
198                         pMsgInfo->dataSize = strlen(pMsgInfo->msgData);
199                         pMsgInfo->bTextSms = true;
200                         memcpy(&pRequest->msgInfo, pMsgInfo, sizeof(MSG_MESSAGE_INFO_S));
201
202                         pRequest->msgInfo.msgType.subType = MSG_NOTIFYRESPIND_MMS;
203
204                         return true;
205                 }
206         }
207
208         // should send http 'GET'
209         if (retrieveType == MSG_HOME_AUTO_DOWNLOAD || retrieveType == MSG_ABROAD_AUTO_DOWNLOAD) {
210                 MSG_DEBUG("=========== START AUTO RETRIEVE MODE ============");
211                 memset(pMsgInfo->msgData, 0, MAX_MSG_DATA_LEN + 1);
212
213                 memcpy(pMsgInfo->msgData, mmsHeader.szContentLocation, strlen(mmsHeader.szContentLocation)) ;
214
215                 pMsgInfo->dataSize = strlen(pMsgInfo->msgData);
216
217                 pMsgInfo->bTextSms = true;
218
219                 memcpy(&pRequest->msgInfo, pMsgInfo, sizeof(MSG_MESSAGE_INFO_S));
220
221                 pRequest->msgInfo.msgType.subType = MSG_GET_MMS;
222
223                 MSG_DEBUG("MSG SUBTYPE = %d msg data %s bTextsms %d", pRequest->msgInfo.msgType.subType, pRequest->msgInfo.msgData, pRequest->msgInfo.bTextSms);
224         } else {
225         // should send m-notify-resp-ind
226                 MSG_DEBUG("=========== START MANUAL RETRIEVE MODE ===========");
227                 // m-notify-resp-ind encoding process
228                 memset(pMsgInfo->msgData, 0, MAX_MSG_DATA_LEN + 1);
229
230                 if (retrieveType == MSG_HOME_MANUAL || retrieveType == MSG_ABROAD_MANUAL) {
231                         encodeNotifyRespInd(mmsHeader.szTrID, MSG_DELIVERY_REPORT_DEFERRED, bReportAllowed, pMsgInfo->msgData);
232                 }
233
234                 pMsgInfo->dataSize = strlen(pMsgInfo->msgData);
235                 pMsgInfo->bTextSms = true;
236                 memcpy(&pRequest->msgInfo, pMsgInfo, sizeof(MSG_MESSAGE_INFO_S));
237
238                 pRequest->msgInfo.msgType.subType = MSG_NOTIFYRESPIND_MMS;
239         }
240
241         return true;
242 }
243
244 void MmsPluginInternal::processDeliveryInd(MSG_MESSAGE_INFO_S *pMsgInfo)
245 {
246         MSG_BEGIN();
247
248         MmsMsgMultiStatus status;
249         memset(&status, 0x00, sizeof(MmsMsgMultiStatus));
250
251         status.msgStatus = mmsHeader.msgStatus;
252         status.handledTime = mmsHeader.date;
253         status.bDeliveryReportIsRead = false;
254         status.bDeliveyrReportIsLast= true;
255
256         MmsAddrUtilRemovePlmnString(mmsHeader.pTo->szAddr);
257         MSG_DEBUG("[INFO] [ADDR: %s, MMSID: %s]",mmsHeader.pTo->szAddr, mmsHeader.szMsgID);
258
259         pMsgInfo->msgType.mainType      = MSG_MMS_TYPE;
260         pMsgInfo->msgType.subType       = MSG_DELIVERYIND_MMS;
261         pMsgInfo->bTextSms = true;
262         pMsgInfo->dataSize = 0;
263         memset(pMsgInfo->msgData, 0x00, MAX_MSG_DATA_LEN + 1);
264
265         strncpy(pMsgInfo->msgData, getMmsDeliveryStatus(status.msgStatus), MAX_MSG_DATA_LEN);
266         pMsgInfo->dataSize  = strlen(pMsgInfo->msgData);
267         MSG_DEBUG("Delivery Status = %s", pMsgInfo->msgData);
268
269         strncpy(pMsgInfo->addressList[0].addressVal, mmsHeader.pTo->szAddr, MAX_ADDRESS_VAL_LEN);
270
271         int tmpId = (msg_message_id_t)MmsSearchMsgId(mmsHeader.pTo->szAddr, mmsHeader.szMsgID);
272         if (tmpId > 0) {
273                 MSG_DEBUG("Found MSG_ID = %d", tmpId);
274
275                 //Insert to Delievery DB
276                 MmsPluginStorage::instance()->insertDeliveryReport(tmpId, mmsHeader.pTo->szAddr, &status);
277
278                 pMsgInfo->msgId = (msg_message_id_t)tmpId;
279
280         } else {
281                 MSG_DEBUG("Can not find MMS message in DB");
282         }
283
284         MSG_END();
285 }
286
287 void MmsPluginInternal::processReadOrgInd(MSG_MESSAGE_INFO_S *pMsgInfo)
288 {
289         MSG_BEGIN();
290
291         if (pMsgInfo == NULL) {
292                 MSG_DEBUG("parameter err");
293                 return;
294         }
295
296         pMsgInfo->msgType.mainType = MSG_MMS_TYPE;
297         pMsgInfo->msgType.subType = MSG_READORGIND_MMS;
298         pMsgInfo->bTextSms = true;
299
300         MmsAddrUtilRemovePlmnString(mmsHeader.pFrom->szAddr);
301         MmsAddrUtilRemovePlmnString(mmsHeader.pTo->szAddr);
302
303         memset(pMsgInfo->msgData, 0x00, MAX_MSG_DATA_LEN + 1);
304         pMsgInfo->dataSize = 0;
305
306         strncpy(pMsgInfo->msgData, getMmsReadStatus(mmsHeader.readStatus), MAX_MSG_DATA_LEN);
307         pMsgInfo->dataSize  = strlen(pMsgInfo->msgData);
308
309         MSG_DEBUG("read Status = %s", pMsgInfo->msgData);
310         strncpy(pMsgInfo->addressList[0].addressVal, mmsHeader.pFrom->szAddr, MAX_ADDRESS_VAL_LEN);
311
312         int tmpId = MmsSearchMsgId(mmsHeader.pFrom->szAddr, mmsHeader.szMsgID);
313         if (tmpId > 0) {
314                 pMsgInfo->msgId = (msg_message_id_t)tmpId;
315
316                 MmsMsgMultiStatus Status;
317                 memset(&Status, 0x00, sizeof(MmsMsgMultiStatus));
318                 Status.readTime = mmsHeader.date;
319                 Status.readStatus = mmsHeader.readStatus;
320
321                 MmsPluginStorage::instance()->insertReadReport(pMsgInfo->msgId, mmsHeader.pFrom->szAddr, &Status);
322
323         } else {
324                 MSG_DEBUG("Can't not find Message!");
325         }
326
327         MSG_END();
328 }
329
330 void MmsPluginInternal::processSendConf(MSG_MESSAGE_INFO_S *pMsgInfo, mmsTranQEntity *pRequest)
331 {
332         MSG_BEGIN();
333
334         MMS_RECV_DATA_S recvData = {{0}, };
335
336         pMsgInfo->msgId = pRequest->msgId;
337
338         //Set only changed members
339         pMsgInfo->msgType.mainType = MSG_MMS_TYPE;
340         pMsgInfo->msgType.subType = MSG_SENDCONF_MMS;
341
342         pMsgInfo->folderId = MSG_OUTBOX_ID;
343
344         strncpy(pMsgInfo->subject, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN);
345
346         if (mmsHeader.responseStatus == MMS_RESPSTATUS_OK) {
347                 pMsgInfo->networkStatus = MSG_NETWORK_SEND_SUCCESS;
348                 pMsgInfo->dataSize = pRequest->postDataLen;
349         } else {
350                 pMsgInfo->networkStatus = MSG_NETWORK_SEND_FAIL;
351
352                 char responseText[MMS_LOCALE_RESP_TEXT_LEN];
353
354                 memset(responseText, 0x00, MMS_LOCALE_RESP_TEXT_LEN);
355                 snprintf(responseText, MMS_LOCALE_RESP_TEXT_LEN, " %s [%d]", mmsHeader.szResponseText, mmsHeader.responseStatus);
356
357                 memset(pMsgInfo->msgText, 0x00, MAX_MSG_TEXT_LEN + 1);
358                 strncpy(pMsgInfo->msgText, responseText, MMS_LOCALE_RESP_TEXT_LEN);
359         }
360
361         // set message-id from mmsc
362         strncpy(recvData.szMsgID, mmsHeader.szMsgID, MMS_MSG_ID_LEN);
363         strncpy(recvData.szTrID, mmsHeader.szTrID, MMS_TR_ID_LEN);
364
365         memset(pMsgInfo->msgData, 0x00, MAX_MSG_DATA_LEN + 1);
366         memcpy(pMsgInfo->msgData, &recvData, sizeof(MMS_RECV_DATA_S));
367
368         time_t curTime;
369         curTime = time(NULL);
370
371         pMsgInfo->displayTime = curTime;
372
373         MmsMsg *pMsg = NULL;
374         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
375         _MmsInitHeader();
376 #ifdef __SUPPORT_DRM__
377         _MsgFreeDRMInfo(&pMsg->msgType.drmInfo);
378 #endif
379         _MsgFreeBody(&pMsg->msgBody, pMsg->msgType.type);
380
381
382         MSG_END();
383 }
384
385
386 void MmsPluginInternal::processRetrieveConf(MSG_MESSAGE_INFO_S *pMsgInfo, mmsTranQEntity *pRequest, char *pRetrievedFilePath)
387 {
388         MSG_BEGIN();
389
390         int partCnt = 0;
391         int attachCount = 0;
392         MsgType partHeader;
393         bool bMultipartRelated = false;
394
395         msg_error_t err = MSG_SUCCESS;
396         MMS_RECV_DATA_S recvData = {{0}, };
397
398         MmsAttrib attrib;
399
400         MmsInitMsgAttrib(&attrib);
401
402         attrib.priority = mmsHeader.priority;
403         attrib.bAskDeliveryReport = getMmsReport(mmsHeader.deliveryReport);
404         attrib.bAskReadReply = getMmsReport(mmsHeader.readReply);
405
406         //Set only changed members
407         pMsgInfo->msgId = pRequest->msgId;
408         MSG_DEBUG("@@@@@ msgId = %d @@@@@", pMsgInfo->msgId);
409         pMsgInfo->msgType.mainType = MSG_MMS_TYPE;
410
411         if (pRequest->eMmsPduType == eMMS_RETRIEVE_AUTO_CONF)
412                 pMsgInfo->msgType.subType = MSG_RETRIEVE_AUTOCONF_MMS;
413         else
414                 pMsgInfo->msgType.subType = MSG_RETRIEVE_MANUALCONF_MMS;
415
416         strncpy(pMsgInfo->subject, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN);
417
418         strncpy(pRequest->transactionId, mmsHeader.szTrID, MMS_TR_ID_LEN);
419
420         time_t curTime;
421         curTime = time(NULL);
422
423         pMsgInfo->displayTime = curTime;
424
425         if (mmsHeader.retrieveStatus == MMS_RETRSTATUS_OK) {
426                 pMsgInfo->networkStatus = MSG_NETWORK_RETRIEVE_SUCCESS;
427                 pMsgInfo->folderId = MSG_INBOX_ID;
428         } else {
429                 pMsgInfo->networkStatus = MSG_NETWORK_RETRIEVE_FAIL;
430                 pMsgInfo->folderId = MSG_INBOX_ID;
431                 // If failed MMS Retrieve, then saved as MMS Noti Ind Message.
432                 pMsgInfo->msgType.subType = MSG_NOTIFICATIONIND_MMS;
433         }
434
435         pMsgInfo->dataSize = pRequest->getDataLen;
436
437         // set message-id & MMS TPDU file path
438         strcpy(recvData.szMsgID, mmsHeader.szMsgID);
439         if (pRetrievedFilePath)
440                 strncpy(recvData.retrievedFilePath, pRetrievedFilePath, sizeof(recvData.retrievedFilePath));
441
442 #ifdef FEATURE_JAVA_MMS
443         if (mmsHeader.msgType.param.szApplicationID || mmsHeader.msgType.param.szReplyToApplicationID) {
444                 recvData.msgAppId.valid = true;
445                 if (mmsHeader.msgType.param.szApplicationID)
446                         strncpy(recvData.msgAppId.appId, mmsHeader.msgType.param.szApplicationID, sizeof(recvData.msgAppId.appId));
447                 if (mmsHeader.msgType.param.szReplyToApplicationID)
448                         strncpy(recvData.msgAppId.replyToAppId, mmsHeader.msgType.param.szReplyToApplicationID, sizeof(recvData.msgAppId.replyToAppId));
449
450                 char fullPath[MAX_FULL_PATH_SIZE+1] = {0, };
451
452                 char *filename = NULL;
453                 filename = strrchr(pRetrievedFilePath, '/');
454
455                 snprintf(fullPath, MAX_FULL_PATH_SIZE+1, "%s%s", MSG_IPC_DATA_PATH, filename + 1);
456
457                 int ret  = rename(pRetrievedFilePath, fullPath);
458                 if (ret != 0) {
459                         MSG_DEBUG("File rename Error: %s", strerror(errno));
460                 }
461
462                 if (chmod(fullPath, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) != 0) {
463                         MSG_DEBUG("File Write Error: %s", strerror(errno));
464                 }
465
466                 if (chown(fullPath, 0, 6502 ) != 0) {
467                         MSG_DEBUG("File Write Error: %s", strerror(errno));
468                 }
469         }
470 #endif
471         memcpy(pMsgInfo->msgData, &recvData, sizeof(MMS_RECV_DATA_S));
472
473         MSG_DEBUG("@@@@@ MsgData = %s @@@@@", pMsgInfo->msgData);
474         MSG_DEBUG("@@@@@ retrievedFilePath = %s @@@@@", recvData.retrievedFilePath);
475         MSG_DEBUG("@@@@@ szMsgID = %s @@@@@", recvData.szMsgID);
476         //update delivery report, read reply
477
478         MmsPluginStorage *pStorage = MmsPluginStorage::instance();
479
480         MMS_MESSAGE_DATA_S msgData;
481         memset(&msgData, 0, sizeof(MMS_MESSAGE_DATA_S));
482
483         // Conversation is supported only Multipart Related message, Presentation info should be provided
484         if (mmsHeader.msgType.type == MIME_MULTIPART_RELATED || mmsHeader.msgType.type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
485                 char *pSmilDoc = NULL;
486                 MmsMsg *pMsg = NULL;
487                 char szFileName[MSG_FILENAME_LEN_MAX] = {0, };
488
489                 msgData.regionCnt = 0;
490                 msgData.pageCnt = 0;
491                 msgData.attachCnt = 0;
492                 msgData.transitionCnt = 0;
493                 msgData.metaCnt = 0;
494                 memset(msgData.szSmilFilePath, 0, MSG_FILEPATH_LEN_MAX);
495
496                 pSmilDoc = MmsSmilGetPresentationData(pMsgInfo->msgId);
497                 MmsSmilParseSmilDoc(&msgData, pSmilDoc);
498                 MmsRemovePims(&msgData);
499
500                 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
501                 strcpy(szFileName, pMsg->szFileName);
502
503                 err = pStorage->getMsgText(&msgData, pMsgInfo->msgText);
504                 bMultipartRelated = true;
505         } else {
506                 MSG_DEBUG("Multipart mixed message doesn't support mms conversation");
507         }
508
509         err = pStorage->updateMmsAttrib(pMsgInfo->msgId, &attrib, pMsgInfo->msgType.subType);
510
511         partCnt = MmsGetMediaPartCount(pMsgInfo->msgId);
512         MSG_DEBUG("MmsUiGetMediaAttachInfo: partCnt=%d\n", partCnt );
513
514         if (partCnt < 0) {
515                 MSG_DEBUG("MmsUiGetMediaAttachInfo: partCnt=%d\n", partCnt );
516         } else {
517                 for (int i = 0; i < partCnt; ++i) {
518                         if (!MmsGetMediaPartHeader(i, &partHeader)) {
519                                 MSG_DEBUG("MmsUiGetMediaAttachInfo: MmsGetMediaPartHeader failed\n" );
520                                 break;
521                         }
522
523                         if (partHeader.contentSize > 0) {
524                                 char szBuf[MSG_FILEPATH_LEN_MAX];
525
526                                 strcpy((char *)szBuf, partHeader.param.szFileName);
527                                 sprintf(partHeader.param.szFileName, MSG_DATA_PATH"%s", szBuf);
528                                 if (!bMultipartRelated || MmsCheckAdditionalMedia(&msgData, &partHeader)) {
529                                         MMS_ATTACH_S *attachment = NULL;
530                                         int tempType;
531
532                                         attachment = (MMS_ATTACH_S *)calloc(sizeof(MMS_ATTACH_S), 1);
533
534                                         MsgGetTypeByFileName(&tempType, partHeader.param.szFileName);
535                                         attachment->mediatype = (MimeType)tempType;
536
537                                         strcpy(attachment->szFilePath, partHeader.param.szFileName);
538
539                                         strncpy(attachment->szFileName, partHeader.param.szName, MSG_FILENAME_LEN_MAX - 1);
540
541                                         attachment->fileSize = partHeader.contentSize;
542
543                                         _MsgMmsAddAttachment(&msgData, attachment);
544                                         attachCount++;
545
546                                 }
547
548                         }
549                 }
550         }
551
552         MmsMakePreviewInfo(pMsgInfo->msgId, &msgData);
553         MSG_DEBUG("attachCount [%d]", attachCount);
554         err = pStorage->updateMmsAttachCount(pMsgInfo->msgId, attachCount);
555
556         if (bMultipartRelated) {
557                 _MsgMmsReleasePageList(&msgData);
558                 _MsgMmsReleaseRegionList(&msgData);
559                 _MsgMmsReleaseAttachList(&msgData);
560                 _MsgMmsReleaseTransitionList(&msgData);
561                 _MsgMmsReleaseMetaList(&msgData);
562         }
563
564         MmsMsg *pMsg = NULL;
565         pStorage->getMmsMessage(&pMsg);
566         _MmsInitHeader();
567 #ifdef __SUPPORT_DRM__
568         _MsgFreeDRMInfo(&pMsg->msgType.drmInfo);
569 #endif
570         _MsgFreeBody(&pMsg->msgBody, pMsg->msgType.type);
571
572         MSG_END();
573 }
574
575 void MmsPluginInternal::processForwardConf(MSG_MESSAGE_INFO_S *msgInfo, mmsTranQEntity *pRequest)
576 {
577
578 }
579
580 /* This function Send NotifyRespInd Msg
581  *
582  * @param       pTrID [in] Specifies Transaction ID
583  * @param       iStatus [in] Specifies Msg Status
584  * @param       iReportAllowed [in] Specifies whether to send deliveryReport to sender or not
585  * @return      This function returns true on success, or false on failure.
586  */
587 bool MmsPluginInternal::encodeNotifyRespInd(char *szTrID, msg_delivery_report_status_t iStatus, bool bReportAllowed, char *pSendFilePath)
588 {
589         MSG_BEGIN();
590
591         FILE *pFile = NULL;
592         char pTempFileName[MSG_FILENAME_LEN_MAX+1] = {0};
593         char pTempFilePath[MAX_FULL_PATH_SIZE] = {0};
594
595         if (MsgCreateFileName(pTempFileName) == false)
596                 return false;
597
598         snprintf(pTempFilePath, MAX_FULL_PATH_SIZE, MSG_DATA_PATH"%s.noti.ind", pTempFileName);
599
600         pFile = MsgOpenMMSFile(pTempFilePath);
601
602         if (!pFile) {
603                 MSG_DEBUG("[ERROR] MsgOpenMMSFile fail");
604                 return false;
605         }
606
607         if (_MmsEncodeNotiRespInd(pFile, szTrID, iStatus, bReportAllowed) == false) {
608                 MSG_DEBUG("MmsEncodeNotifyRespInd: _MmsEncodeNotiRespInd fail");
609                 MsgCloseFile(pFile);
610                 return false;
611         }
612
613         MsgCloseFile(pFile);
614
615         if (pSendFilePath) {
616                 snprintf(pSendFilePath, MAX_MSG_DATA_LEN+1, "%s.mms", pTempFilePath);
617         } else {
618                 MSG_DEBUG("[ERROR] pSendFilePath is NULL");
619                 return false;
620         }
621
622         MSG_END();
623
624         return true;
625 }
626
627 /* This function Send AcknowledgeInd Msg
628  *
629  * @param       pTrID [in] Specifies Transaction ID
630  * @param       iReportAllowed [in] Specifies whether to send deliveryReport to sender or not
631  * @return      This function returns true on success, or false on failure.
632  */
633 bool MmsPluginInternal::encodeAckInd(char *szTrID, bool bReportAllowed, char *pSendFilePath)
634 {
635         MSG_BEGIN();
636         FILE *pFile = NULL;
637         char pTempFileName[MSG_FILENAME_LEN_MAX+1] = {0};
638         char pTempFilePath[MAX_FULL_PATH_SIZE] = {0};
639
640         if (MsgCreateFileName(pTempFileName) == false)
641                 return false;
642
643         snprintf(pTempFilePath, MAX_FULL_PATH_SIZE, MSG_DATA_PATH"%s.ack.ind", pTempFileName);
644
645         pFile = MsgOpenMMSFile(pTempFilePath);
646         if (!pFile) {
647                 MSG_DEBUG("[ERROR] MsgOpenMMSFile fail \n" );
648                 return false;
649         }
650
651         if (_MmsEncodeAckInd(pFile, szTrID, bReportAllowed) == false) {
652                 MSG_DEBUG("MmsEncodeAckInd: _MmsEncodeAckInd fail \n" );
653                 MsgCloseFile(pFile);
654                 return false;
655         }
656
657         MsgCloseFile(pFile);
658
659         if (pSendFilePath) {
660                 snprintf(pSendFilePath, MAX_MSG_DATA_LEN+1, "%s.mms", pTempFilePath);
661         } else {
662                 MSG_DEBUG("[ERROR] pSendFilePath is NULL");
663                 return false;
664         }
665
666         MSG_END();
667
668         return true;
669 }
670
671 bool MmsPluginInternal::checkRejectNotiInd(int roamState, bool bReportAllowed, char *pSendFilePath)
672 {
673         MSG_BEGIN();
674         MSG_MMS_HOME_RETRIEVE_TYPE_T retrieveType;
675         bool bRejectAnonymous;
676         bool bRejectAdvertisement;
677
678         MsgSettingGetBool(MMS_RECV_REJECT_UNKNOWN, &bRejectAnonymous);
679         MsgSettingGetBool(MMS_RECV_REJECT_ADVERTISE, &bRejectAdvertisement);
680
681         // Anonymous Reject
682         if (bRejectAnonymous &&
683                 (mmsHeader.pFrom == NULL || mmsHeader.pFrom->szAddr[0] == '\0')) {
684                 MSG_DEBUG("Anonymous Reject... ");
685                 encodeNotifyRespInd(mmsHeader.szTrID, MSG_DELIVERY_REPORT_REJECTED, bReportAllowed, pSendFilePath);
686
687                 return true;
688         }
689
690         // Advertisement Reject
691         if (bRejectAdvertisement && mmsHeader.msgClass == MMS_MSGCLASS_ADVERTISEMENT) {
692                 MSG_DEBUG("Advertisement Reject... ");
693                 encodeNotifyRespInd(mmsHeader.szTrID, MSG_DELIVERY_REPORT_REJECTED, bReportAllowed, pSendFilePath);
694
695                 return true;
696         }
697
698         // Message Reject - Roaming Case
699         if (roamState == VCONFKEY_TELEPHONY_SVC_ROAM_ON) {
700                 retrieveType = (MSG_MMS_HOME_RETRIEVE_TYPE_T)MsgSettingGetInt(MMS_RECV_ABROAD_NETWORK);
701                 if (retrieveType == MSG_ABROAD_REJECT) {
702                         MSG_DEBUG("Abroad_Network : Notification Reject... ");
703                         encodeNotifyRespInd(mmsHeader.szTrID, MSG_DELIVERY_REPORT_REJECTED, bReportAllowed, pSendFilePath);
704
705                         return true;
706                 }
707         } else {
708                 retrieveType = (MSG_MMS_HOME_RETRIEVE_TYPE_T)MsgSettingGetInt(MMS_RECV_HOME_NETWORK);
709                 if (retrieveType == MSG_HOME_REJECT) {
710                         MSG_DEBUG("Home_Network : Notification Reject... ");
711                         encodeNotifyRespInd(mmsHeader.szTrID, MSG_DELIVERY_REPORT_REJECTED, bReportAllowed, pSendFilePath);
712
713                         return true;
714                 }
715         }
716
717         // Not Rejected
718         MSG_END();
719         return false;
720
721 }
722
723 bool MmsPluginInternal::getMmsReport(MmsReport mmsReport)
724 {
725         bool result = false;
726
727         if (mmsReport == MMS_REPORT_YES)
728                 result = true;
729         else if (mmsReport == MMS_REPORT_NO)
730                 result = false;
731
732         return result;
733 }
734
735 const char *MmsPluginInternal::getMmsDeliveryStatus(msg_delivery_report_status_t deliveryStatus)
736 {
737         MSG_DEBUG("msgStatus= %d", deliveryStatus);
738
739         switch (deliveryStatus) {
740         case MSG_DELIVERY_REPORT_EXPIRED:
741                 return "expired.";
742         case MSG_DELIVERY_REPORT_REJECTED:
743                 return "rejected.";
744         case MSG_DELIVERY_REPORT_UNREACHABLE:
745                 return "unreachable.";
746         case MSG_DELIVERY_REPORT_UNRECOGNISED:
747                 return "unrecognised.";
748         case MSG_DELIVERY_REPORT_SUCCESS:
749                 return "delivered.";
750         default:
751                 return "delivery failed.";
752         }
753 }
754
755 const char *MmsPluginInternal::getMmsReadStatus(msg_read_report_status_t readStatus)
756 {
757         switch (readStatus) {
758         case MSG_READ_REPORT_IS_READ:
759                 return "message is read.";
760         case MSG_READ_REPORT_IS_DELETED:
761                 return "message is deleted.";
762         default:
763                 return "read status is none.";
764         }
765 }
766