summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiulio Cervera <giulio.cervera@gmail.com>2012-08-01 16:59:49 +0400
committerGerrit Code Review <gerrit@review.cyanogenmod.com>2012-08-01 16:59:49 +0400
commitf98bc690cb0340102d533506007092113c242a4c (patch)
tree9d907692f83ee983dca7c6706c929b9d10f3deb7
parentec2df26d40daef188108422f24c19a72c03e6d48 (diff)
parent488effe65db1526345a38030c6890a03241355cf (diff)
downloadframeworks_base-f98bc690cb0340102d533506007092113c242a4c.zip
frameworks_base-f98bc690cb0340102d533506007092113c242a4c.tar.gz
frameworks_base-f98bc690cb0340102d533506007092113c242a4c.tar.bz2
Merge "telephony: Add Sony RIL for Qualcomm basebands" into ics
-rw-r--r--telephony/java/com/android/internal/telephony/SonyQualcommRIL.java476
1 files changed, 476 insertions, 0 deletions
diff --git a/telephony/java/com/android/internal/telephony/SonyQualcommRIL.java b/telephony/java/com/android/internal/telephony/SonyQualcommRIL.java
new file mode 100644
index 0000000..ffd03e1
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SonyQualcommRIL.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import static com.android.internal.telephony.RILConstants.*;
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.telephony.SmsMessage;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Custom Qualcomm No SimReady RIL for Sony
+ *
+ * {@hide}
+ */
+
+public class SonyQualcommRIL extends RIL implements CommandsInterface {
+ protected String mAid = "";
+ protected HandlerThread mIccThread;
+ protected IccHandler mIccHandler;
+ boolean RILJ_LOGV = true;
+ boolean RILJ_LOGD = true;
+
+ private final int RIL_INT_RADIO_OFF = 0;
+ private final int RIL_INT_RADIO_UNAVALIABLE = 1;
+ private final int RIL_INT_RADIO_ON = 10;
+
+ public SonyQualcommRIL(Context context, int networkMode, int cdmaSubscription) {
+ super(context, networkMode, cdmaSubscription);
+ }
+
+ @Override
+ public void
+ iccIO (int command, int fileid, String path, int p1, int p2, int p3,
+ String data, String pin2, Message result) {
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_SIM_IO, result);
+
+ rr.mp.writeInt(command);
+ rr.mp.writeInt(fileid);
+ rr.mp.writeString(path);
+ rr.mp.writeInt(p1);
+ rr.mp.writeInt(p2);
+ rr.mp.writeInt(p3);
+ rr.mp.writeString(data);
+ rr.mp.writeString(pin2);
+ rr.mp.writeString(mAid);
+
+ 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);
+ }
+
+ @Override public void
+ supplyIccPin(String pin, Message result) {
+ supplyIccPinForApp(pin, mAid, result);
+ }
+
+ @Override public void
+ changeIccPin(String oldPin, String newPin, Message result) {
+ changeIccPinForApp(oldPin, newPin, mAid, result);
+ }
+
+ @Override public void
+ supplyIccPin2(String pin, Message result) {
+ supplyIccPin2ForApp(pin, mAid, result);
+ }
+
+ @Override public void
+ changeIccPin2(String oldPin2, String newPin2, Message result) {
+ changeIccPin2ForApp(oldPin2, newPin2, mAid, result);
+ }
+
+ @Override public void
+ supplyIccPuk(String puk, String newPin, Message result) {
+ supplyIccPukForApp(puk, newPin, mAid, result);
+ }
+
+ @Override public void
+ supplyIccPuk2(String puk2, String newPin2, Message result) {
+ supplyIccPuk2ForApp(puk2, newPin2, mAid, result);
+ }
+
+ @Override
+ public void
+ queryFacilityLock(String facility, String password, int serviceClass,
+ Message response) {
+ queryFacilityLockForApp(facility, password, serviceClass, mAid, response);
+ }
+
+ @Override
+ public void
+ setFacilityLock (String facility, boolean lockState, String password,
+ int serviceClass, Message response) {
+ setFacilityLockForApp(facility, lockState, password, serviceClass, mAid, response);
+ }
+
+ @Override
+ protected Object
+ responseIccCardStatus(Parcel p) {
+ IccCardApplication ca;
+
+ IccCardStatus status = new IccCardStatus();
+ status.setCardState(p.readInt());
+ status.setUniversalPinState(p.readInt());
+ status.setGsmUmtsSubscriptionAppIndex(p.readInt());
+ status.setCdmaSubscriptionAppIndex(p.readInt());
+ status.setImsSubscriptionAppIndex(p.readInt());
+
+ int numApplications = p.readInt();
+ // limit to maximum allowed applications
+ if (numApplications > IccCardStatus.CARD_MAX_APPS) {
+ numApplications = IccCardStatus.CARD_MAX_APPS;
+ }
+ status.setNumApplications(numApplications);
+
+ for (int i = 0 ; i < numApplications ; i++) {
+ ca = new IccCardApplication();
+ ca.app_type = ca.AppTypeFromRILInt(p.readInt());
+ ca.app_state = ca.AppStateFromRILInt(p.readInt());
+ ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt());
+ ca.aid = p.readString();
+ ca.app_label = p.readString();
+ ca.pin1_replaced = p.readInt();
+ ca.pin1 = ca.PinStateFromRILInt(p.readInt());
+ ca.pin2 = ca.PinStateFromRILInt(p.readInt());
+ status.addApplication(ca);
+ }
+
+ updateIccType(status);
+ return status;
+ }
+
+ private void updateIccType(IccCardStatus icccardstatus)
+ {
+ IccCardApplication.AppType apptype = IccCardApplication.AppType.APPTYPE_UNKNOWN;
+ if(icccardstatus.getNumApplications() > 0)
+ {
+ CommandsInterface.RadioState radiostate = getRadioState();
+ int i;
+ IccCardApplication icccardapplication;
+ if(radiostate == CommandsInterface.RadioState.RUIM_LOCKED_OR_ABSENT || radiostate == CommandsInterface.RadioState.RUIM_NOT_READY || radiostate == CommandsInterface.RadioState.RUIM_READY)
+ i = icccardstatus.getCdmaSubscriptionAppIndex();
+ else
+ i = icccardstatus.getGsmUmtsSubscriptionAppIndex();
+ icccardapplication = icccardstatus.getApplication(i);
+ Log.i("RILJ", (new StringBuilder()).append("app_state ").append(icccardapplication.app_state).append(", perso_substate ").append(icccardapplication.perso_substate).append(", app_type ").append(icccardapplication.app_type).toString());
+ mAid = icccardapplication.aid;
+ riljLog((new StringBuilder()).append("Will use ").append(mAid).append(" as default application id. Hopefully you wont mind").toString());
+ apptype = icccardapplication.app_type;
+ }
+ SystemProperties.set("ril.icctype", Integer.toString(apptype.ordinal()));
+ }
+
+ @Override
+ public void
+ getIMSI(Message result) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result);
+ rr.mp.writeInt(1);
+ rr.mp.writeString(mAid);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ @Override
+ protected Object
+ responseOperatorInfos(Parcel p) {
+ String strings[] = (String [])responseStrings(p);
+ ArrayList<OperatorInfo> ret;
+
+ if (strings.length % 5 != 0) {
+ throw new RuntimeException(
+ "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
+ + strings.length + " strings, expected multible of 5");
+ }
+
+ ret = new ArrayList<OperatorInfo>(strings.length / 4);
+
+ for (int i = 0 ; i < strings.length ; i += 5) {
+ ret.add (
+ new OperatorInfo(
+ strings[i+0],
+ strings[i+1],
+ strings[i+2],
+ strings[i+3]));
+ }
+ return ret;
+ }
+
+ @Override
+ public void
+ dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
+
+ rr.mp.writeString(address);
+ rr.mp.writeInt(clirMode);
+
+ if (uusInfo == null) {
+ rr.mp.writeInt(0); // UUS information is absent
+ } else {
+ rr.mp.writeInt(1); // UUS information is present
+ rr.mp.writeInt(uusInfo.getType());
+ rr.mp.writeInt(uusInfo.getDcs());
+ rr.mp.writeByteArray(uusInfo.getUserData());
+ }
+ rr.mp.writeInt(255);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ public void
+ setNetworkSelectionMode(String operatorNumeric, Message response) {
+ RILRequest rr;
+
+ if (operatorNumeric == null)
+ rr = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, response);
+ else
+ rr = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, response);
+
+ rr.mp.writeString(operatorNumeric);
+ rr.mp.writeInt(-1);
+
+ send(rr);
+ }
+
+ @Override
+ public void
+ setNetworkSelectionModeAutomatic(Message response) {
+ setNetworkSelectionMode(null, response);
+ }
+
+ @Override
+ public void
+ setNetworkSelectionModeManual(String operatorNumeric, Message response) {
+ setNetworkSelectionMode(operatorNumeric, response);
+ }
+
+ @Override
+ protected Object
+ responseSignalStrength(Parcel p) {
+ int numInts = 12;
+ int response[];
+
+ boolean noLte = false;
+
+ /* TODO: Add SignalStrength class to match RIL_SignalStrength */
+ response = new int[numInts];
+ for (int i = 0 ; i < numInts ; i++) {
+ if (noLte && i > 6 && i < 12) {
+ response[i] = -1;
+ } else {
+ response[i] = p.readInt();
+ }
+ if (i == 7 && response[i] == 99) {
+ response[i] = -1;
+ noLte = true;
+ }
+ if (i == 8 && !noLte) {
+ response[i] *= -1;
+ }
+ }
+
+ return response;
+ }
+
+ @Override
+ protected void
+ processUnsolicited (Parcel p) {
+ Object ret;
+ int dataPosition = p.dataPosition(); // save off position within the Parcel
+ int response = p.readInt();
+
+ switch(response) {
+ case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
+
+ default:
+ // Rewind the Parcel
+ p.setDataPosition(dataPosition);
+
+ // Forward responses that we are not overriding to the super class
+ super.processUnsolicited(p);
+ return;
+ }
+
+ switch(response) {
+ case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
+ int state = p.readInt();
+ setRadioStateFromRILInt(state);
+ break;
+ }
+ }
+
+ private void setRadioStateFromRILInt (int stateCode) {
+ CommandsInterface.RadioState radioState;
+ HandlerThread handlerThread;
+ Looper looper;
+ IccHandler iccHandler;
+
+ switch (stateCode) {
+ case RIL_INT_RADIO_OFF:
+ radioState = CommandsInterface.RadioState.RADIO_OFF;
+ if (mIccHandler != null) {
+ mIccThread = null;
+ mIccHandler = null;
+ }
+ break;
+ case RIL_INT_RADIO_UNAVALIABLE:
+ radioState = CommandsInterface.RadioState.RADIO_UNAVAILABLE;
+ break;
+ case RIL_INT_RADIO_ON:
+ if (mIccHandler == null) {
+ handlerThread = new HandlerThread("IccHandler");
+ mIccThread = handlerThread;
+
+ mIccThread.start();
+
+ looper = mIccThread.getLooper();
+ mIccHandler = new IccHandler(this,looper);
+ mIccHandler.run();
+ }
+ if (mPhoneType == RILConstants.CDMA_PHONE) {
+ radioState = CommandsInterface.RadioState.RUIM_NOT_READY;
+ } else {
+ radioState = CommandsInterface.RadioState.SIM_NOT_READY;
+ }
+ break;
+ default:
+ throw new RuntimeException("Unrecognized RIL_RadioState: " + stateCode);
+ }
+
+ setRadioState(radioState);
+ }
+
+ class IccHandler extends Handler implements Runnable {
+ private static final int EVENT_GET_ICC_STATUS_DONE = 1;
+ private static final int EVENT_ICC_STATUS_CHANGED = 2;
+ private static final int EVENT_RADIO_ON = 3;
+ private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 4;
+
+ private RIL mRil;
+ private boolean mRadioOn = false;
+
+ public IccHandler (RIL ril, Looper looper) {
+ super (looper);
+ mRil = ril;
+ }
+
+ public void handleMessage (Message paramMessage) {
+ switch (paramMessage.what) {
+ case EVENT_RADIO_ON:
+ mRadioOn = true;
+ Log.d(LOG_TAG, "Radio on -> Forcing sim status update");
+ sendMessage(obtainMessage(EVENT_ICC_STATUS_CHANGED));
+ break;
+ case EVENT_GET_ICC_STATUS_DONE:
+ AsyncResult asyncResult = (AsyncResult) paramMessage.obj;
+ if (asyncResult.exception != null) {
+ Log.e (LOG_TAG, "IccCardStatusDone shouldn't return exceptions!", asyncResult.exception);
+ break;
+ }
+ IccCardStatus status = (IccCardStatus) asyncResult.result;
+ if (status.getNumApplications() == 0) {
+ if (!mRil.getRadioState().isOn()) {
+ break;
+ }
+ if (mPhoneType == RILConstants.CDMA_PHONE) {
+ mRil.setRadioState(CommandsInterface.RadioState.RUIM_LOCKED_OR_ABSENT);
+ } else {
+ mRil.setRadioState(CommandsInterface.RadioState.SIM_LOCKED_OR_ABSENT);
+ }
+ } else {
+ int appIndex = -1;
+ if (mPhoneType == RILConstants.CDMA_PHONE) {
+ appIndex = status.getCdmaSubscriptionAppIndex();
+ Log.d(LOG_TAG, "This is a CDMA PHONE " + appIndex);
+ } else {
+ appIndex = status.getGsmUmtsSubscriptionAppIndex();
+ Log.d(LOG_TAG, "This is a GSM PHONE " + appIndex);
+ }
+
+ IccCardApplication application = status.getApplication(appIndex);
+ IccCardApplication.AppState app_state = application.app_state;
+ IccCardApplication.AppType app_type = application.app_type;
+ switch (app_state) {
+ case APPSTATE_PIN:
+ case APPSTATE_PUK:
+ switch (app_type) {
+ case APPTYPE_SIM:
+ case APPTYPE_USIM:
+ mRil.setRadioState(CommandsInterface.RadioState.SIM_LOCKED_OR_ABSENT);
+ break;
+ case APPTYPE_RUIM:
+ mRil.setRadioState(CommandsInterface.RadioState.RUIM_LOCKED_OR_ABSENT);
+ break;
+ default:
+ Log.e(LOG_TAG, "Currently we don't handle SIMs of type: " + app_type);
+ return;
+ }
+ break;
+ case APPSTATE_READY:
+ switch (app_type) {
+ case APPTYPE_SIM:
+ case APPTYPE_USIM:
+ mRil.setRadioState(CommandsInterface.RadioState.SIM_READY);
+ break;
+ case APPTYPE_RUIM:
+ mRil.setRadioState(CommandsInterface.RadioState.RUIM_READY);
+ break;
+ default:
+ Log.e(LOG_TAG, "Currently we don't handle SIMs of type: " + app_type);
+ return;
+ }
+ break;
+ default:
+ return;
+ }
+ }
+ break;
+ case EVENT_ICC_STATUS_CHANGED:
+ if (mRadioOn) {
+ Log.d(LOG_TAG, "Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
+ mRil.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, paramMessage.obj));
+ } else {
+ Log.d(LOG_TAG, "Received EVENT_ICC_STATUS_CHANGED while radio is not ON. Ignoring");
+ }
+ break;
+ case EVENT_RADIO_OFF_OR_UNAVAILABLE:
+ mRadioOn = false;
+ // disposeCards(); // to be verified;
+ default:
+ Log.e(LOG_TAG, " Unknown Event " + paramMessage.what);
+ break;
+ }
+ }
+
+ public void run () {
+ mRil.registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, null);
+ Message msg = obtainMessage(EVENT_RADIO_ON);
+ mRil.getIccCardStatus(msg);
+ }
+ }
+}