10d4bcdf379842af4b6304809156971e926f374f0Jake Hamby/*
20d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Copyright (C) 2013 The Android Open Source Project
30d4bcdf379842af4b6304809156971e926f374f0Jake Hamby *
40d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Licensed under the Apache License, Version 2.0 (the "License");
50d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * you may not use this file except in compliance with the License.
60d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * You may obtain a copy of the License at
70d4bcdf379842af4b6304809156971e926f374f0Jake Hamby *
80d4bcdf379842af4b6304809156971e926f374f0Jake Hamby *      http://www.apache.org/licenses/LICENSE-2.0
90d4bcdf379842af4b6304809156971e926f374f0Jake Hamby *
100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Unless required by applicable law or agreed to in writing, software
110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * distributed under the License is distributed on an "AS IS" BASIS,
120d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * See the License for the specific language governing permissions and
140d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * limitations under the License.
150d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */
160d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
170d4bcdf379842af4b6304809156971e926f374f0Jake Hambypackage com.android.internal.telephony;
180d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
190d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.content.ContentValues;
200d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.database.Cursor;
210d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
220d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.util.HexDump;
230d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
240d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport java.util.Arrays;
250d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport java.util.Date;
260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
270d4bcdf379842af4b6304809156971e926f374f0Jake Hamby/**
280d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Tracker for an incoming SMS message ready to broadcast to listeners.
290d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * This is similar to {@link com.android.internal.telephony.SMSDispatcher.SmsTracker} used for
300d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * outgoing messages.
310d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */
320d4bcdf379842af4b6304809156971e926f374f0Jake Hambypublic final class InboundSmsTracker {
330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    // Fields for single and multi-part messages
350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private final byte[] mPdu;
360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private final long mTimestamp;
370d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private final int mDestPort;
380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private final boolean mIs3gpp2;
398b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby    private final boolean mIs3gpp2WapPdu;
400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    // Fields for concatenating multi-part SMS messages
420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private final String mAddress;
430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private final int mReferenceNumber;
440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private final int mSequenceNumber;
450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private final int mMessageCount;
460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    // Fields for deleting this message after delivery
480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private String mDeleteWhere;
490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private String[] mDeleteWhereArgs;
500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /** Destination port flag bit for no destination port. */
520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private static final int DEST_PORT_FLAG_NO_PORT = (1 << 16);
530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /** Destination port flag bit to indicate 3GPP format message. */
550d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private static final int DEST_PORT_FLAG_3GPP = (1 << 17);
560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /** Destination port flag bit to indicate 3GPP2 format message. */
580d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private static final int DEST_PORT_FLAG_3GPP2 = (1 << 18);
590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
608b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby    /** Destination port flag bit to indicate 3GPP2 format WAP message. */
618b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby    private static final int DEST_PORT_FLAG_3GPP2_WAP_PDU = (1 << 19);
628b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby
630d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /** Destination port mask (16-bit unsigned value on GSM and CDMA). */
640d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private static final int DEST_PORT_MASK = 0xffff;
650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /**
670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * Create a tracker for a single-part SMS.
680d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param pdu the message PDU
690d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param timestamp the message timestamp
700d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param destPort the destination port
710d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param is3gpp2 true for 3GPP2 format; false for 3GPP format
728b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby     * @param is3gpp2WapPdu true for 3GPP2 format WAP PDU; false otherwise
730d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     */
748b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby    InboundSmsTracker(byte[] pdu, long timestamp, int destPort, boolean is3gpp2,
758b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby            boolean is3gpp2WapPdu) {
760d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mPdu = pdu;
770d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mTimestamp = timestamp;
780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mDestPort = destPort;
790d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mIs3gpp2 = is3gpp2;
808b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby        mIs3gpp2WapPdu = is3gpp2WapPdu;
810d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        // fields for multi-part SMS
820d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mAddress = null;
830d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mReferenceNumber = -1;
840d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mSequenceNumber = getIndexOffset();     // 0 or 1, depending on type
850d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mMessageCount = 1;
860d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
870d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
880d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /**
890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * Create a tracker for a multi-part SMS. Sequence numbers start at 1 for 3GPP and regular
900d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * concatenated 3GPP2 messages, but CDMA WAP push sequence numbers start at 0. The caller
910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * will subtract 1 if necessary so that the sequence number is always 0-based. When loading
920d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * and saving to the raw table, the sequence number is adjusted if necessary for backwards
930d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * compatibility.
940d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     *
950d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param pdu the message PDU
960d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param timestamp the message timestamp
970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param destPort the destination port
980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param is3gpp2 true for 3GPP2 format; false for 3GPP format
990d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param address the originating address
1000d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param referenceNumber the concatenated reference number
1010d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param sequenceNumber the sequence number of this segment (0-based)
1020d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param messageCount the total number of segments
1038b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby     * @param is3gpp2WapPdu true for 3GPP2 format WAP PDU; false otherwise
1040d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     */
1050d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    public InboundSmsTracker(byte[] pdu, long timestamp, int destPort, boolean is3gpp2,
1068b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby            String address, int referenceNumber, int sequenceNumber, int messageCount,
1078b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby            boolean is3gpp2WapPdu) {
1080d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mPdu = pdu;
1090d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mTimestamp = timestamp;
1100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mDestPort = destPort;
1110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mIs3gpp2 = is3gpp2;
1128b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby        mIs3gpp2WapPdu = is3gpp2WapPdu;
1130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        // fields for multi-part SMS
1140d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mAddress = address;
1150d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mReferenceNumber = referenceNumber;
1160d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mSequenceNumber = sequenceNumber;
1170d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mMessageCount = messageCount;
1180d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
1190d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
1200d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /**
1210d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * Create a new tracker from the row of the raw table pointed to by Cursor.
1220d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * Since this constructor is used only for recovery during startup, the Dispatcher is null.
1230d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param cursor a Cursor pointing to the row to construct this SmsTracker for
1240d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     */
1250d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    InboundSmsTracker(Cursor cursor, boolean isCurrentFormat3gpp2) {
1260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mPdu = HexDump.hexStringToByteArray(cursor.getString(InboundSmsHandler.PDU_COLUMN));
1270d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
1280d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (cursor.isNull(InboundSmsHandler.DESTINATION_PORT_COLUMN)) {
1290d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mDestPort = -1;
1300d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mIs3gpp2 = isCurrentFormat3gpp2;
1318b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby            mIs3gpp2WapPdu = false;
1320d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        } else {
1330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            int destPort = cursor.getInt(InboundSmsHandler.DESTINATION_PORT_COLUMN);
1340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            if ((destPort & DEST_PORT_FLAG_3GPP) != 0) {
1350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby                mIs3gpp2 = false;
1360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            } else if ((destPort & DEST_PORT_FLAG_3GPP2) != 0) {
1370d4bcdf379842af4b6304809156971e926f374f0Jake Hamby                mIs3gpp2 = true;
1380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            } else {
1390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby                mIs3gpp2 = isCurrentFormat3gpp2;
1400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            }
1418b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby            mIs3gpp2WapPdu = ((destPort & DEST_PORT_FLAG_3GPP2_WAP_PDU) != 0);
1420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mDestPort = getRealDestPort(destPort);
1430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
1440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
1450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mTimestamp = cursor.getLong(InboundSmsHandler.DATE_COLUMN);
1460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
1470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (cursor.isNull(InboundSmsHandler.COUNT_COLUMN)) {
1480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            // single-part message
1490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            long rowId = cursor.getLong(InboundSmsHandler.ID_COLUMN);
1500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mAddress = null;
1510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mReferenceNumber = -1;
1520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mSequenceNumber = getIndexOffset();     // 0 or 1, depending on type
1530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mMessageCount = 1;
1540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mDeleteWhere = InboundSmsHandler.SELECT_BY_ID;
1550d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mDeleteWhereArgs = new String[]{Long.toString(rowId)};
1560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        } else {
1570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            // multi-part message
1580d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mAddress = cursor.getString(InboundSmsHandler.ADDRESS_COLUMN);
1590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mReferenceNumber = cursor.getInt(InboundSmsHandler.REFERENCE_NUMBER_COLUMN);
1600d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mMessageCount = cursor.getInt(InboundSmsHandler.COUNT_COLUMN);
1610d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
1620d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
1630d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mSequenceNumber = cursor.getInt(InboundSmsHandler.SEQUENCE_COLUMN);
1640d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            int index = mSequenceNumber - getIndexOffset();
1650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
1660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            if (index < 0 || index >= mMessageCount) {
1670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby                throw new IllegalArgumentException("invalid PDU sequence " + mSequenceNumber
1680d4bcdf379842af4b6304809156971e926f374f0Jake Hamby                        + " of " + mMessageCount);
1690d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            }
1700d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
1710d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mDeleteWhere = InboundSmsHandler.SELECT_BY_REFERENCE;
1720d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            mDeleteWhereArgs = new String[]{mAddress,
1730d4bcdf379842af4b6304809156971e926f374f0Jake Hamby                    Integer.toString(mReferenceNumber), Integer.toString(mMessageCount)};
1740d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
1750d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
1760d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
1770d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    ContentValues getContentValues() {
1780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        ContentValues values = new ContentValues();
1790d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        values.put("pdu", HexDump.toHexString(mPdu));
1800d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        values.put("date", mTimestamp);
1810d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        // Always set the destination port, since it now contains message format flags.
1820d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        // Port is a 16-bit value, or -1, so clear the upper bits before setting flags.
1830d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        int destPort;
1840d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (mDestPort == -1) {
1850d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            destPort = DEST_PORT_FLAG_NO_PORT;
1860d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        } else {
1870d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            destPort = mDestPort & DEST_PORT_MASK;
1880d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
1890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (mIs3gpp2) {
1900d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            destPort |= DEST_PORT_FLAG_3GPP2;
1910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        } else {
1920d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            destPort |= DEST_PORT_FLAG_3GPP;
1930d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
1948b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby        if (mIs3gpp2WapPdu) {
1958b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby            destPort |= DEST_PORT_FLAG_3GPP2_WAP_PDU;
1968b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby        }
1970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        values.put("destination_port", destPort);
1980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (mAddress != null) {
1990d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            values.put("address", mAddress);
2000d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            values.put("reference_number", mReferenceNumber);
2010d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            values.put("sequence", mSequenceNumber);
2020d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            values.put("count", mMessageCount);
2030d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
2040d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return values;
2050d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2060d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2070d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /**
2080d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * Get the port number, or -1 if there is no destination port.
2090d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param destPort the destination port value, with flags
2100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @return the real destination port, or -1 for no port
2110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     */
2120d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    static int getRealDestPort(int destPort) {
2130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if ((destPort & DEST_PORT_FLAG_NO_PORT) != 0) {
2140d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            return -1;
2150d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        } else {
2160d4bcdf379842af4b6304809156971e926f374f0Jake Hamby           return destPort & DEST_PORT_MASK;
2170d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
2180d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2190d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2200d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /**
2210d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * Update the values to delete all rows of the message from raw table.
2220d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param deleteWhere the selection to use
2230d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param deleteWhereArgs the selection args to use
2240d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     */
2250d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    void setDeleteWhere(String deleteWhere, String[] deleteWhereArgs) {
2260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mDeleteWhere = deleteWhere;
2270d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mDeleteWhereArgs = deleteWhereArgs;
2280d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2290d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2300d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    public String toString() {
2310d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        StringBuilder builder = new StringBuilder("SmsTracker{timestamp=");
2320d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        builder.append(new Date(mTimestamp));
2330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        builder.append(" destPort=").append(mDestPort);
2340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        builder.append(" is3gpp2=").append(mIs3gpp2);
2350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (mAddress != null) {
2360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            builder.append(" address=").append(mAddress);
2370d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            builder.append(" refNumber=").append(mReferenceNumber);
2380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            builder.append(" seqNumber=").append(mSequenceNumber);
2390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            builder.append(" msgCount=").append(mMessageCount);
2400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
2410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (mDeleteWhere != null) {
2420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            builder.append(" deleteWhere(").append(mDeleteWhere);
2430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            builder.append(") deleteArgs=(").append(Arrays.toString(mDeleteWhereArgs));
2440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            builder.append(')');
2450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
2460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        builder.append('}');
2470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return builder.toString();
2480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    byte[] getPdu() {
2510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mPdu;
2520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    long getTimestamp() {
2550d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mTimestamp;
2560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2580d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    int getDestPort() {
2590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mDestPort;
2600d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2610d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2620d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    boolean is3gpp2() {
2630d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mIs3gpp2;
2640d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    String getFormat() {
2670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mIs3gpp2 ? SmsConstants.FORMAT_3GPP2 : SmsConstants.FORMAT_3GPP;
2680d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2690d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2700d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /**
2718b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby     * Sequence numbers for concatenated messages start at 1. The exception is CDMA WAP PDU
2720d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * messages, which use a 0-based index.
2730d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @return the offset to use to convert between mIndex and the sequence number
2740d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     */
2750d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    int getIndexOffset() {
2768b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby        return (mIs3gpp2 && mIs3gpp2WapPdu) ? 0 : 1;
2770d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2790d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    String getAddress() {
2800d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mAddress;
2810d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2820d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2830d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    int getReferenceNumber() {
2840d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mReferenceNumber;
2850d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2860d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2870d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    int getSequenceNumber() {
2880d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mSequenceNumber;
2890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2900d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    int getMessageCount() {
2920d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mMessageCount;
2930d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2940d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2950d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    String getDeleteWhere() {
2960d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mDeleteWhere;
2970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
2980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
2990d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    String[] getDeleteWhereArgs() {
3000d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        return mDeleteWhereArgs;
3010d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
3020d4bcdf379842af4b6304809156971e926f374f0Jake Hamby}
303