update tizen source
[framework/messaging/msg-service.git] / plugin / mms_plugin / MmsPluginDecode.cpp
1 /*
2 *
3 * Copyright (c) 2000-2012 Samsung Electronics Co., Ltd. All Rights Reserved.
4 *
5 * This file is part of msg-service.
6 *
7 * Contact: Jaeyun Jeong <jyjeong@samsung.com>
8 *          Sangkoo Kim <sangkoo.kim@samsung.com>
9 *          Seunghwan Lee <sh.cat.lee@samsung.com>
10 *          SoonMin Jung <sm0415.jung@samsung.com>
11 *          Jae-Young Lee <jy4710.lee@samsung.com>
12 *          KeeBum Kim <keebum.kim@samsung.com>
13 *
14 * PROPRIETARY/CONFIDENTIAL
15 *
16 * This software is the confidential and proprietary information of
17 * SAMSUNG ELECTRONICS ("Confidential Information"). You shall not
18 * disclose such Confidential Information and shall use it only in
19 * accordance with the terms of the license agreement you entered
20 * into with SAMSUNG ELECTRONICS.
21 *
22 * SAMSUNG make no representations or warranties about the suitability
23 * of the software, either express or implied, including but not limited
24 * to the implied warranties of merchantability, fitness for a particular
25 * purpose, or non-infringement. SAMSUNG shall not be liable for any
26 * damages suffered by licensee as a result of using, modifying or
27 * distributing this software or its derivatives.
28 *
29 */
30
31 #include<stdio.h>
32 #include <string.h>
33 #include <sys/stat.h>
34 #include <stdlib.h>
35 #include <errno.h>
36
37 #include "MsgDebug.h"
38 #include "MsgException.h"
39 #include "MmsPluginMessage.h"
40 #include "MmsPluginStorage.h"
41 #include "MsgUtilFile.h"
42 #include "MmsPluginCodec.h"
43 #include "MmsPluginDebug.h"
44 #include "MsgSettingTypes.h"
45 #include "MsgSettingHandler.h"
46 #include "MmsPluginInternal.h"
47 #include "MmsPluginAvCodec.h"
48 #include "MmsPluginStorage.h"
49 #include "MmsPluginSmil.h"
50 #ifdef __SUPPORT_DRM__
51 #include "MmsPluginDrm.h"
52 #include "MsgDrmWrapper.h"
53 #include "drm-service.h"
54 #endif
55
56
57 static bool _MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength);           /* bufLen < gMmsDecodeMaxLen */
58 static bool _MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength);       /* no bufLen limit */
59 static bool _MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength);
60
61 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength);
62 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength);
63 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength);
64 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
65 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
66 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength);
67 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength);
68 static char *__MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength);
69 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength);
70 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength);
71 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength);
72 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength);
73 static MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength);
74
75 #ifdef __SUPPORT_DRM__
76 bool __MmsParseDCFInfo(FILE *pFile, MsgDRMInfo *pDrmInfo, int totalLength);
77 bool __MmsParseDCFHdr(FILE *pFile, MsgDRMInfo *pDrmInfo, UINT32 headerLen, int totalLength);
78 bool MmsBinaryDecodeDRMMessage(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int fullBodyLength, int totalLength);
79 bool MmsBinaryDecodeDRMContent(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int bodyLength, int totalLength);
80 #endif
81
82 static bool MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength);
83 bool MmsBinaryIsTextEncodedPart(FILE *pFile, int totalLength);
84 static bool     __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength);
85
86 bool __MmsTextDecodeMsgHeader(FILE *pFile);
87 bool MmsTextDecodeMsgBody(FILE *pFile);
88
89 char gszMmsLoadBuf1[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
90 char gszMmsLoadBuf2[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
91
92 static char *gpCurMmsDecodeBuff = NULL;
93 static int gCurMmsDecodeBuffPos = 0;    /* next decoding position in gpCurMmsDecodeBuff  */
94 static int gMmsDecodeMaxLen = 0;
95 static int gMmsDecodeCurOffset = 0;     /* current offset in file (last read) */
96 static int gMmsDecodeBufLen = 0;                /* number of last read characters */
97
98 static char *gpMmsDecodeBuf1 = NULL;
99 static char *gpMmsDecodeBuf2 = NULL;
100
101 MmsHeader       mmsHeader =
102 {
103         false,                                                                  //bActive
104         NULL,                                                                   //pszOwner
105         -1,                                                                             //msgID
106
107         (MmsMsgType)MMS_MSGTYPE_ERROR,                  //MmsMsgType                    iType;
108         "",                                                                             //char[]                                szTrID;
109         //"",                                                                           //short int                             version;
110         0,                                                                              //short int                             version;
111         0,                                                                              //UINT32                                date;
112
113         NULL,                                                                   //MsgHeaderAddress*             pFrom;
114         NULL,                                                                   //MsgHeaderAddress*             pTo;
115         NULL,                                                                   //MsgHeaderAddress*             pCc;
116         NULL,                                                                   //MsgHeaderAddress*             pBcc;
117         "",                                                                             //char[]                                szSubject;
118         (MmsResponseStatus)MMS_RESPSTATUS_OK,   //MmsResponseStatus             iResponseStatus;
119         (MmsRetrieveStatus)MMS_RETRSTATUS_OK,   //MmsRetrieveStatus             iRetrieveStatus;
120         "",                                                                             //char[]                                szResponseText;
121         "",                                                                             //char[]                                szRetrieveText;
122
123
124         /* has default value in specification */
125
126         (MmsMsgClass)MMS_MSGCLASS_PERSONAL,             //MmsMsgClass                   msgClass;
127         {MMS_TIMETYPE_RELATIVE, 0},                             //MmsTimeStruct                 expiryTime;
128         {MMS_TIMETYPE_RELATIVE, 0},                             //MmsTimeStruct                 deliveryTime;
129         (MmsPriority)MMS_PRIORITY_NORMAL,               //MmsPriority                   priority;               // Refer [OMA-MMS-ENC-v1_2-20030915-C]
130         (MmsSenderVisible)MMS_SENDER_SHOW,              //MmsSenderVisible              senderVisible;
131         (MmsReport)MMS_REPORT_NO,                               //MmsReport                             deliveryReport;
132         (MmsReport)MMS_REPORT_NO,                               //MmsReport                             readReply;
133         (MmsReportAllowed)MMS_REPORTALLOWED_NO,//MmsReportAllowed               iReportAllowed;
134         "",                                                                             //char[]                                szContentLocation;
135
136
137         /* there is no right default value */
138
139         (MSG_DELIVERY_REPORT_STATUS_T)MSG_DELIVERY_REPORT_NONE,         //MmsMsgStatus                  iMsgStatus;
140         (MSG_READ_REPORT_STATUS_T)MSG_READ_REPORT_NONE,         //MmsReadStatus                 readStatus;
141
142         /* MMS v1.1 ReplyCharge */
143         {
144                 (MmsReplyChargeType)MMS_REPLY_NONE,     //MmsReplyChargeType    chargeType;
145                 {MMS_TIMETYPE_RELATIVE, 0},                     //MmsTimeStruct                 deadLine;
146                 0,                                                                      //int                                   chargeSize;
147                 "" ,                                                            //char                                  szChargeID;
148         },
149
150         "",                                                                             //char[]                                szMsgID;
151         0,                                                                              //UINT32                                msgSize;
152 };
153
154 #ifdef __SUPPORT_DRM__
155
156 #define MMS_DRM2_CONVERT_BUFFER_MAX     4*1024
157 const UINT32 MMS_UINTVAR_LENGTH_1 =  0x0000007f;                //7bit
158 const UINT32 MMS_UINTVAR_LENGTH_2 =  0x00003fff;                //14bit
159 const UINT32 MMS_UINTVAR_LENGTH_3 =  0x001fffff;                //21bit
160
161 #endif
162
163
164 bool _MmsDecodeInitialize(void)
165 {
166         MmsInitMsgType(&mmsHeader.msgType);
167         MmsInitMsgBody(&mmsHeader.msgBody);
168
169         return true;
170 }
171
172 bool __MmsSetMmsHeaderOwner(int msgID, char* pszNewOwner)
173 {
174         if (pszNewOwner) {
175                 // set new owner
176                 MSG_DEBUG("__MmsSetMmsHeaderOwner: set (%s, msgID=%d)\n", pszNewOwner, msgID);
177
178                 if ((mmsHeader.pszOwner = (char*)malloc(strlen(pszNewOwner) + 1)) == NULL)
179                         return false;
180
181                 memset (mmsHeader.pszOwner, 0, strlen(pszNewOwner) + 1) ;
182
183                 strcpy(mmsHeader.pszOwner, pszNewOwner);
184                 mmsHeader.bActive = true;
185                 mmsHeader.msgID = msgID;
186         } else {
187                 // delete current owner
188                 if (mmsHeader.pszOwner) {
189                         MSG_DEBUG("__MmsSetMmsHeaderOwner: free (%s %d)\n", mmsHeader.pszOwner, msgID);
190                         free(mmsHeader.pszOwner);
191                         mmsHeader.pszOwner = NULL;
192                 }
193                 mmsHeader.bActive = false;
194                 mmsHeader.msgID = -1;
195         }
196
197         return true;
198 }
199
200
201 void _MmsInitHeader()
202 {
203         mmsHeader.type = MMS_MSGTYPE_ERROR;
204
205         memset(mmsHeader.szTrID, 0, MMS_TR_ID_LEN + 1);
206         mmsHeader.version = MMS_VERSION;
207         mmsHeader.date = 0;
208
209         MsgFreeHeaderAddress(mmsHeader.pFrom);
210         MsgFreeHeaderAddress(mmsHeader.pTo);
211         MsgFreeHeaderAddress(mmsHeader.pCc);
212         MsgFreeHeaderAddress(mmsHeader.pBcc);
213
214         mmsHeader.pFrom = NULL;
215         mmsHeader.pTo = NULL;
216         mmsHeader.pCc = NULL;
217         mmsHeader.pBcc = NULL;
218
219         memset(mmsHeader.szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
220
221         mmsHeader.responseStatus = (MmsResponseStatus)MMS_RESPSTATUS_OK;
222         mmsHeader.retrieveStatus = (MmsRetrieveStatus)MMS_RETRSTATUS_OK;
223         memset(mmsHeader.szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
224         memset(mmsHeader.szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
225
226
227         mmsHeader.msgClass = (MmsMsgClass)MMS_MSGCLASS_PERSONAL;
228         mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
229         mmsHeader.expiryTime.time = 0;
230         mmsHeader.deliveryTime.type     = MMS_TIMETYPE_RELATIVE;
231         mmsHeader.deliveryTime.time     = 0;
232         mmsHeader.priority = (MmsPriority)MMS_PRIORITY_NORMAL;  // Refer [OMA-MMS-ENC-v1_2-20030915-C]
233         mmsHeader.hideAddress =(MmsSenderVisible)MMS_SENDER_SHOW;
234         mmsHeader.deliveryReport = (MmsReport)MMS_REPORT_NO;
235         mmsHeader.readReply = (MmsReport)MMS_REPORT_NO;
236         mmsHeader.reportAllowed = (MmsReportAllowed)MMS_REPORTALLOWED_YES;
237         memset(mmsHeader.szContentLocation, 0, MMS_LOCATION_LEN + 1);
238
239
240         mmsHeader.msgStatus = (MSG_DELIVERY_REPORT_STATUS_T)MSG_DELIVERY_REPORT_NONE;
241         mmsHeader.readStatus = (MSG_READ_REPORT_STATUS_T)MSG_READ_REPORT_NONE;
242
243         mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MMS_REPLY_NONE;
244         mmsHeader.replyCharge.chargeSize = 0;
245         mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
246         mmsHeader.replyCharge.deadLine.time = 0;
247         memset(mmsHeader.replyCharge.szChargeID, 0, MMS_MSG_ID_LEN + 1);
248
249
250         memset(mmsHeader.szMsgID, 0, MMS_MSG_ID_LEN + 1);
251         mmsHeader.msgSize = 0;
252 #ifdef __SUPPORT_DRM__
253         mmsHeader.drmType = MSG_DRM_TYPE_NONE;
254 #endif
255
256         _MmsDecodeInitialize();
257 }
258
259
260
261 void _MmsCleanDecodeBuff(void)
262 {
263         memset(gpMmsDecodeBuf1, 0, gMmsDecodeMaxLen + 1);
264         memset(gpMmsDecodeBuf2, 0, gMmsDecodeMaxLen + 1);
265         gpCurMmsDecodeBuff = NULL;
266         gCurMmsDecodeBuffPos = 0;
267         gMmsDecodeBufLen = 0;
268 }
269
270
271 void _MmsRegisterDecodeBuffer(char *pInBuff1, char *pInBuff2, int maxLen)
272 {
273         gpMmsDecodeBuf1 = pInBuff1;
274         gpMmsDecodeBuf2 = pInBuff2;
275         gpCurMmsDecodeBuff = NULL;
276         gCurMmsDecodeBuffPos = 0;
277         gMmsDecodeMaxLen = maxLen;
278         gMmsDecodeCurOffset = 0;
279         gMmsDecodeBufLen = 0;
280 }
281
282 void _MmsUnregisterDecodeBuffer(void)
283 {
284         gpMmsDecodeBuf1 = NULL;
285         gpMmsDecodeBuf2 = NULL;
286         gpCurMmsDecodeBuff = NULL;
287         gCurMmsDecodeBuffPos = 0;
288         gMmsDecodeMaxLen = 0;
289         gMmsDecodeCurOffset = 0;
290         gMmsDecodeBufLen = 0;
291 }
292
293
294 int _MmsGetDecodeOffset(void)
295 {
296         return (gMmsDecodeCurOffset - gMmsDecodeBufLen + gCurMmsDecodeBuffPos);
297 }
298
299
300 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength)
301 {
302         if (*pLength <= valueLength) {
303                 gCurMmsDecodeBuffPos -= valueLength;
304                 gCurMmsDecodeBuffPos += *pLength;
305                 return false;
306         }
307
308         *pLength -= valueLength;
309
310         return true;
311 }
312
313
314 /* ==========================================================
315
316            B  I  N  A  R  Y         D  E  C  O  D  I  N  G
317
318    ==========================================================*/
319
320 /*
321  * Binary Encoded Message Format
322  *
323  *              < Single Part Body Message >
324  * -----------------------------------
325  * |            Header Fields                    |
326  * -----------------------------------
327  * | Content Type:start=xxx;type=xxx |  ->(ex) Text/Plain, Text/Html, ....
328  * -----------------------------------
329  * |            Single Part Body                 |
330  * -----------------------------------
331  *
332  *              < Multi Part Body Message >
333  * -----------------------------------
334  * |            Header Fields                    |
335  * -----------------------------------
336  * | Content Type:start=xxx;type=xxx |  -> (ex) Application/vnd.wap.multipart.mixed(related), multipart/mixed(related)
337  * -----------------------------------
338  * |    # of Entries (body parts)        |
339  * -----------------------------------                          < Each Entry >
340  * |                    Entry 1                          |      ->      -----------------------------
341  * -----------------------------------          |               header Length           |
342  * |                    Entry 2                          |              -----------------------------
343  * -----------------------------------          |               Data Length                     |
344  * |                    ......                           |              -----------------------------  -
345  * -----------------------------------          |               Content-Type            |  |
346  * |                    Entry n                          |              -----------------------------  | Header Length
347  * -----------------------------------          |                       Header                  |  |
348  *                                                                                      -----------------------------  -
349  *                                                                                      |                       Data                    |  | Data Length
350  *                                                                                      -----------------------------  -
351  */
352 bool MmsBinaryDecodeMsgHeader(FILE *pFile, int totalLength)
353 {
354         UINT16 fieldCode = 0xffff;
355         UINT16 fieldValue = 0xffff;
356         UINT8 oneByte = 0xff;
357
358         MsgHeaderAddress *pAddr = NULL;
359         MsgHeaderAddress *pLastTo = NULL;
360         MsgHeaderAddress *pLastCc = NULL;
361         MsgHeaderAddress *pLastBcc = NULL;
362
363         UINT32 valueLength = 0;
364         UINT32 tmpInteger = 0;
365         int     tmpIntLen = 0;
366
367         int offset = 0;
368
369         char szGarbageBuff[MSG_STDSTR_LONG]     = {0, };
370         char *pLimitData = NULL;
371         int nRead = 0;
372
373         MSG_DEBUG("MmsBinaryDecodeMsgHeader: pFile=%d, total len=%d\n", pFile, totalLength);
374
375         _MmsCleanDecodeBuff();
376
377         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
378                                                                    &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
379                                                                    gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
380                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: fail to load to buffer \n");
381                 goto __CATCH;
382         }
383
384         while (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength)) {
385                 fieldCode = oneByte & 0x7f;
386
387                 switch (_MmsGetBinaryType(MmsCodeFieldCode, fieldCode)) {
388                 case MMS_CODE_RESPONSESTATUS:
389
390                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
391                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: responseStatus GetOneByte fail\n");
392                                 goto __CATCH;
393                         }
394
395                         fieldValue = _MmsGetBinaryType(MmsCodeResponseStatus, (UINT16)(oneByte & 0x7F));
396
397                         if (fieldValue == 0xFFFF) {
398                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: responseStatus error\n");
399                                 goto __CATCH;
400                         }
401
402                         if (fieldValue >= 0x0044 && fieldValue <= 0x005F) {
403                                 fieldValue = 0x0040;
404                         } else if (fieldValue >= 0x006A && fieldValue <= 0x007F) {
405                                 fieldValue = 0x0060;
406                         }
407
408                         mmsHeader.responseStatus = (MmsResponseStatus)fieldValue;
409
410                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: response status = %s\n", MmsDebugGetResponseStatus(mmsHeader.responseStatus));
411
412                         break;
413
414                 case MMS_CODE_RETRIEVESTATUS:
415
416                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
417                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: retrieveStatus GetOneByte fail\n");
418                                 goto __CATCH;
419                         }
420
421                         fieldValue = _MmsGetBinaryType(MmsCodeRetrieveStatus, (UINT16)(oneByte & 0x7F));
422
423                         if (fieldValue == 0xFFFF) {
424                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: retrieveStatus error\n");
425                                 goto __CATCH;
426                         }
427
428                         if (fieldValue >= 0x0043 && fieldValue <= 0x005F) {
429                                 fieldValue = 0x0040; // 192; Error-transient-failure
430                         } else if (fieldValue >= 0x0064 && fieldValue <= 0x007F) {
431                                 fieldValue = 0x0060; //224; Error-permanent-failure
432                         }
433
434                         mmsHeader.retrieveStatus = (MmsRetrieveStatus)fieldValue;
435
436                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: retrieve status = %s\n",
437                                                                                                                         MmsDebugGetRetrieveStatus(mmsHeader.retrieveStatus));
438
439                         break;
440
441                 case MMS_CODE_RESPONSETEXT:
442
443                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szResponseText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
444                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : invalid MMS_CODE_RESPONSETEXT \n");
445                                 goto __CATCH;
446                         }
447
448                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: response text = %s\n", mmsHeader.szResponseText);
449                         break;
450
451                 case MMS_CODE_RETRIEVETEXT:
452
453                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szRetrieveText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
454                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : invalid MMS_CODE_RETRIEVETEXT \n");
455                                 goto __CATCH;
456                         }
457
458                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: retrieve text = %s\n", mmsHeader.szResponseText);
459                         break;
460
461                 case MMS_CODE_MSGID:
462
463                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szMsgID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
464                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_MSGID is invalid\n");
465                                 goto __CATCH;
466                         }
467
468                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: msg id = %s\n", mmsHeader.szMsgID);
469
470                         if (MsgStrlen (mmsHeader.szMsgID) > 2)
471                                 MsgMIMERemoveQuote (mmsHeader.szMsgID);
472
473                         break;
474
475                 case MMS_CODE_SUBJECT:
476
477                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN + 1, totalLength) == false) {
478                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : invalid MMS_CODE_SUBJECT \n");
479                                 goto __CATCH;
480                         }
481
482                         pLimitData = (char *)malloc(MSG_LOCALE_SUBJ_LEN + 1);
483
484                         if (pLimitData == NULL) {
485                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : pLimitData malloc fail \n");
486                                 goto __CATCH;
487                         }
488
489                         nRead = MsgCutUTFString((unsigned char*)pLimitData, MSG_LOCALE_SUBJ_LEN + 1, (unsigned char*)mmsHeader.szSubject, MSG_SUBJ_LEN);
490                         MSG_DEBUG("MmsBinaryDecodeMsgHeader : Subject edit.. \n");
491
492                         if (nRead > MSG_LOCALE_SUBJ_LEN) {
493                                 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
494                                 strncpy(mmsHeader.szSubject, pLimitData, MSG_SUBJ_LEN);
495                         } else {
496                                 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
497                                 strncpy(mmsHeader.szSubject, pLimitData, MSG_LOCALE_SUBJ_LEN);
498                         }
499
500                         if (pLimitData) {
501                                 free(pLimitData);
502                                 pLimitData = NULL;
503                         }
504
505                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: subject = %s\n", mmsHeader.szSubject);
506                         break;
507
508                 case MMS_CODE_FROM:
509
510                         /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
511
512                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
513                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_FROM is invalid\n");
514                                 goto __CATCH;
515                         }
516
517                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
518                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: MMS_CODE_FROM GetOneByte fail\n");
519                                 goto __CATCH;
520                         }
521
522                         // DRM_TEMPLATE - start
523
524                         valueLength--;
525
526                         if (oneByte == (_MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
527                                 if (valueLength > 0) {
528                                         mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
529                                         if (mmsHeader.pFrom == NULL) {
530                                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_FROM __MmsDecodeEncodedAddress fail\n");
531                                                 goto __CATCH;
532                                         }
533                                 } else {
534                                         mmsHeader.pFrom = (MsgHeaderAddress *)malloc(sizeof(MsgHeaderAddress));
535                                         if (mmsHeader.pFrom == NULL)
536                                                 goto __CATCH;
537
538                                         mmsHeader.pFrom->szAddr = (char *)malloc(1);
539                                         if (mmsHeader.pFrom->szAddr == NULL) {
540                                                 free(mmsHeader.pFrom);
541                                                 mmsHeader.pFrom = NULL;
542                                                 goto __CATCH;
543                                         }
544
545                                         mmsHeader.pFrom->szAddr[0] = '\0';
546                                         mmsHeader.pFrom->pNext = NULL;
547                                 }
548
549                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: from = %s\n", mmsHeader.pFrom->szAddr);
550                                 // DRM_TEMPLATE - end
551                         } else if (oneByte == (_MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
552                                 /* Present Token only */
553                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_FROM insert token\n");
554                         } else {
555                                 /* from data broken */
556                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: from addr broken\n");
557                                 gCurMmsDecodeBuffPos--;
558                                 goto __CATCH;
559                         }
560                         break;
561
562                 case MMS_CODE_TO:
563
564                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
565                         if (pAddr == NULL) {
566                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_TO __MmsDecodeEncodedAddress fail\n");
567                                 goto __CATCH;
568                         }
569
570                         if (mmsHeader.pTo == NULL) {
571                                 /* the first TO */
572                                 pLastTo = mmsHeader.pTo = pAddr;
573                         } else {
574                                 if (pLastTo)
575                                         pLastTo->pNext = pAddr;
576                                 pLastTo = pAddr;
577                         }
578
579                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: to = %s\n", mmsHeader.pTo->szAddr);
580                         break;
581
582                 case MMS_CODE_BCC:
583
584                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
585                         if (pAddr == NULL) {
586                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_BCC __MmsDecodeEncodedAddress fail\n");
587                                 goto __CATCH;
588                         }
589
590                         if (mmsHeader.pBcc == NULL) {
591                                 /* the first Bcc */
592                                 pLastBcc = mmsHeader.pBcc = pAddr;
593                         } else {
594                                 if (pLastBcc)
595                                         pLastBcc->pNext = pAddr;
596                                 pLastBcc = pAddr;
597                         }
598
599                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: bcc = %s\n", mmsHeader.pBcc->szAddr);
600                         break;
601
602                 case MMS_CODE_CC:
603
604                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
605                         if (pAddr == NULL) {
606                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_CC __MmsDecodeEncodedAddress fail\n");
607                                 goto __CATCH;
608                         }
609
610                         if (mmsHeader.pCc == NULL) {
611                                 /* the first Cc */
612                                 pLastCc = mmsHeader.pCc = pAddr;
613                         } else {
614                                 if (pLastCc)
615                                         pLastCc->pNext = pAddr;
616                                 pLastCc = pAddr;
617                         }
618                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: cc = %s\n", mmsHeader.pCc->szAddr);
619                         break;
620
621                 case MMS_CODE_CONTENTLOCATION:
622
623                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
624                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_CONTENTLOCATION is invalid\n");
625                                 goto __CATCH;
626                         }
627                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: content location = %s\n", mmsHeader.szContentLocation);
628                         break;
629
630                 case MMS_CODE_DATE:
631
632                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
633                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_DATE is invalid\n");
634                                 goto __CATCH;
635                         }
636                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: date = %d\n", mmsHeader.date);
637                         break;
638
639                 case MMS_CODE_DELIVERYREPORT:
640
641                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
642                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: deliveryReport GetOneByte fail\n");
643                                 goto __CATCH;
644                         }
645
646                         fieldValue = _MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
647
648                         if (fieldValue == 0xFFFF) {
649                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: deliveryReport error\n");
650                                 goto __CATCH;
651                         }
652
653                         mmsHeader.deliveryReport = (MmsReport)fieldValue;
654
655                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: delivery report=%s\n", MmsDebugGetMmsReport(mmsHeader.deliveryReport));
656                         break;
657
658                 case MMS_CODE_DELIVERYTIME:
659
660                         /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
661
662                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
663                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : invalid MMS_CODE_DELIVERYTIME \n");
664                                 goto __CATCH;
665                         }
666
667                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
668                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: delivery time GetOneByte fail\n");
669                                 goto __CATCH;
670                         }
671
672                         //DRM_TEMPLATE - start
673                         valueLength--;
674
675                         if (oneByte == (_MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
676                                 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
677
678                                 if (valueLength > 0) {
679                                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
680                                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : invalid MMS_CODE_DELIVERYTIME\n");
681                                                 goto __CATCH;
682                                         }
683                                 }
684                         // DRM_TEMPLATE - end
685                         } else {
686                                 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
687
688                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
689                                         MSG_DEBUG("MmsBinaryDecodeMsgHeader : __MmsBinaryDecodeInteger fail...\n");
690                                         goto __CATCH;
691                                 }
692                         }
693                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: delivery type=%d, time=%d\n", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
694                         break;
695
696                 case MMS_CODE_EXPIRYTIME:
697
698                         /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
699
700                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
701                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : invalid MMS_CODE_EXPIRYTIME \n");
702                                 goto __CATCH;
703                         }
704
705                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
706                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: expiry time GetOneByte fail\n");
707                                 goto __CATCH;
708                         }
709
710                         // DRM_TEMPLATE - start
711                         valueLength--;
712
713                         if (oneByte == (_MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
714                                 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
715
716                                 if (valueLength > 0) {
717                                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
718                                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_EXPIRYTIME is invalid\n");
719                                                 goto __CATCH;
720                                         }
721                                 }
722                         // DRM_TEMPLATE - end
723                         } else {
724                                 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
725
726                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
727                                         MSG_DEBUG("MmsBinaryDecodeMsgHeader : __MmsBinaryDecodeInteger fail...\n");
728                                         goto __CATCH;
729                                 }
730                         }
731                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: expiry = %d\n", mmsHeader.expiryTime.time);
732                         break;
733
734                 case MMS_CODE_MSGCLASS:
735
736                         /* Class-value = Class-identifier | Token Text */
737
738                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
739                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgClass GetOneByte fail\n");
740                                 goto __CATCH;
741                         }
742
743                         if (oneByte > 0x7f) {
744                                 /* Class-identifier */
745                                 mmsHeader.msgClass = (MmsMsgClass)_MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
746                         } else {
747                                 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
748                                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: 1. __MmsBinaryDecodeText fail. (class)\n");
749                                         goto __CATCH;
750                                 }
751                         }
752                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: msg class=%s\n", MmsDebugGetMsgClass(mmsHeader.msgClass));
753                         break;
754
755                 case MMS_CODE_MSGSIZE:
756
757                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
758                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_MSGSIZE is invalid\n");
759                                 goto __CATCH;
760                         }
761                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: msg size = %d\n", mmsHeader.msgSize);
762                         break;
763
764                 case MMS_CODE_MSGSTATUS:
765
766                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
767                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
768                                 goto __CATCH;
769                         }
770
771                         mmsHeader.msgStatus =  (MSG_DELIVERY_REPORT_STATUS_T)_MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
772                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: msg status=%s \n", MmsDebugGetMsgStatus(mmsHeader.msgStatus)) ;
773                         break;
774
775                 case MMS_CODE_MSGTYPE:
776
777                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
778                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
779                                 goto __CATCH;
780                         }
781
782                         mmsHeader.type = (MmsMsgType)_MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
783                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: msg type=%s\n", MmsDebugGetMsgType(mmsHeader.type));
784                         break;
785
786                 case MMS_CODE_PRIORITY:
787
788                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
789                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
790                                 goto __CATCH;
791                         }
792                         mmsHeader.priority = (MmsPriority)_MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
793                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: priority=%d\n", mmsHeader.priority);
794                         break;
795
796                 case MMS_CODE_READREPLY:
797
798                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
799                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
800                                 goto __CATCH;
801                         }
802                         mmsHeader.readReply = (MmsReport)_MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
803                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: read reply=%s \n", MmsDebugGetMmsReport(mmsHeader.readReply));
804                         break;
805
806                 case MMS_CODE_REPORTALLOWED:
807
808                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
809                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
810                                 goto __CATCH;
811                         }
812                         mmsHeader.reportAllowed =  (MmsReportAllowed)_MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
813                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: mmsHeader.reportAllowed=%d\n", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
814                         break;
815
816                 case MMS_CODE_SENDERVISIBILLITY:
817
818                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
819                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
820                                 goto __CATCH;
821                         }
822                         mmsHeader.hideAddress= (MmsSenderVisible)!(_MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
823                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: sender visible=%d \n", mmsHeader.hideAddress);
824                         break;
825
826                 case MMS_CODE_TRID:
827
828                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
829                                 MSG_DEBUG("Transaction ID Too Long \n");
830                                 goto __CATCH;
831                         }
832                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: trID = %s\n", mmsHeader.szTrID);
833                         break;
834
835                 case MMS_CODE_VERSION:
836                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
837                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
838                                 goto __CATCH;
839                         }
840                         mmsHeader.version = oneByte;
841
842                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: ver = 0x%x\n", mmsHeader.version);
843                         break;
844
845                 case MMS_CODE_CONTENTTYPE:
846
847                         /*
848                          * Content-type is the last header field of SendRequest and RetrieveConf.
849                          * It's required to decrease pointer by one and return,
850                          * to parse this field in MmsBinaryDecodeContentType().
851                          */
852                         goto __RETURN;
853
854
855                 /* ----------- Add by MMSENC v1.1 ----------- */
856
857                 case MMS_CODE_READSTATUS:
858
859                         /* Read-status-value = Read | Deleted without being read */
860
861                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
862                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
863                                 goto __CATCH;
864                         }
865
866                         mmsHeader.readStatus =  (MSG_READ_REPORT_STATUS_T)_MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
867                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: read status=%s\n", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
868                         break;
869
870                 case MMS_CODE_REPLYCHARGING:
871
872                         /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
873
874                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
875                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
876                                 goto __CATCH;
877                         }
878
879                         mmsHeader.replyCharge.chargeType =  (MmsReplyChargeType)_MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
880                         MSG_DEBUG("MmsBinaryDecodeMsgHeader: mmsHeader.reply charge=%d\n", mmsHeader.replyCharge.chargeType);
881                         break;
882
883                 case MMS_CODE_REPLYCHARGINGDEADLINE:
884
885                         /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
886
887                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
888                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : invalid MMS_CODE_REPLYCHARGINGDEADLINE \n");
889                                 goto __CATCH;
890                         }
891
892                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
893                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: msgStatus GetOneByte fail\n");
894                                 goto __CATCH;
895                         }
896
897                         if (oneByte == (_MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
898                                 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
899                         } else {
900                                 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
901                         }
902
903                         // DRM_TEMPLATE - start
904                         valueLength--;
905
906                         if (valueLength > 0) {
907                                 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
908                                         MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_REPLYCHARGINGDEADLINE is invalid\n");
909                                         goto __CATCH;
910                                 }
911                         }
912                         // DRM_TEMPLATE - end
913                         break;
914
915                 case MMS_CODE_REPLYCHARGINGID:
916
917                         /* Reply-charging-ID-value = Text-string */
918
919                         if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
920                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: 1. __MmsBinaryDecodeText fail. (szReplyChargingID)\n");
921                                 goto __CATCH;
922                         }
923                         break;
924
925                 case MMS_CODE_REPLYCHARGINGSIZE:
926
927                         /* Reply-charging-size-value = Long-integer */
928
929                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
930                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : MMS_CODE_REPLYCHARGINGSIZE is invalid\n");
931                                 goto __CATCH;
932                         }
933                         break;
934
935                 case MMS_CODE_PREVIOUSLYSENTBY:
936
937                         /*
938                          * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
939                          * Forwarded-count-value = Integer-value
940                          * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
941                          */
942
943                         /*
944                          * fixme: There is no proper field to store this information.
945                          * Just increase pointer now.
946                          */
947
948                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
949                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : 1. invalid MMS_CODE_PREVIOUSLYSENTBY \n");
950                                 goto __CATCH;
951                         }
952
953                         if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
954                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : 2. invalid MMS_CODE_PREVIOUSLYSENTBY \n");
955                                 goto __CATCH;
956                         }
957
958                         if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
959                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : invalid MMS_CODE_RETRIEVETEXT \n");
960                                 goto __CATCH;
961                         }
962                         break;
963
964                 case MMS_CODE_PREVIOUSLYSENTDATE:
965
966                         /*
967                          * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
968                          * Forwarded-count-value = Integer-value
969                          * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
970                          */
971
972                         /*
973                          * fixme: There is no proper field to store this information.
974                          * Just increase pointer now.
975                          */
976
977                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
978                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : 1. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
979                                 goto __CATCH;
980                         }
981
982                         if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
983                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : 2. invalid MS_CODE_PREVIOUSLYSENTDATE \n");
984                                 goto __CATCH;
985                         }
986
987                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
988                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader : 3. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
989                                 goto __CATCH;
990                         }
991                         break;
992
993
994                 default:
995
996                         /*
997                          * Application-header             = Token-text Application-specific-value
998                          * Token-text                             = Token End-of-string
999                          * Application-specific-value = Text -string
1000                          *
1001                          * OR unknown header field - Just ignore these fields.
1002                          *
1003                          * Read one byte and check the value >= 0x80
1004                          * (check these value can be field code)
1005                          */
1006                         {
1007                                 int             remainLength = 0;
1008
1009                                 oneByte = 0x00;
1010
1011                                 offset = _MmsGetDecodeOffset();
1012                                 if (offset >= totalLength)
1013                                         goto __RETURN;
1014
1015                                 remainLength = totalLength - offset;
1016
1017                                 while ((oneByte < 0x80) && (remainLength > 0)) {
1018                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1019                                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: __MmsBinaryDecodeCheckAndDecreaseLength fail\n");
1020                                                 goto __CATCH;
1021                                         }
1022                                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1023                                                 MSG_DEBUG("MmsBinaryDecodeMsgHeader: responseStatus GetOneByte fail\n");
1024                                                 goto __CATCH;
1025                                         }
1026                                 }
1027
1028                                 gCurMmsDecodeBuffPos--;
1029                         }
1030
1031                         break;
1032                 }       /* switch */
1033
1034                 offset = _MmsGetDecodeOffset();
1035                 if (offset >= totalLength)
1036                         goto __RETURN;
1037
1038         }       /* while */
1039
1040
1041 __RETURN:
1042
1043         MSG_DEBUG("MmsBinaryDecodeMsgHeader: success\n");
1044         return true;
1045
1046
1047 __CATCH:
1048         MSG_DEBUG("MmsBinaryDecodeMsgHeader: failed\n");
1049
1050         return false;
1051 }
1052
1053 #ifdef FEATURE_JAVA_MMS
1054 // for JAVA MMS AppId - check later whether it can be handled by MmsBinaryDecodeMsgHeader
1055 bool MmsBinaryDecodeContentType(FILE *pFile, char *szFilePath, int totalLength)
1056 {
1057         int length      = 0;
1058
1059         MSG_DEBUG("MmsBinaryDecodeContentType:\n");
1060
1061         if (szFilePath != NULL)
1062                 strncpy(mmsHeader.msgType.szOrgFilePath, szFilePath, strlen(szFilePath));
1063         mmsHeader.msgType.offset = _MmsGetDecodeOffset() - 1;           // + Content-Type code value
1064
1065         // read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding
1066         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1067                                                                         &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1068                                                                         gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1069                 MSG_DEBUG("MmsBinaryDecodeContentType: fail to load to buffer \n");
1070                 goto __CATCH;
1071         }
1072
1073         // msg's type [ex] related, mixed, single part (jpg, amr and etc)
1074         length = MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1075         if (length == -1) {
1076                 MSG_DEBUG("MmsBinaryDecodeContentType: MMS_CODE_CONTENTTYPE is fail\n");
1077                 goto __CATCH;
1078         }
1079         MSG_DEBUG("Content-Type: Application-ID:%s Reply-To-Application-ID:%s",mmsHeader.msgType.param.szApplicationID, mmsHeader.msgType.param.szReplyToApplicationID);
1080
1081         return true;
1082
1083 __CATCH:
1084
1085         /* fixme: Delete multipart using MmsDeleteMsg() */
1086
1087         return false;
1088 }
1089 #endif
1090
1091 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1092 {
1093         int length = 0;
1094         int offset = 0;
1095
1096         MsgMultipart *pMultipart = NULL;
1097
1098         MSG_DEBUG("MmsBinaryDecodeMsgBody:\n");
1099
1100         if (szFilePath != NULL)
1101                 strncpy(mmsHeader.msgType.szOrgFilePath, szFilePath , strlen(szFilePath));
1102
1103         mmsHeader.msgType.offset = _MmsGetDecodeOffset() - 1;           // + Content-Type code value
1104
1105         // read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding
1106         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1107                                                                         &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1108                                                                         gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1109                 MSG_DEBUG("MmsBinaryDecodeMsgBody: fail to load to buffer \n");
1110                 goto __CATCH;
1111         }
1112
1113         // msg's type [ex] related, mixed, single part (jpg, amr and etc)
1114         length = MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1115         if (length == -1) {
1116                 MSG_DEBUG("MmsBinaryDecodeMsgBody: MMS_CODE_CONTENTTYPE is fail\n");
1117                 goto __CATCH;
1118         }
1119
1120         mmsHeader.msgType.size   = length + 1;                                          // + Content-Type code value
1121         mmsHeader.msgBody.offset = _MmsGetDecodeOffset();
1122
1123         switch (mmsHeader.msgType.type) {
1124         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1125         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1126         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1127         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1128         case MIME_MULTIPART_REPORT:
1129         case MIME_MULTIPART_MIXED:
1130         case MIME_MULTIPART_RELATED:
1131         case MIME_MULTIPART_ALTERNATIVE:
1132         case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1133         case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1134
1135                 MSG_DEBUG("__MmsBinaryMsgBodyDecode: Decode multipart\n");
1136
1137                 offset = _MmsGetDecodeOffset();
1138                 if (offset >= totalLength)
1139                         goto __RETURN;
1140
1141                 if (MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1142                         MSG_DEBUG("__MmsBinaryMsgBodyDecode: MmsBinaryDecodeMultipart is fail.\n");
1143                         goto __CATCH;
1144                 }
1145                 break;
1146
1147         default:
1148
1149                 /* Single part message ---------------------------------------------- */
1150
1151                 strcpy(mmsHeader.msgBody.szOrgFilePath, szFilePath);
1152
1153                 offset = _MmsGetDecodeOffset();
1154                 if (offset >= totalLength)
1155                         goto __RETURN;
1156
1157                 if (MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1158                         MSG_DEBUG("__MmsBinaryMsgBodyDecode: MmsBinaryDecodePartBody is fail.(Single Part)\n");
1159                         goto __CATCH;
1160                 }
1161
1162                 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1163                 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1164
1165                 break;
1166         }
1167
1168 #ifdef __SUPPORT_DRM__
1169         mmsHeader.drmType = MsgGetDRMType(&mmsHeader.msgType, &mmsHeader.msgBody);
1170 #endif
1171
1172 __RETURN:
1173
1174         return true;
1175
1176 __CATCH:
1177
1178         /* fixme: Delete multipart using MmsDeleteMsg() */
1179
1180         if (pMultipart) {
1181                 if (pMultipart->pBody) {
1182                         if (pMultipart->pBody->body.pText) {
1183                                 free(pMultipart->pBody->body.pText);
1184                                 pMultipart->pBody->body.pText = NULL;
1185                         }
1186
1187                         free(pMultipart->pBody);
1188                         pMultipart->pBody = NULL;
1189                 }
1190
1191                 free(pMultipart);
1192                 pMultipart = NULL;
1193         }
1194
1195         return false;
1196 }
1197
1198 #if MMS_ENABLE_EXTEND_CFM
1199 // DRM (Extended)CFM
1200 //      Get Extended CFM value.
1201 static bool __MmsConvertString2Bool(char *pszValue)
1202 {
1203         if (!strcasecmp(pszValue, "no"))
1204                 return true;
1205
1206         return false;
1207 }
1208 #endif
1209
1210 bool MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1211 {
1212         UINT8 oneByte = 0;
1213         int charSetLen = 0;
1214         char *szTypeString = NULL;
1215         char *szTypeValue = NULL;
1216         UINT8 paramCode = 0xff;
1217         UINT32 integer = 0;
1218         int intLen = 0;
1219         int length = 0;
1220         int textLength = 0;
1221
1222         /*
1223          * Parameter = Typed-parameter | Untyped-parameter
1224          * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1225          */
1226
1227         MSG_DEBUG("MmsBinaryDecodeParameter: \n");
1228
1229         while (valueLength > 0) {
1230                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1231                         MSG_DEBUG("MmsBinaryDecodeContentType: paramCode _MmsBinaryDecodeGetOneByte fail\n");
1232                         goto __CATCH;
1233                 }
1234
1235                 paramCode = oneByte;
1236                 valueLength--;
1237
1238                 switch (paramCode) {
1239                 case 0x81: // charset
1240
1241                         if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1242                                 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsBinaryDecodeCharset fail.\n");
1243                                 goto __CATCH;
1244                         }
1245
1246                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1247                                 goto __RETURN;
1248
1249                         break;
1250
1251                 case 0x85: //name = Text-string
1252                 case 0x97: //name = Text-value  = No-value | Token-text | Quoted-string
1253                         memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1254                         length = __MmsDecodeGetFilename(pFile,  pMsgType->param.szName,
1255                                                                                          MSG_FILENAME_LEN_MAX -5,               // MSG_LOCALE_FILENAME_LEN_MAX + 1, :  change @ 110(Ui code have to change for this instead of DM)
1256                                                                                          totalLength);
1257                         if (length < 0) {
1258                                 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsDecodeGetFilename fail. (name parameter)\n");
1259                                 goto __CATCH;
1260                         }
1261
1262                         if (MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1263                                 _MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1264                         }
1265
1266                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1267                                 goto __RETURN;
1268
1269                         break;
1270
1271                 case 0x86: //filename = Text-string
1272                 case 0x98: //filename = Text-value  = No-value | Token-text | Quoted-string
1273                         memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1274                         length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1275                         if (length < 0) {
1276                                 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsDecodeGetFilename fail. (filename parameter)\n");
1277                                 goto __CATCH;
1278                         }
1279
1280                         if (MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1281                                 _MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1282                         }
1283
1284                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1285                                 goto __RETURN;
1286
1287                         break;
1288
1289                 case 0x89: //type = Constrained-encoding = Extension-Media | Short-integer
1290
1291                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1292                                 MSG_DEBUG("MmsBinaryDecodeContentType: type _MmsBinaryDecodeGetOneByte fail\n");
1293                                 goto __CATCH;
1294                         }
1295
1296                         if (oneByte > 0x7f) {
1297                                 pMsgType->param.type = _MmsGetBinaryType(MmsCodeContentType,
1298                                                                                                                   (UINT16)(oneByte & 0x7f));
1299                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1300                                         goto __RETURN;
1301                         } else {
1302                                 gCurMmsDecodeBuffPos--;
1303
1304                                 textLength = 0;
1305                                 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1306                                 pMsgType->param.type = _MmsGetTextType(MmsCodeContentType, szTypeString);
1307
1308                                 if (szTypeString) {
1309                                         free(szTypeString);
1310                                         szTypeString = NULL;
1311                                 }
1312
1313                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1314                                         goto __RETURN;
1315                         }
1316
1317                         break;
1318
1319                 case 0x8A: //start encoding version 1.2
1320                 case 0x99: //start encoding version 1.4
1321
1322                         textLength       = 0;
1323                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1324                         if (szTypeString) {
1325                                 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1326                                 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1327                                 free(szTypeString);
1328                                 szTypeString = NULL;
1329
1330                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1331                                         goto __RETURN;
1332                         }
1333
1334                         break;
1335
1336                 case 0x8B: //startInfo encoding version 1.2
1337                 case 0x9A: //startInfo encoding version 1.4
1338
1339                         textLength       = 0;
1340                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1341
1342                         if (szTypeString) {
1343                                 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1344                                 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1345
1346                                 free(szTypeString);
1347                                 szTypeString = NULL;
1348
1349                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1350                                         goto __RETURN;
1351                         }
1352
1353                         break;
1354
1355                 default:
1356
1357                         if (paramCode > 0x7F) {
1358                                 MSG_DEBUG("MmsBinaryDecodeContentType: Unsupported parameter\n");
1359
1360                                 // In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value.
1361                                 valueLength++;
1362                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1363                                         goto __RETURN;
1364                         } else {
1365                                 /*
1366                                  * Untyped Parameter = Token-text Untyped-value
1367                                  * Token-text            = Token End-of-string
1368                                  * Untyped-value         = Integer-value | Text-value
1369                                  * Text-value            = No-value | Token-text | Quoted-string
1370                                  *
1371                                  * Just increase pointer!!!
1372                                  */
1373
1374
1375                                 /* Token-text */
1376
1377                                 gCurMmsDecodeBuffPos--;
1378                                 valueLength++;
1379
1380                                 textLength        = 0;
1381                                 szTypeString  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1382                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1383                                         goto __RETURN;
1384
1385
1386                                 /* Text-value */
1387
1388                                 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1389                                         MSG_DEBUG("MmsBinaryDecodeContentType: Unsupported parameter(%d)\n", integer);
1390                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1391                                                 goto __RETURN;
1392                                 } else {
1393                                         textLength        = 0;
1394                                         szTypeValue  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1395
1396                                         if (szTypeValue) {
1397                                                 /* checkMe:  forwardLock needs boudary string */
1398                                                 if (strcasecmp(szTypeString, "boundary") == 0) {
1399                                                         memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1400                                                         strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1401 #ifdef FEATURE_JAVA_MMS
1402                                                 } else if (strcasecmp(szTypeString, "Application-ID") == 0) {
1403                                                         pMsgType->param.szApplicationID = (char*) malloc(textLength + 1);
1404                                                         memset(pMsgType->param.szApplicationID,  0,  textLength + 1);
1405                                                         strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1406                                                         MSG_DEBUG("Application-ID:%s",pMsgType->param.szApplicationID);
1407                                                 } else if (strcasecmp(szTypeString,"Reply-To-Application-ID") == 0) {
1408                                                         pMsgType->param.szReplyToApplicationID= (char*) malloc(textLength + 1);
1409                                                         memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1410                                                         strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1411                                                         MSG_DEBUG("ReplyToApplication-ID:%s",pMsgType->param.szReplyToApplicationID);
1412 #endif
1413                                                 }
1414                                                 free(szTypeValue);
1415                                                 szTypeValue = NULL;
1416
1417                                                 MSG_DEBUG("MmsBinaryDecodeContentType: Unsupported parameter(%s)\n", szTypeValue);
1418                                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1419                                                         goto __RETURN;
1420                                         }
1421                                 }
1422
1423                                 if (szTypeString) {
1424                                         MSG_DEBUG("MmsBinaryDecodeContentType: Unsupported parameter(%s)\n", szTypeString);
1425                                         free(szTypeString);
1426                                         szTypeString = NULL;
1427                                 }
1428                         }
1429
1430                         break;
1431                 }
1432         }       /*end of while loop*/
1433
1434
1435 __RETURN:
1436
1437         if (szTypeString) {
1438                 free(szTypeString);
1439                 szTypeString = NULL;
1440         }
1441
1442         return true;
1443
1444 __CATCH:
1445
1446         if (szTypeString) {
1447                 free(szTypeString);
1448                 szTypeString = NULL;
1449         }
1450         return false;
1451 }
1452
1453
1454
1455 /**
1456  * Decode Encoded Content type
1457  *
1458  * @param       pEncodedData    [in] ContentType encoded data
1459  * @param       pMsgType                [out] Decoded MsgType
1460  * @return      Decoded address list
1461  */
1462 int MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1463 {
1464         UINT8 oneByte = 0;
1465         char *szTypeString = NULL;
1466         int valueLength = 0;
1467         int length = 0;
1468         int textLength = 0;
1469
1470
1471         /*
1472          * Content-type-value             : [WAPWSP 8.4.2.24]
1473          * Preassigned content-types  : [WAPWSP Appendix A, Table 40]
1474          * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1475          *
1476          * Content-type-value   = Constrained-media | Content-general-form
1477          * Content-general-form = Value-length Media-type
1478          * Media-type                   = (Well-known-media | Extension-Media) *(Parameter)
1479          */
1480
1481         MSG_DEBUG("MmsBinaryDecodeContentType: decoding content type..\n");
1482
1483
1484         length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1485         if (length <= 0) {
1486                 /*
1487                  * Constrained-media or Single part message
1488                  * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1489                  * Extension-media   = *TEXT End-of-string
1490                  * Short-integer     = OCTET(1xxx xxxx)
1491                  */
1492
1493                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1494                         MSG_DEBUG("MmsBinaryDecodeContentType: Constrained-media _MmsBinaryDecodeGetOneByte fail\n");
1495                         goto __CATCH;
1496                 }
1497
1498                 if (oneByte > 0x7F) {
1499                         /* Short-integer */
1500                         pMsgType->type = _MmsGetBinaryType(MmsCodeContentType, (UINT16)(oneByte & 0x7F));
1501                         length = 1;
1502                 } else {
1503                         char *pszTemp = NULL;
1504
1505                         /* Extension-Media */
1506                         gCurMmsDecodeBuffPos--;
1507
1508                         textLength = 0;
1509                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1510
1511                         if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1512                                 pszTemp = _MsgGetStringUntilDelimiter(szTypeString, ';');
1513                                 if (pszTemp) {
1514                                         free(szTypeString);
1515                                         szTypeString = pszTemp;
1516                                 }
1517                         }
1518
1519                         pMsgType->type = _MmsGetTextType(MmsCodeContentType, szTypeString);
1520
1521                         length = textLength;
1522
1523                         if (szTypeString) {
1524                                 free(szTypeString);
1525                                 szTypeString = NULL;
1526                         }
1527                 }
1528         } else {
1529                 /*
1530                  * Content-general-form = Value-length Media-type
1531                  * Media-type                   = (Well-known-media | Extension-Media)*(Parameter)
1532                  */
1533
1534                 length += valueLength;
1535
1536                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1537                         MSG_DEBUG("MmsBinaryDecodeContentType: Well-known-media _MmsBinaryDecodeGetOneByte fail\n");
1538                         goto __CATCH;
1539                 }
1540
1541                 if (oneByte > 0x7F) {
1542                         /* Well-known-media */
1543                         pMsgType->type = _MmsGetBinaryType(MmsCodeContentType, (UINT16)(oneByte & 0x7F));
1544                         valueLength--;
1545                 } else {
1546                         /* Extension-Media */
1547                         gCurMmsDecodeBuffPos--;
1548
1549                         textLength = 0;
1550                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1551                         pMsgType->type = _MmsGetTextType(MmsCodeContentType, szTypeString);
1552                         valueLength -= textLength;
1553
1554                         if (szTypeString) {
1555                                 free(szTypeString);
1556                                 szTypeString = NULL;
1557                         }
1558                 }
1559
1560                 MSG_DEBUG("MmsBinaryDecodeContentType: content type=%s\n", MmsDebugGetMimeType((MimeType)pMsgType->type));
1561
1562
1563                 if (MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1564                         MSG_DEBUG("MmsBinaryDecodeContentType: Content-Type parameter fail\n");
1565                         goto __CATCH;
1566                 }
1567         }
1568
1569         return length;
1570
1571 __CATCH:
1572         return -1;
1573 }
1574
1575
1576 bool MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1577 {
1578         UINT8 fieldCode = 0xff;
1579         int length = 0;
1580         UINT32 valueLength = 0;
1581         char *pCode = NULL;
1582         char *pValue = NULL;
1583         char *pParam = NULL;
1584         char ch = '\0';
1585         UINT8 oneByte = 0;
1586         int     textLength = 0;
1587         int tmpInt = 0;
1588         int tmpIntLen = 0;
1589         char *pLatinBuff = NULL;
1590         char *szSrc = NULL;
1591         char *szTemp = NULL;
1592
1593
1594         if (pFile == NULL || pMsgType == NULL)
1595                 return false;
1596
1597         /*
1598          * Message-header                         = Well-known-header | Application-header
1599          * Well-known-header              = Well-known-field-name Wap-value
1600          * Application-header             = Token-text Application-specific-value
1601          * Well-known-field-name          = Short-integer
1602          * Application-specific-value = Text-string
1603          */
1604
1605         while (headerLen > 0) {
1606                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1607                         MSG_DEBUG("MmsBinaryDecodePartHeader: field code GetOneByte fail\n");
1608                         goto __CATCH;
1609                 }
1610
1611                 if (0x80 <= oneByte && oneByte <= 0xC7) {
1612                         /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1613
1614                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1615                                 goto __RETURN;
1616
1617                         fieldCode = oneByte & 0x7f;
1618
1619                         switch (fieldCode) {
1620                         case 0x0E:      //Content-Location
1621                         case 0x04:      //Content-Location
1622
1623                                 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1624                                 if (pLatinBuff == NULL)
1625                                         goto __CATCH;
1626
1627                                 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1628                                 if (length == -1) {
1629                                         MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeQuotedString fail.\n");
1630                                         goto __CATCH;
1631                                 }
1632
1633                                 szSrc = MsgChangeHexString(pLatinBuff);
1634
1635                                 if (szSrc) {
1636                                         strcpy(pLatinBuff, szSrc);
1637                                         free(szSrc);
1638                                         szSrc = NULL;
1639                                 }
1640
1641                                 textLength = strlen(pLatinBuff);
1642
1643                                 if (MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, textLength) < 0) {
1644                                         MSG_DEBUG("MmsBinaryDecodePartHeader: MsgLatin2UTF fail \n");
1645                                         goto __CATCH;
1646                                 }
1647
1648                                 free(pLatinBuff);
1649                                 pLatinBuff = NULL;
1650
1651                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1652                                         goto __RETURN;
1653
1654                                 break;
1655
1656                         case 0x40:      // Content-ID
1657
1658                                 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1659                                 if (pLatinBuff == NULL)
1660                                         goto __CATCH;
1661
1662                                 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1663
1664                                 if (length == -1) {
1665                                         MSG_DEBUG("MmsBinaryDecodePartHeader : Content-ID __MmsBinaryDecodeQuotedString fail.\n");
1666                                         goto __CATCH;
1667                                 }
1668
1669                                 szSrc = MsgChangeHexString(pLatinBuff);
1670
1671                                 if (szSrc) {
1672                                         strcpy(pLatinBuff, szSrc);
1673                                         free(szSrc);
1674                                         szSrc = NULL;
1675                                 }
1676
1677                                 textLength = strlen(pLatinBuff);
1678                                 if (MsgLatin2UTF ((unsigned char*)pMsgType->szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, textLength) < 0) {
1679                                         MSG_DEBUG("MmsBinaryDecodePartHeader: MsgLatin2UTF fail \n");
1680                                         goto __CATCH;
1681                                 }
1682                                 free(pLatinBuff);
1683                                 pLatinBuff = NULL;
1684
1685                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1686                                         goto __RETURN;
1687
1688                                 break;
1689
1690                         case 0x2E:      // Content-Disposition
1691                         case 0x45:      // Content-Disposition
1692
1693                                 /*
1694                                  * Content-disposition-value = Value-length Disposition *(Parameter)
1695                                  * Disposition = Form-data | Attachment | Inline | Token-text
1696                                  *                               Form-data = <Octet 128> : 0x80
1697                                  *                               Attachment = <Octet 129> : 0x81
1698                                  *                               Inline = <Octet 130> : 0x82
1699                                  */
1700
1701                                 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1702
1703                                 if (length > 0) {
1704                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1705                                                 goto __RETURN;
1706
1707                                 }
1708
1709                                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1710                                         MSG_DEBUG("MmsBinaryDecodePartHeader: Disposition value GetOneByte fail\n");
1711                                         goto __CATCH;
1712                                 }
1713
1714                                 if (length > 0)
1715                                         valueLength--;
1716
1717                                 if (oneByte >= 0x80) {
1718                                         pMsgType->disposition = _MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1719
1720                                         if (pMsgType->disposition == INVALID_HOBJ) {
1721                                                 MSG_DEBUG("MmsBinaryDecodePartHeader : Content-Disposition _MmsGetBinaryType fail.\n");
1722                                                 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT;             // default
1723                                         }
1724
1725                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1726                                                 goto __RETURN;
1727
1728                                         if (MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1729                                                 MSG_DEBUG("MmsBinaryDecodePartHeader: Disposition parameter fail\n");
1730                                                 goto __CATCH;
1731                                         }
1732
1733                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1734                                                 goto __RETURN;
1735                                 } else {
1736
1737                                         gCurMmsDecodeBuffPos--;
1738                                         valueLength++;
1739
1740                                         pLatinBuff = (char *)malloc(MSG_FILENAME_LEN_MAX);
1741                                         memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1742
1743                                         textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1744
1745
1746                                         if (textLength < 0) {
1747                                                 MSG_DEBUG("MmsBinaryDecodePartHeader : Content-Disposition decodingfail. \n");
1748                                                 goto __CATCH;
1749                                         }
1750                                         free(pLatinBuff);
1751                                         pLatinBuff = NULL;
1752
1753                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1754                                                 goto __RETURN;
1755
1756                                         valueLength -= textLength;
1757
1758                                         if (MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false)
1759                                         {
1760                                                 MSG_DEBUG("MmsBinaryDecodePartHeader: Disposition parameter fail\n");
1761                                                 goto __CATCH;
1762                                         }
1763
1764                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1765                                                 goto __RETURN;
1766
1767                                 }
1768
1769                                 break;
1770
1771                         case 0x0B:      //Content-Encoding
1772
1773                                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1774                                         MSG_DEBUG("MmsBinaryDecodePartHeader: Disposition value GetOneByte fail\n");
1775                                         goto __CATCH;
1776                                 }
1777
1778                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1779                                         goto __RETURN;
1780
1781                                 break;
1782
1783                         case 0x0C:      //Content-Language
1784
1785                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1786                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1787                                                 goto __RETURN;
1788                                 } else {
1789                                         char* cTemp = NULL;
1790
1791                                         cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1792
1793                                         if (cTemp == NULL) {
1794                                                 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeText2 fail...\n");
1795                                                 goto __CATCH;
1796                                         }
1797
1798                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1799                                                 if (cTemp) {
1800                                                         free(cTemp);
1801                                                 }
1802                                                 goto __RETURN;
1803                                         }
1804
1805                                         if (cTemp)
1806                                                 free(cTemp);
1807                                 }
1808
1809                                 break;
1810
1811                         case 0x0D:      //Content-Length
1812
1813                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1814                                         MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeInteger fail...\n");
1815                                         goto __CATCH;
1816                                 }
1817
1818                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1819                                         goto __RETURN;
1820
1821                                 break;
1822
1823                         case 0x30:      //X-Wap-Content-URI skip this value
1824
1825                                 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header.\n");
1826                                 pLatinBuff = (char *)malloc(MMS_TEXT_LEN);
1827                                 if (pLatinBuff == NULL)
1828                                         goto __CATCH;
1829
1830                                 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1831
1832                                 if (length == -1) {
1833                                         MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeQuotedString fail.\n");
1834                                         goto __CATCH;
1835                                 }
1836
1837                                 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header decoded. Value length %d\n", length);
1838                                 free(pLatinBuff);
1839                                 pLatinBuff = NULL;
1840
1841                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1842                                         goto __RETURN;
1843
1844                                 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header skipped.\n");
1845
1846                                 break;
1847
1848                         case 0x01:      // Accept-charset
1849                                 //if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1)
1850                                 {
1851                                         /*      WAP-230-WSP-200010705-a.pdf
1852                                                 8.4.2.8 Accept charset field
1853                                                 The following rules are used to encode accept character set values.
1854                                                 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1855                                                 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1856                                                 Constrained-charset = Any-charset | Constrained-encoding
1857                                                 Well-known-charset = Any-charset | Integer-value
1858                                                 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1859                                                 Any-charset = <Octet 128>
1860                                                 ; Equivalent to the special RFC2616 charset value Â¡Â°*¡±
1861                                         */
1862
1863                                         int     charset = 0;
1864                                         int charSetLen = 0;
1865
1866                                         MSG_DEBUG("MmsBinaryDecodePartHeader : Accept-charset. \n");
1867
1868                                         length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1869                                         if (length > 0) {
1870                                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1871                                                         goto __RETURN;
1872
1873                                         }
1874
1875                                         if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1876                                                 // We only support the well-known-charset format
1877                                                 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeInteger fail...\n");
1878                                                 goto __CATCH;
1879                                         }
1880
1881                                         if (charset > 0)
1882                                                 _MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1883
1884                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1885                                                 goto __RETURN;
1886
1887                                         break;
1888                                 }
1889
1890                         default:
1891
1892                                 /* Other Content-xxx headers : Have valueLength */
1893
1894                                 MSG_DEBUG("MmsBinaryDecodePartHeader : unknown Value = 0x%x\n", oneByte);
1895
1896                                 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1897                                 if (length <= 0) {
1898                                         MSG_DEBUG("MmsBinaryDecodePartHeader : 1. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
1899                                         goto __CATCH;
1900                                 }
1901
1902                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1903                                         goto __RETURN;
1904
1905                                 szTemp = (char *)malloc(valueLength);
1906                                 if (szTemp == NULL)
1907                                         goto __CATCH;
1908
1909                                 if (_MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) < 0) {
1910                                         MSG_DEBUG("MmsBinaryDecodePartHeader : default _MmsBinaryDecodeGetBytes() fail\n");
1911                                         if (szTemp) {
1912                                                 free(szTemp);
1913                                                 szTemp = NULL;
1914                                         }
1915                                         goto __CATCH;
1916                                 }
1917
1918                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1919                                         goto __RETURN;
1920
1921                                 break;
1922                         }
1923                 } else {
1924                         /*
1925                          * Application-header  = Token-text Application-specific-value
1926                          * Application-specific-value = Text-string
1927                          */
1928
1929                         MSG_DEBUG(" MmsBinaryDecodePartHeader: Application-header = Token-text Application-specific-value \n");
1930
1931                         gCurMmsDecodeBuffPos--;
1932
1933                         /* Token-text */
1934
1935                         textLength = 0;
1936                         pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1937                         if (pCode == NULL) {
1938                                 MSG_DEBUG("MmsBinaryDecodePartHeader: pCode is null\n");
1939                                 goto __CATCH;
1940                         }
1941
1942                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1943                                 goto __RETURN;
1944
1945                         MSG_DEBUG(" MmsBinaryDecodePartHeader: Token-text (%s) \n", pCode);
1946
1947
1948                         /* Application-specific-value */
1949
1950                         textLength = 0;
1951                         pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1952                         if (pValue == NULL) {
1953                                 MSG_DEBUG("MmsBinaryDecodePartHeader: pValue is null\n");
1954                                 goto __CATCH;
1955                         }
1956
1957                         MSG_DEBUG(" MmsBinaryDecodePartHeader: Application-specific-value (%s) \n", pValue);
1958
1959
1960                         pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1961                         if (pParam) {
1962                                 ch = *pParam;
1963                                 *pParam = '\0';
1964                         }
1965
1966                         switch (_MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1967                         case MMS_BODYHDR_TRANSFERENCODING:              // Content-Transfer-Encoding
1968                                 pMsgType->encoding = _MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1969                                 break;
1970
1971                         case MMS_BODYHDR_CONTENTID:                             // Content-ID
1972
1973                                 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1974                                 if (pLatinBuff == NULL)
1975                                 {
1976                                         goto __CATCH;
1977                                 }
1978
1979                                 MsgMIMERemoveQuote (pValue);
1980                                 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1981
1982                                 length = strlen(pLatinBuff);
1983                                 if (MsgLatin2UTF ((unsigned char*)pMsgType->szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0)
1984                                 {
1985                                         MSG_DEBUG("MmsBinaryDecodePartHeader: MsgLatin2UTF fail \n");
1986                                         goto __CATCH;
1987                                 }
1988
1989                                 free(pLatinBuff);
1990                                 pLatinBuff = NULL;
1991                                 break;
1992
1993                         case MMS_BODYHDR_CONTENTLOCATION:               // Content-Location
1994
1995                                 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1996                                 if (pLatinBuff == NULL)
1997                                         goto __CATCH;
1998
1999                                 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
2000
2001                                 length = strlen(pLatinBuff);
2002                                 if (MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
2003                                         MSG_DEBUG("MmsBinaryDecodePartHeader: MsgLatin2UTF fail \n");
2004                                         goto __CATCH;
2005                                 }
2006
2007                                 free(pLatinBuff);
2008                                 pLatinBuff = NULL;
2009                                 break;
2010
2011                         case MMS_BODYHDR_DISPOSITION:                   // Content-Disposition
2012                                 pMsgType->disposition = _MmsGetTextType(MmsCodeMsgDisposition, pValue);
2013                                 break;
2014
2015                         case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY:   // DRM RO WAITING
2016                                         break;
2017
2018                         default:
2019                                 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
2020                                 break;
2021                         }
2022
2023                         if (pParam) {
2024                                 _MsgParseParameter(pMsgType, pParam + 1);
2025                                 *pParam = ch;
2026                         }
2027                         if (pCode) {
2028                                 free(pCode);
2029                                 pCode = NULL;
2030                         }
2031                         if (pValue) {
2032                                 free(pValue);
2033                                 pValue = NULL;
2034                         }
2035
2036                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2037                                 goto __RETURN;
2038
2039                 }
2040         }       //while
2041
2042 __RETURN:
2043
2044         if (pLatinBuff) {
2045                 free(pLatinBuff);
2046                 pLatinBuff = NULL;
2047         }
2048
2049         if (szTemp) {
2050                 free(szTemp);
2051                 szTemp = NULL;
2052         }
2053
2054         if (pCode) {
2055                 free(pCode);
2056                 pCode = NULL;
2057         }
2058
2059         return true;
2060
2061 __CATCH:
2062
2063         if (pLatinBuff) {
2064                 free(pLatinBuff);
2065                 pLatinBuff = NULL;
2066         }
2067         if (pCode) {
2068                 free(pCode);
2069                 pCode = NULL;
2070         }
2071         if (pValue) {
2072                 free(pValue);
2073                 pValue = NULL;
2074         }
2075
2076         if (szTemp) {
2077                 free(szTemp);
2078                 szTemp = NULL;
2079         }
2080
2081         return false;
2082 }
2083
2084
2085 bool MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2086 {
2087         int length = 0;
2088
2089         length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2090         if (length <= 0) {
2091                 goto __CATCH;
2092         }
2093
2094         MSG_DEBUG("MmsBinaryDecodeEntries: Number of Entries = %d\n", *npEntries);
2095
2096         return true;
2097
2098 __CATCH:
2099         return false;
2100 }
2101
2102
2103
2104 bool MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2105 {
2106         int offset = 0;
2107
2108         /*
2109          * Currently, offset and size is
2110          * the only information used with msgBody.
2111          * If you need, add here more information
2112          */
2113
2114         MSG_DEBUG("MmsBinaryDecodePartBody: \n");
2115
2116         offset = _MmsGetDecodeOffset();
2117         offset += bodyLength;
2118
2119         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2120                 MSG_DEBUG("MmsBinaryDecodePartBody: fail to seek file pointer \n");
2121                 goto __CATCH;
2122         }
2123
2124         _MmsCleanDecodeBuff();
2125
2126         gMmsDecodeCurOffset = offset;
2127
2128         if (offset >= totalLength)
2129                 goto __RETURN;
2130
2131         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2132                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2133                 MSG_DEBUG("_MmsBinaryDecodeGetOneByte: fail to load to buffer \n");
2134                 goto __CATCH;
2135         }
2136
2137         return true;
2138
2139 __RETURN:
2140         return true;
2141
2142 __CATCH:
2143         return false;
2144 }
2145
2146
2147 static bool MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2148 {
2149         if (offset > totalLength)
2150                 goto __RETURN;
2151
2152         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2153                 MSG_DEBUG("MmsBinaryDecodeMovePointer: fail to seek file pointer \n");
2154                 goto __CATCH;
2155         }
2156
2157         _MmsCleanDecodeBuff();
2158
2159         gMmsDecodeCurOffset = offset;
2160
2161         if (offset == totalLength)
2162                 goto __RETURN;
2163
2164         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2165                                                                         gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2166                 MSG_DEBUG("MmsBinaryDecodeMovePointer: fail to load to buffer \n");
2167                 goto __CATCH;
2168         }
2169
2170 __RETURN:
2171         return true;
2172
2173 __CATCH:
2174         return false;
2175 }
2176
2177
2178 bool MmsBinaryIsTextEncodedPart(FILE *pFile, int totalLength)
2179 {
2180         UINT8 oneByte   = 0;
2181         int byteCount = 0;
2182
2183         byteCount++;                            //check 0x0D
2184
2185         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2186                 goto __CATCH;
2187
2188         if (oneByte != 0x0D) {
2189                 //it can be started "--" without 0x0D 0x0A
2190                 if (oneByte != 0x2D) {
2191                         goto __CATCH;
2192                 } else {
2193                         byteCount++;            // check 0x2D ('-')
2194                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2195                                 goto __CATCH;
2196
2197                         if (oneByte != 0x2D) {
2198                                 goto __CATCH;
2199                         } else {
2200                                 goto __RETURN;
2201                         }
2202                 }
2203         } else {
2204                 byteCount++;                    //check 0x0A
2205                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2206                         goto __CATCH;
2207
2208                 if (oneByte != 0x0A) {
2209                         goto __CATCH;
2210                 } else {
2211                         byteCount++;            // check 0x2D ('-')
2212                         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2213                                 goto __CATCH;
2214
2215                         if (oneByte != 0x2D) {
2216                                 goto __CATCH;
2217                         } else {
2218                                 byteCount++;    // check 0x2D ('-')
2219                                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2220                                         goto __CATCH;
2221
2222                                 if (oneByte != 0x2D) {
2223                                         goto __CATCH;
2224                                 } else {
2225                                         goto __RETURN;
2226                                 }
2227                         }
2228                 }
2229         }
2230
2231 __RETURN:
2232         gCurMmsDecodeBuffPos -= byteCount;
2233         return true;
2234
2235 __CATCH:
2236         gCurMmsDecodeBuffPos -= byteCount;
2237         return false;
2238 }
2239
2240
2241 bool MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2242 {
2243         UINT32 nEntries = 0;
2244         MsgMultipart *pMultipart = NULL;
2245         MsgMultipart *pLastMultipart = NULL;
2246         MsgMultipart *pPreMultipart     = NULL;
2247         int offset = 0;
2248         int     index = 0;
2249
2250         MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2251         MsgPresentaionInfo presentationInfo;
2252
2253         MSG_DEBUG("MmsBinaryDecodeMultipart: total length=%d\n", totalLength);
2254
2255         presentationInfo.factor = MSG_PRESENTATION_NONE;
2256         presentationInfo.pCurPresentation = NULL;
2257         presentationInfo.pPrevPart = NULL;
2258
2259         if (MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2260                 MSG_DEBUG("MmsBinaryDecodeMultipart: MmsBinaryDecodeEntries is fail.\n");
2261                 goto __CATCH;
2262         }
2263
2264         while (nEntries) {
2265                 MSG_DEBUG("MmsBinaryDecodeMultipart: decoding %dth multipart\n", index);
2266
2267                 offset = _MmsGetDecodeOffset();
2268                 if (offset >= totalLength)
2269                         goto __RETURN;
2270
2271                 if ((pMultipart = MsgAllocMultipart()) == NULL) {
2272                         MSG_DEBUG("MmsBinaryDecodeMultipart: MsgAllocMultipart Fail \n");
2273                         goto __CATCH;
2274                 }
2275
2276                 if (MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2277                         MSG_DEBUG("MmsBinaryDecodeMultipart: MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2278                         goto __CATCH;
2279                 }
2280
2281                 if (pMsgType->param.type == MIME_APPLICATION_SMIL) {
2282                         factor = MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2283                 } else {
2284                         factor = MSG_PRESENTATION_NONE;
2285                 }
2286                 // priority 1 : content type match, 2: content location, 3: type
2287                 if (presentationInfo.factor < factor) {
2288                         // Presentation part
2289                         presentationInfo.factor = factor;
2290                         presentationInfo.pPrevPart = pPreMultipart;
2291                         presentationInfo.pCurPresentation = pMultipart;
2292                 }
2293
2294                 if (pMsgBody->body.pMultipart == NULL) {
2295                         /* first multipart */
2296                         pMsgBody->body.pMultipart = pMultipart;
2297                         pLastMultipart                    = pMultipart;
2298                         pPreMultipart                     = NULL;
2299                 } else if (pLastMultipart != NULL) {
2300                         pPreMultipart = pLastMultipart;
2301
2302                         pLastMultipart->pNext   = pMultipart;
2303                         pLastMultipart                  = pMultipart;
2304                 }
2305
2306                 pMsgType->contentSize += pMultipart->pBody->size;
2307
2308                 nEntries--;
2309                 pPreMultipart = pMultipart;
2310                 MmsDebugPrintMulitpartEntry(pMultipart, index++);
2311
2312         }
2313
2314         pMsgBody->size = totalLength - pMsgBody->offset;
2315
2316 #ifdef  __SUPPORT_DRM__
2317         if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_REQUIRED)
2318 #endif
2319                 MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2320
2321         if (MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2322                 MSG_DEBUG("MmsBinaryDecodeMultipart : MsgResolveNestedMultipart failed \n");
2323                 goto __CATCH;
2324         }
2325
2326 __RETURN:
2327         return true;
2328
2329 __CATCH:
2330         return false;
2331 }
2332
2333
2334 bool MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2335 {
2336         int     length = 0;
2337         bool bSuccess = false;
2338         UINT32 headerLength = 0;
2339         UINT32 bodyLength = 0;
2340         int offset = 0;
2341
2342         MSG_DEBUG("MmsBinaryDecodeEachPart: total length=%d\n", totalLength);
2343
2344         /* header length */
2345
2346         if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2347                 MSG_DEBUG("MmsBinaryDecodeEachPart: Get header length fail \n");
2348                 goto __CATCH;
2349         }
2350
2351         offset = _MmsGetDecodeOffset();
2352         if (offset >= totalLength)
2353                 goto __RETURN;
2354
2355
2356         /* body length */
2357
2358         if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2359                 MSG_DEBUG("MmsBinaryDecodeEachPart: Get body length fail\n");
2360                 goto __CATCH;
2361         }
2362
2363
2364         offset = _MmsGetDecodeOffset();
2365         if (offset >= totalLength)
2366                 goto __RETURN;
2367
2368
2369         /* Content Type */
2370         if (szFilePath != NULL)
2371                 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2372
2373         pMsgType->offset = _MmsGetDecodeOffset();
2374         pMsgType->size = headerLength;
2375         pMsgType->contentSize = bodyLength;
2376
2377         if (pMsgType->offset > totalLength)
2378                 goto __RETURN;
2379
2380         length = MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2381         if (length <= 0) {
2382                 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentType Fail \n");
2383                 goto __CATCH;
2384         }
2385
2386         offset = _MmsGetDecodeOffset();
2387         if (offset >= totalLength)
2388                 goto __RETURN;
2389
2390
2391         /* Part Header */
2392
2393         if (MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2394                 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentHeader Fail \n");
2395                 goto __CATCH;
2396         }
2397
2398         offset = _MmsGetDecodeOffset();
2399         if (offset >= totalLength)
2400                 goto __RETURN;
2401
2402         /* Part Body */
2403
2404         if (szFilePath != NULL)
2405                 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2406
2407         pMsgBody->offset = _MmsGetDecodeOffset();
2408         pMsgBody->size   = bodyLength;
2409
2410         if (pMsgBody->offset > totalLength)
2411                 goto __RETURN;
2412
2413         switch (pMsgType->type) {
2414         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2415         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2416         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2417         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2418         case MIME_MULTIPART_REPORT:
2419         case MIME_MULTIPART_MIXED:
2420         case MIME_MULTIPART_RELATED:
2421         case MIME_MULTIPART_ALTERNATIVE:
2422
2423                 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode multipart\n");
2424
2425                 if (MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2426                         MSG_DEBUG("MmsBinaryDecodeEachPart: MmsBinaryDecodeMultipart is fail.\n");
2427                         goto __CATCH;
2428                 }
2429
2430                 offset = _MmsGetDecodeOffset();
2431                 if (offset >= totalLength)
2432                         goto __RETURN;
2433
2434                 break;
2435
2436
2437 #ifdef __SUPPORT_DRM__
2438
2439         case MIME_APPLICATION_VND_OMA_DRM_MESSAGE: /* Contains forwardLock OR combined-delivery media part */
2440                 MSG_DEBUG("MmsBinaryDecodeEachPart: MIME_APPLICATION_VND_OMA_DRM_MESSAGE Part \n");
2441
2442                 if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_NOT_FIXED && MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_REQUIRED) {
2443
2444                         if (MmsBinaryDecodeDRMContent(pFile, szFilePath, pMsgType, pMsgBody, bodyLength, totalLength) == false)
2445                                 goto __CATCH;
2446                 } else {
2447                         MmsDrm2SetConvertState(MMS_DRM2_CONVERT_REQUIRED);
2448
2449                         bSuccess = MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2450                         if (bSuccess == false) {
2451                                 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentBody Fail \n");
2452                                 goto __CATCH;
2453                         }
2454                 }
2455                 offset = _MmsGetDecodeOffset();
2456                 if (offset >= totalLength)
2457                         goto __RETURN;
2458
2459                 break;
2460
2461         case MIME_APPLICATION_VND_OMA_DRM_CONTENT: /* Contains seperate-delivery media part (DCF) */
2462
2463                 MSG_DEBUG("MmsBinaryDecodeEachPart: MIME_APPLICATION_VND_OMA_DRM_CONTENT Part \n");
2464
2465                 if (MmsBinaryDecodeDRMContent(pFile, szFilePath, pMsgType, pMsgBody, bodyLength, totalLength) == false)
2466                         goto __CATCH;
2467
2468                 offset = _MmsGetDecodeOffset();
2469                 if (offset >= totalLength)
2470                         goto __RETURN;
2471
2472                 break;
2473 #endif
2474
2475         default:
2476                 MSG_DEBUG("MmsBinaryDecodeEachPart: Other normal Part \n");
2477
2478                 bSuccess = MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2479                 if (bSuccess == false) {
2480                         MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentBody Fail \n");
2481                         goto __CATCH;
2482                 }
2483
2484                 offset = _MmsGetDecodeOffset();
2485                 if (offset >= totalLength)
2486                         goto __RETURN;
2487
2488                 break;
2489         }
2490
2491         return true;
2492
2493 __RETURN:
2494
2495         return true;
2496
2497 __CATCH:
2498
2499         return false;
2500 }
2501
2502 #ifdef __SUPPORT_DRM__
2503 bool __MmsParseDCFInfo(FILE *pFile, MsgDRMInfo *pDrmInfo, int totalLength)
2504 {
2505         UINT8 version = 0;
2506         UINT8 contentTypeLen = 0;
2507         UINT8 contentURILen = 0;
2508         char *szContentType     = NULL;
2509         char *szContentURI = NULL;
2510
2511         if (_MmsBinaryDecodeGetOneByte(pFile, &version, totalLength) == false) {
2512                 MSG_DEBUG("__MmsParseDCFInfo: [version] GetOneByte fail\n");
2513                 goto __CATCH;
2514         }
2515
2516         if (_MmsBinaryDecodeGetOneByte(pFile, &contentTypeLen, totalLength) == false) {
2517                 MSG_DEBUG("__MmsParseDCFInfo: [contentTypeLen] GetOneByte fail\n");
2518                 goto __CATCH;
2519         }
2520
2521         if (_MmsBinaryDecodeGetOneByte(pFile, &contentURILen, totalLength) == false) {
2522                 MSG_DEBUG("__MmsParseDCFInfo: [contentURILen] GetOneByte fail\n");
2523                 goto __CATCH;
2524         }
2525
2526         //Get media content-type (mime-type)
2527         szContentType = (char *)malloc(contentTypeLen + 1);
2528         if (szContentType == NULL)
2529                 goto __CATCH;
2530
2531         memset(szContentType, 0, contentTypeLen + 1);
2532
2533         if (_MmsBinaryDecodeGetBytes(pFile, szContentType, contentTypeLen + 1, totalLength) < 0) {
2534                 MSG_DEBUG("__MmsParseDCFInfo : contentType is invalid\n");
2535                 goto __CATCH;
2536         }
2537         gCurMmsDecodeBuffPos--;
2538         pDrmInfo->contentType = (MsgContentType)_MsgGetCode(MSG_TYPE, szContentType);
2539
2540
2541         //Get content-ID - 1.remover "cid:",   2.resolve "%hexa",   3.and copy the string
2542         szContentURI = (char *)malloc(contentURILen + 1);
2543         if (szContentURI == NULL)
2544                 goto __CATCH;
2545
2546         memset(szContentURI, 0, contentURILen + 1);
2547
2548         if (_MmsBinaryDecodeGetBytes(pFile, szContentURI, contentURILen + 1, totalLength) < 0) {
2549                 MSG_DEBUG("__MmsParseDCFInfo : contentType is invalid\n");
2550                 goto __CATCH;
2551         }
2552         gCurMmsDecodeBuffPos--;
2553         pDrmInfo->szContentURI = MsgResolveContentURI(szContentURI);
2554
2555
2556         if (szContentType) {
2557                 free(szContentType);
2558                 szContentType = NULL;
2559         }
2560
2561         if (szContentURI) {
2562                 free(szContentURI);
2563                 szContentURI = NULL;
2564         }
2565         return true;
2566
2567
2568 __CATCH:
2569
2570         if (szContentType) {
2571                 free(szContentType);
2572                 szContentType = NULL;
2573         }
2574
2575         if (szContentURI) {
2576                 free(szContentURI);
2577                 szContentURI = NULL;
2578         }
2579         return false;
2580
2581 }
2582
2583
2584 bool __MmsParseDCFHdr(FILE *pFile, MsgDRMInfo *pDrmInfo, UINT32 headerLen, int totalLength)
2585 {
2586         char *szDCFHdr = NULL;
2587         MsgType partType;
2588         ULONG nRead = 0;
2589         int offset = 0;
2590
2591         /* add to parse DCF header such as,
2592          *  Right-Issuer, Content-Name, and Content-Description.
2593          */
2594
2595         szDCFHdr = (char *)malloc(headerLen + 1);
2596         if (szDCFHdr == NULL) {
2597                 MSG_DEBUG("__MmsParseDCFHdr: szDCFHdr alloc fail\n");
2598                 goto __CATCH;
2599         }
2600         memset(szDCFHdr, 0, headerLen + 1);
2601
2602         offset = _MmsGetDecodeOffset();
2603         if (offset >= totalLength)
2604                 goto __RETURN;
2605
2606         if (MsgFseek(pFile, offset, SEEK_SET) < 0)
2607                 goto __CATCH;
2608
2609         if ((nRead = MsgReadFile(szDCFHdr, sizeof(char), headerLen, pFile)) == 0){
2610                 goto __CATCH;
2611         }
2612         szDCFHdr[nRead] = '\0';
2613
2614         _MsgInitMsgType(&partType);
2615         _MsgParsePartHeader(&partType, szDCFHdr, headerLen);
2616
2617         pDrmInfo->szContentName = partType.drmInfo.szContentName;
2618         pDrmInfo->szContentVendor = partType.drmInfo.szContentVendor;
2619         pDrmInfo->szContentDescription = partType.drmInfo.szContentDescription;
2620         pDrmInfo->szRightIssuer = partType.drmInfo.szRightIssuer;
2621
2622         if (MmsBinaryDecodeMovePointer(pFile, offset + headerLen, totalLength) == false)
2623                 goto __CATCH;
2624
2625 __RETURN:
2626
2627         if (szDCFHdr) {
2628                 free(szDCFHdr);
2629                 szDCFHdr = NULL;
2630         }
2631
2632         return true;
2633
2634 __CATCH:
2635
2636         if (szDCFHdr) {
2637                 free(szDCFHdr);
2638                 szDCFHdr = NULL;
2639         }
2640
2641         return false;
2642 }
2643
2644
2645 bool MmsBinaryDecodeDRMContent(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int bodyLength, int totalLength)
2646 {
2647         int offset = 0;
2648         char szTempFilePath[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"drm.dcf";
2649         char *pRawData = NULL;
2650         bool isFileCreated = false;
2651
2652         MSG_DEBUG("bodyLength: %d\n", bodyLength);
2653
2654         offset = _MmsGetDecodeOffset();
2655
2656         if (offset >= totalLength)
2657                 goto __RETURN;
2658
2659         if (szFilePath != NULL)
2660                 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2661         if (szFilePath != NULL)
2662                 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2663
2664         pRawData = (char *)malloc(bodyLength);
2665         if (pRawData == NULL) {
2666                 MSG_DEBUG("pRawData alloc FAIL \n");
2667                 goto __CATCH;
2668         }
2669
2670         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2671                 MSG_DEBUG("MsgFseek() returns -1 \n");
2672                 goto __CATCH;
2673         }
2674         if (MsgReadFile(pRawData, sizeof(char), bodyLength, pFile) != (size_t)bodyLength) {
2675                 MSG_DEBUG("FmReadFile() returns false \n");
2676                 goto __CATCH;
2677         }
2678         if (MsgOpenCreateAndOverwriteFile(szTempFilePath, pRawData, bodyLength) == false) {
2679                 MSG_DEBUG("MsgOpenCreateAndOverwriteFile() returns false \n");
2680                 goto __CATCH;
2681         }
2682
2683         isFileCreated = true;
2684         MSG_DEBUG("MmsDrm2GetConvertState() [%d]", MmsDrm2GetConvertState());
2685
2686         if (pMsgType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE && (MmsDrm2GetConvertState()!=MMS_DRM2_CONVERT_FINISH)) {
2687                 MmsDrm2SetConvertState(MMS_DRM2_CONVERT_REQUIRED);
2688         } else {
2689                 if (MsgDRM2GetDRMInfo(szTempFilePath, pMsgType) == false) {
2690                         MSG_DEBUG("MsgDRM2GetDRMInfo() returns false \n");
2691                         goto __CATCH;
2692                 }
2693         }
2694
2695         remove(szTempFilePath);
2696         isFileCreated = false;
2697
2698         if (MmsBinaryDecodeMovePointer(pFile, offset + bodyLength, totalLength) == false)
2699                 goto __CATCH;
2700
2701 __RETURN:
2702
2703         if (pRawData) {
2704                 free(pRawData);
2705                 pRawData = NULL;
2706         }
2707
2708         return true;
2709
2710 __CATCH:
2711         if (isFileCreated)
2712                 remove(szTempFilePath);
2713
2714         if (pRawData) {
2715                 free(pRawData);
2716                 pRawData = NULL;
2717         }
2718
2719         return false;
2720 }
2721
2722
2723 bool MmsBinaryDecodeDRMMessage(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int fullBodyLength, int totalLength)
2724 {
2725         int offset = 0;
2726         char szTempFilePath[MSG_FILEPATH_LEN_MAX] = "/User/Msg/Mms/Temp/drm.dm";
2727         char *pRawData = NULL;
2728         bool isFileCreated = false;
2729
2730         offset = _MmsGetDecodeOffset();
2731         if (offset >= totalLength)
2732                 goto __RETURN;
2733
2734         if (szFilePath != NULL)
2735                 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2736         if (szFilePath != NULL)
2737                 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2738
2739         pRawData = (char *)malloc(fullBodyLength);
2740         if (pRawData == NULL) {
2741                 MSG_DEBUG("pRawData alloc FAIL \n");
2742                 goto __CATCH;
2743         }
2744
2745         if (MsgFseek(pFile, offset,  SEEK_SET) < 0) {
2746                 MSG_DEBUG("MsgFseek() returns -1 \n");
2747                 goto __CATCH;
2748         }
2749
2750         if (MsgReadFile(pRawData, sizeof(char), fullBodyLength, pFile)!= (size_t)fullBodyLength) {
2751                 MSG_DEBUG("FmReadFile() returns false \n");
2752                 goto __CATCH;
2753         }
2754
2755         if (MsgOpenCreateAndOverwriteFile(szTempFilePath, pRawData, fullBodyLength) == false) {
2756                 MSG_DEBUG("MsgOpenCreateAndOverwriteFile() returns false \n");
2757                 goto __CATCH;
2758         }
2759         isFileCreated = true;
2760
2761         if (strstr(szTempFilePath, ".dm")) {
2762                 char szConvertedFilePath[MSG_FILEPATH_LEN_MAX] = {0,};
2763
2764                 if (MsgDrmConvertDmtoDcfType(szTempFilePath, szConvertedFilePath)) {
2765                         remove(szTempFilePath);
2766                         memset(szTempFilePath, 0, MSG_FILEPATH_LEN_MAX);
2767                         strncpy(szTempFilePath, szConvertedFilePath, MSG_FILEPATH_LEN_MAX-1);
2768                 }
2769         }
2770
2771         if (MsgDRM2GetDRMInfo(szTempFilePath, pMsgType) == false) {
2772                 MSG_DEBUG("MsgDRM2GetDRMInfo() returns false \n");
2773                 goto __CATCH;
2774         }
2775
2776         remove(szTempFilePath);
2777         isFileCreated = false;
2778
2779         if (MmsBinaryDecodeMovePointer(pFile, offset + fullBodyLength, totalLength) == false)
2780                 goto __CATCH;
2781
2782 __RETURN:
2783
2784         if (pRawData) {
2785                 free(pRawData);
2786                 pRawData = NULL;
2787         }
2788         return true;
2789
2790 __CATCH:
2791         if (isFileCreated)
2792                 remove(szTempFilePath);
2793
2794         if (pRawData) {
2795                 free(pRawData);
2796                 pRawData = NULL;
2797         }
2798         return false;
2799 }
2800
2801 static int __MmsDrm2BinaryEncodeUintvarLen(UINT32 integer)
2802 {
2803         UINT32 length   = 0;
2804
2805         /* Find encoded unitvar length */
2806         if (integer  <= MMS_UINTVAR_LENGTH_1) {
2807                 length = 1;
2808         } else {
2809                 if (integer <= MMS_UINTVAR_LENGTH_2) {
2810                         length = 2;
2811                 } else {
2812                         if (integer <= MMS_UINTVAR_LENGTH_3) {
2813                                 length = 3;
2814                         } else {
2815                                 length = 4;
2816                         }
2817                 }
2818         }
2819
2820         return length;
2821 }
2822
2823
2824 static bool __MmsDrm2BinaryEncodeUintvar(UINT32 integer, int length, char *pszOutput)
2825 {
2826         const char ZERO = 0x00;
2827         int i = 2;
2828         char szReverse[MSG_STDSTR_LONG] = {0, };
2829
2830         union {
2831                 UINT32 integer;
2832                 char bytes[4];
2833         } source;
2834         source.integer = integer;
2835         memset(szReverse, 0, MSG_STDSTR_LONG);
2836
2837         /* Seperate integer to 4 1 byte integer */
2838         szReverse[3] = source.bytes[3] & 0x0f;
2839         szReverse[0] = source.bytes[0];
2840         szReverse[0] = szReverse[0] & 0x7f;
2841
2842         while (length >= i) {// initially, i = 2
2843                 /* Move integer bit to proper position */
2844                 source.integer = source.integer << 1;
2845                 source.integer = source.integer >> 8;
2846                 source.bytes[3] = ZERO;
2847
2848                 /* Retrive 1 encode uintvar */
2849                 szReverse[i-1] = source.bytes[0];
2850                 szReverse[i-1] = szReverse[i-1] | 0x80;
2851                 i++;
2852         }
2853
2854         for (i=0; i < length; i++)
2855                 pszOutput[i] = szReverse[length - i - 1];
2856
2857         return true;
2858 }
2859
2860
2861 static int __MmsDrm2GetEntriesValueLength(FILE *pFile, int orgOffset)
2862 {
2863         char szEntries[5] = {0, };
2864         UINT8 oneByte   = 0;
2865         int j = 0;                      //j is the length of nEntries value
2866
2867         if (MsgReadFile(szEntries, sizeof(char), 4, pFile) != (size_t)4) {
2868                 MSG_DEBUG("__MmsDrm2GetEntriesValueLength: FmReadFile() returns false \n");
2869                 return false;
2870         }
2871
2872         while (true) {
2873                 oneByte = szEntries[j++];
2874
2875                 if (oneByte <= 0x7f)
2876                         break;
2877         }
2878
2879         //move file pointer to point nEntries
2880         if (MsgFseek(pFile, orgOffset, SEEK_SET) < 0) {
2881                 MSG_DEBUG("__MmsDrm2GetEntriesValueLength: fail to seek file pointer\n");
2882                 return false;
2883         }
2884
2885         return j;
2886 }
2887
2888
2889 static bool __MmsDrm2WriteDataToConvertedFile(FILE *pSrcFile, FILE *pDestinationFile, char *pszMmsLoadTempBuf, int length, int bufLen)
2890 {
2891         int loadLen = 0, totalLoadLen = 0, nRead = 0;
2892
2893         for (int i=0; i<(length/bufLen)+1; i++) {
2894                 loadLen = (length-totalLoadLen < bufLen) ? length-totalLoadLen : bufLen;
2895
2896                 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2897
2898                 if (MsgReadFile(pszMmsLoadTempBuf, sizeof(char), loadLen, pSrcFile) != (size_t)loadLen) {
2899                         MSG_DEBUG("__MmsDrm2WriteDataToConvertedFile: FmReadFile() returns false \n");
2900                         return false;
2901                 }
2902
2903                 if (MsgWriteFile(pszMmsLoadTempBuf, sizeof(char), loadLen, pDestinationFile) != (size_t)loadLen) {
2904                         MSG_DEBUG("__MmsDrm2WriteDataToConvertedFile: File Writing is failed.\n");
2905                         return false;
2906                 }
2907
2908                 totalLoadLen += nRead;
2909         }
2910
2911         return true;
2912 }
2913
2914
2915 /*************************************************************************
2916  * description : make new message file converting CD & FL part of original message file to SD type
2917  * argument : void
2918  * return value
2919     - bool :  result of converting
2920 **************************************************************************/
2921 bool MmsDrm2ConvertMsgBody(char *szOriginFilePath)
2922 {
2923         FILE *pFile = NULL;
2924         FILE *hConvertedFile = NULL;
2925         FILE *hTempFile = NULL;
2926         FILE *hFile = NULL;
2927         MsgMultipart *pMultipart = NULL;
2928         char szTempFilePath[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"Drm_Convert";
2929         char szTempFile[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"temp.dm";
2930         char *pszMmsLoadTempBuf = NULL;
2931         char *pszOrgData = NULL;
2932         int length = 0;
2933         int bufLen = MMS_DRM2_CONVERT_BUFFER_MAX;
2934         int curOffset = 0;
2935
2936         MSG_DEBUG("start convert~~~~~~\n");
2937
2938         pFile = MsgOpenFile(szOriginFilePath, "rb");
2939         if (pFile == NULL) {
2940                 MSG_DEBUG("Open decode temporary file fail\n");
2941                 goto __CATCH;
2942         }
2943
2944         hConvertedFile = MsgOpenFile(MMS_DECODE_DRM_CONVERTED_TEMP_FILE, "wb+");
2945         if (hConvertedFile == NULL) {
2946                 MSG_DEBUG("Open decode temporary file fail\n");
2947                 goto __CATCH;
2948         }
2949
2950         pszMmsLoadTempBuf = (char*)malloc(MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2951         if (pszMmsLoadTempBuf == NULL) {
2952                 MSG_DEBUG("malloc for pszMmsLoadTempBuf failed\n");
2953                 goto __CATCH;
2954         }
2955         memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2956
2957         // MMS Header  copy
2958         length = mmsHeader.msgBody.offset;
2959         if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2960                 MSG_DEBUG("Write header data fail\n");
2961                 goto __CATCH;
2962         }
2963
2964         curOffset += length;    //change offset
2965
2966         // MMS Body copy
2967         if (MsgIsMultipart(mmsHeader.msgType.type) == true)
2968         {
2969                 // nEntries copy
2970                 length = __MmsDrm2GetEntriesValueLength(pFile, curOffset);      // getting nEntries value's length
2971
2972                 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2973                         MSG_DEBUG("Write nEntries fail\n");
2974                         goto __CATCH;
2975                 }
2976
2977                 curOffset += length;    //change offset
2978
2979                 // each Multipart entry copy
2980                 pMultipart = mmsHeader.msgBody.body.pMultipart;
2981
2982                 while (pMultipart) {
2983                         if (pMultipart->type.type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE) {
2984                                 int orgDataLen = pMultipart->pBody->size;
2985                                 int nSize = 0;
2986
2987                                 MSG_DEBUG("Write MIME_APPLICATION_VND_OMA_DRM_MESSAGE multipart data(orgDataLen = %d).\n", orgDataLen);
2988
2989                                 pszOrgData = (char *)malloc(orgDataLen + 1);
2990                                 if (pszOrgData == NULL) {
2991                                         MSG_DEBUG("pszOrgData is NULL \n");
2992                                         goto __CATCH;
2993                                 }
2994                                 memset(pszOrgData, 0, orgDataLen + 1);
2995
2996                                 // move file pointer to data
2997                                 if (MsgFseek(pFile, pMultipart->pBody->offset, SEEK_SET) < 0) {
2998                                         MSG_DEBUG("fail to seek file pointer 1\n");
2999                                         goto __CATCH;
3000                                 }
3001
3002                                 if (MsgReadFile(pszOrgData, sizeof(char), orgDataLen, pFile) != (size_t)orgDataLen) {
3003                                         MSG_DEBUG("FmReadFile() returns false for orgData\n");
3004                                         goto __CATCH;
3005                                 }
3006
3007                                 if((hFile = MsgOpenFile(szTempFile, "wb+")) == NULL) {
3008                                         MSG_DEBUG("file open failed [%s]", szTempFile);
3009                                         goto __CATCH;
3010                                 }
3011
3012                                 if (MsgWriteFile(pszOrgData, sizeof(char), orgDataLen, hFile) != (size_t)orgDataLen) {
3013                                         MSG_DEBUG("File write error");
3014                                         goto __CATCH;
3015                                 }
3016
3017                                 MsgFflush(hFile);
3018                                 MsgCloseFile(hFile);
3019
3020                                 hFile = NULL;
3021
3022                                 // --> invoking drm agent api, converting data part start
3023                                 MSG_DEBUG("start data part convert by callling drm agent api\n");
3024
3025                                 int ret = 0;
3026                                 ret = MsgDrmConvertDmtoDcfType(szTempFile, szTempFilePath);
3027                                 MSG_DEBUG("MsgDrmConvertDmtoDcfType returned %s", ret ? "true": "false");
3028
3029                                 if (MsgGetFileSize(szTempFilePath, &nSize) == false) {
3030                                         MSG_DEBUG("MsgGetFileSize error");
3031                                         goto __CATCH;
3032                                 }
3033                                 MSG_DEBUG("MmsDrm2ConvertMsgBody: end data part convert(converted data len = %d)\n", nSize);
3034                                 // <-- invoking drm agent api, converting data part end
3035
3036                                 // move file pointer to the head of multipart
3037                                 if (MsgFseek(pFile, curOffset, SEEK_SET) < 0) {
3038                                         MSG_DEBUG("fail to seek file pointer 2\n");
3039                                         goto __CATCH;
3040                                 }
3041
3042                                 // read headerLen, dataLen
3043                                 length = pMultipart->type.offset - curOffset;
3044                                 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
3045                                 if (MsgReadFile(pszMmsLoadTempBuf, sizeof(char), length, pFile) != (size_t)length) {
3046                                         MSG_DEBUG("FmReadFile() returns false for headerLen, dataLen\n");
3047                                         goto __CATCH;
3048                                 }
3049
3050                                 curOffset += length;
3051
3052                                 // change dataLen based on converted data
3053                                 {
3054                                         UINT8   oneByte = 0;
3055                                         int             j = 0;
3056                                         int             encodeLen = 0;
3057                                         char    szOutput[MSG_STDSTR_LONG] = {0, };
3058
3059                                         while (true) {
3060                                                 oneByte = pszMmsLoadTempBuf[j++];
3061
3062                                                 if (oneByte <= 0x7f)
3063                                                         break;
3064                                         }
3065
3066                                         encodeLen = __MmsDrm2BinaryEncodeUintvarLen((UINT32)nSize);
3067                                         __MmsDrm2BinaryEncodeUintvar((UINT32)nSize, encodeLen, szOutput);
3068
3069                                         strncpy(&(pszMmsLoadTempBuf[j]), szOutput, encodeLen);
3070                                         pszMmsLoadTempBuf[j+encodeLen] = '\0';
3071
3072                                         if (MsgWriteFile(pszMmsLoadTempBuf, sizeof(char), length, hConvertedFile) != (size_t)length) {
3073                                                 MSG_DEBUG("Drm2WriteConvertData: FmWriteFile() returns false for dateLen\n");
3074                                                 goto __CATCH;
3075                                         }
3076                                 }
3077
3078
3079                                 length = pMultipart->pBody->offset - pMultipart->type.offset;
3080
3081                                 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
3082                                         MSG_DEBUG("Drm2WriteConvertData: Write content type, headers fail\n");
3083                                         goto __CATCH;
3084                                 }
3085
3086                                 curOffset += length;
3087
3088                                 // write converted data
3089                                 hTempFile = MsgOpenFile(szTempFilePath, "rb");
3090                                 if (hTempFile == NULL) {
3091                                         MSG_DEBUG("Open decode temporary file fail\n");
3092                                         goto __CATCH;
3093                                 }
3094
3095                                 length = nSize;
3096
3097                                 if (__MmsDrm2WriteDataToConvertedFile(hTempFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
3098                                         MSG_DEBUG("Write converted data fail\n");
3099                                         goto __CATCH;
3100                                 }
3101
3102                                 if (hTempFile != NULL) {
3103                                         MsgCloseFile(hTempFile);
3104                                         hTempFile = NULL;
3105                                 }
3106
3107                                 curOffset += pMultipart->pBody->size;
3108
3109                                 // move file pointer to the head of multipart
3110                                 if (MsgFseek(pFile, curOffset, SEEK_SET) < 0) {
3111                                         MSG_DEBUG("fail to seek file pointer \n");
3112                                         goto __CATCH;
3113                                 }
3114                         } else {        // it doesn't need to convert if it is not CD or FL
3115                                 MSG_DEBUG("Write normal multipart data\n");
3116
3117                                 length = pMultipart->pBody->offset + pMultipart->pBody->size - curOffset;
3118
3119                                 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
3120                                         MSG_DEBUG("Write multipart data fail \n");
3121                                         goto __CATCH;
3122                                 }
3123
3124                                 curOffset += length;
3125                         }
3126
3127                         pMultipart = pMultipart->pNext;
3128                 }
3129         }
3130
3131         MSG_DEBUG("end convert~~~~~~\n");
3132
3133         if (pFile != NULL) {
3134                 MsgCloseFile(pFile);
3135                 pFile = NULL;
3136         }
3137
3138         if (hConvertedFile != NULL) {
3139                 MsgCloseFile(hConvertedFile);
3140                 hConvertedFile = NULL;
3141         }
3142
3143         if (hTempFile != NULL) {
3144                 MsgCloseFile(hTempFile);
3145                 hTempFile = NULL;
3146         }
3147
3148         if (pszMmsLoadTempBuf) {
3149                 free(pszMmsLoadTempBuf);
3150                 pszMmsLoadTempBuf = NULL;
3151         }
3152
3153         if (pszOrgData) {
3154                 free(pszOrgData);
3155                 pszOrgData = NULL;
3156         }
3157
3158         if (hFile != NULL) {
3159                 MsgCloseFile(hFile);
3160                 hFile = NULL;
3161         }
3162
3163         remove(szTempFile);
3164         remove(szTempFilePath);
3165
3166         return true;
3167
3168 __CATCH:
3169
3170         if (pFile != NULL) {
3171                 MsgCloseFile(pFile);
3172                 pFile = NULL;
3173         }
3174
3175         if (hConvertedFile != NULL) {
3176                 MsgCloseFile(hConvertedFile);
3177                 hConvertedFile = NULL;
3178         }
3179
3180         if (hTempFile != NULL) {
3181                 MsgCloseFile(hTempFile);
3182                 hTempFile = NULL;
3183         }
3184
3185         if (pszMmsLoadTempBuf) {
3186                 free(pszMmsLoadTempBuf);
3187                 pszMmsLoadTempBuf = NULL;
3188         }
3189
3190         if (pszOrgData) {
3191                 free(pszOrgData);
3192                 pszOrgData = NULL;
3193         }
3194
3195         if (hFile != NULL)
3196         {
3197                 MsgCloseFile(hFile);
3198                 hFile = NULL;
3199         }
3200
3201         remove(szTempFile);
3202         remove(szTempFilePath);
3203         remove(MMS_DECODE_DRM_CONVERTED_TEMP_FILE);     //remove convertin result if it goes to __CATCH
3204
3205         return false;
3206 }
3207
3208
3209 /*************************************************************************
3210  * description : Function for decoding a converted file
3211  * argument : void
3212  * return value
3213     - bool :  result of converting
3214 **************************************************************************/
3215 bool MmsDrm2DecodeConvertedMsg(int msgID, char *pszFullPath)
3216 {
3217         FILE *hConvertedFile = NULL;
3218         int     nSize = 0;
3219
3220         MSG_DEBUG("MmsDrm2DecodeConvertedMsg: start re-decoding~~~~~~\n");
3221
3222         // free
3223         _MsgFreeDRMInfo(&mmsHeader.msgType.drmInfo);
3224         _MsgFreeBody(&mmsHeader.msgBody, mmsHeader.msgType.type);
3225
3226         _MmsInitHeader();
3227         _MmsUnregisterDecodeBuffer();
3228
3229         // start decoding
3230         _MmsRegisterDecodeBuffer(gszMmsLoadBuf1, gszMmsLoadBuf2, MSG_MMS_DECODE_BUFFER_MAX);
3231
3232         // open converted file
3233         if ((hConvertedFile = MsgOpenFile(MMS_DECODE_DRM_CONVERTED_TEMP_FILE, "rb")) == NULL) {
3234                 MSG_DEBUG("MmsDrm2ReDecodeMsg: opening temporary file failed\n");
3235                 goto __CATCH;
3236         }
3237
3238         if (MsgGetFileSize(MMS_DECODE_DRM_CONVERTED_TEMP_FILE, &nSize) == false) {
3239                 MSG_DEBUG("MsgGetFileSize: failed\n");
3240                 goto __CATCH;
3241         }
3242
3243         if (!MmsBinaryDecodeMsgHeader(hConvertedFile, nSize)) {
3244                 MSG_DEBUG("MmsDrm2ReDecodeMsg: decoding header(binary mode) failed\n");
3245                 goto __CATCH;
3246         }
3247
3248         if (!MmsBinaryDecodeMsgBody(hConvertedFile, pszFullPath, nSize)) {
3249                 MSG_DEBUG("MmsDrm2ReDecodeMsg: decoding body failed\n");
3250                 goto __CATCH;
3251         }
3252
3253         if (hConvertedFile != NULL) {
3254                 MsgCloseFile(hConvertedFile);
3255                 hConvertedFile = NULL;
3256         }
3257
3258         return true;
3259
3260 __CATCH:
3261
3262         if (hConvertedFile != NULL) {
3263                 MsgCloseFile(hConvertedFile);
3264                 remove(MMS_DECODE_DRM_CONVERTED_TEMP_FILE);
3265                 hConvertedFile = NULL;
3266         }
3267
3268         return false;
3269 }
3270
3271
3272 bool MmsDrm2ReadMsgConvertedBody(MSG_MESSAGE_INFO_S *pMsg, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
3273 {
3274         MmsMsg *pMmsMsg;
3275         MmsPluginStorage::instance()->getMmsMessage(&pMmsMsg);
3276         _MmsUnregisterDecodeBuffer();
3277 #ifdef __SUPPORT_DRM__
3278         _MsgFreeDRMInfo(&pMmsMsg->msgType.drmInfo);
3279 #endif
3280         _MsgFreeBody(&pMmsMsg->msgBody, pMmsMsg->msgType.type);
3281
3282         if (_MmsReadMsgBody(pMsg->msgId, bSavePartsAsTempFiles, bRetrieved, retrievedPath) == false) {
3283                 MSG_DEBUG("MmsDrm2ReadMsgConvertedBody: _MmsReadMsgBody with converted file is failed\n");
3284                 return false;
3285         }
3286
3287         return true;
3288 }
3289
3290 #endif
3291
3292 /* --------------------------------------------------------------------
3293  *
3294  *     B  I  N  A  R  Y       D  E  C  D  E      U  T  I  L  I  T  Y
3295  *
3296  * --------------------------------------------------------------------*/
3297
3298 bool _MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
3299 {
3300         int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
3301
3302         if (pFile == NULL || pOneByte == NULL)
3303         {
3304                 MSG_DEBUG("_MmsBinaryDecodeGetOneByte: invalid file or buffer\n");
3305                 goto __CATCH;
3306         }
3307
3308         if (length < 1) {
3309                 if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3310                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3311                         MSG_DEBUG("_MmsBinaryDecodeGetOneByte: fail to load to buffer \n");
3312                         goto __CATCH;
3313                 }
3314         }
3315
3316         *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
3317
3318         return true;
3319
3320 __CATCH:
3321         return false;
3322 }
3323
3324
3325 /*
3326  * @remark: bufLen < gMmsDecodeMaxLen
3327  */
3328 bool _MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3329 {
3330         int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
3331         int i = 0;
3332
3333
3334         if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
3335                 goto __CATCH;
3336
3337         memset(szBuff, 0, bufLen);
3338
3339         if (length < bufLen) {
3340                 if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3341                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3342                         MSG_DEBUG("_MmsBinaryDecodeGetBytes: fail to load to buffer \n");
3343                         goto __CATCH;
3344                 }
3345         }
3346
3347         for (i = 0; i < bufLen - 1; i++)
3348                 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
3349
3350
3351         gCurMmsDecodeBuffPos++; //NULL
3352
3353         return true;
3354
3355 __CATCH:
3356         return false;
3357 }
3358
3359
3360
3361 bool _MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3362 {
3363         int iPos = 0;
3364
3365         if (pFile == NULL || szBuff == NULL || bufLen == 0)
3366                 goto __CATCH;
3367
3368         memset(szBuff, 0, bufLen);
3369
3370         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3371                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3372                 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: fail to load to buffer \n");
3373                 goto __CATCH;
3374         }
3375
3376         while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
3377                 if (_MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
3378                         MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: 1. _MmsBinaryDecodeGetBytes fail \n");
3379                         goto __CATCH;
3380                 }
3381
3382                 iPos += gMmsDecodeMaxLen;
3383         }
3384
3385         if ((bufLen - iPos) > 0) {
3386                 if (_MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
3387                         MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: 2. _MmsBinaryDecodeGetBytes fail \n");
3388                         goto __CATCH;
3389                 }
3390
3391                 iPos += (bufLen - iPos);
3392         }
3393
3394         return true;
3395
3396 __CATCH:
3397         return false;
3398 }
3399
3400
3401 /**
3402  * Decode uintvar to 32bit unsigned integer
3403  *
3404  * @param       pEncodedData    [in] encoded data
3405  * @param       pUintVar                [out] Decode uintvar (32bit unsigned integer)
3406  * @return      The length of uintvar (-1, if cannot be converted to a uintvar)
3407  *
3408  * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
3409  * - -------
3410  */
3411 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
3412
3413 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
3414 {
3415         UINT8 count = 0;
3416         UINT8 oneByte = 0;
3417         UINT32 decodedUintvar = 0;
3418         UINT8 iBuff[5] = {0};
3419         int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
3420
3421
3422         if (pFile == NULL || pUintVar == NULL)
3423                 return -1;
3424
3425         if (length < 5) {
3426                 if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3427                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3428                         MSG_DEBUG("__MmsBinaryDecodeUintvar: fail to load to buffer \n");
3429                         goto __CATCH;
3430                 }
3431         }
3432
3433         while (true) {
3434                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3435                         goto __CATCH;
3436
3437                 if (oneByte > 0x7f)     {
3438                         iBuff[count++] = oneByte;
3439                 } else {
3440                         iBuff[count++] = oneByte;
3441                         break;
3442                 }
3443
3444                 if (count > 5) {
3445                         MSG_DEBUG("__MmsBinaryDecodeUintvar : legnth is too long\n");
3446                         goto __CATCH;
3447                 }
3448         }
3449
3450         for (int i = 0; i < count; i++)
3451                 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
3452
3453         *pUintVar = decodedUintvar;
3454
3455         return count;
3456
3457 __CATCH:
3458         gCurMmsDecodeBuffPos -= count;
3459         return -1;
3460 }
3461
3462
3463 /**
3464  * Decode uintvar to 32bit unsigned integer by uintvar length
3465  *
3466  * @param       pEncodedData [in] uintvar encoded data
3467  * @param       length           [in] length of integer value
3468  * @return      unsigned integer value
3469  */
3470 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
3471 {
3472         UINT32 i = 0;
3473         UINT8 oneByte = 0;
3474         char *pData = NULL;
3475         union {
3476                 UINT32  integer;
3477                 UINT8   seg[4];
3478         } returner;
3479
3480         returner.integer = 0;
3481
3482         if (length > 4)
3483                 length = 4;
3484
3485         if (length == 1)
3486         {
3487                 if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3488                         MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: _MmsBinaryDecodeGetOneByte fail\n");
3489                         return oneByte;
3490                 }
3491
3492                 if (oneByte > 0x7f) {
3493                         return (oneByte & 0x7f);
3494                 } else {
3495                         return oneByte;
3496                 }
3497         }
3498
3499         if (length == 0)
3500                 return 0;
3501
3502         pData = (char *)malloc(length + 1);
3503         if (pData == NULL) {
3504                 MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: pData alloc fail\n");
3505                 goto __CATCH;
3506         }
3507         memset(pData, 0, length + 1);
3508
3509         if (_MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
3510                 MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: _MmsBinaryDecodeGetOneByte fail\n");
3511                 goto __CATCH;
3512         }
3513
3514         gCurMmsDecodeBuffPos--; // - NULL
3515
3516         for (i= 0; i < length; i++)
3517                 returner.seg[length - (i+1)] = pData[i];
3518
3519         if (pData) {
3520                 free(pData);
3521                 pData = NULL;
3522         }
3523
3524         return returner.integer;
3525
3526 __CATCH:
3527
3528         if (pData) {
3529                 free(pData);
3530                 pData = NULL;
3531         }
3532
3533         return returner.integer;
3534 }
3535
3536
3537 /**
3538  * Decode uintvar to 32bit unsigned integer by uintvar length
3539  *
3540  * @param       pEncodedData    [in]  uintvar encoded data
3541  * @param       pInteger                [out] Decode integer value (long/short)
3542  * @return      unsigned integer value (-1, if cannot be converted to unsigned integer value)
3543  */
3544 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
3545 {
3546         UINT8 oneByte   = 0;
3547         char *pData     = NULL;
3548         union {
3549                 UINT32  integer;
3550                 UINT8   seg[4];
3551         } returner;
3552
3553
3554         if (pInteger == NULL)
3555                 return false;
3556
3557         returner.integer = 0;
3558         *pIntLen                 = 0;
3559
3560         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3561                 MSG_DEBUG("__MmsBinaryDecodeInteger: GetOneByte fail\n");
3562                 return false;
3563         }
3564
3565         if (oneByte < 0x1F)                             /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
3566         {
3567                 pData = (char *)malloc(oneByte + 1);
3568                 if (pData == NULL) {
3569                         MSG_DEBUG("__MmsBinaryDecodeInteger: pData memalloc fail\n");
3570                         goto __CATCH;
3571                 }
3572                 memset(pData, 0, oneByte + 1);
3573
3574                 // Even NULL is copied in the _MmsBinaryDecodeGetBytes
3575                 if (_MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
3576                         MSG_DEBUG("__MmsBinaryDecodeInteger: GetBytes fail\n");
3577                         goto __CATCH;
3578                 }
3579
3580                 gCurMmsDecodeBuffPos--; // - NULL
3581
3582                 int             length  = 0;
3583                 if (oneByte > 4) {
3584                         length = 4;
3585                 } else {
3586                         length = oneByte;
3587                 }
3588
3589                 int             i = 0;
3590                 for (i = 0; i < length; i++)
3591                         returner.seg[length - (i+1)] = pData[i];
3592
3593                 *pInteger = returner.integer;
3594                 *pIntLen  = oneByte + 1;
3595         } else if (oneByte >= 0x80)     {
3596                 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
3597                 *pInteger = oneByte & 0x7f;
3598                 *pIntLen  = 1;
3599         } else {
3600                 goto __CATCH;
3601         }
3602
3603         if (pData) {
3604                 free(pData);
3605                 pData = NULL;
3606         }
3607
3608         return true;
3609
3610 __CATCH:
3611
3612         gCurMmsDecodeBuffPos--;
3613
3614         if (pData) {
3615                 free(pData);
3616                 pData = NULL;
3617         }
3618
3619         return false;
3620 }
3621
3622
3623 /**
3624  * Decode uintvar to 32bit unsigned integer by uintvar length
3625  *
3626  * @return      1  : Success
3627  *                      0  : This is not Value Length type data
3628  *                      -1 : Requires System error report
3629  */
3630 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
3631 {
3632         int length = 0;
3633         UINT32 uintvar = 0;
3634         UINT8 oneByte = 0;
3635
3636
3637         /*
3638          * value-length = short-length | (Length-quote Length)
3639          *                              = 0~30             | 31 + Uintvar-length
3640          */
3641
3642         if (pFile == NULL || pValueLength == NULL)
3643                 goto __CATCH;
3644
3645         *pValueLength = 0;
3646
3647         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3648                 gCurMmsDecodeBuffPos--;
3649                 goto __CATCH;
3650         }
3651
3652         if (0x00 < oneByte && oneByte < 0x1F) {
3653                 /* short-length */
3654
3655                 *pValueLength = oneByte;
3656                 length = 1;
3657         } else if (oneByte == 0x1F) {
3658                 /* Length-quote = 0x1F */
3659
3660                 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
3661                 if (length == -1) {
3662                         MSG_DEBUG("__MmsDecodeValueLength: __MmsBinaryDecodeUintvar fail..\n");
3663                         goto __CATCH;
3664                 }
3665                 length ++;                                      // + length-quote
3666                 *pValueLength = uintvar;
3667         } else {
3668                 MSG_DEBUG("__MmsDecodeValueLength: not a value length type data\n");
3669                 gCurMmsDecodeBuffPos--;
3670                 return 0;
3671         }
3672
3673         return length;
3674
3675 __CATCH:
3676         MSG_DEBUG("__MmsDecodeValueLength: getting data fail\n");
3677         return -1;
3678 }
3679
3680
3681
3682 /**
3683  * Decode uintvar to 32bit unsigned integer by uintvar length
3684  *
3685  * @return      1  : Success
3686  *                      0  : This is not Value Length type data
3687  *                      -1 : Requires System error report
3688  * @ defference : if there is not length-quote, consider it as short length.
3689  */
3690 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
3691 {
3692         int length      = 0;
3693         UINT32 uintvar = 0;
3694         UINT8 oneByte = 0;
3695
3696
3697         /*
3698          * value-length = short-length | (Length-quote Length)
3699          *                              = 0~30             | 31 + Uintvar-length
3700          */
3701
3702         if (pFile == NULL || pValueLength == NULL)
3703                 goto __CATCH;
3704
3705         *pValueLength = 0;
3706
3707         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3708                 gCurMmsDecodeBuffPos--;
3709                 goto __CATCH;
3710         }
3711
3712         if (0x00 < oneByte && oneByte < 0x1F) {
3713                 /* short-length */
3714
3715                 *pValueLength = oneByte;
3716                 length = 1;
3717         } else if (oneByte == 0x1F) {
3718                 /* Length-quote = 0x1F */
3719
3720                 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
3721                 if (length == -1) {
3722                         MSG_DEBUG("__MmsDecodeValueLength2: __MmsBinaryDecodeUintvar fail..\n");
3723                         goto __CATCH;
3724                 }
3725                 length ++;                                      // + length-quote
3726                 *pValueLength = uintvar;
3727         } else {
3728                 MSG_DEBUG("__MmsDecodeValueLength2: there is not length-quote, consider it as short length.\n");
3729                 *pValueLength = oneByte;
3730                 length = 1;
3731         }
3732
3733         return length;
3734
3735 __CATCH:
3736         MSG_DEBUG("__MmsDecodeValueLength2: getting data fail\n");
3737         return -1;
3738 }
3739
3740
3741
3742 /**
3743  * Decode QuotedString
3744  *
3745  * @param       pEncodedData    [in] QuotedString encoded data
3746  * @param       szBuff                  [out] Decoded quoted string
3747  * @param       bufLen                  [out] Buffer length
3748  * @return      length of quoted string
3749  */
3750 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3751 {
3752         int iPos = 0;
3753         int length = 0;
3754         int readBytes = 0;
3755         char *pData = NULL;
3756         int returnLength = 0;
3757
3758         /*
3759          * Quoted-string = <Octet 34> *TEXT End-of-string
3760          * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
3761          */
3762
3763         if (pFile == NULL || szBuff == NULL || bufLen <= 0)
3764                 return -1;
3765
3766         memset(szBuff, 0, bufLen);
3767
3768         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3769                                                                          gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3770                 MSG_DEBUG("__MmsBinaryDecodeQuotedString: 1. fail to load to buffer \n");
3771                 goto __CATCH;
3772         }
3773
3774         length = strlen(gpCurMmsDecodeBuff) + 1;        // + NULL
3775
3776         if (length == 0)
3777                 goto __RETURN;
3778
3779         while (length > gMmsDecodeBufLen) {
3780                 if (gMmsDecodeBufLen <= 0) {
3781                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
3782                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3783                                                                                 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3784                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3785                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3786                                                                                 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3787                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3788                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3789                                                                                 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3790                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3791                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3792                                                                                 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3793                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3794                         goto __CATCH;
3795                 }
3796
3797                 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3798                 if (pData == NULL)
3799                         goto __CATCH;
3800
3801                 memset(pData, 0, gMmsDecodeBufLen + 1);
3802
3803                 if (_MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3804                         goto __CATCH;
3805
3806                 returnLength += gMmsDecodeBufLen;
3807
3808                 if ((bufLen - iPos) > 0) {
3809                         readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3810                         if (iPos == 0 && (pData[0] == MARK)) {
3811                                 /* MARK: check first time only */
3812
3813                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3814                                 iPos += (readBytes - 1);
3815                         } else {
3816                                 strncpy(szBuff + iPos, (char*)pData, readBytes);
3817                                 iPos += readBytes;
3818                         }
3819                 }
3820
3821                 if (pData) {
3822                         free(pData);
3823                         pData = NULL;
3824                 }
3825
3826                 if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3827                                                                                 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3828                         MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
3829                         goto __CATCH;
3830                 }
3831                 length = strlen(gpCurMmsDecodeBuff) + 1;        // + NULL
3832         }       /* while */
3833
3834         if (length > 0) {
3835                 pData = (char *)malloc(length);
3836                 if (pData == NULL)
3837                         goto __CATCH;
3838
3839                 if (_MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3840                         goto __CATCH;
3841
3842                 returnLength += length;
3843
3844                 if ((bufLen - iPos) > 0) {
3845                         /* read until NULL from raw data, and copy only string */
3846                         readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3847                         if (iPos == 0 && (pData[0] == MARK)) {
3848                                 /* MARK: check first time only */
3849                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3850                                 iPos += (readBytes - 1);
3851                         } else {
3852                                 strncpy(szBuff + iPos, (char*)pData, readBytes - 1);    // + NULL
3853                                 iPos += readBytes;
3854                         }
3855                 }
3856
3857                 if (pData) {
3858                         free(pData);
3859                         pData = NULL;
3860                 }
3861         }
3862
3863         szBuff[bufLen - 1] = '\0';
3864
3865         return returnLength;
3866
3867 __RETURN:
3868
3869         if (pData) {
3870                 free(pData);
3871                 pData = NULL;
3872         }
3873
3874         return length;
3875
3876 __CATCH:
3877
3878         if (pData) {
3879                 free(pData);
3880                 pData = NULL;
3881         }
3882
3883         return -1;
3884 }
3885
3886
3887 /**
3888  * Decode Text
3889  *
3890  * @param       pEncodedData    [in] QuotedString encoded data
3891  * @param       szBuff                  [out] Decoded quoted string
3892  * @param       bufLen                  [out] Buffer length
3893  * @return      length of decode text string
3894  */
3895 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3896 {
3897         int length = 0;
3898         int readBytes = 0;
3899         int iPos = 0;
3900         int returnLength = 0;
3901         char *pData = NULL;
3902         bool bQuote = false;
3903         int offset = 0;
3904
3905         /*
3906          * Text-String = [QUOTE]*TEXT end_of_string
3907          *                               [QUOTE]*(128~255)\0
3908          *                               *(32~126)\0
3909          */
3910
3911         if (pFile == NULL || szBuff == NULL || bufLen <= 0)
3912                 return -1;
3913
3914         offset = _MmsGetDecodeOffset();
3915         if (offset >= totalLength)
3916                 goto __RETURN;
3917
3918         memset(szBuff, 0, bufLen);
3919
3920         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3921                                                                         gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3922                 MSG_DEBUG("__MmsBinaryDecodeText: 1. fail to load to buffer \n");
3923                 goto __CATCH;
3924         }
3925
3926         length = strlen(gpCurMmsDecodeBuff) + 1;        // + NULL
3927
3928         if (length == 0)
3929                 goto __RETURN;
3930
3931         while (length > gMmsDecodeBufLen) {
3932                 if (gMmsDecodeBufLen <= 0) {
3933                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
3934                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3935                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3936                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3937                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3938                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3939                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3940                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3941                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3942                         goto __CATCH;
3943                 }
3944
3945                 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3946                 if (pData == NULL)
3947                         goto __CATCH;
3948
3949                 memset(pData, 0, gMmsDecodeBufLen + 1);
3950
3951                 if (_MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3952                         goto __CATCH;
3953
3954                 if ((bufLen - iPos) > 0) {
3955                         readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3956                         if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3957                                 /* QUOTE: check first time only */
3958
3959                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3960                                 iPos += (readBytes - 1);
3961                                 bQuote = true;
3962                         } else {
3963                                 strncpy(szBuff + iPos, (char*)pData, readBytes);
3964                                 iPos += readBytes;
3965                         }
3966                 }
3967
3968                 if (pData) {
3969                         free(pData);
3970                         pData = NULL;
3971                 }
3972
3973                 returnLength += gMmsDecodeBufLen;
3974
3975                 if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3976                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3977                         MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
3978                         goto __CATCH;
3979                 }
3980                 length = strlen(gpCurMmsDecodeBuff) + 1;        // + NULL
3981         }       /* while */
3982
3983         if (length > 0) {
3984                 pData = (char *)malloc(length);
3985                 if (pData == NULL)
3986                         goto __CATCH;
3987
3988                 memset(pData, 0, length);
3989
3990                 if (_MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3991                         goto __CATCH;
3992
3993                 if ((bufLen - iPos) > 0) {
3994                         readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3995                         if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3996                                 /* QUOTE: check first time only */
3997
3998                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3999                                 iPos += (readBytes - 1);
4000                                 bQuote = true;
4001                         } else {
4002                                 strncpy(szBuff + iPos, (char*)pData, readBytes - 1);    // + NULL
4003                                 iPos += readBytes;
4004                         }
4005                 }
4006
4007                 if (pData) {
4008                         free(pData);
4009                         pData = NULL;
4010                 }
4011
4012                 returnLength += length;         // + NULL
4013         }
4014
4015         szBuff[bufLen - 1] = '\0';
4016
4017         return returnLength;
4018
4019 __RETURN:
4020
4021         if (pData) {
4022                 free(pData);
4023                 pData = NULL;
4024         }
4025
4026         szBuff[0] = '\0';
4027         length = 0;
4028
4029         MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
4030
4031         return length;
4032
4033 __CATCH:
4034
4035         if (pData) {
4036                 free(pData);
4037                 pData = NULL;
4038         }
4039
4040         return -1;
4041 }
4042
4043
4044 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
4045 {
4046         int length = 0;
4047         int curLen = 0;
4048         char *pData = NULL;
4049         char *szBuff = NULL;
4050         char *szTempPtr = NULL;
4051         bool bQuote = false;
4052         int offset = 0;
4053
4054         /*
4055          * Text-String = [QUOTE]*TEXT end_of_string
4056          *                               [QUOTE]*(128~255)\0
4057          *                               *(32~126)\0
4058          */
4059
4060         if (pFile == NULL || pLength == NULL)
4061                 goto __CATCH;
4062
4063         *pLength = 0;
4064         offset = _MmsGetDecodeOffset();
4065         if (offset >= totalLength)
4066                 goto __RETURN;
4067
4068         if (MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
4069                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
4070                 MSG_DEBUG("__MmsBinaryDecodeTextLen: 1. fail to load to buffer \n");
4071                 goto __CATCH;
4072         }
4073
4074         length = strlen(gpCurMmsDecodeBuff) + 1;
4075
4076         if (length == 0)
4077                 goto __CATCH;
4078
4079         while (length > gMmsDecodeBufLen) {
4080                 if (gMmsDecodeBufLen <= 0) {
4081                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
4082                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
4083                                                                                 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
4084                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
4085                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
4086                                                                                 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
4087                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
4088                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
4089                                                                                 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
4090                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
4091                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
4092                                                                                 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
4093                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
4094                         goto __CATCH;
4095                 }
4096
4097                 pData = (char *)malloc(gMmsDecodeBufLen + 1);
4098                 if (pData == NULL)
4099                         goto __CATCH;
4100
4101                 memset(pData, 0, gMmsDecodeBufLen + 1);
4102
4103                 if (_MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
4104                         goto __CATCH;
4105
4106                 if (szBuff == NULL)     {
4107                         szBuff = (char *)malloc(gMmsDecodeBufLen + 1);
4108                 } else {
4109                         szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
4110
4111                         //NULL pointer check for realloc
4112                         if (szTempPtr == NULL) {
4113                                 goto __CATCH;
4114                         } else {
4115                                 szBuff = szTempPtr;
4116                         }
4117                 }
4118                 if (szBuff == NULL)
4119                         goto __CATCH;
4120
4121                 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
4122
4123                 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
4124                         /* QUOTE: check first time only */
4125
4126                         strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
4127                         curLen += (gMmsDecodeBufLen - 1);
4128                         bQuote = true;
4129                 } else {
4130                         strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
4131                         curLen += gMmsDecodeBufLen;
4132                 }
4133
4134                 if (pData) {
4135                         free(pData);
4136                         pData = NULL;
4137                 }
4138
4139                 *pLength += gMmsDecodeBufLen;
4140
4141                 if (MsgLoadDataToDecodeBuffer(pFile,
4142                                                            &gpCurMmsDecodeBuff,
4143                                                            &gCurMmsDecodeBuffPos,
4144                                                            &gMmsDecodeCurOffset,
4145                                                            gpMmsDecodeBuf1,
4146                                                            gpMmsDecodeBuf2,
4147                                                            gMmsDecodeMaxLen,
4148                                                            &gMmsDecodeBufLen,
4149                                                            totalLength) == false)
4150                 {
4151                         MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
4152                         goto __CATCH;
4153                 }
4154                 length = strlen(gpCurMmsDecodeBuff) + 1;
4155         }       /* while */
4156
4157         if (length > 0) {
4158                 pData = (char *)malloc(length);
4159                 if (pData == NULL) {
4160                         goto __CATCH;
4161                 }
4162
4163                 if (_MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
4164                         goto __CATCH;
4165                 }
4166
4167                 if (szBuff == NULL) {
4168                         szBuff = (char *)malloc(length);
4169                 } else {
4170                         szTempPtr = (char *)realloc(szBuff, curLen + length);
4171
4172                         //NULL pointer check for realloc
4173                         if (szTempPtr == NULL)
4174                                 goto __CATCH;
4175                         else
4176                                 szBuff = szTempPtr;
4177                 }
4178
4179                 if (szBuff == NULL) {
4180                         goto __CATCH;
4181                 }
4182
4183                 memset(szBuff + curLen, 0, length);
4184
4185                 if (curLen == 0 && (pData[0] == QUOTE)  && (bQuote == false)) {
4186                         /* QUOTE: check first time only */
4187
4188                         strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
4189                         curLen += (length - 1);
4190                         bQuote = true;
4191                 } else {
4192                         strncpy(szBuff + curLen, (char*)pData, length - 1);
4193                         curLen += length;
4194                 }
4195
4196                 if (pData) {
4197                         free(pData);
4198                         pData = NULL;
4199                 }
4200
4201                 *pLength += length;             // + NULL
4202         }
4203
4204         return szBuff;
4205
4206 __RETURN:
4207         if (pData) {
4208                 free(pData);
4209                 pData = NULL;
4210         }
4211
4212         *pLength = 1;
4213
4214         MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
4215
4216         return szBuff;
4217
4218 __CATCH:
4219
4220         if (szBuff) {
4221                 free(szBuff);
4222                 szBuff = NULL;
4223         }
4224
4225         if (pData) {
4226                 free(pData);
4227                 pData = NULL;
4228         }
4229
4230         return NULL;
4231 }
4232
4233
4234 /**
4235  * Decode Charset
4236  *
4237  * @param       pEncodedData    [in] QuotedString encoded data
4238  * @param       nCharSet                [out] Decoded character set
4239  * @return      length of charset value
4240  */
4241 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
4242 {
4243         UINT32 integer = 0;
4244
4245         /*
4246          * Charset v1.1 0x01 Well-known-charset
4247          *                                       Well-known-charset = Any-charset | Integer-value
4248          *                                              ; Both are encoded using values from
4249          *                                                Character Set Assignments table in Assigned Numbers
4250          *                                       Any-charset = <Octet 128>
4251          *                                              ; Equivalent to the special RFC2616 charset value Â¡Â°*¡±
4252          */
4253
4254         if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
4255                 return false;
4256
4257         if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
4258                 MSG_DEBUG("__MmsBinaryDecodeCharset : __MmsBinaryDecodeInteger fail...\n");
4259                 goto __CATCH;
4260         }
4261
4262         if (integer == 0) {
4263                 /* AnyCharSet : return MSG_CHARSET_UTF8 */
4264                 *nCharSet = MSG_CHARSET_UTF8;
4265                 return true;
4266         }
4267
4268         *nCharSet = _MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
4269
4270         if (*nCharSet == MIME_UNKNOWN) {
4271                 MSG_DEBUG("__MmsBinaryDecodeCharset : _MmsGetBinaryType fail..\n");
4272                 *nCharSet = MSG_CHARSET_UNKNOWN;
4273         }
4274
4275         return true;
4276
4277 __CATCH:
4278         return false;
4279 }
4280
4281
4282
4283 /**
4284  * Decode EncodedString
4285  *
4286  * @param       pEncodedData    [in] QuotedString encoded data
4287  * @param       szBuff                  [out] Decoded string buffer
4288  * @param       bufLen                  [in]  Decoded buffer length
4289  * @return      length of decoded string length
4290  */
4291 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
4292 {
4293         UINT32 valueLength = 0;
4294         UINT32 charSet = 0;
4295         int charSetLen = 0;
4296         int nChar = 0;
4297         int nRead2 = 0;
4298         int nByte = 0;
4299         int nTemp = 0;
4300         char *pData = NULL;
4301         char *pTempData = NULL;
4302         unsigned short *mszTempStr = NULL;
4303         char *pConvertedStr = NULL;
4304         char *pNewData = NULL;
4305
4306
4307         MSG_DEBUG("__MmsBinaryDecodeEncodedString: decode string..\n");
4308
4309         if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
4310                 MSG_DEBUG("__MmsBinaryDecodeEncodedString: invalid file or buffer\n");
4311                 goto __CATCH;
4312         }
4313
4314         /*
4315          * Encoded_string_value = Text-string | Value-length Char-set Text-String
4316          *                                                Text-string    = [Quote]*TEXT End-of-string
4317          *                                                Value-length   = 0 ~ 31
4318          */
4319
4320         memset(szBuff, 0, bufLen);
4321
4322         switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
4323         case -1:
4324                 goto __CATCH;
4325
4326         case 0:
4327
4328                 /* Text-string = [Quote]*TEXT End-of-string */
4329
4330                 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
4331                         MSG_DEBUG("__MmsBinaryDecodeEncodedString : 1. __MmsBinaryDecodeText fail.\n");
4332                         goto __CATCH;
4333                 }
4334                 break;
4335
4336         default:
4337
4338                 /* Value-length Charset Text_string */
4339
4340                 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
4341                         MSG_DEBUG("__MmsBinaryDecodeEncodedString : __MmsBinaryDecodeCharset error\n");
4342                         goto __CATCH;                   /* (valueLength + valueLengthLen) */
4343                 }
4344
4345                 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
4346                 if (nTemp < 0) {
4347                         /* There can be some error in data - no NULL -> try again with value length */
4348
4349                         pData = (char *)malloc(valueLength - charSetLen);
4350                         if (pData == NULL) {
4351                                 MSG_DEBUG("__MmsBinaryDecodeEncodedString : pData alloc fail.\n");
4352                                 goto __CATCH;
4353                         }
4354
4355                         if (_MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
4356                                 MSG_DEBUG("__MmsBinaryDecodeEncodedString : _MmsBinaryDecodeGetLongBytes fail.\n");
4357                                 goto __CATCH;
4358                         }
4359
4360                         strncpy(szBuff, pData, bufLen - 1);
4361                 }
4362
4363
4364                 /* fixme: charset transformation */
4365                 switch (charSet) {
4366                 case MSG_CHARSET_UTF16:
4367                 case MSG_CHARSET_USC2:
4368
4369                         MSG_DEBUG("__MmsBinaryDecodeEncodedString: MSG_CHARSET_USC2 \n");
4370
4371                         nTemp = strlen(szBuff);
4372                         pTempData = (char *)malloc(nTemp + 1);
4373                         if (pTempData == NULL) {
4374                                 MSG_DEBUG("__MmsBinaryDecodeEncodedString: Memory Full \n");
4375                                 goto __CATCH;
4376                         }
4377
4378                         memset(pTempData, 0, nTemp + 1);
4379                         memcpy(pTempData, szBuff, nTemp + 1);
4380
4381                         if (((UINT8)pTempData[0]) == 0xFF && ((UINT8)pTempData[1]) == 0xFE) {
4382                                 if ((nChar = (nTemp / 2 - 1)) <= 0)     {
4383                                         MSG_DEBUG("__MmsBinaryDecodeEncodedString(%d) : nChar is invalid value (%d), charset(%d)\n", __LINE__, nChar, charSet);
4384                                         goto __CATCH ;
4385                                 }
4386
4387                                 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
4388                                 if (mszTempStr == NULL) {
4389                                         MSG_DEBUG("MmsGetMediaPartData : 1. Memory Full !!! \n");
4390                                         goto __CATCH;
4391                                 }
4392
4393                                 memcpy(mszTempStr, ((unsigned short*)pTempData + 1), nChar * sizeof(unsigned short));
4394
4395                                 nByte = MsgGetUnicode2UTFCodeSize(((unsigned short*)pTempData + 1), nChar);
4396
4397                                 pConvertedStr = (char *)malloc(nByte + 1);
4398                                 if (pConvertedStr)
4399                                         MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
4400                         } else {
4401                                 if ((nChar = (nTemp / 2)) <= 0) {
4402                                         MSG_DEBUG("__MmsBinaryDecodeEncodedString(%d) : nChar is invalid value (%d), charset(%d)\n", __LINE__, nChar, charSet);
4403                                         goto __CATCH ;
4404                                 }
4405
4406                                 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
4407                                 if (mszTempStr == NULL) {
4408                                         MSG_DEBUG("__MmsBinaryDecodeEncodedString: 2. Memory Full !!! \n");
4409                                         goto __CATCH;
4410                                 }
4411
4412                                 memcpy(mszTempStr, ((unsigned short*)pTempData), nChar * sizeof(unsigned short));
4413
4414                                 nByte = MsgGetUnicode2UTFCodeSize(((unsigned short*)pTempData), nChar);
4415
4416                                 pConvertedStr = (char *)malloc(nByte + 1);
4417                                 if (pConvertedStr != NULL)
4418                                         MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
4419                         }
4420
4421                         if (pConvertedStr != NULL) {
4422                                 pNewData = pConvertedStr;
4423                                 nRead2 = nByte;
4424
4425                                 strncpy(szBuff, pNewData, bufLen - 1);
4426                         }
4427
4428                         break;
4429
4430                 case MSG_CHARSET_US_ASCII:
4431
4432                         MSG_DEBUG("__MmsBinaryDecodeEncodedString: MSG_CHARSET_US_ASCII \n");
4433
4434                 case MSG_CHARSET_UTF8:
4435
4436                         MSG_DEBUG("__MmsBinaryDecodeEncodedString: MSG_CHARSET_UTF8 or Others \n");
4437
4438                         pNewData = pTempData;
4439                         nRead2 = nTemp;
4440
4441                         break;
4442
4443                 case MSG_CHARSET_ISO_8859_7: /* Greek */
4444
4445                         MSG_DEBUG("__MmsBinaryDecodeEncodedString: MSG_CHARSET_ISO_8859_7 \n");
4446
4447                         nTemp = strlen(szBuff);
4448                         pTempData = (char *)malloc(nTemp + 1);
4449                         if (pTempData == NULL)
4450                         {
4451                                 MSG_DEBUG("__MmsBinaryDecodeEncodedString: Memory Full \n");
4452                                 goto __CATCH;
4453                         }
4454
4455                         memset(pTempData, 0 , nTemp + 1);
4456                         memcpy(pTempData, szBuff, nTemp + 1);
4457
4458                         nByte = MsgGetLatin72UTFCodeSize((unsigned char*)pTempData, nTemp);
4459                         pConvertedStr = (char *)malloc(nByte + 1);
4460
4461                         if (pConvertedStr != NULL) {
4462                                 MsgLatin7code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTempData, nTemp);
4463
4464                                 pNewData = pConvertedStr;
4465                                 nRead2 = nByte;
4466
4467                                 strncpy(szBuff, pNewData, bufLen - 1);
4468                         }
4469
4470                         break;
4471
4472                 case MSG_CHARSET_ISO_8859_9: /* Turkish */
4473
4474                         MSG_DEBUG("__MmsBinaryDecodeEncodedString: MSG_CHARSET_ISO_8859_9 \n");
4475
4476                         nTemp = strlen(szBuff);
4477                         pTempData = (char *)malloc(nTemp + 1);
4478                         if (pTempData == NULL) {
4479                                 MSG_DEBUG("__MmsBinaryDecodeEncodedString: Memory Full \n");
4480                                 goto __CATCH;
4481                         }
4482
4483                         memset(pTempData, 0 , nTemp + 1);
4484                         memcpy(pTempData, szBuff, nTemp + 1);
4485
4486                         nByte = MsgGetLatin52UTFCodeSize((unsigned char*)pTempData, nTemp);
4487                         pConvertedStr = (char *)malloc(nByte + 1);
4488
4489                         if (pConvertedStr != NULL) {
4490                                 MsgLatin5code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTempData, nTemp);
4491
4492                                 pNewData = pConvertedStr;
4493                                 nRead2 = nByte;
4494
4495                                 strncpy(szBuff, pNewData, bufLen - 1);
4496                         }
4497
4498                         break;
4499
4500                 default:
4501
4502                         MSG_DEBUG("__MmsBinaryDecodeEncodedString: Other charsets \n");
4503
4504                         nTemp = strlen(szBuff);
4505                         pTempData = (char *)malloc(nTemp + 1);
4506                         if (pTempData == NULL) {
4507                                 MSG_DEBUG("__MmsBinaryDecodeEncodedString: Memory Full \n");
4508                                 goto __CATCH;
4509                         }
4510
4511                         memset(pTempData, 0, nTemp + 1);
4512                         memcpy(pTempData, szBuff, nTemp + 1);
4513
4514                         nByte = MsgGetLatin2UTFCodeSize((unsigned char*)pTempData, nTemp);
4515                         pConvertedStr = (char *)malloc(nByte + 1);
4516
4517                         if (pConvertedStr != NULL) {
4518                                 MsgLatin2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTempData, nTemp);
4519
4520                                 pNewData = pConvertedStr;
4521                                 nRead2 = nByte;
4522
4523                                 strncpy(szBuff, pNewData, bufLen - 1);
4524                         }
4525
4526                         break;
4527
4528                 } //switch (charset)
4529
4530         } //switch (__MmsDecodeValueLength....)
4531
4532         if (pData) {
4533                 free(pData);
4534                 pData = NULL;
4535         }
4536
4537         if (pTempData) {
4538                 free(pTempData);
4539                 pTempData = NULL;
4540         }
4541
4542         if (mszTempStr) {
4543                 free(mszTempStr);
4544                 mszTempStr = NULL;
4545         }
4546
4547         if (pConvertedStr) {
4548                 free(pConvertedStr);
4549                 pConvertedStr = NULL;
4550         }
4551
4552
4553         return true;
4554
4555 __CATCH:
4556
4557         if (pData) {
4558                 free(pData);
4559                 pData = NULL;
4560         }
4561
4562         if (pTempData) {
4563                 free(pTempData);
4564                 pTempData = NULL;
4565         }
4566
4567         if (mszTempStr) {
4568                 free(mszTempStr);
4569                 mszTempStr = NULL;
4570         }
4571
4572         if (pConvertedStr) {
4573                 free(pConvertedStr);
4574                 pConvertedStr = NULL;
4575         }
4576
4577         return false;
4578 }
4579
4580
4581
4582 /**
4583  * Decode Encoded Addresses
4584  *
4585  * @param       pEncodedData    [in] QuotedString encoded data
4586  * @param       pAddrLength             [out] Decoded address length
4587  * @return      Decoded address list
4588  */
4589 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
4590 {
4591         UINT32 valueLength      = 0;
4592         UINT32 charSet          = 0;
4593         int charSetLen  = 0;
4594         int textLength  = 0;
4595         char *pAddrStr  = NULL;
4596         MsgHeaderAddress *pAddr = NULL;
4597
4598         MSG_DEBUG("__MmsDecodeEncodedAddress: decoding address..\n");
4599
4600         if (pFile == NULL) {
4601                 MSG_DEBUG("__MmsDecodeEncodedAddress: invalid file or buffer\n");
4602                 goto __CATCH;
4603         }
4604
4605         /*
4606          * Encoded_string_value = Text-string | Value-length Char-set Text-String
4607          *                                                Text-string    = [Quote]*TEXT End-of-string
4608          *                                                Value-length   = 0 ~ 31
4609          */
4610
4611         switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
4612         case -1:
4613                 goto __CATCH;
4614
4615         case 0:
4616
4617                 /* Text-string = [Quote]*TEXT End-of-string */
4618
4619                 textLength = 0;
4620                 pAddrStr   = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4621                 if (pAddrStr == NULL) {
4622                         MSG_DEBUG("__MmsDecodeEncodedAddress : 1. __MmsBinaryDecodeText2 fail.\n");
4623                         goto __CATCH;
4624                 }
4625                 break;
4626
4627         default:
4628
4629                 /* Value-length Charset Text_string */
4630
4631                 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
4632                         MSG_DEBUG("__MmsDecodeEncodedAddress : __MmsBinaryDecodeCharset error\n");
4633                         goto __CATCH;
4634                 }
4635
4636                 textLength = 0;
4637                 pAddrStr   = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4638                 if (pAddrStr == NULL) {
4639                         /* There can be some error in data - no NULL -> try again with value length */
4640
4641                         pAddrStr = (char *)malloc(valueLength - charSetLen);
4642                         if (pAddrStr == NULL) {
4643                                 MSG_DEBUG("__MmsDecodeEncodedAddress : pData alloc fail.\n");
4644                                 goto __CATCH;
4645                         }
4646
4647                         if (_MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
4648                                 MSG_DEBUG("__MmsDecodeEncodedAddress : _MmsBinaryDecodeGetLongBytes fail.\n");
4649                                 goto __CATCH;
4650                         }
4651                 }
4652
4653                 /* fixme: charset transformation */
4654
4655                 break;
4656         }
4657
4658         pAddr = (MsgHeaderAddress *)malloc(sizeof(MsgHeaderAddress));
4659         if (pAddr == NULL)
4660                 goto __CATCH;
4661
4662         memset(pAddr, 0, sizeof(MsgHeaderAddress));
4663         pAddr->szAddr = pAddrStr;
4664
4665         return pAddr;
4666
4667 __CATCH:
4668
4669         if (pAddrStr) {
4670                 free(pAddrStr);
4671                 pAddrStr = NULL;
4672         }
4673
4674         return NULL;
4675 }
4676
4677
4678 /**
4679  * Decode Encoded Pointer String
4680  *
4681  * @param       pEncodedData    [in] Long integer encoded data
4682  * @param       pLongInteger    [out] Decoded long integer
4683  * @return      Decoded address list
4684  */
4685 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
4686 {
4687         UINT8 oneByte = 0;
4688
4689         /*
4690          * Long-integer = Short-length Multi-octet-integer
4691          *                                Short-length = 0~30
4692          *                                Multi-octet-integer
4693          */
4694
4695         if (pFile == NULL || pLongInteger == NULL)
4696                 return false;
4697
4698         *pLongInteger = 0;
4699
4700         if (_MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
4701                 goto __CATCH;
4702
4703         if (oneByte > 31)
4704                 goto __CATCH;
4705
4706         *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
4707
4708         return true;
4709
4710 __CATCH:
4711         return false;
4712 }
4713
4714
4715 /*
4716  * @param       pEncodedData    [in] filename encoded data
4717  * @param       szBuff                  [out] filename output buffer
4718  * @param       fullLength              [in] full filename length
4719  * @param       bufLen                  [in] buffer length
4720  * CAUTION: bufLen - 1
4721  */
4722 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
4723 {
4724         char *pUTF8Buff = NULL;
4725         char *pLatinBuff = NULL;
4726         char *pExt = NULL;
4727         char *szSrc = NULL;
4728         char *szSrc2 = NULL;
4729         int length = 0;
4730         int textLength = 0;
4731
4732         char *pTmpBuff = NULL;
4733
4734         memset (szBuff, 0, bufLen);
4735
4736         textLength = 0;
4737         pLatinBuff  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4738
4739         //remove ""
4740         if (pLatinBuff) {
4741                 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
4742                 if (szSrc) {
4743                         strcpy(pLatinBuff, szSrc);
4744                         free(szSrc);
4745                         szSrc = NULL;
4746                 }
4747
4748                 szSrc2 = MsgChangeHexString(pLatinBuff);
4749                 if (szSrc2) {
4750                         strcpy(pLatinBuff, szSrc2);
4751                         free(szSrc2);
4752                         szSrc2 = NULL;
4753                 }
4754
4755                 if (MsgIsUTF8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
4756                         length = strlen(pLatinBuff);
4757
4758                         int             utf8BufSize = 0;
4759                         utf8BufSize = MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
4760                         pUTF8Buff = (char *)malloc(utf8BufSize + 1);
4761                         if (pUTF8Buff == NULL) {
4762                                 MSG_DEBUG("__MmsDecodeGetFilename: pUTF8Buff alloc fail \n");
4763                                 goto __CATCH;
4764                         }
4765
4766                         if (MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
4767                                 MSG_DEBUG("__MmsDecodeGetFilename: MsgLatin2UTF fail \n");
4768                                 goto __CATCH;
4769                         }
4770                         free(pLatinBuff);
4771                         pLatinBuff = NULL;
4772                 } else {
4773                         pTmpBuff = _MsgDecodeText(pLatinBuff);
4774                         pUTF8Buff = pTmpBuff;
4775                         free (pLatinBuff);
4776                         pLatinBuff = NULL;
4777                 }
4778         }
4779
4780         if (pUTF8Buff) {
4781                 /*
4782                  * keeping extension
4783                  * it should be kept extention even if the file name is shorten
4784                  */
4785
4786                 length = strlen(pUTF8Buff);
4787                 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4788                         int nameLength  = 0;
4789                         nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
4790                         strncpy(szBuff, pUTF8Buff, nameLength);
4791                         strcat (szBuff, pExt);
4792                 } else {
4793                         strncpy(szBuff, pUTF8Buff, bufLen - 1);
4794                 }
4795                 free(pUTF8Buff);
4796                 pUTF8Buff = NULL;
4797
4798                 return textLength;
4799         }
4800
4801 __CATCH:
4802
4803         if (pLatinBuff) {
4804                 free(pLatinBuff);
4805                 pLatinBuff = NULL;
4806         }
4807
4808         if (pUTF8Buff) {
4809                 free(pUTF8Buff);
4810                 pUTF8Buff = NULL;
4811         }
4812
4813         return -1;
4814 }
4815
4816
4817 /* ==========================================================
4818
4819            T  E  X  T         D  E  C  O  D  I  N  G
4820
4821    ==========================================================*/
4822
4823
4824 bool MmsTextDecodeMsgBody(FILE *pFile)
4825 {
4826         MSG_DEBUG("MmsTextDecodeMsgBody: \n");
4827         return false;
4828 }
4829
4830 bool __MmsTextDecodeMsgHeader(FILE *pFile)
4831 {
4832         return true;
4833 }
4834
4835
4836 /* ==========================================================
4837
4838            M  M  S        D  E  C  O  D  I  N  G
4839
4840    ==========================================================*/
4841
4842 //  to get message body this function should be modified from message raw file.
4843 bool _MmsReadMsgBody(MSG_MESSAGE_ID_T msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
4844 {
4845         FILE *pFile     = NULL;
4846         MmsMsg *pMsg = NULL;
4847         MsgMultipart *pMultipart = NULL;
4848         int nSize = 0;
4849         char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
4850         char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
4851         int attachmax = MSG_ATTACH_MAX;
4852
4853         MSG_DEBUG("_MmsReadMsgBody: start read msg(msgID=%d)\n", msgID);
4854
4855         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
4856         memset(pMsg, 0, sizeof(MmsMsg));
4857
4858         _MmsInitHeader();
4859
4860         if (bRetrieved && (retrievedPath != NULL)) {
4861                 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
4862         } else {
4863                 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath);
4864         }
4865
4866         pMsg->msgID = msgID;
4867
4868         /*      read from MMS raw file  */
4869         if (szFullPath != NULL)
4870                 strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
4871
4872         MSG_DEBUG("szFullPath = (%s)", szFullPath);
4873
4874         if (MsgGetFileSize(szFullPath, &nSize) == false) {
4875                 MSG_DEBUG("MsgGetFileSize: failed");
4876                 goto __CATCH;
4877         }
4878
4879         pFile = MsgOpenFile(szFullPath, "rb");
4880
4881         if (pFile == NULL) {
4882                 MSG_DEBUG("_MmsReadMsgBody: invalid mailbox\n");
4883                 goto __CATCH;
4884         }
4885
4886         _MmsRegisterDecodeBuffer(gszMmsLoadBuf1, gszMmsLoadBuf2, MSG_MMS_DECODE_BUFFER_MAX);
4887
4888         if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
4889                 MSG_DEBUG("_MmsReadMsgBody: MmsBinaryDecodeMsgHeader fail...\n");
4890                 goto __CATCH;
4891         }
4892
4893 #ifdef  __SUPPORT_DRM__
4894         if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_FINISH)
4895                 MmsDrm2SetConvertState(MMS_DRM2_CONVERT_NONE);  //initialize convertState
4896 #endif
4897
4898         if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
4899                 MSG_DEBUG("_MmsReadMsgBody: MmsBinaryDecodeMsgBody fail\n");
4900                 goto __CATCH;
4901         }
4902
4903 #ifdef  __SUPPORT_DRM__
4904         if (MmsDrm2GetConvertState() == MMS_DRM2_CONVERT_REQUIRED) {
4905                 MSG_DEBUG("_MmsReadMsgBody: MmsDrm2GetConvertState returns MMS_DRM2_CONVERT_REQUIRED.\n");
4906                 goto RETURN;
4907         }
4908 #endif
4909
4910         /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
4911
4912         pMsg->mmsAttrib.contentType = (MsgContentType)mmsHeader.msgType.type;
4913
4914         memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
4915         memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
4916
4917         if (pMsg->msgBody.pPresentationBody) {
4918                 if(MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
4919                         goto __CATCH;
4920
4921                 pMsg->msgBody.pPresentationBody->body.pText = (char *)malloc(pMsg->msgBody.pPresentationBody->size + 1);
4922                 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
4923                         goto __CATCH;
4924
4925                 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
4926
4927                 ULONG nRead = 0;
4928                 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
4929                 if (nRead == 0)
4930                         goto __CATCH;
4931
4932         }
4933
4934         MsgCloseFile(pFile);
4935         pFile = NULL;
4936
4937         /* nPartCount */
4938         pMsg->nPartCount = 0;
4939
4940         if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
4941                 pMultipart = pMsg->msgBody.body.pMultipart;
4942                 while (pMultipart) {
4943                         pMsg->nPartCount++;
4944
4945                         if (pMultipart->type.type == MIME_TEXT_PLAIN)
4946                                 attachmax++;
4947
4948                         if ((mmsHeader.msgType.type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED)||(mmsHeader.msgType.type == MIME_MULTIPART_MIXED)) {
4949                                 if ((pMsg->nPartCount >= attachmax)&&(pMultipart->pNext != NULL)) {
4950                                         _MsgFreeBody(pMultipart->pNext->pBody, pMultipart->pNext->type.type);
4951
4952                                         free(pMultipart->pNext->pBody);
4953                                         pMultipart->pNext->pBody= NULL;
4954
4955                                         free(pMultipart->pNext);
4956
4957                                         pMultipart->pNext = NULL;
4958                                         break;
4959                                 }
4960                         }
4961                         pMultipart = pMultipart->pNext;
4962                 }
4963         } else {
4964                 if (pMsg->msgBody.size > 0)
4965                         pMsg->nPartCount++;
4966         }
4967
4968         /*      make temporary  */
4969         snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, MSG_DATA_PATH"%s.dir", pMsg->szFileName);
4970
4971         ///////////////////////////////////////////////
4972         // call before processing urgent event.
4973         //_MmsInitHeader();
4974         //_MmsUnregisterDecodeBuffer();
4975         ///////////////////////////////////////////////
4976
4977         if (MsgIsMultipart(pMsg->msgType.type) == true) {
4978                 int partIndex = 0;
4979                 pMultipart = pMsg->msgBody.body.pMultipart;
4980
4981                 if (bSavePartsAsTempFiles) {
4982                         if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
4983                                 if (errno == EEXIST) {
4984                                         MSG_DEBUG("The %s already exists", szTempMediaDir);
4985                                 } else {
4986                                         MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
4987                                         goto __CATCH;
4988                                 }
4989                         }
4990                 }
4991
4992                 while (pMultipart) {
4993
4994                         if (_MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
4995                                                                                         (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
4996                                 goto __CATCH;
4997
4998                         pMultipart = pMultipart->pNext;
4999                         partIndex ++;
5000                 }
5001
5002         } else { //single part
5003                 if (pMsg->nPartCount > 0) {
5004
5005                         if (bSavePartsAsTempFiles) {
5006                                 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
5007                                         if (errno == EEXIST) {
5008                                                 MSG_DEBUG("The %s already exists", szTempMediaDir);
5009                                         } else {
5010                                                 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
5011                                                 goto __CATCH;
5012                                         }
5013                                 }
5014                         }
5015
5016                         if (_MmsMultipartSaveAsTempFile( &pMsg->msgType, &pMsg->msgBody,
5017                                                                                         (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
5018                                 goto __CATCH;
5019                 }
5020         }
5021         MSG_DEBUG("****   _MmsReadMsgBody:  E  N  D   (Success)  ***\n");
5022         return true;
5023
5024 #ifdef  __SUPPORT_DRM__
5025
5026 RETURN:
5027
5028         if (pFile != NULL) {
5029                 MsgCloseFile(pFile);
5030                 pFile = NULL;
5031         }
5032
5033         return false;
5034
5035 #endif
5036
5037 __CATCH:
5038
5039         _MmsInitHeader();
5040         _MmsUnregisterDecodeBuffer();
5041
5042         if (pFile != NULL) {
5043                 MsgCloseFile(pFile);
5044                 pFile = NULL;
5045         }
5046
5047 #ifdef __SUPPORT_DRM__
5048         _MsgFreeDRMInfo(&pMsg->msgType.drmInfo);
5049 #endif
5050
5051         _MsgFreeBody(&pMsg->msgBody, pMsg->msgType.type);
5052         MSG_DEBUG("_MmsReadMsgBody:    E  N  D    (fail)    ******************** \n");
5053
5054         return false;
5055 }
5056
5057
5058 bool MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
5059 {
5060         MsgHeaderAddress *pTempAddr = NULL;
5061
5062         while (pAddr != NULL) {
5063                 pTempAddr = pAddr;
5064                 pAddr = pAddr->pNext;
5065
5066                 if (pTempAddr->szAddr) {
5067                         free(pTempAddr->szAddr);
5068                         pTempAddr->szAddr = NULL;
5069                 }
5070
5071                 free(pTempAddr);
5072                 pTempAddr = NULL;
5073         }
5074
5075         return true;
5076 }
5077
5078 bool MsgCheckFileNameHasInvalidChar(char *szName)
5079 {
5080         int     strLen = 0;
5081         int i = 0;
5082
5083         strLen = strlen(szName);
5084
5085         for (i=0; i<strLen; i++) {
5086                 if (__MsgIsInvalidFileNameChar(szName[i]))
5087                         return true;
5088         }
5089
5090         return false;
5091 }
5092
5093 bool _MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
5094 {
5095         int nCount = 0;
5096         int totalLength = 0;
5097
5098         totalLength = strlen(szInText);
5099
5100         while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
5101                 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
5102                         if (__MsgIsInvalidFileNameChar(szInText[nCount]))
5103                                 *(szInText+nCount) = replaceChar;
5104
5105                         nCount += 1;
5106                 } else {
5107                         nCount += 2;
5108                 }
5109         }
5110
5111         return true;
5112 }
5113
5114 char *_MsgGetStringUntilDelimiter(char *pszString, char delimiter)
5115 {
5116         char *pszBuffer = NULL;
5117         char *pszStrDelimiter = NULL;
5118         int     bufLength = 0;
5119
5120         if (!pszString) {
5121                 MSG_DEBUG("_MsgGetStringUntilDelimiter: pszString == NULL \n");
5122                 return NULL;
5123         }
5124
5125         if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
5126                 MSG_DEBUG("_MsgGetStringUntilDelimiter: There is no %c in %s. \n", delimiter, pszString);
5127                 return NULL;
5128         }
5129
5130         bufLength = pszStrDelimiter - pszString;
5131
5132         if ((pszBuffer = (char*)malloc (bufLength + 1)) == NULL) {
5133                 MSG_DEBUG("malloc is failed");
5134                 return NULL;
5135         }
5136         memset(pszBuffer, 0, bufLength + 1) ;
5137
5138         strncat(pszBuffer, pszString, bufLength);
5139
5140         return pszBuffer;
5141 }
5142
5143 char *MsgChangeHexString(char *pOrg)
5144 {
5145         char *pNew = NULL;
5146         char szBuf[10] = {0,};
5147         char OneChar;
5148         int cLen = 0;
5149         int cIndex =0;
5150         int index = 0;
5151
5152         if (pOrg == NULL)
5153                 return false;
5154
5155         cLen = strlen(pOrg);
5156
5157         pNew = (char *)malloc(cLen + 1);
5158         if (pNew == NULL)
5159                 return NULL;
5160
5161         memset(pNew, 0, cLen + 1);
5162
5163         for (cIndex = 0; cIndex< cLen ; cIndex++) {
5164                 if (pOrg[cIndex] == '%') {
5165                         if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0)         {
5166                                 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); // read two chars after '%'
5167
5168                                 if (MsgIsHexChar(szBuf) == true) { // check the two character is between  0 ~ F
5169                                         OneChar = _MsgConvertHexValue(szBuf);
5170
5171                                         pNew[index] = OneChar;
5172                                         index++;
5173                                         cIndex+= 2;
5174                                         continue;
5175                                 }
5176                         }
5177                 }
5178                 pNew[index++] = pOrg[cIndex];
5179         }
5180         return pNew;
5181 }
5182
5183 bool _MsgParseParameter(MsgType *pType, char *pSrc)
5184 {
5185         char *pName = NULL;
5186         char *pValue = NULL;
5187         char *pDec = NULL;
5188         char *pTest = NULL;
5189         char *pNextParam = NULL;
5190         char *pExt = NULL;
5191         int nameLen = 0;
5192         int count;
5193         char *pTempNextParam = NULL;
5194         char *pCh = NULL;
5195         char *szSrc = NULL;
5196         char *pUTF8Buff = NULL;
5197
5198         while (pSrc != NULL) {
5199                 pSrc = _MsgSkipWS(pSrc);
5200                 if (pSrc == NULL) {
5201                         /* End of parse parameter */
5202                         return true;
5203                 }
5204
5205                 pNextParam = NULL;
5206                 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
5207                 pCh = pSrc;
5208
5209                 if (*pCh == MSG_CH_QUOT) {
5210                         count = 1;
5211                 } else {
5212                         count = 0;
5213                 }
5214
5215                 pCh++;
5216                 for (; pCh<=pTempNextParam ; pCh++) {
5217                         if (*pCh == MSG_CH_QUOT)
5218                                 if (*(pCh - 1) != '\\')
5219                                         count++;
5220                 }
5221
5222                 if (count%2 == 0)
5223                         pNextParam = pTempNextParam;
5224
5225                 if (pNextParam)
5226                         *pNextParam++ = MSG_CH_NULL;
5227
5228                 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
5229                         *pName++ = MSG_CH_NULL;
5230
5231                         if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
5232                                 *pValue++ = MSG_CH_NULL;
5233
5234                                 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
5235                                         *pTest = MSG_CH_NULL;
5236
5237                                 pDec = _MsgDecodeText(pValue);          // Api is to long, consider Add to another file (MsgMIMECodec.c)
5238                         } else {
5239                                 pDec = _MsgDecodeText(pName);
5240                         }
5241
5242                         switch (_MsgGetCode(MSG_PARAM, pSrc)) {
5243                         case MSG_PARAM_BOUNDARY:
5244
5245                                 /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
5246
5247                                 memset (pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
5248                                 strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
5249                                 MSG_DEBUG("_MsgParseParameter: szBoundary = %s \n", pType->param.szBoundary);
5250                                 break;
5251
5252                         case MSG_PARAM_CHARSET:
5253                                 pType->param.charset = _MsgGetCode(MSG_CHARSET, pDec);
5254
5255                                 if (pType->param.charset == INVALID_HOBJ)
5256                                         pType->param.charset = MSG_CHARSET_UNKNOWN;
5257
5258                                 MSG_DEBUG("_MsgParseParameter: type = %d    [charset] = %d \n", pType->type, pType->param.charset);
5259                                 break;
5260
5261                         case MSG_PARAM_NAME:
5262
5263                                 memset (pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
5264
5265                                 pUTF8Buff = MsgConvertLatin2UTF8FileName(pDec);
5266
5267                                 if (pUTF8Buff) {
5268                                         if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
5269                                                 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
5270                                                         nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
5271                                                 } else {
5272                                                         nameLen = strlen(pUTF8Buff) - strlen(pExt);
5273                                                 }
5274
5275                                                 strncpy(pType->param.szName, pUTF8Buff, nameLen);
5276                                                 strcat (pType->param.szName, pExt);
5277                                         } else {
5278                                                 strncpy(pType->param.szName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
5279                                         }
5280                                         free(pUTF8Buff);
5281                                         pUTF8Buff = NULL;
5282
5283                                         if (_MsgChangeSpace(pType->param.szName, &szSrc) == true) {
5284                                                 if (szSrc)
5285                                                         strncpy(pType->param.szName, szSrc , strlen(szSrc));
5286                                         }
5287
5288                                         if (szSrc) {
5289                                                 free(szSrc);
5290                                                 szSrc = NULL;
5291                                         }
5292
5293                                         // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
5294                                         _MsgRemoveFilePath(pType->param.szName);
5295                                 } else {
5296                                         MSG_DEBUG("_MsgParseParameter: MsgConvertLatin2UTF8FileName(%s) return NULL\n", pDec);
5297                                 }
5298
5299                                 MSG_DEBUG("_MsgParseParameter: szName = %s \n", pType->param.szName);
5300                                 break;
5301
5302                         case MSG_PARAM_FILENAME:
5303
5304                                 memset (pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
5305
5306                                 pUTF8Buff = MsgConvertLatin2UTF8FileName(pDec);
5307
5308                                 if (pUTF8Buff) {
5309                                         if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
5310                                                 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
5311                                                         nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
5312                                                 } else {
5313                                                         nameLen = strlen(pUTF8Buff) - strlen(pExt);
5314                                                 }
5315
5316                                                 strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
5317                                                 strcat (pType->param.szFileName, pExt);
5318                                         } else {
5319                                                 strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
5320                                         }
5321                                         free(pUTF8Buff);
5322                                         pUTF8Buff = NULL;
5323
5324                                         if (_MsgChangeSpace(pType->param.szFileName, &szSrc) == true)
5325                                                 strcpy(pType->param.szFileName, szSrc);
5326
5327                                         if (szSrc) {
5328                                                 free(szSrc);
5329                                                 szSrc = NULL;
5330                                         }
5331
5332                                         // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
5333                                         _MsgRemoveFilePath(pType->param.szFileName);
5334                                 } else {
5335                                         MSG_DEBUG("_MsgParseParameter: MsgConvertLatin2UTF8FileName(%s) return NULL\n", pDec);
5336                                 }
5337
5338                                 MSG_DEBUG("_MsgParseParameter: szFileName = %s \n", pType->param.szFileName);
5339
5340                                 break;
5341
5342                         case MSG_PARAM_TYPE:
5343
5344                                 /* type/subtype of root. Only if content-type is multipart/related */
5345
5346                                 pType->param.type = _MsgGetCode(MSG_TYPE, pDec);
5347                                 MSG_DEBUG("_MsgParseParameter: type = %d \n", pType->param.type);
5348
5349                                 break;
5350
5351                         case MSG_PARAM_START:
5352
5353                                 /* Content-id. Only if content-type is multipart/related */
5354
5355                                 memset (pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
5356                                 strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
5357
5358                                 MSG_DEBUG("_MsgParseParameter: szStart = %s \n", pType->param.szStart);
5359
5360                                 break;
5361
5362                         case MSG_PARAM_START_INFO :
5363
5364                                 /* Only if content-type is multipart/related */
5365
5366                                 memset (pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
5367                                 strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
5368
5369                                 MSG_DEBUG("_MsgParseParameter: szStartInfo = %s \n", pType->param.szStartInfo);
5370
5371                                 break;
5372
5373                         case MSG_PARAM_REPORT_TYPE :
5374
5375                                 //  only used as parameter of Content-Type: multipart/report; report-type=delivery-status;
5376
5377                                 if (pDec != NULL && strcasecmp(pDec, "delivery-status") == 0) {
5378                                         pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
5379                                 } else {
5380                                         pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
5381                                 }
5382
5383                                 MSG_DEBUG("_MsgParseParameter: reportType = %s \n", pDec);
5384                                 break;
5385
5386                         default:
5387
5388                                 MSG_DEBUG("_MsgParseParameter: Unknown paremeter (%s)\n", pDec);
5389                                 break;
5390                         }
5391
5392                         if (pDec) {
5393                                 free(pDec);
5394                                 pDec = NULL;
5395                         }
5396                 }
5397                 pSrc = pNextParam;
5398         }
5399         return true;
5400 }
5401
5402 char *_MsgSkipWS(char *s)
5403 {
5404         while (true) {
5405                 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
5406                         ++s;
5407                 } else if ((*s != '(') || (__MsgSkipComment(s,(long)NULL)==NULL)) {
5408                         return s;
5409                 }
5410         }
5411 }
5412
5413 char *__MsgSkipComment (char *s,long trim)
5414 {
5415
5416         char *ret;
5417         char *s1 = s;
5418         char *t = NULL;
5419
5420         // ignore empty space
5421         for (ret = ++s1; *ret == ' '; ret++)
5422                 ;
5423
5424         // handle '(', ')', '\',  '\0'
5425         do {
5426                 switch (*s1) {
5427                 case '(':
5428                         if (!__MsgSkipComment (s1,(long)NULL))
5429                                 return NULL;
5430                         t = --s1;
5431                         break;
5432                 case ')':
5433                         s = ++s1;
5434                         if (trim) {
5435                                 if (t) {
5436                                         t[1] = '\0';
5437                                 } else {
5438                                         *ret = '\0';
5439                                 }
5440                         }
5441                         return ret;
5442                 case '\\':
5443                         if (*++s1)
5444                                 break;
5445                 case '\0':
5446                         *s = '\0';
5447                         return NULL;
5448                 case ' ':
5449                         break;
5450                 default:
5451                         t = s1;
5452                         break;
5453                 }
5454         }while (s1++);
5455
5456         return NULL;
5457 }
5458
5459 char *MsgConvertLatin2UTF8FileName(char *pSrc)
5460 {
5461         char *pUTF8Buff  = NULL;
5462         char *pData = NULL;
5463
5464
5465         //convert utf8 string
5466         if (MsgIsUTF8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
5467                 int length  = 0;
5468                 int utf8BufSize = 0;
5469
5470                 length = strlen(pSrc);
5471                 utf8BufSize = MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
5472                 pUTF8Buff = (char *)malloc(utf8BufSize + 1);
5473
5474                 if (pUTF8Buff == NULL) {
5475                         MSG_DEBUG("MsgConvertLatin2UTF8FileName: pUTF8Buff alloc fail \n");
5476                         goto __CATCH;
5477                 }
5478
5479                 if (MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
5480                         MSG_DEBUG("MsgConvertLatin2UTF8FileName: MsgLatin2UTF fail \n");
5481                         goto __CATCH;
5482                 }
5483         } else {
5484                 int length = strlen(pSrc);
5485                 pUTF8Buff = (char *)calloc(1, length+1);
5486
5487                 if (pUTF8Buff == NULL) {
5488                         MSG_DEBUG("MsgConvertLatin2UTF8FileName: pUTF8Buff alloc fail \n");
5489                         goto __CATCH;
5490                 }
5491
5492                 memcpy(pUTF8Buff, pSrc, length);
5493         }
5494
5495         //convert hex string
5496         if (MsgIsPercentSign(pUTF8Buff) == true) {
5497                 pData = MsgChangeHexString(pUTF8Buff);
5498                 if (pData) {
5499                         strcpy(pUTF8Buff, pData);
5500                         free(pData);
5501                         pData = NULL;
5502                 }
5503         }
5504
5505         return pUTF8Buff;
5506
5507 __CATCH:
5508
5509         if (pUTF8Buff) {
5510                 free(pUTF8Buff);
5511                 pUTF8Buff = NULL;
5512         }
5513         if (pData) {
5514                 free(pData);
5515                 pData = NULL;
5516         }
5517         return NULL;
5518 }
5519
5520 bool _MsgChangeSpace(char *pOrg, char **ppNew)
5521 {
5522         char *pNew = NULL;
5523         int cLen = 0;
5524         int cIndex =0;
5525         int index = 0;
5526
5527         if (pOrg == NULL)
5528                 return false;
5529
5530         cLen = strlen(pOrg);
5531
5532         pNew = (char *)malloc(cLen + 1);
5533         if (pNew == NULL)
5534                 return false;
5535
5536         memset(pNew, 0, cLen + 1);
5537
5538         for (cIndex=0; cIndex<cLen;cIndex++) {
5539                 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
5540                         pNew[index] = ' ';
5541                         index++;
5542                         cIndex+= 2;
5543                         continue;
5544                 }
5545                 pNew[index++] = pOrg[cIndex];
5546         }
5547
5548         *ppNew = pNew;
5549
5550         return true;
5551 }
5552
5553 void _MsgRemoveFilePath(char *pSrc)
5554 {
5555         // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
5556         char *pPath = NULL;
5557         char *pTemp = NULL;
5558         char szFileName[MSG_FILENAME_LEN_MAX] = {0};
5559
5560         if (pSrc == NULL)
5561                 return;
5562
5563         pTemp = pSrc;
5564         while ((pTemp = strchr(pTemp, '/')) != NULL) {
5565                 // Find the last  '/'
5566                 pPath = pTemp;
5567                 pTemp++;
5568         }
5569
5570         if (pPath) {
5571                 MSG_DEBUG("_MsgRemoveFilePath: filename(%s)\n", pSrc);
5572
5573                 // case : images/vf7.gif -> vf7.gif
5574                 if (pPath != NULL && *(pPath+1) != '\0') {
5575                         strncpy(szFileName, pPath+1, strlen(pPath+1));
5576                         strncpy(pSrc, szFileName , strlen(szFileName));
5577                 }
5578         }
5579         // Remove additional file information
5580         // ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
5581         // if "?size=" exist, insert NULL char.
5582         {
5583                 pTemp = strcasestr(pSrc, "?size=");
5584                 if (pTemp != NULL)
5585                         *pTemp = '\0';
5586         }
5587 }
5588
5589 bool MsgIsUTF8String(unsigned char *szSrc, int nChar)
5590 {
5591         MSG_DEBUG("MsgIsUTF8String: --------------- \n");
5592
5593         if (szSrc == NULL) {
5594                 MSG_DEBUG("MsgIsUTF8String: szSrc is NULL !!!! --------------- \n");
5595                 return true;
5596         }
5597
5598         while (nChar > 0 && (*szSrc != '\0')) {
5599                 if (*szSrc < 0x80) {
5600                         szSrc++;
5601                         nChar--;
5602                 } else if ((0xC0 <= *szSrc) && (*szSrc < 0xE0)) {
5603                         if (*(szSrc + 1) >= 0x80) {
5604                                 szSrc += 2;
5605                                 nChar -= 2;
5606                         } else {
5607                                 MSG_DEBUG("MsgIsUTF8String: 1. NOT utf8 range!\n");
5608                                 goto __CATCH;
5609                         }
5610                 } else if (*szSrc >= 0xE0) {
5611                         if (*(szSrc + 1) >= 0x80) {
5612                                 if (*(szSrc + 2) >= 0x80) {
5613                                         szSrc += 3;
5614                                         nChar -= 3;
5615                                 } else {
5616                                         MSG_DEBUG("MsgIsUTF8String: 2. NOT utf8 range!\n");
5617                                         goto __CATCH;
5618                                 }
5619                         } else {
5620                                 MSG_DEBUG("MsgIsUTF8String: 3. NOT utf8 range!\n");
5621                                 goto __CATCH;
5622                         }
5623                 } else {
5624                         MSG_DEBUG("MsgIsUTF8String: 4. NOT utf8 range!\n");
5625                         goto __CATCH;
5626                 }
5627         }
5628
5629         return true;
5630
5631 __CATCH:
5632         return false;
5633 }
5634
5635 bool MsgIsPercentSign(char *pSrc)
5636 {
5637         char *pCh = NULL;
5638         bool bRet = false;
5639
5640         pCh = strchr(pSrc , '%');
5641
5642         if (pCh != NULL) {
5643                 bRet = true;
5644         } else {
5645                 bRet = false;
5646         }
5647
5648         return bRet;
5649 }
5650
5651 MsgMultipart *MsgAllocMultipart(void)
5652 {
5653         MsgMultipart *pMultipart = NULL;
5654
5655         MSG_DEBUG("MsgAllocMultipart: --------- \n");
5656
5657         pMultipart = (MsgMultipart*)malloc(sizeof(MsgMultipart));
5658         if (pMultipart == NULL) {
5659                 MSG_DEBUG("MsgAllocMultipart: pMultipart malloc Fail \n");
5660                 goto __CATCH;
5661         }
5662
5663         pMultipart->pBody = (MsgBody*)malloc(sizeof(MsgBody));
5664         if (pMultipart->pBody == NULL) {
5665                 MSG_DEBUG("MsgAllocMultipart: pMultipart->pBody malloc Fail \n");
5666                 goto __CATCH;
5667         }
5668
5669         _MsgInitMsgType(&pMultipart->type);
5670         _MsgInitMsgBody(pMultipart->pBody);
5671
5672         pMultipart->pNext = NULL;
5673
5674         return pMultipart;
5675
5676 __CATCH:
5677
5678         if (pMultipart) {
5679                 if (pMultipart->pBody) {
5680                         free(pMultipart->pBody);
5681                         pMultipart->pBody = NULL;
5682                 }
5683
5684                 free(pMultipart);
5685                 pMultipart = NULL;
5686         }
5687
5688         return NULL;
5689 }
5690
5691 bool _MsgInitMsgType(MsgType *pMsgType)
5692 {
5693         pMsgType->offset = 0;
5694         pMsgType->size = 0;
5695         pMsgType->contentSize = 0;
5696         pMsgType->disposition = 0;
5697         pMsgType->encoding = 0;
5698         pMsgType->type = MIME_UNKNOWN;
5699 #ifdef FEATURE_JAVA_MMS_MIME
5700         pMsgType->szMimeString[0] ='\0';
5701 #endif
5702         pMsgType->section = 0;
5703
5704         pMsgType->szOrgFilePath[0] = '\0';
5705         pMsgType->szContentID[0] = '\0';
5706         pMsgType->szContentLocation[0] = '\0';
5707
5708         pMsgType->szContentRepPos[0] = '\0';
5709         pMsgType->szContentRepSize[0] = '\0';
5710         pMsgType->szContentRepIndex[0] = '\0';
5711
5712         __MsgInitMsgContentParam(&pMsgType->param);
5713 #ifdef __SUPPORT_DRM__
5714         __MsgInitMsgDRMInfo(&pMsgType->drmInfo);
5715 #endif
5716
5717         return true;
5718 }
5719
5720
5721 bool __MsgInitMsgContentParam(MsgContentParam *pMsgContentParam)
5722 {
5723         pMsgContentParam->charset = MSG_CHARSET_UNKNOWN;
5724         pMsgContentParam->type = MIME_UNKNOWN;
5725         pMsgContentParam->szBoundary[0] = '\0';
5726         pMsgContentParam->szFileName[0] = '\0';
5727         pMsgContentParam->szName[0] = '\0';
5728 #ifdef FEATURE_JAVA_MMS
5729         pMsgContentParam->szApplicationID = NULL;
5730         pMsgContentParam->szReplyToApplicationID = NULL;
5731 #endif
5732         pMsgContentParam->szStart[0] = '\0';
5733         pMsgContentParam->szStartInfo[0] = '\0';
5734         pMsgContentParam->pPresentation = NULL;
5735
5736         pMsgContentParam->reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN; //  add only used as parameter of Content-Type: multipart/report; report-type
5737
5738         return true;
5739 }
5740
5741
5742 bool _MsgInitMsgBody(MsgBody *pMsgBody)
5743 {
5744         pMsgBody->offset = 0;
5745         pMsgBody->size = 0;
5746         pMsgBody->body.pText = NULL;
5747         pMsgBody->szOrgFilePath[0] = '\0';
5748
5749         _MsgInitMsgType(&pMsgBody->presentationType);
5750         pMsgBody->pPresentationBody = NULL;
5751
5752         memset(pMsgBody->szOrgFilePath, 0, MSG_FILEPATH_LEN_MAX);
5753
5754         return true;
5755 }
5756
5757
5758 MsgPresentationFactor MsgIsPresentationEx(MsgType *multipartType, char* szStart, MsgContentType typeParam)
5759 {
5760         char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
5761         char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
5762         char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
5763         int strLen = 0;
5764
5765         // remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445>
5766         if (szStart && szStart[0]) {
5767                 int startLen = 0;
5768                 startLen = strlen(szStart);
5769                 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
5770                         strncpy(szTmpStart, &szStart[1], startLen - 2);
5771                 } else {
5772                         strncpy(szTmpStart, szStart, startLen);
5773                 }
5774         }
5775
5776         // remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445>
5777         if (multipartType->szContentID[0])      {
5778                 strLen = strlen(multipartType->szContentID);
5779                 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
5780                         strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
5781                 } else {
5782                         strncpy(szTmpContentID, multipartType->szContentID, strLen);
5783                 }
5784         }
5785
5786         // remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445>
5787         if (multipartType->szContentLocation[0]) {
5788                 strLen = strlen(multipartType->szContentLocation);
5789                 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
5790                         strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
5791                 } else {
5792                         strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
5793                 }
5794         }
5795
5796         if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
5797                 return  MSG_PRESENTATION_NONE;
5798
5799         // exception handling
5800         if (szTmpStart[0] != '\0') {
5801                 // presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type
5802                 if (strcmp(szTmpStart, szTmpContentID) == 0) {
5803                         return MSG_PRESENTATION_ID;
5804                 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
5805                         return   MSG_PRESENTATION_LOCATION;
5806                 } else if (multipartType->type == typeParam) {
5807                         return   MSG_PRESENTATION_TYPE_BASE;
5808                 } else {
5809                         return   MSG_PRESENTATION_NONE;
5810                 }
5811         } else {
5812                 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
5813                         return   MSG_PRESENTATION_TYPE_BASE;
5814                 } else {
5815                         return   MSG_PRESENTATION_NONE;
5816                 }
5817         }
5818 }
5819
5820 void MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
5821 {
5822         MSG_BEGIN();
5823         MsgMultipart *pNextPart = NULL;
5824         MsgMultipart *pRemovePart = NULL;
5825
5826         if (MsgIsMultipartRelated(pMsgType->type)) {
5827                 // assign the multipart to presentation part
5828                 // remove the multipart(pCurPresentation) which is presentation part from the linked list.
5829                 // if there is no presentation part -> assign first multipart to presentation part by force.
5830                 if (pPresentationInfo->pCurPresentation == NULL) {
5831                         pPresentationInfo->pCurPresentation     = pMsgBody->body.pMultipart;
5832                         pPresentationInfo->pPrevPart            = NULL;
5833                         pPresentationInfo->factor                       = MSG_PRESENTATION_NONE;
5834                 }
5835
5836                 if (pPresentationInfo->pCurPresentation != NULL && MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
5837                         /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
5838                          * In this case, COPY the Presentation part and leave other multiparts.
5839                          */
5840                         memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
5841                         pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
5842
5843                         // remove pCurPresentation from multipart linked list
5844                         if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE)||(pPresentationInfo->pPrevPart == NULL)) {
5845                                 // first part
5846                                 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
5847                                 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
5848                                 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
5849                                 if (pPresentationInfo->pCurPresentation) {
5850 #ifdef __SUPPORT_DRM__
5851                                         _MsgFreeDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
5852 #endif
5853                                         free(pPresentationInfo->pCurPresentation);
5854                                         pPresentationInfo->pCurPresentation = NULL;
5855                                 }
5856                         } else {
5857                                 // not a first part
5858                                 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
5859                                 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
5860                                 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
5861                                 if (pPresentationInfo->pCurPresentation) {
5862                                         free(pPresentationInfo->pCurPresentation);
5863                                         pPresentationInfo->pCurPresentation = NULL;
5864                                 }
5865                         }
5866                 } else if (pPresentationInfo->pCurPresentation != NULL && MsgIsText(pPresentationInfo->pCurPresentation->type.type)) {
5867                         /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
5868                          * In this case, leave the Presentation part as a multipart and remove other multiparts.
5869                          */
5870
5871                         // Backup the multipart link information
5872                         pNextPart = pMsgBody->body.pMultipart;
5873
5874                         // Copy presentation part as a main part
5875                         memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
5876                         memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
5877
5878                         // Remove multipart linked list
5879                         while (pNextPart) {
5880                                 pRemovePart = pNextPart;
5881                                 pNextPart = pNextPart->pNext;
5882
5883                                 if (pRemovePart->pBody) {
5884                                         _MsgFreeBody(pRemovePart->pBody, pRemovePart->type.type);
5885                                         free(pRemovePart->pBody);
5886                                         pRemovePart->pBody = NULL;
5887                                 }
5888
5889                                 free(pRemovePart);
5890                                 pRemovePart = NULL;
5891                         }
5892                 } else {
5893 #ifdef __SUPPORT_DRM__
5894                         _MsgFreeDRMInfo(&pMsgBody->presentationType.drmInfo);
5895 #endif
5896                         _MsgInitMsgType(&pMsgBody->presentationType);
5897                         pMsgBody->pPresentationBody = NULL;
5898                 }
5899         }
5900         MSG_END();
5901 }
5902
5903 bool MsgIsMultipartRelated(int type)
5904 {
5905         if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
5906                 return true;
5907         } else {
5908                 return false;
5909         }
5910 }
5911
5912 bool MsgIsPresentablePart(int type)
5913 {
5914         if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
5915                 return true;
5916         } else {
5917                 return false;
5918         }
5919 }
5920
5921 #ifdef __SUPPORT_DRM__
5922 void _MsgFreeDRMInfo(MsgDRMInfo *pDrmInfo)
5923 {
5924         MSG_DEBUG("_MsgFreeDRMInfo: S T A R T  !!! \n");
5925
5926         if (pDrmInfo == NULL) {
5927                 MSG_DEBUG("pDrmInfo is NULL");
5928                 return;
5929         }
5930
5931         if (pDrmInfo->szContentDescription) {
5932                 free(pDrmInfo->szContentDescription);
5933                 pDrmInfo->szContentDescription = NULL;
5934         }
5935
5936         if (pDrmInfo->szContentVendor) {
5937                 free(pDrmInfo->szContentVendor);
5938                 pDrmInfo->szContentVendor = NULL;
5939         }
5940
5941         if (pDrmInfo->szContentName) {
5942                 free(pDrmInfo->szContentName);
5943                 pDrmInfo->szContentName = NULL;
5944         }
5945
5946         if (pDrmInfo->szContentURI) {
5947                 free(pDrmInfo->szContentURI);
5948                 pDrmInfo->szContentURI = NULL;
5949         }
5950
5951         if (pDrmInfo->szRightIssuer) {
5952                 free(pDrmInfo->szRightIssuer);
5953                 pDrmInfo->szRightIssuer = NULL;
5954         }
5955
5956         if (pDrmInfo->szDrm2FullPath) {
5957                 free(pDrmInfo->szDrm2FullPath);
5958                 pDrmInfo->szDrm2FullPath = NULL;
5959         }
5960
5961 #if MMS_ENABLE_EXTEND_CFM
5962         // DRM (Extended)CFM
5963         if (pDrmInfo->pszContentType) {
5964                 free(pDrmInfo->pszContentType);
5965                 pDrmInfo->pszContentType = NULL;
5966         }
5967 #endif
5968
5969         pDrmInfo->contentType = MIME_UNKNOWN;
5970         pDrmInfo->drmType = MSG_DRM_TYPE_NONE;
5971 }
5972
5973 bool MsgCopyDrmInfo(MsgType *pPartType)
5974 {
5975         char *pExt = NULL;
5976         char *pTmpBuf = NULL;
5977
5978         //convert application/vnd.oma.drm.content to media type
5979         pPartType->type = pPartType->drmInfo.contentType;
5980
5981         // fix wrong file name presentation on save media screen.
5982         if (pPartType->szContentID[0] == '\0' && pPartType->drmInfo.szContentURI)
5983                 strncpy(pPartType->szContentID, pPartType->drmInfo.szContentURI, MSG_MSG_ID_LEN);
5984
5985         /* set title name (content name) */
5986         if (pPartType->param.szName[0] == '\0') {
5987                 /*      szName is vitual name, real filename is *.dcf or *.dm   */
5988                 if (pPartType->drmInfo.szContentName && pPartType->drmInfo.szContentName[0] != '\0') {
5989                         /* In case of szContentName retrieved from DRM agent is exist. */
5990                         pTmpBuf = pPartType->drmInfo.szContentName;
5991                 } else if (pPartType->szContentLocation[0] != '\0')     {
5992                         /* In case of szContentLocation parsed from MMS header */
5993                         pTmpBuf = strrchr(pPartType->szContentLocation, '/');
5994                         if (pTmpBuf == NULL)
5995                                 pTmpBuf = pPartType->szContentLocation;
5996                 } else {
5997                         /* use another name */
5998                         /* possible NULL pointer assignment*/
5999                         pTmpBuf = strdup("untitled");
6000                 }
6001
6002                 if ((pExt = strrchr(pTmpBuf, '.')) != NULL) {
6003                         int extLen = 0;
6004                         int fileNameLen = 0;
6005                         int tmpLen = 0;
6006
6007                         extLen = strlen(pExt);
6008                         tmpLen = strlen(pTmpBuf);
6009                         fileNameLen = (tmpLen - extLen < MSG_LOCALE_FILENAME_LEN_MAX - extLen)?(tmpLen - extLen):(MSG_LOCALE_FILENAME_LEN_MAX - extLen);
6010                         strncpy(pPartType->param.szName, pTmpBuf, fileNameLen);
6011                         strcpy (pPartType->param.szName + fileNameLen, pExt);
6012                 } else {
6013                         strncpy(pPartType->param.szName, pTmpBuf, MSG_LOCALE_FILENAME_LEN_MAX);
6014                         MsgMakeFileName(pPartType->type, pPartType->param.szName, MSG_DRM_TYPE_NONE, 0);
6015                 }
6016         }
6017
6018         return true;
6019 }
6020
6021 #endif
6022
6023 bool MsgIsText(int type)
6024 {
6025         if (type == MIME_TEXT_PLAIN || type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML ||
6026                 type == MIME_TEXT_X_VNOTE || type == MIME_APPLICATION_SMIL || type == MIME_TEXT_X_IMELODY) {
6027                 return true;
6028         } else {
6029                 return false;
6030         }
6031 }
6032
6033 bool MsgFreeAttrib(MmsAttrib *pAttrib)
6034 {
6035         MSG_BEGIN();
6036
6037         if (pAttrib == NULL) {
6038                 MSG_DEBUG("pAttrib is NULL");
6039                 return false;
6040         }
6041
6042         if (pAttrib->szTo) {
6043                 free(pAttrib->szTo);
6044                 pAttrib->szTo = NULL;
6045         }
6046
6047         if (pAttrib->szCc) {
6048                 free(pAttrib->szCc);
6049                 pAttrib->szCc = NULL;
6050         }
6051
6052         if (pAttrib->szBcc) {
6053                 free(pAttrib->szBcc);
6054                 pAttrib->szBcc = NULL;
6055         }
6056
6057         //check if pMultiStatus should be freed or not, because pMultiStatus is not allocated
6058         if (pAttrib->pMultiStatus) {
6059                 MmsMsgMultiStatus *pMultiStatus = pAttrib->pMultiStatus;
6060                 MmsMsgMultiStatus *pCurStatus = NULL;
6061
6062                 while (pMultiStatus != NULL ) {
6063                         pCurStatus = pMultiStatus;
6064                         pMultiStatus = pMultiStatus->pNext;
6065
6066                         if (pCurStatus) {
6067                                 free(pCurStatus);
6068                                 pCurStatus = NULL;
6069                         }
6070                 }
6071
6072                 pAttrib->pMultiStatus = NULL;
6073         }
6074
6075
6076         MSG_END();
6077
6078         return true;
6079 }
6080
6081 bool _MsgFreeBody(MsgBody *pBody, int type)
6082 {
6083         MSG_DEBUG("_MsgFreeBody: S T A R T  !!! \n") ;
6084
6085         if (pBody == NULL) {
6086                 MSG_DEBUG("_MsgFreeBody: pBody == NULL \n" );
6087                 MSG_DEBUG("_MsgFreeBody: E  N  D   (End)!!! \n") ;
6088
6089                 return false;
6090         }
6091
6092         switch (type) {
6093         case MIME_MULTIPART_REPORT:
6094         case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
6095         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
6096         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
6097         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
6098         case MIME_MULTIPART_MIXED:
6099         case MIME_MULTIPART_RELATED:
6100         case MIME_MULTIPART_ALTERNATIVE:
6101         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
6102                 {
6103                         MsgMultipart *pMulti = pBody->body.pMultipart;
6104                         MsgMultipart *pCurrPart = NULL;
6105                         MsgBody *pPresentation = pBody->pPresentationBody;
6106                         while (pMulti != NULL) {
6107                                 pCurrPart = pMulti;
6108
6109                                 pMulti = pMulti->pNext;
6110
6111                                 if (pCurrPart) {
6112 #ifdef __SUPPORT_DRM__
6113                                         _MsgFreeDRMInfo(&pCurrPart->type.drmInfo);
6114 #endif
6115
6116                                         if (pCurrPart->pBody) {
6117                                                 if (pCurrPart->pBody->body.pBinary) {
6118                                                         free(pCurrPart->pBody->body.pBinary);
6119                                                         pCurrPart->pBody->body.pBinary = NULL;
6120                                                 }
6121                                                 free(pCurrPart->pBody);
6122                                                 pCurrPart->pBody = NULL;
6123                                         }
6124                                         free(pCurrPart);
6125                                         pCurrPart = NULL;
6126                                 }
6127                         }
6128
6129                         pBody->body.pMultipart = NULL;
6130
6131                         if (pPresentation) {
6132                                 if (pPresentation->body.pText) {
6133                                         free(pPresentation->body.pText);
6134                                         pPresentation->body.pText = NULL;
6135                                 }
6136                                 free(pPresentation);
6137                                 pBody->pPresentationBody = NULL;
6138                         }
6139
6140                         _MsgInitMsgType(&pBody->presentationType);
6141
6142                         break;
6143                 }
6144
6145         default:
6146                 /* Any single part */
6147
6148                 if (pBody->body.pBinary) {
6149                         free(pBody->body.pBinary);
6150                         pBody->body.pBinary = NULL;
6151                 }
6152
6153                 break;
6154         }
6155
6156         MSG_DEBUG("_MsgFreeBody: E  N  D  (Successfully) !!! \n") ;
6157
6158         return true;
6159
6160 }
6161
6162 bool MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
6163 {
6164         MSG_BEGIN();
6165         MsgMultipart *pTmpMultipart = NULL;
6166         MsgMultipart *pSelectedPart = NULL;
6167         MsgMultipart *pPrevPart = NULL;
6168         MsgMultipart *pFirstPart = NULL;
6169         MsgMultipart *pLastPart = NULL;
6170         MsgMultipart *pRemoveList = NULL;
6171         MsgMultipart *pNextRemovePart = NULL;
6172
6173         switch (pPartType->type) {
6174         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
6175         case MIME_MULTIPART_ALTERNATIVE:
6176
6177                 /* fixme:
6178                  * Policy: multipart/alternative
6179                  * multipart/alternative message has only several parts of media.
6180                  * You should choose one of them and make the alternative part
6181                  * to the selected media part.
6182                  */
6183
6184                 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE\n");
6185
6186                 pSelectedPart = pPartBody->body.pMultipart;
6187
6188                 // NULL Pointer check!!
6189                 if (pSelectedPart == NULL) {
6190                         MSG_DEBUG("MsgResolveNestedMultipart : multipart(ALTERNATIVE) does not exist\n");
6191                         break;
6192                 }
6193
6194                 pTmpMultipart = pPartBody->body.pMultipart->pNext;
6195
6196                 while (pTmpMultipart) {
6197                         if (pSelectedPart->type.type <= pTmpMultipart->type.type)
6198                                 pSelectedPart = pTmpMultipart;
6199
6200                         pTmpMultipart = pTmpMultipart->pNext;
6201                 }
6202
6203                 pTmpMultipart = pPartBody->body.pMultipart;
6204                 pPrevPart = NULL;
6205
6206                 while (pTmpMultipart) {
6207                         if (pSelectedPart == pTmpMultipart)
6208                                 break;
6209
6210                         pPrevPart = pTmpMultipart;
6211                         pTmpMultipart = pTmpMultipart->pNext;
6212                 }
6213
6214                 if (pPrevPart == NULL) {
6215                         /* selected part is the first part */
6216                         pRemoveList = pSelectedPart->pNext;
6217                 } else {
6218                         pPrevPart->pNext = pSelectedPart->pNext;
6219                         pRemoveList = pPartBody->body.pMultipart;
6220                         pPartBody->body.pMultipart = pSelectedPart;
6221                 }
6222
6223                 pSelectedPart->pNext = NULL;
6224
6225                 if (pRemoveList) {
6226 #ifdef __SUPPORT_DRM__
6227                         _MsgFreeDRMInfo(&pRemoveList->type.drmInfo);
6228 #endif
6229                         _MsgFreeBody(pRemoveList->pBody, pRemoveList->type.type);
6230
6231                         free(pRemoveList->pBody);
6232                         free(pRemoveList);
6233                 }
6234
6235                 if (MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
6236                         MSG_DEBUG("MsgResolveNestedMultipart : MsgPriorityCopyMsgType failed \n");
6237                         goto __CATCH;
6238                 }
6239
6240                 if (pSelectedPart->pBody != NULL)
6241                         memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
6242
6243                 if (pSelectedPart != NULL) {
6244 #ifdef __SUPPORT_DRM__
6245                         _MsgFreeDRMInfo(&pSelectedPart->type.drmInfo);
6246 #endif
6247
6248                         if (pSelectedPart->pBody != NULL) {
6249                                 free(pSelectedPart->pBody);
6250                                 pSelectedPart->pBody = NULL;
6251                         }
6252                         free(pSelectedPart);
6253                         pSelectedPart = NULL;
6254                 }
6255
6256                 break;
6257
6258         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
6259         case MIME_MULTIPART_RELATED:
6260
6261                 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_RELATED\n");
6262
6263                 pSelectedPart = pPartBody->body.pMultipart;
6264
6265                 while (pSelectedPart) {
6266                         if (MsgIsMultipartMixed(pSelectedPart->type.type)) {
6267
6268                                 if (pSelectedPart->pBody == NULL) {
6269                                         MSG_DEBUG("MsgResolveNestedMultipart :pSelectedPart->pBody(1) is NULL\n");
6270                                         break;
6271                                 }
6272
6273                                 pFirstPart = pSelectedPart->pBody->body.pMultipart;
6274
6275                                 if (pFirstPart == NULL) {
6276                                         MSG_DEBUG("MsgResolveNestedMultipart : multipart(RELATED) does not exist\n");
6277                                         break;
6278                                 }
6279
6280                                 if (pFirstPart->pNext) {
6281                                         pLastPart = pFirstPart->pNext;
6282                                         while (pLastPart->pNext)
6283                                                 pLastPart = pLastPart->pNext;
6284                                 } else {
6285                                         pLastPart = pFirstPart;
6286                                 }
6287
6288                                 if (pPrevPart == NULL) {
6289                                         /* the first part */
6290                                         pTmpMultipart = pPartBody->body.pMultipart->pNext;
6291                                         pPartBody->body.pMultipart = pFirstPart;
6292                                         pLastPart->pNext = pTmpMultipart;
6293                                 } else {
6294                                         pTmpMultipart = pSelectedPart->pNext;
6295                                         pPrevPart->pNext = pFirstPart;
6296                                         pLastPart->pNext = pTmpMultipart;
6297                                 }
6298
6299                                 if (pSelectedPart) {
6300 #ifdef __SUPPORT_DRM__
6301                                         _MsgFreeDRMInfo(&pSelectedPart->type.drmInfo);
6302 #endif
6303                                         free(pSelectedPart->pBody);
6304                                         free(pSelectedPart);
6305                                 }
6306                                 pSelectedPart = pTmpMultipart;
6307                         } else if (MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
6308                                 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
6309                                 _MsgFreeBody(pSelectedPart->pBody, pSelectedPart->type.type);
6310
6311                                 free(pSelectedPart->pBody);
6312                                 free(pSelectedPart);
6313                                 pSelectedPart = pTmpMultipart;
6314                         } else {
6315                                 pPrevPart = pSelectedPart;
6316                                 pSelectedPart = pSelectedPart->pNext;
6317                         }
6318                 }
6319
6320                 break;
6321
6322
6323         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
6324         case MIME_MULTIPART_MIXED:
6325
6326                 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_MIXED\n");
6327
6328                 pPrevPart = NULL;
6329                 pSelectedPart = pPartBody->body.pMultipart;
6330
6331                 while (pSelectedPart) {
6332                         if (MsgIsMultipart(pSelectedPart->type.type)) {
6333                                 if (pSelectedPart->pBody == NULL) {
6334                                         MSG_DEBUG("MsgResolveNestedMultipart :pSelectedPart->pBody(2) is NULL\n");
6335                                         break;
6336                                 }
6337
6338                                 pFirstPart = pSelectedPart->pBody->body.pMultipart;
6339
6340                                 // NULL Pointer check!!
6341                                 if (pFirstPart == NULL) {
6342                                         MSG_DEBUG("MsgResolveNestedMultipart : multipart does not exist\n");
6343                                         break;
6344                                 }
6345
6346                                 if (pFirstPart->pNext) {
6347                                         pLastPart = pFirstPart->pNext;
6348                                         while (pLastPart->pNext)
6349                                                 pLastPart = pLastPart->pNext;
6350                                 } else {
6351                                         pLastPart = pFirstPart;
6352                                 }
6353
6354                                 if (pPrevPart == NULL) {
6355                                         /* the first part */
6356                                         pTmpMultipart = pPartBody->body.pMultipart->pNext;
6357                                         pPartBody->body.pMultipart = pFirstPart;
6358                                         pLastPart->pNext = pTmpMultipart;
6359                                 } else {
6360                                         pTmpMultipart = pSelectedPart->pNext;
6361                                         pPrevPart->pNext = pFirstPart;
6362                                         pLastPart->pNext = pTmpMultipart;
6363                                 }
6364
6365                                 if (pSelectedPart->pBody->pPresentationBody)
6366                                         pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
6367
6368                                 memcpy(&pPartBody->presentationType,
6369                                                   &pSelectedPart->pBody->presentationType, sizeof(MsgType));
6370
6371                                 pPartType->type = pSelectedPart->type.type;
6372
6373 #ifdef __SUPPORT_DRM__
6374                                 _MsgFreeDRMInfo(&pSelectedPart->type.drmInfo);
6375 #endif
6376                                 free(pSelectedPart->pBody);
6377                                 free(pSelectedPart);
6378
6379                                 pSelectedPart = pTmpMultipart;
6380                         } else {
6381                                 pPrevPart = pSelectedPart;
6382                                 pSelectedPart = pSelectedPart->pNext;
6383                         }
6384                 }
6385
6386                 break;
6387
6388         case MIME_MULTIPART_REPORT:
6389
6390                 MSG_DEBUG("MsgResolveNestedMultipart : MIME_MULTIPART_REPORT \n");
6391
6392                 pTmpMultipart = pPartBody->body.pMultipart;
6393                 pPrevPart = NULL;
6394
6395                 if (pTmpMultipart == NULL) {
6396                         MSG_DEBUG("MsgResolveNestedMultipart : pTmpMultipart == NULL \n");
6397                         return false;
6398                 }
6399
6400                 while (pTmpMultipart) {
6401                         if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
6402                                 pSelectedPart = pTmpMultipart;
6403                                 break;
6404                         }
6405
6406                         pPrevPart = pTmpMultipart;
6407                         pTmpMultipart = pTmpMultipart->pNext;
6408                 }
6409
6410                 if (pSelectedPart == NULL) {
6411                         MSG_DEBUG("MsgResolveNestedMultipart : MIME_MULTIPART_REPORT [no selected part]\n");
6412                         MSG_DEBUG("MsgResolveNestedMultipart : MIME_MULTIPART_REPORT [no selected part]\n");
6413
6414                         pRemoveList = pPartBody->body.pMultipart->pNext;
6415                         pSelectedPart = pPartBody->body.pMultipart;
6416                         pSelectedPart->pNext = NULL;
6417                 } else {
6418                         if (pPrevPart == NULL) {
6419                                 // first part is selected
6420                                 pRemoveList = pPartBody->body.pMultipart->pNext;
6421                         } else {
6422                                 pRemoveList = pPartBody->body.pMultipart->pNext;
6423                                 pPrevPart->pNext = pSelectedPart->pNext;
6424                         }
6425
6426                         pSelectedPart->pNext = NULL;
6427                         pPartBody->body.pMultipart = pSelectedPart;
6428                 }
6429
6430                 pTmpMultipart = pRemoveList;
6431
6432                 while (pTmpMultipart) {
6433 #ifdef __SUPPORT_DRM__
6434                         _MsgFreeDRMInfo(&pTmpMultipart->type.drmInfo);
6435 #endif
6436                         _MsgFreeBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
6437                         pNextRemovePart = pTmpMultipart->pNext;
6438
6439                         free(pTmpMultipart->pBody);
6440                         free(pTmpMultipart);
6441                         pTmpMultipart = pNextRemovePart;
6442                 }
6443
6444                 if (MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
6445                         MSG_DEBUG("MsgResolveNestedMultipart : MsgPriorityCopyMsgType failed \n");
6446                         goto __CATCH;
6447                 }
6448
6449                 if (pSelectedPart->pBody != NULL)
6450                         memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
6451
6452                 if (pSelectedPart != NULL) {
6453 #ifdef __SUPPORT_DRM__
6454                         _MsgFreeDRMInfo(&pSelectedPart->type.drmInfo);
6455 #endif
6456                         if (pSelectedPart->pBody != NULL) {
6457                                 free(pSelectedPart->pBody);
6458                                 pSelectedPart->pBody = NULL;
6459                         }
6460                         free(pSelectedPart);
6461                         pSelectedPart = NULL;
6462                 }
6463
6464                 break;
6465
6466         default:
6467                 break;
6468         }
6469         MSG_END();
6470
6471         return true;
6472
6473 __CATCH:
6474         return false;
6475
6476 }
6477
6478 char *MsgResolveContentURI(char *szSrc)
6479 {
6480         char *szTemp = NULL;
6481         char *szReturn = NULL;
6482         int length = 0;
6483
6484         if (szSrc == NULL) {
6485                 goto __CATCH;
6486         }
6487
6488         if (szSrc[0] == '\0')
6489                 goto __CATCH;
6490
6491
6492         if (!strncasecmp(szSrc, "cid:", 4)) {
6493                 length = strlen(szSrc) - 3;
6494                 szSrc += 4;
6495         } else {
6496                 length = strlen(szSrc) + 1;
6497         }
6498
6499         szTemp = (char *)malloc(length);
6500         if (szTemp == NULL) {
6501                 MSG_DEBUG("MsgResolveContentURI: memory full\n");
6502                 goto __CATCH;
6503         }
6504
6505         memset(szTemp, 0, length);
6506         strcpy(szTemp, szSrc);
6507
6508         szReturn = MsgChangeHexString(szTemp);
6509
6510         if (szTemp) {
6511                 free(szTemp);
6512                 szTemp = NULL;
6513         }
6514
6515         return szReturn;
6516
6517 __CATCH:
6518         if (szTemp) {
6519                 free(szTemp);
6520                 szTemp = NULL;
6521         }
6522
6523         return NULL;
6524 }
6525
6526 bool _MsgParsePartHeader(MsgType *pType, const char *pRawData, int nRawData)
6527 {
6528         char ch = '\0';
6529         int cRaw = nRawData;
6530         char *pFieldLine = NULL;
6531         char *pFieldValue = NULL;
6532         char *szFieldValue = NULL;
6533         char *szSrc = NULL;
6534         int nLen = 0;
6535         char fieldLine[MSG_LINE_LEN] = {0, }; //temporary line buffer
6536         int length = 0;
6537
6538         char szTempBuf[MSG_LOCAL_TEMP_BUF_SIZE];
6539
6540         while ((cRaw > 0) && *pRawData != MSG_CH_LF) {
6541                 memset(fieldLine, 0, MSG_LINE_LEN);
6542                 pFieldLine = fieldLine;
6543
6544                 ch = MSG_CH_SP; //remember previous character.
6545
6546                 while (ch) {
6547                         switch (ch = *pRawData++) {
6548                         case MSG_CH_CR: //'\r'
6549                                 if (*pRawData == MSG_CH_LF)
6550                                         break;
6551
6552                         case MSG_CH_LF: //'\n'
6553                                 if (*pRawData != MSG_CH_SP && *pRawData != MSG_CH_TAB) {
6554                                         ch = MSG_CH_NULL;
6555                                         *pFieldLine = ch;
6556                                         pFieldLine++;
6557                                 }
6558                                 break;
6559
6560                         case MSG_CH_TAB: //'\t'
6561                                 *pFieldLine = MSG_CH_SP;
6562                                 pFieldLine++;
6563                                 break;
6564
6565                         default:
6566                                 *pFieldLine = ch;
6567                                 pFieldLine++;
6568                                 break;
6569                         }
6570
6571                         if (--cRaw <= 0) {  //If is the last character of header
6572                                 *pFieldLine = MSG_CH_NULL;
6573                                 pFieldLine++;
6574                         }
6575                 }
6576
6577
6578                 if ((pFieldValue =  strchr(fieldLine, MSG_CH_COLON)) != NULL) {
6579                         char*   pTemp = pFieldValue;
6580                         char*   pValue = NULL;
6581
6582                         *pFieldValue++ = MSG_CH_NULL; //remove ':'
6583
6584                         while (*pFieldValue == MSG_CH_SP) //remove space ' '
6585                                 pFieldValue++;
6586
6587                         while ((fieldLine < pTemp--) && (*pTemp == MSG_CH_SP))
6588                                 *pTemp = MSG_CH_NULL;
6589
6590                         nLen = strlen(pFieldValue);
6591
6592                         if (nLen >= MSG_LOCAL_TEMP_BUF_SIZE) {
6593                                 szFieldValue = (char *)malloc(nLen + 1);
6594                                 memset(szFieldValue, 0 , nLen + 1);
6595                                 memcpy(szFieldValue, pFieldValue, nLen + 1);
6596                         } else {
6597                                 memset(szTempBuf, 0, MSG_LOCAL_TEMP_BUF_SIZE);
6598                                 strcpy(szTempBuf, pFieldValue);
6599                                 szFieldValue = szTempBuf;
6600                         }
6601
6602                         if (MsgStrcpyWithoutCRLF(szFieldValue, &szSrc) == true) {
6603                                 if (szSrc != NULL)
6604                                         strncpy(szFieldValue, szSrc, strlen(szSrc));
6605                         }
6606                         if (szSrc) {
6607                                 free(szSrc);
6608                                 szSrc = NULL;
6609                         }
6610
6611                         switch (_MsgGetCode(MSG_FIELD, fieldLine)) {
6612                         case MSG_FIELD_CONTENT_ID:
6613                                 if ((pTemp = strchr(szFieldValue, MSG_CH_SEMICOLON)) != NULL)
6614                                         *pTemp++ = MSG_CH_NULL;
6615
6616                                 pValue = _MsgDecodeText(szFieldValue);
6617                                 memset (pType->szContentID, 0, MSG_MSG_ID_LEN + 1);
6618
6619                                 if (pValue) {
6620                                         // support CD & SD
6621                                         length = MsgStrlen(pValue);
6622                                         if (pValue[0] == '<' && pValue[length-1] == '>') {
6623                                                 strncpy(pType->szContentID, pValue + 1, length - 2);
6624                                         } else {
6625                                                 strncpy(pType->szContentID, pValue, MSG_MSG_ID_LEN);
6626                                         }
6627
6628                                         MSG_DEBUG("_MsgParsePartHeader: Content-ID = %s     %s\n", pFieldValue, pType->szContentID);
6629
6630                                         if (pTemp != NULL)
6631                                                 _MsgParseParameter(pType, pTemp);
6632
6633                                         free(pValue);
6634                                         pValue = NULL;
6635                                 }
6636
6637                                 break;
6638
6639                         case MSG_FIELD_CONTENT_LOCATION:
6640                                 if ((pTemp = strchr(szFieldValue, MSG_CH_SEMICOLON)) != NULL)
6641                                         *pTemp++ = MSG_CH_NULL;
6642
6643                                 pValue = _MsgDecodeText(szFieldValue);
6644                                 memset (pType->szContentLocation, 0, MSG_MSG_ID_LEN + 1);
6645
6646                                 if (pValue) {
6647                                         strncpy(pType->szContentLocation, pValue, MSG_MSG_ID_LEN);
6648
6649                                         MSG_DEBUG("_MsgParsePartHeader: Content-Location = %s     %s\n", pFieldValue, pType->szContentLocation);
6650
6651                                         if (pTemp != NULL)
6652                                                 _MsgParseParameter(pType, pTemp);
6653
6654                                         free(pValue);
6655                                         pValue = NULL;
6656                                 }
6657
6658                                 break;
6659
6660                         case MSG_FIELD_CONTENT_TYPE:
6661                                 if ((pTemp = strchr(szFieldValue, MSG_CH_SEMICOLON)) == NULL) {
6662                                         if ((pTemp = strchr(szFieldValue, MSG_CH_SP)) != NULL)
6663                                                 *pTemp++ = MSG_CH_NULL;
6664                                 } else {
6665                                         *pTemp++ = MSG_CH_NULL;
6666                                 }
6667
6668                                 pType->type = _MsgGetCode(MSG_TYPE, szFieldValue);
6669
6670                                 MSG_DEBUG("_MsgParsePartHeader: Content-Type = %s     %d\n", pFieldValue, pType->type);
6671
6672                                 if (pType->type == INVALID_HOBJ)
6673                                         pType->type = MIME_UNKNOWN;
6674
6675                                 if (pTemp != NULL)
6676                                         _MsgParseParameter(pType, pTemp);
6677
6678                                 break;
6679
6680                         case MSG_FIELD_CONTENT_TRANSFER_ENCODING:
6681                                 if ((pTemp = strchr(szFieldValue, MSG_CH_SEMICOLON)) == NULL) {
6682                                         if ((pTemp = strchr(szFieldValue, MSG_CH_SP)) != NULL)
6683                                                 *pTemp++ = MSG_CH_NULL;
6684                                 } else {
6685                                         *pTemp++ = MSG_CH_NULL;
6686                                 }
6687
6688                                 pType->encoding = _MsgGetCode(MSG_ENCODING, szFieldValue);
6689
6690                                 MSG_DEBUG("_MsgParsePartHeader: Content-Encoding = %s     %d\n", pFieldValue, pType->encoding);
6691
6692                                 if (pTemp != NULL)
6693                                         _MsgParseParameter(pType, pTemp);
6694
6695                                 break;
6696
6697                         case MSG_FIELD_CONTENT_DISPOSITION:
6698                                 if ((pTemp = strchr(szFieldValue, MSG_CH_SEMICOLON)) == NULL) {
6699                                         if ((pTemp = strchr(szFieldValue, MSG_CH_SP)) != NULL)
6700                                                 *pTemp++ = MSG_CH_NULL;
6701                                 } else {
6702                                         *pTemp++ = MSG_CH_NULL;
6703                                 }
6704
6705                                 pType->disposition = _MsgGetCode(MSG_DISPOSITION, szFieldValue);
6706
6707                                 MSG_DEBUG("_MsgParsePartHeader: Content-Disposition = %s     %d\n", pFieldValue, pType->disposition);
6708
6709                                 if (pTemp != NULL)
6710                                         _MsgParseParameter(pType, pTemp);
6711
6712                                 break;
6713
6714 #ifdef __SUPPORT_DRM__
6715
6716                         case MSG_FIELD_CONTENT_NAME:
6717                                 /* add to parse DCF header such as,
6718                                  * Right-Issuer, Content-Name, and Content-Description.
6719                                  */
6720                                 MsgMIMERemoveQuote(szFieldValue);
6721                                 pType->drmInfo.szContentName = MsgStrCopy(szFieldValue);
6722                                 break;
6723
6724                         case MSG_FIELD_CONTENT_DESCRIPTION:
6725                                 MsgMIMERemoveQuote(szFieldValue);
6726                                 pType->drmInfo.szContentDescription = MsgStrCopy(szFieldValue);
6727                                 break;
6728
6729                         case MSG_FIELD_CONTENT_VENDOR:
6730                                 MsgMIMERemoveQuote(szFieldValue);
6731                                 pType->drmInfo.szContentVendor = MsgStrCopy(szFieldValue);
6732                                 break;
6733
6734                         case MSG_FIELD_RIGHT_ISSUER:
6735                                 MsgMIMERemoveQuote(szFieldValue);
6736                                 pType->drmInfo.szRightIssuer = MsgStrCopy(szFieldValue);
6737                                 break;
6738
6739
6740                         case MSG_FIELD_DRM_CONVERTED:
6741                                 MsgMIMERemoveQuote(szFieldValue);
6742                                 pType->nDrmConvertedStatus = atoi(szFieldValue);
6743                                 break;
6744
6745 #endif
6746                         case MSG_FILED_CONTENT_REPLACE_POS:
6747                                 MsgMIMERemoveQuote(szFieldValue);
6748                                 strncpy(pType->szContentRepPos, szFieldValue, sizeof(pType->szContentRepPos));
6749                                 break;
6750
6751                         case MSG_FILED_CONTENT_REPLACE_SIZE:
6752                                 MsgMIMERemoveQuote(szFieldValue);
6753                                 strncpy(pType->szContentRepSize, szFieldValue, sizeof(pType->szContentRepSize));
6754                                 break;
6755
6756                         case MSG_FILED_CONTENT_REPLACE_INDEX:
6757                                 MsgMIMERemoveQuote(szFieldValue);
6758                                 strncpy(pType->szContentRepIndex, szFieldValue, sizeof(pType->szContentRepIndex));
6759                                 break;
6760
6761                         default:
6762                                 MSG_DEBUG("_MsgParsePartHeader: Unhandled field \n");
6763                                 break;
6764                         }
6765                 }
6766
6767                 if (szFieldValue != NULL && szFieldValue != szTempBuf) {
6768                         free(szFieldValue);
6769                         szFieldValue = NULL;
6770                 }
6771
6772         }
6773
6774         return true;
6775 }
6776
6777 char *MsgRemoveQuoteFromFilename(char *pSrc)
6778 {
6779         int cLen = 0;   // length of pBuff
6780         char *pBuff = NULL;
6781
6782         if (pSrc == NULL) {
6783                 MSG_DEBUG("MsgRemoveQuoteFromFilename: pSrc is Null\n");
6784                 return NULL;
6785         }
6786
6787         cLen = strlen(pSrc);
6788
6789         pBuff = (char *)malloc(cLen + 1);
6790
6791         if (pBuff == NULL) {
6792                 MSG_DEBUG("MsgRemoveQuoteFromFilename: pBuff mem alloc fail!\n");
6793                 return NULL;
6794         }
6795         memset(pBuff, 0 , sizeof(char)*(cLen + 1));
6796
6797         // remove front quote
6798         if (pSrc[0] == MSG_CH_QUOT) {
6799                 cLen--;
6800                 strncpy(pBuff, &pSrc[1], cLen);
6801                 pBuff[cLen] = '\0';
6802         }
6803
6804         if (pSrc[0] == MSG_CH_LF) {
6805                 cLen--;
6806                 strncpy(pBuff, &pSrc[1], cLen);
6807         } else {
6808                 strcpy(pBuff, pSrc);
6809         }
6810
6811         // remove last qoute
6812         if (pBuff[cLen-1] == MSG_CH_QUOT) {
6813                 pBuff[cLen-1] = '\0';
6814         }
6815
6816         return pBuff;
6817 }
6818
6819 bool MsgIsMultipart(int type)
6820 {
6821         if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
6822                 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
6823                 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
6824                 return true;
6825         } else {
6826                 return false;
6827         }
6828 }
6829
6830
6831 bool MsgIsHexChar(char *pSrc)
6832 {
6833         int cIndex = 0;
6834         int cLen = 0;
6835         bool bRet = false;
6836
6837         cLen = strlen(pSrc);
6838
6839         for (cIndex = 0; cIndex < cLen ; cIndex++) {
6840                 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
6841                         (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
6842                         bRet = true;
6843                 } else {
6844                         return false;
6845                 }
6846         }
6847
6848         return bRet;
6849 }
6850
6851 char _MsgConvertHexValue(char *pSrc)
6852 {
6853         int ch = 0;
6854         int cIndex = 0;
6855         int cLen = 0;
6856         char ResultChar;
6857         unsigned char uCh[2] = {0,};
6858
6859         cLen = strlen(pSrc);
6860
6861         for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
6862                 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
6863                 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
6864                 ch = (int)uCh[0]<<4|uCh[1];
6865         }
6866
6867         ResultChar = (char)ch;
6868
6869         return ResultChar;
6870 }
6871
6872 int __MsgConvertCharToInt(char ch)
6873 {
6874         if (ch>='0' && ch<='9') {
6875                 return ch - '0';
6876         } else if (ch>='a'&& ch <='f') {
6877                 return ch -'a'+10;
6878         } else if (ch>='A'&& ch <='F') {
6879                 return ch -'A'+10;
6880         } else {
6881                 return 0;
6882         }
6883 }
6884
6885 bool MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
6886 {
6887         if (pMsgType1->section == INVALID_HOBJ)
6888                 pMsgType1->section = pMsgType2->section;
6889
6890 #ifdef __SUPPORT_DRM__
6891         int             length = 0;
6892
6893         if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
6894                 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
6895
6896
6897         if (pMsgType1->szContentID[0] == '\0') {
6898                 strcpy(pMsgType1->szContentID, pMsgType2->szContentID);
6899
6900                 if (pMsgType2->szContentID[0]) {
6901                         length = MsgStrlen(pMsgType2->szContentID);
6902                         if (pMsgType2->szContentID[0] == '<' && pMsgType2->szContentID[length - 1] == '>') {
6903                                 pMsgType1->drmInfo.szContentURI = MsgStrNCopy(pMsgType2->szContentID + 1, length - 2);
6904                         } else {
6905                                 pMsgType1->drmInfo.szContentURI = MsgStrCopy(pMsgType2->szContentID);
6906                         }
6907                 }
6908         } else {
6909                 length = MsgStrlen(pMsgType1->szContentID);
6910                 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
6911                         pMsgType1->drmInfo.szContentURI = MsgStrNCopy(pMsgType1->szContentID + 1, length - 2);
6912                 } else {
6913                         pMsgType1->drmInfo.szContentURI = MsgStrCopy(pMsgType1->szContentID);
6914                 }
6915         }
6916 #endif
6917
6918         if (pMsgType1->szContentLocation[0] == '\0')
6919                 strcpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation);
6920
6921         /* Copy informations - we shoud open the pMsgType2's orgFile
6922          * concerning its offset and size.
6923          */
6924         if (pMsgType2->szOrgFilePath[0] != '\0')
6925                 strcpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath);
6926
6927         if (pMsgType2->disposition != INVALID_HOBJ)
6928                 pMsgType1->disposition = pMsgType2->disposition;
6929
6930         if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
6931                  pMsgType2->encoding != INVALID_HOBJ)
6932                 pMsgType1->encoding = pMsgType2->encoding;
6933
6934         pMsgType1->contentSize = pMsgType2->contentSize;
6935         pMsgType1->offset = pMsgType2->offset;
6936         pMsgType1->size = pMsgType2->size;
6937         pMsgType1->type = pMsgType2->type;
6938
6939         MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
6940
6941         if (pMsgType1->param.szName[0]) {
6942 #ifdef __SUPPORT_DRM__
6943                 pMsgType1->drmInfo.szContentName = MsgStrCopy(pMsgType2->param.szName);
6944 #endif
6945         }
6946
6947         return true;
6948 }
6949
6950
6951 bool MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
6952 {
6953         if (pParam1->charset == MSG_CHARSET_UNKNOWN)
6954                 pParam1->charset = pParam2->charset;
6955
6956         if (pParam1->type == MIME_UNKNOWN)
6957                 pParam1->type = pParam2->type;
6958
6959         /* Don't copy pParam2->pPresentation */
6960
6961         /* For alternative: copy the boundary string */
6962         if (pParam2->szBoundary[0] !='\0')
6963                 strcpy(pParam1->szBoundary, pParam2->szBoundary);
6964
6965         if (pParam1->szFileName[0] =='\0')
6966                 strcpy(pParam1->szFileName, pParam2->szFileName);
6967
6968         if (pParam1->szName[0] =='\0')
6969                 strcpy(pParam1->szName, pParam2->szName);
6970
6971         if (pParam1->szStart[0] =='\0')
6972                 strcpy(pParam1->szStart, pParam2->szStart);
6973
6974         if (pParam1->szStartInfo[0] =='\0')
6975                 strcpy(pParam1->szStartInfo, pParam2->szStartInfo);
6976
6977         return true;
6978 }
6979
6980 bool MsgIsMultipartMixed(int type)
6981 {
6982         if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
6983                 return true;
6984         } else {
6985                 return false;
6986         }
6987 }
6988
6989 bool MsgStrcpyWithoutCRLF(char *pOrg, char **ppNew)
6990 {
6991         int nLen = 0;
6992         int     i = 0;
6993         int index = 0;
6994         char*   pDest = NULL;
6995
6996
6997         nLen = strlen(pOrg);
6998
6999         pDest = (char *)malloc(nLen + 1);
7000
7001         if (pDest == NULL) {
7002                 MSG_DEBUG("MsgStrcpyWithoutCRLF: malloc is failed\n");
7003                 return false;
7004         }
7005
7006         memset(pDest, 0 , (nLen + 1));
7007
7008         for (i = 0; i < nLen ; i++) {
7009                 if (i < nLen - 2) {
7010                         if ((pOrg[i] == MSG_CH_CR && pOrg[i+1] == MSG_CH_LF && pOrg[i+2] == MSG_CH_TAB) ||
7011                                 (pOrg[i] == MSG_CH_CR && pOrg[i+1] == MSG_CH_LF && pOrg[i+2] == MSG_CH_SP)) {
7012                                 i+=2;
7013                                 continue;
7014                         }
7015                 }
7016                 pDest[index++] = pOrg[i];
7017         }
7018         *ppNew = pDest;
7019
7020         return true;
7021 }
7022
7023 bool MmsGetMsgAttrib(MmsMsgID msgID, MmsAttrib* pAttrib)
7024 {
7025         MmsMsg *pMsg = NULL;
7026
7027         memset(pAttrib, 0, sizeof(MmsAttrib));
7028         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
7029         memcpy(pAttrib, &(pMsg->mmsAttrib), sizeof(MmsAttrib));
7030
7031         MSG_DEBUG("MmsGetMsgAttrib: msgID = %lu ---------------------\n", msgID);
7032
7033         if ('\0' != pMsg->szTrID[0])
7034                 MSG_DEBUG("szTrID = %s \n", pMsg->szTrID);
7035
7036         MSG_END();
7037         return true;
7038 }
7039
7040 bool __MsgIsInvalidFileNameChar(char ch)
7041 {
7042         if ((ch == 0x5C /* \ */) ||
7043                 (ch == 0x2F /* / */) ||
7044                 (ch == 0x3A /* : */) ||
7045                 (ch == 0x2A /* * */) ||
7046                 (ch == 0x3F /* ? */) ||
7047                 (ch == 0x22 /* " */) ||
7048                 (ch == 0x3C /* < */) ||
7049                 (ch == 0x3E /* > */) ||
7050                 (ch == 0x7C /* | */))
7051                 return true;
7052
7053         return false;
7054 }
7055
7056 bool _MmsDataUpdateLastStatus(MmsMsg *pMsg)
7057 {
7058         MmsMsgMultiStatus*      pStatus = NULL;
7059
7060         pStatus = pMsg->mmsAttrib.pMultiStatus;
7061
7062         while (pStatus != NULL) {
7063                 pStatus->bDeliveyrReportIsLast = false;
7064                 pStatus->bReadReplyIsLast = false;
7065                 pStatus = pStatus->pNext;
7066         }
7067
7068         return true;
7069 }
7070
7071
7072 bool MmsAddrUtilCompareAddr(char *pszAddr1, char *pszAddr2)
7073 {
7074         int len1;
7075         int len2;
7076         char *p;
7077
7078         MmsAddrUtilRemovePlmnString(pszAddr1);
7079         MmsAddrUtilRemovePlmnString(pszAddr2);
7080
7081         MSG_DEBUG("##### pszAddr1 = %s #####", pszAddr1);
7082         MSG_DEBUG("##### pszAddr2 = %s #####", pszAddr2);
7083         if (!strcmp(pszAddr1, pszAddr2))
7084                 return true;
7085
7086         len1 = strlen(pszAddr1);
7087         len2 = strlen(pszAddr2);
7088
7089         if (len1 > len2) {
7090                 p = strstr(pszAddr1, pszAddr2);
7091         } else {
7092                 p = strstr(pszAddr2, pszAddr1);
7093         }
7094
7095         if (p)
7096                 return true;
7097
7098         return false;
7099 }
7100
7101 int MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
7102 {
7103         int nCount = 0;
7104
7105         MSG_DEBUG("MsgGetLatin2UTFCodeSize: --------------- \n");
7106
7107         if ((szSrc == NULL) || (nChar <= 0)) {
7108                 MSG_DEBUG("MsgGetLatin2UTFCodeSize: szSrc is NULL !!!! --------------- \n");
7109                 return 0;
7110         }
7111
7112         while ((nChar > 0) && (*szSrc != '\0')) {
7113                 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
7114                         nCount += 1;
7115                         szSrc++;
7116                         nChar--;
7117                 } else {
7118                         nCount += 2;
7119                         szSrc++;
7120                         nChar--;
7121                 }
7122         }
7123
7124         return nCount;
7125 }
7126
7127 int MsgLatin5code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
7128 {
7129         unsigned char *org;
7130         unsigned char t1;
7131         unsigned char t2;
7132         unsigned short temp = 0;
7133
7134         org = des;
7135         outBufSize--;   //Null Character
7136
7137         while ((nChar > 0) && (*szSrc != '\0')) {
7138
7139                 if (*szSrc >= 0x01 && *szSrc <= 0x7F) { //basic common
7140                         temp = (unsigned short)(*szSrc);
7141
7142                         outBufSize --;
7143                         if (outBufSize < 0)
7144                                 goto __RETURN;
7145
7146                         *des = (unsigned char) ((*szSrc) & 0x007F);
7147
7148                         des++;
7149                         szSrc++;
7150                         nChar--;
7151                 } else if ((*szSrc == 0x00) || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
7152                                         (*szSrc >= 0xA0 && *szSrc <= 0xCF) || (*szSrc >= 0xD1 && *szSrc <= 0xDC) ||
7153                                         (*szSrc >= 0xDF && *szSrc <= 0xEF) || (*szSrc >= 0xF1 && *szSrc <= 0xFC) ||
7154                                         (*szSrc == 0xFF)) {//uni 0x00A0 ~ 0x00CF
7155
7156                         temp = (unsigned short)(*szSrc);
7157
7158                         outBufSize -= 2;
7159                         if (outBufSize < 0)
7160                                 goto __RETURN;
7161
7162                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7163                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7164
7165                         *des = 0xC0 | (t1 & 0x1F);
7166                         *(des+1) = 0x80 | (t2 & 0x3F);
7167
7168                         des += 2;
7169                         szSrc += 1;
7170                         nChar -= 1;
7171                 } else if (*szSrc == 0xD0) {//empty section OR vendor specific codes.
7172
7173                         temp = 0x011E;
7174
7175                         outBufSize -= 2;
7176                         if (outBufSize < 0)
7177                                 goto __RETURN;
7178
7179                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7180                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7181
7182                         *des = 0xC0 | (t1 & 0x1F);
7183                         *(des+1) = 0x80 | (t2 & 0x3F);
7184
7185                         des += 2;
7186                         szSrc += 1;
7187                         nChar -= 1;
7188                 } else if (*szSrc == 0xDD) {
7189                         temp = 0x0130;
7190
7191                         outBufSize -= 2;
7192                         if (outBufSize < 0)
7193                                 goto __RETURN;
7194
7195                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7196                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7197
7198                         *des = 0xC0 | (t1 & 0x1F);
7199                         *(des+1) = 0x80 | (t2 & 0x3F);
7200
7201                         des += 2;
7202                         szSrc += 1;
7203                         nChar -= 1;
7204                 } else if (*szSrc == 0xDE) {
7205                         temp = 0x015E;
7206
7207                         outBufSize -= 2;
7208                         if (outBufSize < 0)
7209                                 goto __RETURN;
7210
7211                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7212                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7213
7214                         *des = 0xC0 | (t1 & 0x1F);
7215                         *(des+1) = 0x80 | (t2 & 0x3F);
7216
7217                         des += 2;
7218                         szSrc += 1;
7219                         nChar -= 1;
7220                 } else if (*szSrc == 0xF0) {
7221                         temp = 0x011F;
7222                                 outBufSize -= 2;
7223                         if (outBufSize < 0)
7224                                 goto __RETURN;
7225
7226                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7227                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7228
7229                         *des = 0xC0 | (t1 & 0x1F);
7230                         *(des+1) = 0x80 | (t2 & 0x3F);
7231
7232                         des += 2;
7233                         szSrc += 1;
7234                         nChar -= 1;
7235                 } else if (*szSrc == 0xFD) {
7236                         temp = 0x0131;
7237
7238                         outBufSize -= 2;
7239
7240                         if (outBufSize < 0)
7241                                 goto __RETURN;
7242
7243                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7244                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7245
7246                         *des = 0xC0 | (t1 & 0x1F);
7247                         *(des+1) = 0x80 | (t2 & 0x3F);
7248
7249                         des += 2;
7250                         szSrc += 1;
7251                         nChar -= 1;
7252                 } else if (*szSrc == 0xFE) {
7253                         temp = 0x015F;
7254
7255                         outBufSize -= 2;
7256                         if (outBufSize < 0)
7257                                 goto __RETURN;
7258
7259                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7260                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7261
7262                         *des = 0xC0 | (t1 & 0x1F);
7263                         *(des+1) = 0x80 | (t2 & 0x3F);
7264
7265                         des += 2;
7266                         szSrc += 1;
7267                         nChar -= 1;
7268                 } else {
7269                         return -1;
7270                 }
7271         }
7272 __RETURN:
7273         *des = 0;
7274         return(des-org);
7275 }
7276
7277 int MsgGetLatin52UTFCodeSize(unsigned char *szSrc, int nChar)
7278 {
7279         int nCount = 0;
7280
7281         MSG_DEBUG("MsgGetLatin52UTFCodeSize: --------------- \n");
7282
7283         if ((szSrc == NULL) || (nChar <= 0))
7284                 return 0;
7285
7286         while ((nChar > 0) && (*szSrc != '\0')) {
7287                 if (*szSrc >= 0x01 && *szSrc <= 0x7F) {
7288                         nCount += 1;
7289                         szSrc++;
7290                         nChar--;
7291                 } else if (*szSrc == 0x00 || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
7292                                         (*szSrc >= 0xA0 && *szSrc <= 0xCF) || (*szSrc >= 0xD1 && *szSrc <= 0xDC) |
7293                                         (*szSrc >= 0xDF && *szSrc <= 0xEF) || (*szSrc >= 0xF1 && *szSrc <= 0xFC) ||
7294                                         *szSrc == 0xD0 || *szSrc == 0xDD || *szSrc == 0xDE || *szSrc == 0xF0 ||
7295                                         *szSrc == 0xFD || *szSrc == 0xFE        || *szSrc == 0xFF) { //uni 0x00A0 ~ 0x00CF
7296                         nCount += 2;
7297                         szSrc++;
7298                         nChar--;
7299                 } else {
7300                         return -1;
7301                 }
7302         }
7303         return nCount;
7304 }
7305
7306 int MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
7307 {
7308         unsigned char*  org;
7309         unsigned char   t1, t2;
7310
7311         MSG_DEBUG("MsgLatin2UTF: --------------- \n");
7312
7313         org = des;
7314         outBufSize--;                   // NULL character
7315
7316         while ((nChar > 0) && (*szSrc != '\0')) {
7317                 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
7318                         /* check outbuffer's room for this UTF8 character */
7319
7320                         outBufSize --;
7321                         if (outBufSize < 0)
7322                                 goto __RETURN;
7323
7324                         *des = (unsigned char) (*szSrc & 0x007F);
7325
7326                         des++;
7327                         szSrc++;
7328                         nChar--;
7329                 } else {
7330                         /* check outbuffer's room for this UTF8 character */
7331
7332                         outBufSize -= 2;
7333                         if (outBufSize < 0)
7334                                 goto __RETURN;
7335
7336                         t2 = (unsigned char) (*szSrc & 0x003F);                         //      right most 6 bit
7337                         t1 = (unsigned char) ((*szSrc & 0xC0) >> 6);            //      right most 2 bit
7338
7339                         *des = 0xC0 | (t1 & 0x1F);
7340                         *(des + 1) = 0x80 | (t2 & 0x3F);
7341
7342                         des += 2;
7343                         szSrc += 1;
7344                         nChar -= 1;
7345                 }
7346         }
7347
7348 __RETURN:
7349
7350         *des = 0;
7351         return (des - org);
7352 }
7353
7354
7355 int MsgLatin7code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
7356 {
7357         unsigned char *org;
7358         unsigned char t1;
7359         unsigned char t2;
7360         unsigned char t3;
7361         unsigned short temp = 0;
7362
7363         MSG_DEBUG("MsgUnicode2UTF: --------------- \n");
7364
7365         org = des;
7366         outBufSize--;   //Null Character
7367
7368         while ((nChar > 0) && (*szSrc != '\0')) {
7369                 if (*szSrc >= 0x01 && *szSrc <= 0x7F) {
7370                         temp = (unsigned short)(*szSrc);
7371
7372                         outBufSize --;
7373                         if (outBufSize < 0)
7374                                 goto __RETURN;
7375
7376                         *des = (unsigned char) (temp & 0x007F);
7377
7378                         des++;
7379                         szSrc++;
7380                         nChar--;
7381
7382                 } else if ((*szSrc == 0x00) || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
7383                                         (*szSrc >= 0xA3 && *szSrc <= 0xAD) || (*szSrc == 0xBB)) { // consider 0xA4, 0xA5
7384
7385                         temp = (unsigned short)(*szSrc);
7386
7387                         outBufSize -= 2;
7388                         if (outBufSize < 0)
7389                                 goto __RETURN;
7390
7391                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7392                         t1 = (unsigned char) ((temp & 0xC0) >> 6);              //      right most 2 bit
7393
7394                         *des = 0xC0 | (t1 & 0x1F);
7395                         *(des + 1) = 0x80 | (t2 & 0x3F);
7396
7397                         des += 2;
7398                         szSrc += 1;
7399                         nChar -= 1;
7400                 } else if (*szSrc == 0xA0) {
7401                         temp = 0x0020;
7402                         //*des = temp to utf-8
7403                         outBufSize--;
7404                         if (outBufSize < 0)
7405                                 goto __RETURN;
7406
7407                         *des = (unsigned char) (temp & 0x007F);
7408
7409                         des++;
7410                         szSrc++;
7411                         nChar--;
7412
7413                 } else if (*szSrc == 0xA1) {
7414                         temp = 0x2018;
7415
7416                         outBufSize -= 3;
7417                         if (outBufSize < 0)
7418                                 goto __RETURN;
7419
7420                         t3 = (unsigned char) (temp & 0x003F);                                   //      right most 6 bit
7421                         t2 = (unsigned char) ((temp & 0x0FC0) >> 6);                    //      right most 6 bit
7422                         t1 = (unsigned char) ((temp & 0xF000) >> 12);                   //      right most 4 bit
7423
7424                         *des = 0xE0 | (t1 & 0x0F);
7425                         *(des+1) = 0x80 | (t2 & 0x3F);
7426                         *(des+2) = 0x80 | (t3 & 0x3F);
7427
7428                         des += 3;
7429                         szSrc += 1;
7430                         nChar -= 1;
7431
7432                 } else if (*szSrc == 0xA2) {
7433                         temp = 0x2019;
7434
7435                         outBufSize -= 3;
7436                         if (outBufSize < 0)
7437                                 goto __RETURN;
7438
7439                         t3 = (unsigned char) (temp & 0x003F);                                   //      right most 6 bit
7440                         t2 = (unsigned char) ((temp & 0x0FC0) >> 6);                    //      right most 6 bit
7441                         t1 = (unsigned char) ((temp & 0xF000) >> 12);                   //      right most 4 bit
7442
7443                         *des = 0xE0 | (t1 & 0x0F);
7444                         *(des+1) = 0x80 | (t2 & 0x3F);
7445                         *(des+2) = 0x80 | (t3 & 0x3F);
7446
7447                         des += 3;
7448                         szSrc += 1;
7449                         nChar -= 1;
7450
7451                 } else if (*szSrc == 0xAF) {
7452                         temp = 0x2015;
7453
7454                         outBufSize -= 3;
7455                         if (outBufSize < 0)
7456                                 goto __RETURN;
7457
7458                         t3 = (unsigned char) (temp & 0x003F);                                   //      right most 6 bit
7459                         t2 = (unsigned char) ((temp & 0x0FC0) >> 6);                    //      right most 6 bit
7460                         t1 = (unsigned char) ((temp & 0xF000) >> 12);                   //      right most 4 bit
7461
7462                         *des = 0xE0 | (t1 & 0x0F);
7463                         *(des+1) = 0x80 | (t2 & 0x3F);
7464                         *(des+2) = 0x80 | (t3 & 0x3F);
7465
7466                         des += 3;
7467                         szSrc += 1;
7468                         nChar -= 1;
7469
7470                 } else if (0xB0 <= *szSrc && *szSrc <= 0xB4) { //0x00B0 ~ 0x00B4
7471
7472                         temp = (unsigned short)(*szSrc);
7473
7474                         outBufSize -= 2;
7475                         if (outBufSize < 0)
7476                                 goto __RETURN;
7477
7478                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7479                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7480
7481                         *des = 0xC0 | (t1 & 0x1F);
7482                         *(des+1) = 0x80 | (t2 & 0x3F);
7483
7484                         des += 2;
7485                         szSrc += 1;
7486                         nChar -= 1;
7487
7488                 } else if ((0xB5 <= *szSrc &&  *szSrc <= 0xBA) ||
7489                                 (0xBC <= *szSrc && *szSrc <= 0xD1) ||
7490                                 (0xD3 <= *szSrc && *szSrc <= 0xFE)) {
7491                         temp= (unsigned short)(*szSrc + 0x02D0);
7492
7493                         outBufSize -= 2;
7494                         if (outBufSize < 0)
7495                                 goto __RETURN;
7496
7497                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
7498                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
7499
7500                         *des = 0xC0 | (t1 & 0x1F);
7501                         *(des+1) = 0x80 | (t2 & 0x3F);
7502
7503                         des += 2;
7504                         szSrc += 1;
7505                         nChar -= 1;
7506
7507                 } else {
7508                         return -1;
7509                 }
7510
7511         }
7512
7513 __RETURN:
7514         *des = 0;
7515         return(des - org);
7516 }
7517
7518 int MsgGetLatin72UTFCodeSize(unsigned char *szSrc, int nChar)
7519 {
7520         int nCount = 0;
7521
7522         MSG_DEBUG("MsgGetLatin72UTFCodeSize: --------------- \n");
7523
7524         if ((szSrc == NULL) || (nChar <= 0))
7525                 return 0;
7526
7527         while ((nChar > 0) && (*szSrc != '\0')) {
7528
7529                 if ((*szSrc >= 0x01 && *szSrc <= 0x7F) || (*szSrc == 0xA0)) {
7530                         nCount += 1;
7531                         szSrc++;
7532                         nChar--;
7533                 } else if (*szSrc == 0x00 || (0x80 <= *szSrc && *szSrc <= 0x9F) || (0xA3 <= *szSrc && *szSrc <= 0xAD) ||
7534                                         (0xB0 <= *szSrc && *szSrc <= 0xB4) || (0xB5 <= *szSrc && *szSrc <= 0xFE)) {
7535                         nCount += 2;
7536                         szSrc++;
7537                         nChar--;
7538                 } else if (*szSrc == 0xA1 ||*szSrc == 0xA2 || *szSrc == 0xAF) {
7539                         nCount += 3;
7540                         szSrc += 1;
7541                         nChar -= 1;
7542
7543                 } else {
7544                         return -1;
7545                 }
7546         }
7547         return nCount;
7548 }
7549
7550 int MsgUnicode2UTF(unsigned char *des, int outBufSize, unsigned short *szSrc, int nChar)
7551 {
7552         unsigned char *org;
7553         unsigned char t1;
7554         unsigned char t2;
7555         unsigned char t3;
7556
7557         MSG_DEBUG("MsgUnicode2UTF: --------------- \n");
7558
7559         org = des;
7560         outBufSize--;                   // NULL character
7561
7562         while ((nChar > 0) && (*szSrc != '\0')) {
7563                 if (0x0001 <= *szSrc && *szSrc <= 0x007F) {
7564                         /* check outbuffer's room for this UTF8 character */
7565
7566                         outBufSize --;
7567                         if (outBufSize < 0)
7568                                 goto __RETURN;
7569
7570                         *des = (unsigned char) (*szSrc & 0x007F);
7571
7572                         des++;
7573                         szSrc++;
7574                         nChar--;
7575                 } else if  ((*szSrc == 0x0000) || (0x0080 <= *szSrc && *szSrc <= 0x07FF)) {
7576                         /* check outbuffer's room for this UTF8 character */
7577
7578                         outBufSize -= 2;
7579                         if (outBufSize < 0)
7580                                 goto __RETURN;
7581
7582                         t2 = (unsigned char) (*szSrc & 0x003F);                         //      right most 6 bit
7583                         t1 = (unsigned char) ((*szSrc & 0x07C0) >> 6);          //      right most 5 bit
7584
7585                         *des = 0xC0 | (t1 & 0x1F);
7586                         *(des+1) = 0x80 | (t2 & 0x3F);
7587
7588                         des += 2;
7589                         szSrc += 1;
7590                         nChar -= 1;
7591                 } else {
7592                         /* check outbuffer's room for this UTF8 character */
7593
7594                         outBufSize -= 3;
7595                         if (outBufSize < 0)
7596                                 goto __RETURN;
7597
7598                         t3 = (unsigned char) (*szSrc & 0x003F);                                 //      right most 6 bit
7599                         t2 = (unsigned char) ((*szSrc & 0x0FC0) >> 6);                  //      right most 6 bit
7600                         t1 = (unsigned char) ((*szSrc & 0xF000) >> 12);                 //      right most 4 bit
7601
7602                         *des = 0xE0 | (t1 & 0x0F);
7603                         *(des+1) = 0x80 | (t2 & 0x3F);
7604                         *(des+2) = 0x80 | (t3 & 0x3F);
7605
7606                         des += 3;
7607                         szSrc += 1;
7608                         nChar -= 1;
7609                 }
7610         }
7611
7612 __RETURN:
7613
7614         *des = 0;
7615         return (des - org);
7616 }
7617
7618 int MsgGetUnicode2UTFCodeSize(unsigned short *szSrc, int nChar)
7619 {
7620         int nCount = 0;
7621
7622         MSG_DEBUG("MsgGetUnicode2UTFCodeSize: --------------- \n");
7623
7624         if ((szSrc == NULL) || (nChar <= 0)) {
7625                 MSG_DEBUG("MsgGetUnicode2UTFCodeSize: szSrc is NULL !!!! --------------- \n");
7626                 return 0;
7627         }
7628
7629         while ((nChar > 0) && (*szSrc != '\0')) {
7630                 if (0x0001 <= *szSrc && *szSrc <= 0x007F) {
7631                         nCount += 1;
7632                         szSrc++;
7633                         nChar--;
7634                 } else if  ((*szSrc == 0x0000) || (0x0080 <= *szSrc && *szSrc <= 0x07FF)) {
7635                         nCount += 2;
7636                         szSrc++;
7637                         nChar--;
7638                 } else {
7639                         nCount += 3;
7640                         szSrc++;
7641                         nChar--;
7642                 }
7643         }
7644
7645         return nCount;
7646 }
7647
7648 bool MmsAddrUtilCheckEmailAddress(char *pszAddr)
7649 {
7650         if (!pszAddr || pszAddr[0] == 0)
7651                 return false;
7652
7653         if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
7654                 return false;
7655
7656         return true;
7657 }
7658
7659 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
7660 {
7661         char *pszAddrCopy = NULL;
7662         char *pszStrStart = NULL;
7663         char *pszStrTemp = NULL;
7664         int strLen = 0;
7665
7666         if ((!pszAddr) || (pszAddr[0] == 0)) {
7667                 MSG_DEBUG("MmsAddrUtilRemovePlmnString: pszAddr is null or zero\n");
7668                 return false;
7669         }
7670
7671         strLen = strlen(pszAddr);
7672
7673         pszAddrCopy = (char*)malloc(strLen + 1);
7674         if (!pszAddrCopy) {
7675                 MSG_DEBUG("MmsAddrUtilRemovePlmnString: pszAddrCopy is NULL, mem alloc failed\n");
7676                 return false;
7677         }
7678
7679         strcpy(pszAddrCopy, pszAddr);
7680
7681
7682         pszAddr[0] = 0;
7683         pszStrStart = pszAddrCopy;
7684
7685         while (true) {
7686                 char*   pszStrEnd = NULL;
7687                 int             addressLen = 0;
7688
7689                 if (MmsAddrUtilCheckEmailAddress(pszAddrCopy))
7690                         pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
7691                 else
7692                         pszStrEnd = strstr(pszStrStart, "/");
7693
7694                 if (!pszStrEnd) {
7695                         // "/TYPE=PLMN" not found
7696
7697                         int remainedLen = strlen(pszStrStart);
7698
7699                         if (remainedLen <= 0)
7700                                 break;
7701
7702                         strcat(pszAddr, pszStrStart);
7703
7704                         break;
7705                 }
7706
7707                 // Get one address length
7708                 addressLen = pszStrEnd - pszStrStart;
7709
7710                 strncat(pszAddr, pszStrStart, addressLen);
7711
7712                 // Find next address
7713                 pszStrStart = pszStrEnd;
7714
7715                 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
7716
7717                 if (pszStrTemp) {
7718                         addressLen = pszStrTemp - pszStrEnd;
7719                         pszStrStart += addressLen;
7720                 } else {
7721                         pszStrStart += strlen(pszStrEnd);
7722                 }
7723
7724                 if (pszStrStart[0] == 0)        // end of string
7725                         break;
7726
7727
7728                 strcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER);    // add ';'
7729                 pszStrStart++;  // remove ';'
7730         }
7731
7732         if (pszAddr[0] == 0)
7733                 strcpy(pszAddr, pszAddrCopy);
7734
7735         free(pszAddrCopy);
7736
7737         return true;
7738 }
7739
7740 int MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
7741 {
7742         unsigned char *org;
7743
7744         MSG_DEBUG("MsgCutUTFString: --------------- \n");
7745
7746         org = des;
7747         outBufSize--;                   // NULL character
7748
7749         while ((nChar > 0) && (*szSrc != '\0')) {
7750                 if (*szSrc < 0x80) {
7751                         outBufSize --;
7752                         if (outBufSize < 0)
7753                                 goto __RETURN;
7754
7755                         *des = *szSrc;
7756                         des++;
7757                         szSrc++;
7758                 } else if  (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
7759                         outBufSize -= 2;
7760                         if (outBufSize < 0)
7761                                 goto __RETURN;
7762
7763                         *des = *szSrc;
7764                         *(des + 1) = *(szSrc + 1);
7765
7766                         des += 2;
7767                         szSrc += 2;
7768                 } else if  ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
7769                         outBufSize -= 3;
7770                         if (outBufSize < 0)
7771                                 goto __RETURN;
7772
7773                         *des = *szSrc;
7774                         *(des + 1) = *(szSrc + 1);
7775                         *(des + 2) = *(szSrc + 2);
7776
7777                         des += 3;
7778                         szSrc += 3;
7779                 } else {
7780                         outBufSize --;
7781                         if (outBufSize < 0)
7782                                 goto __RETURN;
7783
7784                         *des = *szSrc;
7785                         des++;
7786                         szSrc++;
7787                         MSG_DEBUG("MsgCutUTFString: utf8 incorrect range!\n");
7788                 }
7789
7790                 nChar--;
7791         }
7792
7793 __RETURN:
7794
7795         *des = 0;
7796         return (des - org);
7797 }
7798
7799 void MsgMIMERemoveQuote(char *szSrc)
7800 {
7801         int             length = 0;
7802
7803         length = MsgStrlen(szSrc);
7804         if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
7805                 int index = 0;
7806
7807                 for (index = 0; index < length-2; index++)
7808                         szSrc[index] = szSrc[index+1];
7809                 szSrc[index] = '\0';
7810         }
7811 }
7812
7813 bool MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
7814 {
7815         MSG_BEGIN();
7816         int nRead = 0;
7817         int length= 0;
7818
7819         MSG_DEBUG("MsgLoadDataToDecodeBuffer: \n");
7820
7821         if (pFile == NULL) {
7822                 MSG_DEBUG("Error");
7823
7824                 *pBufLen = 0;
7825                 return false;
7826         }
7827
7828         if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
7829                 MSG_DEBUG("Error");
7830
7831                 *pBufLen = 0;
7832                 return false;
7833         }
7834
7835         if (*pBufLen == 0) {
7836                 length = maxLen - (*pPtr);
7837         } else {
7838                 length = (*pBufLen) - (*pPtr);
7839         }
7840
7841         if (length < 0)
7842                 length = 0;
7843
7844         if ((*ppBuf) == NULL) {
7845                 memset(pInBuf1, 0, maxLen);
7846                 (*ppBuf) = pInBuf1;
7847         } else if ((*ppBuf) == pInBuf1) {
7848                 memset(pInBuf2, 0, maxLen);
7849                 if (length)
7850                         memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
7851                 (*ppBuf) = pInBuf2;
7852         } else {
7853                 memset(pInBuf1, 0, maxLen);
7854                 if (length)
7855                         memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
7856                 (*ppBuf) = pInBuf1;
7857         }
7858
7859         (*pPtr) = 0;
7860
7861         if (*pOffset == endOfFile) {
7862                 *pBufLen = length;
7863                 return true;
7864         }
7865
7866         if (maxLen == length) {
7867                 /* (*pPtr) was 0 */
7868                 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
7869                         return false;
7870
7871                 *pBufLen = nRead;
7872         } else {
7873                 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
7874                         return false;
7875
7876                 *pBufLen = length + nRead;
7877         }
7878
7879         if ((*pOffset = MsgFtell(pFile)) == -1L) {
7880                 MSG_DEBUG("MsgFtell Error");
7881                 return false;
7882         }
7883
7884         MSG_END();
7885
7886         return true;
7887 }
7888
7889
7890 bool MsgGetTypeByFileName(int *type, char *szFileName)
7891 {
7892         char *pExt   = NULL;
7893         AvCodecType AvType = AV_CODEC_NONE;
7894
7895         pExt = strrchr(szFileName, '.');
7896         if (pExt == NULL || pExt[0] == '\0')
7897                 goto __CATCH;
7898
7899         pExt++;
7900
7901         if (strcasecmp(pExt, "mp4") == 0 ||strcasecmp(pExt, "mpeg4") == 0 ||strcasecmp(pExt, "3gp") == 0 ||strcasecmp(pExt, "3gpp") == 0) {
7902
7903                 if (szFileName[0] != '/')
7904                         goto __CATCH;
7905
7906                 AvType = AvGetFileCodecType(szFileName);
7907                 MSG_DEBUG("MsgGetTypeByFileName:AvType(0x%x)\n", AvType);
7908
7909                 switch (AvType) {
7910                 case AV_DEC_AUDIO_MPEG4:
7911                         *type = MIME_AUDIO_MP4;
7912                         break;
7913
7914                 case AV_DEC_VIDEO_MPEG4:
7915                         *type = MIME_VIDEO_MP4;
7916                         break;
7917
7918                 default:
7919                         *type = MIME_VIDEO_3GPP;
7920                         break;
7921                 }
7922                 return true;
7923         }
7924
7925         if (strcasecmp(pExt, "amr") == 0) {
7926                 *type = MIME_AUDIO_AMR;
7927                 return true;
7928         } else if ((strcasecmp(pExt, "mid") == 0) || (strcasecmp(pExt, "midi") == 0)) {
7929                 *type = MIME_AUDIO_MIDI;
7930                 return true;
7931         } else if (strcasecmp(pExt, "imy") == 0) {
7932                 *type = MIME_TEXT_X_IMELODY;
7933                 return true;
7934         }
7935
7936         *type = MimeGetMimeFromExtInt((const char*)pExt);
7937         MSG_DEBUG("MsgGetTypeByFileName: szFileName = %s     type = %d \n", szFileName, type);
7938         return true;
7939
7940
7941 __CATCH:
7942
7943         *type = MIME_UNKNOWN;
7944         MSG_DEBUG("MsgGetTypeByFileName: szFileName = %s     type = %d \n", szFileName, type);
7945
7946         return false;
7947
7948 }
7949
7950
7951 /*
7952  *      This function write media data from raw data to file.
7953  *      @param  pMsg
7954  *      @param  pPartBody
7955  *      @param  pszMailboxPath  : path of mailbox
7956  *      @param  pszMsgFilename  : name of msg file
7957  *      @param  index                   : used for file naming
7958  *      @param  bSave                   : if true, file will be save otherwise just filename will be stored.
7959  */
7960 bool _MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
7961 {
7962         FILE *pFile = NULL;
7963         char *pExt = NULL;
7964         char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, };        // file name of temp file
7965         char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; // full absolute path of temp file.
7966
7967         MSG_DEBUG("****   _MmsSaveMediaData:  [Multi part]  START  ***\n");
7968
7969         if (!pPartType) {
7970                 MSG_DEBUG("pPartType is NULL\n");
7971                 return true; // why true value is retured ??? ; false;
7972         }
7973
7974         if (pPartType->param.szName[0] == '\0' && pPartType->param.szFileName[0] == '\0')
7975                 strcpy(pPartType->param.szName, pPartType->param.szFileName);
7976
7977         if (pPartType->param.szName) {
7978                 strcpy(szFileName, pPartType->param.szName);
7979         } else {
7980                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
7981         }
7982
7983
7984 #ifndef __SUPPORT_DRM__
7985         MsgMakeFileName(pPartType->type, szFileName, 0);        //FL & CD -> extension(.dm) SD -> extension(.dcf)
7986 #else
7987         MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0);    //FL & CD -> extension(.dm) SD -> extension(.dcf)
7988         if (MsgDRMIsForwardLockType(pPartType->drmInfo.drmType))
7989                 MsgChangeDrm2FileName(szFileName);
7990 #endif
7991
7992
7993         snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName);  // get absolute path of each temp file of each part
7994         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.
7995
7996         if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
7997                 MsgGetTypeByFileName(&pPartType->type, szFullPath);
7998
7999         // save file
8000         if (bSave) {
8001                 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
8002                         MSG_DEBUG("MsgOpenFile failed");
8003                         goto __CATCH;
8004                 }
8005
8006                 if (MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
8007                         MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
8008                         goto __CATCH;
8009                 }
8010
8011                 MsgCloseFile(pFile);
8012                 pFile = NULL;
8013                 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
8014                         MsgDrmRegisterFile(MSG_MODE_FILE, szFullPath, strlen(szFullPath));
8015
8016                         /* change szDrm2FullPath as current content path*/
8017                         if (pPartType->drmInfo.szDrm2FullPath) {
8018                                 free(pPartType->drmInfo.szDrm2FullPath);
8019                                 pPartType->drmInfo.szDrm2FullPath = MsgStrCopy(szFullPath);
8020                         }
8021                 }
8022
8023         }
8024         MSG_DEBUG("****   MmsGetMediaPartData:  [Multi part]  E  N  D  (Successfully)  ***\n");
8025
8026         return true;
8027
8028 __CATCH:
8029
8030         if (pFile != NULL) {
8031                 MsgCloseFile(pFile);
8032                 pFile = NULL;
8033         }
8034
8035         return false;
8036 }
8037
8038
8039
8040 bool MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
8041 {
8042         int nRead = 0;
8043         int nRead2 = 0;
8044         char *pData = NULL;
8045         char *pNewData = NULL;
8046         char *pTempData = NULL;
8047         int msgEncodingValue = 0;
8048         int msgTypeValue = 0;
8049         int msgCharsetValue     = 0;
8050         int cidLen = 0;
8051         char *szCid = NULL;
8052         int offset = 0;
8053         int size = 0;
8054
8055         msgEncodingValue = pPartType->encoding;
8056         msgTypeValue = pPartType->type;
8057         msgCharsetValue = pPartType->param.charset;
8058
8059         cidLen = MsgStrlen(szCid);
8060
8061         offset = pPartBody->offset;
8062         size = pPartBody->size;
8063
8064         if (pPartBody->szOrgFilePath[0]) {
8065                 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
8066
8067                 if (pTempData == NULL) {
8068                         MSG_DEBUG("MmsGetMediaPartData : pTempData read fail\n");
8069                         goto __CATCH;
8070                 }
8071
8072                 pData = pTempData;
8073         } else if (pPartBody->body.pText) {
8074                 pData = pPartBody->body.pText;
8075                 nRead = pPartBody->size;
8076         }
8077
8078         if (pData == NULL) {
8079                 MSG_DEBUG("MmsGetMediaPartData : there is no data \n");
8080                 goto __RETURN;
8081         }
8082
8083         pNewData = MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
8084         pPartType->encoding = MSG_ENCODING_BINARY;
8085
8086         if (MsgIsText(msgTypeValue))
8087                 pPartType->param.charset = MSG_CHARSET_UTF8;
8088
8089         if (MsgWriteFile(pNewData, sizeof(char), nRead2,  pFile) != (size_t)nRead2) {
8090                 MSG_DEBUG("MmsGetMediaPartData: file writing fail \n");
8091
8092                 goto __CATCH;
8093         }
8094
8095 __RETURN:
8096
8097         if (pNewData) {
8098                 free(pNewData);
8099                 pNewData = NULL;
8100         }
8101
8102         if (pTempData) {
8103                 free(pTempData);
8104                 pTempData = NULL;
8105         }
8106
8107         return true;
8108
8109 __CATCH:
8110
8111         if (pNewData) {
8112                 free(pNewData);
8113                 pNewData = NULL;
8114         }
8115
8116         if (pTempData) {
8117                 free(pTempData);
8118                 pTempData = NULL;
8119         }
8120
8121         return false;
8122 }
8123
8124 char *MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
8125 {
8126         int nChar = 0;
8127         int nByte = 0;
8128         int nTemp = 0;
8129         char *pTemp = NULL;
8130         unsigned short *mszTempStr = NULL;
8131         char *pConvertedStr     = NULL;
8132         char *pConvertedData = NULL;
8133         char *pNewData = NULL;
8134         char *pReturnData = NULL;
8135
8136
8137         switch (msgEncodingValue) {
8138         case MSG_ENCODING_BASE64:
8139
8140                 pConvertedData = (char*)_MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
8141                 MSG_DEBUG("MmsGetBinaryUTF8Data : MSG_ENCODING_BASE64     bodyLength = %d \n", nByte);
8142
8143                 pTemp = pConvertedData;
8144                 nTemp = nByte;
8145
8146                 break;
8147
8148         case MSG_ENCODING_QUOTE_PRINTABLE:
8149
8150                 pConvertedData = (char*)_MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
8151                 MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_ENCODING_QUOTE_PRINTABLE     bodyLength = %d \n", nByte);
8152
8153                 pTemp = pConvertedData;
8154                 nTemp = nByte;
8155
8156                 break;
8157
8158         default:
8159
8160                 MSG_DEBUG("MmsGetBinaryUTF8Data: 8bit    OR    Binary   bodyLength = %d \n", nRead);
8161
8162                 pTemp = pData;
8163                 nTemp = nRead;
8164
8165                 break;
8166         }
8167
8168         if (MsgIsText(msgTypeValue)) {
8169                 /* charset converting */
8170
8171                 switch (msgCharsetValue) {
8172                 case MSG_CHARSET_UTF16:
8173                 case MSG_CHARSET_USC2:
8174
8175                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_USC2 \n");
8176
8177                         if (((UINT8)pTemp[0]) == 0xFF && ((UINT8)pTemp[1]) == 0xFE) {
8178                                 nChar = (nTemp / 2 - 1);
8179
8180                                 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
8181                                 if (mszTempStr == NULL) {
8182                                         MSG_DEBUG("MmsGetBinaryUTF8Data : 1. Memory Full !!! \n");
8183                                         goto __CATCH;
8184                                 }
8185
8186                                 memcpy(mszTempStr, ((unsigned short*)pTemp + 1), nChar * sizeof(unsigned short));
8187
8188                                 nByte = MsgGetUnicode2UTFCodeSize(((unsigned short*)pTemp + 1), nChar);
8189
8190                                 pConvertedStr = (char *)malloc(nByte + 1);
8191                                 if (pConvertedStr != NULL)
8192                                         MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
8193                         } else {
8194                                 nChar = (nTemp / 2);
8195
8196                                 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
8197                                 if (mszTempStr == NULL) {
8198                                         MSG_DEBUG("MmsGetBinaryUTF8Data: 2. Memory Full !!! \n");
8199                                         goto __CATCH;
8200                                 }
8201
8202                                 memcpy(mszTempStr, ((unsigned short*)pTemp), nChar * sizeof(unsigned short));
8203
8204                                 nByte = MsgGetUnicode2UTFCodeSize(((unsigned short*)pTemp), nChar);
8205
8206                                 pConvertedStr = (char *)malloc(nByte + 1);
8207                                 if (pConvertedStr)
8208                                         MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
8209                         }
8210
8211                         if (pConvertedStr != NULL)
8212                                 pNewData = pConvertedStr;
8213
8214                         *npRead = nByte + 1;
8215
8216                         break;
8217
8218                 case MSG_CHARSET_US_ASCII:
8219
8220                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_US_ASCII \n");
8221
8222                         /* fall through */
8223
8224                 case MSG_CHARSET_UTF8:
8225
8226                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_UTF8 or Others \n");
8227
8228                         // skip BOM (Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM)
8229                         if (nTemp >= 3) {
8230                                 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
8231                                         pTemp += 3;
8232                                         nTemp -= 3;
8233                                 }
8234                         }
8235                         pNewData = pTemp;
8236                         *npRead = nTemp;
8237
8238                         break;
8239
8240                 case MSG_CHARSET_ISO_8859_7:
8241
8242                         /* Greek */
8243
8244                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_ISO_8859_7 \n");
8245
8246                         nByte = MsgGetLatin72UTFCodeSize((unsigned char*)pTemp, nTemp);
8247                         pConvertedStr = (char *)malloc(nByte + 1);
8248                         if (pConvertedStr)
8249                                 MsgLatin7code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
8250
8251                         pNewData = pConvertedStr;
8252                         *npRead = nByte + 1;
8253
8254                         break;
8255
8256                 case MSG_CHARSET_ISO_8859_9:
8257
8258                         /* Turkish */
8259                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_ISO_8859_9 \n");
8260
8261                         nByte = MsgGetLatin52UTFCodeSize((unsigned char*)pTemp, nTemp);
8262                         pConvertedStr = (char *)malloc(nByte + 1);
8263                         if (pConvertedStr)
8264                                         MsgLatin5code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
8265
8266                         pNewData = pConvertedStr;
8267                         *npRead = nByte + 1;
8268
8269                         break;
8270
8271                 default:
8272
8273                         MSG_DEBUG("MmsGetBinaryUTF8Data: Other charsets \n");
8274
8275                         nByte = MsgGetLatin2UTFCodeSize((unsigned char*)pTemp, nTemp);
8276                         pConvertedStr = (char *)malloc(nByte + 1);
8277                         if (pConvertedStr)
8278                                 MsgLatin2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
8279
8280                         pNewData = pConvertedStr;
8281                         *npRead = nByte + 1;
8282
8283                         break;
8284                 }
8285         } else {
8286                 pNewData = pTemp;
8287                 *npRead = nTemp;
8288         }
8289
8290         pReturnData = (char *)malloc(*npRead);
8291         if (pReturnData == NULL) {
8292                 MSG_DEBUG("MmsGetBinaryUTF8Data : pReturnData alloc fail. \n");
8293
8294                 goto __CATCH;
8295         }
8296
8297         if (pNewData != NULL) {
8298                 memset(pReturnData, 0, *npRead);
8299                 memcpy(pReturnData, pNewData, *npRead);
8300         }
8301
8302         if (pConvertedData) {
8303                 free(pConvertedData);
8304                 pConvertedData = NULL;
8305         }
8306
8307         if (pConvertedStr) {
8308                 free(pConvertedStr);
8309                 pConvertedStr = NULL;
8310         }
8311
8312         if (mszTempStr) {
8313                 free(mszTempStr);
8314                 mszTempStr = NULL;
8315         }
8316
8317         return pReturnData;
8318
8319 __CATCH:
8320
8321         if (pConvertedData) {
8322                 free(pConvertedData);
8323                 pConvertedData = NULL;
8324         }
8325
8326         if (pConvertedStr) {
8327                 free(pConvertedStr);
8328                 pConvertedStr = NULL;
8329         }
8330
8331         if (mszTempStr) {
8332                 free(mszTempStr);
8333                 mszTempStr = NULL;
8334         }
8335
8336         return NULL;
8337 }
8338
8339 #ifndef __SUPPORT_DRM__
8340 bool MsgMakeFileName(int iMsgType, char *szFileName, int nUntitleIndex)
8341 {
8342         char szText[MSG_FILENAME_LEN_MAX+1]={0,};
8343         char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
8344         char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
8345         char *pExt = NULL;
8346
8347
8348         MSG_DEBUG("MsgMakeFileName: iMsgType = %d     szFileName = %s \n", iMsgType, szFileName);
8349
8350         if (szFileName == NULL)
8351                 return false;
8352
8353         if (szFileName && (szFileName[0] != '\0')) {
8354                 MsgGetFileNameWithoutExtension (szTempFileName, szFileName);
8355
8356                 pExt = strrchr(szTempFileName, '.');
8357                 if (pExt == NULL) {
8358                         memset  (szText, 0, MSG_FILENAME_LEN_MAX+1);
8359                         strncpy(szText, szTempFileName, MSG_FILEPATH_LEN_MAX - 1);
8360                         strcat(szText, ".");                    // add '.'
8361                 } else {
8362                         memset  (szText, 0, MSG_FILENAME_LEN_MAX+1);
8363                         strncpy(szText, szTempFileName, pExt+1 - szFileName);   // add '.'
8364                 }
8365         } else {
8366                 if (nUntitleIndex >= 1) {
8367                         snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s_%d.", "Untitled", nUntitleIndex);
8368                 } else {
8369                         snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s.", "Untitled");
8370                 }
8371         }
8372
8373         if (iMsgType == MIME_APPLICATION_OCTET_STREAM) {
8374                 MSG_DEBUG("MsgMakeFileName: unsupported MsgType\n");
8375                 goto __CATCH;
8376         } else {
8377                 int             nLen = 0;
8378                 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
8379                 if (iMsgType == MIME_UNKNOWN || (pExt = MimeGetExtFromMimeInt((MimeType)iMsgType)) == NULL) {
8380                         MSG_DEBUG("MsgMakeFileName: Failed to get extension of that mime data file. \n");
8381                         goto __CATCH;
8382                 }
8383                 nLen = MSG_FILENAME_LEN_MAX - strlen(szTemp);
8384                 strncat(szTemp, pExt, nLen);
8385         }
8386
8387
8388         strcpy(szFileName, szTemp);
8389
8390         MSG_DEBUG("MsgMakeFileName: made szFileName = %s \n", szFileName);
8391
8392         return true;
8393
8394 __CATCH:
8395         {
8396                 char *p = NULL;
8397                 p = strrchr(szText, '.');
8398                 if (p != NULL)
8399                         *p = 0;
8400                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", szText);
8401
8402                 return false;
8403         }
8404 }
8405 #else
8406 bool MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex)
8407 {
8408         char szText[MSG_FILENAME_LEN_MAX+1]={0,};
8409         char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
8410         char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
8411         char *pExt = NULL;
8412
8413         MSG_DEBUG("MsgMakeFileName: iMsgType = 0x%x, drmType = %d, szFileName = %s \n", iMsgType, drmType, szFileName);
8414
8415         if (szFileName == NULL)
8416                 return false;
8417
8418         if (szFileName && (szFileName[0] != '\0')) {
8419                 MsgGetFileNameWithoutExtension (szTempFileName, szFileName);
8420
8421                 if (drmType != MSG_DRM_TYPE_NONE) {
8422                         pExt = strrchr(szTempFileName, '.');
8423                         if (pExt == NULL) {
8424                                 memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
8425                                 strncpy(szText, szTempFileName, MSG_FILENAME_LEN_MAX - 1);
8426                                 strcat(szText, ".");                    // add '.'
8427                         } else {
8428                                 memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
8429                                 strncpy(szText, szTempFileName, pExt+1 - szFileName);
8430                         }
8431                 } else {
8432                         if (strrchr(szTempFileName, '.'))
8433                                 return true;
8434
8435                         memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
8436                         strncpy(szText, szTempFileName, MSG_FILENAME_LEN_MAX - 1);
8437                 //temporary commented to save file as original name.
8438                         pExt = strrchr(szFileName, '.');
8439                 }
8440         } else {
8441                 if (nUntitleIndex >= 1) {
8442                         snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s_%d.", "untitled", nUntitleIndex);
8443                 } else {
8444                         snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s.", "untitled");
8445                 }
8446         }
8447
8448         if (drmType == MSG_DRM_TYPE_SD) {
8449                 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
8450                 strcat(szTemp, "dcf");
8451         } else if (MsgDRMIsForwardLockType(drmType)) {
8452                 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 4);
8453                 strcat(szTemp, "dm");
8454         } else {
8455                 if (iMsgType == MIME_APPLICATION_OCTET_STREAM) {
8456                         MSG_DEBUG("MsgMakeFileName: unsupported MsgType\n");
8457                         goto __CATCH;
8458                 } else {
8459                         int             nLen = 0;
8460                         strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
8461                         //temporary commented to save file as original name.
8462                         if (pExt == NULL) {
8463
8464                                 if (iMsgType == MIME_UNKNOWN || (pExt = MimeGetExtFromMimeInt((MimeType)iMsgType)) == NULL) {
8465                                         MSG_DEBUG("MsgMakeFileName: Failed to get extension of that mime data file. \n");
8466                                         goto __CATCH;
8467                                 }
8468                         }
8469
8470                         nLen = MSG_FILENAME_LEN_MAX - strlen(szTemp);
8471                         strncat(szTemp, pExt, nLen);
8472                 }
8473         }
8474
8475         strcpy(szFileName, szTemp);
8476
8477         MSG_DEBUG("MsgMakeFileName: made szFileName = %s \n", szFileName);
8478
8479         return true;
8480
8481 __CATCH:
8482         {
8483                 char *p = NULL;
8484                 p = strrchr(szText, '.');
8485                 if (p != NULL)
8486                         *p = 0;
8487                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", szText);
8488
8489                 return false;
8490         }
8491 }
8492 #endif
8493
8494 bool MsgGetFileNameWithoutExtension (char *szOutputName, char *szName)
8495 {
8496         char *pszExt = NULL;
8497
8498         if (szOutputName == NULL) {
8499                 MSG_DEBUG("szOutputName is NULL");
8500                 return false;
8501         }
8502
8503         strncpy(szOutputName, szName, strlen(szName));
8504
8505         if ((pszExt = strrchr(szOutputName, '.'))) {
8506                 if (pszExt[0] == '.')
8507                         pszExt[0] = '\0';
8508         }
8509
8510         return true;
8511 }
8512
8513 int MmsGetMediaPartCount(MSG_MESSAGE_ID_T msgId)
8514 {
8515         MmsMsg *pMsg;
8516
8517         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
8518
8519         if (msgId != pMsg->msgID) {
8520                 MSG_DEBUG("Invalid Message Id");
8521                 return -1;
8522         }
8523
8524         return pMsg->nPartCount;
8525 }
8526
8527 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
8528 {
8529         MmsMsg *pMsg = NULL;
8530         MsgMultipart *pPart = NULL;
8531
8532         if (pHeader == NULL) {
8533                 MSG_DEBUG("MmsGetMediaPartHeader: Invalid pHeader input. It's null \n");
8534                 return false;
8535         }
8536
8537         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
8538
8539         _MsgInitMsgType(pHeader);
8540
8541
8542         /* Requires header of non-presentation */
8543         if (MsgIsMultipart(pMsg->msgType.type)) {
8544                 MSG_DEBUG("MmsGetMediaPartHeader: Multipart header [index = %d] \n", index);
8545
8546                 pPart = pMsg->msgBody.body.pMultipart;
8547
8548                 while (pPart && index--)
8549                         pPart = pPart->pNext;
8550
8551                 if (pPart == NULL) {
8552                         MSG_DEBUG("MmsGetMediaPartHeader: There is no such msg part.\n");
8553                         return false;
8554                 }
8555
8556                 memcpy(pHeader, &pPart->type, sizeof(MsgType));
8557         } else {
8558                 MSG_DEBUG("MmsGetMediaPartHeader: Requires singlepart header \n");
8559                 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
8560         }
8561
8562         return true;
8563 }
8564
8565 bool MmsDebugPrintMulitpartEntry(MsgMultipart *pMultipart, int index)
8566 {
8567         MSG_DEBUG("------------------------------\n");
8568         MSG_DEBUG("%dth multipart info\n", index);
8569         MSG_DEBUG("header size=%d\n", pMultipart->type.size);
8570         MSG_DEBUG("body size=%d\n", pMultipart->type.contentSize);
8571         MSG_DEBUG("content type=%s\n", MmsDebugGetMimeType((MimeType)pMultipart->type.type));
8572         MSG_DEBUG("content ID=%s\n", pMultipart->type.szContentID);
8573         MSG_DEBUG("content location=%s\n", pMultipart->type.szContentLocation);
8574
8575         if (pMultipart->type.type == MIME_TEXT_PLAIN) {
8576                 MSG_DEBUG("text info\n");
8577                 MSG_DEBUG("charset=%d\n", pMultipart->type.param.charset);
8578                 MSG_DEBUG("text file name=%s\n", pMultipart->type.param.szName);
8579         }
8580 #ifdef __SUPPORT_DRM__
8581         if (pMultipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
8582                 MSG_DEBUG("drm info\n");
8583                 MSG_DEBUG("drm type=%d      (0: NONE 1: Fowward Lock, 2:Combined Delivery, 3: Separated Delivery)\n", pMultipart->type.drmInfo.drmType);
8584                 MSG_DEBUG("drm content type=%s\n", MmsDebugGetMimeType((MimeType)pMultipart->type.drmInfo.contentType));
8585                 MSG_DEBUG("drm content URI=%s\n", pMultipart->type.drmInfo.szContentURI);
8586                 MSG_DEBUG("drm2FullPath=%s\n", pMultipart->type.drmInfo.szDrm2FullPath);
8587         }
8588 #endif
8589         MSG_DEBUG("------------------------------\n");
8590         return true;
8591 }
8592