Added more RIL classes for the purposes of testing.
diff --git a/ril/SamsungQcom3GDSRIL.java b/ril/SamsungQcom3GDSRIL.java
new file mode 100644
index 0000000..b6bac99
--- /dev/null
+++ b/ril/SamsungQcom3GDSRIL.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2014, The CyanogenMod Project. All rights reserved.
+ *
+ * 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.telephony.Rlog;
+import android.os.AsyncResult;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.SystemProperties;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SignalStrength;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus;
+import com.android.internal.telephony.uicc.IccCardStatus;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Qualcomm RIL for Samsung MSM8916 (3G) devices
+ * {@hide}
+ */
+public class SamsungQcom3GDSRIL extends RIL {
+
+ private static final int RIL_REQUEST_DIAL_EMERGENCY = 10001;
+ private static final int RIL_UNSOL_ON_SS_LL = 11055;
+
+ public SamsungQcom3GDSRIL(Context context, int networkMode, int cdmaSubscription) {
+ super(context, networkMode, cdmaSubscription, null);
+ mQANElements = 6;
+ }
+
+ public SamsungQcom3GDSRIL(Context context, int preferredNetworkType,
+ int cdmaSubscription, Integer instanceId) {
+ super(context, preferredNetworkType, cdmaSubscription, instanceId);
+ mQANElements = 6;
+ }
+
+ @Override
+ public void
+ dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
+ if (PhoneNumberUtils.isEmergencyNumber(address)) {
+ dialEmergencyCall(address, clirMode, result);
+ return;
+ }
+
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
+
+ rr.mParcel.writeString(address);
+ rr.mParcel.writeInt(clirMode);
+ rr.mParcel.writeInt(0); // CallDetails.call_type
+ rr.mParcel.writeInt(1); // CallDetails.call_domain
+ rr.mParcel.writeString(""); // CallDetails.getCsvFromExtras
+
+ if (uusInfo == null) {
+ rr.mParcel.writeInt(0); // UUS information is absent
+ } else {
+ rr.mParcel.writeInt(1); // UUS information is present
+ rr.mParcel.writeInt(uusInfo.getType());
+ rr.mParcel.writeInt(uusInfo.getDcs());
+ rr.mParcel.writeByteArray(uusInfo.getUserData());
+ }
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ @Override
+ protected Object
+ responseIccCardStatus(Parcel p) {
+ IccCardApplicationStatus appStatus;
+
+ IccCardStatus cardStatus = new IccCardStatus();
+ cardStatus.setCardState(p.readInt());
+ cardStatus.setUniversalPinState(p.readInt());
+ cardStatus.mGsmUmtsSubscriptionAppIndex = p.readInt();
+ cardStatus.mCdmaSubscriptionAppIndex = p.readInt();
+ cardStatus.mImsSubscriptionAppIndex = p.readInt();
+
+ int numApplications = p.readInt();
+
+ // limit to maximum allowed applications
+ if (numApplications > IccCardStatus.CARD_MAX_APPS) {
+ numApplications = IccCardStatus.CARD_MAX_APPS;
+ }
+ cardStatus.mApplications = new IccCardApplicationStatus[numApplications];
+
+ for (int i = 0 ; i < numApplications ; i++) {
+ appStatus = new IccCardApplicationStatus();
+ appStatus.app_type = appStatus.AppTypeFromRILInt(p.readInt());
+ appStatus.app_state = appStatus.AppStateFromRILInt(p.readInt());
+ appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(p.readInt());
+ appStatus.aid = p.readString();
+ appStatus.app_label = p.readString();
+ appStatus.pin1_replaced = p.readInt();
+ appStatus.pin1 = appStatus.PinStateFromRILInt(p.readInt());
+ appStatus.pin2 = appStatus.PinStateFromRILInt(p.readInt());
+ p.readInt(); // pin1_num_retries
+ p.readInt(); // puk1_num_retries
+ p.readInt(); // pin2_num_retries
+ p.readInt(); // puk2_num_retries
+ p.readInt(); // perso_unblock_retries
+
+ cardStatus.mApplications[i] = appStatus;
+ }
+ return cardStatus;
+ }
+
+ @Override
+ protected Object
+ responseCallList(Parcel p) {
+ int num;
+ int voiceSettings;
+ ArrayList<DriverCall> response;
+ DriverCall dc;
+
+ num = p.readInt();
+ response = new ArrayList<DriverCall>(num);
+
+ if (RILJ_LOGV) {
+ riljLog("responseCallList: num=" + num +
+ " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant +
+ " mTestingEmergencyCall=" + mTestingEmergencyCall.get());
+ }
+ for (int i = 0 ; i < num ; i++) {
+ dc = new DriverCall();
+
+ dc.state = DriverCall.stateFromCLCC(p.readInt());
+ dc.index = p.readInt() & 0xff;
+ 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;
+ boolean isVideo;
+ int call_type = p.readInt(); // Samsung CallDetails
+ int call_domain = p.readInt(); // Samsung CallDetails
+ String csv = p.readString(); // Samsung CallDetails
+ dc.isVoicePrivacy = (0 != p.readInt());
+ dc.number = p.readString();
+ int np = p.readInt();
+ dc.numberPresentation = DriverCall.presentationFromCLIP(np);
+ dc.name = p.readString();
+ dc.namePresentation = DriverCall.presentationFromCLIP(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);
+
+ if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) {
+ if (mEmergencyCallbackModeRegistrant != null) {
+ riljLog("responseCallList: call ended, testing emergency call," +
+ " notify ECM Registrants");
+ mEmergencyCallbackModeRegistrant.notifyRegistrant();
+ }
+ }
+
+ return response;
+ }
+
+ @Override
+ protected Object
+ responseSignalStrength(Parcel p) {
+ int gsmSignalStrength = p.readInt() & 0xff;
+ int gsmBitErrorRate = p.readInt();
+ int cdmaDbm = p.readInt();
+ int cdmaEcio = p.readInt();
+ int evdoDbm = p.readInt();
+ int evdoEcio = p.readInt();
+ int evdoSnr = p.readInt();
+ int lteSignalStrength = p.readInt();
+ int lteRsrp = p.readInt();
+ int lteRsrq = p.readInt();
+ int lteRssnr = p.readInt();
+ int lteCqi = p.readInt();
+ int tdScdmaRscp = p.readInt();
+ // constructor sets default true, makeSignalStrengthFromRilParcel does not set it
+ boolean isGsm = true;
+
+ if ((lteSignalStrength & 0xff) == 255 || lteSignalStrength == 99) {
+ lteSignalStrength = 99;
+ lteRsrp = SignalStrength.INVALID;
+ lteRsrq = SignalStrength.INVALID;
+ lteRssnr = SignalStrength.INVALID;
+ lteCqi = SignalStrength.INVALID;
+ } else {
+ lteSignalStrength &= 0xff;
+ }
+
+ if (RILJ_LOGD)
+ riljLog("gsmSignalStrength:" + gsmSignalStrength + " gsmBitErrorRate:" + gsmBitErrorRate +
+ " cdmaDbm:" + cdmaDbm + " cdmaEcio:" + cdmaEcio + " evdoDbm:" + evdoDbm +
+ " evdoEcio: " + evdoEcio + " evdoSnr:" + evdoSnr +
+ " lteSignalStrength:" + lteSignalStrength + " lteRsrp:" + lteRsrp +
+ " lteRsrq:" + lteRsrq + " lteRssnr:" + lteRssnr + " lteCqi:" + lteCqi +
+ " tdScdmaRscp:" + tdScdmaRscp + " isGsm:" + (isGsm ? "true" : "false"));
+
+ return new SignalStrength(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, evdoDbm,
+ evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, lteRsrq, lteRssnr, lteCqi,
+ tdScdmaRscp, isGsm);
+ }
+
+ @Override
+ protected void
+ processUnsolicited (Parcel p) {
+ Object ret;
+ int dataPosition = p.dataPosition();
+ int response = p.readInt();
+ int newResponse = response;
+
+ switch(response) {
+ case RIL_UNSOL_ON_SS_LL:
+ newResponse = RIL_UNSOL_ON_SS;
+ break;
+ }
+ if (newResponse != response) {
+ p.setDataPosition(dataPosition);
+ p.writeInt(newResponse);
+ }
+ p.setDataPosition(dataPosition);
+ super.processUnsolicited(p);
+ }
+
+ @Override
+ public void
+ acceptCall (Message result) {
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_ANSWER, result);
+
+ rr.mParcel.writeInt(1);
+ rr.mParcel.writeInt(0);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ private void
+ dialEmergencyCall(String address, int clirMode, Message result) {
+ RILRequest rr;
+
+ rr = RILRequest.obtain(RIL_REQUEST_DIAL_EMERGENCY, result);
+ rr.mParcel.writeString(address);
+ rr.mParcel.writeInt(clirMode);
+ rr.mParcel.writeInt(0); // CallDetails.call_type
+ rr.mParcel.writeInt(3); // CallDetails.call_domain
+ rr.mParcel.writeString(""); // CallDetails.getCsvFromExtra
+ rr.mParcel.writeInt(0); // Unknown
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ @Override
+ protected RILRequest
+ processSolicited (Parcel p) {
+ int serial, error;
+ boolean found = false;
+ int dataPosition = p.dataPosition(); // save off position within the Parcel
+ serial = p.readInt();
+ error = p.readInt();
+ RILRequest rr = null;
+ /* Pre-process the reply before popping it */
+ synchronized (mRequestList) {
+ RILRequest tr = mRequestList.get(serial);
+ if (tr != null && tr.mSerial == serial) {
+ if (error == 0 || p.dataAvail() > 0) {
+ try {switch (tr.mRequest) {
+ /* Get those we're interested in */
+ case RIL_REQUEST_DATA_REGISTRATION_STATE:
+ rr = tr;
+ break;
+ }} catch (Throwable thr) {
+ // Exceptions here usually mean invalid RIL responses
+ if (tr.mResult != null) {
+ AsyncResult.forMessage(tr.mResult, null, thr);
+ tr.mResult.sendToTarget();
+ }
+ return tr;
+ }
+ }
+ }
+ }
+ if (rr == null) {
+ /* Nothing we care about, go up */
+ p.setDataPosition(dataPosition);
+ // Forward responses that we are not overriding to the super class
+ return super.processSolicited(p);
+ }
+ rr = findAndRemoveRequestFromList(serial);
+ if (rr == null) {
+ return rr;
+ }
+ Object ret = null;
+ if (error == 0 || p.dataAvail() > 0) {
+ switch (rr.mRequest) {
+ case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseDataRegistrationState(p); break;
+ default:
+ throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
+ }
+ //break;
+ }
+ if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
+ + " " + retToString(rr.mRequest, ret));
+ if (rr.mResult != null) {
+ AsyncResult.forMessage(rr.mResult, ret, null);
+ rr.mResult.sendToTarget();
+ }
+ return rr;
+ }
+
+ private Object
+ responseDataRegistrationState(Parcel p) {
+ String response[] = (String[])responseStrings(p);
+ /* DANGER WILL ROBINSON
+ * In some cases from Vodaphone we are receiving a RAT of 102
+ * while in tunnels of the metro. Lets Assume that if we
+ * receive 102 we actually want a RAT of 2 for EDGE service */
+ if (response.length > 4 &&
+ response[0].equals("1") &&
+ response[3].equals("102")) {
+ response[3] = "2";
+ }
+ return response;
+ }
+}
\ No newline at end of file