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;
260 static void __MmsCleanDecodeBuff(void)
262 memset(gpMmsDecodeBuf1, 0, gMmsDecodeMaxLen + 1);
263 memset(gpMmsDecodeBuf2, 0, gMmsDecodeMaxLen + 1);
264 gpCurMmsDecodeBuff = NULL;
265 gCurMmsDecodeBuffPos = 0;
266 gMmsDecodeBufLen = 0;
269 void MmsRegisterDecodeBuffer()
271 gpMmsDecodeBuf1 = gszMmsLoadBuf1;
272 gpMmsDecodeBuf2 = gszMmsLoadBuf2;
273 gpCurMmsDecodeBuff = NULL;
274 gCurMmsDecodeBuffPos = 0;
275 gMmsDecodeMaxLen = MSG_MMS_DECODE_BUFFER_MAX;
276 gMmsDecodeCurOffset = 0;
277 gMmsDecodeBufLen = 0;
280 void MmsUnregisterDecodeBuffer(void)
282 gpMmsDecodeBuf1 = NULL;
283 gpMmsDecodeBuf2 = NULL;
284 gpCurMmsDecodeBuff = NULL;
285 gCurMmsDecodeBuffPos = 0;
286 gMmsDecodeMaxLen = 0;
287 gMmsDecodeCurOffset = 0;
288 gMmsDecodeBufLen = 0;
292 static int __MmsGetDecodeOffset(void)
294 return (gMmsDecodeCurOffset - gMmsDecodeBufLen + gCurMmsDecodeBuffPos);
297 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength)
299 if (*pLength <= valueLength) {
300 gCurMmsDecodeBuffPos -= valueLength;
301 gCurMmsDecodeBuffPos += *pLength;
305 *pLength -= valueLength;
311 /* ==========================================================
313 B I N A R Y D E C O D I N G
315 ==========================================================*/
318 * Binary Encoded Message Format
320 * < Single Part Body Message >
321 * -----------------------------------
323 * -----------------------------------
324 * | Content Type:start=xxx;type=xxx | ->(ex) Text/Plain, Text/Html, ....
325 * -----------------------------------
326 * | Single Part Body |
327 * -----------------------------------
329 * < Multi Part Body Message >
330 * -----------------------------------
332 * -----------------------------------
333 * | Content Type:start=xxx;type=xxx | -> (ex) Application/vnd.wap.multipart.mixed(related), multipart/mixed(related)
334 * -----------------------------------
335 * | # of Entries (body parts) |
336 * ----------------------------------- < Each Entry >
337 * | Entry 1 | -> -----------------------------
338 * ----------------------------------- | header Length |
339 * | Entry 2 | -----------------------------
340 * ----------------------------------- | Data Length |
341 * | ...... | ----------------------------- -
342 * ----------------------------------- | Content-Type | |
343 * | Entry n | ----------------------------- | Header Length
344 * ----------------------------------- | Header | |
345 * ----------------------------- -
346 * | Data | | Data Length
347 * ----------------------------- -
349 bool MmsBinaryDecodeMsgHeader(FILE *pFile, int totalLength)
352 UINT16 fieldCode = 0xffff;
353 UINT16 fieldValue = 0xffff;
354 UINT8 oneByte = 0xff;
356 MsgHeaderAddress *pAddr = NULL;
357 MsgHeaderAddress *pLastTo = NULL;
358 MsgHeaderAddress *pLastCc = NULL;
359 MsgHeaderAddress *pLastBcc = NULL;
361 UINT32 valueLength = 0;
362 UINT32 tmpInteger = 0;
367 char szGarbageBuff[MSG_STDSTR_LONG] = {0, };
368 char *pLimitData = NULL;
371 MSG_DEBUG("pFile ptr : [%p], total len = [%d]", pFile, totalLength);
373 __MmsCleanDecodeBuff();
375 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
376 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
377 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
378 MSG_FATAL("fail to load to buffer");
382 while (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength)) {
383 fieldCode = oneByte & 0x7f;
385 switch (MmsGetBinaryType(MmsCodeFieldCode, fieldCode)) {
386 case MMS_CODE_RESPONSESTATUS: {
387 MmsResponseStatus resposeStatus = MMS_RESPSTATUS_ERROR;
389 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
390 MSG_DEBUG("responseStatus GetOneByte fail");
394 fieldValue = oneByte;
396 /* range 197 to 223 as it does to the value 192 (Error-transient-failure). */
397 /* range 236 to 255 as it does to the value 224 (Error-permanent-failure). */
398 if (fieldValue >= 197 && fieldValue <= 223) {
400 } else if (fieldValue >= 236 && fieldValue <= 255) {
404 resposeStatus = (MmsResponseStatus)MmsGetBinaryType(MmsCodeResponseStatus, (UINT16)(fieldValue & 0x7F));
406 mmsHeader.responseStatus = (MmsResponseStatus)resposeStatus;
408 MSG_SEC_INFO("X-Mms-Response-Status = [0x%02x][0x%02x][%s]", oneByte, fieldValue, MmsDebugGetResponseStatus(mmsHeader.responseStatus));
411 case MMS_CODE_RETRIEVESTATUS: {
412 MmsRetrieveStatus RetrieveStatus = MMS_RETRSTATUS_ERROR;
414 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
415 MSG_DEBUG("retrieveStatus GetOneByte fail");
419 fieldValue = oneByte;
421 /* 195 to 223 as it does to the value 192 (Error-transient-failure). */
422 /* 228 to 255 as it does to the value 224 (Error-permanent-failure). */
423 if (fieldValue >= 195 && fieldValue <= 223) {
424 fieldValue = 192; /* 192; Error-transient-failure */
425 } else if (fieldValue >= 228 && fieldValue <= 255) {
426 fieldValue = 224; /* 224; Error-permanent-failure */
429 RetrieveStatus = (MmsRetrieveStatus)MmsGetBinaryType(MmsCodeRetrieveStatus, (UINT16)(fieldValue & 0x7F));
431 mmsHeader.retrieveStatus = (MmsRetrieveStatus)RetrieveStatus;
433 MSG_SEC_INFO("X-Mms-Retrieve-Status = [0x%02x][0x%02x][%s]", oneByte, fieldValue, MmsDebugGetRetrieveStatus(mmsHeader.retrieveStatus));
437 case MMS_CODE_RESPONSETEXT:
439 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szResponseText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
440 MSG_DEBUG("invalid MMS_CODE_RESPONSETEXT");
444 MSG_SEC_INFO("X-Mms-Response-Text = [%s]", mmsHeader.szResponseText);
447 case MMS_CODE_RETRIEVETEXT:
449 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szRetrieveText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
450 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
454 MSG_SEC_INFO("X-Mms-Retrieve-Text = [%s]", mmsHeader.szRetrieveText);
459 if (__MmsBinaryDecodeText(pFile, mmsHeader.szMsgID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
460 MSG_DEBUG("MMS_CODE_MSGID is invalid");
464 MSG_SEC_INFO("Message-ID =[%s]", mmsHeader.szMsgID);
466 if (strlen(mmsHeader.szMsgID) > 2)
467 __MsgMIMERemoveQuote (mmsHeader.szMsgID);
471 case MMS_CODE_SUBJECT:
473 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN + 1, totalLength) == false) {
474 MSG_DEBUG("invalid MMS_CODE_SUBJECT");
478 pLimitData = (char *)calloc(1, MSG_LOCALE_SUBJ_LEN + 1);
480 if (pLimitData == NULL) {
481 MSG_DEBUG("pLimitData calloc fail");
485 nRead = __MsgCutUTFString((unsigned char*)pLimitData, MSG_LOCALE_SUBJ_LEN + 1, (unsigned char*)mmsHeader.szSubject, MSG_SUBJ_LEN);
486 MSG_DEBUG("Subject edit..");
488 if (nRead > MSG_LOCALE_SUBJ_LEN) {
489 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
490 strncpy(mmsHeader.szSubject, pLimitData, MSG_SUBJ_LEN);
492 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
493 strncpy(mmsHeader.szSubject, pLimitData, MSG_LOCALE_SUBJ_LEN);
501 MSG_SEC_INFO("Subject = [%s]", mmsHeader.szSubject);
506 /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
508 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
509 MSG_DEBUG("MMS_CODE_FROM is invalid");
513 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
514 MSG_DEBUG("MMS_CODE_FROM GetOneByte fail");
518 /* DRM_TEMPLATE - start */
522 if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
523 if (valueLength > 0) {
524 mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
525 if (mmsHeader.pFrom == NULL) {
526 MSG_DEBUG("MMS_CODE_FROM __MmsDecodeEncodedAddress fail");
530 mmsHeader.pFrom = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
531 if (mmsHeader.pFrom == NULL)
534 mmsHeader.pFrom->szAddr = (char *)calloc(1, 1);
535 if (mmsHeader.pFrom->szAddr == NULL) {
536 free(mmsHeader.pFrom);
537 mmsHeader.pFrom = NULL;
541 mmsHeader.pFrom->szAddr[0] = '\0';
542 mmsHeader.pFrom->pNext = NULL;
545 MSG_SEC_INFO("From = [%s]", mmsHeader.pFrom->szAddr);
546 /* DRM_TEMPLATE - end */
547 } else if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
548 /* Present Token only */
549 MSG_SEC_INFO("From = [insert token]");
551 /* from data broken */
552 MSG_WARN("from addr broken");
553 gCurMmsDecodeBuffPos--;
560 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
562 MSG_DEBUG("MMS_CODE_TO __MmsDecodeEncodedAddress fail");
566 if (mmsHeader.pTo == NULL) {
568 pLastTo = mmsHeader.pTo = pAddr;
571 pLastTo->pNext = pAddr;
575 MSG_SEC_INFO("To = [%s]", pAddr->szAddr);
580 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
582 MSG_DEBUG("MMS_CODE_BCC __MmsDecodeEncodedAddress fail");
586 if (mmsHeader.pBcc == NULL) {
588 pLastBcc = mmsHeader.pBcc = pAddr;
591 pLastBcc->pNext = pAddr;
595 MSG_SEC_INFO("Bcc = [%s]", pAddr->szAddr);
600 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
602 MSG_DEBUG("MMS_CODE_CC __MmsDecodeEncodedAddress fail");
606 if (mmsHeader.pCc == NULL) {
608 pLastCc = mmsHeader.pCc = pAddr;
611 pLastCc->pNext = pAddr;
614 MSG_SEC_INFO("Cc = [%s]", pAddr->szAddr);
617 case MMS_CODE_CONTENTLOCATION:
619 if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
620 MSG_DEBUG("MMS_CODE_CONTENTLOCATION is invalid");
623 MSG_SEC_DEBUG("X-Mms-Content-Location = [%s]", mmsHeader.szContentLocation);
628 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
629 MSG_DEBUG("MMS_CODE_DATE is invalid");
633 MSG_SEC_INFO("Date = [%u][%d]", mmsHeader.date, (const time_t *)&mmsHeader.date);
636 case MMS_CODE_DELIVERYREPORT:
638 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
639 MSG_DEBUG("deliveryReport GetOneByte fail");
643 fieldValue = MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
645 if (fieldValue == 0xFFFF) {
646 MSG_DEBUG("deliveryReport error");
650 mmsHeader.deliveryReport = (MmsReport)fieldValue;
652 MSG_SEC_INFO("X-Mms-Delivery-Report =[0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.deliveryReport));
655 case MMS_CODE_DELIVERYTIME:
657 /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
659 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
660 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
664 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
665 MSG_DEBUG("delivery time GetOneByte fail");
669 /* DRM_TEMPLATE - start */
672 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
673 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
675 if (valueLength > 0) {
676 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
677 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME");
681 /* DRM_TEMPLATE - end */
683 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
685 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
686 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
690 MSG_SEC_INFO("X-Mms-Delivery-Time : type = [%d], time= [%u]", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
693 case MMS_CODE_EXPIRYTIME:
695 /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
697 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
698 MSG_DEBUG("invalid MMS_CODE_EXPIRYTIME");
702 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
703 MSG_DEBUG("expiry time GetOneByte fail");
707 /* DRM_TEMPLATE - start */
710 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
711 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
713 if (valueLength > 0) {
714 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
715 MSG_DEBUG("MMS_CODE_EXPIRYTIME is invalid");
719 /* DRM_TEMPLATE - end */
721 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
723 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
724 MSG_INFO("__MmsBinaryDecodeInteger fail...");
729 MSG_DEBUG("X-Mms-Expiry : type = [%d], time = [%u]", mmsHeader.expiryTime.type, mmsHeader.expiryTime.time);
732 case MMS_CODE_MSGCLASS:
734 /* Class-value = Class-identifier | Token Text */
736 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
737 MSG_DEBUG("msgClass GetOneByte fail");
741 if (oneByte > 0x7f) {
742 /* Class-identifier */
743 mmsHeader.msgClass = (MmsMsgClass)MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
745 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
746 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (class)");
751 MSG_SEC_INFO("X-Mms-Message-Class =[%s]", MmsDebugGetMsgClass(mmsHeader.msgClass));
754 case MMS_CODE_MSGSIZE:
756 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
757 MSG_DEBUG("MMS_CODE_MSGSIZE is invalid");
761 MSG_SEC_INFO("X-Mms-Message-Size = [%d]", mmsHeader.msgSize);
764 case MMS_CODE_MSGSTATUS:
766 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
767 MSG_DEBUG("msgStatus GetOneByte fail");
771 mmsHeader.msgStatus = (msg_delivery_report_status_t)MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
772 MSG_SEC_INFO("X-Mms-Status = [%s]", MmsDebugGetMsgStatus(mmsHeader.msgStatus));
775 case MMS_CODE_MSGTYPE:
777 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
778 MSG_DEBUG("msgStatus GetOneByte fail");
782 mmsHeader.type = (MmsMsgType)MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
783 MSG_SEC_INFO("X-Mms-Message-Type = [%s]", MmsDebugGetMsgType(mmsHeader.type));
786 case MMS_CODE_PRIORITY:
788 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
789 MSG_DEBUG("msgStatus GetOneByte fail");
792 mmsHeader.priority = (MmsPriority)MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
793 MSG_SEC_INFO("X-Mms-Priority = [%d]", mmsHeader.priority);
796 case MMS_CODE_READREPLY:
798 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
799 MSG_DEBUG("msgStatus GetOneByte fail");
802 mmsHeader.readReply = (MmsReport)MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
803 MSG_SEC_INFO("X-Mms-Read-Report = [0x%02x][%s]", oneByte, MmsDebugGetMmsReport(mmsHeader.readReply));
806 case MMS_CODE_REPORTALLOWED:
808 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
809 MSG_DEBUG("msgStatus GetOneByte fail");
812 mmsHeader.reportAllowed = (MmsReportAllowed)MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
813 MSG_SEC_INFO("X-Mms-Report-Allowed = [%d]", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
816 case MMS_CODE_SENDERVISIBILLITY:
818 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
819 MSG_DEBUG("msgStatus GetOneByte fail");
822 mmsHeader.hideAddress= (MmsSenderVisible)!(MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
823 MSG_SEC_INFO("X-Mms-Sender-Visibility = [%d]", mmsHeader.hideAddress);
828 if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
829 MSG_DEBUG("Transaction ID Too Long");
832 MSG_SEC_INFO("X-Mms-Transaction-Id = [%s]", mmsHeader.szTrID);
835 case MMS_CODE_VERSION:
836 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
837 MSG_DEBUG("msgStatus GetOneByte fail");
840 mmsHeader.version = oneByte;
842 MSG_SEC_INFO("X-Mms-MMS-Version = [0x%02x]", mmsHeader.version);
845 case MMS_CODE_CONTENTTYPE:
848 * Content-type is the last header field of SendRequest and RetrieveConf.
849 * It's required to decrease pointer by one and return,
850 * to parse this field in MmsBinaryDecodeContentType().
855 /* ----------- Add by MMSENC v1.1 ----------- */
857 case MMS_CODE_READSTATUS:
859 /* Read-status-value = Read | Deleted without being read */
861 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
862 MSG_DEBUG("msgStatus GetOneByte fail");
866 mmsHeader.readStatus = (msg_read_report_status_t)MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
867 MSG_SEC_INFO("X-Mms-Read-Status = [%s]", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
870 case MMS_CODE_REPLYCHARGING:
872 /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
874 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
875 MSG_DEBUG("msgStatus GetOneByte fail");
879 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
880 MSG_SEC_INFO("X-Mms-Reply-Charging = [%d]", mmsHeader.replyCharge.chargeType);
883 case MMS_CODE_REPLYCHARGINGDEADLINE:
885 /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
887 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
888 MSG_DEBUG("invalid MMS_CODE_REPLYCHARGINGDEADLINE");
892 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
893 MSG_DEBUG("msgStatus GetOneByte fail");
897 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
898 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
900 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
903 /* DRM_TEMPLATE - start */
906 if (valueLength > 0) {
907 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
908 MSG_DEBUG("MMS_CODE_REPLYCHARGINGDEADLINE is invalid");
913 MSG_SEC_INFO("X-Mms-Reply-Charging-Deadline : type = [%d], time = [%u]", mmsHeader.replyCharge.deadLine.type, mmsHeader.replyCharge.deadLine.time);
914 /* DRM_TEMPLATE - end */
917 case MMS_CODE_REPLYCHARGINGID:
919 /* Reply-charging-ID-value = Text-string */
920 if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
921 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (szReplyChargingID)");
924 SECURE_SLOGD("X-Mms-Reply-Charging-ID = [%s]", mmsHeader.replyCharge.szChargeID);
927 case MMS_CODE_REPLYCHARGINGSIZE:
929 /* Reply-charging-size-value = Long-integer */
930 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
931 MSG_DEBUG("MMS_CODE_REPLYCHARGINGSIZE is invalid");
934 MSG_SEC_INFO("X-Mms-Reply-Charging-Size = [%d]", mmsHeader.replyCharge.chargeSize);
937 case MMS_CODE_PREVIOUSLYSENTBY:
940 * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
941 * Forwarded-count-value = Integer-value
942 * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
946 * fixme: There is no proper field to store this information.
947 * Just increase pointer now.
950 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
951 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTBY");
955 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
956 MSG_DEBUG("2. invalid MMS_CODE_PREVIOUSLYSENTBY");
960 if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
961 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT");
966 case MMS_CODE_PREVIOUSLYSENTDATE:
969 * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
970 * Forwarded-count-value = Integer-value
971 * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
975 * fixme: There is no proper field to store this information.
976 * Just increase pointer now.
979 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
980 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTDATE");
984 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
985 MSG_DEBUG("2. invalid MS_CODE_PREVIOUSLYSENTDATE");
989 if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
990 MSG_DEBUG("3. invalid MMS_CODE_PREVIOUSLYSENTDATE");
998 * Application-header = Token-text Application-specific-value
999 * Token-text = Token End-of-string
1000 * Application-specific-value = Text -string
1002 * OR unknown header field - Just ignore these fields.
1004 * Read one byte and check the value >= 0x80
1005 * (check these value can be field code)
1008 int remainLength = 0;
1012 offset = __MmsGetDecodeOffset();
1013 if (offset >= totalLength)
1016 remainLength = totalLength - offset;
1018 while ((oneByte < 0x80) && (remainLength > 0)) {
1019 if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1020 MSG_DEBUG("__MmsBinaryDecodeCheckAndDecreaseLength fail");
1024 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1025 MSG_DEBUG("responseStatus GetOneByte fail");
1030 gCurMmsDecodeBuffPos--;
1035 offset = __MmsGetDecodeOffset();
1036 if (offset >= totalLength)
1044 if (mmsHeader.pTo == NULL && pLastTo) {
1048 if (mmsHeader.pCc == NULL && pLastCc) {
1052 if (mmsHeader.pBcc == NULL && pLastBcc) {
1056 MSG_INFO("## Decode Header Success ##");
1063 if (mmsHeader.pTo == NULL && pLastTo) {
1067 if (mmsHeader.pCc == NULL && pLastCc) {
1071 if (mmsHeader.pBcc == NULL && pLastBcc) {
1075 MSG_FATAL("## Decode Header Fail ##");
1080 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1087 if (szFilePath != NULL)
1088 snprintf(mmsHeader.msgType.szOrgFilePath, sizeof(mmsHeader.msgType.szOrgFilePath), "%s", szFilePath);
1090 mmsHeader.msgType.offset = __MmsGetDecodeOffset() - 1; /* + Content-Type code value */
1092 /* read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding */
1093 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1094 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1095 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1096 MSG_DEBUG("fail to load to buffer");
1100 /* msg's type [ex] related, mixed, single part (jpg, amr and etc) */
1101 length = __MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1103 MSG_DEBUG("MMS_CODE_CONTENTTYPE is fail");
1107 mmsHeader.msgType.size = length + 1; /* + Content-Type code value */
1108 mmsHeader.msgBody.offset = __MmsGetDecodeOffset();
1110 switch (mmsHeader.msgType.type) {
1111 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1112 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1113 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1114 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1115 case MIME_MULTIPART_REPORT:
1116 case MIME_MULTIPART_MIXED:
1117 case MIME_MULTIPART_RELATED:
1118 case MIME_MULTIPART_ALTERNATIVE:
1119 case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1120 case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1122 MSG_DEBUG("Decode Multipart");
1124 offset = __MmsGetDecodeOffset();
1125 if (offset >= totalLength)
1128 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1129 MSG_DEBUG("MmsBinaryDecodeMultipart is fail.");
1136 /* Single part message ---------------------------------------------- */
1137 MSG_DEBUG("Decode Singlepart");
1139 offset = __MmsGetDecodeOffset();
1140 if (offset >= totalLength)
1143 if (__MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1144 MSG_DEBUG("MmsBinaryDecodePartBody is fail.(Single Part)");
1148 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1149 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1162 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1167 char *szTypeString = NULL;
1168 char *szTypeValue = NULL;
1169 UINT8 paramCode = 0xff;
1176 * Parameter = Typed-parameter | Untyped-parameter
1177 * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1180 while (valueLength > 0) {
1181 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1182 MSG_DEBUG("paramCode _MmsBinaryDecodeGetOneByte fail");
1186 paramCode = oneByte;
1189 switch (paramCode) {
1190 case 0x81: /* charset */
1192 if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1193 MSG_DEBUG("__MmsBinaryDecodeCharset fail.");
1197 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1202 case 0x85: /* name = Text-string */
1203 case 0x97: /* name = Text-value = No-value | Token-text | Quoted-string */
1204 memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1205 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szName,
1206 MSG_FILENAME_LEN_MAX -5, /* MSG_LOCALE_FILENAME_LEN_MAX + 1, : change @ 110(Ui code have to change for this instead of DM) */
1209 MSG_DEBUG("__MmsDecodeGetFilename fail. (name parameter)");
1213 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1214 __MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1217 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1222 case 0x86: /* filename = Text-string */
1223 case 0x98: /* filename = Text-value = No-value | Token-text | Quoted-string */
1224 memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1225 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1227 MSG_DEBUG("__MmsDecodeGetFilename fail. (filename parameter)");
1231 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1232 __MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1235 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1240 case 0x89: /* type = Constrained-encoding = Extension-Media | Short-integer */
1242 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1243 MSG_DEBUG("type _MmsBinaryDecodeGetOneByte fail");
1247 if (oneByte > 0x7f) {
1248 pMsgType->param.type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1249 /* MmsGetBinaryType(MmsCodeContentType,(UINT16)(oneByte & 0x7f)); */
1250 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1253 gCurMmsDecodeBuffPos--;
1256 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1257 pMsgType->param.type = MimeGetMimeIntFromMimeString(szTypeString);
1260 szTypeString = NULL;
1263 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1269 case 0x8A: /* start encoding version 1.2 */
1270 case 0x99: /* start encoding version 1.4 */
1273 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1275 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1276 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1278 szTypeString = NULL;
1280 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1286 case 0x8B: /* startInfo encoding version 1.2 */
1287 case 0x9A: /* startInfo encoding version 1.4 */
1290 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1293 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1294 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1297 szTypeString = NULL;
1299 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1307 if (paramCode > 0x7F) {
1308 MSG_DEBUG("Unsupported parameter");
1310 /* In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value. */
1312 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1316 * Untyped Parameter = Token-text Untyped-value
1317 * Token-text = Token End-of-string
1318 * Untyped-value = Integer-value | Text-value
1319 * Text-value = No-value | Token-text | Quoted-string
1321 * Just increase pointer!!!
1327 gCurMmsDecodeBuffPos--;
1331 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1332 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1338 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1339 MSG_DEBUG("Unsupported parameter(%d)\n", integer);
1340 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1344 szTypeValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1347 /* checkMe: forwardLock needs boudary string */
1348 if (strcasecmp(szTypeString, "boundary") == 0) {
1349 memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1350 strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1351 #ifdef FEATURE_JAVA_MMS
1352 } else if (strcasecmp(szTypeString, "Application-ID") == 0) {
1353 pMsgType->param.szApplicationID = (char*) calloc(1, textLength + 1);
1354 if (pMsgType->param.szApplicationID) {
1355 memset(pMsgType->param.szApplicationID, 0, textLength + 1);
1356 strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1357 MSG_SEC_DEBUG("Application-ID:%s",pMsgType->param.szApplicationID);
1359 } else if (strcasecmp(szTypeString,"Reply-To-Application-ID") == 0) {
1360 pMsgType->param.szReplyToApplicationID = (char*) calloc(1, textLength + 1);
1361 if (pMsgType->param.szReplyToApplicationID) {
1362 memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1363 strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1364 MSG_SEC_DEBUG("ReplyToApplication-ID:%s",pMsgType->param.szReplyToApplicationID);
1369 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeValue);
1373 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1379 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeString);
1381 szTypeString = NULL;
1387 } /*end of while loop*/
1394 szTypeString = NULL;
1406 * Decode Encoded Content type
1408 * @param pEncodedData [in] ContentType encoded data
1409 * @param pMsgType [out] Decoded MsgType
1410 * @return Decoded address list
1412 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1416 char *szTypeString = NULL;
1417 int valueLength = 0;
1423 * Content-type-value : [WAPWSP 8.4.2.24]
1424 * Preassigned content-types : [WAPWSP Appendix A, Table 40]
1425 * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1427 * Content-type-value = Constrained-media | Content-general-form
1428 * Content-general-form = Value-length Media-type
1429 * Media-type = (Well-known-media | Extension-Media) *(Parameter)
1432 length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1435 * Constrained-media or Single part message
1436 * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1437 * Extension-media = *TEXT End-of-string
1438 * Short-integer = OCTET(1xxx xxxx)
1441 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1442 MSG_DEBUG("Constrained-media _MmsBinaryDecodeGetOneByte fail");
1446 if (oneByte > 0x7F) {
1448 pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1450 MSG_SEC_DEBUG("Constrained-media : Short-integer : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1454 char *pszTemp = NULL;
1456 /* Extension-Media */
1457 gCurMmsDecodeBuffPos--;
1460 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1462 if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1464 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type with delimiter = [%s]", szTypeString);
1466 pszTemp = __MsgGetStringUntilDelimiter(szTypeString, ';');
1469 szTypeString = pszTemp;
1473 pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1475 MSG_SEC_DEBUG("Constrained-media : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1477 length = textLength;
1481 szTypeString = NULL;
1486 * Content-general-form = Value-length Media-type
1487 * Media-type = (Well-known-media | Extension-Media)*(Parameter)
1490 length += valueLength;
1492 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1493 MSG_DEBUG("Well-known-media _MmsBinaryDecodeGetOneByte fail");
1497 if (oneByte > 0x7F) {
1498 /* Well-known-media */
1499 pMsgType->type = MimeGetMimeIntFromBi((UINT16)(oneByte & 0x7f));
1500 MSG_SEC_DEBUG("Content-general-form : Well-known-media : Content Type = [0x%04x], MimeType = [0x%04x]", oneByte, pMsgType->type);
1503 /* Extension-Media */
1504 gCurMmsDecodeBuffPos--;
1507 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1509 pMsgType->type = MimeGetMimeIntFromMimeString(szTypeString);
1511 MSG_SEC_DEBUG("Content-general-form : Extension-Media : Content Type = [%s], MimeType = [0x%04x]", szTypeString, pMsgType->type);
1513 valueLength -= textLength;
1517 szTypeString = NULL;
1521 MSG_SEC_DEBUG("Content-Type = [%s]", MmsDebugGetMimeType((MimeType)pMsgType->type));
1523 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1524 MSG_DEBUG("Content-Type parameter fail");
1537 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1539 UINT8 fieldCode = 0xff;
1541 UINT32 valueLength = 0;
1543 char *pValue = NULL;
1544 char *pParam = NULL;
1550 char *pLatinBuff = NULL;
1552 char *szTemp = NULL;
1554 MSG_INFO("headerLen[%d] totalLength[%d]", headerLen, totalLength);
1556 if (pFile == NULL || pMsgType == NULL)
1560 * Message-header = Well-known-header | Application-header
1561 * Well-known-header = Well-known-field-name Wap-value
1562 * Application-header = Token-text Application-specific-value
1563 * Well-known-field-name = Short-integer
1564 * Application-specific-value = Text-string
1567 while (headerLen > 0) {
1568 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1569 MSG_DEBUG("field code GetOneByte fail");
1573 if (0x80 <= oneByte && oneByte <= 0xC7) {
1574 /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1576 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1579 fieldCode = oneByte & 0x7f;
1581 switch (fieldCode) {
1582 case 0x0E: /* Content-Location */
1583 case 0x04: /* Content-Location */
1585 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1586 if (pLatinBuff == NULL)
1589 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1591 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1595 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1597 snprintf(pMsgType->szContentLocation, sizeof(pMsgType->szContentLocation), "%s", szSrc);
1598 MSG_SEC_DEBUG("Content Location : [%s]", pMsgType->szContentLocation);
1606 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1611 case 0x40: /* Content-ID */
1613 char szContentID[MMS_CONTENT_ID_LEN + 1] = {0, };
1615 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1616 if (pLatinBuff == NULL)
1619 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1622 MSG_DEBUG("Content-ID __MmsBinaryDecodeQuotedString fail.");
1626 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1628 snprintf(szContentID, sizeof(szContentID), "%s", szSrc);
1629 MSG_SEC_DEBUG("Content ID : [%s]", szContentID);
1637 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1639 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1644 case 0x2E: /* Content-Disposition */
1645 case 0x45: /* Content-Disposition */
1648 * Content-disposition-value = Value-length Disposition *(Parameter)
1649 * Disposition = Form-data | Attachment | Inline | Token-text
1650 * Form-data = <Octet 128> : 0x80
1651 * Attachment = <Octet 129> : 0x81
1652 * Inline = <Octet 130> : 0x82
1655 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1658 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1663 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1664 MSG_DEBUG("Disposition value GetOneByte fail");
1671 if (oneByte >= 0x80) {
1672 pMsgType->disposition = MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1674 if (pMsgType->disposition == -1) {
1675 MSG_DEBUG("Content-Disposition MmsGetBinaryType fail.");
1676 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT; /* default */
1679 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1682 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1683 MSG_DEBUG("Disposition parameter fail");
1687 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1691 gCurMmsDecodeBuffPos--;
1694 pLatinBuff = (char *)calloc(1, MSG_FILENAME_LEN_MAX);
1695 if (pLatinBuff == NULL)
1697 memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1699 textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1702 if (textLength < 0) {
1703 MSG_DEBUG("Content-Disposition decodingfail.");
1709 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1712 valueLength -= textLength;
1714 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false)
1716 MSG_DEBUG("Disposition parameter fail");
1720 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1727 case 0x0B: /* Content-Encoding */
1729 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1730 MSG_DEBUG("Disposition value GetOneByte fail");
1734 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1739 case 0x0C: /* Content-Language */
1741 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1742 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1747 cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1749 if (cTemp == NULL) {
1750 MSG_DEBUG("__MmsBinaryDecodeText2 fail...");
1754 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1767 case 0x0D: /* Content-Length */
1769 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1770 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1774 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1779 case 0x1C: /* Location */
1781 pLatinBuff = (char *)calloc(1, MMS_LOCATION_URL_LEN + 1);
1782 if (pLatinBuff == NULL)
1785 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_LOCATION_URL_LEN, totalLength);
1787 MSG_DEBUG("__MmsBinaryDecodeQuotedString fail.");
1791 szSrc = __MsgConvertLatin2UTF8FileName(pLatinBuff);
1793 snprintf(pMsgType->szLocation, sizeof(pMsgType->szLocation), "%s", szSrc);
1794 MSG_INFO("Location : [%s]", pMsgType->szLocation);
1802 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1807 case 0x30: /* X-Wap-Content-URI skip this value */
1809 MSG_DEBUG("X-Wap-Content-URI header.");
1810 pLatinBuff = (char *)calloc(1, MMS_TEXT_LEN);
1811 if (pLatinBuff == NULL)
1814 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1817 MSG_DEBUG(" __MmsBinaryDecodeQuotedString fail.");
1821 MSG_DEBUG("X-Wap-Content-URI header decoded. Value length %d\n", length);
1825 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1828 MSG_DEBUG("X-Wap-Content-URI header skipped.");
1832 case 0x01: /* Accept-charset */
1833 /* if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1) */
1835 /* WAP-230-WSP-200010705-a.pdf
1836 8.4.2.8 Accept charset field
1837 The following rules are used to encode accept character set values.
1838 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1839 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1840 Constrained-charset = Any-charset | Constrained-encoding
1841 Well-known-charset = Any-charset | Integer-value
1842 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1843 Any-charset = <Octet 128>
1844 ; Equivalent to the special RFC2616 charset value ��*��
1850 MSG_DEBUG("Accept-charset.");
1852 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1854 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1859 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1860 /* We only support the well-known-charset format */
1861 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
1866 MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1868 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1876 /* Other Content-xxx headers : Have valueLength */
1878 MSG_WARN("unknown Value = 0x%x\n", oneByte);
1880 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1882 MSG_WARN("invalid MMS_CODE_PREVIOUSLYSENTDATE");
1886 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1889 szTemp = (char *)calloc(1, valueLength);
1893 if (__MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) == false) {
1894 MSG_WARN("default _MmsBinaryDecodeGetBytes() fail");
1902 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1909 * Application-header = Token-text Application-specific-value
1910 * Application-specific-value = Text-string
1913 MSG_DEBUG(" Application-header = Token-text Application-specific-value");
1915 gCurMmsDecodeBuffPos--;
1920 pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1921 if (pCode == NULL) {
1922 MSG_DEBUG("pCode is null");
1926 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1929 MSG_DEBUG(" Token-text (%s) \n", pCode);
1932 /* Application-specific-value */
1935 pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1936 if (pValue == NULL) {
1937 MSG_DEBUG("pValue is null");
1941 MSG_DEBUG(" Application-specific-value (%s) \n", pValue);
1944 pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1950 switch (MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1951 case MMS_BODYHDR_TRANSFERENCODING: /* Content-Transfer-Encoding */
1952 pMsgType->encoding = MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1955 case MMS_BODYHDR_CONTENTID: /* Content-ID */
1957 char szContentID[MMS_CONTENT_ID_LEN + 1];
1959 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1960 if (pLatinBuff == NULL)
1965 __MsgMIMERemoveQuote (pValue);
1966 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1968 length = strlen(pLatinBuff);
1969 if (__MsgLatin2UTF ((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0)
1971 MSG_DEBUG("MsgLatin2UTF fail");
1975 MmsRemoveLessGreaterChar(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID)); /* remove "< >" */
1981 case MMS_BODYHDR_CONTENTLOCATION: /* Content-Location */
1983 pLatinBuff = (char *)calloc(1, MMS_CONTENT_ID_LEN + 1);
1984 if (pLatinBuff == NULL)
1987 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1989 length = strlen(pLatinBuff);
1990 if (__MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1991 MSG_DEBUG("MsgLatin2UTF fail");
1999 case MMS_BODYHDR_DISPOSITION: /* Content-Disposition */
2000 pMsgType->disposition = MmsGetTextType(MmsCodeMsgDisposition, pValue);
2003 case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY: /* DRM RO WAITING */
2007 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
2012 __MsgParseParameter(pMsgType, pParam + 1);
2024 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2067 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2071 length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2076 MSG_INFO("Number of Entries = [%d]", *npEntries);
2084 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2089 * Currently, offset and size is
2090 * the only information used with msgBody.
2091 * If you need, add here more information
2095 offset = __MmsGetDecodeOffset();
2096 offset += bodyLength;
2098 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2099 MSG_DEBUG("fail to seek file pointer");
2103 __MmsCleanDecodeBuff();
2105 gMmsDecodeCurOffset = offset;
2107 if (offset >= totalLength)
2110 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2111 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2112 MSG_DEBUG("fail to load to buffer");
2125 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2127 if (offset > totalLength)
2130 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2131 MSG_DEBUG("fail to seek file pointer");
2135 __MmsCleanDecodeBuff();
2137 gMmsDecodeCurOffset = offset;
2139 if (offset == totalLength)
2142 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2143 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2144 MSG_DEBUG("fail to load to buffer");
2155 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2157 UINT32 nEntries = 0;
2158 MsgMultipart *pMultipart = NULL;
2159 MsgMultipart *pLastMultipart = NULL;
2163 MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2164 MsgPresentaionInfo presentationInfo;
2166 MSG_DEBUG("pdu length = [%d]", totalLength);
2168 presentationInfo.factor = MSG_PRESENTATION_NONE;
2169 presentationInfo.pCurPresentation = NULL;
2170 presentationInfo.pPrevPart = NULL;
2172 if (__MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2173 MSG_DEBUG("MmsBinaryDecodeEntries is fail.");
2177 if (pMsgBody->body.pMultipart != NULL) {
2178 pLastMultipart = pMsgBody->body.pMultipart;
2179 MSG_DEBUG("previous multipart exist [%p]", pMsgBody->body.pMultipart);
2181 MSG_DEBUG("first multipart");
2185 MSG_DEBUG("decoding [%d]th multipart", index);
2187 offset = __MmsGetDecodeOffset();
2188 if (offset >= totalLength) {
2189 MSG_DEBUG("offset is over totalLength");
2193 if ((pMultipart = MmsAllocMultipart()) == NULL) {
2194 MSG_DEBUG("MsgAllocMultipart Fail");
2198 if (__MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2199 MSG_DEBUG("MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2203 if (pMultipart->type.type == MIME_APPLICATION_SMIL) {
2204 /* P151019-00477 : received mms message is type of multipart mixed, but among multiparts if there's smil part then set it multipart related */
2205 if (pMsgType->type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED)
2206 pMsgType->type = MIME_APPLICATION_VND_WAP_MULTIPART_RELATED;
2208 factor = __MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2209 if (factor == MSG_PRESENTATION_NONE) {
2210 factor = MSG_PRESENTATION_TYPE_BASE;
2213 factor = MSG_PRESENTATION_NONE;
2216 /* priority 1 : content type match, 2: content location, 3: type */
2217 if (presentationInfo.factor < factor) {
2218 /* Presentation part */
2219 presentationInfo.factor = factor;
2220 presentationInfo.pPrevPart = pLastMultipart;
2221 presentationInfo.pCurPresentation = pMultipart;
2224 /* first multipart */
2225 if (pLastMultipart == NULL) {
2226 pMsgBody->body.pMultipart = pMultipart;
2227 pLastMultipart = pMultipart;
2229 pLastMultipart->pNext = pMultipart;
2230 pLastMultipart = pMultipart;
2233 pMsgType->contentSize += pMultipart->pBody->size;
2237 MmsPrintMulitpart(pMultipart, index++);
2241 pMsgBody->size = totalLength - pMsgBody->offset;
2243 __MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2245 if (__MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2246 MSG_DEBUG("MsgResolveNestedMultipart failed");
2254 if (pMultipart->pBody) {
2255 free(pMultipart->pBody);
2256 pMultipart->pBody = NULL;
2266 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2269 bool bSuccess = false;
2270 UINT32 headerLength = 0;
2271 UINT32 bodyLength = 0;
2274 MSG_DEBUG("pdu length = [%d]", totalLength);
2277 if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2278 MSG_DEBUG("Get header length fail");
2282 offset = __MmsGetDecodeOffset();
2283 if (offset >= totalLength)
2287 if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2288 MSG_DEBUG("Get body length fail");
2292 offset = __MmsGetDecodeOffset();
2293 if (offset >= totalLength)
2297 if (szFilePath != NULL)
2298 snprintf(pMsgType->szOrgFilePath, sizeof(pMsgType->szOrgFilePath), "%s", szFilePath);
2300 pMsgType->offset = __MmsGetDecodeOffset();
2301 pMsgType->size = headerLength;
2302 pMsgType->contentSize = bodyLength;
2304 if (pMsgType->offset > totalLength)
2307 length = __MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2309 MSG_DEBUG("Decode contentType Fail");
2313 offset = __MmsGetDecodeOffset();
2314 if (offset >= totalLength)
2320 if (__MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2321 MSG_DEBUG("Decode contentHeader Fail");
2325 offset = __MmsGetDecodeOffset();
2326 if (offset >= totalLength)
2331 if (szFilePath != NULL)
2332 snprintf(pMsgBody->szOrgFilePath, sizeof(pMsgBody->szOrgFilePath), "%s", szFilePath);
2334 pMsgBody->offset = __MmsGetDecodeOffset();
2335 pMsgBody->size = bodyLength;
2337 if (pMsgBody->offset > totalLength)
2340 switch (pMsgType->type) {
2341 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2342 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2343 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2344 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2345 case MIME_MULTIPART_REPORT:
2346 case MIME_MULTIPART_MIXED:
2347 case MIME_MULTIPART_RELATED:
2348 case MIME_MULTIPART_ALTERNATIVE:
2350 MSG_DEBUG("Multipart");
2351 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2352 MSG_DEBUG("MmsBinaryDecodeMultipart is fail");
2356 offset = __MmsGetDecodeOffset();
2357 if (offset >= totalLength)
2363 MSG_DEBUG("Normal Part");
2365 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2366 if (bSuccess == false) {
2367 MSG_DEBUG("Decode contentBody Fail");
2371 offset = __MmsGetDecodeOffset();
2372 if (offset >= totalLength)
2390 /* --------------------------------------------------------------------
2392 * B I N A R Y D E C D E U T I L I T Y
2394 * --------------------------------------------------------------------*/
2396 bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
2398 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2400 if (pFile == NULL || pOneByte == NULL)
2402 MSG_DEBUG("invalid file or buffer");
2407 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2408 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2409 MSG_DEBUG("fail to load to buffer");
2414 *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2423 * @remark: bufLen < gMmsDecodeMaxLen
2425 bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2427 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2431 if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
2434 memset(szBuff, 0, bufLen);
2436 if (length < bufLen) {
2437 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2438 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2439 MSG_DEBUG("fail to load to buffer");
2444 for (i = 0; i < bufLen - 1; i++) {
2445 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2448 gCurMmsDecodeBuffPos++; /* NULL */
2456 bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2460 if (pFile == NULL || szBuff == NULL || bufLen == 0)
2463 memset(szBuff, 0, bufLen);
2465 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2466 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2467 MSG_DEBUG("fail to load to buffer");
2471 while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
2472 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
2473 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2477 iPos += gMmsDecodeMaxLen;
2480 if ((bufLen - iPos) > 0) {
2481 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
2482 MSG_DEBUG("__MmsBinaryDecodeGetBytes fail");
2486 iPos += (bufLen - iPos);
2496 * Decode uintvar to 32bit unsigned integer
2498 * @param pEncodedData [in] encoded data
2499 * @param pUintVar [out] Decode uintvar (32bit unsigned integer)
2500 * @return The length of uintvar (-1, if cannot be converted to a uintvar)
2502 * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
2505 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
2507 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
2511 UINT32 decodedUintvar = 0;
2512 UINT8 iBuff[5] = {0};
2513 int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
2516 if (pFile == NULL || pUintVar == NULL)
2520 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2521 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2522 MSG_DEBUG("fail to load to buffer");
2528 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
2531 if (oneByte > 0x7f) {
2532 iBuff[count++] = oneByte;
2534 iBuff[count++] = oneByte;
2539 MSG_DEBUG("legnth is too long");
2544 for (int i = 0; i < count; i++)
2545 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
2547 *pUintVar = decodedUintvar;
2552 gCurMmsDecodeBuffPos -= count;
2557 * Decode uintvar to 32bit unsigned integer by uintvar length
2559 * @param pEncodedData [in] uintvar encoded data
2560 * @param length [in] length of integer value
2561 * @return unsigned integer value
2563 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
2573 returner.integer = 0;
2580 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2581 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2585 if (oneByte > 0x7f) {
2586 return (oneByte & 0x7f);
2595 pData = (char *)calloc(1, length + 1);
2596 if (pData == NULL) {
2597 MSG_DEBUG("pData alloc fail");
2600 memset(pData, 0, length + 1);
2602 if (__MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
2603 MSG_DEBUG("_MmsBinaryDecodeGetOneByte fail");
2607 gCurMmsDecodeBuffPos--; /* - NULL */
2609 for (i= 0; i < length; i++)
2610 returner.seg[length - (i+1)] = pData[i];
2617 return returner.integer;
2626 return returner.integer;
2630 * Decode uintvar to 32bit unsigned integer by uintvar length
2632 * @param pEncodedData [in] uintvar encoded data
2633 * @param pInteger [out] Decode integer value (long/short)
2634 * @return unsigned integer value (-1, if cannot be converted to unsigned integer value)
2636 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
2646 if (pInteger == NULL)
2649 returner.integer = 0;
2652 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2653 MSG_DEBUG("GetOneByte fail");
2657 if (oneByte < 0x1F) /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2659 pData = (char *)calloc(1, oneByte + 1);
2660 if (pData == NULL) {
2661 MSG_DEBUG("pData calloc fail");
2664 memset(pData, 0, oneByte + 1);
2666 /* Even NULL is copied in the _MmsBinaryDecodeGetBytes */
2667 if (__MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
2668 MSG_DEBUG("GetBytes fail");
2672 gCurMmsDecodeBuffPos--; /* - NULL */
2682 for (i = 0; i < length; i++)
2683 returner.seg[length - (i+1)] = pData[i];
2685 *pInteger = returner.integer;
2686 *pIntLen = oneByte + 1;
2687 } else if (oneByte >= 0x80) {
2688 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
2689 *pInteger = oneByte & 0x7f;
2704 gCurMmsDecodeBuffPos--;
2715 * Decode uintvar to 32bit unsigned integer by uintvar length
2717 * @return 1 : Success
2718 * 0 : This is not Value Length type data
2719 * -1 : Requires System error report
2721 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
2729 * value-length = short-length | (Length-quote Length)
2730 * = 0~30 | 31 + Uintvar-length
2733 if (pFile == NULL || pValueLength == NULL)
2738 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2739 gCurMmsDecodeBuffPos--;
2743 if (0x00 < oneByte && oneByte < 0x1F) {
2746 *pValueLength = oneByte;
2748 } else if (oneByte == 0x1F) {
2749 /* Length-quote = 0x1F */
2751 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2753 MSG_DEBUG(" __MmsBinaryDecodeUintvar fail..");
2756 length ++; /* + length-quote */
2757 *pValueLength = uintvar;
2759 MSG_DEBUG("not a value length type data");
2760 gCurMmsDecodeBuffPos--;
2767 MSG_DEBUG("getting data fail");
2772 * Decode uintvar to 32bit unsigned integer by uintvar length
2774 * @return 1 : Success
2775 * 0 : This is not Value Length type data
2776 * -1 : Requires System error report
2777 * @ defference : if there is not length-quote, consider it as short length.
2779 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
2787 * value-length = short-length | (Length-quote Length)
2788 * = 0~30 | 31 + Uintvar-length
2791 if (pFile == NULL || pValueLength == NULL)
2796 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
2797 gCurMmsDecodeBuffPos--;
2801 if (0x00 < oneByte && oneByte < 0x1F) {
2804 *pValueLength = oneByte;
2806 } else if (oneByte == 0x1F) {
2807 /* Length-quote = 0x1F */
2809 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
2811 MSG_DEBUG("__MmsBinaryDecodeUintvar fail..");
2814 length ++; /* + length-quote */
2815 *pValueLength = uintvar;
2817 MSG_DEBUG("there is not length-quote, consider it as short length.");
2818 *pValueLength = oneByte;
2825 MSG_DEBUG("getting data fail");
2830 * Decode QuotedString
2832 * @param pEncodedData [in] QuotedString encoded data
2833 * @param szBuff [out] Decoded quoted string
2834 * @param bufLen [out] Buffer length
2835 * @return length of quoted string
2837 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2843 int returnLength = 0;
2846 * Quoted-string = <Octet 34> *TEXT End-of-string
2847 * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
2850 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2853 memset(szBuff, 0, bufLen);
2855 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2856 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2857 MSG_DEBUG("fail to load to buffer");
2861 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2866 while (length > gMmsDecodeBufLen) {
2867 if (gMmsDecodeBufLen <= 0) {
2868 MSG_DEBUG("gMmsDecodeBufLen <= 0");
2869 MSG_DEBUG("%x %x %x %x %x",
2870 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
2871 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
2872 MSG_DEBUG("%x %x %x %x %x",
2873 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
2874 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
2875 MSG_DEBUG("%x %x %x %x %x",
2876 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
2877 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
2878 MSG_DEBUG("%x %x %x %x %x",
2879 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
2880 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
2884 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
2888 memset(pData, 0, gMmsDecodeBufLen + 1);
2890 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
2893 returnLength += gMmsDecodeBufLen;
2895 if ((bufLen - iPos) > 0) {
2896 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
2897 if (iPos == 0 && (pData[0] == MARK)) {
2898 /* MARK: check first time only */
2900 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2901 iPos += (readBytes - 1);
2903 strncpy(szBuff + iPos, (char*)pData, readBytes);
2913 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2914 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2915 MSG_DEBUG("fail to load to buffer");
2918 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
2922 pData = (char *)calloc(1, length);
2926 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
2929 returnLength += length;
2931 if ((bufLen - iPos) > 0) {
2932 /* read until NULL from raw data, and copy only string */
2933 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
2934 if (iPos == 0 && (pData[0] == MARK)) {
2935 /* MARK: check first time only */
2936 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
2937 iPos += (readBytes - 1);
2939 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); /* + NULL */
2950 szBuff[bufLen - 1] = '\0';
2952 return returnLength;
2971 * @param pEncodedData [in] QuotedString encoded data
2972 * @param szBuff [out] Decoded quoted string
2973 * @param bufLen [out] Buffer length
2974 * @return length of decode text string
2976 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2981 int returnLength = 0;
2983 bool bQuote = false;
2987 * Text-String = [QUOTE]*TEXT end_of_string
2988 * [QUOTE]*(128~255)\0
2992 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
2995 offset = __MmsGetDecodeOffset();
2996 if (offset >= totalLength)
2999 memset(szBuff, 0, bufLen);
3001 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3002 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3003 MSG_DEBUG("fail to load to buffer");
3007 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
3012 while (length > gMmsDecodeBufLen) {
3013 if (gMmsDecodeBufLen <= 0) {
3014 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3015 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3016 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3017 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3018 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3019 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3020 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3021 MSG_DEBUG("%x %x %x %x %x", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3022 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3026 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3030 memset(pData, 0, gMmsDecodeBufLen + 1);
3032 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3035 if ((bufLen - iPos) > 0) {
3036 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3037 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3038 /* QUOTE: check first time only */
3040 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3041 iPos += (readBytes - 1);
3044 strncpy(szBuff + iPos, (char*)pData, readBytes);
3054 returnLength += gMmsDecodeBufLen;
3056 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3057 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3058 MSG_DEBUG("fail to load to buffer");
3061 length = strlen(gpCurMmsDecodeBuff) + 1; /* + NULL */
3065 pData = (char *)calloc(1, length);
3069 memset(pData, 0, length);
3071 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3074 if ((bufLen - iPos) > 0) {
3075 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3076 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3077 /* QUOTE: check first time only */
3079 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3080 iPos += (readBytes - 1);
3083 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); /* + NULL */
3093 returnLength += length; /* + NULL */
3096 szBuff[bufLen - 1] = '\0';
3098 return returnLength;
3105 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3119 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
3124 char *szBuff = NULL;
3125 char *szTempPtr = NULL;
3126 bool bQuote = false;
3130 * Text-String = [QUOTE]*TEXT end_of_string
3131 * [QUOTE]*(128~255)\0
3135 if (pFile == NULL || pLength == NULL)
3139 offset = __MmsGetDecodeOffset();
3140 if (offset >= totalLength)
3143 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3144 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3145 MSG_DEBUG("fail to load to buffer");
3149 length = strlen(gpCurMmsDecodeBuff) + 1;
3154 while (length > gMmsDecodeBufLen) {
3155 if (gMmsDecodeBufLen <= 0) {
3156 MSG_DEBUG("gMmsDecodeBufLen <= 0");
3157 MSG_DEBUG("%x %x %x %x %x",
3158 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3159 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3160 MSG_DEBUG("%x %x %x %x %x",
3161 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3162 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3163 MSG_DEBUG("%x %x %x %x %x",
3164 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3165 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3166 MSG_DEBUG("%x %x %x %x %x\n",
3167 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3168 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3172 pData = (char *)calloc(1, gMmsDecodeBufLen + 1);
3176 memset(pData, 0, gMmsDecodeBufLen + 1);
3178 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3181 if (szBuff == NULL) {
3182 szBuff = (char *)calloc(1, gMmsDecodeBufLen + 1);
3184 szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
3186 /* NULL pointer check for realloc */
3187 if (szTempPtr == NULL) {
3196 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
3198 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3199 /* QUOTE: check first time only */
3201 strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
3202 curLen += (gMmsDecodeBufLen - 1);
3205 strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
3206 curLen += gMmsDecodeBufLen;
3214 *pLength += gMmsDecodeBufLen;
3216 if (__MsgLoadDataToDecodeBuffer(pFile,
3217 &gpCurMmsDecodeBuff,
3218 &gCurMmsDecodeBuffPos,
3219 &gMmsDecodeCurOffset,
3224 totalLength) == false) {
3225 MSG_DEBUG("fail to load to buffer");
3228 length = strlen(gpCurMmsDecodeBuff) + 1;
3232 pData = (char *)calloc(1, length);
3233 if (pData == NULL) {
3237 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
3241 if (szBuff == NULL) {
3242 szBuff = (char *)calloc(1, length);
3244 szTempPtr = (char *)realloc(szBuff, curLen + length);
3246 /* NULL pointer check for realloc */
3247 if (szTempPtr == NULL)
3253 if (szBuff == NULL) {
3257 memset(szBuff + curLen, 0, length);
3259 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3260 /* QUOTE: check first time only */
3262 strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
3263 curLen += (length - 1);
3266 strncpy(szBuff + curLen, (char*)pData, length - 1);
3275 *pLength += length; /* + NULL */
3284 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3306 * @param pEncodedData [in] QuotedString encoded data
3307 * @param nCharSet [out] Decoded character set
3308 * @return length of charset value
3310 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
3315 * Charset v1.1 0x01 Well-known-charset
3316 * Well-known-charset = Any-charset | Integer-value
3317 * ; Both are encoded using values from
3318 * Character Set Assignments table in Assigned Numbers
3319 * Any-charset = <Octet 128>
3320 * ; Equivalent to the special RFC2616 charset value ��*��
3323 if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
3326 if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
3327 MSG_DEBUG("__MmsBinaryDecodeInteger fail...");
3332 /* AnyCharSet : return MSG_CHARSET_UTF8 */
3333 *nCharSet = MSG_CHARSET_UTF8;
3337 *nCharSet = MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
3338 MSG_DEBUG("Decoded charset MIBenum = [%d], charset enum = [%d]", integer, *nCharSet);
3339 if (*nCharSet == MIME_UNKNOWN) {
3340 MSG_DEBUG("MmsGetBinaryType fail..");
3341 *nCharSet = MSG_CHARSET_UNKNOWN;
3351 * Decode EncodedString
3353 * @param pEncodedData [in] QuotedString encoded data
3354 * @param szBuff [out] Decoded string buffer
3355 * @param bufLen [in] Decoded buffer length
3356 * @return length of decoded string length
3358 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3360 UINT32 valueLength = 0;
3366 MSG_DEBUG(" decode string..");
3368 if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
3369 MSG_DEBUG("invalid file or buffer");
3374 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3375 * Text-string = [Quote]*TEXT End-of-string
3376 * Value-length = 0 ~ 31
3379 memset(szBuff, 0, bufLen);
3381 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3387 /* Text-string = [Quote]*TEXT End-of-string */
3389 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
3390 MSG_DEBUG("__MmsBinaryDecodeText fail.");
3397 /* Value-length Charset Text_string */
3399 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3400 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3401 goto __CATCH; /* (valueLength + valueLengthLen) */
3404 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
3407 /* There can be some error in data - no NULL -> try again with value length */
3409 pData = (char *)calloc(1, valueLength - charSetLen);
3410 if (pData == NULL) {
3411 MSG_DEBUG("pData alloc fail.");
3415 if (__MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
3416 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes fail.");
3420 strncpy(szBuff, pData, bufLen - 1);
3425 nTemp = strlen(szBuff);
3427 const char *pToCharSet = "UTF-8";
3429 UINT16 charset_code = MmsGetBinaryValue(MmsCodeCharSet, charSet);
3431 const char *pFromCharSet = MmsPluginTextConvertGetCharSet(charset_code);
3432 if (pFromCharSet == NULL || !strcmp(pFromCharSet, pToCharSet)) {
3443 if (MmsPluginTextConvert(pToCharSet, pFromCharSet, szBuff, nTemp, &pDest, &destLen) == false) {
3444 MSG_DEBUG("MmsPluginTextConvert Fail");
3447 memset(szBuff, 0x00, bufLen);
3448 snprintf(szBuff, destLen+1, "%s", pDest);
3479 * Decode Encoded Addresses
3481 * @param pEncodedData [in] QuotedString encoded data
3482 * @param pAddrLength [out] Decoded address length
3483 * @return Decoded address list
3485 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
3487 UINT32 valueLength = 0;
3491 char *pAddrStr = NULL;
3492 MsgHeaderAddress *pAddr = NULL;
3494 MSG_DEBUG("decoding address..");
3496 if (pFile == NULL) {
3497 MSG_DEBUG("invalid file or buffer");
3502 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3503 * Text-string = [Quote]*TEXT End-of-string
3504 * Value-length = 0 ~ 31
3507 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3513 /* Text-string = [Quote]*TEXT End-of-string */
3516 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3517 if (pAddrStr == NULL) {
3518 MSG_DEBUG(" __MmsBinaryDecodeText2 fail.");
3525 /* Value-length Charset Text_string */
3527 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3528 MSG_DEBUG(" __MmsBinaryDecodeCharset error");
3533 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3534 if (pAddrStr == NULL) {
3535 /* There can be some error in data - no NULL -> try again with value length */
3537 pAddrStr = (char *)calloc(1, valueLength - charSetLen);
3538 if (pAddrStr == NULL) {
3539 MSG_DEBUG("pData alloc fail.");
3543 if (__MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
3544 MSG_DEBUG(" _MmsBinaryDecodeGetLongBytes fail.");
3549 /* fixme: charset transformation */
3554 pAddr = (MsgHeaderAddress *)calloc(1, sizeof(MsgHeaderAddress));
3558 memset(pAddr, 0, sizeof(MsgHeaderAddress));
3559 pAddr->szAddr = pAddrStr;
3575 * Decode Encoded Pointer String
3577 * @param pEncodedData [in] Long integer encoded data
3578 * @param pLongInteger [out] Decoded long integer
3579 * @return Decoded address list
3581 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
3586 * Long-integer = Short-length Multi-octet-integer
3587 * Short-length = 0~30
3588 * Multi-octet-integer
3591 if (pFile == NULL || pLongInteger == NULL)
3596 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3602 *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
3612 * @param pEncodedData [in] filename encoded data
3613 * @param szBuff [out] filename output buffer
3614 * @param fullLength [in] full filename length
3615 * @param bufLen [in] buffer length
3616 * CAUTION: bufLen - 1
3618 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3620 char *pUTF8Buff = NULL;
3621 char *pLatinBuff = NULL;
3624 char *szSrc2 = NULL;
3628 char *pTmpBuff = NULL;
3630 memset (szBuff, 0, bufLen);
3633 pLatinBuff = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
3637 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
3639 strncpy(pLatinBuff, szSrc, textLength);
3644 szSrc2 = MsgChangeHexString(pLatinBuff);
3646 strncpy(pLatinBuff, szSrc2, textLength);
3651 if (MmsIsUtf8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
3652 length = strlen(pLatinBuff);
3654 int utf8BufSize = 0;
3655 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
3656 if (utf8BufSize < 3)
3657 utf8BufSize = 3; /* min value */
3659 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
3660 if (pUTF8Buff == NULL) {
3661 MSG_DEBUG("pUTF8Buff alloc fail");
3665 if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
3666 MSG_DEBUG("MsgLatin2UTF fail");
3672 pTmpBuff = MsgDecodeText(pLatinBuff);
3673 pUTF8Buff = pTmpBuff;
3682 * it should be kept extention even if the file name is shorten
3685 length = strlen(pUTF8Buff);
3686 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
3688 nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
3689 strncpy(szBuff, pUTF8Buff, nameLength);
3690 g_strlcat(szBuff, pExt,(gsize)bufLen);
3693 strncpy(szBuff, pUTF8Buff, bufLen - 1);
3717 /* ==========================================================
3719 M M S D E C O D I N G
3721 ==========================================================*/
3723 /* to get message body this function should be modified from message raw file. */
3724 bool MmsReadMsgBody(msg_message_id_t msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
3727 MmsMsg *pMsg = NULL;
3728 MsgMultipart *pMultipart = NULL;
3730 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
3731 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
3735 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
3736 memset(pMsg, 0, sizeof(MmsMsg));
3740 if (bRetrieved && (retrievedPath != NULL)) {
3741 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
3743 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath, sizeof(szFullPath));
3746 pMsg->msgID = msgID;
3748 /* read from MMS raw file */
3749 strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
3751 MSG_SEC_DEBUG("msg_id = [%d]", msgID);
3752 MSG_SEC_DEBUG("raw file path = [%s]", szFullPath);
3754 if (MsgGetFileSize(szFullPath, &nSize) == false) {
3755 MSG_FATAL("Fail MsgGetFileSize");
3759 pFile = MsgOpenFile(szFullPath, "rb");
3760 if (pFile == NULL) {
3761 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
3765 MmsRegisterDecodeBuffer();
3767 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
3768 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
3772 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
3773 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
3777 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
3779 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
3780 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
3782 { /* attribute convert mmsHeader -> mmsAttribute */
3784 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
3786 pMsg->mmsAttrib.date = mmsHeader.date;
3788 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
3789 pMsg->mmsAttrib.bAskDeliveryReport = true;
3792 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
3794 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
3796 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
3798 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
3800 pMsg->mmsAttrib.msgType = mmsHeader.type;
3802 pMsg->mmsAttrib.version = mmsHeader.version;
3804 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
3806 pMsg->mmsAttrib.priority = mmsHeader.priority;
3808 if (mmsHeader.readReply == MMS_REPORT_YES) {
3809 pMsg->mmsAttrib.bAskReadReply = true;
3812 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
3814 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
3816 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
3818 /* FIXME:: mmsHeader will release after delete global mmsHeader */
3819 /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
3821 if (pMsg->msgBody.pPresentationBody) {
3822 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
3825 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
3826 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
3829 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
3832 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
3838 MsgCloseFile(pFile);
3841 pMsg->nPartCount = 0;
3843 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
3844 pMultipart = pMsg->msgBody.body.pMultipart;
3845 while (pMultipart) {
3847 pMultipart = pMultipart->pNext;
3850 if (pMsg->msgBody.size > 0)
3854 /* make temporary */
3855 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
3857 if (MsgIsMultipart(pMsg->msgType.type) == true) {
3859 pMultipart = pMsg->msgBody.body.pMultipart;
3861 if (bSavePartsAsTempFiles) {
3862 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3863 if (errno == EEXIST) {
3864 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
3866 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3870 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
3874 if (pMsg->msgBody.pPresentationBody) {
3875 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
3876 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3880 while (pMultipart) {
3882 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
3883 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
3886 MmsPrintMulitpart(pMultipart, partIndex);
3888 pMultipart = pMultipart->pNext;
3892 } else { /* single part */
3893 if (pMsg->nPartCount > 0) {
3895 if (bSavePartsAsTempFiles) {
3896 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
3897 if (errno == EEXIST) {
3898 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
3900 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
3904 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
3908 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
3909 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
3913 MSG_DEBUG("### Success ###");
3920 MmsUnregisterDecodeBuffer();
3922 if (pFile != NULL) {
3923 MsgCloseFile(pFile);
3928 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
3930 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
3932 MSG_DEBUG("### Fail ###");
3937 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
3939 MsgHeaderAddress *pTempAddr = NULL;
3941 while (pAddr != NULL) {
3943 pAddr = pAddr->pNext;
3945 if (pTempAddr->szAddr) {
3946 free(pTempAddr->szAddr);
3947 pTempAddr->szAddr = NULL;
3957 static bool __MsgCheckFileNameHasInvalidChar(char *szName)
3962 strLen = strlen(szName);
3964 for (i=0; i<strLen; i++) {
3965 if (__MsgIsInvalidFileNameChar(szName[i]))
3972 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
3975 int totalLength = 0;
3977 totalLength = strlen(szInText);
3979 while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
3980 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
3981 if (__MsgIsInvalidFileNameChar(szInText[nCount]))
3982 *(szInText+nCount) = replaceChar;
3993 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter)
3995 char *pszBuffer = NULL;
3996 char *pszStrDelimiter = NULL;
4000 MSG_DEBUG("pszString == NULL");
4004 if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
4005 MSG_DEBUG("There is no %c in %s. \n", delimiter, pszString);
4009 bufLength = pszStrDelimiter - pszString;
4011 if ((pszBuffer = (char*)calloc (1, bufLength + 1)) == NULL) {
4012 MSG_DEBUG("calloc is failed");
4015 memset(pszBuffer, 0, bufLength + 1) ;
4017 strncat(pszBuffer, pszString, bufLength);
4022 char *MsgChangeHexString(char *pOrg)
4025 char szBuf[10] = {0,};
4034 cLen = strlen(pOrg);
4036 pNew = (char *)calloc(1, cLen + 1);
4040 memset(pNew, 0, cLen + 1);
4042 for (cIndex = 0; cIndex< cLen ; cIndex++) {
4043 if (pOrg[cIndex] == '%') {
4044 if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0) {
4045 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); /* read two chars after '%' */
4047 if (__MsgIsHexChar(szBuf) == true) { /* check the two character is between 0 ~ F */
4048 OneChar = __MsgConvertHexValue(szBuf);
4050 pNew[index] = OneChar;
4057 pNew[index++] = pOrg[cIndex];
4062 static bool __MsgParseParameter(MsgType *pType, char *pSrc)
4065 char *pValue = NULL;
4068 char *pNextParam = NULL;
4072 char *pTempNextParam = NULL;
4075 char *pUTF8Buff = NULL;
4077 while (pSrc != NULL) {
4078 pSrc = __MsgSkipWS(pSrc);
4080 /* End of parse parameter */
4085 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
4088 if (*pCh == MSG_CH_QUOT) {
4095 for (; pCh<=pTempNextParam ; pCh++) {
4096 if (*pCh == MSG_CH_QUOT)
4097 if (*(pCh - 1) != '\\')
4102 pNextParam = pTempNextParam;
4105 *pNextParam++ = MSG_CH_NULL;
4107 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
4108 *pName++ = MSG_CH_NULL;
4110 if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
4111 *pValue++ = MSG_CH_NULL;
4113 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
4114 *pTest = MSG_CH_NULL;
4116 pDec = MsgDecodeText(pValue); /* Api is to long, consider Add to another file (MsgMIMECodec.c) */
4118 pDec = MsgDecodeText(pName);
4122 switch (MmsGetTextType(MmsCodeParameterCode, pSrc)) {
4123 case MSG_PARAM_BOUNDARY:
4125 /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
4127 memset (pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
4128 strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
4129 MSG_SEC_INFO("szBoundary = [%s]", pType->param.szBoundary);
4132 case MSG_PARAM_CHARSET:
4133 pType->param.charset = MmsGetTextType(MmsCodeParameterCode, pDec);
4135 if (pType->param.charset == -1)
4136 pType->param.charset = MSG_CHARSET_UNKNOWN;
4138 MSG_SEC_INFO("type = %d [charset] = %d", pType->type, pType->param.charset);
4141 case MSG_PARAM_NAME:
4143 memset (pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
4145 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4148 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4149 if ((MSG_LOCALE_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4150 nameLen = (MSG_LOCALE_FILENAME_LEN_MAX-1) - strlen(pExt);
4152 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4155 strncpy(pType->param.szName, pUTF8Buff, nameLen);
4156 g_strlcat(pType->param.szName, pExt, sizeof(pType->param.szName));
4158 strncpy(pType->param.szName, pUTF8Buff, (MSG_LOCALE_FILENAME_LEN_MAX-1));
4163 if (__MsgChangeSpace(pType->param.szName, &szSrc) == true) {
4165 strncpy(pType->param.szName, szSrc , strlen(szSrc));
4173 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4174 __MsgRemoveFilePath(pType->param.szName);
4176 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4179 MSG_SEC_INFO("szName = %s", pType->param.szName);
4182 case MSG_PARAM_FILENAME:
4184 memset (pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
4186 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4189 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4190 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4191 nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
4193 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4196 strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
4197 g_strlcat (pType->param.szFileName, pExt, sizeof(pType->param.szFileName));
4199 strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
4204 if (__MsgChangeSpace(pType->param.szFileName, &szSrc) == true) {
4205 snprintf(pType->param.szFileName, sizeof(pType->param.szFileName), "%s", szSrc);
4213 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4214 __MsgRemoveFilePath(pType->param.szFileName);
4216 MSG_SEC_DEBUG("MsgConvertLatin2UTF8FileName(%s) return NULL", pDec);
4219 MSG_SEC_INFO("szFileName = %s", pType->param.szFileName);
4223 case MSG_PARAM_TYPE:
4225 /* type/subtype of root. Only if content-type is multipart/related */
4227 pType->param.type = MimeGetMimeIntFromMimeString(pDec);
4228 MSG_SEC_INFO("type = %d", pType->param.type);
4232 case MSG_PARAM_START:
4234 /* Content-id. Only if content-type is multipart/related */
4236 memset (pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
4237 strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
4239 MSG_SEC_INFO("szStart = %s", pType->param.szStart);
4243 case MSG_PARAM_START_INFO:
4245 /* Only if content-type is multipart/related */
4247 memset (pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
4248 strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
4250 MSG_SEC_INFO("szStartInfo = %s", pType->param.szStartInfo);
4254 case MSG_PARAM_REPORT_TYPE:
4256 /* only used as parameter of Content-Type: multipart/report; report-type=delivery-status; */
4258 if (strcasecmp(pDec, "delivery-status") == 0) {
4259 pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
4261 pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
4264 MSG_SEC_INFO("reportType = %s", pDec);
4269 MSG_DEBUG("Unknown paremeter (%s)", pDec);
4282 static char *__MsgSkipWS(char *s)
4285 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
4287 } else if ((*s != '(') || (__MsgSkipComment(s,(long)NULL)==NULL)) {
4293 static char *__MsgSkipComment (char *s,long trim)
4300 /* ignore empty space */
4301 for (ret = ++s1; *ret == ' '; ret++)
4304 /* handle '(', ')', '\', '\0' */
4308 if (!__MsgSkipComment (s1,(long)NULL))
4340 static char *__MsgConvertLatin2UTF8FileName(char *pSrc)
4342 char *pUTF8Buff = NULL;
4343 /* char *pData = NULL; */
4346 /* convert utf8 string */
4347 if (MmsIsUtf8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
4349 int utf8BufSize = 0;
4351 length = strlen(pSrc);
4352 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
4353 if (utf8BufSize < 3)
4354 utf8BufSize = 3; /* min value */
4356 pUTF8Buff = (char *)calloc(1, utf8BufSize + 1);
4358 if (pUTF8Buff == NULL) {
4359 MSG_DEBUG("pUTF8Buff alloc fail");
4363 if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
4364 MSG_DEBUG("MsgLatin2UTF fail");
4368 int length = strlen(pSrc);
4369 pUTF8Buff = (char *)calloc(1, length+1);
4371 if (pUTF8Buff == NULL) {
4372 MSG_DEBUG("pUTF8Buff alloc fail");
4376 memcpy(pUTF8Buff, pSrc, length);
4379 /* convert hex string */
4381 if (__MsgIsPercentSign(pUTF8Buff) == true) {
4382 pData = MsgChangeHexString(pUTF8Buff);
4402 static bool __MsgChangeSpace(char *pOrg, char **ppNew)
4412 cLen = strlen(pOrg);
4414 pNew = (char *)calloc(1, cLen + 1);
4418 memset(pNew, 0, cLen + 1);
4420 for (cIndex=0; cIndex<cLen;cIndex++) {
4421 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
4427 pNew[index++] = pOrg[cIndex];
4435 static void __MsgRemoveFilePath(char *pSrc)
4437 /* Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif" */
4439 char *tmp_name = NULL;
4441 tmp_name = MsgGetFileName(pSrc);
4443 snprintf(pSrc, strlen(tmp_name), "%s", tmp_name);
4448 /* Remove additional file information
4449 * ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
4450 * if "?size=" exist, insert NULL char. */
4452 pTemp = strcasestr(pSrc, "?size=");
4459 static bool __MsgIsPercentSign(char *pSrc)
4464 pCh = strchr(pSrc , '%');
4476 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam)
4478 char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
4479 char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
4480 char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
4483 /* remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445> */
4484 if (szStart && szStart[0]) {
4486 startLen = strlen(szStart);
4487 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
4488 strncpy(szTmpStart, &szStart[1], startLen - 2);
4490 strncpy(szTmpStart, szStart, startLen);
4494 /* remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445> */
4495 if (multipartType->szContentID[0]) {
4496 strLen = strlen(multipartType->szContentID);
4497 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
4498 strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
4500 strncpy(szTmpContentID, multipartType->szContentID, strLen);
4504 /* remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445> */
4505 if (multipartType->szContentLocation[0]) {
4506 strLen = strlen(multipartType->szContentLocation);
4507 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
4508 strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
4510 strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
4514 if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
4515 return MSG_PRESENTATION_NONE;
4517 /* exception handling */
4518 if (szTmpStart[0] != '\0') {
4519 /* presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type */
4520 if (strcmp(szTmpStart, szTmpContentID) == 0) {
4521 return MSG_PRESENTATION_ID;
4522 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
4523 return MSG_PRESENTATION_LOCATION;
4524 } else if (multipartType->type == typeParam) {
4525 return MSG_PRESENTATION_TYPE_BASE;
4527 return MSG_PRESENTATION_NONE;
4530 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
4531 return MSG_PRESENTATION_TYPE_BASE;
4533 return MSG_PRESENTATION_NONE;
4538 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
4541 MsgMultipart *pNextPart = NULL;
4542 MsgMultipart *pRemovePart = NULL;
4544 if (__MsgIsMultipartRelated(pMsgType->type)) {
4545 /* assign the multipart to presentation part */
4546 /* remove the multipart(pCurPresentation) which is presentation part from the linked list. */
4547 /* if there is no presentation part -> assign first multipart to presentation part by force. */
4548 if (pPresentationInfo->pCurPresentation == NULL) {
4549 pPresentationInfo->pCurPresentation = pMsgBody->body.pMultipart;
4550 pPresentationInfo->pPrevPart = NULL;
4551 pPresentationInfo->factor = MSG_PRESENTATION_NONE;
4554 if (pPresentationInfo->pCurPresentation != NULL && __MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
4555 /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
4556 * In this case, COPY the Presentation part and leave other multiparts.
4558 memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4559 pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
4561 /* remove pCurPresentation from multipart linked list */
4562 if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE)||(pPresentationInfo->pPrevPart == NULL)) {
4564 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
4565 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4566 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4567 if (pPresentationInfo->pCurPresentation) {
4569 MmsReleaseMsgDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
4571 free(pPresentationInfo->pCurPresentation);
4572 pPresentationInfo->pCurPresentation = NULL;
4575 /* not a first part */
4576 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
4577 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
4578 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
4579 if (pPresentationInfo->pCurPresentation) {
4580 free(pPresentationInfo->pCurPresentation);
4581 pPresentationInfo->pCurPresentation = NULL;
4584 } else if (pPresentationInfo->pCurPresentation != NULL && MmsIsTextType(pPresentationInfo->pCurPresentation->type.type)) {
4585 /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
4586 * In this case, leave the Presentation part as a multipart and remove other multiparts.
4589 /* Backup the multipart link information */
4590 pNextPart = pMsgBody->body.pMultipart;
4592 /* Copy presentation part as a main part */
4593 memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
4594 memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
4596 /* Remove multipart linked list */
4598 pRemovePart = pNextPart;
4599 pNextPart = pNextPart->pNext;
4601 if (pRemovePart->pBody) {
4602 MmsReleaseMsgBody(pRemovePart->pBody, pRemovePart->type.type);
4603 free(pRemovePart->pBody);
4604 pRemovePart->pBody = NULL;
4613 MmsReleaseMsgDRMInfo(&pMsgBody->presentationType.drmInfo);
4615 MmsInitMsgType(&pMsgBody->presentationType);
4616 pMsgBody->pPresentationBody = NULL;
4622 static bool __MsgIsMultipartRelated(int type)
4624 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
4631 static bool __MsgIsPresentablePart(int type)
4633 if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
4640 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
4643 MsgMultipart *pTmpMultipart = NULL;
4644 MsgMultipart *pSelectedPart = NULL;
4645 MsgMultipart *pPrevPart = NULL;
4646 MsgMultipart *pFirstPart = NULL;
4647 MsgMultipart *pLastPart = NULL;
4648 MsgMultipart *pRemoveList = NULL;
4649 MsgMultipart *pNextRemovePart = NULL;
4651 switch (pPartType->type) {
4652 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
4653 case MIME_MULTIPART_ALTERNATIVE:
4656 * Policy: multipart/alternative
4657 * multipart/alternative message has only several parts of media.
4658 * You should choose one of them and make the alternative part
4659 * to the selected media part.
4662 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE");
4664 pSelectedPart = pPartBody->body.pMultipart;
4666 /* NULL Pointer check!! */
4667 if (pSelectedPart == NULL) {
4668 MSG_DEBUG("multipart(ALTERNATIVE) does not exist");
4672 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4674 while (pTmpMultipart) {
4675 if (pSelectedPart->type.type <= pTmpMultipart->type.type)
4676 pSelectedPart = pTmpMultipart;
4678 pTmpMultipart = pTmpMultipart->pNext;
4681 pTmpMultipart = pPartBody->body.pMultipart;
4684 while (pTmpMultipart) {
4685 if (pSelectedPart == pTmpMultipart)
4688 pPrevPart = pTmpMultipart;
4689 pTmpMultipart = pTmpMultipart->pNext;
4692 if (pPrevPart == NULL) {
4693 /* selected part is the first part */
4694 pRemoveList = pSelectedPart->pNext;
4696 pPrevPart->pNext = pSelectedPart->pNext;
4697 pRemoveList = pPartBody->body.pMultipart;
4698 pPartBody->body.pMultipart = pSelectedPart;
4701 pSelectedPart->pNext = NULL;
4705 MmsReleaseMsgDRMInfo(&pRemoveList->type.drmInfo);
4707 MmsReleaseMsgBody(pRemoveList->pBody, pRemoveList->type.type);
4709 free(pRemoveList->pBody);
4713 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4714 MSG_DEBUG("MsgPriorityCopyMsgType failed");
4718 if (pSelectedPart->pBody != NULL)
4719 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4721 if (pSelectedPart != NULL) {
4723 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4725 if (pSelectedPart->pBody != NULL) {
4726 free(pSelectedPart->pBody);
4727 pSelectedPart->pBody = NULL;
4729 free(pSelectedPart);
4730 pSelectedPart = NULL;
4735 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
4736 case MIME_MULTIPART_RELATED:
4738 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_RELATED");
4740 pSelectedPart = pPartBody->body.pMultipart;
4742 while (pSelectedPart) {
4743 if (__MsgIsMultipartMixed(pSelectedPart->type.type)) {
4745 if (pSelectedPart->pBody == NULL) {
4746 MSG_DEBUG("pSelectedPart->pBody(1) is NULL");
4750 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4752 if (pFirstPart == NULL) {
4753 MSG_DEBUG("multipart(RELATED) does not exist");
4757 if (pFirstPart->pNext) {
4758 pLastPart = pFirstPart->pNext;
4759 while (pLastPart->pNext)
4760 pLastPart = pLastPart->pNext;
4762 pLastPart = pFirstPart;
4765 if (pPrevPart == NULL) {
4766 /* the first part */
4767 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4768 pPartBody->body.pMultipart = pFirstPart;
4769 pLastPart->pNext = pTmpMultipart;
4771 pTmpMultipart = pSelectedPart->pNext;
4772 pPrevPart->pNext = pFirstPart;
4773 pLastPart->pNext = pTmpMultipart;
4776 if (pSelectedPart) {
4778 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4780 free(pSelectedPart->pBody);
4781 free(pSelectedPart);
4783 pSelectedPart = pTmpMultipart;
4784 } else if (__MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
4785 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
4786 MmsReleaseMsgBody(pSelectedPart->pBody, pSelectedPart->type.type);
4788 free(pSelectedPart->pBody);
4789 free(pSelectedPart);
4790 pSelectedPart = pTmpMultipart;
4792 pPrevPart = pSelectedPart;
4793 pSelectedPart = pSelectedPart->pNext;
4800 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
4801 case MIME_MULTIPART_MIXED:
4803 MSG_DEBUG("MIME_APPLICATION_VND_WAP_MULTIPART_MIXED");
4806 pSelectedPart = pPartBody->body.pMultipart;
4808 while (pSelectedPart) {
4809 if (MsgIsMultipart(pSelectedPart->type.type)) {
4810 if (pSelectedPart->pBody == NULL) {
4811 MSG_DEBUG("pSelectedPart->pBody(2) is NULL");
4815 pFirstPart = pSelectedPart->pBody->body.pMultipart;
4817 /* NULL Pointer check!! */
4818 if (pFirstPart == NULL) {
4819 MSG_DEBUG("multipart does not exist");
4823 if (pFirstPart->pNext) {
4824 pLastPart = pFirstPart->pNext;
4825 while (pLastPart->pNext)
4826 pLastPart = pLastPart->pNext;
4828 pLastPart = pFirstPart;
4831 if (pPrevPart == NULL) {
4832 /* the first part */
4833 pTmpMultipart = pPartBody->body.pMultipart->pNext;
4834 pPartBody->body.pMultipart = pFirstPart;
4835 pLastPart->pNext = pTmpMultipart;
4837 pTmpMultipart = pSelectedPart->pNext;
4838 pPrevPart->pNext = pFirstPart;
4839 pLastPart->pNext = pTmpMultipart;
4842 if (pSelectedPart->pBody->pPresentationBody)
4843 pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
4845 memcpy(&pPartBody->presentationType,
4846 &pSelectedPart->pBody->presentationType, sizeof(MsgType));
4848 pPartType->type = pSelectedPart->type.type;
4850 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4852 free(pSelectedPart->pBody);
4853 free(pSelectedPart);
4855 pSelectedPart = pTmpMultipart;
4857 pPrevPart = pSelectedPart;
4858 pSelectedPart = pSelectedPart->pNext;
4864 case MIME_MULTIPART_REPORT:
4866 MSG_DEBUG("MIME_MULTIPART_REPORT");
4868 pTmpMultipart = pPartBody->body.pMultipart;
4871 if (pTmpMultipart == NULL) {
4872 MSG_DEBUG("pTmpMultipart == NULL");
4876 while (pTmpMultipart) {
4877 if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
4878 pSelectedPart = pTmpMultipart;
4882 pPrevPart = pTmpMultipart;
4883 pTmpMultipart = pTmpMultipart->pNext;
4886 if (pSelectedPart == NULL) {
4887 MSG_DEBUG("MIME_MULTIPART_REPORT [no selected part]");
4889 pRemoveList = pPartBody->body.pMultipart->pNext;
4890 if (pPartBody->body.pMultipart != NULL) {
4891 pSelectedPart = pPartBody->body.pMultipart;
4892 pSelectedPart->pNext = NULL;
4895 if (pPrevPart == NULL) {
4896 /* first part is selected */
4897 pRemoveList = pPartBody->body.pMultipart->pNext;
4899 pRemoveList = pPartBody->body.pMultipart->pNext;
4900 pPrevPart->pNext = pSelectedPart->pNext;
4903 pSelectedPart->pNext = NULL;
4904 pPartBody->body.pMultipart = pSelectedPart;
4907 pTmpMultipart = pRemoveList;
4909 while (pTmpMultipart) {
4911 MmsReleaseMsgDRMInfo(&pTmpMultipart->type.drmInfo);
4913 MmsReleaseMsgBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
4914 pNextRemovePart = pTmpMultipart->pNext;
4916 free(pTmpMultipart->pBody);
4917 free(pTmpMultipart);
4918 pTmpMultipart = pNextRemovePart;
4921 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
4922 MSG_DEBUG("MsgPriorityCopyMsgType failed");
4926 if (pSelectedPart != NULL) {
4928 if (pSelectedPart->pBody != NULL)
4929 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
4931 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
4933 if (pSelectedPart->pBody != NULL) {
4934 free(pSelectedPart->pBody);
4935 pSelectedPart->pBody = NULL;
4937 free(pSelectedPart);
4938 pSelectedPart = NULL;
4955 char *MsgResolveContentURI(char *szSrc)
4957 char *szTemp = NULL;
4958 char *szReturn = NULL;
4961 if (szSrc == NULL) {
4965 if (szSrc[0] == '\0')
4969 if (!strncasecmp(szSrc, "cid:", 4)) {
4970 length = strlen(szSrc) - 3;
4973 length = strlen(szSrc) + 1;
4976 szTemp = (char *)calloc(1, length);
4977 if (szTemp == NULL) {
4978 MSG_DEBUG("memory full");
4982 memset(szTemp, 0, length);
4984 strncpy(szTemp, szSrc, length - 1);
4986 szReturn = MsgChangeHexString(szTemp);
5000 char *MsgRemoveQuoteFromFilename(char *pSrc)
5002 int cLen = 0; /* length of pBuff */
5006 MSG_DEBUG("pSrc is Null");
5010 cLen = strlen(pSrc);
5012 pBuff = (char *)calloc(1, cLen + 1);
5014 if (pBuff == NULL) {
5015 MSG_DEBUG("pBuff mem alloc fail!");
5018 memset(pBuff, 0 , sizeof(char)*(cLen + 1));
5020 /* remove front quote */
5021 if (pSrc[0] == MSG_CH_QUOT) {
5023 strncpy(pBuff, &pSrc[1], cLen);
5025 } else if (pSrc[0] == MSG_CH_LF) {
5027 strncpy(pBuff, &pSrc[1], cLen);
5029 strncpy(pBuff, pSrc, cLen);
5032 /* remove last qoute */
5033 if (pBuff[cLen-1] == MSG_CH_QUOT) {
5034 pBuff[cLen-1] = '\0';
5040 bool MsgIsMultipart(int type)
5042 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
5043 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
5044 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
5052 static bool __MsgIsHexChar(char *pSrc)
5058 cLen = strlen(pSrc);
5060 for (cIndex = 0; cIndex < cLen ; cIndex++) {
5061 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
5062 (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
5072 static char __MsgConvertHexValue(char *pSrc)
5078 unsigned char uCh[2] = {0,};
5080 cLen = strlen(pSrc);
5082 for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
5083 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
5084 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
5085 ch = (int)uCh[0]<<4|uCh[1];
5088 ResultChar = (char)ch;
5093 static int __MsgConvertCharToInt(char ch)
5095 if (ch>='0' && ch<='9') {
5097 } else if (ch>='a'&& ch <='f') {
5099 } else if (ch>='A'&& ch <='F') {
5106 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
5108 if (!pMsgType1 || !pMsgType2)
5111 /* if (pMsgType1->section == INVALID_HOBJ) */
5112 pMsgType1->section = pMsgType2->section;
5116 if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
5117 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
5120 if (pMsgType1->szContentID[0] == '\0') {
5121 snprintf(pMsgType1->szContentID, sizeof(pMsgType1->szContentID), "%s", pMsgType2->szContentID);
5124 if (pMsgType1->szContentID[0] != '\0') {
5126 length = strlen(pMsgType1->szContentID);
5127 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
5128 char szTempString[MSG_MSG_ID_LEN + 1];
5129 MmsRemoveLessGreaterChar(pMsgType1->szContentID, szTempString, sizeof(szTempString));
5130 pMsgType1->drmInfo.szContentURI = g_strdup(szTempString);
5132 pMsgType1->drmInfo.szContentURI = g_strdup(pMsgType1->szContentID);
5136 if (pMsgType1->szContentLocation[0] == '\0') {
5137 strncpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation, MSG_MSG_ID_LEN);
5140 /* Copy informations - we shoud open the pMsgType2's orgFile
5141 * concerning its offset and size.
5143 if (pMsgType2->szOrgFilePath[0] != '\0') {
5144 strncpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath, MSG_FILEPATH_LEN_MAX-1);
5147 if (pMsgType2->disposition != -1)
5148 pMsgType1->disposition = pMsgType2->disposition;
5150 if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
5151 pMsgType2->encoding != -1)
5152 pMsgType1->encoding = pMsgType2->encoding;
5154 pMsgType1->contentSize = pMsgType2->contentSize;
5155 pMsgType1->offset = pMsgType2->offset;
5156 pMsgType1->size = pMsgType2->size;
5157 pMsgType1->type = pMsgType2->type;
5159 __MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
5161 if (pMsgType1->param.szName[0]) {
5162 pMsgType1->drmInfo.szContentName = g_strdup(pMsgType2->param.szName);
5168 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
5170 if (pParam1->charset == MSG_CHARSET_UNKNOWN)
5171 pParam1->charset = pParam2->charset;
5173 if (pParam1->type == MIME_UNKNOWN)
5174 pParam1->type = pParam2->type;
5176 /* Don't copy pParam2->pPresentation */
5178 /* For alternative: copy the boundary string */
5179 if (pParam2->szBoundary[0] !='\0') {
5180 strncpy(pParam1->szBoundary, pParam2->szBoundary, MSG_BOUNDARY_LEN);
5183 if (pParam1->szFileName[0] =='\0') {
5184 strncpy(pParam1->szFileName, pParam2->szFileName, MSG_FILENAME_LEN_MAX);
5187 if (pParam1->szName[0] =='\0') {
5188 strncpy(pParam1->szName, pParam2->szName, MSG_LOCALE_FILENAME_LEN_MAX);
5191 if (pParam1->szStart[0] =='\0') {
5192 strncpy(pParam1->szStart, pParam2->szStart, MSG_MSG_ID_LEN);
5195 if (pParam1->szStartInfo[0] =='\0') {
5196 strncpy(pParam1->szStartInfo, pParam2->szStartInfo, MSG_MSG_ID_LEN);
5201 static bool __MsgIsMultipartMixed(int type)
5203 if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
5210 static bool __MsgIsInvalidFileNameChar(char ch)
5212 if ((ch == 0x5C /* \ */) ||
5213 (ch == 0x2F /* / */) ||
5214 (ch == 0x3A /* : */) ||
5215 (ch == 0x2A /* * */) ||
5216 (ch == 0x3F /* ? */) ||
5217 (ch == 0x22 /* " */) ||
5218 (ch == 0x3C /* < */) ||
5219 (ch == 0x3E /* > */) ||
5220 (ch == 0x7C /* | */))
5226 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
5230 MSG_DEBUG("---------------");
5232 if ((szSrc == NULL) || (nChar <= 0)) {
5233 MSG_DEBUG("szSrc is NULL !!!! ---------------");
5237 while ((nChar > 0) && (*szSrc != '\0')) {
5238 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5252 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5255 unsigned char t1, t2;
5257 MSG_DEBUG("---------------");
5260 outBufSize--; /* NULL character */
5262 while ((nChar > 0) && (*szSrc != '\0')) {
5263 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
5264 /* check outbuffer's room for this UTF8 character */
5270 *des = (unsigned char) (*szSrc & 0x007F);
5276 /* check outbuffer's room for this UTF8 character */
5282 t2 = (unsigned char) (*szSrc & 0x003F); /* right most 6 bit */
5283 t1 = (unsigned char) ((*szSrc & 0xC0) >> 6); /* right most 2 bit */
5285 *des = 0xC0 | (t1 & 0x1F);
5286 *(des + 1) = 0x80 | (t2 & 0x3F);
5300 bool MmsAddrUtilCheckEmailAddress(char *pszAddr)
5302 if (!pszAddr || pszAddr[0] == 0)
5305 if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
5311 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
5313 char *pszAddrCopy = NULL;
5314 char *pszStrStart = NULL;
5315 char *pszStrTemp = NULL;
5318 if ((!pszAddr) || (pszAddr[0] == 0)) {
5319 MSG_DEBUG("pszAddr is null or zero");
5323 strLen = strlen(pszAddr);
5325 pszAddrCopy = (char*)calloc(1,strLen + 1);
5327 MSG_DEBUG("pszAddrCopy is NULL, mem alloc failed");
5331 strncpy(pszAddrCopy, pszAddr, strLen);
5334 pszStrStart = pszAddrCopy;
5337 char* pszStrEnd = NULL;
5340 if (MmsAddrUtilCheckEmailAddress(pszAddrCopy))
5341 pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
5343 pszStrEnd = strstr(pszStrStart, "/");
5346 char *pszStart = NULL;
5347 char *pszEnd = NULL;
5348 /* "/TYPE=PLMN" not found */
5350 int remainedLen = strlen(pszStrStart);
5352 if (remainedLen <= 0)
5355 /* Email address can occur with Sender Name<email-address> format */
5356 /* remove the Sender name and only retain the email address. */
5357 pszStart = strstr(pszStrStart, "<");
5359 pszEnd = strstr(pszStrStart, ">");
5362 pszStart++; /* skip "<" */
5363 g_strlcat(pszAddr, pszStart, pszEnd - pszStart + 1);
5368 g_strlcat(pszAddr, pszStrStart, strLen + 1);
5372 /* Get one address length */
5373 addressLen = pszStrEnd - pszStrStart;
5375 strncat(pszAddr, pszStrStart, addressLen);
5377 /* Find next address */
5378 pszStrStart = pszStrEnd;
5380 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
5383 addressLen = pszStrTemp - pszStrEnd;
5384 pszStrStart += addressLen;
5386 pszStrStart += strlen(pszStrEnd);
5389 if (pszStrStart[0] == 0) /* end of string */
5393 g_strlcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER, strLen + 1); /* add ';' */
5394 pszStrStart++; /* remove ';' */
5397 if (pszAddr[0] == 0)
5398 strncpy(pszAddr, pszAddrCopy, strLen);
5405 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
5409 MSG_DEBUG("---------------");
5412 outBufSize--; /* NULL character */
5414 while ((nChar > 0) && (*szSrc != '\0')) {
5415 if (*szSrc < 0x80) {
5423 } else if (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
5429 *(des + 1) = *(szSrc + 1);
5433 } else if ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
5439 *(des + 1) = *(szSrc + 1);
5440 *(des + 2) = *(szSrc + 2);
5452 MSG_DEBUG("utf8 incorrect range!");
5464 static void __MsgMIMERemoveQuote(char *szSrc)
5468 length = strlen(szSrc);
5469 if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
5472 for (index = 0; index < length-2; index++)
5473 szSrc[index] = szSrc[index+1];
5474 szSrc[index] = '\0';
5478 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
5484 if (pFile == NULL) {
5491 if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
5498 if (*pBufLen == 0) {
5499 length = maxLen - (*pPtr);
5501 length = (*pBufLen) - (*pPtr);
5507 if ((*ppBuf) == NULL) {
5508 memset(pInBuf1, 0, maxLen);
5510 } else if ((*ppBuf) == pInBuf1) {
5511 memset(pInBuf2, 0, maxLen);
5513 memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
5516 memset(pInBuf1, 0, maxLen);
5518 memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
5524 if (*pOffset == endOfFile) {
5529 if (maxLen == length) {
5531 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
5536 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
5539 *pBufLen = length + nRead;
5542 if ((*pOffset = MsgFtell(pFile)) == -1L) {
5543 MSG_DEBUG("MsgFtell Error");
5553 * This function write media data from raw data to file.
5556 * @param pszMailboxPath : path of mailbox
5557 * @param pszMsgFilename : name of msg file
5558 * @param index : used for file naming
5559 * @param bSave : if true, file will be save otherwise just filename will be stored.
5561 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
5564 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, }; /* file name of temp file */
5565 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; /* full absolute path of temp file. */
5566 bool bFileExist = false;
5570 MSG_DEBUG("pPartType is NULL");
5574 if (pPartType->type == MIME_APPLICATION_SMIL) {
5575 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", "smil.txt");
5578 if (pPartType->param.szName[0] != '\0') {
5579 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szName);
5580 } else if (pPartType->param.szFileName[0] != '\0') {
5581 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szFileName);
5582 } else if (pPartType->szContentLocation[0] != '\0') {
5583 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->szContentLocation);
5585 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
5589 /* make full path for save */
5590 __MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0, szFileName, sizeof(szFileName)); /* FL & CD -> extension(.dm) SD -> extension(.dcf) */
5592 snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName); /* get absolute path of each temp file of each part */
5594 if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
5595 MsgGetMimeTypeFromFileName(MIME_MAINTYPE_UNKNOWN, szFullPath, (MimeType *)&pPartType->type, NULL);
5598 bFileExist = MsgAccessFile(szFullPath, F_OK);
5600 MSG_SEC_DEBUG("save flag [%d], filepath [%s], file exist [%d]", bSave, szFullPath, bFileExist);
5602 if (bSave == true && bFileExist == false) {
5604 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
5605 MSG_DEBUG("MsgOpenFile failed");
5609 if (__MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
5610 MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
5614 MsgCloseFile(pFile);
5617 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5619 /* IF DRM type Convert to dcf */
5620 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5621 || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5623 char destDrmPath[MSG_FILEPATH_LEN_MAX] = {0,};
5625 if (MsgDrmConvertDmtoDcfType(pPartBody->szOrgFilePath, destDrmPath) == true) {
5626 MSG_INFO("Success Convert to Dcf");
5628 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5631 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5632 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5636 MSG_INFO("Fail Convert to Dcf");
5639 if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5640 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5642 MSG_SEC_INFO("Drm File Path [%s] isdrm [%d]", pPartBody->szOrgFilePath, MsgDrmIsDrmFile(pPartBody->szOrgFilePath));
5645 pPartBody->offset = 0;
5646 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5648 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
5649 MsgDrmRegisterFile(MSG_MODE_FILE, pPartBody->szOrgFilePath, strlen(pPartBody->szOrgFilePath));
5651 /* change szDrm2FullPath as current content path*/
5652 if (pPartType->drmInfo.szDrm2FullPath) {
5653 free(pPartType->drmInfo.szDrm2FullPath);
5654 pPartType->drmInfo.szDrm2FullPath = g_strdup(pPartBody->szOrgFilePath);
5658 MSG_SEC_DEBUG("Save Part File to [%s]", pPartBody->szOrgFilePath);
5661 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
5663 /* IF DRM type check dcf exist */
5664 if (pPartType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE
5665 || pPartType->type == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5667 char destDrmPath[MSG_FILEPATH_LEN_MAX] = {0,};
5669 MsgGetFileNameWithoutExtension(destDrmPath, pPartBody->szOrgFilePath);
5670 strncat(destDrmPath, ".dcf", 4);
5672 bFileExist = MsgAccessFile(destDrmPath, F_OK);
5675 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", destDrmPath);
5676 MsgGetFileName(pPartBody->szOrgFilePath, szFileName, MSG_FILENAME_LEN_MAX);
5679 if (MsgDrmIsDrmFile(pPartBody->szOrgFilePath) == true)
5680 MmsPluginDrmGetInfo(pPartBody->szOrgFilePath, pPartType);
5683 pPartBody->offset = 0;
5684 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
5686 MSG_SEC_DEBUG("Set Part File to [%s]", pPartBody->szOrgFilePath);
5690 if (szFileName[0] != '\0') {
5691 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. */
5692 snprintf(pPartType->param.szName, MSG_LOCALE_FILENAME_LEN_MAX+1, "%s", szFileName);
5693 MSG_SEC_DEBUG("Set Name : %s", pPartType->param.szName);
5701 if (pFile != NULL) {
5702 MsgCloseFile(pFile);
5709 bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
5714 char *pNewData = NULL;
5715 char *pTempData = NULL;
5716 int msgEncodingValue = 0;
5717 int msgTypeValue = 0;
5718 int msgCharsetValue = 0;
5723 msgEncodingValue = pPartType->encoding;
5724 msgTypeValue = pPartType->type;
5725 msgCharsetValue = pPartType->param.charset;
5727 offset = pPartBody->offset;
5728 size = pPartBody->size;
5730 if (pPartBody->szOrgFilePath[0]) {
5731 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
5733 if (pTempData == NULL) {
5734 MSG_DEBUG("pTempData read fail");
5739 } else if (pPartBody->body.pText) {
5740 pData = pPartBody->body.pText;
5741 nRead = pPartBody->size;
5744 if (pData == NULL) {
5745 MSG_DEBUG("there is no data");
5749 pNewData = __MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
5752 pPartType->encoding = MSG_ENCODING_BINARY;
5754 if (MmsIsTextType(msgTypeValue))
5755 pPartType->param.charset = MSG_CHARSET_UTF8;
5757 if (MsgWriteFile(pNewData, sizeof(char), nRead2, pFile) != (size_t)nRead2) {
5758 MSG_DEBUG("file writing fail");
5763 if (MsgWriteFile(pData, sizeof(char), nRead, pFile) != (size_t)nRead) {
5764 MSG_DEBUG("file writing fail");
5798 char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
5804 char *pConvertedStr = NULL;
5805 char *pConvertedData = NULL;
5806 char *pNewData = NULL;
5807 char *pReturnData = NULL;
5809 const char *pToCodeSet = "UTF-8";
5810 const char *pFromCodeSet = NULL;
5812 switch (msgEncodingValue) {
5813 case MSG_ENCODING_BASE64:
5815 pConvertedData = (char*)MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5816 MSG_DEBUG("MSG_ENCODING_BASE64 bodyLength [%d]", nByte);
5818 pTemp = pConvertedData;
5823 case MSG_ENCODING_QUOTE_PRINTABLE:
5825 pConvertedData = (char*)MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
5826 MSG_DEBUG("MSG_ENCODING_QUOTE_PRINTABLE bodyLength [%d]", nByte);
5828 pTemp = pConvertedData;
5835 MSG_DEBUG("encoding val [%d] bodyLength [%d]", msgEncodingValue, nRead);
5842 if (MmsIsTextType(msgTypeValue)) {
5844 if (msgCharsetValue == MSG_CHARSET_US_ASCII) {
5847 } else if (msgCharsetValue == MSG_CHARSET_UTF8) {
5849 /* skip BOM (Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM) */
5851 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
5861 UINT16 MIBenum = MmsGetBinaryValue(MmsCodeCharSet, msgCharsetValue);
5863 pFromCodeSet = MmsGetTextByCode(MmsCodeCharSet, MIBenum);
5865 MSG_DEBUG("char set enum = [%d], MIBenum = [%d], str = [%s]", msgCharsetValue, MIBenum, pFromCodeSet);
5868 MSG_DEBUG("Convert to UTF-8");
5870 if (MmsPluginTextConvert(pToCodeSet, pFromCodeSet, pTemp, nTemp, &pConvertedStr, npRead) == true) {
5871 pNewData = pConvertedStr;
5873 MSG_DEBUG("Failed MmsPluginTextConvert");
5878 } else { /* unsupported charset */
5879 MSG_DEBUG("unsupported charset");
5890 pReturnData = (char *)calloc(1, *npRead);
5891 if (pReturnData == NULL) {
5892 MSG_DEBUG("pReturnData alloc fail.");
5896 if (pNewData != NULL) {
5897 memset(pReturnData, 0, *npRead);
5898 memcpy(pReturnData, pNewData, *npRead);
5901 if (pConvertedData) {
5902 free(pConvertedData);
5903 pConvertedData = NULL;
5906 if (pConvertedStr) {
5907 free(pConvertedStr);
5908 pConvertedStr = NULL;
5915 if (pConvertedData) {
5916 free(pConvertedData);
5917 pConvertedData = NULL;
5920 if (pConvertedStr) {
5921 free(pConvertedStr);
5922 pConvertedStr = NULL;
5928 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex, char *outBuf, int outBufLen)
5930 char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
5931 char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
5932 const char *pExt = NULL;
5934 MSG_SEC_DEBUG("Input : type [0x%x], drmType [%d], filename [%s]", iMsgType, drmType, szFileName);
5936 if (szFileName == NULL)
5940 int inp_len = strlen(szFileName);
5943 pExt = strrchr(szFileName, '.');
5945 if (pExt != NULL && *(pExt + 1) != '\0') {
5951 MsgGetFileNameWithoutExtension(szTempFileName, szFileName);
5953 if (nUntitleIndex >= 1) {
5954 snprintf(szTempFileName, sizeof(szTempFileName), "%s_%d", "untitled", nUntitleIndex);
5956 snprintf(szTempFileName, sizeof(szTempFileName), "%s", "untitled");
5961 if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_MESSAGE)
5963 else if (iMsgType == MIME_APPLICATION_VND_OMA_DRM_CONTENT)
5966 if (pExt == NULL) { /* find ext from content type */
5968 if (iMsgType == MIME_APPLICATION_OCTET_STREAM || iMsgType == MIME_UNKNOWN) {
5969 MSG_DEBUG("unsupported MsgType [%d]", iMsgType);
5973 pExt = MimeGetExtFromMimeInt((MimeType)iMsgType);
5976 /* Filename + extension */
5978 snprintf(szTemp, sizeof(szTemp), "%s.%s", szTempFileName, pExt);
5980 MSG_DEBUG("Failed to get extension of that mime data file.");
5984 snprintf(outBuf, outBufLen, "%s", szTemp);
5985 MSG_SEC_DEBUG("Result : filename [%s]", outBuf);
5992 bool MsgGetFileNameWithoutExtension (char *szOutputName, char *szName)
5994 char *pszExt = NULL;
5996 if (szOutputName == NULL) {
5997 MSG_DEBUG("szOutputName is NULL");
6001 strncpy(szOutputName, szName, strlen(szName));
6003 if ((pszExt = strrchr(szOutputName, '.'))) {
6004 if (pszExt[0] == '.')
6011 bool MsgGetFileName(char *szFilePath, char *szFileName, int size)
6013 char *filename = NULL;
6015 filename = strrchr(szFilePath, '/');
6016 if (filename != NULL) {
6017 snprintf(szFileName, size, "%s", filename + 1);
6019 snprintf(szFileName, size, "%s", szFilePath);
6028 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
6030 MmsMsg *pMsg = NULL;
6031 MsgMultipart *pPart = NULL;
6033 if (pHeader == NULL) {
6034 MSG_DEBUG("Invalid pHeader input. It's null");
6038 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
6040 MmsInitMsgType(pHeader);
6043 /* Requires header of non-presentation */
6044 if (MsgIsMultipart(pMsg->msgType.type)) {
6045 MSG_DEBUG("Multipart header [index = %d] \n", index);
6047 pPart = pMsg->msgBody.body.pMultipart;
6049 while (pPart && index--)
6050 pPart = pPart->pNext;
6052 if (pPart == NULL) {
6053 MSG_DEBUG("There is no such msg part.");
6057 memcpy(pHeader, &pPart->type, sizeof(MsgType));
6059 MSG_DEBUG("Requires singlepart header");
6060 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
6067 ///////////////////////////////////////////////////////////////////////////////
6069 MmsPluginDecoder *MmsPluginDecoder::pInstance = NULL;
6071 MmsPluginDecoder *MmsPluginDecoder::instance()
6073 if (!MmsPluginDecoder::pInstance)
6074 MmsPluginDecoder::pInstance = new MmsPluginDecoder();
6076 return MmsPluginDecoder::pInstance;
6079 MmsPluginDecoder::MmsPluginDecoder(){}
6080 MmsPluginDecoder::~MmsPluginDecoder(){}
6082 void MmsPluginDecoder::decodeMmsPdu(MmsMsg *pMsg, msg_message_id_t msgID, const char *pduFilePath)
6087 MsgMultipart *pMultipart = NULL;
6089 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6090 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
6094 pMsg->msgID = msgID;
6096 snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6098 MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName));
6100 if (MsgGetFileSize(szFullPath, &nSize) == false) {
6101 MSG_FATAL("Fail MsgGetFileSize");
6105 pFile = MsgOpenFile(szFullPath, "rb");
6106 if (pFile == NULL) {
6107 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6111 MmsRegisterDecodeBuffer();
6113 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6114 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6118 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6119 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6123 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
6125 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
6126 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
6128 { /* attribute convert mmsHeader -> mmsAttribute */
6130 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
6132 pMsg->mmsAttrib.date = mmsHeader.date;
6134 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6135 pMsg->mmsAttrib.bAskDeliveryReport = true;
6138 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6140 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6142 MSG_DEBUG("@@@@@pMsg->mmsAttrib.deliveryTime=[%d]", pMsg->mmsAttrib.deliveryTime);
6144 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
6146 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
6148 pMsg->mmsAttrib.msgType = mmsHeader.type;
6150 pMsg->mmsAttrib.version = mmsHeader.version;
6152 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
6154 pMsg->mmsAttrib.priority = mmsHeader.priority;
6156 if (mmsHeader.readReply == MMS_REPORT_YES) {
6157 pMsg->mmsAttrib.bAskReadReply = true;
6160 /* TODO : fill pMsg->mmsAttrib.szCc and pMsg->mmsAttrib.szTo field */
6162 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
6164 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
6166 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
6168 /* FIXME:: mmsHeader will release after delete global mmsHeader */
6169 /* memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody)); */ /* After copy to MmsMsg */
6171 if (pMsg->msgBody.pPresentationBody) {
6172 if (MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
6175 pMsg->msgBody.pPresentationBody->body.pText = (char *)calloc(1, pMsg->msgBody.pPresentationBody->size + 1);
6176 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
6179 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
6182 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
6188 MsgCloseFile(pFile);
6191 pMsg->nPartCount = 0;
6193 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
6194 pMultipart = pMsg->msgBody.body.pMultipart;
6195 while (pMultipart) {
6197 pMultipart = pMultipart->pNext;
6200 if (pMsg->msgBody.size > 0)
6204 /* make temporary */
6205 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, "%s%s.dir", MSG_DATA_PATH, pMsg->szFileName);
6207 if (MsgIsMultipart(pMsg->msgType.type) == true) {
6209 pMultipart = pMsg->msgBody.body.pMultipart;
6211 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6212 if (errno == EEXIST) {
6213 MSG_SEC_DEBUG("exist dir : [%s]", szTempMediaDir);
6215 MSG_SEC_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6219 MSG_SEC_DEBUG("make dir : [%s]", szTempMediaDir);
6222 if (pMsg->msgBody.pPresentationBody) {
6223 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
6224 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6228 while (pMultipart) {
6230 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
6231 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, true) == false)
6234 MmsPrintMulitpart(pMultipart, partIndex);
6236 pMultipart = pMultipart->pNext;
6240 } else { /* single part */
6241 if (pMsg->nPartCount > 0) {
6243 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
6244 if (errno == EEXIST) {
6245 MSG_DEBUG("exist dir : [%s]", szTempMediaDir);
6247 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
6251 MSG_DEBUG("make dir : [%s]", szTempMediaDir);
6254 if (__MmsMultipartSaveAsTempFile(&pMsg->msgType, &pMsg->msgBody,
6255 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, true) == false)
6259 MSG_DEBUG("### Success ###");
6266 MmsUnregisterDecodeBuffer();
6268 if (pFile != NULL) {
6269 MsgCloseFile(pFile);
6274 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
6276 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
6278 MSG_DEBUG("### Fail ###");
6284 /* CID 41989: Removed function decodeMmsPdu which is unused. */
6286 void MmsPluginDecoder::decodeMmsPdu(MMS_DATA_S *pMmsData, const char *pduFilePath)
6291 MsgMultipart * iter_multipart = NULL;
6293 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
6297 //pMsg->msgID = msgID;
6299 snprintf(szFullPath, sizeof(szFullPath), "%s", pduFilePath);
6301 //MsgGetFileName(szFullPath, pMsg->szFileName, sizeof(pMsg->szFileName));
6303 if (MsgGetFileSize(szFullPath, &nSize) == false) {
6304 MSG_FATAL("Fail MsgGetFileSize");
6308 pFile = MsgOpenFile(szFullPath, "rb");
6309 if (pFile == NULL) {
6310 MSG_SEC_DEBUG("Fail MsgOpenFile [%s]", szFullPath);
6314 MmsRegisterDecodeBuffer();
6316 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
6317 MSG_FATAL("Fail to MmsBinaryDecodeMsgHeader");
6321 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
6322 MSG_FATAL("Fail to MmsBinaryDecodeMsgBody");
6327 if (pMmsData->header == NULL) {
6328 pMmsData->header = MsgMmsCreateHeader();
6331 pMmsData->header->messageType = mmsHeader.type;
6333 pMmsData->header->mmsVersion = mmsHeader.version;
6335 pMmsData->header->contentType = mmsHeader.msgType.type;
6337 pMmsData->header->date = mmsHeader.date;
6339 pMmsData->header->messageSize = mmsHeader.msgSize;
6341 pMmsData->header->mmsPriority = mmsHeader.priority;
6343 pMmsData->header->messageClass = mmsHeader.msgClass;
6345 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
6346 pMmsData->header->bDeliveryReport = true;
6349 if (mmsHeader.readReply == MMS_REPORT_YES) {
6350 pMmsData->header->bReadReport = true;
6353 memcpy(&pMmsData->header->delivery, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
6355 memcpy(&pMmsData->header->expiry, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
6358 snprintf(pMmsData->header->messageID, sizeof(pMmsData->header->messageID), "%s", mmsHeader.szMsgID);
6360 snprintf(pMmsData->header->szSubject, sizeof(pMmsData->header->szSubject), "%s", mmsHeader.szSubject);
6362 snprintf(pMmsData->header->trID, sizeof(pMmsData->header->trID), "%s", mmsHeader.szTrID);
6364 //CID 41989: Moving assignment of iter_multipart before its de-referencing.
6365 iter_multipart = mmsHeader.msgBody.body.pMultipart;
6367 if (pMmsData->header->contentType == MIME_MULTIPART_RELATED || pMmsData->header->contentType == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
6369 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6371 pMultipart->type = MIME_APPLICATION_SMIL;
6372 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s", "application/smil");
6373 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", mmsHeader.msgBody.presentationType.szContentID);
6374 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", mmsHeader.msgBody.presentationType.szContentLocation);
6375 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", mmsHeader.msgBody.presentationType.param.szName);
6377 //snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), MSG_DATA_PATH"%s", mmsHeader.msgBody.presentationType.param.szFileName);
6379 MsgBody *pBody = iter_multipart->pBody;
6380 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6382 pMmsData->smil = pMultipart;
6386 while (iter_multipart) {
6388 MMS_MULTIPART_DATA_S *pMultipart = MsgMmsCreateMultipart();
6390 pMultipart->type = (MimeType)iter_multipart->type.type;
6392 snprintf(pMultipart->szContentType, sizeof(pMultipart->szContentType), "%s",MimeGetMimeStringFromMimeInt(iter_multipart->type.type));
6393 snprintf(pMultipart->szContentID, sizeof(pMultipart->szContentID), "%s", iter_multipart->type.szContentID);
6394 snprintf(pMultipart->szContentLocation, sizeof(pMultipart->szContentLocation), "%s", iter_multipart->type.szContentLocation);
6395 snprintf(pMultipart->szFileName, sizeof(pMultipart->szFileName), "%s", iter_multipart->type.param.szName);
6397 //snprintf(pMultipart->szFilePath, sizeof(pMultipart->szFilePath), "%s", iter_multipart->pBody->szOrgFilePath);
6399 MsgBody *pBody = iter_multipart->pBody;
6400 pMultipart->pMultipartData = MsgOpenAndReadMmsFile(pBody->szOrgFilePath, pBody->offset, pBody->size, (int*)&pMultipart->nMultipartDataLen);
6403 #ifdef __SUPPORT_DRM__
6404 if (iter_multipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
6405 pMultipart->drmType = iter_multipart->type.drmInfo.drmType;
6409 pMmsData->multipartlist = g_list_append(pMmsData->multipartlist, pMultipart);
6410 iter_multipart = iter_multipart->pNext;
6414 MSG_DEBUG("### SUCCESS ###");
6420 MmsUnregisterDecodeBuffer();
6422 if (pFile != NULL) {
6423 MsgCloseFile(pFile);
6427 MSG_DEBUG("### Fail ###");