1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2007-2008 Esmertec AG. 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2007-2008 The Android Open Source Project 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage android.support.v7.mms.pdu; 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.util.Log; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.ByteArrayInputStream; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.ByteArrayOutputStream; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.UnsupportedEncodingException; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.Arrays; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.HashMap; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class PduParser { 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The next are WAP values defined in WSP specification. 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int QUOTE = 127; 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int LENGTH_QUOTE = 31; 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int TEXT_MIN = 32; 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int TEXT_MAX = 127; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int SHORT_INTEGER_MAX = 127; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int SHORT_LENGTH_MAX = 30; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int LONG_INTEGER_LENGTH_MAX = 8; 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int QUOTED_STRING_FLAG = 34; 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int END_STRING_FLAG = 0x00; 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd //The next two are used by the interface "parseWapString" to 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd //distinguish Text-String and Quoted-String. 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int TYPE_TEXT_STRING = 0; 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int TYPE_QUOTED_STRING = 1; 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int TYPE_TOKEN_STRING = 2; 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Specify the part position. 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int THE_FIRST_PART = 0; 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int THE_LAST_PART = 1; 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The pdu data. 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ByteArrayInputStream mPduDataStream = null; 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Store pdu headers 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private PduHeaders mHeaders = null; 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Store pdu parts. 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private PduBody mBody = null; 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Store the "type" parameter in "Content-Type" header field. 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static byte[] mTypeParam = null; 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Store the "start" parameter in "Content-Type" header field. 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static byte[] mStartParam = null; 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The log tag. 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String LOG_TAG = "PduParser"; 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final boolean DEBUG = false; 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final boolean LOCAL_LOGV = false; 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Whether to parse content-disposition part header 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final boolean mParseContentDisposition; 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constructor. 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data to be parsed 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param parseContentDisposition whether to parse the Content-Disposition part header 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public PduParser(byte[] pduDataStream, boolean parseContentDisposition) { 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mPduDataStream = new ByteArrayInputStream(pduDataStream); 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mParseContentDisposition = parseContentDisposition; 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse the pdu. 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the pdu structure if parsing successfully. 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * null if parsing error happened or mandatory fields are not set. 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public GenericPdu parse(){ 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mPduDataStream == null) { 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse headers */ 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mHeaders = parseHeaders(mPduDataStream); 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == mHeaders) { 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Parse headers failed. 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* get the message type */ 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int messageType = mHeaders.getOctet(PduHeaders.MESSAGE_TYPE); 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* check mandatory header fields */ 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (false == checkMandatoryHeader(mHeaders)) { 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("check mandatory headers failed!"); 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((PduHeaders.MESSAGE_TYPE_SEND_REQ == messageType) || 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF == messageType)) { 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* need to parse the parts */ 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mBody = parseParts(mPduDataStream); 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == mBody) { 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Parse parts failed. 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (messageType) { 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_SEND_REQ: 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_REQ"); 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd SendReq sendReq = new SendReq(mHeaders, mBody); 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return sendReq; 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_SEND_CONF: 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_CONF"); 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd SendConf sendConf = new SendConf(mHeaders); 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return sendConf; 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFICATION_IND"); 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd NotificationInd notificationInd = 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new NotificationInd(mHeaders); 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return notificationInd; 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFYRESP_IND"); 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd NotifyRespInd notifyRespInd = 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new NotifyRespInd(mHeaders); 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return notifyRespInd; 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_RETRIEVE_CONF"); 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd RetrieveConf retrieveConf = 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new RetrieveConf(mHeaders, mBody); 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] contentType = retrieveConf.getContentType(); 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == contentType) { 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String ctTypeStr = new String(contentType); 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (ctTypeStr.equals(ContentType.MULTIPART_MIXED) 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd || ctTypeStr.equals(ContentType.MULTIPART_RELATED) 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // The MMS content type must be "application/vnd.wap.multipart.mixed" 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // or "application/vnd.wap.multipart.related" 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // or "application/vnd.wap.multipart.alternative" 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return retrieveConf; 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // "application/vnd.wap.multipart.alternative" 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // should take only the first part. 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduPart firstPart = mBody.getPart(0); 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mBody.removeAll(); 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mBody.addPart(0, firstPart); 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return retrieveConf; 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_DELIVERY_IND"); 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd DeliveryInd deliveryInd = 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new DeliveryInd(mHeaders); 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return deliveryInd; 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_ACKNOWLEDGE_IND"); 203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd AcknowledgeInd acknowledgeInd = 205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new AcknowledgeInd(mHeaders); 206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return acknowledgeInd; 207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: 208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_ORIG_IND"); 210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ReadOrigInd readOrigInd = 212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new ReadOrigInd(mHeaders); 213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return readOrigInd; 214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_READ_REC_IND: 215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_REC_IND"); 217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ReadRecInd readRecInd = 219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new ReadRecInd(mHeaders); 220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return readRecInd; 221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: 222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("Parser doesn't support this message type in this version!"); 223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse pdu headers. 229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return headers in PduHeaders structure, null when parse fail 232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream){ 234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (pduDataStream == null) { 235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean keepParsing = true; 238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders headers = new PduHeaders(); 239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd while (keepParsing && (pduDataStream.available() > 0)) { 241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int headerField = extractByteValue(pduDataStream); 243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse custom text header */ 244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) { 245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING); 247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "TextHeader: " + new String(bVal)); 249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* we should ignore it at the moment */ 251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd continue; 252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (headerField) { 254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE: 255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int messageType = extractByteValue(pduDataStream); 257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: messageType: " + messageType); 259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (messageType) { 261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // We don't support these kind of messages now. 262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: 263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_FORWARD_CONF: 264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ: 265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF: 266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ: 267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF: 268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ: 269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF: 270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ: 271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF: 272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_MBOX_DESCR: 273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_DELETE_REQ: 274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_DELETE_CONF: 275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_CANCEL_REQ: 276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_CANCEL_CONF: 277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setOctet(messageType, headerField); 281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(InvalidHeaderValueException e) { 282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("Set invalid Octet value: " + messageType + 283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd " into the header filed: " + headerField); 284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Octet header field!"); 287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Octect value */ 292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.REPORT_ALLOWED: 293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.ADAPTATION_ALLOWED: 294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.DELIVERY_REPORT: 295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.DRM_CONTENT: 296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.DISTRIBUTION_INDICATOR: 297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.QUOTAS: 298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.READ_REPORT: 299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.STORE: 300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.STORED: 301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.TOTALS: 302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.SENDER_VISIBILITY: 303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.READ_STATUS: 304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.CANCEL_STATUS: 305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.PRIORITY: 306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.STATUS: 307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.REPLY_CHARGING: 308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MM_STATE: 309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.RECOMMENDED_RETRIEVAL_MODE: 310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.CONTENT_CLASS: 311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.RETRIEVE_STATUS: 312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.STORE_STATUS: 313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The following field has a different value when 315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. 316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * For now we ignore this fact, since we do not support these PDUs 317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.RESPONSE_STATUS: 319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int value = extractByteValue(pduDataStream); 321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: byte: " + headerField + " value: " + 323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd value); 324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setOctet(value, headerField); 328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(InvalidHeaderValueException e) { 329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("Set invalid Octet value: " + value + 330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd " into the header filed: " + headerField); 331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Octet header field!"); 334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Long-Integer */ 340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.DATE: 341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.REPLY_CHARGING_SIZE: 342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_SIZE: 343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long value = parseLongInteger(pduDataStream); 346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: longint: " + headerField + " value: " + 348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd value); 349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setLongInteger(value, headerField); 351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Long-Integer header field!"); 353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Integer-Value */ 359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_COUNT: 360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.START: 361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.LIMIT: 362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long value = parseIntegerValue(pduDataStream); 365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: int: " + headerField + " value: " + 367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd value); 368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setLongInteger(value, headerField); 370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Long-Integer header field!"); 372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Text-String */ 378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.TRANSACTION_ID: 379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.REPLY_CHARGING_ID: 380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.AUX_APPLIC_ID: 381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.APPLIC_ID: 382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.REPLY_APPLIC_ID: 383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The next three header fields are email addresses 385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * as defined in RFC2822, 386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * not including the characters "<" and ">" 387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_ID: 389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.REPLACE_ID: 390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.CANCEL_ID: 391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The following field has a different value when 393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. 394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * For now we ignore this fact, since we do not support these PDUs 395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.CONTENT_LOCATION: 397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING); 399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != value) { 400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: string: " + headerField + " value: " + 403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new String(value)); 404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setTextString(value, headerField); 406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Text-String header field!"); 410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Encoded-string-value */ 417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.SUBJECT: 418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT: 419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.RETRIEVE_TEXT: 420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.STATUS_TEXT: 421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.STORE_STATUS_TEXT: 422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* the next one is not support 423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * M-Mbox-Delete.conf and M-Delete.conf now */ 424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.RESPONSE_TEXT: 425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue value = 427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseEncodedStringValue(pduDataStream); 428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != value) { 429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: encoded string: " + headerField 432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " value: " + value.getString()); 433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setEncodedStringValue(value, headerField); 435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (RuntimeException e) { 438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Encoded-String-Value header field!"); 439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Addressing model */ 446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.BCC: 447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.CC: 448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.TO: 449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue value = 451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseEncodedStringValue(pduDataStream); 452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != value) { 453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] address = value.getTextString(); 454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != address) { 455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String str = new String(address); 456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: (to/cc/bcc) address: " + headerField 458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " value: " + str); 459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int endIndex = str.indexOf("/"); 461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (endIndex > 0) { 462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd str = str.substring(0, endIndex); 463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd value.setTextString(str.getBytes()); 466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.appendEncodedStringValue(value, headerField); 474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Encoded-String-Value header field!"); 478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 482d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 483d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 484d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Value-length 485d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * (Absolute-token Date-value | Relative-token Delta-seconds-value) */ 486d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.DELIVERY_TIME: 487d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.EXPIRY: 488d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.REPLY_CHARGING_DEADLINE: 489d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 490d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse Value-length */ 491d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseValueLength(pduDataStream); 492d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 493d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Absolute-token or Relative-token */ 494d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int token = extractByteValue(pduDataStream); 495d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 496d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Date-value or Delta-seconds-value */ 497d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long timeValue; 498d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 499d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd timeValue = parseLongInteger(pduDataStream); 500d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 501d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Long-Integer header field!"); 502d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 503d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 504d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (PduHeaders.VALUE_RELATIVE_TOKEN == token) { 505d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* need to convert the Delta-seconds-value 506d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * into Date-value */ 507d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd timeValue = System.currentTimeMillis()/1000 + timeValue; 508d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 509d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 510d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 511d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 512d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: time value: " + headerField 513d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " value: " + timeValue); 514d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 515d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setLongInteger(timeValue, headerField); 516d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 517d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Long-Integer header field!"); 518d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 519d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 520d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 521d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 522d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 523d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.FROM: { 524d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* From-value = 525d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Value-length 526d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * (Address-present-token Encoded-string-value | Insert-address-token) 527d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 528d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue from = null; 529d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseValueLength(pduDataStream); /* parse value-length */ 530d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 531d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Address-present-token or Insert-address-token */ 532d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int fromToken = extractByteValue(pduDataStream); 533d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 534d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Address-present-token or Insert-address-token */ 535d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) { 536d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Encoded-string-value */ 537d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd from = parseEncodedStringValue(pduDataStream); 538d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != from) { 539d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] address = from.getTextString(); 540d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != address) { 541d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String str = new String(address); 542d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int endIndex = str.indexOf("/"); 543d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (endIndex > 0) { 544d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd str = str.substring(0, endIndex); 545d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 546d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 547d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd from.setTextString(str.getBytes()); 548d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 549d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 550d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 551d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 552d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 553d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 554d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 555d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 556d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd from = new EncodedStringValue( 557d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()); 558d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 559d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Encoded-String-Value header field!"); 560d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 561d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 562d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 563d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 564d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 565d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 566d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: from address: " + headerField 567d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " value: " + from.getString()); 568d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 569d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setEncodedStringValue(from, PduHeaders.FROM); 570d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 571d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 572d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 573d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Encoded-String-Value header field!"); 574d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 575d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 576d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 577d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 578d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 579d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_CLASS: { 580d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Message-class-value = Class-identifier | Token-text */ 581d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 582d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int messageClass = extractByteValue(pduDataStream); 583d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 584d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: MESSAGE_CLASS: " + headerField 585d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " value: " + messageClass); 586d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 587d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 588d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) { 589d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Class-identifier */ 590d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 591d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) { 592d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setTextString( 593d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(), 594d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.MESSAGE_CLASS); 595d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) { 596d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setTextString( 597d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(), 598d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.MESSAGE_CLASS); 599d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) { 600d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setTextString( 601d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(), 602d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.MESSAGE_CLASS); 603d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) { 604d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setTextString( 605d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(), 606d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.MESSAGE_CLASS); 607d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 608d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 609d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 610d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 611d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Text-String header field!"); 612d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 613d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 614d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 615d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Token-text */ 616d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 617d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING); 618d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != messageClassString) { 619d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 620d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS); 621d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 622d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 623d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 624d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Text-String header field!"); 625d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 626d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 627d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 628d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 629d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 630d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 631d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 632d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MMS_VERSION: { 633d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int version = parseShortInteger(pduDataStream); 634d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 635d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 636d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 637d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: MMS_VERSION: " + headerField 638d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " value: " + version); 639d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 640d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setOctet(version, PduHeaders.MMS_VERSION); 641d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(InvalidHeaderValueException e) { 642d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("Set invalid Octet value: " + version + 643d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd " into the header filed: " + headerField); 644d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 645d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 646d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Octet header field!"); 647d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 648d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 649d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 650d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 651d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 652d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.PREVIOUSLY_SENT_BY: { 653d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Previously-sent-by-value = 654d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Value-length Forwarded-count-value Encoded-string-value */ 655d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse value-length */ 656d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseValueLength(pduDataStream); 657d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 658d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse Forwarded-count-value */ 659d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 660d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseIntegerValue(pduDataStream); 661d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 662d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + " is not Integer-Value"); 663d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 664d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 665d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 666d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse Encoded-string-value */ 667d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue previouslySentBy = 668d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseEncodedStringValue(pduDataStream); 669d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != previouslySentBy) { 670d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 671d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 672d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_BY: " + headerField 673d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " value: " + previouslySentBy.getString()); 674d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 675d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setEncodedStringValue(previouslySentBy, 676d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.PREVIOUSLY_SENT_BY); 677d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 678d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 679d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 680d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Encoded-String-Value header field!"); 681d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 682d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 683d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 684d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 685d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 686d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 687d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.PREVIOUSLY_SENT_DATE: { 688d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Previously-sent-date-value = 689d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Value-length Forwarded-count-value Date-value */ 690d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse value-length */ 691d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseValueLength(pduDataStream); 692d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 693d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse Forwarded-count-value */ 694d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 695d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseIntegerValue(pduDataStream); 696d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 697d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + " is not Integer-Value"); 698d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 699d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 700d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 701d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Date-value */ 702d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 703d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long perviouslySentDate = parseLongInteger(pduDataStream); 704d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 705d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_DATE: " + headerField 706d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " value: " + perviouslySentDate); 707d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 708d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setLongInteger(perviouslySentDate, 709d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduHeaders.PREVIOUSLY_SENT_DATE); 710d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 711d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Long-Integer header field!"); 712d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 713d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 714d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 715d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 716d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 717d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MM_FLAGS: { 718d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* MM-flags-value = 719d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Value-length 720d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * ( Add-token | Remove-token | Filter-token ) 721d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Encoded-string-value 722d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 723d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 724d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: MM_FLAGS: " + headerField 725d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " NOT REALLY SUPPORTED"); 726d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 727d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 728d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse Value-length */ 729d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseValueLength(pduDataStream); 730d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 731d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Add-token | Remove-token | Filter-token */ 732d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extractByteValue(pduDataStream); 733d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 734d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Encoded-string-value */ 735d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseEncodedStringValue(pduDataStream); 736d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 737d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* not store this header filed in "headers", 738d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * because now PduHeaders doesn't support it */ 739d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 740d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 741d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 742d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Value-length 743d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * (Message-total-token | Size-total-token) Integer-Value */ 744d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MBOX_TOTALS: 745d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MBOX_QUOTAS: 746d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd { 747d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 748d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: MBOX_TOTALS: " + headerField); 749d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 750d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Value-length */ 751d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseValueLength(pduDataStream); 752d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 753d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Message-total-token | Size-total-token */ 754d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extractByteValue(pduDataStream); 755d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 756d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /*Integer-Value*/ 757d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 758d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseIntegerValue(pduDataStream); 759d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 760d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + " is not Integer-Value"); 761d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 762d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 763d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 764d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* not store these headers filed in "headers", 765d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd because now PduHeaders doesn't support them */ 766d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 767d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 768d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 769d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.ELEMENT_DESCRIPTOR: { 770d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 771d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: ELEMENT_DESCRIPTOR: " + headerField); 772d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 773d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseContentType(pduDataStream, null); 774d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 775d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* not store this header filed in "headers", 776d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd because now PduHeaders doesn't support it */ 777d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 778d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 779d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 780d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.CONTENT_TYPE: { 781d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd HashMap<Integer, Object> map = 782d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new HashMap<Integer, Object>(); 783d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] contentType = 784d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseContentType(pduDataStream, map); 785d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 786d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != contentType) { 787d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 788d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 789d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: CONTENT_TYPE: " + headerField + 790d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Arrays.toString(contentType)); 791d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 792d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd headers.setTextString(contentType, PduHeaders.CONTENT_TYPE); 793d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(NullPointerException e) { 794d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("null pointer error!"); 795d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(RuntimeException e) { 796d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log(headerField + "is not Text-String header field!"); 797d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 798d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 799d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 800d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 801d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* get start parameter */ 802d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mStartParam = (byte[]) map.get(PduPart.P_START); 803d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 804d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* get charset parameter */ 805d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTypeParam= (byte[]) map.get(PduPart.P_TYPE); 806d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 807d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd keepParsing = false; 808d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 809d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 810d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 811d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.CONTENT: 812d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.ADDITIONAL_HEADERS: 813d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.ATTRIBUTES: 814d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: { 815d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 816d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "parseHeaders: Unknown header: " + headerField); 817d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 818d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("Unknown header"); 819d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 820d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 821d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 822d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 823d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return headers; 824d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 825d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 826d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 827d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse pdu parts. 828d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 829d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 830d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return parts in PduBody structure 831d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 832d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected PduBody parseParts(ByteArrayInputStream pduDataStream) { 833d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (pduDataStream == null) { 834d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 835d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 836d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 837d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int count = parseUnsignedInt(pduDataStream); // get the number of parts 838d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduBody body = new PduBody(); 839d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 840d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i = 0 ; i < count ; i++) { 841d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int headerLength = parseUnsignedInt(pduDataStream); 842d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int dataLength = parseUnsignedInt(pduDataStream); 843d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduPart part = new PduPart(); 844d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int startPos = pduDataStream.available(); 845d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (startPos <= 0) { 846d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Invalid part. 847d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 848d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 849d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 850d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse part's content-type */ 851d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd HashMap<Integer, Object> map = new HashMap<Integer, Object>(); 852d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] contentType = parseContentType(pduDataStream, map); 853d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != contentType) { 854d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentType(contentType); 855d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 856d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*" 857d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 858d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 859d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* get name parameter */ 860d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] name = (byte[]) map.get(PduPart.P_NAME); 861d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != name) { 862d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setName(name); 863d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 864d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 865d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* get charset parameter */ 866d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Integer charset = (Integer) map.get(PduPart.P_CHARSET); 867d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != charset) { 868d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setCharset(charset); 869d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 870d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 871d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* parse part's headers */ 872d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int endPos = pduDataStream.available(); 873d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int partHeaderLen = headerLength - (startPos - endPos); 874d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (partHeaderLen > 0) { 875d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) { 876d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Parse part header faild. 877d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 878d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 879d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (partHeaderLen < 0) { 880d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Invalid length of content-type. 881d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 882d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 883d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 884d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* FIXME: check content-id, name, filename and content location, 885d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * if not set anyone of them, generate a default content-location 886d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 887d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((null == part.getContentLocation()) 888d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd && (null == part.getName()) 889d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd && (null == part.getFilename()) 890d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd && (null == part.getContentId())) { 891d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentLocation(Long.toOctalString( 892d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd System.currentTimeMillis()).getBytes()); 893d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 894d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 895d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* get part's data */ 896d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (dataLength > 0) { 897d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] partData = new byte[dataLength]; 898d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String partContentType = new String(part.getContentType()); 899d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.read(partData, 0, dataLength); 900d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) { 901d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // parse "multipart/vnd.wap.multipart.alternative". 902d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduBody childBody = parseParts(new ByteArrayInputStream(partData)); 903d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // take the first part of children. 904d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part = childBody.getPart(0); 905d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 906d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Check Content-Transfer-Encoding. 907d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] partDataEncoding = part.getContentTransferEncoding(); 908d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != partDataEncoding) { 909d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String encoding = new String(partDataEncoding); 910d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { 911d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Decode "base64" into "binary". 912d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd partData = Base64.decodeBase64(partData); 913d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { 914d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Decode "quoted-printable" into "binary". 915d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd partData = QuotedPrintable.decodeQuotedPrintable(partData); 916d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 917d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // "binary" is the default encoding. 918d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 919d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 920d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == partData) { 921d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd log("Decode part data error!"); 922d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 923d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 924d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setData(partData); 925d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 926d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 927d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 928d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* add this part to body */ 929d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (THE_FIRST_PART == checkPartPosition(part)) { 930d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* this is the first part */ 931d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd body.addPart(0, part); 932d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 933d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* add the part to the end */ 934d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd body.addPart(part); 935d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 936d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 937d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 938d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return body; 939d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 940d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 941d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 942d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Log status. 943d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 944d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param text log information 945d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 946d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static void log(String text) { 947d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 948d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, text); 949d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 950d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 951d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 952d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 953d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse unsigned integer. 954d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 955d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 956d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the integer, -1 when failed 957d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 958d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int parseUnsignedInt(ByteArrayInputStream pduDataStream) { 959d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 960d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 961d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The maximum size of a uintvar is 32 bits. 962d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * So it will be encoded in no more than 5 octets. 963d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 964d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 965d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int result = 0; 966d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 967d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (temp == -1) { 968d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return temp; 969d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 970d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 971d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd while((temp & 0x80) != 0) { 972d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd result = result << 7; 973d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd result |= temp & 0x7F; 974d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd temp = pduDataStream.read(); 975d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (temp == -1) { 976d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return temp; 977d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 978d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 979d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 980d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd result = result << 7; 981d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd result |= temp & 0x7F; 982d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 983d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return result; 984d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 985d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 986d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 987d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse value length. 988d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 989d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 990d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the integer 991d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 992d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int parseValueLength(ByteArrayInputStream pduDataStream) { 993d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 994d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 995d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Value-length = Short-length | (Length-quote Length) 996d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Short-length = <Any octet 0-30> 997d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Length-quote = <Octet 31> 998d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Length = Uintvar-integer 999d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Uintvar-integer = 1*5 OCTET 1000d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1001d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1002d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1003d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1004d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int first = temp & 0xFF; 1005d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1006d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (first <= SHORT_LENGTH_MAX) { 1007d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return first; 1008d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (first == LENGTH_QUOTE) { 1009d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return parseUnsignedInt(pduDataStream); 1010d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1011d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1012d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new RuntimeException("Value length > LENGTH_QUOTE!"); 1013d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1014d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1015d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1016d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse encoded string value. 1017d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1018d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1019d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the EncodedStringValue 1020d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1021d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static EncodedStringValue parseEncodedStringValue(ByteArrayInputStream pduDataStream){ 1022d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1023d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf 1024d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Encoded-string-value = Text-string | Value-length Char-set Text-string 1025d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1026d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1027d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1028d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue returnValue = null; 1029d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int charset = 0; 1030d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1031d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1032d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int first = temp & 0xFF; 1033d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (first == 0) { 1034d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new EncodedStringValue(""); 1035d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1036d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1037d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1038d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (first < TEXT_MIN) { 1039d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseValueLength(pduDataStream); 1040d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1041d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd charset = parseShortInteger(pduDataStream); //get the "Charset" 1042d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1043d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1044d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1045d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1046d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 1047d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 != charset) { 1048d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd returnValue = new EncodedStringValue(charset, textString); 1049d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1050d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd returnValue = new EncodedStringValue(textString); 1051d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1052d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch(Exception e) { 1053d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1054d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1055d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1056d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return returnValue; 1057d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1058d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1059d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1060d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse Text-String or Quoted-String. 1061d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1062d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1063d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param stringType TYPE_TEXT_STRING or TYPE_QUOTED_STRING 1064d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the string without End-of-string in byte array 1065d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1066d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static byte[] parseWapString(ByteArrayInputStream pduDataStream, 1067d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int stringType) { 1068d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1069d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1070d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1071d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Text-string = [Quote] *TEXT End-of-string 1072d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * If the first character in the TEXT is in the range of 128-255, 1073d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * a Quote character must precede it. 1074d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Otherwise the Quote character must be omitted. 1075d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The Quote is not part of the contents. 1076d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Quote = <Octet 127> 1077d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * End-of-string = <Octet 0> 1078d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1079d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Quoted-string = <Octet 34> *TEXT End-of-string 1080d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1081d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Token-text = Token End-of-string 1082d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1083d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1084d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Mark supposed beginning of Text-string 1085d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // We will have to mark again if first char is QUOTE or QUOTED_STRING_FLAG 1086d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1087d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1088d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Check first char 1089d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1090d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1091d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((TYPE_QUOTED_STRING == stringType) && 1092d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (QUOTED_STRING_FLAG == temp)) { 1093d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Mark again if QUOTED_STRING_FLAG and ignore it 1094d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1095d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if ((TYPE_TEXT_STRING == stringType) && 1096d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (QUOTE == temp)) { 1097d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Mark again if QUOTE and ignore it 1098d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1099d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Otherwise go back to origin 1101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // We are now definitely at the beginning of string 1105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Return *TOKEN or *TEXT (Text-String without QUOTE, 1107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Quoted-String without QUOTED_STRING_FLAG and without End-of-string) 1108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getWapString(pduDataStream, stringType); 1110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check TOKEN data defined in RFC2616. 1114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param ch checking data 1115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true when ch is TOKEN, false when ch is not TOKEN 1116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static boolean isTokenCharacter(int ch) { 1118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Token = 1*<any CHAR except CTLs or separators> 1120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * separators = "("(40) | ")"(41) | "<"(60) | ">"(62) | "@"(64) 1121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * | ","(44) | ";"(59) | ":"(58) | "\"(92) | <">(34) 1122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * | "/"(47) | "["(91) | "]"(93) | "?"(63) | "="(61) 1123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * | "{"(123) | "}"(125) | SP(32) | HT(9) 1124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * CHAR = <any US-ASCII character (octets 0 - 127)> 1125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * CTL = <any US-ASCII control character 1126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * (octets 0 - 31) and DEL (127)> 1127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * SP = <US-ASCII SP, space (32)> 1128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * HT = <US-ASCII HT, horizontal-tab (9)> 1129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if((ch < 33) || (ch > 126)) { 1131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch(ch) { 1135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '"': /* '"' */ 1136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '(': /* '(' */ 1137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case ')': /* ')' */ 1138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case ',': /* ',' */ 1139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '/': /* '/' */ 1140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case ':': /* ':' */ 1141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case ';': /* ';' */ 1142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '<': /* '<' */ 1143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '=': /* '=' */ 1144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '>': /* '>' */ 1145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '?': /* '?' */ 1146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '@': /* '@' */ 1147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '[': /* '[' */ 1148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '\\': /* '\' */ 1149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case ']': /* ']' */ 1150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '{': /* '{' */ 1151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '}': /* '}' */ 1152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 1156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check TEXT data defined in RFC2616. 1160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param ch checking data 1161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true when ch is TEXT, false when ch is not TEXT 1162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static boolean isText(int ch) { 1164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * TEXT = <any OCTET except CTLs, 1166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * but including LWS> 1167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * CTL = <any US-ASCII control character 1168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * (octets 0 - 31) and DEL (127)> 1169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * LWS = [CRLF] 1*( SP | HT ) 1170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * CRLF = CR LF 1171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * CR = <US-ASCII CR, carriage return (13)> 1172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * LF = <US-ASCII LF, linefeed (10)> 1173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if(((ch >= 32) && (ch <= 126)) || ((ch >= 128) && (ch <= 255))) { 1175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 1176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch(ch) { 1179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '\t': /* '\t' */ 1180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '\n': /* '\n' */ 1181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case '\r': /* '\r' */ 1182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 1183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static byte[] getWapString(ByteArrayInputStream pduDataStream, 1189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int stringType) { 1190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ByteArrayOutputStream out = new ByteArrayOutputStream(); 1192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd while((-1 != temp) && ('\0' != temp)) { 1195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // check each of the character 1196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (stringType == TYPE_TOKEN_STRING) { 1197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (isTokenCharacter(temp)) { 1198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd out.write(temp); 1199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (isText(temp)) { 1202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd out.write(temp); 1203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd temp = pduDataStream.read(); 1207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (out.size() > 0) { 1211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return out.toByteArray(); 1212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Extract a byte value from the input stream. 1219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the byte 1222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int extractByteValue(ByteArrayInputStream pduDataStream) { 1224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return temp & 0xFF; 1228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse Short-Integer. 1232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the byte 1235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int parseShortInteger(ByteArrayInputStream pduDataStream) { 1237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Short-integer = OCTET 1240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Integers in range 0-127 shall be encoded as a one 1241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * octet value with the most significant bit set to one (1xxx xxxx) 1242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * and with the value in the remaining least significant bits. 1243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return temp & 0x7F; 1248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse Long-Integer. 1252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return long integer 1255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static long parseLongInteger(ByteArrayInputStream pduDataStream) { 1257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Long-integer = Short-length Multi-octet-integer 1260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The Short-length indicates the length of the Multi-octet-integer 1261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Multi-octet-integer = 1*30 OCTET 1262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The content octets shall be an unsigned integer value 1263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * with the most significant octet encoded first (big-endian representation). 1264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The minimum number of octets must be used to encode the value. 1265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Short-length = <Any octet 0-30> 1266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int count = temp & 0xFF; 1271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (count > LONG_INTEGER_LENGTH_MAX) { 1273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new RuntimeException("Octet count greater than 8 and I can't represent that!"); 1274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long result = 0; 1277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i = 0 ; i < count ; i++) { 1279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd temp = pduDataStream.read(); 1280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd result <<= 8; 1282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd result += (temp & 0xFF); 1283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return result; 1286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse Integer-Value. 1290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return long integer 1293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static long parseIntegerValue(ByteArrayInputStream pduDataStream) { 1295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Integer-Value = Short-integer | Long-integer 1298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (temp > SHORT_INTEGER_MAX) { 1305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return parseShortInteger(pduDataStream); 1306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return parseLongInteger(pduDataStream); 1308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * To skip length of the wap value. 1313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param length area size 1316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the values in this area 1317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int skipWapValue(ByteArrayInputStream pduDataStream, int length) { 1319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] area = new byte[length]; 1321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int readLen = pduDataStream.read(area, 0, length); 1322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (readLen < length) { //The actually read length is lower than the length 1323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return -1; 1324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return readLen; 1326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse content type parameters. For now we just support 1331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * four parameters used in mms: "type", "start", "name", "charset". 1332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param map to store parameters of Content-Type field 1335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param length length of all the parameters 1336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static void parseContentTypeParams(ByteArrayInputStream pduDataStream, 1338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd HashMap<Integer, Object> map, Integer length) { 1339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parameter = Typed-parameter | Untyped-parameter 1342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Typed-parameter = Well-known-parameter-token Typed-value 1343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * the actual expected type of the value is implied by the well-known parameter 1344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Well-known-parameter-token = Integer-value 1345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * the code values used for parameters are specified in the Assigned Numbers appendix 1346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Typed-value = Compact-value | Text-value 1347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * In addition to the expected type, there may be no value. 1348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * If the value cannot be encoded using the expected type, it shall be encoded as text. 1349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Compact-value = Integer-value | 1350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Date-value | Delta-seconds-value | Q-value | Version-value | 1351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Uri-value 1352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Untyped-parameter = Token-text Untyped-value 1353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * the type of the value is unknown, but it shall be encoded as an integer, 1354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * if that is possible. 1355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Untyped-value = Integer-value | Text-value 1356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(length > 0); 1359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int startPos = pduDataStream.available(); 1361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int tempPos = 0; 1362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int lastLen = length; 1363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd while(0 < lastLen) { 1364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int param = pduDataStream.read(); 1365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != param); 1366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen--; 1367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (param) { 1369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From rfc2387, chapter 3.1 1371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The type parameter must be specified and its value is the MIME media 1372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * type of the "root" body part. It permits a MIME user agent to 1373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * determine the content-type without reference to the enclosed body 1374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * part. If the value of the type parameter and the root body part's 1375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * content-type differ then the User Agent's behavior is undefined. 1376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * type = Constrained-encoding 1379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constrained-encoding = Extension-Media | Short-integer 1380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Extension-media = *TEXT End-of-string 1381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_TYPE: 1383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_CT_MR_TYPE: 1384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int first = extractByteValue(pduDataStream); 1386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (first > TEXT_MAX) { 1388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Short-integer (well-known type) 1389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int index = parseShortInteger(pduDataStream); 1390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (index < PduContentTypes.contentTypes.length) { 1392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] type = (PduContentTypes.contentTypes[index]).getBytes(); 1393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd map.put(PduPart.P_TYPE, type); 1394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd //not support this type, ignore it. 1396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Text-String (extension-media) 1399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] type = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((null != type) && (null != map)) { 1401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd map.put(PduPart.P_TYPE, type); 1402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempPos = pduDataStream.available(); 1406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = length - (startPos - tempPos); 1407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.3. 1411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Start Parameter Referring to Presentation 1412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From rfc2387, chapter 3.2 1414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The start parameter, if given, is the content-ID of the compound 1415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * object's "root". If not present the "root" is the first body part in 1416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * the Multipart/Related entity. The "root" is the element the 1417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * applications processes first. 1418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * start = Text-String 1421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_START: 1423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_DEP_START: 1424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] start = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((null != start) && (null != map)) { 1426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd map.put(PduPart.P_START, start); 1427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempPos = pduDataStream.available(); 1430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = length - (startPos - tempPos); 1431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From oma-ts-mms-conf-v1_3.pdf 1435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * In creation, the character set SHALL be either us-ascii 1436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * (IANA MIBenum 3) or utf-8 (IANA MIBenum 106)[Unicode]. 1437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * In retrieval, both us-ascii and utf-8 SHALL be supported. 1438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * charset = Well-known-charset|Text-String 1441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Well-known-charset = Any-charset | Integer-value 1442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Both are encoded using values from Character Set 1443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Assignments table in Assigned Numbers 1444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Any-charset = <Octet 128> 1445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Equivalent to the special RFC2616 charset value "*" 1446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_CHARSET: 1448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int firstValue = extractByteValue(pduDataStream); 1450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd //Check first char 1452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (((firstValue > TEXT_MIN) && (firstValue < TEXT_MAX)) || 1453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (END_STRING_FLAG == firstValue)) { 1454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd //Text-String (extension-charset) 1455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] charsetStr = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 1457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int charsetInt = CharacterSets.getMibEnumValue( 1458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new String(charsetStr)); 1459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd map.put(PduPart.P_CHARSET, charsetInt); 1460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (UnsupportedEncodingException e) { 1461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Not a well-known charset, use "*". 1462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.e(LOG_TAG, Arrays.toString(charsetStr), e); 1463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET); 1464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd //Well-known-charset 1467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int charset = (int) parseIntegerValue(pduDataStream); 1468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (map != null) { 1469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd map.put(PduPart.P_CHARSET, charset); 1470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempPos = pduDataStream.available(); 1474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = length - (startPos - tempPos); 1475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From oma-ts-mms-conf-v1_3.pdf 1479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * A name for multipart object SHALL be encoded using name-parameter 1480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * for Content-Type header in WSP multipart headers. 1481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1482d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1483d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * name = Text-String 1484d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1485d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_DEP_NAME: 1486d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_NAME: 1487d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] name = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1488d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((null != name) && (null != map)) { 1489d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd map.put(PduPart.P_NAME, name); 1490d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1491d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1492d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempPos = pduDataStream.available(); 1493d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = length - (startPos - tempPos); 1494d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1495d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: 1496d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 1497d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "Not supported Content-Type parameter"); 1498d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1499d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (-1 == skipWapValue(pduDataStream, lastLen)) { 1500d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.e(LOG_TAG, "Corrupt Content-Type"); 1501d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1502d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = 0; 1503d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1504d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1505d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1506d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1507d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1508d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 != lastLen) { 1509d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.e(LOG_TAG, "Corrupt Content-Type"); 1510d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1511d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1512d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1513d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1514d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse content type. 1515d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1516d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1517d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param map to store parameters in Content-Type header field 1518d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return Content-Type value 1519d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1520d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static byte[] parseContentType(ByteArrayInputStream pduDataStream, 1521d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd HashMap<Integer, Object> map) { 1522d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1523d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf 1524d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Content-type-value = Constrained-media | Content-general-form 1525d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Content-general-form = Value-length Media-type 1526d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Media-type = (Well-known-media | Extension-Media) *(Parameter) 1527d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1528d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1529d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1530d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] contentType = null; 1531d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1532d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int temp = pduDataStream.read(); 1533d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1534d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1535d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1536d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int cur = (temp & 0xFF); 1537d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1538d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cur < TEXT_MIN) { 1539d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int length = parseValueLength(pduDataStream); 1540d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int startPos = pduDataStream.available(); 1541d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1542d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd temp = pduDataStream.read(); 1543d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != temp); 1544d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1545d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int first = (temp & 0xFF); 1546d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1547d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((first >= TEXT_MIN) && (first <= TEXT_MAX)) { 1548d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1549d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (first > TEXT_MAX) { 1550d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int index = parseShortInteger(pduDataStream); 1551d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1552d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (index < PduContentTypes.contentTypes.length) { //well-known type 1553d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd contentType = (PduContentTypes.contentTypes[index]).getBytes(); 1554d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1555d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1556d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1557d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1558d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1559d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.e(LOG_TAG, "Corrupt content-type"); 1560d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" 1561d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1562d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1563d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int endPos = pduDataStream.available(); 1564d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int parameterLen = length - (startPos - endPos); 1565d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (parameterLen > 0) {//have parameters 1566d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseContentTypeParams(pduDataStream, map, parameterLen); 1567d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1568d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1569d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (parameterLen < 0) { 1570d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.e(LOG_TAG, "Corrupt MMS message"); 1571d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" 1572d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1573d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (cur <= TEXT_MAX) { 1574d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1575d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1576d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd contentType = 1577d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (PduContentTypes.contentTypes[parseShortInteger(pduDataStream)]).getBytes(); 1578d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1579d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1580d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return contentType; 1581d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1582d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1583d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1584d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse part's headers. 1585d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1586d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param pduDataStream pdu data input stream 1587d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param part to store the header informations of the part 1588d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param length length of the headers 1589d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if parse successfully, false otherwise 1590d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1591d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected boolean parsePartHeaders(ByteArrayInputStream pduDataStream, 1592d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduPart part, int length) { 1593d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != pduDataStream); 1594d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != part); 1595d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(length > 0); 1596d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1597d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1598d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2. 1599d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * A name for multipart object SHALL be encoded using name-parameter 1600d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * for Content-Type header in WSP multipart headers. 1601d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * In decoding, name-parameter of Content-Type SHALL be used if available. 1602d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * If name-parameter of Content-Type is not available, 1603d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * filename parameter of Content-Disposition header SHALL be used if available. 1604d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * If neither name-parameter of Content-Type header nor filename parameter 1605d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * of Content-Disposition header is available, 1606d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Content-Location header SHALL be used if available. 1607d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1608d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Within SMIL part the reference to the media object parts SHALL use 1609d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * either Content-ID or Content-Location mechanism [RFC2557] 1610d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * and the corresponding WSP part headers in media object parts 1611d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * contain the corresponding definitions. 1612d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1613d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int startPos = pduDataStream.available(); 1614d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int tempPos = 0; 1615d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int lastLen = length; 1616d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd while(0 < lastLen) { 1617d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int header = pduDataStream.read(); 1618d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(-1 != header); 1619d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen--; 1620d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1621d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (header > TEXT_MAX) { 1622d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Number assigned headers. 1623d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (header) { 1624d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_CONTENT_LOCATION: 1625d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1626d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 1627d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Content-location-value = Uri-value 1628d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1629d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] contentLocation = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1630d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != contentLocation) { 1631d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentLocation(contentLocation); 1632d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1633d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1634d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempPos = pduDataStream.available(); 1635d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = length - (startPos - tempPos); 1636d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1637d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_CONTENT_ID: 1638d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1639d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 1640d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Content-ID-value = Quoted-string 1641d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1642d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] contentId = parseWapString(pduDataStream, TYPE_QUOTED_STRING); 1643d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != contentId) { 1644d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentId(contentId); 1645d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1646d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1647d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempPos = pduDataStream.available(); 1648d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = length - (startPos - tempPos); 1649d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1650d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_DEP_CONTENT_DISPOSITION: 1651d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduPart.P_CONTENT_DISPOSITION: 1652d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1653d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 1654d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Content-disposition-value = Value-length Disposition *(Parameter) 1655d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Disposition = Form-data | Attachment | Inline | Token-text 1656d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Form-data = <Octet 128> 1657d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Attachment = <Octet 129> 1658d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Inline = <Octet 130> 1659d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1660d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1661d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* 1662d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * some carrier mmsc servers do not support content_disposition 1663d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * field correctly 1664d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1665d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mParseContentDisposition) { 1666d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int len = parseValueLength(pduDataStream); 1667d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.mark(1); 1668d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int thisStartPos = pduDataStream.available(); 1669d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int thisEndPos = 0; 1670d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int value = pduDataStream.read(); 1671d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1672d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (value == PduPart.P_DISPOSITION_FROM_DATA ) { 1673d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA); 1674d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) { 1675d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT); 1676d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (value == PduPart.P_DISPOSITION_INLINE) { 1677d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentDisposition(PduPart.DISPOSITION_INLINE); 1678d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1679d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.reset(); 1680d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* Token-text */ 1681d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentDisposition(parseWapString(pduDataStream 1682d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd , TYPE_TEXT_STRING)); 1683d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1684d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1685d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* get filename parameter and skip other parameters */ 1686d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd thisEndPos = pduDataStream.available(); 1687d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (thisStartPos - thisEndPos < len) { 1688d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd value = pduDataStream.read(); 1689d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (value == PduPart.P_FILENAME) { //filename is text-string 1690d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setFilename(parseWapString(pduDataStream 1691d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd , TYPE_TEXT_STRING)); 1692d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1693d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1694d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* skip other parameters */ 1695d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd thisEndPos = pduDataStream.available(); 1696d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (thisStartPos - thisEndPos < len) { 1697d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int last = len - (thisStartPos - thisEndPos); 1698d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] temp = new byte[last]; 1699d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd pduDataStream.read(temp, 0, last); 1700d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1701d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1702d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1703d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempPos = pduDataStream.available(); 1704d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = length - (startPos - tempPos); 1705d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1706d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1707d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: 1708d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 1709d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "Not supported Part headers: " + header); 1710d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1711d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (-1 == skipWapValue(pduDataStream, lastLen)) { 1712d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.e(LOG_TAG, "Corrupt Part headers"); 1713d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1714d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1715d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = 0; 1716d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1717d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1718d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if ((header >= TEXT_MIN) && (header <= TEXT_MAX)) { 1719d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Not assigned header. 1720d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] tempHeader = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1721d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] tempValue = parseWapString(pduDataStream, TYPE_TEXT_STRING); 1722d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1723d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Check the header whether it is "Content-Transfer-Encoding". 1724d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (true == 1725d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PduPart.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(new String(tempHeader))) { 1726d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.setContentTransferEncoding(tempValue); 1727d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1728d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1729d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempPos = pduDataStream.available(); 1730d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = length - (startPos - tempPos); 1731d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1732d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LOCAL_LOGV) { 1733d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.v(LOG_TAG, "Not supported Part headers: " + header); 1734d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1735d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Skip all headers of this part. 1736d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (-1 == skipWapValue(pduDataStream, lastLen)) { 1737d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.e(LOG_TAG, "Corrupt Part headers"); 1738d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1739d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1740d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd lastLen = 0; 1741d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1742d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1743d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1744d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 != lastLen) { 1745d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.e(LOG_TAG, "Corrupt Part headers"); 1746d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1747d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1748d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1749d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 1750d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1751d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1752d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1753d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check the position of a specified part. 1754d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1755d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param part the part to be checked 1756d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return part position, THE_FIRST_PART when it's the 1757d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * first one, THE_LAST_PART when it's the last one. 1758d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1759d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static int checkPartPosition(PduPart part) { 1760d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd assert(null != part); 1761d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((null == mTypeParam) && 1762d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (null == mStartParam)) { 1763d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return THE_LAST_PART; 1764d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1765d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1766d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* check part's content-id */ 1767d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != mStartParam) { 1768d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] contentId = part.getContentId(); 1769d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != contentId) { 1770d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (true == Arrays.equals(mStartParam, contentId)) { 1771d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return THE_FIRST_PART; 1772d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1773d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1774d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // This is not the first part, so append to end (keeping the original order) 1775d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Check b/19607294 for details of this change 1776d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return THE_LAST_PART; 1777d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1778d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1779d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* check part's content-type */ 1780d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != mTypeParam) { 1781d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] contentType = part.getContentType(); 1782d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null != contentType) { 1783d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (true == Arrays.equals(mTypeParam, contentType)) { 1784d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return THE_FIRST_PART; 1785d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1786d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1787d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1788d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1789d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return THE_LAST_PART; 1790d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1791d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1792d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1793d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check mandatory headers of a pdu. 1794d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1795d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param headers pdu headers 1796d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if the pdu has all of the mandatory headers, false otherwise. 1797d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1798d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static boolean checkMandatoryHeader(PduHeaders headers) { 1799d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == headers) { 1800d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1801d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1802d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1803d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* get message type */ 1804d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int messageType = headers.getOctet(PduHeaders.MESSAGE_TYPE); 1805d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1806d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* check Mms-Version field */ 1807d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int mmsVersion = headers.getOctet(PduHeaders.MMS_VERSION); 1808d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 == mmsVersion) { 1809d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Every message should have Mms-Version field. 1810d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1811d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1812d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1813d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* check mandatory header fields */ 1814d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (messageType) { 1815d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_SEND_REQ: 1816d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Content-Type field. 1817d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] srContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); 1818d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == srContentType) { 1819d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1820d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1821d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1822d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // From field. 1823d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue srFrom = headers.getEncodedStringValue(PduHeaders.FROM); 1824d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == srFrom) { 1825d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1826d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1827d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1828d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Transaction-Id field. 1829d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] srTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1830d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == srTransactionId) { 1831d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1832d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1833d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1834d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1835d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_SEND_CONF: 1836d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Response-Status field. 1837d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int scResponseStatus = headers.getOctet(PduHeaders.RESPONSE_STATUS); 1838d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 == scResponseStatus) { 1839d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1840d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1841d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1842d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Transaction-Id field. 1843d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] scTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1844d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == scTransactionId) { 1845d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1846d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1847d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1848d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1849d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 1850d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Content-Location field. 1851d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] niContentLocation = headers.getTextString(PduHeaders.CONTENT_LOCATION); 1852d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == niContentLocation) { 1853d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1854d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1855d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1856d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Expiry field. 1857d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long niExpiry = headers.getLongInteger(PduHeaders.EXPIRY); 1858d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (-1 == niExpiry) { 1859d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1860d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1861d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1862d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Message-Class field. 1863d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] niMessageClass = headers.getTextString(PduHeaders.MESSAGE_CLASS); 1864d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == niMessageClass) { 1865d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1866d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1867d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1868d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Message-Size field. 1869d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long niMessageSize = headers.getLongInteger(PduHeaders.MESSAGE_SIZE); 1870d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (-1 == niMessageSize) { 1871d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1872d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1873d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1874d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Transaction-Id field. 1875d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] niTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1876d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == niTransactionId) { 1877d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1878d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1879d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1880d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1881d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: 1882d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Status field. 1883d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int nriStatus = headers.getOctet(PduHeaders.STATUS); 1884d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 == nriStatus) { 1885d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1886d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1887d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1888d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Transaction-Id field. 1889d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] nriTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1890d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == nriTransactionId) { 1891d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1892d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1893d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1894d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1895d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: 1896d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Content-Type field. 1897d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] rcContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); 1898d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == rcContentType) { 1899d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1900d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1901d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1902d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Date field. 1903d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long rcDate = headers.getLongInteger(PduHeaders.DATE); 1904d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (-1 == rcDate) { 1905d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1906d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1907d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1908d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1909d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: 1910d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Date field. 1911d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long diDate = headers.getLongInteger(PduHeaders.DATE); 1912d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (-1 == diDate) { 1913d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1914d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1915d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1916d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Message-Id field. 1917d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] diMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); 1918d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == diMessageId) { 1919d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1920d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1921d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1922d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Status field. 1923d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int diStatus = headers.getOctet(PduHeaders.STATUS); 1924d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 == diStatus) { 1925d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1926d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1927d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1928d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // To field. 1929d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue[] diTo = headers.getEncodedStringValues(PduHeaders.TO); 1930d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == diTo) { 1931d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1932d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1933d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1934d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1935d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: 1936d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Transaction-Id field. 1937d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] aiTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); 1938d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == aiTransactionId) { 1939d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1940d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1941d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1942d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1943d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: 1944d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Date field. 1945d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long roDate = headers.getLongInteger(PduHeaders.DATE); 1946d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (-1 == roDate) { 1947d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1948d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1949d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1950d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // From field. 1951d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue roFrom = headers.getEncodedStringValue(PduHeaders.FROM); 1952d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == roFrom) { 1953d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1954d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1955d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1956d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Message-Id field. 1957d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] roMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); 1958d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == roMessageId) { 1959d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1960d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1961d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1962d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Read-Status field. 1963d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int roReadStatus = headers.getOctet(PduHeaders.READ_STATUS); 1964d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 == roReadStatus) { 1965d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1966d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1967d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1968d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // To field. 1969d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue[] roTo = headers.getEncodedStringValues(PduHeaders.TO); 1970d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == roTo) { 1971d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1972d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1973d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1974d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1975d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case PduHeaders.MESSAGE_TYPE_READ_REC_IND: 1976d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // From field. 1977d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue rrFrom = headers.getEncodedStringValue(PduHeaders.FROM); 1978d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == rrFrom) { 1979d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1980d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1981d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1982d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Message-Id field. 1983d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] rrMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); 1984d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == rrMessageId) { 1985d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1986d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1987d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1988d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Read-Status field. 1989d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int rrReadStatus = headers.getOctet(PduHeaders.READ_STATUS); 1990d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (0 == rrReadStatus) { 1991d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1992d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1993d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1994d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // To field. 1995d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd EncodedStringValue[] rrTo = headers.getEncodedStringValues(PduHeaders.TO); 1996d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (null == rrTo) { 1997d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1998d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1999d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2000d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 2001d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: 2002d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Parser doesn't support this message type in this version. 2003d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 2004d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2005d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2006d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 2007d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2008d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 2009