19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007-2008 Esmertec AG.
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007-2008 The Android Open Source Project
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18a87afd07c0093cab638e9ef9bc2c53c8200ca711Tom Taylorpackage com.google.android.mms.pdu;
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
22ed16d4b7deb767f10db80ba57fca3721ac814c92Wei Huangimport android.util.Log;
23ed16d4b7deb767f10db80ba57fca3721ac814c92Wei Huangimport android.text.TextUtils;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.ByteArrayOutputStream;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PduComposer {
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Address type.
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_PHONE_NUMBER_ADDRESS_TYPE = 1;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_EMAIL_ADDRESS_TYPE = 2;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_IPV4_ADDRESS_TYPE = 3;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_IPV6_ADDRESS_TYPE = 4;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_UNKNOWN_ADDRESS_TYPE = 5;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Address regular expression string.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String REGEXP_PHONE_NUMBER_ADDRESS_TYPE = "\\+?[0-9|\\.|\\-]+";
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String REGEXP_EMAIL_ADDRESS_TYPE = "[a-zA-Z| ]*\\<{0,1}[a-zA-Z| ]+@{1}" +
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "[a-zA-Z| ]+\\.{1}[a-zA-Z| ]+\\>{0,1}";
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String REGEXP_IPV6_ADDRESS_TYPE =
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "[a-fA-F]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" +
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" +
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}";
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String REGEXP_IPV4_ADDRESS_TYPE = "[0-9]{1,3}\\.{1}[0-9]{1,3}\\.{1}" +
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "[0-9]{1,3}\\.{1}[0-9]{1,3}";
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The postfix strings of address.
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String STRING_PHONE_NUMBER_ADDRESS_TYPE = "/TYPE=PLMN";
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String STRING_IPV4_ADDRESS_TYPE = "/TYPE=IPV4";
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String STRING_IPV6_ADDRESS_TYPE = "/TYPE=IPV6";
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Error values.
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_COMPOSE_SUCCESS = 0;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_COMPOSE_CONTENT_ERROR = 1;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_COMPOSE_FIELD_NOT_SET = 2;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_COMPOSE_FIELD_NOT_SUPPORTED = 3;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * WAP values defined in WSP spec.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int QUOTED_STRING_FLAG = 34;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int END_STRING_FLAG = 0;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int LENGTH_QUOTE = 31;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int TEXT_MAX = 127;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int SHORT_INTEGER_MAX = 127;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int LONG_INTEGER_LENGTH_MAX = 8;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Block size when read data from InputStream.
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final int PDU_COMPOSER_BLOCK_SIZE = 1024;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The output message.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected ByteArrayOutputStream mMessage = null;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The PDU.
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private GenericPdu mPdu = null;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Current visiting position of the mMessage.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected int mPosition = 0;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Message compose buffer stack.
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private BufferStack mStack = null;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Content resolver.
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final ContentResolver mResolver;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Header of this pdu.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private PduHeaders mPduHeader = null;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Map of all content type
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static HashMap<String, Integer> mContentTypeMap = null;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContentTypeMap = new HashMap<String, Integer>();
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i = 0; i < PduContentTypes.contentTypes.length; i++) {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContentTypeMap.put(PduContentTypes.contentTypes[i], i);
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructor.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context the context
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pdu the pdu to be composed
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PduComposer(Context context, GenericPdu pdu) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPdu = pdu;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mResolver = context.getContentResolver();
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPduHeader = pdu.getPduHeaders();
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStack = new BufferStack();
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMessage = new ByteArrayOutputStream();
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPosition = 0;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Make the message. No need to check whether mandatory fields are set,
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * because the constructors of outgoing pdus are taking care of this.
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return OutputStream of maked message. Return null if
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the PDU is invalid.
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public byte[] make() {
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get Message-type.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int type = mPdu.getMessageType();
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* make the message */
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (type) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (makeSendReqPdu() != PDU_COMPOSE_SUCCESS) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return null;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (makeNotifyResp() != PDU_COMPOSE_SUCCESS) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return null;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (makeAckInd() != PDU_COMPOSE_SUCCESS) {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return null;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (makeReadRecInd() != PDU_COMPOSE_SUCCESS) {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return null;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mMessage.toByteArray();
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  Copy buf to mMessage.
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void arraycopy(byte[] buf, int pos, int length) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMessage.write(buf, pos, length);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPosition = mPosition + length;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append a byte to mMessage.
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void append(int value) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMessage.write(value);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPosition ++;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append short integer value to mMessage.
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendShortInteger(int value) {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Short-integer = OCTET
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; Integers in range 0-127 shall be encoded as a one octet value
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; with the most significant bit set to one (1xxx xxxx) and with
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; the value in the remaining least significant bits.
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * In our implementation, only low 7 bits are stored and otherwise
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * bits are ignored.
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        append((value | 0x80) & 0xff);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append an octet number between 128 and 255 into mMessage.
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * NOTE:
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A value between 0 and 127 should be appended by using appendShortInteger.
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendOctet(int number) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        append(number);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append a short length into mMessage.
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendShortLength(int value) {
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Short-length = <Any octet 0-30>
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        append(value);
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append long integer into mMessage. it's used for really long integers.
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendLongInteger(long longInt) {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Long-integer = Short-length Multi-octet-integer
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; The Short-length indicates the length of the Multi-octet-integer
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Multi-octet-integer = 1*30 OCTET
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; The content octets shall be an unsigned integer value with the
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; most significant octet encoded first (big-endian representation).
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; The minimum number of octets must be used to encode the value.
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int size;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long temp = longInt;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Count the length of the long integer.
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for(size = 0; (temp != 0) && (size < LONG_INTEGER_LENGTH_MAX); size++) {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            temp = (temp >>> 8);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set Length.
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendShortLength(size);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Count and set the long integer.
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i;
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int shift = (size -1) * 8;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i = 0; i < size; i++) {
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            append((int)((longInt >>> shift) & 0xff));
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = shift - 8;
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append text string into mMessage.
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendTextString(byte[] text) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Text-string = [Quote] *TEXT End-of-string
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; If the first character in the TEXT is in the range of 128-255,
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; a Quote character must precede it. Otherwise the Quote character
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ;must be omitted. The Quote is not part of the contents.
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (((text[0])&0xff) > TEXT_MAX) { // No need to check for <= 255
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            append(TEXT_MAX);
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        arraycopy(text, 0, text.length);
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        append(0);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append text string into mMessage.
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendTextString(String str) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Text-string = [Quote] *TEXT End-of-string
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; If the first character in the TEXT is in the range of 128-255,
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; a Quote character must precede it. Otherwise the Quote character
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ;must be omitted. The Quote is not part of the contents.
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendTextString(str.getBytes());
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append encoded string value to mMessage.
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendEncodedString(EncodedStringValue enStr) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From OMA-TS-MMS-ENC-V1_3-20050927-C:
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Encoded-string-value = Text-string | Value-length Char-set Text-string
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assert(enStr != null);
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int charset = enStr.getCharacterSet();
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        byte[] textString = enStr.getTextString();
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (null == textString) {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * In the implementation of EncodedStringValue, the charset field will
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * never be 0. It will always be composed as
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Encoded-string-value = Value-length Char-set Text-string
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStack.newbuf();
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PositionMarker start = mStack.mark();
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendShortInteger(charset);
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendTextString(textString);
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int len = start.getLength();
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStack.pop();
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendValueLength(len);
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStack.copy();
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append uintvar integer into mMessage.
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendUintvarInteger(long value) {
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * To encode a large unsigned integer, split it into 7-bit fragments
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * and place them in the payloads of multiple octets. The most significant
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * bits are placed in the first octets with the least significant bits
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ending up in the last octet. All octets MUST set the Continue bit to 1
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * except the last octet, which MUST set the Continue bit to 0.
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i;
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long max = SHORT_INTEGER_MAX;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i = 0; i < 5; i++) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (value < max) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            max = (max << 7) | 0x7fl;
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while(i > 0) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long temp = value >>> (i * 7);
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            temp = temp & 0x7f;
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            append((int)((temp | 0x80) & 0xff));
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            i--;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        append((int)(value & 0x7f));
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append date value into mMessage.
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendDateValue(long date) {
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From OMA-TS-MMS-ENC-V1_3-20050927-C:
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Date-value = Long-integer
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendLongInteger(date);
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append value length to mMessage.
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendValueLength(long value) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Value-length = Short-length | (Length-quote Length)
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ; Value length is used to indicate the length of the value to follow
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Short-length = <Any octet 0-30>
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Length-quote = <Octet 31>
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Length = Uintvar-integer
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (value < LENGTH_QUOTE) {
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendShortLength((int) value);
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        append(LENGTH_QUOTE);
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendUintvarInteger(value);
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append quoted string to mMessage.
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendQuotedString(byte[] text) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Quoted-string = <Octet 34> *TEXT End-of-string
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ;quotation-marks <"> removed.
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        append(QUOTED_STRING_FLAG);
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        arraycopy(text, 0, text.length);
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        append(END_STRING_FLAG);
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append quoted string to mMessage.
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation doesn't check the validity of parameter, since it
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * assumes that the values are validated in the GenericPdu setter methods.
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void appendQuotedString(String str) {
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From WAP-230-WSP-20010705-a:
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Quoted-string = <Octet 34> *TEXT End-of-string
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ;quotation-marks <"> removed.
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendQuotedString(str.getBytes());
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45530e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang    private EncodedStringValue appendAddressType(EncodedStringValue address) {
45630e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang        EncodedStringValue temp = null;
45730e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang
45830e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang        try {
45930e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang            int addressType = checkAddressType(address.getString());
46030e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang            temp = EncodedStringValue.copy(address);
46130e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang            if (PDU_PHONE_NUMBER_ADDRESS_TYPE == addressType) {
46230e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                // Phone number.
46330e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                temp.appendTextString(STRING_PHONE_NUMBER_ADDRESS_TYPE.getBytes());
46430e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang            } else if (PDU_IPV4_ADDRESS_TYPE == addressType) {
46530e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                // Ipv4 address.
46630e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                temp.appendTextString(STRING_IPV4_ADDRESS_TYPE.getBytes());
46730e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang            } else if (PDU_IPV6_ADDRESS_TYPE == addressType) {
46830e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                // Ipv6 address.
46930e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                temp.appendTextString(STRING_IPV6_ADDRESS_TYPE.getBytes());
47030e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang            }
47130e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang        } catch (NullPointerException e) {
47230e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang            return null;
47330e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang        }
47430e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang
47530e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang        return temp;
47630e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang    }
47730e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Append header to mMessage.
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int appendHeader(int field) {
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (field) {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.MMS_VERSION:
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(field);
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int version = mPduHeader.getOctet(field);
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (0 == version) {
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendShortInteger(PduHeaders.CURRENT_MMS_VERSION);
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendShortInteger(version);
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.MESSAGE_ID:
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.TRANSACTION_ID:
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                byte[] textString = mPduHeader.getTextString(field);
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (null == textString) {
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_FIELD_NOT_SET;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(field);
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendTextString(textString);
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.TO:
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.BCC:
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.CC:
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                EncodedStringValue[] addr = mPduHeader.getEncodedStringValues(field);
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (null == addr) {
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_FIELD_NOT_SET;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                EncodedStringValue temp;
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0; i < addr.length; i++) {
51730e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                    temp = appendAddressType(addr[i]);
51830e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                    if (temp == null) {
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return PDU_COMPOSE_CONTENT_ERROR;
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendOctet(field);
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendEncodedString(temp);
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.FROM:
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Value-length (Address-present-token Encoded-string-value | Insert-address-token)
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(field);
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                EncodedStringValue from = mPduHeader.getEncodedStringValue(field);
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((from == null)
533ed16d4b7deb767f10db80ba57fca3721ac814c92Wei Huang                        || TextUtils.isEmpty(from.getString())
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || new String(from.getTextString()).equals(
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Length of from = 1
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    append(1);
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Insert-address-token = <Octet 129>
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    append(PduHeaders.FROM_INSERT_ADDRESS_TOKEN);
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mStack.newbuf();
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    PositionMarker fstart = mStack.mark();
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Address-present-token = <Octet 128>
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    append(PduHeaders.FROM_ADDRESS_PRESENT_TOKEN);
54630e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang
54730e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                    temp = appendAddressType(from);
54830e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                    if (temp == null) {
54930e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                        return PDU_COMPOSE_CONTENT_ERROR;
55030e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                    }
55130e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang
55230e59f6ec13bb1f706c6a82ae5d508bb619f4ab6Wei Huang                    appendEncodedString(temp);
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int flen = fstart.getLength();
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mStack.pop();
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendValueLength(flen);
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mStack.copy();
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.READ_STATUS:
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.STATUS:
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.REPORT_ALLOWED:
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.PRIORITY:
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.DELIVERY_REPORT:
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.READ_REPORT:
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int octet = mPduHeader.getOctet(field);
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (0 == octet) {
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_FIELD_NOT_SET;
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(field);
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(octet);
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.DATE:
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long date = mPduHeader.getLongInteger(field);
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (-1 == date) {
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_FIELD_NOT_SET;
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(field);
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendDateValue(date);
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.SUBJECT:
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                EncodedStringValue enString =
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mPduHeader.getEncodedStringValue(field);
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (null == enString) {
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_FIELD_NOT_SET;
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(field);
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendEncodedString(enString);
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.MESSAGE_CLASS:
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                byte[] messageClass = mPduHeader.getTextString(field);
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (null == messageClass) {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_FIELD_NOT_SET;
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(field);
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Arrays.equals(messageClass,
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes())) {
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendOctet(PduHeaders.MESSAGE_CLASS_ADVERTISEMENT);
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (Arrays.equals(messageClass,
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes())) {
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendOctet(PduHeaders.MESSAGE_CLASS_AUTO);
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (Arrays.equals(messageClass,
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes())) {
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendOctet(PduHeaders.MESSAGE_CLASS_PERSONAL);
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (Arrays.equals(messageClass,
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes())) {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendOctet(PduHeaders.MESSAGE_CLASS_INFORMATIONAL);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendTextString(messageClass);
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PduHeaders.EXPIRY:
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long expiry = mPduHeader.getLongInteger(field);
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (-1 == expiry) {
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_FIELD_NOT_SET;
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(field);
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStack.newbuf();
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                PositionMarker expiryStart = mStack.mark();
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                append(PduHeaders.VALUE_RELATIVE_TOKEN);
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendLongInteger(expiry);
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int expiryLength = expiryStart.getLength();
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStack.pop();
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendValueLength(expiryLength);
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStack.copy();
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return PDU_COMPOSE_FIELD_NOT_SUPPORTED;
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return PDU_COMPOSE_SUCCESS;
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Make ReadRec.Ind.
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int makeReadRecInd() {
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mMessage == null) {
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMessage = new ByteArrayOutputStream();
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPosition = 0;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Message-Type
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.MESSAGE_TYPE);
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.MESSAGE_TYPE_READ_REC_IND);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-MMS-Version
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Message-ID
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.MESSAGE_ID) != PDU_COMPOSE_SUCCESS) {
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // To
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_SUCCESS) {
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // From
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Date Optional
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.DATE);
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Read-Status
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.READ_STATUS) != PDU_COMPOSE_SUCCESS) {
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Applic-ID Optional(not support)
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Reply-Applic-ID Optional(not support)
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Aux-Applic-Info Optional(not support)
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return PDU_COMPOSE_SUCCESS;
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Make NotifyResp.Ind.
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int makeNotifyResp() {
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mMessage == null) {
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMessage = new ByteArrayOutputStream();
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPosition = 0;
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    X-Mms-Message-Type
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.MESSAGE_TYPE);
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND);
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Transaction-ID
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) {
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-MMS-Version
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //  X-Mms-Status
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.STATUS) != PDU_COMPOSE_SUCCESS) {
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Report-Allowed Optional (not support)
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return PDU_COMPOSE_SUCCESS;
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Make Acknowledge.Ind.
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int makeAckInd() {
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mMessage == null) {
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMessage = new ByteArrayOutputStream();
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPosition = 0;
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    X-Mms-Message-Type
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.MESSAGE_TYPE);
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND);
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Transaction-ID
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) {
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //     X-Mms-MMS-Version
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Report-Allowed Optional
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.REPORT_ALLOWED);
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return PDU_COMPOSE_SUCCESS;
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Make Send.req.
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int makeSendReqPdu() {
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mMessage == null) {
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMessage = new ByteArrayOutputStream();
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPosition = 0;
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Message-Type
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.MESSAGE_TYPE);
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.MESSAGE_TYPE_SEND_REQ);
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Transaction-ID
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.TRANSACTION_ID);
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        byte[] trid = mPduHeader.getTextString(PduHeaders.TRANSACTION_ID);
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (trid == null) {
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Transaction-ID should be set(by Transaction) before make().
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("Transaction-ID is null.");
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendTextString(trid);
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //  X-Mms-MMS-Version
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Date Date-value Optional.
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.DATE);
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // From
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) {
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean recipient = false;
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // To
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_CONTENT_ERROR) {
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            recipient = true;
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Cc
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.CC) != PDU_COMPOSE_CONTENT_ERROR) {
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            recipient = true;
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Bcc
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (appendHeader(PduHeaders.BCC) != PDU_COMPOSE_CONTENT_ERROR) {
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            recipient = true;
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Need at least one of "cc", "bcc" and "to".
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (false == recipient) {
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Subject Optional
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.SUBJECT);
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Message-Class Optional
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Message-class-value = Class-identifier | Token-text
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.MESSAGE_CLASS);
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Expiry Optional
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.EXPIRY);
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Priority Optional
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.PRIORITY);
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Delivery-Report Optional
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.DELIVERY_REPORT);
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // X-Mms-Read-Report Optional
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendHeader(PduHeaders.READ_REPORT);
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    Content-Type
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendOctet(PduHeaders.CONTENT_TYPE);
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //  Message body
83854c3ce2f14b8aa8559150b75f85c89a17dfaeba8Matthias Thomae        return makeMessageBody();
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Make message body.
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int makeMessageBody() {
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // 1. add body informations
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStack.newbuf();  // Switching buffer because we need to
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PositionMarker ctStart = mStack.mark();
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This contentTypeIdentifier should be used for type of attachment...
851c6b336d6a411ceacba4aa0dab9a01a5083729c71Wei Huang        String contentType = new String(mPduHeader.getTextString(PduHeaders.CONTENT_TYPE));
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Integer contentTypeIdentifier = mContentTypeMap.get(contentType);
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (contentTypeIdentifier == null) {
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // content type is mandatory
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_CONTENT_ERROR;
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendShortInteger(contentTypeIdentifier.intValue());
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // content-type parameter: start
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PduBody body = ((SendReq) mPdu).getBody();
862c6b336d6a411ceacba4aa0dab9a01a5083729c71Wei Huang        if (null == body || body.getPartsNum() == 0) {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // empty message
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendUintvarInteger(0);
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStack.pop();
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStack.copy();
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_COMPOSE_SUCCESS;
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PduPart part;
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            part = body.getPart(0);
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte[] start = part.getContentId();
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (start != null) {
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(PduPart.P_DEP_START);
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (('<' == start[0]) && ('>' == start[start.length - 1])) {
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendTextString(start);
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendTextString("<" + new String(start) + ">");
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // content-type parameter: type
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendOctet(PduPart.P_CT_MR_TYPE);
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendTextString(part.getContentType());
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        catch (ArrayIndexOutOfBoundsException e){
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            e.printStackTrace();
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int ctLength = ctStart.getLength();
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStack.pop();
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendValueLength(ctLength);
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStack.copy();
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // 3. add content
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int partNum = body.getPartsNum();
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendUintvarInteger(partNum);
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < partNum; i++) {
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            part = body.getPart(i);
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStack.newbuf();  // Leaving space for header lengh and data length
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PositionMarker attachment = mStack.mark();
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStack.newbuf();  // Leaving space for Content-Type length
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PositionMarker contentTypeBegin = mStack.mark();
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte[] partContentType = part.getContentType();
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (partContentType == null) {
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // content type is mandatory
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return PDU_COMPOSE_CONTENT_ERROR;
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // content-type value
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Integer partContentTypeIdentifier =
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mContentTypeMap.get(new String(partContentType));
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (partContentTypeIdentifier == null) {
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendTextString(partContentType);
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendShortInteger(partContentTypeIdentifier.intValue());
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* Content-type parameter : name.
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * The value of name, filename, content-location is the same.
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * Just one of them is enough for this PDU.
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             */
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte[] name = part.getName();
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (null == name) {
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = part.getFilename();
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (null == name) {
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    name = part.getContentLocation();
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (null == name) {
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        /* at lease one of name, filename, Content-location
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         * should be available.
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         */
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return PDU_COMPOSE_CONTENT_ERROR;
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendOctet(PduPart.P_DEP_NAME);
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendTextString(name);
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // content-type parameter : charset
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int charset = part.getCharset();
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (charset != 0) {
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(PduPart.P_CHARSET);
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendShortInteger(charset);
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int contentTypeLength = contentTypeBegin.getLength();
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStack.pop();
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendValueLength(contentTypeLength);
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStack.copy();
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // content id
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte[] contentId = part.getContentId();
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (null != contentId) {
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                appendOctet(PduPart.P_CONTENT_ID);
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (('<' == contentId[0]) && ('>' == contentId[contentId.length - 1])) {
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendQuotedString(contentId);
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    appendQuotedString("<" + new String(contentId) + ">");
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // content-location
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte[] contentLocation = part.getContentLocation();
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (null != contentLocation) {
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            	appendOctet(PduPart.P_CONTENT_LOCATION);
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            	appendTextString(contentLocation);
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // content
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int headerLength = attachment.getLength();
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int dataLength = 0; // Just for safety...
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte[] partData = part.getData();
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (partData != null) {
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                arraycopy(partData, 0, partData.length);
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dataLength = partData.length;
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputStream cr;
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    byte[] buffer = new byte[PDU_COMPOSER_BLOCK_SIZE];
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    cr = mResolver.openInputStream(part.getDataUri());
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int len = 0;
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    while ((len = cr.read(buffer)) != -1) {
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mMessage.write(buffer, 0, len);
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mPosition += len;
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        dataLength += len;
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (FileNotFoundException e) {
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_CONTENT_ERROR;
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (IOException e) {
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_CONTENT_ERROR;
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RuntimeException e) {
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return PDU_COMPOSE_CONTENT_ERROR;
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (dataLength != (attachment.getLength() - headerLength)) {
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException("BUG: Length sanity check failed");
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStack.pop();
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendUintvarInteger(headerLength);
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            appendUintvarInteger(dataLength);
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStack.copy();
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return PDU_COMPOSE_SUCCESS;
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  Record current message informations.
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private class LengthRecordNode {
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ByteArrayOutputStream currentMessage = null;
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int currentPosition = 0;
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public LengthRecordNode next = null;
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Mark current message position and stact size.
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class PositionMarker {
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private int c_pos;   // Current position
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private int currentStackSize;  // Current stack size
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int getLength() {
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If these assert fails, likely that you are finding the
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // size of buffer that is deep in BufferStack you can only
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // find the length of the buffer that is on top
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (currentStackSize != mStack.stackSize) {
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException("BUG: Invalid call to getLength()");
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mPosition - c_pos;
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation can be OPTIMIZED to use only
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 2 buffers. This optimization involves changing BufferStack
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * only... Its usage (interface) will not change.
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class BufferStack {
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private LengthRecordNode stack = null;
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private LengthRecordNode toCopy = null;
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int stackSize = 0;
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  Create a new message buffer and push it into the stack.
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void newbuf() {
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // You can't create a new buff when toCopy != null
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // That is after calling pop() and before calling copy()
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If you do, it is a bug
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (toCopy != null) {
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException("BUG: Invalid newbuf() before copy()");
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LengthRecordNode temp = new LengthRecordNode();
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            temp.currentMessage = mMessage;
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            temp.currentPosition = mPosition;
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            temp.next = stack;
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stack = temp;
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stackSize = stackSize + 1;
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMessage = new ByteArrayOutputStream();
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPosition = 0;
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  Pop the message before and record current message in the stack.
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void pop() {
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ByteArrayOutputStream currentMessage = mMessage;
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int currentPosition = mPosition;
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMessage = stack.currentMessage;
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPosition = stack.currentPosition;
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            toCopy = stack;
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Re using the top element of the stack to avoid memory allocation
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stack = stack.next;
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stackSize = stackSize - 1;
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            toCopy.currentMessage = currentMessage;
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            toCopy.currentPosition = currentPosition;
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  Append current message to the message before.
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void copy() {
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            arraycopy(toCopy.currentMessage.toByteArray(), 0,
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    toCopy.currentPosition);
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            toCopy = null;
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  Mark current message position
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PositionMarker mark() {
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PositionMarker m = new PositionMarker();
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            m.c_pos = mPosition;
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            m.currentStackSize = stackSize;
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return m;
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Check address type.
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param address address string without the postfix stinng type,
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        such as "/TYPE=PLMN", "/TYPE=IPv6" and "/TYPE=IPv4"
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return PDU_PHONE_NUMBER_ADDRESS_TYPE if it is phone number,
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         PDU_EMAIL_ADDRESS_TYPE if it is email address,
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         PDU_IPV4_ADDRESS_TYPE if it is ipv4 address,
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         PDU_IPV6_ADDRESS_TYPE if it is ipv6 address,
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         PDU_UNKNOWN_ADDRESS_TYPE if it is unknown.
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected static int checkAddressType(String address) {
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf, section 8.
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * address = ( e-mail / device-address / alphanum-shortcode / num-shortcode)
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * e-mail = mailbox; to the definition of mailbox as described in
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * section 3.4 of [RFC2822], but excluding the
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * obsolete definitions as indicated by the "obs-" prefix.
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * device-address = ( global-phone-number "/TYPE=PLMN" )
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * / ( ipv4 "/TYPE=IPv4" ) / ( ipv6 "/TYPE=IPv6" )
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * / ( escaped-value "/TYPE=" address-type )
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * global-phone-number = ["+"] 1*( DIGIT / written-sep )
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * written-sep =("-"/".")
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ipv4 = 1*3DIGIT 3( "." 1*3DIGIT ) ; IPv4 address value
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * ipv6 = 4HEXDIG 7( ":" 4HEXDIG ) ; IPv6 address per RFC 2373
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (null == address) {
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_UNKNOWN_ADDRESS_TYPE;
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (address.matches(REGEXP_IPV4_ADDRESS_TYPE)) {
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Ipv4 address.
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_IPV4_ADDRESS_TYPE;
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }else if (address.matches(REGEXP_PHONE_NUMBER_ADDRESS_TYPE)) {
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Phone number.
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_PHONE_NUMBER_ADDRESS_TYPE;
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (address.matches(REGEXP_EMAIL_ADDRESS_TYPE)) {
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Email address.
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_EMAIL_ADDRESS_TYPE;
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (address.matches(REGEXP_IPV6_ADDRESS_TYPE)) {
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Ipv6 address.
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_IPV6_ADDRESS_TYPE;
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Unknown address.
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PDU_UNKNOWN_ADDRESS_TYPE;
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1180