diff options
author | Shareef Ali <shareefalis@gmail.com> | 2012-06-28 10:36:04 -0500 |
---|---|---|
committer | Shareef Ali <shareefalis@gmail.com> | 2012-07-03 13:20:47 -0500 |
commit | 544de1a65d5570165ae6da13fb36d109e1e4f3ec (patch) | |
tree | 6c339d10fcab607b5dd69658c52c9cb82a1ffbc9 | |
parent | 44f9c784306665b040acab64b37aa514f8e22920 (diff) | |
download | frameworks_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.java | 364 |
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); + } + } + + +} |