104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville/*
204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * Copyright (C) 2008 The Android Open Source Project
304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville *
404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * you may not use this file except in compliance with the License.
604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * You may obtain a copy of the License at
704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville *
804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville *
1004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * Unless required by applicable law or agreed to in writing, software
1104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
1204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * See the License for the specific language governing permissions and
1404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * limitations under the License.
1504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville */
1604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
1704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savillepackage com.android.internal.telephony;
1804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
1904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport android.app.PendingIntent;
2004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport android.content.Context;
2104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport android.util.Log;
2204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
231f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalinkimport com.android.internal.util.HexDump;
241f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink
2504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport java.util.ArrayList;
2604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport java.util.List;
2704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
2804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
2904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
3004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville/**
3104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * IccSmsInterfaceManager to provide an inter-process communication to
3204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * access Sms in Icc.
3304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville */
3404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savillepublic abstract class IccSmsInterfaceManager extends ISms.Stub {
3504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    protected PhoneBase mPhone;
3604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    protected Context mContext;
3704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    protected SMSDispatcher mDispatcher;
3804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
3904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    protected IccSmsInterfaceManager(PhoneBase phone){
4004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        mPhone = phone;
4104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        mContext = phone.getContext();
4204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    }
4304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
4404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    protected void enforceReceiveAndSend(String message) {
4504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        mContext.enforceCallingPermission(
4604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                "android.permission.RECEIVE_SMS", message);
4704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        mContext.enforceCallingPermission(
4804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                "android.permission.SEND_SMS", message);
4904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    }
5004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
5104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /**
521f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * Send a data based SMS to a specific application port.
5304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *
541f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param destAddr the address to send the message to
551f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param scAddr is the service center address or null to use
561f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  the current default SMSC
571f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param destPort the port to deliver the message to
581f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param data the body of the message to send
591f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param sentIntent if not NULL this <code>PendingIntent</code> is
60bb3716332321e22537a5015be13e2229fb9b90bcJake Hamby     *  broadcast when the message is successfully sent, or failed.
6104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *  The result code will be <code>Activity.RESULT_OK<code> for success,
621f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  or one of these errors:<br>
631f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
641f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
651f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  <code>RESULT_ERROR_NULL_PDU</code><br>
661f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
671f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  the extra "errorCode" containing a radio technology specific value,
681f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  generally only useful for troubleshooting.<br>
691f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  The per-application based SMS control checks sentIntent. If sentIntent
70bb3716332321e22537a5015be13e2229fb9b90bcJake Hamby     *  is NULL the caller will be checked against all unknown applications,
711f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  which cause smaller number of SMS to be sent in checking period.
721f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
7304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *  broadcast when the message is delivered to the recipient.  The
7404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *  raw pdu of the status report is in the extended data ("pdu").
7504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     */
761f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink    public void sendData(String destAddr, String scAddr, int destPort,
771f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
781f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink        mPhone.getContext().enforceCallingPermission(
791f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink                "android.permission.SEND_SMS",
801f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink                "Sending SMS message");
818be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang        if (Log.isLoggable("SMS", Log.VERBOSE)) {
828be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang            log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
831f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink                destPort + " data='"+ HexDump.toHexString(data)  + "' sentIntent=" +
841f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink                sentIntent + " deliveryIntent=" + deliveryIntent);
858be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang        }
861f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink        mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
871f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink    }
8804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
891f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink    /**
901f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * Send a text based SMS.
911f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *
921f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param destAddr the address to send the message to
931f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param scAddr is the service center address or null to use
941f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  the current default SMSC
951f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param text the body of the message to send
961f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param sentIntent if not NULL this <code>PendingIntent</code> is
97bb3716332321e22537a5015be13e2229fb9b90bcJake Hamby     *  broadcast when the message is successfully sent, or failed.
981f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  The result code will be <code>Activity.RESULT_OK<code> for success,
991f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  or one of these errors:<br>
1001f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
1011f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
1021f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  <code>RESULT_ERROR_NULL_PDU</code><br>
1031f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
1041f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  the extra "errorCode" containing a radio technology specific value,
1051f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  generally only useful for troubleshooting.<br>
1061f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  The per-application based SMS control checks sentIntent. If sentIntent
1071f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  is NULL the caller will be checked against all unknown applications,
1081f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  which cause smaller number of SMS to be sent in checking period.
1091f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
1101f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  broadcast when the message is delivered to the recipient.  The
1111f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  raw pdu of the status report is in the extended data ("pdu").
1121f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     */
1131f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink    public void sendText(String destAddr, String scAddr,
1141f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink            String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
1151f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink        mPhone.getContext().enforceCallingPermission(
11604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                "android.permission.SEND_SMS",
11704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                "Sending SMS message");
1188be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang        if (Log.isLoggable("SMS", Log.VERBOSE)) {
1198be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang            log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +
1201f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink                " text='"+ text + "' sentIntent=" +
1211f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink                sentIntent + " deliveryIntent=" + deliveryIntent);
1228be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang        }
1231f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink        mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
12404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    }
12504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
12604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /**
12704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * Send a multi-part text based SMS.
12804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *
1291f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param destAddr the address to send the message to
1301f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     * @param scAddr is the service center address or null to use
13104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   the current default SMSC
13204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @param parts an <code>ArrayList</code> of strings that, in order,
13304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   comprise the original message
13404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @param sentIntents if not null, an <code>ArrayList</code> of
13504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   <code>PendingIntent</code>s (one for each message part) that is
13604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   broadcast when the corresponding message part has been sent.
13704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   The result code will be <code>Activity.RESULT_OK<code> for success,
13804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   or one of these errors:
13904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
14004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   <code>RESULT_ERROR_RADIO_OFF</code>
14104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   <code>RESULT_ERROR_NULL_PDU</code>.
1421f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  The per-application based SMS control checks sentIntent. If sentIntent
143bb3716332321e22537a5015be13e2229fb9b90bcJake Hamby     *  is NULL the caller will be checked against all unknown applications,
1441f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink     *  which cause smaller number of SMS to be sent in checking period.
14504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @param deliveryIntents if not null, an <code>ArrayList</code> of
14604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   <code>PendingIntent</code>s (one for each message part) that is
14704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   broadcast when the corresponding message part has been delivered
14804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   to the recipient.  The raw pdu of the status report is in the
14904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *   extended data ("pdu").
15004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     */
1511f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink    public void sendMultipartText(String destAddr, String scAddr, List<String> parts,
15204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville            List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
1531f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink        mPhone.getContext().enforceCallingPermission(
15404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                "android.permission.SEND_SMS",
15504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                "Sending SMS message");
1568be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang        if (Log.isLoggable("SMS", Log.VERBOSE)) {
1578be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang            int i = 0;
1588be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang            for (String part : parts) {
1598be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang                log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr +
1608be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang                        ", part[" + (i++) + "]=" + part);
1618be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang            }
1628be9ccdc5c76b015ee8c7aa9922c80fdc4dc59eaWei Huang        }
1631f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink        mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,
16404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
16504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    }
16604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
16704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /**
16804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * create SmsRawData lists from all sms record byte[]
16904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * Use null to indicate "free" record
17004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *
17104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @param messages List of message records from EF_SMS.
17204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @return SmsRawData list of all in-used records
17304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     */
17404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) {
17504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        int count = messages.size();
17604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        ArrayList<SmsRawData> ret;
17704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
17804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        ret = new ArrayList<SmsRawData>(count);
17904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
18004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        for (int i = 0; i < count; i++) {
18104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville            byte[] ba = messages.get(i);
18204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville            if (ba[0] == STATUS_ON_ICC_FREE) {
18304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                ret.add(null);
18404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville            } else {
18504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville                ret.add(new SmsRawData(messages.get(i)));
18604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville            }
18704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        }
18804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
18904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        return ret;
19004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    }
19104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
19204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    /**
19304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * Generates an EF_SMS record from status and raw PDU.
19404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     *
19504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @param status Message status.  See TS 51.011 10.5.3.
19604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @param pdu Raw message PDU.
19704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     * @return byte array for the record.
19804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville     */
19904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    protected byte[] makeSmsRecordData(int status, byte[] pdu) {
20004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH];
20104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
20204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        // Status bits for this record.  See TS 51.011 10.5.3
20304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        data[0] = (byte)(status & 7);
20404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
20504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        System.arraycopy(pdu, 0, data, 1, pdu.length);
20604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
20704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        // Pad out with 0xFF's.
20804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) {
20904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville            data[j] = -1;
21004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        }
21104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
21204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville        return data;
21304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    }
21404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
21504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville    protected abstract void log(String msg);
21604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville
21704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville}
218