CdmaSMSDispatcher.java revision 0d4bcdf379842af4b6304809156971e926f374f0
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony.cdma;
18
19import android.app.Activity;
20import android.app.PendingIntent;
21import android.app.PendingIntent.CanceledException;
22import android.content.Intent;
23import android.os.Message;
24import android.os.SystemProperties;
25import android.telephony.Rlog;
26import android.telephony.SmsManager;
27
28import com.android.internal.telephony.GsmAlphabet;
29import com.android.internal.telephony.SMSDispatcher;
30import com.android.internal.telephony.SmsConstants;
31import com.android.internal.telephony.SmsHeader;
32import com.android.internal.telephony.SmsUsageMonitor;
33import com.android.internal.telephony.TelephonyProperties;
34import com.android.internal.telephony.cdma.sms.UserData;
35
36import java.util.HashMap;
37
38final class CdmaSMSDispatcher extends SMSDispatcher {
39    private static final String TAG = "CdmaSMSDispatcher";
40    private static final boolean VDBG = false;
41
42    CdmaSMSDispatcher(CDMAPhone phone, SmsUsageMonitor usageMonitor) {
43        super(phone, usageMonitor);
44    }
45
46    @Override
47    protected String getFormat() {
48        return android.telephony.SmsMessage.FORMAT_3GPP2;
49    }
50
51    /**
52     * Send the SMS status report to the dispatcher thread to process.
53     * @param sms the CDMA SMS message containing the status report
54     */
55    void sendStatusReportMessage(SmsMessage sms) {
56        if (VDBG) Rlog.d(TAG, "sending EVENT_HANDLE_STATUS_REPORT message");
57        sendMessage(obtainMessage(EVENT_HANDLE_STATUS_REPORT, sms));
58    }
59
60    @Override
61    protected void handleStatusReport(Object o) {
62        if (o instanceof SmsMessage) {
63            if (VDBG) Rlog.d(TAG, "calling handleCdmaStatusReport()");
64            handleCdmaStatusReport((SmsMessage) o);
65        } else {
66            Rlog.e(TAG, "handleStatusReport() called for object type " + o.getClass().getName());
67        }
68    }
69
70    /**
71     * Called from parent class to handle status report from {@code CdmaInboundSmsHandler}.
72     * @param sms the CDMA SMS message to process
73     */
74    void handleCdmaStatusReport(SmsMessage sms) {
75        for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
76            SmsTracker tracker = deliveryPendingList.get(i);
77            if (tracker.mMessageRef == sms.mMessageRef) {
78                // Found it.  Remove from list and broadcast.
79                deliveryPendingList.remove(i);
80                PendingIntent intent = tracker.mDeliveryIntent;
81                Intent fillIn = new Intent();
82                fillIn.putExtra("pdu", sms.getPdu());
83                fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2);
84                try {
85                    intent.send(mContext, Activity.RESULT_OK, fillIn);
86                } catch (CanceledException ex) {}
87                break;  // Only expect to see one tracker matching this message.
88            }
89        }
90    }
91
92    /** {@inheritDoc} */
93    @Override
94    protected void sendData(String destAddr, String scAddr, int destPort,
95            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
96        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
97                scAddr, destAddr, destPort, data, (deliveryIntent != null));
98        sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr);
99    }
100
101    /** {@inheritDoc} */
102    @Override
103    protected void sendText(String destAddr, String scAddr, String text,
104            PendingIntent sentIntent, PendingIntent deliveryIntent) {
105        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
106                scAddr, destAddr, text, (deliveryIntent != null), null);
107        sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr);
108    }
109
110    /** {@inheritDoc} */
111    @Override
112    protected GsmAlphabet.TextEncodingDetails calculateLength(CharSequence messageBody,
113            boolean use7bitOnly) {
114        return SmsMessage.calculateLength(messageBody, use7bitOnly);
115    }
116
117    /** {@inheritDoc} */
118    @Override
119    protected void sendNewSubmitPdu(String destinationAddress, String scAddress,
120            String message, SmsHeader smsHeader, int encoding,
121            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) {
122        UserData uData = new UserData();
123        uData.payloadStr = message;
124        uData.userDataHeader = smsHeader;
125        if (encoding == SmsConstants.ENCODING_7BIT) {
126            uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
127        } else { // assume UTF-16
128            uData.msgEncoding = UserData.ENCODING_UNICODE_16;
129        }
130        uData.msgEncodingSet = true;
131
132        /* By setting the statusReportRequested bit only for the
133         * last message fragment, this will result in only one
134         * callback to the sender when that last fragment delivery
135         * has been acknowledged. */
136        SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destinationAddress,
137                uData, (deliveryIntent != null) && lastPart);
138
139        sendSubmitPdu(submitPdu, sentIntent, deliveryIntent, destinationAddress);
140    }
141
142    void sendSubmitPdu(SmsMessage.SubmitPdu pdu,
143            PendingIntent sentIntent, PendingIntent deliveryIntent, String destAddr) {
144        if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) {
145            if (sentIntent != null) {
146                try {
147                    sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE);
148                } catch (CanceledException ex) {}
149            }
150            if (VDBG) {
151                Rlog.d(TAG, "Block SMS in Emergency Callback mode");
152            }
153            return;
154        }
155        sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, destAddr);
156    }
157
158    /** {@inheritDoc} */
159    @Override
160    protected void sendSms(SmsTracker tracker) {
161        HashMap<String, Object> map = tracker.mData;
162
163        // byte[] smsc = (byte[]) map.get("smsc");  // unused for CDMA
164        byte[] pdu = (byte[]) map.get("pdu");
165
166        Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
167        mCi.sendCdmaSms(pdu, reply);
168    }
169}
170