1526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen/* 2526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Copyright (C) 2007-2008 Esmertec AG. 3526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Copyright (C) 2007-2008 The Android Open Source Project 4526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 5526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Licensed under the Apache License, Version 2.0 (the "License"); 6526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * you may not use this file except in compliance with the License. 7526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * You may obtain a copy of the License at 8526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 9526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * http://www.apache.org/licenses/LICENSE-2.0 10526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 11526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Unless required by applicable law or agreed to in writing, software 12526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * distributed under the License is distributed on an "AS IS" BASIS, 13526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * See the License for the specific language governing permissions and 15526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * limitations under the License. 16526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 17526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 18526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenpackage com.google.android.mms.pdu; 19526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 20526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.ContentType; 21526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.InvalidHeaderValueException; 22526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.pdu.EncodedStringValue; 23526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 24526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.util.Log; 25526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 26526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.ByteArrayInputStream; 27526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.ByteArrayOutputStream; 28526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.UnsupportedEncodingException; 29526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.util.Arrays; 30526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.util.HashMap; 31526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 32526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.content.res.Resources; 33526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 34526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenpublic class PduParser { 35526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 36526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The next are WAP values defined in WSP specification. 37526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 38526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int QUOTE = 127; 39526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int LENGTH_QUOTE = 31; 40526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int TEXT_MIN = 32; 41526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int TEXT_MAX = 127; 42526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int SHORT_INTEGER_MAX = 127; 43526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int SHORT_LENGTH_MAX = 30; 44526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int LONG_INTEGER_LENGTH_MAX = 8; 45526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int QUOTED_STRING_FLAG = 34; 46526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int END_STRING_FLAG = 0x00; 47526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen //The next two are used by the interface "parseWapString" to 48526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen //distinguish Text-String and Quoted-String. 49526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int TYPE_TEXT_STRING = 0; 50526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int TYPE_QUOTED_STRING = 1; 51526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int TYPE_TOKEN_STRING = 2; 52526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 53526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 54526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Specify the part position. 55526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 56526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int THE_FIRST_PART = 0; 57526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int THE_LAST_PART = 1; 58526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 59526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 60526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The pdu data. 61526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 62526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private ByteArrayInputStream mPduDataStream = null; 63526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 64526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 65526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Store pdu headers 66526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 67526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private PduHeaders mHeaders = null; 68526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 69526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 70526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Store pdu parts. 71526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 72526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private PduBody mBody = null; 73526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 74526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 75526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Store the "type" parameter in "Content-Type" header field. 76526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 77526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static byte[] mTypeParam = null; 78526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 79526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 80526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Store the "start" parameter in "Content-Type" header field. 81526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 82526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static byte[] mStartParam = null; 83526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 84526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 85526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The log tag. 86526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 87526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final String LOG_TAG = "PduParser"; 88526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final boolean DEBUG = false; 89526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final boolean LOCAL_LOGV = false; 90526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 91526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 92526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Constructor. 93526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 94526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data to be parsed 95526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 96526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public PduParser(byte[] pduDataStream) { 97526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mPduDataStream = new ByteArrayInputStream(pduDataStream); 98526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 99526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 100526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 101526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse the pdu. 102526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 103526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return the pdu structure if parsing successfully. 104526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * null if parsing error happened or mandatory fields are not set. 105526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 106526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public GenericPdu parse(){ 107526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (mPduDataStream == null) { 108526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 109526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 110526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 111526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse headers */ 112526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mHeaders = parseHeaders(mPduDataStream); 113526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == mHeaders) { 114526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Parse headers failed. 115526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 116526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 117526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 118526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* get the message type */ 119526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int messageType = mHeaders.getOctet(PduHeaders.MESSAGE_TYPE); 120526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 121526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* check mandatory header fields */ 122526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (false == checkMandatoryHeader(mHeaders)) { 123526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("check mandatory headers failed!"); 124526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 125526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 126526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 127526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((PduHeaders.MESSAGE_TYPE_SEND_REQ == messageType) || 128526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen (PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF == messageType)) { 129526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* need to parse the parts */ 130526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mBody = parseParts(mPduDataStream); 131526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == mBody) { 132526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Parse parts failed. 133526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 134526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 135526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 136526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 137526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (messageType) { 138526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_SEND_REQ: 139526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 140526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_REQ"); 141526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 142526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SendReq sendReq = new SendReq(mHeaders, mBody); 143526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return sendReq; 144526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_SEND_CONF: 145526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 146526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_CONF"); 147526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 148526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SendConf sendConf = new SendConf(mHeaders); 149526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return sendConf; 150526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 151526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 152526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFICATION_IND"); 153526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 154526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen NotificationInd notificationInd = 155526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new NotificationInd(mHeaders); 156526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return notificationInd; 157526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: 158526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 159526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFYRESP_IND"); 160526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 161526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen NotifyRespInd notifyRespInd = 162526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new NotifyRespInd(mHeaders); 163526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return notifyRespInd; 164526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: 165526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 166526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_RETRIEVE_CONF"); 167526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 168526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen RetrieveConf retrieveConf = 169526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new RetrieveConf(mHeaders, mBody); 170526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 171526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentType = retrieveConf.getContentType(); 172526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == contentType) { 173526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 174526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 175526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String ctTypeStr = new String(contentType); 176526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (ctTypeStr.equals(ContentType.MULTIPART_MIXED) 177526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || ctTypeStr.equals(ContentType.MULTIPART_RELATED) 178526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { 179526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // The MMS content type must be "application/vnd.wap.multipart.mixed" 180526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // or "application/vnd.wap.multipart.related" 181526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // or "application/vnd.wap.multipart.alternative" 182526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return retrieveConf; 183526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { 184526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // "application/vnd.wap.multipart.alternative" 185526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // should take only the first part. 186526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart firstPart = mBody.getPart(0); 187526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mBody.removeAll(); 188526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mBody.addPart(0, firstPart); 189526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return retrieveConf; 190526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 191526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 192526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: 193526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 194526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_DELIVERY_IND"); 195526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 196526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen DeliveryInd deliveryInd = 197526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new DeliveryInd(mHeaders); 198526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return deliveryInd; 199526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: 200526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 201526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_ACKNOWLEDGE_IND"); 202526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 203526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen AcknowledgeInd acknowledgeInd = 204526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new AcknowledgeInd(mHeaders); 205526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return acknowledgeInd; 206526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: 207526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 208526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_ORIG_IND"); 209526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 210526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ReadOrigInd readOrigInd = 211526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new ReadOrigInd(mHeaders); 212526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return readOrigInd; 213526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_READ_REC_IND: 214526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 215526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_REC_IND"); 216526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 217526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ReadRecInd readRecInd = 218526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new ReadRecInd(mHeaders); 219526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return readRecInd; 220526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen default: 221526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("Parser doesn't support this message type in this version!"); 222526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 223526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 224526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 225526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 226526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 227526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse pdu headers. 228526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 229526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 230526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return headers in PduHeaders structure, null when parse fail 231526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 232526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream){ 233526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (pduDataStream == null) { 234526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 235526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 236526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen boolean keepParsing = true; 237526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders headers = new PduHeaders(); 238526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 239526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen while (keepParsing && (pduDataStream.available() > 0)) { 240526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 241526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int headerField = extractByteValue(pduDataStream); 242526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse custom text header */ 243526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) { 244526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 245526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING); 246526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 247526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "TextHeader: " + new String(bVal)); 248526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 249526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* we should ignore it at the moment */ 250526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen continue; 251526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 252526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (headerField) { 253526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE: 254526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 255526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int messageType = extractByteValue(pduDataStream); 256526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 257526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: messageType: " + messageType); 258526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 259526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (messageType) { 260526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // We don't support these kind of messages now. 261526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: 262526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_FORWARD_CONF: 263526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ: 264526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF: 265526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ: 266526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF: 267526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ: 268526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF: 269526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ: 270526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF: 271526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_DESCR: 272526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_DELETE_REQ: 273526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_DELETE_CONF: 274526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_CANCEL_REQ: 275526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_CANCEL_CONF: 276526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 277526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 278526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 279526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setOctet(messageType, headerField); 280526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(InvalidHeaderValueException e) { 281526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("Set invalid Octet value: " + messageType + 282526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen " into the header filed: " + headerField); 283526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 284526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 285526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Octet header field!"); 286526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 287526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 288526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 289526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 290526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Octect value */ 291526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.REPORT_ALLOWED: 292526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.ADAPTATION_ALLOWED: 293526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.DELIVERY_REPORT: 294526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.DRM_CONTENT: 295526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.DISTRIBUTION_INDICATOR: 296526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.QUOTAS: 297526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.READ_REPORT: 298526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.STORE: 299526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.STORED: 300526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.TOTALS: 301526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.SENDER_VISIBILITY: 302526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.READ_STATUS: 303526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.CANCEL_STATUS: 304526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.PRIORITY: 305526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.STATUS: 306526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.REPLY_CHARGING: 307526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MM_STATE: 308526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.RECOMMENDED_RETRIEVAL_MODE: 309526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.CONTENT_CLASS: 310526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.RETRIEVE_STATUS: 311526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.STORE_STATUS: 312526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 313526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The following field has a different value when 314526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. 315526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * For now we ignore this fact, since we do not support these PDUs 316526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 317526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.RESPONSE_STATUS: 318526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 319526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int value = extractByteValue(pduDataStream); 320526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 321526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: byte: " + headerField + " value: " + 322526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value); 323526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 324526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 325526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 326526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setOctet(value, headerField); 327526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(InvalidHeaderValueException e) { 328526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("Set invalid Octet value: " + value + 329526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen " into the header filed: " + headerField); 330526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 331526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 332526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Octet header field!"); 333526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 334526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 335526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 336526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 337526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 338526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Long-Integer */ 339526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.DATE: 340526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.REPLY_CHARGING_SIZE: 341526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_SIZE: 342526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 343526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 344526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long value = parseLongInteger(pduDataStream); 345526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 346526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: longint: " + headerField + " value: " + 347526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value); 348526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 349526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setLongInteger(value, headerField); 350526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 351526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Long-Integer header field!"); 352526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 353526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 354526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 355526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 356526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 357526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Integer-Value */ 358526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_COUNT: 359526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.START: 360526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.LIMIT: 361526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 362526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 363526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long value = parseIntegerValue(pduDataStream); 364526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 365526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: int: " + headerField + " value: " + 366526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value); 367526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 368526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setLongInteger(value, headerField); 369526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 370526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Long-Integer header field!"); 371526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 372526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 373526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 374526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 375526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 376526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Text-String */ 377526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.TRANSACTION_ID: 378526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.REPLY_CHARGING_ID: 379526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.AUX_APPLIC_ID: 380526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.APPLIC_ID: 381526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.REPLY_APPLIC_ID: 382526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 383526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The next three header fields are email addresses 384526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * as defined in RFC2822, 385526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * not including the characters "<" and ">" 386526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 387526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_ID: 388526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.REPLACE_ID: 389526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.CANCEL_ID: 390526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 391526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The following field has a different value when 392526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. 393526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * For now we ignore this fact, since we do not support these PDUs 394526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 395526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.CONTENT_LOCATION: 396526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 397526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING); 398526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != value) { 399526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 400526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 401526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: string: " + headerField + " value: " + 402526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new String(value)); 403526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 404526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setTextString(value, headerField); 405526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 406526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 407526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 408526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Text-String header field!"); 409526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 410526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 411526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 412526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 413526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 414526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 415526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Encoded-string-value */ 416526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.SUBJECT: 417526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT: 418526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.RETRIEVE_TEXT: 419526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.STATUS_TEXT: 420526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.STORE_STATUS_TEXT: 421526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* the next one is not support 422526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * M-Mbox-Delete.conf and M-Delete.conf now */ 423526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.RESPONSE_TEXT: 424526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 425526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue value = 426526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseEncodedStringValue(pduDataStream); 427526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != value) { 428526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 429526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 430526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: encoded string: " + headerField 431526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " value: " + value.getString()); 432526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 433526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setEncodedStringValue(value, headerField); 434526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 435526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 436526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (RuntimeException e) { 437526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Encoded-String-Value header field!"); 438526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 439526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 440526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 441526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 442526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 443526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 444526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Addressing model */ 445526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.BCC: 446526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.CC: 447526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.TO: 448526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 449526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue value = 450526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseEncodedStringValue(pduDataStream); 451526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != value) { 452526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] address = value.getTextString(); 453526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != address) { 454526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String str = new String(address); 455526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 456526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: (to/cc/bcc) address: " + headerField 457526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " value: " + str); 458526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 459526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int endIndex = str.indexOf("/"); 460526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (endIndex > 0) { 461526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen str = str.substring(0, endIndex); 462526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 463526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 464526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value.setTextString(str.getBytes()); 465526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 466526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 467526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 468526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 469526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 470526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 471526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 472526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.appendEncodedStringValue(value, headerField); 473526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 474526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 475526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 476526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Encoded-String-Value header field!"); 477526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 478526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 479526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 480526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 481526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 482526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 483526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Value-length 484526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * (Absolute-token Date-value | Relative-token Delta-seconds-value) */ 485526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.DELIVERY_TIME: 486526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.EXPIRY: 487526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.REPLY_CHARGING_DEADLINE: 488526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 489526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse Value-length */ 490526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseValueLength(pduDataStream); 491526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 492526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Absolute-token or Relative-token */ 493526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int token = extractByteValue(pduDataStream); 494526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 495526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Date-value or Delta-seconds-value */ 496526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long timeValue; 497526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 498526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen timeValue = parseLongInteger(pduDataStream); 499526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 500526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Long-Integer header field!"); 501526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 502526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 503526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (PduHeaders.VALUE_RELATIVE_TOKEN == token) { 504526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* need to convert the Delta-seconds-value 505526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * into Date-value */ 506526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen timeValue = System.currentTimeMillis()/1000 + timeValue; 507526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 508526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 509526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 510526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 511526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: time value: " + headerField 512526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " value: " + timeValue); 513526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 514526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setLongInteger(timeValue, headerField); 515526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 516526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Long-Integer header field!"); 517526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 518526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 519526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 520526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 521526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 522526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.FROM: { 523526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* From-value = 524526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Value-length 525526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * (Address-present-token Encoded-string-value | Insert-address-token) 526526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 527526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue from = null; 528526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseValueLength(pduDataStream); /* parse value-length */ 529526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 530526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Address-present-token or Insert-address-token */ 531526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int fromToken = extractByteValue(pduDataStream); 532526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 533526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Address-present-token or Insert-address-token */ 534526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) { 535526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Encoded-string-value */ 536526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen from = parseEncodedStringValue(pduDataStream); 537526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != from) { 538526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] address = from.getTextString(); 539526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != address) { 540526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String str = new String(address); 541526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int endIndex = str.indexOf("/"); 542526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (endIndex > 0) { 543526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen str = str.substring(0, endIndex); 544526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 545526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 546526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen from.setTextString(str.getBytes()); 547526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 548526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 549526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 550526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 551526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 552526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 553526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 554526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 555526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen from = new EncodedStringValue( 556526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()); 557526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 558526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Encoded-String-Value header field!"); 559526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 560526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 561526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 562526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 563526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 564526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 565526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: from address: " + headerField 566526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " value: " + from.getString()); 567526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 568526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setEncodedStringValue(from, PduHeaders.FROM); 569526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 570526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 571526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 572526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Encoded-String-Value header field!"); 573526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 574526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 575526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 576526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 577526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 578526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_CLASS: { 579526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Message-class-value = Class-identifier | Token-text */ 580526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 581526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int messageClass = extractByteValue(pduDataStream); 582526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 583526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: MESSAGE_CLASS: " + headerField 584526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " value: " + messageClass); 585526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 586526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 587526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) { 588526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Class-identifier */ 589526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 590526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) { 591526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setTextString( 592526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(), 593526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.MESSAGE_CLASS); 594526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) { 595526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setTextString( 596526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(), 597526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.MESSAGE_CLASS); 598526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) { 599526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setTextString( 600526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(), 601526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.MESSAGE_CLASS); 602526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) { 603526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setTextString( 604526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(), 605526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.MESSAGE_CLASS); 606526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 607526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 608526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 609526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 610526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Text-String header field!"); 611526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 612526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 613526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 614526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Token-text */ 615526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 616526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING); 617526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != messageClassString) { 618526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 619526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS); 620526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 621526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 622526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 623526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Text-String header field!"); 624526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 625526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 626526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 627526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 628526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 629526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 630526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 631526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MMS_VERSION: { 632526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int version = parseShortInteger(pduDataStream); 633526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 634526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 635526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 636526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: MMS_VERSION: " + headerField 637526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " value: " + version); 638526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 639526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setOctet(version, PduHeaders.MMS_VERSION); 640526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(InvalidHeaderValueException e) { 641526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("Set invalid Octet value: " + version + 642526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen " into the header filed: " + headerField); 643526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 644526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 645526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Octet header field!"); 646526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 647526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 648526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 649526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 650526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 651526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.PREVIOUSLY_SENT_BY: { 652526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Previously-sent-by-value = 653526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Value-length Forwarded-count-value Encoded-string-value */ 654526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse value-length */ 655526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseValueLength(pduDataStream); 656526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 657526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse Forwarded-count-value */ 658526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 659526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseIntegerValue(pduDataStream); 660526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 661526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + " is not Integer-Value"); 662526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 663526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 664526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 665526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse Encoded-string-value */ 666526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue previouslySentBy = 667526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseEncodedStringValue(pduDataStream); 668526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != previouslySentBy) { 669526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 670526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 671526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_BY: " + headerField 672526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " value: " + previouslySentBy.getString()); 673526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 674526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setEncodedStringValue(previouslySentBy, 675526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.PREVIOUSLY_SENT_BY); 676526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 677526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 678526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 679526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Encoded-String-Value header field!"); 680526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 681526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 682526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 683526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 684526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 685526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 686526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.PREVIOUSLY_SENT_DATE: { 687526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Previously-sent-date-value = 688526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Value-length Forwarded-count-value Date-value */ 689526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse value-length */ 690526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseValueLength(pduDataStream); 691526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 692526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse Forwarded-count-value */ 693526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 694526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseIntegerValue(pduDataStream); 695526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 696526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + " is not Integer-Value"); 697526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 698526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 699526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 700526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Date-value */ 701526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 702526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long perviouslySentDate = parseLongInteger(pduDataStream); 703526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 704526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_DATE: " + headerField 705526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " value: " + perviouslySentDate); 706526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 707526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setLongInteger(perviouslySentDate, 708526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.PREVIOUSLY_SENT_DATE); 709526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 710526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Long-Integer header field!"); 711526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 712526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 713526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 714526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 715526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 716526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MM_FLAGS: { 717526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* MM-flags-value = 718526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Value-length 719526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * ( Add-token | Remove-token | Filter-token ) 720526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Encoded-string-value 721526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 722526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 723526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: MM_FLAGS: " + headerField 724526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " NOT REALLY SUPPORTED"); 725526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 726526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 727526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse Value-length */ 728526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseValueLength(pduDataStream); 729526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 730526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Add-token | Remove-token | Filter-token */ 731526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen extractByteValue(pduDataStream); 732526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 733526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Encoded-string-value */ 734526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseEncodedStringValue(pduDataStream); 735526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 736526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* not store this header filed in "headers", 737526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * because now PduHeaders doesn't support it */ 738526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 739526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 740526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 741526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Value-length 742526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * (Message-total-token | Size-total-token) Integer-Value */ 743526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MBOX_TOTALS: 744526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MBOX_QUOTAS: 745526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen { 746526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 747526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: MBOX_TOTALS: " + headerField); 748526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 749526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Value-length */ 750526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseValueLength(pduDataStream); 751526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 752526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Message-total-token | Size-total-token */ 753526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen extractByteValue(pduDataStream); 754526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 755526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /*Integer-Value*/ 756526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 757526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseIntegerValue(pduDataStream); 758526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 759526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + " is not Integer-Value"); 760526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 761526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 762526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 763526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* not store these headers filed in "headers", 764526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen because now PduHeaders doesn't support them */ 765526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 766526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 767526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 768526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.ELEMENT_DESCRIPTOR: { 769526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 770526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: ELEMENT_DESCRIPTOR: " + headerField); 771526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 772526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseContentType(pduDataStream, null); 773526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 774526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* not store this header filed in "headers", 775526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen because now PduHeaders doesn't support it */ 776526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 777526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 778526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 779526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.CONTENT_TYPE: { 780526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashMap<Integer, Object> map = 781526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new HashMap<Integer, Object>(); 782526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentType = 783526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseContentType(pduDataStream, map); 784526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 785526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != contentType) { 786526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 787526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 788526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: CONTENT_TYPE: " + headerField + 789526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen contentType.toString()); 790526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 791526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setTextString(contentType, PduHeaders.CONTENT_TYPE); 792526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(NullPointerException e) { 793526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("null pointer error!"); 794526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(RuntimeException e) { 795526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log(headerField + "is not Text-String header field!"); 796526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 797526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 798526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 799526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 800526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* get start parameter */ 801526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mStartParam = (byte[]) map.get(PduPart.P_START); 802526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 803526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* get charset parameter */ 804526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mTypeParam= (byte[]) map.get(PduPart.P_TYPE); 805526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 806526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen keepParsing = false; 807526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 808526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 809526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 810526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.CONTENT: 811526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.ADDITIONAL_HEADERS: 812526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.ATTRIBUTES: 813526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen default: { 814526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 815526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "parseHeaders: Unknown header: " + headerField); 816526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 817526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("Unknown header"); 818526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 819526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 820526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 821526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 822526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return headers; 823526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 824526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 825526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 826526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse pdu parts. 827526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 828526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 829526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return parts in PduBody structure 830526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 831526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static PduBody parseParts(ByteArrayInputStream pduDataStream) { 832526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (pduDataStream == null) { 833526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 834526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 835526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 836526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int count = parseUnsignedInt(pduDataStream); // get the number of parts 837526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduBody body = new PduBody(); 838526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 839526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int i = 0 ; i < count ; i++) { 840526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int headerLength = parseUnsignedInt(pduDataStream); 841526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int dataLength = parseUnsignedInt(pduDataStream); 842526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart part = new PduPart(); 843526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int startPos = pduDataStream.available(); 844526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (startPos <= 0) { 845526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Invalid part. 846526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 847526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 848526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 849526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse part's content-type */ 850526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashMap<Integer, Object> map = new HashMap<Integer, Object>(); 851526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentType = parseContentType(pduDataStream, map); 852526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != contentType) { 853526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentType(contentType); 854526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 855526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*" 856526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 857526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 858526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* get name parameter */ 859526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] name = (byte[]) map.get(PduPart.P_NAME); 860526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != name) { 861526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setName(name); 862526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 863526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 864526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* get charset parameter */ 865526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Integer charset = (Integer) map.get(PduPart.P_CHARSET); 866526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != charset) { 867526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setCharset(charset); 868526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 869526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 870526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* parse part's headers */ 871526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int endPos = pduDataStream.available(); 872526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int partHeaderLen = headerLength - (startPos - endPos); 873526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (partHeaderLen > 0) { 874526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) { 875526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Parse part header faild. 876526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 877526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 878526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (partHeaderLen < 0) { 879526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Invalid length of content-type. 880526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 881526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 882526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 883526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* FIXME: check content-id, name, filename and content location, 884526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * if not set anyone of them, generate a default content-location 885526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 886526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((null == part.getContentLocation()) 887526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen && (null == part.getName()) 888526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen && (null == part.getFilename()) 889526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen && (null == part.getContentId())) { 890526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentLocation(Long.toOctalString( 891526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen System.currentTimeMillis()).getBytes()); 892526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 893526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 894526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* get part's data */ 895526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (dataLength > 0) { 896526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] partData = new byte[dataLength]; 897526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String partContentType = new String(part.getContentType()); 898526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.read(partData, 0, dataLength); 899526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) { 900526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // parse "multipart/vnd.wap.multipart.alternative". 901526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduBody childBody = parseParts(new ByteArrayInputStream(partData)); 902526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // take the first part of children. 903526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part = childBody.getPart(0); 904526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 905526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Check Content-Transfer-Encoding. 906526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] partDataEncoding = part.getContentTransferEncoding(); 907526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != partDataEncoding) { 908526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String encoding = new String(partDataEncoding); 909526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { 910526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Decode "base64" into "binary". 911526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen partData = Base64.decodeBase64(partData); 912526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { 913526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Decode "quoted-printable" into "binary". 914526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen partData = QuotedPrintable.decodeQuotedPrintable(partData); 915526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 916526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // "binary" is the default encoding. 917526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 918526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 919526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == partData) { 920526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen log("Decode part data error!"); 921526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 922526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 923526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setData(partData); 924526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 925526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 926526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 927526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* add this part to body */ 928526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (THE_FIRST_PART == checkPartPosition(part)) { 929526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* this is the first part */ 930526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen body.addPart(0, part); 931526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 932526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* add the part to the end */ 933526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen body.addPart(part); 934526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 935526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 936526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 937526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return body; 938526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 939526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 940526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 941526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Log status. 942526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 943526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param text log information 944526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 945526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static void log(String text) { 946526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 947526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, text); 948526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 949526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 950526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 951526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 952526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse unsigned integer. 953526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 954526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 955526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return the integer, -1 when failed 956526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 957526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static int parseUnsignedInt(ByteArrayInputStream pduDataStream) { 958526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 959526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 960526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The maximum size of a uintvar is 32 bits. 961526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * So it will be encoded in no more than 5 octets. 962526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 963526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 964526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int result = 0; 965526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 966526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (temp == -1) { 967526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return temp; 968526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 969526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 970526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen while((temp & 0x80) != 0) { 971526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = result << 7; 972526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result |= temp & 0x7F; 973526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen temp = pduDataStream.read(); 974526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (temp == -1) { 975526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return temp; 976526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 977526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 978526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 979526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = result << 7; 980526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result |= temp & 0x7F; 981526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 982526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return result; 983526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 984526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 985526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 986526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse value length. 987526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 988526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 989526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return the integer 990526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 991526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static int parseValueLength(ByteArrayInputStream pduDataStream) { 992526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 993526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 994526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Value-length = Short-length | (Length-quote Length) 995526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Short-length = <Any octet 0-30> 996526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Length-quote = <Octet 31> 997526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Length = Uintvar-integer 998526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Uintvar-integer = 1*5 OCTET 999526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1000526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1001526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1002526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1003526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int first = temp & 0xFF; 1004526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1005526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (first <= SHORT_LENGTH_MAX) { 1006526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return first; 1007526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (first == LENGTH_QUOTE) { 1008526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return parseUnsignedInt(pduDataStream); 1009526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1010526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1011526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new RuntimeException ("Value length > LENGTH_QUOTE!"); 1012526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1013526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1014526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1015526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse encoded string value. 1016526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1017526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1018526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return the EncodedStringValue 1019526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1020526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static EncodedStringValue parseEncodedStringValue(ByteArrayInputStream pduDataStream){ 1021526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1022526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf 1023526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Encoded-string-value = Text-string | Value-length Char-set Text-string 1024526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1025526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1026526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1027526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue returnValue = null; 1028526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int charset = 0; 1029526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1030526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1031526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int first = temp & 0xFF; 1032526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (first == 0) { 1033526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return new EncodedStringValue(""); 1034526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1035526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1036526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1037526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (first < TEXT_MIN) { 1038526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseValueLength(pduDataStream); 1039526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1040526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen charset = parseShortInteger(pduDataStream); //get the "Charset" 1041526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1042526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1043526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1044526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1045526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 1046526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 != charset) { 1047526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen returnValue = new EncodedStringValue(charset, textString); 1048526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1049526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen returnValue = new EncodedStringValue(textString); 1050526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1051526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch(Exception e) { 1052526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 1053526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1054526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1055526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return returnValue; 1056526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1057526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1058526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1059526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse Text-String or Quoted-String. 1060526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1061526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1062526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param stringType TYPE_TEXT_STRING or TYPE_QUOTED_STRING 1063526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return the string without End-of-string in byte array 1064526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1065526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static byte[] parseWapString(ByteArrayInputStream pduDataStream, 1066526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int stringType) { 1067526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1068526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1069526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1070526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Text-string = [Quote] *TEXT End-of-string 1071526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * If the first character in the TEXT is in the range of 128-255, 1072526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * a Quote character must precede it. 1073526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Otherwise the Quote character must be omitted. 1074526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The Quote is not part of the contents. 1075526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Quote = <Octet 127> 1076526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * End-of-string = <Octet 0> 1077526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1078526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Quoted-string = <Octet 34> *TEXT End-of-string 1079526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1080526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Token-text = Token End-of-string 1081526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1082526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1083526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Mark supposed beginning of Text-string 1084526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // We will have to mark again if first char is QUOTE or QUOTED_STRING_FLAG 1085526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1086526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1087526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Check first char 1088526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1089526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1090526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((TYPE_QUOTED_STRING == stringType) && 1091526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen (QUOTED_STRING_FLAG == temp)) { 1092526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Mark again if QUOTED_STRING_FLAG and ignore it 1093526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1094526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if ((TYPE_TEXT_STRING == stringType) && 1095526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen (QUOTE == temp)) { 1096526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Mark again if QUOTE and ignore it 1097526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1098526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1099526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Otherwise go back to origin 1100526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1101526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1102526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1103526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // We are now definitely at the beginning of string 1104526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1105526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Return *TOKEN or *TEXT (Text-String without QUOTE, 1106526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Quoted-String without QUOTED_STRING_FLAG and without End-of-string) 1107526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1108526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return getWapString(pduDataStream, stringType); 1109526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1110526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1111526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1112526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Check TOKEN data defined in RFC2616. 1113526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param ch checking data 1114526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return true when ch is TOKEN, false when ch is not TOKEN 1115526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1116526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static boolean isTokenCharacter(int ch) { 1117526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1118526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Token = 1*<any CHAR except CTLs or separators> 1119526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * separators = "("(40) | ")"(41) | "<"(60) | ">"(62) | "@"(64) 1120526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * | ","(44) | ";"(59) | ":"(58) | "\"(92) | <">(34) 1121526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * | "/"(47) | "["(91) | "]"(93) | "?"(63) | "="(61) 1122526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * | "{"(123) | "}"(125) | SP(32) | HT(9) 1123526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * CHAR = <any US-ASCII character (octets 0 - 127)> 1124526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * CTL = <any US-ASCII control character 1125526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * (octets 0 - 31) and DEL (127)> 1126526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * SP = <US-ASCII SP, space (32)> 1127526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * HT = <US-ASCII HT, horizontal-tab (9)> 1128526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1129526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if((ch < 33) || (ch > 126)) { 1130526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1131526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1132526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1133526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch(ch) { 1134526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '"': /* '"' */ 1135526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '(': /* '(' */ 1136526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case ')': /* ')' */ 1137526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case ',': /* ',' */ 1138526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '/': /* '/' */ 1139526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case ':': /* ':' */ 1140526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case ';': /* ';' */ 1141526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '<': /* '<' */ 1142526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '=': /* '=' */ 1143526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '>': /* '>' */ 1144526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '?': /* '?' */ 1145526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '@': /* '@' */ 1146526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '[': /* '[' */ 1147526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '\\': /* '\' */ 1148526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case ']': /* ']' */ 1149526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '{': /* '{' */ 1150526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '}': /* '}' */ 1151526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1152526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1153526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1154526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return true; 1155526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1156526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1157526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1158526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Check TEXT data defined in RFC2616. 1159526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param ch checking data 1160526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return true when ch is TEXT, false when ch is not TEXT 1161526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1162526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static boolean isText(int ch) { 1163526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1164526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * TEXT = <any OCTET except CTLs, 1165526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * but including LWS> 1166526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * CTL = <any US-ASCII control character 1167526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * (octets 0 - 31) and DEL (127)> 1168526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * LWS = [CRLF] 1*( SP | HT ) 1169526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * CRLF = CR LF 1170526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * CR = <US-ASCII CR, carriage return (13)> 1171526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * LF = <US-ASCII LF, linefeed (10)> 1172526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1173526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if(((ch >= 32) && (ch <= 126)) || ((ch >= 128) && (ch <= 255))) { 1174526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return true; 1175526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1176526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1177526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch(ch) { 1178526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '\t': /* '\t' */ 1179526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '\n': /* '\n' */ 1180526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case '\r': /* '\r' */ 1181526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return true; 1182526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1183526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1184526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1185526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1186526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1187526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static byte[] getWapString(ByteArrayInputStream pduDataStream, 1188526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int stringType) { 1189526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1190526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ByteArrayOutputStream out = new ByteArrayOutputStream(); 1191526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1192526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1193526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen while((-1 != temp) && ('\0' != temp)) { 1194526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // check each of the character 1195526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (stringType == TYPE_TOKEN_STRING) { 1196526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (isTokenCharacter(temp)) { 1197526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen out.write(temp); 1198526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1199526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1200526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (isText(temp)) { 1201526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen out.write(temp); 1202526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1203526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1204526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1205526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen temp = pduDataStream.read(); 1206526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1207526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1208526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1209526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (out.size() > 0) { 1210526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return out.toByteArray(); 1211526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1212526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1213526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 1214526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1215526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1216526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1217526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Extract a byte value from the input stream. 1218526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1219526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1220526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return the byte 1221526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1222526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static int extractByteValue(ByteArrayInputStream pduDataStream) { 1223526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1224526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1225526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1226526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return temp & 0xFF; 1227526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1228526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1229526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1230526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse Short-Integer. 1231526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1232526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1233526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return the byte 1234526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1235526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static int parseShortInteger(ByteArrayInputStream pduDataStream) { 1236526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1237526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1238526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Short-integer = OCTET 1239526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Integers in range 0-127 shall be encoded as a one 1240526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * octet value with the most significant bit set to one (1xxx xxxx) 1241526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * and with the value in the remaining least significant bits. 1242526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1243526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1244526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1245526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1246526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return temp & 0x7F; 1247526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1248526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1249526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1250526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse Long-Integer. 1251526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1252526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1253526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return long integer 1254526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1255526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static long parseLongInteger(ByteArrayInputStream pduDataStream) { 1256526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1257526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1258526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Long-integer = Short-length Multi-octet-integer 1259526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The Short-length indicates the length of the Multi-octet-integer 1260526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Multi-octet-integer = 1*30 OCTET 1261526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The content octets shall be an unsigned integer value 1262526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * with the most significant octet encoded first (big-endian representation). 1263526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The minimum number of octets must be used to encode the value. 1264526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Short-length = <Any octet 0-30> 1265526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1266526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1267526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1268526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1269526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int count = temp & 0xFF; 1270526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1271526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (count > LONG_INTEGER_LENGTH_MAX) { 1272526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new RuntimeException("Octet count greater than 8 and I can't represent that!"); 1273526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1274526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1275526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long result = 0; 1276526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1277526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int i = 0 ; i < count ; i++) { 1278526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen temp = pduDataStream.read(); 1279526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1280526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result <<= 8; 1281526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result += (temp & 0xFF); 1282526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1283526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1284526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return result; 1285526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1286526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1287526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1288526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse Integer-Value. 1289526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1290526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1291526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return long integer 1292526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1293526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static long parseIntegerValue(ByteArrayInputStream pduDataStream) { 1294526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1295526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1296526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Integer-Value = Short-integer | Long-integer 1297526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1298526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1299526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1300526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1301526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1302526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1303526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (temp > SHORT_INTEGER_MAX) { 1304526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return parseShortInteger(pduDataStream); 1305526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1306526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return parseLongInteger(pduDataStream); 1307526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1308526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1309526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1310526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1311526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * To skip length of the wap value. 1312526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1313526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1314526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param length area size 1315526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return the values in this area 1316526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1317526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static int skipWapValue(ByteArrayInputStream pduDataStream, int length) { 1318526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1319526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] area = new byte[length]; 1320526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int readLen = pduDataStream.read(area, 0, length); 1321526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (readLen < length) { //The actually read length is lower than the length 1322526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return -1; 1323526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1324526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return readLen; 1325526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1326526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1327526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1328526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1329526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse content type parameters. For now we just support 1330526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * four parameters used in mms: "type", "start", "name", "charset". 1331526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1332526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1333526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param map to store parameters of Content-Type field 1334526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param length length of all the parameters 1335526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1336526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static void parseContentTypeParams(ByteArrayInputStream pduDataStream, 1337526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashMap<Integer, Object> map, Integer length) { 1338526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1339526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1340526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parameter = Typed-parameter | Untyped-parameter 1341526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Typed-parameter = Well-known-parameter-token Typed-value 1342526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * the actual expected type of the value is implied by the well-known parameter 1343526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Well-known-parameter-token = Integer-value 1344526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * the code values used for parameters are specified in the Assigned Numbers appendix 1345526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Typed-value = Compact-value | Text-value 1346526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * In addition to the expected type, there may be no value. 1347526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * If the value cannot be encoded using the expected type, it shall be encoded as text. 1348526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Compact-value = Integer-value | 1349526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Date-value | Delta-seconds-value | Q-value | Version-value | 1350526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Uri-value 1351526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Untyped-parameter = Token-text Untyped-value 1352526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * the type of the value is unknown, but it shall be encoded as an integer, 1353526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * if that is possible. 1354526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Untyped-value = Integer-value | Text-value 1355526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1356526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1357526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(length > 0); 1358526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1359526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int startPos = pduDataStream.available(); 1360526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int tempPos = 0; 1361526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int lastLen = length; 1362526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen while(0 < lastLen) { 1363526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int param = pduDataStream.read(); 1364526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != param); 1365526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen--; 1366526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1367526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (param) { 1368526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1369526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From rfc2387, chapter 3.1 1370526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The type parameter must be specified and its value is the MIME media 1371526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * type of the "root" body part. It permits a MIME user agent to 1372526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * determine the content-type without reference to the enclosed body 1373526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * part. If the value of the type parameter and the root body part's 1374526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * content-type differ then the User Agent's behavior is undefined. 1375526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1376526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1377526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * type = Constrained-encoding 1378526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Constrained-encoding = Extension-Media | Short-integer 1379526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Extension-media = *TEXT End-of-string 1380526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1381526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_TYPE: 1382526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_CT_MR_TYPE: 1383526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1384526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int first = extractByteValue(pduDataStream); 1385526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1386526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (first > TEXT_MAX) { 1387526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Short-integer (well-known type) 1388526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int index = parseShortInteger(pduDataStream); 1389526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1390526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (index < PduContentTypes.contentTypes.length) { 1391526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] type = (PduContentTypes.contentTypes[index]).getBytes(); 1392526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen map.put(PduPart.P_TYPE, type); 1393526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1394526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen //not support this type, ignore it. 1395526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1396526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1397526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Text-String (extension-media) 1398526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] type = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1399526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((null != type) && (null != map)) { 1400526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen map.put(PduPart.P_TYPE, type); 1401526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1402526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1403526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1404526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen tempPos = pduDataStream.available(); 1405526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = length - (startPos - tempPos); 1406526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1407526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1408526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1409526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.3. 1410526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Start Parameter Referring to Presentation 1411526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1412526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From rfc2387, chapter 3.2 1413526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The start parameter, if given, is the content-ID of the compound 1414526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * object's "root". If not present the "root" is the first body part in 1415526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * the Multipart/Related entity. The "root" is the element the 1416526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * applications processes first. 1417526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1418526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1419526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * start = Text-String 1420526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1421526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_START: 1422526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_DEP_START: 1423526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] start = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1424526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((null != start) && (null != map)) { 1425526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen map.put(PduPart.P_START, start); 1426526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1427526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1428526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen tempPos = pduDataStream.available(); 1429526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = length - (startPos - tempPos); 1430526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1431526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1432526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1433526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From oma-ts-mms-conf-v1_3.pdf 1434526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * In creation, the character set SHALL be either us-ascii 1435526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * (IANA MIBenum 3) or utf-8 (IANA MIBenum 106)[Unicode]. 1436526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * In retrieval, both us-ascii and utf-8 SHALL be supported. 1437526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1438526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1439526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * charset = Well-known-charset|Text-String 1440526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Well-known-charset = Any-charset | Integer-value 1441526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Both are encoded using values from Character Set 1442526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Assignments table in Assigned Numbers 1443526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Any-charset = <Octet 128> 1444526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Equivalent to the special RFC2616 charset value "*" 1445526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1446526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_CHARSET: 1447526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1448526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int firstValue = extractByteValue(pduDataStream); 1449526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1450526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen //Check first char 1451526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (((firstValue > TEXT_MIN) && (firstValue < TEXT_MAX)) || 1452526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen (END_STRING_FLAG == firstValue)) { 1453526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen //Text-String (extension-charset) 1454526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] charsetStr = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1455526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 1456526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int charsetInt = CharacterSets.getMibEnumValue( 1457526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new String(charsetStr)); 1458526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen map.put(PduPart.P_CHARSET, charsetInt); 1459526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (UnsupportedEncodingException e) { 1460526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Not a well-known charset, use "*". 1461526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(LOG_TAG, Arrays.toString(charsetStr), e); 1462526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET); 1463526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1464526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1465526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen //Well-known-charset 1466526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int charset = (int) parseIntegerValue(pduDataStream); 1467526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (map != null) { 1468526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen map.put(PduPart.P_CHARSET, charset); 1469526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1470526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1471526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1472526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen tempPos = pduDataStream.available(); 1473526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = length - (startPos - tempPos); 1474526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1475526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1476526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1477526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From oma-ts-mms-conf-v1_3.pdf 1478526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * A name for multipart object SHALL be encoded using name-parameter 1479526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * for Content-Type header in WSP multipart headers. 1480526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1481526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1482526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * name = Text-String 1483526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1484526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_DEP_NAME: 1485526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_NAME: 1486526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] name = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1487526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((null != name) && (null != map)) { 1488526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen map.put(PduPart.P_NAME, name); 1489526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1490526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1491526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen tempPos = pduDataStream.available(); 1492526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = length - (startPos - tempPos); 1493526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1494526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen default: 1495526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 1496526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "Not supported Content-Type parameter"); 1497526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1498526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (-1 == skipWapValue(pduDataStream, lastLen)) { 1499526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(LOG_TAG, "Corrupt Content-Type"); 1500526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1501526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = 0; 1502526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1503526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1504526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1505526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1506526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1507526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 != lastLen) { 1508526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(LOG_TAG, "Corrupt Content-Type"); 1509526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1510526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1511526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1512526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1513526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse content type. 1514526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1515526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1516526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param map to store parameters in Content-Type header field 1517526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return Content-Type value 1518526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1519526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static byte[] parseContentType(ByteArrayInputStream pduDataStream, 1520526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashMap<Integer, Object> map) { 1521526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1522526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf 1523526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Content-type-value = Constrained-media | Content-general-form 1524526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Content-general-form = Value-length Media-type 1525526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Media-type = (Well-known-media | Extension-Media) *(Parameter) 1526526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1527526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1528526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1529526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentType = null; 1530526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1531526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int temp = pduDataStream.read(); 1532526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1533526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1534526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1535526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int cur = (temp & 0xFF); 1536526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1537526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (cur < TEXT_MIN) { 1538526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int length = parseValueLength(pduDataStream); 1539526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int startPos = pduDataStream.available(); 1540526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1541526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen temp = pduDataStream.read(); 1542526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != temp); 1543526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1544526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int first = (temp & 0xFF); 1545526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1546526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((first >= TEXT_MIN) && (first <= TEXT_MAX)) { 1547526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1548526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (first > TEXT_MAX) { 1549526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int index = parseShortInteger(pduDataStream); 1550526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1551526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (index < PduContentTypes.contentTypes.length) { //well-known type 1552526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen contentType = (PduContentTypes.contentTypes[index]).getBytes(); 1553526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1554526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1555526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1556526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1557526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1558526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(LOG_TAG, "Corrupt content-type"); 1559526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" 1560526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1561526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1562526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int endPos = pduDataStream.available(); 1563526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int parameterLen = length - (startPos - endPos); 1564526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (parameterLen > 0) {//have parameters 1565526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parseContentTypeParams(pduDataStream, map, parameterLen); 1566526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1567526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1568526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (parameterLen < 0) { 1569526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(LOG_TAG, "Corrupt MMS message"); 1570526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" 1571526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1572526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (cur <= TEXT_MAX) { 1573526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1574526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1575526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen contentType = 1576526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen (PduContentTypes.contentTypes[parseShortInteger(pduDataStream)]).getBytes(); 1577526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1578526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1579526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return contentType; 1580526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1581526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1582526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1583526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Parse part's headers. 1584526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1585526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pduDataStream pdu data input stream 1586526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param part to store the header informations of the part 1587526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param length length of the headers 1588526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return true if parse successfully, false otherwise 1589526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1590526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static boolean parsePartHeaders(ByteArrayInputStream pduDataStream, 1591526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart part, int length) { 1592526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != pduDataStream); 1593526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != part); 1594526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(length > 0); 1595526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1596526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1597526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2. 1598526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * A name for multipart object SHALL be encoded using name-parameter 1599526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * for Content-Type header in WSP multipart headers. 1600526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * In decoding, name-parameter of Content-Type SHALL be used if available. 1601526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * If name-parameter of Content-Type is not available, 1602526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * filename parameter of Content-Disposition header SHALL be used if available. 1603526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * If neither name-parameter of Content-Type header nor filename parameter 1604526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * of Content-Disposition header is available, 1605526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Content-Location header SHALL be used if available. 1606526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1607526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Within SMIL part the reference to the media object parts SHALL use 1608526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * either Content-ID or Content-Location mechanism [RFC2557] 1609526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * and the corresponding WSP part headers in media object parts 1610526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * contain the corresponding definitions. 1611526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1612526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int startPos = pduDataStream.available(); 1613526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int tempPos = 0; 1614526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int lastLen = length; 1615526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen while(0 < lastLen) { 1616526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int header = pduDataStream.read(); 1617526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(-1 != header); 1618526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen--; 1619526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1620526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (header > TEXT_MAX) { 1621526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Number assigned headers. 1622526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (header) { 1623526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_CONTENT_LOCATION: 1624526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1625526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 1626526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Content-location-value = Uri-value 1627526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1628526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentLocation = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1629526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != contentLocation) { 1630526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentLocation(contentLocation); 1631526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1632526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1633526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen tempPos = pduDataStream.available(); 1634526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = length - (startPos - tempPos); 1635526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1636526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_CONTENT_ID: 1637526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1638526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 1639526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Content-ID-value = Quoted-string 1640526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1641526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentId = parseWapString(pduDataStream, TYPE_QUOTED_STRING); 1642526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != contentId) { 1643526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentId(contentId); 1644526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1645526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1646526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen tempPos = pduDataStream.available(); 1647526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = length - (startPos - tempPos); 1648526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1649526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_DEP_CONTENT_DISPOSITION: 1650526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduPart.P_CONTENT_DISPOSITION: 1651526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1652526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 1653526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Content-disposition-value = Value-length Disposition *(Parameter) 1654526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Disposition = Form-data | Attachment | Inline | Token-text 1655526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Form-data = <Octet 128> 1656526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Attachment = <Octet 129> 1657526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Inline = <Octet 130> 1658526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1659526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1660526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* 1661526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * some carrier mmsc servers do not support content_disposition 1662526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * field correctly 1663526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1664526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen boolean contentDisposition = Resources.getSystem().getBoolean(com 1665526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen .android.internal.R.bool.config_mms_content_disposition_support); 1666526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1667526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (contentDisposition) { 1668526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int len = parseValueLength(pduDataStream); 1669526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.mark(1); 1670526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int thisStartPos = pduDataStream.available(); 1671526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int thisEndPos = 0; 1672526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int value = pduDataStream.read(); 1673526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1674526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (value == PduPart.P_DISPOSITION_FROM_DATA ) { 1675526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA); 1676526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) { 1677526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT); 1678526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (value == PduPart.P_DISPOSITION_INLINE) { 1679526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentDisposition(PduPart.DISPOSITION_INLINE); 1680526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1681526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.reset(); 1682526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* Token-text */ 1683526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentDisposition(parseWapString(pduDataStream 1684526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen , TYPE_TEXT_STRING)); 1685526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1686526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1687526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* get filename parameter and skip other parameters */ 1688526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen thisEndPos = pduDataStream.available(); 1689526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (thisStartPos - thisEndPos < len) { 1690526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value = pduDataStream.read(); 1691526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (value == PduPart.P_FILENAME) { //filename is text-string 1692526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setFilename(parseWapString(pduDataStream 1693526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen , TYPE_TEXT_STRING)); 1694526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1695526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1696526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* skip other parameters */ 1697526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen thisEndPos = pduDataStream.available(); 1698526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (thisStartPos - thisEndPos < len) { 1699526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int last = len - (thisStartPos - thisEndPos); 1700526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] temp = new byte[last]; 1701526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pduDataStream.read(temp, 0, last); 1702526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1703526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1704526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1705526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen tempPos = pduDataStream.available(); 1706526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = length - (startPos - tempPos); 1707526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1708526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1709526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen default: 1710526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 1711526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "Not supported Part headers: " + header); 1712526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1713526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (-1 == skipWapValue(pduDataStream, lastLen)) { 1714526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(LOG_TAG, "Corrupt Part headers"); 1715526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1716526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1717526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = 0; 1718526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1719526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1720526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if ((header >= TEXT_MIN) && (header <= TEXT_MAX)) { 1721526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Not assigned header. 1722526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] tempHeader = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1723526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] tempValue = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1724526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1725526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Check the header whether it is "Content-Transfer-Encoding". 1726526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (true == 1727526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(new String(tempHeader))) { 1728526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentTransferEncoding(tempValue); 1729526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1730526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1731526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen tempPos = pduDataStream.available(); 1732526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = length - (startPos - tempPos); 1733526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1734526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 1735526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(LOG_TAG, "Not supported Part headers: " + header); 1736526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1737526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Skip all headers of this part. 1738526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (-1 == skipWapValue(pduDataStream, lastLen)) { 1739526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(LOG_TAG, "Corrupt Part headers"); 1740526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1741526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1742526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen lastLen = 0; 1743526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1744526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1745526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1746526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 != lastLen) { 1747526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(LOG_TAG, "Corrupt Part headers"); 1748526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1749526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1750526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1751526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return true; 1752526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1753526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1754526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1755526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Check the position of a specified part. 1756526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1757526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param part the part to be checked 1758526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return part position, THE_FIRST_PART when it's the 1759526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * first one, THE_LAST_PART when it's the last one. 1760526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1761526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static int checkPartPosition(PduPart part) { 1762526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(null != part); 1763526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((null == mTypeParam) && 1764526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen (null == mStartParam)) { 1765526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return THE_LAST_PART; 1766526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1767526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1768526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* check part's content-id */ 1769526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != mStartParam) { 1770526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentId = part.getContentId(); 1771526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != contentId) { 1772526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (true == Arrays.equals(mStartParam, contentId)) { 1773526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return THE_FIRST_PART; 1774526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1775526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1776526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1777526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1778526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* check part's content-type */ 1779526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != mTypeParam) { 1780526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentType = part.getContentType(); 1781526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != contentType) { 1782526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (true == Arrays.equals(mTypeParam, contentType)) { 1783526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return THE_FIRST_PART; 1784526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1785526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1786526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1787526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1788526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return THE_LAST_PART; 1789526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1790526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1791526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1792526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Check mandatory headers of a pdu. 1793526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1794526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param headers pdu headers 1795526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return true if the pdu has all of the mandatory headers, false otherwise. 1796526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1797526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen protected static boolean checkMandatoryHeader(PduHeaders headers) { 1798526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == headers) { 1799526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1800526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1801526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1802526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* get message type */ 1803526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int messageType = headers.getOctet(PduHeaders.MESSAGE_TYPE); 1804526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1805526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* check Mms-Version field */ 1806526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int mmsVersion = headers.getOctet(PduHeaders.MMS_VERSION); 1807526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 == mmsVersion) { 1808526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Every message should have Mms-Version field. 1809526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1810526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1811526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1812526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /* check mandatory header fields */ 1813526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (messageType) { 1814526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_SEND_REQ: 1815526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Content-Type field. 1816526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] srContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); 1817526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == srContentType) { 1818526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1819526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1820526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1821526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // From field. 1822526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue srFrom = headers.getEncodedStringValue(PduHeaders.FROM); 1823526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == srFrom) { 1824526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1825526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1826526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1827526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Transaction-Id field. 1828526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] srTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1829526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == srTransactionId) { 1830526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1831526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1832526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1833526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1834526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_SEND_CONF: 1835526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Response-Status field. 1836526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int scResponseStatus = headers.getOctet(PduHeaders.RESPONSE_STATUS); 1837526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 == scResponseStatus) { 1838526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1839526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1840526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1841526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Transaction-Id field. 1842526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] scTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1843526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == scTransactionId) { 1844526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1845526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1846526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1847526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1848526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 1849526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Content-Location field. 1850526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] niContentLocation = headers.getTextString(PduHeaders.CONTENT_LOCATION); 1851526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == niContentLocation) { 1852526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1853526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1854526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1855526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Expiry field. 1856526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long niExpiry = headers.getLongInteger(PduHeaders.EXPIRY); 1857526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (-1 == niExpiry) { 1858526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1859526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1860526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1861526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Message-Class field. 1862526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] niMessageClass = headers.getTextString(PduHeaders.MESSAGE_CLASS); 1863526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == niMessageClass) { 1864526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1865526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1866526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1867526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Message-Size field. 1868526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long niMessageSize = headers.getLongInteger(PduHeaders.MESSAGE_SIZE); 1869526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (-1 == niMessageSize) { 1870526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1871526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1872526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1873526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Transaction-Id field. 1874526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] niTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1875526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == niTransactionId) { 1876526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1877526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1878526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1879526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1880526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: 1881526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Status field. 1882526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int nriStatus = headers.getOctet(PduHeaders.STATUS); 1883526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 == nriStatus) { 1884526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1885526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1886526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1887526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Transaction-Id field. 1888526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] nriTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1889526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == nriTransactionId) { 1890526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1891526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1892526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1893526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1894526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: 1895526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Content-Type field. 1896526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] rcContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); 1897526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == rcContentType) { 1898526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1899526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1900526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1901526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Date field. 1902526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long rcDate = headers.getLongInteger(PduHeaders.DATE); 1903526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (-1 == rcDate) { 1904526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1905526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1906526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1907526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1908526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: 1909526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Date field. 1910526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long diDate = headers.getLongInteger(PduHeaders.DATE); 1911526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (-1 == diDate) { 1912526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1913526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1914526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1915526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Message-Id field. 1916526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] diMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); 1917526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == diMessageId) { 1918526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1919526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1920526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1921526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Status field. 1922526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int diStatus = headers.getOctet(PduHeaders.STATUS); 1923526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 == diStatus) { 1924526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1925526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1926526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1927526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // To field. 1928526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue[] diTo = headers.getEncodedStringValues(PduHeaders.TO); 1929526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == diTo) { 1930526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1931526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1932526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1933526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1934526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: 1935526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Transaction-Id field. 1936526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] aiTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1937526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == aiTransactionId) { 1938526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1939526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1940526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1941526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1942526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: 1943526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Date field. 1944526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long roDate = headers.getLongInteger(PduHeaders.DATE); 1945526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (-1 == roDate) { 1946526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1947526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1948526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1949526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // From field. 1950526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue roFrom = headers.getEncodedStringValue(PduHeaders.FROM); 1951526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == roFrom) { 1952526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1953526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1954526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1955526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Message-Id field. 1956526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] roMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); 1957526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == roMessageId) { 1958526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1959526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1960526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1961526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Read-Status field. 1962526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int roReadStatus = headers.getOctet(PduHeaders.READ_STATUS); 1963526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 == roReadStatus) { 1964526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1965526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1966526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1967526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // To field. 1968526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue[] roTo = headers.getEncodedStringValues(PduHeaders.TO); 1969526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == roTo) { 1970526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1971526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1972526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1973526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1974526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_READ_REC_IND: 1975526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // From field. 1976526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue rrFrom = headers.getEncodedStringValue(PduHeaders.FROM); 1977526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == rrFrom) { 1978526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1979526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1980526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1981526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Message-Id field. 1982526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] rrMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); 1983526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == rrMessageId) { 1984526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1985526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1986526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1987526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Read-Status field. 1988526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int rrReadStatus = headers.getOctet(PduHeaders.READ_STATUS); 1989526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (0 == rrReadStatus) { 1990526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1991526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1992526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1993526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // To field. 1994526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue[] rrTo = headers.getEncodedStringValues(PduHeaders.TO); 1995526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == rrTo) { 1996526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 1997526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1998526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1999526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 2000526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen default: 2001526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Parser doesn't support this message type in this version. 2002526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return false; 2003526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 2004526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 2005526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return true; 2006526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 2007526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen} 2008