2 * Copyright 2012-2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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://floralicense.org
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include "MsgUtilFile.h"
25 #include "MmsPluginDebug.h"
26 #include "MmsPluginDecode.h"
27 #include "MmsPluginCodecCommon.h"
28 #include "MmsPluginStorage.h"
29 #include "MmsPluginDebug.h"
30 #include "MmsPluginMIME.h"
31 #include "MmsPluginAvCodec.h"
32 #include "MmsPluginSmil.h"
33 #include "MmsPluginTextConvert.h"
34 #include "MmsPluginUtil.h"
36 #ifdef __SUPPORT_DRM__
37 #include "MmsPluginDrm.h"
38 #include "MsgDrmWrapper.h"
43 static int __MmsGetDecodeOffset(void);
44 static bool __MmsDecodeInitialize(void);
45 static void __MmsCleanDecodeBuff(void);
46 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength);
47 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength);
49 static bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength); /* bufLen < gMmsDecodeMaxLen */
50 static bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength); /* no bufLen limit */
51 static bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength);
53 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength);
55 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength);
56 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength);
57 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength);
58 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength);
59 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength);
60 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength);
61 static char *__MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength);
62 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
63 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
65 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength);
66 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength);
67 static MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength);
69 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
70 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
71 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength);
72 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength);
73 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength);
74 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength);
76 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength);
78 #ifdef __SUPPORT_DRM__
79 static bool __MmsBinaryDecodeDRMContent(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int bodyLength, int totalLength);
83 static void __MsgRemoveFilePath(char *pSrc);
84 static bool __MsgChangeSpace(char *pOrg, char **ppNew);
85 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo);
86 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam);
87 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *npRead, int endOfFile);
88 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr);
89 static bool __MsgCheckFileNameHasInvalidChar(char *szName);
91 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar);
92 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter);
93 static bool __MsgParseParameter(MsgType *pType, char *pSrc);
94 static char *__MsgSkipWS(char *s);
95 static char *__MsgSkipComment(char *s, long trim);
96 static MsgMultipart *__MsgAllocMultipart(void);
98 static char *__MsgConvertLatin2UTF8FileName(char *pSrc);
99 static bool __MsgIsUTF8String(unsigned char *szSrc, int nChar);
100 static bool __MsgIsPercentSign(char *pSrc);
101 static bool __MsgIsMultipartRelated(int type);
102 static bool __MsgIsPresentablePart(int type);
103 static bool __MsgIsText(int type);
104 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody);
105 static bool __MsgIsHexChar(char *pSrc);
106 static char __MsgConvertHexValue(char *pSrc);
107 static int __MsgConvertCharToInt(char ch);
108 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2);
109 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2);
110 static bool __MsgIsMultipartMixed(int type);
112 static bool __MsgIsInvalidFileNameChar(char ch);
114 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar);
115 static int __MsgLatin5code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
116 static int __MsgGetLatin52UTFCodeSize(unsigned char *szSrc, int nChar);
117 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
118 static int __MsgLatin7code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
119 static int __MsgGetLatin72UTFCodeSize(unsigned char *szSrc, int nChar);
120 static int __MsgUnicode2UTF(unsigned char *des, int outBufSize, unsigned short *szSrc, int nChar);
121 static int __MsgGetUnicode2UTFCodeSize(unsigned short *szSrc, int nChar);
122 static bool __MmsAddrUtilCheckEmailAddress(char *pszAddr);
123 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
124 static void __MsgMIMERemoveQuote(char *szSrc);
125 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave);
127 static bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE *pFile);
128 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead);
130 #ifndef __SUPPORT_DRM__
131 static bool __MsgMakeFileName(int iMsgType, char *szFileName, int nUntitleIndex);
133 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex);
136 static bool __MmsDebugPrintMulitpartEntry(MsgMultipart *pMultipart, int index);
138 static char gszMmsLoadBuf1[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
139 static char gszMmsLoadBuf2[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
141 static char *gpCurMmsDecodeBuff = NULL;
142 static int gCurMmsDecodeBuffPos = 0; /* next decoding position in gpCurMmsDecodeBuff */
143 static int gMmsDecodeMaxLen = 0;
144 static int gMmsDecodeCurOffset = 0; /* current offset in file (last read) */
145 static int gMmsDecodeBufLen = 0; /* number of last read characters */
147 static char *gpMmsDecodeBuf1 = NULL;
148 static char *gpMmsDecodeBuf2 = NULL;
150 MmsHeader mmsHeader =
156 (MmsMsgType)MMS_MSGTYPE_ERROR, //MmsMsgType iType;
158 //"", //short int version;
159 0, //short int version;
162 NULL, //MsgHeaderAddress* pFrom;
163 NULL, //MsgHeaderAddress* pTo;
164 NULL, //MsgHeaderAddress* pCc;
165 NULL, //MsgHeaderAddress* pBcc;
166 "", //char[] szSubject;
167 (MmsResponseStatus)MMS_RESPSTATUS_OK, //MmsResponseStatus iResponseStatus;
168 (MmsRetrieveStatus)MMS_RETRSTATUS_OK, //MmsRetrieveStatus iRetrieveStatus;
169 "", //char[] szResponseText;
170 "", //char[] szRetrieveText;
173 /* has default value in specification */
175 (MmsMsgClass)MMS_MSGCLASS_PERSONAL, //MmsMsgClass msgClass;
176 {MMS_TIMETYPE_RELATIVE, 0}, //MmsTimeStruct expiryTime;
177 {MMS_TIMETYPE_RELATIVE, 0}, //MmsTimeStruct deliveryTime;
178 (MmsPriority)MMS_PRIORITY_NORMAL, //MmsPriority priority; // Refer [OMA-MMS-ENC-v1_2-20030915-C]
179 (MmsSenderVisible)MMS_SENDER_SHOW, //MmsSenderVisible senderVisible;
180 (MmsReport)MMS_REPORT_NO, //MmsReport deliveryReport;
181 (MmsReport)MMS_REPORT_NO, //MmsReport readReply;
182 (MmsReportAllowed)MMS_REPORTALLOWED_NO,//MmsReportAllowed iReportAllowed;
183 "", //char[] szContentLocation;
186 /* there is no right default value */
188 (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE, //MmsMsgStatus iMsgStatus;
189 (msg_read_report_status_t)MSG_READ_REPORT_NONE, //MmsReadStatus readStatus;
191 /* MMS v1.1 ReplyCharge */
193 (MmsReplyChargeType)MMS_REPLY_NONE, //MmsReplyChargeType chargeType;
194 {MMS_TIMETYPE_RELATIVE, 0}, //MmsTimeStruct deadLine;
196 "" , //char szChargeID;
199 "", //char[] szMsgID;
203 #ifdef __SUPPORT_DRM__
205 #define MMS_DRM2_CONVERT_BUFFER_MAX 4*1024
206 const UINT32 MMS_UINTVAR_LENGTH_1 = 0x0000007f; //7bit
207 const UINT32 MMS_UINTVAR_LENGTH_2 = 0x00003fff; //14bit
208 const UINT32 MMS_UINTVAR_LENGTH_3 = 0x001fffff; //21bit
211 static bool __MmsDecodeInitialize(void)
213 MmsInitMsgType(&mmsHeader.msgType);
214 MmsInitMsgBody(&mmsHeader.msgBody);
220 mmsHeader.type = MMS_MSGTYPE_ERROR;
222 memset(mmsHeader.szTrID, 0, MMS_TR_ID_LEN + 1);
223 mmsHeader.version = MMS_VERSION;
226 __MsgFreeHeaderAddress(mmsHeader.pFrom);
227 __MsgFreeHeaderAddress(mmsHeader.pTo);
228 __MsgFreeHeaderAddress(mmsHeader.pCc);
229 __MsgFreeHeaderAddress(mmsHeader.pBcc);
231 mmsHeader.pFrom = NULL;
232 mmsHeader.pTo = NULL;
233 mmsHeader.pCc = NULL;
234 mmsHeader.pBcc = NULL;
236 memset(mmsHeader.szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
238 mmsHeader.responseStatus = (MmsResponseStatus)MMS_RESPSTATUS_OK;
239 mmsHeader.retrieveStatus = (MmsRetrieveStatus)MMS_RETRSTATUS_OK;
240 memset(mmsHeader.szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
241 memset(mmsHeader.szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
244 mmsHeader.msgClass = (MmsMsgClass)MMS_MSGCLASS_PERSONAL;
245 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
246 mmsHeader.expiryTime.time = 0;
247 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
248 mmsHeader.deliveryTime.time = 0;
249 mmsHeader.priority = (MmsPriority)MMS_PRIORITY_NORMAL; // Refer [OMA-MMS-ENC-v1_2-20030915-C]
250 mmsHeader.hideAddress =(MmsSenderVisible)MMS_SENDER_SHOW;
251 mmsHeader.deliveryReport = (MmsReport)MMS_REPORT_NO;
252 mmsHeader.readReply = (MmsReport)MMS_REPORT_NO;
253 mmsHeader.reportAllowed = (MmsReportAllowed)MMS_REPORTALLOWED_YES;
254 memset(mmsHeader.szContentLocation, 0, MMS_LOCATION_LEN + 1);
257 mmsHeader.msgStatus = (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE;
258 mmsHeader.readStatus = (msg_read_report_status_t)MSG_READ_REPORT_NONE;
260 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MMS_REPLY_NONE;
261 mmsHeader.replyCharge.chargeSize = 0;
262 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
263 mmsHeader.replyCharge.deadLine.time = 0;
264 memset(mmsHeader.replyCharge.szChargeID, 0, MMS_MSG_ID_LEN + 1);
267 memset(mmsHeader.szMsgID, 0, MMS_MSG_ID_LEN + 1);
268 mmsHeader.msgSize = 0;
269 #ifdef __SUPPORT_DRM__
270 mmsHeader.drmType = MSG_DRM_TYPE_NONE;
273 __MmsDecodeInitialize();
276 void MmsReleaseHeader(MmsHeader *mms)
278 __MsgFreeHeaderAddress(mms->pFrom);
279 __MsgFreeHeaderAddress(mms->pTo);
280 __MsgFreeHeaderAddress(mms->pCc);
281 __MsgFreeHeaderAddress(mms->pBcc);
283 mmsHeader.pFrom = NULL;
284 mmsHeader.pTo = NULL;
285 mmsHeader.pCc = NULL;
286 mmsHeader.pBcc = NULL;
290 static void __MmsCleanDecodeBuff(void)
292 memset(gpMmsDecodeBuf1, 0, gMmsDecodeMaxLen + 1);
293 memset(gpMmsDecodeBuf2, 0, gMmsDecodeMaxLen + 1);
294 gpCurMmsDecodeBuff = NULL;
295 gCurMmsDecodeBuffPos = 0;
296 gMmsDecodeBufLen = 0;
299 void MmsRegisterDecodeBuffer()
301 gpMmsDecodeBuf1 = gszMmsLoadBuf1;
302 gpMmsDecodeBuf2 = gszMmsLoadBuf2;
303 gpCurMmsDecodeBuff = NULL;
304 gCurMmsDecodeBuffPos = 0;
305 gMmsDecodeMaxLen = MSG_MMS_DECODE_BUFFER_MAX;
306 gMmsDecodeCurOffset = 0;
307 gMmsDecodeBufLen = 0;
310 void MmsUnregisterDecodeBuffer(void)
312 gpMmsDecodeBuf1 = NULL;
313 gpMmsDecodeBuf2 = NULL;
314 gpCurMmsDecodeBuff = NULL;
315 gCurMmsDecodeBuffPos = 0;
316 gMmsDecodeMaxLen = 0;
317 gMmsDecodeCurOffset = 0;
318 gMmsDecodeBufLen = 0;
322 static int __MmsGetDecodeOffset(void)
324 return (gMmsDecodeCurOffset - gMmsDecodeBufLen + gCurMmsDecodeBuffPos);
327 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength)
329 if (*pLength <= valueLength) {
330 gCurMmsDecodeBuffPos -= valueLength;
331 gCurMmsDecodeBuffPos += *pLength;
335 *pLength -= valueLength;
341 /* ==========================================================
343 B I N A R Y D E C O D I N G
345 ==========================================================*/
348 * Binary Encoded Message Format
350 * < Single Part Body Message >
351 * -----------------------------------
353 * -----------------------------------
354 * | Content Type:start=xxx;type=xxx | ->(ex) Text/Plain, Text/Html, ....
355 * -----------------------------------
356 * | Single Part Body |
357 * -----------------------------------
359 * < Multi Part Body Message >
360 * -----------------------------------
362 * -----------------------------------
363 * | Content Type:start=xxx;type=xxx | -> (ex) Application/vnd.wap.multipart.mixed(related), multipart/mixed(related)
364 * -----------------------------------
365 * | # of Entries (body parts) |
366 * ----------------------------------- < Each Entry >
367 * | Entry 1 | -> -----------------------------
368 * ----------------------------------- | header Length |
369 * | Entry 2 | -----------------------------
370 * ----------------------------------- | Data Length |
371 * | ...... | ----------------------------- -
372 * ----------------------------------- | Content-Type | |
373 * | Entry n | ----------------------------- | Header Length
374 * ----------------------------------- | Header | |
375 * ----------------------------- -
376 * | Data | | Data Length
377 * ----------------------------- -
379 bool MmsBinaryDecodeMsgHeader(FILE *pFile, int totalLength)
381 UINT16 fieldCode = 0xffff;
382 UINT16 fieldValue = 0xffff;
383 UINT8 oneByte = 0xff;
385 MsgHeaderAddress *pAddr = NULL;
386 MsgHeaderAddress *pLastTo = NULL;
387 MsgHeaderAddress *pLastCc = NULL;
388 MsgHeaderAddress *pLastBcc = NULL;
390 UINT32 valueLength = 0;
391 UINT32 tmpInteger = 0;
396 char szGarbageBuff[MSG_STDSTR_LONG] = {0, };
397 char *pLimitData = NULL;
400 MSG_DEBUG("pFile=%d, total len=%d\n", pFile, totalLength);
402 __MmsCleanDecodeBuff();
404 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
405 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
406 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
407 MSG_DEBUG("fail to load to buffer \n");
411 while (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength)) {
412 fieldCode = oneByte & 0x7f;
414 switch (MmsGetBinaryType(MmsCodeFieldCode, fieldCode)) {
415 case MMS_CODE_RESPONSESTATUS:
417 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
418 MSG_DEBUG("responseStatus GetOneByte fail\n");
422 // range 197 to 223 as it does to the value 192 (Error-transient-failure).
423 // range 236 to 255 as it does to the value 224 (Error-permanent-failure).
424 if (fieldValue >= 0x0045 && fieldValue <= 0x005F) {
426 } else if (fieldValue >= 0x006A && fieldValue <= 0x007F) {
430 MSG_DEBUG("response status code = 0x%02x", oneByte);
432 fieldValue = MmsGetBinaryType(MmsCodeResponseStatus, (UINT16)(oneByte & 0x7F));
434 if (fieldValue == 0xFFFF) {
435 MSG_DEBUG("responseStatus error\n");
439 mmsHeader.responseStatus = (MmsResponseStatus)fieldValue;
441 MSG_DEBUG("response status text = %s\n", MmsDebugGetResponseStatus(mmsHeader.responseStatus));
445 case MMS_CODE_RETRIEVESTATUS:
447 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
448 MSG_DEBUG("retrieveStatus GetOneByte fail\n");
452 MSG_DEBUG("retrieve status code = 0x%02x", oneByte);
454 fieldValue = MmsGetBinaryType(MmsCodeRetrieveStatus, (UINT16)(oneByte & 0x7F));
456 if (fieldValue == 0xFFFF) {
457 MSG_DEBUG("retrieveStatus error\n");
461 if (fieldValue >= 0x0043 && fieldValue <= 0x005F) {
462 fieldValue = 0x0040; // 192; Error-transient-failure
463 } else if (fieldValue >= 0x0064 && fieldValue <= 0x007F) {
464 fieldValue = 0x0060; //224; Error-permanent-failure
467 mmsHeader.retrieveStatus = (MmsRetrieveStatus)fieldValue;
469 MSG_DEBUG("retrieve status = %s\n", MmsDebugGetRetrieveStatus(mmsHeader.retrieveStatus));
473 case MMS_CODE_RESPONSETEXT:
475 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szResponseText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
476 MSG_DEBUG("invalid MMS_CODE_RESPONSETEXT \n");
480 MSG_DEBUG("response text = %s\n", mmsHeader.szResponseText);
483 case MMS_CODE_RETRIEVETEXT:
485 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szRetrieveText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
486 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT \n");
490 MSG_DEBUG("retrieve text = %s\n", mmsHeader.szRetrieveText);
495 if (__MmsBinaryDecodeText(pFile, mmsHeader.szMsgID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
496 MSG_DEBUG("MMS_CODE_MSGID is invalid\n");
500 MSG_DEBUG("msg id = %s\n", mmsHeader.szMsgID);
502 if (MsgStrlen (mmsHeader.szMsgID) > 2)
503 __MsgMIMERemoveQuote (mmsHeader.szMsgID);
507 case MMS_CODE_SUBJECT:
509 if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN + 1, totalLength) == false) {
510 MSG_DEBUG("invalid MMS_CODE_SUBJECT \n");
514 pLimitData = (char *)malloc(MSG_LOCALE_SUBJ_LEN + 1);
516 if (pLimitData == NULL) {
517 MSG_DEBUG("pLimitData malloc fail \n");
521 nRead = __MsgCutUTFString((unsigned char*)pLimitData, MSG_LOCALE_SUBJ_LEN + 1, (unsigned char*)mmsHeader.szSubject, MSG_SUBJ_LEN);
522 MSG_DEBUG("Subject edit.. \n");
524 if (nRead > MSG_LOCALE_SUBJ_LEN) {
525 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
526 strncpy(mmsHeader.szSubject, pLimitData, MSG_SUBJ_LEN);
528 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
529 strncpy(mmsHeader.szSubject, pLimitData, MSG_LOCALE_SUBJ_LEN);
537 MSG_DEBUG("subject = %s\n", mmsHeader.szSubject);
542 /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
544 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
545 MSG_DEBUG("MMS_CODE_FROM is invalid\n");
549 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
550 MSG_DEBUG("MMS_CODE_FROM GetOneByte fail\n");
554 // DRM_TEMPLATE - start
558 if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
559 if (valueLength > 0) {
560 mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
561 if (mmsHeader.pFrom == NULL) {
562 MSG_DEBUG("MMS_CODE_FROM __MmsDecodeEncodedAddress fail\n");
566 mmsHeader.pFrom = (MsgHeaderAddress *)malloc(sizeof(MsgHeaderAddress));
567 if (mmsHeader.pFrom == NULL)
570 mmsHeader.pFrom->szAddr = (char *)malloc(1);
571 if (mmsHeader.pFrom->szAddr == NULL) {
572 free(mmsHeader.pFrom);
573 mmsHeader.pFrom = NULL;
577 mmsHeader.pFrom->szAddr[0] = '\0';
578 mmsHeader.pFrom->pNext = NULL;
581 MSG_DEBUG("from = %s\n", mmsHeader.pFrom->szAddr);
582 // DRM_TEMPLATE - end
583 } else if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
584 /* Present Token only */
585 MSG_DEBUG("MMS_CODE_FROM insert token\n");
587 /* from data broken */
588 MSG_DEBUG("from addr broken\n");
589 gCurMmsDecodeBuffPos--;
596 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
598 MSG_DEBUG("MMS_CODE_TO __MmsDecodeEncodedAddress fail\n");
602 if (mmsHeader.pTo == NULL) {
604 pLastTo = mmsHeader.pTo = pAddr;
607 pLastTo->pNext = pAddr;
611 MSG_DEBUG("to = %s\n", mmsHeader.pTo->szAddr);
616 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
618 MSG_DEBUG("MMS_CODE_BCC __MmsDecodeEncodedAddress fail\n");
622 if (mmsHeader.pBcc == NULL) {
624 pLastBcc = mmsHeader.pBcc = pAddr;
627 pLastBcc->pNext = pAddr;
631 MSG_DEBUG("bcc = %s\n", mmsHeader.pBcc->szAddr);
636 pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
638 MSG_DEBUG("MMS_CODE_CC __MmsDecodeEncodedAddress fail\n");
642 if (mmsHeader.pCc == NULL) {
644 pLastCc = mmsHeader.pCc = pAddr;
647 pLastCc->pNext = pAddr;
650 MSG_DEBUG("cc = %s\n", mmsHeader.pCc->szAddr);
653 case MMS_CODE_CONTENTLOCATION:
655 if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
656 MSG_DEBUG("MMS_CODE_CONTENTLOCATION is invalid\n");
659 MSG_DEBUG("content location = %s\n", mmsHeader.szContentLocation);
664 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
665 MSG_DEBUG("MMS_CODE_DATE is invalid\n");
668 MSG_DEBUG("date = %d\n", mmsHeader.date);
671 case MMS_CODE_DELIVERYREPORT:
673 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
674 MSG_DEBUG("deliveryReport GetOneByte fail\n");
678 fieldValue = MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
680 if (fieldValue == 0xFFFF) {
681 MSG_DEBUG("deliveryReport error\n");
685 mmsHeader.deliveryReport = (MmsReport)fieldValue;
687 MSG_DEBUG("delivery report=%s\n", MmsDebugGetMmsReport(mmsHeader.deliveryReport));
690 case MMS_CODE_DELIVERYTIME:
692 /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
694 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
695 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME \n");
699 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
700 MSG_DEBUG("delivery time GetOneByte fail\n");
704 //DRM_TEMPLATE - start
707 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
708 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
710 if (valueLength > 0) {
711 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
712 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME\n");
716 // DRM_TEMPLATE - end
718 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
720 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
721 MSG_DEBUG("__MmsBinaryDecodeInteger fail...\n");
725 MSG_DEBUG("delivery type=%d, time=%d\n", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
728 case MMS_CODE_EXPIRYTIME:
730 /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
732 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
733 MSG_DEBUG("invalid MMS_CODE_EXPIRYTIME \n");
737 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
738 MSG_DEBUG("expiry time GetOneByte fail\n");
742 // DRM_TEMPLATE - start
745 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
746 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
748 if (valueLength > 0) {
749 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
750 MSG_DEBUG("MMS_CODE_EXPIRYTIME is invalid\n");
754 // DRM_TEMPLATE - end
756 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
758 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
759 MSG_DEBUG("__MmsBinaryDecodeInteger fail...\n");
763 MSG_DEBUG("expiry = %d\n", mmsHeader.expiryTime.time);
766 case MMS_CODE_MSGCLASS:
768 /* Class-value = Class-identifier | Token Text */
770 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
771 MSG_DEBUG("msgClass GetOneByte fail\n");
775 if (oneByte > 0x7f) {
776 /* Class-identifier */
777 mmsHeader.msgClass = (MmsMsgClass)MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
779 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
780 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (class)\n");
784 MSG_DEBUG("msg class=%s\n", MmsDebugGetMsgClass(mmsHeader.msgClass));
787 case MMS_CODE_MSGSIZE:
789 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
790 MSG_DEBUG("MMS_CODE_MSGSIZE is invalid\n");
793 MSG_DEBUG("msg size = %d\n", mmsHeader.msgSize);
796 case MMS_CODE_MSGSTATUS:
798 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
799 MSG_DEBUG("msgStatus GetOneByte fail\n");
803 mmsHeader.msgStatus = (msg_delivery_report_status_t)MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
804 MSG_DEBUG("msg status=%s \n", MmsDebugGetMsgStatus(mmsHeader.msgStatus)) ;
807 case MMS_CODE_MSGTYPE:
809 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
810 MSG_DEBUG("msgStatus GetOneByte fail\n");
814 mmsHeader.type = (MmsMsgType)MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
815 MSG_DEBUG("msg type=%s\n", MmsDebugGetMsgType(mmsHeader.type));
818 case MMS_CODE_PRIORITY:
820 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
821 MSG_DEBUG("msgStatus GetOneByte fail\n");
824 mmsHeader.priority = (MmsPriority)MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
825 MSG_DEBUG("priority=%d\n", mmsHeader.priority);
828 case MMS_CODE_READREPLY:
830 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
831 MSG_DEBUG("msgStatus GetOneByte fail\n");
834 mmsHeader.readReply = (MmsReport)MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
835 MSG_DEBUG("read reply=%s \n", MmsDebugGetMmsReport(mmsHeader.readReply));
838 case MMS_CODE_REPORTALLOWED:
840 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
841 MSG_DEBUG("msgStatus GetOneByte fail\n");
844 mmsHeader.reportAllowed = (MmsReportAllowed)MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
845 MSG_DEBUG("mmsHeader.reportAllowed=%d\n", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
848 case MMS_CODE_SENDERVISIBILLITY:
850 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
851 MSG_DEBUG("msgStatus GetOneByte fail\n");
854 mmsHeader.hideAddress= (MmsSenderVisible)!(MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
855 MSG_DEBUG("sender visible=%d \n", mmsHeader.hideAddress);
860 if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
861 MSG_DEBUG("Transaction ID Too Long \n");
864 MSG_DEBUG("trID = %s\n", mmsHeader.szTrID);
867 case MMS_CODE_VERSION:
868 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
869 MSG_DEBUG("msgStatus GetOneByte fail\n");
872 mmsHeader.version = oneByte;
874 MSG_DEBUG("ver = 0x%x\n", mmsHeader.version);
877 case MMS_CODE_CONTENTTYPE:
880 * Content-type is the last header field of SendRequest and RetrieveConf.
881 * It's required to decrease pointer by one and return,
882 * to parse this field in MmsBinaryDecodeContentType().
887 /* ----------- Add by MMSENC v1.1 ----------- */
889 case MMS_CODE_READSTATUS:
891 /* Read-status-value = Read | Deleted without being read */
893 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
894 MSG_DEBUG("msgStatus GetOneByte fail\n");
898 mmsHeader.readStatus = (msg_read_report_status_t)MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
899 MSG_DEBUG("read status=%s\n", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
902 case MMS_CODE_REPLYCHARGING:
904 /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
906 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
907 MSG_DEBUG("msgStatus GetOneByte fail\n");
911 mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
912 MSG_DEBUG("mmsHeader.reply charge=%d\n", mmsHeader.replyCharge.chargeType);
915 case MMS_CODE_REPLYCHARGINGDEADLINE:
917 /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
919 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
920 MSG_DEBUG("invalid MMS_CODE_REPLYCHARGINGDEADLINE \n");
924 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
925 MSG_DEBUG("msgStatus GetOneByte fail\n");
929 if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
930 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
932 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
935 // DRM_TEMPLATE - start
938 if (valueLength > 0) {
939 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
940 MSG_DEBUG("MMS_CODE_REPLYCHARGINGDEADLINE is invalid\n");
944 // DRM_TEMPLATE - end
947 case MMS_CODE_REPLYCHARGINGID:
949 /* Reply-charging-ID-value = Text-string */
951 if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
952 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (szReplyChargingID)\n");
957 case MMS_CODE_REPLYCHARGINGSIZE:
959 /* Reply-charging-size-value = Long-integer */
961 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
962 MSG_DEBUG("MMS_CODE_REPLYCHARGINGSIZE is invalid\n");
967 case MMS_CODE_PREVIOUSLYSENTBY:
970 * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
971 * Forwarded-count-value = Integer-value
972 * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
976 * fixme: There is no proper field to store this information.
977 * Just increase pointer now.
980 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
981 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTBY \n");
985 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
986 MSG_DEBUG("2. invalid MMS_CODE_PREVIOUSLYSENTBY \n");
990 if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
991 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT \n");
996 case MMS_CODE_PREVIOUSLYSENTDATE:
999 * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
1000 * Forwarded-count-value = Integer-value
1001 * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
1005 * fixme: There is no proper field to store this information.
1006 * Just increase pointer now.
1009 if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
1010 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
1014 if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
1015 MSG_DEBUG("2. invalid MS_CODE_PREVIOUSLYSENTDATE \n");
1019 if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
1020 MSG_DEBUG("3. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
1028 * Application-header = Token-text Application-specific-value
1029 * Token-text = Token End-of-string
1030 * Application-specific-value = Text -string
1032 * OR unknown header field - Just ignore these fields.
1034 * Read one byte and check the value >= 0x80
1035 * (check these value can be field code)
1038 int remainLength = 0;
1042 offset = __MmsGetDecodeOffset();
1043 if (offset >= totalLength)
1046 remainLength = totalLength - offset;
1048 while ((oneByte < 0x80) && (remainLength > 0)) {
1049 if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1050 MSG_DEBUG("__MmsBinaryDecodeCheckAndDecreaseLength fail\n");
1053 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1054 MSG_DEBUG("responseStatus GetOneByte fail\n");
1059 gCurMmsDecodeBuffPos--;
1065 offset = __MmsGetDecodeOffset();
1066 if (offset >= totalLength)
1074 if (mmsHeader.pTo == NULL && pLastTo) {
1078 if (mmsHeader.pCc == NULL && pLastCc) {
1082 if (mmsHeader.pBcc == NULL && pLastBcc) {
1086 MSG_DEBUG("success\n");
1092 if (mmsHeader.pTo == NULL && pLastTo) {
1096 if (mmsHeader.pCc == NULL && pLastCc) {
1100 if (mmsHeader.pBcc == NULL && pLastBcc) {
1104 MSG_DEBUG("failed\n");
1109 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1116 if (szFilePath != NULL)
1117 strncpy(mmsHeader.msgType.szOrgFilePath, szFilePath , strlen(szFilePath));
1119 mmsHeader.msgType.offset = __MmsGetDecodeOffset() - 1; // + Content-Type code value
1121 // read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding
1122 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1123 &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1124 gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1125 MSG_DEBUG("fail to load to buffer \n");
1129 // msg's type [ex] related, mixed, single part (jpg, amr and etc)
1130 length = __MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1132 MSG_DEBUG("MMS_CODE_CONTENTTYPE is fail\n");
1136 mmsHeader.msgType.size = length + 1; // + Content-Type code value
1137 mmsHeader.msgBody.offset = __MmsGetDecodeOffset();
1139 switch (mmsHeader.msgType.type) {
1140 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1141 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1142 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1143 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1144 case MIME_MULTIPART_REPORT:
1145 case MIME_MULTIPART_MIXED:
1146 case MIME_MULTIPART_RELATED:
1147 case MIME_MULTIPART_ALTERNATIVE:
1148 case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1149 case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1151 MSG_DEBUG("Decode multipart\n");
1153 offset = __MmsGetDecodeOffset();
1154 if (offset >= totalLength)
1157 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1158 MSG_DEBUG("MmsBinaryDecodeMultipart is fail.\n");
1165 /* Single part message ---------------------------------------------- */
1166 if (szFilePath != NULL)
1167 strcpy(mmsHeader.msgBody.szOrgFilePath, szFilePath);
1169 offset = __MmsGetDecodeOffset();
1170 if (offset >= totalLength)
1173 if (__MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1174 MSG_DEBUG("MmsBinaryDecodePartBody is fail.(Single Part)\n");
1178 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1179 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1184 #ifdef __SUPPORT_DRM__
1185 mmsHeader.drmType = MsgGetDRMType(&mmsHeader.msgType, &mmsHeader.msgBody);
1196 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1200 char *szTypeString = NULL;
1201 char *szTypeValue = NULL;
1202 UINT8 paramCode = 0xff;
1209 * Parameter = Typed-parameter | Untyped-parameter
1210 * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1215 while (valueLength > 0) {
1216 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1217 MSG_DEBUG("paramCode _MmsBinaryDecodeGetOneByte fail\n");
1221 paramCode = oneByte;
1224 switch (paramCode) {
1225 case 0x81: // charset
1227 if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1228 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsBinaryDecodeCharset fail.\n");
1232 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1237 case 0x85: //name = Text-string
1238 case 0x97: //name = Text-value = No-value | Token-text | Quoted-string
1239 memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1240 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szName,
1241 MSG_FILENAME_LEN_MAX -5, // MSG_LOCALE_FILENAME_LEN_MAX + 1, : change @ 110(Ui code have to change for this instead of DM)
1244 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsDecodeGetFilename fail. (name parameter)\n");
1248 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1249 __MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1252 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1257 case 0x86: //filename = Text-string
1258 case 0x98: //filename = Text-value = No-value | Token-text | Quoted-string
1259 memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1260 length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1262 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsDecodeGetFilename fail. (filename parameter)\n");
1266 if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1267 __MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1270 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1275 case 0x89: //type = Constrained-encoding = Extension-Media | Short-integer
1277 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1278 MSG_DEBUG("type _MmsBinaryDecodeGetOneByte fail\n");
1282 if (oneByte > 0x7f) {
1283 pMsgType->param.type = MmsGetBinaryType(MmsCodeContentType,
1284 (UINT16)(oneByte & 0x7f));
1285 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1288 gCurMmsDecodeBuffPos--;
1291 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1292 pMsgType->param.type = MmsGetTextType(MmsCodeContentType, szTypeString);
1296 szTypeString = NULL;
1299 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1305 case 0x8A: //start encoding version 1.2
1306 case 0x99: //start encoding version 1.4
1309 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1311 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1312 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1314 szTypeString = NULL;
1316 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1322 case 0x8B: //startInfo encoding version 1.2
1323 case 0x9A: //startInfo encoding version 1.4
1326 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1329 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1330 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1333 szTypeString = NULL;
1335 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1343 if (paramCode > 0x7F) {
1344 MSG_DEBUG("Unsupported parameter\n");
1346 // In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value.
1348 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1352 * Untyped Parameter = Token-text Untyped-value
1353 * Token-text = Token End-of-string
1354 * Untyped-value = Integer-value | Text-value
1355 * Text-value = No-value | Token-text | Quoted-string
1357 * Just increase pointer!!!
1363 gCurMmsDecodeBuffPos--;
1367 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1368 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1374 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1375 MSG_DEBUG("Unsupported parameter(%d)\n", integer);
1376 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1380 szTypeValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1383 /* checkMe: forwardLock needs boudary string */
1384 if (strcasecmp(szTypeString, "boundary") == 0) {
1385 memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1386 strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1387 #ifdef FEATURE_JAVA_MMS
1388 } else if (strcasecmp(szTypeString, "Application-ID") == 0) {
1389 pMsgType->param.szApplicationID = (char*) malloc(textLength + 1);
1390 memset(pMsgType->param.szApplicationID, 0, textLength + 1);
1391 strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1392 MSG_DEBUG("Application-ID:%s",pMsgType->param.szApplicationID);
1393 } else if (strcasecmp(szTypeString,"Reply-To-Application-ID") == 0) {
1394 pMsgType->param.szReplyToApplicationID= (char*) malloc(textLength + 1);
1395 memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1396 strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1397 MSG_DEBUG("ReplyToApplication-ID:%s",pMsgType->param.szReplyToApplicationID);
1403 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeValue);
1404 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1410 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeString);
1412 szTypeString = NULL;
1418 } /*end of while loop*/
1425 szTypeString = NULL;
1436 * Decode Encoded Content type
1438 * @param pEncodedData [in] ContentType encoded data
1439 * @param pMsgType [out] Decoded MsgType
1440 * @return Decoded address list
1442 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1445 char *szTypeString = NULL;
1446 int valueLength = 0;
1452 * Content-type-value : [WAPWSP 8.4.2.24]
1453 * Preassigned content-types : [WAPWSP Appendix A, Table 40]
1454 * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1456 * Content-type-value = Constrained-media | Content-general-form
1457 * Content-general-form = Value-length Media-type
1458 * Media-type = (Well-known-media | Extension-Media) *(Parameter)
1461 MSG_DEBUG("decoding content type..\n");
1463 length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1466 * Constrained-media or Single part message
1467 * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1468 * Extension-media = *TEXT End-of-string
1469 * Short-integer = OCTET(1xxx xxxx)
1472 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1473 MSG_DEBUG("Constrained-media _MmsBinaryDecodeGetOneByte fail\n");
1477 if (oneByte > 0x7F) {
1479 pMsgType->type = MmsGetBinaryType(MmsCodeContentType, (UINT16)(oneByte & 0x7F));
1482 char *pszTemp = NULL;
1484 /* Extension-Media */
1485 gCurMmsDecodeBuffPos--;
1488 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1490 if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1491 pszTemp = __MsgGetStringUntilDelimiter(szTypeString, ';');
1494 szTypeString = pszTemp;
1498 pMsgType->type = MmsGetTextType(MmsCodeContentType, szTypeString);
1500 length = textLength;
1504 szTypeString = NULL;
1509 * Content-general-form = Value-length Media-type
1510 * Media-type = (Well-known-media | Extension-Media)*(Parameter)
1513 length += valueLength;
1515 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1516 MSG_DEBUG("Well-known-media _MmsBinaryDecodeGetOneByte fail\n");
1520 if (oneByte > 0x7F) {
1521 /* Well-known-media */
1522 pMsgType->type = MmsGetBinaryType(MmsCodeContentType, (UINT16)(oneByte & 0x7F));
1525 /* Extension-Media */
1526 gCurMmsDecodeBuffPos--;
1529 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1530 pMsgType->type = MmsGetTextType(MmsCodeContentType, szTypeString);
1531 valueLength -= textLength;
1535 szTypeString = NULL;
1539 MSG_DEBUG("content type=%s\n", MmsDebugGetMimeType((MimeType)pMsgType->type));
1542 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1543 MSG_DEBUG("Content-Type parameter fail\n");
1554 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1556 UINT8 fieldCode = 0xff;
1558 UINT32 valueLength = 0;
1560 char *pValue = NULL;
1561 char *pParam = NULL;
1567 char *pLatinBuff = NULL;
1569 char *szTemp = NULL;
1572 if (pFile == NULL || pMsgType == NULL)
1576 * Message-header = Well-known-header | Application-header
1577 * Well-known-header = Well-known-field-name Wap-value
1578 * Application-header = Token-text Application-specific-value
1579 * Well-known-field-name = Short-integer
1580 * Application-specific-value = Text-string
1583 while (headerLen > 0) {
1584 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1585 MSG_DEBUG("field code GetOneByte fail\n");
1589 if (0x80 <= oneByte && oneByte <= 0xC7) {
1590 /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1592 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1595 fieldCode = oneByte & 0x7f;
1597 switch (fieldCode) {
1598 case 0x0E: //Content-Location
1599 case 0x04: //Content-Location
1601 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1602 if (pLatinBuff == NULL)
1605 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1607 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeQuotedString fail.\n");
1611 szSrc = MsgChangeHexString(pLatinBuff);
1614 strcpy(pLatinBuff, szSrc);
1619 textLength = strlen(pLatinBuff);
1621 if (__MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, textLength) < 0) {
1622 MSG_DEBUG("MsgLatin2UTF fail \n");
1629 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1634 case 0x40: // Content-ID
1636 char szContentID[MMS_CONTENT_ID_LEN + 1];
1638 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1639 if (pLatinBuff == NULL)
1642 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1645 MSG_DEBUG("MmsBinaryDecodePartHeader : Content-ID __MmsBinaryDecodeQuotedString fail.\n");
1649 szSrc = MsgChangeHexString(pLatinBuff);
1652 strcpy(pLatinBuff, szSrc);
1657 textLength = strlen(pLatinBuff);
1658 if (__MsgLatin2UTF ((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, textLength) < 0) {
1659 MSG_DEBUG("MsgLatin2UTF fail \n");
1665 removeLessGreaterMark(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID));//remove "< >"
1667 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1672 case 0x2E: // Content-Disposition
1673 case 0x45: // Content-Disposition
1676 * Content-disposition-value = Value-length Disposition *(Parameter)
1677 * Disposition = Form-data | Attachment | Inline | Token-text
1678 * Form-data = <Octet 128> : 0x80
1679 * Attachment = <Octet 129> : 0x81
1680 * Inline = <Octet 130> : 0x82
1683 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1686 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1691 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1692 MSG_DEBUG("Disposition value GetOneByte fail\n");
1699 if (oneByte >= 0x80) {
1700 pMsgType->disposition = MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1702 if (pMsgType->disposition == INVALID_HOBJ) {
1703 MSG_DEBUG("MmsBinaryDecodePartHeader : Content-Disposition MmsGetBinaryType fail.\n");
1704 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT; // default
1707 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1710 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1711 MSG_DEBUG("Disposition parameter fail\n");
1715 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1719 gCurMmsDecodeBuffPos--;
1722 pLatinBuff = (char *)malloc(MSG_FILENAME_LEN_MAX);
1723 memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1725 textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1728 if (textLength < 0) {
1729 MSG_DEBUG("MmsBinaryDecodePartHeader : Content-Disposition decodingfail. \n");
1735 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1738 valueLength -= textLength;
1740 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false)
1742 MSG_DEBUG("Disposition parameter fail\n");
1746 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1753 case 0x0B: //Content-Encoding
1755 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1756 MSG_DEBUG("Disposition value GetOneByte fail\n");
1760 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1765 case 0x0C: //Content-Language
1767 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1768 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1773 cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1775 if (cTemp == NULL) {
1776 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeText2 fail...\n");
1780 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1793 case 0x0D: //Content-Length
1795 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1796 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeInteger fail...\n");
1800 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1805 case 0x30: //X-Wap-Content-URI skip this value
1807 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header.\n");
1808 pLatinBuff = (char *)malloc(MMS_TEXT_LEN);
1809 if (pLatinBuff == NULL)
1812 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1815 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeQuotedString fail.\n");
1819 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header decoded. Value length %d\n", length);
1823 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1826 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header skipped.\n");
1830 case 0x01: // Accept-charset
1831 //if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1)
1833 /* WAP-230-WSP-200010705-a.pdf
1834 8.4.2.8 Accept charset field
1835 The following rules are used to encode accept character set values.
1836 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1837 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1838 Constrained-charset = Any-charset | Constrained-encoding
1839 Well-known-charset = Any-charset | Integer-value
1840 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1841 Any-charset = <Octet 128>
1842 ; Equivalent to the special RFC2616 charset value ��*��
1848 MSG_DEBUG("MmsBinaryDecodePartHeader : Accept-charset. \n");
1850 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1852 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1857 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1858 // We only support the well-known-charset format
1859 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeInteger fail...\n");
1864 MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1866 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1874 /* Other Content-xxx headers : Have valueLength */
1876 MSG_DEBUG("MmsBinaryDecodePartHeader : unknown Value = 0x%x\n", oneByte);
1878 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1880 MSG_DEBUG("MmsBinaryDecodePartHeader : 1. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
1884 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1887 szTemp = (char *)malloc(valueLength);
1891 if (__MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) == false) {
1892 MSG_DEBUG("MmsBinaryDecodePartHeader : default _MmsBinaryDecodeGetBytes() fail\n");
1900 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1907 * Application-header = Token-text Application-specific-value
1908 * Application-specific-value = Text-string
1911 MSG_DEBUG(" Application-header = Token-text Application-specific-value \n");
1913 gCurMmsDecodeBuffPos--;
1918 pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1919 if (pCode == NULL) {
1920 MSG_DEBUG("pCode is null\n");
1924 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1927 MSG_DEBUG(" Token-text (%s) \n", pCode);
1930 /* Application-specific-value */
1933 pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1934 if (pValue == NULL) {
1935 MSG_DEBUG("pValue is null\n");
1939 MSG_DEBUG(" Application-specific-value (%s) \n", pValue);
1942 pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1948 switch (MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1949 case MMS_BODYHDR_TRANSFERENCODING: // Content-Transfer-Encoding
1950 pMsgType->encoding = MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1953 case MMS_BODYHDR_CONTENTID: // Content-ID
1955 char szContentID[MMS_CONTENT_ID_LEN + 1];
1957 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1958 if (pLatinBuff == NULL)
1963 __MsgMIMERemoveQuote (pValue);
1964 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1966 length = strlen(pLatinBuff);
1967 if (__MsgLatin2UTF ((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0)
1969 MSG_DEBUG("MsgLatin2UTF fail \n");
1973 removeLessGreaterMark(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID));//remove "< >"
1979 case MMS_BODYHDR_CONTENTLOCATION: // Content-Location
1981 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1982 if (pLatinBuff == NULL)
1985 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1987 length = strlen(pLatinBuff);
1988 if (__MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1989 MSG_DEBUG("MsgLatin2UTF fail \n");
1997 case MMS_BODYHDR_DISPOSITION: // Content-Disposition
1998 pMsgType->disposition = MmsGetTextType(MmsCodeMsgDisposition, pValue);
2001 case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY: // DRM RO WAITING
2005 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
2010 __MsgParseParameter(pMsgType, pParam + 1);
2022 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2070 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2074 length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2079 MSG_DEBUG("Number of Entries = %d\n", *npEntries);
2087 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2092 * Currently, offset and size is
2093 * the only information used with msgBody.
2094 * If you need, add here more information
2098 offset = __MmsGetDecodeOffset();
2099 offset += bodyLength;
2101 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2102 MSG_DEBUG("fail to seek file pointer \n");
2106 __MmsCleanDecodeBuff();
2108 gMmsDecodeCurOffset = offset;
2110 if (offset >= totalLength)
2113 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2114 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2115 MSG_DEBUG("fail to load to buffer \n");
2128 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2130 if (offset > totalLength)
2133 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2134 MSG_DEBUG("fail to seek file pointer \n");
2138 __MmsCleanDecodeBuff();
2140 gMmsDecodeCurOffset = offset;
2142 if (offset == totalLength)
2145 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2146 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2147 MSG_DEBUG("fail to load to buffer \n");
2158 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2160 UINT32 nEntries = 0;
2161 MsgMultipart *pMultipart = NULL;
2162 MsgMultipart *pLastMultipart = NULL;
2163 MsgMultipart *pPreMultipart = NULL;
2167 MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2168 MsgPresentaionInfo presentationInfo;
2170 MSG_DEBUG("total length=%d\n", totalLength);
2172 presentationInfo.factor = MSG_PRESENTATION_NONE;
2173 presentationInfo.pCurPresentation = NULL;
2174 presentationInfo.pPrevPart = NULL;
2176 if (__MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2177 MSG_DEBUG("MmsBinaryDecodeEntries is fail.\n");
2181 if (pMsgBody->body.pMultipart != NULL) {
2182 pLastMultipart = pMsgBody->body.pMultipart;
2183 MSG_DEBUG("pMsgBody->body.pMultipart exist \n");
2185 MSG_DEBUG("pMsgBody->body.pMultipart == NULL\n");
2189 MSG_DEBUG("decoding %dth multipart\n", index);
2191 offset = __MmsGetDecodeOffset();
2192 if (offset >= totalLength)
2195 if ((pMultipart = __MsgAllocMultipart()) == NULL) {
2196 MSG_DEBUG("MsgAllocMultipart Fail \n");
2200 if (__MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2201 MSG_DEBUG("MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2205 if (pMsgType->param.type == MIME_APPLICATION_SMIL) {
2206 factor = __MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2208 factor = MSG_PRESENTATION_NONE;
2210 // priority 1 : content type match, 2: content location, 3: type
2211 if (presentationInfo.factor < factor) {
2212 // Presentation part
2213 presentationInfo.factor = factor;
2214 presentationInfo.pPrevPart = pPreMultipart;
2215 presentationInfo.pCurPresentation = pMultipart;
2218 /* first multipart */
2219 if (pLastMultipart == NULL) {
2220 pMsgBody->body.pMultipart = pMultipart;
2221 pLastMultipart = pMultipart;
2222 pPreMultipart = NULL;
2224 pLastMultipart->pNext = pMultipart;
2225 pLastMultipart = pMultipart;
2226 pPreMultipart = pMultipart;
2229 pMsgType->contentSize += pMultipart->pBody->size;
2233 __MmsDebugPrintMulitpartEntry(pMultipart, index++);
2237 pMsgBody->size = totalLength - pMsgBody->offset;
2239 #ifdef __SUPPORT_DRM__
2240 if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_REQUIRED)
2242 __MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2244 if (__MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2245 MSG_DEBUG("MmsBinaryDecodeMultipart : MsgResolveNestedMultipart failed \n");
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("MmsBinaryDecodeEachPart: total length=%d\n", totalLength);
2278 if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2279 MSG_DEBUG("MmsBinaryDecodeEachPart: Get header length fail \n");
2283 offset = __MmsGetDecodeOffset();
2284 if (offset >= totalLength)
2290 if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2291 MSG_DEBUG("MmsBinaryDecodeEachPart: Get body length fail\n");
2296 offset = __MmsGetDecodeOffset();
2297 if (offset >= totalLength)
2302 if (szFilePath != NULL)
2303 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2305 pMsgType->offset = __MmsGetDecodeOffset();
2306 pMsgType->size = headerLength;
2307 pMsgType->contentSize = bodyLength;
2309 if (pMsgType->offset > totalLength)
2312 length = __MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2314 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentType Fail \n");
2318 offset = __MmsGetDecodeOffset();
2319 if (offset >= totalLength)
2325 if (__MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2326 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentHeader Fail \n");
2330 offset = __MmsGetDecodeOffset();
2331 if (offset >= totalLength)
2336 if (szFilePath != NULL)
2337 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2339 pMsgBody->offset = __MmsGetDecodeOffset();
2340 pMsgBody->size = bodyLength;
2342 if (pMsgBody->offset > totalLength)
2345 switch (pMsgType->type) {
2346 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2347 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2348 case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2349 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2350 case MIME_MULTIPART_REPORT:
2351 case MIME_MULTIPART_MIXED:
2352 case MIME_MULTIPART_RELATED:
2353 case MIME_MULTIPART_ALTERNATIVE:
2355 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode multipart\n");
2357 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2358 MSG_DEBUG("MmsBinaryDecodeEachPart: MmsBinaryDecodeMultipart is fail.\n");
2362 offset = __MmsGetDecodeOffset();
2363 if (offset >= totalLength)
2369 #ifdef __SUPPORT_DRM__
2371 case MIME_APPLICATION_VND_OMA_DRM_MESSAGE: /* Contains forwardLock OR combined-delivery media part */
2372 MSG_DEBUG("MmsBinaryDecodeEachPart: MIME_APPLICATION_VND_OMA_DRM_MESSAGE Part \n");
2374 if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_NOT_FIXED && MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_REQUIRED) {
2376 if (__MmsBinaryDecodeDRMContent(pFile, szFilePath, pMsgType, pMsgBody, bodyLength, totalLength) == false)
2379 MmsDrm2SetConvertState(MMS_DRM2_CONVERT_REQUIRED);
2381 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2382 if (bSuccess == false) {
2383 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentBody Fail \n");
2387 offset = __MmsGetDecodeOffset();
2388 if (offset >= totalLength)
2393 case MIME_APPLICATION_VND_OMA_DRM_CONTENT: /* Contains seperate-delivery media part (DCF) */
2395 MSG_DEBUG("MmsBinaryDecodeEachPart: MIME_APPLICATION_VND_OMA_DRM_CONTENT Part \n");
2397 if (__MmsBinaryDecodeDRMContent(pFile, szFilePath, pMsgType, pMsgBody, bodyLength, totalLength) == false)
2400 offset = __MmsGetDecodeOffset();
2401 if (offset >= totalLength)
2408 MSG_DEBUG("MmsBinaryDecodeEachPart: Other normal Part \n");
2410 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2411 if (bSuccess == false) {
2412 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentBody Fail \n");
2416 offset = __MmsGetDecodeOffset();
2417 if (offset >= totalLength)
2434 #ifdef __SUPPORT_DRM__
2435 static bool __MmsBinaryDecodeDRMContent(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int bodyLength, int totalLength)
2438 char szTempFilePath[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"drm.dcf";
2439 char *pRawData = NULL;
2440 bool isFileCreated = false;
2442 MSG_DEBUG("bodyLength: %d\n", bodyLength);
2444 offset = __MmsGetDecodeOffset();
2446 if (offset >= totalLength)
2449 if (szFilePath != NULL)
2450 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2451 if (szFilePath != NULL)
2452 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2454 pRawData = (char *)malloc(bodyLength);
2455 if (pRawData == NULL) {
2456 MSG_DEBUG("pRawData alloc FAIL \n");
2460 if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2461 MSG_DEBUG("MsgFseek() returns -1 \n");
2464 if (MsgReadFile(pRawData, sizeof(char), bodyLength, pFile) != (size_t)bodyLength) {
2465 MSG_DEBUG("FmReadFile() returns false \n");
2468 if (MsgOpenCreateAndOverwriteFile(szTempFilePath, pRawData, bodyLength) == false) {
2469 MSG_DEBUG("MsgOpenCreateAndOverwriteFile() returns false \n");
2473 isFileCreated = true;
2474 MSG_DEBUG("MmsDrm2GetConvertState() [%d]", MmsDrm2GetConvertState());
2476 if (pMsgType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE && (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_FINISH)) {
2477 MmsDrm2SetConvertState(MMS_DRM2_CONVERT_REQUIRED);
2479 if (MsgDRM2GetDRMInfo(szTempFilePath, pMsgType) == false) {
2480 MSG_DEBUG("MsgDRM2GetDRMInfo() returns false \n");
2485 if(remove(szTempFilePath) != 0)
2486 MSG_DEBUG("remove fail");
2487 isFileCreated = false;
2489 if (__MmsBinaryDecodeMovePointer(pFile, offset + bodyLength, totalLength) == false)
2503 if(remove(szTempFilePath) != 0)
2504 MSG_DEBUG("remove fail");
2514 static int __MmsDrm2BinaryEncodeUintvarLen(UINT32 integer)
2518 /* Find encoded unitvar length */
2519 if (integer <= MMS_UINTVAR_LENGTH_1) {
2522 if (integer <= MMS_UINTVAR_LENGTH_2) {
2525 if (integer <= MMS_UINTVAR_LENGTH_3) {
2536 static bool __MmsDrm2BinaryEncodeUintvar(UINT32 integer, int length, char *pszOutput)
2538 const char ZERO = 0x00;
2540 char szReverse[MSG_STDSTR_LONG] = {0, };
2546 source.integer = integer;
2547 memset(szReverse, 0, MSG_STDSTR_LONG);
2549 /* Seperate integer to 4 1 byte integer */
2550 szReverse[3] = source.bytes[3] & 0x0f;
2551 szReverse[0] = source.bytes[0];
2552 szReverse[0] = szReverse[0] & 0x7f;
2554 while (length >= i) {// initially, i = 2
2555 /* Move integer bit to proper position */
2556 source.integer = source.integer << 1;
2557 source.integer = source.integer >> 8;
2558 source.bytes[3] = ZERO;
2560 /* Retrive 1 encode uintvar */
2561 szReverse[i-1] = source.bytes[0];
2562 szReverse[i-1] = szReverse[i-1] | 0x80;
2566 for (i=0; i < length; i++)
2567 pszOutput[i] = szReverse[length - i - 1];
2572 static int __MmsDrm2GetEntriesValueLength(FILE *pFile, int orgOffset)
2574 char szEntries[5] = {0, };
2576 int j = 0; //j is the length of nEntries value
2578 if (MsgReadFile(szEntries, sizeof(char), 4, pFile) != (size_t)4) {
2579 MSG_DEBUG("__MmsDrm2GetEntriesValueLength: FmReadFile() returns false \n");
2584 oneByte = szEntries[j++];
2586 if (oneByte <= 0x7f)
2590 //move file pointer to point nEntries
2591 if (MsgFseek(pFile, orgOffset, SEEK_SET) < 0) {
2592 MSG_DEBUG("__MmsDrm2GetEntriesValueLength: fail to seek file pointer\n");
2599 static bool __MmsDrm2WriteDataToConvertedFile(FILE *pSrcFile, FILE *pDestinationFile, char *pszMmsLoadTempBuf, int length, int bufLen)
2601 int loadLen = 0, totalLoadLen = 0, nRead = 0;
2603 for (int i=0; i<(length/bufLen)+1; i++) {
2604 loadLen = (length-totalLoadLen < bufLen) ? length-totalLoadLen : bufLen;
2606 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2608 if (MsgReadFile(pszMmsLoadTempBuf, sizeof(char), loadLen, pSrcFile) != (size_t)loadLen) {
2609 MSG_DEBUG("__MmsDrm2WriteDataToConvertedFile: FmReadFile() returns false \n");
2613 if (MsgWriteFile(pszMmsLoadTempBuf, sizeof(char), loadLen, pDestinationFile) != (size_t)loadLen) {
2614 MSG_DEBUG("__MmsDrm2WriteDataToConvertedFile: File Writing is failed.\n");
2618 totalLoadLen += nRead;
2624 /*************************************************************************
2625 * description : make new message file converting CD & FL part of original message file to SD type
2628 - bool : result of converting
2629 **************************************************************************/
2630 bool MmsDrm2ConvertMsgBody(char *szOriginFilePath)
2633 FILE *hConvertedFile = NULL;
2634 FILE *hTempFile = NULL;
2636 MsgMultipart *pMultipart = NULL;
2637 char szTempFilePath[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"Drm_Convert";
2638 char szTempFile[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"temp.dm";
2639 char *pszMmsLoadTempBuf = NULL;
2640 char *pszOrgData = NULL;
2642 int bufLen = MMS_DRM2_CONVERT_BUFFER_MAX;
2645 MSG_DEBUG("start convert~~~~~~\n");
2647 pFile = MsgOpenFile(szOriginFilePath, "rb");
2648 if (pFile == NULL) {
2649 MSG_DEBUG("Open decode temporary file fail\n");
2653 hConvertedFile = MsgOpenFile(MMS_DECODE_DRM_CONVERTED_TEMP_FILE, "wb+");
2654 if (hConvertedFile == NULL) {
2655 MSG_DEBUG("Open decode temporary file fail\n");
2659 pszMmsLoadTempBuf = (char*)malloc(MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2660 if (pszMmsLoadTempBuf == NULL) {
2661 MSG_DEBUG("malloc for pszMmsLoadTempBuf failed\n");
2664 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2667 length = mmsHeader.msgBody.offset;
2668 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2669 MSG_DEBUG("Write header data fail\n");
2673 curOffset += length; //change offset
2676 if (MsgIsMultipart(mmsHeader.msgType.type) == true)
2679 length = __MmsDrm2GetEntriesValueLength(pFile, curOffset); // getting nEntries value's length
2681 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2682 MSG_DEBUG("Write nEntries fail\n");
2686 curOffset += length; //change offset
2688 // each Multipart entry copy
2689 pMultipart = mmsHeader.msgBody.body.pMultipart;
2691 while (pMultipart) {
2692 if (pMultipart->type.type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE) {
2693 int orgDataLen = pMultipart->pBody->size;
2696 MSG_DEBUG("Write MIME_APPLICATION_VND_OMA_DRM_MESSAGE multipart data(orgDataLen = %d).\n", orgDataLen);
2698 pszOrgData = (char *)malloc(orgDataLen + 1);
2699 if (pszOrgData == NULL) {
2700 MSG_DEBUG("pszOrgData is NULL \n");
2703 memset(pszOrgData, 0, orgDataLen + 1);
2705 // move file pointer to data
2706 if (MsgFseek(pFile, pMultipart->pBody->offset, SEEK_SET) < 0) {
2707 MSG_DEBUG("fail to seek file pointer 1\n");
2711 if (MsgReadFile(pszOrgData, sizeof(char), orgDataLen, pFile) != (size_t)orgDataLen) {
2712 MSG_DEBUG("FmReadFile() returns false for orgData\n");
2716 if((hFile = MsgOpenFile(szTempFile, "wb+")) == NULL) {
2717 MSG_DEBUG("file open failed [%s]", szTempFile);
2721 if (MsgWriteFile(pszOrgData, sizeof(char), orgDataLen, hFile) != (size_t)orgDataLen) {
2722 MSG_DEBUG("File write error");
2732 MsgCloseFile(hFile);
2736 // --> invoking drm agent api, converting data part start
2737 MSG_DEBUG("start data part convert by callling drm agent api\n");
2740 ret = MsgDrmConvertDmtoDcfType(szTempFile, szTempFilePath);
2741 MSG_DEBUG("MsgDrmConvertDmtoDcfType returned %s", ret ? "true": "false");
2743 if (MsgGetFileSize(szTempFilePath, &nSize) == false) {
2744 MSG_DEBUG("MsgGetFileSize error");
2747 MSG_DEBUG("end data part convert(converted data len = %d)\n", nSize);
2749 // move file pointer to the head of multipart
2750 if (MsgFseek(pFile, curOffset, SEEK_SET) < 0) {
2751 MSG_DEBUG("fail to seek file pointer 2\n");
2755 // read headerLen, dataLen
2756 length = pMultipart->type.offset - curOffset;
2757 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2758 if (MsgReadFile(pszMmsLoadTempBuf, sizeof(char), length, pFile) != (size_t)length) {
2759 MSG_DEBUG("FmReadFile() returns false for headerLen, dataLen\n");
2763 curOffset += length;
2765 // change dataLen based on converted data
2770 char szOutput[MSG_STDSTR_LONG] = {0, };
2773 oneByte = pszMmsLoadTempBuf[j++];
2775 if (oneByte <= 0x7f)
2779 encodeLen = __MmsDrm2BinaryEncodeUintvarLen((UINT32)nSize);
2780 __MmsDrm2BinaryEncodeUintvar((UINT32)nSize, encodeLen, szOutput);
2782 strncpy(&(pszMmsLoadTempBuf[j]), szOutput, encodeLen);
2783 pszMmsLoadTempBuf[j+encodeLen] = '\0';
2785 if (MsgWriteFile(pszMmsLoadTempBuf, sizeof(char), length, hConvertedFile) != (size_t)length) {
2786 MSG_DEBUG("Drm2WriteConvertData: FmWriteFile() returns false for dateLen\n");
2792 length = pMultipart->pBody->offset - pMultipart->type.offset;
2794 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2795 MSG_DEBUG("Drm2WriteConvertData: Write content type, headers fail\n");
2799 curOffset += length;
2801 // write converted data
2802 hTempFile = MsgOpenFile(szTempFilePath, "rb");
2803 if (hTempFile == NULL) {
2804 MSG_DEBUG("Open decode temporary file fail\n");
2810 if (__MmsDrm2WriteDataToConvertedFile(hTempFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2811 MSG_DEBUG("Write converted data fail\n");
2815 if (hTempFile != NULL) {
2816 MsgCloseFile(hTempFile);
2820 curOffset += pMultipart->pBody->size;
2822 // move file pointer to the head of multipart
2823 if (MsgFseek(pFile, curOffset, SEEK_SET) < 0) {
2824 MSG_DEBUG("fail to seek file pointer \n");
2827 } else { // it doesn't need to convert if it is not CD or FL
2828 MSG_DEBUG("Write normal multipart data\n");
2830 length = pMultipart->pBody->offset + pMultipart->pBody->size - curOffset;
2832 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2833 MSG_DEBUG("Write multipart data fail \n");
2837 curOffset += length;
2840 pMultipart = pMultipart->pNext;
2844 MSG_DEBUG("end convert~~~~~~\n");
2846 if (pFile != NULL) {
2847 MsgCloseFile(pFile);
2851 if (hConvertedFile != NULL) {
2852 MsgCloseFile(hConvertedFile);
2853 hConvertedFile = NULL;
2856 if (pszMmsLoadTempBuf) {
2857 free(pszMmsLoadTempBuf);
2858 pszMmsLoadTempBuf = NULL;
2861 if(remove(szTempFile) != 0)
2862 MSG_DEBUG("remove fail");
2863 if(remove(szTempFilePath) != 0)
2864 MSG_DEBUG("remove fail");
2870 if (pFile != NULL) {
2871 MsgCloseFile(pFile);
2875 if (hConvertedFile != NULL) {
2876 MsgCloseFile(hConvertedFile);
2877 hConvertedFile = NULL;
2880 if (hTempFile != NULL) {
2881 MsgCloseFile(hTempFile);
2885 if (pszMmsLoadTempBuf) {
2886 free(pszMmsLoadTempBuf);
2887 pszMmsLoadTempBuf = NULL;
2897 MsgCloseFile(hFile);
2901 if (remove(szTempFile) != 0)
2902 MSG_DEBUG("remove fail");
2904 if (remove(szTempFilePath) != 0)
2905 MSG_DEBUG("remove fail");
2907 if (remove(MMS_DECODE_DRM_CONVERTED_TEMP_FILE) != 0)
2908 MSG_DEBUG("remove fail"); //remove convertin result if it goes to __CATCH
2913 /*************************************************************************
2914 * description : Function for decoding a converted file
2917 - bool : result of converting
2918 **************************************************************************/
2920 bool MmsDrm2ReadMsgConvertedBody(MSG_MESSAGE_INFO_S *pMsg, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
2923 MmsPluginStorage::instance()->getMmsMessage(&pMmsMsg);
2924 MmsUnregisterDecodeBuffer();
2925 #ifdef __SUPPORT_DRM__
2926 MmsReleaseMsgDRMInfo(&pMmsMsg->msgType.drmInfo);
2928 MmsReleaseMsgBody(&pMmsMsg->msgBody, pMmsMsg->msgType.type);
2930 if (MmsReadMsgBody(pMsg->msgId, bSavePartsAsTempFiles, bRetrieved, retrievedPath) == false) {
2931 MSG_DEBUG("MmsDrm2ReadMsgConvertedBody: _MmsReadMsgBody with converted file is failed\n");
2940 /* --------------------------------------------------------------------
2942 * B I N A R Y D E C D E U T I L I T Y
2944 * --------------------------------------------------------------------*/
2946 bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
2948 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2950 if (pFile == NULL || pOneByte == NULL)
2952 MSG_DEBUG("_MmsBinaryDecodeGetOneByte: invalid file or buffer\n");
2957 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2958 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2959 MSG_DEBUG("_MmsBinaryDecodeGetOneByte: fail to load to buffer \n");
2964 *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2973 * @remark: bufLen < gMmsDecodeMaxLen
2975 bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2977 int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2981 if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
2984 memset(szBuff, 0, bufLen);
2986 if (length < bufLen) {
2987 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2988 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2989 MSG_DEBUG("_MmsBinaryDecodeGetBytes: fail to load to buffer \n");
2994 for (i = 0; i < bufLen - 1; i++)
2995 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2998 gCurMmsDecodeBuffPos++; //NULL
3006 bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3010 if (pFile == NULL || szBuff == NULL || bufLen == 0)
3013 memset(szBuff, 0, bufLen);
3015 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3016 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3017 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: fail to load to buffer \n");
3021 while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
3022 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
3023 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: 1. _MmsBinaryDecodeGetBytes fail \n");
3027 iPos += gMmsDecodeMaxLen;
3030 if ((bufLen - iPos) > 0) {
3031 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
3032 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: 2. _MmsBinaryDecodeGetBytes fail \n");
3036 iPos += (bufLen - iPos);
3046 * Decode uintvar to 32bit unsigned integer
3048 * @param pEncodedData [in] encoded data
3049 * @param pUintVar [out] Decode uintvar (32bit unsigned integer)
3050 * @return The length of uintvar (-1, if cannot be converted to a uintvar)
3052 * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
3055 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
3057 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
3061 UINT32 decodedUintvar = 0;
3062 UINT8 iBuff[5] = {0};
3063 int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
3066 if (pFile == NULL || pUintVar == NULL)
3070 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3071 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3072 MSG_DEBUG("__MmsBinaryDecodeUintvar: fail to load to buffer \n");
3078 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3081 if (oneByte > 0x7f) {
3082 iBuff[count++] = oneByte;
3084 iBuff[count++] = oneByte;
3089 MSG_DEBUG("__MmsBinaryDecodeUintvar : legnth is too long\n");
3094 for (int i = 0; i < count; i++)
3095 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
3097 *pUintVar = decodedUintvar;
3102 gCurMmsDecodeBuffPos -= count;
3107 * Decode uintvar to 32bit unsigned integer by uintvar length
3109 * @param pEncodedData [in] uintvar encoded data
3110 * @param length [in] length of integer value
3111 * @return unsigned integer value
3113 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
3123 returner.integer = 0;
3130 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3131 MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: _MmsBinaryDecodeGetOneByte fail\n");
3135 if (oneByte > 0x7f) {
3136 return (oneByte & 0x7f);
3145 pData = (char *)malloc(length + 1);
3146 if (pData == NULL) {
3147 MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: pData alloc fail\n");
3150 memset(pData, 0, length + 1);
3152 if (__MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
3153 MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: _MmsBinaryDecodeGetOneByte fail\n");
3157 gCurMmsDecodeBuffPos--; // - NULL
3159 for (i= 0; i < length; i++)
3160 returner.seg[length - (i+1)] = pData[i];
3167 return returner.integer;
3176 return returner.integer;
3180 * Decode uintvar to 32bit unsigned integer by uintvar length
3182 * @param pEncodedData [in] uintvar encoded data
3183 * @param pInteger [out] Decode integer value (long/short)
3184 * @return unsigned integer value (-1, if cannot be converted to unsigned integer value)
3186 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
3196 if (pInteger == NULL)
3199 returner.integer = 0;
3202 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3203 MSG_DEBUG("__MmsBinaryDecodeInteger: GetOneByte fail\n");
3207 if (oneByte < 0x1F) /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
3209 pData = (char *)malloc(oneByte + 1);
3210 if (pData == NULL) {
3211 MSG_DEBUG("__MmsBinaryDecodeInteger: pData memalloc fail\n");
3214 memset(pData, 0, oneByte + 1);
3216 // Even NULL is copied in the _MmsBinaryDecodeGetBytes
3217 if (__MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
3218 MSG_DEBUG("__MmsBinaryDecodeInteger: GetBytes fail\n");
3222 gCurMmsDecodeBuffPos--; // - NULL
3232 for (i = 0; i < length; i++)
3233 returner.seg[length - (i+1)] = pData[i];
3235 *pInteger = returner.integer;
3236 *pIntLen = oneByte + 1;
3237 } else if (oneByte >= 0x80) {
3238 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
3239 *pInteger = oneByte & 0x7f;
3254 gCurMmsDecodeBuffPos--;
3265 * Decode uintvar to 32bit unsigned integer by uintvar length
3267 * @return 1 : Success
3268 * 0 : This is not Value Length type data
3269 * -1 : Requires System error report
3271 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
3279 * value-length = short-length | (Length-quote Length)
3280 * = 0~30 | 31 + Uintvar-length
3283 if (pFile == NULL || pValueLength == NULL)
3288 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3289 gCurMmsDecodeBuffPos--;
3293 if (0x00 < oneByte && oneByte < 0x1F) {
3296 *pValueLength = oneByte;
3298 } else if (oneByte == 0x1F) {
3299 /* Length-quote = 0x1F */
3301 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
3303 MSG_DEBUG("__MmsDecodeValueLength: __MmsBinaryDecodeUintvar fail..\n");
3306 length ++; // + length-quote
3307 *pValueLength = uintvar;
3309 MSG_DEBUG("__MmsDecodeValueLength: not a value length type data\n");
3310 gCurMmsDecodeBuffPos--;
3317 MSG_DEBUG("__MmsDecodeValueLength: getting data fail\n");
3322 * Decode uintvar to 32bit unsigned integer by uintvar length
3324 * @return 1 : Success
3325 * 0 : This is not Value Length type data
3326 * -1 : Requires System error report
3327 * @ defference : if there is not length-quote, consider it as short length.
3329 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
3337 * value-length = short-length | (Length-quote Length)
3338 * = 0~30 | 31 + Uintvar-length
3341 if (pFile == NULL || pValueLength == NULL)
3346 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3347 gCurMmsDecodeBuffPos--;
3351 if (0x00 < oneByte && oneByte < 0x1F) {
3354 *pValueLength = oneByte;
3356 } else if (oneByte == 0x1F) {
3357 /* Length-quote = 0x1F */
3359 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
3361 MSG_DEBUG("__MmsDecodeValueLength2: __MmsBinaryDecodeUintvar fail..\n");
3364 length ++; // + length-quote
3365 *pValueLength = uintvar;
3367 MSG_DEBUG("__MmsDecodeValueLength2: there is not length-quote, consider it as short length.\n");
3368 *pValueLength = oneByte;
3375 MSG_DEBUG("__MmsDecodeValueLength2: getting data fail\n");
3380 * Decode QuotedString
3382 * @param pEncodedData [in] QuotedString encoded data
3383 * @param szBuff [out] Decoded quoted string
3384 * @param bufLen [out] Buffer length
3385 * @return length of quoted string
3387 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3393 int returnLength = 0;
3396 * Quoted-string = <Octet 34> *TEXT End-of-string
3397 * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
3400 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
3403 memset(szBuff, 0, bufLen);
3405 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3406 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3407 MSG_DEBUG("__MmsBinaryDecodeQuotedString: 1. fail to load to buffer \n");
3411 length = strlen(gpCurMmsDecodeBuff) + 1; // + NULL
3416 while (length > gMmsDecodeBufLen) {
3417 if (gMmsDecodeBufLen <= 0) {
3418 MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
3419 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3420 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3421 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3422 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3423 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3424 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3425 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3426 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3427 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3428 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3429 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3430 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3434 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3438 memset(pData, 0, gMmsDecodeBufLen + 1);
3440 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3443 returnLength += gMmsDecodeBufLen;
3445 if ((bufLen - iPos) > 0) {
3446 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3447 if (iPos == 0 && (pData[0] == MARK)) {
3448 /* MARK: check first time only */
3450 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3451 iPos += (readBytes - 1);
3453 strncpy(szBuff + iPos, (char*)pData, readBytes);
3463 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3464 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3465 MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
3468 length = strlen(gpCurMmsDecodeBuff) + 1; // + NULL
3472 pData = (char *)malloc(length);
3476 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3479 returnLength += length;
3481 if ((bufLen - iPos) > 0) {
3482 /* read until NULL from raw data, and copy only string */
3483 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3484 if (iPos == 0 && (pData[0] == MARK)) {
3485 /* MARK: check first time only */
3486 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3487 iPos += (readBytes - 1);
3489 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); // + NULL
3500 szBuff[bufLen - 1] = '\0';
3502 return returnLength;
3521 * @param pEncodedData [in] QuotedString encoded data
3522 * @param szBuff [out] Decoded quoted string
3523 * @param bufLen [out] Buffer length
3524 * @return length of decode text string
3526 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3531 int returnLength = 0;
3533 bool bQuote = false;
3537 * Text-String = [QUOTE]*TEXT end_of_string
3538 * [QUOTE]*(128~255)\0
3542 if (pFile == NULL || szBuff == NULL || bufLen <= 0)
3545 offset = __MmsGetDecodeOffset();
3546 if (offset >= totalLength)
3549 memset(szBuff, 0, bufLen);
3551 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3552 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3553 MSG_DEBUG("__MmsBinaryDecodeText: 1. fail to load to buffer \n");
3557 length = strlen(gpCurMmsDecodeBuff) + 1; // + NULL
3562 while (length > gMmsDecodeBufLen) {
3563 if (gMmsDecodeBufLen <= 0) {
3564 MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
3565 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3566 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3567 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3568 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3569 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3570 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3571 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3572 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3576 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3580 memset(pData, 0, gMmsDecodeBufLen + 1);
3582 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3585 if ((bufLen - iPos) > 0) {
3586 readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3587 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3588 /* QUOTE: check first time only */
3590 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3591 iPos += (readBytes - 1);
3594 strncpy(szBuff + iPos, (char*)pData, readBytes);
3604 returnLength += gMmsDecodeBufLen;
3606 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3607 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3608 MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
3611 length = strlen(gpCurMmsDecodeBuff) + 1; // + NULL
3615 pData = (char *)malloc(length);
3619 memset(pData, 0, length);
3621 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3624 if ((bufLen - iPos) > 0) {
3625 readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3626 if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3627 /* QUOTE: check first time only */
3629 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3630 iPos += (readBytes - 1);
3633 strncpy(szBuff + iPos, (char*)pData, readBytes - 1); // + NULL
3643 returnLength += length; // + NULL
3646 szBuff[bufLen - 1] = '\0';
3648 return returnLength;
3655 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3669 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
3674 char *szBuff = NULL;
3675 char *szTempPtr = NULL;
3676 bool bQuote = false;
3680 * Text-String = [QUOTE]*TEXT end_of_string
3681 * [QUOTE]*(128~255)\0
3685 if (pFile == NULL || pLength == NULL)
3689 offset = __MmsGetDecodeOffset();
3690 if (offset >= totalLength)
3693 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3694 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3695 MSG_DEBUG("__MmsBinaryDecodeTextLen: 1. fail to load to buffer \n");
3699 length = strlen(gpCurMmsDecodeBuff) + 1;
3704 while (length > gMmsDecodeBufLen) {
3705 if (gMmsDecodeBufLen <= 0) {
3706 MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
3707 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3708 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3709 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3710 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3711 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3712 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3713 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3714 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3715 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3716 MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3717 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3718 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3722 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3726 memset(pData, 0, gMmsDecodeBufLen + 1);
3728 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3731 if (szBuff == NULL) {
3732 szBuff = (char *)malloc(gMmsDecodeBufLen + 1);
3734 szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
3736 //NULL pointer check for realloc
3737 if (szTempPtr == NULL) {
3746 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
3748 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3749 /* QUOTE: check first time only */
3751 strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
3752 curLen += (gMmsDecodeBufLen - 1);
3755 strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
3756 curLen += gMmsDecodeBufLen;
3764 *pLength += gMmsDecodeBufLen;
3766 if (__MsgLoadDataToDecodeBuffer(pFile,
3767 &gpCurMmsDecodeBuff,
3768 &gCurMmsDecodeBuffPos,
3769 &gMmsDecodeCurOffset,
3774 totalLength) == false)
3776 MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
3779 length = strlen(gpCurMmsDecodeBuff) + 1;
3783 pData = (char *)malloc(length);
3784 if (pData == NULL) {
3788 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
3792 if (szBuff == NULL) {
3793 szBuff = (char *)malloc(length);
3795 szTempPtr = (char *)realloc(szBuff, curLen + length);
3797 //NULL pointer check for realloc
3798 if (szTempPtr == NULL)
3804 if (szBuff == NULL) {
3808 memset(szBuff + curLen, 0, length);
3810 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3811 /* QUOTE: check first time only */
3813 strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
3814 curLen += (length - 1);
3817 strncpy(szBuff + curLen, (char*)pData, length - 1);
3826 *pLength += length; // + NULL
3835 __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3857 * @param pEncodedData [in] QuotedString encoded data
3858 * @param nCharSet [out] Decoded character set
3859 * @return length of charset value
3861 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
3866 * Charset v1.1 0x01 Well-known-charset
3867 * Well-known-charset = Any-charset | Integer-value
3868 * ; Both are encoded using values from
3869 * Character Set Assignments table in Assigned Numbers
3870 * Any-charset = <Octet 128>
3871 * ; Equivalent to the special RFC2616 charset value ��*��
3874 if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
3877 if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
3878 MSG_DEBUG("__MmsBinaryDecodeCharset : __MmsBinaryDecodeInteger fail...\n");
3883 /* AnyCharSet : return MSG_CHARSET_UTF8 */
3884 *nCharSet = MSG_CHARSET_UTF8;
3888 *nCharSet = MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
3890 if (*nCharSet == MIME_UNKNOWN) {
3891 MSG_DEBUG("__MmsBinaryDecodeCharset : MmsGetBinaryType fail..\n");
3892 *nCharSet = MSG_CHARSET_UNKNOWN;
3902 * Decode EncodedString
3904 * @param pEncodedData [in] QuotedString encoded data
3905 * @param szBuff [out] Decoded string buffer
3906 * @param bufLen [in] Decoded buffer length
3907 * @return length of decoded string length
3909 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3911 UINT32 valueLength = 0;
3917 MSG_DEBUG("__MmsBinaryDecodeEncodedString: decode string..\n");
3919 if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
3920 MSG_DEBUG("__MmsBinaryDecodeEncodedString: invalid file or buffer\n");
3925 * Encoded_string_value = Text-string | Value-length Char-set Text-String
3926 * Text-string = [Quote]*TEXT End-of-string
3927 * Value-length = 0 ~ 31
3930 memset(szBuff, 0, bufLen);
3932 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3938 /* Text-string = [Quote]*TEXT End-of-string */
3940 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
3941 MSG_DEBUG("__MmsBinaryDecodeEncodedString : 1. __MmsBinaryDecodeText fail.\n");
3948 /* Value-length Charset Text_string */
3950 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3951 MSG_DEBUG("__MmsBinaryDecodeEncodedString : __MmsBinaryDecodeCharset error\n");
3952 goto __CATCH; /* (valueLength + valueLengthLen) */
3955 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
3957 /* There can be some error in data - no NULL -> try again with value length */
3959 pData = (char *)malloc(valueLength - charSetLen);
3960 if (pData == NULL) {
3961 MSG_DEBUG("__MmsBinaryDecodeEncodedString : pData alloc fail.\n");
3965 if (__MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
3966 MSG_DEBUG("__MmsBinaryDecodeEncodedString : _MmsBinaryDecodeGetLongBytes fail.\n");
3970 strncpy(szBuff, pData, bufLen - 1);
3975 nTemp = strlen(szBuff);
3977 const char *pToCharSet = "UTF-8";
3979 UINT16 charset_code = MmsGetBinaryValue(MmsCodeCharSet, charSet);
3981 const char *pFromCharSet = MmsPluginTextConvertGetCharSet(charset_code);
3982 if (pFromCharSet == NULL || !strcmp(pFromCharSet, pToCharSet)) {
3993 if (MmsPluginTextConvert(pToCharSet, pFromCharSet, szBuff, nTemp, &pDest, &destLen) == false) {
3994 MSG_DEBUG("MmsPluginTextConvert Fail");
3998 memset(szBuff, 0x00, bufLen);
3999 snprintf(szBuff, destLen, "%s", pDest);
4024 * Decode Encoded Addresses
4026 * @param pEncodedData [in] QuotedString encoded data
4027 * @param pAddrLength [out] Decoded address length
4028 * @return Decoded address list
4030 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
4032 UINT32 valueLength = 0;
4036 char *pAddrStr = NULL;
4037 MsgHeaderAddress *pAddr = NULL;
4039 MSG_DEBUG("__MmsDecodeEncodedAddress: decoding address..\n");
4041 if (pFile == NULL) {
4042 MSG_DEBUG("__MmsDecodeEncodedAddress: invalid file or buffer\n");
4047 * Encoded_string_value = Text-string | Value-length Char-set Text-String
4048 * Text-string = [Quote]*TEXT End-of-string
4049 * Value-length = 0 ~ 31
4052 switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
4058 /* Text-string = [Quote]*TEXT End-of-string */
4061 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4062 if (pAddrStr == NULL) {
4063 MSG_DEBUG("__MmsDecodeEncodedAddress : 1. __MmsBinaryDecodeText2 fail.\n");
4070 /* Value-length Charset Text_string */
4072 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
4073 MSG_DEBUG("__MmsDecodeEncodedAddress : __MmsBinaryDecodeCharset error\n");
4078 pAddrStr = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4079 if (pAddrStr == NULL) {
4080 /* There can be some error in data - no NULL -> try again with value length */
4082 pAddrStr = (char *)malloc(valueLength - charSetLen);
4083 if (pAddrStr == NULL) {
4084 MSG_DEBUG("__MmsDecodeEncodedAddress : pData alloc fail.\n");
4088 if (__MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
4089 MSG_DEBUG("__MmsDecodeEncodedAddress : _MmsBinaryDecodeGetLongBytes fail.\n");
4094 /* fixme: charset transformation */
4099 pAddr = (MsgHeaderAddress *)malloc(sizeof(MsgHeaderAddress));
4103 memset(pAddr, 0, sizeof(MsgHeaderAddress));
4104 pAddr->szAddr = pAddrStr;
4120 * Decode Encoded Pointer String
4122 * @param pEncodedData [in] Long integer encoded data
4123 * @param pLongInteger [out] Decoded long integer
4124 * @return Decoded address list
4126 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
4131 * Long-integer = Short-length Multi-octet-integer
4132 * Short-length = 0~30
4133 * Multi-octet-integer
4136 if (pFile == NULL || pLongInteger == NULL)
4141 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
4147 *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
4157 * @param pEncodedData [in] filename encoded data
4158 * @param szBuff [out] filename output buffer
4159 * @param fullLength [in] full filename length
4160 * @param bufLen [in] buffer length
4161 * CAUTION: bufLen - 1
4163 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
4165 char *pUTF8Buff = NULL;
4166 char *pLatinBuff = NULL;
4169 char *szSrc2 = NULL;
4173 char *pTmpBuff = NULL;
4175 memset (szBuff, 0, bufLen);
4178 pLatinBuff = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4182 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
4184 strcpy(pLatinBuff, szSrc);
4189 szSrc2 = MsgChangeHexString(pLatinBuff);
4191 strcpy(pLatinBuff, szSrc2);
4196 if (__MsgIsUTF8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
4197 length = strlen(pLatinBuff);
4199 int utf8BufSize = 0;
4200 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
4201 if (utf8BufSize < 3)
4202 utf8BufSize = 3;//min value
4204 pUTF8Buff = (char *)malloc(utf8BufSize + 1);
4205 if (pUTF8Buff == NULL) {
4206 MSG_DEBUG("__MmsDecodeGetFilename: pUTF8Buff alloc fail \n");
4210 if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
4211 MSG_DEBUG("__MmsDecodeGetFilename: MsgLatin2UTF fail \n");
4217 pTmpBuff = MsgDecodeText(pLatinBuff);
4218 pUTF8Buff = pTmpBuff;
4227 * it should be kept extention even if the file name is shorten
4230 length = strlen(pUTF8Buff);
4231 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4233 nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
4234 strncpy(szBuff, pUTF8Buff, nameLength);
4235 strcat (szBuff, pExt);
4237 strncpy(szBuff, pUTF8Buff, bufLen - 1);
4260 /* ==========================================================
4262 M M S D E C O D I N G
4264 ==========================================================*/
4266 // to get message body this function should be modified from message raw file.
4267 bool MmsReadMsgBody(msg_message_id_t msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
4270 MmsMsg *pMsg = NULL;
4271 MsgMultipart *pMultipart = NULL;
4273 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
4274 char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
4275 int attachmax = MSG_ATTACH_MAX;
4278 MSG_DEBUG("msg id : %d", msgID);
4280 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
4281 memset(pMsg, 0, sizeof(MmsMsg));
4285 if (bRetrieved && (retrievedPath != NULL)) {
4286 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
4288 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath);
4291 pMsg->msgID = msgID;
4293 /* read from MMS raw file */
4294 strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
4296 MSG_DEBUG("szFullPath = (%s)", szFullPath);
4298 if (MsgGetFileSize(szFullPath, &nSize) == false) {
4299 MSG_DEBUG("MsgGetFileSize: failed");
4303 pFile = MsgOpenFile(szFullPath, "rb");
4305 if (pFile == NULL) {
4306 MSG_DEBUG("_MmsReadMsgBody: invalid mailbox\n");
4310 MmsRegisterDecodeBuffer();
4312 if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
4313 MSG_DEBUG("_MmsReadMsgBody: MmsBinaryDecodeMsgHeader fail...\n");
4317 #ifdef __SUPPORT_DRM__
4318 if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_FINISH)
4319 MmsDrm2SetConvertState(MMS_DRM2_CONVERT_NONE); //initialize convertState
4322 if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
4323 MSG_DEBUG("_MmsReadMsgBody: MmsBinaryDecodeMsgBody fail\n");
4327 #ifdef __SUPPORT_DRM__
4328 if (MmsDrm2GetConvertState() == MMS_DRM2_CONVERT_REQUIRED) {
4329 MSG_DEBUG("_MmsReadMsgBody: MmsDrm2GetConvertState returns MMS_DRM2_CONVERT_REQUIRED.\n");
4334 /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
4336 memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
4337 memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
4339 {//attribute convert mmsHeader -> mmsAttribute
4341 pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
4343 pMsg->mmsAttrib.date = mmsHeader.date;
4345 if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
4346 pMsg->mmsAttrib.bAskDeliveryReport = true;
4349 memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
4351 memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
4353 pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
4355 snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
4357 pMsg->mmsAttrib.msgType = mmsHeader.type;
4359 pMsg->mmsAttrib.version = mmsHeader.version;
4361 pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
4363 pMsg->mmsAttrib.priority = mmsHeader.priority;
4365 if (mmsHeader.readReply == MMS_REPORT_YES) {
4366 pMsg->mmsAttrib.bAskReadReply = true;
4369 snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
4371 snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
4373 pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
4375 //FIXME:: mmsHeader will release after delete global mmsHeader
4376 //memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody));//After copy to MmsMsg
4378 if (pMsg->msgBody.pPresentationBody) {
4379 if(MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
4382 pMsg->msgBody.pPresentationBody->body.pText = (char *)malloc(pMsg->msgBody.pPresentationBody->size + 1);
4383 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
4386 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
4389 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
4395 MsgCloseFile(pFile);
4399 pMsg->nPartCount = 0;
4401 if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
4402 pMultipart = pMsg->msgBody.body.pMultipart;
4403 while (pMultipart) {
4406 if (pMultipart->type.type == MIME_TEXT_PLAIN)
4409 if ((mmsHeader.msgType.type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED)||(mmsHeader.msgType.type == MIME_MULTIPART_MIXED)) {
4410 if ((pMsg->nPartCount >= attachmax)&&(pMultipart->pNext != NULL)) {
4411 MmsReleaseMsgBody(pMultipart->pNext->pBody, pMultipart->pNext->type.type);
4413 free(pMultipart->pNext->pBody);
4414 pMultipart->pNext->pBody= NULL;
4416 free(pMultipart->pNext);
4418 pMultipart->pNext = NULL;
4422 pMultipart = pMultipart->pNext;
4425 if (pMsg->msgBody.size > 0)
4429 /* make temporary */
4430 snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, MSG_DATA_PATH"%s.dir", pMsg->szFileName);
4432 if (MsgIsMultipart(pMsg->msgType.type) == true) {
4434 pMultipart = pMsg->msgBody.body.pMultipart;
4436 if (bSavePartsAsTempFiles) {
4437 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
4438 if (errno == EEXIST) {
4439 MSG_DEBUG("The %s already exists", szTempMediaDir);
4441 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
4447 if (pMsg->msgBody.pPresentationBody) {
4448 if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
4449 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
4453 while (pMultipart) {
4455 if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
4456 (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
4459 pMultipart = pMultipart->pNext;
4463 } else { //single part
4464 if (pMsg->nPartCount > 0) {
4466 if (bSavePartsAsTempFiles) {
4467 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
4468 if (errno == EEXIST) {
4469 MSG_DEBUG("The %s already exists", szTempMediaDir);
4471 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
4477 if (__MmsMultipartSaveAsTempFile( &pMsg->msgType, &pMsg->msgBody,
4478 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
4482 MSG_DEBUG("**** _MmsReadMsgBody: E N D (Success) ***\n");
4485 #ifdef __SUPPORT_DRM__
4489 if (pFile != NULL) {
4490 MsgCloseFile(pFile);
4501 MmsUnregisterDecodeBuffer();
4503 if (pFile != NULL) {
4504 MsgCloseFile(pFile);
4508 #ifdef __SUPPORT_DRM__
4509 MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
4512 MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
4513 MSG_DEBUG("_MmsReadMsgBody: E N D (fail) ******************** \n");
4518 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
4520 MsgHeaderAddress *pTempAddr = NULL;
4522 while (pAddr != NULL) {
4524 pAddr = pAddr->pNext;
4526 if (pTempAddr->szAddr) {
4527 free(pTempAddr->szAddr);
4528 pTempAddr->szAddr = NULL;
4538 static bool __MsgCheckFileNameHasInvalidChar(char *szName)
4543 strLen = strlen(szName);
4545 for (i=0; i<strLen; i++) {
4546 if (__MsgIsInvalidFileNameChar(szName[i]))
4553 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
4556 int totalLength = 0;
4558 totalLength = strlen(szInText);
4560 while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
4561 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
4562 if (__MsgIsInvalidFileNameChar(szInText[nCount]))
4563 *(szInText+nCount) = replaceChar;
4574 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter)
4576 char *pszBuffer = NULL;
4577 char *pszStrDelimiter = NULL;
4581 MSG_DEBUG("_MsgGetStringUntilDelimiter: pszString == NULL \n");
4585 if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
4586 MSG_DEBUG("_MsgGetStringUntilDelimiter: There is no %c in %s. \n", delimiter, pszString);
4590 bufLength = pszStrDelimiter - pszString;
4592 if ((pszBuffer = (char*)malloc (bufLength + 1)) == NULL) {
4593 MSG_DEBUG("malloc is failed");
4596 memset(pszBuffer, 0, bufLength + 1) ;
4598 strncat(pszBuffer, pszString, bufLength);
4603 char *MsgChangeHexString(char *pOrg)
4606 char szBuf[10] = {0,};
4615 cLen = strlen(pOrg);
4617 pNew = (char *)malloc(cLen + 1);
4621 memset(pNew, 0, cLen + 1);
4623 for (cIndex = 0; cIndex< cLen ; cIndex++) {
4624 if (pOrg[cIndex] == '%') {
4625 if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0) {
4626 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); // read two chars after '%'
4628 if (__MsgIsHexChar(szBuf) == true) { // check the two character is between 0 ~ F
4629 OneChar = __MsgConvertHexValue(szBuf);
4631 pNew[index] = OneChar;
4638 pNew[index++] = pOrg[cIndex];
4643 static bool __MsgParseParameter(MsgType *pType, char *pSrc)
4646 char *pValue = NULL;
4649 char *pNextParam = NULL;
4653 char *pTempNextParam = NULL;
4656 char *pUTF8Buff = NULL;
4658 while (pSrc != NULL) {
4659 pSrc = __MsgSkipWS(pSrc);
4661 /* End of parse parameter */
4666 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
4669 if (*pCh == MSG_CH_QUOT) {
4676 for (; pCh<=pTempNextParam ; pCh++) {
4677 if (*pCh == MSG_CH_QUOT)
4678 if (*(pCh - 1) != '\\')
4683 pNextParam = pTempNextParam;
4686 *pNextParam++ = MSG_CH_NULL;
4688 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
4689 *pName++ = MSG_CH_NULL;
4691 if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
4692 *pValue++ = MSG_CH_NULL;
4694 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
4695 *pTest = MSG_CH_NULL;
4697 pDec = MsgDecodeText(pValue); // Api is to long, consider Add to another file (MsgMIMECodec.c)
4699 pDec = MsgDecodeText(pName);
4702 switch (_MsgGetCode(MSG_PARAM, pSrc)) {
4703 case MSG_PARAM_BOUNDARY:
4705 /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
4707 memset (pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
4708 strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
4709 MSG_DEBUG("_MsgParseParameter: szBoundary = %s \n", pType->param.szBoundary);
4712 case MSG_PARAM_CHARSET:
4713 pType->param.charset = _MsgGetCode(MSG_CHARSET, pDec);
4715 if (pType->param.charset == INVALID_HOBJ)
4716 pType->param.charset = MSG_CHARSET_UNKNOWN;
4718 MSG_DEBUG("_MsgParseParameter: type = %d [charset] = %d \n", pType->type, pType->param.charset);
4721 case MSG_PARAM_NAME:
4723 memset (pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
4725 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4728 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4729 if ((MSG_LOCALE_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4730 nameLen = (MSG_LOCALE_FILENAME_LEN_MAX-1) - strlen(pExt);
4732 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4735 strncpy(pType->param.szName, pUTF8Buff, nameLen);
4736 strcat (pType->param.szName, pExt);
4738 strncpy(pType->param.szName, pUTF8Buff, (MSG_LOCALE_FILENAME_LEN_MAX-1));
4743 if (__MsgChangeSpace(pType->param.szName, &szSrc) == true) {
4745 strncpy(pType->param.szName, szSrc , strlen(szSrc));
4753 // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
4754 __MsgRemoveFilePath(pType->param.szName);
4756 MSG_DEBUG("_MsgParseParameter: MsgConvertLatin2UTF8FileName(%s) return NULL\n", pDec);
4759 MSG_DEBUG("_MsgParseParameter: szName = %s \n", pType->param.szName);
4762 case MSG_PARAM_FILENAME:
4764 memset (pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
4766 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4769 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4770 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4771 nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
4773 nameLen = strlen(pUTF8Buff) - strlen(pExt);
4776 strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
4777 strcat (pType->param.szFileName, pExt);
4779 strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
4784 if (__MsgChangeSpace(pType->param.szFileName, &szSrc) == true)
4785 strcpy(pType->param.szFileName, szSrc);
4792 // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
4793 __MsgRemoveFilePath(pType->param.szFileName);
4795 MSG_DEBUG("_MsgParseParameter: MsgConvertLatin2UTF8FileName(%s) return NULL\n", pDec);
4798 MSG_DEBUG("_MsgParseParameter: szFileName = %s \n", pType->param.szFileName);
4802 case MSG_PARAM_TYPE:
4804 /* type/subtype of root. Only if content-type is multipart/related */
4806 pType->param.type = _MsgGetCode(MSG_TYPE, pDec);
4807 MSG_DEBUG("_MsgParseParameter: type = %d \n", pType->param.type);
4811 case MSG_PARAM_START:
4813 /* Content-id. Only if content-type is multipart/related */
4815 memset (pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
4816 strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
4818 MSG_DEBUG("_MsgParseParameter: szStart = %s \n", pType->param.szStart);
4822 case MSG_PARAM_START_INFO :
4824 /* Only if content-type is multipart/related */
4826 memset (pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
4827 strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
4829 MSG_DEBUG("_MsgParseParameter: szStartInfo = %s \n", pType->param.szStartInfo);
4833 case MSG_PARAM_REPORT_TYPE :
4835 // only used as parameter of Content-Type: multipart/report; report-type=delivery-status;
4837 if (pDec != NULL && strcasecmp(pDec, "delivery-status") == 0) {
4838 pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
4840 pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
4843 MSG_DEBUG("_MsgParseParameter: reportType = %s \n", pDec);
4848 MSG_DEBUG("_MsgParseParameter: Unknown paremeter (%s)\n", pDec);
4862 static char *__MsgSkipWS(char *s)
4865 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
4867 } else if ((*s != '(') || (__MsgSkipComment(s,(long)NULL)==NULL)) {
4873 static char *__MsgSkipComment (char *s,long trim)
4880 // ignore empty space
4881 for (ret = ++s1; *ret == ' '; ret++)
4884 // handle '(', ')', '\', '\0'
4888 if (!__MsgSkipComment (s1,(long)NULL))
4921 static char *__MsgConvertLatin2UTF8FileName(char *pSrc)
4923 char *pUTF8Buff = NULL;
4927 //convert utf8 string
4928 if (__MsgIsUTF8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
4930 int utf8BufSize = 0;
4932 length = strlen(pSrc);
4933 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
4934 if (utf8BufSize < 3)
4935 utf8BufSize = 3; //min value
4937 pUTF8Buff = (char *)malloc(utf8BufSize + 1);
4939 if (pUTF8Buff == NULL) {
4940 MSG_DEBUG("MsgConvertLatin2UTF8FileName: pUTF8Buff alloc fail \n");
4944 if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
4945 MSG_DEBUG("MsgConvertLatin2UTF8FileName: MsgLatin2UTF fail \n");
4949 int length = strlen(pSrc);
4950 pUTF8Buff = (char *)calloc(1, length+1);
4952 if (pUTF8Buff == NULL) {
4953 MSG_DEBUG("MsgConvertLatin2UTF8FileName: pUTF8Buff alloc fail \n");
4957 memcpy(pUTF8Buff, pSrc, length);
4960 //convert hex string
4961 if (__MsgIsPercentSign(pUTF8Buff) == true) {
4962 pData = MsgChangeHexString(pUTF8Buff);
4964 strcpy(pUTF8Buff, pData);
4982 static bool __MsgChangeSpace(char *pOrg, char **ppNew)
4992 cLen = strlen(pOrg);
4994 pNew = (char *)malloc(cLen + 1);
4998 memset(pNew, 0, cLen + 1);
5000 for (cIndex=0; cIndex<cLen;cIndex++) {
5001 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
5007 pNew[index++] = pOrg[cIndex];
5015 static void __MsgRemoveFilePath(char *pSrc)
5017 // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
5020 char szFileName[MSG_FILENAME_LEN_MAX] = {0};
5026 while ((pTemp = strchr(pTemp, '/')) != NULL) {
5027 // Find the last '/'
5033 MSG_DEBUG("_MsgRemoveFilePath: filename(%s)\n", pSrc);
5035 // case : images/vf7.gif -> vf7.gif
5036 if (pPath != NULL && *(pPath+1) != '\0') {
5037 strncpy(szFileName, pPath+1, strlen(pPath+1));
5038 strncpy(pSrc, szFileName , strlen(szFileName));
5041 // Remove additional file information
5042 // ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
5043 // if "?size=" exist, insert NULL char.
5045 pTemp = strcasestr(pSrc, "?size=");
5051 static bool __MsgIsUTF8String(unsigned char *szSrc, int nChar)
5053 MSG_DEBUG("MsgIsUTF8String: --------------- \n");
5055 if (szSrc == NULL) {
5056 MSG_DEBUG("MsgIsUTF8String: szSrc is NULL !!!! --------------- \n");
5060 while (nChar > 0 && (*szSrc != '\0')) {
5061 if (*szSrc < 0x80) {
5064 } else if ((0xC0 <= *szSrc) && (*szSrc < 0xE0)) {
5065 if (*(szSrc + 1) >= 0x80) {
5069 MSG_DEBUG("MsgIsUTF8String: 1. NOT utf8 range!\n");
5072 } else if (*szSrc >= 0xE0) {
5073 if (*(szSrc + 1) >= 0x80) {
5074 if (*(szSrc + 2) >= 0x80) {
5078 MSG_DEBUG("MsgIsUTF8String: 2. NOT utf8 range!\n");
5082 MSG_DEBUG("MsgIsUTF8String: 3. NOT utf8 range!\n");
5086 MSG_DEBUG("MsgIsUTF8String: 4. NOT utf8 range!\n");
5097 static bool __MsgIsPercentSign(char *pSrc)
5102 pCh = strchr(pSrc , '%');
5113 static MsgMultipart *__MsgAllocMultipart(void)
5115 MsgMultipart *pMultipart = NULL;
5117 MSG_DEBUG("MsgAllocMultipart: --------- \n");
5119 pMultipart = (MsgMultipart*)malloc(sizeof(MsgMultipart));
5120 if (pMultipart == NULL) {
5121 MSG_DEBUG("MsgAllocMultipart: pMultipart malloc Fail \n");
5125 pMultipart->pBody = (MsgBody*)malloc(sizeof(MsgBody));
5126 if (pMultipart->pBody == NULL) {
5127 MSG_DEBUG("MsgAllocMultipart: pMultipart->pBody malloc Fail \n");
5131 MmsInitMsgType(&pMultipart->type);
5132 MmsInitMsgBody(pMultipart->pBody);
5134 pMultipart->pNext = NULL;
5141 if (pMultipart->pBody) {
5142 free(pMultipart->pBody);
5143 pMultipart->pBody = NULL;
5153 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam)
5155 char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
5156 char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
5157 char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
5160 // remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445>
5161 if (szStart && szStart[0]) {
5163 startLen = strlen(szStart);
5164 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
5165 strncpy(szTmpStart, &szStart[1], startLen - 2);
5167 strncpy(szTmpStart, szStart, startLen);
5171 // remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445>
5172 if (multipartType->szContentID[0]) {
5173 strLen = strlen(multipartType->szContentID);
5174 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
5175 strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
5177 strncpy(szTmpContentID, multipartType->szContentID, strLen);
5181 // remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445>
5182 if (multipartType->szContentLocation[0]) {
5183 strLen = strlen(multipartType->szContentLocation);
5184 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
5185 strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
5187 strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
5191 if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
5192 return MSG_PRESENTATION_NONE;
5194 // exception handling
5195 if (szTmpStart[0] != '\0') {
5196 // presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type
5197 if (strcmp(szTmpStart, szTmpContentID) == 0) {
5198 return MSG_PRESENTATION_ID;
5199 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
5200 return MSG_PRESENTATION_LOCATION;
5201 } else if (multipartType->type == typeParam) {
5202 return MSG_PRESENTATION_TYPE_BASE;
5204 return MSG_PRESENTATION_NONE;
5207 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
5208 return MSG_PRESENTATION_TYPE_BASE;
5210 return MSG_PRESENTATION_NONE;
5215 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
5218 MsgMultipart *pNextPart = NULL;
5219 MsgMultipart *pRemovePart = NULL;
5221 if (__MsgIsMultipartRelated(pMsgType->type)) {
5222 // assign the multipart to presentation part
5223 // remove the multipart(pCurPresentation) which is presentation part from the linked list.
5224 // if there is no presentation part -> assign first multipart to presentation part by force.
5225 if (pPresentationInfo->pCurPresentation == NULL) {
5226 pPresentationInfo->pCurPresentation = pMsgBody->body.pMultipart;
5227 pPresentationInfo->pPrevPart = NULL;
5228 pPresentationInfo->factor = MSG_PRESENTATION_NONE;
5231 if (pPresentationInfo->pCurPresentation != NULL && __MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
5232 /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
5233 * In this case, COPY the Presentation part and leave other multiparts.
5235 memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
5236 pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
5238 // remove pCurPresentation from multipart linked list
5239 if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE)||(pPresentationInfo->pPrevPart == NULL)) {
5241 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
5242 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
5243 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
5244 if (pPresentationInfo->pCurPresentation) {
5245 #ifdef __SUPPORT_DRM__
5246 MmsReleaseMsgDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
5248 free(pPresentationInfo->pCurPresentation);
5249 pPresentationInfo->pCurPresentation = NULL;
5253 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
5254 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
5255 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
5256 if (pPresentationInfo->pCurPresentation) {
5257 free(pPresentationInfo->pCurPresentation);
5258 pPresentationInfo->pCurPresentation = NULL;
5261 } else if (pPresentationInfo->pCurPresentation != NULL && __MsgIsText(pPresentationInfo->pCurPresentation->type.type)) {
5262 /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
5263 * In this case, leave the Presentation part as a multipart and remove other multiparts.
5266 // Backup the multipart link information
5267 pNextPart = pMsgBody->body.pMultipart;
5269 // Copy presentation part as a main part
5270 memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
5271 memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
5273 // Remove multipart linked list
5275 pRemovePart = pNextPart;
5276 pNextPart = pNextPart->pNext;
5278 if (pRemovePart->pBody) {
5279 MmsReleaseMsgBody(pRemovePart->pBody, pRemovePart->type.type);
5280 free(pRemovePart->pBody);
5281 pRemovePart->pBody = NULL;
5289 #ifdef __SUPPORT_DRM__
5290 MmsReleaseMsgDRMInfo(&pMsgBody->presentationType.drmInfo);
5292 MmsInitMsgType(&pMsgBody->presentationType);
5293 pMsgBody->pPresentationBody = NULL;
5299 static bool __MsgIsMultipartRelated(int type)
5301 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
5308 static bool __MsgIsPresentablePart(int type)
5310 if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
5317 #ifdef __SUPPORT_DRM__
5319 bool MsgCopyDrmInfo(MsgType *pPartType)
5322 char *pTmpBuf = NULL;
5324 //convert application/vnd.oma.drm.content to media type
5325 pPartType->type = pPartType->drmInfo.contentType;
5327 // fix wrong file name presentation on save media screen.
5328 if (pPartType->szContentID[0] == '\0' && pPartType->drmInfo.szContentURI)
5329 strncpy(pPartType->szContentID, pPartType->drmInfo.szContentURI, MSG_MSG_ID_LEN);
5331 /* set title name (content name) */
5332 if (pPartType->param.szName[0] == '\0') {
5333 /* szName is vitual name, real filename is *.dcf or *.dm */
5334 if (pPartType->drmInfo.szContentName && pPartType->drmInfo.szContentName[0] != '\0') {
5335 /* In case of szContentName retrieved from DRM agent is exist. */
5336 pTmpBuf = pPartType->drmInfo.szContentName;
5337 } else if (pPartType->szContentLocation[0] != '\0') {
5338 /* In case of szContentLocation parsed from MMS header */
5339 pTmpBuf = strrchr(pPartType->szContentLocation, '/');
5340 if (pTmpBuf == NULL)
5341 pTmpBuf = pPartType->szContentLocation;
5343 /* use another name */
5344 /* possible NULL pointer assignment*/
5345 pTmpBuf = strdup("untitled");
5348 if ((pExt = strrchr(pTmpBuf, '.')) != NULL) {
5350 int fileNameLen = 0;
5353 extLen = strlen(pExt);
5354 tmpLen = strlen(pTmpBuf);
5355 fileNameLen = (tmpLen - extLen < MSG_LOCALE_FILENAME_LEN_MAX - extLen)?(tmpLen - extLen):(MSG_LOCALE_FILENAME_LEN_MAX - extLen);
5356 strncpy(pPartType->param.szName, pTmpBuf, fileNameLen);
5357 strcpy (pPartType->param.szName + fileNameLen, pExt);
5359 strncpy(pPartType->param.szName, pTmpBuf, MSG_LOCALE_FILENAME_LEN_MAX);
5360 __MsgMakeFileName(pPartType->type, pPartType->param.szName, MSG_DRM_TYPE_NONE, 0);
5369 static bool __MsgIsText(int type)
5371 if (type == MIME_TEXT_PLAIN || type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML ||
5372 type == MIME_TEXT_X_VNOTE || type == MIME_APPLICATION_SMIL || type == MIME_TEXT_X_IMELODY) {
5381 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
5384 MsgMultipart *pTmpMultipart = NULL;
5385 MsgMultipart *pSelectedPart = NULL;
5386 MsgMultipart *pPrevPart = NULL;
5387 MsgMultipart *pFirstPart = NULL;
5388 MsgMultipart *pLastPart = NULL;
5389 MsgMultipart *pRemoveList = NULL;
5390 MsgMultipart *pNextRemovePart = NULL;
5392 switch (pPartType->type) {
5393 case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
5394 case MIME_MULTIPART_ALTERNATIVE:
5397 * Policy: multipart/alternative
5398 * multipart/alternative message has only several parts of media.
5399 * You should choose one of them and make the alternative part
5400 * to the selected media part.
5403 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE\n");
5405 pSelectedPart = pPartBody->body.pMultipart;
5407 // NULL Pointer check!!
5408 if (pSelectedPart == NULL) {
5409 MSG_DEBUG("MsgResolveNestedMultipart : multipart(ALTERNATIVE) does not exist\n");
5413 pTmpMultipart = pPartBody->body.pMultipart->pNext;
5415 while (pTmpMultipart) {
5416 if (pSelectedPart->type.type <= pTmpMultipart->type.type)
5417 pSelectedPart = pTmpMultipart;
5419 pTmpMultipart = pTmpMultipart->pNext;
5422 pTmpMultipart = pPartBody->body.pMultipart;
5425 while (pTmpMultipart) {
5426 if (pSelectedPart == pTmpMultipart)
5429 pPrevPart = pTmpMultipart;
5430 pTmpMultipart = pTmpMultipart->pNext;
5433 if (pPrevPart == NULL) {
5434 /* selected part is the first part */
5435 pRemoveList = pSelectedPart->pNext;
5437 pPrevPart->pNext = pSelectedPart->pNext;
5438 pRemoveList = pPartBody->body.pMultipart;
5439 pPartBody->body.pMultipart = pSelectedPart;
5442 pSelectedPart->pNext = NULL;
5445 #ifdef __SUPPORT_DRM__
5446 MmsReleaseMsgDRMInfo(&pRemoveList->type.drmInfo);
5448 MmsReleaseMsgBody(pRemoveList->pBody, pRemoveList->type.type);
5450 free(pRemoveList->pBody);
5454 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
5455 MSG_DEBUG("MsgResolveNestedMultipart : MsgPriorityCopyMsgType failed \n");
5459 if (pSelectedPart->pBody != NULL)
5460 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
5462 if (pSelectedPart != NULL) {
5463 #ifdef __SUPPORT_DRM__
5464 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5467 if (pSelectedPart->pBody != NULL) {
5468 free(pSelectedPart->pBody);
5469 pSelectedPart->pBody = NULL;
5471 free(pSelectedPart);
5472 pSelectedPart = NULL;
5477 case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
5478 case MIME_MULTIPART_RELATED:
5480 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_RELATED\n");
5482 pSelectedPart = pPartBody->body.pMultipart;
5484 while (pSelectedPart) {
5485 if (__MsgIsMultipartMixed(pSelectedPart->type.type)) {
5487 if (pSelectedPart->pBody == NULL) {
5488 MSG_DEBUG("MsgResolveNestedMultipart :pSelectedPart->pBody(1) is NULL\n");
5492 pFirstPart = pSelectedPart->pBody->body.pMultipart;
5494 if (pFirstPart == NULL) {
5495 MSG_DEBUG("MsgResolveNestedMultipart : multipart(RELATED) does not exist\n");
5499 if (pFirstPart->pNext) {
5500 pLastPart = pFirstPart->pNext;
5501 while (pLastPart->pNext)
5502 pLastPart = pLastPart->pNext;
5504 pLastPart = pFirstPart;
5507 if (pPrevPart == NULL) {
5508 /* the first part */
5509 pTmpMultipart = pPartBody->body.pMultipart->pNext;
5510 pPartBody->body.pMultipart = pFirstPart;
5511 pLastPart->pNext = pTmpMultipart;
5513 pTmpMultipart = pSelectedPart->pNext;
5514 pPrevPart->pNext = pFirstPart;
5515 pLastPart->pNext = pTmpMultipart;
5518 if (pSelectedPart) {
5519 #ifdef __SUPPORT_DRM__
5520 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5522 free(pSelectedPart->pBody);
5523 free(pSelectedPart);
5525 pSelectedPart = pTmpMultipart;
5526 } else if (__MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
5527 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
5528 MmsReleaseMsgBody(pSelectedPart->pBody, pSelectedPart->type.type);
5530 free(pSelectedPart->pBody);
5531 free(pSelectedPart);
5532 pSelectedPart = pTmpMultipart;
5534 pPrevPart = pSelectedPart;
5535 pSelectedPart = pSelectedPart->pNext;
5542 case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
5543 case MIME_MULTIPART_MIXED:
5545 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_MIXED\n");
5548 pSelectedPart = pPartBody->body.pMultipart;
5550 while (pSelectedPart) {
5551 if (MsgIsMultipart(pSelectedPart->type.type)) {
5552 if (pSelectedPart->pBody == NULL) {
5553 MSG_DEBUG("MsgResolveNestedMultipart :pSelectedPart->pBody(2) is NULL\n");
5557 pFirstPart = pSelectedPart->pBody->body.pMultipart;
5559 // NULL Pointer check!!
5560 if (pFirstPart == NULL) {
5561 MSG_DEBUG("MsgResolveNestedMultipart : multipart does not exist\n");
5565 if (pFirstPart->pNext) {
5566 pLastPart = pFirstPart->pNext;
5567 while (pLastPart->pNext)
5568 pLastPart = pLastPart->pNext;
5570 pLastPart = pFirstPart;
5573 if (pPrevPart == NULL) {
5574 /* the first part */
5575 pTmpMultipart = pPartBody->body.pMultipart->pNext;
5576 pPartBody->body.pMultipart = pFirstPart;
5577 pLastPart->pNext = pTmpMultipart;
5579 pTmpMultipart = pSelectedPart->pNext;
5580 pPrevPart->pNext = pFirstPart;
5581 pLastPart->pNext = pTmpMultipart;
5584 if (pSelectedPart->pBody->pPresentationBody)
5585 pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
5587 memcpy(&pPartBody->presentationType,
5588 &pSelectedPart->pBody->presentationType, sizeof(MsgType));
5590 pPartType->type = pSelectedPart->type.type;
5592 #ifdef __SUPPORT_DRM__
5593 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5595 free(pSelectedPart->pBody);
5596 free(pSelectedPart);
5598 pSelectedPart = pTmpMultipart;
5600 pPrevPart = pSelectedPart;
5601 pSelectedPart = pSelectedPart->pNext;
5607 case MIME_MULTIPART_REPORT:
5609 MSG_DEBUG("MsgResolveNestedMultipart : MIME_MULTIPART_REPORT \n");
5611 pTmpMultipart = pPartBody->body.pMultipart;
5614 if (pTmpMultipart == NULL) {
5615 MSG_DEBUG("MsgResolveNestedMultipart : pTmpMultipart == NULL \n");
5619 while (pTmpMultipart) {
5620 if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
5621 pSelectedPart = pTmpMultipart;
5625 pPrevPart = pTmpMultipart;
5626 pTmpMultipart = pTmpMultipart->pNext;
5629 if (pSelectedPart == NULL) {
5630 MSG_DEBUG("MsgResolveNestedMultipart : MIME_MULTIPART_REPORT [no selected part]\n");
5632 pRemoveList = pPartBody->body.pMultipart->pNext;
5633 if (pPartBody->body.pMultipart != NULL) {
5634 pSelectedPart = pPartBody->body.pMultipart;
5635 pSelectedPart->pNext = NULL;
5638 if (pPrevPart == NULL) {
5639 // first part is selected
5640 pRemoveList = pPartBody->body.pMultipart->pNext;
5642 pRemoveList = pPartBody->body.pMultipart->pNext;
5643 pPrevPart->pNext = pSelectedPart->pNext;
5646 pSelectedPart->pNext = NULL;
5647 pPartBody->body.pMultipart = pSelectedPart;
5650 pTmpMultipart = pRemoveList;
5652 while (pTmpMultipart) {
5653 #ifdef __SUPPORT_DRM__
5654 MmsReleaseMsgDRMInfo(&pTmpMultipart->type.drmInfo);
5656 MmsReleaseMsgBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
5657 pNextRemovePart = pTmpMultipart->pNext;
5659 free(pTmpMultipart->pBody);
5660 free(pTmpMultipart);
5661 pTmpMultipart = pNextRemovePart;
5664 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
5665 MSG_DEBUG("MsgResolveNestedMultipart : MsgPriorityCopyMsgType failed \n");
5669 if (pSelectedPart != NULL) {
5671 if (pSelectedPart->pBody != NULL)
5672 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
5674 #ifdef __SUPPORT_DRM__
5675 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5677 if (pSelectedPart->pBody != NULL) {
5678 free(pSelectedPart->pBody);
5679 pSelectedPart->pBody = NULL;
5681 free(pSelectedPart);
5682 pSelectedPart = NULL;
5699 char *MsgResolveContentURI(char *szSrc)
5701 char *szTemp = NULL;
5702 char *szReturn = NULL;
5705 if (szSrc == NULL) {
5709 if (szSrc[0] == '\0')
5713 if (!strncasecmp(szSrc, "cid:", 4)) {
5714 length = strlen(szSrc) - 3;
5717 length = strlen(szSrc) + 1;
5720 szTemp = (char *)malloc(length);
5721 if (szTemp == NULL) {
5722 MSG_DEBUG("MsgResolveContentURI: memory full\n");
5726 memset(szTemp, 0, length);
5727 strcpy(szTemp, szSrc);
5729 szReturn = MsgChangeHexString(szTemp);
5743 char *MsgRemoveQuoteFromFilename(char *pSrc)
5745 int cLen = 0; // length of pBuff
5749 MSG_DEBUG("MsgRemoveQuoteFromFilename: pSrc is Null\n");
5753 cLen = strlen(pSrc);
5755 pBuff = (char *)malloc(cLen + 1);
5757 if (pBuff == NULL) {
5758 MSG_DEBUG("MsgRemoveQuoteFromFilename: pBuff mem alloc fail!\n");
5761 memset(pBuff, 0 , sizeof(char)*(cLen + 1));
5763 // remove front quote
5764 if (pSrc[0] == MSG_CH_QUOT) {
5766 strncpy(pBuff, &pSrc[1], cLen);
5770 if (pSrc[0] == MSG_CH_LF) {
5772 strncpy(pBuff, &pSrc[1], cLen);
5774 strcpy(pBuff, pSrc);
5777 // remove last qoute
5778 if (pBuff[cLen-1] == MSG_CH_QUOT) {
5779 pBuff[cLen-1] = '\0';
5785 bool MsgIsMultipart(int type)
5787 if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
5788 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
5789 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
5797 static bool __MsgIsHexChar(char *pSrc)
5803 cLen = strlen(pSrc);
5805 for (cIndex = 0; cIndex < cLen ; cIndex++) {
5806 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
5807 (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
5817 static char __MsgConvertHexValue(char *pSrc)
5823 unsigned char uCh[2] = {0,};
5825 cLen = strlen(pSrc);
5827 for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
5828 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
5829 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
5830 ch = (int)uCh[0]<<4|uCh[1];
5833 ResultChar = (char)ch;
5838 static int __MsgConvertCharToInt(char ch)
5840 if (ch>='0' && ch<='9') {
5842 } else if (ch>='a'&& ch <='f') {
5844 } else if (ch>='A'&& ch <='F') {
5851 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
5853 if(!pMsgType1 || !pMsgType2)
5856 if (pMsgType1->section == INVALID_HOBJ)
5857 pMsgType1->section = pMsgType2->section;
5859 #ifdef __SUPPORT_DRM__
5862 if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
5863 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
5866 if (pMsgType1->szContentID[0] == '\0') {
5867 strcpy(pMsgType1->szContentID, pMsgType2->szContentID);
5869 if (pMsgType2->szContentID[0]) {
5870 length = MsgStrlen(pMsgType2->szContentID);
5871 if (pMsgType2->szContentID[0] == '<' && pMsgType2->szContentID[length - 1] == '>') {
5872 pMsgType1->drmInfo.szContentURI = MsgStrNCopy(pMsgType2->szContentID + 1, length - 2);
5874 pMsgType1->drmInfo.szContentURI = MsgStrCopy(pMsgType2->szContentID);
5878 length = MsgStrlen(pMsgType1->szContentID);
5879 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
5880 pMsgType1->drmInfo.szContentURI = MsgStrNCopy(pMsgType1->szContentID + 1, length - 2);
5882 pMsgType1->drmInfo.szContentURI = MsgStrCopy(pMsgType1->szContentID);
5887 if (pMsgType1->szContentLocation[0] == '\0')
5888 strcpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation);
5890 /* Copy informations - we shoud open the pMsgType2's orgFile
5891 * concerning its offset and size.
5893 if (pMsgType2->szOrgFilePath[0] != '\0')
5894 strcpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath);
5896 if (pMsgType2->disposition != INVALID_HOBJ)
5897 pMsgType1->disposition = pMsgType2->disposition;
5899 if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
5900 pMsgType2->encoding != INVALID_HOBJ)
5901 pMsgType1->encoding = pMsgType2->encoding;
5903 pMsgType1->contentSize = pMsgType2->contentSize;
5904 pMsgType1->offset = pMsgType2->offset;
5905 pMsgType1->size = pMsgType2->size;
5906 pMsgType1->type = pMsgType2->type;
5908 __MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
5910 if (pMsgType1->param.szName[0]) {
5911 #ifdef __SUPPORT_DRM__
5912 pMsgType1->drmInfo.szContentName = MsgStrCopy(pMsgType2->param.szName);
5919 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
5921 if (pParam1->charset == MSG_CHARSET_UNKNOWN)
5922 pParam1->charset = pParam2->charset;
5924 if (pParam1->type == MIME_UNKNOWN)
5925 pParam1->type = pParam2->type;
5927 /* Don't copy pParam2->pPresentation */
5929 /* For alternative: copy the boundary string */
5930 if (pParam2->szBoundary[0] !='\0')
5931 strcpy(pParam1->szBoundary, pParam2->szBoundary);
5933 if (pParam1->szFileName[0] =='\0')
5934 strcpy(pParam1->szFileName, pParam2->szFileName);
5936 if (pParam1->szName[0] =='\0')
5937 strcpy(pParam1->szName, pParam2->szName);
5939 if (pParam1->szStart[0] =='\0')
5940 strcpy(pParam1->szStart, pParam2->szStart);
5942 if (pParam1->szStartInfo[0] =='\0')
5943 strcpy(pParam1->szStartInfo, pParam2->szStartInfo);
5948 static bool __MsgIsMultipartMixed(int type)
5950 if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
5957 bool MmsGetMsgAttrib(MmsMsgID msgID, MmsAttrib* pAttrib)
5959 MmsMsg *pMsg = NULL;
5961 memset(pAttrib, 0, sizeof(MmsAttrib));
5962 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
5963 memcpy(pAttrib, &(pMsg->mmsAttrib), sizeof(MmsAttrib));
5965 MSG_DEBUG("MmsGetMsgAttrib: msgID = %lu ---------------------\n", msgID);
5967 if ('\0' != pMsg->szTrID[0])
5968 MSG_DEBUG("szTrID = %s \n", pMsg->szTrID);
5974 static bool __MsgIsInvalidFileNameChar(char ch)
5976 if ((ch == 0x5C /* \ */) ||
5977 (ch == 0x2F /* / */) ||
5978 (ch == 0x3A /* : */) ||
5979 (ch == 0x2A /* * */) ||
5980 (ch == 0x3F /* ? */) ||
5981 (ch == 0x22 /* " */) ||
5982 (ch == 0x3C /* < */) ||
5983 (ch == 0x3E /* > */) ||
5984 (ch == 0x7C /* | */))
5990 bool MmsDataUpdateLastStatus(MmsMsg *pMsg)
5992 MmsMsgMultiStatus* pStatus = NULL;
5994 pStatus = pMsg->mmsAttrib.pMultiStatus;
5996 while (pStatus != NULL) {
5997 pStatus->bDeliveyrReportIsLast = false;
5998 pStatus->bReadReplyIsLast = false;
5999 pStatus = pStatus->pNext;
6006 bool MmsAddrUtilCompareAddr(char *pszAddr1, char *pszAddr2)
6012 MmsAddrUtilRemovePlmnString(pszAddr1);
6013 MmsAddrUtilRemovePlmnString(pszAddr2);
6015 MSG_DEBUG("##### pszAddr1 = %s #####", pszAddr1);
6016 MSG_DEBUG("##### pszAddr2 = %s #####", pszAddr2);
6017 if (!strcmp(pszAddr1, pszAddr2))
6020 len1 = strlen(pszAddr1);
6021 len2 = strlen(pszAddr2);
6024 p = strstr(pszAddr1, pszAddr2);
6026 p = strstr(pszAddr2, pszAddr1);
6035 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
6039 MSG_DEBUG("MsgGetLatin2UTFCodeSize: --------------- \n");
6041 if ((szSrc == NULL) || (nChar <= 0)) {
6042 MSG_DEBUG("MsgGetLatin2UTFCodeSize: szSrc is NULL !!!! --------------- \n");
6046 while ((nChar > 0) && (*szSrc != '\0')) {
6047 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
6061 static int __MsgLatin5code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6066 unsigned short temp = 0;
6069 outBufSize--; //Null Character
6071 while ((nChar > 0) && (*szSrc != '\0')) {
6073 if (*szSrc >= 0x01 && *szSrc <= 0x7F) { //basic common
6074 temp = (unsigned short)(*szSrc);
6080 *des = (unsigned char) ((*szSrc) & 0x007F);
6085 } else if ((*szSrc == 0x00) || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6086 (*szSrc >= 0xA0 && *szSrc <= 0xCF) || (*szSrc >= 0xD1 && *szSrc <= 0xDC) ||
6087 (*szSrc >= 0xDF && *szSrc <= 0xEF) || (*szSrc >= 0xF1 && *szSrc <= 0xFC) ||
6088 (*szSrc == 0xFF)) {//uni 0x00A0 ~ 0x00CF
6090 temp = (unsigned short)(*szSrc);
6096 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6097 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6099 *des = 0xC0 | (t1 & 0x1F);
6100 *(des+1) = 0x80 | (t2 & 0x3F);
6105 } else if (*szSrc == 0xD0) {//empty section OR vendor specific codes.
6113 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6114 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6116 *des = 0xC0 | (t1 & 0x1F);
6117 *(des+1) = 0x80 | (t2 & 0x3F);
6122 } else if (*szSrc == 0xDD) {
6129 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6130 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6132 *des = 0xC0 | (t1 & 0x1F);
6133 *(des+1) = 0x80 | (t2 & 0x3F);
6138 } else if (*szSrc == 0xDE) {
6145 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6146 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6148 *des = 0xC0 | (t1 & 0x1F);
6149 *(des+1) = 0x80 | (t2 & 0x3F);
6154 } else if (*szSrc == 0xF0) {
6160 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6161 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6163 *des = 0xC0 | (t1 & 0x1F);
6164 *(des+1) = 0x80 | (t2 & 0x3F);
6169 } else if (*szSrc == 0xFD) {
6177 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6178 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6180 *des = 0xC0 | (t1 & 0x1F);
6181 *(des+1) = 0x80 | (t2 & 0x3F);
6186 } else if (*szSrc == 0xFE) {
6193 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6194 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6196 *des = 0xC0 | (t1 & 0x1F);
6197 *(des+1) = 0x80 | (t2 & 0x3F);
6211 static int __MsgGetLatin52UTFCodeSize(unsigned char *szSrc, int nChar)
6215 MSG_DEBUG("MsgGetLatin52UTFCodeSize: --------------- \n");
6217 if ((szSrc == NULL) || (nChar <= 0))
6220 while ((nChar > 0) && (*szSrc != '\0')) {
6221 if (*szSrc >= 0x01 && *szSrc <= 0x7F) {
6225 } else if (*szSrc == 0x00 || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6226 (*szSrc >= 0xA0 && *szSrc <= 0xCF) || (*szSrc >= 0xD1 && *szSrc <= 0xDC) |
6227 (*szSrc >= 0xDF && *szSrc <= 0xEF) || (*szSrc >= 0xF1 && *szSrc <= 0xFC) ||
6228 *szSrc == 0xD0 || *szSrc == 0xDD || *szSrc == 0xDE || *szSrc == 0xF0 ||
6229 *szSrc == 0xFD || *szSrc == 0xFE || *szSrc == 0xFF) { //uni 0x00A0 ~ 0x00CF
6240 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6243 unsigned char t1, t2;
6245 MSG_DEBUG("MsgLatin2UTF: --------------- \n");
6248 outBufSize--; // NULL character
6250 while ((nChar > 0) && (*szSrc != '\0')) {
6251 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
6252 /* check outbuffer's room for this UTF8 character */
6258 *des = (unsigned char) (*szSrc & 0x007F);
6264 /* check outbuffer's room for this UTF8 character */
6270 t2 = (unsigned char) (*szSrc & 0x003F); // right most 6 bit
6271 t1 = (unsigned char) ((*szSrc & 0xC0) >> 6); // right most 2 bit
6273 *des = 0xC0 | (t1 & 0x1F);
6274 *(des + 1) = 0x80 | (t2 & 0x3F);
6289 static int __MsgLatin7code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6295 unsigned short temp = 0;
6297 MSG_DEBUG("MsgUnicode2UTF: --------------- \n");
6300 outBufSize--; //Null Character
6302 while ((nChar > 0) && (*szSrc != '\0')) {
6303 if (*szSrc >= 0x01 && *szSrc <= 0x7F) {
6304 temp = (unsigned short)(*szSrc);
6310 *des = (unsigned char) (temp & 0x007F);
6316 } else if ((*szSrc == 0x00) || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6317 (*szSrc >= 0xA3 && *szSrc <= 0xAD) || (*szSrc == 0xBB)) { // consider 0xA4, 0xA5
6319 temp = (unsigned short)(*szSrc);
6325 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6326 t1 = (unsigned char) ((temp & 0xC0) >> 6); // right most 2 bit
6328 *des = 0xC0 | (t1 & 0x1F);
6329 *(des + 1) = 0x80 | (t2 & 0x3F);
6334 } else if (*szSrc == 0xA0) {
6336 //*des = temp to utf-8
6341 *des = (unsigned char) (temp & 0x007F);
6347 } else if (*szSrc == 0xA1) {
6354 t3 = (unsigned char) (temp & 0x003F); // right most 6 bit
6355 t2 = (unsigned char) ((temp & 0x0FC0) >> 6); // right most 6 bit
6356 t1 = (unsigned char) ((temp & 0xF000) >> 12); // right most 4 bit
6358 *des = 0xE0 | (t1 & 0x0F);
6359 *(des+1) = 0x80 | (t2 & 0x3F);
6360 *(des+2) = 0x80 | (t3 & 0x3F);
6366 } else if (*szSrc == 0xA2) {
6373 t3 = (unsigned char) (temp & 0x003F); // right most 6 bit
6374 t2 = (unsigned char) ((temp & 0x0FC0) >> 6); // right most 6 bit
6375 t1 = (unsigned char) ((temp & 0xF000) >> 12); // right most 4 bit
6377 *des = 0xE0 | (t1 & 0x0F);
6378 *(des+1) = 0x80 | (t2 & 0x3F);
6379 *(des+2) = 0x80 | (t3 & 0x3F);
6385 } else if (*szSrc == 0xAF) {
6392 t3 = (unsigned char) (temp & 0x003F); // right most 6 bit
6393 t2 = (unsigned char) ((temp & 0x0FC0) >> 6); // right most 6 bit
6394 t1 = (unsigned char) ((temp & 0xF000) >> 12); // right most 4 bit
6396 *des = 0xE0 | (t1 & 0x0F);
6397 *(des+1) = 0x80 | (t2 & 0x3F);
6398 *(des+2) = 0x80 | (t3 & 0x3F);
6404 } else if (0xB0 <= *szSrc && *szSrc <= 0xB4) { //0x00B0 ~ 0x00B4
6406 temp = (unsigned short)(*szSrc);
6412 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6413 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6415 *des = 0xC0 | (t1 & 0x1F);
6416 *(des+1) = 0x80 | (t2 & 0x3F);
6422 } else if ((0xB5 <= *szSrc && *szSrc <= 0xBA) ||
6423 (0xBC <= *szSrc && *szSrc <= 0xD1) ||
6424 (0xD3 <= *szSrc && *szSrc <= 0xFE)) {
6425 temp= (unsigned short)(*szSrc + 0x02D0);
6431 t2 = (unsigned char) (temp & 0x003F); // right most 6 bit
6432 t1 = (unsigned char) ((temp & 0x07C0) >> 6); // right most 5 bit
6434 *des = 0xC0 | (t1 & 0x1F);
6435 *(des+1) = 0x80 | (t2 & 0x3F);
6452 static int __MsgGetLatin72UTFCodeSize(unsigned char *szSrc, int nChar)
6456 MSG_DEBUG("MsgGetLatin72UTFCodeSize: --------------- \n");
6458 if ((szSrc == NULL) || (nChar <= 0))
6461 while ((nChar > 0) && (*szSrc != '\0')) {
6463 if ((*szSrc >= 0x01 && *szSrc <= 0x7F) || (*szSrc == 0xA0)) {
6467 } else if (*szSrc == 0x00 || (0x80 <= *szSrc && *szSrc <= 0x9F) || (0xA3 <= *szSrc && *szSrc <= 0xAD) ||
6468 (0xB0 <= *szSrc && *szSrc <= 0xB4) || (0xB5 <= *szSrc && *szSrc <= 0xFE)) {
6472 } else if (*szSrc == 0xA1 ||*szSrc == 0xA2 || *szSrc == 0xAF) {
6484 static int __MsgUnicode2UTF(unsigned char *des, int outBufSize, unsigned short *szSrc, int nChar)
6491 MSG_DEBUG("MsgUnicode2UTF: --------------- \n");
6494 outBufSize--; // NULL character
6496 while ((nChar > 0) && (*szSrc != '\0')) {
6497 if (0x0001 <= *szSrc && *szSrc <= 0x007F) {
6498 /* check outbuffer's room for this UTF8 character */
6504 *des = (unsigned char) (*szSrc & 0x007F);
6509 } else if ((*szSrc == 0x0000) || (0x0080 <= *szSrc && *szSrc <= 0x07FF)) {
6510 /* check outbuffer's room for this UTF8 character */
6516 t2 = (unsigned char) (*szSrc & 0x003F); // right most 6 bit
6517 t1 = (unsigned char) ((*szSrc & 0x07C0) >> 6); // right most 5 bit
6519 *des = 0xC0 | (t1 & 0x1F);
6520 *(des+1) = 0x80 | (t2 & 0x3F);
6526 /* check outbuffer's room for this UTF8 character */
6532 t3 = (unsigned char) (*szSrc & 0x003F); // right most 6 bit
6533 t2 = (unsigned char) ((*szSrc & 0x0FC0) >> 6); // right most 6 bit
6534 t1 = (unsigned char) ((*szSrc & 0xF000) >> 12); // right most 4 bit
6536 *des = 0xE0 | (t1 & 0x0F);
6537 *(des+1) = 0x80 | (t2 & 0x3F);
6538 *(des+2) = 0x80 | (t3 & 0x3F);
6552 static int __MsgGetUnicode2UTFCodeSize(unsigned short *szSrc, int nChar)
6556 MSG_DEBUG("MsgGetUnicode2UTFCodeSize: --------------- \n");
6558 if ((szSrc == NULL) || (nChar <= 0)) {
6559 MSG_DEBUG("MsgGetUnicode2UTFCodeSize: szSrc is NULL !!!! --------------- \n");
6563 while ((nChar > 0) && (*szSrc != '\0')) {
6564 if (0x0001 <= *szSrc && *szSrc <= 0x007F) {
6568 } else if ((*szSrc == 0x0000) || (0x0080 <= *szSrc && *szSrc <= 0x07FF)) {
6582 static bool __MmsAddrUtilCheckEmailAddress(char *pszAddr)
6584 if (!pszAddr || pszAddr[0] == 0)
6587 if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
6593 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
6595 char *pszAddrCopy = NULL;
6596 char *pszStrStart = NULL;
6597 char *pszStrTemp = NULL;
6600 if ((!pszAddr) || (pszAddr[0] == 0)) {
6601 MSG_DEBUG("MmsAddrUtilRemovePlmnString: pszAddr is null or zero\n");
6605 strLen = strlen(pszAddr);
6607 pszAddrCopy = (char*)calloc(1,strLen + 1);
6609 MSG_DEBUG("MmsAddrUtilRemovePlmnString: pszAddrCopy is NULL, mem alloc failed\n");
6613 strcpy(pszAddrCopy, pszAddr);
6617 pszStrStart = pszAddrCopy;
6620 char* pszStrEnd = NULL;
6623 if (__MmsAddrUtilCheckEmailAddress(pszAddrCopy))
6624 pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
6626 pszStrEnd = strstr(pszStrStart, "/");
6629 // "/TYPE=PLMN" not found
6631 int remainedLen = strlen(pszStrStart);
6633 if (remainedLen <= 0)
6636 strcat(pszAddr, pszStrStart);
6641 // Get one address length
6642 addressLen = pszStrEnd - pszStrStart;
6644 strncat(pszAddr, pszStrStart, addressLen);
6646 // Find next address
6647 pszStrStart = pszStrEnd;
6649 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
6652 addressLen = pszStrTemp - pszStrEnd;
6653 pszStrStart += addressLen;
6655 pszStrStart += strlen(pszStrEnd);
6658 if (pszStrStart[0] == 0) // end of string
6662 strcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER); // add ';'
6663 pszStrStart++; // remove ';'
6666 if (pszAddr[0] == 0)
6667 strcpy(pszAddr, pszAddrCopy);
6674 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6678 MSG_DEBUG("MsgCutUTFString: --------------- \n");
6681 outBufSize--; // NULL character
6683 while ((nChar > 0) && (*szSrc != '\0')) {
6684 if (*szSrc < 0x80) {
6692 } else if (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
6698 *(des + 1) = *(szSrc + 1);
6702 } else if ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
6708 *(des + 1) = *(szSrc + 1);
6709 *(des + 2) = *(szSrc + 2);
6721 MSG_DEBUG("MsgCutUTFString: utf8 incorrect range!\n");
6733 static void __MsgMIMERemoveQuote(char *szSrc)
6737 length = MsgStrlen(szSrc);
6738 if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
6741 for (index = 0; index < length-2; index++)
6742 szSrc[index] = szSrc[index+1];
6743 szSrc[index] = '\0';
6747 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
6753 MSG_DEBUG("MsgLoadDataToDecodeBuffer: \n");
6755 if (pFile == NULL) {
6762 if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
6769 if (*pBufLen == 0) {
6770 length = maxLen - (*pPtr);
6772 length = (*pBufLen) - (*pPtr);
6778 if ((*ppBuf) == NULL) {
6779 memset(pInBuf1, 0, maxLen);
6781 } else if ((*ppBuf) == pInBuf1) {
6782 memset(pInBuf2, 0, maxLen);
6784 memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
6787 memset(pInBuf1, 0, maxLen);
6789 memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
6795 if (*pOffset == endOfFile) {
6800 if (maxLen == length) {
6802 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
6807 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
6810 *pBufLen = length + nRead;
6813 if ((*pOffset = MsgFtell(pFile)) == -1L) {
6814 MSG_DEBUG("MsgFtell Error");
6824 bool MsgGetTypeByFileName(int *type, char *szFileName)
6827 AvCodecType AvType = AV_CODEC_NONE;
6829 pExt = strrchr(szFileName, '.');
6830 if (pExt == NULL || pExt[0] == '\0')
6835 if (strcasecmp(pExt, "mp4") == 0 ||strcasecmp(pExt, "mpeg4") == 0 ||strcasecmp(pExt, "3gp") == 0 ||strcasecmp(pExt, "3gpp") == 0) {
6837 if (szFileName[0] != '/')
6840 AvType = AvGetFileCodecType(szFileName);
6841 MSG_DEBUG("MsgGetTypeByFileName:AvType(0x%x)\n", AvType);
6844 case AV_DEC_AUDIO_MPEG4:
6845 *type = MIME_AUDIO_MP4;
6848 case AV_DEC_VIDEO_MPEG4:
6849 *type = MIME_VIDEO_MP4;
6853 *type = MIME_VIDEO_3GPP;
6859 if (strcasecmp(pExt, "amr") == 0) {
6860 *type = MIME_AUDIO_AMR;
6862 } else if ((strcasecmp(pExt, "mid") == 0) || (strcasecmp(pExt, "midi") == 0)) {
6863 *type = MIME_AUDIO_MIDI;
6865 } else if (strcasecmp(pExt, "imy") == 0) {
6866 *type = MIME_TEXT_X_IMELODY;
6870 *type = MimeGetMimeFromExtInt((const char*)pExt);
6871 MSG_DEBUG("MsgGetTypeByFileName: szFileName = %s type = %d \n", szFileName, type);
6877 *type = MIME_UNKNOWN;
6878 MSG_DEBUG("MsgGetTypeByFileName: szFileName = %s type = %d \n", szFileName, type);
6886 * This function write media data from raw data to file.
6889 * @param pszMailboxPath : path of mailbox
6890 * @param pszMsgFilename : name of msg file
6891 * @param index : used for file naming
6892 * @param bSave : if true, file will be save otherwise just filename will be stored.
6894 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
6897 char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, }; // file name of temp file
6898 char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; // full absolute path of temp file.
6900 MSG_DEBUG("**** _MmsSaveMediaData: [Multi part] START ***\n");
6903 MSG_DEBUG("pPartType is NULL\n");
6907 if (pPartType->type == MIME_APPLICATION_SMIL) {
6908 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", "smil.txt");
6910 if (pPartType->param.szName[0] != '\0') {
6911 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szName);
6912 } else if (pPartType->param.szFileName[0] != '\0') {
6913 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szFileName);
6915 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
6920 #ifndef __SUPPORT_DRM__
6921 __MsgMakeFileName(pPartType->type, szFileName, 0); //FL & CD -> extension(.dm) SD -> extension(.dcf)
6923 __MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0); //FL & CD -> extension(.dm) SD -> extension(.dcf)
6924 if (MsgDRMIsForwardLockType(pPartType->drmInfo.drmType))
6925 MsgChangeDrm2FileName(szFileName);
6929 snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName); // get absolute path of each temp file of each part
6930 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.
6932 if (pPartType->param.szName[0] == '\0') {
6933 snprintf(pPartType->param.szName, MSG_LOCALE_FILENAME_LEN_MAX+1, "%s", szFileName);
6934 MSG_DEBUG("Set Name : %s", pPartType->param.szName);
6937 if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
6938 MsgGetTypeByFileName(&pPartType->type, szFullPath);
6942 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
6943 MSG_DEBUG("MsgOpenFile failed");
6947 if (__MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
6948 MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
6952 MsgCloseFile(pFile);
6955 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
6956 pPartBody->offset = 0;
6957 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
6959 MSG_DEBUG("Save Temp File to [%s]", pPartBody->szOrgFilePath);
6961 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
6962 MsgDrmRegisterFile(MSG_MODE_FILE, szFullPath, strlen(szFullPath));
6964 /* change szDrm2FullPath as current content path*/
6965 if (pPartType->drmInfo.szDrm2FullPath) {
6966 free(pPartType->drmInfo.szDrm2FullPath);
6967 pPartType->drmInfo.szDrm2FullPath = MsgStrCopy(szFullPath);
6972 MSG_DEBUG("**** MmsGetMediaPartData: [Multi part] E N D (Successfully) ***\n");
6978 if (pFile != NULL) {
6979 MsgCloseFile(pFile);
6986 static bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
6991 char *pNewData = NULL;
6992 char *pTempData = NULL;
6993 int msgEncodingValue = 0;
6994 int msgTypeValue = 0;
6995 int msgCharsetValue = 0;
7001 msgEncodingValue = pPartType->encoding;
7002 msgTypeValue = pPartType->type;
7003 msgCharsetValue = pPartType->param.charset;
7005 cidLen = MsgStrlen(szCid);
7007 offset = pPartBody->offset;
7008 size = pPartBody->size;
7010 if (pPartBody->szOrgFilePath[0]) {
7011 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
7013 if (pTempData == NULL) {
7014 MSG_DEBUG("MmsGetMediaPartData : pTempData read fail\n");
7019 } else if (pPartBody->body.pText) {
7020 pData = pPartBody->body.pText;
7021 nRead = pPartBody->size;
7024 if (pData == NULL) {
7025 MSG_DEBUG("MmsGetMediaPartData : there is no data \n");
7029 pNewData = __MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
7030 pPartType->encoding = MSG_ENCODING_BINARY;
7032 if (__MsgIsText(msgTypeValue))
7033 pPartType->param.charset = MSG_CHARSET_UTF8;
7035 if (MsgWriteFile(pNewData, sizeof(char), nRead2, pFile) != (size_t)nRead2) {
7036 MSG_DEBUG("MmsGetMediaPartData: file writing fail \n");
7070 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
7076 unsigned short *mszTempStr = NULL;
7077 char *pConvertedStr = NULL;
7078 char *pConvertedData = NULL;
7079 char *pNewData = NULL;
7080 char *pReturnData = NULL;
7083 switch (msgEncodingValue) {
7084 case MSG_ENCODING_BASE64:
7086 pConvertedData = (char*)MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
7087 MSG_DEBUG("MmsGetBinaryUTF8Data : MSG_ENCODING_BASE64 bodyLength = %d \n", nByte);
7089 pTemp = pConvertedData;
7094 case MSG_ENCODING_QUOTE_PRINTABLE:
7096 pConvertedData = (char*)MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
7097 MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_ENCODING_QUOTE_PRINTABLE bodyLength = %d \n", nByte);
7099 pTemp = pConvertedData;
7106 MSG_DEBUG("MmsGetBinaryUTF8Data: 8bit OR Binary bodyLength = %d \n", nRead);
7114 if (__MsgIsText(msgTypeValue)) {
7115 /* charset converting */
7117 switch (msgCharsetValue) {
7118 case MSG_CHARSET_UTF16:
7119 case MSG_CHARSET_USC2:
7121 MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_USC2 \n");
7123 if (((UINT8)pTemp[0]) == 0xFF && ((UINT8)pTemp[1]) == 0xFE) {
7124 nChar = (nTemp / 2 - 1);
7126 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
7127 if (mszTempStr == NULL) {
7128 MSG_DEBUG("MmsGetBinaryUTF8Data : 1. Memory Full !!! \n");
7132 memcpy(mszTempStr, ((unsigned short*)pTemp + 1), nChar * sizeof(unsigned short));
7134 nByte = __MsgGetUnicode2UTFCodeSize(((unsigned short*)pTemp + 1), nChar);
7136 nByte = 3; //min value
7138 pConvertedStr = (char *)malloc(nByte + 1);
7139 if (pConvertedStr != NULL)
7140 __MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
7142 nChar = (nTemp / 2);
7144 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
7145 if (mszTempStr == NULL) {
7146 MSG_DEBUG("MmsGetBinaryUTF8Data: 2. Memory Full !!! \n");
7150 memcpy(mszTempStr, ((unsigned short*)pTemp), nChar * sizeof(unsigned short));
7152 nByte = __MsgGetUnicode2UTFCodeSize(((unsigned short*)pTemp), nChar);
7154 pConvertedStr = (char *)malloc(nByte + 1);
7156 __MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
7159 if (pConvertedStr != NULL)
7160 pNewData = pConvertedStr;
7162 *npRead = nByte + 1;
7166 case MSG_CHARSET_US_ASCII:
7168 MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_US_ASCII \n");
7172 case MSG_CHARSET_UTF8:
7174 MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_UTF8 or Others \n");
7176 // skip BOM (Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM)
7178 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
7188 case MSG_CHARSET_ISO_8859_7:
7192 MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_ISO_8859_7 \n");
7194 nByte = __MsgGetLatin72UTFCodeSize((unsigned char*)pTemp, nTemp);
7195 pConvertedStr = (char *)malloc(nByte + 1);
7197 __MsgLatin7code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7199 pNewData = pConvertedStr;
7200 *npRead = nByte + 1;
7204 case MSG_CHARSET_ISO_8859_9:
7207 MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_ISO_8859_9 \n");
7209 nByte = __MsgGetLatin52UTFCodeSize((unsigned char*)pTemp, nTemp);
7210 pConvertedStr = (char *)malloc(nByte + 1);
7212 __MsgLatin5code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7214 pNewData = pConvertedStr;
7215 *npRead = nByte + 1;
7221 MSG_DEBUG("MmsGetBinaryUTF8Data: Other charsets \n");
7223 nByte = __MsgGetLatin2UTFCodeSize((unsigned char*)pTemp, nTemp);
7224 pConvertedStr = (char *)malloc(nByte + 1);
7226 __MsgLatin2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7228 pNewData = pConvertedStr;
7229 *npRead = nByte + 1;
7238 pReturnData = (char *)malloc(*npRead);
7239 if (pReturnData == NULL) {
7240 MSG_DEBUG("MmsGetBinaryUTF8Data : pReturnData alloc fail. \n");
7245 if (pNewData != NULL) {
7246 memset(pReturnData, 0, *npRead);
7247 memcpy(pReturnData, pNewData, *npRead);
7250 if (pConvertedData) {
7251 free(pConvertedData);
7252 pConvertedData = NULL;
7255 if (pConvertedStr) {
7256 free(pConvertedStr);
7257 pConvertedStr = NULL;
7269 if (pConvertedData) {
7270 free(pConvertedData);
7271 pConvertedData = NULL;
7274 if (pConvertedStr) {
7275 free(pConvertedStr);
7276 pConvertedStr = NULL;
7287 #ifndef __SUPPORT_DRM__
7288 static bool __MsgMakeFileName(int iMsgType, char *szFileName, int nUntitleIndex)
7290 char szText[MSG_FILENAME_LEN_MAX+1]={0,};
7291 char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
7292 char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
7296 MSG_DEBUG("MsgMakeFileName: iMsgType = %d szFileName = %s \n", iMsgType, szFileName);
7298 if (szFileName == NULL)
7301 if (szFileName && (szFileName[0] != '\0')) {
7302 MsgGetFileNameWithoutExtension (szTempFileName, szFileName);
7304 pExt = strrchr(szTempFileName, '.');
7306 memset (szText, 0, MSG_FILENAME_LEN_MAX+1);
7307 strncpy(szText, szTempFileName, MSG_FILEPATH_LEN_MAX - 1);
7308 strcat(szText, "."); // add '.'
7310 memset (szText, 0, MSG_FILENAME_LEN_MAX+1);
7311 strncpy(szText, szTempFileName, pExt+1 - szFileName); // add '.'
7314 if (nUntitleIndex >= 1) {
7315 snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s_%d.", "Untitled", nUntitleIndex);
7317 snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s.", "Untitled");
7321 if (iMsgType == MIME_APPLICATION_OCTET_STREAM) {
7322 MSG_DEBUG("MsgMakeFileName: unsupported MsgType\n");
7326 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
7327 if (iMsgType == MIME_UNKNOWN || (pExt = MimeGetExtFromMimeInt((MimeType)iMsgType)) == NULL) {
7328 MSG_DEBUG("MsgMakeFileName: Failed to get extension of that mime data file. \n");
7331 nLen = MSG_FILENAME_LEN_MAX - strlen(szTemp);
7332 strncat(szTemp, pExt, nLen);
7336 strcpy(szFileName, szTemp);
7338 MSG_DEBUG("MsgMakeFileName: made szFileName = %s \n", szFileName);
7345 p = strrchr(szText, '.');
7348 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", szText);
7354 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex)
7356 char szText[MSG_FILENAME_LEN_MAX+1]={0,};
7357 char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
7358 char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
7361 MSG_DEBUG("MsgMakeFileName: iMsgType = 0x%x, drmType = %d, szFileName = %s \n", iMsgType, drmType, szFileName);
7363 if (szFileName == NULL)
7366 if (szFileName && (szFileName[0] != '\0')) {
7367 MsgGetFileNameWithoutExtension (szTempFileName, szFileName);
7369 if (drmType != MSG_DRM_TYPE_NONE) {
7370 pExt = strrchr(szTempFileName, '.');
7372 memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
7373 strncpy(szText, szTempFileName, MSG_FILENAME_LEN_MAX - 1);
7374 strcat(szText, "."); // add '.'
7376 memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
7377 strncpy(szText, szTempFileName, pExt+1 - szFileName);
7380 pExt = strrchr(szTempFileName, '.');
7382 memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
7383 strncpy(szText, szTempFileName, MSG_FILENAME_LEN_MAX - 1);
7384 strcat(szText, ".");
7390 if (nUntitleIndex >= 1) {
7391 snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s_%d.", "untitled", nUntitleIndex);
7393 snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s.", "untitled");
7397 if (drmType == MSG_DRM_TYPE_SD) {
7398 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
7399 strcat(szTemp, "dcf");
7400 } else if (MsgDRMIsForwardLockType(drmType)) {
7401 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 4);
7402 strcat(szTemp, "dm");
7404 if (iMsgType == MIME_APPLICATION_OCTET_STREAM) {
7405 MSG_DEBUG("MsgMakeFileName: unsupported MsgType\n");
7409 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
7410 //temporary commented to save file as original name.
7413 if (iMsgType == MIME_UNKNOWN || (pExt = MimeGetExtFromMimeInt((MimeType)iMsgType)) == NULL) {
7414 MSG_DEBUG("MsgMakeFileName: Failed to get extension of that mime data file. \n");
7419 nLen = MSG_FILENAME_LEN_MAX - strlen(szTemp);
7420 strncat(szTemp, pExt, nLen);
7424 strcpy(szFileName, szTemp);
7426 MSG_DEBUG("MsgMakeFileName: made szFileName = %s \n", szFileName);
7433 p = strrchr(szText, '.');
7436 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", szText);
7443 bool MsgGetFileNameWithoutExtension (char *szOutputName, char *szName)
7445 char *pszExt = NULL;
7447 if (szOutputName == NULL) {
7448 MSG_DEBUG("szOutputName is NULL");
7452 strncpy(szOutputName, szName, strlen(szName));
7454 if ((pszExt = strrchr(szOutputName, '.'))) {
7455 if (pszExt[0] == '.')
7462 int MmsGetMediaPartCount(msg_message_id_t msgId)
7466 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
7468 if (msgId != pMsg->msgID) {
7469 MSG_DEBUG("Invalid Message Id");
7473 return pMsg->nPartCount;
7476 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
7478 MmsMsg *pMsg = NULL;
7479 MsgMultipart *pPart = NULL;
7481 if (pHeader == NULL) {
7482 MSG_DEBUG("MmsGetMediaPartHeader: Invalid pHeader input. It's null \n");
7486 MmsPluginStorage::instance()->getMmsMessage(&pMsg);
7488 MmsInitMsgType(pHeader);
7491 /* Requires header of non-presentation */
7492 if (MsgIsMultipart(pMsg->msgType.type)) {
7493 MSG_DEBUG("MmsGetMediaPartHeader: Multipart header [index = %d] \n", index);
7495 pPart = pMsg->msgBody.body.pMultipart;
7497 while (pPart && index--)
7498 pPart = pPart->pNext;
7500 if (pPart == NULL) {
7501 MSG_DEBUG("MmsGetMediaPartHeader: There is no such msg part.\n");
7505 memcpy(pHeader, &pPart->type, sizeof(MsgType));
7507 MSG_DEBUG("MmsGetMediaPartHeader: Requires singlepart header \n");
7508 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
7514 static bool __MmsDebugPrintMulitpartEntry(MsgMultipart *pMultipart, int index)
7516 MSG_DEBUG("------------------------------\n");
7517 MSG_DEBUG("%dth multipart info\n", index);
7518 MSG_DEBUG("header size=%d\n", pMultipart->type.size);
7519 MSG_DEBUG("body size=%d\n", pMultipart->type.contentSize);
7520 MSG_DEBUG("content type=%s\n", MmsDebugGetMimeType((MimeType)pMultipart->type.type));
7521 MSG_DEBUG("content ID=%s\n", pMultipart->type.szContentID);
7522 MSG_DEBUG("content location=%s\n", pMultipart->type.szContentLocation);
7524 if (pMultipart->type.type == MIME_TEXT_PLAIN) {
7525 MSG_DEBUG("text info\n");
7526 MSG_DEBUG("charset=%d\n", pMultipart->type.param.charset);
7527 MSG_DEBUG("text file name=%s\n", pMultipart->type.param.szName);
7529 #ifdef __SUPPORT_DRM__
7530 if (pMultipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
7531 MSG_DEBUG("drm info\n");
7532 MSG_DEBUG("drm type=%d (0: NONE 1: Fowward Lock, 2:Combined Delivery, 3: Separated Delivery)\n", pMultipart->type.drmInfo.drmType);
7533 MSG_DEBUG("drm content type=%s\n", MmsDebugGetMimeType((MimeType)pMultipart->type.drmInfo.contentType));
7534 MSG_DEBUG("drm content URI=%s\n", pMultipart->type.drmInfo.szContentURI);
7535 MSG_DEBUG("drm2FullPath=%s\n", pMultipart->type.drmInfo.szDrm2FullPath);
7538 MSG_DEBUG("------------------------------\n");