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