GsmSMSDispatcher.java revision 0217e2d6e60f7edd95407c7b385a627da9f1c1e3
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
31260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony.gsm;
19c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.Activity;
21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent.CanceledException;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Telephony.Sms;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Telephony.Sms.Intents;
28ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.GsmAlphabet;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.PhoneBase;
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SMSDispatcher;
330d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.SmsConstants;
341260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.ImsSMSDispatcher;
351260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.InboundSmsHandler;
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SmsHeader;
371260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.SmsStorageMonitor;
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SmsUsageMonitor;
391260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.TelephonyProperties;
401260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.uicc.IccRecords;
41d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils;
421260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.uicc.UiccCardApplication;
431260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.uicc.UiccController;
441260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.uicc.UsimServiceTable;
451260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.gsm.GsmInboundSmsHandler;
46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashMap;
481260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport java.util.Iterator;
491260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport java.util.concurrent.atomic.AtomicReference;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic final class GsmSMSDispatcher extends SMSDispatcher {
52cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final String TAG = "GsmSMSDispatcher";
531260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    private static final boolean VDBG = false;
541260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    private ImsSMSDispatcher mImsSMSDispatcher;
551260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    protected UiccController mUiccController = null;
561260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    private AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
571260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    private AtomicReference<UiccCardApplication> mUiccApplication =
581260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            new AtomicReference<UiccCardApplication>();
591260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    private GsmInboundSmsHandler mGsmInboundSmsHandler;
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Status report received */
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_NEW_SMS_STATUS_REPORT = 100;
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
641260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    public GsmSMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor,
651260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            SmsUsageMonitor usageMonitor, ImsSMSDispatcher imsSMSDispatcher,
661260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            GsmInboundSmsHandler gsmInboundSmsHandler) {
670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        super(phone, usageMonitor);
6822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
691260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        mImsSMSDispatcher = imsSMSDispatcher;
701260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        mGsmInboundSmsHandler = gsmInboundSmsHandler;
711260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        Rlog.d(TAG, "GsmSMSDispatcher created");
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dispose() {
760d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        super.dispose();
7722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnSmsStatus(this);
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected String getFormat() {
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return SmsConstants.FORMAT_3GPP;
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Handles 3GPP format-specific events coming from the phone stack.
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Other events are handled by {@link SMSDispatcher#handleMessage}.
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param msg the message to handle
90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void handleMessage(Message msg) {
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (msg.what) {
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case EVENT_NEW_SMS_STATUS_REPORT:
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            handleStatusReport((AsyncResult) msg.obj);
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
981260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        case EVENT_NEW_ICC_SMS:
991260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        // pass to InboundSmsHandler to process
1001260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, msg.obj);
1011260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        break;
1021260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
1031260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        case EVENT_ICC_CHANGED:
1041260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            onUpdateIccAvailability();
1051260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            break;
1061260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        default:
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            super.handleMessage(msg);
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Called when a status report is received.  This should correspond to
114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * a previously successful SEND.
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param ar AsyncResult passed into the message handler.  ar.result should
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *           be a String representing the status report PDU, as ASCII hex.
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleStatusReport(AsyncResult ar) {
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String pduString = (String) ar.result;
121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SmsMessage sms = SmsMessage.newFromCDS(pduString);
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (sms != null) {
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int tpStatus = sms.getStatus();
12522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            int messageRef = sms.mMessageRef;
126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                SmsTracker tracker = deliveryPendingList.get(i);
128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (tracker.mMessageRef == messageRef) {
129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Found it.  Remove from list and broadcast.
130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) {
131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                       deliveryPendingList.remove(i);
1320217e2d6e60f7edd95407c7b385a627da9f1c1e3David Braun                       // Update the message status (COMPLETE or FAILED)
1330217e2d6e60f7edd95407c7b385a627da9f1c1e3David Braun                       tracker.updateSentMessageStatus(mContext, tpStatus);
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    PendingIntent intent = tracker.mDeliveryIntent;
136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    Intent fillIn = new Intent();
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
1381260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    fillIn.putExtra("format", getFormat());
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    try {
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        intent.send(mContext, Activity.RESULT_OK, fillIn);
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } catch (CanceledException ex) {}
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Only expect to see one tracker matching this messageref
144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mCi.acknowledgeLastIncomingGsmSms(true, Intents.RESULT_SMS_HANDLED, null);
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** {@inheritDoc} */
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void sendData(String destAddr, String scAddr, int destPort,
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                scAddr, destAddr, destPort, data, (deliveryIntent != null));
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (pdu != null) {
1581260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            HashMap map =  SmsTrackerMapFactory(destAddr, scAddr, destPort, data, pdu);
1591260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            SmsTracker tracker = SmsTrackerFactory(map, sentIntent, deliveryIntent,
1601260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    getFormat());
1611260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            sendRawPdu(tracker);
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
163ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(TAG, "GsmSMSDispatcher.sendData(): getSubmitPdu() returned null");
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** {@inheritDoc} */
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void sendText(String destAddr, String scAddr, String text,
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            PendingIntent sentIntent, PendingIntent deliveryIntent) {
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                scAddr, destAddr, text, (deliveryIntent != null));
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (pdu != null) {
1741260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            HashMap map =  SmsTrackerMapFactory(destAddr, scAddr, text, pdu);
1751260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            SmsTracker tracker = SmsTrackerFactory(map, sentIntent, deliveryIntent,
1761260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    getFormat());
1771260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            sendRawPdu(tracker);
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
179ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null");
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** {@inheritDoc} */
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected GsmAlphabet.TextEncodingDetails calculateLength(CharSequence messageBody,
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            boolean use7bitOnly) {
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return SmsMessage.calculateLength(messageBody, use7bitOnly);
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** {@inheritDoc} */
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void sendNewSubmitPdu(String destinationAddress, String scAddress,
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String message, SmsHeader smsHeader, int encoding,
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) {
195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader),
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                encoding, smsHeader.languageTable, smsHeader.languageShiftTable);
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (pdu != null) {
1991260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            HashMap map =  SmsTrackerMapFactory(destinationAddress, scAddress,
2001260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    message, pdu);
2011260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            SmsTracker tracker = SmsTrackerFactory(map, sentIntent,
2021260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    deliveryIntent, getFormat());
2031260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            sendRawPdu(tracker);
204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
205ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(TAG, "GsmSMSDispatcher.sendNewSubmitPdu(): getSubmitPdu() returned null");
206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** {@inheritDoc} */
210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void sendSms(SmsTracker tracker) {
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        HashMap<String, Object> map = tracker.mData;
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte smsc[] = (byte[]) map.get("smsc");
215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte pdu[] = (byte[]) map.get("pdu");
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
218454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks
219454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks        if (tracker.mRetryCount > 0) {
220454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks            Rlog.d(TAG, "sendSms: "
221454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks                    + " mRetryCount=" + tracker.mRetryCount
222454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks                    + " mMessageRef=" + tracker.mMessageRef
223454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks                    + " SS=" + mPhone.getServiceState().getState());
224454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks
225454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks            // per TS 23.040 Section 9.2.3.6:  If TP-MTI SMS-SUBMIT (0x01) type
226454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks            //   TP-RD (bit 2) is 1 for retry
227454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks            //   and TP-MR is set to previously failed sms TP-MR
228454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks            if (((0x01 & pdu[0]) == 0x01)) {
229454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks                pdu[0] |= 0x04; // TP-RD
230454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks                pdu[1] = (byte) tracker.mMessageRef; // TP-MR
231454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks            }
232454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks        }
2331260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        Rlog.d(TAG, "sendSms: "
2341260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                +" isIms()="+isIms()
2351260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                +" mRetryCount="+tracker.mRetryCount
2361260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                +" mImsRetry="+tracker.mImsRetry
2371260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                +" mMessageRef="+tracker.mMessageRef
2381260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                +" SS=" +mPhone.getServiceState().getState());
2391260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
2401260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        // sms over gsm is used:
2411260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        //   if sms over IMS is not supported AND
2421260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        //   this is not a retry case after sms over IMS failed
2431260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        //     indicated by mImsRetry > 0
2441260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        if (0 == tracker.mImsRetry && !isIms()) {
2451260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            if (tracker.mRetryCount > 0) {
2461260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                // per TS 23.040 Section 9.2.3.6:  If TP-MTI SMS-SUBMIT (0x01) type
2471260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                //   TP-RD (bit 2) is 1 for retry
2481260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                //   and TP-MR is set to previously failed sms TP-MR
2491260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                if (((0x01 & pdu[0]) == 0x01)) {
2501260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    pdu[0] |= 0x04; // TP-RD
2511260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    pdu[1] = (byte) tracker.mMessageRef; // TP-MR
2521260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                }
2531260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            }
2541260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            mCi.sendSMS(IccUtils.bytesToHexString(smsc),
2551260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    IccUtils.bytesToHexString(pdu), reply);
2561260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        } else {
2571260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            mCi.sendImsGsmSms(IccUtils.bytesToHexString(smsc),
2581260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    IccUtils.bytesToHexString(pdu), tracker.mImsRetry,
2591260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    tracker.mMessageRef, reply);
2601260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            // increment it here, so in case of SMS_FAIL_RETRY over IMS
2611260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            // next retry will be sent using IMS request again.
2621260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            tracker.mImsRetry++;
2631260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        }
2641260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    }
2651260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
2661260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    @Override
2671260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    public void sendRetrySms(SmsTracker tracker) {
2681260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        //re-routing to ImsSMSDispatcher
2691260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        mImsSMSDispatcher.sendRetrySms(tracker);
2701260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    }
2711260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
2721260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    protected UiccCardApplication getUiccCardApplication() {
2731260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        return mUiccController.getUiccCardApplication(UiccController.APP_FAM_3GPP);
2741260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    }
2751260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
2761260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    private void onUpdateIccAvailability() {
2771260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        if (mUiccController == null ) {
2781260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            return;
2791260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        }
2801260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
2811260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        UiccCardApplication newUiccApplication = getUiccCardApplication();
2821260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
2831260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        UiccCardApplication app = mUiccApplication.get();
2841260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        if (app != newUiccApplication) {
2851260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            if (app != null) {
2861260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                Rlog.d(TAG, "Removing stale icc objects.");
2871260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                if (mIccRecords.get() != null) {
2881260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    mIccRecords.get().unregisterForNewSms(this);
2891260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                }
2901260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                mIccRecords.set(null);
2911260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                mUiccApplication.set(null);
2921260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            }
2931260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            if (newUiccApplication != null) {
2941260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                Rlog.d(TAG, "New Uicc application found");
2951260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                mUiccApplication.set(newUiccApplication);
2961260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                mIccRecords.set(newUiccApplication.getIccRecords());
2971260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                if (mIccRecords.get() != null) {
2981260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                    mIccRecords.get().registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
2991260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                }
3001260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            }
3011260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        }
3021260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    }
3031260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
3041260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    @Override
3051260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    public boolean isIms() {
3061260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        return mImsSMSDispatcher.isIms();
3071260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    }
3081260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
3091260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    @Override
3101260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    public String getImsSmsFormat() {
3111260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        return mImsSMSDispatcher.getImsSmsFormat();
312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
314