add code for to/cc feature
[platform/core/messaging/msg-service.git] / plugin / mms_plugin / MmsPluginDecode.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
3  *
4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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 <string.h>
19 #include <sys/stat.h>
20 #include <stdlib.h>
21 #include <errno.h>
22
23 #include "MsgUtilFile.h"
24 #include "MsgUtilMime.h"
25 #include "MsgSmil.h"
26 #include "MsgMmsMessage.h"
27
28 #include "MmsPluginDebug.h"
29 #include "MmsPluginDecode.h"
30 #include "MmsPluginCodecCommon.h"
31 #include "MmsPluginStorage.h"
32 #include "MmsPluginDebug.h"
33 #include "MmsPluginTextConvert.h"
34 #include "MmsPluginUtil.h"
35
36 #include "MmsPluginDrm.h"
37 #include "MsgDrmWrapper.h"
38
39 /*Decode wsp*/
40 static int __MmsGetDecodeOffset(void);
41 static bool __MmsDecodeInitialize(void);
42 static void __MmsCleanDecodeBuff(void);
43 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength);
44 static bool     __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength);
45
46 static bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength);          /* bufLen < gMmsDecodeMaxLen */
47 static bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength);      /* no bufLen limit */
48 static bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength);
49
50 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength);
51
52 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength);
53 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength);
54 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength);
55 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength);
56 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength);
57 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength);
58 static char *__MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength);
59 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
60 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
61
62 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength);
63 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength);
64 static MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength);
65
66 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
67 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
68 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength);
69 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength);
70 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength);
71 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength);
72
73 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength);
74
75
76 /* util funcion */
77 static void __MsgRemoveFilePath(char *pSrc);
78 static bool __MsgChangeSpace(char *pOrg, char **ppNew);
79 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo);
80 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam);
81 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *npRead, int endOfFile);
82 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr);
83 static bool __MsgCheckFileNameHasInvalidChar(char *szName);
84
85 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar);
86 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter);
87 static bool __MsgParseParameter(MsgType *pType, char *pSrc);
88 static char *__MsgSkipWS(char *s);
89 static char *__MsgSkipComment(char *s, long trim);
90
91 static char *__MsgConvertLatin2UTF8FileName(char *pSrc);
92
93 /* static bool __MsgIsPercentSign(char *pSrc); */
94 static bool __MsgIsMultipartRelated(int type);
95 static bool __MsgIsPresentablePart(int type);
96 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody);
97 static bool __MsgIsHexChar(char *pSrc);
98 static char __MsgConvertHexValue(char *pSrc);
99 static int __MsgConvertCharToInt(char ch);
100 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2);
101 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2);
102 static bool __MsgIsMultipartMixed(int type);
103
104 static bool __MsgIsInvalidFileNameChar(char ch);
105
106 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar);
107 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
108 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
109 static void __MsgMIMERemoveQuote(char *szSrc);
110 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave);
111
112 static bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE *pFile);
113 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead);
114
115 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen);
116
117
118 __thread char gszMmsLoadBuf1[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
119 __thread char gszMmsLoadBuf2[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
120
121 __thread char *gpCurMmsDecodeBuff = NULL;
122 __thread int gCurMmsDecodeBuffPos = 0;  /* next decoding position in gpCurMmsDecodeBuff  */
123 __thread int gMmsDecodeMaxLen = 0;
124 __thread int gMmsDecodeCurOffset = 0;   /* current offset in file (last read) */
125 __thread int gMmsDecodeBufLen = 0;              /* number of last read characters */
126
127 __thread char *gpMmsDecodeBuf1 = NULL;
128 __thread char *gpMmsDecodeBuf2 = NULL;
129
130 __thread MmsHeader mmsHeader =
131 {
132         (MmsMsgType)MMS_MSGTYPE_ERROR,                  /* MmsMsgType                   iType; */
133         "",                                                                             /* char[]                               szTrID; */
134         0,                                                                              /* short int                            version; */
135         0,                                                                              /* UINT32                               date; */
136
137         NULL,                                                                   /* MsgHeaderAddress*            pFrom; */
138         NULL,                                                                   /* MsgHeaderAddress*            pTo; */
139         NULL,                                                                   /* MsgHeaderAddress*            pCc; */
140         NULL,                                                                   /* MsgHeaderAddress*            pBcc; */
141         "",                                                                             /* char[]                               szSubject; */
142         (MmsResponseStatus)MMS_RESPSTATUS_OK,   /* MmsResponseStatus            iResponseStatus; */
143         (MmsRetrieveStatus)MMS_RETRSTATUS_OK,   /* MmsRetrieveStatus            iRetrieveStatus; */
144         "",                                                                             /* char[]                               szResponseText; */
145         "",                                                                             /* char[]                               szRetrieveText; */
146
147
148         /* has default value in specification */
149
150         (MmsMsgClass)MMS_MSGCLASS_PERSONAL,             /* MmsMsgClass                  msgClass; */
151         {MMS_TIMETYPE_RELATIVE, 0},                             /* MmsTimeStruct                        expiryTime; */
152         {MMS_TIMETYPE_RELATIVE, 0},                             /* MmsTimeStruct                        deliveryTime; */
153         (MmsPriority)MMS_PRIORITY_NORMAL,               /* MmsPriority                  priority; */ /* Refer [OMA-MMS-ENC-v1_2-20030915-C] */
154         (MmsSenderVisible)MMS_SENDER_SHOW,              /* MmsSenderVisible             senderVisible; */
155         (MmsReport)MMS_REPORT_NO,                               /* MmsReport                            deliveryReport; */
156         (MmsReport)MMS_REPORT_NO,                               /* MmsReport                            readReply; */
157         (MmsReportAllowed)MMS_REPORTALLOWED_NO, /* MmsReportAllowed             iReportAllowed; */
158         "",                                                                             /* char[]                               szContentLocation; */
159
160
161         /* there is no right default value */
162
163         (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE,         /* MmsMsgStatus                 iMsgStatus; */
164         (msg_read_report_status_t)MSG_READ_REPORT_NONE,         /* MmsReadStatus                        readStatus; */
165
166         /* MMS v1.1 ReplyCharge */
167         {
168                 (MmsReplyChargeType)MMS_REPLY_NONE,     /* MmsReplyChargeType   chargeType; */
169                 {MMS_TIMETYPE_RELATIVE, 0},                     /* MmsTimeStruct                        deadLine; */
170                 0,                                                                      /* int                                  chargeSize; */
171                 "" ,                                                            /* char                                 szChargeID; */
172         },
173
174         "",                                                                             /* char[]                               szMsgID; */
175         0,                                                                              /* UINT32                               msgSize; */
176 };
177
178 #define MMS_DRM2_CONVERT_BUFFER_MAX     4*1024
179 const UINT32 MMS_UINTVAR_LENGTH_1 =  0x0000007f;                /* 7bit */
180 const UINT32 MMS_UINTVAR_LENGTH_2 =  0x00003fff;                /* 14bit */
181 const UINT32 MMS_UINTVAR_LENGTH_3 =  0x001fffff;                /* 21bit */
182
183 static bool __MmsDecodeInitialize(void)
184 {
185         MmsInitMsgType(&mmsHeader.msgType);
186         MmsInitMsgBody(&mmsHeader.msgBody);
187         return true;
188 }
189
190 void MmsInitHeader()
191 {
192         mmsHeader.type = MMS_MSGTYPE_ERROR;
193
194         memset(mmsHeader.szTrID, 0, MMS_TR_ID_LEN + 1);
195         mmsHeader.version = MMS_VERSION;
196         mmsHeader.date = 0;
197
198         __MsgFreeHeaderAddress(mmsHeader.pFrom);
199         __MsgFreeHeaderAddress(mmsHeader.pTo);
200         __MsgFreeHeaderAddress(mmsHeader.pCc);
201         __MsgFreeHeaderAddress(mmsHeader.pBcc);
202
203         mmsHeader.pFrom = NULL;
204         mmsHeader.pTo = NULL;
205         mmsHeader.pCc = NULL;
206         mmsHeader.pBcc = NULL;
207
208         memset(mmsHeader.szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
209
210         mmsHeader.responseStatus = (MmsResponseStatus)MMS_RESPSTATUS_OK;
211         mmsHeader.retrieveStatus = (MmsRetrieveStatus)MMS_RETRSTATUS_OK;
212         memset(mmsHeader.szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
213         memset(mmsHeader.szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
214
215
216         mmsHeader.msgClass = (MmsMsgClass)MMS_MSGCLASS_PERSONAL;
217         mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
218         mmsHeader.expiryTime.time = 0;
219         mmsHeader.deliveryTime.type     = MMS_TIMETYPE_RELATIVE;
220         mmsHeader.deliveryTime.time     = 0;
221         mmsHeader.priority = (MmsPriority)MMS_PRIORITY_NORMAL;  /* Refer [OMA-MMS-ENC-v1_2-20030915-C] */
222         mmsHeader.hideAddress =(MmsSenderVisible)MMS_SENDER_SHOW;
223         mmsHeader.deliveryReport = (MmsReport)MMS_REPORT_NO;
224         mmsHeader.readReply = (MmsReport)MMS_REPORT_NO;
225         mmsHeader.reportAllowed = (MmsReportAllowed)MMS_REPORTALLOWED_YES;
226         memset(mmsHeader.szContentLocation, 0, MMS_LOCATION_LEN + 1);
227
228
229         mmsHeader.msgStatus = (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE;
230         mmsHeader.readStatus = (msg_read_report_status_t)MSG_READ_REPORT_NONE;
231
232         mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MMS_REPLY_NONE;
233         mmsHeader.replyCharge.chargeSize = 0;
234         mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
235         mmsHeader.replyCharge.deadLine.time = 0;
236         memset(mmsHeader.replyCharge.szChargeID, 0, MMS_MSG_ID_LEN + 1);
237
238
239         memset(mmsHeader.szMsgID, 0, MMS_MSG_ID_LEN + 1);
240         mmsHeader.msgSize = 0;
241         mmsHeader.drmType = MSG_DRM_TYPE_NONE;
242
243         __MmsDecodeInitialize();
244 }
245
246 void MmsReleaseHeader(MmsHeader *mms)
247 {
248         __MsgFreeHeaderAddress(mms->pFrom);
249         __MsgFreeHeaderAddress(mms->pTo);
250         __MsgFreeHeaderAddress(mms->pCc);
251         __MsgFreeHeaderAddress(mms->pBcc);
252
253         mmsHeader.pFrom = NULL;
254         mmsHeader.pTo = NULL;
255         mmsHeader.pCc = NULL;
256         mmsHeader.pBcc = NULL;
257
258 }
259
260 static void __MmsCleanDecodeBuff(void)
261 {
262         memset(gpMmsDecodeBuf1, 0, gMmsDecodeMaxLen + 1);
263         memset(gpMmsDecodeBuf2, 0, gMmsDecodeMaxLen + 1);
264         gpCurMmsDecodeBuff = NULL;
265         gCurMmsDecodeBuffPos = 0;
266         gMmsDecodeBufLen = 0;
267 }
268
269 void MmsRegisterDecodeBuffer()
270 {
271         gpMmsDecodeBuf1 = gszMmsLoadBuf1;
272         gpMmsDecodeBuf2 = gszMmsLoadBuf2;
273         gpCurMmsDecodeBuff = NULL;
274         gCurMmsDecodeBuffPos = 0;
275         gMmsDecodeMaxLen = MSG_MMS_DECODE_BUFFER_MAX;
276         gMmsDecodeCurOffset = 0;
277         gMmsDecodeBufLen = 0;
278 }
279
280 void MmsUnregisterDecodeBuffer(void)
281 {
282         gpMmsDecodeBuf1 = NULL;
283         gpMmsDecodeBuf2 = NULL;
284         gpCurMmsDecodeBuff = NULL;
285         gCurMmsDecodeBuffPos = 0;
286         gMmsDecodeMaxLen = 0;
287         gMmsDecodeCurOffset = 0;
288         gMmsDecodeBufLen = 0;
289 }
290
291
292 static int __MmsGetDecodeOffset(void)
293 {
294         return (gMmsDecodeCurOffset - gMmsDecodeBufLen + gCurMmsDecodeBuffPos);
295 }
296
297 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength)
298 {
299         if (*pLength <= valueLength) {
300                 gCurMmsDecodeBuffPos -= valueLength;
301                 gCurMmsDecodeBuffPos += *pLength;
302                 return false;
303         }
304
305         *pLength -= valueLength;
306
307         return true;
308 }
309
310
311 /* ==========================================================
312
313            B  I  N  A  R  Y         D  E  C  O  D  I  N  G
314
315    ==========================================================*/
316
317 /*
318  * Binary Encoded Message Format
319  *
320  *              < Single Part Body Message >
321  * -----------------------------------
322  * |            Header Fields                    |
323  * -----------------------------------
324  * | Content Type:start=xxx;type=xxx |  ->(ex) Text/Plain, Text/Html, ....
325  * -----------------------------------
326  * |            Single Part Body                 |
327  * -----------------------------------
328  *
329  *              < Multi Part Body Message >
330  * -----------------------------------
331  * |            Header Fields                    |
332  * -----------------------------------
333  * | Content Type:start=xxx;type=xxx |  -> (ex) Application/vnd.wap.multipart.mixed(related), multipart/mixed(related)
334  * -----------------------------------
335  * |    # of Entries (body parts)        |
336  * -----------------------------------                          < Each Entry >
337  * |                    Entry 1                          |      ->      -----------------------------
338  * -----------------------------------          |               header Length           |
339  * |                    Entry 2                          |              -----------------------------
340  * -----------------------------------          |               Data Length                     |
341  * |                    ......                           |              -----------------------------  -
342  * -----------------------------------          |               Content-Type            |  |
343  * |                    Entry n                          |              -----------------------------  | Header Length
344  * -----------------------------------          |                       Header                  |  |
345  *                                                                                      -----------------------------  -
346  *                                                                                      |                       Data                    |  | Data Length
347  *                                                                                      -----------------------------  -
348  */
349 bool MmsBinaryDecodeMsgHeader(FILE *pFile, int totalLength)
350 {
351         MSG_BEGIN();
352         UINT16 fieldCode = 0xffff;
353         UINT16 fieldValue = 0xffff;
354         UINT8 oneByte = 0xff;
355
356         MsgHeaderAddress *pAddr = NULL;
357         MsgHeaderAddress *pLastTo = NULL;
358         MsgHeaderAddress *pLastCc = NULL;
359         MsgHeaderAddress *pLastBcc = NULL;
360
361         UINT32 valueLength = 0;
362         UINT32 tmpInteger = 0;
363         int     tmpIntLen = 0;
364
365         int offset = 0;
366
367         char szGarbageBuff[MSG_STDSTR_LONG]     = {0, };
368         char *pLimitData = NULL;
369         int nRead = 0;
370
371         MSG_DEBUG("pFile ptr : [%p], total len = [%d]", pFile, totalLength);
372
373         __MmsCleanDecodeBuff();
374
375         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
376                                                                    &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
377                                                                    gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
378                 MSG_FATAL("fail to load to buffer");
379                 goto __CATCH;
380         }
381
382         while (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength)) {
383                 fieldCode = oneByte & 0x7f;
384
385                 switch (MmsGetBinaryType(MmsCodeFieldCode, fieldCode)) {
386                 case MMS_CODE_RESPONSESTATUS: {
387                         MmsResponseStatus resposeStatus = MMS_RESPSTATUS_ERROR;
388
389                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
390                                 MSG_DEBUG("responseStatus GetOneByte fail");
391                                 goto __CATCH;
392                         }
393
394                         fieldValue = oneByte;
395
396                         /* range 197 to 223 as it does to the value 192 (Error-transient-failure). */
397                         /* range 236 to 255 as it does to the value 224 (Error-permanent-failure). */
398                         if (fieldValue >= 197 && fieldValue <= 223) {
399                                 fieldValue = 192;
400                         } else if (fieldValue >= 236 && fieldValue <= 255) {
401                                 fieldValue = 224;
402                         }
403
404                         resposeStatus = (MmsResponseStatus)MmsGetBinaryType(MmsCodeResponseStatus, (UINT16)(fieldValue & 0x7F));
405
406                         mmsHeader.responseStatus = (MmsResponseStatus)resposeStatus;
407
408                         MSG_SEC_INFO("X-Mms-Response-Status = [0x%02x][0x%02x][%s]", oneByte, fieldValue, MmsDebugGetResponseStatus(mmsHeader.responseStatus));
409                         break;
410                 }
411                 case MMS_CODE_RETRIEVESTATUS: {
412                         MmsRetrieveStatus RetrieveStatus = MMS_RETRSTATUS_ERROR;
413
414                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
415                                 MSG_DEBUG("retrieveStatus GetOneByte fail");
416                                 goto __CATCH;
417                         }
418
419                         fieldValue = oneByte;
420
421                         /* 195 to 223 as it does to the value 192 (Error-transient-failure). */
422                         /* 228 to 255 as it does to the value 224 (Error-permanent-failure). */
423                         if (fieldValue >= 195 && fieldValue <= 223) {
424                                 fieldValue = 192; /* 192; Error-transient-failure */
425                         } else if (fieldValue >= 228 && fieldValue <= 255) {
426                                 fieldValue = 224; /* 224; Error-permanent-failure */
427                         }
428
429                         RetrieveStatus = (MmsRetrieveStatus)MmsGetBinaryType(MmsCodeRetrieveStatus, (UINT16)(fieldValue & 0x7F));
430
431                         mmsHeader.retrieveStatus = (MmsRetrieveStatus)RetrieveStatus;
432
433                         MSG_SEC_INFO("X-Mms-Retrieve-Status = [0x%02x][0x%02x][%s]", oneByte, fieldValue, MmsDebugGetRetrieveStatus(mmsHeader.retrieveStatus));
434
435                         break;
436                 }
437                 case MMS_CODE_RESPONSETEXT:
438
439                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szResponseText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
440                                 MSG_DEBUG("invalid MMS_CODE_RESPONSETEXT");
441                                 goto __CATCH;
442                         }
443
444                         MSG_SEC_INFO("X-Mms-Response-Text = [%s]", mmsHeader.szResponseText);
445                         break;
446
447                 case MMS_CODE_RETRIEVETEXT:
448
449                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szRetrieveText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
450                                 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
451                                 goto __CATCH;
452                         }
453
454                         MSG_SEC_INFO("X-Mms-Retrieve-Text = [%s]", mmsHeader.szRetrieveText);
455                         break;
456
457                 case MMS_CODE_MSGID:
458
459                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szMsgID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
460                                 MSG_DEBUG("MMS_CODE_MSGID is invalid");
461                                 goto __CATCH;
462                         }
463
464                         MSG_SEC_INFO("Message-ID =[%s]", mmsHeader.szMsgID);
465
466                         if (strlen(mmsHeader.szMsgID) > 2)
467                                 __MsgMIMERemoveQuote (mmsHeader.szMsgID);
468
469                         break;
470
471                 case MMS_CODE_SUBJECT:
472
473                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN + 1, totalLength) == false) {
474                                 MSG_DEBUG("invalid MMS_CODE_SUBJECT");
475                                 goto __CATCH;
476                         }
477
478                         pLimitData = (char *)calloc(1, MSG_LOCALE_SUBJ_LEN + 1);
479
480                         if (pLimitData == NULL) {
481                                 MSG_DEBUG("pLimitData calloc fail");
482                                 goto __CATCH;
483                         }
484
485                         nRead = __MsgCutUTFString((unsigned char*)pLimitData, MSG_LOCALE_SUBJ_LEN + 1, (unsigned char*)mmsHeader.szSubject, MSG_SUBJ_LEN);
486                         MSG_DEBUG("Subject edit..");
487
488                         if (nRead > MSG_LOCALE_SUBJ_LEN) {
489                                 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
490                                 strncpy(mmsHeader.szSubject, pLimitData, MSG_SUBJ_LEN);
491                         } else {
492                                 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
493                                 strncpy(mmsHeader.szSubject, pLimitData, MSG_LOCALE_SUBJ_LEN);
494                         }
495
496                         if (pLimitData) {
497                                 free(pLimitData);
498                                 pLimitData = NULL;
499                         }
500
501                         MSG_SEC_INFO("Subject = [%s]", mmsHeader.szSubject);
502                         break;
503
504                 case MMS_CODE_FROM:
505
506                         /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
507
508                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
509                                 MSG_DEBUG("MMS_CODE_FROM is invalid");
510                                 goto __CATCH;
511                         }
512
513                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
514                                 MSG_DEBUG("MMS_CODE_FROM GetOneByte fail");
515                                 goto __CATCH;
516                         }
517
518                         /* DRM_TEMPLATE - start */
519
520                         valueLength--;
521
522                         if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
523                                 if (valueLength > 0) {
524                                         mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
525                                         if (mmsHeader.pFrom == NULL) {
526                                                 MSG_DEBUG("MMS_CODE_FROM __MmsDecodeEncodedAddress fail");
527                                                 goto __CATCH;
528                                         }
529                                 } else {
530                                         mmsHeader.pFrom = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
531                                         if (mmsHeader.pFrom == NULL)
532                                                 goto __CATCH;
533
534                                         mmsHeader.pFrom->szAddr = (char *)calloc(1, 1);
535                                         if (mmsHeader.pFrom->szAddr == NULL) {
536                                                 free(mmsHeader.pFrom);
537                                                 mmsHeader.pFrom = NULL;
538                                                 goto __CATCH;
539                                         }
540
541                                         mmsHeader.pFrom->szAddr[0] = '\0';
542                                         mmsHeader.pFrom->pNext = NULL;
543                                 }
544
545                                 MSG_SEC_INFO("From = [%s]", mmsHeader.pFrom->szAddr);
546                                 /* DRM_TEMPLATE - end */
547                         } else if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
548                                 /* Present Token only */
549                                 MSG_SEC_INFO("From = [insert token]");
550                         } else {
551                                 /* from data broken */
552                                 MSG_WARN("from addr broken");
553                                 gCurMmsDecodeBuffPos--;
554                                 goto __CATCH;
555                         }
556                         break;
557
558                 case MMS_CODE_TO:
559
560                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
561                         if (pAddr == NULL) {
562                                 MSG_DEBUG("MMS_CODE_TO __MmsDecodeEncodedAddress fail");
563                                 goto __CATCH;
564                         }
565
566                         if (mmsHeader.pTo == NULL) {
567                                 /* the first TO */
568                                 pLastTo = mmsHeader.pTo = pAddr;
569                         } else {
570                                 if (pLastTo)
571                                         pLastTo->pNext = pAddr;
572                                 pLastTo = pAddr;
573                         }
574
575                         MSG_SEC_INFO("To = [%s]", pAddr->szAddr);
576                         break;
577
578                 case MMS_CODE_BCC:
579
580                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
581                         if (pAddr == NULL) {
582                                 MSG_DEBUG("MMS_CODE_BCC __MmsDecodeEncodedAddress fail");
583                                 goto __CATCH;
584                         }
585
586                         if (mmsHeader.pBcc == NULL) {
587                                 /* the first Bcc */
588                                 pLastBcc = mmsHeader.pBcc = pAddr;
589                         } else {
590                                 if (pLastBcc)
591                                         pLastBcc->pNext = pAddr;
592                                 pLastBcc = pAddr;
593                         }
594
595                         MSG_SEC_INFO("Bcc = [%s]", pAddr->szAddr);
596                         break;
597
598                 case MMS_CODE_CC:
599
600                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
601                         if (pAddr == NULL) {
602                                 MSG_DEBUG("MMS_CODE_CC __MmsDecodeEncodedAddress fail");
603                                 goto __CATCH;
604                         }
605
606                         if (mmsHeader.pCc == NULL) {
607                                 /* the first Cc */
608                                 pLastCc = mmsHeader.pCc = pAddr;
609                         } else {
610                                 if (pLastCc)
611                                         pLastCc->pNext = pAddr;
612                                 pLastCc = pAddr;
613                         }
614                         MSG_SEC_INFO("Cc = [%s]", pAddr->szAddr);
615                         break;
616
617                 case MMS_CODE_CONTENTLOCATION:
618
619                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
620                                 MSG_DEBUG("MMS_CODE_CONTENTLOCATION is invalid");
621                                 goto __CATCH;
622                         }
623                         MSG_SEC_DEBUG("X-Mms-Content-Location = [%s]", mmsHeader.szContentLocation);
624                         break;
625
626                 case MMS_CODE_DATE:
627
628                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
629                                 MSG_DEBUG("MMS_CODE_DATE is invalid");
630                                 goto __CATCH;
631                         }
632
633                         MSG_SEC_INFO("Date = [%u][%d]", mmsHeader.date, (const time_t *)&mmsHeader.date);
634                         break;
635
636                 case MMS_CODE_DELIVERYREPORT:
637
638                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
639                                 MSG_DEBUG("deliveryReport GetOneByte fail");
640                                 goto __CATCH;
641                         }
642
643                         fieldValue = MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
644
645                         if (fieldValue == 0xFFFF) {
646                                 MSG_DEBUG("deliveryReport error");
647                                 goto __CATCH;
648                         }
649
650                         mmsHeader.deliveryReport = (MmsReport)fieldValue;
651
652                         MSG_SEC_INFO("X-Mms-Delivery-Report =[0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.deliveryReport));
653                         break;
654
655                 case MMS_CODE_DELIVERYTIME:
656
657                         /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
658
659                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
660                                 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
661                                 goto __CATCH;
662                         }
663
664                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
665                                 MSG_DEBUG("delivery time GetOneByte fail");
666                                 goto __CATCH;
667                         }
668
669                         /* DRM_TEMPLATE - start */
670                         valueLength--;
671
672                         if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
673                                 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
674
675                                 if (valueLength > 0) {
676                                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
677                                                 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
678                                                 goto __CATCH;
679                                         }
680                                 }
681                         /* DRM_TEMPLATE - end */
682                         } else {
683                                 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
684
685                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
686                                         MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
687                                         goto __CATCH;
688                                 }
689                         }
690                         MSG_SEC_INFO("X-Mms-Delivery-Time : type = [%d], time= [%u]", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
691                         break;
692
693                 case MMS_CODE_EXPIRYTIME:
694
695                         /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
696
697                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
698                                 MSG_DEBUG("invalid MMS_CODE_EXPIRYTIME");
699                                 goto __CATCH;
700                         }
701
702                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
703                                 MSG_DEBUG("expiry time GetOneByte fail");
704                                 goto __CATCH;
705                         }
706
707                         /* DRM_TEMPLATE - start */
708                         valueLength--;
709
710                         if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
711                                 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
712
713                                 if (valueLength > 0) {
714                                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
715                                                 MSG_DEBUG("MMS_CODE_EXPIRYTIME is invalid");
716                                                 goto __CATCH;
717                                         }
718                                 }
719                         /* DRM_TEMPLATE - end */
720                         } else {
721                                 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
722
723                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
724                                         MSG_INFO("__MmsBinaryDecodeInteger fail...");
725                                         goto __CATCH;
726                                 }
727                         }
728
729                         MSG_DEBUG("X-Mms-Expiry : type = [%d], time = [%u]", mmsHeader.expiryTime.type, mmsHeader.expiryTime.time);
730                         break;
731
732                 case MMS_CODE_MSGCLASS:
733
734                         /* Class-value = Class-identifier | Token Text */
735
736                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
737                                 MSG_DEBUG("msgClass GetOneByte fail");
738                                 goto __CATCH;
739                         }
740
741                         if (oneByte > 0x7f) {
742                                 /* Class-identifier */
743                                 mmsHeader.msgClass = (MmsMsgClass)MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
744                         } else {
745                                 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
746                                         MSG_DEBUG("1. __MmsBinaryDecodeText fail. (class)");
747                                         goto __CATCH;
748                                 }
749                         }
750
751                         MSG_SEC_INFO("X-Mms-Message-Class =[%s]", MmsDebugGetMsgClass(mmsHeader.msgClass));
752                         break;
753
754                 case MMS_CODE_MSGSIZE:
755
756                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
757                                 MSG_DEBUG("MMS_CODE_MSGSIZE is invalid");
758                                 goto __CATCH;
759                         }
760
761                         MSG_SEC_INFO("X-Mms-Message-Size = [%d]", mmsHeader.msgSize);
762                         break;
763
764                 case MMS_CODE_MSGSTATUS:
765
766                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
767                                 MSG_DEBUG("msgStatus GetOneByte fail");
768                                 goto __CATCH;
769                         }
770
771                         mmsHeader.msgStatus =  (msg_delivery_report_status_t)MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
772                         MSG_SEC_INFO("X-Mms-Status = [%s]", MmsDebugGetMsgStatus(mmsHeader.msgStatus));
773                         break;
774
775                 case MMS_CODE_MSGTYPE:
776
777                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
778                                 MSG_DEBUG("msgStatus GetOneByte fail");
779                                 goto __CATCH;
780                         }
781
782                         mmsHeader.type = (MmsMsgType)MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
783                         MSG_SEC_INFO("X-Mms-Message-Type = [%s]", MmsDebugGetMsgType(mmsHeader.type));
784                         break;
785
786                 case MMS_CODE_PRIORITY:
787
788                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
789                                 MSG_DEBUG("msgStatus GetOneByte fail");
790                                 goto __CATCH;
791                         }
792                         mmsHeader.priority = (MmsPriority)MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
793                         MSG_SEC_INFO("X-Mms-Priority = [%d]", mmsHeader.priority);
794                         break;
795
796                 case MMS_CODE_READREPLY:
797
798                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
799                                 MSG_DEBUG("msgStatus GetOneByte fail");
800                                 goto __CATCH;
801                         }
802                         mmsHeader.readReply = (MmsReport)MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
803                         MSG_SEC_INFO("X-Mms-Read-Report = [0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.readReply));
804                         break;
805
806                 case MMS_CODE_REPORTALLOWED:
807
808                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
809                                 MSG_DEBUG("msgStatus GetOneByte fail");
810                                 goto __CATCH;
811                         }
812                         mmsHeader.reportAllowed =  (MmsReportAllowed)MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
813                         MSG_SEC_INFO("X-Mms-Report-Allowed = [%d]", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
814                         break;
815
816                 case MMS_CODE_SENDERVISIBILLITY:
817
818                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
819                                 MSG_DEBUG("msgStatus GetOneByte fail");
820                                 goto __CATCH;
821                         }
822                         mmsHeader.hideAddress= (MmsSenderVisible)!(MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
823                         MSG_SEC_INFO("X-Mms-Sender-Visibility = [%d]", mmsHeader.hideAddress);
824                         break;
825
826                 case MMS_CODE_TRID:
827
828                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
829                                 MSG_DEBUG("Transaction ID Too Long");
830                                 goto __CATCH;
831                         }
832                         MSG_SEC_INFO("X-Mms-Transaction-Id = [%s]", mmsHeader.szTrID);
833                         break;
834
835                 case MMS_CODE_VERSION:
836                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
837                                 MSG_DEBUG("msgStatus GetOneByte fail");
838                                 goto __CATCH;
839                         }
840                         mmsHeader.version = oneByte;
841
842                         MSG_SEC_INFO("X-Mms-MMS-Version = [0x%02x]", mmsHeader.version);
843                         break;
844
845                 case MMS_CODE_CONTENTTYPE:
846
847                         /*
848                          * Content-type is the last header field of SendRequest and RetrieveConf.
849                          * It's required to decrease pointer by one and return,
850                          * to parse this field in MmsBinaryDecodeContentType().
851                          */
852                         goto __RETURN;
853
854
855                 /* ----------- Add by MMSENC v1.1 ----------- */
856
857                 case MMS_CODE_READSTATUS:
858
859                         /* Read-status-value = Read | Deleted without being read */
860
861                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
862                                 MSG_DEBUG("msgStatus GetOneByte fail");
863                                 goto __CATCH;
864                         }
865
866                         mmsHeader.readStatus =  (msg_read_report_status_t)MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
867                         MSG_SEC_INFO("X-Mms-Read-Status = [%s]", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
868                         break;
869
870                 case MMS_CODE_REPLYCHARGING:
871
872                         /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
873
874                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
875                                 MSG_DEBUG("msgStatus GetOneByte fail");
876                                 goto __CATCH;
877                         }
878
879                         mmsHeader.replyCharge.chargeType =  (MmsReplyChargeType)MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
880                         MSG_SEC_INFO("X-Mms-Reply-Charging = [%d]", mmsHeader.replyCharge.chargeType);
881                         break;
882
883                 case MMS_CODE_REPLYCHARGINGDEADLINE:
884
885                         /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
886
887                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
888                                 MSG_DEBUG("invalid MMS_CODE_REPLYCHARGINGDEADLINE");
889                                 goto __CATCH;
890                         }
891
892                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
893                                 MSG_DEBUG("msgStatus GetOneByte fail");
894                                 goto __CATCH;
895                         }
896
897                         if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
898                                 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
899                         } else {
900                                 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
901                         }
902
903                         /* DRM_TEMPLATE - start */
904                         valueLength--;
905
906                         if (valueLength > 0) {
907                                 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
908                                         MSG_DEBUG("MMS_CODE_REPLYCHARGINGDEADLINE is invalid");
909                                         goto __CATCH;
910                                 }
911                         }
912
913                         MSG_SEC_INFO("X-Mms-Reply-Charging-Deadline : type = [%d], time = [%u]", mmsHeader.replyCharge.deadLine.type, mmsHeader.replyCharge.deadLine.time);
914                         /* DRM_TEMPLATE - end */
915                         break;
916
917                 case MMS_CODE_REPLYCHARGINGID:
918
919                         /* Reply-charging-ID-value = Text-string */
920                         if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
921                                 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (szReplyChargingID)");
922                                 goto __CATCH;
923                         }
924                         SECURE_SLOGD("X-Mms-Reply-Charging-ID = [%s]", mmsHeader.replyCharge.szChargeID);
925                         break;
926
927                 case MMS_CODE_REPLYCHARGINGSIZE:
928
929                         /* Reply-charging-size-value = Long-integer */
930                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
931                                 MSG_DEBUG("MMS_CODE_REPLYCHARGINGSIZE is invalid");
932                                 goto __CATCH;
933                         }
934                         MSG_SEC_INFO("X-Mms-Reply-Charging-Size = [%d]", mmsHeader.replyCharge.chargeSize);
935                         break;
936
937                 case MMS_CODE_PREVIOUSLYSENTBY:
938
939                         /*
940                          * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
941                          * Forwarded-count-value = Integer-value
942                          * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
943                          */
944
945                         /*
946                          * fixme: There is no proper field to store this information.
947                          * Just increase pointer now.
948                          */
949
950                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
951                                 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTBY");
952                                 goto __CATCH;
953                         }
954
955                         if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
956                                 MSG_DEBUG("2. invalid MMS_CODE_PREVIOUSLYSENTBY");
957                                 goto __CATCH;
958                         }
959
960                         if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
961                                 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
962                                 goto __CATCH;
963                         }
964                         break;
965
966                 case MMS_CODE_PREVIOUSLYSENTDATE:
967
968                         /*
969                          * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
970                          * Forwarded-count-value = Integer-value
971                          * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
972                          */
973
974                         /*
975                          * fixme: There is no proper field to store this information.
976                          * Just increase pointer now.
977                          */
978
979                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
980                                 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTDATE");
981                                 goto __CATCH;
982                         }
983
984                         if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
985                                 MSG_DEBUG("2. invalid MS_CODE_PREVIOUSLYSENTDATE");
986                                 goto __CATCH;
987                         }
988
989                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
990                                 MSG_DEBUG("3. invalid MMS_CODE_PREVIOUSLYSENTDATE");
991                                 goto __CATCH;
992                         }
993                         break;
994
995                 default: {
996
997                         /*
998                          * Application-header             = Token-text Application-specific-value
999                          * Token-text                             = Token End-of-string
1000                          * Application-specific-value = Text -string
1001                          *
1002                          * OR unknown header field - Just ignore these fields.
1003                          *
1004                          * Read one byte and check the value >= 0x80
1005                          * (check these value can be field code)
1006                          */
1007
1008                         int remainLength = 0;
1009
1010                         oneByte = 0x00;
1011
1012                         offset = __MmsGetDecodeOffset();
1013                         if (offset >= totalLength)
1014                                 goto __RETURN;
1015
1016                         remainLength = totalLength - offset;
1017
1018                         while ((oneByte < 0x80) && (remainLength > 0)) {
1019                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1020                                         MSG_DEBUG("__MmsBinaryDecodeCheckAndDecreaseLength fail");
1021                                         goto __CATCH;
1022                                 }
1023
1024                                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1025                                         MSG_DEBUG("responseStatus GetOneByte fail");
1026                                         goto __CATCH;
1027                                 }
1028                         }
1029
1030                         gCurMmsDecodeBuffPos--;
1031                         break;
1032                 }
1033                 }       /* switch */
1034
1035                 offset = __MmsGetDecodeOffset();
1036                 if (offset >= totalLength)
1037                         goto __RETURN;
1038
1039         }       /* while */
1040
1041
1042 __RETURN:
1043
1044         if (mmsHeader.pTo == NULL && pLastTo) {
1045                 free(pLastTo);
1046         }
1047
1048         if (mmsHeader.pCc == NULL && pLastCc) {
1049                 free(pLastCc);
1050         }
1051
1052         if (mmsHeader.pBcc == NULL && pLastBcc) {
1053                 free(pLastBcc);
1054         }
1055
1056         MSG_INFO("## Decode Header Success ##");
1057         MSG_END();
1058         return true;
1059
1060
1061 __CATCH:
1062
1063         if (mmsHeader.pTo == NULL && pLastTo) {
1064                 free(pLastTo);
1065         }
1066
1067         if (mmsHeader.pCc == NULL && pLastCc) {
1068                 free(pLastCc);
1069         }
1070
1071         if (mmsHeader.pBcc == NULL && pLastBcc) {
1072                 free(pLastBcc);
1073         }
1074
1075         MSG_FATAL("## Decode Header Fail ##");
1076         MSG_END();
1077         return false;
1078 }
1079
1080 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1081 {
1082         MSG_BEGIN();
1083
1084         int length = 0;
1085         int offset = 0;
1086
1087         if (szFilePath != NULL)
1088                 snprintf(mmsHeader.msgType.szOrgFilePath, sizeof(mmsHeader.msgType.szOrgFilePath), "%s", szFilePath);
1089
1090         mmsHeader.msgType.offset = __MmsGetDecodeOffset() - 1;          /* + Content-Type code value */
1091
1092         /* read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding */
1093         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1094                                                                         &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1095                                                                         gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1096                 MSG_DEBUG("fail to load to buffer");
1097                 goto __CATCH;
1098         }
1099
1100         /* msg's type [ex] related, mixed, single part (jpg, amr and etc) */
1101         length = __MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1102         if (length == -1) {
1103                 MSG_DEBUG("MMS_CODE_CONTENTTYPE is fail");
1104                 goto __CATCH;
1105         }
1106
1107         mmsHeader.msgType.size   = length + 1; /* + Content-Type code value */
1108         mmsHeader.msgBody.offset = __MmsGetDecodeOffset();
1109
1110         switch (mmsHeader.msgType.type) {
1111         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1112         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1113         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1114         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1115         case MIME_MULTIPART_REPORT:
1116         case MIME_MULTIPART_MIXED:
1117         case MIME_MULTIPART_RELATED:
1118         case MIME_MULTIPART_ALTERNATIVE:
1119         case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1120         case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1121
1122                 MSG_DEBUG("Decode Multipart");
1123
1124                 offset = __MmsGetDecodeOffset();
1125                 if (offset >= totalLength)
1126                         goto __RETURN;
1127
1128                 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1129                         MSG_DEBUG("MmsBinaryDecodeMultipart is fail.");
1130                         goto __CATCH;
1131                 }
1132                 break;
1133
1134         default:
1135
1136                 /* Single part message ---------------------------------------------- */
1137                 MSG_DEBUG("Decode Singlepart");
1138
1139                 offset = __MmsGetDecodeOffset();
1140                 if (offset >= totalLength)
1141                         goto __RETURN;
1142
1143                 if (__MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1144                         MSG_DEBUG("MmsBinaryDecodePartBody is fail.(Single Part)");
1145                         goto __CATCH;
1146                 }
1147
1148                 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1149                 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1150
1151                 break;
1152         }
1153
1154 __RETURN:
1155         MSG_END();
1156         return true;
1157
1158 __CATCH:
1159         return false;
1160 }
1161
1162 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1163 {
1164         MSG_BEGIN();
1165         UINT8 oneByte = 0;
1166         int charSetLen = 0;
1167         char *szTypeString = NULL;
1168         char *szTypeValue = NULL;
1169         UINT8 paramCode = 0xff;
1170         UINT32 integer = 0;
1171         int intLen = 0;
1172         int length = 0;
1173         int textLength = 0;
1174
1175         /*
1176          * Parameter = Typed-parameter | Untyped-parameter
1177          * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1178          */
1179
1180         while (valueLength > 0) {
1181                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1182                         MSG_DEBUG("paramCode _MmsBinaryDecodeGetOneByte fail");
1183                         goto __CATCH;
1184                 }
1185
1186                 paramCode = oneByte;
1187                 valueLength--;
1188
1189                 switch (paramCode) {
1190                 case 0x81: /* charset */
1191
1192                         if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1193                                 MSG_DEBUG("__MmsBinaryDecodeCharset fail.");
1194                                 goto __CATCH;
1195                         }
1196
1197                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1198                                 goto __RETURN;
1199
1200                         break;
1201
1202                 case 0x85: /* name = Text-string */
1203                 case 0x97: /* name = Text-value  = No-value | Token-text | Quoted-string */
1204                         memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1205                         length = __MmsDecodeGetFilename(pFile,  pMsgType->param.szName,
1206                                                                                          MSG_FILENAME_LEN_MAX -5,               /* MSG_LOCALE_FILENAME_LEN_MAX + 1, :  change @ 110(Ui code have to change for this instead of DM) */
1207                                                                                          totalLength);
1208                         if (length < 0) {
1209                                 MSG_DEBUG("__MmsDecodeGetFilename fail. (name parameter)");
1210                                 goto __CATCH;
1211                         }
1212
1213                         if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1214                                 __MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1215                         }
1216
1217                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1218                                 goto __RETURN;
1219
1220                         break;
1221
1222                 case 0x86: /* filename = Text-string */
1223                 case 0x98: /* filename = Text-value  = No-value | Token-text | Quoted-string */
1224                         memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1225                         length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1226                         if (length < 0) {
1227                                 MSG_DEBUG("__MmsDecodeGetFilename fail. (filename parameter)");
1228                                 goto __CATCH;
1229                         }
1230
1231                         if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1232                                 __MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1233                         }
1234
1235                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1236                                 goto __RETURN;
1237
1238                         break;
1239
1240                 case 0x89: /* type = Constrained-encoding = Extension-Media | Short-integer */
1241
1242                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1243                                 MSG_DEBUG("type _MmsBinaryDecodeGetOneByte fail");
1244                                 goto __CATCH;
1245                         }
1246
1247                         if (oneByte > 0x7f) {
1248                                 pMsgType->param.type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1249                                 /* MmsGetBinaryType(MmsCodeContentType,(UINT16)(oneByte & 0x7f)); */
1250                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1251                                         goto __RETURN;
1252                         } else {
1253                                 gCurMmsDecodeBuffPos--;
1254
1255                                 textLength = 0;
1256                                 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1257                                 pMsgType->param.type = MimeGetMimeIntFromMimeString(szTypeString);
1258                                 if (szTypeString) {
1259                                         free(szTypeString);
1260                                         szTypeString = NULL;
1261                                 }
1262
1263                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1264                                         goto __RETURN;
1265                         }
1266
1267                         break;
1268
1269                 case 0x8A: /* start encoding version 1.2 */
1270                 case 0x99: /* start encoding version 1.4 */
1271
1272                         textLength       = 0;
1273                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1274                         if (szTypeString) {
1275                                 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1276                                 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1277                                 free(szTypeString);
1278                                 szTypeString = NULL;
1279
1280                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1281                                         goto __RETURN;
1282                         }
1283
1284                         break;
1285
1286                 case 0x8B: /* startInfo encoding version 1.2 */
1287                 case 0x9A: /* startInfo encoding version 1.4 */
1288
1289                         textLength       = 0;
1290                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1291
1292                         if (szTypeString) {
1293                                 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1294                                 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1295
1296                                 free(szTypeString);
1297                                 szTypeString = NULL;
1298
1299                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1300                                         goto __RETURN;
1301                         }
1302
1303                         break;
1304
1305                 default:
1306
1307                         if (paramCode > 0x7F) {
1308                                 MSG_DEBUG("Unsupported parameter");
1309
1310                                 /* In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value. */
1311                                 valueLength++;
1312                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1313                                         goto __RETURN;
1314                         } else {
1315                                 /*
1316                                  * Untyped Parameter = Token-text Untyped-value
1317                                  * Token-text            = Token End-of-string
1318                                  * Untyped-value         = Integer-value | Text-value
1319                                  * Text-value            = No-value | Token-text | Quoted-string
1320                                  *
1321                                  * Just increase pointer!!!
1322                                  */
1323
1324
1325                                 /* Token-text */
1326
1327                                 gCurMmsDecodeBuffPos--;
1328                                 valueLength++;
1329
1330                                 textLength        = 0;
1331                                 szTypeString  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1332                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1333                                         goto __RETURN;
1334
1335
1336                                 /* Text-value */
1337
1338                                 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1339                                         MSG_DEBUG("Unsupported parameter(%d)\n", integer);
1340                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1341                                                 goto __RETURN;
1342                                 } else {
1343                                         textLength        = 0;
1344                                         szTypeValue  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1345
1346                                         if (szTypeValue) {
1347                                                 /* checkMe:  forwardLock needs boudary string */
1348                                                 if (strcasecmp(szTypeString, "boundary") == 0) {
1349                                                         memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1350                                                         strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1351 #ifdef FEATURE_JAVA_MMS
1352                                                 } else if (strcasecmp(szTypeString, "Application-ID") == 0) {
1353                                                         pMsgType->param.szApplicationID = (char*) calloc(1, textLength + 1);
1354                                                         if (pMsgType->param.szApplicationID) {
1355                                                                 memset(pMsgType->param.szApplicationID,  0,  textLength + 1);
1356                                                                 strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1357                                                                 MSG_SEC_DEBUG("Application-ID:%s",pMsgType->param.szApplicationID);
1358                                                         }
1359                                                 } else if (strcasecmp(szTypeString,"Reply-To-Application-ID") == 0) {
1360                                                         pMsgType->param.szReplyToApplicationID = (char*) calloc(1, textLength + 1);
1361                                                         if (pMsgType->param.szReplyToApplicationID) {
1362                                                                 memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1363                                                                 strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1364                                                                 MSG_SEC_DEBUG("ReplyToApplication-ID:%s",pMsgType->param.szReplyToApplicationID);
1365                                                         }
1366 #endif
1367                                                 }
1368
1369                                                 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeValue);
1370                                                 free(szTypeValue);
1371                                                 szTypeValue = NULL;
1372
1373                                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1374                                                         goto __RETURN;
1375                                         }
1376                                 }
1377
1378                                 if (szTypeString) {
1379                                         MSG_DEBUG("Unsupported parameter(%s)\n", szTypeString);
1380                                         free(szTypeString);
1381                                         szTypeString = NULL;
1382                                 }
1383                         }
1384
1385                         break;
1386                 }
1387         }       /*end of while loop*/
1388
1389
1390 __RETURN:
1391
1392         if (szTypeString) {
1393                 free(szTypeString);
1394                 szTypeString = NULL;
1395         }
1396
1397         MSG_END();
1398         return true;
1399
1400 __CATCH:
1401         MSG_END();
1402         return false;
1403 }
1404
1405 /**
1406  * Decode Encoded Content type
1407  *
1408  * @param       pEncodedData    [in] ContentType encoded data
1409  * @param       pMsgType                [out] Decoded MsgType
1410  * @return      Decoded address list
1411  */
1412 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1413 {
1414         MSG_BEGIN();
1415         UINT8 oneByte = 0;
1416         char *szTypeString = NULL;
1417         int valueLength = 0;
1418         int length = 0;
1419         int textLength = 0;
1420
1421
1422         /*
1423          * Content-type-value             : [WAPWSP 8.4.2.24]
1424          * Preassigned content-types  : [WAPWSP Appendix A, Table 40]
1425          * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1426          *
1427          * Content-type-value   = Constrained-media | Content-general-form
1428          * Content-general-form = Value-length Media-type
1429          * Media-type                   = (Well-known-media | Extension-Media) *(Parameter)
1430          */
1431
1432         length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1433         if (length <= 0) {
1434                 /*
1435                  * Constrained-media or Single part message
1436                  * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1437                  * Extension-media   = *TEXT End-of-string
1438                  * Short-integer     = OCTET(1xxx xxxx)
1439                  */
1440
1441                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1442                         MSG_DEBUG("Constrained-media _MmsBinaryDecodeGetOneByte fail");
1443                         goto __CATCH;
1444                 }
1445
1446                 if (oneByte > 0x7F) {
1447                         /* Short-integer */
1448                         pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1449
1450                         MSG_SEC_DEBUG("Constrained-media : Short-integer : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1451
1452                         length = 1;
1453                 } else {
1454                         char *pszTemp = NULL;
1455
1456                         /* Extension-Media */
1457                         gCurMmsDecodeBuffPos--;
1458
1459                         textLength = 0;
1460                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1461
1462                         if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1463
1464                                 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type with delimiter = [%s]", szTypeString);
1465
1466                                 pszTemp = __MsgGetStringUntilDelimiter(szTypeString, ';');
1467                                 if (pszTemp) {
1468                                         free(szTypeString);
1469                                         szTypeString = pszTemp;
1470                                 }
1471                         }
1472
1473                         pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1474
1475                         MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1476
1477                         length = textLength;
1478
1479                         if (szTypeString) {
1480                                 free(szTypeString);
1481                                 szTypeString = NULL;
1482                         }
1483                 }
1484         } else {
1485                 /*
1486                  * Content-general-form = Value-length Media-type
1487                  * Media-type                   = (Well-known-media | Extension-Media)*(Parameter)
1488                  */
1489
1490                 length += valueLength;
1491
1492                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1493                         MSG_DEBUG("Well-known-media _MmsBinaryDecodeGetOneByte fail");
1494                         goto __CATCH;
1495                 }
1496
1497                 if (oneByte > 0x7F) {
1498                         /* Well-known-media */
1499                         pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1500                         MSG_SEC_DEBUG("Content-general-form : Well-known-media : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1501                         valueLength--;
1502                 } else {
1503                         /* Extension-Media */
1504                         gCurMmsDecodeBuffPos--;
1505
1506                         textLength = 0;
1507                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1508
1509                         pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1510
1511                         MSG_SEC_DEBUG("Content-general-form : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1512
1513                         valueLength -= textLength;
1514
1515                         if (szTypeString) {
1516                                 free(szTypeString);
1517                                 szTypeString = NULL;
1518                         }
1519                 }
1520
1521                 MSG_SEC_DEBUG("Content-Type = [%s]", MmsDebugGetMimeType((MimeType)pMsgType->type));
1522
1523                 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1524                         MSG_DEBUG("Content-Type parameter fail");
1525                         goto __CATCH;
1526                 }
1527         }
1528
1529         MSG_END();
1530         return length;
1531
1532 __CATCH:
1533         MSG_END();
1534         return -1;
1535 }
1536
1537 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1538 {
1539         UINT8 fieldCode = 0xff;
1540         int length = 0;
1541         UINT32 valueLength = 0;
1542         char *pCode = NULL;
1543         char *pValue = NULL;
1544         char *pParam = NULL;
1545         char ch = '\0';
1546         UINT8 oneByte = 0;
1547         int     textLength = 0;
1548         int tmpInt = 0;
1549         int tmpIntLen = 0;
1550         char *pLatinBuff = NULL;
1551         char *szSrc = NULL;
1552         char *szTemp = NULL;
1553
1554         MSG_INFO("headerLen[%d] totalLength[%d]", headerLen, totalLength);
1555
1556         if (pFile == NULL || pMsgType == NULL)
1557                 return false;
1558
1559         /*
1560          * Message-header                         = Well-known-header | Application-header
1561          * Well-known-header              = Well-known-field-name Wap-value
1562          * Application-header             = Token-text Application-specific-value
1563          * Well-known-field-name          = Short-integer
1564          * Application-specific-value = Text-string
1565          */
1566
1567         while (headerLen > 0) {
1568                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1569                         MSG_DEBUG("field code GetOneByte fail");
1570                         goto __CATCH;
1571                 }
1572
1573                 if (0x80 <= oneByte && oneByte <= 0xC7) {
1574                         /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1575
1576                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1577                                 goto __RETURN;
1578
1579                         fieldCode = oneByte & 0x7f;
1580
1581                         switch (fieldCode) {
1582                         case 0x0E:      /* Content-Location */
1583                         case 0x04:      /* Content-Location */
1584                         {
1585                                 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1586                                 if (pLatinBuff == NULL)
1587                                         goto __CATCH;
1588
1589                                 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1590                                 if (length == -1) {
1591                                         MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1592                                         goto __CATCH;
1593                                 }
1594
1595                                 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1596                                 if (szSrc) {
1597                                         snprintf(pMsgType->szContentLocation, sizeof(pMsgType->szContentLocation), "%s", szSrc);
1598                                         MSG_SEC_DEBUG("Content Location : [%s]", pMsgType->szContentLocation);
1599                                         free(szSrc);
1600                                         szSrc = NULL;
1601                                 }
1602
1603                                 free(pLatinBuff);
1604                                 pLatinBuff = NULL;
1605
1606                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1607                                         goto __RETURN;
1608                         }
1609                                 break;
1610
1611                         case 0x40:      /* Content-ID */
1612                         {
1613                                 char szContentID[MMS_CONTENT_ID_LEN + 1] = {0, };
1614
1615                                 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1616                                 if (pLatinBuff == NULL)
1617                                         goto __CATCH;
1618
1619                                 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1620
1621                                 if (length == -1) {
1622                                         MSG_DEBUG("Content-ID __MmsBinaryDecodeQuotedString fail.");
1623                                         goto __CATCH;
1624                                 }
1625
1626                                 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1627                                 if (szSrc) {
1628                                         snprintf(szContentID, sizeof(szContentID), "%s", szSrc);
1629                                         MSG_SEC_DEBUG("Content ID : [%s]", szContentID);
1630                                         free(szSrc);
1631                                         szSrc = NULL;
1632                                 }
1633
1634                                 free(pLatinBuff);
1635                                 pLatinBuff = NULL;
1636
1637                                 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1638
1639                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1640                                         goto __RETURN;
1641                         }
1642                                 break;
1643
1644                         case 0x2E:      /* Content-Disposition */
1645                         case 0x45:      /* Content-Disposition */
1646
1647                                 /*
1648                                  * Content-disposition-value = Value-length Disposition *(Parameter)
1649                                  * Disposition = Form-data | Attachment | Inline | Token-text
1650                                  *                               Form-data = <Octet 128> : 0x80
1651                                  *                               Attachment = <Octet 129> : 0x81
1652                                  *                               Inline = <Octet 130> : 0x82
1653                                  */
1654
1655                                 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1656
1657                                 if (length > 0) {
1658                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1659                                                 goto __RETURN;
1660
1661                                 }
1662
1663                                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1664                                         MSG_DEBUG("Disposition value GetOneByte fail");
1665                                         goto __CATCH;
1666                                 }
1667
1668                                 if (length > 0)
1669                                         valueLength--;
1670
1671                                 if (oneByte >= 0x80) {
1672                                         pMsgType->disposition = MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1673
1674                                         if (pMsgType->disposition == -1) {
1675                                                 MSG_DEBUG("Content-Disposition MmsGetBinaryType fail.");
1676                                                 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT;             /* default */
1677                                         }
1678
1679                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1680                                                 goto __RETURN;
1681
1682                                         if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1683                                                 MSG_DEBUG("Disposition parameter fail");
1684                                                 goto __CATCH;
1685                                         }
1686
1687                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1688                                                 goto __RETURN;
1689                                 } else {
1690
1691                                         gCurMmsDecodeBuffPos--;
1692                                         valueLength++;
1693
1694                                         pLatinBuff = (char *)calloc(1, MSG_FILENAME_LEN_MAX);
1695                                         if (pLatinBuff == NULL)
1696                                                 goto __CATCH;
1697                                         memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1698
1699                                         textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1700
1701
1702                                         if (textLength < 0) {
1703                                                 MSG_DEBUG("Content-Disposition decodingfail.");
1704                                                 goto __CATCH;
1705                                         }
1706                                         free(pLatinBuff);
1707                                         pLatinBuff = NULL;
1708
1709                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1710                                                 goto __RETURN;
1711
1712                                         valueLength -= textLength;
1713
1714                                         if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false)
1715                                         {
1716                                                 MSG_DEBUG("Disposition parameter fail");
1717                                                 goto __CATCH;
1718                                         }
1719
1720                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1721                                                 goto __RETURN;
1722
1723                                 }
1724
1725                                 break;
1726
1727                         case 0x0B:      /* Content-Encoding */
1728
1729                                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1730                                         MSG_DEBUG("Disposition value GetOneByte fail");
1731                                         goto __CATCH;
1732                                 }
1733
1734                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1735                                         goto __RETURN;
1736
1737                                 break;
1738
1739                         case 0x0C:      /* Content-Language */
1740
1741                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1742                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1743                                                 goto __RETURN;
1744                                 } else {
1745                                         char* cTemp = NULL;
1746
1747                                         cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1748
1749                                         if (cTemp == NULL) {
1750                                                 MSG_DEBUG("__MmsBinaryDecodeText2 fail...");
1751                                                 goto __CATCH;
1752                                         }
1753
1754                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1755                                                 if (cTemp) {
1756                                                         free(cTemp);
1757                                                 }
1758                                                 goto __RETURN;
1759                                         }
1760
1761                                         if (cTemp)
1762                                                 free(cTemp);
1763                                 }
1764
1765                                 break;
1766
1767                         case 0x0D:      /* Content-Length */
1768
1769                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1770                                         MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1771                                         goto __CATCH;
1772                                 }
1773
1774                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1775                                         goto __RETURN;
1776
1777                                 break;
1778
1779                         case 0x1C:      /* Location */
1780
1781                                 pLatinBuff = (char *)calloc(1, MMS_LOCATION_URL_LEN + 1);
1782                                 if (pLatinBuff == NULL)
1783                                         goto __CATCH;
1784
1785                                 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_LOCATION_URL_LEN, totalLength);
1786                                 if (length == -1) {
1787                                         MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1788                                         goto __CATCH;
1789                                 }
1790
1791                                 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1792                                 if (szSrc) {
1793                                         snprintf(pMsgType->szLocation, sizeof(pMsgType->szLocation), "%s", szSrc);
1794                                         MSG_INFO("Location : [%s]", pMsgType->szLocation);
1795                                         free(szSrc);
1796                                         szSrc = NULL;
1797                                 }
1798
1799                                 free(pLatinBuff);
1800                                 pLatinBuff = NULL;
1801
1802                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1803                                         goto __RETURN;
1804
1805                                 break;
1806
1807                         case 0x30:      /* X-Wap-Content-URI skip this value */
1808
1809                                 MSG_DEBUG("X-Wap-Content-URI header.");
1810                                 pLatinBuff = (char *)calloc(1, MMS_TEXT_LEN);
1811                                 if (pLatinBuff == NULL)
1812                                         goto __CATCH;
1813
1814                                 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1815
1816                                 if (length == -1) {
1817                                         MSG_DEBUG(" __MmsBinaryDecodeQuotedString fail.");
1818                                         goto __CATCH;
1819                                 }
1820
1821                                 MSG_DEBUG("X-Wap-Content-URI header decoded. Value length %d\n", length);
1822                                 free(pLatinBuff);
1823                                 pLatinBuff = NULL;
1824
1825                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1826                                         goto __RETURN;
1827
1828                                 MSG_DEBUG("X-Wap-Content-URI header skipped.");
1829
1830                                 break;
1831
1832                         case 0x01:      /* Accept-charset */
1833 /*                              if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1) */
1834                                 {
1835                                         /*      WAP-230-WSP-200010705-a.pdf
1836                                                 8.4.2.8 Accept charset field
1837                                                 The following rules are used to encode accept character set values.
1838                                                 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1839                                                 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1840                                                 Constrained-charset = Any-charset | Constrained-encoding
1841                                                 Well-known-charset = Any-charset | Integer-value
1842                                                 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1843                                                 Any-charset = <Octet 128>
1844                                                 ; Equivalent to the special RFC2616 charset value ï¿½ï¿½*��
1845                                         */
1846
1847                                         int     charset = 0;
1848                                         int charSetLen = 0;
1849
1850                                         MSG_DEBUG("Accept-charset.");
1851
1852                                         length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1853                                         if (length > 0) {
1854                                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1855                                                         goto __RETURN;
1856
1857                                         }
1858
1859                                         if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1860                                                 /* We only support the well-known-charset format */
1861                                                 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1862                                                 goto __CATCH;
1863                                         }
1864
1865                                         if (charset > 0)
1866                                                 MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1867
1868                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1869                                                 goto __RETURN;
1870
1871                                         break;
1872                                 }
1873
1874                         default:
1875
1876                                 /* Other Content-xxx headers : Have valueLength */
1877
1878                                 MSG_WARN("unknown Value = 0x%x\n", oneByte);
1879
1880                                 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1881                                 if (length <= 0) {
1882                                         MSG_WARN("invalid MMS_CODE_PREVIOUSLYSENTDATE");
1883                                         goto __CATCH;
1884                                 }
1885
1886                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1887                                         goto __RETURN;
1888
1889                                 szTemp = (char *)calloc(1, valueLength);
1890                                 if (szTemp == NULL)
1891                                         goto __CATCH;
1892
1893                                 if (__MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) == false) {
1894                                         MSG_WARN("default _MmsBinaryDecodeGetBytes() fail");
1895                                         if (szTemp) {
1896                                                 free(szTemp);
1897                                                 szTemp = NULL;
1898                                         }
1899                                         goto __CATCH;
1900                                 }
1901
1902                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1903                                         goto __RETURN;
1904
1905                                 break;
1906                         }
1907                 } else {
1908                         /*
1909                          * Application-header  = Token-text Application-specific-value
1910                          * Application-specific-value = Text-string
1911                          */
1912
1913                         MSG_DEBUG(" Application-header = Token-text Application-specific-value");
1914
1915                         gCurMmsDecodeBuffPos--;
1916
1917                         /* Token-text */
1918
1919                         textLength = 0;
1920                         pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1921                         if (pCode == NULL) {
1922                                 MSG_DEBUG("pCode is null");
1923                                 goto __CATCH;
1924                         }
1925
1926                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1927                                 goto __RETURN;
1928
1929                         MSG_DEBUG(" Token-text (%s) \n", pCode);
1930
1931
1932                         /* Application-specific-value */
1933
1934                         textLength = 0;
1935                         pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1936                         if (pValue == NULL) {
1937                                 MSG_DEBUG("pValue is null");
1938                                 goto __CATCH;
1939                         }
1940
1941                         MSG_DEBUG(" Application-specific-value (%s) \n", pValue);
1942
1943
1944                         pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1945                         if (pParam) {
1946                                 ch = *pParam;
1947                                 *pParam = '\0';
1948                         }
1949
1950                         switch (MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1951                         case MMS_BODYHDR_TRANSFERENCODING:              /* Content-Transfer-Encoding */
1952                                 pMsgType->encoding = MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1953                                 break;
1954
1955                         case MMS_BODYHDR_CONTENTID:                             /* Content-ID */
1956                         {
1957                                 char szContentID[MMS_CONTENT_ID_LEN + 1];
1958
1959                                 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1960                                 if (pLatinBuff == NULL)
1961                                 {
1962                                         goto __CATCH;
1963                                 }
1964
1965                                 __MsgMIMERemoveQuote (pValue);
1966                                 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1967
1968                                 length = strlen(pLatinBuff);
1969                                 if (__MsgLatin2UTF ((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0)
1970                                 {
1971                                         MSG_DEBUG("MsgLatin2UTF fail");
1972                                         goto __CATCH;
1973                                 }
1974
1975                                 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1976
1977                                 free(pLatinBuff);
1978                                 pLatinBuff = NULL;
1979                                 break;
1980                         }
1981                         case MMS_BODYHDR_CONTENTLOCATION:               /* Content-Location */
1982
1983                                 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1984                                 if (pLatinBuff == NULL)
1985                                         goto __CATCH;
1986
1987                                 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1988
1989                                 length = strlen(pLatinBuff);
1990                                 if (__MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1991                                         MSG_DEBUG("MsgLatin2UTF fail");
1992                                         goto __CATCH;
1993                                 }
1994
1995                                 free(pLatinBuff);
1996                                 pLatinBuff = NULL;
1997                                 break;
1998
1999                         case MMS_BODYHDR_DISPOSITION:                   /* Content-Disposition */
2000                                 pMsgType->disposition = MmsGetTextType(MmsCodeMsgDisposition, pValue);
2001                                 break;
2002
2003                         case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY:   /* DRM RO WAITING */
2004                                         break;
2005
2006                         default:
2007                                 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
2008                                 break;
2009                         }
2010
2011                         if (pParam) {
2012                                 __MsgParseParameter(pMsgType, pParam + 1);
2013                                 *pParam = ch;
2014                         }
2015                         if (pCode) {
2016                                 free(pCode);
2017                                 pCode = NULL;
2018                         }
2019                         if (pValue) {
2020                                 free(pValue);
2021                                 pValue = NULL;
2022                         }
2023
2024                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2025                                 goto __RETURN;
2026
2027                 }
2028         } /* while */
2029
2030 __RETURN:
2031
2032         if (szTemp) {
2033                 free(szTemp);
2034                 szTemp = NULL;
2035         }
2036
2037         if (pCode) {
2038                 free(pCode);
2039                 pCode = NULL;
2040         }
2041
2042         return true;
2043
2044 __CATCH:
2045
2046         if (pLatinBuff) {
2047                 free(pLatinBuff);
2048                 pLatinBuff = NULL;
2049         }
2050         if (pCode) {
2051                 free(pCode);
2052                 pCode = NULL;
2053         }
2054         if (pValue) {
2055                 free(pValue);
2056                 pValue = NULL;
2057         }
2058
2059         if (szTemp) {
2060                 free(szTemp);
2061                 szTemp = NULL;
2062         }
2063
2064         return false;
2065 }
2066
2067 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2068 {
2069         int length = 0;
2070
2071         length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2072         if (length <= 0) {
2073                 goto __CATCH;
2074         }
2075
2076         MSG_INFO("Number of Entries = [%d]", *npEntries);
2077
2078         return true;
2079
2080 __CATCH:
2081         return false;
2082 }
2083
2084 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2085 {
2086         int offset = 0;
2087
2088         /*
2089          * Currently, offset and size is
2090          * the only information used with msgBody.
2091          * If you need, add here more information
2092          */
2093         MSG_BEGIN();
2094
2095         offset = __MmsGetDecodeOffset();
2096         offset += bodyLength;
2097
2098         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2099                 MSG_DEBUG("fail to seek file pointer");
2100                 goto __CATCH;
2101         }
2102
2103         __MmsCleanDecodeBuff();
2104
2105         gMmsDecodeCurOffset = offset;
2106
2107         if (offset >= totalLength)
2108                 goto __RETURN;
2109
2110         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2111                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2112                 MSG_DEBUG("fail to load to buffer");
2113                 goto __CATCH;
2114         }
2115
2116         return true;
2117
2118 __RETURN:
2119         return true;
2120
2121 __CATCH:
2122         return false;
2123 }
2124
2125 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2126 {
2127         if (offset > totalLength)
2128                 goto __RETURN;
2129
2130         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2131                 MSG_DEBUG("fail to seek file pointer");
2132                 goto __CATCH;
2133         }
2134
2135         __MmsCleanDecodeBuff();
2136
2137         gMmsDecodeCurOffset = offset;
2138
2139         if (offset == totalLength)
2140                 goto __RETURN;
2141
2142         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2143                                                                         gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2144                 MSG_DEBUG("fail to load to buffer");
2145                 goto __CATCH;
2146         }
2147
2148 __RETURN:
2149         return true;
2150
2151 __CATCH:
2152         return false;
2153 }
2154
2155 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2156 {
2157         UINT32 nEntries = 0;
2158         MsgMultipart *pMultipart = NULL;
2159         MsgMultipart *pLastMultipart = NULL;
2160         int offset = 0;
2161         int     index = 0;
2162
2163         MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2164         MsgPresentaionInfo presentationInfo;
2165
2166         MSG_DEBUG("pdu length = [%d]", totalLength);
2167
2168         presentationInfo.factor = MSG_PRESENTATION_NONE;
2169         presentationInfo.pCurPresentation = NULL;
2170         presentationInfo.pPrevPart = NULL;
2171
2172         if (__MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2173                 MSG_DEBUG("MmsBinaryDecodeEntries is fail.");
2174                 goto __CATCH;
2175         }
2176
2177         if (pMsgBody->body.pMultipart != NULL) {
2178                 pLastMultipart = pMsgBody->body.pMultipart;
2179                 MSG_DEBUG("previous multipart exist [%p]", pMsgBody->body.pMultipart);
2180         } else {
2181                 MSG_DEBUG("first multipart");
2182         }
2183
2184         while (nEntries) {
2185                 MSG_DEBUG("decoding [%d]th multipart", index);
2186
2187                 offset = __MmsGetDecodeOffset();
2188                 if (offset >= totalLength) {
2189                         MSG_DEBUG("offset is over totalLength");
2190                         break;
2191                 }
2192
2193                 if ((pMultipart = MmsAllocMultipart()) == NULL) {
2194                         MSG_DEBUG("MsgAllocMultipart Fail");
2195                         goto __CATCH;
2196                 }
2197
2198                 if (__MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2199                         MSG_DEBUG("MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2200                         goto __CATCH;
2201                 }
2202
2203                 if (pMultipart->type.type == MIME_APPLICATION_SMIL) {
2204                         /* P151019-00477 : received mms message is type of multipart mixed, but among multiparts if there's smil part then set it multipart related */
2205                         if (pMsgType->type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED)
2206                                 pMsgType->type = MIME_APPLICATION_VND_WAP_MULTIPART_RELATED;
2207
2208                         factor = __MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2209                         if (factor == MSG_PRESENTATION_NONE) {
2210                                 factor = MSG_PRESENTATION_TYPE_BASE;
2211                         }
2212                 } else {
2213                         factor = MSG_PRESENTATION_NONE;
2214                 }
2215
2216                 /* priority 1 : content type match, 2: content location, 3: type */
2217                 if (presentationInfo.factor < factor) {
2218                         /* Presentation part */
2219                         presentationInfo.factor = factor;
2220                         presentationInfo.pPrevPart = pLastMultipart;
2221                         presentationInfo.pCurPresentation = pMultipart;
2222                 }
2223
2224                 /* first multipart */
2225                 if (pLastMultipart == NULL) {
2226                         pMsgBody->body.pMultipart = pMultipart;
2227                         pLastMultipart = pMultipart;
2228                 } else {
2229                         pLastMultipart->pNext = pMultipart;
2230                         pLastMultipart = pMultipart;
2231                 }
2232
2233                 pMsgType->contentSize += pMultipart->pBody->size;
2234
2235                 nEntries--;
2236
2237                 MmsPrintMulitpart(pMultipart, index++);
2238
2239         }
2240
2241         pMsgBody->size = totalLength - pMsgBody->offset;
2242
2243         __MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2244
2245         if (__MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2246                 MSG_DEBUG("MsgResolveNestedMultipart failed");
2247                 goto __CATCH;
2248         }
2249
2250         return true;
2251
2252 __CATCH:
2253         if (pMultipart) {
2254                 if (pMultipart->pBody) {
2255                         free(pMultipart->pBody);
2256                         pMultipart->pBody = NULL;
2257                 }
2258
2259                 free(pMultipart);
2260                 pMultipart = NULL;
2261         }
2262
2263         return false;
2264 }
2265
2266 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2267 {
2268         int     length = 0;
2269         bool bSuccess = false;
2270         UINT32 headerLength = 0;
2271         UINT32 bodyLength = 0;
2272         int offset = 0;
2273
2274         MSG_DEBUG("pdu length = [%d]", totalLength);
2275
2276         /* header length */
2277         if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2278                 MSG_DEBUG("Get header length fail");
2279                 goto __CATCH;
2280         }
2281
2282         offset = __MmsGetDecodeOffset();
2283         if (offset >= totalLength)
2284                 goto __RETURN;
2285
2286         /* body length */
2287         if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2288                 MSG_DEBUG("Get body length fail");
2289                 goto __CATCH;
2290         }
2291
2292         offset = __MmsGetDecodeOffset();
2293         if (offset >= totalLength)
2294                 goto __RETURN;
2295
2296         /* Content Type */
2297         if (szFilePath != NULL)
2298                 snprintf(pMsgType->szOrgFilePath, sizeof(pMsgType->szOrgFilePath), "%s", szFilePath);
2299
2300         pMsgType->offset = __MmsGetDecodeOffset();
2301         pMsgType->size = headerLength;
2302         pMsgType->contentSize = bodyLength;
2303
2304         if (pMsgType->offset > totalLength)
2305                 goto __RETURN;
2306
2307         length = __MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2308         if (length <= 0) {
2309                 MSG_DEBUG("Decode contentType Fail");
2310                 goto __CATCH;
2311         }
2312
2313         offset = __MmsGetDecodeOffset();
2314         if (offset >= totalLength)
2315                 goto __RETURN;
2316
2317
2318         /* Part Header */
2319
2320         if (__MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2321                 MSG_DEBUG("Decode contentHeader Fail");
2322                 goto __CATCH;
2323         }
2324
2325         offset = __MmsGetDecodeOffset();
2326         if (offset >= totalLength)
2327                 goto __RETURN;
2328
2329         /* Part Body */
2330
2331         if (szFilePath != NULL)
2332                 snprintf(pMsgBody->szOrgFilePath, sizeof(pMsgBody->szOrgFilePath), "%s", szFilePath);
2333
2334         pMsgBody->offset = __MmsGetDecodeOffset();
2335         pMsgBody->size   = bodyLength;
2336
2337         if (pMsgBody->offset > totalLength)
2338                 goto __RETURN;
2339
2340         switch (pMsgType->type) {
2341         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2342         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2343         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2344         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2345         case MIME_MULTIPART_REPORT:
2346         case MIME_MULTIPART_MIXED:
2347         case MIME_MULTIPART_RELATED:
2348         case MIME_MULTIPART_ALTERNATIVE:
2349
2350                 MSG_DEBUG("Multipart");
2351                 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2352                         MSG_DEBUG("MmsBinaryDecodeMultipart is fail");
2353                         goto __CATCH;
2354                 }
2355
2356                 offset = __MmsGetDecodeOffset();
2357                 if (offset >= totalLength)
2358                         goto __RETURN;
2359
2360                 break;
2361
2362         default:
2363                 MSG_DEBUG("Normal Part");
2364
2365                 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2366                 if (bSuccess == false) {
2367                         MSG_DEBUG("Decode contentBody Fail");
2368                         goto __CATCH;
2369                 }
2370
2371                 offset = __MmsGetDecodeOffset();
2372                 if (offset >= totalLength)
2373                         goto __RETURN;
2374
2375                 break;
2376         }
2377
2378         MSG_END();
2379         return true;
2380
2381 __RETURN:
2382         MSG_END();
2383         return true;
2384
2385 __CATCH:
2386         MSG_END();
2387         return false;
2388 }
2389
2390 /* --------------------------------------------------------------------
2391  *
2392  *     B  I  N  A  R  Y       D  E  C  D  E      U  T  I  L  I  T  Y
2393  *
2394  * --------------------------------------------------------------------*/
2395
2396 bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
2397 {
2398         int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2399
2400         if (pFile == NULL || pOneByte == NULL)
2401         {
2402                 MSG_DEBUG("invalid file or buffer");
2403                 goto __CATCH;
2404         }
2405
2406         if (length < 1) {
2407                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2408                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2409                         MSG_DEBUG("fail to load to buffer");
2410                         goto __CATCH;
2411                 }
2412         }
2413
2414         *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2415
2416         return true;
2417
2418 __CATCH:
2419         return false;
2420 }
2421
2422 /*
2423  * @remark: bufLen < gMmsDecodeMaxLen
2424  */
2425 bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2426 {
2427         int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2428         int i = 0;
2429
2430
2431         if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
2432                 goto __CATCH;
2433
2434         memset(szBuff, 0, bufLen);
2435
2436         if (length < bufLen) {
2437                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2438                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2439                         MSG_DEBUG("fail to load to buffer");
2440                         goto __CATCH;
2441                 }
2442         }
2443
2444         for (i = 0; i < bufLen - 1; i++) {
2445                 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2446         }
2447
2448         gCurMmsDecodeBuffPos++; /* NULL */
2449
2450         return true;
2451
2452 __CATCH:
2453         return false;
2454 }
2455
2456 bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2457 {
2458         int iPos = 0;
2459
2460         if (pFile == NULL || szBuff == NULL || bufLen == 0)
2461                 goto __CATCH;
2462
2463         memset(szBuff, 0, bufLen);
2464
2465         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2466                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2467                 MSG_DEBUG("fail to load to buffer");
2468                 goto __CATCH;
2469         }
2470
2471         while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
2472                 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
2473                         MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2474                         goto __CATCH;
2475                 }
2476
2477                 iPos += gMmsDecodeMaxLen;
2478         }
2479
2480         if ((bufLen - iPos) > 0) {
2481                 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
2482                         MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2483                         goto __CATCH;
2484                 }
2485
2486                 iPos += (bufLen - iPos);
2487         }
2488
2489         return true;
2490
2491 __CATCH:
2492         return false;
2493 }
2494
2495 /**
2496  * Decode uintvar to 32bit unsigned integer
2497  *
2498  * @param       pEncodedData    [in] encoded data
2499  * @param       pUintVar                [out] Decode uintvar (32bit unsigned integer)
2500  * @return      The length of uintvar (-1, if cannot be converted to a uintvar)
2501  *
2502  * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
2503  * - -------
2504  */
2505 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
2506
2507 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
2508 {
2509         UINT8 count = 0;
2510         UINT8 oneByte = 0;
2511         UINT32 decodedUintvar = 0;
2512         UINT8 iBuff[5] = {0};
2513         int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
2514
2515
2516         if (pFile == NULL || pUintVar == NULL)
2517                 return -1;
2518
2519         if (length < 5) {
2520                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2521                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2522                         MSG_DEBUG("fail to load to buffer");
2523                         goto __CATCH;
2524                 }
2525         }
2526
2527         while (true) {
2528                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2529                         goto __CATCH;
2530
2531                 if (oneByte > 0x7f)     {
2532                         iBuff[count++] = oneByte;
2533                 } else {
2534                         iBuff[count++] = oneByte;
2535                         break;
2536                 }
2537
2538                 if (count > 4) {
2539                         MSG_DEBUG("legnth is too long");
2540                         goto __CATCH;
2541                 }
2542         }
2543
2544         for (int i = 0; i < count; i++)
2545                 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
2546
2547         *pUintVar = decodedUintvar;
2548
2549         return count;
2550
2551 __CATCH:
2552         gCurMmsDecodeBuffPos -= count;
2553         return -1;
2554 }
2555
2556 /**
2557  * Decode uintvar to 32bit unsigned integer by uintvar length
2558  *
2559  * @param       pEncodedData [in] uintvar encoded data
2560  * @param       length           [in] length of integer value
2561  * @return      unsigned integer value
2562  */
2563 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
2564 {
2565         UINT32 i = 0;
2566         UINT8 oneByte = 0;
2567         char *pData = NULL;
2568         union {
2569                 UINT32  integer;
2570                 UINT8   seg[4];
2571         } returner;
2572
2573         returner.integer = 0;
2574
2575         if (length > 4)
2576                 length = 4;
2577
2578         if (length == 1)
2579         {
2580                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2581                         MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2582                         return oneByte;
2583                 }
2584
2585                 if (oneByte > 0x7f) {
2586                         return (oneByte & 0x7f);
2587                 } else {
2588                         return oneByte;
2589                 }
2590         }
2591
2592         if (length == 0)
2593                 return 0;
2594
2595         pData = (char *)calloc(1, length + 1);
2596         if (pData == NULL) {
2597                 MSG_DEBUG("pData alloc fail");
2598                 goto __CATCH;
2599         }
2600         memset(pData, 0, length + 1);
2601
2602         if (__MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
2603                 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2604                 goto __CATCH;
2605         }
2606
2607         gCurMmsDecodeBuffPos--; /* - NULL */
2608
2609         for (i= 0; i < length; i++)
2610                 returner.seg[length - (i+1)] = pData[i];
2611
2612         if (pData) {
2613                 free(pData);
2614                 pData = NULL;
2615         }
2616
2617         return returner.integer;
2618
2619 __CATCH:
2620
2621         if (pData) {
2622                 free(pData);
2623                 pData = NULL;
2624         }
2625
2626         return returner.integer;
2627 }
2628
2629 /**
2630  * Decode uintvar to 32bit unsigned integer by uintvar length
2631  *
2632  * @param       pEncodedData    [in]  uintvar encoded data
2633  * @param       pInteger                [out] Decode integer value (long/short)
2634  * @return      unsigned integer value (-1, if cannot be converted to unsigned integer value)
2635  */
2636 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
2637 {
2638         UINT8 oneByte   = 0;
2639         char *pData     = NULL;
2640         union {
2641                 UINT32  integer;
2642                 UINT8   seg[4];
2643         } returner;
2644
2645
2646         if (pInteger == NULL)
2647                 return false;
2648
2649         returner.integer = 0;
2650         *pIntLen                 = 0;
2651
2652         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2653                 MSG_DEBUG("GetOneByte fail");
2654                 return false;
2655         }
2656
2657         if (oneByte < 0x1F)                             /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2658         {
2659                 pData = (char *)calloc(1, oneByte + 1);
2660                 if (pData == NULL) {
2661                         MSG_DEBUG("pData calloc fail");
2662                         goto __CATCH;
2663                 }
2664                 memset(pData, 0, oneByte + 1);
2665
2666                 /* Even NULL is copied in the _MmsBinaryDecodeGetBytes */
2667                 if (__MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
2668                         MSG_DEBUG("GetBytes fail");
2669                         goto __CATCH;
2670                 }
2671
2672                 gCurMmsDecodeBuffPos--; /* - NULL */
2673
2674                 int             length  = 0;
2675                 if (oneByte > 4) {
2676                         length = 4;
2677                 } else {
2678                         length = oneByte;
2679                 }
2680
2681                 int             i = 0;
2682                 for (i = 0; i < length; i++)
2683                         returner.seg[length - (i+1)] = pData[i];
2684
2685                 *pInteger = returner.integer;
2686                 *pIntLen  = oneByte + 1;
2687         } else if (oneByte >= 0x80)     {
2688                 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2689                 *pInteger = oneByte & 0x7f;
2690                 *pIntLen  = 1;
2691         } else {
2692                 goto __CATCH;
2693         }
2694
2695         if (pData) {
2696                 free(pData);
2697                 pData = NULL;
2698         }
2699
2700         return true;
2701
2702 __CATCH:
2703
2704         gCurMmsDecodeBuffPos--;
2705
2706         if (pData) {
2707                 free(pData);
2708                 pData = NULL;
2709         }
2710
2711         return false;
2712 }
2713
2714 /**
2715  * Decode uintvar to 32bit unsigned integer by uintvar length
2716  *
2717  * @return      1  : Success
2718  *                      0  : This is not Value Length type data
2719  *                      -1 : Requires System error report
2720  */
2721 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
2722 {
2723         int length = 0;
2724         UINT32 uintvar = 0;
2725         UINT8 oneByte = 0;
2726
2727
2728         /*
2729          * value-length = short-length | (Length-quote Length)
2730          *                              = 0~30             | 31 + Uintvar-length
2731          */
2732
2733         if (pFile == NULL || pValueLength == NULL)
2734                 goto __CATCH;
2735
2736         *pValueLength = 0;
2737
2738         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2739                 gCurMmsDecodeBuffPos--;
2740                 goto __CATCH;
2741         }
2742
2743         if (0x00 < oneByte && oneByte < 0x1F) {
2744                 /* short-length */
2745
2746                 *pValueLength = oneByte;
2747                 length = 1;
2748         } else if (oneByte == 0x1F) {
2749                 /* Length-quote = 0x1F */
2750
2751                 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2752                 if (length == -1) {
2753                         MSG_DEBUG(" __MmsBinaryDecodeUintvar fail..");
2754                         goto __CATCH;
2755                 }
2756                 length ++;                                      /* + length-quote */
2757                 *pValueLength = uintvar;
2758         } else {
2759                 MSG_DEBUG("not a value length type data");
2760                 gCurMmsDecodeBuffPos--;
2761                 return 0;
2762         }
2763
2764         return length;
2765
2766 __CATCH:
2767         MSG_DEBUG("getting data fail");
2768         return -1;
2769 }
2770
2771 /**
2772  * Decode uintvar to 32bit unsigned integer by uintvar length
2773  *
2774  * @return      1  : Success
2775  *                      0  : This is not Value Length type data
2776  *                      -1 : Requires System error report
2777  * @ defference : if there is not length-quote, consider it as short length.
2778  */
2779 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
2780 {
2781         int length      = 0;
2782         UINT32 uintvar = 0;
2783         UINT8 oneByte = 0;
2784
2785
2786         /*
2787          * value-length = short-length | (Length-quote Length)
2788          *                              = 0~30             | 31 + Uintvar-length
2789          */
2790
2791         if (pFile == NULL || pValueLength == NULL)
2792                 goto __CATCH;
2793
2794         *pValueLength = 0;
2795
2796         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2797                 gCurMmsDecodeBuffPos--;
2798                 goto __CATCH;
2799         }
2800
2801         if (0x00 < oneByte && oneByte < 0x1F) {
2802                 /* short-length */
2803
2804                 *pValueLength = oneByte;
2805                 length = 1;
2806         } else if (oneByte == 0x1F) {
2807                 /* Length-quote = 0x1F */
2808
2809                 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2810                 if (length == -1) {
2811                         MSG_DEBUG("__MmsBinaryDecodeUintvar fail..");
2812                         goto __CATCH;
2813                 }
2814                 length ++;                                      /* + length-quote */
2815                 *pValueLength = uintvar;
2816         } else {
2817                 MSG_DEBUG("there is not length-quote, consider it as short length.");
2818                 *pValueLength = oneByte;
2819                 length = 1;
2820         }
2821
2822         return length;
2823
2824 __CATCH:
2825         MSG_DEBUG("getting data fail");
2826         return -1;
2827 }
2828
2829 /**
2830  * Decode QuotedString
2831  *
2832  * @param       pEncodedData    [in] QuotedString encoded data
2833  * @param       szBuff                  [out] Decoded quoted string
2834  * @param       bufLen                  [out] Buffer length
2835  * @return      length of quoted string
2836  */
2837 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2838 {
2839         int iPos = 0;
2840         int length = 0;
2841         int readBytes = 0;
2842         char *pData = NULL;
2843         int returnLength = 0;
2844
2845         /*
2846          * Quoted-string = <Octet 34> *TEXT End-of-string
2847          * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
2848          */
2849
2850         if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2851                 return -1;
2852
2853         memset(szBuff, 0, bufLen);
2854
2855         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2856                                                                          gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2857                 MSG_DEBUG("fail to load to buffer");
2858                 goto __CATCH;
2859         }
2860
2861         length = strlen(gpCurMmsDecodeBuff) + 1;        /* + NULL */
2862
2863         if (length == 0)
2864                 goto __RETURN;
2865
2866         while (length > gMmsDecodeBufLen) {
2867                 if (gMmsDecodeBufLen <= 0) {
2868                         MSG_DEBUG("gMmsDecodeBufLen <= 0");
2869                         MSG_DEBUG("%x %x %x %x %x",
2870                                                                                 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
2871                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
2872                         MSG_DEBUG("%x %x %x %x %x",
2873                                                                                 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
2874                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
2875                         MSG_DEBUG("%x %x %x %x %x",
2876                                                                                 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
2877                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
2878                         MSG_DEBUG("%x %x %x %x %x",
2879                                                                                 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
2880                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
2881                         goto __CATCH;
2882                 }
2883
2884                 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
2885                 if (pData == NULL)
2886                         goto __CATCH;
2887
2888                 memset(pData, 0, gMmsDecodeBufLen + 1);
2889
2890                 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
2891                         goto __CATCH;
2892
2893                 returnLength += gMmsDecodeBufLen;
2894
2895                 if ((bufLen - iPos) > 0) {
2896                         readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
2897                         if (iPos == 0 && (pData[0] == MARK)) {
2898                                 /* MARK: check first time only */
2899
2900                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2901                                 iPos += (readBytes - 1);
2902                         } else {
2903                                 strncpy(szBuff + iPos, (char*)pData, readBytes);
2904                                 iPos += readBytes;
2905                         }
2906                 }
2907
2908                 if (pData) {
2909                         free(pData);
2910                         pData = NULL;
2911                 }
2912
2913                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2914                                                                                 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2915                         MSG_DEBUG("fail to load to buffer");
2916                         goto __CATCH;
2917                 }
2918                 length = strlen(gpCurMmsDecodeBuff) + 1;        /* + NULL */
2919         }       /* while */
2920
2921         if (length > 0) {
2922                 pData = (char *)calloc(1, length);
2923                 if (pData == NULL)
2924                         goto __CATCH;
2925
2926                 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
2927                         goto __CATCH;
2928
2929                 returnLength += length;
2930
2931                 if ((bufLen - iPos) > 0) {
2932                         /* read until NULL from raw data, and copy only string */
2933                         readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
2934                         if (iPos == 0 && (pData[0] == MARK)) {
2935                                 /* MARK: check first time only */
2936                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2937                                 iPos += (readBytes - 1);
2938                         } else {
2939                                 strncpy(szBuff + iPos, (char*)pData, readBytes - 1);    /* + NULL */
2940                                 iPos += readBytes;
2941                         }
2942                 }
2943
2944                 if (pData) {
2945                         free(pData);
2946                         pData = NULL;
2947                 }
2948         }
2949
2950         szBuff[bufLen - 1] = '\0';
2951
2952         return returnLength;
2953
2954 __RETURN:
2955
2956         return length;
2957
2958 __CATCH:
2959
2960         if (pData) {
2961                 free(pData);
2962                 pData = NULL;
2963         }
2964
2965         return -1;
2966 }
2967
2968 /**
2969  * Decode Text
2970  *
2971  * @param       pEncodedData    [in] QuotedString encoded data
2972  * @param       szBuff                  [out] Decoded quoted string
2973  * @param       bufLen                  [out] Buffer length
2974  * @return      length of decode text string
2975  */
2976 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2977 {
2978         int length = 0;
2979         int readBytes = 0;
2980         int iPos = 0;
2981         int returnLength = 0;
2982         char *pData = NULL;
2983         bool bQuote = false;
2984         int offset = 0;
2985
2986         /*
2987          * Text-String = [QUOTE]*TEXT end_of_string
2988          *                               [QUOTE]*(128~255)\0
2989          *                               *(32~126)\0
2990          */
2991
2992         if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2993                 return -1;
2994
2995         offset = __MmsGetDecodeOffset();
2996         if (offset >= totalLength)
2997                 goto __RETURN;
2998
2999         memset(szBuff, 0, bufLen);
3000
3001         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3002                                                                         gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3003                 MSG_DEBUG("fail to load to buffer");
3004                 goto __CATCH;
3005         }
3006
3007         length = strlen(gpCurMmsDecodeBuff) + 1;        /* + NULL */
3008
3009         if (length == 0)
3010                 goto __RETURN;
3011
3012         while (length > gMmsDecodeBufLen) {
3013                 if (gMmsDecodeBufLen <= 0) {
3014                         MSG_DEBUG("gMmsDecodeBufLen <= 0");
3015                         MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3016                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3017                         MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3018                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3019                         MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3020                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3021                         MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3022                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3023                         goto __CATCH;
3024                 }
3025
3026                 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3027                 if (pData == NULL)
3028                         goto __CATCH;
3029
3030                 memset(pData, 0, gMmsDecodeBufLen + 1);
3031
3032                 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3033                         goto __CATCH;
3034
3035                 if ((bufLen - iPos) > 0) {
3036                         readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3037                         if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3038                                 /* QUOTE: check first time only */
3039
3040                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3041                                 iPos += (readBytes - 1);
3042                                 bQuote = true;
3043                         } else {
3044                                 strncpy(szBuff + iPos, (char*)pData, readBytes);
3045                                 iPos += readBytes;
3046                         }
3047                 }
3048
3049                 if (pData) {
3050                         free(pData);
3051                         pData = NULL;
3052                 }
3053
3054                 returnLength += gMmsDecodeBufLen;
3055
3056                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3057                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3058                         MSG_DEBUG("fail to load to buffer");
3059                         goto __CATCH;
3060                 }
3061                 length = strlen(gpCurMmsDecodeBuff) + 1;        /* + NULL */
3062         }       /* while */
3063
3064         if (length > 0) {
3065                 pData = (char *)calloc(1, length);
3066                 if (pData == NULL)
3067                         goto __CATCH;
3068
3069                 memset(pData, 0, length);
3070
3071                 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3072                         goto __CATCH;
3073
3074                 if ((bufLen - iPos) > 0) {
3075                         readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3076                         if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3077                                 /* QUOTE: check first time only */
3078
3079                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3080                                 iPos += (readBytes - 1);
3081                                 bQuote = true;
3082                         } else {
3083                                 strncpy(szBuff + iPos, (char*)pData, readBytes - 1);    /* + NULL */
3084                                 iPos += readBytes;
3085                         }
3086                 }
3087
3088                 if (pData) {
3089                         free(pData);
3090                         pData = NULL;
3091                 }
3092
3093                 returnLength += length;         /* + NULL */
3094         }
3095
3096         szBuff[bufLen - 1] = '\0';
3097
3098         return returnLength;
3099
3100 __RETURN:
3101
3102         szBuff[0] = '\0';
3103         length = 0;
3104
3105         __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3106
3107         return length;
3108
3109 __CATCH:
3110
3111         if (pData) {
3112                 free(pData);
3113                 pData = NULL;
3114         }
3115
3116         return -1;
3117 }
3118
3119 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
3120 {
3121         int length = 0;
3122         int curLen = 0;
3123         char *pData = NULL;
3124         char *szBuff = NULL;
3125         char *szTempPtr = NULL;
3126         bool bQuote = false;
3127         int offset = 0;
3128
3129         /*
3130          * Text-String = [QUOTE]*TEXT end_of_string
3131          *                               [QUOTE]*(128~255)\0
3132          *                               *(32~126)\0
3133          */
3134
3135         if (pFile == NULL || pLength == NULL)
3136                 goto __CATCH;
3137
3138         *pLength = 0;
3139         offset = __MmsGetDecodeOffset();
3140         if (offset >= totalLength)
3141                 goto __RETURN;
3142
3143         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3144                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3145                 MSG_DEBUG("fail to load to buffer");
3146                 goto __CATCH;
3147         }
3148
3149         length = strlen(gpCurMmsDecodeBuff) + 1;
3150
3151         if (length == 0)
3152                 goto __CATCH;
3153
3154         while (length > gMmsDecodeBufLen) {
3155                 if (gMmsDecodeBufLen <= 0) {
3156                         MSG_DEBUG("gMmsDecodeBufLen <= 0");
3157                         MSG_DEBUG("%x %x %x %x %x",
3158                                                                                 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3159                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3160                         MSG_DEBUG("%x %x %x %x %x",
3161                                                                                 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3162                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3163                         MSG_DEBUG("%x %x %x %x %x",
3164                                                                                 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3165                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3166                         MSG_DEBUG("%x %x %x %x %x\n",
3167                                                                                 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3168                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3169                         goto __CATCH;
3170                 }
3171
3172                 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3173                 if (pData == NULL)
3174                         goto __CATCH;
3175
3176                 memset(pData, 0, gMmsDecodeBufLen + 1);
3177
3178                 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3179                         goto __CATCH;
3180
3181                 if (szBuff == NULL)     {
3182                         szBuff = (char *)calloc(1, gMmsDecodeBufLen + 1);
3183                 } else {
3184                         szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
3185
3186                         /* NULL pointer check for realloc */
3187                         if (szTempPtr == NULL) {
3188                                 goto __CATCH;
3189                         } else {
3190                                 szBuff = szTempPtr;
3191                         }
3192                 }
3193                 if (szBuff == NULL)
3194                         goto __CATCH;
3195
3196                 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
3197
3198                 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3199                         /* QUOTE: check first time only */
3200
3201                         strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
3202                         curLen += (gMmsDecodeBufLen - 1);
3203                         bQuote = true;
3204                 } else {
3205                         strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
3206                         curLen += gMmsDecodeBufLen;
3207                 }
3208
3209                 if (pData) {
3210                         free(pData);
3211                         pData = NULL;
3212                 }
3213
3214                 *pLength += gMmsDecodeBufLen;
3215
3216                 if (__MsgLoadDataToDecodeBuffer(pFile,
3217                                                            &gpCurMmsDecodeBuff,
3218                                                            &gCurMmsDecodeBuffPos,
3219                                                            &gMmsDecodeCurOffset,
3220                                                            gpMmsDecodeBuf1,
3221                                                            gpMmsDecodeBuf2,
3222                                                            gMmsDecodeMaxLen,
3223                                                            &gMmsDecodeBufLen,
3224                                                            totalLength) == false) {
3225                         MSG_DEBUG("fail to load to buffer");
3226                         goto __CATCH;
3227                 }
3228                 length = strlen(gpCurMmsDecodeBuff) + 1;
3229         }       /* while */
3230
3231         if (length > 0) {
3232                 pData = (char *)calloc(1, length);
3233                 if (pData == NULL) {
3234                         goto __CATCH;
3235                 }
3236
3237                 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
3238                         goto __CATCH;
3239                 }
3240
3241                 if (szBuff == NULL) {
3242                         szBuff = (char *)calloc(1, length);
3243                 } else {
3244                         szTempPtr = (char *)realloc(szBuff, curLen + length);
3245
3246                         /* NULL pointer check for realloc */
3247                         if (szTempPtr == NULL)
3248                                 goto __CATCH;
3249                         else
3250                                 szBuff = szTempPtr;
3251                 }
3252
3253                 if (szBuff == NULL) {
3254                         goto __CATCH;
3255                 }
3256
3257                 memset(szBuff + curLen, 0, length);
3258
3259                 if (curLen == 0 && (pData[0] == QUOTE)  && (bQuote == false)) {
3260                         /* QUOTE: check first time only */
3261
3262                         strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
3263                         curLen += (length - 1);
3264                         bQuote = true;
3265                 } else {
3266                         strncpy(szBuff + curLen, (char*)pData, length - 1);
3267                         curLen += length;
3268                 }
3269
3270                 if (pData) {
3271                         free(pData);
3272                         pData = NULL;
3273                 }
3274
3275                 *pLength += length;             /* + NULL */
3276         }
3277
3278         return szBuff;
3279
3280 __RETURN:
3281
3282         *pLength = 1;
3283
3284         __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3285
3286         return szBuff;
3287
3288 __CATCH:
3289
3290         if (szBuff) {
3291                 free(szBuff);
3292                 szBuff = NULL;
3293         }
3294
3295         if (pData) {
3296                 free(pData);
3297                 pData = NULL;
3298         }
3299
3300         return NULL;
3301 }
3302
3303 /**
3304  * Decode Charset
3305  *
3306  * @param       pEncodedData    [in] QuotedString encoded data
3307  * @param       nCharSet                [out] Decoded character set
3308  * @return      length of charset value
3309  */
3310 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
3311 {
3312         UINT32 integer = 0;
3313
3314         /*
3315          * Charset v1.1 0x01 Well-known-charset
3316          *                                       Well-known-charset = Any-charset | Integer-value
3317          *                                              ; Both are encoded using values from
3318          *                                                Character Set Assignments table in Assigned Numbers
3319          *                                       Any-charset = <Octet 128>
3320          *                                              ; Equivalent to the special RFC2616 charset value ï¿½ï¿½*��
3321          */
3322
3323         if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
3324                 return false;
3325
3326         if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
3327                 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
3328                 goto __CATCH;
3329         }
3330
3331         if (integer == 0) {
3332                 /* AnyCharSet : return MSG_CHARSET_UTF8 */
3333                 *nCharSet = MSG_CHARSET_UTF8;
3334                 return true;
3335         }
3336
3337         *nCharSet = MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
3338         MSG_DEBUG("Decoded charset MIBenum = [%d], charset enum = [%d]", integer, *nCharSet);
3339         if (*nCharSet == MIME_UNKNOWN) {
3340                 MSG_DEBUG("MmsGetBinaryType fail..");
3341                 *nCharSet = MSG_CHARSET_UNKNOWN;
3342         }
3343
3344         return true;
3345
3346 __CATCH:
3347         return false;
3348 }
3349
3350 /**
3351  * Decode EncodedString
3352  *
3353  * @param       pEncodedData    [in] QuotedString encoded data
3354  * @param       szBuff                  [out] Decoded string buffer
3355  * @param       bufLen                  [in]  Decoded buffer length
3356  * @return      length of decoded string length
3357  */
3358 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3359 {
3360         UINT32 valueLength = 0;
3361         UINT32 charSet = 0;
3362         int charSetLen = 0;
3363         int nTemp = 0;
3364         char *pData = NULL;
3365
3366         MSG_DEBUG(" decode string..");
3367
3368         if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
3369                 MSG_DEBUG("invalid file or buffer");
3370                 goto __CATCH;
3371         }
3372
3373         /*
3374          * Encoded_string_value = Text-string | Value-length Char-set Text-String
3375          *                                                Text-string    = [Quote]*TEXT End-of-string
3376          *                                                Value-length   = 0 ~ 31
3377          */
3378
3379         memset(szBuff, 0, bufLen);
3380
3381         switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3382         case -1:
3383                 goto __CATCH;
3384
3385         case 0:
3386
3387                 /* Text-string = [Quote]*TEXT End-of-string */
3388
3389                 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
3390                         MSG_DEBUG("__MmsBinaryDecodeText fail.");
3391                         goto __CATCH;
3392                 }
3393                 break;
3394
3395         default:
3396
3397                 /* Value-length Charset Text_string */
3398
3399                 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3400                         MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3401                         goto __CATCH;                   /* (valueLength + valueLengthLen) */
3402                 }
3403
3404                 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
3405
3406                 if (nTemp < 0) {
3407                         /* There can be some error in data - no NULL -> try again with value length */
3408
3409                         pData = (char *)calloc(1, valueLength - charSetLen);
3410                         if (pData == NULL) {
3411                                 MSG_DEBUG("pData alloc fail.");
3412                                 goto __CATCH;
3413                         }
3414
3415                         if (__MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
3416                                 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes fail.");
3417                                 goto __CATCH;
3418                         }
3419
3420                         strncpy(szBuff, pData, bufLen - 1);
3421                 }
3422
3423                 { /* temp brace */
3424
3425                         nTemp = strlen(szBuff);
3426
3427                         const char *pToCharSet = "UTF-8";
3428
3429                         UINT16 charset_code =  MmsGetBinaryValue(MmsCodeCharSet, charSet);
3430
3431                         const char *pFromCharSet = MmsPluginTextConvertGetCharSet(charset_code);
3432                         if (pFromCharSet == NULL || !strcmp(pFromCharSet, pToCharSet)) {
3433                                 if (pData) {
3434                                         free(pData);
3435                                         pData = NULL;
3436                                 }
3437                                 return true;
3438                         }
3439
3440                         char *pDest = NULL;
3441                         int destLen = 0;
3442
3443                         if (MmsPluginTextConvert(pToCharSet, pFromCharSet, szBuff, nTemp, &pDest, &destLen) == false) {
3444                                 MSG_DEBUG("MmsPluginTextConvert Fail");
3445
3446                         } else {
3447                                 memset(szBuff, 0x00, bufLen);
3448                                 snprintf(szBuff, destLen+1, "%s", pDest);
3449                         }
3450
3451                         if (pDest) {
3452                                 free(pDest);
3453                                 pDest = NULL;
3454                         }
3455                 }
3456                 break;
3457         }
3458
3459         if (pData) {
3460                 free(pData);
3461                 pData = NULL;
3462         }
3463
3464         return true;
3465
3466 __CATCH:
3467
3468         if (pData) {
3469                 free(pData);
3470                 pData = NULL;
3471         }
3472
3473         return false;
3474 }
3475
3476
3477
3478 /**
3479  * Decode Encoded Addresses
3480  *
3481  * @param       pEncodedData    [in] QuotedString encoded data
3482  * @param       pAddrLength             [out] Decoded address length
3483  * @return      Decoded address list
3484  */
3485 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
3486 {
3487         UINT32 valueLength      = 0;
3488         UINT32 charSet          = 0;
3489         int charSetLen  = 0;
3490         int textLength  = 0;
3491         char *pAddrStr  = NULL;
3492         MsgHeaderAddress *pAddr = NULL;
3493
3494         MSG_DEBUG("decoding address..");
3495
3496         if (pFile == NULL) {
3497                 MSG_DEBUG("invalid file or buffer");
3498                 goto __CATCH;
3499         }
3500
3501         /*
3502          * Encoded_string_value = Text-string | Value-length Char-set Text-String
3503          *                                                Text-string    = [Quote]*TEXT End-of-string
3504          *                                                Value-length   = 0 ~ 31
3505          */
3506
3507         switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3508         case -1:
3509                 goto __CATCH;
3510
3511         case 0:
3512
3513                 /* Text-string = [Quote]*TEXT End-of-string */
3514
3515                 textLength = 0;
3516                 pAddrStr   = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3517                 if (pAddrStr == NULL) {
3518                         MSG_DEBUG(" __MmsBinaryDecodeText2 fail.");
3519                         goto __CATCH;
3520                 }
3521                 break;
3522
3523         default:
3524
3525                 /* Value-length Charset Text_string */
3526
3527                 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3528                         MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3529                         goto __CATCH;
3530                 }
3531
3532                 textLength = 0;
3533                 pAddrStr   = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3534                 if (pAddrStr == NULL) {
3535                         /* There can be some error in data - no NULL -> try again with value length */
3536
3537                         pAddrStr = (char *)calloc(1, valueLength - charSetLen);
3538                         if (pAddrStr == NULL) {
3539                                 MSG_DEBUG("pData alloc fail.");
3540                                 goto __CATCH;
3541                         }
3542
3543                         if (__MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
3544                                 MSG_DEBUG(" _MmsBinaryDecodeGetLongBytes fail.");
3545                                 goto __CATCH;
3546                         }
3547                 }
3548
3549                 /* fixme: charset transformation */
3550
3551                 break;
3552         }
3553
3554         pAddr = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
3555         if (pAddr == NULL)
3556                 goto __CATCH;
3557
3558         memset(pAddr, 0, sizeof(MsgHeaderAddress));
3559         pAddr->szAddr = pAddrStr;
3560
3561         return pAddr;
3562
3563 __CATCH:
3564
3565         if (pAddrStr) {
3566                 free(pAddrStr);
3567                 pAddrStr = NULL;
3568         }
3569
3570         return NULL;
3571 }
3572
3573
3574 /**
3575  * Decode Encoded Pointer String
3576  *
3577  * @param       pEncodedData    [in] Long integer encoded data
3578  * @param       pLongInteger    [out] Decoded long integer
3579  * @return      Decoded address list
3580  */
3581 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
3582 {
3583         UINT8 oneByte = 0;
3584
3585         /*
3586          * Long-integer = Short-length Multi-octet-integer
3587          *                                Short-length = 0~30
3588          *                                Multi-octet-integer
3589          */
3590
3591         if (pFile == NULL || pLongInteger == NULL)
3592                 return false;
3593
3594         *pLongInteger = 0;
3595
3596         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3597                 goto __CATCH;
3598
3599         if (oneByte > 31)
3600                 goto __CATCH;
3601
3602         *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
3603
3604         return true;
3605
3606 __CATCH:
3607         return false;
3608 }
3609
3610
3611 /*
3612  * @param       pEncodedData    [in] filename encoded data
3613  * @param       szBuff                  [out] filename output buffer
3614  * @param       fullLength              [in] full filename length
3615  * @param       bufLen                  [in] buffer length
3616  * CAUTION: bufLen - 1
3617  */
3618 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3619 {
3620         char *pUTF8Buff = NULL;
3621         char *pLatinBuff = NULL;
3622         char *pExt = NULL;
3623         char *szSrc = NULL;
3624         char *szSrc2 = NULL;
3625         int length = 0;
3626         int textLength = 0;
3627
3628         char *pTmpBuff = NULL;
3629
3630         memset (szBuff, 0, bufLen);
3631
3632         textLength = 0;
3633         pLatinBuff  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3634
3635         /* remove "" */
3636         if (pLatinBuff) {
3637                 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
3638                 if (szSrc) {
3639                         strncpy(pLatinBuff, szSrc, textLength);
3640                         free(szSrc);
3641                         szSrc = NULL;
3642                 }
3643
3644                 szSrc2 = MsgChangeHexString(pLatinBuff);
3645                 if (szSrc2) {
3646                         strncpy(pLatinBuff, szSrc2, textLength);
3647                         free(szSrc2);
3648                         szSrc2 = NULL;
3649                 }
3650
3651                 if (MmsIsUtf8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
3652                         length = strlen(pLatinBuff);
3653
3654                         int             utf8BufSize = 0;
3655                         utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
3656                         if (utf8BufSize < 3)
3657                                 utf8BufSize = 3; /* min value */
3658
3659                         pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
3660                         if (pUTF8Buff == NULL) {
3661                                 MSG_DEBUG("pUTF8Buff alloc fail");
3662                                 goto __CATCH;
3663                         }
3664
3665                         if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
3666                                 MSG_DEBUG("MsgLatin2UTF fail");
3667                                 goto __CATCH;
3668                         }
3669                         free(pLatinBuff);
3670                         pLatinBuff = NULL;
3671                 } else {
3672                         pTmpBuff = MsgDecodeText(pLatinBuff);
3673                         pUTF8Buff = pTmpBuff;
3674                         free (pLatinBuff);
3675                         pLatinBuff = NULL;
3676                 }
3677         }
3678
3679         if (pUTF8Buff) {
3680                 /*
3681                  * keeping extension
3682                  * it should be kept extention even if the file name is shorten
3683                  */
3684
3685                 length = strlen(pUTF8Buff);
3686                 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
3687                         int nameLength = 0;
3688                         nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
3689                         strncpy(szBuff, pUTF8Buff, nameLength);
3690                         g_strlcat(szBuff, pExt,(gsize)bufLen);
3691
3692                 } else {
3693                         strncpy(szBuff, pUTF8Buff, bufLen - 1);
3694                 }
3695
3696                 free(pUTF8Buff);
3697                 pUTF8Buff = NULL;
3698
3699                 return textLength;
3700         }
3701
3702 __CATCH:
3703
3704         if (pLatinBuff) {
3705                 free(pLatinBuff);
3706                 pLatinBuff = NULL;
3707         }
3708
3709         if (pUTF8Buff) {
3710                 free(pUTF8Buff);
3711                 pUTF8Buff = NULL;
3712         }
3713
3714         return -1;
3715 }
3716
3717 /* ==========================================================
3718
3719            M  M  S        D  E  C  O  D  I  N  G
3720
3721    ==========================================================*/
3722
3723 /* to get message body this function should be modified from message raw file. */
3724 bool MmsReadMsgBody(msg_message_id_t msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
3725 {
3726         FILE *pFile     = NULL;
3727         MmsMsg *pMsg = NULL;
3728         MsgMultipart *pMultipart = NULL;
3729         int nSize = 0;
3730         char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
3731         char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
3732
3733         MSG_BEGIN();
3734
3735         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
3736         memset(pMsg, 0, sizeof(MmsMsg));
3737
3738         MmsInitHeader();
3739
3740         if (bRetrieved && (retrievedPath != NULL)) {
3741                 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
3742         } else {
3743                 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath, sizeof(szFullPath));
3744         }
3745
3746         pMsg->msgID = msgID;
3747
3748         /*      read from MMS raw file  */
3749         strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
3750
3751         MSG_SEC_DEBUG("msg_id = [%d]", msgID);
3752         MSG_SEC_DEBUG("raw file path = [%s]", szFullPath);
3753
3754         if (MsgGetFileSize(szFullPath, &nSize) == false) {
3755                 MSG_FATAL("Fail MsgGetFileSize");
3756                 goto __CATCH;
3757         }
3758
3759         pFile = MsgOpenFile(szFullPath, "rb");
3760         if (pFile == NULL) {
3761                 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
3762                 goto __CATCH;
3763         }
3764
3765         MmsRegisterDecodeBuffer();
3766
3767         if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
3768                 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
3769                 goto __CATCH;
3770         }
3771
3772         if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
3773                 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
3774                 goto __CATCH;
3775         }
3776
3777         /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
3778
3779         memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
3780         memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
3781
3782 { /* attribute convert mmsHeader -> mmsAttribute */
3783
3784         pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
3785
3786         pMsg->mmsAttrib.date = mmsHeader.date;
3787
3788         if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
3789                 pMsg->mmsAttrib.bAskDeliveryReport = true;
3790         }
3791
3792         memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
3793
3794         memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
3795
3796         pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
3797
3798         snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
3799
3800         pMsg->mmsAttrib.msgType = mmsHeader.type;
3801
3802         pMsg->mmsAttrib.version = mmsHeader.version;
3803
3804         pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
3805
3806         pMsg->mmsAttrib.priority = mmsHeader.priority;
3807
3808         if (mmsHeader.readReply == MMS_REPORT_YES) {
3809                 pMsg->mmsAttrib.bAskReadReply = true;
3810         }
3811
3812         snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
3813
3814         snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
3815
3816         pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
3817
3818         /* FIXME:: mmsHeader will release after delete global mmsHeader */
3819         /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
3820 }
3821         if (pMsg->msgBody.pPresentationBody) {
3822                 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
3823                         goto __CATCH;
3824
3825                 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
3826                 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
3827                         goto __CATCH;
3828
3829                 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
3830
3831                 ULONG nRead = 0;
3832                 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
3833                 if (nRead == 0)
3834                         goto __CATCH;
3835
3836         }
3837
3838         MsgCloseFile(pFile);
3839         pFile = NULL;
3840         /* nPartCount */
3841         pMsg->nPartCount = 0;
3842
3843         if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
3844                 pMultipart = pMsg->msgBody.body.pMultipart;
3845                 while (pMultipart) {
3846                         pMsg->nPartCount++;
3847                         pMultipart = pMultipart->pNext;
3848                 }
3849         } else {
3850                 if (pMsg->msgBody.size > 0)
3851                         pMsg->nPartCount++;
3852         }
3853
3854         /*      make temporary  */
3855         snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
3856
3857         if (MsgIsMultipart(pMsg->msgType.type) == true) {
3858                 int partIndex = 0;
3859                 pMultipart = pMsg->msgBody.body.pMultipart;
3860
3861                 if (bSavePartsAsTempFiles) {
3862                         if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3863                                 if (errno == EEXIST) {
3864                                         MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
3865                                 } else {
3866                                         MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3867                                         goto __CATCH;
3868                                 }
3869                         } else {
3870                                 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
3871                         }
3872                 }
3873
3874                 if (pMsg->msgBody.pPresentationBody) {
3875                         if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
3876                                                                                                 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3877                                 goto __CATCH;
3878                 }
3879
3880                 while (pMultipart) {
3881
3882                         if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
3883                                                                                         (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
3884                                 goto __CATCH;
3885
3886                         MmsPrintMulitpart(pMultipart, partIndex);
3887
3888                         pMultipart = pMultipart->pNext;
3889                         partIndex ++;
3890                 }
3891
3892         } else { /* single part */
3893                 if (pMsg->nPartCount > 0) {
3894
3895                         if (bSavePartsAsTempFiles) {
3896                                 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3897                                         if (errno == EEXIST) {
3898                                                 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
3899                                         } else {
3900                                                 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3901                                                 goto __CATCH;
3902                                         }
3903                                 } else {
3904                                         MSG_DEBUG("make dir : [%s]", szTempMediaDir);
3905                                 }
3906                         }
3907
3908                         if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
3909                                                                                         (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3910                                 goto __CATCH;
3911                 }
3912         }
3913         MSG_DEBUG("### Success ###");
3914         MSG_END();
3915         return true;
3916
3917 __CATCH:
3918
3919         MmsInitHeader();
3920         MmsUnregisterDecodeBuffer();
3921
3922         if (pFile != NULL) {
3923                 MsgCloseFile(pFile);
3924                 pFile = NULL;
3925         }
3926
3927
3928         MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
3929
3930         MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
3931
3932         MSG_DEBUG("### Fail ###");
3933         MSG_END();
3934         return false;
3935 }
3936
3937 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
3938 {
3939         MsgHeaderAddress *pTempAddr = NULL;
3940
3941         while (pAddr != NULL) {
3942                 pTempAddr = pAddr;
3943                 pAddr = pAddr->pNext;
3944
3945                 if (pTempAddr->szAddr) {
3946                         free(pTempAddr->szAddr);
3947                         pTempAddr->szAddr = NULL;
3948                 }
3949
3950                 free(pTempAddr);
3951                 pTempAddr = NULL;
3952         }
3953
3954         return true;
3955 }
3956
3957 static bool __MsgCheckFileNameHasInvalidChar(char *szName)
3958 {
3959         int     strLen = 0;
3960         int i = 0;
3961
3962         strLen = strlen(szName);
3963
3964         for (i=0; i<strLen; i++) {
3965                 if (__MsgIsInvalidFileNameChar(szName[i]))
3966                         return true;
3967         }
3968
3969         return false;
3970 }
3971
3972 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
3973 {
3974         int nCount = 0;
3975         int totalLength = 0;
3976
3977         totalLength = strlen(szInText);
3978
3979         while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
3980                 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
3981                         if (__MsgIsInvalidFileNameChar(szInText[nCount]))
3982                                 *(szInText+nCount) = replaceChar;
3983
3984                         nCount += 1;
3985                 } else {
3986                         nCount += 2;
3987                 }
3988         }
3989
3990         return true;
3991 }
3992
3993 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter)
3994 {
3995         char *pszBuffer = NULL;
3996         char *pszStrDelimiter = NULL;
3997         int     bufLength = 0;
3998
3999         if (!pszString) {
4000                 MSG_DEBUG("pszString == NULL");
4001                 return NULL;
4002         }
4003
4004         if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
4005                 MSG_DEBUG("There is no %c in %s. \n", delimiter, pszString);
4006                 return NULL;
4007         }
4008
4009         bufLength = pszStrDelimiter - pszString;
4010
4011         if ((pszBuffer = (char*)calloc (1, bufLength + 1)) == NULL) {
4012                 MSG_DEBUG("calloc is failed");
4013                 return NULL;
4014         }
4015         memset(pszBuffer, 0, bufLength + 1) ;
4016
4017         strncat(pszBuffer, pszString, bufLength);
4018
4019         return pszBuffer;
4020 }
4021
4022 char *MsgChangeHexString(char *pOrg)
4023 {
4024         char *pNew = NULL;
4025         char szBuf[10] = {0,};
4026         char OneChar;
4027         int cLen = 0;
4028         int cIndex =0;
4029         int index = 0;
4030
4031         if (pOrg == NULL)
4032                 return false;
4033
4034         cLen = strlen(pOrg);
4035
4036         pNew = (char *)calloc(1, cLen + 1);
4037         if (pNew == NULL)
4038                 return NULL;
4039
4040         memset(pNew, 0, cLen + 1);
4041
4042         for (cIndex = 0; cIndex< cLen ; cIndex++) {
4043                 if (pOrg[cIndex] == '%') {
4044                         if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0) {
4045                                 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); /* read two chars after '%' */
4046
4047                                 if (__MsgIsHexChar(szBuf) == true) { /* check the two character is between  0 ~ F */
4048                                         OneChar = __MsgConvertHexValue(szBuf);
4049
4050                                         pNew[index] = OneChar;
4051                                         index++;
4052                                         cIndex+= 2;
4053                                         continue;
4054                                 }
4055                         }
4056                 }
4057                 pNew[index++] = pOrg[cIndex];
4058         }
4059         return pNew;
4060 }
4061
4062 static bool __MsgParseParameter(MsgType *pType, char *pSrc)
4063 {
4064         char *pName = NULL;
4065         char *pValue = NULL;
4066         char *pDec = NULL;
4067         char *pTest = NULL;
4068         char *pNextParam = NULL;
4069         char *pExt = NULL;
4070         int nameLen = 0;
4071         int count;
4072         char *pTempNextParam = NULL;
4073         char *pCh = NULL;
4074         char *szSrc = NULL;
4075         char *pUTF8Buff = NULL;
4076
4077         while (pSrc != NULL) {
4078                 pSrc = __MsgSkipWS(pSrc);
4079                 if (pSrc == NULL) {
4080                         /* End of parse parameter */
4081                         return true;
4082                 }
4083
4084                 pNextParam = NULL;
4085                 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
4086                 pCh = pSrc;
4087
4088                 if (*pCh == MSG_CH_QUOT) {
4089                         count = 1;
4090                 } else {
4091                         count = 0;
4092                 }
4093
4094                 pCh++;
4095                 for (; pCh<=pTempNextParam ; pCh++) {
4096                         if (*pCh == MSG_CH_QUOT)
4097                                 if (*(pCh - 1) != '\\')
4098                                         count++;
4099                 }
4100
4101                 if (count%2 == 0)
4102                         pNextParam = pTempNextParam;
4103
4104                 if (pNextParam)
4105                         *pNextParam++ = MSG_CH_NULL;
4106
4107                 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
4108                         *pName++ = MSG_CH_NULL;
4109
4110                         if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
4111                                 *pValue++ = MSG_CH_NULL;
4112
4113                                 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
4114                                         *pTest = MSG_CH_NULL;
4115
4116                                 pDec = MsgDecodeText(pValue);           /* Api is to long, consider Add to another file (MsgMIMECodec.c) */
4117                         } else {
4118                                 pDec = MsgDecodeText(pName);
4119                         }
4120
4121                         if (pDec) {
4122                                 switch (MmsGetTextType(MmsCodeParameterCode, pSrc)) {
4123                                 case MSG_PARAM_BOUNDARY:
4124
4125                                         /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
4126
4127                                         memset (pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
4128                                         strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
4129                                         MSG_SEC_INFO("szBoundary = [%s]", pType->param.szBoundary);
4130                                         break;
4131
4132                                 case MSG_PARAM_CHARSET:
4133                                         pType->param.charset = MmsGetTextType(MmsCodeParameterCode, pDec);
4134
4135                                         if (pType->param.charset == -1)
4136                                                 pType->param.charset = MSG_CHARSET_UNKNOWN;
4137
4138                                         MSG_SEC_INFO("type = %d    [charset] = %d", pType->type, pType->param.charset);
4139                                         break;
4140
4141                                 case MSG_PARAM_NAME:
4142
4143                                         memset (pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
4144
4145                                         pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4146
4147                                         if (pUTF8Buff) {
4148                                                 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4149                                                         if ((MSG_LOCALE_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4150                                                                 nameLen = (MSG_LOCALE_FILENAME_LEN_MAX-1) - strlen(pExt);
4151                                                         } else {
4152                                                                 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4153                                                         }
4154
4155                                                         strncpy(pType->param.szName, pUTF8Buff, nameLen);
4156                                                         g_strlcat(pType->param.szName, pExt, sizeof(pType->param.szName));
4157                                                 } else {
4158                                                         strncpy(pType->param.szName, pUTF8Buff, (MSG_LOCALE_FILENAME_LEN_MAX-1));
4159                                                 }
4160                                                 free(pUTF8Buff);
4161                                                 pUTF8Buff = NULL;
4162
4163                                                 if (__MsgChangeSpace(pType->param.szName, &szSrc) == true) {
4164                                                         if (szSrc)
4165                                                                 strncpy(pType->param.szName, szSrc , strlen(szSrc));
4166                                                 }
4167
4168                                                 if (szSrc) {
4169                                                         free(szSrc);
4170                                                         szSrc = NULL;
4171                                                 }
4172
4173                                                 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4174                                                 __MsgRemoveFilePath(pType->param.szName);
4175                                         } else {
4176                                                 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4177                                         }
4178
4179                                         MSG_SEC_INFO("szName = %s", pType->param.szName);
4180                                         break;
4181
4182                                 case MSG_PARAM_FILENAME:
4183
4184                                         memset (pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
4185
4186                                         pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4187
4188                                         if (pUTF8Buff) {
4189                                                 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4190                                                         if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4191                                                                 nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
4192                                                         } else {
4193                                                                 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4194                                                         }
4195
4196                                                         strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
4197                                                         g_strlcat (pType->param.szFileName, pExt, sizeof(pType->param.szFileName));
4198                                                 } else {
4199                                                         strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
4200                                                 }
4201                                                 free(pUTF8Buff);
4202                                                 pUTF8Buff = NULL;
4203
4204                                                 if (__MsgChangeSpace(pType->param.szFileName, &szSrc) == true) {
4205                                                         snprintf(pType->param.szFileName, sizeof(pType->param.szFileName), "%s", szSrc);
4206                                                 }
4207
4208                                                 if (szSrc) {
4209                                                         free(szSrc);
4210                                                         szSrc = NULL;
4211                                                 }
4212
4213                                                 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4214                                                 __MsgRemoveFilePath(pType->param.szFileName);
4215                                         } else {
4216                                                 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4217                                         }
4218
4219                                         MSG_SEC_INFO("szFileName = %s", pType->param.szFileName);
4220
4221                                         break;
4222
4223                                 case MSG_PARAM_TYPE:
4224
4225                                         /* type/subtype of root. Only if content-type is multipart/related */
4226
4227                                         pType->param.type = MimeGetMimeIntFromMimeString(pDec);
4228                                         MSG_SEC_INFO("type = %d", pType->param.type);
4229
4230                                         break;
4231
4232                                 case MSG_PARAM_START:
4233
4234                                         /* Content-id. Only if content-type is multipart/related */
4235
4236                                         memset (pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
4237                                         strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
4238
4239                                         MSG_SEC_INFO("szStart = %s", pType->param.szStart);
4240
4241                                         break;
4242
4243                                 case MSG_PARAM_START_INFO:
4244
4245                                         /* Only if content-type is multipart/related */
4246
4247                                         memset (pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
4248                                         strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
4249
4250                                         MSG_SEC_INFO("szStartInfo = %s", pType->param.szStartInfo);
4251
4252                                         break;
4253
4254                                 case MSG_PARAM_REPORT_TYPE:
4255
4256                                         /* only used as parameter of Content-Type: multipart/report; report-type=delivery-status; */
4257
4258                                         if (strcasecmp(pDec, "delivery-status") == 0) {
4259                                                 pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
4260                                         } else {
4261                                                 pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
4262                                         }
4263
4264                                         MSG_SEC_INFO("reportType = %s", pDec);
4265                                         break;
4266
4267                                 default:
4268
4269                                         MSG_DEBUG("Unknown paremeter (%s)", pDec);
4270                                         break;
4271                                 }
4272
4273                                 free(pDec);
4274                                 pDec = NULL;
4275                         }
4276                 }
4277                 pSrc = pNextParam;
4278         }
4279         return true;
4280 }
4281
4282 static char *__MsgSkipWS(char *s)
4283 {
4284         while (true) {
4285                 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
4286                         ++s;
4287                 } else if ((*s != '(') || (__MsgSkipComment(s,(long)NULL)==NULL)) {
4288                         return s;
4289                 }
4290         }
4291 }
4292
4293 static char *__MsgSkipComment (char *s,long trim)
4294 {
4295
4296         char *ret;
4297         char *s1 = s;
4298         char *t = NULL;
4299
4300         /* ignore empty space */
4301         for (ret = ++s1; *ret == ' '; ret++)
4302                 ;
4303
4304         /* handle '(', ')', '\',  '\0' */
4305         do {
4306                 switch (*s1) {
4307                 case '(':
4308                         if (!__MsgSkipComment (s1,(long)NULL))
4309                                 goto __NULL_RETURN;
4310                         t = --s1;
4311                         break;
4312                 case ')':
4313                         s = ++s1;
4314                         if (trim) {
4315                                 if (t) {
4316                                         t[1] = '\0';
4317                                 } else {
4318                                         *ret = '\0';
4319                                 }
4320                         }
4321                         return ret;
4322                 case '\\':
4323                         if (*++s1)
4324                                 break;
4325                 case '\0':
4326                         *s = '\0';
4327                         goto __NULL_RETURN;
4328                 case ' ':
4329                         break;
4330                 default:
4331                         t = s1;
4332                         break;
4333                 }
4334         } while (s1++);
4335
4336 __NULL_RETURN:
4337         return NULL;
4338 }
4339
4340 static char *__MsgConvertLatin2UTF8FileName(char *pSrc)
4341 {
4342         char *pUTF8Buff  = NULL;
4343 /*      char *pData = NULL; */
4344
4345
4346         /* convert utf8 string */
4347         if (MmsIsUtf8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
4348                 int length  = 0;
4349                 int utf8BufSize = 0;
4350
4351                 length = strlen(pSrc);
4352                 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
4353                 if (utf8BufSize < 3)
4354                         utf8BufSize = 3; /* min value */
4355
4356                 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
4357
4358                 if (pUTF8Buff == NULL) {
4359                         MSG_DEBUG("pUTF8Buff alloc fail");
4360                         goto __CATCH;
4361                 }
4362
4363                 if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
4364                         MSG_DEBUG("MsgLatin2UTF fail");
4365                         goto __CATCH;
4366                 }
4367         } else {
4368                 int length = strlen(pSrc);
4369                 pUTF8Buff = (char *)calloc(1, length+1);
4370
4371                 if (pUTF8Buff == NULL) {
4372                         MSG_DEBUG("pUTF8Buff alloc fail");
4373                         goto __CATCH;
4374                 }
4375
4376                 memcpy(pUTF8Buff, pSrc, length);
4377         }
4378
4379         /* convert hex string */
4380 /*
4381         if (__MsgIsPercentSign(pUTF8Buff) == true) {
4382                 pData = MsgChangeHexString(pUTF8Buff);
4383                 if (pData) {
4384                         free(pUTF8Buff);
4385                         pUTF8Buff = pData;
4386                 }
4387         }
4388 */
4389
4390         return pUTF8Buff;
4391
4392 __CATCH:
4393
4394         if (pUTF8Buff) {
4395                 free(pUTF8Buff);
4396                 pUTF8Buff = NULL;
4397         }
4398
4399         return NULL;
4400 }
4401
4402 static bool __MsgChangeSpace(char *pOrg, char **ppNew)
4403 {
4404         char *pNew = NULL;
4405         int cLen = 0;
4406         int cIndex =0;
4407         int index = 0;
4408
4409         if (pOrg == NULL)
4410                 return false;
4411
4412         cLen = strlen(pOrg);
4413
4414         pNew = (char *)calloc(1, cLen + 1);
4415         if (pNew == NULL)
4416                 return false;
4417
4418         memset(pNew, 0, cLen + 1);
4419
4420         for (cIndex=0; cIndex<cLen;cIndex++) {
4421                 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
4422                         pNew[index] = ' ';
4423                         index++;
4424                         cIndex+= 2;
4425                         continue;
4426                 }
4427                 pNew[index++] = pOrg[cIndex];
4428         }
4429
4430         *ppNew = pNew;
4431
4432         return true;
4433 }
4434
4435 static void __MsgRemoveFilePath(char *pSrc)
4436 {
4437         /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4438         char *pTemp = NULL;
4439         char *tmp_name = NULL;
4440
4441         tmp_name = MsgGetFileName(pSrc);
4442         if (tmp_name) {
4443                 snprintf(pSrc, strlen(tmp_name), "%s", tmp_name);
4444                 g_free(tmp_name);
4445                 tmp_name = NULL;
4446         }
4447
4448         /* Remove additional file information
4449          * ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
4450          * if "?size=" exist, insert NULL char. */
4451         {
4452                 pTemp = strcasestr(pSrc, "?size=");
4453                 if (pTemp != NULL)
4454                         *pTemp = '\0';
4455         }
4456 }
4457
4458 #if 0
4459 static bool __MsgIsPercentSign(char *pSrc)
4460 {
4461         char *pCh = NULL;
4462         bool bRet = false;
4463
4464         pCh = strchr(pSrc , '%');
4465
4466         if (pCh != NULL) {
4467                 bRet = true;
4468         } else {
4469                 bRet = false;
4470         }
4471
4472         return bRet;
4473 }
4474 #endif
4475
4476 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam)
4477 {
4478         char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
4479         char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
4480         char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
4481         int strLen = 0;
4482
4483         /* remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445> */
4484         if (szStart && szStart[0]) {
4485                 int startLen = 0;
4486                 startLen = strlen(szStart);
4487                 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
4488                         strncpy(szTmpStart, &szStart[1], startLen - 2);
4489                 } else {
4490                         strncpy(szTmpStart, szStart, startLen);
4491                 }
4492         }
4493
4494         /* remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445> */
4495         if (multipartType->szContentID[0])      {
4496                 strLen = strlen(multipartType->szContentID);
4497                 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
4498                         strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
4499                 } else {
4500                         strncpy(szTmpContentID, multipartType->szContentID, strLen);
4501                 }
4502         }
4503
4504         /* remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445> */
4505         if (multipartType->szContentLocation[0]) {
4506                 strLen = strlen(multipartType->szContentLocation);
4507                 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
4508                         strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
4509                 } else {
4510                         strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
4511                 }
4512         }
4513
4514         if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
4515                 return  MSG_PRESENTATION_NONE;
4516
4517         /* exception handling */
4518         if (szTmpStart[0] != '\0') {
4519                 /* presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type */
4520                 if (strcmp(szTmpStart, szTmpContentID) == 0) {
4521                         return MSG_PRESENTATION_ID;
4522                 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
4523                         return   MSG_PRESENTATION_LOCATION;
4524                 } else if (multipartType->type == typeParam) {
4525                         return   MSG_PRESENTATION_TYPE_BASE;
4526                 } else {
4527                         return   MSG_PRESENTATION_NONE;
4528                 }
4529         } else {
4530                 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
4531                         return   MSG_PRESENTATION_TYPE_BASE;
4532                 } else {
4533                         return   MSG_PRESENTATION_NONE;
4534                 }
4535         }
4536 }
4537
4538 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
4539 {
4540         MSG_BEGIN();
4541         MsgMultipart *pNextPart = NULL;
4542         MsgMultipart *pRemovePart = NULL;
4543
4544         if (__MsgIsMultipartRelated(pMsgType->type)) {
4545                 /* assign the multipart to presentation part */
4546                 /* remove the multipart(pCurPresentation) which is presentation part from the linked list. */
4547                 /* if there is no presentation part -> assign first multipart to presentation part by force. */
4548                 if (pPresentationInfo->pCurPresentation == NULL) {
4549                         pPresentationInfo->pCurPresentation     = pMsgBody->body.pMultipart;
4550                         pPresentationInfo->pPrevPart            = NULL;
4551                         pPresentationInfo->factor                       = MSG_PRESENTATION_NONE;
4552                 }
4553
4554                 if (pPresentationInfo->pCurPresentation != NULL && __MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
4555                         /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
4556                          * In this case, COPY the Presentation part and leave other multiparts.
4557                          */
4558                         memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4559                         pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
4560
4561                         /* remove pCurPresentation from multipart linked list */
4562                         if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE)||(pPresentationInfo->pPrevPart == NULL)) {
4563                                 /* first part */
4564                                 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
4565                                 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4566                                 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4567                                 if (pPresentationInfo->pCurPresentation) {
4568
4569                                         MmsReleaseMsgDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
4570
4571                                         free(pPresentationInfo->pCurPresentation);
4572                                         pPresentationInfo->pCurPresentation = NULL;
4573                                 }
4574                         } else {
4575                                 /* not a first part */
4576                                 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
4577                                 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4578                                 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4579                                 if (pPresentationInfo->pCurPresentation) {
4580                                         free(pPresentationInfo->pCurPresentation);
4581                                         pPresentationInfo->pCurPresentation = NULL;
4582                                 }
4583                         }
4584                 } else if (pPresentationInfo->pCurPresentation != NULL && MmsIsTextType(pPresentationInfo->pCurPresentation->type.type)) {
4585                         /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
4586                          * In this case, leave the Presentation part as a multipart and remove other multiparts.
4587                          */
4588
4589                         /* Backup the multipart link information */
4590                         pNextPart = pMsgBody->body.pMultipart;
4591
4592                         /* Copy presentation part as a main part */
4593                         memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4594                         memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
4595
4596                         /* Remove multipart linked list */
4597                         while (pNextPart) {
4598                                 pRemovePart = pNextPart;
4599                                 pNextPart = pNextPart->pNext;
4600
4601                                 if (pRemovePart->pBody) {
4602                                         MmsReleaseMsgBody(pRemovePart->pBody, pRemovePart->type.type);
4603                                         free(pRemovePart->pBody);
4604                                         pRemovePart->pBody = NULL;
4605                                 }
4606
4607                                 free(pRemovePart);
4608                                 pRemovePart = NULL;
4609                         }
4610                 } else {
4611
4612
4613                         MmsReleaseMsgDRMInfo(&pMsgBody->presentationType.drmInfo);
4614
4615                         MmsInitMsgType(&pMsgBody->presentationType);
4616                         pMsgBody->pPresentationBody = NULL;
4617                 }
4618         }
4619         MSG_END();
4620 }
4621
4622 static bool __MsgIsMultipartRelated(int type)
4623 {
4624         if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
4625                 return true;
4626         } else {
4627                 return false;
4628         }
4629 }
4630
4631 static bool __MsgIsPresentablePart(int type)
4632 {
4633         if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
4634                 return true;
4635         } else {
4636                 return false;
4637         }
4638 }
4639
4640 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
4641 {
4642         MSG_BEGIN();
4643         MsgMultipart *pTmpMultipart = NULL;
4644         MsgMultipart *pSelectedPart = NULL;
4645         MsgMultipart *pPrevPart = NULL;
4646         MsgMultipart *pFirstPart = NULL;
4647         MsgMultipart *pLastPart = NULL;
4648         MsgMultipart *pRemoveList = NULL;
4649         MsgMultipart *pNextRemovePart = NULL;
4650
4651         switch (pPartType->type) {
4652         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
4653         case MIME_MULTIPART_ALTERNATIVE:
4654
4655                 /* fixme:
4656                  * Policy: multipart/alternative
4657                  * multipart/alternative message has only several parts of media.
4658                  * You should choose one of them and make the alternative part
4659                  * to the selected media part.
4660                  */
4661
4662                 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE");
4663
4664                 pSelectedPart = pPartBody->body.pMultipart;
4665
4666                 /* NULL Pointer check!! */
4667                 if (pSelectedPart == NULL) {
4668                         MSG_DEBUG("multipart(ALTERNATIVE) does not exist");
4669                         break;
4670                 }
4671
4672                 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4673
4674                 while (pTmpMultipart) {
4675                         if (pSelectedPart->type.type <= pTmpMultipart->type.type)
4676                                 pSelectedPart = pTmpMultipart;
4677
4678                         pTmpMultipart = pTmpMultipart->pNext;
4679                 }
4680
4681                 pTmpMultipart = pPartBody->body.pMultipart;
4682                 pPrevPart = NULL;
4683
4684                 while (pTmpMultipart) {
4685                         if (pSelectedPart == pTmpMultipart)
4686                                 break;
4687
4688                         pPrevPart = pTmpMultipart;
4689                         pTmpMultipart = pTmpMultipart->pNext;
4690                 }
4691
4692                 if (pPrevPart == NULL) {
4693                         /* selected part is the first part */
4694                         pRemoveList = pSelectedPart->pNext;
4695                 } else {
4696                         pPrevPart->pNext = pSelectedPart->pNext;
4697                         pRemoveList = pPartBody->body.pMultipart;
4698                         pPartBody->body.pMultipart = pSelectedPart;
4699                 }
4700
4701                 pSelectedPart->pNext = NULL;
4702
4703                 if (pRemoveList) {
4704
4705                         MmsReleaseMsgDRMInfo(&pRemoveList->type.drmInfo);
4706
4707                         MmsReleaseMsgBody(pRemoveList->pBody, pRemoveList->type.type);
4708
4709                         free(pRemoveList->pBody);
4710                         free(pRemoveList);
4711                 }
4712
4713                 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4714                         MSG_DEBUG("MsgPriorityCopyMsgType failed");
4715                         goto __CATCH;
4716                 }
4717
4718                 if (pSelectedPart->pBody != NULL)
4719                         memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4720
4721                 if (pSelectedPart != NULL) {
4722
4723                         MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4724
4725                         if (pSelectedPart->pBody != NULL) {
4726                                 free(pSelectedPart->pBody);
4727                                 pSelectedPart->pBody = NULL;
4728                         }
4729                         free(pSelectedPart);
4730                         pSelectedPart = NULL;
4731                 }
4732
4733                 break;
4734
4735         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
4736         case MIME_MULTIPART_RELATED:
4737
4738                 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_RELATED");
4739
4740                 pSelectedPart = pPartBody->body.pMultipart;
4741
4742                 while (pSelectedPart) {
4743                         if (__MsgIsMultipartMixed(pSelectedPart->type.type)) {
4744
4745                                 if (pSelectedPart->pBody == NULL) {
4746                                         MSG_DEBUG("pSelectedPart->pBody(1) is NULL");
4747                                         break;
4748                                 }
4749
4750                                 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4751
4752                                 if (pFirstPart == NULL) {
4753                                         MSG_DEBUG("multipart(RELATED) does not exist");
4754                                         break;
4755                                 }
4756
4757                                 if (pFirstPart->pNext) {
4758                                         pLastPart = pFirstPart->pNext;
4759                                         while (pLastPart->pNext)
4760                                                 pLastPart = pLastPart->pNext;
4761                                 } else {
4762                                         pLastPart = pFirstPart;
4763                                 }
4764
4765                                 if (pPrevPart == NULL) {
4766                                         /* the first part */
4767                                         pTmpMultipart = pPartBody->body.pMultipart->pNext;
4768                                         pPartBody->body.pMultipart = pFirstPart;
4769                                         pLastPart->pNext = pTmpMultipart;
4770                                 } else {
4771                                         pTmpMultipart = pSelectedPart->pNext;
4772                                         pPrevPart->pNext = pFirstPart;
4773                                         pLastPart->pNext = pTmpMultipart;
4774                                 }
4775
4776                                 if (pSelectedPart) {
4777
4778                                         MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4779
4780                                         free(pSelectedPart->pBody);
4781                                         free(pSelectedPart);
4782                                 }
4783                                 pSelectedPart = pTmpMultipart;
4784                         } else if (__MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
4785                                 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
4786                                 MmsReleaseMsgBody(pSelectedPart->pBody, pSelectedPart->type.type);
4787
4788                                 free(pSelectedPart->pBody);
4789                                 free(pSelectedPart);
4790                                 pSelectedPart = pTmpMultipart;
4791                         } else {
4792                                 pPrevPart = pSelectedPart;
4793                                 pSelectedPart = pSelectedPart->pNext;
4794                         }
4795                 }
4796
4797                 break;
4798
4799
4800         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
4801         case MIME_MULTIPART_MIXED:
4802
4803                 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_MIXED");
4804
4805                 pPrevPart = NULL;
4806                 pSelectedPart = pPartBody->body.pMultipart;
4807
4808                 while (pSelectedPart) {
4809                         if (MsgIsMultipart(pSelectedPart->type.type)) {
4810                                 if (pSelectedPart->pBody == NULL) {
4811                                         MSG_DEBUG("pSelectedPart->pBody(2) is NULL");
4812                                         break;
4813                                 }
4814
4815                                 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4816
4817                                 /* NULL Pointer check!! */
4818                                 if (pFirstPart == NULL) {
4819                                         MSG_DEBUG("multipart does not exist");
4820                                         break;
4821                                 }
4822
4823                                 if (pFirstPart->pNext) {
4824                                         pLastPart = pFirstPart->pNext;
4825                                         while (pLastPart->pNext)
4826                                                 pLastPart = pLastPart->pNext;
4827                                 } else {
4828                                         pLastPart = pFirstPart;
4829                                 }
4830
4831                                 if (pPrevPart == NULL) {
4832                                         /* the first part */
4833                                         pTmpMultipart = pPartBody->body.pMultipart->pNext;
4834                                         pPartBody->body.pMultipart = pFirstPart;
4835                                         pLastPart->pNext = pTmpMultipart;
4836                                 } else {
4837                                         pTmpMultipart = pSelectedPart->pNext;
4838                                         pPrevPart->pNext = pFirstPart;
4839                                         pLastPart->pNext = pTmpMultipart;
4840                                 }
4841
4842                                 if (pSelectedPart->pBody->pPresentationBody)
4843                                         pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
4844
4845                                 memcpy(&pPartBody->presentationType,
4846                                                   &pSelectedPart->pBody->presentationType, sizeof(MsgType));
4847
4848                                 pPartType->type = pSelectedPart->type.type;
4849
4850                                 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4851
4852                                 free(pSelectedPart->pBody);
4853                                 free(pSelectedPart);
4854
4855                                 pSelectedPart = pTmpMultipart;
4856                         } else {
4857                                 pPrevPart = pSelectedPart;
4858                                 pSelectedPart = pSelectedPart->pNext;
4859                         }
4860                 }
4861
4862                 break;
4863
4864         case MIME_MULTIPART_REPORT:
4865
4866                 MSG_DEBUG("MIME_MULTIPART_REPORT");
4867
4868                 pTmpMultipart = pPartBody->body.pMultipart;
4869                 pPrevPart = NULL;
4870
4871                 if (pTmpMultipart == NULL) {
4872                         MSG_DEBUG("pTmpMultipart == NULL");
4873                         return false;
4874                 }
4875
4876                 while (pTmpMultipart) {
4877                         if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
4878                                 pSelectedPart = pTmpMultipart;
4879                                 break;
4880                         }
4881
4882                         pPrevPart = pTmpMultipart;
4883                         pTmpMultipart = pTmpMultipart->pNext;
4884                 }
4885
4886                 if (pSelectedPart == NULL) {
4887                         MSG_DEBUG("MIME_MULTIPART_REPORT [no selected part]");
4888
4889                         pRemoveList = pPartBody->body.pMultipart->pNext;
4890                         if (pPartBody->body.pMultipart != NULL) {
4891                                 pSelectedPart = pPartBody->body.pMultipart;
4892                                 pSelectedPart->pNext = NULL;
4893                         }
4894                 } else {
4895                         if (pPrevPart == NULL) {
4896                                 /* first part is selected */
4897                                 pRemoveList = pPartBody->body.pMultipart->pNext;
4898                         } else {
4899                                 pRemoveList = pPartBody->body.pMultipart->pNext;
4900                                 pPrevPart->pNext = pSelectedPart->pNext;
4901                         }
4902
4903                         pSelectedPart->pNext = NULL;
4904                         pPartBody->body.pMultipart = pSelectedPart;
4905                 }
4906
4907                 pTmpMultipart = pRemoveList;
4908
4909                 while (pTmpMultipart) {
4910
4911                         MmsReleaseMsgDRMInfo(&pTmpMultipart->type.drmInfo);
4912
4913                         MmsReleaseMsgBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
4914                         pNextRemovePart = pTmpMultipart->pNext;
4915
4916                         free(pTmpMultipart->pBody);
4917                         free(pTmpMultipart);
4918                         pTmpMultipart = pNextRemovePart;
4919                 }
4920
4921                 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4922                         MSG_DEBUG("MsgPriorityCopyMsgType failed");
4923                         goto __CATCH;
4924                 }
4925
4926                 if (pSelectedPart != NULL) {
4927
4928                         if (pSelectedPart->pBody != NULL)
4929                                 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4930
4931                         MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4932
4933                         if (pSelectedPart->pBody != NULL) {
4934                                 free(pSelectedPart->pBody);
4935                                 pSelectedPart->pBody = NULL;
4936                         }
4937                         free(pSelectedPart);
4938                         pSelectedPart = NULL;
4939                 }
4940
4941                 break;
4942
4943         default:
4944                 break;
4945         }
4946         MSG_END();
4947
4948         return true;
4949
4950 __CATCH:
4951         return false;
4952
4953 }
4954
4955 char *MsgResolveContentURI(char *szSrc)
4956 {
4957         char *szTemp = NULL;
4958         char *szReturn = NULL;
4959         int length = 0;
4960
4961         if (szSrc == NULL) {
4962                 goto __CATCH;
4963         }
4964
4965         if (szSrc[0] == '\0')
4966                 goto __CATCH;
4967
4968
4969         if (!strncasecmp(szSrc, "cid:", 4)) {
4970                 length = strlen(szSrc) - 3;
4971                 szSrc += 4;
4972         } else {
4973                 length = strlen(szSrc) + 1;
4974         }
4975
4976         szTemp = (char *)calloc(1, length);
4977         if (szTemp == NULL) {
4978                 MSG_DEBUG("memory full");
4979                 goto __CATCH;
4980         }
4981
4982         memset(szTemp, 0, length);
4983
4984         strncpy(szTemp, szSrc, length - 1);
4985
4986         szReturn = MsgChangeHexString(szTemp);
4987
4988         if (szTemp) {
4989                 free(szTemp);
4990                 szTemp = NULL;
4991         }
4992
4993         return szReturn;
4994
4995 __CATCH:
4996
4997         return NULL;
4998 }
4999
5000 char *MsgRemoveQuoteFromFilename(char *pSrc)
5001 {
5002         int cLen = 0;   /* length of pBuff */
5003         char *pBuff = NULL;
5004
5005         if (pSrc == NULL) {
5006                 MSG_DEBUG("pSrc is Null");
5007                 return NULL;
5008         }
5009
5010         cLen = strlen(pSrc);
5011
5012         pBuff = (char *)calloc(1, cLen + 1);
5013
5014         if (pBuff == NULL) {
5015                 MSG_DEBUG("pBuff mem alloc fail!");
5016                 return NULL;
5017         }
5018         memset(pBuff, 0 , sizeof(char)*(cLen + 1));
5019
5020         /* remove front quote */
5021         if (pSrc[0] == MSG_CH_QUOT) {
5022                 cLen--;
5023                 strncpy(pBuff, &pSrc[1], cLen);
5024                 pBuff[cLen] = '\0';
5025         } else if (pSrc[0] == MSG_CH_LF) {
5026                 cLen--;
5027                 strncpy(pBuff, &pSrc[1], cLen);
5028         } else {
5029                 strncpy(pBuff, pSrc, cLen);
5030         }
5031
5032         /* remove last qoute */
5033         if (pBuff[cLen-1] == MSG_CH_QUOT) {
5034                 pBuff[cLen-1] = '\0';
5035         }
5036
5037         return pBuff;
5038 }
5039
5040 bool MsgIsMultipart(int type)
5041 {
5042         if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
5043                 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
5044                 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
5045                 return true;
5046         } else {
5047                 return false;
5048         }
5049 }
5050
5051
5052 static bool __MsgIsHexChar(char *pSrc)
5053 {
5054         int cIndex = 0;
5055         int cLen = 0;
5056         bool bRet = false;
5057
5058         cLen = strlen(pSrc);
5059
5060         for (cIndex = 0; cIndex < cLen ; cIndex++) {
5061                 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
5062                         (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
5063                         bRet = true;
5064                 } else {
5065                         return false;
5066                 }
5067         }
5068
5069         return bRet;
5070 }
5071
5072 static char __MsgConvertHexValue(char *pSrc)
5073 {
5074         int ch = 0;
5075         int cIndex = 0;
5076         int cLen = 0;
5077         char ResultChar;
5078         unsigned char uCh[2] = {0,};
5079
5080         cLen = strlen(pSrc);
5081
5082         for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
5083                 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
5084                 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
5085                 ch = (int)uCh[0]<<4|uCh[1];
5086         }
5087
5088         ResultChar = (char)ch;
5089
5090         return ResultChar;
5091 }
5092
5093 static int __MsgConvertCharToInt(char ch)
5094 {
5095         if (ch>='0' && ch<='9') {
5096                 return ch - '0';
5097         } else if (ch>='a'&& ch <='f') {
5098                 return ch -'a'+10;
5099         } else if (ch>='A'&& ch <='F') {
5100                 return ch -'A'+10;
5101         } else {
5102                 return 0;
5103         }
5104 }
5105
5106 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
5107 {
5108         if (!pMsgType1 || !pMsgType2)
5109                 return false;
5110
5111 /*      if (pMsgType1->section == INVALID_HOBJ) */
5112                 pMsgType1->section = pMsgType2->section;
5113
5114         int length = 0;
5115
5116         if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
5117                 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
5118
5119
5120         if (pMsgType1->szContentID[0] == '\0') {
5121                 snprintf(pMsgType1->szContentID, sizeof(pMsgType1->szContentID), "%s", pMsgType2->szContentID);
5122         }
5123
5124         if (pMsgType1->szContentID[0] != '\0') {
5125
5126                 length = strlen(pMsgType1->szContentID);
5127                 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
5128                         char szTempString[MSG_MSG_ID_LEN + 1];
5129                         MmsRemoveLessGreaterChar(pMsgType1->szContentID, szTempString, sizeof(szTempString));
5130                         pMsgType1->drmInfo.szContentURI = g_strdup(szTempString);
5131                 } else {
5132                         pMsgType1->drmInfo.szContentURI = g_strdup(pMsgType1->szContentID);
5133                 }
5134         }
5135
5136         if (pMsgType1->szContentLocation[0] == '\0') {
5137                 strncpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation, MSG_MSG_ID_LEN);
5138         }
5139
5140         /* Copy informations - we shoud open the pMsgType2's orgFile
5141          * concerning its offset and size.
5142          */
5143         if (pMsgType2->szOrgFilePath[0] != '\0') {
5144                 strncpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath, MSG_FILEPATH_LEN_MAX-1);
5145         }
5146
5147         if (pMsgType2->disposition != -1)
5148                 pMsgType1->disposition = pMsgType2->disposition;
5149
5150         if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
5151                  pMsgType2->encoding != -1)
5152                 pMsgType1->encoding = pMsgType2->encoding;
5153
5154         pMsgType1->contentSize = pMsgType2->contentSize;
5155         pMsgType1->offset = pMsgType2->offset;
5156         pMsgType1->size = pMsgType2->size;
5157         pMsgType1->type = pMsgType2->type;
5158
5159         __MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
5160
5161         if (pMsgType1->param.szName[0]) {
5162                 pMsgType1->drmInfo.szContentName = g_strdup(pMsgType2->param.szName);
5163         }
5164
5165         return true;
5166 }
5167
5168 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
5169 {
5170         if (pParam1->charset == MSG_CHARSET_UNKNOWN)
5171                 pParam1->charset = pParam2->charset;
5172
5173         if (pParam1->type == MIME_UNKNOWN)
5174                 pParam1->type = pParam2->type;
5175
5176         /* Don't copy pParam2->pPresentation */
5177
5178         /* For alternative: copy the boundary string */
5179         if (pParam2->szBoundary[0] !='\0') {
5180                 strncpy(pParam1->szBoundary, pParam2->szBoundary, MSG_BOUNDARY_LEN);
5181         }
5182
5183         if (pParam1->szFileName[0] =='\0') {
5184                 strncpy(pParam1->szFileName, pParam2->szFileName, MSG_FILENAME_LEN_MAX);
5185         }
5186
5187         if (pParam1->szName[0] =='\0') {
5188                 strncpy(pParam1->szName, pParam2->szName, MSG_LOCALE_FILENAME_LEN_MAX);
5189         }
5190
5191         if (pParam1->szStart[0] =='\0') {
5192                 strncpy(pParam1->szStart, pParam2->szStart, MSG_MSG_ID_LEN);
5193         }
5194
5195         if (pParam1->szStartInfo[0] =='\0') {
5196                 strncpy(pParam1->szStartInfo, pParam2->szStartInfo, MSG_MSG_ID_LEN);
5197         }
5198         return true;
5199 }
5200
5201 static bool __MsgIsMultipartMixed(int type)
5202 {
5203         if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
5204                 return true;
5205         } else {
5206                 return false;
5207         }
5208 }
5209
5210 static bool __MsgIsInvalidFileNameChar(char ch)
5211 {
5212         if ((ch == 0x5C /* \ */) ||
5213                 (ch == 0x2F /* / */) ||
5214                 (ch == 0x3A /* : */) ||
5215                 (ch == 0x2A /* * */) ||
5216                 (ch == 0x3F /* ? */) ||
5217                 (ch == 0x22 /* " */) ||
5218                 (ch == 0x3C /* < */) ||
5219                 (ch == 0x3E /* > */) ||
5220                 (ch == 0x7C /* | */))
5221                 return true;
5222
5223         return false;
5224 }
5225
5226 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
5227 {
5228         int nCount = 0;
5229
5230         MSG_DEBUG("---------------");
5231
5232         if ((szSrc == NULL) || (nChar <= 0)) {
5233                 MSG_DEBUG("szSrc is NULL !!!! ---------------");
5234                 return 0;
5235         }
5236
5237         while ((nChar > 0) && (*szSrc != '\0')) {
5238                 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5239                         nCount += 1;
5240                         szSrc++;
5241                         nChar--;
5242                 } else {
5243                         nCount += 2;
5244                         szSrc++;
5245                         nChar--;
5246                 }
5247         }
5248
5249         return nCount;
5250 }
5251
5252 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5253 {
5254         unsigned char*  org;
5255         unsigned char   t1, t2;
5256
5257         MSG_DEBUG("---------------");
5258
5259         org = des;
5260         outBufSize--;                   /* NULL character */
5261
5262         while ((nChar > 0) && (*szSrc != '\0')) {
5263                 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5264                         /* check outbuffer's room for this UTF8 character */
5265
5266                         outBufSize --;
5267                         if (outBufSize < 0)
5268                                 goto __RETURN;
5269
5270                         *des = (unsigned char) (*szSrc & 0x007F);
5271
5272                         des++;
5273                         szSrc++;
5274                         nChar--;
5275                 } else {
5276                         /* check outbuffer's room for this UTF8 character */
5277
5278                         outBufSize -= 2;
5279                         if (outBufSize < 0)
5280                                 goto __RETURN;
5281
5282                         t2 = (unsigned char) (*szSrc & 0x003F);                         /* right most 6 bit */
5283                         t1 = (unsigned char) ((*szSrc & 0xC0) >> 6);            /* right most 2 bit */
5284
5285                         *des = 0xC0 | (t1 & 0x1F);
5286                         *(des + 1) = 0x80 | (t2 & 0x3F);
5287
5288                         des += 2;
5289                         szSrc += 1;
5290                         nChar -= 1;
5291                 }
5292         }
5293
5294 __RETURN:
5295
5296         *des = 0;
5297         return (des - org);
5298 }
5299
5300 bool MmsAddrUtilCheckEmailAddress(char *pszAddr)
5301 {
5302         if (!pszAddr || pszAddr[0] == 0)
5303                 return false;
5304
5305         if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
5306                 return false;
5307
5308         return true;
5309 }
5310
5311 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
5312 {
5313         char *pszAddrCopy = NULL;
5314         char *pszStrStart = NULL;
5315         char *pszStrTemp = NULL;
5316         int strLen = 0;
5317
5318         if ((!pszAddr) || (pszAddr[0] == 0)) {
5319                 MSG_DEBUG("pszAddr is null or zero");
5320                 return false;
5321         }
5322
5323         strLen = strlen(pszAddr);
5324
5325         pszAddrCopy = (char*)calloc(1,strLen + 1);
5326         if (!pszAddrCopy) {
5327                 MSG_DEBUG("pszAddrCopy is NULL, mem alloc failed");
5328                 return false;
5329         }
5330
5331         strncpy(pszAddrCopy, pszAddr, strLen);
5332
5333         pszAddr[0] = 0;
5334         pszStrStart = pszAddrCopy;
5335
5336         while (true) {
5337                 char*   pszStrEnd = NULL;
5338                 int     addressLen = 0;
5339
5340                 if (MmsAddrUtilCheckEmailAddress(pszAddrCopy))
5341                         pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
5342                 else
5343                         pszStrEnd = strstr(pszStrStart, "/");
5344
5345                 if (!pszStrEnd) {
5346                         char *pszStart = NULL;
5347                         char *pszEnd = NULL;
5348                         /* "/TYPE=PLMN" not found */
5349
5350                         int remainedLen = strlen(pszStrStart);
5351
5352                         if (remainedLen <= 0)
5353                                 break;
5354
5355                         /* Email address can occur with Sender Name<email-address> format */
5356                         /* remove the Sender name and only retain the email address. */
5357                         pszStart = strstr(pszStrStart, "<");
5358                         if (pszStart) {
5359                                 pszEnd = strstr(pszStrStart, ">");
5360
5361                                 if (pszEnd) {
5362                                         pszStart++; /* skip "<" */
5363                                         g_strlcat(pszAddr, pszStart, pszEnd - pszStart + 1);
5364                                         break;
5365                                 }
5366                         }
5367
5368                         g_strlcat(pszAddr, pszStrStart, strLen + 1);
5369                         break;
5370                 }
5371
5372                 /* Get one address length */
5373                 addressLen = pszStrEnd - pszStrStart;
5374
5375                 strncat(pszAddr, pszStrStart, addressLen);
5376
5377                 /* Find next address */
5378                 pszStrStart = pszStrEnd;
5379
5380                 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
5381
5382                 if (pszStrTemp) {
5383                         addressLen = pszStrTemp - pszStrEnd;
5384                         pszStrStart += addressLen;
5385                 } else {
5386                         pszStrStart += strlen(pszStrEnd);
5387                 }
5388
5389                 if (pszStrStart[0] == 0)        /* end of string */
5390                         break;
5391
5392
5393                 g_strlcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER, strLen + 1);     /* add ';' */
5394                 pszStrStart++;  /* remove ';' */
5395         }
5396
5397         if (pszAddr[0] == 0)
5398                 strncpy(pszAddr, pszAddrCopy, strLen);
5399
5400         free(pszAddrCopy);
5401
5402         return true;
5403 }
5404
5405 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5406 {
5407         unsigned char *org;
5408
5409         MSG_DEBUG("---------------");
5410
5411         org = des;
5412         outBufSize--;                   /* NULL character */
5413
5414         while ((nChar > 0) && (*szSrc != '\0')) {
5415                 if (*szSrc < 0x80) {
5416                         outBufSize --;
5417                         if (outBufSize < 0)
5418                                 goto __RETURN;
5419
5420                         *des = *szSrc;
5421                         des++;
5422                         szSrc++;
5423                 } else if  (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
5424                         outBufSize -= 2;
5425                         if (outBufSize < 0)
5426                                 goto __RETURN;
5427
5428                         *des = *szSrc;
5429                         *(des + 1) = *(szSrc + 1);
5430
5431                         des += 2;
5432                         szSrc += 2;
5433                 } else if  ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
5434                         outBufSize -= 3;
5435                         if (outBufSize < 0)
5436                                 goto __RETURN;
5437
5438                         *des = *szSrc;
5439                         *(des + 1) = *(szSrc + 1);
5440                         *(des + 2) = *(szSrc + 2);
5441
5442                         des += 3;
5443                         szSrc += 3;
5444                 } else {
5445                         outBufSize --;
5446                         if (outBufSize < 0)
5447                                 goto __RETURN;
5448
5449                         *des = *szSrc;
5450                         des++;
5451                         szSrc++;
5452                         MSG_DEBUG("utf8 incorrect range!");
5453                 }
5454
5455                 nChar--;
5456         }
5457
5458 __RETURN:
5459
5460         *des = 0;
5461         return (des - org);
5462 }
5463
5464 static void __MsgMIMERemoveQuote(char *szSrc)
5465 {
5466         int length = 0;
5467
5468         length = strlen(szSrc);
5469         if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
5470                 int index = 0;
5471
5472                 for (index = 0; index < length-2; index++)
5473                         szSrc[index] = szSrc[index+1];
5474                 szSrc[index] = '\0';
5475         }
5476 }
5477
5478 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
5479 {
5480         MSG_BEGIN();
5481         int nRead = 0;
5482         int length= 0;
5483
5484         if (pFile == NULL) {
5485                 MSG_DEBUG("Error");
5486
5487                 *pBufLen = 0;
5488                 return false;
5489         }
5490
5491         if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
5492                 MSG_DEBUG("Error");
5493
5494                 *pBufLen = 0;
5495                 return false;
5496         }
5497
5498         if (*pBufLen == 0) {
5499                 length = maxLen - (*pPtr);
5500         } else {
5501                 length = (*pBufLen) - (*pPtr);
5502         }
5503
5504         if (length < 0)
5505                 length = 0;
5506
5507         if ((*ppBuf) == NULL) {
5508                 memset(pInBuf1, 0, maxLen);
5509                 (*ppBuf) = pInBuf1;
5510         } else if ((*ppBuf) == pInBuf1) {
5511                 memset(pInBuf2, 0, maxLen);
5512                 if (length)
5513                         memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
5514                 (*ppBuf) = pInBuf2;
5515         } else {
5516                 memset(pInBuf1, 0, maxLen);
5517                 if (length)
5518                         memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
5519                 (*ppBuf) = pInBuf1;
5520         }
5521
5522         (*pPtr) = 0;
5523
5524         if (*pOffset == endOfFile) {
5525                 *pBufLen = length;
5526                 return true;
5527         }
5528
5529         if (maxLen == length) {
5530                 /* (*pPtr) was 0 */
5531                 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
5532                         return false;
5533
5534                 *pBufLen = nRead;
5535         } else {
5536                 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
5537                         return false;
5538
5539                 *pBufLen = length + nRead;
5540         }
5541
5542         if ((*pOffset = MsgFtell(pFile)) == -1L) {
5543                 MSG_DEBUG("MsgFtell Error");
5544                 return false;
5545         }
5546
5547         MSG_END();
5548
5549         return true;
5550 }
5551
5552 /*
5553  *      This function write media data from raw data to file.
5554  *      @param  pMsg
5555  *      @param  pPartBody
5556  *      @param  pszMailboxPath  : path of mailbox
5557  *      @param  pszMsgFilename  : name of msg file
5558  *      @param  index                   : used for file naming
5559  *      @param  bSave                   : if true, file will be save otherwise just filename will be stored.
5560  */
5561 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
5562 {
5563         FILE *pFile = NULL;
5564         char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, };        /* file name of temp file */
5565         char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; /* full absolute path of temp file. */
5566         bool bFileExist = false;
5567         MSG_BEGIN();
5568
5569         if (!pPartType) {
5570                 MSG_DEBUG("pPartType is NULL");
5571                 return false;
5572         }
5573
5574         if (pPartType->type == MIME_APPLICATION_SMIL) {
5575                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", "smil.txt");
5576         } else {
5577
5578                 if (pPartType->param.szName[0] != '\0') {
5579                         snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szName);
5580                 } else if (pPartType->param.szFileName[0] != '\0') {
5581                         snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szFileName);
5582                 } else if (pPartType->szContentLocation[0] != '\0') {
5583                         snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->szContentLocation);
5584                 } else {
5585                         snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
5586                 }
5587         }
5588
5589         /* make full path for save */
5590         __MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0, szFileName, sizeof(szFileName));  /* FL & CD -> extension(.dm) SD -> extension(.dcf) */
5591
5592         snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName);  /* get absolute path of each temp file of each part */
5593
5594         if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
5595                 MsgGetMimeTypeFromFileName(MIME_MAINTYPE_UNKNOWN, szFullPath, (MimeType *)&pPartType->type, NULL);
5596
5597         /* save file */
5598         bFileExist = MsgAccessFile(szFullPath, F_OK);
5599
5600         MSG_SEC_DEBUG("save flag  [%d],  filepath [%s], file exist [%d]", bSave, szFullPath, bFileExist);
5601
5602         if (bSave == true && bFileExist == false) {
5603
5604                 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
5605                         MSG_DEBUG("MsgOpenFile failed");
5606                         goto __CATCH;
5607                 }
5608
5609                 if (__MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
5610                         MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
5611                         goto __CATCH;
5612                 }
5613
5614                 MsgCloseFile(pFile);
5615                 pFile = NULL;
5616
5617                 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5618
5619                 /* IF DRM type Convert to dcf */
5620                 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5621                         || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5622                 {
5623                         char destDrmPath[MSG_FILEPATH_LEN_MAX] = {0,};
5624
5625                         if (MsgDrmConvertDmtoDcfType(pPartBody->szOrgFilePath, destDrmPath) == true) {
5626                                 MSG_INFO("Success Convert to Dcf");
5627
5628                                 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5629
5630                                 if (bFileExist) {
5631                                         snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5632                                         MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5633                                 }
5634
5635                         } else {
5636                                 MSG_INFO("Fail Convert to Dcf");
5637                         }
5638
5639                         if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5640                                 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5641
5642                         MSG_SEC_INFO("Drm File Path [%s] isdrm [%d]", pPartBody->szOrgFilePath, MsgDrmIsDrmFile(pPartBody->szOrgFilePath));
5643                 }
5644
5645                 pPartBody->offset = 0;
5646                 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5647
5648                 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
5649                         MsgDrmRegisterFile(MSG_MODE_FILE, pPartBody->szOrgFilePath, strlen(pPartBody->szOrgFilePath));
5650
5651                         /* change szDrm2FullPath as current content path*/
5652                         if (pPartType->drmInfo.szDrm2FullPath) {
5653                                 free(pPartType->drmInfo.szDrm2FullPath);
5654                                 pPartType->drmInfo.szDrm2FullPath = g_strdup(pPartBody->szOrgFilePath);
5655                         }
5656                 }
5657
5658                 MSG_SEC_DEBUG("Save Part File to [%s]", pPartBody->szOrgFilePath);
5659
5660         } else {
5661                 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5662
5663                 /* IF DRM type check dcf exist */
5664                 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5665                         || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5666                 {
5667                         char destDrmPath[MSG_FILEPATH_LEN_MAX] = {0,};
5668
5669                         MsgGetFileNameWithoutExtension(destDrmPath, pPartBody->szOrgFilePath);
5670                         strncat(destDrmPath, ".dcf", 4);
5671
5672                         bFileExist = MsgAccessFile(destDrmPath, F_OK);
5673
5674                         if (bFileExist) {
5675                                 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5676                                 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5677                         }
5678
5679                         if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5680                                 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5681                 }
5682
5683                 pPartBody->offset = 0;
5684                 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5685
5686                 MSG_SEC_DEBUG("Set Part File to [%s]", pPartBody->szOrgFilePath);
5687         }
5688
5689         /* file name fix */
5690         if (szFileName[0]  != '\0') {
5691                 snprintf(pPartType->param.szFileName, MSG_FILENAME_LEN_MAX+1, "%s.dir/%s", pszMsgFilename, szFileName); /* store relative path of each temp file of each part including sub folder. */
5692                 snprintf(pPartType->param.szName, MSG_LOCALE_FILENAME_LEN_MAX+1, "%s", szFileName);
5693                 MSG_SEC_DEBUG("Set Name : %s", pPartType->param.szName);
5694         }
5695
5696         MSG_END();
5697         return true;
5698
5699 __CATCH:
5700
5701         if (pFile != NULL) {
5702                 MsgCloseFile(pFile);
5703                 pFile = NULL;
5704         }
5705         MSG_END();
5706         return false;
5707 }
5708
5709 bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
5710 {
5711         int nRead = 0;
5712         int nRead2 = 0;
5713         char *pData = NULL;
5714         char *pNewData = NULL;
5715         char *pTempData = NULL;
5716         int msgEncodingValue = 0;
5717         int msgTypeValue = 0;
5718         int msgCharsetValue     = 0;
5719
5720         int offset = 0;
5721         int size = 0;
5722
5723         msgEncodingValue = pPartType->encoding;
5724         msgTypeValue = pPartType->type;
5725         msgCharsetValue = pPartType->param.charset;
5726
5727         offset = pPartBody->offset;
5728         size = pPartBody->size;
5729
5730         if (pPartBody->szOrgFilePath[0]) {
5731                 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
5732
5733                 if (pTempData == NULL) {
5734                         MSG_DEBUG("pTempData read fail");
5735                         goto __CATCH;
5736                 }
5737
5738                 pData = pTempData;
5739         } else if (pPartBody->body.pText) {
5740                 pData = pPartBody->body.pText;
5741                 nRead = pPartBody->size;
5742         }
5743
5744         if (pData == NULL) {
5745                 MSG_DEBUG("there is no data");
5746                 goto __RETURN;
5747         }
5748
5749         pNewData = __MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
5750
5751         if (pNewData) {
5752                 pPartType->encoding = MSG_ENCODING_BINARY;
5753
5754                 if (MmsIsTextType(msgTypeValue))
5755                         pPartType->param.charset = MSG_CHARSET_UTF8;
5756
5757                 if (MsgWriteFile(pNewData, sizeof(char), nRead2,  pFile) != (size_t)nRead2) {
5758                         MSG_DEBUG("file writing fail");
5759                         goto __CATCH;
5760                 }
5761
5762         } else {
5763                 if (MsgWriteFile(pData, sizeof(char), nRead,  pFile) != (size_t)nRead) {
5764                         MSG_DEBUG("file writing fail");
5765                         goto __CATCH;
5766                 }
5767         }
5768
5769 __RETURN:
5770
5771         if (pNewData) {
5772                 free(pNewData);
5773                 pNewData = NULL;
5774         }
5775
5776         if (pTempData) {
5777                 free(pTempData);
5778                 pTempData = NULL;
5779         }
5780
5781         return true;
5782
5783 __CATCH:
5784
5785         if (pNewData) {
5786                 free(pNewData);
5787                 pNewData = NULL;
5788         }
5789
5790         if (pTempData) {
5791                 free(pTempData);
5792                 pTempData = NULL;
5793         }
5794
5795         return false;
5796 }
5797
5798 char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
5799 {
5800         int nByte = 0;
5801         int nTemp = 0;
5802         char *pTemp = NULL;
5803
5804         char *pConvertedStr     = NULL;
5805         char *pConvertedData = NULL;
5806         char *pNewData = NULL;
5807         char *pReturnData = NULL;
5808
5809         const char *pToCodeSet = "UTF-8";
5810         const char *pFromCodeSet = NULL;
5811
5812         switch (msgEncodingValue) {
5813         case MSG_ENCODING_BASE64:
5814
5815                 pConvertedData = (char*)MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5816                 MSG_DEBUG("MSG_ENCODING_BASE64 bodyLength [%d]", nByte);
5817
5818                 pTemp = pConvertedData;
5819                 nTemp = nByte;
5820
5821                 break;
5822
5823         case MSG_ENCODING_QUOTE_PRINTABLE:
5824
5825                 pConvertedData = (char*)MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5826                 MSG_DEBUG("MSG_ENCODING_QUOTE_PRINTABLE bodyLength [%d]", nByte);
5827
5828                 pTemp = pConvertedData;
5829                 nTemp = nByte;
5830
5831                 break;
5832
5833         default:
5834
5835                 MSG_DEBUG("encoding val [%d] bodyLength [%d]", msgEncodingValue, nRead);
5836                 pTemp = pData;
5837                 nTemp = nRead;
5838
5839                 break;
5840         }
5841
5842         if (MmsIsTextType(msgTypeValue)) {
5843
5844                 if (msgCharsetValue == MSG_CHARSET_US_ASCII) {
5845                         pNewData = pTemp;
5846                         *npRead = nTemp;
5847                 } else if (msgCharsetValue == MSG_CHARSET_UTF8) {
5848
5849                         /* skip BOM (Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM) */
5850                         if (nTemp >= 3) {
5851                                 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
5852                                         pTemp += 3;
5853                                         nTemp -= 3;
5854                                 }
5855                         }
5856
5857                         pNewData = pTemp;
5858                         *npRead = nTemp;
5859                 } else {
5860
5861                         UINT16 MIBenum = MmsGetBinaryValue(MmsCodeCharSet, msgCharsetValue);
5862
5863                         pFromCodeSet = MmsGetTextByCode(MmsCodeCharSet, MIBenum);
5864
5865                         MSG_DEBUG("char set enum = [%d], MIBenum = [%d], str = [%s]", msgCharsetValue, MIBenum, pFromCodeSet);
5866
5867                         if (pFromCodeSet) {
5868                                 MSG_DEBUG("Convert to UTF-8");
5869
5870                                 if (MmsPluginTextConvert(pToCodeSet, pFromCodeSet, pTemp, nTemp, &pConvertedStr, npRead) == true) {
5871                                         pNewData = pConvertedStr;
5872                                 } else {
5873                                         MSG_DEBUG("Failed MmsPluginTextConvert");
5874                                         pNewData = pTemp;
5875                                         *npRead = nTemp;
5876                                 }
5877
5878                         } else { /* unsupported charset */
5879                                 MSG_DEBUG("unsupported charset");
5880                                 pNewData = pTemp;
5881                                 *npRead = nTemp;
5882                         }
5883                 }
5884
5885         } else {
5886                 pNewData = pTemp;
5887                 *npRead = nTemp;
5888         }
5889
5890         pReturnData = (char *)calloc(1, *npRead);
5891         if (pReturnData == NULL) {
5892                 MSG_DEBUG("pReturnData alloc fail.");
5893                 goto __CATCH;
5894         }
5895
5896         if (pNewData != NULL) {
5897                 memset(pReturnData, 0, *npRead);
5898                 memcpy(pReturnData, pNewData, *npRead);
5899         }
5900
5901         if (pConvertedData) {
5902                 free(pConvertedData);
5903                 pConvertedData = NULL;
5904         }
5905
5906         if (pConvertedStr) {
5907                 free(pConvertedStr);
5908                 pConvertedStr = NULL;
5909         }
5910
5911         return pReturnData;
5912
5913 __CATCH:
5914
5915         if (pConvertedData) {
5916                 free(pConvertedData);
5917                 pConvertedData = NULL;
5918         }
5919
5920         if (pConvertedStr) {
5921                 free(pConvertedStr);
5922                 pConvertedStr = NULL;
5923         }
5924
5925         return NULL;
5926 }
5927
5928 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen)
5929 {
5930         char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
5931         char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
5932         const char *pExt = NULL;
5933
5934         MSG_SEC_DEBUG("Input : type  [0x%x], drmType [%d], filename [%s]", iMsgType, drmType, szFileName);
5935
5936         if (szFileName == NULL)
5937                 return false;
5938
5939         /* Filename */
5940         int inp_len = strlen(szFileName);
5941         if (inp_len > 0) {
5942
5943                 pExt = strrchr(szFileName, '.');
5944
5945                 if (pExt != NULL && *(pExt + 1) != '\0') {
5946                         pExt = pExt +1;
5947                 } else {
5948                         pExt = NULL;
5949                 }
5950
5951                 MsgGetFileNameWithoutExtension(szTempFileName, szFileName);
5952         } else {
5953                 if (nUntitleIndex >= 1) {
5954                         snprintf(szTempFileName, sizeof(szTempFileName), "%s_%d", "untitled", nUntitleIndex);
5955                 } else {
5956                         snprintf(szTempFileName, sizeof(szTempFileName), "%s", "untitled");
5957                 }
5958         }
5959
5960         /* extension */
5961         if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_MESSAGE)
5962                 pExt = "dm";
5963         else if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5964                 pExt = "dcf";
5965
5966         if (pExt == NULL) { /* find ext from content type */
5967
5968                 if (iMsgType == MIME_APPLICATION_OCTET_STREAM || iMsgType == MIME_UNKNOWN) {
5969                         MSG_DEBUG("unsupported MsgType [%d]", iMsgType);
5970                         goto __CATCH;
5971                 }
5972
5973                 pExt = MimeGetExtFromMimeInt((MimeType)iMsgType);
5974         }
5975
5976         /* Filename + extension */
5977         if (pExt) {
5978                 snprintf(szTemp, sizeof(szTemp), "%s.%s", szTempFileName, pExt);
5979         } else {
5980                 MSG_DEBUG("Failed to get extension of that mime data file.");
5981                 goto __CATCH;
5982         }
5983
5984         snprintf(outBuf, outBufLen, "%s", szTemp);
5985         MSG_SEC_DEBUG("Result : filename [%s]", outBuf);
5986         return true;
5987
5988 __CATCH:
5989         return false;
5990 }
5991
5992 bool MsgGetFileNameWithoutExtension (char *szOutputName, char *szName)
5993 {
5994         char *pszExt = NULL;
5995
5996         if (szOutputName == NULL) {
5997                 MSG_DEBUG("szOutputName is NULL");
5998                 return false;
5999         }
6000
6001         strncpy(szOutputName, szName, strlen(szName));
6002
6003         if ((pszExt = strrchr(szOutputName, '.'))) {
6004                 if (pszExt[0] == '.')
6005                         pszExt[0] = '\0';
6006         }
6007
6008         return true;
6009 }
6010
6011 bool MsgGetFileName(char *szFilePath, char *szFileName, int size)
6012 {
6013         char *filename = NULL;
6014         if (szFilePath) {
6015                 filename = strrchr(szFilePath, '/');
6016                 if (filename != NULL) {
6017                         snprintf(szFileName, size, "%s", filename + 1);
6018                 } else {
6019                         snprintf(szFileName, size, "%s", szFilePath);
6020                 }
6021         } else {
6022                 return false;
6023         }
6024
6025         return true;
6026 }
6027
6028 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
6029 {
6030         MmsMsg *pMsg = NULL;
6031         MsgMultipart *pPart = NULL;
6032
6033         if (pHeader == NULL) {
6034                 MSG_DEBUG("Invalid pHeader input. It's null");
6035                 return false;
6036         }
6037
6038         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
6039
6040         MmsInitMsgType(pHeader);
6041
6042
6043         /* Requires header of non-presentation */
6044         if (MsgIsMultipart(pMsg->msgType.type)) {
6045                 MSG_DEBUG("Multipart header [index = %d] \n", index);
6046
6047                 pPart = pMsg->msgBody.body.pMultipart;
6048
6049                 while (pPart && index--)
6050                         pPart = pPart->pNext;
6051
6052                 if (pPart == NULL) {
6053                         MSG_DEBUG("There is no such msg part.");
6054                         return false;
6055                 }
6056
6057                 memcpy(pHeader, &pPart->type, sizeof(MsgType));
6058         } else {
6059                 MSG_DEBUG("Requires singlepart header");
6060                 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
6061         }
6062
6063         return true;
6064 }
6065
6066
6067 ///////////////////////////////////////////////////////////////////////////////
6068
6069 MmsPluginDecoder *MmsPluginDecoder::pInstance = NULL;
6070
6071 MmsPluginDecoder *MmsPluginDecoder::instance()
6072 {
6073         if (!MmsPluginDecoder::pInstance)
6074                 MmsPluginDecoder::pInstance = new MmsPluginDecoder();
6075
6076         return MmsPluginDecoder::pInstance;
6077 }
6078
6079 MmsPluginDecoder::MmsPluginDecoder(){}
6080 MmsPluginDecoder::~MmsPluginDecoder(){}
6081
6082 void MmsPluginDecoder::decodeMmsPdu(MmsMsg *pMsg, msg_message_id_t msgID, const char *pduFilePath)
6083 {
6084         MSG_BEGIN();
6085
6086         FILE *pFile     = NULL;
6087         MsgMultipart *pMultipart = NULL;
6088         int nSize = 0;
6089         char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6090         char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
6091
6092         MmsInitHeader();
6093
6094         pMsg->msgID = msgID;
6095
6096         snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6097
6098         MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName));
6099
6100         if (MsgGetFileSize(szFullPath, &nSize) == false) {
6101                 MSG_FATAL("Fail MsgGetFileSize");
6102                 goto __CATCH;
6103         }
6104
6105         pFile = MsgOpenFile(szFullPath, "rb");
6106         if (pFile == NULL) {
6107                 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6108                 goto __CATCH;
6109         }
6110
6111         MmsRegisterDecodeBuffer();
6112
6113         if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6114                 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6115                 goto __CATCH;
6116         }
6117
6118         if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6119                 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6120                 goto __CATCH;
6121         }
6122
6123         /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
6124
6125         memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
6126         memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
6127
6128 { /* attribute convert mmsHeader -> mmsAttribute */
6129
6130         pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
6131
6132         pMsg->mmsAttrib.date = mmsHeader.date;
6133
6134         if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6135                 pMsg->mmsAttrib.bAskDeliveryReport = true;
6136         }
6137
6138         memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6139
6140         memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6141
6142         MSG_DEBUG("@@@@@pMsg->mmsAttrib.deliveryTime=[%d]", pMsg->mmsAttrib.deliveryTime);
6143
6144         pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
6145
6146         snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
6147
6148         pMsg->mmsAttrib.msgType = mmsHeader.type;
6149
6150         pMsg->mmsAttrib.version = mmsHeader.version;
6151
6152         pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
6153
6154         pMsg->mmsAttrib.priority = mmsHeader.priority;
6155
6156         if (mmsHeader.readReply == MMS_REPORT_YES) {
6157                 pMsg->mmsAttrib.bAskReadReply = true;
6158         }
6159
6160         /* TODO : fill pMsg->mmsAttrib.szCc and pMsg->mmsAttrib.szTo field */
6161
6162         snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
6163
6164         snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
6165
6166         pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
6167
6168         /* FIXME:: mmsHeader will release after delete global mmsHeader */
6169         /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
6170 }
6171         if (pMsg->msgBody.pPresentationBody) {
6172                 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
6173                         goto __CATCH;
6174
6175                 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
6176                 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
6177                         goto __CATCH;
6178
6179                 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
6180
6181                 ULONG nRead = 0;
6182                 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
6183                 if (nRead == 0)
6184                         goto __CATCH;
6185
6186         }
6187
6188         MsgCloseFile(pFile);
6189         pFile = NULL;
6190         /* nPartCount */
6191         pMsg->nPartCount = 0;
6192
6193         if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
6194                 pMultipart = pMsg->msgBody.body.pMultipart;
6195                 while (pMultipart) {
6196                         pMsg->nPartCount++;
6197                         pMultipart = pMultipart->pNext;
6198                 }
6199         } else {
6200                 if (pMsg->msgBody.size > 0)
6201                         pMsg->nPartCount++;
6202         }
6203
6204         /*      make temporary  */
6205         snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
6206
6207         if (MsgIsMultipart(pMsg->msgType.type) == true) {
6208                 int partIndex = 0;
6209                 pMultipart = pMsg->msgBody.body.pMultipart;
6210
6211                 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6212                         if (errno == EEXIST) {
6213                                 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
6214                         } else {
6215                                 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6216                                 goto __CATCH;
6217                         }
6218                 } else {
6219                         MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
6220                 }
6221
6222                 if (pMsg->msgBody.pPresentationBody) {
6223                         if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
6224                                                                                                 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6225                                 goto __CATCH;
6226                 }
6227
6228                 while (pMultipart) {
6229
6230                         if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
6231                                                                                         (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, true) == false)
6232                                 goto __CATCH;
6233
6234                         MmsPrintMulitpart(pMultipart, partIndex);
6235
6236                         pMultipart = pMultipart->pNext;
6237                         partIndex ++;
6238                 }
6239
6240         } else { /* single part */
6241                 if (pMsg->nPartCount > 0) {
6242
6243                         if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6244                                 if (errno == EEXIST) {
6245                                         MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
6246                                 } else {
6247                                         MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6248                                         goto __CATCH;
6249                                 }
6250                         } else {
6251                                 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
6252                         }
6253
6254                         if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
6255                                                                                         (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6256                                 goto __CATCH;
6257                 }
6258         }
6259         MSG_DEBUG("### Success ###");
6260         MSG_END();
6261         return;
6262
6263 __CATCH:
6264
6265         MmsInitHeader();
6266         MmsUnregisterDecodeBuffer();
6267
6268         if (pFile != NULL) {
6269                 MsgCloseFile(pFile);
6270                 pFile = NULL;
6271         }
6272
6273
6274         MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
6275
6276         MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
6277
6278         MSG_DEBUG("### Fail ###");
6279         MSG_END();
6280         return;
6281
6282 }
6283
6284 /* CID 41989: Removed function decodeMmsPdu which is unused. */
6285 #if 0
6286 void MmsPluginDecoder::decodeMmsPdu(MMS_DATA_S *pMmsData, const char *pduFilePath)
6287 {
6288         MSG_BEGIN();
6289
6290         FILE *pFile     = NULL;
6291         MsgMultipart * iter_multipart = NULL;
6292         int nSize = 0;
6293         char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6294
6295         MmsInitHeader();
6296
6297         //pMsg->msgID = msgID;
6298
6299         snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6300
6301         //MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName));
6302
6303         if (MsgGetFileSize(szFullPath, &nSize) == false) {
6304                 MSG_FATAL("Fail MsgGetFileSize");
6305                 goto __CATCH;
6306         }
6307
6308         pFile = MsgOpenFile(szFullPath, "rb");
6309         if (pFile == NULL) {
6310                 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6311                 goto __CATCH;
6312         }
6313
6314         MmsRegisterDecodeBuffer();
6315
6316         if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6317                 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6318                 goto __CATCH;
6319         }
6320
6321         if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6322                 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6323                 goto __CATCH;
6324         }
6325
6326         //set header
6327         if (pMmsData->header == NULL) {
6328                 pMmsData->header = MsgMmsCreateHeader();
6329         }
6330
6331         pMmsData->header->messageType = mmsHeader.type;
6332
6333         pMmsData->header->mmsVersion = mmsHeader.version;
6334
6335         pMmsData->header->contentType = mmsHeader.msgType.type;
6336
6337         pMmsData->header->date = mmsHeader.date;
6338
6339         pMmsData->header->messageSize  = mmsHeader.msgSize;
6340
6341         pMmsData->header->mmsPriority = mmsHeader.priority;
6342
6343         pMmsData->header->messageClass = mmsHeader.msgClass;
6344
6345         if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6346                 pMmsData->header->bDeliveryReport = true;
6347         }
6348
6349         if (mmsHeader.readReply == MMS_REPORT_YES) {
6350                 pMmsData->header->bReadReport = true;
6351         }
6352
6353         memcpy(&pMmsData->header->delivery, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6354
6355         memcpy(&pMmsData->header->expiry, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6356
6357
6358         snprintf(pMmsData->header->messageID, sizeof(pMmsData->header->messageID), "%s", mmsHeader.szMsgID);
6359
6360         snprintf(pMmsData->header->szSubject, sizeof(pMmsData->header->szSubject), "%s", mmsHeader.szSubject);
6361
6362         snprintf(pMmsData->header->trID, sizeof(pMmsData->header->trID), "%s", mmsHeader.szTrID);
6363
6364         //CID 41989: Moving assignment of iter_multipart before its de-referencing.
6365         iter_multipart = mmsHeader.msgBody.body.pMultipart;
6366         //set multipart
6367         if (pMmsData->header->contentType == MIME_MULTIPART_RELATED || pMmsData->header->contentType == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
6368
6369                 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6370
6371                 pMultipart->type = MIME_APPLICATION_SMIL;
6372                 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s", "application/smil");
6373                 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", mmsHeader.msgBody.presentationType.szContentID);
6374                 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", mmsHeader.msgBody.presentationType.szContentLocation);
6375                 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", mmsHeader.msgBody.presentationType.param.szName);
6376
6377                 //snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), MSG_DATA_PATH"%s", mmsHeader.msgBody.presentationType.param.szFileName);
6378
6379                 MsgBody *pBody = iter_multipart->pBody;
6380                 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6381
6382                 pMmsData->smil = pMultipart;
6383         }
6384
6385
6386         while (iter_multipart) {
6387
6388                 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6389
6390                 pMultipart->type = (MimeType)iter_multipart->type.type;
6391
6392                 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s",MimeGetMimeStringFromMimeInt(iter_multipart->type.type));
6393                 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", iter_multipart->type.szContentID);
6394                 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", iter_multipart->type.szContentLocation);
6395                 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", iter_multipart->type.param.szName);
6396
6397                 //snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), "%s", iter_multipart->pBody->szOrgFilePath);
6398
6399                 MsgBody *pBody = iter_multipart->pBody;
6400                 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6401
6402
6403 #ifdef __SUPPORT_DRM__
6404                 if (iter_multipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
6405                         pMultipart->drmType = iter_multipart->type.drmInfo.drmType;
6406                 }
6407 #endif
6408
6409                 pMmsData->multipartlist = g_list_append(pMmsData->multipartlist, pMultipart);
6410                 iter_multipart = iter_multipart->pNext;
6411         }
6412
6413
6414         MSG_DEBUG("### SUCCESS ###");
6415         MSG_END();
6416         return;
6417 __CATCH:
6418
6419         MmsInitHeader();
6420         MmsUnregisterDecodeBuffer();
6421
6422         if (pFile != NULL) {
6423                 MsgCloseFile(pFile);
6424                 pFile = NULL;
6425         }
6426
6427         MSG_DEBUG("### Fail ###");
6428         MSG_END();
6429         return;
6430 }
6431 #endif