diff options
Diffstat (limited to 'telephony/java/com/android/internal')
47 files changed, 2712 insertions, 1211 deletions
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java index fbc596c..e78422e 100644 --- a/telephony/java/com/android/internal/telephony/BaseCommands.java +++ b/telephony/java/com/android/internal/telephony/BaseCommands.java @@ -54,34 +54,32 @@ public abstract class BaseCommands implements CommandsInterface { protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList(); protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList(); protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList(); + protected RegistrantList mOtaSessionRegistrants = new RegistrantList(); + protected RegistrantList mCallWaitingRegistrants = new RegistrantList(); + protected RegistrantList mInformationRecordsRegistrants = new RegistrantList(); protected Registrant mUnsolOemHookRawRegistrant; protected Registrant mSMSRegistrant; protected Registrant mNITZTimeRegistrant; protected Registrant mSignalStrengthRegistrant; protected Registrant mUSSDRegistrant; protected Registrant mSmsOnSimRegistrant; - /** Registrant for handling SMS Status Reports */ protected Registrant mSmsStatusRegistrant; - /** Registrant for handling Supplementary Service Notifications */ protected Registrant mSsnRegistrant; protected Registrant mStkSessionEndRegistrant; protected Registrant mStkProCmdRegistrant; protected Registrant mStkEventRegistrant; protected Registrant mStkCallSetUpRegistrant; - /** Registrant for handling SIM/RUIM SMS storage full messages */ protected Registrant mIccSmsFullRegistrant; - /** Registrant for handling Icc Refresh notifications */ + protected Registrant mEmergencyCallbackModeRegistrant; protected Registrant mIccRefreshRegistrant; - /** Registrant for handling RING notifications */ protected Registrant mRingRegistrant; - /** Registrant for handling RESTRICTED STATE changed notification */ protected Registrant mRestrictedStateRegistrant; - //Network Mode received from PhoneFactory + // Network Mode received from PhoneFactory protected int mNetworkMode; - //CDMA subscription received from PhoneFactory + // CDMA subscription received from PhoneFactory protected int mCdmaSubscription; - //Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone. + // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone. protected int mPhoneType; @@ -424,6 +422,10 @@ public abstract class BaseCommands implements CommandsInterface { mIccRefreshRegistrant = new Registrant (h, what, obj); } + public void setEmergencyCallbackMode(Handler h, int what, Object obj) { + mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj); + } + public void unSetOnIccRefresh(Handler h) { mIccRefreshRegistrant.clear(); } @@ -470,6 +472,33 @@ public abstract class BaseCommands implements CommandsInterface { mUnsolOemHookRawRegistrant.clear(); } + public void registerForOtaSessionStatus(Handler h, int what, Object obj){ + Registrant r = new Registrant (h, what, obj); + mOtaSessionRegistrants.add(r); + } + + public void unregisterForOtaSessionStatus(Handler h){ + mOtaSessionRegistrants.remove(h); + } + + public void registerForCdmaCallWaiting(Handler h, int what, Object obj){ + Registrant r = new Registrant (h, what, obj); + mCallWaitingRegistrants.add(r); + } + + public void unregisterForCdmaCallWaiting(Handler h){ + mCallWaitingRegistrants.remove(h); + } + + public void registerCdmaInformationRecord(Handler h, int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + mInformationRecordsRegistrants.add(r); + } + + public void unregisterCdmaInformationRecord(Handler h) { + mInformationRecordsRegistrants.remove(h); + } + //***** Protected Methods /** * Store new RadioState and send notification based on the changes diff --git a/telephony/java/com/android/internal/telephony/CdmaInformationRecord.java b/telephony/java/com/android/internal/telephony/CdmaInformationRecord.java new file mode 100644 index 0000000..690df05 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/CdmaInformationRecord.java @@ -0,0 +1,201 @@ +/* + * 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; + +/** + * TODO(Teleca): This class was poorly implemented and didn't + * follow the Android coding conventions. It is now more or less + * follows the conventions but there is still some work, see the + * TODO's. + */ + + +public class CdmaInformationRecord { + public int messageName; + + public CdmaDisplayInfoRec displayInfoRec; + public CdmaNumberInfoRec numberInfoRec; + public CdmaSignalInfoRec signalInfoRec; + public CdmaRedirectingNumberInfoRec redirectingNumberInfoRec; + public CdmaLineControlInfoRec lineControlInfoRec; + public CdmaT53ClirInfoRec cdmaT53ClirInfoRec; + public CdmaT53AudioControlInfoRec cdmaT53AudioControlInfoRec; + + public static final int RIL_CDMA_DISPLAY_INFO_REC = 0; + public static final int RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC = 1; + public static final int RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC = 2; + public static final int RIL_CDMA_CONNECTED_NUMBER_INFO_REC = 3; + public static final int RIL_CDMA_SIGNAL_INFO_REC = 4; + public static final int RIL_CDMA_REDIRECTING_NUMBER_INFO_REC = 5; + public static final int RIL_CDMA_LINE_CONTROL_INFO_REC = 6; + public static final int RIL_CDMA_EXTENDED_DISPLAY_INFO_REC = 7; + public static final int RIL_CDMA_T53_CLIR_INFO_REC = 8; + public static final int RIL_CDMA_T53_RELEASE_INFO_REC = 9; + public static final int RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC = 10; + + public CdmaInformationRecord(int messageName) { + this.messageName = messageName; + } + + void createDisplayInfo(int length, char buffer[]) { + displayInfoRec = new CdmaDisplayInfoRec(length, buffer); + } + + void createNumberInfo(int length, char buffer[]) { + numberInfoRec = new CdmaNumberInfoRec(length, buffer); + } + + void createSignalInfo(char buffer[]) { + signalInfoRec = new CdmaSignalInfoRec(buffer); + } + + void createRedirectingNumberInfo(int length, char buffer[], int reason) { + redirectingNumberInfoRec = new CdmaRedirectingNumberInfoRec(length, buffer, reason); + } + + void createLineControlInfo(char buffer[]) { + lineControlInfoRec = new CdmaLineControlInfoRec(buffer); + } + + void createT53ClirInfo(char buffer) { + cdmaT53ClirInfoRec = new CdmaT53ClirInfoRec(buffer); + } + + void createT53AudioControlInfo(char ul, char dl) { + cdmaT53AudioControlInfoRec = new CdmaT53AudioControlInfoRec(ul, dl); + } + + /** + * TODO(Teleca): Add comments for each class giving the + * document and section where the information is defined + * as shown CdmaSignalInfoRec. Also add a toString to + * each of these to ease debugging. + */ + + /** + * Signal Information record from 3GPP2 C.S005 3.7.5.5 + */ + public static class CdmaSignalInfoRec { + public boolean isPresent; /* non-zero if signal information record is present */ + public int signalType; + public int alertPitch; + public int signalCode; + + public CdmaSignalInfoRec() {} + + public CdmaSignalInfoRec(char buffer[]) { + isPresent = buffer[0] == 1; + signalType = buffer[1]; + alertPitch = buffer[2]; + signalCode = buffer[3]; + } + + @Override + public String toString() { + return "CdmaSignalInfo: {" + + " isPresent: " + isPresent + + ", signalType: " + signalType + + ", alertPitch: " + alertPitch + + ", signalCode: " + signalCode + + " }"; + } + } + + public static class CdmaDisplayInfoRec { + public char alphaLen; + public char alphaBuf[]; + + public CdmaDisplayInfoRec(int length, char buffer[]) { + alphaLen = (char)length; + alphaBuf = new char[length]; + for(int i = 0; i < length; i++) + alphaBuf[i] = buffer[i]; + } + } + + public static class CdmaNumberInfoRec { + public int len; + public char buf[]; + public char numberType; + public char numberPlan; + public char pi; // TODO(Teleca): poor name, no meaning + public char si; // TODO(Teleca): poor name + + public CdmaNumberInfoRec(int length, char buffer[]) { + int i; + + len = length; + buf = new char[length]; + for (i = 0; i < len; i++) { + buf[i] = buffer[i]; + } + + numberType = buffer[i++]; + numberPlan = buffer[i++]; + pi = buffer[i++]; + si = buffer[i++]; + } + } + + public static class CdmaRedirectingNumberInfoRec { + public static final int REASON_UNKNOWN = 0; + public static final int REASON_CALL_FORWARDING_BUSY = 1; + public static final int REASON_CALL_FORWARDING_NO_REPLY = 2; + public static final int REASON_CALLED_DTE_OUT_OF_ORDER = 9; + public static final int REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10; + public static final int REASON_CALL_FORWARDING_UNCONDITIONAL = 15; + + public CdmaNumberInfoRec numberInfoRec; + public int redirectingReason; + + public CdmaRedirectingNumberInfoRec(int length, char buffer[], int reason) { + numberInfoRec = new CdmaNumberInfoRec(length, buffer); + redirectingReason = reason; + } + } + + public static class CdmaLineControlInfoRec { + public char lineCtrlPolarityIncluded; + public char lineCtrlToggle; + public char lineCtrlReverse; + public char lineCtrlPowerDenial; + + CdmaLineControlInfoRec(char buffer[]) { + lineCtrlPolarityIncluded = buffer[0]; + lineCtrlToggle = buffer[1]; + lineCtrlReverse = buffer[2]; + lineCtrlPowerDenial = buffer[3]; + } + } + + // TODO(Teleca): A class for a single character, is this needed? + public static class CdmaT53ClirInfoRec { + public char cause; + + public CdmaT53ClirInfoRec(char buffer) { + cause = buffer; + } + } + + public static class CdmaT53AudioControlInfoRec { + public char uplink; + public char downlink; + + public CdmaT53AudioControlInfoRec(char ul, char dl) { + uplink = ul; + downlink = dl; + } + } +} diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java index 5a1bb7e..ddf6b50 100644 --- a/telephony/java/com/android/internal/telephony/CommandsInterface.java +++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java @@ -241,6 +241,24 @@ public interface CommandsInterface { void unregisterForRUIMReady(Handler h); /** + * Registers for the status of an OTASP/OTAPA session + */ + void registerForOtaSessionStatus(Handler h, int what, Object obj); + void unregisterForOtaSessionStatus(Handler h); + + /** + * register for Call waiting for CDMA + */ + void registerForCdmaCallWaiting(Handler h, int what, Object obj); + void unregisterForCdmaCallWaiting(Handler h); + + /** + * Registers for CDMA information records + */ + void registerCdmaInformationRecord(Handler h, int what, Object obj); + void unregisterCdmaInformationRecord(Handler h); + + /** * unlike the register* methods, there's only one new SMS handler * if you need to unregister, you should also tell the radio to stop * sending SMS's to you (via AT+CNMI) @@ -326,6 +344,16 @@ public interface CommandsInterface { void unSetOnIccSmsFull(Handler h); /** + * Sets the handler for Emergency call-back Mode enter mesage. + * Unlike the register* methods, there's only one notification handler + * + * @param h Handler for notification message. + * @param what User-defined message code. + * @param obj User object. + */ + void setEmergencyCallbackMode(Handler h, int what, Object obj); + + /** * Sets the handler for SIM Refresh notifications. * Unlike the register* methods, there's only one notification handler * @@ -348,12 +376,12 @@ public interface CommandsInterface { void unSetOnCallRing(Handler h); /** - * Sets the handler for RESTRICTED_STATE changed notification, + * Sets the handler for RESTRICTED_STATE changed notification, * eg, for Domain Specific Access Control * unlike the register* methods, there's only one signal strength handler - * - * AsyncResult.result is an int[1] - * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values + * + * AsyncResult.result is an int[1] + * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values */ void setOnRestrictedStateChanged(Handler h, int what, Object obj); @@ -516,7 +544,7 @@ public interface CommandsInterface { * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj - * ar.result contains a List of PDPContextState + * ar.result contains a List of DataCallState * @deprecated */ void getPDPContextList(Message result); @@ -526,7 +554,7 @@ public interface CommandsInterface { * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj - * ar.result contains a List of PDPContextState + * ar.result contains a List of DataCallState */ void getDataCallList(Message result); @@ -767,6 +795,12 @@ public interface CommandsInterface { */ void stopDtmf(Message result); + /** + * ar.exception carries exception on failure + * ar.userObject contains the orignal value of result.obj + * ar.result is null on success and failure + */ + void sendBurstDtmf(String dtmfString, Message result); /** * smscPDU is smsc address in PDU form GSM BCD format prefixed @@ -1087,13 +1121,12 @@ public interface CommandsInterface { public void getDeviceIdentity(Message response); /** - * Request the device IMSI_M / MDN / AH_SID / H_SID / H_NID. + * Request the device MDN / H_SID / H_NID / MIN. * "response" is const char ** - * [0] is IMSI_M if CDMA subscription is available - * [1] is MDN if CDMA subscription is available - * [2] is AH_SID (Analog Home SID) if CDMA subscription - * [3] is H_SID (Home SID) if CDMA subscription is available - * [4] is H_NID (Home SID) if CDMA subscription is available + * [0] is MDN if CDMA subscription is available + * [1] is H_SID (Home SID) if CDMA subscription is available + * [2] is H_NID (Home NID) if CDMA subscription is available + * [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available */ public void getCDMASubscription(Message response); @@ -1133,7 +1166,7 @@ public interface CommandsInterface { * @param enable is true to enable, false to disable * @param response is callback message */ - void setTTYModeEnabled(boolean enable, Message response); + void setTTYMode(int ttyMode, Message response); /** * Query the TTY mode for the CDMA phone @@ -1142,7 +1175,7 @@ public interface CommandsInterface { * * @param response is callback message */ - void queryTTYModeEnabled(Message response); + void queryTTYMode(Message response); /** * Setup a packet data connection On successful completion, the result @@ -1196,6 +1229,10 @@ public interface CommandsInterface { * @param result * Callback message is empty on completion */ + /** + * TODO(Teleca): configValuesArray is represented as a RIL_BroadcastSMSConfig + * so we think this should be a class with the appropriate parameters not an array? + */ public void setCdmaBroadcastConfig(int[] configValuesArray, Message result); /** @@ -1205,4 +1242,10 @@ public interface CommandsInterface { * Callback message contains the configuration from the modem on completion */ public void getCdmaBroadcastConfig(Message result); + + /** + * Requests the radio's system selection module to exit emergency callback mode. + * @param response callback message + */ + public void exitEmergencyCallbackMode(Message response); } diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java index 86ceb89..c6bbf82 100644 --- a/telephony/java/com/android/internal/telephony/Connection.java +++ b/telephony/java/com/android/internal/telephony/Connection.java @@ -29,25 +29,34 @@ public abstract class Connection { public enum DisconnectCause { - NOT_DISCONNECTED, /* has not yet disconnected */ - INCOMING_MISSED, /* an incoming call that was missed and never answered */ - NORMAL, /* normal; remote */ - LOCAL, /* normal; local hangup */ - BUSY, /* outgoing call to busy line */ - CONGESTION, /* outgoing call to congested network */ - MMI, /* not presently used; dial() returns null */ - INVALID_NUMBER, /* invalid dial string */ + NOT_DISCONNECTED, /* has not yet disconnected */ + INCOMING_MISSED, /* an incoming call that was missed and never answered */ + NORMAL, /* normal; remote */ + LOCAL, /* normal; local hangup */ + BUSY, /* outgoing call to busy line */ + CONGESTION, /* outgoing call to congested network */ + MMI, /* not presently used; dial() returns null */ + INVALID_NUMBER, /* invalid dial string */ LOST_SIGNAL, - LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */ - INCOMING_REJECTED, /* an incoming call that was rejected */ - POWER_OFF, /* radio is turned off explicitly */ - OUT_OF_SERVICE, /* out of service */ - ICC_ERROR, /* No ICC, ICC locked, or other ICC error */ - CALL_BARRED, /* call was blocked by call barrring */ - FDN_BLOCKED, /* call was blocked by fixed dial number */ - CS_RESTRICTED, /* call was blocked by restricted all voice access */ - CS_RESTRICTED_NORMAL,/* call was blocked by restricted normal voice access */ - CS_RESTRICTED_EMERGENCY/* call was blocked by restricted emergency voice access */ + LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */ + INCOMING_REJECTED, /* an incoming call that was rejected */ + POWER_OFF, /* radio is turned off explicitly */ + OUT_OF_SERVICE, /* out of service */ + ICC_ERROR, /* No ICC, ICC locked, or other ICC error */ + CALL_BARRED, /* call was blocked by call barrring */ + FDN_BLOCKED, /* call was blocked by fixed dial number */ + CS_RESTRICTED, /* call was blocked by restricted all voice access */ + CS_RESTRICTED_NORMAL, /* call was blocked by restricted normal voice access */ + CS_RESTRICTED_EMERGENCY, /* call was blocked by restricted emergency voice access */ + CDMA_LOCKED_UNTIL_POWER_CYCLE, /* MS is locked until next power cycle */ + CDMA_DROP, + CDMA_INTERCEPT, /* INTERCEPT order received, MS state idle entered */ + CDMA_REORDER, /* MS has been redirected, call is cancelled */ + CDMA_SO_REJECT, /* service option rejection */ + CDMA_RETRY_ORDER, /* requeseted service is rejected, retry delay is set */ + CDMA_ACCESS_FAILURE, + CDMA_PREEMPTED, + CDMA_NOT_EMERGENCY /* not an emergency call */ } Object userData; diff --git a/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java b/telephony/java/com/android/internal/telephony/DataCallState.java index 31cdacf..d0f3d24 100644 --- a/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java +++ b/telephony/java/com/android/internal/telephony/DataCallState.java @@ -1,5 +1,6 @@ /* - * Copyright (C) 2006 The Android Open Source Project + * Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved. + * Copyright (C) 2009 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. @@ -14,25 +15,18 @@ * limitations under the License. */ -package com.android.internal.telephony.gsm; +package com.android.internal.telephony; -/** - * {@hide} - */ -public class PDPContextState { +public class DataCallState { public int cid; public int active; public String type; public String apn; public String address; + @Override public String toString() { - return "com.android.internal.telephony.gsm.PDPContextState: {" + - " cid: " + cid + - ", active: " + active + - ", type: " + type + - ", apn: " + apn + - ", address: " + address + - " }"; + return "DataCallState: {" + " cid: " + cid + ", active: " + active + ", type: " + type + + ", apn: " + apn + ", address: " + address + " }"; } } diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java index 5b826b2..d23af1f 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -63,7 +63,8 @@ public abstract class DataConnectionTracker extends Handler { NONE, DATAIN, DATAOUT, - DATAINANDOUT + DATAINANDOUT, + DORMANT } //***** Event Codes diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java index 79b4afe..d6151c6 100644 --- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java +++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java @@ -62,7 +62,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier { public void notifySignalStrength(Phone sender) { try { - mRegistry.notifySignalStrength(sender.getSignalStrengthASU()); + mRegistry.notifySignalStrength(sender.getSignalStrength()); } catch (RemoteException ex) { // system process is dead } @@ -200,6 +200,8 @@ public class DefaultPhoneNotifier implements PhoneNotifier { return TelephonyManager.DATA_ACTIVITY_OUT; case DATAINANDOUT: return TelephonyManager.DATA_ACTIVITY_INOUT; + case DORMANT: + return TelephonyManager.DATA_ACTIVITY_DORMANT; default: return TelephonyManager.DATA_ACTIVITY_NONE; } @@ -217,6 +219,8 @@ public class DefaultPhoneNotifier implements PhoneNotifier { return Phone.DataActivityState.DATAOUT; case TelephonyManager.DATA_ACTIVITY_INOUT: return Phone.DataActivityState.DATAINANDOUT; + case TelephonyManager.DATA_ACTIVITY_DORMANT: + return Phone.DataActivityState.DORMANT; default: return Phone.DataActivityState.NONE; } diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java index 8f4c69c..8e2941b 100644 --- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java +++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java @@ -182,7 +182,7 @@ public class GsmAlphabet { return stringToGsm7BitPacked(data); } - int headerBits = header.length * 8; + int headerBits = (header.length + 1) * 8; int headerSeptets = headerBits / 7; headerSeptets += (headerBits % 7) > 0 ? 1 : 0; @@ -194,7 +194,8 @@ public class GsmAlphabet { (headerSeptets*7), true); // Paste in the header - System.arraycopy(header, 0, ret, 1, header.length); + ret[1] = (byte)header.length; + System.arraycopy(header, 0, ret, 2, header.length); return ret; } diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index e0884b3..0202ec8 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -18,6 +18,7 @@ package com.android.internal.telephony; import android.os.Bundle; import android.telephony.ServiceState; +import android.telephony.SignalStrength; oneway interface IPhoneStateListener { void onServiceStateChanged(in ServiceState serviceState); @@ -30,5 +31,6 @@ oneway interface IPhoneStateListener { void onCallStateChanged(int state, String incomingNumber); void onDataConnectionStateChanged(int state); void onDataActivity(int direction); + void onSignalStrengthsChanged(in SignalStrength signalStrength); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index bab0603..cc6b452 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -221,5 +221,22 @@ interface ITelephony { */ int getActivePhoneType(); + /** + * Returns the CDMA ERI icon index to display + */ + int getCdmaEriIconIndex(); + + /** + * Returns the CDMA ERI icon mode, + * 0 - ON + * 1 - FLASHING + */ + int getCdmaEriIconMode(); + + /** + * Returns the CDMA ERI text, + */ + String getCdmaEriText(); + } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 1b011fe..865c6ca 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -19,6 +19,7 @@ package com.android.internal.telephony; import android.content.Intent; import android.os.Bundle; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import com.android.internal.telephony.IPhoneStateListener; interface ITelephonyRegistry { @@ -26,7 +27,7 @@ interface ITelephonyRegistry { void notifyCallState(int state, String incomingNumber); void notifyServiceState(in ServiceState state); - void notifySignalStrength(int signalStrengthASU); + void notifySignalStrength(in SignalStrength signalStrength); void notifyMessageWaitingChanged(boolean mwi); void notifyCallForwardingChanged(boolean cfi); void notifyDataActivity(int state); diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java index 014fbb6..7eafafd 100644 --- a/telephony/java/com/android/internal/telephony/IccConstants.java +++ b/telephony/java/com/android/internal/telephony/IccConstants.java @@ -61,4 +61,5 @@ public interface IccConstants { static final String DF_TELECOM = "7F10"; static final String DF_GRAPHICS = "5F50"; static final String DF_GSM = "7F20"; + static final String DF_CDMA = "7F25"; } diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java index 03c1c56..4d0cf41 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -23,6 +23,7 @@ import android.os.Message; import android.preference.PreferenceManager; import android.telephony.CellLocation; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import com.android.internal.telephony.DataConnection; import com.android.internal.telephony.gsm.NetworkInfo; @@ -82,9 +83,11 @@ public interface Phone { * <li>DATAIN = Receiving IP ppp traffic</li> * <li>DATAOUT = Sending IP ppp traffic</li> * <li>DATAINANDOUT = Both receiving and sending IP ppp traffic</li> + * <li>DORMANT = The data connection is still active, + but physical link is down</li> * </ul> */ - NONE, DATAIN, DATAOUT, DATAINANDOUT; + NONE, DATAIN, DATAOUT, DATAINANDOUT, DORMANT; }; enum SuppService { @@ -150,7 +153,7 @@ public interface Phone { static final String REASON_PS_RESTRICT_ENABLED = "psRestrictEnabled"; static final String REASON_PS_RESTRICT_DISABLED = "psRestrictDisabled"; static final String REASON_SIM_LOADED = "simLoaded"; - + // Used for band mode selection methods static final int BM_UNSPECIFIED = 0; // selected by baseband automatically static final int BM_EURO_BAND = 1; // GSM-900 / DCS-1800 / WCDMA-IMT-2000 @@ -162,28 +165,35 @@ public interface Phone { // Used for preferred network type // Note NT_* substitute RILConstants.NETWORK_MODE_* above the Phone - int NT_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */ - int NT_MODE_GSM_ONLY = 1; /* GSM only */ - int NT_MODE_WCDMA_ONLY = 2; /* WCDMA only */ - int NT_MODE_GSM_UMTS = 3; /* GSM/WCDMA (auto mode, according to PRL) - AVAILABLE Application Settings menu*/ - int NT_MODE_CDMA = 4; /* CDMA and EvDo (auto mode, according to PRL) - AVAILABLE Application Settings menu*/ - int NT_MODE_CDMA_NO_EVDO = 5; /* CDMA only */ - int NT_MODE_EVDO_NO_CDMA = 6; /* EvDo only */ - int NT_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) - AVAILABLE Application Settings menu*/ - int PREFERRED_NT_MODE = NT_MODE_GSM_ONLY; + int NT_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF; + int NT_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY; + int NT_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY; + int NT_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS; + + int NT_MODE_CDMA = RILConstants.NETWORK_MODE_CDMA; + + int NT_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO; + int NT_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA; + int NT_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL; + + int PREFERRED_NT_MODE = RILConstants.PREFERRED_NETWORK_MODE; // Used for CDMA roaming mode - static final int CDMA_RM_HOME = 0; //Home Networks only, as defined in PRL - static final int CDMA_RM_AFFILIATED = 1; //Roaming an Affiliated networks, as defined in PRL - static final int CDMA_RM_ANY = 2; //Roaming on Any Network, as defined in PRL + static final int CDMA_RM_HOME = 0; // Home Networks only, as defined in PRL + static final int CDMA_RM_AFFILIATED = 1; // Roaming an Affiliated networks, as defined in PRL + static final int CDMA_RM_ANY = 2; // Roaming on Any Network, as defined in PRL // Used for CDMA subscription mode - static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; //RUIM/SIM (default) - static final int CDMA_SUBSCRIPTION_NV = 1; //NV -> non-volatile memory + static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // RUIM/SIM (default) + static final int CDMA_SUBSCRIPTION_NV = 1; // NV -> non-volatile memory + + static final int PREFERRED_CDMA_SUBSCRIPTION = CDMA_SUBSCRIPTION_NV; + + static final int TTY_MODE_OFF = 0; + static final int TTY_MODE_FULL = 1; + static final int TTY_MODE_HCO = 2; + static final int TTY_MODE_VCO = 3; /** * Get the current ServiceState. Use @@ -263,16 +273,11 @@ public interface Phone { String getActiveApn(); /** - * Get current signal strength. No change notification available on this - * interface. Use <code>PhoneStateNotifier</code> or an equivalent. - * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu). - * The following special values are defined:</p> - * <ul><li>0 means "-113 dBm or less".</li> - * <li>31 means "-51 dBm or greater".</li></ul> + * Get current signal strength. * - * @return Current signal strength in ASU's. + * @return Current signal strength as SignalStrength */ - int getSignalStrengthASU(); + SignalStrength getSignalStrength(); /** * Notifies when a previously untracked non-ringing/waiting connection has appeared. @@ -494,6 +499,53 @@ public interface Phone { void unregisterForInCallVoicePrivacyOff(Handler h); /** + * Register for notifications about information record available + * + * @param h Handler that receives the notification message. + * @param what User-defined message code. + * @param obj User object. + */ + void registerCdmaInformationRecord(Handler h, int what, Object obj); + + /** + * Unregister for notifications about information record available + * + * @param h Handler to be removed from the registrant list. + */ + void unregisterCdmaInformationRecord(Handler h); + + /** + * Register for the indication of OTA status change + * + * @param h Handler that receives the notification message. + * @param what User-defined message code. + * @param obj User object. + */ + void registerForOtaStatusChange(Handler h, int what, Object obj); + + /** + * Unregister for the indication of OTA status change + * + * @param h Handler to be removed from the registrant list. + */ + void unregisterForOtaStatusChange(Handler h); + + /** + * Register for the indication of Cdma Call Waiting + * + * @param h Handler that receives the notification message. + * @param what User-defined message code. + * @param obj User object. + */ + void registerForCdmaCallWaiting(Handler h, int what, Object obj); + + /** + * Unregister for the indication of Cdma Call Waiting + * + * @param h Handler to be removed from the registrant list. + */ + void unregisterForCdmaCallWaiting(Handler h); + /** * Returns SIM record load state. Use * <code>getSimCard().registerForReady()</code> for change notification. * @@ -707,6 +759,10 @@ public interface Phone { */ void stopDtmf(); + /** + * Play a Burst of DTMF tone on the active call. Ignored if there is no active call. + */ + void sendBurstDtmf(String dtmfString); /** * Sets the radio power on/off state (off is sometimes @@ -1279,6 +1335,10 @@ public interface Phone { //***** CDMA support methods + /** + * Retrieves the MIN for CDMA phones. + */ + String getMin(); /** * Retrieves the ESN for CDMA phones. @@ -1306,22 +1366,30 @@ public interface Phone { public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(); /** - * setTTYModeEnabled + * setTTYMode * sets a TTY mode option. * * @param enable is a boolean representing the state that you are * requesting, true for enabled, false for disabled. * @param onComplete a callback message when the action is completed */ - void setTTYModeEnabled(boolean enable, Message onComplete); + void setTTYMode(int ttyMode, Message onComplete); /** - * queryTTYModeEnabled + * queryTTYMode * query the status of the TTY mode * * @param onComplete a callback message when the action is completed. */ - void queryTTYModeEnabled(Message onComplete); + void queryTTYMode(Message onComplete); + + /** + * exitEmergencyCallbackMode + * exits the emergency callback mode + * + * @param onComplete a callback message when the action is completed. + */ + void exitEmergencyCallbackMode(Message onComplete); /** * Activate or deactivate cell broadcast SMS. @@ -1344,10 +1412,30 @@ public interface Phone { /** * Configure cell broadcast SMS. * + * TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig + * * @param response * Callback message is empty on completion */ public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response); public void notifyDataActivity(); + + /** + * Returns the CDMA ERI icon index to display + */ + public int getCdmaEriIconIndex(); + + /** + * Returns the CDMA ERI icon mode, + * 0 - ON + * 1 - FLASHING + */ + public int getCdmaEriIconMode(); + + /** + * Returns the CDMA ERI text, + */ + public String getCdmaEriText(); + } diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java index 0314034..7234aa3 100644 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ b/telephony/java/com/android/internal/telephony/PhoneBase.java @@ -29,6 +29,7 @@ import android.os.RegistrantList; import android.os.SystemProperties; import android.preference.PreferenceManager; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import android.text.TextUtils; import android.util.Log; @@ -52,6 +53,15 @@ import java.util.Locale; * */ +/** + * TODO(Teleca): This has a multitude of methods that are CDMA specific + * , (registerForVoicePrivacy, registerCdmaInformationRecord, registerCdmaCallWaiting, + * setCdmaRoamingPreference, setCdmaSubscription, getCdmaEriIcon, getCdmaEriText, ...) can + * these type of calls be more abstract. For example CallWaiting is common between the GSM/CDMA + * it would seem that doesn't need to be cdma specific. Also, should the application be directly + * dealing with the CdmaInformationRecord's could they be abstracted to something more generic. + */ + public abstract class PhoneBase implements Phone { private static final String LOG_TAG = "PHONE"; private static final boolean LOCAL_DEBUG = true; @@ -90,6 +100,8 @@ public abstract class PhoneBase implements Phone { protected static final int EVENT_RUIM_RECORDS_LOADED = 21; protected static final int EVENT_NV_READY = 22; protected static final int EVENT_SET_ENHANCED_VP = 23; + protected static final int EVENT_CDMA_CALL_WAITING = 24; + protected static final int EVENT_EMERGENCY_CALLBACK_MODE = 25; // Key used to read/write current CLIR setting public static final String CLIR_KEY = "clir_key"; @@ -187,7 +199,7 @@ public abstract class PhoneBase implements Phone { setUnitTestMode(unitTestMode); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); - mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); + mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); } // Inherited documentation suffices. @@ -204,7 +216,7 @@ public abstract class PhoneBase implements Phone { mDnsCheckDisabled = b; SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences.Editor editor = sp.edit(); - editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); + editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); editor.commit(); } @@ -282,6 +294,35 @@ public abstract class PhoneBase implements Phone { mCM.unregisterForInCallVoicePrivacyOff(h); } + // Inherited documentation suffices. + public void registerForOtaStatusChange(Handler h, int what, Object obj){ + mCM.registerForOtaSessionStatus(h,what,obj); + } + + // Inherited documentation suffices. + public void unregisterForOtaStatusChange(Handler h){ + mCM.unregisterForOtaSessionStatus(h); + } + + // Inherited documentation suffices. + public void registerCdmaInformationRecord(Handler h, int what, Object obj){ + mCM.registerCdmaInformationRecord(h,what,obj); + } + + // Inherited documentation suffices. + public void unregisterCdmaInformationRecord(Handler h){ + mCM.unregisterCdmaInformationRecord(h); + } + + // Inherited documentation suffices. + public void registerForCdmaCallWaiting(Handler h, int what, Object obj){ + mCM.registerForCdmaCallWaiting(h,what,obj); + } + + // Inherited documentation suffices. + public void unregisterForCdmaCallWaiting(Handler h){ + mCM.unregisterForCdmaCallWaiting(h); + } /** * Notifiy registrants of a new ringing Connection. @@ -567,9 +608,6 @@ public abstract class PhoneBase implements Phone { mCM.setPreferredNetworkType(networkType, response); } - /** - * Set the status of the preferred Network Type: Global, CDMA only or GSM/UMTS only - */ public void getPreferredNetworkType(Message response) { mCM.getPreferredNetworkType(response); } @@ -582,12 +620,20 @@ public abstract class PhoneBase implements Phone { mCM.setSmscAddress(address, result); } - public void setTTYModeEnabled(boolean enable, Message onComplete) { + public void setTTYMode(int ttyMode, Message onComplete) { + // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. + Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); + } + + public void queryTTYMode(Message onComplete) { // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); } - public void queryTTYModeEnabled(Message onComplete) { + /** + * Send the exit emergency callback mode message + */ + public void exitEmergencyCallbackMode(Message onComplete) { // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); } @@ -638,4 +684,30 @@ public abstract class PhoneBase implements Phone { public abstract String getPhoneName(); + /** + * Returns the CDMA ERI icon index to display + */ + public int getCdmaEriIconIndex() { + Log.e(LOG_TAG, "Error! getCdmaEriIconIndex should never be executed in GSM mode"); + return -1; + } + + /** + * Returns the CDMA ERI icon mode, + * 0 - ON + * 1 - FLASHING + */ + public int getCdmaEriIconMode() { + Log.e(LOG_TAG, "Error! getCdmaEriIconMode should never be executed in GSM mode"); + return -1; + } + + /** + * Returns the CDMA ERI text, + */ + public String getCdmaEriText() { + Log.e(LOG_TAG, "Error! getCdmaEriText should never be executed in GSM mode"); + return "GSM nw, no ERI"; + } + } diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java index 86e2f04..a84f74e 100644 --- a/telephony/java/com/android/internal/telephony/PhoneFactory.java +++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java @@ -107,30 +107,49 @@ public class PhoneFactory { //reads the system properties and makes commandsinterface sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); - switch(networkMode) { - case RILConstants.NETWORK_MODE_CDMA: - case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: - case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: - case RILConstants.NETWORK_MODE_GLOBAL: - sProxyPhone = new PhoneProxy(new CDMAPhone(context, - sCommandsInterface, sPhoneNotifier)); - Log.i(LOG_TAG, "Creating CDMAPhone"); - break; - case RILConstants.NETWORK_MODE_WCDMA_PREF: - case RILConstants.NETWORK_MODE_GSM_ONLY: - case RILConstants.NETWORK_MODE_WCDMA_ONLY: - case RILConstants.NETWORK_MODE_GSM_UMTS: - default: - sProxyPhone = new PhoneProxy(new GSMPhone(context, - sCommandsInterface, sPhoneNotifier)); - Log.i(LOG_TAG, "Creating GSMPhone"); - break; + int phoneType = getPhoneType(networkMode); + if (phoneType == RILConstants.GSM_PHONE) { + sProxyPhone = new PhoneProxy(new GSMPhone(context, + sCommandsInterface, sPhoneNotifier)); + Log.i(LOG_TAG, "Creating GSMPhone"); + } else if (phoneType == RILConstants.CDMA_PHONE) { + sProxyPhone = new PhoneProxy(new CDMAPhone(context, + sCommandsInterface, sPhoneNotifier)); + Log.i(LOG_TAG, "Creating CDMAPhone"); } + sMadeDefaults = true; } } } + /* + * This function returns the type of the phone, depending + * on the network mode. + * + * @param network mode + * @return Phone Type + */ + public static int getPhoneType(int networkMode) { + switch(networkMode) { + case RILConstants.NETWORK_MODE_CDMA: + case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: + case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: + return RILConstants.CDMA_PHONE; + + case RILConstants.NETWORK_MODE_WCDMA_PREF: + case RILConstants.NETWORK_MODE_GSM_ONLY: + case RILConstants.NETWORK_MODE_WCDMA_ONLY: + case RILConstants.NETWORK_MODE_GSM_UMTS: + return RILConstants.GSM_PHONE; + + case RILConstants.NETWORK_MODE_GLOBAL: + return RILConstants.CDMA_PHONE; + default: + return RILConstants.GSM_PHONE; + } + } + public static Phone getDefaultPhone() { if (sLooper != Looper.myLooper()) { throw new RuntimeException( diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java index b76d801..a329cbb 100644 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java @@ -26,6 +26,7 @@ import android.os.Message; import android.preference.PreferenceManager; import android.telephony.CellLocation; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import android.util.Log; import com.android.internal.telephony.cdma.CDMAPhone; @@ -127,10 +128,9 @@ public class PhoneProxy extends Handler implements Phone { Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED); intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName()); ActivityManagerNative.broadcastStickyIntent(intent, null); - break; default: - Log.e(LOG_TAG, "Error! This handler was not registered for this message type. Message: " + Log.e(LOG_TAG,"Error! This handler was not registered for this message type. Message: " + msg.what); break; } @@ -198,8 +198,8 @@ public class PhoneProxy extends Handler implements Phone { return mActivePhone.getActiveApn(); } - public int getSignalStrengthASU() { - return mActivePhone.getSignalStrengthASU(); + public SignalStrength getSignalStrength() { + return mActivePhone.getSignalStrength(); } public void registerForUnknownConnection(Handler h, int what, Object obj) { @@ -306,6 +306,30 @@ public class PhoneProxy extends Handler implements Phone { mActivePhone.unregisterForInCallVoicePrivacyOff(h); } + public void registerCdmaInformationRecord(Handler h, int what, Object obj) { + mActivePhone.registerCdmaInformationRecord(h,what,obj); + } + + public void unregisterCdmaInformationRecord(Handler h) { + mActivePhone.unregisterCdmaInformationRecord(h); + } + + public void registerForOtaStatusChange(Handler h, int what, Object obj){ + mActivePhone.registerForOtaStatusChange(h,what,obj); + } + + public void unregisterForOtaStatusChange(Handler h){ + mActivePhone.unregisterForOtaStatusChange(h); + } + + public void registerForCdmaCallWaiting(Handler h, int what, Object obj){ + mActivePhone.registerForCdmaCallWaiting(h,what,obj); + } + + public void unregisterForCdmaCallWaiting(Handler h){ + mActivePhone.unregisterForCdmaCallWaiting(h); + } + public boolean getIccRecordsLoaded() { return mActivePhone.getIccRecordsLoaded(); } @@ -390,6 +414,10 @@ public class PhoneProxy extends Handler implements Phone { mActivePhone.stopDtmf(); } + public void sendBurstDtmf(String dtmfString) { + mActivePhone.sendBurstDtmf(dtmfString); + } + public void setRadioPower(boolean power) { mActivePhone.setRadioPower(power); } @@ -628,6 +656,10 @@ public class PhoneProxy extends Handler implements Phone { return mActivePhone.getIccSerialNumber(); } + public String getMin() { + return mActivePhone.getMin(); + } + public String getEsn() { return mActivePhone.getEsn(); } @@ -648,12 +680,16 @@ public class PhoneProxy extends Handler implements Phone { return mActivePhone.getIccPhoneBookInterfaceManager(); } - public void setTTYModeEnabled(boolean enable, Message onComplete) { - mActivePhone.setTTYModeEnabled(enable, onComplete); + public void setTTYMode(int ttyMode, Message onComplete) { + mActivePhone.setTTYMode(ttyMode, onComplete); + } + + public void queryTTYMode(Message onComplete) { + mActivePhone.queryTTYMode(onComplete); } - public void queryTTYModeEnabled(Message onComplete) { - mActivePhone.queryTTYModeEnabled(onComplete); + public void exitEmergencyCallbackMode(Message onComplete) { + mActivePhone.exitEmergencyCallbackMode(onComplete); } public void activateCellBroadcastSms(int activate, Message response) { @@ -679,5 +715,17 @@ public class PhoneProxy extends Handler implements Phone { public void setSmscAddress(String address, Message result) { mActivePhone.setSmscAddress(address, result); } + + public int getCdmaEriIconIndex() { + return mActivePhone.getCdmaEriIconIndex(); + } + + public int getCdmaEriIconMode() { + return mActivePhone.getCdmaEriIconMode(); + } + + public String getCdmaEriText() { + return mActivePhone.getCdmaEriText(); + } } diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java index fd822cd..b31161c 100644 --- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java +++ b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java @@ -23,6 +23,7 @@ import android.content.IntentFilter; import android.os.Handler; import android.os.Message; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.util.Log; @@ -39,8 +40,6 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver { private static final String LOG_TAG = "PHONE"; private static final boolean DBG = false; - public static final String INTENT_KEY_ASU = "asu"; - private static final int NOTIF_PHONE = 1 << 0; private static final int NOTIF_SERVICE = 1 << 1; private static final int NOTIF_SIGNAL = 1 << 2; @@ -49,7 +48,8 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver { Phone.State mPhoneState = Phone.State.IDLE; ServiceState mServiceState = new ServiceState(); - int mAsu = -1; + SignalStrength mSignalStrength = new SignalStrength(); + private Context mContext; private Handler mTarget; private IntentFilter mFilter; @@ -106,12 +106,14 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver { * Throws RuntimeException if client has not called notifySignalStrength() */ public int getSignalStrength() { + // TODO: use new SignalStrength instead of asu if ((mWants & NOTIF_SIGNAL) == 0) { throw new RuntimeException ("client must call notifySignalStrength(int)"); } + int gsmSignalStrength = mSignalStrength.getGsmSignalStrength(); - return mAsu; + return (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); } /** @@ -129,10 +131,15 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver { int dBm = -1; - if (mAsu != -1) { - dBm = -113 + 2*mAsu; + if(!mSignalStrength.isGsm()) { + dBm = mSignalStrength.getCdmaDbm(); + } else { + int gsmSignalStrength = mSignalStrength.getGsmSignalStrength(); + int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); + if (asu != -1) { + dBm = -113 + 2*asu; + } } - return dBm; } @@ -180,8 +187,7 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver { try { if (TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED.equals(action)) { - mAsu = intent.getIntExtra(INTENT_KEY_ASU, mAsu); - if (DBG) Log.d(LOG_TAG, "onReceiveIntent: set asu=" + mAsu); + mSignalStrength = SignalStrength.newFromBundle(intent.getExtras()); if (mTarget != null && getNotifySignalStrength()) { Message message = Message.obtain(mTarget, mAsuEventWhat); diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index be18a39..070d233 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -38,8 +38,10 @@ import android.telephony.SmsMessage; import android.util.Config; import android.util.Log; +import com.android.internal.telephony.CdmaInformationRecord; +import com.android.internal.telephony.cdma.CdmaCallWaiting; +import com.android.internal.telephony.DataCallState; import com.android.internal.telephony.gsm.NetworkInfo; -import com.android.internal.telephony.gsm.PDPContextState; import com.android.internal.telephony.gsm.SuppServiceNotification; import java.io.ByteArrayInputStream; @@ -233,6 +235,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31; BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { sendScreenState(true); @@ -562,18 +565,22 @@ public final class RIL extends BaseCommands implements CommandsInterface { mNetworkMode = networkMode; //At startup mPhoneType is first set from networkMode switch(networkMode) { + case RILConstants.NETWORK_MODE_WCDMA_PREF: + case RILConstants.NETWORK_MODE_GSM_ONLY: + case RILConstants.NETWORK_MODE_WCDMA_ONLY: + case RILConstants.NETWORK_MODE_GSM_UMTS: + mPhoneType = RILConstants.GSM_PHONE; + break; case RILConstants.NETWORK_MODE_CDMA: case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: + mPhoneType = RILConstants.CDMA_PHONE; + break; case RILConstants.NETWORK_MODE_GLOBAL: mPhoneType = RILConstants.CDMA_PHONE; break; - case RILConstants.NETWORK_MODE_WCDMA_PREF: - case RILConstants.NETWORK_MODE_GSM_ONLY: - case RILConstants.NETWORK_MODE_WCDMA_ONLY: - case RILConstants.NETWORK_MODE_GSM_UMTS: default: - mPhoneType = RILConstants.GSM_PHONE; + mPhoneType = RILConstants.CDMA_PHONE; } PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); @@ -1052,6 +1059,16 @@ public final class RIL extends BaseCommands implements CommandsInterface { send(rr); } + public void + sendBurstDtmf(String dtmfString, Message result) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BURST_DTMF, result); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeString(dtmfString); + + send(rr); + } public void sendSMS (String smscPDU, String pdu, Message result) { @@ -1361,6 +1378,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest) + " 0x" + Integer.toHexString(command) + " 0x" + Integer.toHexString(fileid) + " " + + " path: " + path + "," + p1 + "," + p2 + "," + p3); send(rr); @@ -1793,7 +1811,8 @@ public final class RIL extends BaseCommands implements CommandsInterface { rr.mp.writeInt(1); rr.mp.writeInt(on ? 1 : 0); - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + ": " + on); + if (RILJ_LOGD) riljLog(rr.serialString() + + "> " + requestToString(rr.mRequest) + ": " + on); send(rr); } @@ -1838,7 +1857,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { * and/or radio knowing. */ if (RILJ_LOGD) Log.d(LOG_TAG, "Radio ON @ init; reset to OFF"); - setRadioPower(false, null); + setRadioPower(false, null); } else { if (DBG) Log.d(LOG_TAG, "Radio OFF @ init"); setRadioState(newState); @@ -2055,6 +2074,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break; case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break; case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break; + case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; default: throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest); //break; @@ -2176,13 +2196,18 @@ public final class RIL extends BaseCommands implements CommandsInterface { case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break; case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break; case RIL_UNSOL_SIM_REFRESH: ret = responseInts(p); break; - case RIL_UNSOL_CALL_RING: ret = responseVoid(p); break; + case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break; case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break; case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break; case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseString(p); break; case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break; + case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; + case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break; + case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break; + case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break; case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break; + default: throw new RuntimeException("Unrecognized unsol response: " + response); //break; (implied) @@ -2415,6 +2440,39 @@ public final class RIL extends BaseCommands implements CommandsInterface { mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null)); } break; + + case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: + if (RILJ_LOGD) unsljLog(response); + + if (mEmergencyCallbackModeRegistrant != null) { + mEmergencyCallbackModeRegistrant.notifyRegistrant(); + } + break; + + case RIL_UNSOL_CDMA_CALL_WAITING: + if (RILJ_LOGD) unsljLog(response); + + if(mCallWaitingRegistrants != null) { + mCallWaitingRegistrants.notifyRegistrants(new AsyncResult (null, ret, null)); + } + break; + + case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: + if (RILJ_LOGD) unsljLog(response); + + if (mOtaSessionRegistrants != null) { + mOtaSessionRegistrants.notifyRegistrants(new AsyncResult(null, ret, null)); + } + break; + + case RIL_UNSOL_CDMA_INFO_REC: + if (RILJ_LOGD) + unsljLog(response); + if (mInformationRecordsRegistrants != null) { + mInformationRecordsRegistrants.notifyRegistrants(new AsyncResult(null, ret, + null)); + } + break; } } @@ -2547,6 +2605,11 @@ public final class RIL extends BaseCommands implements CommandsInterface { String s = p.readString(); + if (RILJ_LOGD) riljLog("< iccIO: " + + " 0x" + Integer.toHexString(sw1) + + " 0x" + Integer.toHexString(sw2) + " " + + s); + return new IccIoResult(sw1, sw2, s); } @@ -2677,14 +2740,14 @@ public final class RIL extends BaseCommands implements CommandsInterface { response.add(dc); - if ( RILConstants.CDMA_VOICE_PRIVACY == voiceSettings ) { + if ( RILConstants.CDMA_VOICE_PRIVACY == voicePrivacy ) { mVoicePrivacyOnRegistrants.notifyRegistrants(); Log.d(LOG_TAG, "InCall VoicePrivacy is enabled: " + - Integer.toString(voiceSettings)); + Integer.toString(voicePrivacy)); } else { mVoicePrivacyOffRegistrants.notifyRegistrants(); Log.d(LOG_TAG, "InCall VoicePrivacy is disabled: " + - Integer.toString(voiceSettings)); + Integer.toString(voicePrivacy)); } } @@ -2696,21 +2759,21 @@ public final class RIL extends BaseCommands implements CommandsInterface { private Object responseDataCallList(Parcel p) { int num; - ArrayList<PDPContextState> response; + ArrayList<DataCallState> response; num = p.readInt(); - response = new ArrayList<PDPContextState>(num); + response = new ArrayList<DataCallState>(num); for (int i = 0; i < num; i++) { - PDPContextState pdp = new PDPContextState(); + DataCallState dataCall = new DataCallState(); - pdp.cid = p.readInt(); - pdp.active = p.readInt(); - pdp.type = p.readString(); - pdp.apn = p.readString(); - pdp.address = p.readString(); + dataCall.cid = p.readInt(); + dataCall.active = p.readInt(); + dataCall.type = p.readString(); + dataCall.apn = p.readString(); + dataCall.address = p.readString(); - response.add(pdp); + response.add(dataCall); } return response; @@ -2771,42 +2834,135 @@ public final class RIL extends BaseCommands implements CommandsInterface { private Object responseCDMA_BR_CNF(Parcel p) { - int numServiceCategories; + int numInts; int response[]; - numServiceCategories = p.readInt(); - - if (numServiceCategories == 0) { - int numInts; - numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1; - response = new int[numInts]; - - // indicate that a zero length table was received - response[0] = 0; - //for all supported service categories set 'english' as default language - //and selection status to false - for (int i = 1, j = 1 - ; i <= (CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES - * CDMA_BSI_NO_OF_INTS_STRUCT) - ; i += CDMA_BSI_NO_OF_INTS_STRUCT, j++ ) { - response[i] = j; - response[i+1] = 1; - response[i+2] = 0; + numInts = p.readInt(); + + response = new int[numInts]; + + response[0] = numInts; + for (int i = 1 ; i < numInts; i++) { + response[i] = p.readInt(); + } + + return response; + } + + private Object + responseCdmaInformationRecord(Parcel p){ + + int num; + ArrayList<CdmaInformationRecord> response; + + num = p.readInt(); + + response = new ArrayList<CdmaInformationRecord>(num); + + for (int i = 0; i < num; i++) { + int name = p.readInt(); + CdmaInformationRecord InfoRec = new CdmaInformationRecord(name); + + char buffer[]; + int length; + switch (name) { + case CdmaInformationRecord.RIL_CDMA_DISPLAY_INFO_REC: + case CdmaInformationRecord.RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: + length = p.readInt(); + buffer = new char[length]; + for (int j = 0; j < length; j++) { + buffer[j] = (char)p.readInt(); + } + InfoRec.createDisplayInfo(length, buffer); + break; + + case CdmaInformationRecord.RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: + case CdmaInformationRecord.RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: + case CdmaInformationRecord.RIL_CDMA_CONNECTED_NUMBER_INFO_REC: + length = p.readInt(); + buffer = new char[length + 4]; + for (int j = 0; j < (length + 4); j++) { + buffer[j] = (char)p.readInt(); + } + InfoRec.createNumberInfo(length, buffer); + break; + + case CdmaInformationRecord.RIL_CDMA_SIGNAL_INFO_REC: + buffer = new char[4]; + for (int j = 0; j < 4; j++) { + buffer[j] = (char)p.readInt(); + } + InfoRec.createSignalInfo(buffer); + break; + + case CdmaInformationRecord.RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: + length = p.readInt(); + buffer = new char[length + 4]; + int reason; + for (int j = 0; j < (length + 4); j++) { + buffer[j] = (char)p.readInt(); + } + reason = p.readInt(); + InfoRec.createRedirectingNumberInfo(length, buffer, reason); + break; + + case CdmaInformationRecord.RIL_CDMA_LINE_CONTROL_INFO_REC: + buffer = new char[4]; + for (int j = 0; j < 4; j++) { + buffer[j] = (char)p.readInt(); + } + InfoRec.createLineControlInfo(buffer); + break; + + case CdmaInformationRecord.RIL_CDMA_T53_CLIR_INFO_REC: + char ch = (char)p.readInt(); + InfoRec.createT53ClirInfo(ch); + break; + + case CdmaInformationRecord.RIL_CDMA_T53_RELEASE_INFO_REC: + break; + + case CdmaInformationRecord.RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: + char ul = (char)p.readInt(); + char dl = (char)p.readInt(); + InfoRec.createT53AudioControlInfo(ul, dl); + break; + + default: + break; } - } else { - int numInts; - numInts = numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT + 1; - response = new int[numInts]; - - response[0] = numServiceCategories; - for (int i = 1 ; i < numInts; i++) { - response[i] = p.readInt(); - } + response.add(InfoRec); } return response; } + private Object + responseCdmaCallWaiting(Parcel p){ + CdmaCallWaiting response = new CdmaCallWaiting(); + response.number = p.readString(); + response.numberPresentation = p.readInt(); + response.name = p.readString(); + response.signalInfoRecord.isPresent = p.readInt() == 0 ? false : true; + response.signalInfoRecord.signalType = p.readInt(); + response.signalInfoRecord.alertPitch = p.readInt(); + response.signalInfoRecord.signalCode = p.readInt(); + + return response; + } + + private Object + responseCallRing(Parcel p){ + char response[] = new char[4]; + + response[0] = (char) p.readInt(); // isPresent + response[1] = (char) p.readInt(); // signalType + response[2] = (char) p.readInt(); // alertPitch + response[3] = (char) p.readInt(); // signal + + return response; + } + static String requestToString(int request) { /* @@ -2915,6 +3071,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY"; case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS"; case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS"; + case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE"; default: return "<unknown request>"; } } @@ -2949,6 +3106,14 @@ public final class RIL extends BaseCommands implements CommandsInterface { case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING"; case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "RIL_UNSOL_RESTRICTED_STATE_CHANGED"; case RIL_UNSOL_OEM_HOOK_RAW: return "RIL_UNSOL_OEM_HOOK_RAW"; + case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED"; + case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS"; + case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS"; + case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL"; + case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE"; + case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING"; + case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS"; + case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC"; default: return "<unknown reponse>"; } } @@ -3048,7 +3213,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { /** * {@inheritDoc} */ - public void queryTTYModeEnabled(Message response) { + public void queryTTYMode(Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response); @@ -3058,12 +3223,12 @@ public final class RIL extends BaseCommands implements CommandsInterface { /** * {@inheritDoc} */ - public void setTTYModeEnabled(boolean enable, Message response) { + public void setTTYMode(int ttyMode, Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_SET_TTY_MODE, response); rr.mp.writeInt(1); - rr.mp.writeInt(enable ? 1 : 0); + rr.mp.writeInt(ttyMode); send(rr); } @@ -3090,11 +3255,14 @@ public final class RIL extends BaseCommands implements CommandsInterface { send(rr); } + /** + * TODO(Teleca): configValuesArray is represented as a RIL_BroadcastSMSConfig + * so we think this should be a class with the appropriate parameters not an array? + */ public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response); - rr.mp.writeInt(configValuesArray[0]); - for(int i = 1; i <= (configValuesArray[0] * 3); i++) { + for(int i = 0; i < configValuesArray.length; i++) { rr.mp.writeInt(configValuesArray[i]); } @@ -3113,4 +3281,16 @@ public final class RIL extends BaseCommands implements CommandsInterface { send(rr); } + + /** + * {@inheritDoc} + */ + public void exitEmergencyCallbackMode(Message response) { + RILRequest rr + = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + send(rr); + } } diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index bcf5141..44c863b 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -16,6 +16,13 @@ package com.android.internal.telephony; +/** + * TODO: This should probably not be an interface see + * http://www.javaworld.com/javaworld/javaqa/2001-06/01-qa-0608-constants.html and google with + * http://www.google.com/search?q=interface+constants&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a + * + * Also they should all probably be static final. + */ /** * {@hide} @@ -51,7 +58,7 @@ public interface RILConstants { int NETWORK_MODE_EVDO_NO_CDMA = 6; /* EvDo only */ int NETWORK_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) AVAILABLE Application Settings menu*/ - int PREFERRED_NETWORK_MODE = NETWORK_MODE_GSM_ONLY; + int PREFERRED_NETWORK_MODE = NETWORK_MODE_WCDMA_PREF; /* CDMA subscription source. See ril.h RIL_REQUEST_CDMA_SET_SUBSCRIPTION */ int SUBSCRIPTION_FROM_RUIM = 0; /* CDMA subscription from RUIM when available */ @@ -67,6 +74,10 @@ public interface RILConstants { int CDM_TTY_MODE_DISABLED = 0; int CDM_TTY_MODE_ENABLED = 1; + int CDM_TTY_FULL_MODE = 1; + int CDM_TTY_HCO_MODE = 2; + int CDM_TTY_VCO_MODE = 3; + byte CDMA_VOICE_PRIVACY = 0x70; /* "p" value used in Ril_Call.isVoice if Privacy is active */ @@ -208,6 +219,7 @@ cat include/telephony/ril.h | \ int RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM = 96; int RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM = 97; int RIL_REQUEST_DEVICE_IDENTITY = 98; + int RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE = 99; int RIL_REQUEST_GET_SMSC_ADDRESS = 100; int RIL_REQUEST_SET_SMSC_ADDRESS = 101; int RIL_UNSOL_RESPONSE_BASE = 1000; diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index f2bd361..d055c31 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -122,7 +122,7 @@ public abstract class SMSDispatcher extends Handler { * CONCATENATED_16_BIT_REFERENCE message set. Should be * incremented for each set of concatenated messages. */ - protected static int sConcatenatedRef; + private static int sConcatenatedRef; private SmsCounter mCounter; @@ -132,6 +132,11 @@ public abstract class SMSDispatcher extends Handler { private static SmsMessageBase mSmsMessageBase; private SmsMessageBase.SubmitPduBase mSubmitPduBase; + protected static int getNextConcatenatedRef() { + sConcatenatedRef += 1; + return sConcatenatedRef; + } + /** * Implement the per-application based SMS control, which only allows * a limit on the number of SMS/MMS messages an app can send in checking @@ -419,12 +424,15 @@ public abstract class SMSDispatcher extends Handler { /** * If this is the last part send the parts out to the application, otherwise * the part is stored for later processing. + * + * NOTE: concatRef (naturally) needs to be non-null, but portAddrs can be null. */ - protected void processMessagePart(SmsMessageBase sms, int referenceNumber, - int sequence, int count, int destinationPort) { + protected void processMessagePart(SmsMessageBase sms, + SmsHeader.ConcatRef concatRef, SmsHeader.PortAddrs portAddrs) { + // Lookup all other related parts StringBuilder where = new StringBuilder("reference_number ="); - where.append(referenceNumber); + where.append(concatRef.refNumber); where.append(" AND address = ?"); String[] whereArgs = new String[] {sms.getOriginatingAddress()}; @@ -433,20 +441,19 @@ public abstract class SMSDispatcher extends Handler { try { cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null); int cursorCount = cursor.getCount(); - if (cursorCount != count - 1) { + if (cursorCount != concatRef.msgCount - 1) { // We don't have all the parts yet, store this one away ContentValues values = new ContentValues(); values.put("date", new Long(sms.getTimestampMillis())); values.put("pdu", HexDump.toHexString(sms.getPdu())); values.put("address", sms.getOriginatingAddress()); - values.put("reference_number", referenceNumber); - values.put("count", count); - values.put("sequence", sequence); - if (destinationPort != -1) { - values.put("destination_port", destinationPort); + values.put("reference_number", concatRef.refNumber); + values.put("count", concatRef.msgCount); + values.put("sequence", concatRef.seqNumber); + if (portAddrs != null) { + values.put("destination_port", portAddrs.destPort); } mResolver.insert(mRawUri, values); - return; } @@ -454,7 +461,7 @@ public abstract class SMSDispatcher extends Handler { int pduColumn = cursor.getColumnIndex("pdu"); int sequenceColumn = cursor.getColumnIndex("sequence"); - pdus = new byte[count][]; + pdus = new byte[concatRef.msgCount][]; for (int i = 0; i < cursorCount; i++) { cursor.moveToNext(); int cursorSequence = (int)cursor.getLong(sequenceColumn); @@ -462,7 +469,7 @@ public abstract class SMSDispatcher extends Handler { cursor.getString(pduColumn)); } // This one isn't in the DB, so add it - pdus[sequence - 1] = sms.getPdu(); + pdus[concatRef.seqNumber - 1] = sms.getPdu(); // Remove the parts from the database mResolver.delete(mRawUri, where.toString(), whereArgs); @@ -473,31 +480,34 @@ public abstract class SMSDispatcher extends Handler { if (cursor != null) cursor.close(); } + /** + * TODO(cleanup): The following code has duplicated logic with + * the radio-specific dispatchMessage code, which is fragile, + * in addition to being redundant. Instead, if this method + * maybe returned the reassembled message (or just contents), + * the following code (which is not really related to + * reconstruction) could be better consolidated. + */ + // Dispatch the PDUs to applications - switch (destinationPort) { - case SmsHeader.PORT_WAP_PUSH: { - // Build up the data stream - ByteArrayOutputStream output = new ByteArrayOutputStream(); - for (int i = 0; i < count; i++) { - SmsMessage msg = SmsMessage.createFromPdu(pdus[i]); - byte[] data = msg.getUserData(); - output.write(data, 0, data.length); + if (portAddrs != null) { + if (portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) { + // Build up the data stream + ByteArrayOutputStream output = new ByteArrayOutputStream(); + for (int i = 0; i < concatRef.msgCount; i++) { + SmsMessage msg = SmsMessage.createFromPdu(pdus[i]); + byte[] data = msg.getUserData(); + output.write(data, 0, data.length); + } + // Handle the PUSH + mWapPush.dispatchWapPdu(output.toByteArray()); + } else { + // The messages were sent to a port, so concoct a URI for it + dispatchPortAddressedPdus(pdus, portAddrs.destPort); } - - // Handle the PUSH - mWapPush.dispatchWapPdu(output.toByteArray()); - break; - } - - case -1: + } else { // The messages were not sent to a port dispatchPdus(pdus); - break; - - default: - // The messages were sent to a port, so concoct a URI for it - dispatchPortAddressedPdus(pdus, destinationPort); - break; } } diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java index 7274e99..5112ba0 100644 --- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java @@ -22,6 +22,7 @@ import android.os.Message; import android.os.Registrant; import android.os.RegistrantList; import android.telephony.ServiceState; +import android.telephony.SignalStrength; /** * {@hide} @@ -50,6 +51,8 @@ public abstract class ServiceStateTracker extends Handler { public ServiceState ss; protected ServiceState newSS; + public SignalStrength mSignalStrength; + // Used as a unique identifier to track requests associated with a poll // and ignore stale responses.The value is a count-down of expected responses // in this pollingContext @@ -104,13 +107,15 @@ public abstract class ServiceStateTracker extends Handler { protected static final int EVENT_POLL_STATE_OPERATOR_CDMA = 25; protected static final int EVENT_RUIM_READY = 26; protected static final int EVENT_RUIM_RECORDS_LOADED = 27; - protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA = 28; - protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA = 29; - protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA = 30; - protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA = 31; - protected static final int EVENT_GET_LOC_DONE_CDMA = 32; - protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA = 33; - protected static final int EVENT_NV_LOADED = 34; + protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA = 28; + protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA = 29; + protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA = 30; + protected static final int EVENT_GET_LOC_DONE_CDMA = 31; + protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA = 32; + protected static final int EVENT_NV_LOADED = 33; + protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION = 34; + protected static final int EVENT_NV_READY = 35; + protected static final int EVENT_ERI_FILE_LOADED = 36; //***** Time Zones protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; @@ -142,6 +147,9 @@ public abstract class ServiceStateTracker extends Handler { "uk", // U.K }; + //***** Registration denied reason + protected static final String REGISTRATION_DENIED_GEN = "General"; + protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure"; //***** Constructors public ServiceStateTracker() { diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java index 64b884e..d220648 100644 --- a/telephony/java/com/android/internal/telephony/SmsHeader.java +++ b/telephony/java/com/android/internal/telephony/SmsHeader.java @@ -16,227 +16,233 @@ package com.android.internal.telephony; +import android.telephony.SmsMessage; + import com.android.internal.util.HexDump; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + import java.util.ArrayList; /** - * This class represents a SMS user data header. - * + * SMS user data header, as specified in TS 23.040 9.2.3.24. */ public class SmsHeader { - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int CONCATENATED_8_BIT_REFERENCE = 0x00; - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int SPECIAL_SMS_MESSAGE_INDICATION = 0x01; - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int APPLICATION_PORT_ADDRESSING_8_BIT = 0x04; - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int APPLICATION_PORT_ADDRESSING_16_BIT= 0x05; - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int CONCATENATED_16_BIT_REFERENCE = 0x08; - public static final int PORT_WAP_PUSH = 2948; - public static final int PORT_WAP_WSP = 9200; - - private byte[] m_data; - private ArrayList<Element> m_elements = new ArrayList<Element>(); - public int nbrOfHeaders; + // TODO(cleanup): this datastructure is generally referred to as + // the 'user data header' or UDH, and so the class name should + // change to reflect this... - /** - * Creates an SmsHeader object from raw user data header bytes. - * - * @param data is user data header bytes - * @return an SmsHeader object + /** SMS user data header information element identifiers. + * (see TS 23.040 9.2.3.24) */ - public static SmsHeader parse(byte[] data) { - SmsHeader header = new SmsHeader(); - header.m_data = data; - - int index = 0; - header.nbrOfHeaders = 0; - while (index < data.length) { - int id = data[index++] & 0xff; - int length = data[index++] & 0xff; - byte[] elementData = new byte[length]; - System.arraycopy(data, index, elementData, 0, length); - header.add(new Element(id, elementData)); - index += length; - header.nbrOfHeaders++; - } + public static final int ELT_ID_CONCATENATED_8_BIT_REFERENCE = 0x00; + public static final int ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION = 0x01; + public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT = 0x04; + public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT = 0x05; + public static final int ELT_ID_SMSC_CONTROL_PARAMS = 0x06; + public static final int ELT_ID_UDH_SOURCE_INDICATION = 0x07; + public static final int ELT_ID_CONCATENATED_16_BIT_REFERENCE = 0x08; + public static final int ELT_ID_WIRELESS_CTRL_MSG_PROTOCOL = 0x09; + public static final int ELT_ID_TEXT_FORMATTING = 0x0A; + public static final int ELT_ID_PREDEFINED_SOUND = 0x0B; + public static final int ELT_ID_USER_DEFINED_SOUND = 0x0C; + public static final int ELT_ID_PREDEFINED_ANIMATION = 0x0D; + public static final int ELT_ID_LARGE_ANIMATION = 0x0E; + public static final int ELT_ID_SMALL_ANIMATION = 0x0F; + public static final int ELT_ID_LARGE_PICTURE = 0x10; + public static final int ELT_ID_SMALL_PICTURE = 0x11; + public static final int ELT_ID_VARIABLE_PICTURE = 0x12; + public static final int ELT_ID_USER_PROMPT_INDICATOR = 0x13; + public static final int ELT_ID_EXTENDED_OBJECT = 0x14; + public static final int ELT_ID_REUSED_EXTENDED_OBJECT = 0x15; + public static final int ELT_ID_COMPRESSION_CONTROL = 0x16; + public static final int ELT_ID_OBJECT_DISTR_INDICATOR = 0x17; + public static final int ELT_ID_STANDARD_WVG_OBJECT = 0x18; + public static final int ELT_ID_CHARACTER_SIZE_WVG_OBJECT = 0x19; + public static final int ELT_ID_EXTENDED_OBJECT_DATA_REQUEST_CMD = 0x1A; + public static final int ELT_ID_RFC_822_EMAIL_HEADER = 0x20; + public static final int ELT_ID_HYPERLINK_FORMAT_ELEMENT = 0x21; + public static final int ELT_ID_REPLY_ADDRESS_ELEMENT = 0x22; + public static final int ELT_ID_ENHANCED_VOICE_MAIL_INFORMATION = 0x23; - return header; - } + public static final int PORT_WAP_PUSH = 2948; + public static final int PORT_WAP_WSP = 9200; - public SmsHeader() { } + public static class PortAddrs { + public int destPort; + public int origPort; + public boolean areEightBits; + } - /** - * Returns the list of SmsHeader Elements that make up the header. - * - * @return the list of SmsHeader Elements. - */ - public ArrayList<Element> getElements() { - return m_elements; + public static class ConcatRef { + public int refNumber; + public int seqNumber; + public int msgCount; + public boolean isEightBits; } /** - * Add an element to the SmsHeader. - * - * @param element to add. + * A header element that is not explicitly parsed, meaning not + * PortAddrs or ConcatRef. */ - public void add(Element element) { - m_elements.add(element); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - - builder.append("UDH LENGTH: " + m_data.length + " octets"); - builder.append("UDH: "); - builder.append(HexDump.toHexString(m_data)); - builder.append("\n"); - - for (Element e : getElements()) { - builder.append(" 0x" + HexDump.toHexString((byte)e.getID()) + " - "); - switch (e.getID()) { - case CONCATENATED_8_BIT_REFERENCE: { - builder.append("Concatenated Short Message 8bit ref\n"); - byte[] data = e.getData(); - builder.append(" " + data.length + " (0x"); - builder.append(HexDump.toHexString((byte)data.length) - + ") Bytes - Information Element\n"); - builder.append(" " + data[0] + " : SM reference number\n"); - builder.append(" " + data[1] + " : number of messages\n"); - builder.append(" " + data[2] + " : this SM sequence number\n"); - break; - } - - case CONCATENATED_16_BIT_REFERENCE: { - builder.append("Concatenated Short Message 16bit ref\n"); - byte[] data = e.getData(); - builder.append(" " + data.length + " (0x"); - builder.append(HexDump.toHexString((byte)data.length) - + ") Bytes - Information Element\n"); - builder.append(" " + (data[0] & 0xff) * 256 + (data[1] & 0xff) - + " : SM reference number\n"); - builder.append(" " + data[2] + " : number of messages\n"); - builder.append(" " + data[3] + " : this SM sequence number\n"); - break; - } - - case APPLICATION_PORT_ADDRESSING_8_BIT: - { - builder.append("Application port addressing 8bit\n"); - byte[] data = e.getData(); - - builder.append(" " + data.length + " (0x"); - builder.append(HexDump.toHexString( - (byte)data.length) + ") Bytes - Information Element\n"); - - int source = (data[0] & 0xff); - builder.append(" " + source + " : DESTINATION port\n"); - - int dest = (data[1] & 0xff); - builder.append(" " + dest + " : SOURCE port\n"); - break; - } - - case APPLICATION_PORT_ADDRESSING_16_BIT: { - builder.append("Application port addressing 16bit\n"); - byte[] data = e.getData(); - - builder.append(" " + data.length + " (0x"); - builder.append(HexDump.toHexString((byte)data.length) - + ") Bytes - Information Element\n"); - - int source = (data[0] & 0xff) << 8; - source |= (data[1] & 0xff); - builder.append(" " + source + " : DESTINATION port\n"); - - int dest = (data[2] & 0xff) << 8; - dest |= (data[3] & 0xff); - builder.append(" " + dest + " : SOURCE port\n"); - break; - } - - default: { - builder.append("Unknown element\n"); - break; - } - } - } - - return builder.toString(); + public static class MiscElt { + public int id; + public byte[] data; } - private int calcSize() { - int size = 1; // +1 for the UDHL field - for (Element e : m_elements) { - size += e.getData().length; - size += 2; // 1 byte ID, 1 byte length - } + public PortAddrs portAddrs; + public ConcatRef concatRef; + public ArrayList<MiscElt> miscEltList = new ArrayList<MiscElt>(); - return size; - } + public SmsHeader() {} /** - * Converts SmsHeader object to a byte array as specified in TS 23.040 9.2.3.24. - * @return Byte array representing the SmsHeader + * Create structured SmsHeader object from serialized byte array representation. + * (see TS 23.040 9.2.3.24) + * @param data is user data header bytes + * @return SmsHeader object */ - public byte[] toByteArray() { - if (m_elements.size() == 0) return null; - - if (m_data == null) { - int size = calcSize(); - int cur = 1; - m_data = new byte[size]; - - m_data[0] = (byte) (size-1); // UDHL does not include itself - - for (Element e : m_elements) { - int length = e.getData().length; - m_data[cur++] = (byte) e.getID(); - m_data[cur++] = (byte) length; - System.arraycopy(e.getData(), 0, m_data, cur, length); - cur += length; + public static SmsHeader fromByteArray(byte[] data) { + ByteArrayInputStream inStream = new ByteArrayInputStream(data); + SmsHeader smsHeader = new SmsHeader(); + while (inStream.available() > 0) { + /** + * NOTE: as defined in the spec, ConcatRef and PortAddr + * fields should not reoccur, but if they do the last + * occurrence is to be used. + */ + int id = inStream.read(); + int length = inStream.read(); + ConcatRef concatRef; + PortAddrs portAddrs; + switch (id) { + case ELT_ID_CONCATENATED_8_BIT_REFERENCE: + concatRef = new ConcatRef(); + concatRef.refNumber = inStream.read(); + concatRef.msgCount = inStream.read(); + concatRef.seqNumber = inStream.read(); + concatRef.isEightBits = true; + smsHeader.concatRef = concatRef; + break; + case ELT_ID_CONCATENATED_16_BIT_REFERENCE: + concatRef = new ConcatRef(); + concatRef.refNumber = (inStream.read() << 8) | inStream.read(); + concatRef.msgCount = inStream.read(); + concatRef.seqNumber = inStream.read(); + concatRef.isEightBits = false; + smsHeader.concatRef = concatRef; + break; + case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT: + portAddrs = new PortAddrs(); + portAddrs.destPort = inStream.read(); + portAddrs.origPort = inStream.read(); + portAddrs.areEightBits = true; + smsHeader.portAddrs = portAddrs; + break; + case ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT: + portAddrs = new PortAddrs(); + portAddrs.destPort = (inStream.read() << 8) | inStream.read(); + portAddrs.origPort = (inStream.read() << 8) | inStream.read(); + portAddrs.areEightBits = false; + smsHeader.portAddrs = portAddrs; + break; + default: + MiscElt miscElt = new MiscElt(); + miscElt.id = id; + miscElt.data = new byte[length]; + inStream.read(miscElt.data, 0, length); + smsHeader.miscEltList.add(miscElt); } } - - return m_data; + return smsHeader; } /** - * A single Element in the SMS User Data Header. - * - * See TS 23.040 9.2.3.24. - * + * Create serialized byte array representation from structured SmsHeader object. + * (see TS 23.040 9.2.3.24) + * @return Byte array representing the SmsHeader */ - public static class Element { - private byte[] m_data; - private int m_id; - - public Element(int id, byte[] data) { - m_id = id; - m_data = data; + public static byte[] toByteArray(SmsHeader smsHeader) { + if ((smsHeader.portAddrs == null) && + (smsHeader.concatRef == null) && + (smsHeader.miscEltList.size() == 0)) { + return null; } - /** - * Returns the Information Element Identifier for this element. - * - * @return the IE identifier. - */ - public int getID() { - return m_id; + ByteArrayOutputStream outStream = new ByteArrayOutputStream(SmsMessage.MAX_USER_DATA_BYTES); + ConcatRef concatRef = smsHeader.concatRef; + if (concatRef != null) { + if (concatRef.isEightBits) { + outStream.write(ELT_ID_CONCATENATED_8_BIT_REFERENCE); + outStream.write(3); + outStream.write(concatRef.refNumber); + } else { + outStream.write(ELT_ID_CONCATENATED_16_BIT_REFERENCE); + outStream.write(4); + outStream.write(concatRef.refNumber >>> 8); + outStream.write(concatRef.refNumber & 0x00FF); + } + outStream.write(concatRef.msgCount); + outStream.write(concatRef.seqNumber); } + PortAddrs portAddrs = smsHeader.portAddrs; + if (portAddrs != null) { + if (portAddrs.areEightBits) { + outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT); + outStream.write(2); + outStream.write(portAddrs.destPort); + outStream.write(portAddrs.origPort); + } else { + outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT); + outStream.write(4); + outStream.write(portAddrs.destPort >>> 8); + outStream.write(portAddrs.destPort & 0x00FF); + outStream.write(portAddrs.origPort >>> 8); + outStream.write(portAddrs.origPort & 0x00FF); + } + } + for (MiscElt miscElt : smsHeader.miscEltList) { + outStream.write(miscElt.id); + outStream.write(miscElt.data.length); + outStream.write(miscElt.data, 0, miscElt.data.length); + } + return outStream.toByteArray(); + } - /** - * Returns the data portion of this element. - * - * @return element data. - */ - public byte[] getData() { - return m_data; + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("UserDataHeader "); + builder.append("{ ConcatRef "); + if (concatRef == null) { + builder.append("unset"); + } else { + builder.append("{ refNumber=" + concatRef.refNumber); + builder.append(", msgCount=" + concatRef.msgCount); + builder.append(", seqNumber=" + concatRef.seqNumber); + builder.append(", isEightBits=" + concatRef.isEightBits); + builder.append(" }"); + } + builder.append(", PortAddrs "); + if (portAddrs == null) { + builder.append("unset"); + } else { + builder.append("{ destPort=" + portAddrs.destPort); + builder.append(", origPort=" + portAddrs.origPort); + builder.append(", areEightBits=" + portAddrs.areEightBits); + builder.append(" }"); + } + for (MiscElt miscElt : miscEltList) { + builder.append(", MiscElt "); + builder.append("{ id=" + miscElt.id); + builder.append(", length=" + miscElt.data.length); + builder.append(", data=" + HexDump.toHexString(miscElt.data)); + builder.append(" }"); } + builder.append(" }"); + return builder.toString(); } + } diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java index 1aad38d..31bb652 100644 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java @@ -245,8 +245,6 @@ public abstract class SmsMessageBase { /** * Returns an object representing the user data header * - * @return an object representing the user data header - * * {@hide} */ public SmsHeader getUserDataHeader() { @@ -254,9 +252,14 @@ public abstract class SmsMessageBase { } /** + * TODO(cleanup): The term PDU is used in a seemingly non-unique + * manner -- for example, what is the difference between this byte + * array and the contents of SubmitPdu objects. Maybe a more + * illustrative term would be appropriate. + */ + + /** * Returns the raw PDU for the message. - * - * @return the raw PDU for the message. */ public byte[] getPdu() { return mPdu; diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index c342233..91aa34e 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -53,7 +53,20 @@ public class TelephonyIntents { */ public static final String ACTION_RADIO_TECHNOLOGY_CHANGED = "android.intent.action.RADIO_TECHNOLOGY"; - + /** + * <p>Broadcast Action: The emergency callback mode is entered. + * + * <p class="note"> + * You can <em>not</em> receive this through components declared + * in manifests, only by explicitly registering for it with + * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver, + * android.content.IntentFilter) Context.registerReceiver()}. + * + * <p class="note"> + * Requires no permission. + */ + public static final String ACTION_EMERGENCY_CALLBACK_MODE_ENTERED + = "android.intent.action.EMERGENCY_CALLBACK_MODE"; /** * Broadcast Action: The phone's signal strength has changed. The intent will have the * following extra values:</p> diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index 396b42d..453185f 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -44,6 +44,7 @@ public interface TelephonyProperties * Availability: when registered to a network */ static final String PROPERTY_OPERATOR_ALPHA = "gsm.operator.alpha"; + //TODO: most of these proprieties are generic, substitute gsm. with phone. bug 1856959 /** Numeric name (MCC+MNC) of current registered operator. * Availability: when registered to a network @@ -68,6 +69,8 @@ public interface TelephonyProperties */ static final String PROPERTY_OPERATOR_ISO_COUNTRY = "gsm.operator.iso-country"; + static final String CURRENT_ACTIVE_PHONE = "gsm.current.phone-type"; + //****** SIM Card /** * One of <code>"UNKNOWN"</code> <code>"ABSENT"</code> <code>"PIN_REQUIRED"</code> diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index 8ffb7ec..03f7f98 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -16,7 +16,9 @@ package com.android.internal.telephony.cdma; +import android.app.ActivityManagerNative; import android.content.Context; +import android.content.Intent; import android.os.AsyncResult; import android.os.Handler; import android.os.Looper; @@ -28,6 +30,7 @@ import android.provider.Settings; import android.telephony.CellLocation; import android.telephony.PhoneNumberUtils; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import android.text.TextUtils; import android.util.Log; @@ -48,6 +51,8 @@ import com.android.internal.telephony.PhoneNotifier; import com.android.internal.telephony.PhoneProxy; import com.android.internal.telephony.PhoneSubInfo; import com.android.internal.telephony.RILConstants; +import com.android.internal.telephony.TelephonyIntents; +import com.android.internal.telephony.TelephonyProperties; import java.util.ArrayList; import java.util.List; @@ -71,8 +76,13 @@ public class CDMAPhone extends PhoneBase { RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager; RuimSmsInterfaceManager mRuimSmsInterfaceManager; PhoneSubInfo mSubInfo; + EriManager mEriManager; - protected RegistrantList mNvLoadedRegistrants = new RegistrantList(); + // mNvLoadedRegistrants are informed after the EVENT_NV_READY + private RegistrantList mNvLoadedRegistrants = new RegistrantList(); + + // mEriFileLoadedRegistrants are informed after the ERI text has been loaded + private RegistrantList mEriFileLoadedRegistrants = new RegistrantList(); private String mEsn; private String mMeid; @@ -102,6 +112,7 @@ public class CDMAPhone extends PhoneBase { mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this); mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this); mSubInfo = new PhoneSubInfo(this); + mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML); mCM.registerForAvailable(h, EVENT_RADIO_AVAILABLE, null); mRuimRecords.registerForRecordsLoaded(h, EVENT_RUIM_RECORDS_LOADED, null); @@ -111,10 +122,13 @@ public class CDMAPhone extends PhoneBase { mCM.setOnCallRing(h, EVENT_CALL_RING, null); mSST.registerForNetworkAttach(h, EVENT_REGISTERED_TO_NETWORK, null); mCM.registerForNVReady(h, EVENT_NV_READY, null); + mCM.registerForCdmaCallWaiting(h,EVENT_CDMA_CALL_WAITING,null); + mCM.setEmergencyCallbackMode(h, EVENT_EMERGENCY_CALLBACK_MODE, null); + //Change the system setting - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.CURRENT_ACTIVE_PHONE, RILConstants.CDMA_PHONE); + SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE, + new Integer(RILConstants.CDMA_PHONE).toString()); } public void dispose() { @@ -129,6 +143,7 @@ public class CDMAPhone extends PhoneBase { mSST.unregisterForNetworkAttach(h); //EVENT_REGISTERED_TO_NETWORK mCM.unSetOnSuppServiceNotification(h); mCM.unSetOnCallRing(h); + mCM.unregisterForCdmaCallWaiting(h); //Force all referenced classes to unregister their former registered events mCT.dispose(); @@ -141,6 +156,7 @@ public class CDMAPhone extends PhoneBase { mRuimPhoneBookInterfaceManager.dispose(); mRuimSmsInterfaceManager.dispose(); mSubInfo.dispose(); + mEriManager.dispose(); } } @@ -155,6 +171,7 @@ public class CDMAPhone extends PhoneBase { this.mDataConnection = null; this.mCT = null; this.mSST = null; + this.mEriManager = null; } protected void finalize() { @@ -229,6 +246,10 @@ public class CDMAPhone extends PhoneBase { case DATAINANDOUT: ret = DataActivityState.DATAINANDOUT; break; + + case DORMANT: + ret = DataActivityState.DORMANT; + break; } } return ret; @@ -261,9 +282,8 @@ public class CDMAPhone extends PhoneBase { } } - - public int getSignalStrengthASU() { - return mSST.rssi == 99 ? -1 : mSST.rssi; + public SignalStrength getSignalStrength() { + return mSST.mSignalStrength; } public boolean @@ -350,6 +370,10 @@ public class CDMAPhone extends PhoneBase { return mRuimRecords.getMdnNumber(); } + public String getMin() { + return mRuimRecords.getMin(); + } + public void getCallWaiting(Message onComplete) { mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete); } @@ -476,10 +500,10 @@ public class CDMAPhone extends PhoneBase { ret = DataState.CONNECTED; } else if (mSST == null) { - // Radio Technology Change is ongoning, dispose() and removeReferences() have - // already been called + // Radio Technology Change is ongoning, dispose() and removeReferences() have + // already been called - ret = DataState.DISCONNECTED; + ret = DataState.DISCONNECTED; } else if (mSST.getCurrentCdmaDataConnectionState() == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) { // If we're out of service, open TCP sockets may still work @@ -541,6 +565,21 @@ public class CDMAPhone extends PhoneBase { mCM.stopDtmf(null); } + public void sendBurstDtmf(String dtmfString) { + boolean check = true; + for (int itr = 0;itr < dtmfString.length(); itr++) { + if (!PhoneNumberUtils.is12Key(dtmfString.charAt(itr))) { + Log.e(LOG_TAG, + "sendDtmf called with invalid character '" + dtmfString.charAt(itr)+ "'"); + check = false; + break; + } + } + if ((mCT.state == Phone.State.OFFHOOK)&&(check)) { + mCM.sendBurstDtmf(dtmfString, null); + } + } + public void getAvailableNetworks(Message response) { Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA"); } @@ -767,6 +806,12 @@ public class CDMAPhone extends PhoneBase { } break; + case EVENT_EMERGENCY_CALLBACK_MODE: { + Log.d(LOG_TAG, "Event EVENT_EMERGENCY_CALLBACK_MODE Received"); + Intent intent = + new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_ENTERED); + ActivityManagerNative.broadcastStickyIntent(intent, null); + } case EVENT_RUIM_RECORDS_LOADED:{ Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received"); } @@ -800,7 +845,18 @@ public class CDMAPhone extends PhoneBase { case EVENT_NV_READY:{ Log.d(LOG_TAG, "Event EVENT_NV_READY Received"); //Inform the Service State Tracker + mEriManager.loadEriFile(); mNvLoadedRegistrants.notifyRegistrants(); + if(mEriManager.isEriFileLoaded()) { + // when the ERI file is loaded + Log.d(LOG_TAG, "ERI read, notify registrants"); + mEriFileLoadedRegistrants.notifyRegistrants(); + } + } + break; + + case EVENT_CDMA_CALL_WAITING:{ + Log.d(LOG_TAG, "Event EVENT_CDMA_CALL_WAITING Received"); } break; @@ -841,6 +897,15 @@ public class CDMAPhone extends PhoneBase { mNvLoadedRegistrants.remove(h); } + public void registerForEriFileLoaded(Handler h, int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + mEriFileLoadedRegistrants.add(r); + } + + public void unregisterForEriFileLoaded(Handler h) { + mEriFileLoadedRegistrants.remove(h); + } + // override for allowing access from other classes of this package /** * {@inheritDoc} @@ -866,15 +931,22 @@ public class CDMAPhone extends PhoneBase { /** * Set the TTY mode of the CDMAPhone */ - public void setTTYModeEnabled(boolean enable, Message onComplete) { - this.mCM.setTTYModeEnabled(enable, onComplete); + public void setTTYMode(int ttyMode, Message onComplete) { + this.mCM.setTTYMode(ttyMode, onComplete); } /** * Queries the TTY mode of the CDMAPhone */ - public void queryTTYModeEnabled(Message onComplete) { - this.mCM.queryTTYModeEnabled(onComplete); + public void queryTTYMode(Message onComplete) { + this.mCM.queryTTYMode(onComplete); + } + + /** + * Sends Exit EmergencyCallbackMode Exit request on CDMAPhone + */ + public void exitEmergencyCallbackMode(Message onComplete) { + this.mCM.exitEmergencyCallbackMode(onComplete); } /** @@ -908,4 +980,244 @@ public class CDMAPhone extends PhoneBase { public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){ mSMS.setCellBroadcastConfig(configValuesArray, response); } + + public void registerForOtaSessionStatus(Handler h, int what, Object obj){ + mCM.registerForOtaSessionStatus(h, what, obj); + } + + public void unregisterForOtaSessionStatus(Handler h){ + mCM.unregisterForOtaSessionStatus(h); + } + +/** + * TODO(Teleca): The code in getCdmaEriIconIndex, getCdmaEriIconMode & getCdmaEriText share a + * lot of logic, refactor. + */ + /** + * Returns the CDMA ERI icon index to display, + * it returns 1, EriInfo.ROAMING_INDICATOR_OFF, in case there is no icon to display + */ + @Override + public int getCdmaEriIconIndex() { + int roamInd = getServiceState().getCdmaRoamingIndicator(); + int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator(); + int ret = -1; + + switch (roamInd) { + // Handling the standard roaming indicator (non-ERI) + case EriInfo.ROAMING_INDICATOR_ON: + case EriInfo.ROAMING_INDICATOR_OFF: + case EriInfo.ROAMING_INDICATOR_FLASH: + Log.d(LOG_TAG, "Using Standard Roaming Indicator (non-ERI): " + roamInd); + ret = roamInd; + break; + + // Handling the Enhanced Roaming Indicator (roamInd > 2) + default: + if (!mEriManager.isEriFileLoaded()) { + /** + * TODO(Teleca): What is going on here? Conditionals on the variable being + * switched? Seems unreasonably confusing... Especially since the above comment + * indicates this should always be true... If we used explicit returns, the + * switch could be used to filter specific cases for early bail, and the rest + * could then be dealt with outside the switch... + */ + + if(defRoamInd > 2) { + Log.d(LOG_TAG, "ERI File not loaded, using: " + + EriInfo.ROAMING_INDICATOR_FLASH); + ret = EriInfo.ROAMING_INDICATOR_FLASH; + } else { + Log.d(LOG_TAG, "ERI File not loaded, using: " + defRoamInd); + ret = defRoamInd; + } + } else if (mEriManager.getEriInfo(roamInd) == null) { + if(mEriManager.getEriInfo(defRoamInd) == null) { +/** + * TODO(Teleca): Why the redundant code? Especially since it results in this very strange looking + * almost-identical conditional... How about calling each version of mEriManager.getEriInfo just + * once, and conditionalizing on the results.. + */ + Log.e(LOG_TAG, "Error: ERI entry: " + roamInd + + " not present, defRoamInd: " + defRoamInd + + " not defined in ERI file"); + ret = EriInfo.ROAMING_INDICATOR_ON; + } else { + int iconIndex = mEriManager.getEriInfo(defRoamInd).mIconIndex; + Log.d(LOG_TAG, "ERI entry " + roamInd + " not present, using icon: " + + iconIndex); + ret = iconIndex; + } + } else { + int iconIndex = mEriManager.getEriInfo(roamInd).mIconIndex; + Log.d(LOG_TAG, "Using ERI icon: " + iconIndex); + ret = iconIndex; + } + break; + } + return ret; + } + + /** + * Returns the CDMA ERI icon mode, + * 0 - ON + * 1 - FLASHING + */ + @Override + public int getCdmaEriIconMode() { + int roamInd = getServiceState().getCdmaRoamingIndicator(); + int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator(); + int ret = -1; + + switch (roamInd) { + // Handling the standard roaming indicator (non-ERI) + case EriInfo.ROAMING_INDICATOR_ON: + case EriInfo.ROAMING_INDICATOR_OFF: + Log.d(LOG_TAG, "Using Standard Roaming Indicator (non-ERI): normal"); + ret = EriInfo.ROAMING_ICON_MODE_NORMAL; + break; + + case EriInfo.ROAMING_INDICATOR_FLASH: + Log.d(LOG_TAG, "Using Standard Roaming Indicator (non-ERI): flashing"); + ret = EriInfo.ROAMING_ICON_MODE_FLASH; + break; + + // Handling the Enhanced Roaming Indicator (roamInd > 2) + default: + if (!mEriManager.isEriFileLoaded()) { + if(defRoamInd > 2) { + Log.d(LOG_TAG, "ERI File not loaded, defRoamInd > 2, flashing"); + ret = EriInfo.ROAMING_ICON_MODE_FLASH; + } else { + switch (defRoamInd) { + // Handling the standard roaming indicator (non-ERI) + case EriInfo.ROAMING_INDICATOR_ON: + case EriInfo.ROAMING_INDICATOR_OFF: + Log.d(LOG_TAG, "ERI File not loaded, normal"); + ret = EriInfo.ROAMING_ICON_MODE_NORMAL; + break; + + case EriInfo.ROAMING_INDICATOR_FLASH: + Log.d(LOG_TAG, "ERI File not loaded, normal"); + ret = EriInfo.ROAMING_ICON_MODE_FLASH; + break; + } + } + } else if (mEriManager.getEriInfo(roamInd) == null) { + if(mEriManager.getEriInfo(defRoamInd) == null) { + Log.e(LOG_TAG, "Error: defRoamInd not defined in ERI file, normal"); + ret = EriInfo.ROAMING_ICON_MODE_NORMAL; + } else { + int mode = mEriManager.getEriInfo(defRoamInd).mIconMode; + Log.d(LOG_TAG, "ERI entry " + roamInd + " not present, icon mode: " + + mode); + ret = mode; + } + } else { + int mode = mEriManager.getEriInfo(roamInd).mIconMode; + Log.d(LOG_TAG, "Using ERI icon mode: " + mode); + ret = mode; + } + break; + } + return ret; + } + + /** + * Returns the CDMA ERI text, + */ + @Override + public String getCdmaEriText() { + int roamInd = getServiceState().getCdmaRoamingIndicator(); + int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator(); + String ret = "ERI text"; + + switch (roamInd) { + // Handling the standard roaming indicator (non-ERI) + case EriInfo.ROAMING_INDICATOR_ON: + ret = EriInfo.ROAMING_TEXT_0; + break; + case EriInfo.ROAMING_INDICATOR_OFF: + ret = EriInfo.ROAMING_TEXT_1; + break; + case EriInfo.ROAMING_INDICATOR_FLASH: + ret = EriInfo.ROAMING_TEXT_2; + break; + + // Handling the standard ERI + case 3: + ret = EriInfo.ROAMING_TEXT_3; + break; + case 4: + ret = EriInfo.ROAMING_TEXT_4; + break; + case 5: + ret = EriInfo.ROAMING_TEXT_5; + break; + case 6: + ret = EriInfo.ROAMING_TEXT_6; + break; + case 7: + ret = EriInfo.ROAMING_TEXT_7; + break; + case 8: + ret = EriInfo.ROAMING_TEXT_8; + break; + case 9: + ret = EriInfo.ROAMING_TEXT_9; + break; + case 10: + ret = EriInfo.ROAMING_TEXT_10; + break; + case 11: + ret = EriInfo.ROAMING_TEXT_11; + break; + case 12: + ret = EriInfo.ROAMING_TEXT_12; + break; + + // Handling the non standard Enhanced Roaming Indicator (roamInd > 63) + default: + if (!mEriManager.isEriFileLoaded()) { + if(defRoamInd > 2) { + Log.d(LOG_TAG, "ERI File not loaded, defRoamInd > 2, " + + EriInfo.ROAMING_TEXT_2); + ret = EriInfo.ROAMING_TEXT_2; + } else { + switch (defRoamInd) { + // Handling the standard roaming indicator (non-ERI) + case EriInfo.ROAMING_INDICATOR_ON: + Log.d(LOG_TAG, "ERI File not loaded, " + EriInfo.ROAMING_TEXT_0); + ret = EriInfo.ROAMING_TEXT_0; + break; + case EriInfo.ROAMING_INDICATOR_OFF: + Log.d(LOG_TAG, "ERI File not loaded, " + EriInfo.ROAMING_TEXT_1); + ret = EriInfo.ROAMING_TEXT_1; + break; + case EriInfo.ROAMING_INDICATOR_FLASH: + Log.d(LOG_TAG, "ERI File not loaded, " + EriInfo.ROAMING_TEXT_2); + ret = EriInfo.ROAMING_TEXT_2; + break; + } + } + } else if (mEriManager.getEriInfo(roamInd) == null) { + if(mEriManager.getEriInfo(defRoamInd) == null) { + Log.e(LOG_TAG, "Error: defRoamInd not defined in ERI file, " + + EriInfo.ROAMING_TEXT_0); + ret = EriInfo.ROAMING_TEXT_0; + } else { + String eriText = mEriManager.getEriInfo(defRoamInd).mEriText; + Log.d(LOG_TAG, "ERI entry " + roamInd + " not present, eri text: " + + eriText); + ret = eriText; + } + } else { + String eriText = mEriManager.getEriInfo(roamInd).mEriText; + Log.d(LOG_TAG, "Using ERI text: " + eriText); + ret = eriText; + } + break; + } + return ret; + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java index ea557b2..9af245c 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java +++ b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java @@ -25,26 +25,40 @@ package com.android.internal.telephony.cdma; * */ public interface CallFailCause { - static final int NORMAL_CLEARING = 16; + static final int NORMAL_CLEARING = 16; // Busy Tone - static final int USER_BUSY = 17; + static final int USER_BUSY = 17; + // TODO(Teleca): Should we remove commented out values? // // No Tone -// static final int NUMBER_CHANGED = 22; -// static final int STATUS_ENQUIRY = 30; - static final int NORMAL_UNSPECIFIED = 31; +// static final int NUMBER_CHANGED = 22; +// static final int STATUS_ENQUIRY = 30; + static final int NORMAL_UNSPECIFIED = 31; // // // Congestion Tone -// static final int NO_CIRCUIT_AVAIL = 34; -// static final int TEMPORARY_FAILURE = 41; -// static final int SWITCHING_CONGESTION = 42; -// static final int CHANNEL_NOT_AVAIL = 44; -// static final int QOS_NOT_AVAIL = 49; -// static final int BEARER_NOT_AVAIL = 58; + static final int NO_CIRCUIT_AVAIL = 34; +// static final int TEMPORARY_FAILURE = 41; +// static final int SWITCHING_CONGESTION = 42; +// static final int CHANNEL_NOT_AVAIL = 44; +// static final int QOS_NOT_AVAIL = 49; +// static final int BEARER_NOT_AVAIL = 58; // // // others -// static final int ACM_LIMIT_EXCEEDED = 68; -// static final int CALL_BARRED = 240; -// static final int FDN_BLOCKED = 241; + static final int ACM_LIMIT_EXCEEDED = 68; + static final int CALL_BARRED = 240; + static final int FDN_BLOCKED = 241; + + static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; + static final int CDMA_DROP = 1001; + static final int CDMA_INTERCEPT = 1002; + static final int CDMA_REORDER = 1003; + static final int CDMA_SO_REJECT = 1004; + static final int CDMA_RETRY_ORDER = 1005; + static final int CDMA_ACCESS_FAILURE = 1006; + static final int CDMA_PREEMPTED = 1007; + + // For non-emergency number dialed while in emergency callback mode. + static final int CDMA_NOT_EMERGENCY = 1008; + static final int ERROR_UNSPECIFIED = 0xffff; } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaiting.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaiting.java new file mode 100644 index 0000000..64841d7 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaiting.java @@ -0,0 +1,33 @@ +/* + * 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 com.android.internal.telephony.CdmaInformationRecord; + +public class CdmaCallWaiting { + public String number; + public int numberPresentation; + public String name; + + public CdmaInformationRecord.CdmaSignalInfoRec signalInfoRecord = + new CdmaInformationRecord.CdmaSignalInfoRec(); + + @Override + public String toString() { + return "CdmaCallWaiting: {" + " number: " + number + " numberPresentation: " + + numberPresentation + " name: " + name + " signalInfoRecord: " + + signalInfoRecord + " }"; + } +} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java index cdad4a7..0a237c6 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java @@ -84,7 +84,7 @@ public class CdmaConnection extends Connection { static final int EVENT_PAUSE_DONE = 2; static final int EVENT_NEXT_POST_DIAL = 3; static final int EVENT_WAKE_LOCK_TIMEOUT = 4; - + //***** Constants static final int PAUSE_DELAY_FIRST_MILLIS = 100; static final int PAUSE_DELAY_MILLIS = 3 * 1000; @@ -139,7 +139,7 @@ public class CdmaConnection extends Connection { CdmaConnection (Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) { createWakeLock(context); acquireWakeLock(); - + owner = ct; h = new MyHandler(owner.getLooper()); @@ -344,6 +344,32 @@ public class CdmaConnection extends Connection { switch (causeCode) { case CallFailCause.USER_BUSY: return DisconnectCause.BUSY; + case CallFailCause.NO_CIRCUIT_AVAIL: + return DisconnectCause.CONGESTION; + case CallFailCause.ACM_LIMIT_EXCEEDED: + return DisconnectCause.LIMIT_EXCEEDED; + case CallFailCause.CALL_BARRED: + return DisconnectCause.CALL_BARRED; + case CallFailCause.FDN_BLOCKED: + return DisconnectCause.FDN_BLOCKED; + case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE: + return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE; + case CallFailCause.CDMA_DROP: + return DisconnectCause.CDMA_DROP; + case CallFailCause.CDMA_INTERCEPT: + return DisconnectCause.CDMA_INTERCEPT; + case CallFailCause.CDMA_REORDER: + return DisconnectCause.CDMA_REORDER; + case CallFailCause.CDMA_SO_REJECT: + return DisconnectCause.CDMA_SO_REJECT; + case CallFailCause.CDMA_RETRY_ORDER: + return DisconnectCause.CDMA_RETRY_ORDER; + case CallFailCause.CDMA_ACCESS_FAILURE: + return DisconnectCause.CDMA_ACCESS_FAILURE; + case CallFailCause.CDMA_PREEMPTED: + return DisconnectCause.CDMA_PREEMPTED; + case CallFailCause.CDMA_NOT_EMERGENCY: + return DisconnectCause.CDMA_NOT_EMERGENCY; case CallFailCause.ERROR_UNSPECIFIED: case CallFailCause.NORMAL_CLEARING: default: @@ -352,7 +378,7 @@ public class CdmaConnection extends Connection { if (serviceState == ServiceState.STATE_POWER_OFF) { return DisconnectCause.POWER_OFF; } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE - || serviceState == ServiceState.STATE_EMERGENCY_ONLY ) { + || serviceState == ServiceState.STATE_EMERGENCY_ONLY) { return DisconnectCause.OUT_OF_SERVICE; } else if (phone.mCM.getRadioState() != CommandsInterface.RadioState.NV_READY && phone.getIccCard().getState() != RuimCard.State.READY) { @@ -549,7 +575,7 @@ public class CdmaConnection extends Connection { return postDialString.substring(nextPostDialChar); } - + @Override protected void finalize() { @@ -583,7 +609,7 @@ public class CdmaConnection extends Connection { c = 0; } else { boolean isValid; - + setPostDialState(PostDialState.STARTED); c = postDialString.charAt(nextPostDialChar++); @@ -653,31 +679,31 @@ public class CdmaConnection extends Connection { } /** - * Set post dial state and acquire wake lock while switching to "started" - * state, the wake lock will be released if state switches out of "started" - * state or after WAKE_LOCK_TIMEOUT_MILLIS. + * Set post dial state and acquire wake lock while switching to "started" + * state, the wake lock will be released if state switches out of "started" + * state or after WAKE_LOCK_TIMEOUT_MILLIS. * @param s new PostDialState */ private void setPostDialState(PostDialState s) { - if (postDialState != PostDialState.STARTED + if (postDialState != PostDialState.STARTED && s == PostDialState.STARTED) { acquireWakeLock(); Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT); h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS); - } else if (postDialState == PostDialState.STARTED + } else if (postDialState == PostDialState.STARTED && s != PostDialState.STARTED) { h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); releaseWakeLock(); } postDialState = s; } - + private void createWakeLock(Context context) { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); } - + private void acquireWakeLock() { log("acquireWakeLock"); @@ -693,7 +719,7 @@ public class CdmaConnection extends Connection { } } } - + private void log(String msg) { Log.d(LOG_TAG, "[CDMAConn] " + msg); } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 651c505..64f9387 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -44,6 +44,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.internal.telephony.CommandsInterface; +import com.android.internal.telephony.DataCallState; import com.android.internal.telephony.DataConnection; import com.android.internal.telephony.DataConnection.FailCause; import com.android.internal.telephony.DataConnectionTracker; @@ -98,6 +99,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { "com.android.internal.telephony.cdma-reconnect"; private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason"; + /** + * Constants for the data connection activity: + * physical link down/up + */ + private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1; + private static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2; + // Possibly promoate to base class, the only difference is // the INTENT_RECONNECT_ALARM action is a different string. // Do consider technology changes if it is promoted. @@ -258,7 +266,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } /** - * Simply tear down data connections due to radio off + * Simply tear down data connections due to radio off * and don't setup again. */ public void cleanConnectionBeforeRadioOff() { @@ -515,7 +523,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { * override it with an unconditional power on. */ } - + private Runnable mPollNetStat = new Runnable() { public void run() { @@ -608,19 +616,19 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { /** * Return true if data connection need to be setup after disconnected due to * reason. - * + * * @param reason the reason why data is disconnected - * @return true if try setup data connection is need for this reason + * @return true if try setup data connection is need for this reason */ private boolean retryAfterDisconnected(String reason) { boolean retry = true; - + if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) || - Phone.REASON_DATA_DISABLED.equals(reason) ) { + Phone.REASON_DATA_DISABLED.equals(reason) ) { retry = false; } return retry; - } + } private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) { if (state == State.FAILED) { @@ -843,6 +851,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } protected void onDataStateChanged (AsyncResult ar) { + ArrayList<DataCallState> dataCallStates = (ArrayList<DataCallState>)(ar.result); + if (ar.exception != null) { // This is probably "radio not available" or something // of that sort. If so, the whole connection is going @@ -851,7 +861,14 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } if (state == State.CONNECTED) { - Log.i(LOG_TAG, "Data connection has changed."); + if (dataCallStates.get(0).active == DATA_CONNECTION_ACTIVE_PH_LINK_UP ) { + activity = Activity.NONE; + phone.notifyDataActivity(); + } else if (dataCallStates.get(0).active == DATA_CONNECTION_ACTIVE_PH_LINK_DOWN ) { + activity = Activity.DORMANT; + phone.notifyDataActivity(); + } + } else { int cid = -1; EventLog.List val = new EventLog.List(cid, diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index 42c0583..a3d00d7 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -29,7 +29,6 @@ import android.util.Log; import com.android.internal.telephony.SmsHeader; import com.android.internal.telephony.SmsMessageBase; import com.android.internal.telephony.SMSDispatcher; -//import com.android.internal.telephony.SMSDispatcher.SmsTracker; import com.android.internal.telephony.cdma.SmsMessage; import com.android.internal.telephony.cdma.sms.SmsEnvelope; import com.android.internal.util.HexDump; @@ -42,8 +41,11 @@ import java.util.HashMap; final class CdmaSMSDispatcher extends SMSDispatcher { private static final String TAG = "CDMA"; + private CDMAPhone mCdmaPhone; + CdmaSMSDispatcher(CDMAPhone phone) { super(phone); + mCdmaPhone = phone; } /** @@ -70,50 +72,39 @@ final class CdmaSMSDispatcher extends SMSDispatcher { if (smsb == null) { return; } - SmsMessage sms = (SmsMessage) smsb; - int teleService; - boolean handled = false; // Decode BD stream and set sms variables. + SmsMessage sms = (SmsMessage) smsb; sms.parseSms(); - teleService = sms.getTeleService(); + int teleService = sms.getTeleService(); + boolean handled = false; // Teleservices W(E)MT and VMN are handled together: - if ((SmsEnvelope.TELESERVICE_WMT == teleService) - ||(SmsEnvelope.TELESERVICE_WEMT == teleService) - ||(SmsEnvelope.TELESERVICE_VMN == teleService)){ + if ((teleService == SmsEnvelope.TELESERVICE_WMT) + || (teleService == SmsEnvelope.TELESERVICE_WEMT) + || (teleService == SmsEnvelope.TELESERVICE_VMN)) { // From here on we need decoded BD. // Special case the message waiting indicator messages if (sms.isMWISetMessage()) { - ((CDMAPhone) mPhone).updateMessageWaitingIndicator(true); - - if (sms.isMwiDontStore()) { - handled = true; - } - + mCdmaPhone.updateMessageWaitingIndicator(true); + handled |= sms.isMwiDontStore(); if (Config.LOGD) { - Log.d(TAG, - "Received voice mail indicator set SMS shouldStore=" + !handled); + Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled); } } else if (sms.isMWIClearMessage()) { - ((CDMAPhone) mPhone).updateMessageWaitingIndicator(false); - - if (sms.isMwiDontStore()) { - handled = true; - } - + mCdmaPhone.updateMessageWaitingIndicator(false); + handled |= sms.isMwiDontStore(); if (Config.LOGD) { - Log.d(TAG, - "Received voice mail indicator clear SMS shouldStore=" + !handled); + Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled); } } } - if (null == sms.getUserData()){ - handled = true; + if (sms.getUserData() == null) { if (Config.LOGD) { Log.d(TAG, "Received SMS without user data"); } + handled = true; } if (handled) return; @@ -123,82 +114,44 @@ final class CdmaSMSDispatcher extends SMSDispatcher { return; } - // Parse the headers to see if this is partial, or port addressed - int referenceNumber = -1; - int count = 0; - int sequence = 0; - int destPort = -1; - // From here on we need BD distributed to SMS member variables. - - SmsHeader header = sms.getUserDataHeader(); - if (header != null) { - for (SmsHeader.Element element : header.getElements()) { - try { - switch (element.getID()) { - case SmsHeader.CONCATENATED_8_BIT_REFERENCE: { - byte[] data = element.getData(); - - referenceNumber = data[0] & 0xff; - count = data[1] & 0xff; - sequence = data[2] & 0xff; - - // Per TS 23.040, 9.2.3.24.1: If the count is zero, sequence - // is zero, or sequence > count, ignore the entire element - if (count == 0 || sequence == 0 || sequence > count) { - referenceNumber = -1; - } - break; - } - - case SmsHeader.CONCATENATED_16_BIT_REFERENCE: { - byte[] data = element.getData(); - - referenceNumber = (data[0] & 0xff) * 256 + (data[1] & 0xff); - count = data[2] & 0xff; - sequence = data[3] & 0xff; - - // Per TS 23.040, 9.2.3.24.8: If the count is zero, sequence - // is zero, or sequence > count, ignore the entire element - if (count == 0 || sequence == 0 || sequence > count) { - referenceNumber = -1; - } - break; - } - - case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: { - byte[] data = element.getData(); - - destPort = (data[0] & 0xff) << 8; - destPort |= (data[1] & 0xff); - - break; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - Log.e(TAG, "Bad element in header", e); - return; // TODO: NACK the message or something, don't just discard. - } - } - } - - if (referenceNumber == -1) { - // notify everyone of the message if it isn't partial + /** + * TODO(cleanup): Why are we using a getter method for this + * (and for so many other sms fields)? Trivial getters and + * setters like this are direct violations of the style guide. + * If the purpose is to protect agaist writes (by not + * providing a setter) then any protection is illusory (and + * hence bad) for cases where the values are not primitives, + * such as this call for the header. Since this is an issue + * with the public API it cannot be changed easily, but maybe + * something can be done eventually. + */ + SmsHeader smsHeader = sms.getUserDataHeader(); + + /** + * TODO(cleanup): Since both CDMA and GSM use the same header + * format, this dispatch processing is naturally identical, + * and code should probably not be replicated explicitly. + */ + // See if message is partial or port addressed. + if ((smsHeader == null) || (smsHeader.concatRef == null)) { + // Message is not partial (not part of concatenated sequence). byte[][] pdus = new byte[1][]; pdus[0] = sms.getPdu(); - if (destPort != -1) {// GSM-style WAP indication - if (destPort == SmsHeader.PORT_WAP_PUSH) { + if (smsHeader != null && smsHeader.portAddrs != null) { + if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) { + // GSM-style WAP indication mWapPush.dispatchWapPdu(sms.getUserData()); } - // The message was sent to a port, so concoct a URI for it - dispatchPortAddressedPdus(pdus, destPort); + // The message was sent to a port, so concoct a URI for it. + dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort); } else { - // It's a normal message, dispatch it + // Normal short and non-port-addressed message, dispatch it. dispatchPdus(pdus); } } else { - // Process the message part - processMessagePart(sms, referenceNumber, sequence, count, destPort); + // Process the message part. + processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs); } } @@ -314,41 +267,49 @@ final class CdmaSMSDispatcher extends SMSDispatcher { } /** {@inheritDoc} */ - protected void sendMultipartText(String destinationAddress, String scAddress, + protected void sendMultipartText(String destAddr, String scAddr, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { - int ref = ++sConcatenatedRef & 0xff; + /** + * TODO(cleanup): There is no real code difference between + * this and the GSM version, and hence it should be moved to + * the base class or consolidated somehow, provided calling + * the proper submitpdu stuff can be arranged. + */ - for (int i = 0, count = parts.size(); i < count; i++) { - // build SmsHeader data - byte[] data = new byte[5]; - data[0] = (byte) SmsHeader.CONCATENATED_8_BIT_REFERENCE; - data[1] = (byte) 3; // 3 bytes follow - data[2] = (byte) ref; // reference #, unique per message - data[3] = (byte) count; // total part count - data[4] = (byte) (i + 1); // 1-based sequence + int refNumber = getNextConcatenatedRef() & 0x00FF; - PendingIntent sentIntent = null; - PendingIntent deliveryIntent = null; + for (int i = 0, msgCount = parts.size(); i < msgCount; i++) { + SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); + concatRef.refNumber = refNumber; + concatRef.seqNumber = i + 1; // 1-based sequence + concatRef.msgCount = msgCount; + concatRef.isEightBits = true; + SmsHeader smsHeader = new SmsHeader(); + smsHeader.concatRef = concatRef; + PendingIntent sentIntent = null; if (sentIntents != null && sentIntents.size() > i) { sentIntent = sentIntents.get(i); } + + PendingIntent deliveryIntent = null; if (deliveryIntents != null && deliveryIntents.size() > i) { deliveryIntent = deliveryIntents.get(i); } - SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress, - parts.get(i), deliveryIntent != null, data); + SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(scAddr, destAddr, + parts.get(i), deliveryIntent != null, smsHeader); - sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent); + sendSubmitPdu(submitPdu, sentIntent, deliveryIntent); } } - protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, + protected void sendSubmitPdu(SmsMessage.SubmitPdu submitPdu, PendingIntent sentIntent, PendingIntent deliveryIntent) { - super.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent); + sendRawPdu(submitPdu.encodedScAddress, submitPdu.encodedMessage, + sentIntent, deliveryIntent); } /** {@inheritDoc} */ diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index d5cad1c..dbb0f93 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -33,6 +33,7 @@ import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.provider.Telephony.Intents; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import android.telephony.cdma.CdmaCellLocation; import android.text.TextUtils; import android.util.EventLog; @@ -70,8 +71,13 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { CdmaCellLocation cellLoc; CdmaCellLocation newCellLoc; - int rssi = 99; // signal strength 0-31, 99=unknown - // That's "received signal strength indication" fyi + /** + * TODO(Teleca): I don't think the initialization to -1 for all of these are + * really necessary, I don't seem them in GsmServiceStateTracker. Also, + * all of the other initialization is unnecessary as I believe Java guarantees + * 0, false & null, but if you think it's better than do all of them there are + * a few that aren't initialized. + */ /** * The access technology currently in use: DATA_ACCESS_ @@ -80,9 +86,16 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { private int newNetworkType = 0; private boolean mCdmaRoaming = false; + private int mRoamingIndicator = -1; + private int mIsInPrl = -1; + private int mDefaultRoamingIndicator = -1; - private int cdmaDataConnectionState = -1;//Initial we assume no data connection - private int newCdmaDataConnectionState = -1;//Initial we assume no data connection + /** + * TODO(Teleca): Maybe these should be initialized to STATE_OUT_OF_SERVICE like gprsState + * in GsmServiceStateTracker and remove the comment. + */ + private int cdmaDataConnectionState = -1; // Initially we assume no data connection + private int newCdmaDataConnectionState = -1; // Initially we assume no data connection private int mRegistrationState = -1; private RegistrantList cdmaDataConnectionAttachedRegistrants = new RegistrantList(); private RegistrantList cdmaDataConnectionDetachedRegistrants = new RegistrantList(); @@ -95,12 +108,25 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { // Keep track of SPN display rules, so we only broadcast intent if something changes. private String curSpn = null; - private String curPlmn = null; + private String curEriText = null; private int curSpnRule = 0; + private String mMdn = null; + private int mHomeSystemId = -1; + private int mHomeNetworkId = -1; + private String mMin = null; + private boolean isEriTextLoaded = false; + private boolean isSubscriptionFromRuim = false; + + /** + * TODO(Teleca): Is this purely for debugging purposes, or do we expect this string to be + * passed around (eg, to the UI)? If the latter, it would be better to pass around a + * reasonCode, and let the UI provide its own strings. + */ + private String mRegistrationDeniedReason = null; + //***** Constants static final String LOG_TAG = "CDMA"; - static final String TMUK = "23430"; private ContentResolver cr; @@ -124,6 +150,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { newSS = new ServiceState(); cellLoc = new CdmaCellLocation(); newCellLoc = new CdmaCellLocation(); + mSignalStrength = new SignalStrength(); cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); @@ -133,7 +160,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { cm.registerForRUIMReady(this, EVENT_RUIM_READY, null); - phone.registerForNvLoaded(this, EVENT_NV_LOADED,null); + cm.registerForNVReady(this, EVENT_NV_READY, null); + phone.registerForEriFileLoaded(this, EVENT_ERI_FILE_LOADED, null); // system setting property AIRPLANE_MODE_ON is set in Settings. int airplaneMode = Settings.System.getInt( @@ -145,7 +173,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { cr.registerContentObserver( Settings.System.getUriFor(Settings.System.AUTO_TIME), true, mAutoTimeObserver); - setRssiDefaultValues(); + setSignalStrengthDefaultValues(); mNeedToRegForRuimLoaded = true; } @@ -156,14 +184,15 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { cm.unregisterForRadioStateChanged(this); cm.unregisterForNetworkStateChanged(this); cm.unregisterForRUIMReady(this); - phone.unregisterForNvLoaded(this); + cm.unregisterForNVReady(this); + phone.unregisterForEriFileLoaded(this); phone.mRuimRecords.unregisterForRecordsLoaded(this); cm.unSetOnSignalStrengthUpdate(this); cr.unregisterContentObserver(this.mAutoTimeObserver); } protected void finalize() { - if(DBG) Log.d(LOG_TAG, "CdmaServiceStateTracker finalized"); + if (DBG) log("CdmaServiceStateTracker finalized"); } void registerForNetworkAttach(Handler h, int what, Object obj) { @@ -246,13 +275,21 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { // The RUIM is now ready i.e if it was locked // it has been unlocked. At this stage, the radio is already // powered on. + isSubscriptionFromRuim = true; if (mNeedToRegForRuimLoaded) { phone.mRuimRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null); mNeedToRegForRuimLoaded = false; } // restore the previous network selection. - phone.restoreSavedNetworkSelection(null); + pollState(); + + // Signal strength polling stops when radio is off + queueNextSignalStrengthPoll(); + break; + + case EVENT_NV_READY: + isSubscriptionFromRuim = false; pollState(); // Signal strength polling stops when radio is off queueNextSignalStrengthPoll(); @@ -328,9 +365,9 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { } break; - case EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA: //Fall through - case EVENT_POLL_STATE_REGISTRATION_CDMA: //Fall through + case EVENT_POLL_STATE_REGISTRATION_CDMA: case EVENT_POLL_STATE_OPERATOR_CDMA: + case EVENT_POLL_STATE_CDMA_SUBSCRIPTION: ar = (AsyncResult) msg.obj; handlePollStateResult(msg.what, ar); break; @@ -355,7 +392,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { break; case EVENT_RUIM_RECORDS_LOADED: - case EVENT_NV_LOADED: updateSpnDisplay(); break; @@ -367,6 +403,12 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { } break; + case EVENT_ERI_FILE_LOADED: + // Repoll the state once the ERI file has been loaded + if (DBG) log("[CdmaServiceStateTracker] ERI file has been loaded, repolling."); + pollState(); + break; + default: Log.e(LOG_TAG, "Unhandled message with number: " + msg.what); break; @@ -391,13 +433,14 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF, val); } dcTracker.cleanConnectionBeforeRadioOff(); - - // poll data state up to 15 times, with a 100ms delay + + // Poll data state up to 15 times, with a 100ms delay // totaling 1.5 sec. Normal data disable action will finish in 100ms. for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) { - if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED - && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) { - Log.d(LOG_TAG, "Data shutdown complete."); + DataConnectionTracker.State currentState = dcTracker.getState(); + if (currentState != DataConnectionTracker.State.CONNECTED + && currentState != DataConnectionTracker.State.DISCONNECTING) { + if (DBG) log("Data shutdown complete."); break; } SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS); @@ -409,29 +452,29 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { protected void updateSpnDisplay() { - // TODO Check this method again, because it is not sure at the moment how - // the RUIM handles the SIM stuff + // TODO(Teleca): Check this method again, because it is not sure at the moment how + // the RUIM handles the SIM stuff. Please complete this function. //int rule = phone.mRuimRecords.getDisplayRule(ss.getOperatorNumeric()); String spn = null; //phone.mRuimRecords.getServiceProviderName(); - String plmn = ss.getOperatorAlphaLong(); + String eri = ss.getOperatorAlphaLong(); - if (!TextUtils.equals(this.curPlmn, plmn)) { + if (!TextUtils.equals(this.curEriText, eri)) { //TODO (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN; boolean showSpn = false; //TODO (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN; - boolean showPlmn = true; + boolean showEri = true; Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION); intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn); intent.putExtra(Intents.EXTRA_SPN, spn); - intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn); - intent.putExtra(Intents.EXTRA_PLMN, plmn); + intent.putExtra(Intents.EXTRA_SHOW_PLMN, showEri); + intent.putExtra(Intents.EXTRA_PLMN, eri); phone.getContext().sendStickyBroadcast(intent); } //curSpnRule = rule; //curSpn = spn; - this.curPlmn = plmn; + this.curEriText = eri; } /** @@ -473,11 +516,17 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { } } else try { switch (what) { - case EVENT_POLL_STATE_REGISTRATION_CDMA: - //offset, because we don't want the first 3 values in the int-array + case EVENT_POLL_STATE_REGISTRATION_CDMA: // Handle RIL_REQUEST_REGISTRATION_STATE, + // the offset is because we don't want the + // first 3 values in the + // responseValuesRegistrationState array. final int offset = 3; states = (String[])ar.result; + /** + * TODO(Teleca): Change from array to a "Class" or local + * variables so names instead of index's can be used. + */ int responseValuesRegistrationState[] = { -1, //[0] radioTechnology -1, //[1] baseStationId @@ -486,38 +535,40 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { 0, //[4] cssIndicator; init with 0, because it is treated as a boolean -1, //[5] systemId -1, //[6] networkId - -1, //[7] TSB-58 Roaming indicator // NEWRIL:TODO UNUSED - -1, //[8] Indicates if current system is in PRL // NEWRIL:TODO UNUSED - -1, //[9] Is default roaming indicator from PRL // NEWRIL:TODO UNUSED - -1, //[10] If registration state is 3 this is reason for denial // NEWRIL:TODO UNUSED + -1, //[7] Roaming indicator + -1, //[8] Indicates if current system is in PRL + -1, //[9] Is default roaming indicator from PRL + -1, //[10] If registration state is 3 this is reason for denial }; - if (states.length > 0) { + if (states.length == 14) { try { this.mRegistrationState = Integer.parseInt(states[0]); - if (states.length >= 10) { - for(int i = 0; i < states.length - offset; i++) { - if (states[i + offset] != null - && states[i + offset].length() > 0) { - try { - responseValuesRegistrationState[i] = - Integer.parseInt(states[i + offset], 16); - } - catch(NumberFormatException ex) { - Log.w(LOG_TAG, "Warning! There is an unexpected value" - + "returned as response from " - + "RIL_REQUEST_REGISTRATION_STATE."); - } - } - } - } - else { - Log.e(LOG_TAG, "Too less parameters returned from" - + " RIL_REQUEST_REGISTRATION_STATE"); - } } catch (NumberFormatException ex) { Log.w(LOG_TAG, "error parsing RegistrationState: " + ex); } + try { + responseValuesRegistrationState[0] = Integer.parseInt(states[3]); + responseValuesRegistrationState[1] = Integer.parseInt(states[4], 16); + responseValuesRegistrationState[2] = Integer.parseInt(states[5], 16); + responseValuesRegistrationState[3] = Integer.parseInt(states[6], 16); + responseValuesRegistrationState[4] = Integer.parseInt(states[7]); + responseValuesRegistrationState[5] = Integer.parseInt(states[8]); + responseValuesRegistrationState[6] = Integer.parseInt(states[9]); + responseValuesRegistrationState[7] = Integer.parseInt(states[10]); + responseValuesRegistrationState[8] = Integer.parseInt(states[11]); + responseValuesRegistrationState[9] = Integer.parseInt(states[12]); + responseValuesRegistrationState[10] = Integer.parseInt(states[13]); + } + catch(NumberFormatException ex) { + Log.w(LOG_TAG, "Warning! There is an unexpected value" + + "returned as response from " + + "RIL_REQUEST_REGISTRATION_STATE."); + } + } else { + throw new RuntimeException("Warning! Wrong number of parameters returned from " + + "RIL_REQUEST_REGISTRATION_STATE: expected 14 got " + + states.length); } mCdmaRoaming = regCodeIsRoaming(this.mRegistrationState); @@ -529,26 +580,62 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { newSS.setSystemAndNetworkId(responseValuesRegistrationState[5], responseValuesRegistrationState[6]); + mRoamingIndicator = responseValuesRegistrationState[7]; + mIsInPrl = responseValuesRegistrationState[8]; + mDefaultRoamingIndicator = responseValuesRegistrationState[9]; + newNetworkType = responseValuesRegistrationState[0]; // values are -1 if not available newCellLoc.setCellLocationData(responseValuesRegistrationState[1], responseValuesRegistrationState[2], responseValuesRegistrationState[3]); + + if (responseValuesRegistrationState[10] == 0) { + mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN; + } else if (responseValuesRegistrationState[10] == 1) { + mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH; + } else { + mRegistrationDeniedReason = ""; + } + + if (mRegistrationState == 3) { + if (DBG) log("Registration denied, " + mRegistrationDeniedReason); + } break; - case EVENT_POLL_STATE_OPERATOR_CDMA: + case EVENT_POLL_STATE_OPERATOR_CDMA: // Handle RIL_REQUEST_OPERATOR String opNames[] = (String[])ar.result; if (opNames != null && opNames.length >= 3) { - newSS.setOperatorName (opNames[0], opNames[1], opNames[2]); + // TODO(Teleca): Is this necessary here and in the else clause? + newSS.setOperatorName(opNames[0], opNames[1], opNames[2]); + if (phone.mCM.getRadioState().isNVReady()) { + // In CDMA in case on NV the ss.mOperatorAlphaLong is set later with the + // ERI text, so here is ignored what is coming from the modem + newSS.setOperatorName(null, opNames[1], opNames[2]); + } else { + newSS.setOperatorName(opNames[0], opNames[1], opNames[2]); + } + } else { + Log.w(LOG_TAG, "error parsing opNames"); } break; - case EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA: - ints = (int[])ar.result; - newSS.setIsManualSelection(ints[0] == 1); + case EVENT_POLL_STATE_CDMA_SUBSCRIPTION: // Handle RIL_CDMA_SUBSCRIPTION + String cdmaSubscription[] = (String[])ar.result; + + if (cdmaSubscription != null && cdmaSubscription.length >= 4) { + mMdn = cdmaSubscription[0]; + mHomeSystemId = Integer.parseInt(cdmaSubscription[1], 16); + mHomeNetworkId = Integer.parseInt(cdmaSubscription[2], 16); + mMin = cdmaSubscription[3]; + + } else { + Log.w(LOG_TAG, "error parsing cdmaSubscription"); + } break; + default: Log.e(LOG_TAG, "RIL response handle in wrong phone!" + " Expected CDMA RIL request and get GSM RIL request."); @@ -563,29 +650,58 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { pollingContext[0]--; if (pollingContext[0] == 0) { - newSS.setRoaming(isRoamingBetweenOperators(mCdmaRoaming, newSS)); + boolean namMatch = false; + if ((mHomeSystemId != 0) && (mHomeSystemId == newSS.getSystemId()) ) { + namMatch = true; + } - switch(this.mRegistrationState) { - case ServiceState.REGISTRATION_STATE_HOME_NETWORK: - newSS.setExtendedCdmaRoaming(ServiceState.REGISTRATION_STATE_HOME_NETWORK); - break; - case ServiceState.REGISTRATION_STATE_ROAMING: - newSS.setExtendedCdmaRoaming(ServiceState.REGISTRATION_STATE_ROAMING); - break; - case ServiceState.REGISTRATION_STATE_ROAMING_AFFILIATE: - newSS.setExtendedCdmaRoaming(ServiceState.REGISTRATION_STATE_ROAMING_AFFILIATE); - break; - default: - Log.w(LOG_TAG, "Received a different registration state, " - + "but don't changed the extended cdma roaming mode."); + // Setting SS Roaming (general) + if (isSubscriptionFromRuim) { + newSS.setRoaming(isRoamingBetweenOperators(mCdmaRoaming, newSS)); + } else { + newSS.setRoaming(mCdmaRoaming); + } + + /** + * TODO(Teleca): This would be simpler if mIsInPrl was a "boolean" as the + * name implies rather than tri-state. Above I've suggested that the -1's + * might be able to be removed, if so please simplify this. Otherwise change + * the name to mPrlState or some such. Also the logic can be simplified + * by testing for "mIsInPrl" only once. + */ + // Setting SS CdmaRoamingIndicator and CdmaDefaultRoamingIndicator + // TODO(Teleca): use constants for the standard roaming indicators + if (mIsInPrl == 0 && mRegistrationState == 5) { + // System is acquired but prl not loaded or no prl match + newSS.setCdmaRoamingIndicator(2); //FLASHING + } else if (!namMatch && (mIsInPrl == 1)) { + // System is acquired, no nam match, prl match + newSS.setCdmaRoamingIndicator(mRoamingIndicator); + } else if (namMatch && (mIsInPrl == 1) && mRoamingIndicator <= 2) { + // System is acquired, nam match, prl match, mRoamingIndicator <= 2 + newSS.setCdmaRoamingIndicator(1); //OFF + } else if (namMatch && (mIsInPrl == 1) && mRoamingIndicator > 2) { + // System is acquired, nam match, prl match, mRoamingIndicator > 2 + newSS.setCdmaRoamingIndicator(mRoamingIndicator); + } + newSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator); + + // NOTE: Some operator may require to override the mCdmaRoaming (set by the modem) + // depending on the mRoamingIndicator. + + if (DBG) { + log("Set CDMA Roaming Indicator to: " + newSS.getCdmaRoamingIndicator() + + ". mCdmaRoaming = " + mCdmaRoaming + ", namMatch = " + namMatch + + ", mIsInPrl= " + mIsInPrl + ", mRoamingIndicator = " + mRoamingIndicator + + ", mDefaultRoamingIndicator= " + mDefaultRoamingIndicator); } pollStateDone(); } } - private void setRssiDefaultValues() { - rssi = 99; + private void setSignalStrengthDefaultValues() { + mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false); } /** @@ -606,7 +722,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { case RADIO_UNAVAILABLE: newSS.setStateOutOfService(); newCellLoc.setStateInvalid(); - setRssiDefaultValues(); + setSignalStrengthDefaultValues(); mGotCountryCode = false; pollStateDone(); @@ -615,7 +731,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { case RADIO_OFF: newSS.setStateOff(); newCellLoc.setStateInvalid(); - setRssiDefaultValues(); + setSignalStrengthDefaultValues(); mGotCountryCode = false; pollStateDone(); @@ -627,10 +743,10 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { log("Radio Technology Change ongoing, setting SS to off"); newSS.setStateOff(); newCellLoc.setStateInvalid(); - setRssiDefaultValues(); + setSignalStrengthDefaultValues(); mGotCountryCode = false; - pollStateDone(); + //NOTE: pollStateDone() is not needed in this case break; default: @@ -639,20 +755,21 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { // are allowed to arrive out-of-order pollingContext[0]++; - //RIL_REQUEST_OPERATOR is necessary for CDMA - cm.getOperator( - obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext)); - - pollingContext[0]++; - //RIL_REQUEST_REGISTRATION_STATE is necessary for CDMA - cm.getRegistrationState( - obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext)); - - pollingContext[0]++; - //RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE necessary for CDMA - cm.getNetworkSelectionMode( - obtainMessage(EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA, pollingContext)); - break; + // RIL_REQUEST_CDMA_SUBSCRIPTION is necessary for CDMA + cm.getCDMASubscription( + obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION, pollingContext)); + + pollingContext[0]++; + // RIL_REQUEST_OPERATOR is necessary for CDMA + cm.getOperator( + obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext)); + + pollingContext[0]++; + // RIL_REQUEST_REGISTRATION_STATE is necessary for CDMA + cm.getRegistrationState( + obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext)); + + break; } } @@ -685,12 +802,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { private void pollStateDone() { - if (DBG) { - Log.d(LOG_TAG, "Poll ServiceState done: " + - " oldSS=[" + ss ); - Log.d(LOG_TAG, "Poll ServiceState done: " + - " newSS=[" + newSS); - } + if (DBG) log("Poll ServiceState done: oldSS=[" + ss + "] newSS=[" + newSS + "]"); boolean hasRegistered = ss.getState() != ServiceState.STATE_IN_SERVICE @@ -757,6 +869,22 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { } if (hasChanged) { + if (phone.mCM.getRadioState().isNVReady()) { + String eriText; + // Now the CDMAPhone sees the new ServiceState so it can get the new ERI text + if (ss.getState() == ServiceState.STATE_IN_SERVICE) { + eriText = phone.getCdmaEriText(); + } else { + // Note that this is valid only for mRegistrationState 2,3,4, not 0! + /** + * TODO(Teleca): From the comment this apparently isn't always true + * should there be additional logic with other strings? + */ + eriText = EriInfo.SEARCHING_TEXT; + } + ss.setCdmaEriText(eriText); + } + String operatorNumeric; phone.setSystemProperty(PROPERTY_OPERATOR_ALPHA, @@ -784,8 +912,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { phone.setSystemProperty(PROPERTY_OPERATOR_ISROAMING, ss.getRoaming() ? "true" : "false"); - phone.setSystemProperty(PROPERTY_OPERATOR_ISMANUAL, - ss.getIsManualSelection() ? "true" : "false"); updateSpnDisplay(); phone.notifyServiceStateChanged(ss); @@ -825,10 +951,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { // Couldn't find a proper timezone. Perhaps the DST data is wrong. guess = findTimeZone(offset, !dst, when); } - if (DBG) { - Log.d(LOG_TAG, "getNitzTimeZone returning " - + (guess == null ? guess : guess.getID())); - } + if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID())); return guess; } @@ -865,41 +988,49 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { msg = obtainMessage(); msg.what = EVENT_POLL_SIGNAL_STRENGTH; - // TODO Done't poll signal strength if screen is off + // TODO(Teleca): Don't poll signal strength if screen is off sendMessageDelayed(msg, POLL_PERIOD_MILLIS); } /** - * send signal-strength-changed notification if rssi changed + * send signal-strength-changed notification if changed * Called both for solicited and unsolicited signal stength updates */ private void onSignalStrengthResult(AsyncResult ar) { - int oldRSSI = rssi; + SignalStrength oldSignalStrength = mSignalStrength; if (ar.exception != null) { - // 99 = unknown - // most likely radio is resetting/disconnected - rssi = 99; + // Most likely radio is resetting/disconnected change to default values. + setSignalStrengthDefaultValues(); } else { int[] ints = (int[])ar.result; - - // bug 658816 seems to be a case where the result is 0-length - if (ints.length != 0) { - rssi = ints[0]; - } else { - Log.e(LOG_TAG, "Bogus signal strength response"); - rssi = 99; + int offset = 2; + + int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -1; + int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -1; + + int evdoRssi = -1; + int evdoEcio = -1; + int evdoSnr = -1; + if ((networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_0) + || (networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_A)) { + evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -1; + evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1; + evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1; } + + mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, + evdoRssi, evdoEcio, evdoSnr, false); } - if (rssi != oldRSSI) { + if (!mSignalStrength.equals(oldSignalStrength)) { try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after // POLL_PERIOD_MILLIS) during Radio Technology Change) phone.notifySignalStrength(); } catch (NullPointerException ex) { - log("onSignalStrengthResult() Phone already destroyed: " + ex - + "Signal Stranth not notified"); + log("onSignalStrengthResult() Phone already destroyed: " + ex + + "SignalStrength not notified"); } } } @@ -943,9 +1074,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { case 3: // 3 is "registration denied", fall through case 4: // 4 is "unknown" no vaild in current baseband return ServiceState.STATE_OUT_OF_SERVICE; - case 5:// fall through - case 6: - // Registered and: roaming (5) or roaming affiliates (6) + case 5:// 5 is "Registered, roaming" return ServiceState.STATE_IN_SERVICE; default: @@ -983,6 +1112,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) { String spn = SystemProperties.get(PROPERTY_ICC_OPERATOR_ALPHA, "empty"); + // NOTE: in case of RUIM we should completely ignore the ERI data file and + // mOperatorAlphaLong is set from RIL_REQUEST_OPERATOR response 0 (alpha ONS) String onsl = s.getOperatorAlphaLong(); String onss = s.getOperatorAlphaShort(); diff --git a/telephony/java/com/android/internal/telephony/cdma/EriInfo.java b/telephony/java/com/android/internal/telephony/cdma/EriInfo.java new file mode 100644 index 0000000..40358c8 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cdma/EriInfo.java @@ -0,0 +1,65 @@ +/* + * 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; + +public final class EriInfo { + + public static final int ROAMING_INDICATOR_ON = 0; + public static final int ROAMING_INDICATOR_OFF = 1; + public static final int ROAMING_INDICATOR_FLASH = 2; + + public static final int ROAMING_ICON_MODE_NORMAL = 0; + public static final int ROAMING_ICON_MODE_FLASH = 1; + + /** + * TODO(Teleca): These strings appear to be used by the UI + * hence they must be changed to resources so they can be + * translated to the appropriate language. + */ + public static final String ROAMING_TEXT_0 = "Roaming Indicator On"; + public static final String ROAMING_TEXT_1 = "Roaming Indicator Off"; + public static final String ROAMING_TEXT_2 = "Roaming Indicator Flashing"; + public static final String ROAMING_TEXT_3 = "Out of Neighborhood"; + public static final String ROAMING_TEXT_4 = "Out of Building"; + public static final String ROAMING_TEXT_5 = "Roaming - Preferred System"; + public static final String ROAMING_TEXT_6 = "Roaming - Available System"; + public static final String ROAMING_TEXT_7 = "Roaming - Alliance Partner"; + public static final String ROAMING_TEXT_8 = "Roaming - Premium Partner"; + public static final String ROAMING_TEXT_9 = "Roaming - Full Service Functionality"; + public static final String ROAMING_TEXT_10 = "Roaming - Partial Service Functionality"; + public static final String ROAMING_TEXT_11 = "Roaming Banner On"; + public static final String ROAMING_TEXT_12 = "Roaming Banner Off"; + + public static final String SEARCHING_TEXT = "Searching for Svc."; + + + public int mRoamingIndicator; + public int mIconIndex; + public int mIconMode; + public String mEriText; + public int mCallPromptId; + public int mAlertId; + + public EriInfo (int roamingIndicator, int iconIndex, int iconMode, String eriText, + int callPromptId, int alertId) { + + this.mRoamingIndicator = roamingIndicator; + this.mIconIndex = iconIndex; + this.mIconMode = iconMode; + this.mEriText = eriText; + this.mCallPromptId = callPromptId; + this.mAlertId = alertId; + } +} diff --git a/telephony/java/com/android/internal/telephony/cdma/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java new file mode 100644 index 0000000..d905e66 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cdma/EriManager.java @@ -0,0 +1,224 @@ +/* + * 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.content.Context; +import android.content.res.Resources; +import android.content.res.XmlResourceParser; +import android.os.Message; +import android.util.Log; + +import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneBase; + +import com.android.internal.util.XmlUtils; + +import java.util.HashMap; + +/** + * TODO(Teleca): Please as some comments on how this class is to + * be used. We've removed Handler as a base class and instead + * recommend that child classes add a Handler as a member if its + * needed. + */ + + +public final class EriManager { + + class EriFile { + public static final int MAX_ERI_ENTRIES = 30; + + public int mVersionNumber; // File version number + public int mNumberOfEriEntries; // Number of entries + public int mEriFileType; // Eri Phase 0/1 + //public int mNumberOfIconImages; // reserved for future use + //public int mIconImageType; // reserved for future use + public String[] mCallPromptId; // reserved for future use + public HashMap<Integer, EriInfo> mRoamIndTable; // Roaming Indicator Table + + public EriFile() { + this.mVersionNumber = -1; + this.mNumberOfEriEntries = 0; + this.mEriFileType = -1; + this.mCallPromptId = new String[] { "", "", "" }; + this.mRoamIndTable = new HashMap<Integer, EriInfo>(); + } + + } + + static final String LOG_TAG = "CDMA"; + + public static final int ERI_FROM_XML = 0; + public static final int ERI_FROM_FILE_SYSTEM = 1; + public static final int ERI_FROM_MODEM = 2; + + private PhoneBase mPhone; + private Context mContext; + private int mEriFileSource = ERI_FROM_XML; + private boolean isEriFileLoaded = false; + private EriFile mEriFile; + + public EriManager(PhoneBase phone, Context context, int eriFileSource) { + this.mPhone = phone; + this.mContext = context; + this.mEriFileSource = eriFileSource; + this.mEriFile = new EriFile(); + } + + public void dispose() { + mEriFile = new EriFile(); + isEriFileLoaded = false; + } + + + public void loadEriFile() { + switch (mEriFileSource) { + case ERI_FROM_MODEM: + loadEriFileFromModem(); + break; + + case ERI_FROM_FILE_SYSTEM: + loadEriFileFromFileSystem(); + break; + + case ERI_FROM_XML: + default: + loadEriFileFromXml(); + break; + } + } + + /** + * Load the ERI file from the MODEM through chipset specific RIL_REQUEST_OEM_HOOK + * + * In this case the ERI file can be updated from the Phone Support Tool available + * from the Chipset vendor + */ + private void loadEriFileFromModem() { + // NOT IMPLEMENTED, Chipset vendor/Operator specific + } + + /** + * Load the ERI file from a File System file + * + * In this case the a Phone Support Tool to update the ERI file must be provided + * to the Operator + */ + private void loadEriFileFromFileSystem() { + // NOT IMPLEMENTED, Chipset vendor/Operator specific + } + + /** + * Load the ERI file from the application framework resources encoded in XML + * + */ + private void loadEriFileFromXml() { + Resources r = mContext.getResources(); + XmlResourceParser parser = r.getXml(com.android.internal.R.xml.eri); + try { + XmlUtils.beginDocument(parser, "EriFile"); + mEriFile.mVersionNumber = Integer.parseInt( + parser.getAttributeValue(null, "VersionNumber")); + mEriFile.mNumberOfEriEntries = Integer.parseInt( + parser.getAttributeValue(null, "NumberOfEriEntries")); + mEriFile.mEriFileType = Integer.parseInt( + parser.getAttributeValue(null, "EriFileType")); + + int parsedEriEntries = 0; + while(true) { + XmlUtils.nextElement(parser); + String name = parser.getName(); + if (name == null) { + if (parsedEriEntries != mEriFile.mNumberOfEriEntries) + Log.e(LOG_TAG, "Error Parsing ERI file: " + mEriFile.mNumberOfEriEntries + + " defined, " + parsedEriEntries + " parsed!"); + break; + } else if (name.equals("CallPromptId")) { + int id = Integer.parseInt(parser.getAttributeValue(null, "Id")); + String text = parser.getAttributeValue(null, "CallPromptText"); + if (id >= 0 && id <= 2) { + mEriFile.mCallPromptId[id] = text; + } else { + Log.e(LOG_TAG, "Error Parsing ERI file: found" + id + " CallPromptId"); + } + + } else if (name.equals("EriInfo")) { + int roamingIndicator = Integer.parseInt( + parser.getAttributeValue(null, "RoamingIndicator")); + int iconIndex = Integer.parseInt(parser.getAttributeValue(null, "IconIndex")); + int iconMode = Integer.parseInt(parser.getAttributeValue(null, "IconMode")); + String eriText = parser.getAttributeValue(null, "EriText"); + int callPromptId = Integer.parseInt( + parser.getAttributeValue(null, "CallPromptId")); + int alertId = Integer.parseInt(parser.getAttributeValue(null, "AlertId")); + parsedEriEntries++; + mEriFile.mRoamIndTable.put(roamingIndicator, new EriInfo (roamingIndicator, + iconIndex, iconMode, eriText, callPromptId, alertId)); + } + } + + isEriFileLoaded = true; + + } catch (Exception e) { + Log.e(LOG_TAG, "Got exception while loading ERI file.", e); + } finally { + parser.close(); + } + } + + /** + * Returns the version of the ERI file + * + */ + public int getEriFileVersion() { + return mEriFile.mVersionNumber; + } + + /** + * Returns the number of ERI entries parsed + * + */ + public int getEriNumberOfEntries() { + return mEriFile.mNumberOfEriEntries; + } + + /** + * Returns the ERI file type value ( 0 for Phase 0, 1 for Phase 1) + * + */ + public int getEriFileType() { + return mEriFile.mEriFileType; + } + + /** + * Returns if the ERI file has been loaded + * + */ + public boolean isEriFileLoaded() { + return isEriFileLoaded; + } + + /** + * Returns the EriInfo record associated with roamingIndicator + * or null if the entry is not found + */ + public EriInfo getEriInfo(int roamingIndicator) { + if (mEriFile.mRoamIndTable.containsKey(roamingIndicator)) { + return mEriFile.mRoamIndTable.get(roamingIndicator); + } else { + return null; + } + } +} diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java index 9de6c42..3e2a29b 100644 --- a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java @@ -68,7 +68,12 @@ public final class RuimFileHandler extends IccFileHandler { } protected String getEFPath(int efid) { - // TODO(): Implement for CDMA EFs. + switch(efid) { + case EF_SMS: + case EF_CST: + case EF_RUIM_SPN: + return MF_SIM + DF_CDMA; + } return getCommonIccEFPath(efid); } diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java index b18a3f1..321824f 100644 --- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java @@ -49,13 +49,12 @@ public final class RuimRecords extends IccRecords { private static final boolean DBG = true; //***** Instance Variables - String imsi_m; - String mdn = null; // My mobile number - String h_sid; - String h_nid; - String min2_min1; // 10 digit MIN value MIN2+MIN1 NEWRIL:TODO currently unused - // is not initialized + private String mImsi; // TODO(Teleca): to be checked, if this should be removed! + private String mMyMobileNumber; + private String mSid; // TODO(Teleca): Unused should this be removed + private String mNid; // TODO(Teleca): Unused should this be removed + private String mMin2Min1; //***** Event Constants @@ -63,6 +62,7 @@ public final class RuimRecords extends IccRecords { private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2; private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4; private static final int EVENT_GET_ICCID_DONE = 5; + private static final int EVENT_NV_READY = 9; private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10; private static final int EVENT_UPDATE_DONE = 14; private static final int EVENT_GET_SST_DONE = 17; @@ -74,8 +74,6 @@ public final class RuimRecords extends IccRecords { private static final int EVENT_RUIM_REFRESH = 31; - //***** Constructor - RuimRecords(CDMAPhone p) { super(p); @@ -88,6 +86,7 @@ public final class RuimRecords extends IccRecords { p.mCM.registerForRUIMReady(this, EVENT_RUIM_READY, null); + p.mCM.registerForNVReady(this, EVENT_NV_READY, null); p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); // NOTE the EVENT_SMS_ON_RUIM is not registered p.mCM.setOnIccRefresh(this, EVENT_RUIM_REFRESH, null); @@ -104,10 +103,12 @@ public final class RuimRecords extends IccRecords { phone.mCM.unSetOnIccRefresh(this); } + @Override protected void finalize() { if(DBG) Log.d(LOG_TAG, "RuimRecords finalized"); } + @Override protected void onRadioOffOrNotAvailable() { countVoiceMessages = 0; mncLength = 0; @@ -124,17 +125,20 @@ public final class RuimRecords extends IccRecords { recordsRequested = false; } - //***** Public Methods - /** Returns null if RUIM is not yet ready */ public String getIMSI_M() { - return imsi_m; + return mImsi; } public String getMdnNumber() { - return mdn; + return mMyMobileNumber; + } + + public String getMin() { + return mMin2Min1; } + @Override public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){ // In CDMA this is Operator/OEM dependent AsyncResult.forMessage((onComplete)).exception = @@ -148,6 +152,7 @@ public final class RuimRecords extends IccRecords { * @param fileChanged indicates whether any files changed * @param fileList if non-null, a list of EF files that changed */ + @Override public void onRefresh(boolean fileChanged, int[] fileList) { if (fileChanged) { // A future optimization would be to inspect fileList and @@ -157,11 +162,12 @@ public final class RuimRecords extends IccRecords { } } - /** Returns the 5 or 6 digit MCC/MNC of the operator that + /** + * Returns the 5 or 6 digit MCC/MNC of the operator that * provided the RUIM card. Returns null of RUIM is not yet ready */ - String getRUIMOperatorNumeric() { - if (imsi_m == null) { + public String getRUIMOperatorNumeric() { + if (mImsi == null) { return null; } @@ -169,7 +175,7 @@ public final class RuimRecords extends IccRecords { // Length = length of MCC + length of MNC // TODO: change spec name // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3) - return imsi_m.substring(0, 3 + mncLength); + return mImsi.substring(0, 3 + mncLength); } // Guess the MNC length based on the MCC if we don't @@ -177,12 +183,12 @@ public final class RuimRecords extends IccRecords { int mcc; - mcc = Integer.parseInt(imsi_m.substring(0,3)); + mcc = Integer.parseInt(mImsi.substring(0,3)); - return imsi_m.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc)); + return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc)); } - //***** Overridden from Handler + @Override public void handleMessage(Message msg) { AsyncResult ar; @@ -194,7 +200,9 @@ public final class RuimRecords extends IccRecords { case EVENT_RUIM_READY: onRuimReady(); break; - + case EVENT_NV_READY: + onNvReady(); + break; case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: onRadioOffOrNotAvailable(); break; @@ -212,14 +220,12 @@ public final class RuimRecords extends IccRecords { break; } - mdn = localTemp[0]; - h_sid = localTemp[1]; - h_nid = localTemp[2]; - if (localTemp.length >= 3) { // NEWRIL:TODO remove when new ril always returns min2_min1 - min2_min1 = localTemp[3]; - } + mMyMobileNumber = localTemp[0]; + mSid = localTemp[1]; + mNid = localTemp[2]; + mMin2Min1 = localTemp[3]; - Log.d(LOG_TAG, "MDN: " + mdn); + Log.d(LOG_TAG, "MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1); break; @@ -277,6 +283,7 @@ public final class RuimRecords extends IccRecords { } } + @Override protected void onRecordLoaded() { // One record loaded successfully or failed, In either case // we need to update the recordsToLoad count @@ -290,6 +297,7 @@ public final class RuimRecords extends IccRecords { } } + @Override protected void onAllRecordsLoaded() { Log.d(LOG_TAG, "RuimRecords: record load complete"); @@ -301,9 +309,6 @@ public final class RuimRecords extends IccRecords { RuimCard.INTENT_VALUE_ICC_LOADED, null); } - - //***** Private Methods - private void onRuimReady() { /* broadcast intent ICC_READY here so that we can make sure READY is sent before IMSI ready @@ -318,6 +323,11 @@ public final class RuimRecords extends IccRecords { } + private void onNvReady() { + phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); + + } + private void fetchRuimRecords() { recordsRequested = true; @@ -391,9 +401,9 @@ public final class RuimRecords extends IccRecords { } } + @Override protected void log(String s) { Log.d(LOG_TAG, "[RuimRecords] " + s); } } - diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 343a22e..b2083ed 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -277,6 +277,15 @@ public class SmsMessage extends SmsMessageBase { } /** + * TODO(cleanup): why do getSubmitPdu methods take an scAddr input + * and do nothing with it? GSM allows us to specify a SC (eg, + * when responding to an SMS that explicitly requests the response + * is sent to a specific SC), or pass null to use the default + * value. Is there no similar notion in CDMA? Or do we just not + * have it hooked up? + */ + + /** * Get an SMS-SUBMIT PDU for a destination address and a message * * @param scAddr Service Centre address. Null means use default. @@ -290,88 +299,53 @@ public class SmsMessage extends SmsMessageBase { * Returns null on encode error. * @hide */ - public static SubmitPdu getSubmitPdu(String scAddr, - String destAddr, String message, - boolean statusReportRequested, byte[] headerData) { + public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message, + boolean statusReportRequested, SmsHeader smsHeader) { + /** - * TODO(cleanup): why does this method take an scAddr input - * and do nothing with it? GSM allows us to specify a SC (eg, - * when responding to an SMS that explicitly requests the - * response is sent to a specific SC), or pass null to use the - * default value. Is there no similar notion in CDMA? Or do - * we just not have it hooked up? + * TODO(cleanup): Do we really want silent failure like this? + * Would it not be much more reasonable to make sure we don't + * call this function if we really want nothing done? */ - if (message == null || destAddr == null) { return null; } UserData uData = new UserData(); uData.payloadStr = message; - if(headerData != null) { - /** - * TODO(cleanup): we force the outside to deal with _all_ - * of the raw details of properly constructing serialized - * headers, unserialze here, and then promptly reserialze - * during encoding -- rather undesirable. - */ - uData.userDataHeader = SmsHeader.parse(headerData); - } - - return privateGetSubmitPdu(destAddr, statusReportRequested, uData, (headerData == null)); - } - - - /** - * Get an SMS-SUBMIT PDU for a destination address and a message - * - * @param scAddress Service Centre address. Null means use default. - * @return a <code>SubmitPdu</code> containing the encoded SC - * address, if applicable, and the encoded message. - * Returns null on encode error. - */ - public static SubmitPdu getSubmitPdu(String scAddress, - String destinationAddress, String message, - boolean statusReportRequested) { - return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, null); + uData.userDataHeader = smsHeader; + return privateGetSubmitPdu(destAddr, statusReportRequested, uData); } /** * Get an SMS-SUBMIT PDU for a data message to a destination address & port * - * @param scAddress Service Centre address. null == use default - * @param destinationAddress the address of the destination for the message - * @param destinationPort the port to deliver the message to at the + * @param scAddr Service Centre address. null == use default + * @param destAddr the address of the destination for the message + * @param destPort the port to deliver the message to at the * destination * @param data the data for the message * @return a <code>SubmitPdu</code> containing the encoded SC * address, if applicable, and the encoded message. * Returns null on encode error. */ - public static SubmitPdu getSubmitPdu(String scAddress, - String destAddr, short destinationPort, byte[] data, - boolean statusReportRequested) { + public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, short destPort, + byte[] data, boolean statusReportRequested) { /** - * TODO(cleanup): if we had properly exposed SmsHeader - * information, this mess of many getSubmitPdu public - * interface methods that currently pollute the api could have - * been much more cleanly collapsed into one. + * TODO(cleanup): this is not a general-purpose SMS creation + * method, but rather something specialized to messages + * containing OCTET encoded (meaning non-human-readable) user + * data. The name should reflect that, and not just overload. */ - /** - * TODO(cleanup): header serialization should be put somewhere - * canonical to allow proper debugging and reuse. - */ - byte[] destPort = new byte[4]; - destPort[0] = (byte) ((destinationPort >> 8) & 0xFF); // MSB of destination port - destPort[1] = (byte) (destinationPort & 0xFF); // LSB of destination port - destPort[2] = 0x00; // MSB of originating port - destPort[3] = 0x00; // LSB of originating port + SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); + portAddrs.destPort = destPort; + portAddrs.origPort = 0; + portAddrs.areEightBits = false; + SmsHeader smsHeader = new SmsHeader(); - smsHeader.add( - new SmsHeader.Element(SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT, destPort)); - smsHeader.nbrOfHeaders = smsHeader.getElements().size(); + smsHeader.portAddrs = portAddrs; UserData uData = new UserData(); uData.userDataHeader = smsHeader; @@ -379,7 +353,7 @@ public class SmsMessage extends SmsMessageBase { uData.msgEncodingSet = true; uData.payload = data; - return privateGetSubmitPdu(destAddr, statusReportRequested, uData, true); + return privateGetSubmitPdu(destAddr, statusReportRequested, uData); } static class PduParser { @@ -445,31 +419,23 @@ public class SmsMessage extends SmsMessageBase { * {@inheritDoc} */ public boolean isMWIClearMessage() { - if ((mBearerData != null) && (0 == mBearerData.numberOfMessages)) { - return true; - } - return false; + return ((mBearerData != null) && (mBearerData.numberOfMessages == 0)); } /** * {@inheritDoc} */ public boolean isMWISetMessage() { - if ((mBearerData != null) && (mBearerData.numberOfMessages >0)) { - return true; - } - return false; + return ((mBearerData != null) && (mBearerData.numberOfMessages > 0)); } /** * {@inheritDoc} */ public boolean isMwiDontStore() { - if ((mBearerData != null) && (mBearerData.numberOfMessages >0) - && (null == mBearerData.userData)) { - return true; - } - return false; + return ((mBearerData != null) && + (mBearerData.numberOfMessages > 0) && + (mBearerData.userData == null)); } /** @@ -478,7 +444,7 @@ public class SmsMessage extends SmsMessageBase { * shifted to the bits 31-16. */ public int getStatus() { - return(status<<16); + return (status << 16); } /** @@ -518,7 +484,7 @@ public class SmsMessage extends SmsMessageBase { */ private void parsePdu(byte[] pdu) { ByteArrayInputStream bais = new ByteArrayInputStream(pdu); - DataInputStream dis = new DataInputStream(new BufferedInputStream(bais)); + DataInputStream dis = new DataInputStream(bais); byte length; int bearerDataLength; SmsEnvelope env = new SmsEnvelope(); @@ -568,58 +534,23 @@ public class SmsMessage extends SmsMessageBase { protected void parseSms() { mBearerData = BearerData.decode(mEnvelope.bearerData); messageRef = mBearerData.messageId; + if (mBearerData.userData != null) { + userData = mBearerData.userData.payload; + userDataHeader = mBearerData.userData.userDataHeader; + messageBody = mBearerData.userData.payloadStr; + } - // TP-Message-Type-Indicator - // (See 3GPP2 C.S0015-B, v2, 4.5.1) - int messageType = mBearerData.messageType; - - switch (messageType) { + // TP-Message-Type-Indicator (See 3GPP2 C.S0015-B, v2, 4.5.1) + switch (mBearerData.messageType) { case BearerData.MESSAGE_TYPE_USER_ACK: case BearerData.MESSAGE_TYPE_READ_ACK: case BearerData.MESSAGE_TYPE_DELIVER: - // Deliver (mobile-terminated only) - parseSmsDeliver(); - break; case BearerData.MESSAGE_TYPE_DELIVERY_ACK: - parseSmsDeliveryAck(); break; - default: - // the rest of these - throw new RuntimeException("Unsupported message type: " + messageType); - } - } - - /** - * TODO(cleanup): why are there two nearly identical functions - * below? More rubbish... - */ - - /** - * Parses a SMS-DELIVER message. (mobile-terminated only) - * See 3GPP2 C.S0015-B, v2, 4.4.1 - */ - private void parseSmsDeliver() { - if (originatingAddress != null) { - originatingAddress.address = new String(originatingAddress.origBytes); - if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: " - + originatingAddress.address); - } - - if (mBearerData.timeStamp != null) { - scTimeMillis = PduParser.getSCTimestampMillis(mBearerData.timeStamp); + throw new RuntimeException("Unsupported message type: " + mBearerData.messageType); } - if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis); - - parseUserData(mBearerData.userData); - } - - /** - * Parses a SMS-DELIVER message. (mobile-terminated only) - * See 3GPP2 C.S0015-B, v2, 4.4.1 - */ - private void parseSmsDeliveryAck() { if (originatingAddress != null) { originatingAddress.address = new String(originatingAddress.origBytes); if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: " @@ -632,26 +563,13 @@ public class SmsMessage extends SmsMessageBase { if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis); - if (mBearerData.errorClass != BearerData.ERROR_UNDEFINED) { + // TODO(Teleca): do we really want this test to occur only for DELIVERY_ACKs? + if ((mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) && + (mBearerData.errorClass != BearerData.ERROR_UNDEFINED)) { status = mBearerData.errorClass << 8; status |= mBearerData.messageStatus; } - parseUserData(mBearerData.userData); - } - - /** - * Copy parsed user data out from internal datastructures. - */ - private void parseUserData(UserData uData) { - if (uData == null) { - return; - } - - userData = uData.payload; - userDataHeader = uData.userDataHeader; - messageBody = uData.payloadStr; - if (messageBody != null) { if (Config.LOGV) Log.v(LOG_TAG, "SMS message body: '" + messageBody + "'"); parseMessageBody(); @@ -708,7 +626,7 @@ public class SmsMessage extends SmsMessageBase { * @return byte stream for SubmitPdu. */ private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested, - UserData userData, boolean useNewId) { + UserData userData) { /** * TODO(cleanup): give this function a more meaningful name. @@ -720,7 +638,7 @@ public class SmsMessage extends SmsMessageBase { BearerData bearerData = new BearerData(); bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; - if (useNewId) setNextMessageId(); + if (userData != null) setNextMessageId(); bearerData.messageId = nextMessageId; bearerData.deliveryAckReq = statusReportRequested; @@ -812,6 +730,15 @@ public class SmsMessage extends SmsMessageBase { dos.write(env.bearerData, 0, env.bearerData.length); dos.close(); + /** + * TODO(cleanup) -- This is the only place where mPdu is + * defined, and this is not obviously the only place where + * it needs to be defined. It would be much nicer if + * accessing the serialized representation used a less + * fragile mechanism. Maybe the getPdu method could + * generate a representation if there was not yet one? + */ + mPdu = baos.toByteArray(); } catch (IOException ex) { Log.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex); diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java index e64d022..05c8c9d 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java @@ -189,8 +189,12 @@ public final class BearerData{ public int messageStatus = STATUS_UNDEFINED; /** - * 1-bit value that indicates whether a User Data Header is present. + * 1-bit value that indicates whether a User Data Header (UDH) is present. * (See 3GPP2 C.S0015-B, v2, 4.5.1) + * + * NOTE: during encoding, this value will be set based on the + * presence of a UDH in the structured data, any existing setting + * will be overwritten. */ public boolean hasUserDataHeader; @@ -248,25 +252,27 @@ public final class BearerData{ @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("BearerData:\n"); - builder.append(" messageType: " + messageType + "\n"); - builder.append(" messageId: " + (int)messageId + "\n"); - builder.append(" priority: " + (priorityIndicatorSet ? priority : "not set") + "\n"); - builder.append(" privacy: " + (privacyIndicatorSet ? privacy : "not set") + "\n"); - builder.append(" alert: " + (alertIndicatorSet ? alert : "not set") + "\n"); - builder.append(" displayMode: " + (displayModeSet ? displayMode : "not set") + "\n"); - builder.append(" language: " + (languageIndicatorSet ? language : "not set") + "\n"); - builder.append(" errorClass: " + (messageStatusSet ? errorClass : "not set") + "\n"); - builder.append(" msgStatus: " + (messageStatusSet ? messageStatus : "not set") + "\n"); - builder.append(" hasUserDataHeader: " + hasUserDataHeader + "\n"); - builder.append(" timeStamp: " + timeStamp + "\n"); - builder.append(" userAckReq: " + userAckReq + "\n"); - builder.append(" deliveryAckReq: " + deliveryAckReq + "\n"); - builder.append(" readAckReq: " + readAckReq + "\n"); - builder.append(" reportReq: " + reportReq + "\n"); - builder.append(" numberOfMessages: " + numberOfMessages + "\n"); - builder.append(" callbackNumber: " + callbackNumber + "\n"); - builder.append(" userData: " + userData + "\n"); + builder.append("BearerData "); + builder.append("{ messageType=" + messageType); + builder.append(", messageId=" + (int)messageId); + builder.append(", priority=" + (priorityIndicatorSet ? priority : "unset")); + builder.append(", privacy=" + (privacyIndicatorSet ? privacy : "unset")); + builder.append(", alert=" + (alertIndicatorSet ? alert : "unset")); + builder.append(", displayMode=" + (displayModeSet ? displayMode : "unset")); + builder.append(", language=" + (languageIndicatorSet ? language : "unset")); + builder.append(", errorClass=" + (messageStatusSet ? errorClass : "unset")); + builder.append(", msgStatus=" + (messageStatusSet ? messageStatus : "unset")); + builder.append(", timeStamp=" + + ((timeStamp != null) ? HexDump.toHexString(timeStamp) : "unset")); + builder.append(", userAckReq=" + userAckReq); + builder.append(", deliveryAckReq=" + deliveryAckReq); + builder.append(", readAckReq=" + readAckReq); + builder.append(", reportReq=" + reportReq); + builder.append(", numberOfMessages=" + numberOfMessages); + builder.append(", callbackNumber=" + callbackNumber); + builder.append(", hasUserDataHeader=" + hasUserDataHeader); + builder.append(", userData=" + userData); + builder.append(" }"); return builder.toString(); } @@ -335,12 +341,19 @@ public final class BearerData{ private static void encodeUserDataPayload(UserData uData) throws CodingException { + byte[] headerData = null; + if (uData.userDataHeader != null) headerData = SmsHeader.toByteArray(uData.userDataHeader); + int headerDataLen = (headerData == null) ? 0 : headerData.length + 1; // + length octet + + byte[] payloadData; if (uData.msgEncodingSet) { if (uData.msgEncoding == UserData.ENCODING_OCTET) { if (uData.payload == null) { Log.e(LOG_TAG, "user data with octet encoding but null payload"); // TODO(code_review): reasonable for fail case? or maybe bail on encoding? - uData.payload = new byte[0]; + payloadData = new byte[0]; + } else { + payloadData = uData.payload; } } else { if (uData.payloadStr == null) { @@ -349,11 +362,11 @@ public final class BearerData{ uData.payloadStr = ""; } if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) { - uData.payload = encode7bitGsm(uData.payloadStr); + payloadData = encode7bitGsm(uData.payloadStr); } else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) { - uData.payload = encode7bitAscii(uData.payloadStr); + payloadData = encode7bitAscii(uData.payloadStr); } else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) { - uData.payload = encodeUtf16(uData.payloadStr); + payloadData = encodeUtf16(uData.payloadStr); } else { throw new CodingException("unsupported user data encoding (" + uData.msgEncoding + ")"); @@ -367,19 +380,28 @@ public final class BearerData{ uData.payloadStr = ""; } try { - uData.payload = encode7bitAscii(uData.payloadStr); + payloadData = encode7bitAscii(uData.payloadStr); uData.msgEncoding = UserData.ENCODING_7BIT_ASCII; } catch (CodingException ex) { - uData.payload = encodeUtf16(uData.payloadStr); + payloadData = encodeUtf16(uData.payloadStr); uData.msgEncoding = UserData.ENCODING_UNICODE_16; } uData.msgEncodingSet = true; uData.numFields = uData.payloadStr.length(); } - if (uData.payload.length > SmsMessage.MAX_USER_DATA_BYTES) { - throw new CodingException("encoded user data too large (" + uData.payload.length + + + int totalLength = payloadData.length + headerDataLen; + if (totalLength > SmsMessage.MAX_USER_DATA_BYTES) { + throw new CodingException("encoded user data too large (" + totalLength + " > " + SmsMessage.MAX_USER_DATA_BYTES + " bytes)"); } + + uData.payload = new byte[totalLength]; + if (headerData != null) { + uData.payload[0] = (byte)headerData.length; + System.arraycopy(headerData, 0, uData.payload, 1, headerData.length); + } + System.arraycopy(payloadData, 0, uData.payload, headerDataLen, payloadData.length); } private static void encodeUserData(BearerData bData, BitwiseOutputStream outStream) @@ -394,11 +416,6 @@ public final class BearerData{ * */ int dataBits = (bData.userData.payload.length * 8) - bData.userData.paddingBits; - byte[] headerData = null; - if (bData.hasUserDataHeader) { - headerData = bData.userData.userDataHeader.toByteArray(); - dataBits += headerData.length * 8; - } int paramBits = dataBits + 13; if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) || (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) { @@ -413,7 +430,6 @@ public final class BearerData{ outStream.write(8, bData.userData.msgType); } outStream.write(8, bData.userData.numFields); - if (headerData != null) outStream.writeByteArray(headerData.length * 8, headerData); outStream.writeByteArray(dataBits, bData.userData.payload); if (paddingBits > 0) outStream.write(paddingBits, 0); } @@ -557,6 +573,8 @@ public final class BearerData{ * @return data byta array of raw encoded SMS bearer data. */ public static byte[] encode(BearerData bData) { + bData.hasUserDataHeader = ((bData.userData != null) && + (bData.userData.userDataHeader != null)); try { BitwiseOutputStream outStream = new BitwiseOutputStream(200); outStream.write(8, SUBPARAM_MESSAGE_IDENTIFIER); @@ -723,11 +741,11 @@ public final class BearerData{ { int offset = 0; if (hasUserDataHeader) { - int udhLen = userData.payload[0]; - offset += udhLen; + int udhLen = userData.payload[0] & 0x00FF; + offset += udhLen + 1; byte[] headerData = new byte[udhLen]; System.arraycopy(userData.payload, 1, headerData, 0, udhLen); - userData.userDataHeader = SmsHeader.parse(headerData); + userData.userDataHeader = SmsHeader.fromByteArray(headerData); } switch (userData.msgEncoding) { case UserData.ENCODING_OCTET: diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java index 02e94ad..7c37bc2 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java @@ -93,14 +93,15 @@ public class UserData { @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("UserData:\n"); - builder.append(" msgEncoding: " + (msgEncodingSet ? msgEncoding : "not set") + "\n"); - builder.append(" msgType: " + msgType + "\n"); - builder.append(" paddingBits: " + paddingBits + "\n"); - builder.append(" numFields: " + (int)numFields + "\n"); - builder.append(" userDataHeader: " + userDataHeader + "\n"); - builder.append(" payload: '" + HexDump.toHexString(payload) + "'"); - builder.append(", payloadStr: '" + payloadStr + "'"); + builder.append("UserData "); + builder.append("{ msgEncoding=" + (msgEncodingSet ? msgEncoding : "unset")); + builder.append(", msgType=" + msgType); + builder.append(", paddingBits=" + paddingBits); + builder.append(", numFields=" + (int)numFields); + builder.append(", userDataHeader=" + userDataHeader); + builder.append(", payload='" + HexDump.toHexString(payload) + "'"); + builder.append(", payloadStr='" + payloadStr + "'"); + builder.append(" }"); return builder.toString(); } diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index a2d3c5e..3459dcd 100755 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -34,6 +34,7 @@ import android.provider.Telephony; import android.telephony.CellLocation; import android.telephony.PhoneNumberUtils; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import android.text.TextUtils; import android.util.Log; @@ -67,6 +68,7 @@ import com.android.internal.telephony.PhoneNotifier; import com.android.internal.telephony.PhoneProxy; import com.android.internal.telephony.PhoneSubInfo; import com.android.internal.telephony.RILConstants; +import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.gsm.stk.StkService; import com.android.internal.telephony.test.SimulatedRadioControl; import com.android.internal.telephony.IccVmNotSupportedException; @@ -203,9 +205,9 @@ public class GSMPhone extends PhoneBase { } } - //Change the system setting - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.CURRENT_ACTIVE_PHONE, RILConstants.GSM_PHONE); + //Change the system property + SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE, + new Integer(RILConstants.GSM_PHONE).toString()); } public void dispose() { @@ -285,9 +287,8 @@ public class GSMPhone extends PhoneBase { return mDataConnection.getActiveApnString(); } - public int - getSignalStrengthASU() { - return mSST.rssi == 99 ? -1 : mSST.rssi; + public SignalStrength getSignalStrength() { + return mSST.mSignalStrength; } public boolean @@ -825,6 +826,11 @@ public class GSMPhone extends PhoneBase { } public void + sendBurstDtmf(String dtmfString) { + Log.e(LOG_TAG, "[GSMPhone] sendBurstDtmf() is a CDMA method"); + } + + public void setRadioPower(boolean power) { mSST.setRadioPower(power); } @@ -832,21 +838,21 @@ public class GSMPhone extends PhoneBase { private void storeVoiceMailNumber(String number) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences.Editor editor = sp.edit(); - editor.putString(VM_NUMBER, number); + editor.putString(VM_NUMBER, number); editor.commit(); setVmSimImsi(getSubscriberId()); } public String getVoiceMailNumber() { // Read from the SIM. If its null, try reading from the shared preference area. - String number = mSIMRecords.getVoiceMailNumber(); + String number = mSIMRecords.getVoiceMailNumber(); if (TextUtils.isEmpty(number)) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); number = sp.getString(VM_NUMBER, null); - } + } return number; } - + private String getVmSimImsi() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); return sp.getString(VM_SIM_IMSI, null); @@ -858,7 +864,7 @@ public class GSMPhone extends PhoneBase { editor.putString(VM_SIM_IMSI, imsi); editor.commit(); } - + public String getVoiceMailAlphaTag() { String ret; @@ -872,6 +878,11 @@ public class GSMPhone extends PhoneBase { return ret; } + public String getMin() { + Log.e(LOG_TAG, "[GSMPhone] getMin() is a CDMA method"); + return "0"; + } + public String getDeviceId() { return mImei; } @@ -922,13 +933,13 @@ public class GSMPhone extends PhoneBase { public void setVoiceMailNumber(String alphaTag, String voiceMailNumber, Message onComplete) { - - Message resp; + + Message resp; mVmNumber = voiceMailNumber; resp = h.obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete); mSIMRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp); } - + private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) { switch (commandInterfaceCFReason) { case CF_REASON_UNCONDITIONAL: @@ -1307,11 +1318,11 @@ public class GSMPhone extends PhoneBase { case EVENT_SIM_RECORDS_LOADED: updateCurrentCarrierInProvider(); - + // Check if this is a different SIM than the previous one. If so unset the // voice mail number. String imsi = getVmSimImsi(); - if (imsi != null && !getSubscriberId().equals(imsi)) { + if (imsi != null && !getSubscriberId().equals(imsi)) { storeVoiceMailNumber(null); setVmSimImsi(null); } @@ -1393,7 +1404,7 @@ public class GSMPhone extends PhoneBase { onComplete.sendToTarget(); } break; - + case EVENT_SET_VM_NUMBER_DONE: ar = (AsyncResult)msg.obj; if (IccVmNotSupportedException.class.isInstance(ar.exception)) { @@ -1407,7 +1418,7 @@ public class GSMPhone extends PhoneBase { } break; - + case EVENT_GET_CALL_FORWARD_DONE: ar = (AsyncResult)msg.obj; if (ar.exception == null) { @@ -1450,7 +1461,7 @@ public class GSMPhone extends PhoneBase { /** * Sets the "current" field in the telephony provider according to the SIM's operator - * + * * @return true for success; false otherwise. */ boolean updateCurrentCarrierInProvider() { diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 9e6ebc4..1d7aaf1 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -50,6 +50,7 @@ import android.text.TextUtils; import android.util.EventLog; import android.util.Log; +import com.android.internal.telephony.DataCallState; import com.android.internal.telephony.DataConnection; import com.android.internal.telephony.DataConnection.FailCause; import com.android.internal.telephony.DataConnectionTracker; @@ -779,7 +780,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } private boolean - pdpStatesHasCID (ArrayList<PDPContextState> states, int cid) { + pdpStatesHasCID (ArrayList<DataCallState> states, int cid) { for (int i = 0, s = states.size() ; i < s ; i++) { if (states.get(i).cid == cid) return true; } @@ -788,9 +789,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } private boolean - pdpStatesHasActiveCID (ArrayList<PDPContextState> states, int cid) { + pdpStatesHasActiveCID (ArrayList<DataCallState> states, int cid) { for (int i = 0, s = states.size() ; i < s ; i++) { - if (states.get(i).cid == cid) return (states.get(i).active != 0); + if ((states.get(i).cid == cid) && (states.get(i).active != 0)) { + return true; + } } return false; @@ -825,9 +828,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { * previous state */ protected void onPdpStateChanged (AsyncResult ar, boolean explicitPoll) { - ArrayList<PDPContextState> pdpStates; + ArrayList<DataCallState> pdpStates; - pdpStates = (ArrayList<PDPContextState>)(ar.result); + pdpStates = (ArrayList<DataCallState>)(ar.result); if (ar.exception != null) { // This is probably "radio not available" or something diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java index 3e73caf..699142a 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java @@ -39,8 +39,11 @@ import java.util.HashMap; final class GsmSMSDispatcher extends SMSDispatcher { private static final String TAG = "GSM"; + private GSMPhone mGsmPhone; + GsmSMSDispatcher(GSMPhone phone) { super(phone); + mGsmPhone = phone; } /** @@ -97,110 +100,41 @@ final class GsmSMSDispatcher extends SMSDispatcher { // Special case the message waiting indicator messages if (sms.isMWISetMessage()) { - ((GSMPhone) mPhone).updateMessageWaitingIndicator(true); - - if (sms.isMwiDontStore()) { - handled = true; - } - + mGsmPhone.updateMessageWaitingIndicator(true); + handled |= sms.isMwiDontStore(); if (Config.LOGD) { - Log.d(TAG, - "Received voice mail indicator set SMS shouldStore=" - + !handled); + Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled); } } else if (sms.isMWIClearMessage()) { - ((GSMPhone) mPhone).updateMessageWaitingIndicator(false); - - if (sms.isMwiDontStore()) { - handled = true; - } - + mGsmPhone.updateMessageWaitingIndicator(false); + handled |= sms.isMwiDontStore(); if (Config.LOGD) { - Log.d(TAG, - "Received voice mail indicator clear SMS shouldStore=" - + !handled); + Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled); } } - if (handled) { - return; - } + if (handled) return; - // Parse the headers to see if this is partial, or port addressed - int referenceNumber = -1; - int count = 0; - int sequence = 0; - int destPort = -1; - - SmsHeader header = sms.getUserDataHeader(); - if (header != null) { - for (SmsHeader.Element element : header.getElements()) { - try { - switch (element.getID()) { - case SmsHeader.CONCATENATED_8_BIT_REFERENCE: { - byte[] data = element.getData(); - - referenceNumber = data[0] & 0xff; - count = data[1] & 0xff; - sequence = data[2] & 0xff; - - // Per TS 23.040, 9.2.3.24.1: If the count is zero, sequence - // is zero, or sequence > count, ignore the entire element - if (count == 0 || sequence == 0 || sequence > count) { - referenceNumber = -1; - } - break; - } - - case SmsHeader.CONCATENATED_16_BIT_REFERENCE: { - byte[] data = element.getData(); - - referenceNumber = (data[0] & 0xff) * 256 + (data[1] & 0xff); - count = data[2] & 0xff; - sequence = data[3] & 0xff; - - // Per TS 23.040, 9.2.3.24.8: If the count is zero, sequence - // is zero, or sequence > count, ignore the entire element - if (count == 0 || sequence == 0 || sequence > count) { - referenceNumber = -1; - } - break; - } - - case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: { - byte[] data = element.getData(); - - destPort = (data[0] & 0xff) << 8; - destPort |= (data[1] & 0xff); - - break; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - Log.e(TAG, "Bad element in header", e); - return; // TODO: NACK the message or something, don't just discard. - } - } - } - - if (referenceNumber == -1) { - // notify everyone of the message if it isn't partial + SmsHeader smsHeader = sms.getUserDataHeader(); + // See if message is partial or port addressed. + if ((smsHeader == null) || (smsHeader.concatRef == null)) { + // Message is not partial (not part of concatenated sequence). byte[][] pdus = new byte[1][]; pdus[0] = sms.getPdu(); - if (destPort != -1) { - if (destPort == SmsHeader.PORT_WAP_PUSH) { + if (smsHeader != null && smsHeader.portAddrs != null) { + if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) { mWapPush.dispatchWapPdu(sms.getUserData()); } - // The message was sent to a port, so concoct a URI for it - dispatchPortAddressedPdus(pdus, destPort); + // The message was sent to a port, so concoct a URI for it. + dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort); } else { - // It's a normal message, dispatch it + // Normal short and non-port-addressed message, dispatch it. dispatchPdus(pdus); } } else { - // Process the message part - processMessagePart(sms, referenceNumber, sequence, count, destPort); + // Process the message part. + processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs); } } @@ -208,28 +142,30 @@ final class GsmSMSDispatcher extends SMSDispatcher { protected void sendMultipartText(String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { - int ref = ++sConcatenatedRef & 0xff; - - for (int i = 0, count = parts.size(); i < count; i++) { - // build SmsHeader - byte[] data = new byte[3]; - data[0] = (byte) ref; // reference #, unique per message - data[1] = (byte) count; // total part count - data[2] = (byte) (i + 1); // 1-based sequence - SmsHeader header = new SmsHeader(); - header.add(new SmsHeader.Element(SmsHeader.CONCATENATED_8_BIT_REFERENCE, data)); - PendingIntent sentIntent = null; - PendingIntent deliveryIntent = null; + int refNumber = getNextConcatenatedRef() & 0x00FF; + + for (int i = 0, msgCount = parts.size(); i < msgCount; i++) { + SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); + concatRef.refNumber = refNumber; + concatRef.seqNumber = i + 1; // 1-based sequence + concatRef.msgCount = msgCount; + concatRef.isEightBits = false; + SmsHeader smsHeader = new SmsHeader(); + smsHeader.concatRef = concatRef; + + PendingIntent sentIntent = null; if (sentIntents != null && sentIntents.size() > i) { sentIntent = sentIntents.get(i); } + + PendingIntent deliveryIntent = null; if (deliveryIntents != null && deliveryIntents.size() > i) { deliveryIntent = deliveryIntents.get(i); } SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress, - parts.get(i), deliveryIntent != null, header.toByteArray()); + parts.get(i), deliveryIntent != null, SmsHeader.toByteArray(smsHeader)); sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent); } @@ -259,18 +195,16 @@ final class GsmSMSDispatcher extends SMSDispatcher { * to the recipient. The raw pdu of the status report is in the * extended data ("pdu"). */ - private void sendMultipartTextWithPermit(String destinationAddress, + private void sendMultipartTextWithPermit(String destinationAddress, String scAddress, ArrayList<String> parts, - ArrayList<PendingIntent> sentIntents, + ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { - - PendingIntent sentIntent = null; - PendingIntent deliveryIntent = null; - + // check if in service int ss = mPhone.getServiceState().getState(); if (ss != ServiceState.STATE_IN_SERVICE) { for (int i = 0, count = parts.size(); i < count; i++) { + PendingIntent sentIntent = null; if (sentIntents != null && sentIntents.size() > i) { sentIntent = sentIntents.get(i); } @@ -280,26 +214,29 @@ final class GsmSMSDispatcher extends SMSDispatcher { return; } - int ref = ++sConcatenatedRef & 0xff; - - for (int i = 0, count = parts.size(); i < count; i++) { - // build SmsHeader - byte[] data = new byte[3]; - data[0] = (byte) ref; // reference #, unique per message - data[1] = (byte) count; // total part count - data[2] = (byte) (i + 1); // 1-based sequence - SmsHeader header = new SmsHeader(); - header.add(new SmsHeader.Element(SmsHeader.CONCATENATED_8_BIT_REFERENCE, data)); - + int refNumber = getNextConcatenatedRef() & 0x00FF; + + for (int i = 0, msgCount = parts.size(); i < msgCount; i++) { + SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); + concatRef.refNumber = refNumber; + concatRef.seqNumber = i + 1; // 1-based sequence + concatRef.msgCount = msgCount; + concatRef.isEightBits = false; + SmsHeader smsHeader = new SmsHeader(); + smsHeader.concatRef = concatRef; + + PendingIntent sentIntent = null; if (sentIntents != null && sentIntents.size() > i) { sentIntent = sentIntents.get(i); } + + PendingIntent deliveryIntent = null; if (deliveryIntents != null && deliveryIntents.size() > i) { deliveryIntent = deliveryIntents.get(i); } SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress, - parts.get(i), deliveryIntent != null, header.toByteArray()); + parts.get(i), deliveryIntent != null, SmsHeader.toByteArray(smsHeader)); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("smsc", pdus.encodedScAddress); @@ -307,7 +244,7 @@ final class GsmSMSDispatcher extends SMSDispatcher { SmsTracker tracker = SmsTrackerFactory(map, sentIntent, deliveryIntent); sendSms(tracker); - } + } } /** {@inheritDoc} */ @@ -376,4 +313,3 @@ final class GsmSMSDispatcher extends SMSDispatcher { } } - diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index 9ab1002..7a4ea64 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -38,6 +38,7 @@ import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.provider.Telephony.Intents; import android.telephony.ServiceState; +import android.telephony.SignalStrength; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.util.Config; @@ -73,6 +74,14 @@ import java.util.TimeZone; * {@hide} */ final class GsmServiceStateTracker extends ServiceStateTracker { + + /** + * TODO(Teleca): John Huang asks: Will you be adding handling of + * "reason for registration denied in EVENT_POLL_STATE_REGISTRATION? + * I see some handling of this in CdmaServiceStateTracker, but as I + * understand it this field was added at the request of a GSM carrier. + */ + //***** Instance Variables GSMPhone phone; GsmCellLocation cellLoc; @@ -80,9 +89,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker { int mPreferredNetworkType; RestrictedState rs; - int rssi = 99; // signal strength 0-31, 99=unknown - // That's "received signal strength indication" fyi - private int gprsState = ServiceState.STATE_OUT_OF_SERVICE; private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE; @@ -121,7 +127,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { private boolean mStartedGprsRegCheck = false; // Already sent the event-log for no gprs register private boolean mReportedGprsNoReg = false; - + /** * The Notification object given to the NotificationManager. */ @@ -151,9 +157,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker { static final int CS_DISABLED = 1004; // Access Control enables all voice/sms service static final int CS_NORMAL_ENABLED = 1005; // Access Control blocks normal voice/sms service static final int CS_EMERGENCY_ENABLED = 1006; // Access Control blocks emergency call service - + // notification id - static final int PS_NOTIFICATION = 888; //id to update and cancel PS restricted + static final int PS_NOTIFICATION = 888; //id to update and cancel PS restricted static final int CS_NOTIFICATION = 999; //id to update and cancel CS restricted private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) { @@ -177,6 +183,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { cellLoc = new GsmCellLocation(); newCellLoc = new GsmCellLocation(); rs = new RestrictedState(); + mSignalStrength = new SignalStrength(); PowerManager powerManager = (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE); @@ -201,7 +208,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { cr.registerContentObserver( Settings.System.getUriFor(Settings.System.AUTO_TIME), true, mAutoTimeObserver); - setRssiDefaultValues(); + setSignalStrengthDefaultValues(); mNeedToRegForSimLoaded = true; } @@ -280,7 +287,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { * @param obj placed in Message.obj */ /*protected*/ void registerForPsRestrictedEnabled(Handler h, int what, Object obj) { - Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedEnabled "); + Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedEnabled "); Registrant r = new Registrant(h, what, obj); psRestrictEnabledRegistrants.add(r); @@ -300,7 +307,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { * @param obj placed in Message.obj */ /*protected*/ void registerForPsRestrictedDisabled(Handler h, int what, Object obj) { - Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedDisabled "); + Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedDisabled "); Registrant r = new Registrant(h, what, obj); psRestrictDisabledRegistrants.add(r); @@ -308,7 +315,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { r.notifyRegistrant(); } } - + /*protected*/ void unregisterForPsRestrictedDisabled(Handler h) { psRestrictDisabledRegistrants.remove(h); } @@ -506,13 +513,13 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } mStartedGprsRegCheck = false; break; - + case EVENT_RESTRICTED_STATE_CHANGED: // This is a notification from // CommandsInterface.setOnRestrictedStateChanged Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_RESTRICTED_STATE_CHANGED"); - + ar = (AsyncResult) msg.obj; onRestrictedStateChanged(ar); @@ -542,11 +549,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker { EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF, val); } dcTracker.cleanConnectionBeforeRadioOff(); - + // poll data state up to 15 times, with a 100ms delay // totaling 1.5 sec. Normal data disable action will finish in 100ms. for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) { - if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED + if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) { Log.d(LOG_TAG, "Data shutdown complete."); break; @@ -557,7 +564,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { cm.setRadioPower(false, null); } // Otherwise, we're in the desired state } - + protected void updateSpnDisplay() { int rule = phone.mSIMRecords.getDisplayRule(ss.getOperatorNumeric()); String spn = phone.mSIMRecords.getServiceProviderName(); @@ -699,9 +706,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } - private void - setRssiDefaultValues() { - rssi = 99; + private void setSignalStrengthDefaultValues() { + mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, true); } /** @@ -722,7 +728,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { case RADIO_UNAVAILABLE: newSS.setStateOutOfService(); newCellLoc.setStateInvalid(); - setRssiDefaultValues(); + setSignalStrengthDefaultValues(); mGotCountryCode = false; pollStateDone(); @@ -731,7 +737,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { case RADIO_OFF: newSS.setStateOff(); newCellLoc.setStateInvalid(); - setRssiDefaultValues(); + setSignalStrengthDefaultValues(); mGotCountryCode = false; pollStateDone(); @@ -745,10 +751,10 @@ final class GsmServiceStateTracker extends ServiceStateTracker { Log.d(LOG_TAG, "Radio Technology Change ongoing, setting SS to off"); newSS.setStateOff(); newCellLoc.setStateInvalid(); - setRssiDefaultValues(); + setSignalStrengthDefaultValues(); mGotCountryCode = false; - pollStateDone(); + //NOTE: pollStateDone() is not needed in this case break; default: @@ -1044,17 +1050,18 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } /** - * send signal-strength-changed notification if rssi changed + * send signal-strength-changed notification if changed * Called both for solicited and unsolicited signal stength updates */ private void onSignalStrengthResult(AsyncResult ar) { - int oldRSSI = rssi; + SignalStrength oldSignalStrength = mSignalStrength; + int rssi = 99; if (ar.exception != null) { - // 99 = unknown + // -1 = unknown // most likely radio is resetting/disconnected - rssi = 99; + setSignalStrengthDefaultValues(); } else { int[] ints = (int[])ar.result; @@ -1067,13 +1074,16 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } } - if (rssi != oldRSSI) { + mSignalStrength = new SignalStrength(rssi, -1, -1, -1, + -1, -1, -1, true); + + if (!mSignalStrength.equals(oldSignalStrength)) { try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after // POLL_PERIOD_MILLIS) during Radio Technology Change) phone.notifySignalStrength(); } catch (NullPointerException ex) { - Log.d(LOG_TAG, "onSignalStrengthResult() Phone already destroyed: " + ex - + "Signal Stranth not notified"); + log("onSignalStrengthResult() Phone already destroyed: " + ex + + "SignalStrength not notified"); } } } @@ -1089,27 +1099,27 @@ final class GsmServiceStateTracker extends ServiceStateTracker { { Log.d(LOG_TAG, "[DSAC DEB] " + "onRestrictedStateChanged"); RestrictedState newRs = new RestrictedState(); - + Log.d(LOG_TAG, "[DSAC DEB] " + "current rs at enter "+ rs); - + if (ar.exception == null) { int[] ints = (int[])ar.result; int state = ints[0]; - + newRs.setCsEmergencyRestricted( ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) || ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) ); //ignore the normal call and data restricted state before SIM READY - if (phone.getIccCard().getState() == IccCard.State.READY) { + if (phone.getIccCard().getState() == IccCard.State.READY) { newRs.setCsNormalRestricted( ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) || ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) ); newRs.setPsRestricted( (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0); } - - Log.d(LOG_TAG, "[DSAC DEB] " + "new rs "+ newRs); - + + Log.d(LOG_TAG, "[DSAC DEB] " + "new rs "+ newRs); + if (!rs.isPsRestricted() && newRs.isPsRestricted()) { psRestrictEnabledRegistrants.notifyRegistrants(); setNotification(PS_ENABLED); @@ -1117,9 +1127,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker { psRestrictDisabledRegistrants.notifyRegistrants(); setNotification(PS_DISABLED); } - + /** - * There are two kind of cs restriction, normal and emergency. So + * There are two kind of cs restriction, normal and emergency. So * there are 4 x 4 combinations in current and new restricted states * and we only need to notify when state is changed. */ @@ -1129,32 +1139,32 @@ final class GsmServiceStateTracker extends ServiceStateTracker { setNotification(CS_DISABLED); } else if (!newRs.isCsNormalRestricted()) { // remove normal restriction - setNotification(CS_EMERGENCY_ENABLED); + setNotification(CS_EMERGENCY_ENABLED); } else if (!newRs.isCsEmergencyRestricted()) { // remove emergency restriction - setNotification(CS_NORMAL_ENABLED); + setNotification(CS_NORMAL_ENABLED); } } else if (rs.isCsEmergencyRestricted() && !rs.isCsNormalRestricted()) { if (!newRs.isCsRestricted()) { // remove all restriction - setNotification(CS_DISABLED); + setNotification(CS_DISABLED); } else if (newRs.isCsRestricted()) { // enable all restriction setNotification(CS_ENABLED); } else if (newRs.isCsNormalRestricted()) { // remove emergency restriction and enable normal restriction - setNotification(CS_NORMAL_ENABLED); + setNotification(CS_NORMAL_ENABLED); } } else if (!rs.isCsEmergencyRestricted() && rs.isCsNormalRestricted()) { if (!newRs.isCsRestricted()) { // remove all restriction - setNotification(CS_DISABLED); + setNotification(CS_DISABLED); } else if (newRs.isCsRestricted()) { // enable all restriction setNotification(CS_ENABLED); } else if (newRs.isCsEmergencyRestricted()) { // remove normal restriction and enable emergency restriction - setNotification(CS_EMERGENCY_ENABLED); + setNotification(CS_EMERGENCY_ENABLED); } } else { if (newRs.isCsRestricted()) { @@ -1162,10 +1172,10 @@ final class GsmServiceStateTracker extends ServiceStateTracker { setNotification(CS_ENABLED); } else if (newRs.isCsEmergencyRestricted()) { // enable emergency restriction - setNotification(CS_EMERGENCY_ENABLED); + setNotification(CS_EMERGENCY_ENABLED); } else if (newRs.isCsNormalRestricted()) { // enable normal restriction - setNotification(CS_NORMAL_ENABLED); + setNotification(CS_NORMAL_ENABLED); } } @@ -1527,7 +1537,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { /** * Post a notification to NotificationManager for restricted state - * + * * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE */ private void setNotification(int notifyType) { @@ -1546,7 +1556,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { CharSequence details = ""; CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle); int notificationId = CS_NOTIFICATION; - + switch (notifyType) { case PS_ENABLED: notificationId = PS_NOTIFICATION; @@ -1557,24 +1567,24 @@ final class GsmServiceStateTracker extends ServiceStateTracker { break; case CS_ENABLED: details = context.getText(com.android.internal.R.string.RestrictedOnAll);; - break; + break; case CS_NORMAL_ENABLED: details = context.getText(com.android.internal.R.string.RestrictedOnNormal);; - break; + break; case CS_EMERGENCY_ENABLED: details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);; - break; + break; case CS_DISABLED: // do nothing and cancel the notification later - break; + break; } - + Log.d(LOG_TAG, "[DSAC DEB] " + "put notification " + title + " / " +details); mNotification.tickerText = title; - mNotification.setLatestEventInfo(context, title, details, + mNotification.setLatestEventInfo(context, title, details, mNotification.contentIntent); - - NotificationManager notificationManager = (NotificationManager) + + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) { @@ -1585,4 +1595,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker { notificationManager.notify(notificationId, mNotification); } } + + private void log(String s) { + Log.d(LOG_TAG, "[GsmServiceStateTracker] " + s); + } } diff --git a/telephony/java/com/android/internal/telephony/gsm/MccTable.java b/telephony/java/com/android/internal/telephony/gsm/MccTable.java index 6198979..e18da56 100644 --- a/telephony/java/com/android/internal/telephony/gsm/MccTable.java +++ b/telephony/java/com/android/internal/telephony/gsm/MccTable.java @@ -182,7 +182,7 @@ public final class MccTable table.add(new MccEntry(222,"it",2,"Europe/Rome","it")); //Italy table.add(new MccEntry(225,"va",2,"Europe/Rome","it")); //Vatican City State table.add(new MccEntry(226,"ro",2)); //Romania - table.add(new MccEntry(228,"ch",2,"Europe/Zurich","en")); //Switzerland (Confederation of) + table.add(new MccEntry(228,"ch",2,"Europe/Zurich","de")); //Switzerland (Confederation of) table.add(new MccEntry(230,"cz",2,"Europe/Prague","cs")); //Czech Republic table.add(new MccEntry(231,"sk",2)); //Slovak Republic table.add(new MccEntry(232,"at",2,"Europe/Vienna","de")); //Austria diff --git a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java index 88acb1b..3f794a8 100644 --- a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java @@ -95,16 +95,20 @@ public class PdpConnection extends DataConnection { apn.password, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE)); } + private void tearDownData(Message msg) { + if (dataLink != null) { + dataLink.disconnect(); + } + + if (phone.mCM.getRadioState().isOn()) { + phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg)); + } + } + protected void disconnect(Message msg) { onDisconnect = msg; if (state == State.ACTIVE) { - if (dataLink != null) { - dataLink.disconnect(); - } - - if (phone.mCM.getRadioState().isOn()) { - phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg)); - } + tearDownData(msg); } else if (state == State.ACTIVATING) { receivedDisconnectReq = true; } else { @@ -243,7 +247,7 @@ public class PdpConnection extends DataConnection { // Don't bother reporting success if there's already a // pending disconnect request, since DataConnectionTracker // has already updated its state. - disconnect(onDisconnect); + tearDownData(onDisconnect); } else { String[] response = ((String[]) ar.result); cid = Integer.parseInt(response[0]); diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index 867b719..ed61c3f 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -330,9 +330,20 @@ public class SmsMessage extends SmsMessageBase{ public static SubmitPdu getSubmitPdu(String scAddress, String destinationAddress, short destinationPort, byte[] data, boolean statusReportRequested) { - if (data.length > (MAX_USER_DATA_BYTES - 7 /* UDH size */)) { + + SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); + portAddrs.destPort = destinationPort; + portAddrs.origPort = 0; + portAddrs.areEightBits = false; + + SmsHeader smsHeader = new SmsHeader(); + smsHeader.portAddrs = portAddrs; + + byte[] smsHeaderData = SmsHeader.toByteArray(smsHeader); + + if ((data.length + smsHeaderData.length + 1) > MAX_USER_DATA_BYTES) { Log.e(LOG_TAG, "SMS data message may only contain " - + (MAX_USER_DATA_BYTES - 7) + " bytes"); + + (MAX_USER_DATA_BYTES - smsHeaderData.length - 1) + " bytes"); return null; } @@ -348,21 +359,12 @@ public class SmsMessage extends SmsMessageBase{ // (no TP-Validity-Period) - // User data size - bo.write(data.length + 7); - - // User data header size - bo.write(0x06); // header is 6 octets + // Total size + bo.write(data.length + smsHeaderData.length + 1); - // User data header, indicating the destination port - bo.write(SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT); // port - // addressing - // header - bo.write(0x04); // each port is 2 octets - bo.write((destinationPort >> 8) & 0xFF); // MSB of destination port - bo.write(destinationPort & 0xFF); // LSB of destination port - bo.write(0x00); // MSB of originating port - bo.write(0x00); // LSB of originating port + // User data header + bo.write(smsHeaderData.length); + bo.write(smsHeaderData, 0, smsHeaderData.length); // User data bo.write(data, 0, data.length); @@ -562,7 +564,7 @@ public class SmsMessage extends SmsMessageBase{ byte[] udh = new byte[userDataHeaderLength]; System.arraycopy(pdu, offset, udh, 0, userDataHeaderLength); - userDataHeader = SmsHeader.parse(udh); + userDataHeader = SmsHeader.fromByteArray(udh); offset += userDataHeaderLength; int headerBits = (userDataHeaderLength + 1) * 8; diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java index 5c69017..42bb2e0 100644 --- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java +++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java @@ -26,8 +26,8 @@ import android.util.Log; import com.android.internal.telephony.BaseCommands; import com.android.internal.telephony.CommandException; import com.android.internal.telephony.CommandsInterface; +import com.android.internal.telephony.DataCallState; import com.android.internal.telephony.gsm.CallFailCause; -import com.android.internal.telephony.gsm.PDPContextState; import com.android.internal.telephony.gsm.SuppServiceNotification; import com.android.internal.telephony.Phone; @@ -59,7 +59,7 @@ public final class SimulatedCommands extends BaseCommands private final static String SIM_PUK2_CODE = "87654321"; //***** Instance Variables - + SimulatedGsmCallState simulatedCallState; HandlerThread mHandlerThread; SimLockState mSimLockedState; @@ -79,7 +79,7 @@ public final class SimulatedCommands extends BaseCommands ArrayList<Message> pausedResponses = new ArrayList<Message>(); int nextCallFailCause = CallFailCause.NORMAL_CLEARING; - + //***** Constructor public @@ -88,9 +88,9 @@ public final class SimulatedCommands extends BaseCommands mHandlerThread = new HandlerThread("SimulatedCommands"); mHandlerThread.start(); Looper looper = mHandlerThread.getLooper(); - + simulatedCallState = new SimulatedGsmCallState(looper); - + setRadioState(RadioState.RADIO_OFF); mSimLockedState = INITIAL_LOCK_STATE; mSimLockEnabled = (mSimLockedState != SimLockState.NONE); @@ -353,11 +353,11 @@ public final class SimulatedCommands extends BaseCommands public void setSuppServiceNotifications(boolean enable, Message result) { resultSuccess(result, null); - + if (enable && mSsnNotifyOn) { Log.w(LOG_TAG, "Supp Service Notifications already enabled!"); } - + mSsnNotifyOn = enable; } @@ -465,7 +465,7 @@ public final class SimulatedCommands extends BaseCommands unimplemented(result); } - /** + /** * returned message * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure @@ -479,13 +479,13 @@ public final class SimulatedCommands extends BaseCommands resultSuccess(result, simulatedCallState.getDriverCalls()); } else { //Log.i("GSM", "[SimCmds] getCurrentCalls: SIM not ready!"); - resultFail(result, + resultFail(result, new CommandException( CommandException.Error.RADIO_NOT_AVAILABLE)); } } - /** + /** * @deprecated */ public void getPDPContextList(Message result) { @@ -497,13 +497,13 @@ public final class SimulatedCommands extends BaseCommands * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj - * ar.result contains a List of PDPContextState + * ar.result contains a List of DataCallState */ public void getDataCallList(Message result) { - resultSuccess(result, new ArrayList<PDPContextState>(0)); + resultSuccess(result, new ArrayList<DataCallState>(0)); } - /** + /** * returned message * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure @@ -520,7 +520,7 @@ public final class SimulatedCommands extends BaseCommands resultSuccess(result, null); } - /** + /** * returned message * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure @@ -531,7 +531,7 @@ public final class SimulatedCommands extends BaseCommands resultSuccess(result, "012345678901234"); } - /** + /** * returned message * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure @@ -542,7 +542,7 @@ public final class SimulatedCommands extends BaseCommands resultSuccess(result, "012345678901234"); } - /** + /** * returned message * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure @@ -553,7 +553,7 @@ public final class SimulatedCommands extends BaseCommands resultSuccess(result, "99"); } - /** + /** * Hang up one individual connection. * returned message * retMsg.obj = AsyncResult ar @@ -566,7 +566,7 @@ public final class SimulatedCommands extends BaseCommands */ public void hangupConnection (int gsmIndex, Message result) { boolean success; - + success = simulatedCallState.onChld('1', (char)('0'+gsmIndex)); if (!success){ @@ -588,7 +588,7 @@ public final class SimulatedCommands extends BaseCommands */ public void hangupWaitingOrBackground (Message result) { boolean success; - + success = simulatedCallState.onChld('0', '\0'); if (!success){ @@ -600,7 +600,7 @@ public final class SimulatedCommands extends BaseCommands /** * 3GPP 22.030 6.5.5 - * "Releases all active calls (if any exist) and accepts + * "Releases all active calls (if any exist) and accepts * the other (held or waiting) call." * * ar.exception carries exception on failure @@ -609,7 +609,7 @@ public final class SimulatedCommands extends BaseCommands */ public void hangupForegroundResumeBackground (Message result) { boolean success; - + success = simulatedCallState.onChld('1', '\0'); if (!success){ @@ -621,7 +621,7 @@ public final class SimulatedCommands extends BaseCommands /** * 3GPP 22.030 6.5.5 - * "Places all active calls (if any exist) on hold and accepts + * "Places all active calls (if any exist) on hold and accepts * the other (held or waiting) call." * * ar.exception carries exception on failure @@ -630,7 +630,7 @@ public final class SimulatedCommands extends BaseCommands */ public void switchWaitingOrHoldingAndActive (Message result) { boolean success; - + success = simulatedCallState.onChld('2', '\0'); if (!success){ @@ -647,10 +647,10 @@ public final class SimulatedCommands extends BaseCommands * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj * ar.result is null on success and failure - */ + */ public void conference (Message result) { boolean success; - + success = simulatedCallState.onChld('3', '\0'); if (!success){ @@ -682,7 +682,7 @@ public final class SimulatedCommands extends BaseCommands /** * 3GPP 22.030 6.5.5 - * "Places all active calls on hold except call X with which + * "Places all active calls on hold except call X with which * communication shall be supported." */ public void separateConnection (int gsmIndex, Message result) { @@ -703,10 +703,10 @@ public final class SimulatedCommands extends BaseCommands * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj * ar.result is null on success and failure - */ + */ public void acceptCall (Message result) { boolean success; - + success = simulatedCallState.onAnswer(); if (!success){ @@ -716,15 +716,15 @@ public final class SimulatedCommands extends BaseCommands } } - /** + /** * also known as UDUB * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj * ar.result is null on success and failure - */ + */ public void rejectCall (Message result) { boolean success; - + success = simulatedCallState.onChld('0', '\0'); if (!success){ @@ -734,7 +734,7 @@ public final class SimulatedCommands extends BaseCommands } } - /** + /** * cause code returned as Integer in Message.obj.response * Returns integer cause code defined in TS 24.008 * Annex H or closest approximation. @@ -765,11 +765,11 @@ public final class SimulatedCommands extends BaseCommands public void getMute (Message result) {unimplemented(result);} - /** + /** * response.obj is an AsyncResult * response.obj.result is an int[2] - * response.obj.result[0] is received signal strength (0-31, 99) - * response.obj.result[1] is bit error rate (0-7, 99) + * response.obj.result[0] is received signal strength (0-31, 99) + * response.obj.result[1] is bit error rate (0-7, 99) * as defined in TS 27.007 8.5 */ public void getSignalStrength (Message result) { @@ -893,7 +893,7 @@ public final class SimulatedCommands extends BaseCommands * response.obj.result[0] is long alpha or null if unregistered * response.obj.result[1] is short alpha or null if unregistered * response.obj.result[2] is numeric or null if unregistered - */ + */ public void getOperator(Message result) { String[] ret = new String[3]; @@ -908,7 +908,7 @@ public final class SimulatedCommands extends BaseCommands * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj * ar.result is null on success and failure - */ + */ public void sendDtmf(char c, Message result) { resultSuccess(result, null); } @@ -932,10 +932,19 @@ public final class SimulatedCommands extends BaseCommands } /** + * ar.exception carries exception on failure + * ar.userObject contains the orignal value of result.obj + * ar.result is null on success and failure + */ + public void sendBurstDtmf(String dtmfString, Message result) { + resultSuccess(result, null); + } + + /** * smscPDU is smsc address in PDU form GSM BCD format prefixed * by a length byte (as expected by TS 27.005) or NULL for default SMSC * pdu is SMS in PDU format as an ASCII hex string - * less the SMSC address + * less the SMSC address */ public void sendSMS (String smscPDU, String pdu, Message result) {unimplemented(result);} @@ -1040,8 +1049,8 @@ public final class SimulatedCommands extends BaseCommands unimplemented(result); } - /** - * parameters equivilient to 27.007 AT+CRSM command + /** + * parameters equivilient to 27.007 AT+CRSM command * response.obj will be an AsyncResult * response.obj.userObj will be a SimIoResult on success */ @@ -1052,7 +1061,7 @@ public final class SimulatedCommands extends BaseCommands /** * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned". + * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned". * * @param response is callback message */ @@ -1063,46 +1072,46 @@ public final class SimulatedCommands extends BaseCommands * response.obj will be a an int[2] * * response.obj[0] will be TS 27.007 +CLIR parameter 'n' - * 0 presentation indicator is used according to the subscription of the CLIR service - * 1 CLIR invocation - * 2 CLIR suppression + * 0 presentation indicator is used according to the subscription of the CLIR service + * 1 CLIR invocation + * 2 CLIR suppression * * response.obj[1] will be TS 27.007 +CLIR parameter 'm' - * 0 CLIR not provisioned - * 1 CLIR provisioned in permanent mode - * 2 unknown (e.g. no network, etc.) - * 3 CLIR temporary mode presentation restricted - * 4 CLIR temporary mode presentation allowed + * 0 CLIR not provisioned + * 1 CLIR provisioned in permanent mode + * 2 unknown (e.g. no network, etc.) + * 3 CLIR temporary mode presentation restricted + * 4 CLIR temporary mode presentation allowed */ public void getCLIR(Message result) {unimplemented(result);} - + /** * clirMode is one of the CLIR_* constants above * * response.obj is null */ - + public void setCLIR(int clirMode, Message result) {unimplemented(result);} /** * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 0 for disabled, 1 for enabled. + * 0 for disabled, 1 for enabled. * * @param serviceClass is a sum of SERVICE_CLASS_* * @param response is callback message */ - + public void queryCallWaiting(int serviceClass, Message response) { unimplemented(response); } - + /** * @param enable is true to enable, false to disable * @param serviceClass is a sum of SERVICE_CLASS_* * @param response is callback message */ - + public void setCallWaiting(boolean enable, int serviceClass, Message response) { unimplemented(response); @@ -1111,9 +1120,9 @@ public final class SimulatedCommands extends BaseCommands /** * @param action is one of CF_ACTION_* * @param cfReason is one of CF_REASON_* - * @param serviceClass is a sum of SERVICE_CLASSS_* + * @param serviceClass is a sum of SERVICE_CLASSS_* */ - public void setCallForward(int action, int cfReason, int serviceClass, + public void setCallForward(int action, int cfReason, int serviceClass, String number, int timeSeconds, Message result) {unimplemented(result);} /** @@ -1121,7 +1130,7 @@ public final class SimulatedCommands extends BaseCommands * * ((AsyncResult)response.obj).result will be an array of * CallForwardInfo's - * + * * An array of length 0 means "disabled for all codes" */ public void queryCallForwardStatus(int cfReason, int serviceClass, @@ -1155,7 +1164,7 @@ public final class SimulatedCommands extends BaseCommands public void getAvailableNetworks(Message result) {unimplemented(result);} public void getBasebandVersion (Message result) { - resultSuccess(result, "SimulatedCommands"); + resultSuccess(result, "SimulatedCommands"); } /** @@ -1167,7 +1176,7 @@ public final class SimulatedCommands extends BaseCommands public void triggerIncomingUssd(String statusCode, String message) { if (mUSSDRegistrant != null) { String[] result = {statusCode, message}; - mUSSDRegistrant.notifyResult(result); + mUSSDRegistrant.notifyResult(result); } } @@ -1215,7 +1224,7 @@ public final class SimulatedCommands extends BaseCommands //***** SimulatedRadioControl - + /** Start the simulated phone ringing */ public void triggerRing(String number) { @@ -1249,9 +1258,9 @@ public final class SimulatedCommands extends BaseCommands simulatedCallState.setNextDialFailImmediately(b); } - public void + public void setNextCallFailCause(int gsmCause) { - nextCallFailCause = gsmCause; + nextCallFailCause = gsmCause; } public void @@ -1319,7 +1328,7 @@ public final class SimulatedCommands extends BaseCommands private void unimplemented(Message result) { if (result != null) { - AsyncResult.forMessage(result).exception + AsyncResult.forMessage(result).exception = new RuntimeException("Unimplemented"); if (pausedResponseCount > 0) { @@ -1359,13 +1368,13 @@ public final class SimulatedCommands extends BaseCommands unimplemented(response); } - public void + public void getCDMASubscription(Message response) { Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); unimplemented(response); } - public void + public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); unimplemented(response); @@ -1403,7 +1412,7 @@ public final class SimulatedCommands extends BaseCommands * @param serviceClass is a sum of SERVICE_CLASS_* * @param response is callback message */ - public void setTTYModeEnabled(boolean enable, Message response) { + public void setTTYMode(int ttyMode, Message response) { Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); unimplemented(response); } @@ -1411,12 +1420,12 @@ public final class SimulatedCommands extends BaseCommands /** * Query the TTY mode for the CDMA phone * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 0 for disabled, 1 for enabled. - * + * 0 for disabled, 1 for enabled. + * * @param serviceClass is a sum of SERVICE_CLASS_* * @param response is callback message */ - public void queryTTYModeEnabled(Message response) { + public void queryTTYMode(Message response) { Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); unimplemented(response); } @@ -1451,4 +1460,11 @@ public final class SimulatedCommands extends BaseCommands } + public void exitEmergencyCallbackMode(Message response) { + // TODO method stub + } + + public void forceDataDormancy(Message response) { + // TODO method stub + } } |