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.
23 #include "MsgUtilFile.h"
24 #include "MsgUtilMime.h"
26 #include "MsgMmsMessage.h"
28 #include "MmsPluginDebug.h"
29 #include "MmsPluginDecode.h"
30 #include "MmsPluginCodecCommon.h"
31 #include "MmsPluginStorage.h"
32 #include "MmsPluginDebug.h"
33 #include "MmsPluginTextConvert.h"
34 #include "MmsPluginUtil.h"
36 #include "MmsPluginDrm.h"
37 #include "MsgDrmWrapper.h"
40 static int __MmsGetDecodeOffset(void);
41 static bool __MmsDecodeInitialize(void);
42 static void __MmsCleanDecodeBuff(void);
43 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength);
44 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength);
46 static bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength); /* bufLen < gMmsDecodeMaxLen */
47 static bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength); /* no bufLen limit */
48 static bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength);
50 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength);
52 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength);
53 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength);
54 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength);
55 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength);
56 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength);
57 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength);
58 static char *__MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength);
59 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
60 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
62 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength);
63 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength);
64 static MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength);
66 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
67 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
68 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength);
69 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength);
70 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength);
71 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength);
73 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength);
77 static void __MsgRemoveFilePath(char *pSrc);
78 static bool __MsgChangeSpace(char *pOrg, char **ppNew);
79 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo);
80 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam);
81 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *npRead, int endOfFile);
82 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr);
83 static bool __MsgCheckFileNameHasInvalidChar(char *szName);
85 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar);
86 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter);
87 static bool __MsgParseParameter(MsgType *pType, char *pSrc);
88 static char *__MsgSkipWS(char *s);
89 static char *__MsgSkipComment(char *s, long trim);
91 static char *__MsgConvertLatin2UTF8FileName(char *pSrc);
93 /* static bool __MsgIsPercentSign(char *pSrc); */
94 static bool __MsgIsMultipartRelated(int type);
95 static bool __MsgIsPresentablePart(int type);
96 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody);
97 static bool __MsgIsHexChar(char *pSrc);
98 static char __MsgConvertHexValue(char *pSrc);
99 static int __MsgConvertCharToInt(char ch);
100 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2);
101 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2);
102 static bool __MsgIsMultipartMixed(int type);
104 static bool __MsgIsInvalidFileNameChar(char ch);
106 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar);
107 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
108 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
109 static void __MsgMIMERemoveQuote(char *szSrc);
110 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave);
112 static bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE *pFile);
113 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead);
115 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen);
118 __thread char gszMmsLoadBuf1[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
119 __thread char gszMmsLoadBuf2[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
121 __thread char *gpCurMmsDecodeBuff = NULL;
122 __thread int gCurMmsDecodeBuffPos = 0; /* next decoding position in gpCurMmsDecodeBuff */
123 __thread int gMmsDecodeMaxLen = 0;
124 __thread int gMmsDecodeCurOffset = 0; /* current offset in file (last read) */
125 __thread int gMmsDecodeBufLen = 0; /* number of last read characters */
127 __thread char *gpMmsDecodeBuf1 = NULL;
128 __thread char *gpMmsDecodeBuf2 = NULL;
130 __thread MmsHeader mmsHeader =
132 (MmsMsgType)MMS_MSGTYPE_ERROR, /* MmsMsgType iType; */
133 "", /* char[] szTrID; */
134 0, /* short int version; */
135 0, /* UINT32 date; */
137 NULL, /* MsgHeaderAddress* pFrom; */
138 NULL, /* MsgHeaderAddress* pTo; */
139 NULL, /* MsgHeaderAddress* pCc; */
140 NULL, /* MsgHeaderAddress* pBcc; */
141 "", /* char[] szSubject; */
142 (MmsResponseStatus)MMS_RESPSTATUS_OK, /* MmsResponseStatus iResponseStatus; */
143 (MmsRetrieveStatus)MMS_RETRSTATUS_OK, /* MmsRetrieveStatus iRetrieveStatus; */
144 "", /* char[] szResponseText; */
145 "", /* char[] szRetrieveText; */
148 /* has default value in specification */
150 (MmsMsgClass)MMS_MSGCLASS_PERSONAL, /* MmsMsgClass msgClass; */
151 {MMS_TIMETYPE_RELATIVE, 0}, /* MmsTimeStruct expiryTime; */
152 {MMS_TIMETYPE_RELATIVE, 0}, /* MmsTimeStruct deliveryTime; */
153 (MmsPriority)MMS_PRIORITY_NORMAL, /* MmsPriority priority; */ /* Refer [OMA-MMS-ENC-v1_2-20030915-C] */
154 (MmsSenderVisible)MMS_SENDER_SHOW, /* MmsSenderVisible senderVisible; */
155 (MmsReport)MMS_REPORT_NO, /* MmsReport deliveryReport; */
156 (MmsReport)MMS_REPORT_NO, /* MmsReport readReply; */
157 (MmsReportAllowed)MMS_REPORTALLOWED_NO, /* MmsReportAllowed iReportAllowed; */
158 "", /* char[] szContentLocation; */
161 /* there is no right default value */
163 (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE, /* MmsMsgStatus iMsgStatus; */
164 (msg_read_report_status_t)MSG_READ_REPORT_NONE, /* MmsReadStatus readStatus; */
166 /* MMS v1.1 ReplyCharge */
168 (MmsReplyChargeType)MMS_REPLY_NONE, /* MmsReplyChargeType chargeType; */
169 {MMS_TIMETYPE_RELATIVE, 0}, /* MmsTimeStruct deadLine; */
170 0, /* int chargeSize; */
171 "" , /* char szChargeID; */
174 "", /* char[] szMsgID; */
175 0, /* UINT32 msgSize; */
178 #define MMS_DRM2_CONVERT_BUFFER_MAX 4*1024
179 const UINT32 MMS_UINTVAR_LENGTH_1 = 0x0000007f; /* 7bit */
180 const UINT32 MMS_UINTVAR_LENGTH_2 = 0x00003fff; /* 14bit */
181 const UINT32 MMS_UINTVAR_LENGTH_3 = 0x001fffff; /* 21bit */
183 static bool __MmsDecodeInitialize(void)
185 MmsInitMsgType(&mmsHeader.msgType);
186 MmsInitMsgBody(&mmsHeader.msgBody);
192 mmsHeader.type = MMS_MSGTYPE_ERROR;
194 memset(mmsHeader.szTrID, 0, MMS_TR_ID_LEN + 1);
195 mmsHeader.version = MMS_VERSION;
198 __MsgFreeHeaderAddress(mmsHeader.pFrom);
199 __MsgFreeHeaderAddress(mmsHeader.pTo);
200 __MsgFreeHeaderAddress(mmsHeader.pCc);
201 __MsgFreeHeaderAddress(mmsHeader.pBcc);
203 mmsHeader.pFrom = NULL;
204 mmsHeader.pTo = NULL;
205 mmsHeader.pCc = NULL;
206 mmsHeader.pBcc = NULL;
208 memset(mmsHeader.szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
210 mmsHeader.responseStatus = (MmsResponseStatus)MMS_RESPSTATUS_OK;
211 mmsHeader.retrieveStatus = (MmsRetrieveStatus)MMS_RETRSTATUS_OK;
212 memset(mmsHeader.szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
213 memset(mmsHeader.szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
216 mmsHeader.msgClass = (MmsMsgClass)MMS_MSGCLASS_PERSONAL;
217 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
218 mmsHeader.expiryTime.time = 0;
219 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
220 mmsHeader.deliveryTime.time = 0;
221 mmsHeader.priority = (MmsPriority)MMS_PRIORITY_NORMAL; /* Refer [OMA-MMS-ENC-v1_2-20030915-C] */
222 mmsHeader.hideAddress =(MmsSenderVisible)MMS_SENDER_SHOW;
223 mmsHeader.deliveryReport = (MmsReport)MMS_REPORT_NO;
224 mmsHeader.readReply = (MmsReport)MMS_REPORT_NO;
225 mmsHeader.reportAllowed = (MmsReportAllowed)MMS_REPORTALLOWED_YES;
226 memset(mmsHeader.szContentLocation, 0, MMS_LOCATION_LEN + 1);
229 mmsHeader.msgStatus = (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE;
230 mmsHeader.readStatus = (msg_read_report_status_t)MSG_READ_REPORT_NONE;
232 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MMS_REPLY_NONE;
233 mmsHeader.replyCharge.chargeSize = 0;
234 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
235 mmsHeader.replyCharge.deadLine.time = 0;
236 memset(mmsHeader.replyCharge.szChargeID, 0, MMS_MSG_ID_LEN + 1);
239 memset(mmsHeader.szMsgID, 0, MMS_MSG_ID_LEN + 1);
240 mmsHeader.msgSize = 0;
241 mmsHeader.drmType = MSG_DRM_TYPE_NONE;
243 __MmsDecodeInitialize();
246 void MmsReleaseHeader(MmsHeader *mms)
248 __MsgFreeHeaderAddress(mms->pFrom);
249 __MsgFreeHeaderAddress(mms->pTo);
250 __MsgFreeHeaderAddress(mms->pCc);
251 __MsgFreeHeaderAddress(mms->pBcc);
253 mmsHeader.pFrom = NULL;
254 mmsHeader.pTo = NULL;
255 mmsHeader.pCc = NULL;
256 mmsHeader.pBcc = NULL;
259 static void __MmsCleanDecodeBuff(void)
261 memset(gpMmsDecodeBuf1, 0, gMmsDecodeMaxLen + 1);
262 memset(gpMmsDecodeBuf2, 0, gMmsDecodeMaxLen + 1);
263 gpCurMmsDecodeBuff = NULL;
264 gCurMmsDecodeBuffPos = 0;
265 gMmsDecodeBufLen = 0;
268 void MmsRegisterDecodeBuffer()
270 gpMmsDecodeBuf1 = gszMmsLoadBuf1;
271 gpMmsDecodeBuf2 = gszMmsLoadBuf2;
272 gpCurMmsDecodeBuff = NULL;
273 gCurMmsDecodeBuffPos = 0;
274 gMmsDecodeMaxLen = MSG_MMS_DECODE_BUFFER_MAX;
275 gMmsDecodeCurOffset = 0;
276 gMmsDecodeBufLen = 0;
279 void MmsUnregisterDecodeBuffer(void)
281 gpMmsDecodeBuf1 = NULL;
282 gpMmsDecodeBuf2 = NULL;
283 gpCurMmsDecodeBuff = NULL;
284 gCurMmsDecodeBuffPos = 0;
285 gMmsDecodeMaxLen = 0;
286 gMmsDecodeCurOffset = 0;
287 gMmsDecodeBufLen = 0;
291 static int __MmsGetDecodeOffset(void)
293 return (gMmsDecodeCurOffset - gMmsDecodeBufLen + gCurMmsDecodeBuffPos);
296 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength)
298 if (*pLength <= valueLength) {
299 gCurMmsDecodeBuffPos -= valueLength;
300 gCurMmsDecodeBuffPos += *pLength;
304 *pLength -= valueLength;
310 /* ==========================================================
312 B I N A R Y D E C O D I N G
314 ==========================================================*/
317 * Binary Encoded Message Format
319 * < Single Part Body Message >
320 * -----------------------------------
322 * -----------------------------------
323 * | Content Type:start=xxx;type=xxx | ->(ex) Text/Plain, Text/Html, ....
324 * -----------------------------------
325 * | Single Part Body |
326 * -----------------------------------
328 * < Multi Part Body Message >
329 * -----------------------------------
331 * -----------------------------------
332 * | Content Type:start=xxx;type=xxx | -> (ex) Application/vnd.wap.multipart.mixed(related), multipart/mixed(related)
333 * -----------------------------------
334 * | # of Entries (body parts) |
335 * ----------------------------------- < Each Entry >
336 * | Entry 1 | -> -----------------------------
337 * ----------------------------------- | header Length |
338 * | Entry 2 | -----------------------------
339 * ----------------------------------- | Data Length |
340 * | ...... | ----------------------------- -
341 * ----------------------------------- | Content-Type | |
342 * | Entry n | ----------------------------- | Header Length
343 * ----------------------------------- | Header | |
344 * ----------------------------- -
345 * | Data | | Data Length
346 * ----------------------------- -
348 bool MmsBinaryDecodeMsgHeader(FILE *pFile, int totalLength)
351 UINT16 fieldCode = 0xffff;
352 UINT16 fieldValue = 0xffff;
353 UINT8 oneByte = 0xff;
355 MsgHeaderAddress *pAddr = NULL;
356 MsgHeaderAddress *pLastTo = NULL;
357 MsgHeaderAddress *pLastCc = NULL;
358 MsgHeaderAddress *pLastBcc = NULL;
360 UINT32 valueLength = 0;
361 UINT32 tmpInteger = 0;
366 char szGarbageBuff[MSG_STDSTR_LONG] = {0, };
367 char *pLimitData = NULL;
370 MSG_DEBUG("pFile ptr : [%p], total len = [%d]", pFile, totalLength);
372 __MmsCleanDecodeBuff();
374 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
375 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
376 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
377 MSG_FATAL("fail to load to buffer");
381 while (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength)) {
382 fieldCode = oneByte & 0x7f;
384 switch (MmsGetBinaryType(MmsCodeFieldCode, fieldCode)) {
385 case MMS_CODE_RESPONSESTATUS: {
386 MmsResponseStatus resposeStatus = MMS_RESPSTATUS_ERROR;
388 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
389 MSG_DEBUG("responseStatus GetOneByte fail");
393 fieldValue = oneByte;
395 /* range 197 to 223 as it does to the value 192 (Error-transient-failure). */
396 /* range 236 to 255 as it does to the value 224 (Error-permanent-failure). */
397 if (fieldValue >= 197 && fieldValue <= 223) {
399 } else if (fieldValue >= 236 && fieldValue <= 255) {
403 resposeStatus = (MmsResponseStatus)MmsGetBinaryType(MmsCodeResponseStatus, (UINT16)(fieldValue & 0x7F));
405 mmsHeader.responseStatus = (MmsResponseStatus)resposeStatus;
407 MSG_SEC_INFO("X-Mms-Response-Status = [0x%02x][0x%02x][%s]", oneByte, fieldValue, MmsDebugGetResponseStatus(mmsHeader.responseStatus));
410 case MMS_CODE_RETRIEVESTATUS: {
411 MmsRetrieveStatus RetrieveStatus = MMS_RETRSTATUS_ERROR;
413 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
414 MSG_DEBUG("retrieveStatus GetOneByte fail");
418 fieldValue = oneByte;
420 /* 195 to 223 as it does to the value 192 (Error-transient-failure). */
421 /* 228 to 255 as it does to the value 224 (Error-permanent-failure). */
422 if (fieldValue >= 195 && fieldValue <= 223) {
423 fieldValue = 192; /* 192; Error-transient-failure */
424 } else if (fieldValue >= 228 && fieldValue <= 255) {
425 fieldValue = 224; /* 224; Error-permanent-failure */
428 RetrieveStatus = (MmsRetrieveStatus)MmsGetBinaryType(MmsCodeRetrieveStatus, (UINT16)(fieldValue & 0x7F));
430 mmsHeader.retrieveStatus = (MmsRetrieveStatus)RetrieveStatus;
432 MSG_SEC_INFO("X-Mms-Retrieve-Status = [0x%02x][0x%02x][%s]", oneByte, fieldValue, MmsDebugGetRetrieveStatus(mmsHeader.retrieveStatus));
436 case MMS_CODE_RESPONSETEXT:
438 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szResponseText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
439 MSG_DEBUG("invalid MMS_CODE_RESPONSETEXT");
443 MSG_SEC_INFO("X-Mms-Response-Text = [%s]", mmsHeader.szResponseText);
446 case MMS_CODE_RETRIEVETEXT:
448 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szRetrieveText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
449 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
453 MSG_SEC_INFO("X-Mms-Retrieve-Text = [%s]", mmsHeader.szRetrieveText);
458 if (__MmsBinaryDecodeText(pFile, mmsHeader.szMsgID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
459 MSG_DEBUG("MMS_CODE_MSGID is invalid");
463 MSG_SEC_INFO("Message-ID =[%s]", mmsHeader.szMsgID);
465 if (strlen(mmsHeader.szMsgID) > 2)
466 __MsgMIMERemoveQuote(mmsHeader.szMsgID);
470 case MMS_CODE_SUBJECT:
472 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN + 1, totalLength) == false) {
473 MSG_DEBUG("invalid MMS_CODE_SUBJECT");
477 pLimitData = (char *)calloc(1, MSG_LOCALE_SUBJ_LEN + 1);
479 if (pLimitData == NULL) {
480 MSG_DEBUG("pLimitData calloc fail");
484 nRead = __MsgCutUTFString((unsigned char*)pLimitData, MSG_LOCALE_SUBJ_LEN + 1, (unsigned char*)mmsHeader.szSubject, MSG_SUBJ_LEN);
485 MSG_DEBUG("Subject edit..");
487 if (nRead > MSG_LOCALE_SUBJ_LEN) {
488 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
489 strncpy(mmsHeader.szSubject, pLimitData, MSG_SUBJ_LEN);
491 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
492 strncpy(mmsHeader.szSubject, pLimitData, MSG_LOCALE_SUBJ_LEN);
500 MSG_SEC_INFO("Subject = [%s]", mmsHeader.szSubject);
505 if (mmsHeader.pFrom != NULL) {
506 MSG_DEBUG("MMS_CODE_FROM is already decoded");
510 /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
512 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
513 MSG_DEBUG("MMS_CODE_FROM is invalid");
517 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
518 MSG_DEBUG("MMS_CODE_FROM GetOneByte fail");
522 /* DRM_TEMPLATE - start */
526 if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
527 if (valueLength > 0) {
528 mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
529 if (mmsHeader.pFrom == NULL) {
530 MSG_DEBUG("MMS_CODE_FROM __MmsDecodeEncodedAddress fail");
534 mmsHeader.pFrom = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
535 if (mmsHeader.pFrom == NULL)
538 mmsHeader.pFrom->szAddr = (char *)calloc(1, 1);
539 if (mmsHeader.pFrom->szAddr == NULL) {
540 free(mmsHeader.pFrom);
541 mmsHeader.pFrom = NULL;
545 mmsHeader.pFrom->szAddr[0] = '\0';
546 mmsHeader.pFrom->pNext = NULL;
549 MSG_SEC_INFO("From = [%s]", mmsHeader.pFrom->szAddr);
550 /* DRM_TEMPLATE - end */
551 } else if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
552 /* Present Token only */
553 MSG_SEC_INFO("From = [insert token]");
555 /* from data broken */
556 MSG_WARN("from addr broken");
557 gCurMmsDecodeBuffPos--;
564 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
566 MSG_DEBUG("MMS_CODE_TO __MmsDecodeEncodedAddress fail");
570 if (mmsHeader.pTo == NULL) {
572 pLastTo = mmsHeader.pTo = pAddr;
575 pLastTo->pNext = pAddr;
579 MSG_SEC_INFO("To = [%s]", pAddr->szAddr);
584 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
586 MSG_DEBUG("MMS_CODE_BCC __MmsDecodeEncodedAddress fail");
590 if (mmsHeader.pBcc == NULL) {
592 pLastBcc = mmsHeader.pBcc = pAddr;
595 pLastBcc->pNext = pAddr;
599 MSG_SEC_INFO("Bcc = [%s]", pAddr->szAddr);
604 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
606 MSG_DEBUG("MMS_CODE_CC __MmsDecodeEncodedAddress fail");
610 if (mmsHeader.pCc == NULL) {
612 pLastCc = mmsHeader.pCc = pAddr;
615 pLastCc->pNext = pAddr;
618 MSG_SEC_INFO("Cc = [%s]", pAddr->szAddr);
621 case MMS_CODE_CONTENTLOCATION:
623 if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
624 MSG_DEBUG("MMS_CODE_CONTENTLOCATION is invalid");
627 MSG_SEC_DEBUG("X-Mms-Content-Location = [%s]", mmsHeader.szContentLocation);
632 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
633 MSG_DEBUG("MMS_CODE_DATE is invalid");
637 MSG_SEC_INFO("Date = [%u][%d]", mmsHeader.date, (const time_t *)&mmsHeader.date);
640 case MMS_CODE_DELIVERYREPORT:
642 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
643 MSG_DEBUG("deliveryReport GetOneByte fail");
647 fieldValue = MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
649 if (fieldValue == 0xFFFF) {
650 MSG_DEBUG("deliveryReport error");
654 mmsHeader.deliveryReport = (MmsReport)fieldValue;
656 MSG_SEC_INFO("X-Mms-Delivery-Report =[0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.deliveryReport));
659 case MMS_CODE_DELIVERYTIME:
661 /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
663 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
664 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
668 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
669 MSG_DEBUG("delivery time GetOneByte fail");
673 /* DRM_TEMPLATE - start */
676 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
677 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
679 if (valueLength > 0) {
680 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
681 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
685 /* DRM_TEMPLATE - end */
687 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
689 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
690 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
694 MSG_SEC_INFO("X-Mms-Delivery-Time : type = [%d], time= [%u]", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
697 case MMS_CODE_EXPIRYTIME:
699 /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
701 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
702 MSG_DEBUG("invalid MMS_CODE_EXPIRYTIME");
706 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
707 MSG_DEBUG("expiry time GetOneByte fail");
711 /* DRM_TEMPLATE - start */
714 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
715 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
717 if (valueLength > 0) {
718 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
719 MSG_DEBUG("MMS_CODE_EXPIRYTIME is invalid");
723 /* DRM_TEMPLATE - end */
725 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
727 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
728 MSG_INFO("__MmsBinaryDecodeInteger fail...");
733 MSG_DEBUG("X-Mms-Expiry : type = [%d], time = [%u]", mmsHeader.expiryTime.type, mmsHeader.expiryTime.time);
736 case MMS_CODE_MSGCLASS:
738 /* Class-value = Class-identifier | Token Text */
740 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
741 MSG_DEBUG("msgClass GetOneByte fail");
745 if (oneByte > 0x7f) {
746 /* Class-identifier */
747 mmsHeader.msgClass = (MmsMsgClass)MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
749 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
750 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (class)");
755 MSG_SEC_INFO("X-Mms-Message-Class =[%s]", MmsDebugGetMsgClass(mmsHeader.msgClass));
758 case MMS_CODE_MSGSIZE:
760 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
761 MSG_DEBUG("MMS_CODE_MSGSIZE is invalid");
765 MSG_SEC_INFO("X-Mms-Message-Size = [%d]", mmsHeader.msgSize);
768 case MMS_CODE_MSGSTATUS:
770 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
771 MSG_DEBUG("msgStatus GetOneByte fail");
775 mmsHeader.msgStatus = (msg_delivery_report_status_t)MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
776 MSG_SEC_INFO("X-Mms-Status = [%s]", MmsDebugGetMsgStatus(mmsHeader.msgStatus));
779 case MMS_CODE_MSGTYPE:
781 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
782 MSG_DEBUG("msgStatus GetOneByte fail");
786 mmsHeader.type = (MmsMsgType)MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
787 MSG_SEC_INFO("X-Mms-Message-Type = [%s]", MmsDebugGetMsgType(mmsHeader.type));
790 case MMS_CODE_PRIORITY:
792 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
793 MSG_DEBUG("msgStatus GetOneByte fail");
796 mmsHeader.priority = (MmsPriority)MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
797 MSG_SEC_INFO("X-Mms-Priority = [%d]", mmsHeader.priority);
800 case MMS_CODE_READREPLY:
802 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
803 MSG_DEBUG("msgStatus GetOneByte fail");
806 mmsHeader.readReply = (MmsReport)MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
807 MSG_SEC_INFO("X-Mms-Read-Report = [0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.readReply));
810 case MMS_CODE_REPORTALLOWED:
812 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
813 MSG_DEBUG("msgStatus GetOneByte fail");
816 mmsHeader.reportAllowed = (MmsReportAllowed)MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
817 MSG_SEC_INFO("X-Mms-Report-Allowed = [%d]", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
820 case MMS_CODE_SENDERVISIBILLITY:
822 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
823 MSG_DEBUG("msgStatus GetOneByte fail");
826 mmsHeader.hideAddress = (MmsSenderVisible)!(MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
827 MSG_SEC_INFO("X-Mms-Sender-Visibility = [%d]", mmsHeader.hideAddress);
832 if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
833 MSG_DEBUG("Transaction ID Too Long");
836 MSG_SEC_INFO("X-Mms-Transaction-Id = [%s]", mmsHeader.szTrID);
839 case MMS_CODE_VERSION:
840 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
841 MSG_DEBUG("msgStatus GetOneByte fail");
844 mmsHeader.version = oneByte;
846 MSG_SEC_INFO("X-Mms-MMS-Version = [0x%02x]", mmsHeader.version);
849 case MMS_CODE_CONTENTTYPE:
852 * Content-type is the last header field of SendRequest and RetrieveConf.
853 * It's required to decrease pointer by one and return,
854 * to parse this field in MmsBinaryDecodeContentType().
859 /* ----------- Add by MMSENC v1.1 ----------- */
861 case MMS_CODE_READSTATUS:
863 /* Read-status-value = Read | Deleted without being read */
865 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
866 MSG_DEBUG("msgStatus GetOneByte fail");
870 mmsHeader.readStatus = (msg_read_report_status_t)MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
871 MSG_SEC_INFO("X-Mms-Read-Status = [%s]", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
874 case MMS_CODE_REPLYCHARGING:
876 /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
878 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
879 MSG_DEBUG("msgStatus GetOneByte fail");
883 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
884 MSG_SEC_INFO("X-Mms-Reply-Charging = [%d]", mmsHeader.replyCharge.chargeType);
887 case MMS_CODE_REPLYCHARGINGDEADLINE:
889 /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
891 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
892 MSG_DEBUG("invalid MMS_CODE_REPLYCHARGINGDEADLINE");
896 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
897 MSG_DEBUG("msgStatus GetOneByte fail");
901 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
902 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
904 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
907 /* DRM_TEMPLATE - start */
910 if (valueLength > 0) {
911 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
912 MSG_DEBUG("MMS_CODE_REPLYCHARGINGDEADLINE is invalid");
917 MSG_SEC_INFO("X-Mms-Reply-Charging-Deadline : type = [%d], time = [%u]", mmsHeader.replyCharge.deadLine.type, mmsHeader.replyCharge.deadLine.time);
918 /* DRM_TEMPLATE - end */
921 case MMS_CODE_REPLYCHARGINGID:
923 /* Reply-charging-ID-value = Text-string */
924 if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
925 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (szReplyChargingID)");
928 SECURE_SLOGD("X-Mms-Reply-Charging-ID = [%s]", mmsHeader.replyCharge.szChargeID);
931 case MMS_CODE_REPLYCHARGINGSIZE:
933 /* Reply-charging-size-value = Long-integer */
934 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
935 MSG_DEBUG("MMS_CODE_REPLYCHARGINGSIZE is invalid");
938 MSG_SEC_INFO("X-Mms-Reply-Charging-Size = [%d]", mmsHeader.replyCharge.chargeSize);
941 case MMS_CODE_PREVIOUSLYSENTBY:
944 * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
945 * Forwarded-count-value = Integer-value
946 * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
950 * fixme: There is no proper field to store this information.
951 * Just increase pointer now.
954 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
955 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTBY");
959 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
960 MSG_DEBUG("2. invalid MMS_CODE_PREVIOUSLYSENTBY");
964 if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
965 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
970 case MMS_CODE_PREVIOUSLYSENTDATE:
973 * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
974 * Forwarded-count-value = Integer-value
975 * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
979 * fixme: There is no proper field to store this information.
980 * Just increase pointer now.
983 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
984 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTDATE");
988 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
989 MSG_DEBUG("2. invalid MS_CODE_PREVIOUSLYSENTDATE");
993 if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
994 MSG_DEBUG("3. invalid MMS_CODE_PREVIOUSLYSENTDATE");
1001 * Application-header = Token-text Application-specific-value
1002 * Token-text = Token End-of-string
1003 * Application-specific-value = Text -string
1005 * OR unknown header field - Just ignore these fields.
1007 * Read one byte and check the value >= 0x80
1008 * (check these value can be field code)
1011 int remainLength = 0;
1015 offset = __MmsGetDecodeOffset();
1016 if (offset >= totalLength)
1019 remainLength = totalLength - offset;
1021 while ((oneByte < 0x80) && (remainLength > 0)) {
1022 if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1023 MSG_DEBUG("__MmsBinaryDecodeCheckAndDecreaseLength fail");
1027 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1028 MSG_DEBUG("responseStatus GetOneByte fail");
1033 gCurMmsDecodeBuffPos--;
1038 offset = __MmsGetDecodeOffset();
1039 if (offset >= totalLength)
1045 if (mmsHeader.pTo == NULL && pLastTo) {
1049 if (mmsHeader.pCc == NULL && pLastCc) {
1053 if (mmsHeader.pBcc == NULL && pLastBcc) {
1057 MSG_INFO("## Decode Header Success ##");
1064 if (mmsHeader.pTo == NULL && pLastTo) {
1068 if (mmsHeader.pCc == NULL && pLastCc) {
1072 if (mmsHeader.pBcc == NULL && pLastBcc) {
1076 MSG_FATAL("## Decode Header Fail ##");
1081 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1088 if (szFilePath != NULL)
1089 snprintf(mmsHeader.msgType.szOrgFilePath, sizeof(mmsHeader.msgType.szOrgFilePath), "%s", szFilePath);
1091 mmsHeader.msgType.offset = __MmsGetDecodeOffset() - 1; /* + Content-Type code value */
1093 /* read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding */
1094 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1095 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1096 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1097 MSG_DEBUG("fail to load to buffer");
1101 /* msg's type [ex] related, mixed, single part (jpg, amr and etc) */
1102 length = __MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1104 MSG_DEBUG("MMS_CODE_CONTENTTYPE is fail");
1108 mmsHeader.msgType.size = length + 1; /* + Content-Type code value */
1109 mmsHeader.msgBody.offset = __MmsGetDecodeOffset();
1111 switch (mmsHeader.msgType.type) {
1112 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1113 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1114 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1115 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1116 case MIME_MULTIPART_REPORT:
1117 case MIME_MULTIPART_MIXED:
1118 case MIME_MULTIPART_RELATED:
1119 case MIME_MULTIPART_ALTERNATIVE:
1120 case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1121 case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1123 MSG_DEBUG("Decode Multipart");
1125 offset = __MmsGetDecodeOffset();
1126 if (offset >= totalLength)
1129 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1130 MSG_DEBUG("MmsBinaryDecodeMultipart is fail.");
1137 /* Single part message ---------------------------------------------- */
1138 MSG_DEBUG("Decode Singlepart");
1140 offset = __MmsGetDecodeOffset();
1141 if (offset >= totalLength)
1144 if (__MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1145 MSG_DEBUG("MmsBinaryDecodePartBody is fail.(Single Part)");
1149 snprintf(mmsHeader.msgBody.szOrgFilePath, MSG_FILEPATH_LEN_MAX, "%s", szFilePath);
1150 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1151 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1164 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1169 char *szTypeString = NULL;
1170 char *szTypeValue = NULL;
1171 UINT8 paramCode = 0xff;
1178 * Parameter = Typed-parameter | Untyped-parameter
1179 * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1182 while (valueLength > 0) {
1183 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1184 MSG_DEBUG("paramCode _MmsBinaryDecodeGetOneByte fail");
1188 paramCode = oneByte;
1191 switch (paramCode) {
1192 case 0x81: /* charset */
1194 if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1195 MSG_DEBUG("__MmsBinaryDecodeCharset fail.");
1199 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1204 case 0x85: /* name = Text-string */
1205 case 0x97: /* name = Text-value = No-value | Token-text | Quoted-string */
1206 memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1207 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szName,
1208 MSG_FILENAME_LEN_MAX -5, /* MSG_LOCALE_FILENAME_LEN_MAX + 1, : change @ 110(Ui code have to change for this instead of DM) */
1211 MSG_DEBUG("__MmsDecodeGetFilename fail. (name parameter)");
1215 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1216 __MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1219 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1224 case 0x86: /* filename = Text-string */
1225 case 0x98: /* filename = Text-value = No-value | Token-text | Quoted-string */
1226 memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1227 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1229 MSG_DEBUG("__MmsDecodeGetFilename fail. (filename parameter)");
1233 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1234 __MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1237 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1242 case 0x89: /* type = Constrained-encoding = Extension-Media | Short-integer */
1244 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1245 MSG_DEBUG("type _MmsBinaryDecodeGetOneByte fail");
1249 if (oneByte > 0x7f) {
1250 pMsgType->param.type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1251 /* MmsGetBinaryType(MmsCodeContentType,(UINT16)(oneByte & 0x7f)); */
1252 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1255 gCurMmsDecodeBuffPos--;
1258 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1259 pMsgType->param.type = MimeGetMimeIntFromMimeString(szTypeString);
1262 szTypeString = NULL;
1265 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1271 case 0x8A: /* start encoding version 1.2 */
1272 case 0x99: /* start encoding version 1.4 */
1275 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1277 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1278 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1280 szTypeString = NULL;
1282 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1288 case 0x8B: /* startInfo encoding version 1.2 */
1289 case 0x9A: /* startInfo encoding version 1.4 */
1292 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1295 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1296 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1299 szTypeString = NULL;
1301 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1309 if (paramCode > 0x7F) {
1310 MSG_DEBUG("Unsupported parameter");
1312 /* In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value. */
1314 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1318 * Untyped Parameter = Token-text Untyped-value
1319 * Token-text = Token End-of-string
1320 * Untyped-value = Integer-value | Text-value
1321 * Text-value = No-value | Token-text | Quoted-string
1323 * Just increase pointer!!!
1329 gCurMmsDecodeBuffPos--;
1333 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1334 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1340 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1341 MSG_DEBUG("Unsupported parameter(%d)\n", integer);
1342 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1346 szTypeValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1349 /* checkMe: forwardLock needs boudary string */
1350 if (g_ascii_strcasecmp(szTypeString, "boundary") == 0) {
1351 memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1352 strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1353 #ifdef FEATURE_JAVA_MMS
1354 } else if (g_ascii_strcasecmp(szTypeString, "Application-ID") == 0) {
1355 pMsgType->param.szApplicationID = (char*) calloc(1, textLength + 1);
1356 if (pMsgType->param.szApplicationID) {
1357 memset(pMsgType->param.szApplicationID, 0, textLength + 1);
1358 strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1359 MSG_SEC_DEBUG("Application-ID:%s", pMsgType->param.szApplicationID);
1361 } else if (g_ascii_strcasecmp(szTypeString, "Reply-To-Application-ID") == 0) {
1362 pMsgType->param.szReplyToApplicationID = (char*)calloc(1, textLength + 1);
1363 if (pMsgType->param.szReplyToApplicationID) {
1364 memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1365 strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1366 MSG_SEC_DEBUG("ReplyToApplication-ID:%s", pMsgType->param.szReplyToApplicationID);
1371 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeValue);
1375 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1381 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeString);
1383 szTypeString = NULL;
1389 } /*end of while loop*/
1396 szTypeString = NULL;
1408 * Decode Encoded Content type
1410 * @param pEncodedData [in] ContentType encoded data
1411 * @param pMsgType [out] Decoded MsgType
1412 * @return Decoded address list
1414 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1418 char *szTypeString = NULL;
1419 int valueLength = 0;
1425 * Content-type-value : [WAPWSP 8.4.2.24]
1426 * Preassigned content-types : [WAPWSP Appendix A, Table 40]
1427 * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1429 * Content-type-value = Constrained-media | Content-general-form
1430 * Content-general-form = Value-length Media-type
1431 * Media-type = (Well-known-media | Extension-Media) *(Parameter)
1434 length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1437 * Constrained-media or Single part message
1438 * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1439 * Extension-media = *TEXT End-of-string
1440 * Short-integer = OCTET(1xxx xxxx)
1443 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1444 MSG_DEBUG("Constrained-media _MmsBinaryDecodeGetOneByte fail");
1448 if (oneByte > 0x7F) {
1450 pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1452 MSG_SEC_DEBUG("Constrained-media : Short-integer : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1456 char *pszTemp = NULL;
1458 /* Extension-Media */
1459 gCurMmsDecodeBuffPos--;
1462 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1464 if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1465 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type with delimiter = [%s]", szTypeString);
1467 pszTemp = __MsgGetStringUntilDelimiter(szTypeString, ';');
1470 szTypeString = pszTemp;
1474 pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1476 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1478 length = textLength;
1482 szTypeString = NULL;
1487 * Content-general-form = Value-length Media-type
1488 * Media-type = (Well-known-media | Extension-Media)*(Parameter)
1491 length += valueLength;
1493 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1494 MSG_DEBUG("Well-known-media _MmsBinaryDecodeGetOneByte fail");
1498 if (oneByte > 0x7F) {
1499 /* Well-known-media */
1500 pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1501 MSG_SEC_DEBUG("Content-general-form : Well-known-media : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1504 /* Extension-Media */
1505 gCurMmsDecodeBuffPos--;
1508 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1510 pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1512 MSG_SEC_DEBUG("Content-general-form : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1514 valueLength -= textLength;
1518 szTypeString = NULL;
1522 MSG_SEC_DEBUG("Content-Type = [%s]", MmsDebugGetMimeType((MimeType)pMsgType->type));
1524 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1525 MSG_DEBUG("Content-Type parameter fail");
1538 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1540 UINT8 fieldCode = 0xff;
1542 UINT32 valueLength = 0;
1544 char *pValue = NULL;
1545 char *pParam = NULL;
1551 char *pLatinBuff = NULL;
1553 char *szTemp = NULL;
1555 MSG_INFO("headerLen[%d] totalLength[%d]", headerLen, totalLength);
1557 if (pFile == NULL || pMsgType == NULL)
1561 * Message-header = Well-known-header | Application-header
1562 * Well-known-header = Well-known-field-name Wap-value
1563 * Application-header = Token-text Application-specific-value
1564 * Well-known-field-name = Short-integer
1565 * Application-specific-value = Text-string
1568 while (headerLen > 0) {
1569 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1570 MSG_DEBUG("field code GetOneByte fail");
1574 if (0x80 <= oneByte && oneByte <= 0xC7) {
1575 /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1577 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1580 fieldCode = oneByte & 0x7f;
1582 switch (fieldCode) {
1583 case 0x0E: /* Content-Location */
1584 case 0x04: { /* Content-Location */
1585 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1586 if (pLatinBuff == NULL)
1589 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1591 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1595 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1597 snprintf(pMsgType->szContentLocation, sizeof(pMsgType->szContentLocation), "%s", szSrc);
1598 MSG_SEC_DEBUG("Content Location : [%s]", pMsgType->szContentLocation);
1606 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1611 case 0x40: { /* Content-ID */
1612 char szContentID[MMS_CONTENT_ID_LEN + 1] = {0, };
1614 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1615 if (pLatinBuff == NULL)
1618 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1621 MSG_DEBUG("Content-ID __MmsBinaryDecodeQuotedString fail.");
1625 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1627 snprintf(szContentID, sizeof(szContentID), "%s", szSrc);
1628 MSG_SEC_DEBUG("Content ID : [%s]", szContentID);
1636 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1638 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1643 case 0x2E: /* Content-Disposition */
1644 case 0x45: /* Content-Disposition */
1647 * Content-disposition-value = Value-length Disposition *(Parameter)
1648 * Disposition = Form-data | Attachment | Inline | Token-text
1649 * Form-data = <Octet 128> : 0x80
1650 * Attachment = <Octet 129> : 0x81
1651 * Inline = <Octet 130> : 0x82
1654 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1657 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1661 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1662 MSG_DEBUG("Disposition value GetOneByte fail");
1669 if (oneByte >= 0x80) {
1670 pMsgType->disposition = MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1672 if (pMsgType->disposition == -1) {
1673 MSG_DEBUG("Content-Disposition MmsGetBinaryType fail.");
1674 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT; /* default */
1677 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1680 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1681 MSG_DEBUG("Disposition parameter fail");
1685 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1688 gCurMmsDecodeBuffPos--;
1691 pLatinBuff = (char *)calloc(1, MSG_FILENAME_LEN_MAX);
1692 if (pLatinBuff == NULL)
1694 memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1696 textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1699 if (textLength < 0) {
1700 MSG_DEBUG("Content-Disposition decodingfail.");
1706 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1709 valueLength -= textLength;
1711 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1712 MSG_DEBUG("Disposition parameter fail");
1716 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1722 case 0x0B: /* Content-Encoding */
1723 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1724 MSG_DEBUG("Disposition value GetOneByte fail");
1728 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1733 case 0x0C: /* Content-Language */
1734 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1735 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1740 cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1742 if (cTemp == NULL) {
1743 MSG_DEBUG("__MmsBinaryDecodeText2 fail...");
1747 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1759 case 0x0D: /* Content-Length */
1760 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1761 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1765 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1770 case 0x1C: /* Location */
1771 pLatinBuff = (char *)calloc(1, MMS_LOCATION_URL_LEN + 1);
1772 if (pLatinBuff == NULL)
1775 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_LOCATION_URL_LEN, totalLength);
1777 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1781 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1783 snprintf(pMsgType->szLocation, sizeof(pMsgType->szLocation), "%s", szSrc);
1784 MSG_INFO("Location : [%s]", pMsgType->szLocation);
1792 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1797 case 0x30: /* X-Wap-Content-URI skip this value */
1798 MSG_DEBUG("X-Wap-Content-URI header.");
1799 pLatinBuff = (char *)calloc(1, MMS_TEXT_LEN);
1800 if (pLatinBuff == NULL)
1803 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1806 MSG_DEBUG(" __MmsBinaryDecodeQuotedString fail.");
1810 MSG_DEBUG("X-Wap-Content-URI header decoded. Value length %d\n", length);
1814 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1817 MSG_DEBUG("X-Wap-Content-URI header skipped.");
1821 case 0x01: { /* Accept-charset */
1822 /* if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1) */
1823 /* WAP-230-WSP-200010705-a.pdf
1824 8.4.2.8 Accept charset field
1825 The following rules are used to encode accept character set values.
1826 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1827 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1828 Constrained-charset = Any-charset | Constrained-encoding
1829 Well-known-charset = Any-charset | Integer-value
1830 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1831 Any-charset = <Octet 128>
1832 ; Equivalent to the special RFC2616 charset value ��*��
1838 MSG_DEBUG("Accept-charset.");
1840 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1842 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1846 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1847 /* We only support the well-known-charset format */
1848 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1853 MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1855 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1862 /* Other Content-xxx headers : Have valueLength */
1863 MSG_WARN("unknown Value = 0x%x\n", oneByte);
1865 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1867 MSG_WARN("invalid MMS_CODE_PREVIOUSLYSENTDATE");
1871 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1874 szTemp = (char *)calloc(1, valueLength);
1878 if (__MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) == false) {
1879 MSG_WARN("default _MmsBinaryDecodeGetBytes() fail");
1887 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1894 * Application-header = Token-text Application-specific-value
1895 * Application-specific-value = Text-string
1898 MSG_DEBUG(" Application-header = Token-text Application-specific-value");
1900 gCurMmsDecodeBuffPos--;
1905 pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1906 if (pCode == NULL) {
1907 MSG_DEBUG("pCode is null");
1911 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1914 MSG_DEBUG(" Token-text (%s) \n", pCode);
1917 /* Application-specific-value */
1920 pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1921 if (pValue == NULL) {
1922 MSG_DEBUG("pValue is null");
1926 MSG_DEBUG(" Application-specific-value (%s) \n", pValue);
1929 pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1935 switch (MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1936 case MMS_BODYHDR_TRANSFERENCODING: /* Content-Transfer-Encoding */
1937 pMsgType->encoding = MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1940 case MMS_BODYHDR_CONTENTID: { /* Content-ID */
1941 char szContentID[MMS_CONTENT_ID_LEN + 1];
1943 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1944 if (pLatinBuff == NULL) {
1948 __MsgMIMERemoveQuote(pValue);
1949 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1951 length = strlen(pLatinBuff);
1952 if (__MsgLatin2UTF((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1953 MSG_DEBUG("MsgLatin2UTF fail");
1957 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1963 case MMS_BODYHDR_CONTENTLOCATION: /* Content-Location */
1965 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1966 if (pLatinBuff == NULL)
1969 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1971 length = strlen(pLatinBuff);
1972 if (__MsgLatin2UTF((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1973 MSG_DEBUG("MsgLatin2UTF fail");
1981 case MMS_BODYHDR_DISPOSITION: /* Content-Disposition */
1982 pMsgType->disposition = MmsGetTextType(MmsCodeMsgDisposition, pValue);
1985 case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY: /* DRM RO WAITING */
1989 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
1994 __MsgParseParameter(pMsgType, pParam + 1);
2006 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2048 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2052 length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2057 MSG_INFO("Number of Entries = [%d]", *npEntries);
2065 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2070 * Currently, offset and size is
2071 * the only information used with msgBody.
2072 * If you need, add here more information
2076 offset = __MmsGetDecodeOffset();
2077 offset += bodyLength;
2079 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2080 MSG_DEBUG("fail to seek file pointer");
2084 __MmsCleanDecodeBuff();
2086 gMmsDecodeCurOffset = offset;
2088 if (offset >= totalLength)
2091 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2092 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2093 MSG_DEBUG("fail to load to buffer");
2106 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2108 if (offset > totalLength)
2111 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2112 MSG_DEBUG("fail to seek file pointer");
2116 __MmsCleanDecodeBuff();
2118 gMmsDecodeCurOffset = offset;
2120 if (offset == totalLength)
2123 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2124 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2125 MSG_DEBUG("fail to load to buffer");
2136 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2138 UINT32 nEntries = 0;
2139 MsgMultipart *pMultipart = NULL;
2140 MsgMultipart *pLastMultipart = NULL;
2144 MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2145 MsgPresentaionInfo presentationInfo;
2147 MSG_DEBUG("pdu length = [%d]", totalLength);
2149 presentationInfo.factor = MSG_PRESENTATION_NONE;
2150 presentationInfo.pCurPresentation = NULL;
2151 presentationInfo.pPrevPart = NULL;
2153 if (__MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2154 MSG_DEBUG("MmsBinaryDecodeEntries is fail.");
2158 if (pMsgBody->body.pMultipart != NULL) {
2159 pLastMultipart = pMsgBody->body.pMultipart;
2160 MSG_DEBUG("previous multipart exist [%p]", pMsgBody->body.pMultipart);
2162 MSG_DEBUG("first multipart");
2166 MSG_DEBUG("decoding [%d]th multipart", index);
2168 offset = __MmsGetDecodeOffset();
2169 if (offset >= totalLength) {
2170 MSG_DEBUG("offset is over totalLength");
2174 if ((pMultipart = MmsAllocMultipart()) == NULL) {
2175 MSG_DEBUG("MsgAllocMultipart Fail");
2179 if (__MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2180 MSG_DEBUG("MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2184 if (pMultipart->type.type == MIME_APPLICATION_SMIL) {
2185 /* P151019-00477 : received mms message is type of multipart mixed, but among multiparts if there's smil part then set it multipart related */
2186 if (pMsgType->type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED)
2187 pMsgType->type = MIME_APPLICATION_VND_WAP_MULTIPART_RELATED;
2189 factor = __MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2190 if (factor == MSG_PRESENTATION_NONE) {
2191 factor = MSG_PRESENTATION_TYPE_BASE;
2194 factor = MSG_PRESENTATION_NONE;
2197 /* priority 1 : content type match, 2: content location, 3: type */
2198 if (presentationInfo.factor < factor) {
2199 /* Presentation part */
2200 presentationInfo.factor = factor;
2201 presentationInfo.pPrevPart = pLastMultipart;
2202 presentationInfo.pCurPresentation = pMultipart;
2205 /* first multipart */
2206 if (pLastMultipart == NULL) {
2207 pMsgBody->body.pMultipart = pMultipart;
2208 pLastMultipart = pMultipart;
2210 pLastMultipart->pNext = pMultipart;
2211 pLastMultipart = pMultipart;
2214 pMsgType->contentSize += pMultipart->pBody->size;
2218 MmsPrintMulitpart(pMultipart, index++);
2221 pMsgBody->size = totalLength - pMsgBody->offset;
2223 __MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2225 if (__MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2226 MSG_DEBUG("MsgResolveNestedMultipart failed");
2234 if (pMultipart->pBody) {
2235 free(pMultipart->pBody);
2236 pMultipart->pBody = NULL;
2246 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2249 bool bSuccess = false;
2250 UINT32 headerLength = 0;
2251 UINT32 bodyLength = 0;
2254 MSG_DEBUG("pdu length = [%d]", totalLength);
2257 if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2258 MSG_DEBUG("Get header length fail");
2262 offset = __MmsGetDecodeOffset();
2263 if (offset >= totalLength)
2267 if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2268 MSG_DEBUG("Get body length fail");
2272 offset = __MmsGetDecodeOffset();
2273 if (offset >= totalLength)
2277 if (szFilePath != NULL)
2278 snprintf(pMsgType->szOrgFilePath, sizeof(pMsgType->szOrgFilePath), "%s", szFilePath);
2280 pMsgType->offset = __MmsGetDecodeOffset();
2281 pMsgType->size = headerLength;
2282 pMsgType->contentSize = bodyLength;
2284 if (pMsgType->offset > totalLength)
2287 length = __MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2289 MSG_DEBUG("Decode contentType Fail");
2293 offset = __MmsGetDecodeOffset();
2294 if (offset >= totalLength)
2300 if (__MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2301 MSG_DEBUG("Decode contentHeader Fail");
2305 offset = __MmsGetDecodeOffset();
2306 if (offset >= totalLength)
2311 if (szFilePath != NULL)
2312 snprintf(pMsgBody->szOrgFilePath, sizeof(pMsgBody->szOrgFilePath), "%s", szFilePath);
2314 pMsgBody->offset = __MmsGetDecodeOffset();
2315 pMsgBody->size = bodyLength;
2317 if (pMsgBody->offset > totalLength)
2320 switch (pMsgType->type) {
2321 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2322 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2323 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2324 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2325 case MIME_MULTIPART_REPORT:
2326 case MIME_MULTIPART_MIXED:
2327 case MIME_MULTIPART_RELATED:
2328 case MIME_MULTIPART_ALTERNATIVE:
2329 MSG_DEBUG("Multipart");
2330 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2331 MSG_DEBUG("MmsBinaryDecodeMultipart is fail");
2335 offset = __MmsGetDecodeOffset();
2336 if (offset >= totalLength)
2342 MSG_DEBUG("Normal Part");
2344 if (pMsgType->type == MIME_UNKNOWN) {
2345 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0};
2346 MimeType mimeType = MIME_UNKNOWN;
2348 if (pMsgType->param.szName[0] != '\0')
2349 snprintf(szFileName, MSG_FILENAME_LEN_MAX, "%s", pMsgType->param.szName);
2350 else if (pMsgType->param.szFileName[0] != '\0')
2351 snprintf(szFileName, MSG_FILENAME_LEN_MAX, "%s", pMsgType->param.szFileName);
2352 else if (pMsgType->szContentLocation[0] != '\0')
2353 snprintf(szFileName, MSG_FILENAME_LEN_MAX, "%s", pMsgType->szContentLocation);
2355 MsgGetMimeTypeFromFileName(MIME_MAINTYPE_UNKNOWN, szFileName, &mimeType, NULL);
2356 pMsgType->type = mimeType;
2359 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2360 if (bSuccess == false) {
2361 MSG_DEBUG("Decode contentBody Fail");
2365 offset = __MmsGetDecodeOffset();
2366 if (offset >= totalLength)
2384 /* --------------------------------------------------------------------
2386 * B I N A R Y D E C D E U T I L I T Y
2388 * --------------------------------------------------------------------*/
2390 bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
2392 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2394 if (pFile == NULL || pOneByte == NULL) {
2395 MSG_DEBUG("invalid file or buffer");
2400 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2401 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2402 MSG_DEBUG("fail to load to buffer");
2407 *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2416 * @remark: bufLen < gMmsDecodeMaxLen
2418 bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2420 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2424 if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
2427 memset(szBuff, 0, bufLen);
2429 if (length < bufLen) {
2430 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2431 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2432 MSG_DEBUG("fail to load to buffer");
2437 for (i = 0; i < bufLen - 1; i++) {
2438 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2441 gCurMmsDecodeBuffPos++; /* NULL */
2449 bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2453 if (pFile == NULL || szBuff == NULL || bufLen == 0)
2456 memset(szBuff, 0, bufLen);
2458 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2459 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2460 MSG_DEBUG("fail to load to buffer");
2464 while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
2465 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
2466 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2470 iPos += gMmsDecodeMaxLen;
2473 if ((bufLen - iPos) > 0) {
2474 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
2475 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2479 iPos += (bufLen - iPos);
2489 * Decode uintvar to 32bit unsigned integer
2491 * @param pEncodedData [in] encoded data
2492 * @param pUintVar [out] Decode uintvar (32bit unsigned integer)
2493 * @return The length of uintvar (-1, if cannot be converted to a uintvar)
2495 * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
2498 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
2500 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
2504 UINT32 decodedUintvar = 0;
2505 UINT8 iBuff[5] = {0};
2506 int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
2509 if (pFile == NULL || pUintVar == NULL)
2513 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2514 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2515 MSG_DEBUG("fail to load to buffer");
2521 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2524 if (oneByte > 0x7f) {
2525 iBuff[count++] = oneByte;
2527 iBuff[count++] = oneByte;
2532 MSG_DEBUG("legnth is too long");
2537 for (int i = 0; i < count; i++)
2538 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
2540 *pUintVar = decodedUintvar;
2545 gCurMmsDecodeBuffPos -= count;
2550 * Decode uintvar to 32bit unsigned integer by uintvar length
2552 * @param pEncodedData [in] uintvar encoded data
2553 * @param length [in] length of integer value
2554 * @return unsigned integer value
2556 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
2566 returner.integer = 0;
2572 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2573 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2577 if (oneByte > 0x7f) {
2578 return (oneByte & 0x7f);
2587 pData = (char *)calloc(1, length + 1);
2588 if (pData == NULL) {
2589 MSG_DEBUG("pData alloc fail");
2592 memset(pData, 0, length + 1);
2594 if (__MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
2595 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2599 gCurMmsDecodeBuffPos--; /* - NULL */
2601 for (i= 0; i < length; i++)
2602 returner.seg[length - (i+1)] = pData[i];
2609 return returner.integer;
2618 return returner.integer;
2622 * Decode uintvar to 32bit unsigned integer by uintvar length
2624 * @param pEncodedData [in] uintvar encoded data
2625 * @param pInteger [out] Decode integer value (long/short)
2626 * @return unsigned integer value (-1, if cannot be converted to unsigned integer value)
2628 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
2638 if (pInteger == NULL)
2641 returner.integer = 0;
2644 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2645 MSG_DEBUG("GetOneByte fail");
2649 if (oneByte < 0x1F) { /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2650 pData = (char *)calloc(1, oneByte + 1);
2651 if (pData == NULL) {
2652 MSG_DEBUG("pData calloc fail");
2655 memset(pData, 0, oneByte + 1);
2657 /* Even NULL is copied in the _MmsBinaryDecodeGetBytes */
2658 if (__MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
2659 MSG_DEBUG("GetBytes fail");
2663 gCurMmsDecodeBuffPos--; /* - NULL */
2673 for (i = 0; i < length; i++)
2674 returner.seg[length - (i+1)] = pData[i];
2676 *pInteger = returner.integer;
2677 *pIntLen = oneByte + 1;
2678 } else if (oneByte >= 0x80) {
2679 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2680 *pInteger = oneByte & 0x7f;
2695 gCurMmsDecodeBuffPos--;
2706 * Decode uintvar to 32bit unsigned integer by uintvar length
2708 * @return 1 : Success
2709 * 0 : This is not Value Length type data
2710 * -1 : Requires System error report
2712 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
2720 * value-length = short-length | (Length-quote Length)
2721 * = 0~30 | 31 + Uintvar-length
2724 if (pFile == NULL || pValueLength == NULL)
2729 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2730 gCurMmsDecodeBuffPos--;
2734 if (0x00 < oneByte && oneByte < 0x1F) {
2736 *pValueLength = oneByte;
2738 } else if (oneByte == 0x1F) {
2739 /* Length-quote = 0x1F */
2741 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2743 MSG_DEBUG(" __MmsBinaryDecodeUintvar fail..");
2746 length++; /* + length-quote */
2747 *pValueLength = uintvar;
2749 MSG_DEBUG("not a value length type data");
2750 gCurMmsDecodeBuffPos--;
2757 MSG_DEBUG("getting data fail");
2762 * Decode uintvar to 32bit unsigned integer by uintvar length
2764 * @return 1 : Success
2765 * 0 : This is not Value Length type data
2766 * -1 : Requires System error report
2767 * @ defference : if there is not length-quote, consider it as short length.
2769 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
2777 * value-length = short-length | (Length-quote Length)
2778 * = 0~30 | 31 + Uintvar-length
2781 if (pFile == NULL || pValueLength == NULL)
2786 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2787 gCurMmsDecodeBuffPos--;
2791 if (0x00 < oneByte && oneByte < 0x1F) {
2793 *pValueLength = oneByte;
2795 } else if (oneByte == 0x1F) {
2796 /* Length-quote = 0x1F */
2798 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2800 MSG_DEBUG("__MmsBinaryDecodeUintvar fail..");
2803 length++; /* + length-quote */
2804 *pValueLength = uintvar;
2806 MSG_DEBUG("there is not length-quote, consider it as short length.");
2807 *pValueLength = oneByte;
2814 MSG_DEBUG("getting data fail");
2819 * Decode QuotedString
2821 * @param pEncodedData [in] QuotedString encoded data
2822 * @param szBuff [out] Decoded quoted string
2823 * @param bufLen [out] Buffer length
2824 * @return length of quoted string
2826 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2832 int returnLength = 0;
2835 * Quoted-string = <Octet 34> *TEXT End-of-string
2836 * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
2839 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2842 memset(szBuff, 0, bufLen);
2844 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2845 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2846 MSG_DEBUG("fail to load to buffer");
2850 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2855 while (length > gMmsDecodeBufLen) {
2856 if (gMmsDecodeBufLen <= 0) {
2857 MSG_DEBUG("gMmsDecodeBufLen <= 0");
2858 MSG_DEBUG("%x %x %x %x %x",
2859 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
2860 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
2861 MSG_DEBUG("%x %x %x %x %x",
2862 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
2863 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
2864 MSG_DEBUG("%x %x %x %x %x",
2865 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
2866 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
2867 MSG_DEBUG("%x %x %x %x %x",
2868 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
2869 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
2873 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
2877 memset(pData, 0, gMmsDecodeBufLen + 1);
2879 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
2882 returnLength += gMmsDecodeBufLen;
2884 if ((bufLen - iPos) > 0) {
2885 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
2886 if (iPos == 0 && (pData[0] == MARK)) {
2887 /* MARK: check first time only */
2889 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2890 iPos += (readBytes - 1);
2892 strncpy(szBuff + iPos, (char*)pData, readBytes);
2902 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2903 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2904 MSG_DEBUG("fail to load to buffer");
2907 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2911 pData = (char *)calloc(1, length);
2915 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
2918 returnLength += length;
2920 if ((bufLen - iPos) > 0) {
2921 /* read until NULL from raw data, and copy only string */
2922 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
2923 if (iPos == 0 && (pData[0] == MARK)) {
2924 /* MARK: check first time only */
2925 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2926 iPos += (readBytes - 1);
2928 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); /* + NULL */
2939 szBuff[bufLen - 1] = '\0';
2941 return returnLength;
2960 * @param pEncodedData [in] QuotedString encoded data
2961 * @param szBuff [out] Decoded quoted string
2962 * @param bufLen [out] Buffer length
2963 * @return length of decode text string
2965 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2970 int returnLength = 0;
2972 bool bQuote = false;
2976 * Text-String = [QUOTE]*TEXT end_of_string
2977 * [QUOTE]*(128~255)\0
2981 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2984 offset = __MmsGetDecodeOffset();
2985 if (offset >= totalLength)
2988 memset(szBuff, 0, bufLen);
2990 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2991 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2992 MSG_DEBUG("fail to load to buffer");
2996 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
3001 while (length > gMmsDecodeBufLen) {
3002 if (gMmsDecodeBufLen <= 0) {
3003 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3004 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3005 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3006 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3007 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3008 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3009 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3010 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3011 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3015 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3019 memset(pData, 0, gMmsDecodeBufLen + 1);
3021 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3024 if ((bufLen - iPos) > 0) {
3025 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3026 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3027 /* QUOTE: check first time only */
3029 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3030 iPos += (readBytes - 1);
3033 strncpy(szBuff + iPos, (char*)pData, readBytes);
3043 returnLength += gMmsDecodeBufLen;
3045 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3046 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3047 MSG_DEBUG("fail to load to buffer");
3050 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
3054 pData = (char *)calloc(1, length);
3058 memset(pData, 0, length);
3060 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3063 if ((bufLen - iPos) > 0) {
3064 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3065 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3066 /* QUOTE: check first time only */
3068 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3069 iPos += (readBytes - 1);
3072 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); /* + NULL */
3082 returnLength += length; /* + NULL */
3085 szBuff[bufLen - 1] = '\0';
3087 return returnLength;
3094 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3108 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
3113 char *szBuff = NULL;
3114 char *szTempPtr = NULL;
3115 bool bQuote = false;
3119 * Text-String = [QUOTE]*TEXT end_of_string
3120 * [QUOTE]*(128~255)\0
3124 if (pFile == NULL || pLength == NULL)
3128 offset = __MmsGetDecodeOffset();
3129 if (offset >= totalLength)
3132 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3133 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3134 MSG_DEBUG("fail to load to buffer");
3138 length = strlen(gpCurMmsDecodeBuff) + 1;
3143 while (length > gMmsDecodeBufLen) {
3144 if (gMmsDecodeBufLen <= 0) {
3145 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3146 MSG_DEBUG("%x %x %x %x %x",
3147 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3148 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3149 MSG_DEBUG("%x %x %x %x %x",
3150 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3151 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3152 MSG_DEBUG("%x %x %x %x %x",
3153 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3154 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3155 MSG_DEBUG("%x %x %x %x %x\n",
3156 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3157 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3161 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3165 memset(pData, 0, gMmsDecodeBufLen + 1);
3167 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3170 if (szBuff == NULL) {
3171 szBuff = (char *)calloc(1, gMmsDecodeBufLen + 1);
3173 szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
3175 /* NULL pointer check for realloc */
3176 if (szTempPtr == NULL) {
3185 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
3187 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3188 /* QUOTE: check first time only */
3190 strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
3191 curLen += (gMmsDecodeBufLen - 1);
3194 strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
3195 curLen += gMmsDecodeBufLen;
3203 *pLength += gMmsDecodeBufLen;
3205 if (__MsgLoadDataToDecodeBuffer(pFile,
3206 &gpCurMmsDecodeBuff,
3207 &gCurMmsDecodeBuffPos,
3208 &gMmsDecodeCurOffset,
3213 totalLength) == false) {
3214 MSG_DEBUG("fail to load to buffer");
3217 length = strlen(gpCurMmsDecodeBuff) + 1;
3221 pData = (char *)calloc(1, length);
3222 if (pData == NULL) {
3226 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
3230 if (szBuff == NULL) {
3231 szBuff = (char *)calloc(1, length);
3233 szTempPtr = (char *)realloc(szBuff, curLen + length);
3235 /* NULL pointer check for realloc */
3236 if (szTempPtr == NULL)
3242 if (szBuff == NULL) {
3246 memset(szBuff + curLen, 0, length);
3248 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3249 /* QUOTE: check first time only */
3251 strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
3252 curLen += (length - 1);
3255 strncpy(szBuff + curLen, (char*)pData, length - 1);
3264 *pLength += length; /* + NULL */
3273 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3295 * @param pEncodedData [in] QuotedString encoded data
3296 * @param nCharSet [out] Decoded character set
3297 * @return length of charset value
3299 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
3304 * Charset v1.1 0x01 Well-known-charset
3305 * Well-known-charset = Any-charset | Integer-value
3306 * ; Both are encoded using values from
3307 * Character Set Assignments table in Assigned Numbers
3308 * Any-charset = <Octet 128>
3309 * ; Equivalent to the special RFC2616 charset value ��*��
3312 if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
3315 if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
3316 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
3321 /* AnyCharSet : return MSG_CHARSET_UTF8 */
3322 *nCharSet = MSG_CHARSET_UTF8;
3326 *nCharSet = MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
3327 MSG_DEBUG("Decoded charset MIBenum = [%d], charset enum = [%d]", integer, *nCharSet);
3328 if (*nCharSet == MIME_UNKNOWN) {
3329 MSG_DEBUG("MmsGetBinaryType fail..");
3330 *nCharSet = MSG_CHARSET_UNKNOWN;
3340 * Decode EncodedString
3342 * @param pEncodedData [in] QuotedString encoded data
3343 * @param szBuff [out] Decoded string buffer
3344 * @param bufLen [in] Decoded buffer length
3345 * @return length of decoded string length
3347 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3349 UINT32 valueLength = 0;
3355 MSG_DEBUG(" decode string..");
3357 if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
3358 MSG_DEBUG("invalid file or buffer");
3363 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3364 * Text-string = [Quote]*TEXT End-of-string
3365 * Value-length = 0 ~ 31
3368 memset(szBuff, 0, bufLen);
3370 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3376 /* Text-string = [Quote]*TEXT End-of-string */
3378 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
3379 MSG_DEBUG("__MmsBinaryDecodeText fail.");
3386 /* Value-length Charset Text_string */
3388 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3389 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3390 goto __CATCH; /* (valueLength + valueLengthLen) */
3393 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
3396 /* There can be some error in data - no NULL -> try again with value length */
3398 pData = (char *)calloc(1, valueLength - charSetLen);
3399 if (pData == NULL) {
3400 MSG_DEBUG("pData alloc fail.");
3404 if (__MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
3405 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes fail.");
3409 strncpy(szBuff, pData, bufLen - 1);
3412 nTemp = strlen(szBuff);
3414 const char *pToCharSet = "UTF-8";
3416 UINT16 charset_code = MmsGetBinaryValue(MmsCodeCharSet, charSet);
3418 const char *pFromCharSet = MmsPluginTextConvertGetCharSet(charset_code);
3419 if (pFromCharSet == NULL || !strcmp(pFromCharSet, pToCharSet)) {
3430 if (MmsPluginTextConvert(pToCharSet, pFromCharSet, szBuff, nTemp, &pDest, &destLen) == false) {
3431 MSG_DEBUG("MmsPluginTextConvert Fail");
3434 memset(szBuff, 0x00, bufLen);
3435 snprintf(szBuff, destLen+1, "%s", pDest);
3465 * Decode Encoded Addresses
3467 * @param pEncodedData [in] QuotedString encoded data
3468 * @param pAddrLength [out] Decoded address length
3469 * @return Decoded address list
3471 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
3473 UINT32 valueLength = 0;
3477 char *pAddrStr = NULL;
3478 MsgHeaderAddress *pAddr = NULL;
3480 MSG_DEBUG("decoding address..");
3482 if (pFile == NULL) {
3483 MSG_DEBUG("invalid file or buffer");
3488 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3489 * Text-string = [Quote]*TEXT End-of-string
3490 * Value-length = 0 ~ 31
3493 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3499 /* Text-string = [Quote]*TEXT End-of-string */
3502 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3503 if (pAddrStr == NULL) {
3504 MSG_DEBUG(" __MmsBinaryDecodeText2 fail.");
3511 /* Value-length Charset Text_string */
3513 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3514 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3519 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3520 if (pAddrStr == NULL) {
3521 /* There can be some error in data - no NULL -> try again with value length */
3523 pAddrStr = (char *)calloc(1, valueLength - charSetLen);
3524 if (pAddrStr == NULL) {
3525 MSG_DEBUG("pData alloc fail.");
3529 if (__MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
3530 MSG_DEBUG(" _MmsBinaryDecodeGetLongBytes fail.");
3535 /* fixme: charset transformation */
3540 pAddr = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
3544 memset(pAddr, 0, sizeof(MsgHeaderAddress));
3545 pAddr->szAddr = pAddrStr;
3561 * Decode Encoded Pointer String
3563 * @param pEncodedData [in] Long integer encoded data
3564 * @param pLongInteger [out] Decoded long integer
3565 * @return Decoded address list
3567 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
3572 * Long-integer = Short-length Multi-octet-integer
3573 * Short-length = 0~30
3574 * Multi-octet-integer
3577 if (pFile == NULL || pLongInteger == NULL)
3582 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3588 *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
3598 * @param pEncodedData [in] filename encoded data
3599 * @param szBuff [out] filename output buffer
3600 * @param fullLength [in] full filename length
3601 * @param bufLen [in] buffer length
3602 * CAUTION: bufLen - 1
3604 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3606 char *pUTF8Buff = NULL;
3607 char *pLatinBuff = NULL;
3610 char *szSrc2 = NULL;
3614 char *pTmpBuff = NULL;
3616 memset(szBuff, 0, bufLen);
3619 pLatinBuff = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3623 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
3625 strncpy(pLatinBuff, szSrc, textLength);
3630 szSrc2 = MsgChangeHexString(pLatinBuff);
3632 strncpy(pLatinBuff, szSrc2, textLength);
3637 if (MmsIsUtf8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
3638 length = strlen(pLatinBuff);
3640 int utf8BufSize = 0;
3641 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
3642 if (utf8BufSize < 3)
3643 utf8BufSize = 3; /* min value */
3645 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
3646 if (pUTF8Buff == NULL) {
3647 MSG_DEBUG("pUTF8Buff alloc fail");
3651 if (__MsgLatin2UTF((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
3652 MSG_DEBUG("MsgLatin2UTF fail");
3658 pTmpBuff = MsgDecodeText(pLatinBuff);
3659 pUTF8Buff = pTmpBuff;
3668 * it should be kept extention even if the file name is shorten
3671 length = strlen(pUTF8Buff);
3672 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
3674 nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
3675 strncpy(szBuff, pUTF8Buff, nameLength);
3676 g_strlcat(szBuff, pExt, (gsize)bufLen);
3678 strncpy(szBuff, pUTF8Buff, bufLen - 1);
3702 /* ==========================================================
3704 M M S D E C O D I N G
3706 ==========================================================*/
3708 /* to get message body this function should be modified from message raw file. */
3709 bool MmsReadMsgBody(msg_message_id_t msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
3712 MmsMsg *pMsg = NULL;
3713 MsgMultipart *pMultipart = NULL;
3715 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
3716 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
3720 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
3721 memset(pMsg, 0, sizeof(MmsMsg));
3725 if (bRetrieved && (retrievedPath != NULL)) {
3726 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
3728 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath, sizeof(szFullPath));
3731 pMsg->msgID = msgID;
3733 /* read from MMS raw file */
3734 strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
3736 MSG_SEC_DEBUG("msg_id = [%d]", msgID);
3737 MSG_SEC_DEBUG("raw file path = [%s]", szFullPath);
3739 if (MsgGetFileSize(szFullPath, &nSize) == false) {
3740 MSG_FATAL("Fail MsgGetFileSize");
3744 pFile = MsgOpenFile(szFullPath, "rb");
3745 if (pFile == NULL) {
3746 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
3750 MmsRegisterDecodeBuffer();
3752 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
3753 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
3757 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
3758 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
3762 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
3764 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
3765 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
3767 { /* attribute convert mmsHeader -> mmsAttribute */
3768 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
3770 pMsg->mmsAttrib.date = mmsHeader.date;
3772 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
3773 pMsg->mmsAttrib.bAskDeliveryReport = true;
3776 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
3778 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
3780 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
3782 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
3784 pMsg->mmsAttrib.msgType = mmsHeader.type;
3786 pMsg->mmsAttrib.version = mmsHeader.version;
3788 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
3790 pMsg->mmsAttrib.priority = mmsHeader.priority;
3792 if (mmsHeader.readReply == MMS_REPORT_YES) {
3793 pMsg->mmsAttrib.bAskReadReply = true;
3796 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
3798 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
3800 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
3802 /* FIXME:: mmsHeader will release after delete global mmsHeader */
3803 /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
3805 if (pMsg->msgBody.pPresentationBody) {
3806 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
3809 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
3810 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
3813 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
3816 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
3821 MsgCloseFile(pFile);
3824 pMsg->nPartCount = 0;
3826 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
3827 pMultipart = pMsg->msgBody.body.pMultipart;
3828 while (pMultipart) {
3830 pMultipart = pMultipart->pNext;
3833 if (pMsg->msgBody.size > 0)
3837 /* make temporary */
3838 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
3840 if (MsgIsMultipart(pMsg->msgType.type) == true) {
3842 pMultipart = pMsg->msgBody.body.pMultipart;
3844 if (bSavePartsAsTempFiles) {
3845 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3846 if (errno == EEXIST) {
3847 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
3849 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3853 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
3857 if (pMsg->msgBody.pPresentationBody) {
3858 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
3859 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3863 while (pMultipart) {
3864 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
3865 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
3868 MmsPrintMulitpart(pMultipart, partIndex);
3870 pMultipart = pMultipart->pNext;
3874 } else { /* single part */
3875 if (pMsg->nPartCount > 0) {
3876 if (bSavePartsAsTempFiles) {
3877 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3878 if (errno == EEXIST) {
3879 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
3881 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3885 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
3889 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
3890 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3894 MSG_DEBUG("### Success ###");
3901 MmsUnregisterDecodeBuffer();
3903 if (pFile != NULL) {
3904 MsgCloseFile(pFile);
3909 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
3911 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
3913 MSG_DEBUG("### Fail ###");
3918 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
3920 MsgHeaderAddress *pTempAddr = NULL;
3922 while (pAddr != NULL) {
3924 pAddr = pAddr->pNext;
3926 if (pTempAddr->szAddr) {
3927 free(pTempAddr->szAddr);
3928 pTempAddr->szAddr = NULL;
3938 static bool __MsgCheckFileNameHasInvalidChar(char *szName)
3943 strLen = strlen(szName);
3945 for (i = 0; i < strLen; i++) {
3946 if (__MsgIsInvalidFileNameChar(szName[i]))
3953 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
3956 int totalLength = 0;
3958 totalLength = strlen(szInText);
3960 while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
3961 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
3962 if (__MsgIsInvalidFileNameChar(szInText[nCount]))
3963 *(szInText+nCount) = replaceChar;
3974 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter)
3976 char *pszBuffer = NULL;
3977 char *pszStrDelimiter = NULL;
3981 MSG_DEBUG("pszString == NULL");
3985 if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
3986 MSG_DEBUG("There is no %c in %s. \n", delimiter, pszString);
3990 bufLength = pszStrDelimiter - pszString;
3992 if ((pszBuffer = (char*)calloc(1, bufLength + 1)) == NULL) {
3993 MSG_DEBUG("calloc is failed");
3996 memset(pszBuffer, 0, bufLength + 1) ;
3998 strncat(pszBuffer, pszString, bufLength);
4003 char *MsgChangeHexString(char *pOrg)
4006 char szBuf[10] = {0, };
4015 cLen = strlen(pOrg);
4017 pNew = (char *)calloc(1, cLen + 1);
4021 memset(pNew, 0, cLen + 1);
4023 for (cIndex = 0; cIndex< cLen ; cIndex++) {
4024 if (pOrg[cIndex] == '%') {
4025 if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0) {
4026 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); /* read two chars after '%' */
4028 if (__MsgIsHexChar(szBuf) == true) { /* check the two character is between 0 ~ F */
4029 OneChar = __MsgConvertHexValue(szBuf);
4031 pNew[index] = OneChar;
4038 pNew[index++] = pOrg[cIndex];
4043 static bool __MsgParseParameter(MsgType *pType, char *pSrc)
4046 char *pValue = NULL;
4049 char *pNextParam = NULL;
4053 char *pTempNextParam = NULL;
4056 char *pUTF8Buff = NULL;
4058 while (pSrc != NULL) {
4059 pSrc = __MsgSkipWS(pSrc);
4061 /* End of parse parameter */
4066 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
4069 if (*pCh == MSG_CH_QUOT) {
4076 for (; pCh <= pTempNextParam ; pCh++) {
4077 if (*pCh == MSG_CH_QUOT)
4078 if (*(pCh - 1) != '\\')
4083 pNextParam = pTempNextParam;
4086 *pNextParam++ = MSG_CH_NULL;
4088 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
4089 *pName++ = MSG_CH_NULL;
4091 if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
4092 *pValue++ = MSG_CH_NULL;
4094 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
4095 *pTest = MSG_CH_NULL;
4097 pDec = MsgDecodeText(pValue); /* Api is to long, consider Add to another file (MsgMIMECodec.c) */
4099 pDec = MsgDecodeText(pName);
4103 switch (MmsGetTextType(MmsCodeParameterCode, pSrc)) {
4104 case MSG_PARAM_BOUNDARY:
4105 /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
4106 memset(pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
4107 strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
4108 MSG_SEC_INFO("szBoundary = [%s]", pType->param.szBoundary);
4111 case MSG_PARAM_CHARSET:
4112 pType->param.charset = MmsGetTextType(MmsCodeParameterCode, pDec);
4114 if (pType->param.charset == -1)
4115 pType->param.charset = MSG_CHARSET_UNKNOWN;
4117 MSG_SEC_INFO("type = %d [charset] = %d", pType->type, pType->param.charset);
4120 case MSG_PARAM_NAME:
4121 memset(pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
4123 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4126 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4127 if ((MSG_LOCALE_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4128 nameLen = (MSG_LOCALE_FILENAME_LEN_MAX-1) - strlen(pExt);
4130 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4133 strncpy(pType->param.szName, pUTF8Buff, nameLen);
4134 g_strlcat(pType->param.szName, pExt, sizeof(pType->param.szName));
4136 strncpy(pType->param.szName, pUTF8Buff, (MSG_LOCALE_FILENAME_LEN_MAX-1));
4141 if (__MsgChangeSpace(pType->param.szName, &szSrc) == true) {
4143 strncpy(pType->param.szName, szSrc , strlen(szSrc));
4151 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4152 __MsgRemoveFilePath(pType->param.szName);
4154 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4157 MSG_SEC_INFO("szName = %s", pType->param.szName);
4160 case MSG_PARAM_FILENAME:
4161 memset(pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
4163 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4166 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4167 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4168 nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
4170 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4173 strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
4174 g_strlcat (pType->param.szFileName, pExt, sizeof(pType->param.szFileName));
4176 strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
4181 if (__MsgChangeSpace(pType->param.szFileName, &szSrc) == true) {
4182 snprintf(pType->param.szFileName, sizeof(pType->param.szFileName), "%s", szSrc);
4190 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4191 __MsgRemoveFilePath(pType->param.szFileName);
4193 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4196 MSG_SEC_INFO("szFileName = %s", pType->param.szFileName);
4200 case MSG_PARAM_TYPE:
4201 /* type/subtype of root. Only if content-type is multipart/related */
4202 pType->param.type = MimeGetMimeIntFromMimeString(pDec);
4203 MSG_SEC_INFO("type = %d", pType->param.type);
4207 case MSG_PARAM_START:
4208 /* Content-id. Only if content-type is multipart/related */
4209 memset(pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
4210 strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
4212 MSG_SEC_INFO("szStart = %s", pType->param.szStart);
4216 case MSG_PARAM_START_INFO:
4217 /* Only if content-type is multipart/related */
4218 memset(pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
4219 strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
4221 MSG_SEC_INFO("szStartInfo = %s", pType->param.szStartInfo);
4225 case MSG_PARAM_REPORT_TYPE:
4226 /* only used as parameter of Content-Type: multipart/report; report-type=delivery-status; */
4227 if (strcasecmp(pDec, "delivery-status") == 0) {
4228 pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
4230 pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
4233 MSG_SEC_INFO("reportType = %s", pDec);
4237 MSG_DEBUG("Unknown paremeter (%s)", pDec);
4250 static char *__MsgSkipWS(char *s)
4253 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
4255 } else if ((*s != '(') || (__MsgSkipComment(s, (long)NULL) == NULL)) {
4261 static char *__MsgSkipComment(char *s, long trim)
4267 /* ignore empty space */
4268 for (ret = ++s1; *ret == ' '; ret++)
4271 /* handle '(', ')', '\', '\0' */
4275 if (!__MsgSkipComment(s1, (long)NULL))
4307 static char *__MsgConvertLatin2UTF8FileName(char *pSrc)
4309 char *pUTF8Buff = NULL;
4310 /* char *pData = NULL; */
4313 /* convert utf8 string */
4314 if (MmsIsUtf8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
4316 int utf8BufSize = 0;
4318 length = strlen(pSrc);
4319 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
4320 if (utf8BufSize < 3)
4321 utf8BufSize = 3; /* min value */
4323 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
4325 if (pUTF8Buff == NULL) {
4326 MSG_DEBUG("pUTF8Buff alloc fail");
4330 if (__MsgLatin2UTF((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
4331 MSG_DEBUG("MsgLatin2UTF fail");
4335 int length = strlen(pSrc);
4336 pUTF8Buff = (char *)calloc(1, length+1);
4338 if (pUTF8Buff == NULL) {
4339 MSG_DEBUG("pUTF8Buff alloc fail");
4343 memcpy(pUTF8Buff, pSrc, length);
4346 /* convert hex string */
4348 if (__MsgIsPercentSign(pUTF8Buff) == true) {
4349 pData = MsgChangeHexString(pUTF8Buff);
4369 static bool __MsgChangeSpace(char *pOrg, char **ppNew)
4379 cLen = strlen(pOrg);
4381 pNew = (char *)calloc(1, cLen + 1);
4385 memset(pNew, 0, cLen + 1);
4387 for (cIndex=0; cIndex < cLen; cIndex++) {
4388 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
4394 pNew[index++] = pOrg[cIndex];
4402 static void __MsgRemoveFilePath(char *pSrc)
4404 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4406 char *tmp_name = NULL;
4408 tmp_name = MsgGetFileName(pSrc);
4410 snprintf(pSrc, strlen(tmp_name), "%s", tmp_name);
4415 /* Remove additional file information
4416 * ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
4417 * if "?size=" exist, insert NULL char. */
4418 pTemp = strcasestr(pSrc, "?size=");
4424 static bool __MsgIsPercentSign(char *pSrc)
4429 pCh = strchr(pSrc , '%');
4441 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam)
4443 char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
4444 char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
4445 char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
4448 /* remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445> */
4449 if (szStart && szStart[0]) {
4451 startLen = strlen(szStart);
4452 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
4453 strncpy(szTmpStart, &szStart[1], startLen - 2);
4455 strncpy(szTmpStart, szStart, startLen);
4459 /* remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445> */
4460 if (multipartType->szContentID[0]) {
4461 strLen = strlen(multipartType->szContentID);
4462 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
4463 strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
4465 strncpy(szTmpContentID, multipartType->szContentID, strLen);
4469 /* remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445> */
4470 if (multipartType->szContentLocation[0]) {
4471 strLen = strlen(multipartType->szContentLocation);
4472 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
4473 strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
4475 strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
4479 if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
4480 return MSG_PRESENTATION_NONE;
4482 /* exception handling */
4483 if (szTmpStart[0] != '\0') {
4484 /* presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type */
4485 if (strcmp(szTmpStart, szTmpContentID) == 0) {
4486 return MSG_PRESENTATION_ID;
4487 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
4488 return MSG_PRESENTATION_LOCATION;
4489 } else if (multipartType->type == typeParam) {
4490 return MSG_PRESENTATION_TYPE_BASE;
4492 return MSG_PRESENTATION_NONE;
4495 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
4496 return MSG_PRESENTATION_TYPE_BASE;
4498 return MSG_PRESENTATION_NONE;
4503 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
4506 MsgMultipart *pNextPart = NULL;
4507 MsgMultipart *pRemovePart = NULL;
4509 if (__MsgIsMultipartRelated(pMsgType->type)) {
4510 /* assign the multipart to presentation part */
4511 /* remove the multipart(pCurPresentation) which is presentation part from the linked list. */
4512 /* if there is no presentation part -> assign first multipart to presentation part by force. */
4513 if (pPresentationInfo->pCurPresentation == NULL) {
4514 pPresentationInfo->pCurPresentation = pMsgBody->body.pMultipart;
4515 pPresentationInfo->pPrevPart = NULL;
4516 pPresentationInfo->factor = MSG_PRESENTATION_NONE;
4519 if (pPresentationInfo->pCurPresentation != NULL && __MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
4520 /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
4521 * In this case, COPY the Presentation part and leave other multiparts.
4523 memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4524 pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
4526 /* remove pCurPresentation from multipart linked list */
4527 if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE) || (pPresentationInfo->pPrevPart == NULL)) {
4529 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
4530 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4531 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4532 if (pPresentationInfo->pCurPresentation) {
4533 MmsReleaseMsgDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
4535 free(pPresentationInfo->pCurPresentation);
4536 pPresentationInfo->pCurPresentation = NULL;
4539 /* not a first part */
4540 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
4541 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4542 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4543 if (pPresentationInfo->pCurPresentation) {
4544 free(pPresentationInfo->pCurPresentation);
4545 pPresentationInfo->pCurPresentation = NULL;
4548 } else if (pPresentationInfo->pCurPresentation != NULL && MmsIsTextType(pPresentationInfo->pCurPresentation->type.type)) {
4549 /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
4550 * In this case, leave the Presentation part as a multipart and remove other multiparts.
4553 /* Backup the multipart link information */
4554 pNextPart = pMsgBody->body.pMultipart;
4556 /* Copy presentation part as a main part */
4557 memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4558 memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
4560 /* Remove multipart linked list */
4562 pRemovePart = pNextPart;
4563 pNextPart = pNextPart->pNext;
4565 if (pRemovePart->pBody) {
4566 MmsReleaseMsgBody(pRemovePart->pBody, pRemovePart->type.type);
4567 free(pRemovePart->pBody);
4568 pRemovePart->pBody = NULL;
4575 MmsReleaseMsgDRMInfo(&pMsgBody->presentationType.drmInfo);
4577 MmsInitMsgType(&pMsgBody->presentationType);
4578 pMsgBody->pPresentationBody = NULL;
4584 static bool __MsgIsMultipartRelated(int type)
4586 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
4593 static bool __MsgIsPresentablePart(int type)
4595 if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
4602 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
4605 MsgMultipart *pTmpMultipart = NULL;
4606 MsgMultipart *pSelectedPart = NULL;
4607 MsgMultipart *pPrevPart = NULL;
4608 MsgMultipart *pFirstPart = NULL;
4609 MsgMultipart *pLastPart = NULL;
4610 MsgMultipart *pRemoveList = NULL;
4611 MsgMultipart *pNextRemovePart = NULL;
4613 switch (pPartType->type) {
4614 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
4615 case MIME_MULTIPART_ALTERNATIVE:
4618 * Policy: multipart/alternative
4619 * multipart/alternative message has only several parts of media.
4620 * You should choose one of them and make the alternative part
4621 * to the selected media part.
4624 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE");
4626 pSelectedPart = pPartBody->body.pMultipart;
4628 /* NULL Pointer check!! */
4629 if (pSelectedPart == NULL) {
4630 MSG_DEBUG("multipart(ALTERNATIVE) does not exist");
4634 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4636 while (pTmpMultipart) {
4637 if (pSelectedPart->type.type <= pTmpMultipart->type.type)
4638 pSelectedPart = pTmpMultipart;
4640 pTmpMultipart = pTmpMultipart->pNext;
4643 pTmpMultipart = pPartBody->body.pMultipart;
4646 while (pTmpMultipart) {
4647 if (pSelectedPart == pTmpMultipart)
4650 pPrevPart = pTmpMultipart;
4651 pTmpMultipart = pTmpMultipart->pNext;
4654 if (pPrevPart == NULL) {
4655 /* selected part is the first part */
4656 pRemoveList = pSelectedPart->pNext;
4658 pPrevPart->pNext = pSelectedPart->pNext;
4659 pRemoveList = pPartBody->body.pMultipart;
4660 pPartBody->body.pMultipart = pSelectedPart;
4663 pSelectedPart->pNext = NULL;
4666 MmsReleaseMsgDRMInfo(&pRemoveList->type.drmInfo);
4668 MmsReleaseMsgBody(pRemoveList->pBody, pRemoveList->type.type);
4670 free(pRemoveList->pBody);
4674 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4675 MSG_DEBUG("MsgPriorityCopyMsgType failed");
4679 if (pSelectedPart->pBody != NULL)
4680 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4682 if (pSelectedPart != NULL) {
4683 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4685 if (pSelectedPart->pBody != NULL) {
4686 free(pSelectedPart->pBody);
4687 pSelectedPart->pBody = NULL;
4689 free(pSelectedPart);
4690 pSelectedPart = NULL;
4695 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
4696 case MIME_MULTIPART_RELATED:
4698 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_RELATED");
4700 pSelectedPart = pPartBody->body.pMultipart;
4702 while (pSelectedPart) {
4703 if (__MsgIsMultipartMixed(pSelectedPart->type.type)) {
4704 if (pSelectedPart->pBody == NULL) {
4705 MSG_DEBUG("pSelectedPart->pBody(1) is NULL");
4709 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4711 if (pFirstPart == NULL) {
4712 MSG_DEBUG("multipart(RELATED) does not exist");
4716 if (pFirstPart->pNext) {
4717 pLastPart = pFirstPart->pNext;
4718 while (pLastPart->pNext)
4719 pLastPart = pLastPart->pNext;
4721 pLastPart = pFirstPart;
4724 if (pPrevPart == NULL) {
4725 /* the first part */
4726 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4727 pPartBody->body.pMultipart = pFirstPart;
4728 pLastPart->pNext = pTmpMultipart;
4730 pTmpMultipart = pSelectedPart->pNext;
4731 pPrevPart->pNext = pFirstPart;
4732 pLastPart->pNext = pTmpMultipart;
4735 if (pSelectedPart) {
4736 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4738 free(pSelectedPart->pBody);
4739 free(pSelectedPart);
4741 pSelectedPart = pTmpMultipart;
4742 } else if (__MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
4743 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
4744 MmsReleaseMsgBody(pSelectedPart->pBody, pSelectedPart->type.type);
4746 free(pSelectedPart->pBody);
4747 free(pSelectedPart);
4748 pSelectedPart = pTmpMultipart;
4750 pPrevPart = pSelectedPart;
4751 pSelectedPart = pSelectedPart->pNext;
4758 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
4759 case MIME_MULTIPART_MIXED:
4761 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_MIXED");
4764 pSelectedPart = pPartBody->body.pMultipart;
4766 while (pSelectedPart) {
4767 if (MsgIsMultipart(pSelectedPart->type.type)) {
4768 if (pSelectedPart->pBody == NULL) {
4769 MSG_DEBUG("pSelectedPart->pBody(2) is NULL");
4773 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4775 /* NULL Pointer check!! */
4776 if (pFirstPart == NULL) {
4777 MSG_DEBUG("multipart does not exist");
4781 if (pFirstPart->pNext) {
4782 pLastPart = pFirstPart->pNext;
4783 while (pLastPart->pNext)
4784 pLastPart = pLastPart->pNext;
4786 pLastPart = pFirstPart;
4789 if (pPrevPart == NULL) {
4790 /* the first part */
4791 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4792 pPartBody->body.pMultipart = pFirstPart;
4793 pLastPart->pNext = pTmpMultipart;
4795 pTmpMultipart = pSelectedPart->pNext;
4796 pPrevPart->pNext = pFirstPart;
4797 pLastPart->pNext = pTmpMultipart;
4800 if (pSelectedPart->pBody->pPresentationBody)
4801 pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
4803 memcpy(&pPartBody->presentationType,
4804 &pSelectedPart->pBody->presentationType, sizeof(MsgType));
4806 pPartType->type = pSelectedPart->type.type;
4808 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4810 free(pSelectedPart->pBody);
4811 free(pSelectedPart);
4813 pSelectedPart = pTmpMultipart;
4815 pPrevPart = pSelectedPart;
4816 pSelectedPart = pSelectedPart->pNext;
4822 case MIME_MULTIPART_REPORT:
4824 MSG_DEBUG("MIME_MULTIPART_REPORT");
4826 pTmpMultipart = pPartBody->body.pMultipart;
4829 if (pTmpMultipart == NULL) {
4830 MSG_DEBUG("pTmpMultipart == NULL");
4834 while (pTmpMultipart) {
4835 if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
4836 pSelectedPart = pTmpMultipart;
4840 pPrevPart = pTmpMultipart;
4841 pTmpMultipart = pTmpMultipart->pNext;
4844 if (pSelectedPart == NULL) {
4845 MSG_DEBUG("MIME_MULTIPART_REPORT [no selected part]");
4847 pRemoveList = pPartBody->body.pMultipart->pNext;
4848 if (pPartBody->body.pMultipart != NULL) {
4849 pSelectedPart = pPartBody->body.pMultipart;
4850 pSelectedPart->pNext = NULL;
4853 if (pPrevPart == NULL) {
4854 /* first part is selected */
4855 pRemoveList = pPartBody->body.pMultipart->pNext;
4857 pRemoveList = pPartBody->body.pMultipart->pNext;
4858 pPrevPart->pNext = pSelectedPart->pNext;
4861 pSelectedPart->pNext = NULL;
4862 pPartBody->body.pMultipart = pSelectedPart;
4865 pTmpMultipart = pRemoveList;
4867 while (pTmpMultipart) {
4868 MmsReleaseMsgDRMInfo(&pTmpMultipart->type.drmInfo);
4870 MmsReleaseMsgBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
4871 pNextRemovePart = pTmpMultipart->pNext;
4873 free(pTmpMultipart->pBody);
4874 free(pTmpMultipart);
4875 pTmpMultipart = pNextRemovePart;
4878 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4879 MSG_DEBUG("MsgPriorityCopyMsgType failed");
4883 if (pSelectedPart != NULL) {
4884 if (pSelectedPart->pBody != NULL)
4885 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4887 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4889 if (pSelectedPart->pBody != NULL) {
4890 free(pSelectedPart->pBody);
4891 pSelectedPart->pBody = NULL;
4893 free(pSelectedPart);
4894 pSelectedPart = NULL;
4910 char *MsgResolveContentURI(char *szSrc)
4912 char *szTemp = NULL;
4913 char *szReturn = NULL;
4916 if (szSrc == NULL) {
4920 if (szSrc[0] == '\0')
4924 if (!strncasecmp(szSrc, "cid:", 4)) {
4925 length = strlen(szSrc) - 3;
4928 length = strlen(szSrc) + 1;
4931 szTemp = (char *)calloc(1, length);
4932 if (szTemp == NULL) {
4933 MSG_DEBUG("memory full");
4937 memset(szTemp, 0, length);
4939 strncpy(szTemp, szSrc, length - 1);
4941 szReturn = MsgChangeHexString(szTemp);
4955 char *MsgRemoveQuoteFromFilename(char *pSrc)
4957 int cLen = 0; /* length of pBuff */
4961 MSG_DEBUG("pSrc is Null");
4965 cLen = strlen(pSrc);
4967 pBuff = (char *)calloc(1, cLen + 1);
4969 if (pBuff == NULL) {
4970 MSG_DEBUG("pBuff mem alloc fail!");
4973 memset(pBuff, 0 , sizeof(char)*(cLen + 1));
4975 /* remove front quote */
4976 if (pSrc[0] == MSG_CH_QUOT) {
4978 strncpy(pBuff, &pSrc[1], cLen);
4980 } else if (pSrc[0] == MSG_CH_LF) {
4982 strncpy(pBuff, &pSrc[1], cLen);
4984 strncpy(pBuff, pSrc, cLen);
4987 /* remove last qoute */
4988 if (pBuff[cLen-1] == MSG_CH_QUOT) {
4989 pBuff[cLen-1] = '\0';
4995 bool MsgIsMultipart(int type)
4997 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
4998 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
4999 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
5007 static bool __MsgIsHexChar(char *pSrc)
5013 cLen = strlen(pSrc);
5015 for (cIndex = 0; cIndex < cLen ; cIndex++) {
5016 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
5017 (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
5027 static char __MsgConvertHexValue(char *pSrc)
5033 unsigned char uCh[2] = {0, };
5035 cLen = strlen(pSrc);
5037 for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
5038 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
5039 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
5040 ch = (int)uCh[0] << 4 | uCh[1];
5043 ResultChar = (char)ch;
5048 static int __MsgConvertCharToInt(char ch)
5050 if (ch >= '0' && ch <= '9') {
5052 } else if (ch >= 'a' && ch <= 'f') {
5054 } else if (ch >= 'A' && ch <= 'F') {
5061 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
5063 if (!pMsgType1 || !pMsgType2)
5066 /* if (pMsgType1->section == INVALID_HOBJ) */
5067 pMsgType1->section = pMsgType2->section;
5071 if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
5072 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
5075 if (pMsgType1->szContentID[0] == '\0') {
5076 snprintf(pMsgType1->szContentID, sizeof(pMsgType1->szContentID), "%s", pMsgType2->szContentID);
5079 if (pMsgType1->szContentID[0] != '\0') {
5080 length = strlen(pMsgType1->szContentID);
5081 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
5082 char szTempString[MSG_MSG_ID_LEN + 1];
5083 MmsRemoveLessGreaterChar(pMsgType1->szContentID, szTempString, sizeof(szTempString));
5084 pMsgType1->drmInfo.szContentURI = g_strdup(szTempString);
5086 pMsgType1->drmInfo.szContentURI = g_strdup(pMsgType1->szContentID);
5090 if (pMsgType1->szContentLocation[0] == '\0') {
5091 strncpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation, MSG_MSG_ID_LEN);
5094 /* Copy informations - we shoud open the pMsgType2's orgFile
5095 * concerning its offset and size.
5097 if (pMsgType2->szOrgFilePath[0] != '\0') {
5098 strncpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath, MSG_FILEPATH_LEN_MAX-1);
5101 if (pMsgType2->disposition != -1)
5102 pMsgType1->disposition = pMsgType2->disposition;
5104 if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
5105 pMsgType2->encoding != -1)
5106 pMsgType1->encoding = pMsgType2->encoding;
5108 pMsgType1->contentSize = pMsgType2->contentSize;
5109 pMsgType1->offset = pMsgType2->offset;
5110 pMsgType1->size = pMsgType2->size;
5111 pMsgType1->type = pMsgType2->type;
5113 __MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
5115 if (pMsgType1->param.szName[0]) {
5116 pMsgType1->drmInfo.szContentName = g_strdup(pMsgType2->param.szName);
5122 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
5124 if (pParam1->charset == MSG_CHARSET_UNKNOWN)
5125 pParam1->charset = pParam2->charset;
5127 if (pParam1->type == MIME_UNKNOWN)
5128 pParam1->type = pParam2->type;
5130 /* Don't copy pParam2->pPresentation */
5132 /* For alternative: copy the boundary string */
5133 if (pParam2->szBoundary[0] !='\0') {
5134 strncpy(pParam1->szBoundary, pParam2->szBoundary, MSG_BOUNDARY_LEN);
5137 if (pParam1->szFileName[0] =='\0') {
5138 strncpy(pParam1->szFileName, pParam2->szFileName, MSG_FILENAME_LEN_MAX);
5141 if (pParam1->szName[0] =='\0') {
5142 strncpy(pParam1->szName, pParam2->szName, MSG_LOCALE_FILENAME_LEN_MAX);
5145 if (pParam1->szStart[0] =='\0') {
5146 strncpy(pParam1->szStart, pParam2->szStart, MSG_MSG_ID_LEN);
5149 if (pParam1->szStartInfo[0] =='\0') {
5150 strncpy(pParam1->szStartInfo, pParam2->szStartInfo, MSG_MSG_ID_LEN);
5155 static bool __MsgIsMultipartMixed(int type)
5157 if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
5164 static bool __MsgIsInvalidFileNameChar(char ch)
5166 if ((ch == 0x5C /* \ */) ||
5167 (ch == 0x2F /* / */) ||
5168 (ch == 0x3A /* : */) ||
5169 (ch == 0x2A /* * */) ||
5170 (ch == 0x3F /* ? */) ||
5171 (ch == 0x22 /* " */) ||
5172 (ch == 0x3C /* < */) ||
5173 (ch == 0x3E /* > */) ||
5174 (ch == 0x7C /* | */))
5180 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
5184 MSG_DEBUG("---------------");
5186 if ((szSrc == NULL) || (nChar <= 0)) {
5187 MSG_DEBUG("szSrc is NULL !!!! ---------------");
5191 while ((nChar > 0) && (*szSrc != '\0')) {
5192 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5206 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5209 unsigned char t1, t2;
5211 MSG_DEBUG("---------------");
5214 outBufSize--; /* NULL character */
5216 while ((nChar > 0) && (*szSrc != '\0')) {
5217 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5218 /* check outbuffer's room for this UTF8 character */
5223 *des = (unsigned char) (*szSrc & 0x007F);
5229 /* check outbuffer's room for this UTF8 character */
5235 t2 = (unsigned char) (*szSrc & 0x003F); /* right most 6 bit */
5236 t1 = (unsigned char) ((*szSrc & 0xC0) >> 6); /* right most 2 bit */
5238 *des = 0xC0 | (t1 & 0x1F);
5239 *(des + 1) = 0x80 | (t2 & 0x3F);
5253 bool MmsAddrUtilCheckEmailAddress(char *pszAddr)
5255 if (!pszAddr || pszAddr[0] == 0)
5258 if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
5264 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
5266 char *pszAddrCopy = NULL;
5267 char *pszStrStart = NULL;
5268 char *pszStrTemp = NULL;
5271 if ((!pszAddr) || (pszAddr[0] == 0)) {
5272 MSG_DEBUG("pszAddr is null or zero");
5276 strLen = strlen(pszAddr);
5278 pszAddrCopy = (char*)calloc(1, strLen + 1);
5280 MSG_DEBUG("pszAddrCopy is NULL, mem alloc failed");
5284 strncpy(pszAddrCopy, pszAddr, strLen);
5287 pszStrStart = pszAddrCopy;
5290 char* pszStrEnd = NULL;
5293 if (MmsAddrUtilCheckEmailAddress(pszAddrCopy))
5294 pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
5296 pszStrEnd = strstr(pszStrStart, "/");
5299 char *pszStart = NULL;
5300 char *pszEnd = NULL;
5301 /* "/TYPE=PLMN" not found */
5303 int remainedLen = strlen(pszStrStart);
5305 if (remainedLen <= 0)
5308 /* Email address can occur with Sender Name<email-address> format */
5309 /* remove the Sender name and only retain the email address. */
5310 pszStart = strstr(pszStrStart, "<");
5312 pszEnd = strstr(pszStrStart, ">");
5315 pszStart++; /* skip "<" */
5316 g_strlcat(pszAddr, pszStart, pszEnd - pszStart + 1);
5321 g_strlcat(pszAddr, pszStrStart, strLen + 1);
5325 /* Get one address length */
5326 addressLen = pszStrEnd - pszStrStart;
5328 strncat(pszAddr, pszStrStart, addressLen);
5330 /* Find next address */
5331 pszStrStart = pszStrEnd;
5333 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
5336 addressLen = pszStrTemp - pszStrEnd;
5337 pszStrStart += addressLen;
5339 pszStrStart += strlen(pszStrEnd);
5342 if (pszStrStart[0] == 0) /* end of string */
5346 g_strlcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER, strLen + 1); /* add ';' */
5347 pszStrStart++; /* remove ';' */
5350 if (pszAddr[0] == 0)
5351 strncpy(pszAddr, pszAddrCopy, strLen);
5358 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5362 MSG_DEBUG("---------------");
5365 outBufSize--; /* NULL character */
5367 while ((nChar > 0) && (*szSrc != '\0')) {
5368 if (*szSrc < 0x80) {
5376 } else if (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
5382 *(des + 1) = *(szSrc + 1);
5386 } else if ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
5392 *(des + 1) = *(szSrc + 1);
5393 *(des + 2) = *(szSrc + 2);
5405 MSG_DEBUG("utf8 incorrect range!");
5417 static void __MsgMIMERemoveQuote(char *szSrc)
5421 length = strlen(szSrc);
5422 if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
5425 for (index = 0; index < length-2; index++)
5426 szSrc[index] = szSrc[index+1];
5427 szSrc[index] = '\0';
5431 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
5437 if (pFile == NULL) {
5444 if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
5451 if (*pBufLen == 0) {
5452 length = maxLen - (*pPtr);
5454 length = (*pBufLen) - (*pPtr);
5460 if ((*ppBuf) == NULL) {
5461 memset(pInBuf1, 0, maxLen);
5463 } else if ((*ppBuf) == pInBuf1) {
5464 memset(pInBuf2, 0, maxLen);
5466 memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
5469 memset(pInBuf1, 0, maxLen);
5471 memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
5477 if (*pOffset == endOfFile) {
5482 if (maxLen == length) {
5484 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
5489 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
5492 *pBufLen = length + nRead;
5495 if ((*pOffset = MsgFtell(pFile)) == -1L) {
5496 MSG_DEBUG("MsgFtell Error");
5506 * This function write media data from raw data to file.
5509 * @param pszMailboxPath : path of mailbox
5510 * @param pszMsgFilename : name of msg file
5511 * @param index : used for file naming
5512 * @param bSave : if true, file will be save otherwise just filename will be stored.
5514 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
5517 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, }; /* file name of temp file */
5518 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; /* full absolute path of temp file. */
5519 bool bFileExist = false;
5523 MSG_DEBUG("pPartType is NULL");
5527 if (pPartType->type == MIME_APPLICATION_SMIL) {
5528 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", "smil.txt");
5530 if (pPartType->param.szName[0] != '\0') {
5531 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szName);
5532 } else if (pPartType->param.szFileName[0] != '\0') {
5533 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szFileName);
5534 } else if (pPartType->szContentLocation[0] != '\0') {
5535 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->szContentLocation);
5537 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
5541 /* make full path for save */
5542 __MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0, szFileName, sizeof(szFileName)); /* FL & CD -> extension(.dm) SD -> extension(.dcf) */
5544 snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName); /* get absolute path of each temp file of each part */
5546 if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
5547 MsgGetMimeTypeFromFileName(MIME_MAINTYPE_UNKNOWN, szFullPath, (MimeType *)&pPartType->type, NULL);
5550 bFileExist = MsgAccessFile(szFullPath, F_OK);
5552 MSG_SEC_DEBUG("save flag [%d], filepath [%s], file exist [%d]", bSave, szFullPath, bFileExist);
5554 if (bSave == true && bFileExist == false) {
5555 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
5556 MSG_DEBUG("MsgOpenFile failed");
5560 if (__MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
5561 MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
5565 MsgCloseFile(pFile);
5568 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5570 /* IF DRM type Convert to dcf */
5571 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5572 || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT) {
5573 char destDrmPath[MSG_FILEPATH_LEN_MAX] = {0, };
5575 if (MsgDrmConvertDmtoDcfType(pPartBody->szOrgFilePath, destDrmPath) == true) {
5576 MSG_INFO("Success Convert to Dcf");
5578 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5581 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5582 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5586 MSG_INFO("Fail Convert to Dcf");
5589 if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5590 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5592 MSG_SEC_INFO("Drm File Path [%s] isdrm [%d]", pPartBody->szOrgFilePath, MsgDrmIsDrmFile(pPartBody->szOrgFilePath));
5595 pPartBody->offset = 0;
5596 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5598 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
5599 MsgDrmRegisterFile(MSG_MODE_FILE, pPartBody->szOrgFilePath, strlen(pPartBody->szOrgFilePath));
5601 /* change szDrm2FullPath as current content path*/
5602 if (pPartType->drmInfo.szDrm2FullPath) {
5603 free(pPartType->drmInfo.szDrm2FullPath);
5604 pPartType->drmInfo.szDrm2FullPath = g_strdup(pPartBody->szOrgFilePath);
5608 MSG_SEC_DEBUG("Save Part File to [%s]", pPartBody->szOrgFilePath);
5611 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5613 /* IF DRM type check dcf exist */
5614 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5615 || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT) {
5616 char destDrmPath[MSG_FILEPATH_LEN_MAX + 1] = {0, };
5618 MsgGetFileNameWithoutExtension(destDrmPath, pPartBody->szOrgFilePath);
5619 strncat(destDrmPath, ".dcf", 4);
5621 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5624 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5625 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5628 if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5629 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5632 pPartBody->offset = 0;
5633 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5635 MSG_SEC_DEBUG("Set Part File to [%s]", pPartBody->szOrgFilePath);
5639 if (szFileName[0] != '\0') {
5640 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. */
5641 snprintf(pPartType->param.szName, MSG_LOCALE_FILENAME_LEN_MAX+1, "%s", szFileName);
5642 MSG_SEC_DEBUG("Set Name : %s", pPartType->param.szName);
5650 if (pFile != NULL) {
5651 MsgCloseFile(pFile);
5658 bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
5663 char *pNewData = NULL;
5664 char *pTempData = NULL;
5665 int msgEncodingValue = 0;
5666 int msgTypeValue = 0;
5667 int msgCharsetValue = 0;
5672 msgEncodingValue = pPartType->encoding;
5673 msgTypeValue = pPartType->type;
5674 msgCharsetValue = pPartType->param.charset;
5676 offset = pPartBody->offset;
5677 size = pPartBody->size;
5679 if (pPartBody->szOrgFilePath[0]) {
5680 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
5682 if (pTempData == NULL) {
5683 MSG_DEBUG("pTempData read fail");
5688 } else if (pPartBody->body.pText) {
5689 pData = pPartBody->body.pText;
5690 nRead = pPartBody->size;
5693 if (pData == NULL) {
5694 MSG_DEBUG("there is no data");
5698 pNewData = __MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
5701 pPartType->encoding = MSG_ENCODING_BINARY;
5703 if (MmsIsTextType(msgTypeValue))
5704 pPartType->param.charset = MSG_CHARSET_UTF8;
5706 if (MsgWriteFile(pNewData, sizeof(char), nRead2, pFile) != (size_t)nRead2) {
5707 MSG_DEBUG("file writing fail");
5712 if (MsgWriteFile(pData, sizeof(char), nRead, pFile) != (size_t)nRead) {
5713 MSG_DEBUG("file writing fail");
5747 char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
5753 char *pConvertedStr = NULL;
5754 char *pConvertedData = NULL;
5755 char *pNewData = NULL;
5756 char *pReturnData = NULL;
5758 const char *pToCodeSet = "UTF-8";
5759 const char *pFromCodeSet = NULL;
5761 switch (msgEncodingValue) {
5762 case MSG_ENCODING_BASE64:
5764 pConvertedData = (char*)MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5765 MSG_DEBUG("MSG_ENCODING_BASE64 bodyLength [%d]", nByte);
5767 pTemp = pConvertedData;
5772 case MSG_ENCODING_QUOTE_PRINTABLE:
5774 pConvertedData = (char*)MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5775 MSG_DEBUG("MSG_ENCODING_QUOTE_PRINTABLE bodyLength [%d]", nByte);
5777 pTemp = pConvertedData;
5784 MSG_DEBUG("encoding val [%d] bodyLength [%d]", msgEncodingValue, nRead);
5791 if (MmsIsTextType(msgTypeValue)) {
5792 if (msgCharsetValue == MSG_CHARSET_US_ASCII) {
5795 } else if (msgCharsetValue == MSG_CHARSET_UTF8) {
5796 /* skip BOM(Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM) */
5798 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
5807 UINT16 MIBenum = MmsGetBinaryValue(MmsCodeCharSet, msgCharsetValue);
5809 pFromCodeSet = MmsGetTextByCode(MmsCodeCharSet, MIBenum);
5811 MSG_DEBUG("char set enum = [%d], MIBenum = [%d], str = [%s]", msgCharsetValue, MIBenum, pFromCodeSet);
5814 MSG_DEBUG("Convert to UTF-8");
5816 if (MmsPluginTextConvert(pToCodeSet, pFromCodeSet, pTemp, nTemp, &pConvertedStr, npRead) == true) {
5817 pNewData = pConvertedStr;
5819 MSG_DEBUG("Failed MmsPluginTextConvert");
5824 } else { /* unsupported charset */
5825 MSG_DEBUG("unsupported charset");
5836 pReturnData = (char *)calloc(1, *npRead);
5837 if (pReturnData == NULL) {
5838 MSG_DEBUG("pReturnData alloc fail.");
5842 if (pNewData != NULL) {
5843 memset(pReturnData, 0, *npRead);
5844 memcpy(pReturnData, pNewData, *npRead);
5847 if (pConvertedData) {
5848 free(pConvertedData);
5849 pConvertedData = NULL;
5852 if (pConvertedStr) {
5853 free(pConvertedStr);
5854 pConvertedStr = NULL;
5861 if (pConvertedData) {
5862 free(pConvertedData);
5863 pConvertedData = NULL;
5866 if (pConvertedStr) {
5867 free(pConvertedStr);
5868 pConvertedStr = NULL;
5874 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen)
5876 char szTemp[MSG_FILENAME_LEN_MAX+1] = {0, };
5877 char szTempFileName[MSG_FILENAME_LEN_MAX+1] = {0, };
5878 const char *pExt = NULL;
5880 MSG_SEC_DEBUG("Input : type [0x%x], drmType [%d], filename [%s]", iMsgType, drmType, szFileName);
5882 if (szFileName == NULL)
5886 int inp_len = strlen(szFileName);
5888 pExt = strrchr(szFileName, '.');
5890 if (pExt != NULL && *(pExt + 1) != '\0') {
5896 MsgGetFileNameWithoutExtension(szTempFileName, szFileName);
5898 if (nUntitleIndex >= 1) {
5899 snprintf(szTempFileName, sizeof(szTempFileName), "%s_%d", "untitled", nUntitleIndex);
5901 snprintf(szTempFileName, sizeof(szTempFileName), "%s", "untitled");
5906 if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_MESSAGE)
5908 else if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5911 if (pExt == NULL) { /* find ext from content type */
5912 if (iMsgType == MIME_APPLICATION_OCTET_STREAM || iMsgType == MIME_UNKNOWN) {
5913 MSG_DEBUG("unsupported MsgType [%d]", iMsgType);
5917 pExt = MimeGetExtFromMimeInt((MimeType)iMsgType);
5920 /* Filename + extension */
5922 snprintf(szTemp, sizeof(szTemp), "%s.%s", szTempFileName, pExt);
5924 MSG_DEBUG("Failed to get extension of that mime data file.");
5928 snprintf(outBuf, outBufLen, "%s", szTemp);
5929 MSG_SEC_DEBUG("Result : filename [%s]", outBuf);
5936 bool MsgGetFileNameWithoutExtension(char *szOutputName, char *szName)
5938 char *pszExt = NULL;
5940 if (szOutputName == NULL) {
5941 MSG_DEBUG("szOutputName is NULL");
5945 strncpy(szOutputName, szName, strlen(szName));
5946 szOutputName[strlen(szName)] = '\0';
5948 if ((pszExt = strrchr(szOutputName, '.'))) {
5949 if (pszExt[0] == '.')
5956 bool MsgGetFileName(char *szFilePath, char *szFileName, int size)
5958 char *filename = NULL;
5960 filename = strrchr(szFilePath, '/');
5961 if (filename != NULL) {
5962 snprintf(szFileName, size, "%s", filename + 1);
5964 snprintf(szFileName, size, "%s", szFilePath);
5973 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
5975 MmsMsg *pMsg = NULL;
5976 MsgMultipart *pPart = NULL;
5978 if (pHeader == NULL) {
5979 MSG_DEBUG("Invalid pHeader input. It's null");
5983 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
5985 MmsInitMsgType(pHeader);
5988 /* Requires header of non-presentation */
5989 if (MsgIsMultipart(pMsg->msgType.type)) {
5990 MSG_DEBUG("Multipart header [index = %d] \n", index);
5992 pPart = pMsg->msgBody.body.pMultipart;
5994 while (pPart && index--)
5995 pPart = pPart->pNext;
5997 if (pPart == NULL) {
5998 MSG_DEBUG("There is no such msg part.");
6002 memcpy(pHeader, &pPart->type, sizeof(MsgType));
6004 MSG_DEBUG("Requires singlepart header");
6005 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
6012 MmsPluginDecoder *MmsPluginDecoder::pInstance = NULL;
6014 MmsPluginDecoder *MmsPluginDecoder::instance()
6016 if (!MmsPluginDecoder::pInstance)
6017 MmsPluginDecoder::pInstance = new MmsPluginDecoder();
6019 return MmsPluginDecoder::pInstance;
6022 MmsPluginDecoder::MmsPluginDecoder() {}
6023 MmsPluginDecoder::~MmsPluginDecoder() {}
6025 void MmsPluginDecoder::decodeMmsPdu(MmsMsg *pMsg, msg_message_id_t msgID, const char *pduFilePath)
6030 MsgMultipart *pMultipart = NULL;
6032 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6033 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
6037 pMsg->msgID = msgID;
6039 snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6041 MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName));
6043 if (MsgGetFileSize(szFullPath, &nSize) == false) {
6044 MSG_FATAL("Fail MsgGetFileSize");
6048 pFile = MsgOpenFile(szFullPath, "rb");
6049 if (pFile == NULL) {
6050 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6054 MmsRegisterDecodeBuffer();
6056 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6057 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6061 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6062 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6066 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
6068 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
6069 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
6071 { /* attribute convert mmsHeader -> mmsAttribute */
6072 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
6074 pMsg->mmsAttrib.date = mmsHeader.date;
6076 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6077 pMsg->mmsAttrib.bAskDeliveryReport = true;
6080 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6082 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6084 MSG_DEBUG("@@@@@pMsg->mmsAttrib.deliveryTime=[%d]", pMsg->mmsAttrib.deliveryTime);
6086 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
6088 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
6090 pMsg->mmsAttrib.msgType = mmsHeader.type;
6092 pMsg->mmsAttrib.version = mmsHeader.version;
6094 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
6096 pMsg->mmsAttrib.priority = mmsHeader.priority;
6098 if (mmsHeader.readReply == MMS_REPORT_YES) {
6099 pMsg->mmsAttrib.bAskReadReply = true;
6102 /* TODO : fill pMsg->mmsAttrib.szCc and pMsg->mmsAttrib.szTo field */
6104 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
6106 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
6108 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
6110 /* FIXME:: mmsHeader will release after delete global mmsHeader */
6111 /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
6113 if (pMsg->msgBody.pPresentationBody) {
6114 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
6117 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
6118 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
6121 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
6124 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
6129 MsgCloseFile(pFile);
6132 pMsg->nPartCount = 0;
6134 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
6135 pMultipart = pMsg->msgBody.body.pMultipart;
6136 while (pMultipart) {
6138 pMultipart = pMultipart->pNext;
6141 if (pMsg->msgBody.size > 0)
6145 /* make temporary */
6146 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
6148 if (MsgIsMultipart(pMsg->msgType.type) == true) {
6150 pMultipart = pMsg->msgBody.body.pMultipart;
6152 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6153 if (errno == EEXIST) {
6154 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
6156 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6160 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
6163 if (pMsg->msgBody.pPresentationBody) {
6164 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
6165 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6169 while (pMultipart) {
6170 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
6171 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, true) == false)
6174 MmsPrintMulitpart(pMultipart, partIndex);
6176 pMultipart = pMultipart->pNext;
6180 } else { /* single part */
6181 if (pMsg->nPartCount > 0) {
6182 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6183 if (errno == EEXIST) {
6184 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
6186 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6190 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
6193 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
6194 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6198 MSG_DEBUG("### Success ###");
6205 MmsUnregisterDecodeBuffer();
6207 if (pFile != NULL) {
6208 MsgCloseFile(pFile);
6213 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
6215 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
6217 MSG_DEBUG("### Fail ###");
6222 /* CID 41989: Removed function decodeMmsPdu which is unused. */
6224 void MmsPluginDecoder::decodeMmsPdu(MMS_DATA_S *pMmsData, const char *pduFilePath)
6229 MsgMultipart * iter_multipart = NULL;
6231 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6235 /* pMsg->msgID = msgID; */
6237 snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6239 /* MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName)); */
6241 if (MsgGetFileSize(szFullPath, &nSize) == false) {
6242 MSG_FATAL("Fail MsgGetFileSize");
6246 pFile = MsgOpenFile(szFullPath, "rb");
6247 if (pFile == NULL) {
6248 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6252 MmsRegisterDecodeBuffer();
6254 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6255 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6259 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6260 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6265 if (pMmsData->header == NULL) {
6266 pMmsData->header = MsgMmsCreateHeader();
6269 pMmsData->header->messageType = mmsHeader.type;
6271 pMmsData->header->mmsVersion = mmsHeader.version;
6273 pMmsData->header->contentType = mmsHeader.msgType.type;
6275 pMmsData->header->date = mmsHeader.date;
6277 pMmsData->header->messageSize = mmsHeader.msgSize;
6279 pMmsData->header->mmsPriority = mmsHeader.priority;
6281 pMmsData->header->messageClass = mmsHeader.msgClass;
6283 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6284 pMmsData->header->bDeliveryReport = true;
6287 if (mmsHeader.readReply == MMS_REPORT_YES) {
6288 pMmsData->header->bReadReport = true;
6291 memcpy(&pMmsData->header->delivery, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6293 memcpy(&pMmsData->header->expiry, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6296 snprintf(pMmsData->header->messageID, sizeof(pMmsData->header->messageID), "%s", mmsHeader.szMsgID);
6298 snprintf(pMmsData->header->szSubject, sizeof(pMmsData->header->szSubject), "%s", mmsHeader.szSubject);
6300 snprintf(pMmsData->header->trID, sizeof(pMmsData->header->trID), "%s", mmsHeader.szTrID);
6302 iter_multipart = mmsHeader.msgBody.body.pMultipart;
6305 if (pMmsData->header->contentType == MIME_MULTIPART_RELATED || pMmsData->header->contentType == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
6306 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6308 pMultipart->type = MIME_APPLICATION_SMIL;
6309 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s", "application/smil");
6310 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", mmsHeader.msgBody.presentationType.szContentID);
6311 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", mmsHeader.msgBody.presentationType.szContentLocation);
6312 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", mmsHeader.msgBody.presentationType.param.szName);
6314 /* snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), MSG_DATA_PATH"%s", mmsHeader.msgBody.presentationType.param.szFileName); */
6316 MsgBody *pBody = iter_multipart->pBody;
6317 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6319 pMmsData->smil = pMultipart;
6323 while (iter_multipart) {
6324 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6326 pMultipart->type = (MimeType)iter_multipart->type.type;
6328 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s", MimeGetMimeStringFromMimeInt(iter_multipart->type.type));
6329 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", iter_multipart->type.szContentID);
6330 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", iter_multipart->type.szContentLocation);
6331 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", iter_multipart->type.param.szName);
6333 /* snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), "%s", iter_multipart->pBody->szOrgFilePath); */
6335 MsgBody *pBody = iter_multipart->pBody;
6336 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6339 #ifdef __SUPPORT_DRM__
6340 if (iter_multipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
6341 pMultipart->drmType = iter_multipart->type.drmInfo.drmType;
6345 pMmsData->multipartlist = g_list_append(pMmsData->multipartlist, pMultipart);
6346 iter_multipart = iter_multipart->pNext;
6350 MSG_DEBUG("### SUCCESS ###");
6356 MmsUnregisterDecodeBuffer();
6358 if (pFile != NULL) {
6359 MsgCloseFile(pFile);
6363 MSG_DEBUG("### Fail ###");