diff --git a/src/java/com/android/internal/telephony/SemcQualcomm7x30RIL.java b/src/java/com/android/internal/telephony/SemcQualcomm7x30RIL.java new file mode 100644 index 00000000000..e82499c4656 --- /dev/null +++ b/src/java/com/android/internal/telephony/SemcQualcomm7x30RIL.java @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2011-2013 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.text.TextUtils; +import android.util.Log; + +import com.android.internal.telephony.IccCardApplicationStatus; + +import java.util.ArrayList; + +/** + * Custom Qualcomm No SimReady RIL for SEMC 7x30 Radio + * + * {@hide} + */ +public class SemcQualcomm7x30RIL 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 = 2; + + public SemcQualcomm7x30RIL(Context context, int networkMode, int cdmaSubscription) { + super(context, networkMode, cdmaSubscription); + mQANElements = 5; + } + + @Override + protected DataCallState getDataCallState(Parcel p, int version) { + DataCallState dataCall = new DataCallState(); + + dataCall.version = version; + if (version < 5) { + dataCall.cid = p.readInt(); + dataCall.active = p.readInt(); + dataCall.type = p.readString(); + String addresses = p.readString(); + if (!TextUtils.isEmpty(addresses)) { + dataCall.addresses = addresses.split(" "); + } + // DataCallState needs an ifname. Since we don't have one use the name from the ThrottleService resource (default=rmnet0). + dataCall.ifname = "rmnet0"; + } else { + dataCall.status = p.readInt(); + dataCall.suggestedRetryTime = p.readInt(); + dataCall.cid = p.readInt(); + dataCall.active = p.readInt(); + dataCall.type = p.readString(); + dataCall.ifname = p.readString(); + if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) && + TextUtils.isEmpty(dataCall.ifname)) { + throw new RuntimeException("getDataCallState, no ifname"); + } + String addresses = p.readString(); + if (!TextUtils.isEmpty(addresses)) { + dataCall.addresses = addresses.split(" "); + } + String dnses = p.readString(); + if (!TextUtils.isEmpty(dnses)) { + dataCall.dnses = dnses.split(" "); + } + String gateways = p.readString(); + if (!TextUtils.isEmpty(gateways)) { + dataCall.gateways = gateways.split(" "); + } + } + return dataCall; + } + + @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 + public void + iccIO (int command, int fileid, String path, int p1, int p2, int p3, + String data, String pin2, Message result) { + iccIOForApp(command, fileid, path, p1, p2, p3, data, pin2, mAid, result); + } + + @Override + public void + getIMSI(Message result) { + getIMSIForApp(mAid, result); + } + + @Override + public void + getIMSIForApp(String aid, Message result) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result); + + rr.mp.writeString(aid); + + if (RILJ_LOGD) riljLog(rr.serialString() + + "> getIMSI: " + requestToString(rr.mRequest) + + " aid: " + aid); + + send(rr); + } + + @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); + rr.mp.writeInt(0); + + 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 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; + case 1036: ret = responseVoid(p); break; // RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED + + 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; + case 1036: + 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(); + } + radioState = CommandsInterface.RadioState.RADIO_ON; + break; + default: + throw new RuntimeException("Unrecognized RIL_RadioState: " + stateCode); + } + + setRadioState (radioState); + } + + 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 run () { + mRil.registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, null); + Message msg = obtainMessage(EVENT_RADIO_ON); + mRil.getIccCardStatus(msg); + } + } +}