summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShareef Ali <shareefalis@gmail.com>2012-06-28 10:36:04 -0500
committerShareef Ali <shareefalis@gmail.com>2012-07-03 13:20:47 -0500
commit544de1a65d5570165ae6da13fb36d109e1e4f3ec (patch)
tree6c339d10fcab607b5dd69658c52c9cb82a1ffbc9
parent44f9c784306665b040acab64b37aa514f8e22920 (diff)
downloadframeworks_base-544de1a65d5570165ae6da13fb36d109e1e4f3ec.zip
frameworks_base-544de1a65d5570165ae6da13fb36d109e1e4f3ec.tar.gz
frameworks_base-544de1a65d5570165ae6da13fb36d109e1e4f3ec.tar.bz2
Add SamsungCDMAQualcommRIL class for CDMA Galaxy S III family based on msm8960.
* Samsung CDMA RIL doesn't send CDMA NV in RIUM infomation format which causes the CDMA RIL stack to crash and end up not being provisioned. * Samsung put CDMA NV in GSM format. I forced the RIL stack to process CDMA NV request as a GSM SIM in CDMA mode. * Fix hangup bug, force drivercall class not to crash due to a malformed response from ril. I suspect samsung rom ignores that. --FIXED properly JULY 3RD * Workaround for signal strength. * Properly fix drivercall which caused a regression in the previous attempt to fix driver call because the ril is giving another request for videocall infomation and causing drivercall to crash. patchset 3, 4, and 7: Cleanup whitespace patchset 8: wrapped commit message Change-Id: I733a635edc645f4e7952083008e7eca12d7af015
-rw-r--r--telephony/java/com/android/internal/telephony/SamsungCDMAQualcommRIL.java364
1 files changed, 364 insertions, 0 deletions
diff --git a/telephony/java/com/android/internal/telephony/SamsungCDMAQualcommRIL.java b/telephony/java/com/android/internal/telephony/SamsungCDMAQualcommRIL.java
new file mode 100644
index 0000000..ff5bce1
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SamsungCDMAQualcommRIL.java
@@ -0,0 +1,364 @@
+/*
+ * 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 android.telephony.PhoneNumberUtils;
+import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+import com.android.internal.telephony.cdma.CdmaInformationRecords;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Samsung CDMA RIL doesn't send CDMA NV in RIUM infomation format which causes the CDMA RIL stack to crash and end up not being provisioned.
+ * Samsung put CDMA NV in GSM format. I forced the RIL stack to process CDMA NV request as a GSM SIM in CDMA mode.
+ * Custom Qualcomm No SimReady RIL using the latest Uicc stack
+ *
+ * {@hide}
+ */
+public class SamsungCDMAQualcommRIL extends QualcommSharedRIL implements CommandsInterface {
+ protected IccHandler mIccHandler;
+ private final int RIL_INT_RADIO_OFF = 0;
+ private final int RIL_INT_RADIO_UNAVALIABLE = 1;
+ private final int RIL_INT_RADIO_ON = 2;
+ private final int RIL_INT_RADIO_ON_NG = 10;
+ private final int RIL_INT_RADIO_ON_HTC = 13;
+
+ public SamsungCDMAQualcommRIL(Context context, int networkMode, int cdmaSubscription) {
+ super(context, networkMode, cdmaSubscription);
+ }
+
+ @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());
+ p.readInt(); //remaining_count_pin1
+ p.readInt(); //remaining_count_puk1
+ p.readInt(); //remaining_count_pin2
+ p.readInt(); //remaining_count_puk2
+ status.addApplication(ca);
+ }
+ int appIndex = -1;
+ appIndex = status.getGsmUmtsSubscriptionAppIndex();
+ Log.d(LOG_TAG, "This is a CDMA PHONE " + appIndex);
+
+
+ if (numApplications > 0) {
+ IccCardApplication application = status.getApplication(appIndex);
+ mAid = application.aid;
+ mUSIM = application.app_type
+ == IccCardApplication.AppType.APPTYPE_USIM;
+ mSetPreferredNetworkType = mPreferredNetworkType;
+
+ if (TextUtils.isEmpty(mAid))
+ mAid = "";
+ Log.d(LOG_TAG, "mAid " + mAid);
+ }
+
+ return status;
+ }
+
+ 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:
+ case RIL_INT_RADIO_ON_NG:
+ case RIL_INT_RADIO_ON_HTC:
+ if (mIccHandler == null) {
+ handlerThread = new HandlerThread("IccHandler");
+ mIccThread = handlerThread;
+
+ mIccThread.start();
+
+ looper = mIccThread.getLooper();
+ mIccHandler = new IccHandler(this,looper);
+ mIccHandler.run();
+ }
+ radioState = CommandsInterface.RadioState.SIM_NOT_READY;
+
+ setRadioState(radioState);
+ break;
+ default:
+ throw new RuntimeException("Unrecognized RIL_RadioState: " + stateCode);
+ }
+
+ setRadioState (radioState);
+ }
+ @Override
+ protected Object
+ responseSignalStrength(Parcel p) {
+ int numInts = 12;
+ int response[];
+
+ // This is a mashup of algorithms used in
+ // SamsungQualcommUiccRIL.java
+
+ // Get raw data
+ response = new int[numInts];
+ for (int i = 0 ; i < numInts ; i++) {
+ response[i] = p.readInt();
+ }
+ //Workaround: use cdmaecio and evdoecio to determine signal strength and it is better than no signal bars
+ //TODO: find a proper fix for it
+ response[2] = response[3]*4; // mutiply by 4 simulate dbm so the signal bars do not jump often to full bars
+ response[4] = response[5]*4;
+ // RIL_LTE_SignalStrength
+ if (response[7] == 99) {
+ // If LTE is not enabled, clear LTE results
+ // 7-11 must be -1 for GSM signal strength to be used (see frameworks/base/telephony/java/android/telephony/SignalStrength.java)
+ response[7] = -1;
+ response[8] = -1;
+ response[9] = -1;
+ response[10] = -1;
+ response[11] = -1;
+ } else {
+ response[8] *= -1;
+ }
+
+ return response;
+
+ }
+
+ @Override
+ protected Object
+ responseCallList(Parcel p) {
+ int num;
+ int voiceSettings;
+ ArrayList<DriverCall> response;
+ DriverCall dc;
+
+ num = p.readInt();
+ response = new ArrayList<DriverCall>(num);
+
+ for (int i = 0 ; i < num ; i++) {
+ dc = new DriverCall();
+
+ dc.state = DriverCall.stateFromCLCC(p.readInt());
+ dc.index = p.readInt();
+ dc.TOA = p.readInt();
+ dc.isMpty = (0 != p.readInt());
+ dc.isMT = (0 != p.readInt());
+ dc.als = p.readInt();
+ voiceSettings = p.readInt();
+ dc.isVoice = (0 == voiceSettings) ? false : true;
+ dc.isVoicePrivacy = (0 != p.readInt());
+ //Some Samsung magic data for Videocalls
+ // hack taken from smdk4210ril class
+ voiceSettings = p.readInt();
+ //printing it to cosole for later investigation
+ Log.d(LOG_TAG, "Samsung magic = " + voiceSettings);
+ dc.number = p.readString();
+ int np = p.readInt();
+ dc.numberPresentation = DriverCall.presentationFromCLIP(np);
+ dc.name = p.readString();
+ dc.namePresentation = p.readInt();
+ int uusInfoPresent = p.readInt();
+ if (uusInfoPresent == 1) {
+ dc.uusInfo = new UUSInfo();
+ dc.uusInfo.setType(p.readInt());
+ dc.uusInfo.setDcs(p.readInt());
+ byte[] userData = p.createByteArray();
+ dc.uusInfo.setUserData(userData);
+ riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
+ dc.uusInfo.getType(), dc.uusInfo.getDcs(),
+ dc.uusInfo.getUserData().length));
+ riljLogv("Incoming UUS : data (string)="
+ + new String(dc.uusInfo.getUserData()));
+ riljLogv("Incoming UUS : data (hex): "
+ + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
+ } else {
+ riljLogv("Incoming UUS : NOT present!");
+ }
+
+ // Make sure there's a leading + on addresses with a TOA of 145
+ dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
+
+ response.add(dc);
+
+ if (dc.isVoicePrivacy) {
+ mVoicePrivacyOnRegistrants.notifyRegistrants();
+ riljLog("InCall VoicePrivacy is enabled");
+ } else {
+ mVoicePrivacyOffRegistrants.notifyRegistrants();
+ riljLog("InCall VoicePrivacy is disabled");
+ }
+ }
+
+ Collections.sort(response);
+
+ return response;
+ }
+
+ class IccHandler extends Handler implements Runnable {
+ private static final int EVENT_RADIO_ON = 1;
+ private static final int EVENT_ICC_STATUS_CHANGED = 2;
+ private static final int EVENT_GET_ICC_STATUS_DONE = 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;
+ }
+ mRil.setRadioState(CommandsInterface.RadioState.SIM_LOCKED_OR_ABSENT);
+ } else {
+ int appIndex = -1;
+ appIndex = status.getGsmUmtsSubscriptionAppIndex();
+ Log.d(LOG_TAG, "This is a CDMA 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);
+ }
+ }
+
+
+}