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