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