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 17 package com.android.internal.telephony.cdma; 18 19 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE; 20 21 import android.compat.annotation.UnsupportedAppUsage; 22 import android.os.Build; 23 import android.os.Message; 24 import android.telephony.ServiceState; 25 import android.telephony.TelephonyManager; 26 27 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; 28 import com.android.internal.telephony.GsmCdmaPhone; 29 import com.android.internal.telephony.Phone; 30 import com.android.internal.telephony.PhoneConstants; 31 import com.android.internal.telephony.SMSDispatcher; 32 import com.android.internal.telephony.SmsConstants; 33 import com.android.internal.telephony.SmsController; 34 import com.android.internal.telephony.SmsDispatchersController; 35 import com.android.internal.telephony.SmsHeader; 36 import com.android.internal.telephony.SmsMessageBase; 37 import com.android.internal.telephony.util.SMSDispatcherUtil; 38 import com.android.telephony.Rlog; 39 40 public class CdmaSMSDispatcher extends SMSDispatcher { 41 private static final String TAG = "CdmaSMSDispatcher"; 42 private static final boolean VDBG = false; 43 CdmaSMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController)44 public CdmaSMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) { 45 super(phone, smsDispatchersController); 46 Rlog.d(TAG, "CdmaSMSDispatcher created"); 47 } 48 49 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 50 @Override getFormat()51 public String getFormat() { 52 return SmsConstants.FORMAT_3GPP2; 53 } 54 55 /** 56 * Send the SMS status report to the dispatcher thread to process. 57 * @param sms the CDMA SMS message containing the status report 58 */ sendStatusReportMessage(SmsMessage sms)59 public void sendStatusReportMessage(SmsMessage sms) { 60 if (VDBG) Rlog.d(TAG, "sending EVENT_NEW_SMS_STATUS_REPORT message"); 61 sendMessage(obtainMessage(EVENT_NEW_SMS_STATUS_REPORT, sms)); 62 } 63 64 @Override handleStatusReport(Object o)65 protected void handleStatusReport(Object o) { 66 if (o instanceof SmsMessage) { 67 byte[] pdu = ((SmsMessage) o).getPdu(); 68 mSmsDispatchersController.handleSmsStatusReport(SmsConstants.FORMAT_3GPP2, pdu); 69 } else { 70 Rlog.e(TAG, "handleStatusReport() called for object type " + o.getClass().getName()); 71 } 72 } 73 74 @Override shouldBlockSmsForEcbm()75 protected boolean shouldBlockSmsForEcbm() { 76 // We only block outgoing SMS during ECBM when using CDMA. 77 return mPhone.isInEcm() && isCdmaMo() && !isIms(); 78 } 79 80 @Override getSubmitPdu(String scAddr, String destAddr, String message, boolean statusReportRequested, SmsHeader smsHeader, int priority, int validityPeriod)81 protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr, 82 String message, boolean statusReportRequested, SmsHeader smsHeader, int priority, 83 int validityPeriod) { 84 return SMSDispatcherUtil.getSubmitPduCdma(scAddr, destAddr, message, 85 statusReportRequested, smsHeader, priority); 86 } 87 88 @Override getSubmitPdu(String scAddr, String destAddr, int destPort, byte[] message, boolean statusReportRequested)89 protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr, 90 int destPort, byte[] message, boolean statusReportRequested) { 91 return SMSDispatcherUtil.getSubmitPduCdma(scAddr, destAddr, destPort, message, 92 statusReportRequested); 93 } 94 95 @Override getSubmitPdu(String scAddr, String destAddr, String message, boolean statusReportRequested, SmsHeader smsHeader, int priority, int validityPeriod, int messageRef)96 protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr, 97 String message, boolean statusReportRequested, SmsHeader smsHeader, int priority, 98 int validityPeriod, int messageRef) { 99 return SMSDispatcherUtil.getSubmitPduCdma(scAddr, destAddr, message, 100 statusReportRequested, smsHeader, priority); 101 } 102 103 @Override getSubmitPdu(String scAddr, String destAddr, int destPort, byte[] message, boolean statusReportRequested, int messageRef)104 protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr, 105 int destPort, byte[] message, boolean statusReportRequested, int messageRef) { 106 return SMSDispatcherUtil.getSubmitPduCdma(scAddr, destAddr, destPort, message, 107 statusReportRequested); 108 } 109 110 @Override calculateLength(CharSequence messageBody, boolean use7bitOnly)111 protected TextEncodingDetails calculateLength(CharSequence messageBody, boolean use7bitOnly) { 112 return SMSDispatcherUtil.calculateLengthCdma(messageBody, use7bitOnly); 113 } 114 115 /** {@inheritDoc} */ 116 @Override sendSms(SmsTracker tracker)117 public void sendSms(SmsTracker tracker) { 118 int ss = mPhone.getServiceState().getState(); 119 120 Rlog.d(TAG, "sendSms: " 121 + " isIms()=" + isIms() 122 + " mRetryCount=" + tracker.mRetryCount 123 + " mImsRetry=" + tracker.mImsRetry 124 + " mMessageRef=" + tracker.mMessageRef 125 + " mUsesImsServiceForIms=" + tracker.mUsesImsServiceForIms 126 + " SS=" + ss 127 + " " + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 128 129 // if sms over IMS is not supported on data and voice is not available... 130 if (!isIms() && ss != ServiceState.STATE_IN_SERVICE) { 131 tracker.onFailed(mContext, getNotInServiceError(ss), NO_ERROR_CODE); 132 notifySmsSentFailedToEmergencyStateTracker(tracker, false); 133 return; 134 } 135 136 Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 137 byte[] pdu = (byte[]) tracker.getData().get("pdu"); 138 139 int currentDataNetwork = mPhone.getServiceState().getDataNetworkType(); 140 boolean imsSmsDisabled = (currentDataNetwork == TelephonyManager.NETWORK_TYPE_EHRPD 141 || (currentDataNetwork == TelephonyManager.NETWORK_TYPE_LTE 142 || currentDataNetwork == TelephonyManager.NETWORK_TYPE_LTE_CA 143 || currentDataNetwork == TelephonyManager.NETWORK_TYPE_NR) 144 && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) 145 && mPhone.getServiceState().getVoiceNetworkType() 146 == TelephonyManager.NETWORK_TYPE_1xRTT 147 && ((GsmCdmaPhone) mPhone).mCT.mState != PhoneConstants.State.IDLE; 148 149 // sms over cdma is used: 150 // if sms over IMS is not supported AND 151 // this is not a retry case after sms over IMS failed 152 // indicated by mImsRetry > 0 OR 153 // SMS over IMS is disabled because of the network type OR 154 // SMS over IMS is being handled by the ImsSmsDispatcher implementation and has indicated 155 // that the message should fall back to sending over CS. 156 if (0 == tracker.mImsRetry && !isIms() || imsSmsDisabled || tracker.mUsesImsServiceForIms) { 157 if (tracker.mRetryCount == 0 && tracker.mExpectMore) { 158 mCi.sendCdmaSMSExpectMore(pdu, reply); 159 } else { 160 mCi.sendCdmaSms(pdu, reply); 161 } 162 } else { 163 mCi.sendImsCdmaSms(pdu, tracker.mImsRetry, tracker.mMessageRef, reply); 164 // increment it here, so in case of SMS_FAIL_RETRY over IMS 165 // next retry will be sent using IMS request again. 166 tracker.mImsRetry++; 167 } 168 } 169 } 170