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 /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
507 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
508 MSG_DEBUG("MMS_CODE_FROM is invalid");
512 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
513 MSG_DEBUG("MMS_CODE_FROM GetOneByte fail");
517 /* DRM_TEMPLATE - start */
521 if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
522 if (valueLength > 0) {
523 mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
524 if (mmsHeader.pFrom == NULL) {
525 MSG_DEBUG("MMS_CODE_FROM __MmsDecodeEncodedAddress fail");
529 mmsHeader.pFrom = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
530 if (mmsHeader.pFrom == NULL)
533 mmsHeader.pFrom->szAddr = (char *)calloc(1, 1);
534 if (mmsHeader.pFrom->szAddr == NULL) {
535 free(mmsHeader.pFrom);
536 mmsHeader.pFrom = NULL;
540 mmsHeader.pFrom->szAddr[0] = '\0';
541 mmsHeader.pFrom->pNext = NULL;
544 MSG_SEC_INFO("From = [%s]", mmsHeader.pFrom->szAddr);
545 /* DRM_TEMPLATE - end */
546 } else if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
547 /* Present Token only */
548 MSG_SEC_INFO("From = [insert token]");
550 /* from data broken */
551 MSG_WARN("from addr broken");
552 gCurMmsDecodeBuffPos--;
559 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
561 MSG_DEBUG("MMS_CODE_TO __MmsDecodeEncodedAddress fail");
565 if (mmsHeader.pTo == NULL) {
567 pLastTo = mmsHeader.pTo = pAddr;
570 pLastTo->pNext = pAddr;
574 MSG_SEC_INFO("To = [%s]", pAddr->szAddr);
579 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
581 MSG_DEBUG("MMS_CODE_BCC __MmsDecodeEncodedAddress fail");
585 if (mmsHeader.pBcc == NULL) {
587 pLastBcc = mmsHeader.pBcc = pAddr;
590 pLastBcc->pNext = pAddr;
594 MSG_SEC_INFO("Bcc = [%s]", pAddr->szAddr);
599 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
601 MSG_DEBUG("MMS_CODE_CC __MmsDecodeEncodedAddress fail");
605 if (mmsHeader.pCc == NULL) {
607 pLastCc = mmsHeader.pCc = pAddr;
610 pLastCc->pNext = pAddr;
613 MSG_SEC_INFO("Cc = [%s]", pAddr->szAddr);
616 case MMS_CODE_CONTENTLOCATION:
618 if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
619 MSG_DEBUG("MMS_CODE_CONTENTLOCATION is invalid");
622 MSG_SEC_DEBUG("X-Mms-Content-Location = [%s]", mmsHeader.szContentLocation);
627 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
628 MSG_DEBUG("MMS_CODE_DATE is invalid");
632 MSG_SEC_INFO("Date = [%u][%d]", mmsHeader.date, (const time_t *)&mmsHeader.date);
635 case MMS_CODE_DELIVERYREPORT:
637 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
638 MSG_DEBUG("deliveryReport GetOneByte fail");
642 fieldValue = MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
644 if (fieldValue == 0xFFFF) {
645 MSG_DEBUG("deliveryReport error");
649 mmsHeader.deliveryReport = (MmsReport)fieldValue;
651 MSG_SEC_INFO("X-Mms-Delivery-Report =[0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.deliveryReport));
654 case MMS_CODE_DELIVERYTIME:
656 /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
658 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
659 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
663 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
664 MSG_DEBUG("delivery time GetOneByte fail");
668 /* DRM_TEMPLATE - start */
671 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
672 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
674 if (valueLength > 0) {
675 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
676 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
680 /* DRM_TEMPLATE - end */
682 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
684 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
685 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
689 MSG_SEC_INFO("X-Mms-Delivery-Time : type = [%d], time= [%u]", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
692 case MMS_CODE_EXPIRYTIME:
694 /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
696 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
697 MSG_DEBUG("invalid MMS_CODE_EXPIRYTIME");
701 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
702 MSG_DEBUG("expiry time GetOneByte fail");
706 /* DRM_TEMPLATE - start */
709 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
710 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
712 if (valueLength > 0) {
713 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
714 MSG_DEBUG("MMS_CODE_EXPIRYTIME is invalid");
718 /* DRM_TEMPLATE - end */
720 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
722 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
723 MSG_INFO("__MmsBinaryDecodeInteger fail...");
728 MSG_DEBUG("X-Mms-Expiry : type = [%d], time = [%u]", mmsHeader.expiryTime.type, mmsHeader.expiryTime.time);
731 case MMS_CODE_MSGCLASS:
733 /* Class-value = Class-identifier | Token Text */
735 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
736 MSG_DEBUG("msgClass GetOneByte fail");
740 if (oneByte > 0x7f) {
741 /* Class-identifier */
742 mmsHeader.msgClass = (MmsMsgClass)MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
744 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
745 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (class)");
750 MSG_SEC_INFO("X-Mms-Message-Class =[%s]", MmsDebugGetMsgClass(mmsHeader.msgClass));
753 case MMS_CODE_MSGSIZE:
755 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
756 MSG_DEBUG("MMS_CODE_MSGSIZE is invalid");
760 MSG_SEC_INFO("X-Mms-Message-Size = [%d]", mmsHeader.msgSize);
763 case MMS_CODE_MSGSTATUS:
765 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
766 MSG_DEBUG("msgStatus GetOneByte fail");
770 mmsHeader.msgStatus = (msg_delivery_report_status_t)MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
771 MSG_SEC_INFO("X-Mms-Status = [%s]", MmsDebugGetMsgStatus(mmsHeader.msgStatus));
774 case MMS_CODE_MSGTYPE:
776 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
777 MSG_DEBUG("msgStatus GetOneByte fail");
781 mmsHeader.type = (MmsMsgType)MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
782 MSG_SEC_INFO("X-Mms-Message-Type = [%s]", MmsDebugGetMsgType(mmsHeader.type));
785 case MMS_CODE_PRIORITY:
787 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
788 MSG_DEBUG("msgStatus GetOneByte fail");
791 mmsHeader.priority = (MmsPriority)MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
792 MSG_SEC_INFO("X-Mms-Priority = [%d]", mmsHeader.priority);
795 case MMS_CODE_READREPLY:
797 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
798 MSG_DEBUG("msgStatus GetOneByte fail");
801 mmsHeader.readReply = (MmsReport)MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
802 MSG_SEC_INFO("X-Mms-Read-Report = [0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.readReply));
805 case MMS_CODE_REPORTALLOWED:
807 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
808 MSG_DEBUG("msgStatus GetOneByte fail");
811 mmsHeader.reportAllowed = (MmsReportAllowed)MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
812 MSG_SEC_INFO("X-Mms-Report-Allowed = [%d]", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
815 case MMS_CODE_SENDERVISIBILLITY:
817 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
818 MSG_DEBUG("msgStatus GetOneByte fail");
821 mmsHeader.hideAddress = (MmsSenderVisible)!(MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
822 MSG_SEC_INFO("X-Mms-Sender-Visibility = [%d]", mmsHeader.hideAddress);
827 if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
828 MSG_DEBUG("Transaction ID Too Long");
831 MSG_SEC_INFO("X-Mms-Transaction-Id = [%s]", mmsHeader.szTrID);
834 case MMS_CODE_VERSION:
835 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
836 MSG_DEBUG("msgStatus GetOneByte fail");
839 mmsHeader.version = oneByte;
841 MSG_SEC_INFO("X-Mms-MMS-Version = [0x%02x]", mmsHeader.version);
844 case MMS_CODE_CONTENTTYPE:
847 * Content-type is the last header field of SendRequest and RetrieveConf.
848 * It's required to decrease pointer by one and return,
849 * to parse this field in MmsBinaryDecodeContentType().
854 /* ----------- Add by MMSENC v1.1 ----------- */
856 case MMS_CODE_READSTATUS:
858 /* Read-status-value = Read | Deleted without being read */
860 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
861 MSG_DEBUG("msgStatus GetOneByte fail");
865 mmsHeader.readStatus = (msg_read_report_status_t)MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
866 MSG_SEC_INFO("X-Mms-Read-Status = [%s]", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
869 case MMS_CODE_REPLYCHARGING:
871 /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
873 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
874 MSG_DEBUG("msgStatus GetOneByte fail");
878 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
879 MSG_SEC_INFO("X-Mms-Reply-Charging = [%d]", mmsHeader.replyCharge.chargeType);
882 case MMS_CODE_REPLYCHARGINGDEADLINE:
884 /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
886 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
887 MSG_DEBUG("invalid MMS_CODE_REPLYCHARGINGDEADLINE");
891 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
892 MSG_DEBUG("msgStatus GetOneByte fail");
896 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
897 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
899 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
902 /* DRM_TEMPLATE - start */
905 if (valueLength > 0) {
906 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
907 MSG_DEBUG("MMS_CODE_REPLYCHARGINGDEADLINE is invalid");
912 MSG_SEC_INFO("X-Mms-Reply-Charging-Deadline : type = [%d], time = [%u]", mmsHeader.replyCharge.deadLine.type, mmsHeader.replyCharge.deadLine.time);
913 /* DRM_TEMPLATE - end */
916 case MMS_CODE_REPLYCHARGINGID:
918 /* Reply-charging-ID-value = Text-string */
919 if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
920 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (szReplyChargingID)");
923 SECURE_SLOGD("X-Mms-Reply-Charging-ID = [%s]", mmsHeader.replyCharge.szChargeID);
926 case MMS_CODE_REPLYCHARGINGSIZE:
928 /* Reply-charging-size-value = Long-integer */
929 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
930 MSG_DEBUG("MMS_CODE_REPLYCHARGINGSIZE is invalid");
933 MSG_SEC_INFO("X-Mms-Reply-Charging-Size = [%d]", mmsHeader.replyCharge.chargeSize);
936 case MMS_CODE_PREVIOUSLYSENTBY:
939 * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
940 * Forwarded-count-value = Integer-value
941 * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
945 * fixme: There is no proper field to store this information.
946 * Just increase pointer now.
949 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
950 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTBY");
954 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
955 MSG_DEBUG("2. invalid MMS_CODE_PREVIOUSLYSENTBY");
959 if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
960 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
965 case MMS_CODE_PREVIOUSLYSENTDATE:
968 * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
969 * Forwarded-count-value = Integer-value
970 * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
974 * fixme: There is no proper field to store this information.
975 * Just increase pointer now.
978 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
979 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTDATE");
983 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
984 MSG_DEBUG("2. invalid MS_CODE_PREVIOUSLYSENTDATE");
988 if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
989 MSG_DEBUG("3. invalid MMS_CODE_PREVIOUSLYSENTDATE");
996 * Application-header = Token-text Application-specific-value
997 * Token-text = Token End-of-string
998 * Application-specific-value = Text -string
1000 * OR unknown header field - Just ignore these fields.
1002 * Read one byte and check the value >= 0x80
1003 * (check these value can be field code)
1006 int remainLength = 0;
1010 offset = __MmsGetDecodeOffset();
1011 if (offset >= totalLength)
1014 remainLength = totalLength - offset;
1016 while ((oneByte < 0x80) && (remainLength > 0)) {
1017 if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1018 MSG_DEBUG("__MmsBinaryDecodeCheckAndDecreaseLength fail");
1022 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1023 MSG_DEBUG("responseStatus GetOneByte fail");
1028 gCurMmsDecodeBuffPos--;
1033 offset = __MmsGetDecodeOffset();
1034 if (offset >= totalLength)
1040 if (mmsHeader.pTo == NULL && pLastTo) {
1044 if (mmsHeader.pCc == NULL && pLastCc) {
1048 if (mmsHeader.pBcc == NULL && pLastBcc) {
1052 MSG_INFO("## Decode Header Success ##");
1059 if (mmsHeader.pTo == NULL && pLastTo) {
1063 if (mmsHeader.pCc == NULL && pLastCc) {
1067 if (mmsHeader.pBcc == NULL && pLastBcc) {
1071 MSG_FATAL("## Decode Header Fail ##");
1076 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1083 if (szFilePath != NULL)
1084 snprintf(mmsHeader.msgType.szOrgFilePath, sizeof(mmsHeader.msgType.szOrgFilePath), "%s", szFilePath);
1086 mmsHeader.msgType.offset = __MmsGetDecodeOffset() - 1; /* + Content-Type code value */
1088 /* read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding */
1089 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1090 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1091 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1092 MSG_DEBUG("fail to load to buffer");
1096 /* msg's type [ex] related, mixed, single part (jpg, amr and etc) */
1097 length = __MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1099 MSG_DEBUG("MMS_CODE_CONTENTTYPE is fail");
1103 mmsHeader.msgType.size = length + 1; /* + Content-Type code value */
1104 mmsHeader.msgBody.offset = __MmsGetDecodeOffset();
1106 switch (mmsHeader.msgType.type) {
1107 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1108 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1109 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1110 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1111 case MIME_MULTIPART_REPORT:
1112 case MIME_MULTIPART_MIXED:
1113 case MIME_MULTIPART_RELATED:
1114 case MIME_MULTIPART_ALTERNATIVE:
1115 case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1116 case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1118 MSG_DEBUG("Decode Multipart");
1120 offset = __MmsGetDecodeOffset();
1121 if (offset >= totalLength)
1124 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1125 MSG_DEBUG("MmsBinaryDecodeMultipart is fail.");
1132 /* Single part message ---------------------------------------------- */
1133 MSG_DEBUG("Decode Singlepart");
1135 offset = __MmsGetDecodeOffset();
1136 if (offset >= totalLength)
1139 if (__MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1140 MSG_DEBUG("MmsBinaryDecodePartBody is fail.(Single Part)");
1144 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1145 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1158 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1163 char *szTypeString = NULL;
1164 char *szTypeValue = NULL;
1165 UINT8 paramCode = 0xff;
1172 * Parameter = Typed-parameter | Untyped-parameter
1173 * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1176 while (valueLength > 0) {
1177 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1178 MSG_DEBUG("paramCode _MmsBinaryDecodeGetOneByte fail");
1182 paramCode = oneByte;
1185 switch (paramCode) {
1186 case 0x81: /* charset */
1188 if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1189 MSG_DEBUG("__MmsBinaryDecodeCharset fail.");
1193 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1198 case 0x85: /* name = Text-string */
1199 case 0x97: /* name = Text-value = No-value | Token-text | Quoted-string */
1200 memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1201 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szName,
1202 MSG_FILENAME_LEN_MAX -5, /* MSG_LOCALE_FILENAME_LEN_MAX + 1, : change @ 110(Ui code have to change for this instead of DM) */
1205 MSG_DEBUG("__MmsDecodeGetFilename fail. (name parameter)");
1209 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1210 __MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1213 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1218 case 0x86: /* filename = Text-string */
1219 case 0x98: /* filename = Text-value = No-value | Token-text | Quoted-string */
1220 memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1221 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1223 MSG_DEBUG("__MmsDecodeGetFilename fail. (filename parameter)");
1227 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1228 __MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1231 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1236 case 0x89: /* type = Constrained-encoding = Extension-Media | Short-integer */
1238 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1239 MSG_DEBUG("type _MmsBinaryDecodeGetOneByte fail");
1243 if (oneByte > 0x7f) {
1244 pMsgType->param.type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1245 /* MmsGetBinaryType(MmsCodeContentType,(UINT16)(oneByte & 0x7f)); */
1246 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1249 gCurMmsDecodeBuffPos--;
1252 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1253 pMsgType->param.type = MimeGetMimeIntFromMimeString(szTypeString);
1256 szTypeString = NULL;
1259 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1265 case 0x8A: /* start encoding version 1.2 */
1266 case 0x99: /* start encoding version 1.4 */
1269 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1271 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1272 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1274 szTypeString = NULL;
1276 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1282 case 0x8B: /* startInfo encoding version 1.2 */
1283 case 0x9A: /* startInfo encoding version 1.4 */
1286 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1289 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1290 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1293 szTypeString = NULL;
1295 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1303 if (paramCode > 0x7F) {
1304 MSG_DEBUG("Unsupported parameter");
1306 /* In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value. */
1308 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1312 * Untyped Parameter = Token-text Untyped-value
1313 * Token-text = Token End-of-string
1314 * Untyped-value = Integer-value | Text-value
1315 * Text-value = No-value | Token-text | Quoted-string
1317 * Just increase pointer!!!
1323 gCurMmsDecodeBuffPos--;
1327 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1328 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1334 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1335 MSG_DEBUG("Unsupported parameter(%d)\n", integer);
1336 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1340 szTypeValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1343 /* checkMe: forwardLock needs boudary string */
1344 if (g_ascii_strcasecmp(szTypeString, "boundary") == 0) {
1345 memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1346 strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1347 #ifdef FEATURE_JAVA_MMS
1348 } else if (g_ascii_strcasecmp(szTypeString, "Application-ID") == 0) {
1349 pMsgType->param.szApplicationID = (char*) calloc(1, textLength + 1);
1350 if (pMsgType->param.szApplicationID) {
1351 memset(pMsgType->param.szApplicationID, 0, textLength + 1);
1352 strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1353 MSG_SEC_DEBUG("Application-ID:%s", pMsgType->param.szApplicationID);
1355 } else if (g_ascii_strcasecmp(szTypeString, "Reply-To-Application-ID") == 0) {
1356 pMsgType->param.szReplyToApplicationID = (char*)calloc(1, textLength + 1);
1357 if (pMsgType->param.szReplyToApplicationID) {
1358 memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1359 strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1360 MSG_SEC_DEBUG("ReplyToApplication-ID:%s", pMsgType->param.szReplyToApplicationID);
1365 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeValue);
1369 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1375 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeString);
1377 szTypeString = NULL;
1383 } /*end of while loop*/
1390 szTypeString = NULL;
1402 * Decode Encoded Content type
1404 * @param pEncodedData [in] ContentType encoded data
1405 * @param pMsgType [out] Decoded MsgType
1406 * @return Decoded address list
1408 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1412 char *szTypeString = NULL;
1413 int valueLength = 0;
1419 * Content-type-value : [WAPWSP 8.4.2.24]
1420 * Preassigned content-types : [WAPWSP Appendix A, Table 40]
1421 * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1423 * Content-type-value = Constrained-media | Content-general-form
1424 * Content-general-form = Value-length Media-type
1425 * Media-type = (Well-known-media | Extension-Media) *(Parameter)
1428 length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1431 * Constrained-media or Single part message
1432 * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1433 * Extension-media = *TEXT End-of-string
1434 * Short-integer = OCTET(1xxx xxxx)
1437 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1438 MSG_DEBUG("Constrained-media _MmsBinaryDecodeGetOneByte fail");
1442 if (oneByte > 0x7F) {
1444 pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1446 MSG_SEC_DEBUG("Constrained-media : Short-integer : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1450 char *pszTemp = NULL;
1452 /* Extension-Media */
1453 gCurMmsDecodeBuffPos--;
1456 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1458 if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1459 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type with delimiter = [%s]", szTypeString);
1461 pszTemp = __MsgGetStringUntilDelimiter(szTypeString, ';');
1464 szTypeString = pszTemp;
1468 pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1470 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1472 length = textLength;
1476 szTypeString = NULL;
1481 * Content-general-form = Value-length Media-type
1482 * Media-type = (Well-known-media | Extension-Media)*(Parameter)
1485 length += valueLength;
1487 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1488 MSG_DEBUG("Well-known-media _MmsBinaryDecodeGetOneByte fail");
1492 if (oneByte > 0x7F) {
1493 /* Well-known-media */
1494 pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1495 MSG_SEC_DEBUG("Content-general-form : Well-known-media : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1498 /* Extension-Media */
1499 gCurMmsDecodeBuffPos--;
1502 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1504 pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1506 MSG_SEC_DEBUG("Content-general-form : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1508 valueLength -= textLength;
1512 szTypeString = NULL;
1516 MSG_SEC_DEBUG("Content-Type = [%s]", MmsDebugGetMimeType((MimeType)pMsgType->type));
1518 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1519 MSG_DEBUG("Content-Type parameter fail");
1532 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1534 UINT8 fieldCode = 0xff;
1536 UINT32 valueLength = 0;
1538 char *pValue = NULL;
1539 char *pParam = NULL;
1545 char *pLatinBuff = NULL;
1547 char *szTemp = NULL;
1549 MSG_INFO("headerLen[%d] totalLength[%d]", headerLen, totalLength);
1551 if (pFile == NULL || pMsgType == NULL)
1555 * Message-header = Well-known-header | Application-header
1556 * Well-known-header = Well-known-field-name Wap-value
1557 * Application-header = Token-text Application-specific-value
1558 * Well-known-field-name = Short-integer
1559 * Application-specific-value = Text-string
1562 while (headerLen > 0) {
1563 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1564 MSG_DEBUG("field code GetOneByte fail");
1568 if (0x80 <= oneByte && oneByte <= 0xC7) {
1569 /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1571 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1574 fieldCode = oneByte & 0x7f;
1576 switch (fieldCode) {
1577 case 0x0E: /* Content-Location */
1578 case 0x04: { /* Content-Location */
1579 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1580 if (pLatinBuff == NULL)
1583 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1585 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1589 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1591 snprintf(pMsgType->szContentLocation, sizeof(pMsgType->szContentLocation), "%s", szSrc);
1592 MSG_SEC_DEBUG("Content Location : [%s]", pMsgType->szContentLocation);
1600 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1605 case 0x40: { /* Content-ID */
1606 char szContentID[MMS_CONTENT_ID_LEN + 1] = {0, };
1608 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1609 if (pLatinBuff == NULL)
1612 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1615 MSG_DEBUG("Content-ID __MmsBinaryDecodeQuotedString fail.");
1619 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1621 snprintf(szContentID, sizeof(szContentID), "%s", szSrc);
1622 MSG_SEC_DEBUG("Content ID : [%s]", szContentID);
1630 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1632 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1637 case 0x2E: /* Content-Disposition */
1638 case 0x45: /* Content-Disposition */
1641 * Content-disposition-value = Value-length Disposition *(Parameter)
1642 * Disposition = Form-data | Attachment | Inline | Token-text
1643 * Form-data = <Octet 128> : 0x80
1644 * Attachment = <Octet 129> : 0x81
1645 * Inline = <Octet 130> : 0x82
1648 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1651 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1655 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1656 MSG_DEBUG("Disposition value GetOneByte fail");
1663 if (oneByte >= 0x80) {
1664 pMsgType->disposition = MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1666 if (pMsgType->disposition == -1) {
1667 MSG_DEBUG("Content-Disposition MmsGetBinaryType fail.");
1668 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT; /* default */
1671 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1674 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1675 MSG_DEBUG("Disposition parameter fail");
1679 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1682 gCurMmsDecodeBuffPos--;
1685 pLatinBuff = (char *)calloc(1, MSG_FILENAME_LEN_MAX);
1686 if (pLatinBuff == NULL)
1688 memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1690 textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1693 if (textLength < 0) {
1694 MSG_DEBUG("Content-Disposition decodingfail.");
1700 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1703 valueLength -= textLength;
1705 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1706 MSG_DEBUG("Disposition parameter fail");
1710 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1716 case 0x0B: /* Content-Encoding */
1717 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1718 MSG_DEBUG("Disposition value GetOneByte fail");
1722 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1727 case 0x0C: /* Content-Language */
1728 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1729 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1734 cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1736 if (cTemp == NULL) {
1737 MSG_DEBUG("__MmsBinaryDecodeText2 fail...");
1741 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1753 case 0x0D: /* Content-Length */
1754 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1755 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1759 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1764 case 0x1C: /* Location */
1765 pLatinBuff = (char *)calloc(1, MMS_LOCATION_URL_LEN + 1);
1766 if (pLatinBuff == NULL)
1769 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_LOCATION_URL_LEN, totalLength);
1771 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1775 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1777 snprintf(pMsgType->szLocation, sizeof(pMsgType->szLocation), "%s", szSrc);
1778 MSG_INFO("Location : [%s]", pMsgType->szLocation);
1786 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1791 case 0x30: /* X-Wap-Content-URI skip this value */
1792 MSG_DEBUG("X-Wap-Content-URI header.");
1793 pLatinBuff = (char *)calloc(1, MMS_TEXT_LEN);
1794 if (pLatinBuff == NULL)
1797 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1800 MSG_DEBUG(" __MmsBinaryDecodeQuotedString fail.");
1804 MSG_DEBUG("X-Wap-Content-URI header decoded. Value length %d\n", length);
1808 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1811 MSG_DEBUG("X-Wap-Content-URI header skipped.");
1815 case 0x01: { /* Accept-charset */
1816 /* if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1) */
1817 /* WAP-230-WSP-200010705-a.pdf
1818 8.4.2.8 Accept charset field
1819 The following rules are used to encode accept character set values.
1820 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1821 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1822 Constrained-charset = Any-charset | Constrained-encoding
1823 Well-known-charset = Any-charset | Integer-value
1824 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1825 Any-charset = <Octet 128>
1826 ; Equivalent to the special RFC2616 charset value ��*��
1832 MSG_DEBUG("Accept-charset.");
1834 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1836 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1840 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1841 /* We only support the well-known-charset format */
1842 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1847 MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1849 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1856 /* Other Content-xxx headers : Have valueLength */
1857 MSG_WARN("unknown Value = 0x%x\n", oneByte);
1859 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1861 MSG_WARN("invalid MMS_CODE_PREVIOUSLYSENTDATE");
1865 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1868 szTemp = (char *)calloc(1, valueLength);
1872 if (__MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) == false) {
1873 MSG_WARN("default _MmsBinaryDecodeGetBytes() fail");
1881 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1888 * Application-header = Token-text Application-specific-value
1889 * Application-specific-value = Text-string
1892 MSG_DEBUG(" Application-header = Token-text Application-specific-value");
1894 gCurMmsDecodeBuffPos--;
1899 pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1900 if (pCode == NULL) {
1901 MSG_DEBUG("pCode is null");
1905 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1908 MSG_DEBUG(" Token-text (%s) \n", pCode);
1911 /* Application-specific-value */
1914 pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1915 if (pValue == NULL) {
1916 MSG_DEBUG("pValue is null");
1920 MSG_DEBUG(" Application-specific-value (%s) \n", pValue);
1923 pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1929 switch (MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1930 case MMS_BODYHDR_TRANSFERENCODING: /* Content-Transfer-Encoding */
1931 pMsgType->encoding = MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1934 case MMS_BODYHDR_CONTENTID: { /* Content-ID */
1935 char szContentID[MMS_CONTENT_ID_LEN + 1];
1937 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1938 if (pLatinBuff == NULL) {
1942 __MsgMIMERemoveQuote(pValue);
1943 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1945 length = strlen(pLatinBuff);
1946 if (__MsgLatin2UTF((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1947 MSG_DEBUG("MsgLatin2UTF fail");
1951 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1957 case MMS_BODYHDR_CONTENTLOCATION: /* Content-Location */
1959 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1960 if (pLatinBuff == NULL)
1963 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1965 length = strlen(pLatinBuff);
1966 if (__MsgLatin2UTF((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1967 MSG_DEBUG("MsgLatin2UTF fail");
1975 case MMS_BODYHDR_DISPOSITION: /* Content-Disposition */
1976 pMsgType->disposition = MmsGetTextType(MmsCodeMsgDisposition, pValue);
1979 case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY: /* DRM RO WAITING */
1983 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
1988 __MsgParseParameter(pMsgType, pParam + 1);
2000 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2042 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2046 length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2051 MSG_INFO("Number of Entries = [%d]", *npEntries);
2059 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2064 * Currently, offset and size is
2065 * the only information used with msgBody.
2066 * If you need, add here more information
2070 offset = __MmsGetDecodeOffset();
2071 offset += bodyLength;
2073 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2074 MSG_DEBUG("fail to seek file pointer");
2078 __MmsCleanDecodeBuff();
2080 gMmsDecodeCurOffset = offset;
2082 if (offset >= totalLength)
2085 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2086 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2087 MSG_DEBUG("fail to load to buffer");
2100 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2102 if (offset > totalLength)
2105 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2106 MSG_DEBUG("fail to seek file pointer");
2110 __MmsCleanDecodeBuff();
2112 gMmsDecodeCurOffset = offset;
2114 if (offset == totalLength)
2117 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2118 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2119 MSG_DEBUG("fail to load to buffer");
2130 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2132 UINT32 nEntries = 0;
2133 MsgMultipart *pMultipart = NULL;
2134 MsgMultipart *pLastMultipart = NULL;
2138 MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2139 MsgPresentaionInfo presentationInfo;
2141 MSG_DEBUG("pdu length = [%d]", totalLength);
2143 presentationInfo.factor = MSG_PRESENTATION_NONE;
2144 presentationInfo.pCurPresentation = NULL;
2145 presentationInfo.pPrevPart = NULL;
2147 if (__MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2148 MSG_DEBUG("MmsBinaryDecodeEntries is fail.");
2152 if (pMsgBody->body.pMultipart != NULL) {
2153 pLastMultipart = pMsgBody->body.pMultipart;
2154 MSG_DEBUG("previous multipart exist [%p]", pMsgBody->body.pMultipart);
2156 MSG_DEBUG("first multipart");
2160 MSG_DEBUG("decoding [%d]th multipart", index);
2162 offset = __MmsGetDecodeOffset();
2163 if (offset >= totalLength) {
2164 MSG_DEBUG("offset is over totalLength");
2168 if ((pMultipart = MmsAllocMultipart()) == NULL) {
2169 MSG_DEBUG("MsgAllocMultipart Fail");
2173 if (__MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2174 MSG_DEBUG("MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2178 if (pMultipart->type.type == MIME_APPLICATION_SMIL) {
2179 /* P151019-00477 : received mms message is type of multipart mixed, but among multiparts if there's smil part then set it multipart related */
2180 if (pMsgType->type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED)
2181 pMsgType->type = MIME_APPLICATION_VND_WAP_MULTIPART_RELATED;
2183 factor = __MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2184 if (factor == MSG_PRESENTATION_NONE) {
2185 factor = MSG_PRESENTATION_TYPE_BASE;
2188 factor = MSG_PRESENTATION_NONE;
2191 /* priority 1 : content type match, 2: content location, 3: type */
2192 if (presentationInfo.factor < factor) {
2193 /* Presentation part */
2194 presentationInfo.factor = factor;
2195 presentationInfo.pPrevPart = pLastMultipart;
2196 presentationInfo.pCurPresentation = pMultipart;
2199 /* first multipart */
2200 if (pLastMultipart == NULL) {
2201 pMsgBody->body.pMultipart = pMultipart;
2202 pLastMultipart = pMultipart;
2204 pLastMultipart->pNext = pMultipart;
2205 pLastMultipart = pMultipart;
2208 pMsgType->contentSize += pMultipart->pBody->size;
2212 MmsPrintMulitpart(pMultipart, index++);
2215 pMsgBody->size = totalLength - pMsgBody->offset;
2217 __MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2219 if (__MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2220 MSG_DEBUG("MsgResolveNestedMultipart failed");
2228 if (pMultipart->pBody) {
2229 free(pMultipart->pBody);
2230 pMultipart->pBody = NULL;
2240 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2243 bool bSuccess = false;
2244 UINT32 headerLength = 0;
2245 UINT32 bodyLength = 0;
2248 MSG_DEBUG("pdu length = [%d]", totalLength);
2251 if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2252 MSG_DEBUG("Get header length fail");
2256 offset = __MmsGetDecodeOffset();
2257 if (offset >= totalLength)
2261 if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2262 MSG_DEBUG("Get body length fail");
2266 offset = __MmsGetDecodeOffset();
2267 if (offset >= totalLength)
2271 if (szFilePath != NULL)
2272 snprintf(pMsgType->szOrgFilePath, sizeof(pMsgType->szOrgFilePath), "%s", szFilePath);
2274 pMsgType->offset = __MmsGetDecodeOffset();
2275 pMsgType->size = headerLength;
2276 pMsgType->contentSize = bodyLength;
2278 if (pMsgType->offset > totalLength)
2281 length = __MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2283 MSG_DEBUG("Decode contentType Fail");
2287 offset = __MmsGetDecodeOffset();
2288 if (offset >= totalLength)
2294 if (__MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2295 MSG_DEBUG("Decode contentHeader Fail");
2299 offset = __MmsGetDecodeOffset();
2300 if (offset >= totalLength)
2305 if (szFilePath != NULL)
2306 snprintf(pMsgBody->szOrgFilePath, sizeof(pMsgBody->szOrgFilePath), "%s", szFilePath);
2308 pMsgBody->offset = __MmsGetDecodeOffset();
2309 pMsgBody->size = bodyLength;
2311 if (pMsgBody->offset > totalLength)
2314 switch (pMsgType->type) {
2315 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2316 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2317 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2318 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2319 case MIME_MULTIPART_REPORT:
2320 case MIME_MULTIPART_MIXED:
2321 case MIME_MULTIPART_RELATED:
2322 case MIME_MULTIPART_ALTERNATIVE:
2323 MSG_DEBUG("Multipart");
2324 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2325 MSG_DEBUG("MmsBinaryDecodeMultipart is fail");
2329 offset = __MmsGetDecodeOffset();
2330 if (offset >= totalLength)
2336 MSG_DEBUG("Normal Part");
2338 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2339 if (bSuccess == false) {
2340 MSG_DEBUG("Decode contentBody Fail");
2344 offset = __MmsGetDecodeOffset();
2345 if (offset >= totalLength)
2363 /* --------------------------------------------------------------------
2365 * B I N A R Y D E C D E U T I L I T Y
2367 * --------------------------------------------------------------------*/
2369 bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
2371 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2373 if (pFile == NULL || pOneByte == NULL) {
2374 MSG_DEBUG("invalid file or buffer");
2379 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2380 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2381 MSG_DEBUG("fail to load to buffer");
2386 *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2395 * @remark: bufLen < gMmsDecodeMaxLen
2397 bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2399 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2403 if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
2406 memset(szBuff, 0, bufLen);
2408 if (length < bufLen) {
2409 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2410 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2411 MSG_DEBUG("fail to load to buffer");
2416 for (i = 0; i < bufLen - 1; i++) {
2417 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2420 gCurMmsDecodeBuffPos++; /* NULL */
2428 bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2432 if (pFile == NULL || szBuff == NULL || bufLen == 0)
2435 memset(szBuff, 0, bufLen);
2437 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2438 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2439 MSG_DEBUG("fail to load to buffer");
2443 while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
2444 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
2445 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2449 iPos += gMmsDecodeMaxLen;
2452 if ((bufLen - iPos) > 0) {
2453 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
2454 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2458 iPos += (bufLen - iPos);
2468 * Decode uintvar to 32bit unsigned integer
2470 * @param pEncodedData [in] encoded data
2471 * @param pUintVar [out] Decode uintvar (32bit unsigned integer)
2472 * @return The length of uintvar (-1, if cannot be converted to a uintvar)
2474 * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
2477 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
2479 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
2483 UINT32 decodedUintvar = 0;
2484 UINT8 iBuff[5] = {0};
2485 int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
2488 if (pFile == NULL || pUintVar == NULL)
2492 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2493 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2494 MSG_DEBUG("fail to load to buffer");
2500 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2503 if (oneByte > 0x7f) {
2504 iBuff[count++] = oneByte;
2506 iBuff[count++] = oneByte;
2511 MSG_DEBUG("legnth is too long");
2516 for (int i = 0; i < count; i++)
2517 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
2519 *pUintVar = decodedUintvar;
2524 gCurMmsDecodeBuffPos -= count;
2529 * Decode uintvar to 32bit unsigned integer by uintvar length
2531 * @param pEncodedData [in] uintvar encoded data
2532 * @param length [in] length of integer value
2533 * @return unsigned integer value
2535 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
2545 returner.integer = 0;
2551 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2552 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2556 if (oneByte > 0x7f) {
2557 return (oneByte & 0x7f);
2566 pData = (char *)calloc(1, length + 1);
2567 if (pData == NULL) {
2568 MSG_DEBUG("pData alloc fail");
2571 memset(pData, 0, length + 1);
2573 if (__MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
2574 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2578 gCurMmsDecodeBuffPos--; /* - NULL */
2580 for (i= 0; i < length; i++)
2581 returner.seg[length - (i+1)] = pData[i];
2588 return returner.integer;
2597 return returner.integer;
2601 * Decode uintvar to 32bit unsigned integer by uintvar length
2603 * @param pEncodedData [in] uintvar encoded data
2604 * @param pInteger [out] Decode integer value (long/short)
2605 * @return unsigned integer value (-1, if cannot be converted to unsigned integer value)
2607 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
2617 if (pInteger == NULL)
2620 returner.integer = 0;
2623 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2624 MSG_DEBUG("GetOneByte fail");
2628 if (oneByte < 0x1F) { /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2629 pData = (char *)calloc(1, oneByte + 1);
2630 if (pData == NULL) {
2631 MSG_DEBUG("pData calloc fail");
2634 memset(pData, 0, oneByte + 1);
2636 /* Even NULL is copied in the _MmsBinaryDecodeGetBytes */
2637 if (__MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
2638 MSG_DEBUG("GetBytes fail");
2642 gCurMmsDecodeBuffPos--; /* - NULL */
2652 for (i = 0; i < length; i++)
2653 returner.seg[length - (i+1)] = pData[i];
2655 *pInteger = returner.integer;
2656 *pIntLen = oneByte + 1;
2657 } else if (oneByte >= 0x80) {
2658 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2659 *pInteger = oneByte & 0x7f;
2674 gCurMmsDecodeBuffPos--;
2685 * Decode uintvar to 32bit unsigned integer by uintvar length
2687 * @return 1 : Success
2688 * 0 : This is not Value Length type data
2689 * -1 : Requires System error report
2691 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
2699 * value-length = short-length | (Length-quote Length)
2700 * = 0~30 | 31 + Uintvar-length
2703 if (pFile == NULL || pValueLength == NULL)
2708 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2709 gCurMmsDecodeBuffPos--;
2713 if (0x00 < oneByte && oneByte < 0x1F) {
2715 *pValueLength = oneByte;
2717 } else if (oneByte == 0x1F) {
2718 /* Length-quote = 0x1F */
2720 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2722 MSG_DEBUG(" __MmsBinaryDecodeUintvar fail..");
2725 length++; /* + length-quote */
2726 *pValueLength = uintvar;
2728 MSG_DEBUG("not a value length type data");
2729 gCurMmsDecodeBuffPos--;
2736 MSG_DEBUG("getting data fail");
2741 * Decode uintvar to 32bit unsigned integer by uintvar length
2743 * @return 1 : Success
2744 * 0 : This is not Value Length type data
2745 * -1 : Requires System error report
2746 * @ defference : if there is not length-quote, consider it as short length.
2748 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
2756 * value-length = short-length | (Length-quote Length)
2757 * = 0~30 | 31 + Uintvar-length
2760 if (pFile == NULL || pValueLength == NULL)
2765 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2766 gCurMmsDecodeBuffPos--;
2770 if (0x00 < oneByte && oneByte < 0x1F) {
2772 *pValueLength = oneByte;
2774 } else if (oneByte == 0x1F) {
2775 /* Length-quote = 0x1F */
2777 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2779 MSG_DEBUG("__MmsBinaryDecodeUintvar fail..");
2782 length++; /* + length-quote */
2783 *pValueLength = uintvar;
2785 MSG_DEBUG("there is not length-quote, consider it as short length.");
2786 *pValueLength = oneByte;
2793 MSG_DEBUG("getting data fail");
2798 * Decode QuotedString
2800 * @param pEncodedData [in] QuotedString encoded data
2801 * @param szBuff [out] Decoded quoted string
2802 * @param bufLen [out] Buffer length
2803 * @return length of quoted string
2805 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2811 int returnLength = 0;
2814 * Quoted-string = <Octet 34> *TEXT End-of-string
2815 * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
2818 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2821 memset(szBuff, 0, bufLen);
2823 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2824 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2825 MSG_DEBUG("fail to load to buffer");
2829 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2834 while (length > gMmsDecodeBufLen) {
2835 if (gMmsDecodeBufLen <= 0) {
2836 MSG_DEBUG("gMmsDecodeBufLen <= 0");
2837 MSG_DEBUG("%x %x %x %x %x",
2838 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
2839 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
2840 MSG_DEBUG("%x %x %x %x %x",
2841 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
2842 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
2843 MSG_DEBUG("%x %x %x %x %x",
2844 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
2845 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
2846 MSG_DEBUG("%x %x %x %x %x",
2847 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
2848 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
2852 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
2856 memset(pData, 0, gMmsDecodeBufLen + 1);
2858 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
2861 returnLength += gMmsDecodeBufLen;
2863 if ((bufLen - iPos) > 0) {
2864 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
2865 if (iPos == 0 && (pData[0] == MARK)) {
2866 /* MARK: check first time only */
2868 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2869 iPos += (readBytes - 1);
2871 strncpy(szBuff + iPos, (char*)pData, readBytes);
2881 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2882 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2883 MSG_DEBUG("fail to load to buffer");
2886 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2890 pData = (char *)calloc(1, length);
2894 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
2897 returnLength += length;
2899 if ((bufLen - iPos) > 0) {
2900 /* read until NULL from raw data, and copy only string */
2901 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
2902 if (iPos == 0 && (pData[0] == MARK)) {
2903 /* MARK: check first time only */
2904 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2905 iPos += (readBytes - 1);
2907 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); /* + NULL */
2918 szBuff[bufLen - 1] = '\0';
2920 return returnLength;
2939 * @param pEncodedData [in] QuotedString encoded data
2940 * @param szBuff [out] Decoded quoted string
2941 * @param bufLen [out] Buffer length
2942 * @return length of decode text string
2944 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2949 int returnLength = 0;
2951 bool bQuote = false;
2955 * Text-String = [QUOTE]*TEXT end_of_string
2956 * [QUOTE]*(128~255)\0
2960 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2963 offset = __MmsGetDecodeOffset();
2964 if (offset >= totalLength)
2967 memset(szBuff, 0, bufLen);
2969 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2970 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2971 MSG_DEBUG("fail to load to buffer");
2975 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2980 while (length > gMmsDecodeBufLen) {
2981 if (gMmsDecodeBufLen <= 0) {
2982 MSG_DEBUG("gMmsDecodeBufLen <= 0");
2983 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
2984 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
2985 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
2986 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
2987 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
2988 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
2989 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
2990 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
2994 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
2998 memset(pData, 0, gMmsDecodeBufLen + 1);
3000 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3003 if ((bufLen - iPos) > 0) {
3004 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3005 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3006 /* QUOTE: check first time only */
3008 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3009 iPos += (readBytes - 1);
3012 strncpy(szBuff + iPos, (char*)pData, readBytes);
3022 returnLength += gMmsDecodeBufLen;
3024 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3025 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3026 MSG_DEBUG("fail to load to buffer");
3029 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
3033 pData = (char *)calloc(1, length);
3037 memset(pData, 0, length);
3039 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3042 if ((bufLen - iPos) > 0) {
3043 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3044 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3045 /* QUOTE: check first time only */
3047 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3048 iPos += (readBytes - 1);
3051 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); /* + NULL */
3061 returnLength += length; /* + NULL */
3064 szBuff[bufLen - 1] = '\0';
3066 return returnLength;
3073 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3087 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
3092 char *szBuff = NULL;
3093 char *szTempPtr = NULL;
3094 bool bQuote = false;
3098 * Text-String = [QUOTE]*TEXT end_of_string
3099 * [QUOTE]*(128~255)\0
3103 if (pFile == NULL || pLength == NULL)
3107 offset = __MmsGetDecodeOffset();
3108 if (offset >= totalLength)
3111 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3112 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3113 MSG_DEBUG("fail to load to buffer");
3117 length = strlen(gpCurMmsDecodeBuff) + 1;
3122 while (length > gMmsDecodeBufLen) {
3123 if (gMmsDecodeBufLen <= 0) {
3124 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3125 MSG_DEBUG("%x %x %x %x %x",
3126 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3127 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3128 MSG_DEBUG("%x %x %x %x %x",
3129 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3130 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3131 MSG_DEBUG("%x %x %x %x %x",
3132 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3133 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3134 MSG_DEBUG("%x %x %x %x %x\n",
3135 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3136 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3140 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3144 memset(pData, 0, gMmsDecodeBufLen + 1);
3146 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3149 if (szBuff == NULL) {
3150 szBuff = (char *)calloc(1, gMmsDecodeBufLen + 1);
3152 szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
3154 /* NULL pointer check for realloc */
3155 if (szTempPtr == NULL) {
3164 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
3166 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3167 /* QUOTE: check first time only */
3169 strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
3170 curLen += (gMmsDecodeBufLen - 1);
3173 strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
3174 curLen += gMmsDecodeBufLen;
3182 *pLength += gMmsDecodeBufLen;
3184 if (__MsgLoadDataToDecodeBuffer(pFile,
3185 &gpCurMmsDecodeBuff,
3186 &gCurMmsDecodeBuffPos,
3187 &gMmsDecodeCurOffset,
3192 totalLength) == false) {
3193 MSG_DEBUG("fail to load to buffer");
3196 length = strlen(gpCurMmsDecodeBuff) + 1;
3200 pData = (char *)calloc(1, length);
3201 if (pData == NULL) {
3205 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
3209 if (szBuff == NULL) {
3210 szBuff = (char *)calloc(1, length);
3212 szTempPtr = (char *)realloc(szBuff, curLen + length);
3214 /* NULL pointer check for realloc */
3215 if (szTempPtr == NULL)
3221 if (szBuff == NULL) {
3225 memset(szBuff + curLen, 0, length);
3227 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3228 /* QUOTE: check first time only */
3230 strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
3231 curLen += (length - 1);
3234 strncpy(szBuff + curLen, (char*)pData, length - 1);
3243 *pLength += length; /* + NULL */
3252 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3274 * @param pEncodedData [in] QuotedString encoded data
3275 * @param nCharSet [out] Decoded character set
3276 * @return length of charset value
3278 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
3283 * Charset v1.1 0x01 Well-known-charset
3284 * Well-known-charset = Any-charset | Integer-value
3285 * ; Both are encoded using values from
3286 * Character Set Assignments table in Assigned Numbers
3287 * Any-charset = <Octet 128>
3288 * ; Equivalent to the special RFC2616 charset value ��*��
3291 if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
3294 if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
3295 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
3300 /* AnyCharSet : return MSG_CHARSET_UTF8 */
3301 *nCharSet = MSG_CHARSET_UTF8;
3305 *nCharSet = MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
3306 MSG_DEBUG("Decoded charset MIBenum = [%d], charset enum = [%d]", integer, *nCharSet);
3307 if (*nCharSet == MIME_UNKNOWN) {
3308 MSG_DEBUG("MmsGetBinaryType fail..");
3309 *nCharSet = MSG_CHARSET_UNKNOWN;
3319 * Decode EncodedString
3321 * @param pEncodedData [in] QuotedString encoded data
3322 * @param szBuff [out] Decoded string buffer
3323 * @param bufLen [in] Decoded buffer length
3324 * @return length of decoded string length
3326 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3328 UINT32 valueLength = 0;
3334 MSG_DEBUG(" decode string..");
3336 if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
3337 MSG_DEBUG("invalid file or buffer");
3342 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3343 * Text-string = [Quote]*TEXT End-of-string
3344 * Value-length = 0 ~ 31
3347 memset(szBuff, 0, bufLen);
3349 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3355 /* Text-string = [Quote]*TEXT End-of-string */
3357 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
3358 MSG_DEBUG("__MmsBinaryDecodeText fail.");
3365 /* Value-length Charset Text_string */
3367 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3368 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3369 goto __CATCH; /* (valueLength + valueLengthLen) */
3372 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
3375 /* There can be some error in data - no NULL -> try again with value length */
3377 pData = (char *)calloc(1, valueLength - charSetLen);
3378 if (pData == NULL) {
3379 MSG_DEBUG("pData alloc fail.");
3383 if (__MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
3384 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes fail.");
3388 strncpy(szBuff, pData, bufLen - 1);
3391 nTemp = strlen(szBuff);
3393 const char *pToCharSet = "UTF-8";
3395 UINT16 charset_code = MmsGetBinaryValue(MmsCodeCharSet, charSet);
3397 const char *pFromCharSet = MmsPluginTextConvertGetCharSet(charset_code);
3398 if (pFromCharSet == NULL || !strcmp(pFromCharSet, pToCharSet)) {
3409 if (MmsPluginTextConvert(pToCharSet, pFromCharSet, szBuff, nTemp, &pDest, &destLen) == false) {
3410 MSG_DEBUG("MmsPluginTextConvert Fail");
3413 memset(szBuff, 0x00, bufLen);
3414 snprintf(szBuff, destLen+1, "%s", pDest);
3444 * Decode Encoded Addresses
3446 * @param pEncodedData [in] QuotedString encoded data
3447 * @param pAddrLength [out] Decoded address length
3448 * @return Decoded address list
3450 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
3452 UINT32 valueLength = 0;
3456 char *pAddrStr = NULL;
3457 MsgHeaderAddress *pAddr = NULL;
3459 MSG_DEBUG("decoding address..");
3461 if (pFile == NULL) {
3462 MSG_DEBUG("invalid file or buffer");
3467 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3468 * Text-string = [Quote]*TEXT End-of-string
3469 * Value-length = 0 ~ 31
3472 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3478 /* Text-string = [Quote]*TEXT End-of-string */
3481 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3482 if (pAddrStr == NULL) {
3483 MSG_DEBUG(" __MmsBinaryDecodeText2 fail.");
3490 /* Value-length Charset Text_string */
3492 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3493 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3498 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3499 if (pAddrStr == NULL) {
3500 /* There can be some error in data - no NULL -> try again with value length */
3502 pAddrStr = (char *)calloc(1, valueLength - charSetLen);
3503 if (pAddrStr == NULL) {
3504 MSG_DEBUG("pData alloc fail.");
3508 if (__MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
3509 MSG_DEBUG(" _MmsBinaryDecodeGetLongBytes fail.");
3514 /* fixme: charset transformation */
3519 pAddr = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
3523 memset(pAddr, 0, sizeof(MsgHeaderAddress));
3524 pAddr->szAddr = pAddrStr;
3540 * Decode Encoded Pointer String
3542 * @param pEncodedData [in] Long integer encoded data
3543 * @param pLongInteger [out] Decoded long integer
3544 * @return Decoded address list
3546 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
3551 * Long-integer = Short-length Multi-octet-integer
3552 * Short-length = 0~30
3553 * Multi-octet-integer
3556 if (pFile == NULL || pLongInteger == NULL)
3561 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3567 *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
3577 * @param pEncodedData [in] filename encoded data
3578 * @param szBuff [out] filename output buffer
3579 * @param fullLength [in] full filename length
3580 * @param bufLen [in] buffer length
3581 * CAUTION: bufLen - 1
3583 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3585 char *pUTF8Buff = NULL;
3586 char *pLatinBuff = NULL;
3589 char *szSrc2 = NULL;
3593 char *pTmpBuff = NULL;
3595 memset(szBuff, 0, bufLen);
3598 pLatinBuff = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3602 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
3604 strncpy(pLatinBuff, szSrc, textLength);
3609 szSrc2 = MsgChangeHexString(pLatinBuff);
3611 strncpy(pLatinBuff, szSrc2, textLength);
3616 if (MmsIsUtf8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
3617 length = strlen(pLatinBuff);
3619 int utf8BufSize = 0;
3620 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
3621 if (utf8BufSize < 3)
3622 utf8BufSize = 3; /* min value */
3624 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
3625 if (pUTF8Buff == NULL) {
3626 MSG_DEBUG("pUTF8Buff alloc fail");
3630 if (__MsgLatin2UTF((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
3631 MSG_DEBUG("MsgLatin2UTF fail");
3637 pTmpBuff = MsgDecodeText(pLatinBuff);
3638 pUTF8Buff = pTmpBuff;
3647 * it should be kept extention even if the file name is shorten
3650 length = strlen(pUTF8Buff);
3651 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
3653 nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
3654 strncpy(szBuff, pUTF8Buff, nameLength);
3655 g_strlcat(szBuff, pExt, (gsize)bufLen);
3657 strncpy(szBuff, pUTF8Buff, bufLen - 1);
3681 /* ==========================================================
3683 M M S D E C O D I N G
3685 ==========================================================*/
3687 /* to get message body this function should be modified from message raw file. */
3688 bool MmsReadMsgBody(msg_message_id_t msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
3691 MmsMsg *pMsg = NULL;
3692 MsgMultipart *pMultipart = NULL;
3694 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
3695 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
3699 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
3700 memset(pMsg, 0, sizeof(MmsMsg));
3704 if (bRetrieved && (retrievedPath != NULL)) {
3705 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
3707 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath, sizeof(szFullPath));
3710 pMsg->msgID = msgID;
3712 /* read from MMS raw file */
3713 strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
3715 MSG_SEC_DEBUG("msg_id = [%d]", msgID);
3716 MSG_SEC_DEBUG("raw file path = [%s]", szFullPath);
3718 if (MsgGetFileSize(szFullPath, &nSize) == false) {
3719 MSG_FATAL("Fail MsgGetFileSize");
3723 pFile = MsgOpenFile(szFullPath, "rb");
3724 if (pFile == NULL) {
3725 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
3729 MmsRegisterDecodeBuffer();
3731 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
3732 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
3736 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
3737 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
3741 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
3743 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
3744 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
3746 { /* attribute convert mmsHeader -> mmsAttribute */
3747 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
3749 pMsg->mmsAttrib.date = mmsHeader.date;
3751 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
3752 pMsg->mmsAttrib.bAskDeliveryReport = true;
3755 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
3757 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
3759 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
3761 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
3763 pMsg->mmsAttrib.msgType = mmsHeader.type;
3765 pMsg->mmsAttrib.version = mmsHeader.version;
3767 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
3769 pMsg->mmsAttrib.priority = mmsHeader.priority;
3771 if (mmsHeader.readReply == MMS_REPORT_YES) {
3772 pMsg->mmsAttrib.bAskReadReply = true;
3775 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
3777 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
3779 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
3781 /* FIXME:: mmsHeader will release after delete global mmsHeader */
3782 /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
3784 if (pMsg->msgBody.pPresentationBody) {
3785 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
3788 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
3789 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
3792 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
3795 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
3800 MsgCloseFile(pFile);
3803 pMsg->nPartCount = 0;
3805 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
3806 pMultipart = pMsg->msgBody.body.pMultipart;
3807 while (pMultipart) {
3809 pMultipart = pMultipart->pNext;
3812 if (pMsg->msgBody.size > 0)
3816 /* make temporary */
3817 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
3819 if (MsgIsMultipart(pMsg->msgType.type) == true) {
3821 pMultipart = pMsg->msgBody.body.pMultipart;
3823 if (bSavePartsAsTempFiles) {
3824 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3825 if (errno == EEXIST) {
3826 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
3828 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3832 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
3836 if (pMsg->msgBody.pPresentationBody) {
3837 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
3838 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3842 while (pMultipart) {
3843 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
3844 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
3847 MmsPrintMulitpart(pMultipart, partIndex);
3849 pMultipart = pMultipart->pNext;
3853 } else { /* single part */
3854 if (pMsg->nPartCount > 0) {
3855 if (bSavePartsAsTempFiles) {
3856 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3857 if (errno == EEXIST) {
3858 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
3860 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3864 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
3868 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
3869 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3873 MSG_DEBUG("### Success ###");
3880 MmsUnregisterDecodeBuffer();
3882 if (pFile != NULL) {
3883 MsgCloseFile(pFile);
3888 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
3890 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
3892 MSG_DEBUG("### Fail ###");
3897 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
3899 MsgHeaderAddress *pTempAddr = NULL;
3901 while (pAddr != NULL) {
3903 pAddr = pAddr->pNext;
3905 if (pTempAddr->szAddr) {
3906 free(pTempAddr->szAddr);
3907 pTempAddr->szAddr = NULL;
3917 static bool __MsgCheckFileNameHasInvalidChar(char *szName)
3922 strLen = strlen(szName);
3924 for (i = 0; i < strLen; i++) {
3925 if (__MsgIsInvalidFileNameChar(szName[i]))
3932 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
3935 int totalLength = 0;
3937 totalLength = strlen(szInText);
3939 while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
3940 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
3941 if (__MsgIsInvalidFileNameChar(szInText[nCount]))
3942 *(szInText+nCount) = replaceChar;
3953 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter)
3955 char *pszBuffer = NULL;
3956 char *pszStrDelimiter = NULL;
3960 MSG_DEBUG("pszString == NULL");
3964 if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
3965 MSG_DEBUG("There is no %c in %s. \n", delimiter, pszString);
3969 bufLength = pszStrDelimiter - pszString;
3971 if ((pszBuffer = (char*)calloc(1, bufLength + 1)) == NULL) {
3972 MSG_DEBUG("calloc is failed");
3975 memset(pszBuffer, 0, bufLength + 1) ;
3977 strncat(pszBuffer, pszString, bufLength);
3982 char *MsgChangeHexString(char *pOrg)
3985 char szBuf[10] = {0, };
3994 cLen = strlen(pOrg);
3996 pNew = (char *)calloc(1, cLen + 1);
4000 memset(pNew, 0, cLen + 1);
4002 for (cIndex = 0; cIndex< cLen ; cIndex++) {
4003 if (pOrg[cIndex] == '%') {
4004 if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0) {
4005 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); /* read two chars after '%' */
4007 if (__MsgIsHexChar(szBuf) == true) { /* check the two character is between 0 ~ F */
4008 OneChar = __MsgConvertHexValue(szBuf);
4010 pNew[index] = OneChar;
4017 pNew[index++] = pOrg[cIndex];
4022 static bool __MsgParseParameter(MsgType *pType, char *pSrc)
4025 char *pValue = NULL;
4028 char *pNextParam = NULL;
4032 char *pTempNextParam = NULL;
4035 char *pUTF8Buff = NULL;
4037 while (pSrc != NULL) {
4038 pSrc = __MsgSkipWS(pSrc);
4040 /* End of parse parameter */
4045 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
4048 if (*pCh == MSG_CH_QUOT) {
4055 for (; pCh <= pTempNextParam ; pCh++) {
4056 if (*pCh == MSG_CH_QUOT)
4057 if (*(pCh - 1) != '\\')
4062 pNextParam = pTempNextParam;
4065 *pNextParam++ = MSG_CH_NULL;
4067 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
4068 *pName++ = MSG_CH_NULL;
4070 if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
4071 *pValue++ = MSG_CH_NULL;
4073 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
4074 *pTest = MSG_CH_NULL;
4076 pDec = MsgDecodeText(pValue); /* Api is to long, consider Add to another file (MsgMIMECodec.c) */
4078 pDec = MsgDecodeText(pName);
4082 switch (MmsGetTextType(MmsCodeParameterCode, pSrc)) {
4083 case MSG_PARAM_BOUNDARY:
4084 /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
4085 memset(pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
4086 strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
4087 MSG_SEC_INFO("szBoundary = [%s]", pType->param.szBoundary);
4090 case MSG_PARAM_CHARSET:
4091 pType->param.charset = MmsGetTextType(MmsCodeParameterCode, pDec);
4093 if (pType->param.charset == -1)
4094 pType->param.charset = MSG_CHARSET_UNKNOWN;
4096 MSG_SEC_INFO("type = %d [charset] = %d", pType->type, pType->param.charset);
4099 case MSG_PARAM_NAME:
4100 memset(pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
4102 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4105 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4106 if ((MSG_LOCALE_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4107 nameLen = (MSG_LOCALE_FILENAME_LEN_MAX-1) - strlen(pExt);
4109 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4112 strncpy(pType->param.szName, pUTF8Buff, nameLen);
4113 g_strlcat(pType->param.szName, pExt, sizeof(pType->param.szName));
4115 strncpy(pType->param.szName, pUTF8Buff, (MSG_LOCALE_FILENAME_LEN_MAX-1));
4120 if (__MsgChangeSpace(pType->param.szName, &szSrc) == true) {
4122 strncpy(pType->param.szName, szSrc , strlen(szSrc));
4130 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4131 __MsgRemoveFilePath(pType->param.szName);
4133 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4136 MSG_SEC_INFO("szName = %s", pType->param.szName);
4139 case MSG_PARAM_FILENAME:
4140 memset(pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
4142 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4145 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4146 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4147 nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
4149 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4152 strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
4153 g_strlcat (pType->param.szFileName, pExt, sizeof(pType->param.szFileName));
4155 strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
4160 if (__MsgChangeSpace(pType->param.szFileName, &szSrc) == true) {
4161 snprintf(pType->param.szFileName, sizeof(pType->param.szFileName), "%s", szSrc);
4169 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4170 __MsgRemoveFilePath(pType->param.szFileName);
4172 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4175 MSG_SEC_INFO("szFileName = %s", pType->param.szFileName);
4179 case MSG_PARAM_TYPE:
4180 /* type/subtype of root. Only if content-type is multipart/related */
4181 pType->param.type = MimeGetMimeIntFromMimeString(pDec);
4182 MSG_SEC_INFO("type = %d", pType->param.type);
4186 case MSG_PARAM_START:
4187 /* Content-id. Only if content-type is multipart/related */
4188 memset(pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
4189 strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
4191 MSG_SEC_INFO("szStart = %s", pType->param.szStart);
4195 case MSG_PARAM_START_INFO:
4196 /* Only if content-type is multipart/related */
4197 memset(pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
4198 strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
4200 MSG_SEC_INFO("szStartInfo = %s", pType->param.szStartInfo);
4204 case MSG_PARAM_REPORT_TYPE:
4205 /* only used as parameter of Content-Type: multipart/report; report-type=delivery-status; */
4206 if (strcasecmp(pDec, "delivery-status") == 0) {
4207 pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
4209 pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
4212 MSG_SEC_INFO("reportType = %s", pDec);
4216 MSG_DEBUG("Unknown paremeter (%s)", pDec);
4229 static char *__MsgSkipWS(char *s)
4232 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
4234 } else if ((*s != '(') || (__MsgSkipComment(s, (long)NULL) == NULL)) {
4240 static char *__MsgSkipComment(char *s, long trim)
4246 /* ignore empty space */
4247 for (ret = ++s1; *ret == ' '; ret++)
4250 /* handle '(', ')', '\', '\0' */
4254 if (!__MsgSkipComment(s1, (long)NULL))
4286 static char *__MsgConvertLatin2UTF8FileName(char *pSrc)
4288 char *pUTF8Buff = NULL;
4289 /* char *pData = NULL; */
4292 /* convert utf8 string */
4293 if (MmsIsUtf8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
4295 int utf8BufSize = 0;
4297 length = strlen(pSrc);
4298 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
4299 if (utf8BufSize < 3)
4300 utf8BufSize = 3; /* min value */
4302 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
4304 if (pUTF8Buff == NULL) {
4305 MSG_DEBUG("pUTF8Buff alloc fail");
4309 if (__MsgLatin2UTF((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
4310 MSG_DEBUG("MsgLatin2UTF fail");
4314 int length = strlen(pSrc);
4315 pUTF8Buff = (char *)calloc(1, length+1);
4317 if (pUTF8Buff == NULL) {
4318 MSG_DEBUG("pUTF8Buff alloc fail");
4322 memcpy(pUTF8Buff, pSrc, length);
4325 /* convert hex string */
4327 if (__MsgIsPercentSign(pUTF8Buff) == true) {
4328 pData = MsgChangeHexString(pUTF8Buff);
4348 static bool __MsgChangeSpace(char *pOrg, char **ppNew)
4358 cLen = strlen(pOrg);
4360 pNew = (char *)calloc(1, cLen + 1);
4364 memset(pNew, 0, cLen + 1);
4366 for (cIndex=0; cIndex < cLen; cIndex++) {
4367 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
4373 pNew[index++] = pOrg[cIndex];
4381 static void __MsgRemoveFilePath(char *pSrc)
4383 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4385 char *tmp_name = NULL;
4387 tmp_name = MsgGetFileName(pSrc);
4389 snprintf(pSrc, strlen(tmp_name), "%s", tmp_name);
4394 /* Remove additional file information
4395 * ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
4396 * if "?size=" exist, insert NULL char. */
4397 pTemp = strcasestr(pSrc, "?size=");
4403 static bool __MsgIsPercentSign(char *pSrc)
4408 pCh = strchr(pSrc , '%');
4420 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam)
4422 char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
4423 char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
4424 char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
4427 /* remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445> */
4428 if (szStart && szStart[0]) {
4430 startLen = strlen(szStart);
4431 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
4432 strncpy(szTmpStart, &szStart[1], startLen - 2);
4434 strncpy(szTmpStart, szStart, startLen);
4438 /* remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445> */
4439 if (multipartType->szContentID[0]) {
4440 strLen = strlen(multipartType->szContentID);
4441 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
4442 strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
4444 strncpy(szTmpContentID, multipartType->szContentID, strLen);
4448 /* remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445> */
4449 if (multipartType->szContentLocation[0]) {
4450 strLen = strlen(multipartType->szContentLocation);
4451 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
4452 strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
4454 strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
4458 if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
4459 return MSG_PRESENTATION_NONE;
4461 /* exception handling */
4462 if (szTmpStart[0] != '\0') {
4463 /* presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type */
4464 if (strcmp(szTmpStart, szTmpContentID) == 0) {
4465 return MSG_PRESENTATION_ID;
4466 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
4467 return MSG_PRESENTATION_LOCATION;
4468 } else if (multipartType->type == typeParam) {
4469 return MSG_PRESENTATION_TYPE_BASE;
4471 return MSG_PRESENTATION_NONE;
4474 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
4475 return MSG_PRESENTATION_TYPE_BASE;
4477 return MSG_PRESENTATION_NONE;
4482 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
4485 MsgMultipart *pNextPart = NULL;
4486 MsgMultipart *pRemovePart = NULL;
4488 if (__MsgIsMultipartRelated(pMsgType->type)) {
4489 /* assign the multipart to presentation part */
4490 /* remove the multipart(pCurPresentation) which is presentation part from the linked list. */
4491 /* if there is no presentation part -> assign first multipart to presentation part by force. */
4492 if (pPresentationInfo->pCurPresentation == NULL) {
4493 pPresentationInfo->pCurPresentation = pMsgBody->body.pMultipart;
4494 pPresentationInfo->pPrevPart = NULL;
4495 pPresentationInfo->factor = MSG_PRESENTATION_NONE;
4498 if (pPresentationInfo->pCurPresentation != NULL && __MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
4499 /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
4500 * In this case, COPY the Presentation part and leave other multiparts.
4502 memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4503 pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
4505 /* remove pCurPresentation from multipart linked list */
4506 if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE) || (pPresentationInfo->pPrevPart == NULL)) {
4508 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
4509 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4510 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4511 if (pPresentationInfo->pCurPresentation) {
4512 MmsReleaseMsgDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
4514 free(pPresentationInfo->pCurPresentation);
4515 pPresentationInfo->pCurPresentation = NULL;
4518 /* not a first part */
4519 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
4520 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4521 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4522 if (pPresentationInfo->pCurPresentation) {
4523 free(pPresentationInfo->pCurPresentation);
4524 pPresentationInfo->pCurPresentation = NULL;
4527 } else if (pPresentationInfo->pCurPresentation != NULL && MmsIsTextType(pPresentationInfo->pCurPresentation->type.type)) {
4528 /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
4529 * In this case, leave the Presentation part as a multipart and remove other multiparts.
4532 /* Backup the multipart link information */
4533 pNextPart = pMsgBody->body.pMultipart;
4535 /* Copy presentation part as a main part */
4536 memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4537 memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
4539 /* Remove multipart linked list */
4541 pRemovePart = pNextPart;
4542 pNextPart = pNextPart->pNext;
4544 if (pRemovePart->pBody) {
4545 MmsReleaseMsgBody(pRemovePart->pBody, pRemovePart->type.type);
4546 free(pRemovePart->pBody);
4547 pRemovePart->pBody = NULL;
4554 MmsReleaseMsgDRMInfo(&pMsgBody->presentationType.drmInfo);
4556 MmsInitMsgType(&pMsgBody->presentationType);
4557 pMsgBody->pPresentationBody = NULL;
4563 static bool __MsgIsMultipartRelated(int type)
4565 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
4572 static bool __MsgIsPresentablePart(int type)
4574 if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
4581 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
4584 MsgMultipart *pTmpMultipart = NULL;
4585 MsgMultipart *pSelectedPart = NULL;
4586 MsgMultipart *pPrevPart = NULL;
4587 MsgMultipart *pFirstPart = NULL;
4588 MsgMultipart *pLastPart = NULL;
4589 MsgMultipart *pRemoveList = NULL;
4590 MsgMultipart *pNextRemovePart = NULL;
4592 switch (pPartType->type) {
4593 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
4594 case MIME_MULTIPART_ALTERNATIVE:
4597 * Policy: multipart/alternative
4598 * multipart/alternative message has only several parts of media.
4599 * You should choose one of them and make the alternative part
4600 * to the selected media part.
4603 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE");
4605 pSelectedPart = pPartBody->body.pMultipart;
4607 /* NULL Pointer check!! */
4608 if (pSelectedPart == NULL) {
4609 MSG_DEBUG("multipart(ALTERNATIVE) does not exist");
4613 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4615 while (pTmpMultipart) {
4616 if (pSelectedPart->type.type <= pTmpMultipart->type.type)
4617 pSelectedPart = pTmpMultipart;
4619 pTmpMultipart = pTmpMultipart->pNext;
4622 pTmpMultipart = pPartBody->body.pMultipart;
4625 while (pTmpMultipart) {
4626 if (pSelectedPart == pTmpMultipart)
4629 pPrevPart = pTmpMultipart;
4630 pTmpMultipart = pTmpMultipart->pNext;
4633 if (pPrevPart == NULL) {
4634 /* selected part is the first part */
4635 pRemoveList = pSelectedPart->pNext;
4637 pPrevPart->pNext = pSelectedPart->pNext;
4638 pRemoveList = pPartBody->body.pMultipart;
4639 pPartBody->body.pMultipart = pSelectedPart;
4642 pSelectedPart->pNext = NULL;
4645 MmsReleaseMsgDRMInfo(&pRemoveList->type.drmInfo);
4647 MmsReleaseMsgBody(pRemoveList->pBody, pRemoveList->type.type);
4649 free(pRemoveList->pBody);
4653 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4654 MSG_DEBUG("MsgPriorityCopyMsgType failed");
4658 if (pSelectedPart->pBody != NULL)
4659 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4661 if (pSelectedPart != NULL) {
4662 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4664 if (pSelectedPart->pBody != NULL) {
4665 free(pSelectedPart->pBody);
4666 pSelectedPart->pBody = NULL;
4668 free(pSelectedPart);
4669 pSelectedPart = NULL;
4674 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
4675 case MIME_MULTIPART_RELATED:
4677 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_RELATED");
4679 pSelectedPart = pPartBody->body.pMultipart;
4681 while (pSelectedPart) {
4682 if (__MsgIsMultipartMixed(pSelectedPart->type.type)) {
4683 if (pSelectedPart->pBody == NULL) {
4684 MSG_DEBUG("pSelectedPart->pBody(1) is NULL");
4688 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4690 if (pFirstPart == NULL) {
4691 MSG_DEBUG("multipart(RELATED) does not exist");
4695 if (pFirstPart->pNext) {
4696 pLastPart = pFirstPart->pNext;
4697 while (pLastPart->pNext)
4698 pLastPart = pLastPart->pNext;
4700 pLastPart = pFirstPart;
4703 if (pPrevPart == NULL) {
4704 /* the first part */
4705 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4706 pPartBody->body.pMultipart = pFirstPart;
4707 pLastPart->pNext = pTmpMultipart;
4709 pTmpMultipart = pSelectedPart->pNext;
4710 pPrevPart->pNext = pFirstPart;
4711 pLastPart->pNext = pTmpMultipart;
4714 if (pSelectedPart) {
4715 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4717 free(pSelectedPart->pBody);
4718 free(pSelectedPart);
4720 pSelectedPart = pTmpMultipart;
4721 } else if (__MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
4722 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
4723 MmsReleaseMsgBody(pSelectedPart->pBody, pSelectedPart->type.type);
4725 free(pSelectedPart->pBody);
4726 free(pSelectedPart);
4727 pSelectedPart = pTmpMultipart;
4729 pPrevPart = pSelectedPart;
4730 pSelectedPart = pSelectedPart->pNext;
4737 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
4738 case MIME_MULTIPART_MIXED:
4740 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_MIXED");
4743 pSelectedPart = pPartBody->body.pMultipart;
4745 while (pSelectedPart) {
4746 if (MsgIsMultipart(pSelectedPart->type.type)) {
4747 if (pSelectedPart->pBody == NULL) {
4748 MSG_DEBUG("pSelectedPart->pBody(2) is NULL");
4752 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4754 /* NULL Pointer check!! */
4755 if (pFirstPart == NULL) {
4756 MSG_DEBUG("multipart does not exist");
4760 if (pFirstPart->pNext) {
4761 pLastPart = pFirstPart->pNext;
4762 while (pLastPart->pNext)
4763 pLastPart = pLastPart->pNext;
4765 pLastPart = pFirstPart;
4768 if (pPrevPart == NULL) {
4769 /* the first part */
4770 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4771 pPartBody->body.pMultipart = pFirstPart;
4772 pLastPart->pNext = pTmpMultipart;
4774 pTmpMultipart = pSelectedPart->pNext;
4775 pPrevPart->pNext = pFirstPart;
4776 pLastPart->pNext = pTmpMultipart;
4779 if (pSelectedPart->pBody->pPresentationBody)
4780 pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
4782 memcpy(&pPartBody->presentationType,
4783 &pSelectedPart->pBody->presentationType, sizeof(MsgType));
4785 pPartType->type = pSelectedPart->type.type;
4787 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4789 free(pSelectedPart->pBody);
4790 free(pSelectedPart);
4792 pSelectedPart = pTmpMultipart;
4794 pPrevPart = pSelectedPart;
4795 pSelectedPart = pSelectedPart->pNext;
4801 case MIME_MULTIPART_REPORT:
4803 MSG_DEBUG("MIME_MULTIPART_REPORT");
4805 pTmpMultipart = pPartBody->body.pMultipart;
4808 if (pTmpMultipart == NULL) {
4809 MSG_DEBUG("pTmpMultipart == NULL");
4813 while (pTmpMultipart) {
4814 if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
4815 pSelectedPart = pTmpMultipart;
4819 pPrevPart = pTmpMultipart;
4820 pTmpMultipart = pTmpMultipart->pNext;
4823 if (pSelectedPart == NULL) {
4824 MSG_DEBUG("MIME_MULTIPART_REPORT [no selected part]");
4826 pRemoveList = pPartBody->body.pMultipart->pNext;
4827 if (pPartBody->body.pMultipart != NULL) {
4828 pSelectedPart = pPartBody->body.pMultipart;
4829 pSelectedPart->pNext = NULL;
4832 if (pPrevPart == NULL) {
4833 /* first part is selected */
4834 pRemoveList = pPartBody->body.pMultipart->pNext;
4836 pRemoveList = pPartBody->body.pMultipart->pNext;
4837 pPrevPart->pNext = pSelectedPart->pNext;
4840 pSelectedPart->pNext = NULL;
4841 pPartBody->body.pMultipart = pSelectedPart;
4844 pTmpMultipart = pRemoveList;
4846 while (pTmpMultipart) {
4847 MmsReleaseMsgDRMInfo(&pTmpMultipart->type.drmInfo);
4849 MmsReleaseMsgBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
4850 pNextRemovePart = pTmpMultipart->pNext;
4852 free(pTmpMultipart->pBody);
4853 free(pTmpMultipart);
4854 pTmpMultipart = pNextRemovePart;
4857 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4858 MSG_DEBUG("MsgPriorityCopyMsgType failed");
4862 if (pSelectedPart != NULL) {
4863 if (pSelectedPart->pBody != NULL)
4864 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4866 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4868 if (pSelectedPart->pBody != NULL) {
4869 free(pSelectedPart->pBody);
4870 pSelectedPart->pBody = NULL;
4872 free(pSelectedPart);
4873 pSelectedPart = NULL;
4889 char *MsgResolveContentURI(char *szSrc)
4891 char *szTemp = NULL;
4892 char *szReturn = NULL;
4895 if (szSrc == NULL) {
4899 if (szSrc[0] == '\0')
4903 if (!strncasecmp(szSrc, "cid:", 4)) {
4904 length = strlen(szSrc) - 3;
4907 length = strlen(szSrc) + 1;
4910 szTemp = (char *)calloc(1, length);
4911 if (szTemp == NULL) {
4912 MSG_DEBUG("memory full");
4916 memset(szTemp, 0, length);
4918 strncpy(szTemp, szSrc, length - 1);
4920 szReturn = MsgChangeHexString(szTemp);
4934 char *MsgRemoveQuoteFromFilename(char *pSrc)
4936 int cLen = 0; /* length of pBuff */
4940 MSG_DEBUG("pSrc is Null");
4944 cLen = strlen(pSrc);
4946 pBuff = (char *)calloc(1, cLen + 1);
4948 if (pBuff == NULL) {
4949 MSG_DEBUG("pBuff mem alloc fail!");
4952 memset(pBuff, 0 , sizeof(char)*(cLen + 1));
4954 /* remove front quote */
4955 if (pSrc[0] == MSG_CH_QUOT) {
4957 strncpy(pBuff, &pSrc[1], cLen);
4959 } else if (pSrc[0] == MSG_CH_LF) {
4961 strncpy(pBuff, &pSrc[1], cLen);
4963 strncpy(pBuff, pSrc, cLen);
4966 /* remove last qoute */
4967 if (pBuff[cLen-1] == MSG_CH_QUOT) {
4968 pBuff[cLen-1] = '\0';
4974 bool MsgIsMultipart(int type)
4976 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
4977 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
4978 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
4986 static bool __MsgIsHexChar(char *pSrc)
4992 cLen = strlen(pSrc);
4994 for (cIndex = 0; cIndex < cLen ; cIndex++) {
4995 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
4996 (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
5006 static char __MsgConvertHexValue(char *pSrc)
5012 unsigned char uCh[2] = {0, };
5014 cLen = strlen(pSrc);
5016 for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
5017 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
5018 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
5019 ch = (int)uCh[0] << 4 | uCh[1];
5022 ResultChar = (char)ch;
5027 static int __MsgConvertCharToInt(char ch)
5029 if (ch >= '0' && ch <= '9') {
5031 } else if (ch >= 'a' && ch <= 'f') {
5033 } else if (ch >= 'A' && ch <= 'F') {
5040 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
5042 if (!pMsgType1 || !pMsgType2)
5045 /* if (pMsgType1->section == INVALID_HOBJ) */
5046 pMsgType1->section = pMsgType2->section;
5050 if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
5051 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
5054 if (pMsgType1->szContentID[0] == '\0') {
5055 snprintf(pMsgType1->szContentID, sizeof(pMsgType1->szContentID), "%s", pMsgType2->szContentID);
5058 if (pMsgType1->szContentID[0] != '\0') {
5059 length = strlen(pMsgType1->szContentID);
5060 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
5061 char szTempString[MSG_MSG_ID_LEN + 1];
5062 MmsRemoveLessGreaterChar(pMsgType1->szContentID, szTempString, sizeof(szTempString));
5063 pMsgType1->drmInfo.szContentURI = g_strdup(szTempString);
5065 pMsgType1->drmInfo.szContentURI = g_strdup(pMsgType1->szContentID);
5069 if (pMsgType1->szContentLocation[0] == '\0') {
5070 strncpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation, MSG_MSG_ID_LEN);
5073 /* Copy informations - we shoud open the pMsgType2's orgFile
5074 * concerning its offset and size.
5076 if (pMsgType2->szOrgFilePath[0] != '\0') {
5077 strncpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath, MSG_FILEPATH_LEN_MAX-1);
5080 if (pMsgType2->disposition != -1)
5081 pMsgType1->disposition = pMsgType2->disposition;
5083 if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
5084 pMsgType2->encoding != -1)
5085 pMsgType1->encoding = pMsgType2->encoding;
5087 pMsgType1->contentSize = pMsgType2->contentSize;
5088 pMsgType1->offset = pMsgType2->offset;
5089 pMsgType1->size = pMsgType2->size;
5090 pMsgType1->type = pMsgType2->type;
5092 __MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
5094 if (pMsgType1->param.szName[0]) {
5095 pMsgType1->drmInfo.szContentName = g_strdup(pMsgType2->param.szName);
5101 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
5103 if (pParam1->charset == MSG_CHARSET_UNKNOWN)
5104 pParam1->charset = pParam2->charset;
5106 if (pParam1->type == MIME_UNKNOWN)
5107 pParam1->type = pParam2->type;
5109 /* Don't copy pParam2->pPresentation */
5111 /* For alternative: copy the boundary string */
5112 if (pParam2->szBoundary[0] !='\0') {
5113 strncpy(pParam1->szBoundary, pParam2->szBoundary, MSG_BOUNDARY_LEN);
5116 if (pParam1->szFileName[0] =='\0') {
5117 strncpy(pParam1->szFileName, pParam2->szFileName, MSG_FILENAME_LEN_MAX);
5120 if (pParam1->szName[0] =='\0') {
5121 strncpy(pParam1->szName, pParam2->szName, MSG_LOCALE_FILENAME_LEN_MAX);
5124 if (pParam1->szStart[0] =='\0') {
5125 strncpy(pParam1->szStart, pParam2->szStart, MSG_MSG_ID_LEN);
5128 if (pParam1->szStartInfo[0] =='\0') {
5129 strncpy(pParam1->szStartInfo, pParam2->szStartInfo, MSG_MSG_ID_LEN);
5134 static bool __MsgIsMultipartMixed(int type)
5136 if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
5143 static bool __MsgIsInvalidFileNameChar(char ch)
5145 if ((ch == 0x5C /* \ */) ||
5146 (ch == 0x2F /* / */) ||
5147 (ch == 0x3A /* : */) ||
5148 (ch == 0x2A /* * */) ||
5149 (ch == 0x3F /* ? */) ||
5150 (ch == 0x22 /* " */) ||
5151 (ch == 0x3C /* < */) ||
5152 (ch == 0x3E /* > */) ||
5153 (ch == 0x7C /* | */))
5159 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
5163 MSG_DEBUG("---------------");
5165 if ((szSrc == NULL) || (nChar <= 0)) {
5166 MSG_DEBUG("szSrc is NULL !!!! ---------------");
5170 while ((nChar > 0) && (*szSrc != '\0')) {
5171 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5185 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5188 unsigned char t1, t2;
5190 MSG_DEBUG("---------------");
5193 outBufSize--; /* NULL character */
5195 while ((nChar > 0) && (*szSrc != '\0')) {
5196 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5197 /* check outbuffer's room for this UTF8 character */
5202 *des = (unsigned char) (*szSrc & 0x007F);
5208 /* check outbuffer's room for this UTF8 character */
5214 t2 = (unsigned char) (*szSrc & 0x003F); /* right most 6 bit */
5215 t1 = (unsigned char) ((*szSrc & 0xC0) >> 6); /* right most 2 bit */
5217 *des = 0xC0 | (t1 & 0x1F);
5218 *(des + 1) = 0x80 | (t2 & 0x3F);
5232 bool MmsAddrUtilCheckEmailAddress(char *pszAddr)
5234 if (!pszAddr || pszAddr[0] == 0)
5237 if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
5243 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
5245 char *pszAddrCopy = NULL;
5246 char *pszStrStart = NULL;
5247 char *pszStrTemp = NULL;
5250 if ((!pszAddr) || (pszAddr[0] == 0)) {
5251 MSG_DEBUG("pszAddr is null or zero");
5255 strLen = strlen(pszAddr);
5257 pszAddrCopy = (char*)calloc(1, strLen + 1);
5259 MSG_DEBUG("pszAddrCopy is NULL, mem alloc failed");
5263 strncpy(pszAddrCopy, pszAddr, strLen);
5266 pszStrStart = pszAddrCopy;
5269 char* pszStrEnd = NULL;
5272 if (MmsAddrUtilCheckEmailAddress(pszAddrCopy))
5273 pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
5275 pszStrEnd = strstr(pszStrStart, "/");
5278 char *pszStart = NULL;
5279 char *pszEnd = NULL;
5280 /* "/TYPE=PLMN" not found */
5282 int remainedLen = strlen(pszStrStart);
5284 if (remainedLen <= 0)
5287 /* Email address can occur with Sender Name<email-address> format */
5288 /* remove the Sender name and only retain the email address. */
5289 pszStart = strstr(pszStrStart, "<");
5291 pszEnd = strstr(pszStrStart, ">");
5294 pszStart++; /* skip "<" */
5295 g_strlcat(pszAddr, pszStart, pszEnd - pszStart + 1);
5300 g_strlcat(pszAddr, pszStrStart, strLen + 1);
5304 /* Get one address length */
5305 addressLen = pszStrEnd - pszStrStart;
5307 strncat(pszAddr, pszStrStart, addressLen);
5309 /* Find next address */
5310 pszStrStart = pszStrEnd;
5312 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
5315 addressLen = pszStrTemp - pszStrEnd;
5316 pszStrStart += addressLen;
5318 pszStrStart += strlen(pszStrEnd);
5321 if (pszStrStart[0] == 0) /* end of string */
5325 g_strlcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER, strLen + 1); /* add ';' */
5326 pszStrStart++; /* remove ';' */
5329 if (pszAddr[0] == 0)
5330 strncpy(pszAddr, pszAddrCopy, strLen);
5337 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5341 MSG_DEBUG("---------------");
5344 outBufSize--; /* NULL character */
5346 while ((nChar > 0) && (*szSrc != '\0')) {
5347 if (*szSrc < 0x80) {
5355 } else if (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
5361 *(des + 1) = *(szSrc + 1);
5365 } else if ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
5371 *(des + 1) = *(szSrc + 1);
5372 *(des + 2) = *(szSrc + 2);
5384 MSG_DEBUG("utf8 incorrect range!");
5396 static void __MsgMIMERemoveQuote(char *szSrc)
5400 length = strlen(szSrc);
5401 if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
5404 for (index = 0; index < length-2; index++)
5405 szSrc[index] = szSrc[index+1];
5406 szSrc[index] = '\0';
5410 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
5416 if (pFile == NULL) {
5423 if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
5430 if (*pBufLen == 0) {
5431 length = maxLen - (*pPtr);
5433 length = (*pBufLen) - (*pPtr);
5439 if ((*ppBuf) == NULL) {
5440 memset(pInBuf1, 0, maxLen);
5442 } else if ((*ppBuf) == pInBuf1) {
5443 memset(pInBuf2, 0, maxLen);
5445 memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
5448 memset(pInBuf1, 0, maxLen);
5450 memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
5456 if (*pOffset == endOfFile) {
5461 if (maxLen == length) {
5463 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
5468 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
5471 *pBufLen = length + nRead;
5474 if ((*pOffset = MsgFtell(pFile)) == -1L) {
5475 MSG_DEBUG("MsgFtell Error");
5485 * This function write media data from raw data to file.
5488 * @param pszMailboxPath : path of mailbox
5489 * @param pszMsgFilename : name of msg file
5490 * @param index : used for file naming
5491 * @param bSave : if true, file will be save otherwise just filename will be stored.
5493 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
5496 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, }; /* file name of temp file */
5497 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; /* full absolute path of temp file. */
5498 bool bFileExist = false;
5502 MSG_DEBUG("pPartType is NULL");
5506 if (pPartType->type == MIME_APPLICATION_SMIL) {
5507 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", "smil.txt");
5509 if (pPartType->param.szName[0] != '\0') {
5510 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szName);
5511 } else if (pPartType->param.szFileName[0] != '\0') {
5512 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szFileName);
5513 } else if (pPartType->szContentLocation[0] != '\0') {
5514 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->szContentLocation);
5516 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
5520 /* make full path for save */
5521 __MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0, szFileName, sizeof(szFileName)); /* FL & CD -> extension(.dm) SD -> extension(.dcf) */
5523 snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName); /* get absolute path of each temp file of each part */
5525 if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
5526 MsgGetMimeTypeFromFileName(MIME_MAINTYPE_UNKNOWN, szFullPath, (MimeType *)&pPartType->type, NULL);
5529 bFileExist = MsgAccessFile(szFullPath, F_OK);
5531 MSG_SEC_DEBUG("save flag [%d], filepath [%s], file exist [%d]", bSave, szFullPath, bFileExist);
5533 if (bSave == true && bFileExist == false) {
5534 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
5535 MSG_DEBUG("MsgOpenFile failed");
5539 if (__MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
5540 MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
5544 MsgCloseFile(pFile);
5547 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5549 /* IF DRM type Convert to dcf */
5550 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5551 || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT) {
5552 char destDrmPath[MSG_FILEPATH_LEN_MAX] = {0, };
5554 if (MsgDrmConvertDmtoDcfType(pPartBody->szOrgFilePath, destDrmPath) == true) {
5555 MSG_INFO("Success Convert to Dcf");
5557 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5560 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5561 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5565 MSG_INFO("Fail Convert to Dcf");
5568 if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5569 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5571 MSG_SEC_INFO("Drm File Path [%s] isdrm [%d]", pPartBody->szOrgFilePath, MsgDrmIsDrmFile(pPartBody->szOrgFilePath));
5574 pPartBody->offset = 0;
5575 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5577 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
5578 MsgDrmRegisterFile(MSG_MODE_FILE, pPartBody->szOrgFilePath, strlen(pPartBody->szOrgFilePath));
5580 /* change szDrm2FullPath as current content path*/
5581 if (pPartType->drmInfo.szDrm2FullPath) {
5582 free(pPartType->drmInfo.szDrm2FullPath);
5583 pPartType->drmInfo.szDrm2FullPath = g_strdup(pPartBody->szOrgFilePath);
5587 MSG_SEC_DEBUG("Save Part File to [%s]", pPartBody->szOrgFilePath);
5590 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5592 /* IF DRM type check dcf exist */
5593 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5594 || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT) {
5595 char destDrmPath[MSG_FILEPATH_LEN_MAX] = {0, };
5597 MsgGetFileNameWithoutExtension(destDrmPath, pPartBody->szOrgFilePath);
5598 strncat(destDrmPath, ".dcf", 4);
5600 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5603 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5604 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5607 if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5608 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5611 pPartBody->offset = 0;
5612 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5614 MSG_SEC_DEBUG("Set Part File to [%s]", pPartBody->szOrgFilePath);
5618 if (szFileName[0] != '\0') {
5619 snprintf(pPartType->param.szFileName, MSG_FILENAME_LEN_MAX+1, "%s.dir/%s", pszMsgFilename, szFileName); /* store relative path of each temp file of each part including sub folder. */
5620 snprintf(pPartType->param.szName, MSG_LOCALE_FILENAME_LEN_MAX+1, "%s", szFileName);
5621 MSG_SEC_DEBUG("Set Name : %s", pPartType->param.szName);
5629 if (pFile != NULL) {
5630 MsgCloseFile(pFile);
5637 bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
5642 char *pNewData = NULL;
5643 char *pTempData = NULL;
5644 int msgEncodingValue = 0;
5645 int msgTypeValue = 0;
5646 int msgCharsetValue = 0;
5651 msgEncodingValue = pPartType->encoding;
5652 msgTypeValue = pPartType->type;
5653 msgCharsetValue = pPartType->param.charset;
5655 offset = pPartBody->offset;
5656 size = pPartBody->size;
5658 if (pPartBody->szOrgFilePath[0]) {
5659 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
5661 if (pTempData == NULL) {
5662 MSG_DEBUG("pTempData read fail");
5667 } else if (pPartBody->body.pText) {
5668 pData = pPartBody->body.pText;
5669 nRead = pPartBody->size;
5672 if (pData == NULL) {
5673 MSG_DEBUG("there is no data");
5677 pNewData = __MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
5680 pPartType->encoding = MSG_ENCODING_BINARY;
5682 if (MmsIsTextType(msgTypeValue))
5683 pPartType->param.charset = MSG_CHARSET_UTF8;
5685 if (MsgWriteFile(pNewData, sizeof(char), nRead2, pFile) != (size_t)nRead2) {
5686 MSG_DEBUG("file writing fail");
5691 if (MsgWriteFile(pData, sizeof(char), nRead, pFile) != (size_t)nRead) {
5692 MSG_DEBUG("file writing fail");
5726 char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
5732 char *pConvertedStr = NULL;
5733 char *pConvertedData = NULL;
5734 char *pNewData = NULL;
5735 char *pReturnData = NULL;
5737 const char *pToCodeSet = "UTF-8";
5738 const char *pFromCodeSet = NULL;
5740 switch (msgEncodingValue) {
5741 case MSG_ENCODING_BASE64:
5743 pConvertedData = (char*)MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5744 MSG_DEBUG("MSG_ENCODING_BASE64 bodyLength [%d]", nByte);
5746 pTemp = pConvertedData;
5751 case MSG_ENCODING_QUOTE_PRINTABLE:
5753 pConvertedData = (char*)MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5754 MSG_DEBUG("MSG_ENCODING_QUOTE_PRINTABLE bodyLength [%d]", nByte);
5756 pTemp = pConvertedData;
5763 MSG_DEBUG("encoding val [%d] bodyLength [%d]", msgEncodingValue, nRead);
5770 if (MmsIsTextType(msgTypeValue)) {
5771 if (msgCharsetValue == MSG_CHARSET_US_ASCII) {
5774 } else if (msgCharsetValue == MSG_CHARSET_UTF8) {
5775 /* skip BOM(Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM) */
5777 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
5786 UINT16 MIBenum = MmsGetBinaryValue(MmsCodeCharSet, msgCharsetValue);
5788 pFromCodeSet = MmsGetTextByCode(MmsCodeCharSet, MIBenum);
5790 MSG_DEBUG("char set enum = [%d], MIBenum = [%d], str = [%s]", msgCharsetValue, MIBenum, pFromCodeSet);
5793 MSG_DEBUG("Convert to UTF-8");
5795 if (MmsPluginTextConvert(pToCodeSet, pFromCodeSet, pTemp, nTemp, &pConvertedStr, npRead) == true) {
5796 pNewData = pConvertedStr;
5798 MSG_DEBUG("Failed MmsPluginTextConvert");
5803 } else { /* unsupported charset */
5804 MSG_DEBUG("unsupported charset");
5815 pReturnData = (char *)calloc(1, *npRead);
5816 if (pReturnData == NULL) {
5817 MSG_DEBUG("pReturnData alloc fail.");
5821 if (pNewData != NULL) {
5822 memset(pReturnData, 0, *npRead);
5823 memcpy(pReturnData, pNewData, *npRead);
5826 if (pConvertedData) {
5827 free(pConvertedData);
5828 pConvertedData = NULL;
5831 if (pConvertedStr) {
5832 free(pConvertedStr);
5833 pConvertedStr = NULL;
5840 if (pConvertedData) {
5841 free(pConvertedData);
5842 pConvertedData = NULL;
5845 if (pConvertedStr) {
5846 free(pConvertedStr);
5847 pConvertedStr = NULL;
5853 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen)
5855 char szTemp[MSG_FILENAME_LEN_MAX+1] = {0, };
5856 char szTempFileName[MSG_FILENAME_LEN_MAX+1] = {0, };
5857 const char *pExt = NULL;
5859 MSG_SEC_DEBUG("Input : type [0x%x], drmType [%d], filename [%s]", iMsgType, drmType, szFileName);
5861 if (szFileName == NULL)
5865 int inp_len = strlen(szFileName);
5867 pExt = strrchr(szFileName, '.');
5869 if (pExt != NULL && *(pExt + 1) != '\0') {
5875 MsgGetFileNameWithoutExtension(szTempFileName, szFileName);
5877 if (nUntitleIndex >= 1) {
5878 snprintf(szTempFileName, sizeof(szTempFileName), "%s_%d", "untitled", nUntitleIndex);
5880 snprintf(szTempFileName, sizeof(szTempFileName), "%s", "untitled");
5885 if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_MESSAGE)
5887 else if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5890 if (pExt == NULL) { /* find ext from content type */
5891 if (iMsgType == MIME_APPLICATION_OCTET_STREAM || iMsgType == MIME_UNKNOWN) {
5892 MSG_DEBUG("unsupported MsgType [%d]", iMsgType);
5896 pExt = MimeGetExtFromMimeInt((MimeType)iMsgType);
5899 /* Filename + extension */
5901 snprintf(szTemp, sizeof(szTemp), "%s.%s", szTempFileName, pExt);
5903 MSG_DEBUG("Failed to get extension of that mime data file.");
5907 snprintf(outBuf, outBufLen, "%s", szTemp);
5908 MSG_SEC_DEBUG("Result : filename [%s]", outBuf);
5915 bool MsgGetFileNameWithoutExtension(char *szOutputName, char *szName)
5917 char *pszExt = NULL;
5919 if (szOutputName == NULL) {
5920 MSG_DEBUG("szOutputName is NULL");
5924 strncpy(szOutputName, szName, strlen(szName));
5926 if ((pszExt = strrchr(szOutputName, '.'))) {
5927 if (pszExt[0] == '.')
5934 bool MsgGetFileName(char *szFilePath, char *szFileName, int size)
5936 char *filename = NULL;
5938 filename = strrchr(szFilePath, '/');
5939 if (filename != NULL) {
5940 snprintf(szFileName, size, "%s", filename + 1);
5942 snprintf(szFileName, size, "%s", szFilePath);
5951 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
5953 MmsMsg *pMsg = NULL;
5954 MsgMultipart *pPart = NULL;
5956 if (pHeader == NULL) {
5957 MSG_DEBUG("Invalid pHeader input. It's null");
5961 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
5963 MmsInitMsgType(pHeader);
5966 /* Requires header of non-presentation */
5967 if (MsgIsMultipart(pMsg->msgType.type)) {
5968 MSG_DEBUG("Multipart header [index = %d] \n", index);
5970 pPart = pMsg->msgBody.body.pMultipart;
5972 while (pPart && index--)
5973 pPart = pPart->pNext;
5975 if (pPart == NULL) {
5976 MSG_DEBUG("There is no such msg part.");
5980 memcpy(pHeader, &pPart->type, sizeof(MsgType));
5982 MSG_DEBUG("Requires singlepart header");
5983 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
5990 MmsPluginDecoder *MmsPluginDecoder::pInstance = NULL;
5992 MmsPluginDecoder *MmsPluginDecoder::instance()
5994 if (!MmsPluginDecoder::pInstance)
5995 MmsPluginDecoder::pInstance = new MmsPluginDecoder();
5997 return MmsPluginDecoder::pInstance;
6000 MmsPluginDecoder::MmsPluginDecoder() {}
6001 MmsPluginDecoder::~MmsPluginDecoder() {}
6003 void MmsPluginDecoder::decodeMmsPdu(MmsMsg *pMsg, msg_message_id_t msgID, const char *pduFilePath)
6008 MsgMultipart *pMultipart = NULL;
6010 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6011 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
6015 pMsg->msgID = msgID;
6017 snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6019 MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName));
6021 if (MsgGetFileSize(szFullPath, &nSize) == false) {
6022 MSG_FATAL("Fail MsgGetFileSize");
6026 pFile = MsgOpenFile(szFullPath, "rb");
6027 if (pFile == NULL) {
6028 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6032 MmsRegisterDecodeBuffer();
6034 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6035 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6039 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6040 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6044 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
6046 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
6047 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
6049 { /* attribute convert mmsHeader -> mmsAttribute */
6050 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
6052 pMsg->mmsAttrib.date = mmsHeader.date;
6054 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6055 pMsg->mmsAttrib.bAskDeliveryReport = true;
6058 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6060 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6062 MSG_DEBUG("@@@@@pMsg->mmsAttrib.deliveryTime=[%d]", pMsg->mmsAttrib.deliveryTime);
6064 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
6066 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
6068 pMsg->mmsAttrib.msgType = mmsHeader.type;
6070 pMsg->mmsAttrib.version = mmsHeader.version;
6072 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
6074 pMsg->mmsAttrib.priority = mmsHeader.priority;
6076 if (mmsHeader.readReply == MMS_REPORT_YES) {
6077 pMsg->mmsAttrib.bAskReadReply = true;
6080 /* TODO : fill pMsg->mmsAttrib.szCc and pMsg->mmsAttrib.szTo field */
6082 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
6084 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
6086 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
6088 /* FIXME:: mmsHeader will release after delete global mmsHeader */
6089 /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
6091 if (pMsg->msgBody.pPresentationBody) {
6092 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
6095 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
6096 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
6099 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
6102 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
6107 MsgCloseFile(pFile);
6110 pMsg->nPartCount = 0;
6112 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
6113 pMultipart = pMsg->msgBody.body.pMultipart;
6114 while (pMultipart) {
6116 pMultipart = pMultipart->pNext;
6119 if (pMsg->msgBody.size > 0)
6123 /* make temporary */
6124 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
6126 if (MsgIsMultipart(pMsg->msgType.type) == true) {
6128 pMultipart = pMsg->msgBody.body.pMultipart;
6130 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6131 if (errno == EEXIST) {
6132 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
6134 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6138 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
6141 if (pMsg->msgBody.pPresentationBody) {
6142 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
6143 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6147 while (pMultipart) {
6148 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
6149 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, true) == false)
6152 MmsPrintMulitpart(pMultipart, partIndex);
6154 pMultipart = pMultipart->pNext;
6158 } else { /* single part */
6159 if (pMsg->nPartCount > 0) {
6160 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6161 if (errno == EEXIST) {
6162 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
6164 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6168 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
6171 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
6172 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6176 MSG_DEBUG("### Success ###");
6183 MmsUnregisterDecodeBuffer();
6185 if (pFile != NULL) {
6186 MsgCloseFile(pFile);
6191 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
6193 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
6195 MSG_DEBUG("### Fail ###");
6200 /* CID 41989: Removed function decodeMmsPdu which is unused. */
6202 void MmsPluginDecoder::decodeMmsPdu(MMS_DATA_S *pMmsData, const char *pduFilePath)
6207 MsgMultipart * iter_multipart = NULL;
6209 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6213 /* pMsg->msgID = msgID; */
6215 snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6217 /* MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName)); */
6219 if (MsgGetFileSize(szFullPath, &nSize) == false) {
6220 MSG_FATAL("Fail MsgGetFileSize");
6224 pFile = MsgOpenFile(szFullPath, "rb");
6225 if (pFile == NULL) {
6226 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6230 MmsRegisterDecodeBuffer();
6232 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6233 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6237 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6238 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6243 if (pMmsData->header == NULL) {
6244 pMmsData->header = MsgMmsCreateHeader();
6247 pMmsData->header->messageType = mmsHeader.type;
6249 pMmsData->header->mmsVersion = mmsHeader.version;
6251 pMmsData->header->contentType = mmsHeader.msgType.type;
6253 pMmsData->header->date = mmsHeader.date;
6255 pMmsData->header->messageSize = mmsHeader.msgSize;
6257 pMmsData->header->mmsPriority = mmsHeader.priority;
6259 pMmsData->header->messageClass = mmsHeader.msgClass;
6261 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6262 pMmsData->header->bDeliveryReport = true;
6265 if (mmsHeader.readReply == MMS_REPORT_YES) {
6266 pMmsData->header->bReadReport = true;
6269 memcpy(&pMmsData->header->delivery, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6271 memcpy(&pMmsData->header->expiry, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6274 snprintf(pMmsData->header->messageID, sizeof(pMmsData->header->messageID), "%s", mmsHeader.szMsgID);
6276 snprintf(pMmsData->header->szSubject, sizeof(pMmsData->header->szSubject), "%s", mmsHeader.szSubject);
6278 snprintf(pMmsData->header->trID, sizeof(pMmsData->header->trID), "%s", mmsHeader.szTrID);
6280 iter_multipart = mmsHeader.msgBody.body.pMultipart;
6283 if (pMmsData->header->contentType == MIME_MULTIPART_RELATED || pMmsData->header->contentType == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
6284 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6286 pMultipart->type = MIME_APPLICATION_SMIL;
6287 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s", "application/smil");
6288 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", mmsHeader.msgBody.presentationType.szContentID);
6289 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", mmsHeader.msgBody.presentationType.szContentLocation);
6290 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", mmsHeader.msgBody.presentationType.param.szName);
6292 /* snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), MSG_DATA_PATH"%s", mmsHeader.msgBody.presentationType.param.szFileName); */
6294 MsgBody *pBody = iter_multipart->pBody;
6295 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6297 pMmsData->smil = pMultipart;
6301 while (iter_multipart) {
6302 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6304 pMultipart->type = (MimeType)iter_multipart->type.type;
6306 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s", MimeGetMimeStringFromMimeInt(iter_multipart->type.type));
6307 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", iter_multipart->type.szContentID);
6308 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", iter_multipart->type.szContentLocation);
6309 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", iter_multipart->type.param.szName);
6311 /* snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), "%s", iter_multipart->pBody->szOrgFilePath); */
6313 MsgBody *pBody = iter_multipart->pBody;
6314 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6317 #ifdef __SUPPORT_DRM__
6318 if (iter_multipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
6319 pMultipart->drmType = iter_multipart->type.drmInfo.drmType;
6323 pMmsData->multipartlist = g_list_append(pMmsData->multipartlist, pMultipart);
6324 iter_multipart = iter_multipart->pNext;
6328 MSG_DEBUG("### SUCCESS ###");
6334 MmsUnregisterDecodeBuffer();
6336 if (pFile != NULL) {
6337 MsgCloseFile(pFile);
6341 MSG_DEBUG("### Fail ###");