2 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include "MsgUtilFile.h"
25 #include "MsgUtilMime.h"
27 #include "MsgMmsMessage.h"
29 #include "MmsPluginDebug.h"
30 #include "MmsPluginDecode.h"
31 #include "MmsPluginCodecCommon.h"
32 #include "MmsPluginStorage.h"
33 #include "MmsPluginDebug.h"
34 #include "MmsPluginTextConvert.h"
35 #include "MmsPluginUtil.h"
37 #include "MmsPluginDrm.h"
38 #include "MsgDrmWrapper.h"
41 static int __MmsGetDecodeOffset(void);
42 static bool __MmsDecodeInitialize(void);
43 static void __MmsCleanDecodeBuff(void);
44 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength);
45 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength);
47 static bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength); /* bufLen < gMmsDecodeMaxLen */
48 static bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength); /* no bufLen limit */
49 static bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength);
51 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength);
53 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength);
54 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength);
55 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength);
56 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength);
57 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength);
58 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength);
59 static char *__MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength);
60 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
61 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
63 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength);
64 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength);
65 static MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength);
67 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
68 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
69 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength);
70 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength);
71 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength);
72 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength);
74 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength);
78 static void __MsgRemoveFilePath(char *pSrc);
79 static bool __MsgChangeSpace(char *pOrg, char **ppNew);
80 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo);
81 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam);
82 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *npRead, int endOfFile);
83 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr);
84 static bool __MsgCheckFileNameHasInvalidChar(char *szName);
86 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar);
87 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter);
88 static bool __MsgParseParameter(MsgType *pType, char *pSrc);
89 static char *__MsgSkipWS(char *s);
90 static char *__MsgSkipComment(char *s, long trim);
92 static char *__MsgConvertLatin2UTF8FileName(char *pSrc);
94 /* static bool __MsgIsPercentSign(char *pSrc); */
95 static bool __MsgIsMultipartRelated(int type);
96 static bool __MsgIsPresentablePart(int type);
97 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody);
98 static bool __MsgIsHexChar(char *pSrc);
99 static char __MsgConvertHexValue(char *pSrc);
100 static int __MsgConvertCharToInt(char ch);
101 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2);
102 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2);
103 static bool __MsgIsMultipartMixed(int type);
105 static bool __MsgIsInvalidFileNameChar(char ch);
107 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar);
108 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
109 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
110 static void __MsgMIMERemoveQuote(char *szSrc);
111 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave);
113 static bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE *pFile);
114 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead);
116 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen);
119 __thread char gszMmsLoadBuf1[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
120 __thread char gszMmsLoadBuf2[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
122 __thread char *gpCurMmsDecodeBuff = NULL;
123 __thread int gCurMmsDecodeBuffPos = 0; /* next decoding position in gpCurMmsDecodeBuff */
124 __thread int gMmsDecodeMaxLen = 0;
125 __thread int gMmsDecodeCurOffset = 0; /* current offset in file (last read) */
126 __thread int gMmsDecodeBufLen = 0; /* number of last read characters */
128 __thread char *gpMmsDecodeBuf1 = NULL;
129 __thread char *gpMmsDecodeBuf2 = NULL;
131 __thread MmsHeader mmsHeader =
133 (MmsMsgType)MMS_MSGTYPE_ERROR, /* MmsMsgType iType; */
134 "", /* char[] szTrID; */
135 0, /* short int version; */
136 0, /* UINT32 date; */
138 NULL, /* MsgHeaderAddress* pFrom; */
139 NULL, /* MsgHeaderAddress* pTo; */
140 NULL, /* MsgHeaderAddress* pCc; */
141 NULL, /* MsgHeaderAddress* pBcc; */
142 "", /* char[] szSubject; */
143 (MmsResponseStatus)MMS_RESPSTATUS_OK, /* MmsResponseStatus iResponseStatus; */
144 (MmsRetrieveStatus)MMS_RETRSTATUS_OK, /* MmsRetrieveStatus iRetrieveStatus; */
145 "", /* char[] szResponseText; */
146 "", /* char[] szRetrieveText; */
149 /* has default value in specification */
151 (MmsMsgClass)MMS_MSGCLASS_PERSONAL, /* MmsMsgClass msgClass; */
152 {MMS_TIMETYPE_RELATIVE, 0}, /* MmsTimeStruct expiryTime; */
153 {MMS_TIMETYPE_RELATIVE, 0}, /* MmsTimeStruct deliveryTime; */
154 (MmsPriority)MMS_PRIORITY_NORMAL, /* MmsPriority priority; */ /* Refer [OMA-MMS-ENC-v1_2-20030915-C] */
155 (MmsSenderVisible)MMS_SENDER_SHOW, /* MmsSenderVisible senderVisible; */
156 (MmsReport)MMS_REPORT_NO, /* MmsReport deliveryReport; */
157 (MmsReport)MMS_REPORT_NO, /* MmsReport readReply; */
158 (MmsReportAllowed)MMS_REPORTALLOWED_NO, /* MmsReportAllowed iReportAllowed; */
159 "", /* char[] szContentLocation; */
162 /* there is no right default value */
164 (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE, /* MmsMsgStatus iMsgStatus; */
165 (msg_read_report_status_t)MSG_READ_REPORT_NONE, /* MmsReadStatus readStatus; */
167 /* MMS v1.1 ReplyCharge */
169 (MmsReplyChargeType)MMS_REPLY_NONE, /* MmsReplyChargeType chargeType; */
170 {MMS_TIMETYPE_RELATIVE, 0}, /* MmsTimeStruct deadLine; */
171 0, /* int chargeSize; */
172 "" , /* char szChargeID; */
175 "", /* char[] szMsgID; */
176 0, /* UINT32 msgSize; */
179 #define MMS_DRM2_CONVERT_BUFFER_MAX 4*1024
180 const UINT32 MMS_UINTVAR_LENGTH_1 = 0x0000007f; /* 7bit */
181 const UINT32 MMS_UINTVAR_LENGTH_2 = 0x00003fff; /* 14bit */
182 const UINT32 MMS_UINTVAR_LENGTH_3 = 0x001fffff; /* 21bit */
184 static bool __MmsDecodeInitialize(void)
186 MmsInitMsgType(&mmsHeader.msgType);
187 MmsInitMsgBody(&mmsHeader.msgBody);
193 mmsHeader.type = MMS_MSGTYPE_ERROR;
195 memset(mmsHeader.szTrID, 0, MMS_TR_ID_LEN + 1);
196 mmsHeader.version = MMS_VERSION;
199 __MsgFreeHeaderAddress(mmsHeader.pFrom);
200 __MsgFreeHeaderAddress(mmsHeader.pTo);
201 __MsgFreeHeaderAddress(mmsHeader.pCc);
202 __MsgFreeHeaderAddress(mmsHeader.pBcc);
204 mmsHeader.pFrom = NULL;
205 mmsHeader.pTo = NULL;
206 mmsHeader.pCc = NULL;
207 mmsHeader.pBcc = NULL;
209 memset(mmsHeader.szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
211 mmsHeader.responseStatus = (MmsResponseStatus)MMS_RESPSTATUS_OK;
212 mmsHeader.retrieveStatus = (MmsRetrieveStatus)MMS_RETRSTATUS_OK;
213 memset(mmsHeader.szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
214 memset(mmsHeader.szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
217 mmsHeader.msgClass = (MmsMsgClass)MMS_MSGCLASS_PERSONAL;
218 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
219 mmsHeader.expiryTime.time = 0;
220 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
221 mmsHeader.deliveryTime.time = 0;
222 mmsHeader.priority = (MmsPriority)MMS_PRIORITY_NORMAL; /* Refer [OMA-MMS-ENC-v1_2-20030915-C] */
223 mmsHeader.hideAddress =(MmsSenderVisible)MMS_SENDER_SHOW;
224 mmsHeader.deliveryReport = (MmsReport)MMS_REPORT_NO;
225 mmsHeader.readReply = (MmsReport)MMS_REPORT_NO;
226 mmsHeader.reportAllowed = (MmsReportAllowed)MMS_REPORTALLOWED_YES;
227 memset(mmsHeader.szContentLocation, 0, MMS_LOCATION_LEN + 1);
230 mmsHeader.msgStatus = (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE;
231 mmsHeader.readStatus = (msg_read_report_status_t)MSG_READ_REPORT_NONE;
233 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MMS_REPLY_NONE;
234 mmsHeader.replyCharge.chargeSize = 0;
235 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
236 mmsHeader.replyCharge.deadLine.time = 0;
237 memset(mmsHeader.replyCharge.szChargeID, 0, MMS_MSG_ID_LEN + 1);
240 memset(mmsHeader.szMsgID, 0, MMS_MSG_ID_LEN + 1);
241 mmsHeader.msgSize = 0;
242 mmsHeader.drmType = MSG_DRM_TYPE_NONE;
244 __MmsDecodeInitialize();
247 void MmsReleaseHeader(MmsHeader *mms)
249 __MsgFreeHeaderAddress(mms->pFrom);
250 __MsgFreeHeaderAddress(mms->pTo);
251 __MsgFreeHeaderAddress(mms->pCc);
252 __MsgFreeHeaderAddress(mms->pBcc);
254 mmsHeader.pFrom = NULL;
255 mmsHeader.pTo = NULL;
256 mmsHeader.pCc = NULL;
257 mmsHeader.pBcc = NULL;
260 static void __MmsCleanDecodeBuff(void)
262 memset(gpMmsDecodeBuf1, 0, gMmsDecodeMaxLen + 1);
263 memset(gpMmsDecodeBuf2, 0, gMmsDecodeMaxLen + 1);
264 gpCurMmsDecodeBuff = NULL;
265 gCurMmsDecodeBuffPos = 0;
266 gMmsDecodeBufLen = 0;
269 void MmsRegisterDecodeBuffer()
271 gpMmsDecodeBuf1 = gszMmsLoadBuf1;
272 gpMmsDecodeBuf2 = gszMmsLoadBuf2;
273 gpCurMmsDecodeBuff = NULL;
274 gCurMmsDecodeBuffPos = 0;
275 gMmsDecodeMaxLen = MSG_MMS_DECODE_BUFFER_MAX;
276 gMmsDecodeCurOffset = 0;
277 gMmsDecodeBufLen = 0;
280 void MmsUnregisterDecodeBuffer(void)
282 gpMmsDecodeBuf1 = NULL;
283 gpMmsDecodeBuf2 = NULL;
284 gpCurMmsDecodeBuff = NULL;
285 gCurMmsDecodeBuffPos = 0;
286 gMmsDecodeMaxLen = 0;
287 gMmsDecodeCurOffset = 0;
288 gMmsDecodeBufLen = 0;
292 static int __MmsGetDecodeOffset(void)
294 return (gMmsDecodeCurOffset - gMmsDecodeBufLen + gCurMmsDecodeBuffPos);
297 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength)
299 if (*pLength <= valueLength) {
300 gCurMmsDecodeBuffPos -= valueLength;
301 gCurMmsDecodeBuffPos += *pLength;
305 *pLength -= valueLength;
311 /* ==========================================================
313 B I N A R Y D E C O D I N G
315 ==========================================================*/
318 * Binary Encoded Message Format
320 * < Single Part Body Message >
321 * -----------------------------------
323 * -----------------------------------
324 * | Content Type:start=xxx;type=xxx | ->(ex) Text/Plain, Text/Html, ....
325 * -----------------------------------
326 * | Single Part Body |
327 * -----------------------------------
329 * < Multi Part Body Message >
330 * -----------------------------------
332 * -----------------------------------
333 * | Content Type:start=xxx;type=xxx | -> (ex) Application/vnd.wap.multipart.mixed(related), multipart/mixed(related)
334 * -----------------------------------
335 * | # of Entries (body parts) |
336 * ----------------------------------- < Each Entry >
337 * | Entry 1 | -> -----------------------------
338 * ----------------------------------- | header Length |
339 * | Entry 2 | -----------------------------
340 * ----------------------------------- | Data Length |
341 * | ...... | ----------------------------- -
342 * ----------------------------------- | Content-Type | |
343 * | Entry n | ----------------------------- | Header Length
344 * ----------------------------------- | Header | |
345 * ----------------------------- -
346 * | Data | | Data Length
347 * ----------------------------- -
349 bool MmsBinaryDecodeMsgHeader(FILE *pFile, int totalLength)
352 UINT16 fieldCode = 0xffff;
353 UINT16 fieldValue = 0xffff;
354 UINT8 oneByte = 0xff;
356 MsgHeaderAddress *pAddr = NULL;
357 MsgHeaderAddress *pLastTo = NULL;
358 MsgHeaderAddress *pLastCc = NULL;
359 MsgHeaderAddress *pLastBcc = NULL;
361 UINT32 valueLength = 0;
362 UINT32 tmpInteger = 0;
367 char szGarbageBuff[MSG_STDSTR_LONG] = {0, };
368 char *pLimitData = NULL;
371 MSG_DEBUG("pFile ptr : [%p], total len = [%d]", pFile, totalLength);
373 __MmsCleanDecodeBuff();
375 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
376 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
377 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
378 MSG_FATAL("fail to load to buffer");
382 while (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength)) {
383 fieldCode = oneByte & 0x7f;
385 switch (MmsGetBinaryType(MmsCodeFieldCode, fieldCode)) {
386 case MMS_CODE_RESPONSESTATUS: {
387 MmsResponseStatus resposeStatus = MMS_RESPSTATUS_ERROR;
389 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
390 MSG_DEBUG("responseStatus GetOneByte fail");
394 fieldValue = oneByte;
396 /* range 197 to 223 as it does to the value 192 (Error-transient-failure). */
397 /* range 236 to 255 as it does to the value 224 (Error-permanent-failure). */
398 if (fieldValue >= 197 && fieldValue <= 223) {
400 } else if (fieldValue >= 236 && fieldValue <= 255) {
404 resposeStatus = (MmsResponseStatus)MmsGetBinaryType(MmsCodeResponseStatus, (UINT16)(fieldValue & 0x7F));
406 mmsHeader.responseStatus = (MmsResponseStatus)resposeStatus;
408 MSG_SEC_INFO("X-Mms-Response-Status = [0x%02x][0x%02x][%s]", oneByte, fieldValue, MmsDebugGetResponseStatus(mmsHeader.responseStatus));
411 case MMS_CODE_RETRIEVESTATUS: {
412 MmsRetrieveStatus RetrieveStatus = MMS_RETRSTATUS_ERROR;
414 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
415 MSG_DEBUG("retrieveStatus GetOneByte fail");
419 fieldValue = oneByte;
421 /* 195 to 223 as it does to the value 192 (Error-transient-failure). */
422 /* 228 to 255 as it does to the value 224 (Error-permanent-failure). */
423 if (fieldValue >= 195 && fieldValue <= 223) {
424 fieldValue = 192; /* 192; Error-transient-failure */
425 } else if (fieldValue >= 228 && fieldValue <= 255) {
426 fieldValue = 224; /* 224; Error-permanent-failure */
429 RetrieveStatus = (MmsRetrieveStatus)MmsGetBinaryType(MmsCodeRetrieveStatus, (UINT16)(fieldValue & 0x7F));
431 mmsHeader.retrieveStatus = (MmsRetrieveStatus)RetrieveStatus;
433 MSG_SEC_INFO("X-Mms-Retrieve-Status = [0x%02x][0x%02x][%s]", oneByte, fieldValue, MmsDebugGetRetrieveStatus(mmsHeader.retrieveStatus));
437 case MMS_CODE_RESPONSETEXT:
439 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szResponseText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
440 MSG_DEBUG("invalid MMS_CODE_RESPONSETEXT");
444 MSG_SEC_INFO("X-Mms-Response-Text = [%s]", mmsHeader.szResponseText);
447 case MMS_CODE_RETRIEVETEXT:
449 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szRetrieveText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
450 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
454 MSG_SEC_INFO("X-Mms-Retrieve-Text = [%s]", mmsHeader.szRetrieveText);
459 if (__MmsBinaryDecodeText(pFile, mmsHeader.szMsgID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
460 MSG_DEBUG("MMS_CODE_MSGID is invalid");
464 MSG_SEC_INFO("Message-ID =[%s]", mmsHeader.szMsgID);
466 if (strlen(mmsHeader.szMsgID) > 2)
467 __MsgMIMERemoveQuote(mmsHeader.szMsgID);
471 case MMS_CODE_SUBJECT:
473 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN + 1, totalLength) == false) {
474 MSG_DEBUG("invalid MMS_CODE_SUBJECT");
478 pLimitData = (char *)calloc(1, MSG_LOCALE_SUBJ_LEN + 1);
480 if (pLimitData == NULL) {
481 MSG_DEBUG("pLimitData calloc fail");
485 nRead = __MsgCutUTFString((unsigned char*)pLimitData, MSG_LOCALE_SUBJ_LEN + 1, (unsigned char*)mmsHeader.szSubject, MSG_SUBJ_LEN);
486 MSG_DEBUG("Subject edit..");
488 if (nRead > MSG_LOCALE_SUBJ_LEN) {
489 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
490 strncpy(mmsHeader.szSubject, pLimitData, MSG_SUBJ_LEN);
492 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
493 strncpy(mmsHeader.szSubject, pLimitData, MSG_LOCALE_SUBJ_LEN);
501 MSG_SEC_INFO("Subject = [%s]", mmsHeader.szSubject);
506 if (mmsHeader.pFrom != NULL) {
507 MSG_DEBUG("MMS_CODE_FROM is already decoded");
511 /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
513 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
514 MSG_DEBUG("MMS_CODE_FROM is invalid");
518 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
519 MSG_DEBUG("MMS_CODE_FROM GetOneByte fail");
523 /* DRM_TEMPLATE - start */
527 if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
528 if (valueLength > 0) {
529 mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
530 if (mmsHeader.pFrom == NULL) {
531 MSG_DEBUG("MMS_CODE_FROM __MmsDecodeEncodedAddress fail");
535 mmsHeader.pFrom = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
536 if (mmsHeader.pFrom == NULL)
539 mmsHeader.pFrom->szAddr = (char *)calloc(1, 1);
540 if (mmsHeader.pFrom->szAddr == NULL) {
541 free(mmsHeader.pFrom);
542 mmsHeader.pFrom = NULL;
546 mmsHeader.pFrom->szAddr[0] = '\0';
547 mmsHeader.pFrom->pNext = NULL;
550 MSG_SEC_INFO("From = [%s]", mmsHeader.pFrom->szAddr);
551 /* DRM_TEMPLATE - end */
552 } else if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
553 /* Present Token only */
554 MSG_SEC_INFO("From = [insert token]");
556 /* from data broken */
557 MSG_WARN("from addr broken");
558 gCurMmsDecodeBuffPos--;
565 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
567 MSG_DEBUG("MMS_CODE_TO __MmsDecodeEncodedAddress fail");
571 if (mmsHeader.pTo == NULL) {
573 pLastTo = mmsHeader.pTo = pAddr;
576 pLastTo->pNext = pAddr;
580 MSG_SEC_INFO("To = [%s]", pAddr->szAddr);
585 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
587 MSG_DEBUG("MMS_CODE_BCC __MmsDecodeEncodedAddress fail");
591 if (mmsHeader.pBcc == NULL) {
593 pLastBcc = mmsHeader.pBcc = pAddr;
596 pLastBcc->pNext = pAddr;
600 MSG_SEC_INFO("Bcc = [%s]", pAddr->szAddr);
605 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
607 MSG_DEBUG("MMS_CODE_CC __MmsDecodeEncodedAddress fail");
611 if (mmsHeader.pCc == NULL) {
613 pLastCc = mmsHeader.pCc = pAddr;
616 pLastCc->pNext = pAddr;
619 MSG_SEC_INFO("Cc = [%s]", pAddr->szAddr);
622 case MMS_CODE_CONTENTLOCATION:
624 if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
625 MSG_DEBUG("MMS_CODE_CONTENTLOCATION is invalid");
628 MSG_SEC_DEBUG("X-Mms-Content-Location = [%s]", mmsHeader.szContentLocation);
633 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
634 MSG_DEBUG("MMS_CODE_DATE is invalid");
638 MSG_SEC_INFO("Date = [%u][%d]", mmsHeader.date, (const time_t *)&mmsHeader.date);
641 case MMS_CODE_DELIVERYREPORT:
643 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
644 MSG_DEBUG("deliveryReport GetOneByte fail");
648 fieldValue = MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
650 if (fieldValue == 0xFFFF) {
651 MSG_DEBUG("deliveryReport error");
655 mmsHeader.deliveryReport = (MmsReport)fieldValue;
657 MSG_SEC_INFO("X-Mms-Delivery-Report =[0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.deliveryReport));
660 case MMS_CODE_DELIVERYTIME:
662 /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
664 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
665 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
669 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
670 MSG_DEBUG("delivery time GetOneByte fail");
674 /* DRM_TEMPLATE - start */
677 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
678 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
680 if (valueLength > 0) {
681 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
682 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
686 /* DRM_TEMPLATE - end */
688 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
690 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
691 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
695 MSG_SEC_INFO("X-Mms-Delivery-Time : type = [%d], time= [%u]", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
698 case MMS_CODE_EXPIRYTIME:
700 /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
702 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
703 MSG_DEBUG("invalid MMS_CODE_EXPIRYTIME");
707 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
708 MSG_DEBUG("expiry time GetOneByte fail");
712 /* DRM_TEMPLATE - start */
715 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
716 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
718 if (valueLength > 0) {
719 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
720 MSG_DEBUG("MMS_CODE_EXPIRYTIME is invalid");
724 /* DRM_TEMPLATE - end */
726 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
728 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
729 MSG_INFO("__MmsBinaryDecodeInteger fail...");
734 MSG_DEBUG("X-Mms-Expiry : type = [%d], time = [%u]", mmsHeader.expiryTime.type, mmsHeader.expiryTime.time);
737 case MMS_CODE_MSGCLASS:
739 /* Class-value = Class-identifier | Token Text */
741 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
742 MSG_DEBUG("msgClass GetOneByte fail");
746 if (oneByte > 0x7f) {
747 /* Class-identifier */
748 mmsHeader.msgClass = (MmsMsgClass)MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
750 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
751 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (class)");
756 MSG_SEC_INFO("X-Mms-Message-Class =[%s]", MmsDebugGetMsgClass(mmsHeader.msgClass));
759 case MMS_CODE_MSGSIZE:
761 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
762 MSG_DEBUG("MMS_CODE_MSGSIZE is invalid");
766 MSG_SEC_INFO("X-Mms-Message-Size = [%d]", mmsHeader.msgSize);
769 case MMS_CODE_MSGSTATUS:
771 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
772 MSG_DEBUG("msgStatus GetOneByte fail");
776 mmsHeader.msgStatus = (msg_delivery_report_status_t)MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
777 MSG_SEC_INFO("X-Mms-Status = [%s]", MmsDebugGetMsgStatus(mmsHeader.msgStatus));
780 case MMS_CODE_MSGTYPE:
782 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
783 MSG_DEBUG("msgStatus GetOneByte fail");
787 mmsHeader.type = (MmsMsgType)MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
788 MSG_SEC_INFO("X-Mms-Message-Type = [%s]", MmsDebugGetMsgType(mmsHeader.type));
791 case MMS_CODE_PRIORITY:
793 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
794 MSG_DEBUG("msgStatus GetOneByte fail");
797 mmsHeader.priority = (MmsPriority)MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
798 MSG_SEC_INFO("X-Mms-Priority = [%d]", mmsHeader.priority);
801 case MMS_CODE_READREPLY:
803 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
804 MSG_DEBUG("msgStatus GetOneByte fail");
807 mmsHeader.readReply = (MmsReport)MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
808 MSG_SEC_INFO("X-Mms-Read-Report = [0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.readReply));
811 case MMS_CODE_REPORTALLOWED:
813 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
814 MSG_DEBUG("msgStatus GetOneByte fail");
817 mmsHeader.reportAllowed = (MmsReportAllowed)MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
818 MSG_SEC_INFO("X-Mms-Report-Allowed = [%d]", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
821 case MMS_CODE_SENDERVISIBILLITY:
823 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
824 MSG_DEBUG("msgStatus GetOneByte fail");
827 mmsHeader.hideAddress = (MmsSenderVisible)!(MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
828 MSG_SEC_INFO("X-Mms-Sender-Visibility = [%d]", mmsHeader.hideAddress);
833 if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
834 MSG_DEBUG("Transaction ID Too Long");
837 MSG_SEC_INFO("X-Mms-Transaction-Id = [%s]", mmsHeader.szTrID);
840 case MMS_CODE_VERSION:
841 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
842 MSG_DEBUG("msgStatus GetOneByte fail");
845 mmsHeader.version = oneByte;
847 MSG_SEC_INFO("X-Mms-MMS-Version = [0x%02x]", mmsHeader.version);
850 case MMS_CODE_CONTENTTYPE:
853 * Content-type is the last header field of SendRequest and RetrieveConf.
854 * It's required to decrease pointer by one and return,
855 * to parse this field in MmsBinaryDecodeContentType().
860 /* ----------- Add by MMSENC v1.1 ----------- */
862 case MMS_CODE_READSTATUS:
864 /* Read-status-value = Read | Deleted without being read */
866 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
867 MSG_DEBUG("msgStatus GetOneByte fail");
871 mmsHeader.readStatus = (msg_read_report_status_t)MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
872 MSG_SEC_INFO("X-Mms-Read-Status = [%s]", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
875 case MMS_CODE_REPLYCHARGING:
877 /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
879 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
880 MSG_DEBUG("msgStatus GetOneByte fail");
884 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
885 MSG_SEC_INFO("X-Mms-Reply-Charging = [%d]", mmsHeader.replyCharge.chargeType);
888 case MMS_CODE_REPLYCHARGINGDEADLINE:
890 /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
892 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
893 MSG_DEBUG("invalid MMS_CODE_REPLYCHARGINGDEADLINE");
897 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
898 MSG_DEBUG("msgStatus GetOneByte fail");
902 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
903 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
905 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
908 /* DRM_TEMPLATE - start */
911 if (valueLength > 0) {
912 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
913 MSG_DEBUG("MMS_CODE_REPLYCHARGINGDEADLINE is invalid");
918 MSG_SEC_INFO("X-Mms-Reply-Charging-Deadline : type = [%d], time = [%u]", mmsHeader.replyCharge.deadLine.type, mmsHeader.replyCharge.deadLine.time);
919 /* DRM_TEMPLATE - end */
922 case MMS_CODE_REPLYCHARGINGID:
924 /* Reply-charging-ID-value = Text-string */
925 if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
926 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (szReplyChargingID)");
929 SECURE_SLOGD("X-Mms-Reply-Charging-ID = [%s]", mmsHeader.replyCharge.szChargeID);
932 case MMS_CODE_REPLYCHARGINGSIZE:
934 /* Reply-charging-size-value = Long-integer */
935 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
936 MSG_DEBUG("MMS_CODE_REPLYCHARGINGSIZE is invalid");
939 MSG_SEC_INFO("X-Mms-Reply-Charging-Size = [%d]", mmsHeader.replyCharge.chargeSize);
942 case MMS_CODE_PREVIOUSLYSENTBY:
945 * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
946 * Forwarded-count-value = Integer-value
947 * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
951 * fixme: There is no proper field to store this information.
952 * Just increase pointer now.
955 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
956 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTBY");
960 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
961 MSG_DEBUG("2. invalid MMS_CODE_PREVIOUSLYSENTBY");
965 if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
966 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
971 case MMS_CODE_PREVIOUSLYSENTDATE:
974 * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
975 * Forwarded-count-value = Integer-value
976 * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
980 * fixme: There is no proper field to store this information.
981 * Just increase pointer now.
984 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
985 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTDATE");
989 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
990 MSG_DEBUG("2. invalid MS_CODE_PREVIOUSLYSENTDATE");
994 if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
995 MSG_DEBUG("3. invalid MMS_CODE_PREVIOUSLYSENTDATE");
1002 * Application-header = Token-text Application-specific-value
1003 * Token-text = Token End-of-string
1004 * Application-specific-value = Text -string
1006 * OR unknown header field - Just ignore these fields.
1008 * Read one byte and check the value >= 0x80
1009 * (check these value can be field code)
1012 int remainLength = 0;
1016 offset = __MmsGetDecodeOffset();
1017 if (offset >= totalLength)
1020 remainLength = totalLength - offset;
1022 while ((oneByte < 0x80) && (remainLength > 0)) {
1023 if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1024 MSG_DEBUG("__MmsBinaryDecodeCheckAndDecreaseLength fail");
1028 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1029 MSG_DEBUG("responseStatus GetOneByte fail");
1034 gCurMmsDecodeBuffPos--;
1039 offset = __MmsGetDecodeOffset();
1040 if (offset >= totalLength)
1046 if (mmsHeader.pTo == NULL && pLastTo) {
1050 if (mmsHeader.pCc == NULL && pLastCc) {
1054 if (mmsHeader.pBcc == NULL && pLastBcc) {
1058 MSG_INFO("## Decode Header Success ##");
1065 if (mmsHeader.pTo == NULL && pLastTo) {
1069 if (mmsHeader.pCc == NULL && pLastCc) {
1073 if (mmsHeader.pBcc == NULL && pLastBcc) {
1077 MSG_FATAL("## Decode Header Fail ##");
1082 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1089 if (szFilePath != NULL)
1090 snprintf(mmsHeader.msgType.szOrgFilePath, sizeof(mmsHeader.msgType.szOrgFilePath), "%s", szFilePath);
1092 mmsHeader.msgType.offset = __MmsGetDecodeOffset() - 1; /* + Content-Type code value */
1094 /* read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding */
1095 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1096 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1097 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1098 MSG_DEBUG("fail to load to buffer");
1102 /* msg's type [ex] related, mixed, single part (jpg, amr and etc) */
1103 length = __MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1105 MSG_DEBUG("MMS_CODE_CONTENTTYPE is fail");
1109 mmsHeader.msgType.size = length + 1; /* + Content-Type code value */
1110 mmsHeader.msgBody.offset = __MmsGetDecodeOffset();
1112 switch (mmsHeader.msgType.type) {
1113 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1114 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1115 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1116 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1117 case MIME_MULTIPART_REPORT:
1118 case MIME_MULTIPART_MIXED:
1119 case MIME_MULTIPART_RELATED:
1120 case MIME_MULTIPART_ALTERNATIVE:
1121 case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1122 case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1124 MSG_DEBUG("Decode Multipart");
1126 offset = __MmsGetDecodeOffset();
1127 if (offset >= totalLength)
1130 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1131 MSG_DEBUG("MmsBinaryDecodeMultipart is fail.");
1138 /* Single part message ---------------------------------------------- */
1139 MSG_DEBUG("Decode Singlepart");
1141 offset = __MmsGetDecodeOffset();
1142 if (offset >= totalLength)
1145 if (__MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1146 MSG_DEBUG("MmsBinaryDecodePartBody is fail.(Single Part)");
1150 snprintf(mmsHeader.msgBody.szOrgFilePath, MSG_FILEPATH_LEN_MAX, "%s", szFilePath);
1151 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1152 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1165 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1170 char *szTypeString = NULL;
1171 char *szTypeValue = NULL;
1172 UINT8 paramCode = 0xff;
1179 * Parameter = Typed-parameter | Untyped-parameter
1180 * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1183 while (valueLength > 0) {
1184 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1185 MSG_DEBUG("paramCode _MmsBinaryDecodeGetOneByte fail");
1189 paramCode = oneByte;
1192 switch (paramCode) {
1193 case 0x81: /* charset */
1195 if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1196 MSG_DEBUG("__MmsBinaryDecodeCharset fail.");
1200 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1205 case 0x85: /* name = Text-string */
1206 case 0x97: /* name = Text-value = No-value | Token-text | Quoted-string */
1207 memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1208 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szName,
1209 MSG_FILENAME_LEN_MAX -5, /* MSG_LOCALE_FILENAME_LEN_MAX + 1, : change @ 110(Ui code have to change for this instead of DM) */
1212 MSG_DEBUG("__MmsDecodeGetFilename fail. (name parameter)");
1216 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1217 __MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1220 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1225 case 0x86: /* filename = Text-string */
1226 case 0x98: /* filename = Text-value = No-value | Token-text | Quoted-string */
1227 memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1228 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1230 MSG_DEBUG("__MmsDecodeGetFilename fail. (filename parameter)");
1234 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1235 __MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1238 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1243 case 0x89: /* type = Constrained-encoding = Extension-Media | Short-integer */
1245 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1246 MSG_DEBUG("type _MmsBinaryDecodeGetOneByte fail");
1250 if (oneByte > 0x7f) {
1251 pMsgType->param.type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1252 /* MmsGetBinaryType(MmsCodeContentType,(UINT16)(oneByte & 0x7f)); */
1253 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1256 gCurMmsDecodeBuffPos--;
1259 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1260 pMsgType->param.type = MimeGetMimeIntFromMimeString(szTypeString);
1263 szTypeString = NULL;
1266 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1272 case 0x8A: /* start encoding version 1.2 */
1273 case 0x99: /* start encoding version 1.4 */
1276 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1278 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1279 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1281 szTypeString = NULL;
1283 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1289 case 0x8B: /* startInfo encoding version 1.2 */
1290 case 0x9A: /* startInfo encoding version 1.4 */
1293 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1296 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1297 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1300 szTypeString = NULL;
1302 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1310 if (paramCode > 0x7F) {
1311 MSG_DEBUG("Unsupported parameter");
1313 /* In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value. */
1315 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1319 * Untyped Parameter = Token-text Untyped-value
1320 * Token-text = Token End-of-string
1321 * Untyped-value = Integer-value | Text-value
1322 * Text-value = No-value | Token-text | Quoted-string
1324 * Just increase pointer!!!
1330 gCurMmsDecodeBuffPos--;
1334 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1335 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1341 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1342 MSG_DEBUG("Unsupported parameter(%d)\n", integer);
1343 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1347 szTypeValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1350 /* checkMe: forwardLock needs boudary string */
1351 if (g_ascii_strcasecmp(szTypeString, "boundary") == 0) {
1352 memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1353 strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1354 #ifdef FEATURE_JAVA_MMS
1355 } else if (g_ascii_strcasecmp(szTypeString, "Application-ID") == 0) {
1356 pMsgType->param.szApplicationID = (char*) calloc(1, textLength + 1);
1357 if (pMsgType->param.szApplicationID) {
1358 memset(pMsgType->param.szApplicationID, 0, textLength + 1);
1359 strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1360 MSG_SEC_DEBUG("Application-ID:%s", pMsgType->param.szApplicationID);
1362 } else if (g_ascii_strcasecmp(szTypeString, "Reply-To-Application-ID") == 0) {
1363 pMsgType->param.szReplyToApplicationID = (char*)calloc(1, textLength + 1);
1364 if (pMsgType->param.szReplyToApplicationID) {
1365 memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1366 strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1367 MSG_SEC_DEBUG("ReplyToApplication-ID:%s", pMsgType->param.szReplyToApplicationID);
1372 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeValue);
1376 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1382 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeString);
1384 szTypeString = NULL;
1390 } /*end of while loop*/
1397 szTypeString = NULL;
1409 * Decode Encoded Content type
1411 * @param pEncodedData [in] ContentType encoded data
1412 * @param pMsgType [out] Decoded MsgType
1413 * @return Decoded address list
1415 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1419 char *szTypeString = NULL;
1420 int valueLength = 0;
1426 * Content-type-value : [WAPWSP 8.4.2.24]
1427 * Preassigned content-types : [WAPWSP Appendix A, Table 40]
1428 * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1430 * Content-type-value = Constrained-media | Content-general-form
1431 * Content-general-form = Value-length Media-type
1432 * Media-type = (Well-known-media | Extension-Media) *(Parameter)
1435 length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1438 * Constrained-media or Single part message
1439 * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1440 * Extension-media = *TEXT End-of-string
1441 * Short-integer = OCTET(1xxx xxxx)
1444 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1445 MSG_DEBUG("Constrained-media _MmsBinaryDecodeGetOneByte fail");
1449 if (oneByte > 0x7F) {
1451 pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1453 MSG_SEC_DEBUG("Constrained-media : Short-integer : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1457 char *pszTemp = NULL;
1459 /* Extension-Media */
1460 gCurMmsDecodeBuffPos--;
1463 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1465 if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1466 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type with delimiter = [%s]", szTypeString);
1468 pszTemp = __MsgGetStringUntilDelimiter(szTypeString, ';');
1471 szTypeString = pszTemp;
1475 pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1477 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1479 length = textLength;
1483 szTypeString = NULL;
1488 * Content-general-form = Value-length Media-type
1489 * Media-type = (Well-known-media | Extension-Media)*(Parameter)
1492 length += valueLength;
1494 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1495 MSG_DEBUG("Well-known-media _MmsBinaryDecodeGetOneByte fail");
1499 if (oneByte > 0x7F) {
1500 /* Well-known-media */
1501 pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1502 MSG_SEC_DEBUG("Content-general-form : Well-known-media : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1505 /* Extension-Media */
1506 gCurMmsDecodeBuffPos--;
1509 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1511 pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1513 MSG_SEC_DEBUG("Content-general-form : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1515 valueLength -= textLength;
1519 szTypeString = NULL;
1523 MSG_SEC_DEBUG("Content-Type = [%s]", MmsDebugGetMimeType((MimeType)pMsgType->type));
1525 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1526 MSG_DEBUG("Content-Type parameter fail");
1539 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1541 UINT8 fieldCode = 0xff;
1543 UINT32 valueLength = 0;
1545 char *pValue = NULL;
1546 char *pParam = NULL;
1552 char *pLatinBuff = NULL;
1554 char *szTemp = NULL;
1556 MSG_INFO("headerLen[%d] totalLength[%d]", headerLen, totalLength);
1558 if (pFile == NULL || pMsgType == NULL)
1562 * Message-header = Well-known-header | Application-header
1563 * Well-known-header = Well-known-field-name Wap-value
1564 * Application-header = Token-text Application-specific-value
1565 * Well-known-field-name = Short-integer
1566 * Application-specific-value = Text-string
1569 while (headerLen > 0) {
1570 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1571 MSG_DEBUG("field code GetOneByte fail");
1575 if (0x80 <= oneByte && oneByte <= 0xC7) {
1576 /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1578 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1581 fieldCode = oneByte & 0x7f;
1583 switch (fieldCode) {
1584 case 0x0E: /* Content-Location */
1585 case 0x04: { /* Content-Location */
1586 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1587 if (pLatinBuff == NULL)
1590 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1592 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1596 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1598 snprintf(pMsgType->szContentLocation, sizeof(pMsgType->szContentLocation), "%s", szSrc);
1599 MSG_SEC_DEBUG("Content Location : [%s]", pMsgType->szContentLocation);
1607 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1612 case 0x40: { /* Content-ID */
1613 char szContentID[MMS_CONTENT_ID_LEN + 1] = {0, };
1615 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1616 if (pLatinBuff == NULL)
1619 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1622 MSG_DEBUG("Content-ID __MmsBinaryDecodeQuotedString fail.");
1626 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1628 snprintf(szContentID, sizeof(szContentID), "%s", szSrc);
1629 MSG_SEC_DEBUG("Content ID : [%s]", szContentID);
1637 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1639 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1644 case 0x2E: /* Content-Disposition */
1645 case 0x45: /* Content-Disposition */
1648 * Content-disposition-value = Value-length Disposition *(Parameter)
1649 * Disposition = Form-data | Attachment | Inline | Token-text
1650 * Form-data = <Octet 128> : 0x80
1651 * Attachment = <Octet 129> : 0x81
1652 * Inline = <Octet 130> : 0x82
1655 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1658 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1662 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1663 MSG_DEBUG("Disposition value GetOneByte fail");
1670 if (oneByte >= 0x80) {
1671 pMsgType->disposition = MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1673 if (pMsgType->disposition == -1) {
1674 MSG_DEBUG("Content-Disposition MmsGetBinaryType fail.");
1675 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT; /* default */
1678 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1681 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1682 MSG_DEBUG("Disposition parameter fail");
1686 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1689 gCurMmsDecodeBuffPos--;
1692 pLatinBuff = (char *)calloc(1, MSG_FILENAME_LEN_MAX);
1693 if (pLatinBuff == NULL)
1695 memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1697 textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1700 if (textLength < 0) {
1701 MSG_DEBUG("Content-Disposition decodingfail.");
1707 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1710 valueLength -= textLength;
1712 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1713 MSG_DEBUG("Disposition parameter fail");
1717 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1723 case 0x0B: /* Content-Encoding */
1724 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1725 MSG_DEBUG("Disposition value GetOneByte fail");
1729 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1734 case 0x0C: /* Content-Language */
1735 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1736 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1741 cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1743 if (cTemp == NULL) {
1744 MSG_DEBUG("__MmsBinaryDecodeText2 fail...");
1748 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1760 case 0x0D: /* Content-Length */
1761 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1762 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1766 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1771 case 0x1C: /* Location */
1772 pLatinBuff = (char *)calloc(1, MMS_LOCATION_URL_LEN + 1);
1773 if (pLatinBuff == NULL)
1776 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_LOCATION_URL_LEN, totalLength);
1778 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1782 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1784 snprintf(pMsgType->szLocation, sizeof(pMsgType->szLocation), "%s", szSrc);
1785 MSG_INFO("Location : [%s]", pMsgType->szLocation);
1793 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1798 case 0x30: /* X-Wap-Content-URI skip this value */
1799 MSG_DEBUG("X-Wap-Content-URI header.");
1800 pLatinBuff = (char *)calloc(1, MMS_TEXT_LEN);
1801 if (pLatinBuff == NULL)
1804 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1807 MSG_DEBUG(" __MmsBinaryDecodeQuotedString fail.");
1811 MSG_DEBUG("X-Wap-Content-URI header decoded. Value length %d\n", length);
1815 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1818 MSG_DEBUG("X-Wap-Content-URI header skipped.");
1822 case 0x01: { /* Accept-charset */
1823 /* if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1) */
1824 /* WAP-230-WSP-200010705-a.pdf
1825 8.4.2.8 Accept charset field
1826 The following rules are used to encode accept character set values.
1827 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1828 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1829 Constrained-charset = Any-charset | Constrained-encoding
1830 Well-known-charset = Any-charset | Integer-value
1831 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1832 Any-charset = <Octet 128>
1833 ; Equivalent to the special RFC2616 charset value ��*��
1839 MSG_DEBUG("Accept-charset.");
1841 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1843 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1847 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1848 /* We only support the well-known-charset format */
1849 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1854 MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1856 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1863 /* Other Content-xxx headers : Have valueLength */
1864 MSG_WARN("unknown Value = 0x%x\n", oneByte);
1866 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1868 MSG_WARN("invalid MMS_CODE_PREVIOUSLYSENTDATE");
1872 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1875 szTemp = (char *)calloc(1, valueLength);
1879 if (__MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) == false) {
1880 MSG_WARN("default _MmsBinaryDecodeGetBytes() fail");
1888 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1895 * Application-header = Token-text Application-specific-value
1896 * Application-specific-value = Text-string
1899 MSG_DEBUG(" Application-header = Token-text Application-specific-value");
1901 gCurMmsDecodeBuffPos--;
1906 pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1907 if (pCode == NULL) {
1908 MSG_DEBUG("pCode is null");
1912 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1915 MSG_DEBUG(" Token-text (%s) \n", pCode);
1918 /* Application-specific-value */
1921 pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1922 if (pValue == NULL) {
1923 MSG_DEBUG("pValue is null");
1927 MSG_DEBUG(" Application-specific-value (%s) \n", pValue);
1930 pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1936 switch (MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1937 case MMS_BODYHDR_TRANSFERENCODING: /* Content-Transfer-Encoding */
1938 pMsgType->encoding = MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1941 case MMS_BODYHDR_CONTENTID: { /* Content-ID */
1942 char szContentID[MMS_CONTENT_ID_LEN + 1];
1944 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1945 if (pLatinBuff == NULL) {
1949 __MsgMIMERemoveQuote(pValue);
1950 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1952 length = strlen(pLatinBuff);
1953 if (__MsgLatin2UTF((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1954 MSG_DEBUG("MsgLatin2UTF fail");
1958 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1964 case MMS_BODYHDR_CONTENTLOCATION: /* Content-Location */
1966 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1967 if (pLatinBuff == NULL)
1970 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1972 length = strlen(pLatinBuff);
1973 if (__MsgLatin2UTF((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1974 MSG_DEBUG("MsgLatin2UTF fail");
1982 case MMS_BODYHDR_DISPOSITION: /* Content-Disposition */
1983 pMsgType->disposition = MmsGetTextType(MmsCodeMsgDisposition, pValue);
1986 case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY: /* DRM RO WAITING */
1990 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
1995 __MsgParseParameter(pMsgType, pParam + 1);
2007 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2049 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2053 length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2058 MSG_INFO("Number of Entries = [%d]", *npEntries);
2066 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2071 * Currently, offset and size is
2072 * the only information used with msgBody.
2073 * If you need, add here more information
2077 offset = __MmsGetDecodeOffset();
2078 offset += bodyLength;
2080 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2081 MSG_DEBUG("fail to seek file pointer");
2085 __MmsCleanDecodeBuff();
2087 gMmsDecodeCurOffset = offset;
2089 if (offset >= totalLength)
2092 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2093 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2094 MSG_DEBUG("fail to load to buffer");
2107 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2109 if (offset > totalLength)
2112 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2113 MSG_DEBUG("fail to seek file pointer");
2117 __MmsCleanDecodeBuff();
2119 gMmsDecodeCurOffset = offset;
2121 if (offset == totalLength)
2124 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2125 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2126 MSG_DEBUG("fail to load to buffer");
2137 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2139 UINT32 nEntries = 0;
2140 MsgMultipart *pMultipart = NULL;
2141 MsgMultipart *pLastMultipart = NULL;
2145 MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2146 MsgPresentaionInfo presentationInfo;
2148 MSG_DEBUG("pdu length = [%d]", totalLength);
2150 presentationInfo.factor = MSG_PRESENTATION_NONE;
2151 presentationInfo.pCurPresentation = NULL;
2152 presentationInfo.pPrevPart = NULL;
2154 if (__MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2155 MSG_DEBUG("MmsBinaryDecodeEntries is fail.");
2159 if (pMsgBody->body.pMultipart != NULL) {
2160 pLastMultipart = pMsgBody->body.pMultipart;
2161 MSG_DEBUG("previous multipart exist [%p]", pMsgBody->body.pMultipart);
2163 MSG_DEBUG("first multipart");
2167 MSG_DEBUG("decoding [%d]th multipart", index);
2169 offset = __MmsGetDecodeOffset();
2170 if (offset >= totalLength) {
2171 MSG_DEBUG("offset is over totalLength");
2175 if ((pMultipart = MmsAllocMultipart()) == NULL) {
2176 MSG_DEBUG("MsgAllocMultipart Fail");
2180 if (__MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2181 MSG_DEBUG("MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2185 if (pMultipart->type.type == MIME_APPLICATION_SMIL) {
2186 /* P151019-00477 : received mms message is type of multipart mixed, but among multiparts if there's smil part then set it multipart related */
2187 if (pMsgType->type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED)
2188 pMsgType->type = MIME_APPLICATION_VND_WAP_MULTIPART_RELATED;
2190 factor = __MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2191 if (factor == MSG_PRESENTATION_NONE) {
2192 factor = MSG_PRESENTATION_TYPE_BASE;
2195 factor = MSG_PRESENTATION_NONE;
2198 /* priority 1 : content type match, 2: content location, 3: type */
2199 if (presentationInfo.factor < factor) {
2200 /* Presentation part */
2201 presentationInfo.factor = factor;
2202 presentationInfo.pPrevPart = pLastMultipart;
2203 presentationInfo.pCurPresentation = pMultipart;
2206 /* first multipart */
2207 if (pLastMultipart == NULL) {
2208 pMsgBody->body.pMultipart = pMultipart;
2209 pLastMultipart = pMultipart;
2211 pLastMultipart->pNext = pMultipart;
2212 pLastMultipart = pMultipart;
2215 pMsgType->contentSize += pMultipart->pBody->size;
2219 MmsPrintMulitpart(pMultipart, index++);
2222 pMsgBody->size = totalLength - pMsgBody->offset;
2224 __MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2226 if (__MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2227 MSG_DEBUG("MsgResolveNestedMultipart failed");
2235 if (pMultipart->pBody) {
2236 free(pMultipart->pBody);
2237 pMultipart->pBody = NULL;
2247 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2250 bool bSuccess = false;
2251 UINT32 headerLength = 0;
2252 UINT32 bodyLength = 0;
2255 MSG_DEBUG("pdu length = [%d]", totalLength);
2258 if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2259 MSG_DEBUG("Get header length fail");
2263 offset = __MmsGetDecodeOffset();
2264 if (offset >= totalLength)
2268 if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2269 MSG_DEBUG("Get body length fail");
2273 offset = __MmsGetDecodeOffset();
2274 if (offset >= totalLength)
2278 if (szFilePath != NULL)
2279 snprintf(pMsgType->szOrgFilePath, sizeof(pMsgType->szOrgFilePath), "%s", szFilePath);
2281 pMsgType->offset = __MmsGetDecodeOffset();
2282 pMsgType->size = headerLength;
2283 pMsgType->contentSize = bodyLength;
2285 if (pMsgType->offset > totalLength)
2288 length = __MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2290 MSG_DEBUG("Decode contentType Fail");
2294 offset = __MmsGetDecodeOffset();
2295 if (offset >= totalLength)
2301 if (__MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2302 MSG_DEBUG("Decode contentHeader Fail");
2306 offset = __MmsGetDecodeOffset();
2307 if (offset >= totalLength)
2312 if (szFilePath != NULL)
2313 snprintf(pMsgBody->szOrgFilePath, sizeof(pMsgBody->szOrgFilePath), "%s", szFilePath);
2315 pMsgBody->offset = __MmsGetDecodeOffset();
2316 pMsgBody->size = bodyLength;
2318 if (pMsgBody->offset > totalLength)
2321 switch (pMsgType->type) {
2322 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2323 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2324 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2325 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2326 case MIME_MULTIPART_REPORT:
2327 case MIME_MULTIPART_MIXED:
2328 case MIME_MULTIPART_RELATED:
2329 case MIME_MULTIPART_ALTERNATIVE:
2330 MSG_DEBUG("Multipart");
2331 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2332 MSG_DEBUG("MmsBinaryDecodeMultipart is fail");
2336 offset = __MmsGetDecodeOffset();
2337 if (offset >= totalLength)
2343 MSG_DEBUG("Normal Part");
2345 if (pMsgType->type == MIME_UNKNOWN) {
2346 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0};
2347 MimeType mimeType = MIME_UNKNOWN;
2349 if (pMsgType->param.szName[0] != '\0')
2350 snprintf(szFileName, MSG_FILENAME_LEN_MAX, "%s", pMsgType->param.szName);
2351 else if (pMsgType->param.szFileName[0] != '\0')
2352 snprintf(szFileName, MSG_FILENAME_LEN_MAX, "%s", pMsgType->param.szFileName);
2353 else if (pMsgType->szContentLocation[0] != '\0')
2354 snprintf(szFileName, MSG_FILENAME_LEN_MAX, "%s", pMsgType->szContentLocation);
2356 MsgGetMimeTypeFromFileName(MIME_MAINTYPE_UNKNOWN, szFileName, &mimeType, NULL);
2357 pMsgType->type = mimeType;
2360 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2361 if (bSuccess == false) {
2362 MSG_DEBUG("Decode contentBody Fail");
2366 offset = __MmsGetDecodeOffset();
2367 if (offset >= totalLength)
2385 /* --------------------------------------------------------------------
2387 * B I N A R Y D E C D E U T I L I T Y
2389 * --------------------------------------------------------------------*/
2391 bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
2393 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2395 if (pFile == NULL || pOneByte == NULL) {
2396 MSG_DEBUG("invalid file or buffer");
2401 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2402 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2403 MSG_DEBUG("fail to load to buffer");
2408 *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2417 * @remark: bufLen < gMmsDecodeMaxLen
2419 bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2421 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2425 if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
2428 memset(szBuff, 0, bufLen);
2430 if (length < bufLen) {
2431 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2432 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2433 MSG_DEBUG("fail to load to buffer");
2438 for (i = 0; i < bufLen - 1; i++) {
2439 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2442 gCurMmsDecodeBuffPos++; /* NULL */
2450 bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2454 if (pFile == NULL || szBuff == NULL || bufLen == 0)
2457 memset(szBuff, 0, bufLen);
2459 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2460 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2461 MSG_DEBUG("fail to load to buffer");
2465 while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
2466 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
2467 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2471 iPos += gMmsDecodeMaxLen;
2474 if ((bufLen - iPos) > 0) {
2475 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
2476 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2480 iPos += (bufLen - iPos);
2490 * Decode uintvar to 32bit unsigned integer
2492 * @param pEncodedData [in] encoded data
2493 * @param pUintVar [out] Decode uintvar (32bit unsigned integer)
2494 * @return The length of uintvar (-1, if cannot be converted to a uintvar)
2496 * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
2499 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
2501 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
2505 UINT32 decodedUintvar = 0;
2506 UINT8 iBuff[5] = {0};
2507 int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
2510 if (pFile == NULL || pUintVar == NULL)
2514 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2515 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2516 MSG_DEBUG("fail to load to buffer");
2522 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2525 if (oneByte > 0x7f) {
2526 iBuff[count++] = oneByte;
2528 iBuff[count++] = oneByte;
2533 MSG_DEBUG("legnth is too long");
2538 for (int i = 0; i < count; i++)
2539 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
2541 *pUintVar = decodedUintvar;
2546 gCurMmsDecodeBuffPos -= count;
2551 * Decode uintvar to 32bit unsigned integer by uintvar length
2553 * @param pEncodedData [in] uintvar encoded data
2554 * @param length [in] length of integer value
2555 * @return unsigned integer value
2557 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
2567 returner.integer = 0;
2573 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2574 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2578 if (oneByte > 0x7f) {
2579 return (oneByte & 0x7f);
2588 pData = (char *)calloc(1, length + 1);
2589 if (pData == NULL) {
2590 MSG_DEBUG("pData alloc fail");
2593 memset(pData, 0, length + 1);
2595 if (__MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
2596 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2600 gCurMmsDecodeBuffPos--; /* - NULL */
2602 for (i= 0; i < length; i++)
2603 returner.seg[length - (i+1)] = pData[i];
2610 return returner.integer;
2619 return returner.integer;
2623 * Decode uintvar to 32bit unsigned integer by uintvar length
2625 * @param pEncodedData [in] uintvar encoded data
2626 * @param pInteger [out] Decode integer value (long/short)
2627 * @return unsigned integer value (-1, if cannot be converted to unsigned integer value)
2629 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
2639 if (pInteger == NULL)
2642 returner.integer = 0;
2645 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2646 MSG_DEBUG("GetOneByte fail");
2650 if (oneByte < 0x1F) { /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2651 pData = (char *)calloc(1, oneByte + 1);
2652 if (pData == NULL) {
2653 MSG_DEBUG("pData calloc fail");
2656 memset(pData, 0, oneByte + 1);
2658 /* Even NULL is copied in the _MmsBinaryDecodeGetBytes */
2659 if (__MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
2660 MSG_DEBUG("GetBytes fail");
2664 gCurMmsDecodeBuffPos--; /* - NULL */
2674 for (i = 0; i < length; i++)
2675 returner.seg[length - (i+1)] = pData[i];
2677 *pInteger = returner.integer;
2678 *pIntLen = oneByte + 1;
2679 } else if (oneByte >= 0x80) {
2680 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2681 *pInteger = oneByte & 0x7f;
2696 gCurMmsDecodeBuffPos--;
2707 * Decode uintvar to 32bit unsigned integer by uintvar length
2709 * @return 1 : Success
2710 * 0 : This is not Value Length type data
2711 * -1 : Requires System error report
2713 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
2721 * value-length = short-length | (Length-quote Length)
2722 * = 0~30 | 31 + Uintvar-length
2725 if (pFile == NULL || pValueLength == NULL)
2730 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2731 gCurMmsDecodeBuffPos--;
2735 if (0x00 < oneByte && oneByte < 0x1F) {
2737 *pValueLength = oneByte;
2739 } else if (oneByte == 0x1F) {
2740 /* Length-quote = 0x1F */
2742 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2744 MSG_DEBUG(" __MmsBinaryDecodeUintvar fail..");
2747 length++; /* + length-quote */
2748 *pValueLength = uintvar;
2750 MSG_DEBUG("not a value length type data");
2751 gCurMmsDecodeBuffPos--;
2758 MSG_DEBUG("getting data fail");
2763 * Decode uintvar to 32bit unsigned integer by uintvar length
2765 * @return 1 : Success
2766 * 0 : This is not Value Length type data
2767 * -1 : Requires System error report
2768 * @ defference : if there is not length-quote, consider it as short length.
2770 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
2778 * value-length = short-length | (Length-quote Length)
2779 * = 0~30 | 31 + Uintvar-length
2782 if (pFile == NULL || pValueLength == NULL)
2787 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2788 gCurMmsDecodeBuffPos--;
2792 if (0x00 < oneByte && oneByte < 0x1F) {
2794 *pValueLength = oneByte;
2796 } else if (oneByte == 0x1F) {
2797 /* Length-quote = 0x1F */
2799 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2801 MSG_DEBUG("__MmsBinaryDecodeUintvar fail..");
2804 length++; /* + length-quote */
2805 *pValueLength = uintvar;
2807 MSG_DEBUG("there is not length-quote, consider it as short length.");
2808 *pValueLength = oneByte;
2815 MSG_DEBUG("getting data fail");
2820 * Decode QuotedString
2822 * @param pEncodedData [in] QuotedString encoded data
2823 * @param szBuff [out] Decoded quoted string
2824 * @param bufLen [out] Buffer length
2825 * @return length of quoted string
2827 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2833 int returnLength = 0;
2836 * Quoted-string = <Octet 34> *TEXT End-of-string
2837 * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
2840 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2843 memset(szBuff, 0, bufLen);
2845 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2846 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2847 MSG_DEBUG("fail to load to buffer");
2851 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2856 while (length > gMmsDecodeBufLen) {
2857 if (gMmsDecodeBufLen <= 0) {
2858 MSG_DEBUG("gMmsDecodeBufLen <= 0");
2859 MSG_DEBUG("%x %x %x %x %x",
2860 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
2861 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
2862 MSG_DEBUG("%x %x %x %x %x",
2863 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
2864 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
2865 MSG_DEBUG("%x %x %x %x %x",
2866 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
2867 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
2868 MSG_DEBUG("%x %x %x %x %x",
2869 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
2870 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
2874 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
2878 memset(pData, 0, gMmsDecodeBufLen + 1);
2880 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
2883 returnLength += gMmsDecodeBufLen;
2885 if ((bufLen - iPos) > 0) {
2886 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
2887 if (iPos == 0 && (pData[0] == MARK)) {
2888 /* MARK: check first time only */
2890 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2891 iPos += (readBytes - 1);
2893 strncpy(szBuff + iPos, (char*)pData, readBytes);
2903 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2904 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2905 MSG_DEBUG("fail to load to buffer");
2908 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2912 pData = (char *)calloc(1, length);
2916 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
2919 returnLength += length;
2921 if ((bufLen - iPos) > 0) {
2922 /* read until NULL from raw data, and copy only string */
2923 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
2924 if (iPos == 0 && (pData[0] == MARK)) {
2925 /* MARK: check first time only */
2926 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2927 iPos += (readBytes - 1);
2929 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); /* + NULL */
2940 szBuff[bufLen - 1] = '\0';
2942 return returnLength;
2961 * @param pEncodedData [in] QuotedString encoded data
2962 * @param szBuff [out] Decoded quoted string
2963 * @param bufLen [out] Buffer length
2964 * @return length of decode text string
2966 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2971 int returnLength = 0;
2973 bool bQuote = false;
2977 * Text-String = [QUOTE]*TEXT end_of_string
2978 * [QUOTE]*(128~255)\0
2982 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2985 offset = __MmsGetDecodeOffset();
2986 if (offset >= totalLength)
2989 memset(szBuff, 0, bufLen);
2991 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2992 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2993 MSG_DEBUG("fail to load to buffer");
2997 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
3002 while (length > gMmsDecodeBufLen) {
3003 if (gMmsDecodeBufLen <= 0) {
3004 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3005 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3006 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3007 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3008 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3009 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3010 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3011 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3012 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3016 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3020 memset(pData, 0, gMmsDecodeBufLen + 1);
3022 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3025 if ((bufLen - iPos) > 0) {
3026 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3027 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3028 /* QUOTE: check first time only */
3030 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3031 iPos += (readBytes - 1);
3034 strncpy(szBuff + iPos, (char*)pData, readBytes);
3044 returnLength += gMmsDecodeBufLen;
3046 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3047 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3048 MSG_DEBUG("fail to load to buffer");
3051 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
3055 pData = (char *)calloc(1, length);
3059 memset(pData, 0, length);
3061 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3064 if ((bufLen - iPos) > 0) {
3065 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3066 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3067 /* QUOTE: check first time only */
3069 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3070 iPos += (readBytes - 1);
3073 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); /* + NULL */
3083 returnLength += length; /* + NULL */
3086 szBuff[bufLen - 1] = '\0';
3088 return returnLength;
3095 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3109 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
3114 char *szBuff = NULL;
3115 char *szTempPtr = NULL;
3116 bool bQuote = false;
3120 * Text-String = [QUOTE]*TEXT end_of_string
3121 * [QUOTE]*(128~255)\0
3125 if (pFile == NULL || pLength == NULL)
3129 offset = __MmsGetDecodeOffset();
3130 if (offset >= totalLength)
3133 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3134 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3135 MSG_DEBUG("fail to load to buffer");
3139 length = strlen(gpCurMmsDecodeBuff) + 1;
3144 while (length > gMmsDecodeBufLen) {
3145 if (gMmsDecodeBufLen <= 0) {
3146 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3147 MSG_DEBUG("%x %x %x %x %x",
3148 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3149 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3150 MSG_DEBUG("%x %x %x %x %x",
3151 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3152 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3153 MSG_DEBUG("%x %x %x %x %x",
3154 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3155 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3156 MSG_DEBUG("%x %x %x %x %x\n",
3157 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3158 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3162 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3166 memset(pData, 0, gMmsDecodeBufLen + 1);
3168 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3171 if (szBuff == NULL) {
3172 szBuff = (char *)calloc(1, gMmsDecodeBufLen + 1);
3174 szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
3176 /* NULL pointer check for realloc */
3177 if (szTempPtr == NULL) {
3186 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
3188 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3189 /* QUOTE: check first time only */
3191 strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
3192 curLen += (gMmsDecodeBufLen - 1);
3195 strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
3196 curLen += gMmsDecodeBufLen;
3204 *pLength += gMmsDecodeBufLen;
3206 if (__MsgLoadDataToDecodeBuffer(pFile,
3207 &gpCurMmsDecodeBuff,
3208 &gCurMmsDecodeBuffPos,
3209 &gMmsDecodeCurOffset,
3214 totalLength) == false) {
3215 MSG_DEBUG("fail to load to buffer");
3218 length = strlen(gpCurMmsDecodeBuff) + 1;
3222 pData = (char *)calloc(1, length);
3223 if (pData == NULL) {
3227 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
3231 if (szBuff == NULL) {
3232 szBuff = (char *)calloc(1, length);
3234 szTempPtr = (char *)realloc(szBuff, curLen + length);
3236 /* NULL pointer check for realloc */
3237 if (szTempPtr == NULL)
3243 if (szBuff == NULL) {
3247 memset(szBuff + curLen, 0, length);
3249 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3250 /* QUOTE: check first time only */
3252 strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
3253 curLen += (length - 1);
3256 strncpy(szBuff + curLen, (char*)pData, length - 1);
3265 *pLength += length; /* + NULL */
3274 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3296 * @param pEncodedData [in] QuotedString encoded data
3297 * @param nCharSet [out] Decoded character set
3298 * @return length of charset value
3300 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
3305 * Charset v1.1 0x01 Well-known-charset
3306 * Well-known-charset = Any-charset | Integer-value
3307 * ; Both are encoded using values from
3308 * Character Set Assignments table in Assigned Numbers
3309 * Any-charset = <Octet 128>
3310 * ; Equivalent to the special RFC2616 charset value ��*��
3313 if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
3316 if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
3317 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
3322 /* AnyCharSet : return MSG_CHARSET_UTF8 */
3323 *nCharSet = MSG_CHARSET_UTF8;
3327 *nCharSet = MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
3328 MSG_DEBUG("Decoded charset MIBenum = [%d], charset enum = [%d]", integer, *nCharSet);
3329 if (*nCharSet == MIME_UNKNOWN) {
3330 MSG_DEBUG("MmsGetBinaryType fail..");
3331 *nCharSet = MSG_CHARSET_UNKNOWN;
3341 * Decode EncodedString
3343 * @param pEncodedData [in] QuotedString encoded data
3344 * @param szBuff [out] Decoded string buffer
3345 * @param bufLen [in] Decoded buffer length
3346 * @return length of decoded string length
3348 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3350 UINT32 valueLength = 0;
3356 MSG_DEBUG(" decode string..");
3358 if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
3359 MSG_DEBUG("invalid file or buffer");
3364 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3365 * Text-string = [Quote]*TEXT End-of-string
3366 * Value-length = 0 ~ 31
3369 memset(szBuff, 0, bufLen);
3371 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3377 /* Text-string = [Quote]*TEXT End-of-string */
3379 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
3380 MSG_DEBUG("__MmsBinaryDecodeText fail.");
3387 /* Value-length Charset Text_string */
3389 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3390 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3391 goto __CATCH; /* (valueLength + valueLengthLen) */
3394 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
3397 /* There can be some error in data - no NULL -> try again with value length */
3399 pData = (char *)calloc(1, valueLength - charSetLen);
3400 if (pData == NULL) {
3401 MSG_DEBUG("pData alloc fail.");
3405 if (__MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
3406 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes fail.");
3410 strncpy(szBuff, pData, bufLen - 1);
3413 nTemp = strlen(szBuff);
3415 const char *pToCharSet = "UTF-8";
3417 UINT16 charset_code = MmsGetBinaryValue(MmsCodeCharSet, charSet);
3419 const char *pFromCharSet = MmsPluginTextConvertGetCharSet(charset_code);
3420 if (pFromCharSet == NULL || !strcmp(pFromCharSet, pToCharSet)) {
3431 if (MmsPluginTextConvert(pToCharSet, pFromCharSet, szBuff, nTemp, &pDest, &destLen) == false) {
3432 MSG_DEBUG("MmsPluginTextConvert Fail");
3435 memset(szBuff, 0x00, bufLen);
3436 snprintf(szBuff, destLen+1, "%s", pDest);
3466 * Decode Encoded Addresses
3468 * @param pEncodedData [in] QuotedString encoded data
3469 * @param pAddrLength [out] Decoded address length
3470 * @return Decoded address list
3472 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
3474 UINT32 valueLength = 0;
3478 char *pAddrStr = NULL;
3479 MsgHeaderAddress *pAddr = NULL;
3481 MSG_DEBUG("decoding address..");
3483 if (pFile == NULL) {
3484 MSG_DEBUG("invalid file or buffer");
3489 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3490 * Text-string = [Quote]*TEXT End-of-string
3491 * Value-length = 0 ~ 31
3494 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3500 /* Text-string = [Quote]*TEXT End-of-string */
3503 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3504 if (pAddrStr == NULL) {
3505 MSG_DEBUG(" __MmsBinaryDecodeText2 fail.");
3512 /* Value-length Charset Text_string */
3514 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3515 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3520 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3521 if (pAddrStr == NULL) {
3522 /* There can be some error in data - no NULL -> try again with value length */
3524 pAddrStr = (char *)calloc(1, valueLength - charSetLen);
3525 if (pAddrStr == NULL) {
3526 MSG_DEBUG("pData alloc fail.");
3530 if (__MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
3531 MSG_DEBUG(" _MmsBinaryDecodeGetLongBytes fail.");
3536 /* fixme: charset transformation */
3541 pAddr = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
3545 memset(pAddr, 0, sizeof(MsgHeaderAddress));
3546 pAddr->szAddr = pAddrStr;
3562 * Decode Encoded Pointer String
3564 * @param pEncodedData [in] Long integer encoded data
3565 * @param pLongInteger [out] Decoded long integer
3566 * @return Decoded address list
3568 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
3573 * Long-integer = Short-length Multi-octet-integer
3574 * Short-length = 0~30
3575 * Multi-octet-integer
3578 if (pFile == NULL || pLongInteger == NULL)
3583 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3589 *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
3599 * @param pEncodedData [in] filename encoded data
3600 * @param szBuff [out] filename output buffer
3601 * @param fullLength [in] full filename length
3602 * @param bufLen [in] buffer length
3603 * CAUTION: bufLen - 1
3605 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3607 char *pUTF8Buff = NULL;
3608 char *pLatinBuff = NULL;
3611 char *szSrc2 = NULL;
3615 char *pTmpBuff = NULL;
3617 memset(szBuff, 0, bufLen);
3620 pLatinBuff = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3624 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
3626 strncpy(pLatinBuff, szSrc, textLength);
3631 szSrc2 = MsgChangeHexString(pLatinBuff);
3633 strncpy(pLatinBuff, szSrc2, textLength);
3638 if (MmsIsUtf8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
3639 length = strlen(pLatinBuff);
3641 int utf8BufSize = 0;
3642 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
3643 if (utf8BufSize < 3)
3644 utf8BufSize = 3; /* min value */
3646 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
3647 if (pUTF8Buff == NULL) {
3648 MSG_DEBUG("pUTF8Buff alloc fail");
3652 if (__MsgLatin2UTF((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
3653 MSG_DEBUG("MsgLatin2UTF fail");
3659 pTmpBuff = MsgDecodeText(pLatinBuff);
3660 pUTF8Buff = pTmpBuff;
3669 * it should be kept extention even if the file name is shorten
3672 length = strlen(pUTF8Buff);
3673 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
3675 nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
3676 strncpy(szBuff, pUTF8Buff, nameLength);
3677 g_strlcat(szBuff, pExt, (gsize)bufLen);
3679 strncpy(szBuff, pUTF8Buff, bufLen - 1);
3703 /* ==========================================================
3705 M M S D E C O D I N G
3707 ==========================================================*/
3709 /* to get message body this function should be modified from message raw file. */
3710 bool MmsReadMsgBody(msg_message_id_t msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
3713 MmsMsg *pMsg = NULL;
3714 MsgMultipart *pMultipart = NULL;
3716 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
3717 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
3721 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
3722 memset(pMsg, 0, sizeof(MmsMsg));
3726 if (bRetrieved && (retrievedPath != NULL)) {
3727 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
3729 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath, sizeof(szFullPath));
3732 pMsg->msgID = msgID;
3734 /* read from MMS raw file */
3735 strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
3737 MSG_SEC_DEBUG("msg_id = [%d]", msgID);
3738 MSG_SEC_DEBUG("raw file path = [%s]", szFullPath);
3740 if (MsgGetFileSize(szFullPath, &nSize) == false) {
3741 MSG_FATAL("Fail MsgGetFileSize");
3745 pFile = MsgOpenFile(szFullPath, "rb");
3746 if (pFile == NULL) {
3747 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
3751 MmsRegisterDecodeBuffer();
3753 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
3754 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
3758 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
3759 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
3763 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
3765 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
3766 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
3768 { /* attribute convert mmsHeader -> mmsAttribute */
3769 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
3771 pMsg->mmsAttrib.date = mmsHeader.date;
3773 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
3774 pMsg->mmsAttrib.bAskDeliveryReport = true;
3777 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
3779 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
3781 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
3783 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
3785 pMsg->mmsAttrib.msgType = mmsHeader.type;
3787 pMsg->mmsAttrib.version = mmsHeader.version;
3789 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
3791 pMsg->mmsAttrib.priority = mmsHeader.priority;
3793 if (mmsHeader.readReply == MMS_REPORT_YES) {
3794 pMsg->mmsAttrib.bAskReadReply = true;
3797 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
3799 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
3801 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
3803 /* FIXME:: mmsHeader will release after delete global mmsHeader */
3804 /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
3806 if (pMsg->msgBody.pPresentationBody) {
3807 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
3810 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
3811 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
3814 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
3817 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
3822 MsgCloseFile(pFile);
3825 pMsg->nPartCount = 0;
3827 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
3828 pMultipart = pMsg->msgBody.body.pMultipart;
3829 while (pMultipart) {
3831 pMultipart = pMultipart->pNext;
3834 if (pMsg->msgBody.size > 0)
3838 /* make temporary */
3839 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
3841 if (MsgIsMultipart(pMsg->msgType.type) == true) {
3843 pMultipart = pMsg->msgBody.body.pMultipart;
3845 if (bSavePartsAsTempFiles) {
3846 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3847 if (errno == EEXIST) {
3848 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
3850 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3854 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
3858 if (pMsg->msgBody.pPresentationBody) {
3859 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
3860 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3864 while (pMultipart) {
3865 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
3866 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
3869 MmsPrintMulitpart(pMultipart, partIndex);
3871 pMultipart = pMultipart->pNext;
3875 } else { /* single part */
3876 if (pMsg->nPartCount > 0) {
3877 if (bSavePartsAsTempFiles) {
3878 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3879 if (errno == EEXIST) {
3880 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
3882 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3886 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
3890 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
3891 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3895 MSG_DEBUG("### Success ###");
3902 MmsUnregisterDecodeBuffer();
3904 if (pFile != NULL) {
3905 MsgCloseFile(pFile);
3910 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
3912 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
3914 MSG_DEBUG("### Fail ###");
3919 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
3921 MsgHeaderAddress *pTempAddr = NULL;
3923 while (pAddr != NULL) {
3925 pAddr = pAddr->pNext;
3927 if (pTempAddr->szAddr) {
3928 free(pTempAddr->szAddr);
3929 pTempAddr->szAddr = NULL;
3939 static bool __MsgCheckFileNameHasInvalidChar(char *szName)
3944 strLen = strlen(szName);
3946 for (i = 0; i < strLen; i++) {
3947 if (__MsgIsInvalidFileNameChar(szName[i]))
3954 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
3957 int totalLength = 0;
3959 totalLength = strlen(szInText);
3961 while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
3962 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
3963 if (__MsgIsInvalidFileNameChar(szInText[nCount]))
3964 *(szInText+nCount) = replaceChar;
3975 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter)
3977 char *pszBuffer = NULL;
3978 char *pszStrDelimiter = NULL;
3982 MSG_DEBUG("pszString == NULL");
3986 if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
3987 MSG_DEBUG("There is no %c in %s. \n", delimiter, pszString);
3991 bufLength = pszStrDelimiter - pszString;
3993 if ((pszBuffer = (char*)calloc(1, bufLength + 1)) == NULL) {
3994 MSG_DEBUG("calloc is failed");
3997 memset(pszBuffer, 0, bufLength + 1) ;
3999 strncat(pszBuffer, pszString, bufLength);
4004 char *MsgChangeHexString(char *pOrg)
4007 char szBuf[10] = {0, };
4016 cLen = strlen(pOrg);
4018 pNew = (char *)calloc(1, cLen + 1);
4022 memset(pNew, 0, cLen + 1);
4024 for (cIndex = 0; cIndex< cLen ; cIndex++) {
4025 if (pOrg[cIndex] == '%') {
4026 if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0) {
4027 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); /* read two chars after '%' */
4029 if (__MsgIsHexChar(szBuf) == true) { /* check the two character is between 0 ~ F */
4030 OneChar = __MsgConvertHexValue(szBuf);
4032 pNew[index] = OneChar;
4039 pNew[index++] = pOrg[cIndex];
4044 static bool __MsgParseParameter(MsgType *pType, char *pSrc)
4047 char *pValue = NULL;
4050 char *pNextParam = NULL;
4054 char *pTempNextParam = NULL;
4057 char *pUTF8Buff = NULL;
4059 while (pSrc != NULL) {
4060 pSrc = __MsgSkipWS(pSrc);
4062 /* End of parse parameter */
4067 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
4070 if (*pCh == MSG_CH_QUOT) {
4077 for (; pCh <= pTempNextParam ; pCh++) {
4078 if (*pCh == MSG_CH_QUOT)
4079 if (*(pCh - 1) != '\\')
4084 pNextParam = pTempNextParam;
4087 *pNextParam++ = MSG_CH_NULL;
4089 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
4090 *pName++ = MSG_CH_NULL;
4092 if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
4093 *pValue++ = MSG_CH_NULL;
4095 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
4096 *pTest = MSG_CH_NULL;
4098 pDec = MsgDecodeText(pValue); /* Api is to long, consider Add to another file (MsgMIMECodec.c) */
4100 pDec = MsgDecodeText(pName);
4104 switch (MmsGetTextType(MmsCodeParameterCode, pSrc)) {
4105 case MSG_PARAM_BOUNDARY:
4106 /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
4107 memset(pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
4108 strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
4109 MSG_SEC_INFO("szBoundary = [%s]", pType->param.szBoundary);
4112 case MSG_PARAM_CHARSET:
4113 pType->param.charset = MmsGetTextType(MmsCodeParameterCode, pDec);
4115 if (pType->param.charset == -1)
4116 pType->param.charset = MSG_CHARSET_UNKNOWN;
4118 MSG_SEC_INFO("type = %d [charset] = %d", pType->type, pType->param.charset);
4121 case MSG_PARAM_NAME:
4122 memset(pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
4124 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4127 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4128 if ((MSG_LOCALE_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4129 nameLen = (MSG_LOCALE_FILENAME_LEN_MAX-1) - strlen(pExt);
4131 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4134 strncpy(pType->param.szName, pUTF8Buff, nameLen);
4135 g_strlcat(pType->param.szName, pExt, sizeof(pType->param.szName));
4137 strncpy(pType->param.szName, pUTF8Buff, (MSG_LOCALE_FILENAME_LEN_MAX-1));
4142 if (__MsgChangeSpace(pType->param.szName, &szSrc) == true) {
4144 strncpy(pType->param.szName, szSrc , strlen(szSrc));
4152 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4153 __MsgRemoveFilePath(pType->param.szName);
4155 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4158 MSG_SEC_INFO("szName = %s", pType->param.szName);
4161 case MSG_PARAM_FILENAME:
4162 memset(pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
4164 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4167 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4168 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4169 nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
4171 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4174 strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
4175 g_strlcat (pType->param.szFileName, pExt, sizeof(pType->param.szFileName));
4177 strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
4182 if (__MsgChangeSpace(pType->param.szFileName, &szSrc) == true) {
4183 snprintf(pType->param.szFileName, sizeof(pType->param.szFileName), "%s", szSrc);
4191 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4192 __MsgRemoveFilePath(pType->param.szFileName);
4194 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4197 MSG_SEC_INFO("szFileName = %s", pType->param.szFileName);
4201 case MSG_PARAM_TYPE:
4202 /* type/subtype of root. Only if content-type is multipart/related */
4203 pType->param.type = MimeGetMimeIntFromMimeString(pDec);
4204 MSG_SEC_INFO("type = %d", pType->param.type);
4208 case MSG_PARAM_START:
4209 /* Content-id. Only if content-type is multipart/related */
4210 memset(pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
4211 strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
4213 MSG_SEC_INFO("szStart = %s", pType->param.szStart);
4217 case MSG_PARAM_START_INFO:
4218 /* Only if content-type is multipart/related */
4219 memset(pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
4220 strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
4222 MSG_SEC_INFO("szStartInfo = %s", pType->param.szStartInfo);
4226 case MSG_PARAM_REPORT_TYPE:
4227 /* only used as parameter of Content-Type: multipart/report; report-type=delivery-status; */
4228 if (strcasecmp(pDec, "delivery-status") == 0) {
4229 pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
4231 pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
4234 MSG_SEC_INFO("reportType = %s", pDec);
4238 MSG_DEBUG("Unknown paremeter (%s)", pDec);
4251 static char *__MsgSkipWS(char *s)
4254 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
4256 } else if ((*s != '(') || (__MsgSkipComment(s, (long)NULL) == NULL)) {
4262 static char *__MsgSkipComment(char *s, long trim)
4268 /* ignore empty space */
4269 for (ret = ++s1; *ret == ' '; ret++)
4272 /* handle '(', ')', '\', '\0' */
4276 if (!__MsgSkipComment(s1, (long)NULL))
4308 static char *__MsgConvertLatin2UTF8FileName(char *pSrc)
4310 char *pUTF8Buff = NULL;
4311 /* char *pData = NULL; */
4314 /* convert utf8 string */
4315 if (MmsIsUtf8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
4317 int utf8BufSize = 0;
4319 length = strlen(pSrc);
4320 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
4321 if (utf8BufSize < 3)
4322 utf8BufSize = 3; /* min value */
4324 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
4326 if (pUTF8Buff == NULL) {
4327 MSG_DEBUG("pUTF8Buff alloc fail");
4331 if (__MsgLatin2UTF((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
4332 MSG_DEBUG("MsgLatin2UTF fail");
4336 int length = strlen(pSrc);
4337 pUTF8Buff = (char *)calloc(1, length+1);
4339 if (pUTF8Buff == NULL) {
4340 MSG_DEBUG("pUTF8Buff alloc fail");
4344 memcpy(pUTF8Buff, pSrc, length);
4347 /* convert hex string */
4349 if (__MsgIsPercentSign(pUTF8Buff) == true) {
4350 pData = MsgChangeHexString(pUTF8Buff);
4370 static bool __MsgChangeSpace(char *pOrg, char **ppNew)
4380 cLen = strlen(pOrg);
4382 pNew = (char *)calloc(1, cLen + 1);
4386 memset(pNew, 0, cLen + 1);
4388 for (cIndex=0; cIndex < cLen; cIndex++) {
4389 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
4395 pNew[index++] = pOrg[cIndex];
4403 static void __MsgRemoveFilePath(char *pSrc)
4405 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4407 char *tmp_name = NULL;
4409 tmp_name = MsgGetFileName(pSrc);
4411 snprintf(pSrc, strlen(tmp_name), "%s", tmp_name);
4416 /* Remove additional file information
4417 * ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
4418 * if "?size=" exist, insert NULL char. */
4419 pTemp = strcasestr(pSrc, "?size=");
4425 static bool __MsgIsPercentSign(char *pSrc)
4430 pCh = strchr(pSrc , '%');
4442 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam)
4444 char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
4445 char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
4446 char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
4449 /* remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445> */
4450 if (szStart && szStart[0]) {
4452 startLen = strlen(szStart);
4453 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
4454 strncpy(szTmpStart, &szStart[1], startLen - 2);
4456 strncpy(szTmpStart, szStart, startLen);
4460 /* remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445> */
4461 if (multipartType->szContentID[0]) {
4462 strLen = strlen(multipartType->szContentID);
4463 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
4464 strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
4466 strncpy(szTmpContentID, multipartType->szContentID, strLen);
4470 /* remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445> */
4471 if (multipartType->szContentLocation[0]) {
4472 strLen = strlen(multipartType->szContentLocation);
4473 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
4474 strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
4476 strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
4480 if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
4481 return MSG_PRESENTATION_NONE;
4483 /* exception handling */
4484 if (szTmpStart[0] != '\0') {
4485 /* presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type */
4486 if (strcmp(szTmpStart, szTmpContentID) == 0) {
4487 return MSG_PRESENTATION_ID;
4488 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
4489 return MSG_PRESENTATION_LOCATION;
4490 } else if (multipartType->type == typeParam) {
4491 return MSG_PRESENTATION_TYPE_BASE;
4493 return MSG_PRESENTATION_NONE;
4496 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
4497 return MSG_PRESENTATION_TYPE_BASE;
4499 return MSG_PRESENTATION_NONE;
4504 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
4507 MsgMultipart *pNextPart = NULL;
4508 MsgMultipart *pRemovePart = NULL;
4510 if (__MsgIsMultipartRelated(pMsgType->type)) {
4511 /* assign the multipart to presentation part */
4512 /* remove the multipart(pCurPresentation) which is presentation part from the linked list. */
4513 /* if there is no presentation part -> assign first multipart to presentation part by force. */
4514 if (pPresentationInfo->pCurPresentation == NULL) {
4515 pPresentationInfo->pCurPresentation = pMsgBody->body.pMultipart;
4516 pPresentationInfo->pPrevPart = NULL;
4517 pPresentationInfo->factor = MSG_PRESENTATION_NONE;
4520 if (pPresentationInfo->pCurPresentation != NULL && __MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
4521 /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
4522 * In this case, COPY the Presentation part and leave other multiparts.
4524 memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4525 pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
4527 /* remove pCurPresentation from multipart linked list */
4528 if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE) || (pPresentationInfo->pPrevPart == NULL)) {
4530 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
4531 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4532 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4533 if (pPresentationInfo->pCurPresentation) {
4534 MmsReleaseMsgDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
4536 free(pPresentationInfo->pCurPresentation);
4537 pPresentationInfo->pCurPresentation = NULL;
4540 /* not a first part */
4541 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
4542 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4543 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4544 if (pPresentationInfo->pCurPresentation) {
4545 free(pPresentationInfo->pCurPresentation);
4546 pPresentationInfo->pCurPresentation = NULL;
4549 } else if (pPresentationInfo->pCurPresentation != NULL && MmsIsTextType(pPresentationInfo->pCurPresentation->type.type)) {
4550 /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
4551 * In this case, leave the Presentation part as a multipart and remove other multiparts.
4554 /* Backup the multipart link information */
4555 pNextPart = pMsgBody->body.pMultipart;
4557 /* Copy presentation part as a main part */
4558 memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4559 memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
4561 /* Remove multipart linked list */
4563 pRemovePart = pNextPart;
4564 pNextPart = pNextPart->pNext;
4566 if (pRemovePart->pBody) {
4567 MmsReleaseMsgBody(pRemovePart->pBody, pRemovePart->type.type);
4568 free(pRemovePart->pBody);
4569 pRemovePart->pBody = NULL;
4576 MmsReleaseMsgDRMInfo(&pMsgBody->presentationType.drmInfo);
4578 MmsInitMsgType(&pMsgBody->presentationType);
4579 pMsgBody->pPresentationBody = NULL;
4585 static bool __MsgIsMultipartRelated(int type)
4587 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
4594 static bool __MsgIsPresentablePart(int type)
4596 if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
4603 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
4606 MsgMultipart *pTmpMultipart = NULL;
4607 MsgMultipart *pSelectedPart = NULL;
4608 MsgMultipart *pPrevPart = NULL;
4609 MsgMultipart *pFirstPart = NULL;
4610 MsgMultipart *pLastPart = NULL;
4611 MsgMultipart *pRemoveList = NULL;
4612 MsgMultipart *pNextRemovePart = NULL;
4614 switch (pPartType->type) {
4615 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
4616 case MIME_MULTIPART_ALTERNATIVE:
4619 * Policy: multipart/alternative
4620 * multipart/alternative message has only several parts of media.
4621 * You should choose one of them and make the alternative part
4622 * to the selected media part.
4625 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE");
4627 pSelectedPart = pPartBody->body.pMultipart;
4629 /* NULL Pointer check!! */
4630 if (pSelectedPart == NULL) {
4631 MSG_DEBUG("multipart(ALTERNATIVE) does not exist");
4635 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4637 while (pTmpMultipart) {
4638 if (pSelectedPart->type.type <= pTmpMultipart->type.type)
4639 pSelectedPart = pTmpMultipart;
4641 pTmpMultipart = pTmpMultipart->pNext;
4644 pTmpMultipart = pPartBody->body.pMultipart;
4647 while (pTmpMultipart) {
4648 if (pSelectedPart == pTmpMultipart)
4651 pPrevPart = pTmpMultipart;
4652 pTmpMultipart = pTmpMultipart->pNext;
4655 if (pPrevPart == NULL) {
4656 /* selected part is the first part */
4657 pRemoveList = pSelectedPart->pNext;
4659 pPrevPart->pNext = pSelectedPart->pNext;
4660 pRemoveList = pPartBody->body.pMultipart;
4661 pPartBody->body.pMultipart = pSelectedPart;
4664 pSelectedPart->pNext = NULL;
4667 MmsReleaseMsgDRMInfo(&pRemoveList->type.drmInfo);
4669 MmsReleaseMsgBody(pRemoveList->pBody, pRemoveList->type.type);
4671 free(pRemoveList->pBody);
4675 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4676 MSG_DEBUG("MsgPriorityCopyMsgType failed");
4680 if (pSelectedPart->pBody != NULL)
4681 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4683 if (pSelectedPart != NULL) {
4684 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4686 if (pSelectedPart->pBody != NULL) {
4687 free(pSelectedPart->pBody);
4688 pSelectedPart->pBody = NULL;
4690 free(pSelectedPart);
4691 pSelectedPart = NULL;
4696 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
4697 case MIME_MULTIPART_RELATED:
4699 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_RELATED");
4701 pSelectedPart = pPartBody->body.pMultipart;
4703 while (pSelectedPart) {
4704 if (__MsgIsMultipartMixed(pSelectedPart->type.type)) {
4705 if (pSelectedPart->pBody == NULL) {
4706 MSG_DEBUG("pSelectedPart->pBody(1) is NULL");
4710 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4712 if (pFirstPart == NULL) {
4713 MSG_DEBUG("multipart(RELATED) does not exist");
4717 if (pFirstPart->pNext) {
4718 pLastPart = pFirstPart->pNext;
4719 while (pLastPart->pNext)
4720 pLastPart = pLastPart->pNext;
4722 pLastPart = pFirstPart;
4725 if (pPrevPart == NULL) {
4726 /* the first part */
4727 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4728 pPartBody->body.pMultipart = pFirstPart;
4729 pLastPart->pNext = pTmpMultipart;
4731 pTmpMultipart = pSelectedPart->pNext;
4732 pPrevPart->pNext = pFirstPart;
4733 pLastPart->pNext = pTmpMultipart;
4736 if (pSelectedPart) {
4737 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4739 free(pSelectedPart->pBody);
4740 free(pSelectedPart);
4742 pSelectedPart = pTmpMultipart;
4743 } else if (__MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
4744 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
4745 MmsReleaseMsgBody(pSelectedPart->pBody, pSelectedPart->type.type);
4747 free(pSelectedPart->pBody);
4748 free(pSelectedPart);
4749 pSelectedPart = pTmpMultipart;
4751 pPrevPart = pSelectedPart;
4752 pSelectedPart = pSelectedPart->pNext;
4759 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
4760 case MIME_MULTIPART_MIXED:
4762 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_MIXED");
4765 pSelectedPart = pPartBody->body.pMultipart;
4767 while (pSelectedPart) {
4768 if (MsgIsMultipart(pSelectedPart->type.type)) {
4769 if (pSelectedPart->pBody == NULL) {
4770 MSG_DEBUG("pSelectedPart->pBody(2) is NULL");
4774 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4776 /* NULL Pointer check!! */
4777 if (pFirstPart == NULL) {
4778 MSG_DEBUG("multipart does not exist");
4782 if (pFirstPart->pNext) {
4783 pLastPart = pFirstPart->pNext;
4784 while (pLastPart->pNext)
4785 pLastPart = pLastPart->pNext;
4787 pLastPart = pFirstPart;
4790 if (pPrevPart == NULL) {
4791 /* the first part */
4792 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4793 pPartBody->body.pMultipart = pFirstPart;
4794 pLastPart->pNext = pTmpMultipart;
4796 pTmpMultipart = pSelectedPart->pNext;
4797 pPrevPart->pNext = pFirstPart;
4798 pLastPart->pNext = pTmpMultipart;
4801 if (pSelectedPart->pBody->pPresentationBody)
4802 pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
4804 memcpy(&pPartBody->presentationType,
4805 &pSelectedPart->pBody->presentationType, sizeof(MsgType));
4807 pPartType->type = pSelectedPart->type.type;
4809 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4811 free(pSelectedPart->pBody);
4812 free(pSelectedPart);
4814 pSelectedPart = pTmpMultipart;
4816 pPrevPart = pSelectedPart;
4817 pSelectedPart = pSelectedPart->pNext;
4823 case MIME_MULTIPART_REPORT:
4825 MSG_DEBUG("MIME_MULTIPART_REPORT");
4827 pTmpMultipart = pPartBody->body.pMultipart;
4830 if (pTmpMultipart == NULL) {
4831 MSG_DEBUG("pTmpMultipart == NULL");
4835 while (pTmpMultipart) {
4836 if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
4837 pSelectedPart = pTmpMultipart;
4841 pPrevPart = pTmpMultipart;
4842 pTmpMultipart = pTmpMultipart->pNext;
4845 if (pSelectedPart == NULL) {
4846 MSG_DEBUG("MIME_MULTIPART_REPORT [no selected part]");
4848 pRemoveList = pPartBody->body.pMultipart->pNext;
4849 if (pPartBody->body.pMultipart != NULL) {
4850 pSelectedPart = pPartBody->body.pMultipart;
4851 pSelectedPart->pNext = NULL;
4854 if (pPrevPart == NULL) {
4855 /* first part is selected */
4856 pRemoveList = pPartBody->body.pMultipart->pNext;
4858 pRemoveList = pPartBody->body.pMultipart->pNext;
4859 pPrevPart->pNext = pSelectedPart->pNext;
4862 pSelectedPart->pNext = NULL;
4863 pPartBody->body.pMultipart = pSelectedPart;
4866 pTmpMultipart = pRemoveList;
4868 while (pTmpMultipart) {
4869 MmsReleaseMsgDRMInfo(&pTmpMultipart->type.drmInfo);
4871 MmsReleaseMsgBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
4872 pNextRemovePart = pTmpMultipart->pNext;
4874 free(pTmpMultipart->pBody);
4875 free(pTmpMultipart);
4876 pTmpMultipart = pNextRemovePart;
4879 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4880 MSG_DEBUG("MsgPriorityCopyMsgType failed");
4884 if (pSelectedPart != NULL) {
4885 if (pSelectedPart->pBody != NULL)
4886 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4888 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4890 if (pSelectedPart->pBody != NULL) {
4891 free(pSelectedPart->pBody);
4892 pSelectedPart->pBody = NULL;
4894 free(pSelectedPart);
4895 pSelectedPart = NULL;
4911 char *MsgResolveContentURI(char *szSrc)
4913 char *szTemp = NULL;
4914 char *szReturn = NULL;
4917 if (szSrc == NULL) {
4921 if (szSrc[0] == '\0')
4925 if (!strncasecmp(szSrc, "cid:", 4)) {
4926 length = strlen(szSrc) - 3;
4929 length = strlen(szSrc) + 1;
4932 szTemp = (char *)calloc(1, length);
4933 if (szTemp == NULL) {
4934 MSG_DEBUG("memory full");
4938 memset(szTemp, 0, length);
4940 strncpy(szTemp, szSrc, length - 1);
4942 szReturn = MsgChangeHexString(szTemp);
4956 char *MsgRemoveQuoteFromFilename(char *pSrc)
4958 int cLen = 0; /* length of pBuff */
4962 MSG_DEBUG("pSrc is Null");
4966 cLen = strlen(pSrc);
4968 pBuff = (char *)calloc(1, cLen + 1);
4970 if (pBuff == NULL) {
4971 MSG_DEBUG("pBuff mem alloc fail!");
4974 memset(pBuff, 0 , sizeof(char)*(cLen + 1));
4976 /* remove front quote */
4977 if (pSrc[0] == MSG_CH_QUOT) {
4979 strncpy(pBuff, &pSrc[1], cLen);
4981 } else if (pSrc[0] == MSG_CH_LF) {
4983 strncpy(pBuff, &pSrc[1], cLen);
4985 strncpy(pBuff, pSrc, cLen);
4988 /* remove last qoute */
4989 if (pBuff[cLen-1] == MSG_CH_QUOT) {
4990 pBuff[cLen-1] = '\0';
4996 bool MsgIsMultipart(int type)
4998 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
4999 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
5000 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
5008 static bool __MsgIsHexChar(char *pSrc)
5014 cLen = strlen(pSrc);
5016 for (cIndex = 0; cIndex < cLen ; cIndex++) {
5017 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
5018 (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
5028 static char __MsgConvertHexValue(char *pSrc)
5034 unsigned char uCh[2] = {0, };
5036 cLen = strlen(pSrc);
5038 for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
5039 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
5040 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
5041 ch = (int)uCh[0] << 4 | uCh[1];
5044 ResultChar = (char)ch;
5049 static int __MsgConvertCharToInt(char ch)
5051 if (ch >= '0' && ch <= '9') {
5053 } else if (ch >= 'a' && ch <= 'f') {
5055 } else if (ch >= 'A' && ch <= 'F') {
5062 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
5064 if (!pMsgType1 || !pMsgType2)
5067 /* if (pMsgType1->section == INVALID_HOBJ) */
5068 pMsgType1->section = pMsgType2->section;
5072 if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
5073 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
5076 if (pMsgType1->szContentID[0] == '\0') {
5077 snprintf(pMsgType1->szContentID, sizeof(pMsgType1->szContentID), "%s", pMsgType2->szContentID);
5080 if (pMsgType1->szContentID[0] != '\0') {
5081 length = strlen(pMsgType1->szContentID);
5082 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
5083 char szTempString[MSG_MSG_ID_LEN + 1];
5084 MmsRemoveLessGreaterChar(pMsgType1->szContentID, szTempString, sizeof(szTempString));
5085 pMsgType1->drmInfo.szContentURI = g_strdup(szTempString);
5087 pMsgType1->drmInfo.szContentURI = g_strdup(pMsgType1->szContentID);
5091 if (pMsgType1->szContentLocation[0] == '\0') {
5092 strncpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation, MSG_MSG_ID_LEN);
5095 /* Copy informations - we shoud open the pMsgType2's orgFile
5096 * concerning its offset and size.
5098 if (pMsgType2->szOrgFilePath[0] != '\0') {
5099 strncpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath, MSG_FILEPATH_LEN_MAX-1);
5102 if (pMsgType2->disposition != -1)
5103 pMsgType1->disposition = pMsgType2->disposition;
5105 if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
5106 pMsgType2->encoding != -1)
5107 pMsgType1->encoding = pMsgType2->encoding;
5109 pMsgType1->contentSize = pMsgType2->contentSize;
5110 pMsgType1->offset = pMsgType2->offset;
5111 pMsgType1->size = pMsgType2->size;
5112 pMsgType1->type = pMsgType2->type;
5114 __MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
5116 if (pMsgType1->param.szName[0]) {
5117 pMsgType1->drmInfo.szContentName = g_strdup(pMsgType2->param.szName);
5123 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
5125 if (pParam1->charset == MSG_CHARSET_UNKNOWN)
5126 pParam1->charset = pParam2->charset;
5128 if (pParam1->type == MIME_UNKNOWN)
5129 pParam1->type = pParam2->type;
5131 /* Don't copy pParam2->pPresentation */
5133 /* For alternative: copy the boundary string */
5134 if (pParam2->szBoundary[0] !='\0') {
5135 strncpy(pParam1->szBoundary, pParam2->szBoundary, MSG_BOUNDARY_LEN);
5138 if (pParam1->szFileName[0] =='\0') {
5139 strncpy(pParam1->szFileName, pParam2->szFileName, MSG_FILENAME_LEN_MAX);
5142 if (pParam1->szName[0] =='\0') {
5143 strncpy(pParam1->szName, pParam2->szName, MSG_LOCALE_FILENAME_LEN_MAX);
5146 if (pParam1->szStart[0] =='\0') {
5147 strncpy(pParam1->szStart, pParam2->szStart, MSG_MSG_ID_LEN);
5150 if (pParam1->szStartInfo[0] =='\0') {
5151 strncpy(pParam1->szStartInfo, pParam2->szStartInfo, MSG_MSG_ID_LEN);
5156 static bool __MsgIsMultipartMixed(int type)
5158 if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
5165 static bool __MsgIsInvalidFileNameChar(char ch)
5167 if ((ch == 0x5C /* \ */) ||
5168 (ch == 0x2F /* / */) ||
5169 (ch == 0x3A /* : */) ||
5170 (ch == 0x2A /* * */) ||
5171 (ch == 0x3F /* ? */) ||
5172 (ch == 0x22 /* " */) ||
5173 (ch == 0x3C /* < */) ||
5174 (ch == 0x3E /* > */) ||
5175 (ch == 0x7C /* | */))
5181 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
5185 MSG_DEBUG("---------------");
5187 if ((szSrc == NULL) || (nChar <= 0)) {
5188 MSG_DEBUG("szSrc is NULL !!!! ---------------");
5192 while ((nChar > 0) && (*szSrc != '\0')) {
5193 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5207 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5210 unsigned char t1, t2;
5212 MSG_DEBUG("---------------");
5215 outBufSize--; /* NULL character */
5217 while ((nChar > 0) && (*szSrc != '\0')) {
5218 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5219 /* check outbuffer's room for this UTF8 character */
5224 *des = (unsigned char) (*szSrc & 0x007F);
5230 /* check outbuffer's room for this UTF8 character */
5236 t2 = (unsigned char) (*szSrc & 0x003F); /* right most 6 bit */
5237 t1 = (unsigned char) ((*szSrc & 0xC0) >> 6); /* right most 2 bit */
5239 *des = 0xC0 | (t1 & 0x1F);
5240 *(des + 1) = 0x80 | (t2 & 0x3F);
5254 bool MmsAddrUtilCheckEmailAddress(char *pszAddr)
5256 if (!pszAddr || pszAddr[0] == 0)
5259 if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
5265 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
5267 char *pszAddrCopy = NULL;
5268 char *pszStrStart = NULL;
5269 char *pszStrTemp = NULL;
5272 if ((!pszAddr) || (pszAddr[0] == 0)) {
5273 MSG_DEBUG("pszAddr is null or zero");
5277 strLen = strlen(pszAddr);
5279 pszAddrCopy = (char*)calloc(1, strLen + 1);
5281 MSG_DEBUG("pszAddrCopy is NULL, mem alloc failed");
5285 strncpy(pszAddrCopy, pszAddr, strLen);
5288 pszStrStart = pszAddrCopy;
5291 char* pszStrEnd = NULL;
5294 if (MmsAddrUtilCheckEmailAddress(pszAddrCopy))
5295 pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
5297 pszStrEnd = strstr(pszStrStart, "/");
5300 char *pszStart = NULL;
5301 char *pszEnd = NULL;
5302 /* "/TYPE=PLMN" not found */
5304 int remainedLen = strlen(pszStrStart);
5306 if (remainedLen <= 0)
5309 /* Email address can occur with Sender Name<email-address> format */
5310 /* remove the Sender name and only retain the email address. */
5311 pszStart = strstr(pszStrStart, "<");
5313 pszEnd = strstr(pszStrStart, ">");
5316 pszStart++; /* skip "<" */
5317 g_strlcat(pszAddr, pszStart, pszEnd - pszStart + 1);
5322 g_strlcat(pszAddr, pszStrStart, strLen + 1);
5326 /* Get one address length */
5327 addressLen = pszStrEnd - pszStrStart;
5329 strncat(pszAddr, pszStrStart, addressLen);
5331 /* Find next address */
5332 pszStrStart = pszStrEnd;
5334 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
5337 addressLen = pszStrTemp - pszStrEnd;
5338 pszStrStart += addressLen;
5340 pszStrStart += strlen(pszStrEnd);
5343 if (pszStrStart[0] == 0) /* end of string */
5347 g_strlcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER, strLen + 1); /* add ';' */
5348 pszStrStart++; /* remove ';' */
5351 if (pszAddr[0] == 0)
5352 strncpy(pszAddr, pszAddrCopy, strLen);
5359 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5363 MSG_DEBUG("---------------");
5366 outBufSize--; /* NULL character */
5368 while ((nChar > 0) && (*szSrc != '\0')) {
5369 if (*szSrc < 0x80) {
5377 } else if (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
5383 *(des + 1) = *(szSrc + 1);
5387 } else if ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
5393 *(des + 1) = *(szSrc + 1);
5394 *(des + 2) = *(szSrc + 2);
5406 MSG_DEBUG("utf8 incorrect range!");
5418 static void __MsgMIMERemoveQuote(char *szSrc)
5422 length = strlen(szSrc);
5423 if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
5426 for (index = 0; index < length-2; index++)
5427 szSrc[index] = szSrc[index+1];
5428 szSrc[index] = '\0';
5432 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
5438 if (pFile == NULL) {
5445 if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
5452 if (*pBufLen == 0) {
5453 length = maxLen - (*pPtr);
5455 length = (*pBufLen) - (*pPtr);
5461 if ((*ppBuf) == NULL) {
5462 memset(pInBuf1, 0, maxLen);
5464 } else if ((*ppBuf) == pInBuf1) {
5465 memset(pInBuf2, 0, maxLen);
5467 memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
5470 memset(pInBuf1, 0, maxLen);
5472 memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
5478 if (*pOffset == endOfFile) {
5483 if (maxLen == length) {
5485 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
5490 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
5493 *pBufLen = length + nRead;
5496 if ((*pOffset = MsgFtell(pFile)) == -1L) {
5497 MSG_DEBUG("MsgFtell Error");
5507 * This function write media data from raw data to file.
5510 * @param pszMailboxPath : path of mailbox
5511 * @param pszMsgFilename : name of msg file
5512 * @param index : used for file naming
5513 * @param bSave : if true, file will be save otherwise just filename will be stored.
5515 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
5518 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, }; /* file name of temp file */
5519 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; /* full absolute path of temp file. */
5520 bool bFileExist = false;
5524 MSG_DEBUG("pPartType is NULL");
5528 if (pPartType->type == MIME_APPLICATION_SMIL) {
5529 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", "smil.txt");
5531 if (pPartType->param.szName[0] != '\0') {
5532 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szName);
5533 } else if (pPartType->param.szFileName[0] != '\0') {
5534 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szFileName);
5535 } else if (pPartType->szContentLocation[0] != '\0') {
5536 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->szContentLocation);
5538 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
5542 /* make full path for save */
5543 __MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0, szFileName, sizeof(szFileName)); /* FL & CD -> extension(.dm) SD -> extension(.dcf) */
5545 snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName); /* get absolute path of each temp file of each part */
5547 if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
5548 MsgGetMimeTypeFromFileName(MIME_MAINTYPE_UNKNOWN, szFullPath, (MimeType *)&pPartType->type, NULL);
5551 bFileExist = MsgAccessFile(szFullPath, F_OK);
5553 MSG_SEC_DEBUG("save flag [%d], filepath [%s], file exist [%d]", bSave, szFullPath, bFileExist);
5555 if (bSave == true && bFileExist == false) {
5556 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
5557 MSG_DEBUG("MsgOpenFile failed");
5561 if (__MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
5562 MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
5566 MsgCloseFile(pFile);
5569 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5571 /* IF DRM type Convert to dcf */
5572 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5573 || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT) {
5574 char destDrmPath[MSG_FILEPATH_LEN_MAX] = {0, };
5576 if (MsgDrmConvertDmtoDcfType(pPartBody->szOrgFilePath, destDrmPath) == true) {
5577 MSG_INFO("Success Convert to Dcf");
5579 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5582 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5583 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5587 MSG_INFO("Fail Convert to Dcf");
5590 if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5591 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5593 MSG_SEC_INFO("Drm File Path [%s] isdrm [%d]", pPartBody->szOrgFilePath, MsgDrmIsDrmFile(pPartBody->szOrgFilePath));
5596 pPartBody->offset = 0;
5597 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5599 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
5600 MsgDrmRegisterFile(MSG_MODE_FILE, pPartBody->szOrgFilePath, strlen(pPartBody->szOrgFilePath));
5602 /* change szDrm2FullPath as current content path*/
5603 if (pPartType->drmInfo.szDrm2FullPath) {
5604 free(pPartType->drmInfo.szDrm2FullPath);
5605 pPartType->drmInfo.szDrm2FullPath = g_strdup(pPartBody->szOrgFilePath);
5609 MSG_SEC_DEBUG("Save Part File to [%s]", pPartBody->szOrgFilePath);
5612 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5614 /* IF DRM type check dcf exist */
5615 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5616 || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT) {
5617 char destDrmPath[MSG_FILEPATH_LEN_MAX + 1] = {0, };
5619 MsgGetFileNameWithoutExtension(destDrmPath, pPartBody->szOrgFilePath);
5620 g_strlcat(destDrmPath, ".dcf", 5);
5622 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5625 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5626 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5629 if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5630 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5633 pPartBody->offset = 0;
5634 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5636 MSG_SEC_DEBUG("Set Part File to [%s]", pPartBody->szOrgFilePath);
5640 if (szFileName[0] != '\0') {
5641 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. */
5642 snprintf(pPartType->param.szName, MSG_LOCALE_FILENAME_LEN_MAX+1, "%s", szFileName);
5643 MSG_SEC_DEBUG("Set Name : %s", pPartType->param.szName);
5651 if (pFile != NULL) {
5652 MsgCloseFile(pFile);
5659 bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
5664 char *pNewData = NULL;
5665 char *pTempData = NULL;
5666 int msgEncodingValue = 0;
5667 int msgTypeValue = 0;
5668 int msgCharsetValue = 0;
5673 msgEncodingValue = pPartType->encoding;
5674 msgTypeValue = pPartType->type;
5675 msgCharsetValue = pPartType->param.charset;
5677 offset = pPartBody->offset;
5678 size = pPartBody->size;
5680 if (pPartBody->szOrgFilePath[0]) {
5681 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
5683 if (pTempData == NULL) {
5684 MSG_DEBUG("pTempData read fail");
5689 } else if (pPartBody->body.pText) {
5690 pData = pPartBody->body.pText;
5691 nRead = pPartBody->size;
5694 if (pData == NULL) {
5695 MSG_DEBUG("there is no data");
5699 pNewData = __MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
5702 pPartType->encoding = MSG_ENCODING_BINARY;
5704 if (MmsIsTextType(msgTypeValue))
5705 pPartType->param.charset = MSG_CHARSET_UTF8;
5707 if (MsgWriteFile(pNewData, sizeof(char), nRead2, pFile) != (size_t)nRead2) {
5708 MSG_DEBUG("file writing fail");
5713 if (MsgWriteFile(pData, sizeof(char), nRead, pFile) != (size_t)nRead) {
5714 MSG_DEBUG("file writing fail");
5748 char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
5754 char *pConvertedStr = NULL;
5755 char *pConvertedData = NULL;
5756 char *pNewData = NULL;
5757 char *pReturnData = NULL;
5759 const char *pToCodeSet = "UTF-8";
5760 const char *pFromCodeSet = NULL;
5762 switch (msgEncodingValue) {
5763 case MSG_ENCODING_BASE64:
5765 pConvertedData = (char*)MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5766 MSG_DEBUG("MSG_ENCODING_BASE64 bodyLength [%d]", nByte);
5768 pTemp = pConvertedData;
5773 case MSG_ENCODING_QUOTE_PRINTABLE:
5775 pConvertedData = (char*)MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5776 MSG_DEBUG("MSG_ENCODING_QUOTE_PRINTABLE bodyLength [%d]", nByte);
5778 pTemp = pConvertedData;
5785 MSG_DEBUG("encoding val [%d] bodyLength [%d]", msgEncodingValue, nRead);
5792 if (MmsIsTextType(msgTypeValue)) {
5793 if (msgCharsetValue == MSG_CHARSET_US_ASCII) {
5796 } else if (msgCharsetValue == MSG_CHARSET_UTF8) {
5797 /* skip BOM(Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM) */
5799 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
5808 UINT16 MIBenum = MmsGetBinaryValue(MmsCodeCharSet, msgCharsetValue);
5810 pFromCodeSet = MmsGetTextByCode(MmsCodeCharSet, MIBenum);
5812 MSG_DEBUG("char set enum = [%d], MIBenum = [%d], str = [%s]", msgCharsetValue, MIBenum, pFromCodeSet);
5815 MSG_DEBUG("Convert to UTF-8");
5817 if (MmsPluginTextConvert(pToCodeSet, pFromCodeSet, pTemp, nTemp, &pConvertedStr, npRead) == true) {
5818 pNewData = pConvertedStr;
5820 MSG_DEBUG("Failed MmsPluginTextConvert");
5825 } else { /* unsupported charset */
5826 MSG_DEBUG("unsupported charset");
5837 pReturnData = (char *)calloc(1, *npRead);
5838 if (pReturnData == NULL) {
5839 MSG_DEBUG("pReturnData alloc fail.");
5843 if (pNewData != NULL) {
5844 memset(pReturnData, 0, *npRead);
5845 memcpy(pReturnData, pNewData, *npRead);
5848 if (pConvertedData) {
5849 free(pConvertedData);
5850 pConvertedData = NULL;
5853 if (pConvertedStr) {
5854 free(pConvertedStr);
5855 pConvertedStr = NULL;
5862 if (pConvertedData) {
5863 free(pConvertedData);
5864 pConvertedData = NULL;
5867 if (pConvertedStr) {
5868 free(pConvertedStr);
5869 pConvertedStr = NULL;
5875 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen)
5877 char szTemp[MSG_FILENAME_LEN_MAX+1] = {0, };
5878 char szTempFileName[MSG_FILENAME_LEN_MAX+1] = {0, };
5879 const char *pExt = NULL;
5881 MSG_SEC_DEBUG("Input : type [0x%x], drmType [%d], filename [%s]", iMsgType, drmType, szFileName);
5883 if (szFileName == NULL)
5887 int inp_len = strlen(szFileName);
5889 pExt = strrchr(szFileName, '.');
5891 if (pExt != NULL && *(pExt + 1) != '\0') {
5897 MsgGetFileNameWithoutExtension(szTempFileName, szFileName);
5899 if (nUntitleIndex >= 1) {
5900 snprintf(szTempFileName, sizeof(szTempFileName), "%s_%d", "untitled", nUntitleIndex);
5902 snprintf(szTempFileName, sizeof(szTempFileName), "%s", "untitled");
5907 if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_MESSAGE)
5909 else if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5912 if (pExt == NULL) { /* find ext from content type */
5913 if (iMsgType == MIME_APPLICATION_OCTET_STREAM || iMsgType == MIME_UNKNOWN) {
5914 MSG_DEBUG("unsupported MsgType [%d]", iMsgType);
5918 pExt = MimeGetExtFromMimeInt((MimeType)iMsgType);
5921 /* Filename + extension */
5923 snprintf(szTemp, sizeof(szTemp), "%s.%s", szTempFileName, pExt);
5925 MSG_DEBUG("Failed to get extension of that mime data file.");
5929 snprintf(outBuf, outBufLen, "%s", szTemp);
5930 MSG_SEC_DEBUG("Result : filename [%s]", outBuf);
5937 bool MsgGetFileNameWithoutExtension(char *szOutputName, char *szName)
5939 char *pszExt = NULL;
5941 if (szOutputName == NULL) {
5942 MSG_DEBUG("szOutputName is NULL");
5946 strncpy(szOutputName, szName, strlen(szName));
5947 szOutputName[strlen(szName)] = '\0';
5949 if ((pszExt = strrchr(szOutputName, '.'))) {
5950 if (pszExt[0] == '.')
5957 bool MsgGetFileName(char *szFilePath, char *szFileName, int size)
5959 char *filename = NULL;
5961 filename = strrchr(szFilePath, '/');
5962 if (filename != NULL) {
5963 snprintf(szFileName, size, "%s", filename + 1);
5965 snprintf(szFileName, size, "%s", szFilePath);
5974 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
5976 MmsMsg *pMsg = NULL;
5977 MsgMultipart *pPart = NULL;
5979 if (pHeader == NULL) {
5980 MSG_DEBUG("Invalid pHeader input. It's null");
5984 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
5986 MmsInitMsgType(pHeader);
5989 /* Requires header of non-presentation */
5990 if (MsgIsMultipart(pMsg->msgType.type)) {
5991 MSG_DEBUG("Multipart header [index = %d] \n", index);
5993 pPart = pMsg->msgBody.body.pMultipart;
5995 while (pPart && index--)
5996 pPart = pPart->pNext;
5998 if (pPart == NULL) {
5999 MSG_DEBUG("There is no such msg part.");
6003 memcpy(pHeader, &pPart->type, sizeof(MsgType));
6005 MSG_DEBUG("Requires singlepart header");
6006 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
6013 MmsPluginDecoder *MmsPluginDecoder::pInstance = NULL;
6015 MmsPluginDecoder *MmsPluginDecoder::instance()
6017 if (!MmsPluginDecoder::pInstance)
6018 MmsPluginDecoder::pInstance = new MmsPluginDecoder();
6020 return MmsPluginDecoder::pInstance;
6023 MmsPluginDecoder::MmsPluginDecoder() {}
6024 MmsPluginDecoder::~MmsPluginDecoder() {}
6026 void MmsPluginDecoder::decodeMmsPdu(MmsMsg *pMsg, msg_message_id_t msgID, const char *pduFilePath)
6031 MsgMultipart *pMultipart = NULL;
6033 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6034 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
6038 pMsg->msgID = msgID;
6040 snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6042 MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName));
6044 if (MsgGetFileSize(szFullPath, &nSize) == false) {
6045 MSG_FATAL("Fail MsgGetFileSize");
6049 pFile = MsgOpenFile(szFullPath, "rb");
6050 if (pFile == NULL) {
6051 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6055 MmsRegisterDecodeBuffer();
6057 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6058 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6062 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6063 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6067 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
6069 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
6070 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
6072 { /* attribute convert mmsHeader -> mmsAttribute */
6073 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
6075 pMsg->mmsAttrib.date = mmsHeader.date;
6077 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6078 pMsg->mmsAttrib.bAskDeliveryReport = true;
6081 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6083 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6085 MSG_DEBUG("@@@@@pMsg->mmsAttrib.deliveryTime=[%d]", pMsg->mmsAttrib.deliveryTime);
6087 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
6089 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
6091 pMsg->mmsAttrib.msgType = mmsHeader.type;
6093 pMsg->mmsAttrib.version = mmsHeader.version;
6095 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
6097 pMsg->mmsAttrib.priority = mmsHeader.priority;
6099 if (mmsHeader.readReply == MMS_REPORT_YES) {
6100 pMsg->mmsAttrib.bAskReadReply = true;
6103 /* TODO : fill pMsg->mmsAttrib.szCc and pMsg->mmsAttrib.szTo field */
6105 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
6107 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
6109 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
6111 /* FIXME:: mmsHeader will release after delete global mmsHeader */
6112 /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
6114 if (pMsg->msgBody.pPresentationBody) {
6115 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
6118 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
6119 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
6122 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
6125 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
6130 MsgCloseFile(pFile);
6133 pMsg->nPartCount = 0;
6135 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
6136 pMultipart = pMsg->msgBody.body.pMultipart;
6137 while (pMultipart) {
6139 pMultipart = pMultipart->pNext;
6142 if (pMsg->msgBody.size > 0)
6146 /* make temporary */
6147 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
6149 if (MsgIsMultipart(pMsg->msgType.type) == true) {
6151 pMultipart = pMsg->msgBody.body.pMultipart;
6153 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6154 if (errno == EEXIST) {
6155 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
6157 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6161 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
6164 if (pMsg->msgBody.pPresentationBody) {
6165 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
6166 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6170 while (pMultipart) {
6171 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
6172 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, true) == false)
6175 MmsPrintMulitpart(pMultipart, partIndex);
6177 pMultipart = pMultipart->pNext;
6181 } else { /* single part */
6182 if (pMsg->nPartCount > 0) {
6183 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6184 if (errno == EEXIST) {
6185 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
6187 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6191 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
6194 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
6195 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6199 MSG_DEBUG("### Success ###");
6206 MmsUnregisterDecodeBuffer();
6208 if (pFile != NULL) {
6209 MsgCloseFile(pFile);
6214 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
6216 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
6218 MSG_DEBUG("### Fail ###");
6223 /* CID 41989: Removed function decodeMmsPdu which is unused. */
6225 void MmsPluginDecoder::decodeMmsPdu(MMS_DATA_S *pMmsData, const char *pduFilePath)
6230 MsgMultipart * iter_multipart = NULL;
6232 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6236 /* pMsg->msgID = msgID; */
6238 snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6240 /* MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName)); */
6242 if (MsgGetFileSize(szFullPath, &nSize) == false) {
6243 MSG_FATAL("Fail MsgGetFileSize");
6247 pFile = MsgOpenFile(szFullPath, "rb");
6248 if (pFile == NULL) {
6249 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6253 MmsRegisterDecodeBuffer();
6255 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6256 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6260 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6261 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6266 if (pMmsData->header == NULL) {
6267 pMmsData->header = MsgMmsCreateHeader();
6270 pMmsData->header->messageType = mmsHeader.type;
6272 pMmsData->header->mmsVersion = mmsHeader.version;
6274 pMmsData->header->contentType = mmsHeader.msgType.type;
6276 pMmsData->header->date = mmsHeader.date;
6278 pMmsData->header->messageSize = mmsHeader.msgSize;
6280 pMmsData->header->mmsPriority = mmsHeader.priority;
6282 pMmsData->header->messageClass = mmsHeader.msgClass;
6284 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6285 pMmsData->header->bDeliveryReport = true;
6288 if (mmsHeader.readReply == MMS_REPORT_YES) {
6289 pMmsData->header->bReadReport = true;
6292 memcpy(&pMmsData->header->delivery, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6294 memcpy(&pMmsData->header->expiry, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6297 snprintf(pMmsData->header->messageID, sizeof(pMmsData->header->messageID), "%s", mmsHeader.szMsgID);
6299 snprintf(pMmsData->header->szSubject, sizeof(pMmsData->header->szSubject), "%s", mmsHeader.szSubject);
6301 snprintf(pMmsData->header->trID, sizeof(pMmsData->header->trID), "%s", mmsHeader.szTrID);
6303 iter_multipart = mmsHeader.msgBody.body.pMultipart;
6306 if (pMmsData->header->contentType == MIME_MULTIPART_RELATED || pMmsData->header->contentType == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
6307 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6309 pMultipart->type = MIME_APPLICATION_SMIL;
6310 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s", "application/smil");
6311 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", mmsHeader.msgBody.presentationType.szContentID);
6312 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", mmsHeader.msgBody.presentationType.szContentLocation);
6313 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", mmsHeader.msgBody.presentationType.param.szName);
6315 /* snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), MSG_DATA_PATH"%s", mmsHeader.msgBody.presentationType.param.szFileName); */
6317 MsgBody *pBody = iter_multipart->pBody;
6318 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6320 pMmsData->smil = pMultipart;
6324 while (iter_multipart) {
6325 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6327 pMultipart->type = (MimeType)iter_multipart->type.type;
6329 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s", MimeGetMimeStringFromMimeInt(iter_multipart->type.type));
6330 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", iter_multipart->type.szContentID);
6331 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", iter_multipart->type.szContentLocation);
6332 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", iter_multipart->type.param.szName);
6334 /* snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), "%s", iter_multipart->pBody->szOrgFilePath); */
6336 MsgBody *pBody = iter_multipart->pBody;
6337 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6340 #ifdef __SUPPORT_DRM__
6341 if (iter_multipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
6342 pMultipart->drmType = iter_multipart->type.drmInfo.drmType;
6346 pMmsData->multipartlist = g_list_append(pMmsData->multipartlist, pMultipart);
6347 iter_multipart = iter_multipart->pNext;
6351 MSG_DEBUG("### SUCCESS ###");
6357 MmsUnregisterDecodeBuffer();
6359 if (pFile != NULL) {
6360 MsgCloseFile(pFile);
6364 MSG_DEBUG("### Fail ###");