2 * Copyright 2012-2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include "MsgUtilFile.h"
25 #include "MmsPluginDebug.h"
26 #include "MmsPluginDecode.h"
27 #include "MmsPluginCodecCommon.h"
28 #include "MmsPluginStorage.h"
29 #include "MmsPluginDebug.h"
30 #include "MmsPluginMIME.h"
31 #include "MmsPluginAvCodec.h"
32 #include "MmsPluginSmil.h"
33 #include "MmsPluginTextConvert.h"
34 #include "MmsPluginUtil.h"
36 #ifdef __SUPPORT_DRM__
37 #include "MmsPluginDrm.h"
38 #include "MsgDrmWrapper.h"
43 static int __MmsGetDecodeOffset(void);
44 static bool __MmsDecodeInitialize(void);
45 static void __MmsCleanDecodeBuff(void);
46 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength);
47 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength);
49 static bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength); /* bufLen < gMmsDecodeMaxLen */
50 static bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength); /* no bufLen limit */
51 static bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength);
53 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength);
55 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength);
56 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength);
57 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength);
58 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength);
59 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength);
60 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength);
61 static char *__MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength);
62 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
63 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
65 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength);
66 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength);
67 static MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength);
69 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
70 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
71 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength);
72 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength);
73 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength);
74 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength);
76 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength);
78 #ifdef __SUPPORT_DRM__
79 static bool __MmsBinaryDecodeDRMContent(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int bodyLength, int totalLength);
83 static void __MsgRemoveFilePath(char *pSrc);
84 static bool __MsgChangeSpace(char *pOrg, char **ppNew);
85 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo);
86 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam);
87 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *npRead, int endOfFile);
88 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr);
89 static bool __MsgCheckFileNameHasInvalidChar(char *szName);
91 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar);
92 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter);
93 static bool __MsgParseParameter(MsgType *pType, char *pSrc);
94 static char *__MsgSkipWS(char *s);
95 static char *__MsgSkipComment(char *s, long trim);
96 static MsgMultipart *__MsgAllocMultipart(void);
98 static char *__MsgConvertLatin2UTF8FileName(char *pSrc);
99 static bool __MsgIsUTF8String(unsigned char *szSrc, int nChar);
100 static bool __MsgIsPercentSign(char *pSrc);
101 static bool __MsgIsMultipartRelated(int type);
102 static bool __MsgIsPresentablePart(int type);
103 static bool __MsgIsText(int type);
104 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody);
105 static bool __MsgIsHexChar(char *pSrc);
106 static char __MsgConvertHexValue(char *pSrc);
107 static int __MsgConvertCharToInt(char ch);
108 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2);
109 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2);
110 static bool __MsgIsMultipartMixed(int type);
112 static bool __MsgIsInvalidFileNameChar(char ch);
114 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar);
115 static int __MsgLatin5code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
116 static int __MsgGetLatin52UTFCodeSize(unsigned char *szSrc, int nChar);
117 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
118 static int __MsgLatin7code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
119 static int __MsgGetLatin72UTFCodeSize(unsigned char *szSrc, int nChar);
120 static int __MsgUnicode2UTF(unsigned char *des, int outBufSize, unsigned short *szSrc, int nChar);
121 static int __MsgGetUnicode2UTFCodeSize(unsigned short *szSrc, int nChar);
122 static bool __MmsAddrUtilCheckEmailAddress(char *pszAddr);
123 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
124 static void __MsgMIMERemoveQuote(char *szSrc);
125 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave);
127 static bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE *pFile);
128 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead);
130 #ifndef __SUPPORT_DRM__
131 static bool __MsgMakeFileName(int iMsgType, char *szFileName, int nUntitleIndex);
133 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen);
136 static bool __MmsDebugPrintMulitpartEntry(MsgMultipart *pMultipart, int index);
138 static char gszMmsLoadBuf1[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
139 static char gszMmsLoadBuf2[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
141 static char *gpCurMmsDecodeBuff = NULL;
142 static int gCurMmsDecodeBuffPos = 0; /* next decoding position in gpCurMmsDecodeBuff */
143 static int gMmsDecodeMaxLen = 0;
144 static int gMmsDecodeCurOffset = 0; /* current offset in file (last read) */
145 static int gMmsDecodeBufLen = 0; /* number of last read characters */
147 static char *gpMmsDecodeBuf1 = NULL;
148 static char *gpMmsDecodeBuf2 = NULL;
150 __thread MmsHeader mmsHeader =
156 (MmsMsgType)MMS_MSGTYPE_ERROR, //MmsMsgType iType;
158 //"", //short int version;
159 0, //short int version;
162 NULL, //MsgHeaderAddress* pFrom;
163 NULL, //MsgHeaderAddress* pTo;
164 NULL, //MsgHeaderAddress* pCc;
165 NULL, //MsgHeaderAddress* pBcc;
166 "", //char[] szSubject;
167 (MmsResponseStatus)MMS_RESPSTATUS_OK, //MmsResponseStatus iResponseStatus;
168 (MmsRetrieveStatus)MMS_RETRSTATUS_OK, //MmsRetrieveStatus iRetrieveStatus;
169 "", //char[] szResponseText;
170 "", //char[] szRetrieveText;
173 /* has default value in specification */
175 (MmsMsgClass)MMS_MSGCLASS_PERSONAL, //MmsMsgClass msgClass;
176 {MMS_TIMETYPE_RELATIVE, 0}, //MmsTimeStruct expiryTime;
177 {MMS_TIMETYPE_RELATIVE, 0}, //MmsTimeStruct deliveryTime;
178 (MmsPriority)MMS_PRIORITY_NORMAL, //MmsPriority priority; // Refer [OMA-MMS-ENC-v1_2-20030915-C]
179 (MmsSenderVisible)MMS_SENDER_SHOW, //MmsSenderVisible senderVisible;
180 (MmsReport)MMS_REPORT_NO, //MmsReport deliveryReport;
181 (MmsReport)MMS_REPORT_NO, //MmsReport readReply;
182 (MmsReportAllowed)MMS_REPORTALLOWED_NO,//MmsReportAllowed iReportAllowed;
183 "", //char[] szContentLocation;
186 /* there is no right default value */
188 (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE, //MmsMsgStatus iMsgStatus;
189 (msg_read_report_status_t)MSG_READ_REPORT_NONE, //MmsReadStatus readStatus;
191 /* MMS v1.1 ReplyCharge */
193 (MmsReplyChargeType)MMS_REPLY_NONE, //MmsReplyChargeType chargeType;
194 {MMS_TIMETYPE_RELATIVE, 0}, //MmsTimeStruct deadLine;
196 "" , //char szChargeID;
199 "", //char[] szMsgID;
203 #ifdef __SUPPORT_DRM__
205 #define MMS_DRM2_CONVERT_BUFFER_MAX 4*1024
206 const UINT32 MMS_UINTVAR_LENGTH_1 = 0x0000007f; //7bit
207 const UINT32 MMS_UINTVAR_LENGTH_2 = 0x00003fff; //14bit
208 const UINT32 MMS_UINTVAR_LENGTH_3 = 0x001fffff; //21bit
211 static bool __MmsDecodeInitialize(void)
213 MmsInitMsgType(&mmsHeader.msgType);
214 MmsInitMsgBody(&mmsHeader.msgBody);
220 mmsHeader.type = MMS_MSGTYPE_ERROR;
222 memset(mmsHeader.szTrID, 0, MMS_TR_ID_LEN + 1);
223 mmsHeader.version = MMS_VERSION;
226 __MsgFreeHeaderAddress(mmsHeader.pFrom);
227 __MsgFreeHeaderAddress(mmsHeader.pTo);
228 __MsgFreeHeaderAddress(mmsHeader.pCc);
229 __MsgFreeHeaderAddress(mmsHeader.pBcc);
231 mmsHeader.pFrom = NULL;
232 mmsHeader.pTo = NULL;
233 mmsHeader.pCc = NULL;
234 mmsHeader.pBcc = NULL;
236 memset(mmsHeader.szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
238 mmsHeader.responseStatus = (MmsResponseStatus)MMS_RESPSTATUS_OK;
239 mmsHeader.retrieveStatus = (MmsRetrieveStatus)MMS_RETRSTATUS_OK;
240 memset(mmsHeader.szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
241 memset(mmsHeader.szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
244 mmsHeader.msgClass = (MmsMsgClass)MMS_MSGCLASS_PERSONAL;
245 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
246 mmsHeader.expiryTime.time = 0;
247 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
248 mmsHeader.deliveryTime.time = 0;
249 mmsHeader.priority = (MmsPriority)MMS_PRIORITY_NORMAL; // Refer [OMA-MMS-ENC-v1_2-20030915-C]
250 mmsHeader.hideAddress =(MmsSenderVisible)MMS_SENDER_SHOW;
251 mmsHeader.deliveryReport = (MmsReport)MMS_REPORT_NO;
252 mmsHeader.readReply = (MmsReport)MMS_REPORT_NO;
253 mmsHeader.reportAllowed = (MmsReportAllowed)MMS_REPORTALLOWED_YES;
254 memset(mmsHeader.szContentLocation, 0, MMS_LOCATION_LEN + 1);
257 mmsHeader.msgStatus = (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE;
258 mmsHeader.readStatus = (msg_read_report_status_t)MSG_READ_REPORT_NONE;
260 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MMS_REPLY_NONE;
261 mmsHeader.replyCharge.chargeSize = 0;
262 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
263 mmsHeader.replyCharge.deadLine.time = 0;
264 memset(mmsHeader.replyCharge.szChargeID, 0, MMS_MSG_ID_LEN + 1);
267 memset(mmsHeader.szMsgID, 0, MMS_MSG_ID_LEN + 1);
268 mmsHeader.msgSize = 0;
269 #ifdef __SUPPORT_DRM__
270 mmsHeader.drmType = MSG_DRM_TYPE_NONE;
273 __MmsDecodeInitialize();
276 void MmsReleaseHeader(MmsHeader *mms)
278 __MsgFreeHeaderAddress(mms->pFrom);
279 __MsgFreeHeaderAddress(mms->pTo);
280 __MsgFreeHeaderAddress(mms->pCc);
281 __MsgFreeHeaderAddress(mms->pBcc);
283 mmsHeader.pFrom = NULL;
284 mmsHeader.pTo = NULL;
285 mmsHeader.pCc = NULL;
286 mmsHeader.pBcc = NULL;
290 static void __MmsCleanDecodeBuff(void)
292 memset(gpMmsDecodeBuf1, 0, gMmsDecodeMaxLen + 1);
293 memset(gpMmsDecodeBuf2, 0, gMmsDecodeMaxLen + 1);
294 gpCurMmsDecodeBuff = NULL;
295 gCurMmsDecodeBuffPos = 0;
296 gMmsDecodeBufLen = 0;
299 void MmsRegisterDecodeBuffer()
301 gpMmsDecodeBuf1 = gszMmsLoadBuf1;
302 gpMmsDecodeBuf2 = gszMmsLoadBuf2;
303 gpCurMmsDecodeBuff = NULL;
304 gCurMmsDecodeBuffPos = 0;
305 gMmsDecodeMaxLen = MSG_MMS_DECODE_BUFFER_MAX;
306 gMmsDecodeCurOffset = 0;
307 gMmsDecodeBufLen = 0;
310 void MmsUnregisterDecodeBuffer(void)
312 gpMmsDecodeBuf1 = NULL;
313 gpMmsDecodeBuf2 = NULL;
314 gpCurMmsDecodeBuff = NULL;
315 gCurMmsDecodeBuffPos = 0;
316 gMmsDecodeMaxLen = 0;
317 gMmsDecodeCurOffset = 0;
318 gMmsDecodeBufLen = 0;
322 static int __MmsGetDecodeOffset(void)
324 return (gMmsDecodeCurOffset - gMmsDecodeBufLen + gCurMmsDecodeBuffPos);
327 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength)
329 if (*pLength <= valueLength) {
330 gCurMmsDecodeBuffPos -= valueLength;
331 gCurMmsDecodeBuffPos += *pLength;
335 *pLength -= valueLength;
341 /* ==========================================================
343 B I N A R Y D E C O D I N G
345 ==========================================================*/
348 * Binary Encoded Message Format
350 * < Single Part Body Message >
351 * -----------------------------------
353 * -----------------------------------
354 * | Content Type:start=xxx;type=xxx | ->(ex) Text/Plain, Text/Html, ....
355 * -----------------------------------
356 * | Single Part Body |
357 * -----------------------------------
359 * < Multi Part Body Message >
360 * -----------------------------------
362 * -----------------------------------
363 * | Content Type:start=xxx;type=xxx | -> (ex) Application/vnd.wap.multipart.mixed(related), multipart/mixed(related)
364 * -----------------------------------
365 * | # of Entries (body parts) |
366 * ----------------------------------- < Each Entry >
367 * | Entry 1 | -> -----------------------------
368 * ----------------------------------- | header Length |
369 * | Entry 2 | -----------------------------
370 * ----------------------------------- | Data Length |
371 * | ...... | ----------------------------- -
372 * ----------------------------------- | Content-Type | |
373 * | Entry n | ----------------------------- | Header Length
374 * ----------------------------------- | Header | |
375 * ----------------------------- -
376 * | Data | | Data Length
377 * ----------------------------- -
379 bool MmsBinaryDecodeMsgHeader(FILE *pFile, int totalLength)
382 UINT16 fieldCode = 0xffff;
383 UINT16 fieldValue = 0xffff;
384 UINT8 oneByte = 0xff;
386 MsgHeaderAddress *pAddr = NULL;
387 MsgHeaderAddress *pLastTo = NULL;
388 MsgHeaderAddress *pLastCc = NULL;
389 MsgHeaderAddress *pLastBcc = NULL;
391 UINT32 valueLength = 0;
392 UINT32 tmpInteger = 0;
397 char szGarbageBuff[MSG_STDSTR_LONG] = {0, };
398 char *pLimitData = NULL;
401 MSG_DEBUG("pFile ptr : [%p], total len = [%d]", pFile, totalLength);
403 __MmsCleanDecodeBuff();
405 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
406 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
407 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
408 MSG_FATAL("fail to load to buffer");
412 while (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength)) {
413 fieldCode = oneByte & 0x7f;
415 switch (MmsGetBinaryType(MmsCodeFieldCode, fieldCode)) {
416 case MMS_CODE_RESPONSESTATUS:
418 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
419 MSG_DEBUG("responseStatus GetOneByte fail");
423 // range 197 to 223 as it does to the value 192 (Error-transient-failure).
424 // range 236 to 255 as it does to the value 224 (Error-permanent-failure).
425 if (fieldValue >= 0x0045 && fieldValue <= 0x005F) {
427 } else if (fieldValue >= 0x006A && fieldValue <= 0x007F) {
431 fieldValue = MmsGetBinaryType(MmsCodeResponseStatus, (UINT16)(oneByte & 0x7F));
433 if (fieldValue == 0xFFFF) {
434 MSG_DEBUG("responseStatus error");
438 mmsHeader.responseStatus = (MmsResponseStatus)fieldValue;
440 MSG_DEBUG("X-Mms-Response-Status = [0x%02x][%s]", oneByte, MmsDebugGetResponseStatus(mmsHeader.responseStatus));
443 case MMS_CODE_RETRIEVESTATUS:
445 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
446 MSG_DEBUG("retrieveStatus GetOneByte fail");
450 fieldValue = MmsGetBinaryType(MmsCodeRetrieveStatus, (UINT16)(oneByte & 0x7F));
452 if (fieldValue == 0xFFFF) {
453 MSG_DEBUG("retrieveStatus error");
457 if (fieldValue >= 0x0043 && fieldValue <= 0x005F) {
458 fieldValue = 0x0040; // 192; Error-transient-failure
459 } else if (fieldValue >= 0x0064 && fieldValue <= 0x007F) {
460 fieldValue = 0x0060; //224; Error-permanent-failure
463 mmsHeader.retrieveStatus = (MmsRetrieveStatus)fieldValue;
465 MSG_DEBUG("X-Mms-Retrieve-Status = [0x%02x][%s]", oneByte, MmsDebugGetRetrieveStatus(mmsHeader.retrieveStatus));
469 case MMS_CODE_RESPONSETEXT:
471 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szResponseText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
472 MSG_DEBUG("invalid MMS_CODE_RESPONSETEXT");
476 MSG_DEBUG("X-Mms-Response-Text = [%s]", mmsHeader.szResponseText);
479 case MMS_CODE_RETRIEVETEXT:
481 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szRetrieveText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
482 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
486 MSG_DEBUG("X-Mms-Retrieve-Text = [%s]", mmsHeader.szRetrieveText);
491 if (__MmsBinaryDecodeText(pFile, mmsHeader.szMsgID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
492 MSG_DEBUG("MMS_CODE_MSGID is invalid");
496 MSG_DEBUG("Message-ID =[%s]", mmsHeader.szMsgID);
498 if (MsgStrlen (mmsHeader.szMsgID) > 2)
499 __MsgMIMERemoveQuote (mmsHeader.szMsgID);
503 case MMS_CODE_SUBJECT:
505 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN + 1, totalLength) == false) {
506 MSG_DEBUG("invalid MMS_CODE_SUBJECT");
510 pLimitData = (char *)malloc(MSG_LOCALE_SUBJ_LEN + 1);
512 if (pLimitData == NULL) {
513 MSG_DEBUG("pLimitData malloc fail");
517 nRead = __MsgCutUTFString((unsigned char*)pLimitData, MSG_LOCALE_SUBJ_LEN + 1, (unsigned char*)mmsHeader.szSubject, MSG_SUBJ_LEN);
518 MSG_DEBUG("Subject edit..");
520 if (nRead > MSG_LOCALE_SUBJ_LEN) {
521 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
522 strncpy(mmsHeader.szSubject, pLimitData, MSG_SUBJ_LEN);
524 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
525 strncpy(mmsHeader.szSubject, pLimitData, MSG_LOCALE_SUBJ_LEN);
533 MSG_DEBUG("Subject = [%s]", mmsHeader.szSubject);
538 /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
540 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
541 MSG_DEBUG("MMS_CODE_FROM is invalid");
545 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
546 MSG_DEBUG("MMS_CODE_FROM GetOneByte fail");
550 // DRM_TEMPLATE - start
554 if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
555 if (valueLength > 0) {
556 mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
557 if (mmsHeader.pFrom == NULL) {
558 MSG_DEBUG("MMS_CODE_FROM __MmsDecodeEncodedAddress fail");
562 mmsHeader.pFrom = (MsgHeaderAddress *)malloc(sizeof(MsgHeaderAddress));
563 if (mmsHeader.pFrom == NULL)
566 mmsHeader.pFrom->szAddr = (char *)malloc(1);
567 if (mmsHeader.pFrom->szAddr == NULL) {
568 free(mmsHeader.pFrom);
569 mmsHeader.pFrom = NULL;
573 mmsHeader.pFrom->szAddr[0] = '\0';
574 mmsHeader.pFrom->pNext = NULL;
577 MSG_DEBUG("From = [%s]", mmsHeader.pFrom->szAddr);
578 // DRM_TEMPLATE - end
579 } else if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
580 /* Present Token only */
581 MSG_DEBUG("From = [insert token]");
583 /* from data broken */
584 MSG_DEBUG("from addr broken");
585 gCurMmsDecodeBuffPos--;
592 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
594 MSG_DEBUG("MMS_CODE_TO __MmsDecodeEncodedAddress fail");
598 if (mmsHeader.pTo == NULL) {
600 pLastTo = mmsHeader.pTo = pAddr;
603 pLastTo->pNext = pAddr;
607 MSG_DEBUG("To = [%s]", mmsHeader.pTo->szAddr);
612 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
614 MSG_DEBUG("MMS_CODE_BCC __MmsDecodeEncodedAddress fail");
618 if (mmsHeader.pBcc == NULL) {
620 pLastBcc = mmsHeader.pBcc = pAddr;
623 pLastBcc->pNext = pAddr;
627 MSG_DEBUG("Bcc = [%s]", mmsHeader.pBcc->szAddr);
632 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
634 MSG_DEBUG("MMS_CODE_CC __MmsDecodeEncodedAddress fail");
638 if (mmsHeader.pCc == NULL) {
640 pLastCc = mmsHeader.pCc = pAddr;
643 pLastCc->pNext = pAddr;
646 MSG_DEBUG("Cc = [%s]", mmsHeader.pCc->szAddr);
649 case MMS_CODE_CONTENTLOCATION:
651 if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
652 MSG_DEBUG("MMS_CODE_CONTENTLOCATION is invalid");
655 MSG_DEBUG("X-Mms-Content-Location = [%s]", mmsHeader.szContentLocation);
660 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
661 MSG_DEBUG("MMS_CODE_DATE is invalid");
665 MSG_DEBUG("Date = [%u]", mmsHeader.date);
668 case MMS_CODE_DELIVERYREPORT:
670 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
671 MSG_DEBUG("deliveryReport GetOneByte fail");
675 fieldValue = MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
677 if (fieldValue == 0xFFFF) {
678 MSG_DEBUG("deliveryReport error");
682 mmsHeader.deliveryReport = (MmsReport)fieldValue;
684 MSG_DEBUG("X-Mms-Delivery-Report =[0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.deliveryReport));
687 case MMS_CODE_DELIVERYTIME:
689 /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
691 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
692 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
696 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
697 MSG_DEBUG("delivery time GetOneByte fail");
701 //DRM_TEMPLATE - start
704 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
705 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
707 if (valueLength > 0) {
708 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
709 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
713 // DRM_TEMPLATE - end
715 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
717 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
718 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
722 MSG_DEBUG("X-Mms-Delivery-Time : type = [%d], time= [%u]", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
725 case MMS_CODE_EXPIRYTIME:
727 /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
729 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
730 MSG_DEBUG("invalid MMS_CODE_EXPIRYTIME");
734 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
735 MSG_DEBUG("expiry time GetOneByte fail");
739 // DRM_TEMPLATE - start
742 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
743 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
745 if (valueLength > 0) {
746 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
747 MSG_DEBUG("MMS_CODE_EXPIRYTIME is invalid");
751 // DRM_TEMPLATE - end
753 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
755 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
756 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
761 MSG_DEBUG("X-Mms-Expiry : type = [%d], time = [%u]", mmsHeader.expiryTime.type, mmsHeader.expiryTime.time);
764 case MMS_CODE_MSGCLASS:
766 /* Class-value = Class-identifier | Token Text */
768 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
769 MSG_DEBUG("msgClass GetOneByte fail");
773 if (oneByte > 0x7f) {
774 /* Class-identifier */
775 mmsHeader.msgClass = (MmsMsgClass)MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
777 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
778 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (class)");
783 MSG_DEBUG("X-Mms-Message-Class =[%s]", MmsDebugGetMsgClass(mmsHeader.msgClass));
786 case MMS_CODE_MSGSIZE:
788 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
789 MSG_DEBUG("MMS_CODE_MSGSIZE is invalid");
793 MSG_DEBUG("X-Mms-Message-Size = [%d]", mmsHeader.msgSize);
796 case MMS_CODE_MSGSTATUS:
798 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
799 MSG_DEBUG("msgStatus GetOneByte fail");
803 mmsHeader.msgStatus = (msg_delivery_report_status_t)MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
804 MSG_DEBUG("X-Mms-Status = [%s]", MmsDebugGetMsgStatus(mmsHeader.msgStatus));
807 case MMS_CODE_MSGTYPE:
809 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
810 MSG_DEBUG("msgStatus GetOneByte fail");
814 mmsHeader.type = (MmsMsgType)MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
815 MSG_DEBUG("X-Mms-Message-Type = [%s]", MmsDebugGetMsgType(mmsHeader.type));
818 case MMS_CODE_PRIORITY:
820 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
821 MSG_DEBUG("msgStatus GetOneByte fail");
824 mmsHeader.priority = (MmsPriority)MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
825 MSG_DEBUG("X-Mms-Priority = [%d]", mmsHeader.priority);
828 case MMS_CODE_READREPLY:
830 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
831 MSG_DEBUG("msgStatus GetOneByte fail");
834 mmsHeader.readReply = (MmsReport)MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
835 MSG_DEBUG("X-Mms-Read-Report = [0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.readReply));
838 case MMS_CODE_REPORTALLOWED:
840 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
841 MSG_DEBUG("msgStatus GetOneByte fail");
844 mmsHeader.reportAllowed = (MmsReportAllowed)MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
845 MSG_DEBUG("X-Mms-Report-Allowed = [%d]", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
848 case MMS_CODE_SENDERVISIBILLITY:
850 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
851 MSG_DEBUG("msgStatus GetOneByte fail");
854 mmsHeader.hideAddress= (MmsSenderVisible)!(MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
855 MSG_DEBUG("X-Mms-Sender-Visibility = [%d]", mmsHeader.hideAddress);
860 if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
861 MSG_DEBUG("Transaction ID Too Long");
864 MSG_DEBUG("X-Mms-Transaction-Id = [%s]", mmsHeader.szTrID);
867 case MMS_CODE_VERSION:
868 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
869 MSG_DEBUG("msgStatus GetOneByte fail");
872 mmsHeader.version = oneByte;
874 MSG_DEBUG("X-Mms-MMS-Version = [0x%02x]", mmsHeader.version);
877 case MMS_CODE_CONTENTTYPE:
880 * Content-type is the last header field of SendRequest and RetrieveConf.
881 * It's required to decrease pointer by one and return,
882 * to parse this field in MmsBinaryDecodeContentType().
887 /* ----------- Add by MMSENC v1.1 ----------- */
889 case MMS_CODE_READSTATUS:
891 /* Read-status-value = Read | Deleted without being read */
893 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
894 MSG_DEBUG("msgStatus GetOneByte fail");
898 mmsHeader.readStatus = (msg_read_report_status_t)MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
899 MSG_DEBUG("X-Mms-Read-Status = [%s]", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
902 case MMS_CODE_REPLYCHARGING:
904 /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
906 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
907 MSG_DEBUG("msgStatus GetOneByte fail");
911 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
912 MSG_DEBUG("X-Mms-Reply-Charging = [%d]", mmsHeader.replyCharge.chargeType);
915 case MMS_CODE_REPLYCHARGINGDEADLINE:
917 /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
919 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
920 MSG_DEBUG("invalid MMS_CODE_REPLYCHARGINGDEADLINE");
924 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
925 MSG_DEBUG("msgStatus GetOneByte fail");
929 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
930 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
932 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
935 // DRM_TEMPLATE - start
938 if (valueLength > 0) {
939 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
940 MSG_DEBUG("MMS_CODE_REPLYCHARGINGDEADLINE is invalid");
945 MSG_DEBUG("X-Mms-Reply-Charging-Deadline : type = [%d], time = [%u]", mmsHeader.replyCharge.deadLine.type, mmsHeader.replyCharge.deadLine.time);
946 // DRM_TEMPLATE - end
949 case MMS_CODE_REPLYCHARGINGID:
951 /* Reply-charging-ID-value = Text-string */
952 if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
953 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (szReplyChargingID)");
956 MSG_DEBUG("X-Mms-Reply-Charging-ID = [%s]", mmsHeader.replyCharge.szChargeID);
959 case MMS_CODE_REPLYCHARGINGSIZE:
961 /* Reply-charging-size-value = Long-integer */
962 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
963 MSG_DEBUG("MMS_CODE_REPLYCHARGINGSIZE is invalid");
966 MSG_DEBUG("X-Mms-Reply-Charging-Size = [%d]", mmsHeader.replyCharge.chargeSize);
969 case MMS_CODE_PREVIOUSLYSENTBY:
972 * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
973 * Forwarded-count-value = Integer-value
974 * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
978 * fixme: There is no proper field to store this information.
979 * Just increase pointer now.
982 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
983 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTBY");
987 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
988 MSG_DEBUG("2. invalid MMS_CODE_PREVIOUSLYSENTBY");
992 if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
993 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
998 case MMS_CODE_PREVIOUSLYSENTDATE:
1001 * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
1002 * Forwarded-count-value = Integer-value
1003 * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
1007 * fixme: There is no proper field to store this information.
1008 * Just increase pointer now.
1011 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
1012 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTDATE");
1016 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
1017 MSG_DEBUG("2. invalid MS_CODE_PREVIOUSLYSENTDATE");
1021 if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
1022 MSG_DEBUG("3. invalid MMS_CODE_PREVIOUSLYSENTDATE");
1030 * Application-header = Token-text Application-specific-value
1031 * Token-text = Token End-of-string
1032 * Application-specific-value = Text -string
1034 * OR unknown header field - Just ignore these fields.
1036 * Read one byte and check the value >= 0x80
1037 * (check these value can be field code)
1040 int remainLength = 0;
1044 offset = __MmsGetDecodeOffset();
1045 if (offset >= totalLength)
1048 remainLength = totalLength - offset;
1050 while ((oneByte < 0x80) && (remainLength > 0)) {
1051 if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1052 MSG_DEBUG("__MmsBinaryDecodeCheckAndDecreaseLength fail");
1055 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1056 MSG_DEBUG("responseStatus GetOneByte fail");
1061 gCurMmsDecodeBuffPos--;
1067 offset = __MmsGetDecodeOffset();
1068 if (offset >= totalLength)
1076 if (mmsHeader.pTo == NULL && pLastTo) {
1080 if (mmsHeader.pCc == NULL && pLastCc) {
1084 if (mmsHeader.pBcc == NULL && pLastBcc) {
1088 MSG_DEBUG("## Decode Header Success ##");
1095 if (mmsHeader.pTo == NULL && pLastTo) {
1099 if (mmsHeader.pCc == NULL && pLastCc) {
1103 if (mmsHeader.pBcc == NULL && pLastBcc) {
1107 MSG_FATAL("## Decode Header Fail ##");
1112 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1119 if (szFilePath != NULL)
1120 strncpy(mmsHeader.msgType.szOrgFilePath, szFilePath , strlen(szFilePath));
1122 mmsHeader.msgType.offset = __MmsGetDecodeOffset() - 1; // + Content-Type code value
1124 // read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding
1125 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1126 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1127 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1128 MSG_DEBUG("fail to load to buffer");
1132 // msg's type [ex] related, mixed, single part (jpg, amr and etc)
1133 length = __MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1135 MSG_DEBUG("MMS_CODE_CONTENTTYPE is fail");
1139 mmsHeader.msgType.size = length + 1; // + Content-Type code value
1140 mmsHeader.msgBody.offset = __MmsGetDecodeOffset();
1142 switch (mmsHeader.msgType.type) {
1143 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1144 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1145 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1146 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1147 case MIME_MULTIPART_REPORT:
1148 case MIME_MULTIPART_MIXED:
1149 case MIME_MULTIPART_RELATED:
1150 case MIME_MULTIPART_ALTERNATIVE:
1151 case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1152 case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1154 MSG_DEBUG("Decode Multipart");
1156 offset = __MmsGetDecodeOffset();
1157 if (offset >= totalLength)
1160 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1161 MSG_DEBUG("MmsBinaryDecodeMultipart is fail.");
1168 /* Single part message ---------------------------------------------- */
1169 MSG_DEBUG("Decode Singlepart");
1171 offset = __MmsGetDecodeOffset();
1172 if (offset >= totalLength)
1175 if (__MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1176 MSG_DEBUG("MmsBinaryDecodePartBody is fail.(Single Part)");
1180 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1181 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1186 #ifdef __SUPPORT_DRM__
1187 mmsHeader.drmType = MsgGetDRMType(&mmsHeader.msgType, &mmsHeader.msgBody);
1198 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1203 char *szTypeString = NULL;
1204 char *szTypeValue = NULL;
1205 UINT8 paramCode = 0xff;
1212 * Parameter = Typed-parameter | Untyped-parameter
1213 * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1216 while (valueLength > 0) {
1217 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1218 MSG_DEBUG("paramCode _MmsBinaryDecodeGetOneByte fail");
1222 paramCode = oneByte;
1225 switch (paramCode) {
1226 case 0x81: // charset
1228 if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1229 MSG_DEBUG("__MmsBinaryDecodeCharset fail.");
1233 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1238 case 0x85: //name = Text-string
1239 case 0x97: //name = Text-value = No-value | Token-text | Quoted-string
1240 memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1241 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szName,
1242 MSG_FILENAME_LEN_MAX -5, // MSG_LOCALE_FILENAME_LEN_MAX + 1, : change @ 110(Ui code have to change for this instead of DM)
1245 MSG_DEBUG("__MmsDecodeGetFilename fail. (name parameter)");
1249 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1250 __MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1253 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1258 case 0x86: //filename = Text-string
1259 case 0x98: //filename = Text-value = No-value | Token-text | Quoted-string
1260 memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1261 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1263 MSG_DEBUG("__MmsDecodeGetFilename fail. (filename parameter)");
1267 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1268 __MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1271 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1276 case 0x89: //type = Constrained-encoding = Extension-Media | Short-integer
1278 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1279 MSG_DEBUG("type _MmsBinaryDecodeGetOneByte fail");
1283 if (oneByte > 0x7f) {
1284 pMsgType->param.type = MmsGetBinaryType(MmsCodeContentType,
1285 (UINT16)(oneByte & 0x7f));
1286 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1289 gCurMmsDecodeBuffPos--;
1292 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1293 pMsgType->param.type = MmsGetTextType(MmsCodeContentType, szTypeString);
1297 szTypeString = NULL;
1300 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1306 case 0x8A: //start encoding version 1.2
1307 case 0x99: //start encoding version 1.4
1310 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1312 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1313 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1315 szTypeString = NULL;
1317 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1323 case 0x8B: //startInfo encoding version 1.2
1324 case 0x9A: //startInfo encoding version 1.4
1327 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1330 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1331 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1334 szTypeString = NULL;
1336 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1344 if (paramCode > 0x7F) {
1345 MSG_DEBUG("Unsupported parameter");
1347 // In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value.
1349 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1353 * Untyped Parameter = Token-text Untyped-value
1354 * Token-text = Token End-of-string
1355 * Untyped-value = Integer-value | Text-value
1356 * Text-value = No-value | Token-text | Quoted-string
1358 * Just increase pointer!!!
1364 gCurMmsDecodeBuffPos--;
1368 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1369 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1375 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1376 MSG_DEBUG("Unsupported parameter(%d)\n", integer);
1377 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1381 szTypeValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1384 /* checkMe: forwardLock needs boudary string */
1385 if (strcasecmp(szTypeString, "boundary") == 0) {
1386 memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1387 strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1388 #ifdef FEATURE_JAVA_MMS
1389 } else if (strcasecmp(szTypeString, "Application-ID") == 0) {
1390 pMsgType->param.szApplicationID = (char*) malloc(textLength + 1);
1391 memset(pMsgType->param.szApplicationID, 0, textLength + 1);
1392 strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1393 MSG_DEBUG("Application-ID:%s",pMsgType->param.szApplicationID);
1394 } else if (strcasecmp(szTypeString,"Reply-To-Application-ID") == 0) {
1395 pMsgType->param.szReplyToApplicationID= (char*) malloc(textLength + 1);
1396 memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1397 strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1398 MSG_DEBUG("ReplyToApplication-ID:%s",pMsgType->param.szReplyToApplicationID);
1404 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeValue);
1405 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1411 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeString);
1413 szTypeString = NULL;
1419 } /*end of while loop*/
1426 szTypeString = NULL;
1438 * Decode Encoded Content type
1440 * @param pEncodedData [in] ContentType encoded data
1441 * @param pMsgType [out] Decoded MsgType
1442 * @return Decoded address list
1444 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1448 char *szTypeString = NULL;
1449 int valueLength = 0;
1455 * Content-type-value : [WAPWSP 8.4.2.24]
1456 * Preassigned content-types : [WAPWSP Appendix A, Table 40]
1457 * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1459 * Content-type-value = Constrained-media | Content-general-form
1460 * Content-general-form = Value-length Media-type
1461 * Media-type = (Well-known-media | Extension-Media) *(Parameter)
1464 length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1467 * Constrained-media or Single part message
1468 * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1469 * Extension-media = *TEXT End-of-string
1470 * Short-integer = OCTET(1xxx xxxx)
1473 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1474 MSG_DEBUG("Constrained-media _MmsBinaryDecodeGetOneByte fail");
1478 if (oneByte > 0x7F) {
1480 pMsgType->type = MmsGetBinaryType(MmsCodeContentType, (UINT16)(oneByte & 0x7F));
1483 char *pszTemp = NULL;
1485 /* Extension-Media */
1486 gCurMmsDecodeBuffPos--;
1489 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1491 if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1492 pszTemp = __MsgGetStringUntilDelimiter(szTypeString, ';');
1495 szTypeString = pszTemp;
1499 pMsgType->type = MmsGetTextType(MmsCodeContentType, szTypeString);
1501 length = textLength;
1505 szTypeString = NULL;
1510 * Content-general-form = Value-length Media-type
1511 * Media-type = (Well-known-media | Extension-Media)*(Parameter)
1514 length += valueLength;
1516 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1517 MSG_DEBUG("Well-known-media _MmsBinaryDecodeGetOneByte fail");
1521 if (oneByte > 0x7F) {
1522 /* Well-known-media */
1523 pMsgType->type = MmsGetBinaryType(MmsCodeContentType, (UINT16)(oneByte & 0x7F));
1526 /* Extension-Media */
1527 gCurMmsDecodeBuffPos--;
1530 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1531 pMsgType->type = MmsGetTextType(MmsCodeContentType, szTypeString);
1532 valueLength -= textLength;
1536 szTypeString = NULL;
1540 MSG_DEBUG("Content-Type = [%s]", MmsDebugGetMimeType((MimeType)pMsgType->type));
1542 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1543 MSG_DEBUG("Content-Type parameter fail");
1556 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1558 UINT8 fieldCode = 0xff;
1560 UINT32 valueLength = 0;
1562 char *pValue = NULL;
1563 char *pParam = NULL;
1569 char *pLatinBuff = NULL;
1571 char *szTemp = NULL;
1574 if (pFile == NULL || pMsgType == NULL)
1578 * Message-header = Well-known-header | Application-header
1579 * Well-known-header = Well-known-field-name Wap-value
1580 * Application-header = Token-text Application-specific-value
1581 * Well-known-field-name = Short-integer
1582 * Application-specific-value = Text-string
1585 while (headerLen > 0) {
1586 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1587 MSG_DEBUG("field code GetOneByte fail");
1591 if (0x80 <= oneByte && oneByte <= 0xC7) {
1592 /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1594 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1597 fieldCode = oneByte & 0x7f;
1599 switch (fieldCode) {
1600 case 0x0E: //Content-Location
1601 case 0x04: //Content-Location
1603 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1604 if (pLatinBuff == NULL)
1607 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1609 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1613 szSrc = MsgChangeHexString(pLatinBuff);
1616 strcpy(pLatinBuff, szSrc);
1621 textLength = strlen(pLatinBuff);
1623 if (__MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, textLength) < 0) {
1624 MSG_DEBUG("MsgLatin2UTF fail");
1631 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1636 case 0x40: // Content-ID
1638 char szContentID[MMS_CONTENT_ID_LEN + 1];
1640 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1641 if (pLatinBuff == NULL)
1644 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1647 MSG_DEBUG("Content-ID __MmsBinaryDecodeQuotedString fail.");
1651 szSrc = MsgChangeHexString(pLatinBuff);
1654 strcpy(pLatinBuff, szSrc);
1659 textLength = strlen(pLatinBuff);
1660 if (__MsgLatin2UTF ((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, textLength) < 0) {
1661 MSG_DEBUG("MsgLatin2UTF fail");
1667 removeLessGreaterMark(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID));//remove "< >"
1669 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1674 case 0x2E: // Content-Disposition
1675 case 0x45: // Content-Disposition
1678 * Content-disposition-value = Value-length Disposition *(Parameter)
1679 * Disposition = Form-data | Attachment | Inline | Token-text
1680 * Form-data = <Octet 128> : 0x80
1681 * Attachment = <Octet 129> : 0x81
1682 * Inline = <Octet 130> : 0x82
1685 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1688 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1693 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1694 MSG_DEBUG("Disposition value GetOneByte fail");
1701 if (oneByte >= 0x80) {
1702 pMsgType->disposition = MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1704 if (pMsgType->disposition == INVALID_HOBJ) {
1705 MSG_DEBUG("Content-Disposition MmsGetBinaryType fail.");
1706 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT; // default
1709 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1712 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1713 MSG_DEBUG("Disposition parameter fail");
1717 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1721 gCurMmsDecodeBuffPos--;
1724 pLatinBuff = (char *)malloc(MSG_FILENAME_LEN_MAX);
1725 memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1727 textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1730 if (textLength < 0) {
1731 MSG_DEBUG("Content-Disposition decodingfail.");
1737 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1740 valueLength -= textLength;
1742 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false)
1744 MSG_DEBUG("Disposition parameter fail");
1748 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1755 case 0x0B: //Content-Encoding
1757 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1758 MSG_DEBUG("Disposition value GetOneByte fail");
1762 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1767 case 0x0C: //Content-Language
1769 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1770 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1775 cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1777 if (cTemp == NULL) {
1778 MSG_DEBUG("__MmsBinaryDecodeText2 fail...");
1782 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1795 case 0x0D: //Content-Length
1797 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1798 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1802 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1807 case 0x30: //X-Wap-Content-URI skip this value
1809 MSG_DEBUG("X-Wap-Content-URI header.");
1810 pLatinBuff = (char *)malloc(MMS_TEXT_LEN);
1811 if (pLatinBuff == NULL)
1814 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1817 MSG_DEBUG(" __MmsBinaryDecodeQuotedString fail.");
1821 MSG_DEBUG("X-Wap-Content-URI header decoded. Value length %d\n", length);
1825 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1828 MSG_DEBUG("X-Wap-Content-URI header skipped.");
1832 case 0x01: // Accept-charset
1833 //if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1)
1835 /* WAP-230-WSP-200010705-a.pdf
1836 8.4.2.8 Accept charset field
1837 The following rules are used to encode accept character set values.
1838 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1839 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1840 Constrained-charset = Any-charset | Constrained-encoding
1841 Well-known-charset = Any-charset | Integer-value
1842 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1843 Any-charset = <Octet 128>
1844 ; Equivalent to the special RFC2616 charset value ��*��
1850 MSG_DEBUG("Accept-charset.");
1852 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1854 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1859 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1860 // We only support the well-known-charset format
1861 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1866 MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1868 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1876 /* Other Content-xxx headers : Have valueLength */
1878 MSG_DEBUG("unknown Value = 0x%x\n", oneByte);
1880 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1882 MSG_DEBUG("invalid MMS_CODE_PREVIOUSLYSENTDATE");
1886 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1889 szTemp = (char *)malloc(valueLength);
1893 if (__MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) == false) {
1894 MSG_DEBUG("default _MmsBinaryDecodeGetBytes() fail");
1902 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1909 * Application-header = Token-text Application-specific-value
1910 * Application-specific-value = Text-string
1913 MSG_DEBUG(" Application-header = Token-text Application-specific-value");
1915 gCurMmsDecodeBuffPos--;
1920 pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1921 if (pCode == NULL) {
1922 MSG_DEBUG("pCode is null");
1926 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1929 MSG_DEBUG(" Token-text (%s) \n", pCode);
1932 /* Application-specific-value */
1935 pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1936 if (pValue == NULL) {
1937 MSG_DEBUG("pValue is null");
1941 MSG_DEBUG(" Application-specific-value (%s) \n", pValue);
1944 pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1950 switch (MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1951 case MMS_BODYHDR_TRANSFERENCODING: // Content-Transfer-Encoding
1952 pMsgType->encoding = MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1955 case MMS_BODYHDR_CONTENTID: // Content-ID
1957 char szContentID[MMS_CONTENT_ID_LEN + 1];
1959 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1960 if (pLatinBuff == NULL)
1965 __MsgMIMERemoveQuote (pValue);
1966 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1968 length = strlen(pLatinBuff);
1969 if (__MsgLatin2UTF ((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0)
1971 MSG_DEBUG("MsgLatin2UTF fail");
1975 removeLessGreaterMark(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID));//remove "< >"
1981 case MMS_BODYHDR_CONTENTLOCATION: // Content-Location
1983 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1984 if (pLatinBuff == NULL)
1987 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1989 length = strlen(pLatinBuff);
1990 if (__MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1991 MSG_DEBUG("MsgLatin2UTF fail");
1999 case MMS_BODYHDR_DISPOSITION: // Content-Disposition
2000 pMsgType->disposition = MmsGetTextType(MmsCodeMsgDisposition, pValue);
2003 case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY: // DRM RO WAITING
2007 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
2012 __MsgParseParameter(pMsgType, pParam + 1);
2024 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2067 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2071 length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2076 MSG_DEBUG("Number of Entries = [%d]", *npEntries);
2084 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2089 * Currently, offset and size is
2090 * the only information used with msgBody.
2091 * If you need, add here more information
2095 offset = __MmsGetDecodeOffset();
2096 offset += bodyLength;
2098 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2099 MSG_DEBUG("fail to seek file pointer");
2103 __MmsCleanDecodeBuff();
2105 gMmsDecodeCurOffset = offset;
2107 if (offset >= totalLength)
2110 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2111 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2112 MSG_DEBUG("fail to load to buffer");
2125 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2127 if (offset > totalLength)
2130 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2131 MSG_DEBUG("fail to seek file pointer");
2135 __MmsCleanDecodeBuff();
2137 gMmsDecodeCurOffset = offset;
2139 if (offset == totalLength)
2142 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2143 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2144 MSG_DEBUG("fail to load to buffer");
2155 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2157 UINT32 nEntries = 0;
2158 MsgMultipart *pMultipart = NULL;
2159 MsgMultipart *pLastMultipart = NULL;
2160 MsgMultipart *pPreMultipart = NULL;
2164 MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2165 MsgPresentaionInfo presentationInfo;
2167 MSG_DEBUG("pdu length = [%d]", totalLength);
2169 presentationInfo.factor = MSG_PRESENTATION_NONE;
2170 presentationInfo.pCurPresentation = NULL;
2171 presentationInfo.pPrevPart = NULL;
2173 if (__MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2174 MSG_DEBUG("MmsBinaryDecodeEntries is fail.");
2178 if (pMsgBody->body.pMultipart != NULL) {
2179 pLastMultipart = pMsgBody->body.pMultipart;
2180 MSG_DEBUG("previous multipart exist [%p]", pMsgBody->body.pMultipart);
2182 MSG_DEBUG("first multipart");
2186 MSG_DEBUG("decoding [%d]th multipart", index);
2188 offset = __MmsGetDecodeOffset();
2189 if (offset >= totalLength)
2192 if ((pMultipart = __MsgAllocMultipart()) == NULL) {
2193 MSG_DEBUG("MsgAllocMultipart Fail");
2197 if (__MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2198 MSG_DEBUG("MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2202 if (pMultipart->type.type == MIME_APPLICATION_SMIL) {
2203 factor = __MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2204 if (factor == MSG_PRESENTATION_NONE) {
2205 factor = MSG_PRESENTATION_TYPE_BASE;
2208 factor = MSG_PRESENTATION_NONE;
2211 // priority 1 : content type match, 2: content location, 3: type
2212 if (presentationInfo.factor < factor) {
2213 // Presentation part
2214 presentationInfo.factor = factor;
2215 presentationInfo.pPrevPart = pLastMultipart;
2216 presentationInfo.pCurPresentation = pMultipart;
2219 /* first multipart */
2220 if (pLastMultipart == NULL) {
2221 pMsgBody->body.pMultipart = pMultipart;
2222 pLastMultipart = pMultipart;
2223 pPreMultipart = NULL;
2225 pLastMultipart->pNext = pMultipart;
2226 pLastMultipart = pMultipart;
2227 pPreMultipart = pMultipart;
2230 pMsgType->contentSize += pMultipart->pBody->size;
2234 __MmsDebugPrintMulitpartEntry(pMultipart, index++);
2238 pMsgBody->size = totalLength - pMsgBody->offset;
2240 __MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2242 if (__MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2243 MSG_DEBUG("MsgResolveNestedMultipart failed");
2252 if (pMultipart->pBody) {
2253 free(pMultipart->pBody);
2254 pMultipart->pBody = NULL;
2264 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2267 bool bSuccess = false;
2268 UINT32 headerLength = 0;
2269 UINT32 bodyLength = 0;
2272 MSG_DEBUG("pdu length = [%d]", totalLength);
2275 if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2276 MSG_DEBUG("Get header length fail");
2280 offset = __MmsGetDecodeOffset();
2281 if (offset >= totalLength)
2285 if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2286 MSG_DEBUG("Get body length fail");
2290 offset = __MmsGetDecodeOffset();
2291 if (offset >= totalLength)
2295 if (szFilePath != NULL)
2296 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2298 pMsgType->offset = __MmsGetDecodeOffset();
2299 pMsgType->size = headerLength;
2300 pMsgType->contentSize = bodyLength;
2302 if (pMsgType->offset > totalLength)
2305 length = __MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2307 MSG_DEBUG("Decode contentType Fail");
2311 offset = __MmsGetDecodeOffset();
2312 if (offset >= totalLength)
2318 if (__MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2319 MSG_DEBUG("Decode contentHeader Fail");
2323 offset = __MmsGetDecodeOffset();
2324 if (offset >= totalLength)
2329 if (szFilePath != NULL)
2330 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2332 pMsgBody->offset = __MmsGetDecodeOffset();
2333 pMsgBody->size = bodyLength;
2335 if (pMsgBody->offset > totalLength)
2338 switch (pMsgType->type) {
2339 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2340 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2341 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2342 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2343 case MIME_MULTIPART_REPORT:
2344 case MIME_MULTIPART_MIXED:
2345 case MIME_MULTIPART_RELATED:
2346 case MIME_MULTIPART_ALTERNATIVE:
2348 MSG_DEBUG("Multipart");
2349 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2350 MSG_DEBUG("MmsBinaryDecodeMultipart is fail");
2354 offset = __MmsGetDecodeOffset();
2355 if (offset >= totalLength)
2361 #ifdef __SUPPORT_DRM__
2363 case MIME_APPLICATION_VND_OMA_DRM_MESSAGE: /* Contains forwardLock OR combined-delivery media part */
2364 MSG_DEBUG("MIME_APPLICATION_VND_OMA_DRM_MESSAGE Part");
2366 if (__MmsBinaryDecodeDRMContent(pFile, szFilePath, pMsgType, pMsgBody, bodyLength, totalLength) == false)
2369 offset = __MmsGetDecodeOffset();
2370 if (offset >= totalLength)
2375 case MIME_APPLICATION_VND_OMA_DRM_CONTENT: /* Contains seperate-delivery media part (DCF) */
2377 MSG_DEBUG("MIME_APPLICATION_VND_OMA_DRM_CONTENT Part");
2379 if (__MmsBinaryDecodeDRMContent(pFile, szFilePath, pMsgType, pMsgBody, bodyLength, totalLength) == false)
2382 offset = __MmsGetDecodeOffset();
2383 if (offset >= totalLength)
2390 MSG_DEBUG("Normal Part");
2392 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2393 if (bSuccess == false) {
2394 MSG_DEBUG("Decode contentBody Fail");
2398 offset = __MmsGetDecodeOffset();
2399 if (offset >= totalLength)
2417 #ifdef __SUPPORT_DRM__
2418 static bool __MmsBinaryDecodeDRMContent(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int bodyLength, int totalLength)
2421 char szTempFilePath[MSG_FILEPATH_LEN_MAX];
2422 char *pRawData = NULL;
2423 bool isFileCreated = false;
2426 MSG_DEBUG("bodyLength: %d\n", bodyLength);
2428 lenght = snprintf(NULL,0,"%s/drm.dcf",MSG_DATA_PATH);
2429 if (lenght >= MSG_FILEPATH_LEN_MAX){
2430 MSG_DEBUG("File path lenght is too long ");
2434 snprintf(szTempFilePath,lenght,"%s/drm.dcf",MSG_DATA_PATH);
2436 offset = __MmsGetDecodeOffset();
2438 if (offset >= totalLength)
2441 if (szFilePath != NULL)
2442 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2443 if (szFilePath != NULL)
2444 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2446 pRawData = (char *)malloc(bodyLength);
2447 if (pRawData == NULL) {
2448 MSG_DEBUG("pRawData alloc FAIL");
2452 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2453 MSG_DEBUG("MsgFseek() returns -1");
2456 if (MsgReadFile(pRawData, sizeof(char), bodyLength, pFile) != (size_t)bodyLength) {
2457 MSG_DEBUG("FmReadFile() returns false");
2460 if (MsgOpenCreateAndOverwriteFile(szTempFilePath, pRawData, bodyLength) == false) {
2461 MSG_DEBUG("MsgOpenCreateAndOverwriteFile() returns false");
2465 isFileCreated = true;
2467 if (pMsgType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE) {
2468 if (MsgDRM2GetDRMInfo(szTempFilePath, pMsgType) == false) {
2469 MSG_DEBUG("MsgDRM2GetDRMInfo() returns false");
2474 if(remove(szTempFilePath) != 0)
2475 MSG_DEBUG("remove fail");
2476 isFileCreated = false;
2478 if (__MmsBinaryDecodeMovePointer(pFile, offset + bodyLength, totalLength) == false)
2492 if(remove(szTempFilePath) != 0)
2493 MSG_DEBUG("remove fail");
2503 static int __MmsDrm2BinaryEncodeUintvarLen(UINT32 integer)
2507 /* Find encoded unitvar length */
2508 if (integer <= MMS_UINTVAR_LENGTH_1) {
2511 if (integer <= MMS_UINTVAR_LENGTH_2) {
2514 if (integer <= MMS_UINTVAR_LENGTH_3) {
2525 static bool __MmsDrm2BinaryEncodeUintvar(UINT32 integer, int length, char *pszOutput)
2527 const char ZERO = 0x00;
2529 char szReverse[MSG_STDSTR_LONG] = {0, };
2535 source.integer = integer;
2536 memset(szReverse, 0, MSG_STDSTR_LONG);
2538 /* Seperate integer to 4 1 byte integer */
2539 szReverse[3] = source.bytes[3] & 0x0f;
2540 szReverse[0] = source.bytes[0];
2541 szReverse[0] = szReverse[0] & 0x7f;
2543 while (length >= i) {// initially, i = 2
2544 /* Move integer bit to proper position */
2545 source.integer = source.integer << 1;
2546 source.integer = source.integer >> 8;
2547 source.bytes[3] = ZERO;
2549 /* Retrive 1 encode uintvar */
2550 szReverse[i-1] = source.bytes[0];
2551 szReverse[i-1] = szReverse[i-1] | 0x80;
2555 for (i=0; i < length; i++)
2556 pszOutput[i] = szReverse[length - i - 1];
2561 static int __MmsDrm2GetEntriesValueLength(FILE *pFile, int orgOffset)
2563 char szEntries[5] = {0, };
2565 int j = 0; //j is the length of nEntries value
2567 if (MsgReadFile(szEntries, sizeof(char), 4, pFile) != (size_t)4) {
2568 MSG_DEBUG("FmReadFile() returns false");
2573 oneByte = szEntries[j++];
2575 if (oneByte <= 0x7f)
2579 //move file pointer to point nEntries
2580 if (MsgFseek(pFile, orgOffset, SEEK_SET) < 0) {
2581 MSG_DEBUG("fail to seek file pointer");
2588 static bool __MmsDrm2WriteDataToConvertedFile(FILE *pSrcFile, FILE *pDestinationFile, char *pszMmsLoadTempBuf, int length, int bufLen)
2590 int loadLen = 0, totalLoadLen = 0, nRead = 0;
2592 for (int i=0; i<(length/bufLen)+1; i++) {
2593 loadLen = (length-totalLoadLen < bufLen) ? length-totalLoadLen : bufLen;
2595 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2597 nRead = MsgReadFile(pszMmsLoadTempBuf, sizeof(char), loadLen, pSrcFile);
2598 if (nRead != (size_t)loadLen) {
2599 MSG_DEBUG("FmReadFile() returns false, nRead = %d, loadLen = %d", nRead, loadLen);
2602 if (MsgWriteFile(pszMmsLoadTempBuf, sizeof(char), nRead, pDestinationFile) != (size_t)nRead) {
2603 MSG_DEBUG("File Writing is failed.");
2607 totalLoadLen += nRead;
2613 /*************************************************************************
2614 * description : make new message file converting CD & FL part of original message file to SD type
2617 - bool : result of converting
2618 **************************************************************************/
2619 bool MmsDrm2ConvertMsgBody(char *szOriginFilePath)
2622 FILE *hConvertedFile = NULL;
2623 FILE *hTempFile = NULL;
2625 MsgMultipart *pMultipart = NULL;
2626 char szTempFilePath[MSG_FILEPATH_LEN_MAX];
2627 char szTempFile[MSG_FILEPATH_LEN_MAX];
2628 char *pszMmsLoadTempBuf = NULL;
2629 char *pszOrgData = NULL;
2631 int bufLen = MMS_DRM2_CONVERT_BUFFER_MAX;
2634 MSG_DEBUG("start convert~~~~~~");
2636 lenghtFilePath = snprintf(NULL,0,"%s/Drm_Convert",MSG_DATA_PATH);
2638 if (lenghtFilePath >= MSG_FILEPATH_LEN_MAX){
2639 MSG_DEBUG("File path lenght is too long ");
2643 snprintf(szTempFilePath,lenghtFilePath,"%s/Drm_Convert",MSG_DATA_PATH);
2645 lenghtFilePath = snprintf(NULL,0,"%s/temp.dm",MSG_DATA_PATH);
2647 if (lenghtFilePath >= MSG_FILEPATH_LEN_MAX){
2648 MSG_DEBUG("File path lenght is too long ");
2652 snprintf(szTempFilePath,lenghtFilePath,"%s/temp.dm",MSG_DATA_PATH);
2654 pFile = MsgOpenFile(szOriginFilePath, "rb");
2655 if (pFile == NULL) {
2656 MSG_DEBUG("Open decode temporary file fail");
2660 hConvertedFile = MsgOpenFile(MMS_DECODE_DRM_CONVERTED_TEMP_FILE, "wb+");
2661 if (hConvertedFile == NULL) {
2662 MSG_DEBUG("Open decode temporary file fail");
2666 pszMmsLoadTempBuf = (char*)malloc(MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2667 if (pszMmsLoadTempBuf == NULL) {
2668 MSG_DEBUG("malloc for pszMmsLoadTempBuf failed");
2671 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2674 length = mmsHeader.msgBody.offset;
2675 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2676 MSG_DEBUG("Write header data fail");
2680 curOffset += length; //change offset
2683 if (MsgIsMultipart(mmsHeader.msgType.type) == true)
2686 length = __MmsDrm2GetEntriesValueLength(pFile, curOffset); // getting nEntries value's length
2688 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2689 MSG_DEBUG("Write nEntries fail");
2693 curOffset += length; //change offset
2695 // each Multipart entry copy
2696 pMultipart = mmsHeader.msgBody.body.pMultipart;
2698 while (pMultipart) {
2699 if (pMultipart->type.type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE) {
2700 int orgDataLen = pMultipart->pBody->size;
2703 MSG_DEBUG("Write MIME_APPLICATION_VND_OMA_DRM_MESSAGE multipart data(orgDataLen = %d).\n", orgDataLen);
2705 pszOrgData = (char *)malloc(orgDataLen + 1);
2706 if (pszOrgData == NULL) {
2707 MSG_DEBUG("pszOrgData is NULL");
2710 memset(pszOrgData, 0, orgDataLen + 1);
2712 // move file pointer to data
2713 if (MsgFseek(pFile, pMultipart->pBody->offset, SEEK_SET) < 0) {
2714 MSG_DEBUG("fail to seek file pointer 1");
2718 if (MsgReadFile(pszOrgData, sizeof(char), orgDataLen, pFile) != (size_t)orgDataLen) {
2719 MSG_DEBUG("FmReadFile() returns false for orgData");
2723 if((hFile = MsgOpenFile(szTempFile, "wb+")) == NULL) {
2724 MSG_DEBUG("file open failed [%s]", szTempFile);
2728 if (MsgWriteFile(pszOrgData, sizeof(char), orgDataLen, hFile) != (size_t)orgDataLen) {
2729 MSG_DEBUG("File write error");
2739 MsgCloseFile(hFile);
2743 // --> invoking drm agent api, converting data part start
2744 MSG_DEBUG("start data part convert by callling drm agent api");
2747 ret = MsgDrmConvertDmtoDcfType(szTempFile, szTempFilePath);
2748 MSG_DEBUG("MsgDrmConvertDmtoDcfType returned %s", ret ? "true": "false");
2750 if (MsgGetFileSize(szTempFilePath, &nSize) == false) {
2751 MSG_DEBUG("MsgGetFileSize error");
2754 MSG_DEBUG("end data part convert(converted data len = %d)\n", nSize);
2756 // move file pointer to the head of multipart
2757 if (MsgFseek(pFile, curOffset, SEEK_SET) < 0) {
2758 MSG_DEBUG("fail to seek file pointer 2");
2762 // read headerLen, dataLen
2763 length = pMultipart->type.offset - curOffset;
2764 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2765 if (MsgReadFile(pszMmsLoadTempBuf, sizeof(char), length, pFile) != (size_t)length) {
2766 MSG_DEBUG("FmReadFile() returns false for headerLen, dataLen");
2770 curOffset += length;
2772 // change dataLen based on converted data
2777 char szOutput[MSG_STDSTR_LONG] = {0, };
2780 oneByte = pszMmsLoadTempBuf[j++];
2782 if (oneByte <= 0x7f)
2786 encodeLen = __MmsDrm2BinaryEncodeUintvarLen((UINT32)nSize);
2787 __MmsDrm2BinaryEncodeUintvar((UINT32)nSize, encodeLen, szOutput);
2789 strncpy(&(pszMmsLoadTempBuf[j]), szOutput, encodeLen);
2790 pszMmsLoadTempBuf[j+encodeLen] = '\0';
2792 if (MsgWriteFile(pszMmsLoadTempBuf, sizeof(char), length, hConvertedFile) != (size_t)length) {
2793 MSG_DEBUG("FmWriteFile() returns false for dateLen");
2799 length = pMultipart->pBody->offset - pMultipart->type.offset;
2801 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2802 MSG_DEBUG("Write content type, headers fail");
2806 curOffset += length;
2808 // write converted data
2809 hTempFile = MsgOpenFile(szTempFilePath, "rb");
2810 if (hTempFile == NULL) {
2811 MSG_DEBUG("Open decode temporary file fail");
2817 if (__MmsDrm2WriteDataToConvertedFile(hTempFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2818 MSG_DEBUG("Write converted data fail");
2822 if (hTempFile != NULL) {
2823 MsgCloseFile(hTempFile);
2827 curOffset += pMultipart->pBody->size;
2829 // move file pointer to the head of multipart
2830 if (MsgFseek(pFile, curOffset, SEEK_SET) < 0) {
2831 MSG_DEBUG("fail to seek file pointer");
2834 } else { // it doesn't need to convert if it is not CD or FL
2835 MSG_DEBUG("Write normal multipart data");
2837 length = pMultipart->pBody->offset + pMultipart->pBody->size - curOffset;
2839 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2840 MSG_DEBUG("Write multipart data fail");
2844 curOffset += length;
2847 pMultipart = pMultipart->pNext;
2851 MSG_DEBUG("end convert~~~~~~");
2853 if (pFile != NULL) {
2854 MsgCloseFile(pFile);
2858 if (hConvertedFile != NULL) {
2859 MsgCloseFile(hConvertedFile);
2860 hConvertedFile = NULL;
2863 if (pszMmsLoadTempBuf) {
2864 free(pszMmsLoadTempBuf);
2865 pszMmsLoadTempBuf = NULL;
2868 if(remove(szTempFile) != 0)
2869 MSG_DEBUG("remove fail");
2870 if(remove(szTempFilePath) != 0)
2871 MSG_DEBUG("remove fail");
2877 if (pFile != NULL) {
2878 MsgCloseFile(pFile);
2882 if (hConvertedFile != NULL) {
2883 MsgCloseFile(hConvertedFile);
2884 hConvertedFile = NULL;
2887 if (hTempFile != NULL) {
2888 MsgCloseFile(hTempFile);
2892 if (pszMmsLoadTempBuf) {
2893 free(pszMmsLoadTempBuf);
2894 pszMmsLoadTempBuf = NULL;
2904 MsgCloseFile(hFile);
2908 if (remove(szTempFile) != 0)
2909 MSG_DEBUG("remove fail");
2911 if (remove(szTempFilePath) != 0)
2912 MSG_DEBUG("remove fail");
2914 if (remove(MMS_DECODE_DRM_CONVERTED_TEMP_FILE) != 0)
2915 MSG_DEBUG("remove fail"); //remove convertin result if it goes to __CATCH
2920 /*************************************************************************
2921 * description : Function for decoding a converted file
2924 - bool : result of converting
2925 **************************************************************************/
2927 bool MmsDrm2ReadMsgConvertedBody(MSG_MESSAGE_INFO_S *pMsg, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
2930 MmsPluginStorage::instance()->getMmsMessage(&pMmsMsg);
2931 MmsUnregisterDecodeBuffer();
2932 #ifdef __SUPPORT_DRM__
2933 MmsReleaseMsgDRMInfo(&pMmsMsg->msgType.drmInfo);
2935 MmsReleaseMsgBody(&pMmsMsg->msgBody, pMmsMsg->msgType.type);
2937 if (MmsReadMsgBody(pMsg->msgId, bSavePartsAsTempFiles, bRetrieved, retrievedPath) == false) {
2938 MSG_DEBUG("_MmsReadMsgBody with converted file is failed");
2947 /* --------------------------------------------------------------------
2949 * B I N A R Y D E C D E U T I L I T Y
2951 * --------------------------------------------------------------------*/
2953 bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
2955 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2957 if (pFile == NULL || pOneByte == NULL)
2959 MSG_DEBUG("invalid file or buffer");
2964 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2965 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2966 MSG_DEBUG("fail to load to buffer");
2971 *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2980 * @remark: bufLen < gMmsDecodeMaxLen
2982 bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2984 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2988 if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
2991 memset(szBuff, 0, bufLen);
2993 if (length < bufLen) {
2994 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2995 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2996 MSG_DEBUG("fail to load to buffer");
3001 for (i = 0; i < bufLen - 1; i++)
3002 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
3005 gCurMmsDecodeBuffPos++; //NULL
3013 bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3017 if (pFile == NULL || szBuff == NULL || bufLen == 0)
3020 memset(szBuff, 0, bufLen);
3022 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3023 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3024 MSG_DEBUG("fail to load to buffer");
3028 while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
3029 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
3030 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
3034 iPos += gMmsDecodeMaxLen;
3037 if ((bufLen - iPos) > 0) {
3038 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
3039 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
3043 iPos += (bufLen - iPos);
3053 * Decode uintvar to 32bit unsigned integer
3055 * @param pEncodedData [in] encoded data
3056 * @param pUintVar [out] Decode uintvar (32bit unsigned integer)
3057 * @return The length of uintvar (-1, if cannot be converted to a uintvar)
3059 * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
3062 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
3064 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
3068 UINT32 decodedUintvar = 0;
3069 UINT8 iBuff[5] = {0};
3070 int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
3073 if (pFile == NULL || pUintVar == NULL)
3077 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3078 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3079 MSG_DEBUG("fail to load to buffer");
3085 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3088 if (oneByte > 0x7f) {
3089 iBuff[count++] = oneByte;
3091 iBuff[count++] = oneByte;
3096 MSG_DEBUG("legnth is too long");
3101 for (int i = 0; i < count; i++)
3102 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
3104 *pUintVar = decodedUintvar;
3109 gCurMmsDecodeBuffPos -= count;
3114 * Decode uintvar to 32bit unsigned integer by uintvar length
3116 * @param pEncodedData [in] uintvar encoded data
3117 * @param length [in] length of integer value
3118 * @return unsigned integer value
3120 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
3130 returner.integer = 0;
3137 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3138 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
3142 if (oneByte > 0x7f) {
3143 return (oneByte & 0x7f);
3152 pData = (char *)malloc(length + 1);
3153 if (pData == NULL) {
3154 MSG_DEBUG("pData alloc fail");
3157 memset(pData, 0, length + 1);
3159 if (__MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
3160 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
3164 gCurMmsDecodeBuffPos--; // - NULL
3166 for (i= 0; i < length; i++)
3167 returner.seg[length - (i+1)] = pData[i];
3174 return returner.integer;
3183 return returner.integer;
3187 * Decode uintvar to 32bit unsigned integer by uintvar length
3189 * @param pEncodedData [in] uintvar encoded data
3190 * @param pInteger [out] Decode integer value (long/short)
3191 * @return unsigned integer value (-1, if cannot be converted to unsigned integer value)
3193 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
3203 if (pInteger == NULL)
3206 returner.integer = 0;
3209 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3210 MSG_DEBUG("GetOneByte fail");
3214 if (oneByte < 0x1F) /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
3216 pData = (char *)malloc(oneByte + 1);
3217 if (pData == NULL) {
3218 MSG_DEBUG("pData memalloc fail");
3221 memset(pData, 0, oneByte + 1);
3223 // Even NULL is copied in the _MmsBinaryDecodeGetBytes
3224 if (__MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
3225 MSG_DEBUG("GetBytes fail");
3229 gCurMmsDecodeBuffPos--; // - NULL
3239 for (i = 0; i < length; i++)
3240 returner.seg[length - (i+1)] = pData[i];
3242 *pInteger = returner.integer;
3243 *pIntLen = oneByte + 1;
3244 } else if (oneByte >= 0x80) {
3245 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
3246 *pInteger = oneByte & 0x7f;
3261 gCurMmsDecodeBuffPos--;
3272 * Decode uintvar to 32bit unsigned integer by uintvar length
3274 * @return 1 : Success
3275 * 0 : This is not Value Length type data
3276 * -1 : Requires System error report
3278 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
3286 * value-length = short-length | (Length-quote Length)
3287 * = 0~30 | 31 + Uintvar-length
3290 if (pFile == NULL || pValueLength == NULL)
3295 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3296 gCurMmsDecodeBuffPos--;
3300 if (0x00 < oneByte && oneByte < 0x1F) {
3303 *pValueLength = oneByte;
3305 } else if (oneByte == 0x1F) {
3306 /* Length-quote = 0x1F */
3308 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
3310 MSG_DEBUG(" __MmsBinaryDecodeUintvar fail..");
3313 length ++; // + length-quote
3314 *pValueLength = uintvar;
3316 MSG_DEBUG("not a value length type data");
3317 gCurMmsDecodeBuffPos--;
3324 MSG_DEBUG("getting data fail");
3329 * Decode uintvar to 32bit unsigned integer by uintvar length
3331 * @return 1 : Success
3332 * 0 : This is not Value Length type data
3333 * -1 : Requires System error report
3334 * @ defference : if there is not length-quote, consider it as short length.
3336 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
3344 * value-length = short-length | (Length-quote Length)
3345 * = 0~30 | 31 + Uintvar-length
3348 if (pFile == NULL || pValueLength == NULL)
3353 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3354 gCurMmsDecodeBuffPos--;
3358 if (0x00 < oneByte && oneByte < 0x1F) {
3361 *pValueLength = oneByte;
3363 } else if (oneByte == 0x1F) {
3364 /* Length-quote = 0x1F */
3366 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
3368 MSG_DEBUG("__MmsBinaryDecodeUintvar fail..");
3371 length ++; // + length-quote
3372 *pValueLength = uintvar;
3374 MSG_DEBUG("there is not length-quote, consider it as short length.");
3375 *pValueLength = oneByte;
3382 MSG_DEBUG("getting data fail");
3387 * Decode QuotedString
3389 * @param pEncodedData [in] QuotedString encoded data
3390 * @param szBuff [out] Decoded quoted string
3391 * @param bufLen [out] Buffer length
3392 * @return length of quoted string
3394 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3400 int returnLength = 0;
3403 * Quoted-string = <Octet 34> *TEXT End-of-string
3404 * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
3407 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
3410 memset(szBuff, 0, bufLen);
3412 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3413 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3414 MSG_DEBUG("fail to load to buffer");
3418 length = strlen(gpCurMmsDecodeBuff) + 1; // + NULL
3423 while (length > gMmsDecodeBufLen) {
3424 if (gMmsDecodeBufLen <= 0) {
3425 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3426 MSG_DEBUG("%x %x %x %x %x",
3427 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3428 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3429 MSG_DEBUG("%x %x %x %x %x",
3430 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3431 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3432 MSG_DEBUG("%x %x %x %x %x",
3433 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3434 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3435 MSG_DEBUG("%x %x %x %x %x",
3436 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3437 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3441 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3445 memset(pData, 0, gMmsDecodeBufLen + 1);
3447 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3450 returnLength += gMmsDecodeBufLen;
3452 if ((bufLen - iPos) > 0) {
3453 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3454 if (iPos == 0 && (pData[0] == MARK)) {
3455 /* MARK: check first time only */
3457 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3458 iPos += (readBytes - 1);
3460 strncpy(szBuff + iPos, (char*)pData, readBytes);
3470 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3471 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3472 MSG_DEBUG("fail to load to buffer");
3475 length = strlen(gpCurMmsDecodeBuff) + 1; // + NULL
3479 pData = (char *)malloc(length);
3483 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3486 returnLength += length;
3488 if ((bufLen - iPos) > 0) {
3489 /* read until NULL from raw data, and copy only string */
3490 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3491 if (iPos == 0 && (pData[0] == MARK)) {
3492 /* MARK: check first time only */
3493 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3494 iPos += (readBytes - 1);
3496 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); // + NULL
3507 szBuff[bufLen - 1] = '\0';
3509 return returnLength;
3528 * @param pEncodedData [in] QuotedString encoded data
3529 * @param szBuff [out] Decoded quoted string
3530 * @param bufLen [out] Buffer length
3531 * @return length of decode text string
3533 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3538 int returnLength = 0;
3540 bool bQuote = false;
3544 * Text-String = [QUOTE]*TEXT end_of_string
3545 * [QUOTE]*(128~255)\0
3549 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
3552 offset = __MmsGetDecodeOffset();
3553 if (offset >= totalLength)
3556 memset(szBuff, 0, bufLen);
3558 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3559 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3560 MSG_DEBUG("fail to load to buffer");
3564 length = strlen(gpCurMmsDecodeBuff) + 1; // + NULL
3569 while (length > gMmsDecodeBufLen) {
3570 if (gMmsDecodeBufLen <= 0) {
3571 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3572 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3573 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3574 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3575 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3576 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3577 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3578 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3579 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3583 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3587 memset(pData, 0, gMmsDecodeBufLen + 1);
3589 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3592 if ((bufLen - iPos) > 0) {
3593 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3594 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3595 /* QUOTE: check first time only */
3597 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3598 iPos += (readBytes - 1);
3601 strncpy(szBuff + iPos, (char*)pData, readBytes);
3611 returnLength += gMmsDecodeBufLen;
3613 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3614 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3615 MSG_DEBUG("fail to load to buffer");
3618 length = strlen(gpCurMmsDecodeBuff) + 1; // + NULL
3622 pData = (char *)malloc(length);
3626 memset(pData, 0, length);
3628 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3631 if ((bufLen - iPos) > 0) {
3632 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3633 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3634 /* QUOTE: check first time only */
3636 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3637 iPos += (readBytes - 1);
3640 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); // + NULL
3650 returnLength += length; // + NULL
3653 szBuff[bufLen - 1] = '\0';
3655 return returnLength;
3662 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3676 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
3681 char *szBuff = NULL;
3682 char *szTempPtr = NULL;
3683 bool bQuote = false;
3687 * Text-String = [QUOTE]*TEXT end_of_string
3688 * [QUOTE]*(128~255)\0
3692 if (pFile == NULL || pLength == NULL)
3696 offset = __MmsGetDecodeOffset();
3697 if (offset >= totalLength)
3700 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3701 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3702 MSG_DEBUG("fail to load to buffer");
3706 length = strlen(gpCurMmsDecodeBuff) + 1;
3711 while (length > gMmsDecodeBufLen) {
3712 if (gMmsDecodeBufLen <= 0) {
3713 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3714 MSG_DEBUG("%x %x %x %x %x",
3715 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3716 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3717 MSG_DEBUG("%x %x %x %x %x",
3718 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3719 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3720 MSG_DEBUG("%x %x %x %x %x",
3721 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3722 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3723 MSG_DEBUG("%x %x %x %x %x\n",
3724 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3725 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3729 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3733 memset(pData, 0, gMmsDecodeBufLen + 1);
3735 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3738 if (szBuff == NULL) {
3739 szBuff = (char *)malloc(gMmsDecodeBufLen + 1);
3741 szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
3743 //NULL pointer check for realloc
3744 if (szTempPtr == NULL) {
3753 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
3755 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3756 /* QUOTE: check first time only */
3758 strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
3759 curLen += (gMmsDecodeBufLen - 1);
3762 strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
3763 curLen += gMmsDecodeBufLen;
3771 *pLength += gMmsDecodeBufLen;
3773 if (__MsgLoadDataToDecodeBuffer(pFile,
3774 &gpCurMmsDecodeBuff,
3775 &gCurMmsDecodeBuffPos,
3776 &gMmsDecodeCurOffset,
3781 totalLength) == false)
3783 MSG_DEBUG("fail to load to buffer");
3786 length = strlen(gpCurMmsDecodeBuff) + 1;
3790 pData = (char *)malloc(length);
3791 if (pData == NULL) {
3795 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
3799 if (szBuff == NULL) {
3800 szBuff = (char *)malloc(length);
3802 szTempPtr = (char *)realloc(szBuff, curLen + length);
3804 //NULL pointer check for realloc
3805 if (szTempPtr == NULL)
3811 if (szBuff == NULL) {
3815 memset(szBuff + curLen, 0, length);
3817 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3818 /* QUOTE: check first time only */
3820 strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
3821 curLen += (length - 1);
3824 strncpy(szBuff + curLen, (char*)pData, length - 1);
3833 *pLength += length; // + NULL
3842 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3864 * @param pEncodedData [in] QuotedString encoded data
3865 * @param nCharSet [out] Decoded character set
3866 * @return length of charset value
3868 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
3873 * Charset v1.1 0x01 Well-known-charset
3874 * Well-known-charset = Any-charset | Integer-value
3875 * ; Both are encoded using values from
3876 * Character Set Assignments table in Assigned Numbers
3877 * Any-charset = <Octet 128>
3878 * ; Equivalent to the special RFC2616 charset value ��*��
3881 if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
3884 if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
3885 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
3890 /* AnyCharSet : return MSG_CHARSET_UTF8 */
3891 *nCharSet = MSG_CHARSET_UTF8;
3895 *nCharSet = MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
3897 if (*nCharSet == MIME_UNKNOWN) {
3898 MSG_DEBUG("MmsGetBinaryType fail..");
3899 *nCharSet = MSG_CHARSET_UNKNOWN;
3909 * Decode EncodedString
3911 * @param pEncodedData [in] QuotedString encoded data
3912 * @param szBuff [out] Decoded string buffer
3913 * @param bufLen [in] Decoded buffer length
3914 * @return length of decoded string length
3916 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3918 UINT32 valueLength = 0;
3924 MSG_DEBUG(" decode string..");
3926 if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
3927 MSG_DEBUG("invalid file or buffer");
3932 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3933 * Text-string = [Quote]*TEXT End-of-string
3934 * Value-length = 0 ~ 31
3937 memset(szBuff, 0, bufLen);
3939 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3945 /* Text-string = [Quote]*TEXT End-of-string */
3947 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
3948 MSG_DEBUG("__MmsBinaryDecodeText fail.");
3955 /* Value-length Charset Text_string */
3957 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3958 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3959 goto __CATCH; /* (valueLength + valueLengthLen) */
3962 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
3964 /* There can be some error in data - no NULL -> try again with value length */
3966 pData = (char *)malloc(valueLength - charSetLen);
3967 if (pData == NULL) {
3968 MSG_DEBUG("pData alloc fail.");
3972 if (__MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
3973 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes fail.");
3977 strncpy(szBuff, pData, bufLen - 1);
3982 nTemp = strlen(szBuff);
3984 const char *pToCharSet = "UTF-8";
3986 UINT16 charset_code = MmsGetBinaryValue(MmsCodeCharSet, charSet);
3988 const char *pFromCharSet = MmsPluginTextConvertGetCharSet(charset_code);
3989 if (pFromCharSet == NULL || !strcmp(pFromCharSet, pToCharSet)) {
4000 if (MmsPluginTextConvert(pToCharSet, pFromCharSet, szBuff, nTemp, &pDest, &destLen) == false) {
4001 MSG_DEBUG("MmsPluginTextConvert Fail");
4005 memset(szBuff, 0x00, bufLen);
4006 snprintf(szBuff, destLen, "%s", pDest);
4032 * Decode Encoded Addresses
4034 * @param pEncodedData [in] QuotedString encoded data
4035 * @param pAddrLength [out] Decoded address length
4036 * @return Decoded address list
4038 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
4040 UINT32 valueLength = 0;
4044 char *pAddrStr = NULL;
4045 MsgHeaderAddress *pAddr = NULL;
4047 MSG_DEBUG("decoding address..");
4049 if (pFile == NULL) {
4050 MSG_DEBUG("invalid file or buffer");
4055 * Encoded_string_value = Text-string | Value-length Char-set Text-String
4056 * Text-string = [Quote]*TEXT End-of-string
4057 * Value-length = 0 ~ 31
4060 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
4066 /* Text-string = [Quote]*TEXT End-of-string */
4069 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4070 if (pAddrStr == NULL) {
4071 MSG_DEBUG(" __MmsBinaryDecodeText2 fail.");
4078 /* Value-length Charset Text_string */
4080 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
4081 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
4086 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4087 if (pAddrStr == NULL) {
4088 /* There can be some error in data - no NULL -> try again with value length */
4090 pAddrStr = (char *)malloc(valueLength - charSetLen);
4091 if (pAddrStr == NULL) {
4092 MSG_DEBUG("pData alloc fail.");
4096 if (__MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
4097 MSG_DEBUG(" _MmsBinaryDecodeGetLongBytes fail.");
4102 /* fixme: charset transformation */
4107 pAddr = (MsgHeaderAddress *)malloc(sizeof(MsgHeaderAddress));
4111 memset(pAddr, 0, sizeof(MsgHeaderAddress));
4112 pAddr->szAddr = pAddrStr;
4128 * Decode Encoded Pointer String
4130 * @param pEncodedData [in] Long integer encoded data
4131 * @param pLongInteger [out] Decoded long integer
4132 * @return Decoded address list
4134 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
4139 * Long-integer = Short-length Multi-octet-integer
4140 * Short-length = 0~30
4141 * Multi-octet-integer
4144 if (pFile == NULL || pLongInteger == NULL)
4149 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
4155 *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
4165 * @param pEncodedData [in] filename encoded data
4166 * @param szBuff [out] filename output buffer
4167 * @param fullLength [in] full filename length
4168 * @param bufLen [in] buffer length
4169 * CAUTION: bufLen - 1
4171 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
4173 char *pUTF8Buff = NULL;
4174 char *pLatinBuff = NULL;
4177 char *szSrc2 = NULL;
4181 char *pTmpBuff = NULL;
4183 memset (szBuff, 0, bufLen);
4186 pLatinBuff = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4190 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
4192 strcpy(pLatinBuff, szSrc);
4197 szSrc2 = MsgChangeHexString(pLatinBuff);
4199 strcpy(pLatinBuff, szSrc2);
4204 if (__MsgIsUTF8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
4205 length = strlen(pLatinBuff);
4207 int utf8BufSize = 0;
4208 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
4209 if (utf8BufSize < 3)
4210 utf8BufSize = 3;//min value
4212 pUTF8Buff = (char *)malloc(utf8BufSize + 1);
4213 if (pUTF8Buff == NULL) {
4214 MSG_DEBUG("pUTF8Buff alloc fail");
4218 if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
4219 MSG_DEBUG("MsgLatin2UTF fail");
4225 pTmpBuff = MsgDecodeText(pLatinBuff);
4226 pUTF8Buff = pTmpBuff;
4235 * it should be kept extention even if the file name is shorten
4238 length = strlen(pUTF8Buff);
4239 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4241 nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
4242 strncpy(szBuff, pUTF8Buff, nameLength);
4243 strcat (szBuff, pExt);
4245 strncpy(szBuff, pUTF8Buff, bufLen - 1);
4268 /* ==========================================================
4270 M M S D E C O D I N G
4272 ==========================================================*/
4274 // to get message body this function should be modified from message raw file.
4275 bool MmsReadMsgBody(msg_message_id_t msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
4278 MmsMsg *pMsg = NULL;
4279 MsgMultipart *pMultipart = NULL;
4281 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
4282 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
4286 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
4287 memset(pMsg, 0, sizeof(MmsMsg));
4291 if (bRetrieved && (retrievedPath != NULL)) {
4292 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
4294 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath);
4297 pMsg->msgID = msgID;
4299 /* read from MMS raw file */
4300 strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
4302 MSG_DEBUG("msg_id = [%d]", msgID);
4303 MSG_DEBUG("raw file path = [%s]", szFullPath);
4305 if (MsgGetFileSize(szFullPath, &nSize) == false) {
4306 MSG_FATAL("Fail MsgGetFileSize");
4310 pFile = MsgOpenFile(szFullPath, "rb");
4311 if (pFile == NULL) {
4312 MSG_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
4316 MmsRegisterDecodeBuffer();
4318 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
4319 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
4323 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
4324 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
4328 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
4330 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
4331 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
4333 {//attribute convert mmsHeader -> mmsAttribute
4335 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
4337 pMsg->mmsAttrib.date = mmsHeader.date;
4339 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
4340 pMsg->mmsAttrib.bAskDeliveryReport = true;
4343 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
4345 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
4347 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
4349 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
4351 pMsg->mmsAttrib.msgType = mmsHeader.type;
4353 pMsg->mmsAttrib.version = mmsHeader.version;
4355 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
4357 pMsg->mmsAttrib.priority = mmsHeader.priority;
4359 if (mmsHeader.readReply == MMS_REPORT_YES) {
4360 pMsg->mmsAttrib.bAskReadReply = true;
4363 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
4365 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
4367 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
4369 //FIXME:: mmsHeader will release after delete global mmsHeader
4370 //memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody));//After copy to MmsMsg
4372 if (pMsg->msgBody.pPresentationBody) {
4373 if(MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
4376 pMsg->msgBody.pPresentationBody->body.pText = (char *)malloc(pMsg->msgBody.pPresentationBody->size + 1);
4377 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
4380 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
4383 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
4389 MsgCloseFile(pFile);
4392 pMsg->nPartCount = 0;
4394 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
4395 pMultipart = pMsg->msgBody.body.pMultipart;
4396 while (pMultipart) {
4398 pMultipart = pMultipart->pNext;
4401 if (pMsg->msgBody.size > 0)
4405 /* make temporary */
4406 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s/%s.dir", MSG_DATA_PATH, pMsg->szFileName);
4408 if (MsgIsMultipart(pMsg->msgType.type) == true) {
4410 pMultipart = pMsg->msgBody.body.pMultipart;
4412 if (bSavePartsAsTempFiles) {
4413 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
4414 if (errno == EEXIST) {
4415 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
4417 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
4421 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
4425 if (pMsg->msgBody.pPresentationBody) {
4426 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
4427 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
4431 while (pMultipart) {
4433 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
4434 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
4437 pMultipart = pMultipart->pNext;
4441 } else { //single part
4442 if (pMsg->nPartCount > 0) {
4444 if (bSavePartsAsTempFiles) {
4445 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
4446 if (errno == EEXIST) {
4447 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
4449 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
4453 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
4457 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
4458 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
4462 MSG_DEBUG("### Success ###");
4469 MmsUnregisterDecodeBuffer();
4471 if (pFile != NULL) {
4472 MsgCloseFile(pFile);
4476 #ifdef __SUPPORT_DRM__
4477 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
4480 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
4482 MSG_DEBUG("### Fail ###");
4487 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
4489 MsgHeaderAddress *pTempAddr = NULL;
4491 while (pAddr != NULL) {
4493 pAddr = pAddr->pNext;
4495 if (pTempAddr->szAddr) {
4496 free(pTempAddr->szAddr);
4497 pTempAddr->szAddr = NULL;
4507 static bool __MsgCheckFileNameHasInvalidChar(char *szName)
4512 strLen = strlen(szName);
4514 for (i=0; i<strLen; i++) {
4515 if (__MsgIsInvalidFileNameChar(szName[i]))
4522 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
4525 int totalLength = 0;
4527 totalLength = strlen(szInText);
4529 while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
4530 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
4531 if (__MsgIsInvalidFileNameChar(szInText[nCount]))
4532 *(szInText+nCount) = replaceChar;
4543 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter)
4545 char *pszBuffer = NULL;
4546 char *pszStrDelimiter = NULL;
4550 MSG_DEBUG("pszString == NULL");
4554 if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
4555 MSG_DEBUG("There is no %c in %s. \n", delimiter, pszString);
4559 bufLength = pszStrDelimiter - pszString;
4561 if ((pszBuffer = (char*)malloc (bufLength + 1)) == NULL) {
4562 MSG_DEBUG("malloc is failed");
4565 memset(pszBuffer, 0, bufLength + 1) ;
4567 strncat(pszBuffer, pszString, bufLength);
4572 char *MsgChangeHexString(char *pOrg)
4575 char szBuf[10] = {0,};
4584 cLen = strlen(pOrg);
4586 pNew = (char *)malloc(cLen + 1);
4590 memset(pNew, 0, cLen + 1);
4592 for (cIndex = 0; cIndex< cLen ; cIndex++) {
4593 if (pOrg[cIndex] == '%') {
4594 if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0) {
4595 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); // read two chars after '%'
4597 if (__MsgIsHexChar(szBuf) == true) { // check the two character is between 0 ~ F
4598 OneChar = __MsgConvertHexValue(szBuf);
4600 pNew[index] = OneChar;
4607 pNew[index++] = pOrg[cIndex];
4612 static bool __MsgParseParameter(MsgType *pType, char *pSrc)
4615 char *pValue = NULL;
4618 char *pNextParam = NULL;
4622 char *pTempNextParam = NULL;
4625 char *pUTF8Buff = NULL;
4627 while (pSrc != NULL) {
4628 pSrc = __MsgSkipWS(pSrc);
4630 /* End of parse parameter */
4635 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
4638 if (*pCh == MSG_CH_QUOT) {
4645 for (; pCh<=pTempNextParam ; pCh++) {
4646 if (*pCh == MSG_CH_QUOT)
4647 if (*(pCh - 1) != '\\')
4652 pNextParam = pTempNextParam;
4655 *pNextParam++ = MSG_CH_NULL;
4657 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
4658 *pName++ = MSG_CH_NULL;
4660 if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
4661 *pValue++ = MSG_CH_NULL;
4663 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
4664 *pTest = MSG_CH_NULL;
4666 pDec = MsgDecodeText(pValue); // Api is to long, consider Add to another file (MsgMIMECodec.c)
4668 pDec = MsgDecodeText(pName);
4671 switch (_MsgGetCode(MSG_PARAM, pSrc)) {
4672 case MSG_PARAM_BOUNDARY:
4674 /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
4676 memset (pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
4677 strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
4678 MSG_DEBUG("szBoundary = [%s]", pType->param.szBoundary);
4681 case MSG_PARAM_CHARSET:
4682 pType->param.charset = _MsgGetCode(MSG_CHARSET, pDec);
4684 if (pType->param.charset == INVALID_HOBJ)
4685 pType->param.charset = MSG_CHARSET_UNKNOWN;
4687 MSG_DEBUG("type = %d [charset] = %d", pType->type, pType->param.charset);
4690 case MSG_PARAM_NAME:
4692 memset (pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
4694 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4697 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4698 if ((MSG_LOCALE_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4699 nameLen = (MSG_LOCALE_FILENAME_LEN_MAX-1) - strlen(pExt);
4701 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4704 strncpy(pType->param.szName, pUTF8Buff, nameLen);
4705 strcat (pType->param.szName, pExt);
4707 strncpy(pType->param.szName, pUTF8Buff, (MSG_LOCALE_FILENAME_LEN_MAX-1));
4712 if (__MsgChangeSpace(pType->param.szName, &szSrc) == true) {
4714 strncpy(pType->param.szName, szSrc , strlen(szSrc));
4722 // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
4723 __MsgRemoveFilePath(pType->param.szName);
4725 MSG_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4728 MSG_DEBUG("szName = %s", pType->param.szName);
4731 case MSG_PARAM_FILENAME:
4733 memset (pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
4735 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4738 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4739 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4740 nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
4742 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4745 strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
4746 strcat (pType->param.szFileName, pExt);
4748 strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
4753 if (__MsgChangeSpace(pType->param.szFileName, &szSrc) == true)
4754 strcpy(pType->param.szFileName, szSrc);
4761 // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
4762 __MsgRemoveFilePath(pType->param.szFileName);
4764 MSG_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4767 MSG_DEBUG("szFileName = %s", pType->param.szFileName);
4771 case MSG_PARAM_TYPE:
4773 /* type/subtype of root. Only if content-type is multipart/related */
4775 pType->param.type = _MsgGetCode(MSG_TYPE, pDec);
4776 MSG_DEBUG("type = %d", pType->param.type);
4780 case MSG_PARAM_START:
4782 /* Content-id. Only if content-type is multipart/related */
4784 memset (pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
4785 strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
4787 MSG_DEBUG("szStart = %s", pType->param.szStart);
4791 case MSG_PARAM_START_INFO :
4793 /* Only if content-type is multipart/related */
4795 memset (pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
4796 strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
4798 MSG_DEBUG("szStartInfo = %s", pType->param.szStartInfo);
4802 case MSG_PARAM_REPORT_TYPE :
4804 // only used as parameter of Content-Type: multipart/report; report-type=delivery-status;
4806 if (pDec != NULL && strcasecmp(pDec, "delivery-status") == 0) {
4807 pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
4809 pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
4812 MSG_DEBUG("reportType = %s", pDec);
4817 MSG_DEBUG("Unknown paremeter (%s)", pDec);
4831 static char *__MsgSkipWS(char *s)
4834 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
4836 } else if ((*s != '(') || (__MsgSkipComment(s,(long)NULL)==NULL)) {
4842 static char *__MsgSkipComment (char *s,long trim)
4849 // ignore empty space
4850 for (ret = ++s1; *ret == ' '; ret++)
4853 // handle '(', ')', '\', '\0'
4857 if (!__MsgSkipComment (s1,(long)NULL))
4890 static char *__MsgConvertLatin2UTF8FileName(char *pSrc)
4892 char *pUTF8Buff = NULL;
4896 //convert utf8 string
4897 if (__MsgIsUTF8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
4899 int utf8BufSize = 0;
4901 length = strlen(pSrc);
4902 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
4903 if (utf8BufSize < 3)
4904 utf8BufSize = 3; //min value
4906 pUTF8Buff = (char *)malloc(utf8BufSize + 1);
4908 if (pUTF8Buff == NULL) {
4909 MSG_DEBUG("pUTF8Buff alloc fail");
4913 if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
4914 MSG_DEBUG("MsgLatin2UTF fail");
4918 int length = strlen(pSrc);
4919 pUTF8Buff = (char *)calloc(1, length+1);
4921 if (pUTF8Buff == NULL) {
4922 MSG_DEBUG("pUTF8Buff alloc fail");
4926 memcpy(pUTF8Buff, pSrc, length);
4929 //convert hex string
4930 if (__MsgIsPercentSign(pUTF8Buff) == true) {
4931 pData = MsgChangeHexString(pUTF8Buff);
4933 strcpy(pUTF8Buff, pData);
4951 static bool __MsgChangeSpace(char *pOrg, char **ppNew)
4961 cLen = strlen(pOrg);
4963 pNew = (char *)malloc(cLen + 1);
4967 memset(pNew, 0, cLen + 1);
4969 for (cIndex=0; cIndex<cLen;cIndex++) {
4970 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
4976 pNew[index++] = pOrg[cIndex];
4984 static void __MsgRemoveFilePath(char *pSrc)
4986 // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
4989 char szFileName[MSG_FILENAME_LEN_MAX] = {0};
4995 while ((pTemp = strchr(pTemp, '/')) != NULL) {
4996 // Find the last '/'
5002 MSG_DEBUG("filename(%s)", pSrc);
5004 // case : images/vf7.gif -> vf7.gif
5005 if (pPath != NULL && *(pPath+1) != '\0') {
5006 strncpy(szFileName, pPath+1, strlen(pPath+1));
5007 strncpy(pSrc, szFileName , strlen(szFileName));
5010 // Remove additional file information
5011 // ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
5012 // if "?size=" exist, insert NULL char.
5014 pTemp = strcasestr(pSrc, "?size=");
5020 static bool __MsgIsUTF8String(unsigned char *szSrc, int nChar)
5022 MSG_DEBUG("MsgIsUTF8String: ---------------");
5024 if (szSrc == NULL) {
5025 MSG_DEBUG("szSrc is NULL !!!! ---------------");
5029 while (nChar > 0 && (*szSrc != '\0')) {
5030 if (*szSrc < 0x80) {
5033 } else if ((0xC0 <= *szSrc) && (*szSrc < 0xE0)) {
5034 if (*(szSrc + 1) >= 0x80) {
5038 MSG_DEBUG("1. NOT utf8 range!");
5041 } else if (*szSrc >= 0xE0) {
5042 if (*(szSrc + 1) >= 0x80) {
5043 if (*(szSrc + 2) >= 0x80) {
5047 MSG_DEBUG("2. NOT utf8 range!");
5051 MSG_DEBUG("3. NOT utf8 range!");
5055 MSG_DEBUG("4. NOT utf8 range!");
5066 static bool __MsgIsPercentSign(char *pSrc)
5071 pCh = strchr(pSrc , '%');
5082 static MsgMultipart *__MsgAllocMultipart(void)
5084 MsgMultipart *pMultipart = NULL;
5088 pMultipart = (MsgMultipart*)malloc(sizeof(MsgMultipart));
5089 if (pMultipart == NULL) {
5090 MSG_DEBUG("pMultipart malloc Fail");
5094 pMultipart->pBody = (MsgBody*)malloc(sizeof(MsgBody));
5095 if (pMultipart->pBody == NULL) {
5096 MSG_DEBUG("pMultipart->pBody malloc Fail");
5100 MmsInitMsgType(&pMultipart->type);
5101 MmsInitMsgBody(pMultipart->pBody);
5103 pMultipart->pNext = NULL;
5111 if (pMultipart->pBody) {
5112 free(pMultipart->pBody);
5113 pMultipart->pBody = NULL;
5123 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam)
5125 char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
5126 char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
5127 char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
5130 // remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445>
5131 if (szStart && szStart[0]) {
5133 startLen = strlen(szStart);
5134 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
5135 strncpy(szTmpStart, &szStart[1], startLen - 2);
5137 strncpy(szTmpStart, szStart, startLen);
5141 // remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445>
5142 if (multipartType->szContentID[0]) {
5143 strLen = strlen(multipartType->szContentID);
5144 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
5145 strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
5147 strncpy(szTmpContentID, multipartType->szContentID, strLen);
5151 // remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445>
5152 if (multipartType->szContentLocation[0]) {
5153 strLen = strlen(multipartType->szContentLocation);
5154 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
5155 strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
5157 strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
5161 if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
5162 return MSG_PRESENTATION_NONE;
5164 // exception handling
5165 if (szTmpStart[0] != '\0') {
5166 // presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type
5167 if (strcmp(szTmpStart, szTmpContentID) == 0) {
5168 return MSG_PRESENTATION_ID;
5169 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
5170 return MSG_PRESENTATION_LOCATION;
5171 } else if (multipartType->type == typeParam) {
5172 return MSG_PRESENTATION_TYPE_BASE;
5174 return MSG_PRESENTATION_NONE;
5177 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
5178 return MSG_PRESENTATION_TYPE_BASE;
5180 return MSG_PRESENTATION_NONE;
5185 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
5188 MsgMultipart *pNextPart = NULL;
5189 MsgMultipart *pRemovePart = NULL;
5191 if (__MsgIsMultipartRelated(pMsgType->type)) {
5192 // assign the multipart to presentation part
5193 // remove the multipart(pCurPresentation) which is presentation part from the linked list.
5194 // if there is no presentation part -> assign first multipart to presentation part by force.
5195 if (pPresentationInfo->pCurPresentation == NULL) {
5196 pPresentationInfo->pCurPresentation = pMsgBody->body.pMultipart;
5197 pPresentationInfo->pPrevPart = NULL;
5198 pPresentationInfo->factor = MSG_PRESENTATION_NONE;
5201 if (pPresentationInfo->pCurPresentation != NULL && __MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
5202 /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
5203 * In this case, COPY the Presentation part and leave other multiparts.
5205 memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
5206 pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
5208 // remove pCurPresentation from multipart linked list
5209 if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE)||(pPresentationInfo->pPrevPart == NULL)) {
5211 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
5212 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
5213 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
5214 if (pPresentationInfo->pCurPresentation) {
5215 #ifdef __SUPPORT_DRM__
5216 MmsReleaseMsgDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
5218 free(pPresentationInfo->pCurPresentation);
5219 pPresentationInfo->pCurPresentation = NULL;
5223 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
5224 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
5225 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
5226 if (pPresentationInfo->pCurPresentation) {
5227 free(pPresentationInfo->pCurPresentation);
5228 pPresentationInfo->pCurPresentation = NULL;
5231 } else if (pPresentationInfo->pCurPresentation != NULL && __MsgIsText(pPresentationInfo->pCurPresentation->type.type)) {
5232 /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
5233 * In this case, leave the Presentation part as a multipart and remove other multiparts.
5236 // Backup the multipart link information
5237 pNextPart = pMsgBody->body.pMultipart;
5239 // Copy presentation part as a main part
5240 memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
5241 memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
5243 // Remove multipart linked list
5245 pRemovePart = pNextPart;
5246 pNextPart = pNextPart->pNext;
5248 if (pRemovePart->pBody) {
5249 MmsReleaseMsgBody(pRemovePart->pBody, pRemovePart->type.type);
5250 free(pRemovePart->pBody);
5251 pRemovePart->pBody = NULL;
5259 #ifdef __SUPPORT_DRM__
5260 MmsReleaseMsgDRMInfo(&pMsgBody->presentationType.drmInfo);
5262 MmsInitMsgType(&pMsgBody->presentationType);
5263 pMsgBody->pPresentationBody = NULL;
5269 static bool __MsgIsMultipartRelated(int type)
5271 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
5278 static bool __MsgIsPresentablePart(int type)
5280 if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
5287 #ifdef __SUPPORT_DRM__
5289 bool MsgCopyDrmInfo(MsgType *pPartType)
5292 char *pTmpBuf = NULL;
5294 //convert application/vnd.oma.drm.content to media type
5295 pPartType->type = pPartType->drmInfo.contentType;
5297 // fix wrong file name presentation on save media screen.
5298 if (pPartType->szContentID[0] == '\0' && pPartType->drmInfo.szContentURI)
5299 strncpy(pPartType->szContentID, pPartType->drmInfo.szContentURI, MSG_MSG_ID_LEN);
5301 /* set title name (content name) */
5302 if (pPartType->param.szName[0] == '\0') {
5303 /* szName is vitual name, real filename is *.dcf or *.dm */
5304 if (pPartType->drmInfo.szContentName && pPartType->drmInfo.szContentName[0] != '\0') {
5305 /* In case of szContentName retrieved from DRM agent is exist. */
5306 pTmpBuf = pPartType->drmInfo.szContentName;
5307 } else if (pPartType->szContentLocation[0] != '\0') {
5308 /* In case of szContentLocation parsed from MMS header */
5309 pTmpBuf = strrchr(pPartType->szContentLocation, '/');
5310 if (pTmpBuf == NULL)
5311 pTmpBuf = pPartType->szContentLocation;
5313 /* use another name */
5314 /* possible NULL pointer assignment*/
5315 pTmpBuf = strdup("untitled");
5318 if ((pExt = strrchr(pTmpBuf, '.')) != NULL) {
5320 int fileNameLen = 0;
5323 extLen = strlen(pExt);
5324 tmpLen = strlen(pTmpBuf);
5325 fileNameLen = (tmpLen - extLen < MSG_LOCALE_FILENAME_LEN_MAX - extLen)?(tmpLen - extLen):(MSG_LOCALE_FILENAME_LEN_MAX - extLen);
5326 strncpy(pPartType->param.szName, pTmpBuf, fileNameLen);
5327 strcpy (pPartType->param.szName + fileNameLen, pExt);
5329 strncpy(pPartType->param.szName, pTmpBuf, MSG_LOCALE_FILENAME_LEN_MAX);
5330 __MsgMakeFileName(pPartType->type, pPartType->param.szName, MSG_DRM_TYPE_NONE, 0, pPartType->param.szName, sizeof(pPartType->param.szName));
5339 static bool __MsgIsText(int type)
5341 if (type == MIME_TEXT_PLAIN || type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML ||
5342 type == MIME_TEXT_X_VNOTE || type == MIME_APPLICATION_SMIL || type == MIME_TEXT_X_IMELODY) {
5351 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
5354 MsgMultipart *pTmpMultipart = NULL;
5355 MsgMultipart *pSelectedPart = NULL;
5356 MsgMultipart *pPrevPart = NULL;
5357 MsgMultipart *pFirstPart = NULL;
5358 MsgMultipart *pLastPart = NULL;
5359 MsgMultipart *pRemoveList = NULL;
5360 MsgMultipart *pNextRemovePart = NULL;
5362 switch (pPartType->type) {
5363 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
5364 case MIME_MULTIPART_ALTERNATIVE:
5367 * Policy: multipart/alternative
5368 * multipart/alternative message has only several parts of media.
5369 * You should choose one of them and make the alternative part
5370 * to the selected media part.
5373 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE");
5375 pSelectedPart = pPartBody->body.pMultipart;
5377 // NULL Pointer check!!
5378 if (pSelectedPart == NULL) {
5379 MSG_DEBUG("multipart(ALTERNATIVE) does not exist");
5383 pTmpMultipart = pPartBody->body.pMultipart->pNext;
5385 while (pTmpMultipart) {
5386 if (pSelectedPart->type.type <= pTmpMultipart->type.type)
5387 pSelectedPart = pTmpMultipart;
5389 pTmpMultipart = pTmpMultipart->pNext;
5392 pTmpMultipart = pPartBody->body.pMultipart;
5395 while (pTmpMultipart) {
5396 if (pSelectedPart == pTmpMultipart)
5399 pPrevPart = pTmpMultipart;
5400 pTmpMultipart = pTmpMultipart->pNext;
5403 if (pPrevPart == NULL) {
5404 /* selected part is the first part */
5405 pRemoveList = pSelectedPart->pNext;
5407 pPrevPart->pNext = pSelectedPart->pNext;
5408 pRemoveList = pPartBody->body.pMultipart;
5409 pPartBody->body.pMultipart = pSelectedPart;
5412 pSelectedPart->pNext = NULL;
5415 #ifdef __SUPPORT_DRM__
5416 MmsReleaseMsgDRMInfo(&pRemoveList->type.drmInfo);
5418 MmsReleaseMsgBody(pRemoveList->pBody, pRemoveList->type.type);
5420 free(pRemoveList->pBody);
5424 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
5425 MSG_DEBUG("MsgPriorityCopyMsgType failed");
5429 if (pSelectedPart->pBody != NULL)
5430 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
5432 if (pSelectedPart != NULL) {
5433 #ifdef __SUPPORT_DRM__
5434 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5437 if (pSelectedPart->pBody != NULL) {
5438 free(pSelectedPart->pBody);
5439 pSelectedPart->pBody = NULL;
5441 free(pSelectedPart);
5442 pSelectedPart = NULL;
5447 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
5448 case MIME_MULTIPART_RELATED:
5450 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_RELATED");
5452 pSelectedPart = pPartBody->body.pMultipart;
5454 while (pSelectedPart) {
5455 if (__MsgIsMultipartMixed(pSelectedPart->type.type)) {
5457 if (pSelectedPart->pBody == NULL) {
5458 MSG_DEBUG("pSelectedPart->pBody(1) is NULL");
5462 pFirstPart = pSelectedPart->pBody->body.pMultipart;
5464 if (pFirstPart == NULL) {
5465 MSG_DEBUG("multipart(RELATED) does not exist");
5469 if (pFirstPart->pNext) {
5470 pLastPart = pFirstPart->pNext;
5471 while (pLastPart->pNext)
5472 pLastPart = pLastPart->pNext;
5474 pLastPart = pFirstPart;
5477 if (pPrevPart == NULL) {
5478 /* the first part */
5479 pTmpMultipart = pPartBody->body.pMultipart->pNext;
5480 pPartBody->body.pMultipart = pFirstPart;
5481 pLastPart->pNext = pTmpMultipart;
5483 pTmpMultipart = pSelectedPart->pNext;
5484 pPrevPart->pNext = pFirstPart;
5485 pLastPart->pNext = pTmpMultipart;
5488 if (pSelectedPart) {
5489 #ifdef __SUPPORT_DRM__
5490 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5492 free(pSelectedPart->pBody);
5493 free(pSelectedPart);
5495 pSelectedPart = pTmpMultipart;
5496 } else if (__MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
5497 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
5498 MmsReleaseMsgBody(pSelectedPart->pBody, pSelectedPart->type.type);
5500 free(pSelectedPart->pBody);
5501 free(pSelectedPart);
5502 pSelectedPart = pTmpMultipart;
5504 pPrevPart = pSelectedPart;
5505 pSelectedPart = pSelectedPart->pNext;
5512 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
5513 case MIME_MULTIPART_MIXED:
5515 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_MIXED");
5518 pSelectedPart = pPartBody->body.pMultipart;
5520 while (pSelectedPart) {
5521 if (MsgIsMultipart(pSelectedPart->type.type)) {
5522 if (pSelectedPart->pBody == NULL) {
5523 MSG_DEBUG("pSelectedPart->pBody(2) is NULL");
5527 pFirstPart = pSelectedPart->pBody->body.pMultipart;
5529 // NULL Pointer check!!
5530 if (pFirstPart == NULL) {
5531 MSG_DEBUG("multipart does not exist");
5535 if (pFirstPart->pNext) {
5536 pLastPart = pFirstPart->pNext;
5537 while (pLastPart->pNext)
5538 pLastPart = pLastPart->pNext;
5540 pLastPart = pFirstPart;
5543 if (pPrevPart == NULL) {
5544 /* the first part */
5545 pTmpMultipart = pPartBody->body.pMultipart->pNext;
5546 pPartBody->body.pMultipart = pFirstPart;
5547 pLastPart->pNext = pTmpMultipart;
5549 pTmpMultipart = pSelectedPart->pNext;
5550 pPrevPart->pNext = pFirstPart;
5551 pLastPart->pNext = pTmpMultipart;
5554 if (pSelectedPart->pBody->pPresentationBody)
5555 pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
5557 memcpy(&pPartBody->presentationType,
5558 &pSelectedPart->pBody->presentationType, sizeof(MsgType));
5560 pPartType->type = pSelectedPart->type.type;
5562 #ifdef __SUPPORT_DRM__
5563 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5565 free(pSelectedPart->pBody);
5566 free(pSelectedPart);
5568 pSelectedPart = pTmpMultipart;
5570 pPrevPart = pSelectedPart;
5571 pSelectedPart = pSelectedPart->pNext;
5577 case MIME_MULTIPART_REPORT:
5579 MSG_DEBUG("MIME_MULTIPART_REPORT");
5581 pTmpMultipart = pPartBody->body.pMultipart;
5584 if (pTmpMultipart == NULL) {
5585 MSG_DEBUG("pTmpMultipart == NULL");
5589 while (pTmpMultipart) {
5590 if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
5591 pSelectedPart = pTmpMultipart;
5595 pPrevPart = pTmpMultipart;
5596 pTmpMultipart = pTmpMultipart->pNext;
5599 if (pSelectedPart == NULL) {
5600 MSG_DEBUG("MIME_MULTIPART_REPORT [no selected part]");
5602 pRemoveList = pPartBody->body.pMultipart->pNext;
5603 if (pPartBody->body.pMultipart != NULL) {
5604 pSelectedPart = pPartBody->body.pMultipart;
5605 pSelectedPart->pNext = NULL;
5608 if (pPrevPart == NULL) {
5609 // first part is selected
5610 pRemoveList = pPartBody->body.pMultipart->pNext;
5612 pRemoveList = pPartBody->body.pMultipart->pNext;
5613 pPrevPart->pNext = pSelectedPart->pNext;
5616 pSelectedPart->pNext = NULL;
5617 pPartBody->body.pMultipart = pSelectedPart;
5620 pTmpMultipart = pRemoveList;
5622 while (pTmpMultipart) {
5623 #ifdef __SUPPORT_DRM__
5624 MmsReleaseMsgDRMInfo(&pTmpMultipart->type.drmInfo);
5626 MmsReleaseMsgBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
5627 pNextRemovePart = pTmpMultipart->pNext;
5629 free(pTmpMultipart->pBody);
5630 free(pTmpMultipart);
5631 pTmpMultipart = pNextRemovePart;
5634 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
5635 MSG_DEBUG("MsgPriorityCopyMsgType failed");
5639 if (pSelectedPart != NULL) {
5641 if (pSelectedPart->pBody != NULL)
5642 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
5644 #ifdef __SUPPORT_DRM__
5645 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5647 if (pSelectedPart->pBody != NULL) {
5648 free(pSelectedPart->pBody);
5649 pSelectedPart->pBody = NULL;
5651 free(pSelectedPart);
5652 pSelectedPart = NULL;
5669 char *MsgResolveContentURI(char *szSrc)
5671 char *szTemp = NULL;
5672 char *szReturn = NULL;
5675 if (szSrc == NULL) {
5679 if (szSrc[0] == '\0')
5683 if (!strncasecmp(szSrc, "cid:", 4)) {
5684 length = strlen(szSrc) - 3;
5687 length = strlen(szSrc) + 1;
5690 szTemp = (char *)malloc(length);
5691 if (szTemp == NULL) {
5692 MSG_DEBUG("memory full");
5696 memset(szTemp, 0, length);
5697 strcpy(szTemp, szSrc);
5699 szReturn = MsgChangeHexString(szTemp);
5713 char *MsgRemoveQuoteFromFilename(char *pSrc)
5715 int cLen = 0; // length of pBuff
5719 MSG_DEBUG("pSrc is Null");
5723 cLen = strlen(pSrc);
5725 pBuff = (char *)malloc(cLen + 1);
5727 if (pBuff == NULL) {
5728 MSG_DEBUG("pBuff mem alloc fail!");
5731 memset(pBuff, 0 , sizeof(char)*(cLen + 1));
5733 // remove front quote
5734 if (pSrc[0] == MSG_CH_QUOT) {
5736 strncpy(pBuff, &pSrc[1], cLen);
5740 if (pSrc[0] == MSG_CH_LF) {
5742 strncpy(pBuff, &pSrc[1], cLen);
5744 strcpy(pBuff, pSrc);
5747 // remove last qoute
5748 if (pBuff[cLen-1] == MSG_CH_QUOT) {
5749 pBuff[cLen-1] = '\0';
5755 bool MsgIsMultipart(int type)
5757 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
5758 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
5759 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
5767 static bool __MsgIsHexChar(char *pSrc)
5773 cLen = strlen(pSrc);
5775 for (cIndex = 0; cIndex < cLen ; cIndex++) {
5776 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
5777 (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
5787 static char __MsgConvertHexValue(char *pSrc)
5793 unsigned char uCh[2] = {0,};
5795 cLen = strlen(pSrc);
5797 for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
5798 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
5799 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
5800 ch = (int)uCh[0]<<4|uCh[1];
5803 ResultChar = (char)ch;
5808 static int __MsgConvertCharToInt(char ch)
5810 if (ch>='0' && ch<='9') {
5812 } else if (ch>='a'&& ch <='f') {
5814 } else if (ch>='A'&& ch <='F') {
5821 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
5823 if(!pMsgType1 || !pMsgType2)
5826 if (pMsgType1->section == INVALID_HOBJ)
5827 pMsgType1->section = pMsgType2->section;
5829 #ifdef __SUPPORT_DRM__
5832 if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
5833 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
5836 if (pMsgType1->szContentID[0] == '\0') {
5837 strcpy(pMsgType1->szContentID, pMsgType2->szContentID);
5839 if (pMsgType2->szContentID[0]) {
5840 length = MsgStrlen(pMsgType2->szContentID);
5841 if (pMsgType2->szContentID[0] == '<' && pMsgType2->szContentID[length - 1] == '>') {
5842 pMsgType1->drmInfo.szContentURI = MsgStrNCopy(pMsgType2->szContentID + 1, length - 2);
5844 pMsgType1->drmInfo.szContentURI = MsgStrCopy(pMsgType2->szContentID);
5848 length = MsgStrlen(pMsgType1->szContentID);
5849 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
5850 pMsgType1->drmInfo.szContentURI = MsgStrNCopy(pMsgType1->szContentID + 1, length - 2);
5852 pMsgType1->drmInfo.szContentURI = MsgStrCopy(pMsgType1->szContentID);
5857 if (pMsgType1->szContentLocation[0] == '\0')
5858 strcpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation);
5860 /* Copy informations - we shoud open the pMsgType2's orgFile
5861 * concerning its offset and size.
5863 if (pMsgType2->szOrgFilePath[0] != '\0')
5864 strcpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath);
5866 if (pMsgType2->disposition != INVALID_HOBJ)
5867 pMsgType1->disposition = pMsgType2->disposition;
5869 if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
5870 pMsgType2->encoding != INVALID_HOBJ)
5871 pMsgType1->encoding = pMsgType2->encoding;
5873 pMsgType1->contentSize = pMsgType2->contentSize;
5874 pMsgType1->offset = pMsgType2->offset;
5875 pMsgType1->size = pMsgType2->size;
5876 pMsgType1->type = pMsgType2->type;
5878 __MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
5880 if (pMsgType1->param.szName[0]) {
5881 #ifdef __SUPPORT_DRM__
5882 pMsgType1->drmInfo.szContentName = MsgStrCopy(pMsgType2->param.szName);
5889 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
5891 if (pParam1->charset == MSG_CHARSET_UNKNOWN)
5892 pParam1->charset = pParam2->charset;
5894 if (pParam1->type == MIME_UNKNOWN)
5895 pParam1->type = pParam2->type;
5897 /* Don't copy pParam2->pPresentation */
5899 /* For alternative: copy the boundary string */
5900 if (pParam2->szBoundary[0] !='\0')
5901 strcpy(pParam1->szBoundary, pParam2->szBoundary);
5903 if (pParam1->szFileName[0] =='\0')
5904 strcpy(pParam1->szFileName, pParam2->szFileName);
5906 if (pParam1->szName[0] =='\0')
5907 strcpy(pParam1->szName, pParam2->szName);
5909 if (pParam1->szStart[0] =='\0')
5910 strcpy(pParam1->szStart, pParam2->szStart);
5912 if (pParam1->szStartInfo[0] =='\0')
5913 strcpy(pParam1->szStartInfo, pParam2->szStartInfo);
5918 static bool __MsgIsMultipartMixed(int type)
5920 if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
5927 bool MmsGetMsgAttrib(MmsMsgID msgID, MmsAttrib* pAttrib)
5929 MmsMsg *pMsg = NULL;
5931 memset(pAttrib, 0, sizeof(MmsAttrib));
5932 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
5933 memcpy(pAttrib, &(pMsg->mmsAttrib), sizeof(MmsAttrib));
5935 MSG_DEBUG("msgID = %lu ---------------------\n", msgID);
5937 if ('\0' != pMsg->szTrID[0])
5938 MSG_DEBUG("szTrID = %s \n", pMsg->szTrID);
5944 static bool __MsgIsInvalidFileNameChar(char ch)
5946 if ((ch == 0x5C /* \ */) ||
5947 (ch == 0x2F /* / */) ||
5948 (ch == 0x3A /* : */) ||
5949 (ch == 0x2A /* * */) ||
5950 (ch == 0x3F /* ? */) ||
5951 (ch == 0x22 /* " */) ||
5952 (ch == 0x3C /* < */) ||
5953 (ch == 0x3E /* > */) ||
5954 (ch == 0x7C /* | */))
5960 bool MmsDataUpdateLastStatus(MmsMsg *pMsg)
5962 MmsMsgMultiStatus* pStatus = NULL;
5964 pStatus = pMsg->mmsAttrib.pMultiStatus;
5966 while (pStatus != NULL) {
5967 pStatus->bDeliveyrReportIsLast = false;
5968 pStatus->bReadReplyIsLast = false;
5969 pStatus = pStatus->pNext;
5976 bool MmsAddrUtilCompareAddr(char *pszAddr1, char *pszAddr2)
5982 MmsAddrUtilRemovePlmnString(pszAddr1);
5983 MmsAddrUtilRemovePlmnString(pszAddr2);
5985 MSG_DEBUG("##### pszAddr1 = %s #####", pszAddr1);
5986 MSG_DEBUG("##### pszAddr2 = %s #####", pszAddr2);
5987 if (!strcmp(pszAddr1, pszAddr2))
5990 len1 = strlen(pszAddr1);
5991 len2 = strlen(pszAddr2);
5994 p = strstr(pszAddr1, pszAddr2);
5996 p = strstr(pszAddr2, pszAddr1);
6005 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
6009 MSG_DEBUG("---------------");
6011 if ((szSrc == NULL) || (nChar <= 0)) {
6012 MSG_DEBUG("szSrc is NULL !!!! ---------------");
6016 while ((nChar > 0) && (*szSrc != '\0')) {
6017 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
6031 static int __MsgLatin5code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6036 unsigned short temp = 0;
6039 outBufSize--; //Null Character
6041 while ((nChar > 0) && (*szSrc != '\0')) {
6043 if (*szSrc >= 0x01 && *szSrc <= 0x7F) { //basic common
6044 temp = (unsigned short)(*szSrc);
6050 *des = (unsigned char) ((*szSrc) & 0x007F);
6055 } else if ((*szSrc == 0x00) || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6056 (*szSrc >= 0xA0 && *szSrc <= 0xCF) || (*szSrc >= 0xD1 && *szSrc <= 0xDC) ||
6057 (*szSrc >= 0xDF && *szSrc <= 0xEF) || (*szSrc >= 0xF1 && *szSrc <= 0xFC) ||
6058 (*szSrc == 0xFF)) {//uni 0x00A0 ~ 0x00CF
6060 temp = (unsigned short)(*szSrc);
6066 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6067 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6069 *des = 0xC0 | (t1 & 0x1F);
6070 *(des+1) = 0x80 | (t2 & 0x3F);
6075 } else if (*szSrc == 0xD0) {//empty section OR vendor specific codes.
6083 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6084 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6086 *des = 0xC0 | (t1 & 0x1F);
6087 *(des+1) = 0x80 | (t2 & 0x3F);
6092 } else if (*szSrc == 0xDD) {
6099 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6100 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6102 *des = 0xC0 | (t1 & 0x1F);
6103 *(des+1) = 0x80 | (t2 & 0x3F);
6108 } else if (*szSrc == 0xDE) {
6115 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6116 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6118 *des = 0xC0 | (t1 & 0x1F);
6119 *(des+1) = 0x80 | (t2 & 0x3F);
6124 } else if (*szSrc == 0xF0) {
6130 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6131 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6133 *des = 0xC0 | (t1 & 0x1F);
6134 *(des+1) = 0x80 | (t2 & 0x3F);
6139 } else if (*szSrc == 0xFD) {
6147 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6148 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6150 *des = 0xC0 | (t1 & 0x1F);
6151 *(des+1) = 0x80 | (t2 & 0x3F);
6156 } else if (*szSrc == 0xFE) {
6163 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6164 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6166 *des = 0xC0 | (t1 & 0x1F);
6167 *(des+1) = 0x80 | (t2 & 0x3F);
6181 static int __MsgGetLatin52UTFCodeSize(unsigned char *szSrc, int nChar)
6185 MSG_DEBUG("---------------");
6187 if ((szSrc == NULL) || (nChar <= 0))
6190 while ((nChar > 0) && (*szSrc != '\0')) {
6191 if (*szSrc >= 0x01 && *szSrc <= 0x7F) {
6195 } else if (*szSrc == 0x00 || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6196 (*szSrc >= 0xA0 && *szSrc <= 0xCF) || (*szSrc >= 0xD1 && *szSrc <= 0xDC) ||
6197 (*szSrc >= 0xDF && *szSrc <= 0xEF) || (*szSrc >= 0xF1 && *szSrc <= 0xFC) ||
6198 *szSrc == 0xD0 || *szSrc == 0xDD || *szSrc == 0xDE || *szSrc == 0xF0 ||
6199 *szSrc == 0xFD || *szSrc == 0xFE || *szSrc == 0xFF) { //uni 0x00A0 ~ 0x00CF
6210 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6213 unsigned char t1, t2;
6215 MSG_DEBUG("---------------");
6218 outBufSize--; // NULL character
6220 while ((nChar > 0) && (*szSrc != '\0')) {
6221 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
6222 /* check outbuffer's room for this UTF8 character */
6228 *des = (unsigned char) (*szSrc & 0x007F);
6234 /* check outbuffer's room for this UTF8 character */
6240 t2 = (unsigned char) (*szSrc & 0x003F); // right most 6 bit
6241 t1 = (unsigned char) ((*szSrc & 0xC0) >> 6); // right most 2 bit
6243 *des = 0xC0 | (t1 & 0x1F);
6244 *(des + 1) = 0x80 | (t2 & 0x3F);
6259 static int __MsgLatin7code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6265 unsigned short temp = 0;
6267 MSG_DEBUG("---------------");
6270 outBufSize--; //Null Character
6272 while ((nChar > 0) && (*szSrc != '\0')) {
6273 if (*szSrc >= 0x01 && *szSrc <= 0x7F) {
6274 temp = (unsigned short)(*szSrc);
6280 *des = (unsigned char) (temp & 0x007F);
6286 } else if ((*szSrc == 0x00) || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6287 (*szSrc >= 0xA3 && *szSrc <= 0xAD) || (*szSrc == 0xBB)) { // consider 0xA4, 0xA5
6289 temp = (unsigned short)(*szSrc);
6295 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6296 t1 = (unsigned char) ((temp & 0xC0) >> 6); // right most 2 bit
6298 *des = 0xC0 | (t1 & 0x1F);
6299 *(des + 1) = 0x80 | (t2 & 0x3F);
6304 } else if (*szSrc == 0xA0) {
6306 //*des = temp to utf-8
6311 *des = (unsigned char) (temp & 0x007F);
6317 } else if (*szSrc == 0xA1) {
6324 t3 = (unsigned char) (temp & 0x003F); // right most 6 bit
6325 t2 = (unsigned char) ((temp & 0x0FC0) >> 6); // right most 6 bit
6326 t1 = (unsigned char) ((temp & 0xF000) >> 12); // right most 4 bit
6328 *des = 0xE0 | (t1 & 0x0F);
6329 *(des+1) = 0x80 | (t2 & 0x3F);
6330 *(des+2) = 0x80 | (t3 & 0x3F);
6336 } else if (*szSrc == 0xA2) {
6343 t3 = (unsigned char) (temp & 0x003F); // right most 6 bit
6344 t2 = (unsigned char) ((temp & 0x0FC0) >> 6); // right most 6 bit
6345 t1 = (unsigned char) ((temp & 0xF000) >> 12); // right most 4 bit
6347 *des = 0xE0 | (t1 & 0x0F);
6348 *(des+1) = 0x80 | (t2 & 0x3F);
6349 *(des+2) = 0x80 | (t3 & 0x3F);
6355 } else if (*szSrc == 0xAF) {
6362 t3 = (unsigned char) (temp & 0x003F); // right most 6 bit
6363 t2 = (unsigned char) ((temp & 0x0FC0) >> 6); // right most 6 bit
6364 t1 = (unsigned char) ((temp & 0xF000) >> 12); // right most 4 bit
6366 *des = 0xE0 | (t1 & 0x0F);
6367 *(des+1) = 0x80 | (t2 & 0x3F);
6368 *(des+2) = 0x80 | (t3 & 0x3F);
6374 } else if (0xB0 <= *szSrc && *szSrc <= 0xB4) { //0x00B0 ~ 0x00B4
6376 temp = (unsigned short)(*szSrc);
6382 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6383 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6385 *des = 0xC0 | (t1 & 0x1F);
6386 *(des+1) = 0x80 | (t2 & 0x3F);
6392 } else if ((0xB5 <= *szSrc && *szSrc <= 0xBA) ||
6393 (0xBC <= *szSrc && *szSrc <= 0xD1) ||
6394 (0xD3 <= *szSrc && *szSrc <= 0xFE)) {
6395 temp= (unsigned short)(*szSrc + 0x02D0);
6401 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6402 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6404 *des = 0xC0 | (t1 & 0x1F);
6405 *(des+1) = 0x80 | (t2 & 0x3F);
6422 static int __MsgGetLatin72UTFCodeSize(unsigned char *szSrc, int nChar)
6426 MSG_DEBUG(" ---------------");
6428 if ((szSrc == NULL) || (nChar <= 0))
6431 while ((nChar > 0) && (*szSrc != '\0')) {
6433 if ((*szSrc >= 0x01 && *szSrc <= 0x7F) || (*szSrc == 0xA0)) {
6437 } else if (*szSrc == 0x00 || (0x80 <= *szSrc && *szSrc <= 0x9F) || (0xA3 <= *szSrc && *szSrc <= 0xAD) ||
6438 (0xB0 <= *szSrc && *szSrc <= 0xB4) || (0xB5 <= *szSrc && *szSrc <= 0xFE)) {
6442 } else if (*szSrc == 0xA1 ||*szSrc == 0xA2 || *szSrc == 0xAF) {
6454 static int __MsgUnicode2UTF(unsigned char *des, int outBufSize, unsigned short *szSrc, int nChar)
6461 MSG_DEBUG(" ---------------");
6464 outBufSize--; // NULL character
6466 while ((nChar > 0) && (*szSrc != '\0')) {
6467 if (0x0001 <= *szSrc && *szSrc <= 0x007F) {
6468 /* check outbuffer's room for this UTF8 character */
6474 *des = (unsigned char) (*szSrc & 0x007F);
6479 } else if ((*szSrc == 0x0000) || (0x0080 <= *szSrc && *szSrc <= 0x07FF)) {
6480 /* check outbuffer's room for this UTF8 character */
6486 t2 = (unsigned char) (*szSrc & 0x003F); // right most 6 bit
6487 t1 = (unsigned char) ((*szSrc & 0x07C0) >> 6); // right most 5 bit
6489 *des = 0xC0 | (t1 & 0x1F);
6490 *(des+1) = 0x80 | (t2 & 0x3F);
6496 /* check outbuffer's room for this UTF8 character */
6502 t3 = (unsigned char) (*szSrc & 0x003F); // right most 6 bit
6503 t2 = (unsigned char) ((*szSrc & 0x0FC0) >> 6); // right most 6 bit
6504 t1 = (unsigned char) ((*szSrc & 0xF000) >> 12); // right most 4 bit
6506 *des = 0xE0 | (t1 & 0x0F);
6507 *(des+1) = 0x80 | (t2 & 0x3F);
6508 *(des+2) = 0x80 | (t3 & 0x3F);
6522 static int __MsgGetUnicode2UTFCodeSize(unsigned short *szSrc, int nChar)
6526 MSG_DEBUG(" ---------------");
6528 if ((szSrc == NULL) || (nChar <= 0)) {
6529 MSG_DEBUG("szSrc is NULL !!!! ---------------");
6533 while ((nChar > 0) && (*szSrc != '\0')) {
6534 if (0x0001 <= *szSrc && *szSrc <= 0x007F) {
6538 } else if ((*szSrc == 0x0000) || (0x0080 <= *szSrc && *szSrc <= 0x07FF)) {
6552 static bool __MmsAddrUtilCheckEmailAddress(char *pszAddr)
6554 if (!pszAddr || pszAddr[0] == 0)
6557 if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
6563 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
6565 char *pszAddrCopy = NULL;
6566 char *pszStrStart = NULL;
6567 char *pszStrTemp = NULL;
6570 if ((!pszAddr) || (pszAddr[0] == 0)) {
6571 MSG_DEBUG("pszAddr is null or zero");
6575 strLen = strlen(pszAddr);
6577 pszAddrCopy = (char*)calloc(1,strLen + 1);
6579 MSG_DEBUG("pszAddrCopy is NULL, mem alloc failed");
6583 strcpy(pszAddrCopy, pszAddr);
6587 pszStrStart = pszAddrCopy;
6590 char* pszStrEnd = NULL;
6593 if (__MmsAddrUtilCheckEmailAddress(pszAddrCopy))
6594 pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
6596 pszStrEnd = strstr(pszStrStart, "/");
6599 // "/TYPE=PLMN" not found
6601 int remainedLen = strlen(pszStrStart);
6603 if (remainedLen <= 0)
6606 strcat(pszAddr, pszStrStart);
6611 // Get one address length
6612 addressLen = pszStrEnd - pszStrStart;
6614 strncat(pszAddr, pszStrStart, addressLen);
6616 // Find next address
6617 pszStrStart = pszStrEnd;
6619 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
6622 addressLen = pszStrTemp - pszStrEnd;
6623 pszStrStart += addressLen;
6625 pszStrStart += strlen(pszStrEnd);
6628 if (pszStrStart[0] == 0) // end of string
6632 strcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER); // add ';'
6633 pszStrStart++; // remove ';'
6636 if (pszAddr[0] == 0)
6637 strcpy(pszAddr, pszAddrCopy);
6644 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6648 MSG_DEBUG("---------------");
6651 outBufSize--; // NULL character
6653 while ((nChar > 0) && (*szSrc != '\0')) {
6654 if (*szSrc < 0x80) {
6662 } else if (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
6668 *(des + 1) = *(szSrc + 1);
6672 } else if ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
6678 *(des + 1) = *(szSrc + 1);
6679 *(des + 2) = *(szSrc + 2);
6691 MSG_DEBUG("utf8 incorrect range!");
6703 static void __MsgMIMERemoveQuote(char *szSrc)
6707 length = MsgStrlen(szSrc);
6708 if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
6711 for (index = 0; index < length-2; index++)
6712 szSrc[index] = szSrc[index+1];
6713 szSrc[index] = '\0';
6717 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
6723 if (pFile == NULL) {
6730 if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
6737 if (*pBufLen == 0) {
6738 length = maxLen - (*pPtr);
6740 length = (*pBufLen) - (*pPtr);
6746 if ((*ppBuf) == NULL) {
6747 memset(pInBuf1, 0, maxLen);
6749 } else if ((*ppBuf) == pInBuf1) {
6750 memset(pInBuf2, 0, maxLen);
6752 memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
6755 memset(pInBuf1, 0, maxLen);
6757 memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
6763 if (*pOffset == endOfFile) {
6768 if (maxLen == length) {
6770 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
6775 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
6778 *pBufLen = length + nRead;
6781 if ((*pOffset = MsgFtell(pFile)) == -1L) {
6782 MSG_DEBUG("MsgFtell Error");
6792 bool MsgGetTypeByFileName(int *type, char *szFileName)
6795 AvCodecType AvType = AV_CODEC_NONE;
6797 pExt = strrchr(szFileName, '.');
6798 if (pExt == NULL || pExt[0] == '\0')
6803 if (strcasecmp(pExt, "mp4") == 0 ||strcasecmp(pExt, "mpeg4") == 0 ||strcasecmp(pExt, "3gp") == 0 ||strcasecmp(pExt, "3gpp") == 0) {
6805 if (szFileName[0] != '/')
6808 AvType = AvGetFileCodecType(szFileName);
6809 MSG_DEBUG("AvType(0x%x)\n", AvType);
6812 case AV_DEC_AUDIO_MPEG4:
6813 *type = MIME_AUDIO_MP4;
6816 case AV_DEC_VIDEO_MPEG4:
6817 *type = MIME_VIDEO_MP4;
6821 *type = MIME_VIDEO_3GPP;
6827 if (strcasecmp(pExt, "amr") == 0) {
6828 *type = MIME_AUDIO_AMR;
6830 } else if ((strcasecmp(pExt, "mid") == 0) || (strcasecmp(pExt, "midi") == 0)) {
6831 *type = MIME_AUDIO_MIDI;
6833 } else if (strcasecmp(pExt, "imy") == 0) {
6834 *type = MIME_TEXT_X_IMELODY;
6838 *type = MimeGetMimeFromExtInt((const char*)pExt);
6839 MSG_DEBUG("filename [%s], type [%d]", szFileName, *type);
6844 *type = MIME_UNKNOWN;
6845 MSG_DEBUG("filename [%s], type [%d]", szFileName, *type);
6852 * This function write media data from raw data to file.
6855 * @param pszMailboxPath : path of mailbox
6856 * @param pszMsgFilename : name of msg file
6857 * @param index : used for file naming
6858 * @param bSave : if true, file will be save otherwise just filename will be stored.
6860 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
6863 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, }; // file name of temp file
6864 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; // full absolute path of temp file.
6865 bool bFileExist = false;
6869 MSG_DEBUG("pPartType is NULL");
6873 if (pPartType->type == MIME_APPLICATION_SMIL) {
6874 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", "smil.txt");
6876 if (pPartType->param.szName[0] != '\0') {
6877 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szName);
6878 } else if (pPartType->param.szFileName[0] != '\0') {
6879 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szFileName);
6881 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
6886 #ifndef __SUPPORT_DRM__
6887 __MsgMakeFileName(pPartType->type, szFileName, 0); //FL & CD -> extension(.dm) SD -> extension(.dcf)
6889 __MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0, szFileName, sizeof(szFileName)); //FL & CD -> extension(.dm) SD -> extension(.dcf)
6890 if (MsgDRMIsForwardLockType(pPartType->drmInfo.drmType))
6891 MsgChangeDrm2FileName(szFileName);
6895 snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName); // get absolute path of each temp file of each part
6896 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.
6898 if (pPartType->param.szName[0] == '\0') {
6899 snprintf(pPartType->param.szName, MSG_LOCALE_FILENAME_LEN_MAX+1, "%s", szFileName);
6900 MSG_DEBUG("Set Name : %s", pPartType->param.szName);
6903 if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
6904 MsgGetTypeByFileName(&pPartType->type, szFullPath);
6907 bFileExist = MsgAccessFile(szFullPath, F_OK);
6909 MSG_DEBUG("save flag [%d], filepath [%s], file exist [%d]", bSave, szFullPath, bFileExist);
6911 if (bSave == true && bFileExist == false) {
6913 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
6914 MSG_DEBUG("MsgOpenFile failed");
6918 if (__MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
6919 MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
6923 MsgCloseFile(pFile);
6926 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
6927 pPartBody->offset = 0;
6928 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
6931 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
6932 MsgDrmRegisterFile(MSG_MODE_FILE, szFullPath, strlen(szFullPath));
6934 /* change szDrm2FullPath as current content path*/
6935 if (pPartType->drmInfo.szDrm2FullPath) {
6936 free(pPartType->drmInfo.szDrm2FullPath);
6937 pPartType->drmInfo.szDrm2FullPath = MsgStrCopy(szFullPath);
6940 MSG_DEBUG("Save Part File to [%s]", pPartBody->szOrgFilePath);
6942 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
6943 pPartBody->offset = 0;
6944 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
6945 MSG_DEBUG("Set Part File to [%s]", pPartBody->szOrgFilePath);
6953 if (pFile != NULL) {
6954 MsgCloseFile(pFile);
6961 bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
6966 char *pNewData = NULL;
6967 char *pTempData = NULL;
6968 int msgEncodingValue = 0;
6969 int msgTypeValue = 0;
6970 int msgCharsetValue = 0;
6976 msgEncodingValue = pPartType->encoding;
6977 msgTypeValue = pPartType->type;
6978 msgCharsetValue = pPartType->param.charset;
6980 cidLen = MsgStrlen(szCid);
6982 offset = pPartBody->offset;
6983 size = pPartBody->size;
6985 if (pPartBody->szOrgFilePath[0]) {
6986 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
6988 if (pTempData == NULL) {
6989 MSG_DEBUG("pTempData read fail");
6994 } else if (pPartBody->body.pText) {
6995 pData = pPartBody->body.pText;
6996 nRead = pPartBody->size;
6999 if (pData == NULL) {
7000 MSG_DEBUG("there is no data");
7004 pNewData = __MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
7005 pPartType->encoding = MSG_ENCODING_BINARY;
7007 if (__MsgIsText(msgTypeValue))
7008 pPartType->param.charset = MSG_CHARSET_UTF8;
7010 if (MsgWriteFile(pNewData, sizeof(char), nRead2, pFile) != (size_t)nRead2) {
7011 MSG_DEBUG("file writing fail");
7045 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
7051 unsigned short *mszTempStr = NULL;
7052 char *pConvertedStr = NULL;
7053 char *pConvertedData = NULL;
7054 char *pNewData = NULL;
7055 char *pReturnData = NULL;
7058 switch (msgEncodingValue) {
7059 case MSG_ENCODING_BASE64:
7061 pConvertedData = (char*)MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
7062 MSG_DEBUG("MSG_ENCODING_BASE64 bodyLength [%d]", nByte);
7064 pTemp = pConvertedData;
7069 case MSG_ENCODING_QUOTE_PRINTABLE:
7071 pConvertedData = (char*)MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
7072 MSG_DEBUG("MSG_ENCODING_QUOTE_PRINTABLE bodyLength [%d]", nByte);
7074 pTemp = pConvertedData;
7081 MSG_DEBUG("encoding val [%d] bodyLength [%d]", msgEncodingValue, nRead);
7088 if (__MsgIsText(msgTypeValue)) {
7089 /* charset converting */
7091 switch (msgCharsetValue) {
7092 case MSG_CHARSET_UTF16:
7093 case MSG_CHARSET_USC2:
7095 MSG_DEBUG("MSG_CHARSET_USC2");
7097 if (((UINT8)pTemp[0]) == 0xFF && ((UINT8)pTemp[1]) == 0xFE) {
7098 nChar = (nTemp / 2 - 1);
7100 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
7101 if (mszTempStr == NULL) {
7102 MSG_DEBUG("Memory Full !!!");
7106 memcpy(mszTempStr, ((unsigned short*)pTemp + 1), nChar * sizeof(unsigned short));
7108 nByte = __MsgGetUnicode2UTFCodeSize(((unsigned short*)pTemp + 1), nChar);
7110 nByte = 3; //min value
7112 pConvertedStr = (char *)malloc(nByte + 1);
7113 if (pConvertedStr != NULL)
7114 __MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
7116 nChar = (nTemp / 2);
7118 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
7119 if (mszTempStr == NULL) {
7120 MSG_DEBUG("Memory Full !!!");
7124 memcpy(mszTempStr, ((unsigned short*)pTemp), nChar * sizeof(unsigned short));
7126 nByte = __MsgGetUnicode2UTFCodeSize(((unsigned short*)pTemp), nChar);
7128 pConvertedStr = (char *)malloc(nByte + 1);
7130 __MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
7133 if (pConvertedStr != NULL)
7134 pNewData = pConvertedStr;
7136 *npRead = nByte + 1;
7140 case MSG_CHARSET_US_ASCII:
7142 MSG_DEBUG("MSG_CHARSET_US_ASCII");
7145 case MSG_CHARSET_UTF8:
7147 MSG_DEBUG("MSG_CHARSET_UTF8 or Others");
7149 // skip BOM (Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM)
7151 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
7161 case MSG_CHARSET_ISO_8859_7:
7165 MSG_DEBUG("MSG_CHARSET_ISO_8859_7");
7167 nByte = __MsgGetLatin72UTFCodeSize((unsigned char*)pTemp, nTemp);
7168 pConvertedStr = (char *)malloc(nByte + 1);
7170 __MsgLatin7code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7172 pNewData = pConvertedStr;
7173 *npRead = nByte + 1;
7177 case MSG_CHARSET_ISO_8859_9:
7180 MSG_DEBUG("MSG_CHARSET_ISO_8859_9");
7182 nByte = __MsgGetLatin52UTFCodeSize((unsigned char*)pTemp, nTemp);
7183 pConvertedStr = (char *)malloc(nByte + 1);
7185 __MsgLatin5code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7187 pNewData = pConvertedStr;
7188 *npRead = nByte + 1;
7194 MSG_DEBUG("Other charsets");
7196 nByte = __MsgGetLatin2UTFCodeSize((unsigned char*)pTemp, nTemp);
7197 pConvertedStr = (char *)malloc(nByte + 1);
7199 __MsgLatin2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7201 pNewData = pConvertedStr;
7202 *npRead = nByte + 1;
7211 pReturnData = (char *)malloc(*npRead);
7212 if (pReturnData == NULL) {
7213 MSG_DEBUG("pReturnData alloc fail.");
7218 if (pNewData != NULL) {
7219 memset(pReturnData, 0, *npRead);
7220 memcpy(pReturnData, pNewData, *npRead);
7223 if (pConvertedData) {
7224 free(pConvertedData);
7225 pConvertedData = NULL;
7228 if (pConvertedStr) {
7229 free(pConvertedStr);
7230 pConvertedStr = NULL;
7242 if (pConvertedData) {
7243 free(pConvertedData);
7244 pConvertedData = NULL;
7247 if (pConvertedStr) {
7248 free(pConvertedStr);
7249 pConvertedStr = NULL;
7260 #ifndef __SUPPORT_DRM__
7261 static bool __MsgMakeFileName(int iMsgType, char *szFileName, int nUntitleIndex)
7263 char szText[MSG_FILENAME_LEN_MAX+1]={0,};
7264 char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
7265 char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
7269 MSG_DEBUG("iMsgType = %d, szFileName = %s", iMsgType, szFileName);
7271 if (szFileName == NULL)
7274 if (szFileName && (szFileName[0] != '\0')) {
7275 MsgGetFileNameWithoutExtension (szTempFileName, szFileName);
7277 pExt = strrchr(szTempFileName, '.');
7279 memset (szText, 0, MSG_FILENAME_LEN_MAX+1);
7280 strncpy(szText, szTempFileName, MSG_FILEPATH_LEN_MAX - 1);
7281 strcat(szText, "."); // add '.'
7283 memset (szText, 0, MSG_FILENAME_LEN_MAX+1);
7284 strncpy(szText, szTempFileName, pExt+1 - szFileName); // add '.'
7287 if (nUntitleIndex >= 1) {
7288 snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s_%d.", "Untitled", nUntitleIndex);
7290 snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s.", "Untitled");
7294 if (iMsgType == MIME_APPLICATION_OCTET_STREAM) {
7295 MSG_DEBUG("unsupported MsgType");
7299 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
7300 if (iMsgType == MIME_UNKNOWN || (pExt = MimeGetExtFromMimeInt((MimeType)iMsgType)) == NULL) {
7301 MSG_DEBUG("Failed to get extension of that mime data file.");
7304 nLen = MSG_FILENAME_LEN_MAX - strlen(szTemp);
7305 strncat(szTemp, pExt, nLen);
7309 strcpy(szFileName, szTemp);
7311 MSG_DEBUG("made szFileName = %s", szFileName);
7318 p = strrchr(szText, '.');
7321 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", szText);
7327 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen)
7329 char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
7330 char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
7333 MSG_DEBUG("Input : type [0x%x], drmType [%d], filename [%s]", iMsgType, drmType, szFileName);
7335 if (szFileName == NULL)
7338 int inp_len = strlen(szFileName);
7340 MsgGetFileNameWithoutExtension (szTempFileName, szFileName);
7342 if (nUntitleIndex >= 1) {
7343 snprintf(szTempFileName, sizeof(szTempFileName), "%s_%d", "untitled", nUntitleIndex);
7345 snprintf(szTempFileName, sizeof(szTempFileName), "%s", "untitled");
7349 if (drmType == MSG_DRM_TYPE_SD) {
7350 snprintf(szTemp, sizeof(szTemp), "%s.dcf", szTempFileName);
7351 } else if (MsgDRMIsForwardLockType(drmType)) {
7352 snprintf(szTemp, sizeof(szTemp), "%s.dm", szTempFileName);
7354 if (iMsgType == MIME_APPLICATION_OCTET_STREAM) {
7355 MSG_DEBUG("unsupported MsgType");
7359 if (iMsgType == MIME_UNKNOWN) {
7360 MSG_DEBUG("Failed to get extension of that mime data file.");
7364 pExt = MimeGetExtFromMimeInt((MimeType)iMsgType);
7366 snprintf(szTemp, sizeof(szTemp), "%s.%s", szTempFileName, pExt);
7368 MSG_DEBUG("Failed to get extension of that mime data file.");
7374 snprintf(outBuf, outBufLen, "%s", szTemp);
7375 MSG_DEBUG("Result : filename [%s]", outBuf);
7383 bool MsgGetFileNameWithoutExtension (char *szOutputName, char *szName)
7385 char *pszExt = NULL;
7387 if (szOutputName == NULL) {
7388 MSG_DEBUG("szOutputName is NULL");
7392 strncpy(szOutputName, szName, strlen(szName));
7394 if ((pszExt = strrchr(szOutputName, '.'))) {
7395 if (pszExt[0] == '.')
7402 int MmsGetMediaPartCount(msg_message_id_t msgId)
7406 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
7408 if (msgId != pMsg->msgID) {
7409 MSG_DEBUG("Invalid Message Id");
7413 return pMsg->nPartCount;
7416 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
7418 MmsMsg *pMsg = NULL;
7419 MsgMultipart *pPart = NULL;
7421 if (pHeader == NULL) {
7422 MSG_DEBUG("Invalid pHeader input. It's null");
7426 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
7428 MmsInitMsgType(pHeader);
7431 /* Requires header of non-presentation */
7432 if (MsgIsMultipart(pMsg->msgType.type)) {
7433 MSG_DEBUG("Multipart header [index = %d] \n", index);
7435 pPart = pMsg->msgBody.body.pMultipart;
7437 while (pPart && index--)
7438 pPart = pPart->pNext;
7440 if (pPart == NULL) {
7441 MSG_DEBUG("There is no such msg part.");
7445 memcpy(pHeader, &pPart->type, sizeof(MsgType));
7447 MSG_DEBUG("Requires singlepart header");
7448 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
7454 static bool __MmsDebugPrintMulitpartEntry(MsgMultipart *pMultipart, int index)
7456 MSG_DEBUG("------------------------------");
7457 MSG_DEBUG("[%dth] multipart info", index);
7458 MSG_DEBUG("header size [%d], body size [%d]", pMultipart->type.size, pMultipart->type.contentSize);
7459 MSG_DEBUG("content type [%s]", MmsDebugGetMimeType((MimeType)pMultipart->type.type));
7460 MSG_DEBUG("content ID [%s]", pMultipart->type.szContentID);
7461 MSG_DEBUG("content location [%s]", pMultipart->type.szContentLocation);
7462 MSG_DEBUG("parameter Name [%s]", pMultipart->type.param.szName);
7463 MSG_DEBUG("parameter Filename[%s]", pMultipart->type.param.szFileName);
7465 if (pMultipart->type.type == MIME_TEXT_PLAIN) {
7466 MSG_DEBUG("text info : charset [%d], name [%s]", pMultipart->type.param.charset, pMultipart->type.param.szName);
7468 #ifdef __SUPPORT_DRM__
7469 if (pMultipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
7470 MSG_DEBUG("drm info");
7471 MSG_DEBUG("drm type [%d] (0: NONE 1: Fowward Lock, 2:Combined Delivery, 3: Separated Delivery)", pMultipart->type.drmInfo.drmType);
7472 MSG_DEBUG("drm content type [%s]", MmsDebugGetMimeType((MimeType)pMultipart->type.drmInfo.contentType));
7473 MSG_DEBUG("drm content URI [%s]", pMultipart->type.drmInfo.szContentURI);
7474 MSG_DEBUG("drm2FullPath [%s]", pMultipart->type.drmInfo.szDrm2FullPath);
7477 MSG_DEBUG("------------------------------");