summaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
Diffstat (limited to 'telephony')
-rw-r--r--telephony/java/android/telephony/SignalStrength.java44
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java74
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java16
-rw-r--r--telephony/java/com/android/internal/telephony/cat/AppInterface.java7
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java7
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CatService.java77
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CommandParams.java25
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java45
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java11
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java81
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java24
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GSMPhone.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java11
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java207
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java6
15 files changed, 506 insertions, 131 deletions
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index a88825b..1049669 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -47,6 +47,9 @@ public class SignalStrength implements Parcelable {
"none", "poor", "moderate", "good", "great"
};
+ /** @hide */
+ public static final int INVALID_SNR = 0x7FFFFFFF;
+
private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
private int mCdmaDbm; // This value is the RSSI value
@@ -96,7 +99,7 @@ public class SignalStrength implements Parcelable {
mLteSignalStrength = -1;
mLteRsrp = -1;
mLteRsrq = -1;
- mLteRssnr = -1;
+ mLteRssnr = INVALID_SNR;
mLteCqi = -1;
isGsm = true;
}
@@ -136,7 +139,8 @@ public class SignalStrength implements Parcelable {
int evdoDbm, int evdoEcio, int evdoSnr,
boolean gsm) {
this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
- evdoDbm, evdoEcio, evdoSnr, -1, -1, -1, -1, -1, gsm);
+ evdoDbm, evdoEcio, evdoSnr, -1, -1,
+ -1, INVALID_SNR, -1, gsm);
}
/**
@@ -289,10 +293,11 @@ public class SignalStrength implements Parcelable {
int level;
if (isGsm) {
+ // TODO Need solve the discrepancy of invalid values between
+ // RIL_LTE_SignalStrength and here.
if ((mLteSignalStrength == -1)
&& (mLteRsrp == -1)
&& (mLteRsrq == -1)
- && (mLteRssnr == -1)
&& (mLteCqi == -1)) {
level = getGsmLevel();
} else {
@@ -327,7 +332,6 @@ public class SignalStrength implements Parcelable {
if ((mLteSignalStrength == -1)
&& (mLteRsrp == -1)
&& (mLteRsrq == -1)
- && (mLteRssnr == -1)
&& (mLteCqi == -1)) {
asuLevel = getGsmAsuLevel();
} else {
@@ -363,7 +367,6 @@ public class SignalStrength implements Parcelable {
if ((mLteSignalStrength == -1)
&& (mLteRsrp == -1)
&& (mLteRsrq == -1)
- && (mLteRssnr == -1)
&& (mLteCqi == -1)) {
dBm = getGsmDbm();
} else {
@@ -566,16 +569,31 @@ public class SignalStrength implements Parcelable {
*/
public int getLteLevel() {
int levelLteRsrp = 0;
+ int levelLteRssnr = 0;
if (mLteRsrp == -1) levelLteRsrp = 0;
- else if (mLteRsrp >= -85) levelLteRsrp = SIGNAL_STRENGTH_GREAT;
- else if (mLteRsrp >= -95) levelLteRsrp = SIGNAL_STRENGTH_GOOD;
- else if (mLteRsrp >= -105) levelLteRsrp = SIGNAL_STRENGTH_MODERATE;
- else if (mLteRsrp >= -115) levelLteRsrp = SIGNAL_STRENGTH_POOR;
- else levelLteRsrp = 0;
-
- if (DBG) log("Lte level: "+levelLteRsrp);
- return levelLteRsrp;
+ else if (mLteRsrp >= -95) levelLteRsrp = SIGNAL_STRENGTH_GREAT;
+ else if (mLteRsrp >= -105) levelLteRsrp = SIGNAL_STRENGTH_GOOD;
+ else if (mLteRsrp >= -115) levelLteRsrp = SIGNAL_STRENGTH_MODERATE;
+ else levelLteRsrp = SIGNAL_STRENGTH_POOR;
+
+ if (mLteRssnr == INVALID_SNR) levelLteRssnr = 0;
+ else if (mLteRssnr >= 45) levelLteRssnr = SIGNAL_STRENGTH_GREAT;
+ else if (mLteRssnr >= 10) levelLteRssnr = SIGNAL_STRENGTH_GOOD;
+ else if (mLteRssnr >= -30) levelLteRssnr = SIGNAL_STRENGTH_MODERATE;
+ else levelLteRssnr = SIGNAL_STRENGTH_POOR;
+
+ int level;
+ if (mLteRsrp == -1)
+ level = levelLteRssnr;
+ else if (mLteRssnr == INVALID_SNR)
+ level = levelLteRsrp;
+ else
+ level = (levelLteRssnr < levelLteRsrp) ? levelLteRssnr : levelLteRsrp;
+
+ if (DBG) log("Lte rsrp level: "+levelLteRsrp
+ + " snr level: " + levelLteRssnr + " level: " + level);
+ return level;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 4619899..d0e304f 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -68,6 +68,8 @@ public abstract class DataConnection extends StateMachine {
private List<ApnContext> mApnList = null;
PendingIntent mReconnectIntent = null;
+ private DataConnectionTracker mDataConnectionTracker = null;
+
/**
* Used internally for saving connecting parameters.
*/
@@ -134,7 +136,8 @@ public abstract class DataConnection extends StateMachine {
// specified here
UNKNOWN(0x10000),
RADIO_NOT_AVAILABLE(0x10001),
- UNACCEPTABLE_NETWORK_PARAMETER(0x10002);
+ UNACCEPTABLE_NETWORK_PARAMETER(0x10002),
+ CONNECTION_TO_DATACONNECTIONAC_BROKEN(0x10003);
private final int mErrorCode;
private static final HashMap<Integer, FailCause> sErrorCodeToFailCauseMap;
@@ -201,6 +204,7 @@ public abstract class DataConnection extends StateMachine {
protected static final int EVENT_DEACTIVATE_DONE = BASE + 3;
protected static final int EVENT_DISCONNECT = BASE + 4;
protected static final int EVENT_RIL_CONNECTED = BASE + 5;
+ protected static final int EVENT_DISCONNECT_ALL = BASE + 6;
//***** Tag IDs for EventLog
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
@@ -233,10 +237,12 @@ public abstract class DataConnection extends StateMachine {
//***** Constructor
- protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm) {
+ protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm,
+ DataConnectionTracker dct) {
super(name);
if (DBG) log("DataConnection constructor E");
this.phone = phone;
+ this.mDataConnectionTracker = dct;
mId = id;
mRetryMgr = rm;
this.cid = -1;
@@ -315,11 +321,19 @@ public abstract class DataConnection extends StateMachine {
*
* @param dp is the DisconnectParams.
*/
- private void notifyDisconnectCompleted(DisconnectParams dp) {
+ private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) {
if (VDBG) log("NotifyDisconnectCompleted");
+ ApnContext alreadySent = null;
+ String reason = null;
+
if (dp.onCompletedMsg != null) {
+ // Get ApnContext, but only valid on GSM devices this is a string on CDMA devices.
Message msg = dp.onCompletedMsg;
+ if (msg.obj instanceof ApnContext) {
+ alreadySent = (ApnContext)msg.obj;
+ }
+ reason = dp.reason;
if (VDBG) {
log(String.format("msg=%s msg.obj=%s", msg.toString(),
((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
@@ -327,6 +341,17 @@ public abstract class DataConnection extends StateMachine {
AsyncResult.forMessage(msg);
msg.sendToTarget();
}
+ if (sendAll) {
+ for (ApnContext a : mApnList) {
+ if (a == alreadySent) continue;
+ if (reason != null) a.setReason(reason);
+ Message msg = mDataConnectionTracker.obtainMessage(
+ DataConnectionTracker.EVENT_DISCONNECT_DONE, a);
+ AsyncResult.forMessage(msg);
+ msg.sendToTarget();
+ }
+ }
+
if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
}
@@ -705,6 +730,13 @@ public abstract class DataConnection extends StateMachine {
deferMessage(msg);
break;
+ case EVENT_DISCONNECT_ALL:
+ if (DBG) {
+ log("DcDefaultState deferring msg.what=EVENT_DISCONNECT_ALL" + mRefCount);
+ }
+ deferMessage(msg);
+ break;
+
case EVENT_RIL_CONNECTED:
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
@@ -770,7 +802,7 @@ public abstract class DataConnection extends StateMachine {
}
if (mDisconnectParams != null) {
if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted");
- notifyDisconnectCompleted(mDisconnectParams);
+ notifyDisconnectCompleted(mDisconnectParams, true);
}
clearSettings();
}
@@ -811,7 +843,13 @@ public abstract class DataConnection extends StateMachine {
case EVENT_DISCONNECT:
if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT");
- notifyDisconnectCompleted((DisconnectParams)msg.obj);
+ notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
+ retVal = HANDLED;
+ break;
+
+ case EVENT_DISCONNECT_ALL:
+ if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL");
+ notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
retVal = HANDLED;
break;
@@ -988,12 +1026,24 @@ public abstract class DataConnection extends StateMachine {
transitionTo(mDisconnectingState);
} else {
if (msg.obj != null) {
- notifyDisconnectCompleted((DisconnectParams) msg.obj);
+ notifyDisconnectCompleted((DisconnectParams) msg.obj, false);
}
}
retVal = HANDLED;
break;
+ case EVENT_DISCONNECT_ALL:
+ if (DBG) {
+ log("DcActiveState msg.what=EVENT_DISCONNECT_ALL RefCount=" + mRefCount);
+ }
+ mRefCount = 0;
+ DisconnectParams dp = (DisconnectParams) msg.obj;
+ dp.tag = mTag;
+ tearDownData(dp);
+ transitionTo(mDisconnectingState);
+ retVal = HANDLED;
+ break;
+
default:
if (VDBG) {
log("DcActiveState not handled msg.what=0x" +
@@ -1123,4 +1173,16 @@ public abstract class DataConnection extends StateMachine {
public void tearDown(String reason, Message onCompletedMsg) {
sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(reason, onCompletedMsg)));
}
+
+ /**
+ * Tear down the connection through the apn on the network. Ignores refcount and
+ * and always tears down.
+ *
+ * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
+ * With AsyncResult.userObj set to the original msg.obj.
+ */
+ public void tearDownAll(String reason, Message onCompletedMsg) {
+ sendMessage(obtainMessage(EVENT_DISCONNECT_ALL,
+ new DisconnectParams(reason, onCompletedMsg)));
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 6d9a2c2..863235b 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -212,8 +212,10 @@ public abstract class DataConnectionTracker extends Handler {
// represents an invalid IP address
protected static final String NULL_IP = "0.0.0.0";
- // Default for the data stall alarm
- protected static final int DATA_STALL_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
+ // Default for the data stall alarm while non-aggressive stall detection
+ protected static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
+ // Default for the data stall alarm for aggressive stall detection
+ protected static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
// If attempt is less than this value we're doing first level recovery
protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1;
// Tag for tracking stale alarms
@@ -323,10 +325,12 @@ public abstract class DataConnectionTracker extends Handler {
mIsScreenOn = true;
stopNetStatPoll();
startNetStatPoll();
+ restartDataStallAlarm();
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
mIsScreenOn = false;
stopNetStatPoll();
startNetStatPoll();
+ restartDataStallAlarm();
} else if (action.startsWith(getActionIntentReconnectAlarm())) {
log("Reconnect alarm. Previous state was " + mState);
onActionIntentReconnectAlarm(intent);
@@ -622,6 +626,7 @@ public abstract class DataConnectionTracker extends Handler {
protected abstract String getActionIntentDataStallAlarm();
protected abstract void startNetStatPoll();
protected abstract void stopNetStatPoll();
+ protected abstract void restartDataStallAlarm();
protected abstract void restartRadio();
protected abstract void log(String s);
protected abstract void loge(String s);
@@ -1024,8 +1029,11 @@ public abstract class DataConnectionTracker extends Handler {
didDisable = true;
}
}
- if (didDisable && enabledCount == 0) {
- onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
+ if (didDisable) {
+ if ((enabledCount == 0) || (apnId == APN_DUN_ID)) {
+ mRequestedApnType = Phone.APN_TYPE_DEFAULT;
+ onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
+ }
// send the disconnect msg manually, since the normal route wont send
// it (it's not enabled)
diff --git a/telephony/java/com/android/internal/telephony/cat/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
index 2eb6ccb..299e140 100644
--- a/telephony/java/com/android/internal/telephony/cat/AppInterface.java
+++ b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
@@ -42,6 +42,7 @@ public interface AppInterface {
* Enumeration for representing "Type of Command" of proactive commands.
* Those are the only commands which are supported by the Telephony. Any app
* implementation should support those.
+ * Refer to ETSI TS 102.223 section 9.4
*/
public static enum CommandType {
DISPLAY_TEXT(0x21),
@@ -59,7 +60,11 @@ public interface AppInterface {
SET_UP_IDLE_MODE_TEXT(0x28),
SET_UP_MENU(0x25),
SET_UP_CALL(0x10),
- PROVIDE_LOCAL_INFORMATION(0x26);
+ PROVIDE_LOCAL_INFORMATION(0x26),
+ OPEN_CHANNEL(0x40),
+ CLOSE_CHANNEL(0x41),
+ RECEIVE_DATA(0x42),
+ SEND_DATA(0x43);
private int mValue;
diff --git a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
index 5155bb2..48c2e2b 100644
--- a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -85,6 +85,13 @@ public class CatCmdMessage implements Parcelable {
mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg;
mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg;
break;
+ case OPEN_CHANNEL:
+ case CLOSE_CHANNEL:
+ case RECEIVE_DATA:
+ case SEND_DATA:
+ BIPClientParams param = (BIPClientParams) cmdParams;
+ mTextMsg = param.textMsg;
+ break;
}
}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java
index 5a994f3..74af9fa 100644
--- a/telephony/java/com/android/internal/telephony/cat/CatService.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatService.java
@@ -18,6 +18,8 @@ package com.android.internal.telephony.cat;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
@@ -32,6 +34,7 @@ import com.android.internal.telephony.IccRecords;
import java.io.ByteArrayOutputStream;
+import java.util.List;
import java.util.Locale;
class RilMessage {
@@ -72,6 +75,7 @@ public class CatService extends Handler implements AppInterface {
private CatCmdMessage mMenuCmd = null;
private RilMessageDecoder mMsgDecoder = null;
+ private boolean mStkAppInstalled = false;
// Service constants.
static final int MSG_ID_SESSION_END = 1;
@@ -125,7 +129,10 @@ public class CatService extends Handler implements AppInterface {
mCmdIf.registerForNVReady(this, MSG_ID_SIM_READY, null);
mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
- CatLog.d(this, "Is running");
+ // Check if STK application is availalbe
+ mStkAppInstalled = isStkAppInstalled();
+
+ CatLog.d(this, "Running CAT service. STK app installed:" + mStkAppInstalled);
}
public void dispose() {
@@ -154,7 +161,7 @@ public class CatService extends Handler implements AppInterface {
if (rilMsg.mResCode == ResultCode.OK) {
cmdParams = (CommandParams) rilMsg.mData;
if (cmdParams != null) {
- handleProactiveCommand(cmdParams);
+ handleCommand(cmdParams, false);
}
}
break;
@@ -170,7 +177,7 @@ public class CatService extends Handler implements AppInterface {
}
if (cmdParams != null) {
if (rilMsg.mResCode == ResultCode.OK) {
- handleProactiveCommand(cmdParams);
+ handleCommand(cmdParams, true);
} else {
// for proactive commands that couldn't be decoded
// successfully respond with the code generated by the
@@ -183,7 +190,7 @@ public class CatService extends Handler implements AppInterface {
case MSG_ID_REFRESH:
cmdParams = (CommandParams) rilMsg.mData;
if (cmdParams != null) {
- handleProactiveCommand(cmdParams);
+ handleCommand(cmdParams, false);
}
break;
case MSG_ID_SESSION_END:
@@ -197,11 +204,13 @@ public class CatService extends Handler implements AppInterface {
}
/**
- * Handles RIL_UNSOL_STK_PROACTIVE_COMMAND unsolicited command from RIL.
+ * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command
+ * from RIL.
* Sends valid proactive command data to the application using intents.
- *
+ * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is
+ * from RIL_UNSOL_STK_PROACTIVE_COMMAND.
*/
- private void handleProactiveCommand(CommandParams cmdParams) {
+ private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) {
CatLog.d(this, cmdParams.getCommandType().name());
CharSequence message;
@@ -235,15 +244,16 @@ public class CatService extends Handler implements AppInterface {
case CommandParamsFactory.DTTZ_SETTING:
resp = new DTTZResponseData(null);
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp);
- return;
+ break;
case CommandParamsFactory.LANGUAGE_SETTING:
resp = new LanguageResponseData(Locale.getDefault().getLanguage());
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp);
- return;
+ break;
default:
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
- return;
}
+ // No need to start STK app here.
+ return;
case LAUNCH_BROWSER:
if ((((LaunchBrowserParams) cmdParams).confirmMsg.text != null)
&& (((LaunchBrowserParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) {
@@ -274,6 +284,42 @@ public class CatService extends Handler implements AppInterface {
((CallSetupParams) cmdParams).confirmMsg.text = message.toString();
}
break;
+ case OPEN_CHANNEL:
+ case CLOSE_CHANNEL:
+ case RECEIVE_DATA:
+ case SEND_DATA:
+ BIPClientParams cmd = (BIPClientParams) cmdParams;
+ if (cmd.bHasAlphaId && (cmd.textMsg.text == null)) {
+ CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id");
+ // If alpha length is zero, we just respond with OK.
+ if (isProactiveCmd) {
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ }
+ return;
+ }
+ // Respond with permanent failure to avoid retry if STK app is not present.
+ if (!mStkAppInstalled) {
+ CatLog.d(this, "No STK application found.");
+ if (isProactiveCmd) {
+ sendTerminalResponse(cmdParams.cmdDet,
+ ResultCode.BEYOND_TERMINAL_CAPABILITY,
+ false, 0, null);
+ return;
+ }
+ }
+ /*
+ * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by
+ * either PROACTIVE_COMMAND or EVENT_NOTIFY.
+ * If PROACTIVE_COMMAND is used for those commands, send terminal
+ * response here.
+ */
+ if (isProactiveCmd &&
+ ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) ||
+ (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) ||
+ (cmdParams.getCommandType() == CommandType.SEND_DATA))) {
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ }
+ break;
default:
CatLog.d(this, "Unsupported command");
return;
@@ -684,6 +730,7 @@ public class CatService extends Handler implements AppInterface {
case NO_RESPONSE_FROM_USER:
case UICC_SESSION_TERM_BY_USER:
case BACKWARD_MOVE_BY_USER:
+ case USER_NOT_ACCEPT:
resp = null;
break;
default:
@@ -692,4 +739,14 @@ public class CatService extends Handler implements AppInterface {
sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp);
mCurrntCmd = null;
}
+
+ private boolean isStkAppInstalled() {
+ Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
+ PackageManager pm = mContext.getPackageManager();
+ List<ResolveInfo> broadcastReceivers =
+ pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA);
+ int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size();
+
+ return (numReceiver > 0);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
index 22a5c8c..959c9e2 100644
--- a/telephony/java/com/android/internal/telephony/cat/CommandParams.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
@@ -166,4 +166,29 @@ class GetInputParams extends CommandParams {
}
}
+/*
+ * BIP (Bearer Independent Protocol) is the mechanism for SIM card applications
+ * to access data connection through the mobile device.
+ *
+ * SIM utilizes proactive commands (OPEN CHANNEL, CLOSE CHANNEL, SEND DATA and
+ * RECEIVE DATA to control/read/write data for BIP. Refer to ETSI TS 102 223 for
+ * the details of proactive commands procedures and their structures.
+ */
+class BIPClientParams extends CommandParams {
+ TextMessage textMsg;
+ boolean bHasAlphaId;
+
+ BIPClientParams(CommandDetails cmdDet, TextMessage textMsg, boolean has_alpha_id) {
+ super(cmdDet);
+ this.textMsg = textMsg;
+ this.bHasAlphaId = has_alpha_id;
+ }
+ boolean setIcon(Bitmap icon) {
+ if (icon != null && textMsg != null) {
+ textMsg.icon = icon;
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index e7fca5a..89c1329 100644
--- a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -165,6 +165,12 @@ class CommandParamsFactory extends Handler {
case PROVIDE_LOCAL_INFORMATION:
cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
break;
+ case OPEN_CHANNEL:
+ case CLOSE_CHANNEL:
+ case RECEIVE_DATA:
+ case SEND_DATA:
+ cmdPending = processBIPClient(cmdDet, ctlvs);
+ break;
default:
// unsupported proactive commands
mCmdParams = new CommandParams(cmdDet);
@@ -893,4 +899,43 @@ class CommandParamsFactory extends Handler {
}
return false;
}
+
+ private boolean processBIPClient(CommandDetails cmdDet,
+ List<ComprehensionTlv> ctlvs) throws ResultException {
+ AppInterface.CommandType commandType =
+ AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
+ if (commandType != null) {
+ CatLog.d(this, "process "+ commandType.name());
+ }
+
+ TextMessage textMsg = new TextMessage();
+ IconId iconId = null;
+ ComprehensionTlv ctlv = null;
+ boolean has_alpha_id = false;
+
+ // parse alpha identifier
+ ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
+ if (ctlv != null) {
+ textMsg.text = ValueParser.retrieveAlphaId(ctlv);
+ CatLog.d(this, "alpha TLV text=" + textMsg.text);
+ has_alpha_id = true;
+ }
+
+ // parse icon identifier
+ ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
+ if (ctlv != null) {
+ iconId = ValueParser.retrieveIconId(ctlv);
+ textMsg.iconSelfExplanatory = iconId.selfExplanatory;
+ }
+
+ textMsg.responseNeeded = false;
+ mCmdParams = new BIPClientParams(cmdDet, textMsg, has_alpha_id);
+
+ if (iconId != null) {
+ mIconLoadState = LOAD_SINGLE_ICON;
+ mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
+ return true;
+ }
+ return false;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index d55f346..a93d94f 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -20,6 +20,7 @@ import android.os.Message;
import android.util.Log;
import com.android.internal.telephony.DataConnection;
+import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.RetryManager;
@@ -32,8 +33,9 @@ public class CdmaDataConnection extends DataConnection {
private static final String LOG_TAG = "CDMA";
// ***** Constructor
- private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm) {
- super(phone, name, id, rm);
+ private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm,
+ DataConnectionTracker dct) {
+ super(phone, name, id, rm, dct);
}
/**
@@ -44,12 +46,13 @@ public class CdmaDataConnection extends DataConnection {
* @param rm the RetryManager
* @return CdmaDataConnection that was created.
*/
- static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm) {
+ static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm,
+ DataConnectionTracker dct) {
synchronized (mCountLock) {
mCount += 1;
}
CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDC-" + mCount,
- id, rm);
+ id, rm, dct);
cdmaDc.start();
if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
return cdmaDc;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 5889372..0a1b1e4 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -41,6 +41,7 @@ import com.android.internal.telephony.DataConnectionAc;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.RetryManager;
+import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.Phone;
import com.android.internal.util.AsyncChannel;
@@ -92,6 +93,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
Phone.APN_TYPE_MMS,
Phone.APN_TYPE_HIPRI };
+ private String[] mDunApnTypes = {
+ Phone.APN_TYPE_DUN };
+
private static final int mDefaultApnId = DataConnectionTracker.APN_DEFAULT_ID;
/* Constructor */
@@ -117,11 +121,26 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
createAllDataConnectionList();
broadcastMessenger();
+
+ Context c = mCdmaPhone.getContext();
+ String[] t = c.getResources().getStringArray(
+ com.android.internal.R.array.config_cdma_dun_supported_types);
+ if (t != null && t.length > 0) {
+ ArrayList<String> temp = new ArrayList<String>();
+ for(int i=0; i< t.length; i++) {
+ if (!Phone.APN_TYPE_DUN.equalsIgnoreCase(t[i])) {
+ temp.add(t[i]);
+ }
+ }
+ temp.add(0, Phone.APN_TYPE_DUN);
+ mDunApnTypes = temp.toArray(t);
+ }
+
}
@Override
public void dispose() {
- cleanUpConnection(false, null);
+ cleanUpConnection(false, null, false);
super.dispose();
@@ -158,6 +177,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
@Override
+ protected void restartDataStallAlarm() {}
+
+ @Override
protected void setState(State s) {
if (DBG) log ("setState: " + s);
if (mState != s) {
@@ -204,7 +226,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
internalDataEnabled &&
desiredPowerState &&
!mPendingRestartRadio &&
- !mCdmaPhone.needsOtaServiceProvisioning();
+ ((mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) ||
+ !mCdmaPhone.needsOtaServiceProvisioning());
if (!allowed && DBG) {
String reason = "";
if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
@@ -273,7 +296,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
* @param tearDown true if the underlying DataConnection should be disconnected.
* @param reason for the clean up.
*/
- private void cleanUpConnection(boolean tearDown, String reason) {
+ private void cleanUpConnection(boolean tearDown, String reason, boolean doAll) {
if (DBG) log("cleanUpConnection: reason: " + reason);
// Clear the reconnect alarm, if set.
@@ -293,9 +316,15 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
DataConnectionAc dcac =
mDataConnectionAsyncChannels.get(conn.getDataConnectionId());
if (tearDown) {
- if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
- conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE,
- conn.getDataConnectionId(), 0, reason));
+ if (doAll) {
+ if (DBG) log("cleanUpConnection: teardown, conn.tearDownAll");
+ conn.tearDownAll(reason, obtainMessage(EVENT_DISCONNECT_DONE,
+ conn.getDataConnectionId(), 0, reason));
+ } else {
+ if (DBG) log("cleanUpConnection: teardown, conn.tearDown");
+ conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE,
+ conn.getDataConnectionId(), 0, reason));
+ }
notificationDeferred = true;
} else {
if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
@@ -339,8 +368,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
String[] types;
int apnId;
if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) {
- types = new String[1];
- types[0] = Phone.APN_TYPE_DUN;
+ types = mDunApnTypes;
apnId = DataConnectionTracker.APN_DUN_ID;
} else {
types = mDefaultApnTypes;
@@ -506,7 +534,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
return retry;
}
- private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) {
+ private void reconnectAfterFail(FailCause lastFailCauseCode, String reason, int retryOverride) {
if (mState == State.FAILED) {
/**
* For now With CDMA we never try to reconnect on
@@ -514,9 +542,12 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
* at the last time until the state is changed.
* TODO: Make this configurable?
*/
- int nextReconnectDelay = mDataConnections.get(0).getRetryTimer();
+ int nextReconnectDelay = retryOverride;
+ if (nextReconnectDelay < 0) {
+ nextReconnectDelay = mDataConnections.get(0).getRetryTimer();
+ mDataConnections.get(0).increaseRetryCount();
+ }
startAlarmForReconnect(nextReconnectDelay, reason);
- mDataConnections.get(0).increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
log("NOT Posting Data Connection Unavailable notification "
@@ -575,7 +606,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
@Override
protected void onEnableNewApn() {
// No mRequestedApnType check; only one connection is supported
- cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
+ cleanUpConnection(true, Phone.REASON_APN_SWITCHED, false);
}
/**
@@ -674,7 +705,17 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
notifyNoData(cause);
return;
}
- startDelayedRetry(cause, reason);
+
+ int retryOverride = -1;
+ if (ar.exception instanceof DataConnection.CallSetupException) {
+ retryOverride =
+ ((DataConnection.CallSetupException)ar.exception).getRetryOverride();
+ }
+ if (retryOverride == RILConstants.MAX_INT) {
+ if (DBG) log("No retry is suggested.");
+ } else {
+ startDelayedRetry(cause, reason, retryOverride);
+ }
}
}
@@ -747,13 +788,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
@Override
protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
// No apnId check; only one connection is supported
- cleanUpConnection(tearDown, reason);
+ cleanUpConnection(tearDown, reason, (apnId == APN_DUN_ID));
}
@Override
protected void onCleanUpAllConnections(String cause) {
// Only one CDMA connection is supported
- cleanUpConnection(true, cause);
+ cleanUpConnection(true, cause, false);
}
private void createAllDataConnectionList() {
@@ -772,7 +813,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
int id = mUniqueIdGenerator.getAndIncrement();
- dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm);
+ dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm, this);
mDataConnections.put(id, dataConn);
DataConnectionAc dcac = new DataConnectionAc(dataConn, LOG_TAG);
int status = dcac.fullyConnectSync(mPhone.getContext(), this, dataConn.getHandler());
@@ -799,7 +840,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
} else {
if (mState == State.FAILED) {
- cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED);
+ cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED, false);
mDataConnections.get(0).resetRetryCount();
CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
@@ -878,7 +919,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
log("onDataStateChanged: No active connection"
+ "state is CONNECTED, disconnecting/cleanup");
writeEventLogCdmaDataDrop();
- cleanUpConnection(true, null);
+ cleanUpConnection(true, null, false);
return;
}
@@ -907,9 +948,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
}
- private void startDelayedRetry(FailCause cause, String reason) {
+ private void startDelayedRetry(FailCause cause, String reason, int retryOverride) {
notifyNoData(cause);
- reconnectAfterFail(cause, reason);
+ reconnectAfterFail(cause, reason, retryOverride);
}
@Override
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 3486190..610cd5d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -147,7 +147,9 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
@Override
protected void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, false);
+ // TODO Make a constructor only has boolean gsm as parameter
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, SignalStrength.INVALID_SNR, -1, false);
}
@Override
@@ -452,8 +454,13 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
setSignalStrengthDefaultValues();
} else {
int[] ints = (int[])ar.result;
- int lteCqi = 99, lteRsrp = -1;
- int lteRssi = 99;
+
+ int lteRssi = -1;
+ int lteRsrp = -1;
+ int lteRsrq = -1;
+ int lteRssnr = SignalStrength.INVALID_SNR;
+ int lteCqi = -1;
+
int offset = 2;
int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
int cdmaEcio = (ints[offset + 1] > 0) ? -ints[offset + 1] : -160;
@@ -461,10 +468,13 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
int evdoEcio = (ints[offset + 3] > 0) ? -ints[offset + 3] : -1;
int evdoSnr = ((ints[offset + 4] > 0) && (ints[offset + 4] <= 8)) ? ints[offset + 4]
: -1;
+
if (networkType == ServiceState.RADIO_TECHNOLOGY_LTE) {
- lteRssi = (ints[offset + 5] >= 0) ? ints[offset + 5] : 99;
- lteRsrp = (ints[offset + 6] < 0) ? ints[offset + 6] : -1;
- lteCqi = (ints[offset + 7] >= 0) ? ints[offset + 7] : 99;
+ lteRssi = ints[offset+5];
+ lteRsrp = ints[offset+6];
+ lteRsrq = ints[offset+7];
+ lteRssnr = ints[offset+8];
+ lteCqi = ints[offset+9];
}
if (networkType != ServiceState.RADIO_TECHNOLOGY_LTE) {
@@ -472,7 +482,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
evdoSnr, false);
} else {
mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
- evdoSnr, lteRssi, lteRsrp, -1, -1, lteCqi, true);
+ evdoSnr, lteRssi, lteRsrp, lteRsrq, lteRssnr, lteCqi, true);
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index e1f4c4b..5c95e7d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -1240,7 +1240,7 @@ public class GSMPhone extends PhoneBase {
// If the radio shuts off or resets while one of these
// is pending, we need to clean up.
- for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
+ for (int i = mPendingMMIs.size() - 1; i >= 0; i--) {
if (mPendingMMIs.get(i).isPendingUSSD()) {
mPendingMMIs.get(i).onUssdFinishedError();
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 1f24b58..1f5b7ab 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -22,6 +22,7 @@ import android.util.Patterns;
import android.text.TextUtils;
import com.android.internal.telephony.DataConnection;
+import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.RILConstants;
@@ -38,8 +39,9 @@ public class GsmDataConnection extends DataConnection {
protected int mProfileId = RILConstants.DATA_PROFILE_DEFAULT;
protected String mActiveApnType = Phone.APN_TYPE_DEFAULT;
//***** Constructor
- private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm) {
- super(phone, name, id, rm);
+ private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm,
+ DataConnectionTracker dct) {
+ super(phone, name, id, rm, dct);
}
/**
@@ -50,11 +52,12 @@ public class GsmDataConnection extends DataConnection {
* @param rm the RetryManager
* @return GsmDataConnection that was created.
*/
- static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm) {
+ static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm,
+ DataConnectionTracker dct) {
synchronized (mCountLock) {
mCount += 1;
}
- GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm);
+ GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm, dct);
gsmDc.start();
if (DBG) gsmDc.log("Made " + gsmDc.getName());
return gsmDc;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 963db2c..95ea107 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -76,6 +76,7 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public final class GsmDataConnectionTracker extends DataConnectionTracker {
protected final String LOG_TAG = "GSM";
+ private static final boolean RADIO_TESTS = false;
/**
* Handles changes to the APN db.
@@ -97,13 +98,21 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private ContentResolver mResolver;
// Recovery action taken in case of data stall
- class RecoveryAction {
+ private static class RecoveryAction {
public static final int GET_DATA_CALL_LIST = 0;
public static final int CLEANUP = 1;
public static final int REREGISTER = 2;
public static final int RADIO_RESTART = 3;
public static final int RADIO_RESTART_WITH_PROP = 4;
+
+ private static boolean isAggressiveRecovery(int value) {
+ return ((value == RecoveryAction.CLEANUP) ||
+ (value == RecoveryAction.REREGISTER) ||
+ (value == RecoveryAction.RADIO_RESTART) ||
+ (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
+ }
}
+
public int getRecoveryAction() {
int action = Settings.System.getInt(mPhone.getContext().getContentResolver(),
"radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
@@ -127,10 +136,14 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private static final String INTENT_DATA_STALL_ALARM =
"com.android.internal.telephony.gprs-data-stall";
- static final Uri PREFERAPN_URI = Uri.parse("content://telephony/carriers/preferapn");
+ static final Uri PREFERAPN_NO_UPDATE_URI =
+ Uri.parse("content://telephony/carriers/preferapn_no_update");
static final String APN_ID = "apn_id";
private boolean canSetPreferApn = false;
+ private static final boolean DATA_STALL_SUSPECTED = true;
+ private static final boolean DATA_STALL_NOT_SUSPECTED = false;
+
@Override
protected void onActionIntentReconnectAlarm(Intent intent) {
if (DBG) log("GPRS reconnect alarm. Previous state was " + mState);
@@ -586,7 +599,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (getOverallState() == State.CONNECTED) {
if (DBG) log("onDataConnectionAttached: start polling notify attached");
startNetStatPoll();
- startDataStallAlarm();
+ startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
notifyDataConnection(Phone.REASON_DATA_ATTACHED);
} else {
// update APN availability so that APN can be enabled.
@@ -837,9 +850,28 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// Connection is still there. Try to clean up.
if (dcac != null) {
if (apnContext.getState() != State.DISCONNECTING) {
- if (DBG) log("cleanUpConnection: tearing down");
+ boolean disconnectAll = false;
+ if (Phone.APN_TYPE_DUN.equals(apnContext.getApnType())) {
+ ApnSetting dunSetting = fetchDunApn();
+ if (dunSetting != null &&
+ dunSetting.equals(apnContext.getApnSetting())) {
+ if (DBG) log("tearing down dedicated DUN connection");
+ // we need to tear it down - we brought it up just for dun and
+ // other people are camped on it and now dun is done. We need
+ // to stop using it and let the normal apn list get used to find
+ // connections for the remaining desired connections
+ disconnectAll = true;
+ }
+ }
+ if (DBG) {
+ log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));
+ }
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
- apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
+ if (disconnectAll) {
+ apnContext.getDataConnection().tearDownAll(apnContext.getReason(), msg);
+ } else {
+ apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
+ }
apnContext.setState(State.DISCONNECTING);
}
} else {
@@ -1271,7 +1303,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// setState(State.CONNECTED);
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
startNetStatPoll();
- startDataStallAlarm();
+ startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
// reset reconnect timer
apnContext.getDataConnection().resetRetryCount();
}
@@ -1394,7 +1426,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
- if (VDBG) {
+ if (RADIO_TESTS) {
if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
log("updateDataStallInfo: radio.test.data.stall true received = 0;");
received = 0;
@@ -1437,10 +1469,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
NUMBER_SENT_PACKETS_OF_HANG);
+ boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
if (mSentSinceLastRecv >= hangWatchdogTrigger) {
if (DBG) {
log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
}
+ suspectedStall = DATA_STALL_SUSPECTED;
sendMessage(obtainMessage(EVENT_DO_RECOVERY));
} else {
if (VDBG) {
@@ -1448,7 +1482,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
" pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
}
}
- startDataStallAlarm();
+ startDataStallAlarm(suspectedStall);
}
@@ -1614,12 +1648,24 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
- private void startDataStallAlarm() {
- int delayInMs = Settings.Secure.getInt(mResolver,
- Settings.Secure.DATA_STALL_ALARM_DELAY_IN_MS,
- DATA_STALL_ALARM_DELAY_IN_MS_DEFAULT);
+ private void startDataStallAlarm(boolean suspectedStall) {
+ int nextAction = getRecoveryAction();
+ int delayInMs;
+
+ // If screen is on or data stall is currently suspected, set the alarm
+ // with an aggresive timeout.
+ if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
+ delayInMs = Settings.Secure.getInt(mResolver,
+ Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
+ DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
+ } else {
+ delayInMs = Settings.Secure.getInt(mResolver,
+ Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
+ DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
+ }
+
mDataStallAlarmTag += 1;
- if (DBG) {
+ if (VDBG) {
log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
" delay=" + (delayInMs / 1000) + "s");
}
@@ -1638,7 +1684,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
AlarmManager am =
(AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
- if (DBG) {
+ if (VDBG) {
log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
" mDataStallAlarmIntent=" + mDataStallAlarmIntent);
}
@@ -1649,6 +1695,20 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
+ @Override
+ protected void restartDataStallAlarm() {
+ // To be called on screen status change.
+ // Do not cancel the alarm if it is set with aggressive timeout.
+ int nextAction = getRecoveryAction();
+
+ if (RecoveryAction.isAggressiveRecovery(nextAction)) {
+ if (DBG) log("data stall recovery action is pending. not resetting the alarm.");
+ return;
+ }
+ stopDataStallAlarm();
+ startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
+ }
+
private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode,
ApnContext apnContext) {
if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
@@ -1852,6 +1912,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
@Override
protected void onDataSetupComplete(AsyncResult ar) {
+ DataConnection.FailCause cause = DataConnection.FailCause.UNKNOWN;
+ boolean handleError = false;
ApnContext apnContext = null;
if(ar.userObj instanceof ApnContext){
@@ -1862,52 +1924,73 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (isDataSetupCompleteOk(ar)) {
DataConnectionAc dcac = apnContext.getDataConnectionAc();
- if (dcac == null) {
- throw new RuntimeException("onDataSetupCompete: No dcac");
- }
- DataConnection dc = apnContext.getDataConnection();
- if (DBG) {
- // TODO We may use apnContext.getApnSetting() directly
- // instead of getWaitingApns().get(0)
- String apnStr = "<unknown>";
- if (apnContext.getWaitingApns() != null
- && !apnContext.getWaitingApns().isEmpty()){
- apnStr = apnContext.getWaitingApns().get(0).apn;
+ if (RADIO_TESTS) {
+ // Note: To change radio.test.onDSC.null.dcac from command line you need to
+ // adb root and adb remount and from the command line you can only change the
+ // value to 1 once. To change it a second time you can reboot or execute
+ // adb shell stop and then adb shell start. The command line to set the value is:
+ // adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "insert into system (name,value) values ('radio.test.onDSC.null.dcac', '1');"
+ ContentResolver cr = mPhone.getContext().getContentResolver();
+ String radioTestProperty = "radio.test.onDSC.null.dcac";
+ if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
+ log("onDataSetupComplete: " + radioTestProperty +
+ " is true, set dcac to null and reset property to false");
+ dcac = null;
+ Settings.System.putInt(cr, radioTestProperty, 0);
+ log("onDataSetupComplete: " + radioTestProperty + "=" +
+ Settings.System.getInt(mPhone.getContext().getContentResolver(),
+ radioTestProperty, -1));
}
- log("onDataSetupComplete: success apn=" + apnStr);
}
- ApnSetting apn = apnContext.getApnSetting();
- if (apn.proxy != null && apn.proxy.length() != 0) {
- try {
- String port = apn.port;
- if (TextUtils.isEmpty(port)) port = "8080";
- ProxyProperties proxy = new ProxyProperties(apn.proxy,
- Integer.parseInt(port), null);
- dcac.setLinkPropertiesHttpProxySync(proxy);
- } catch (NumberFormatException e) {
- loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
- apn.port + "): " + e);
+ if (dcac == null) {
+ log("onDataSetupComplete: no connection to DC, handle as error");
+ cause = DataConnection.FailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
+ handleError = true;
+ } else {
+ DataConnection dc = apnContext.getDataConnection();
+
+ if (DBG) {
+ // TODO We may use apnContext.getApnSetting() directly
+ // instead of getWaitingApns().get(0)
+ String apnStr = "<unknown>";
+ if (apnContext.getWaitingApns() != null
+ && !apnContext.getWaitingApns().isEmpty()){
+ apnStr = apnContext.getWaitingApns().get(0).apn;
+ }
+ log("onDataSetupComplete: success apn=" + apnStr);
+ }
+ ApnSetting apn = apnContext.getApnSetting();
+ if (apn.proxy != null && apn.proxy.length() != 0) {
+ try {
+ String port = apn.port;
+ if (TextUtils.isEmpty(port)) port = "8080";
+ ProxyProperties proxy = new ProxyProperties(apn.proxy,
+ Integer.parseInt(port), null);
+ dcac.setLinkPropertiesHttpProxySync(proxy);
+ } catch (NumberFormatException e) {
+ loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
+ apn.port + "): " + e);
+ }
}
- }
- // everything is setup
- if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) {
- SystemProperties.set("gsm.defaultpdpcontext.active", "true");
- if (canSetPreferApn && mPreferredApn == null) {
- if (DBG) log("onDataSetupComplete: PREFERED APN is null");
- mPreferredApn = apnContext.getApnSetting();
- if (mPreferredApn != null) {
- setPreferredApn(mPreferredApn.id);
+ // everything is setup
+ if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) {
+ SystemProperties.set("gsm.defaultpdpcontext.active", "true");
+ if (canSetPreferApn && mPreferredApn == null) {
+ if (DBG) log("onDataSetupComplete: PREFERED APN is null");
+ mPreferredApn = apnContext.getApnSetting();
+ if (mPreferredApn != null) {
+ setPreferredApn(mPreferredApn.id);
+ }
}
+ } else {
+ SystemProperties.set("gsm.defaultpdpcontext.active", "false");
}
- } else {
- SystemProperties.set("gsm.defaultpdpcontext.active", "false");
+ notifyDefaultData(apnContext);
}
- notifyDefaultData(apnContext);
} else {
String apnString;
- DataConnection.FailCause cause;
cause = (DataConnection.FailCause) (ar.result);
if (DBG) {
@@ -1935,7 +2018,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
apnContext.getWaitingApns().size(),
apnContext.getWaitingApnsPermFailCount()));
}
+ handleError = true;
+ }
+ if (handleError) {
// See if there are more APN's to try
if (apnContext.getWaitingApns().isEmpty()) {
if (apnContext.getWaitingApnsPermFailCount() == 0) {
@@ -1947,9 +2033,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
apnContext.setDataConnection(null);
apnContext.setDataConnectionAc(null);
- if (DBG) {
- log("onDataSetupComplete: permanent error apn=%s" + apnString );
- }
} else {
if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
// check to see if retry should be overridden for this failure.
@@ -2044,7 +2127,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (isConnected()) {
if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
startNetStatPoll();
- startDataStallAlarm();
+ startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
} else {
// clean slate after call end.
@@ -2149,7 +2232,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
RetryManager rm = new RetryManager();
int id = mUniqueIdGenerator.getAndIncrement();
- GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm);
+ GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm, this);
mDataConnections.put(id, conn);
DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG);
int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
@@ -2279,26 +2362,30 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private void setPreferredApn(int pos) {
if (!canSetPreferApn) {
+ log("setPreferredApn: X !canSEtPreferApn");
return;
}
+ log("setPreferredApn: delete");
ContentResolver resolver = mPhone.getContext().getContentResolver();
- resolver.delete(PREFERAPN_URI, null, null);
+ resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
if (pos >= 0) {
+ log("setPreferredApn: insert");
ContentValues values = new ContentValues();
values.put(APN_ID, pos);
- resolver.insert(PREFERAPN_URI, values);
+ resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
}
}
private ApnSetting getPreferredApn() {
if (mAllApns.isEmpty()) {
+ log("getPreferredApn: X not found mAllApns.isEmpty");
return null;
}
Cursor cursor = mPhone.getContext().getContentResolver().query(
- PREFERAPN_URI, new String[] { "_id", "name", "apn" },
+ PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
if (cursor != null) {
@@ -2313,6 +2400,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
for(ApnSetting p:mAllApns) {
if (p.id == pos && p.canHandleType(mRequestedApnType)) {
+ log("getPreferredApn: X found apnSetting" + p);
cursor.close();
return p;
}
@@ -2323,6 +2411,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
cursor.close();
}
+ log("getPreferredApn: X not found");
return null;
}
@@ -2386,7 +2475,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
mIsPsRestricted = false;
if (isConnected()) {
startNetStatPoll();
- startDataStallAlarm();
+ startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
} else {
// TODO: Should all PDN states be checked to fail?
if (mState == State.FAILED) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 84127cf..6e2b262 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -671,7 +671,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
private void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, true);
+ // TODO Make a constructor only has boolean gsm as parameter
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, SignalStrength.INVALID_SNR, -1, true);
}
/**
@@ -1023,7 +1025,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
int lteSignalStrength = -1;
int lteRsrp = -1;
int lteRsrq = -1;
- int lteRssnr = -1;
+ int lteRssnr = SignalStrength.INVALID_SNR;
int lteCqi = -1;
if (ar.exception != null) {