| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.internal.telephony.cdma; |
| |
| import android.annotation.UnsupportedAppUsage; |
| import android.os.Message; |
| import android.telephony.Rlog; |
| import android.telephony.ServiceState; |
| import android.telephony.TelephonyManager; |
| import android.util.Pair; |
| |
| import com.android.internal.telephony.GsmCdmaPhone; |
| import com.android.internal.telephony.Phone; |
| import com.android.internal.telephony.PhoneConstants; |
| import com.android.internal.telephony.SmsConstants; |
| import com.android.internal.telephony.SMSDispatcher; |
| import com.android.internal.telephony.SmsDispatchersController; |
| import com.android.internal.telephony.SmsHeader; |
| import com.android.internal.telephony.util.SMSDispatcherUtil; |
| import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; |
| import com.android.internal.telephony.SmsMessageBase; |
| |
| |
| public class CdmaSMSDispatcher extends SMSDispatcher { |
| private static final String TAG = "CdmaSMSDispatcher"; |
| private static final boolean VDBG = false; |
| |
| public CdmaSMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) { |
| super(phone, smsDispatchersController); |
| Rlog.d(TAG, "CdmaSMSDispatcher created"); |
| } |
| |
| @UnsupportedAppUsage |
| @Override |
| public String getFormat() { |
| return SmsConstants.FORMAT_3GPP2; |
| } |
| |
| /** |
| * Send the SMS status report to the dispatcher thread to process. |
| * @param sms the CDMA SMS message containing the status report |
| */ |
| public void sendStatusReportMessage(SmsMessage sms) { |
| if (VDBG) Rlog.d(TAG, "sending EVENT_HANDLE_STATUS_REPORT message"); |
| sendMessage(obtainMessage(EVENT_HANDLE_STATUS_REPORT, sms)); |
| } |
| |
| @Override |
| protected void handleStatusReport(Object o) { |
| if (o instanceof SmsMessage) { |
| if (VDBG) Rlog.d(TAG, "calling handleCdmaStatusReport()"); |
| handleCdmaStatusReport((SmsMessage) o); |
| } else { |
| Rlog.e(TAG, "handleStatusReport() called for object type " + o.getClass().getName()); |
| } |
| } |
| |
| @Override |
| protected boolean shouldBlockSmsForEcbm() { |
| // We only block outgoing SMS during ECBM when using CDMA. |
| return mPhone.isInEcm() && isCdmaMo() && !isIms(); |
| } |
| |
| @Override |
| protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr, |
| String message, boolean statusReportRequested, SmsHeader smsHeader, int priority, |
| int validityPeriod) { |
| return SMSDispatcherUtil.getSubmitPduCdma(scAddr, destAddr, message, |
| statusReportRequested, smsHeader, priority); |
| } |
| |
| @Override |
| protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr, |
| int destPort, byte[] message, boolean statusReportRequested) { |
| return SMSDispatcherUtil.getSubmitPduCdma(scAddr, destAddr, destPort, message, |
| statusReportRequested); |
| } |
| |
| @Override |
| protected TextEncodingDetails calculateLength(CharSequence messageBody, boolean use7bitOnly) { |
| return SMSDispatcherUtil.calculateLengthCdma(messageBody, use7bitOnly); |
| } |
| /** |
| * Called from parent class to handle status report from {@code CdmaInboundSmsHandler}. |
| * @param sms the CDMA SMS message to process |
| */ |
| @UnsupportedAppUsage |
| private void handleCdmaStatusReport(SmsMessage sms) { |
| for (int i = 0, count = deliveryPendingList.size(); i < count; i++) { |
| SmsTracker tracker = deliveryPendingList.get(i); |
| if (tracker.mMessageRef == sms.mMessageRef) { |
| Pair<Boolean, Boolean> result = |
| mSmsDispatchersController.handleSmsStatusReport(tracker, getFormat(), |
| sms.getPdu()); |
| if (result.second) { |
| deliveryPendingList.remove(i); |
| } |
| break; // Only expect to see one tracker matching this message. |
| } |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| @Override |
| public void sendSms(SmsTracker tracker) { |
| Rlog.d(TAG, "sendSms: " |
| + " isIms()=" + isIms() |
| + " mRetryCount=" + tracker.mRetryCount |
| + " mImsRetry=" + tracker.mImsRetry |
| + " mMessageRef=" + tracker.mMessageRef |
| + " mUsesImsServiceForIms=" + tracker.mUsesImsServiceForIms |
| + " SS=" + mPhone.getServiceState().getState()); |
| |
| int ss = mPhone.getServiceState().getState(); |
| // if sms over IMS is not supported on data and voice is not available... |
| if (!isIms() && ss != ServiceState.STATE_IN_SERVICE) { |
| tracker.onFailed(mContext, getNotInServiceError(ss), 0/*errorCode*/); |
| return; |
| } |
| |
| Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); |
| byte[] pdu = (byte[]) tracker.getData().get("pdu"); |
| |
| int currentDataNetwork = mPhone.getServiceState().getDataNetworkType(); |
| boolean imsSmsDisabled = (currentDataNetwork == TelephonyManager.NETWORK_TYPE_EHRPD |
| || (ServiceState.isLte(currentDataNetwork) |
| && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed())) |
| && mPhone.getServiceState().getVoiceNetworkType() |
| == TelephonyManager.NETWORK_TYPE_1xRTT |
| && ((GsmCdmaPhone) mPhone).mCT.mState != PhoneConstants.State.IDLE; |
| |
| // sms over cdma is used: |
| // if sms over IMS is not supported AND |
| // this is not a retry case after sms over IMS failed |
| // indicated by mImsRetry > 0 OR |
| // SMS over IMS is disabled because of the network type OR |
| // SMS over IMS is being handled by the ImsSmsDispatcher implementation and has indicated |
| // that the message should fall back to sending over CS. |
| if (0 == tracker.mImsRetry && !isIms() || imsSmsDisabled || tracker.mUsesImsServiceForIms) { |
| mCi.sendCdmaSms(pdu, reply); |
| } else { |
| mCi.sendImsCdmaSms(pdu, tracker.mImsRetry, tracker.mMessageRef, reply); |
| // increment it here, so in case of SMS_FAIL_RETRY over IMS |
| // next retry will be sent using IMS request again. |
| tracker.mImsRetry++; |
| } |
| } |
| } |