10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2008 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cdma;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
2099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
21a0c22039b77054d659151537896c1db90c7057f7Shishir Agrawalimport android.telephony.ServiceState;
224bd1dec4138ac11a91a8ec606a27fc4c5c63f14bYe Wenimport android.telephony.TelephonyManager;
23d68e767bd3169ae17c7fbc0a6cdf83cc6cdff48dMohamed Abdalkaderimport android.util.Pair;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.telephony.GsmCdmaPhone;
261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.telephony.Phone;
274bd1dec4138ac11a91a8ec606a27fc4c5c63f14bYe Wenimport com.android.internal.telephony.PhoneConstants;
28ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowaimport com.android.internal.telephony.SmsConstants;
292b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkaderimport com.android.internal.telephony.SMSDispatcher;
302b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkaderimport com.android.internal.telephony.SmsDispatchersController;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsHeader;
322b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkaderimport com.android.internal.telephony.util.SMSDispatcherUtil;
332b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkaderimport com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
342b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkaderimport com.android.internal.telephony.SmsMessageBase;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
371260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowapublic class CdmaSMSDispatcher extends SMSDispatcher {
38cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final String TAG = "CdmaSMSDispatcher";
39cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final boolean VDBG = false;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
412b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    public CdmaSMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) {
422b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader        super(phone, smsDispatchersController);
431260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        Rlog.d(TAG, "CdmaSMSDispatcher created");
440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby
46ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa    @Override
475d5ca33a24e6b73a48b575a0e1a5e790784d0bb7Amit Mahajan    public String getFormat() {
48ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa        return SmsConstants.FORMAT_3GPP2;
49ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa    }
50ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa
510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /**
520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * Send the SMS status report to the dispatcher thread to process.
530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param sms the CDMA SMS message containing the status report
540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     */
555d5ca33a24e6b73a48b575a0e1a5e790784d0bb7Amit Mahajan    public void sendStatusReportMessage(SmsMessage sms) {
560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (VDBG) Rlog.d(TAG, "sending EVENT_HANDLE_STATUS_REPORT message");
570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        sendMessage(obtainMessage(EVENT_HANDLE_STATUS_REPORT, sms));
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
610d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    protected void handleStatusReport(Object o) {
620d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (o instanceof SmsMessage) {
630d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            if (VDBG) Rlog.d(TAG, "calling handleCdmaStatusReport()");
640d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            handleCdmaStatusReport((SmsMessage) o);
650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        } else {
660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby            Rlog.e(TAG, "handleStatusReport() called for object type " + o.getClass().getName());
670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        }
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
702b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    @Override
71127f5f22485982575eba72d4a047c49e447ca60bBrad Ebinger    protected boolean shouldBlockSmsForEcbm() {
72127f5f22485982575eba72d4a047c49e447ca60bBrad Ebinger        // We only block outgoing SMS during ECBM when using CDMA.
73127f5f22485982575eba72d4a047c49e447ca60bBrad Ebinger        return mPhone.isInEcm() && isCdmaMo() && !isIms();
742b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    }
752b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader
762b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    @Override
772b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr,
78d5222086533bd645fddc5ca4bf2a2bcc84f1a2afMengjun Leng            String message, boolean statusReportRequested, SmsHeader smsHeader, int priority,
79d5222086533bd645fddc5ca4bf2a2bcc84f1a2afMengjun Leng            int validityPeriod) {
802b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader        return SMSDispatcherUtil.getSubmitPduCdma(scAddr, destAddr, message,
81d5222086533bd645fddc5ca4bf2a2bcc84f1a2afMengjun Leng                statusReportRequested, smsHeader, priority);
822b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    }
832b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader
842b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    @Override
852b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr,
862b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader            int destPort, byte[] message, boolean statusReportRequested) {
872b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader        return SMSDispatcherUtil.getSubmitPduCdma(scAddr, destAddr, destPort, message,
882b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader                statusReportRequested);
892b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    }
902b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader
912b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    @Override
922b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    protected TextEncodingDetails calculateLength(CharSequence messageBody, boolean use7bitOnly) {
932b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader        return SMSDispatcherUtil.calculateLengthCdma(messageBody, use7bitOnly);
942b533ed532c9308ef851fc1d2a0a12d91573c068Mohamed Abdalkader    }
950d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /**
960d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * Called from parent class to handle status report from {@code CdmaInboundSmsHandler}.
970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     * @param sms the CDMA SMS message to process
980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby     */
995d5ca33a24e6b73a48b575a0e1a5e790784d0bb7Amit Mahajan    private void handleCdmaStatusReport(SmsMessage sms) {
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            SmsTracker tracker = deliveryPendingList.get(i);
10222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (tracker.mMessageRef == sms.mMessageRef) {
103d68e767bd3169ae17c7fbc0a6cdf83cc6cdff48dMohamed Abdalkader                Pair<Boolean, Boolean> result =
104d68e767bd3169ae17c7fbc0a6cdf83cc6cdff48dMohamed Abdalkader                        mSmsDispatchersController.handleSmsStatusReport(tracker, getFormat(),
105d68e767bd3169ae17c7fbc0a6cdf83cc6cdff48dMohamed Abdalkader                                sms.getPdu());
106d68e767bd3169ae17c7fbc0a6cdf83cc6cdff48dMohamed Abdalkader                if (result.second) {
107d68e767bd3169ae17c7fbc0a6cdf83cc6cdff48dMohamed Abdalkader                    deliveryPendingList.remove(i);
108d68e767bd3169ae17c7fbc0a6cdf83cc6cdff48dMohamed Abdalkader                }
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;  // Only expect to see one tracker matching this message.
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** {@inheritDoc} */
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1165d5ca33a24e6b73a48b575a0e1a5e790784d0bb7Amit Mahajan    public void sendSms(SmsTracker tracker) {
117f653f91baeb35b18a47c8f80b6ca1b1361dea238Ji Yang        Rlog.d(TAG, "sendSms: "
1188d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang                + " isIms()=" + isIms()
1198d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang                + " mRetryCount=" + tracker.mRetryCount
1208d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang                + " mImsRetry=" + tracker.mImsRetry
1218d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang                + " mMessageRef=" + tracker.mMessageRef
12237d949e6dd19c774b5f5d274e6fdbb1cc69a3b8eBrad Ebinger                + " mUsesImsServiceForIms=" + tracker.mUsesImsServiceForIms
1238d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang                + " SS=" + mPhone.getServiceState().getState());
1248d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang
125a0c22039b77054d659151537896c1db90c7057f7Shishir Agrawal        int ss = mPhone.getServiceState().getState();
126a0c22039b77054d659151537896c1db90c7057f7Shishir Agrawal        // if sms over IMS is not supported on data and voice is not available...
127a0c22039b77054d659151537896c1db90c7057f7Shishir Agrawal        if (!isIms() && ss != ServiceState.STATE_IN_SERVICE) {
128a0c22039b77054d659151537896c1db90c7057f7Shishir Agrawal            tracker.onFailed(mContext, getNotInServiceError(ss), 0/*errorCode*/);
129a0c22039b77054d659151537896c1db90c7057f7Shishir Agrawal            return;
130a0c22039b77054d659151537896c1db90c7057f7Shishir Agrawal        }
131a0c22039b77054d659151537896c1db90c7057f7Shishir Agrawal
1328d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang        Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
1335d5ca33a24e6b73a48b575a0e1a5e790784d0bb7Amit Mahajan        byte[] pdu = (byte[]) tracker.getData().get("pdu");
1341260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
1354eb8e4c8dc684e2109276ea2ec4ce25d3b188568Xia Ying        int currentDataNetwork = mPhone.getServiceState().getDataNetworkType();
1364eb8e4c8dc684e2109276ea2ec4ce25d3b188568Xia Ying        boolean imsSmsDisabled = (currentDataNetwork == TelephonyManager.NETWORK_TYPE_EHRPD
137000f48b9c960010bf41cd22b8625b4ff16c2e719Ajay Nambi                    || (ServiceState.isLte(currentDataNetwork)
1384eb8e4c8dc684e2109276ea2ec4ce25d3b188568Xia Ying                    && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()))
1394eb8e4c8dc684e2109276ea2ec4ce25d3b188568Xia Ying                    && mPhone.getServiceState().getVoiceNetworkType()
1404eb8e4c8dc684e2109276ea2ec4ce25d3b188568Xia Ying                    == TelephonyManager.NETWORK_TYPE_1xRTT
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    && ((GsmCdmaPhone) mPhone).mCT.mState != PhoneConstants.State.IDLE;
1424eb8e4c8dc684e2109276ea2ec4ce25d3b188568Xia Ying
1431260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        // sms over cdma is used:
1441260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        //   if sms over IMS is not supported AND
1451260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        //   this is not a retry case after sms over IMS failed
14637d949e6dd19c774b5f5d274e6fdbb1cc69a3b8eBrad Ebinger        //     indicated by mImsRetry > 0 OR
14737d949e6dd19c774b5f5d274e6fdbb1cc69a3b8eBrad Ebinger        //   SMS over IMS is disabled because of the network type OR
14837d949e6dd19c774b5f5d274e6fdbb1cc69a3b8eBrad Ebinger        //   SMS over IMS is being handled by the ImsSmsDispatcher implementation and has indicated
14937d949e6dd19c774b5f5d274e6fdbb1cc69a3b8eBrad Ebinger        //   that the message should fall back to sending over CS.
15037d949e6dd19c774b5f5d274e6fdbb1cc69a3b8eBrad Ebinger        if (0 == tracker.mImsRetry && !isIms() || imsSmsDisabled || tracker.mUsesImsServiceForIms) {
1511260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            mCi.sendCdmaSms(pdu, reply);
1521260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        } else {
1531260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            mCi.sendImsCdmaSms(pdu, tracker.mImsRetry, tracker.mMessageRef, reply);
1541260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            // increment it here, so in case of SMS_FAIL_RETRY over IMS
1551260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            // next retry will be sent using IMS request again.
1561260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa            tracker.mImsRetry++;
1571260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        }
1581260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    }
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
160