/*
* Copyright (C) 2011 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.util.Log;
import com.android.internal.telephony.IccCardApplication;
import com.android.internal.telephony.IccCardStatus;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.cdma.CdmaInformationRecords;
import java.util.ArrayList;
/**
* Qualcomm RIL class for basebands that do not send the SIM status
* piggybacked in RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED. Instead,
* these radios will send radio state and we have to query for SIM
* status separately.
*
* {@hide}
*/
public class QualcommNoSimReadyRIL extends RIL implements CommandsInterface {
protected HandlerThread mIccThread;
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;
public QualcommNoSimReadyRIL(Context context) {
super(context);
}
public QualcommNoSimReadyRIL(Context context, int networkMode, int cdmaSubscription) {
super(context, networkMode, cdmaSubscription);
}
@Override
protected void
processSolicited (Parcel p) {
int serial, error;
boolean found = false;
serial = p.readInt();
error = p.readInt();
RILRequest rr;
rr = findAndRemoveRequestFromList(serial);
if (rr == null) {
Log.w(LOG_TAG, "Unexpected solicited response! sn: "
+ serial + " error: " + error);
return;
}
Object ret = null;
if (error == 0 || p.dataAvail() > 0) {
// either command succeeds or command fails but with data payload
try {switch (rr.mRequest) {
/*
cat libs/telephony/ril_commands.h \
| egrep "^ *{RIL_" \
| sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
*/
case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break;
case RIL_REQUEST_ENTER_SIM_PIN: ret = responseInts(p); break;
case RIL_REQUEST_ENTER_SIM_PUK: ret = responseInts(p); break;
case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseInts(p); break;
case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseInts(p); break;
case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseInts(p); break;
case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseInts(p); break;
case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseInts(p); break;
case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break;
case RIL_REQUEST_DIAL: ret = responseVoid(p); break;
case RIL_REQUEST_GET_IMSI: ret = responseString(p); break;
case RIL_REQUEST_HANGUP: ret = responseVoid(p); break;
case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break;
case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: ret = responseVoid(p); break;
case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break;
case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break;
case RIL_REQUEST_UDUB: ret = responseVoid(p); break;
case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break;
case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
case RIL_REQUEST_REGISTRATION_STATE: ret = responseStrings(p); break;
case RIL_REQUEST_GPRS_REGISTRATION_STATE: ret = responseStrings(p); break;
case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break;
case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break;
case RIL_REQUEST_DTMF: ret = responseVoid(p); break;
case RIL_REQUEST_SEND_SMS: ret = responseSMS(p); break;
case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret = responseSMS(p); break;
case RIL_REQUEST_SETUP_DATA_CALL: ret = responseStrings(p); break;
case RIL_REQUEST_SIM_IO: ret = responseICC_IO(p); break;
case RIL_REQUEST_SEND_USSD: ret = responseVoid(p); break;
case RIL_REQUEST_CANCEL_USSD: ret = responseVoid(p); break;
case RIL_REQUEST_GET_CLIR: ret = responseInts(p); break;
case RIL_REQUEST_SET_CLIR: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret = responseCallForward(p); break;
case RIL_REQUEST_SET_CALL_FORWARD: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_CALL_WAITING: ret = responseInts(p); break;
case RIL_REQUEST_SET_CALL_WAITING: ret = responseVoid(p); break;
case RIL_REQUEST_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
case RIL_REQUEST_GET_IMEI: ret = responseString(p); break;
case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break;
case RIL_REQUEST_ANSWER: ret = responseVoid(p); break;
case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break;
case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break;
case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break;
case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break;
case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret = responseNetworkInfos(p); break;
case RIL_REQUEST_DTMF_START: ret = responseVoid(p); break;
case RIL_REQUEST_DTMF_STOP: ret = responseVoid(p); break;
case RIL_REQUEST_BASEBAND_VERSION: ret = responseString(p); break;
case RIL_REQUEST_SEPARATE_CONNECTION: ret = responseVoid(p); break;
case RIL_REQUEST_SET_MUTE: ret = responseVoid(p); break;
case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break;
case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break;
case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret = responseInts(p); break;
case RIL_REQUEST_DATA_CALL_LIST: ret = responseDataCallList(p); break;
case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break;
case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break;
case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break;
case RIL_REQUEST_SCREEN_STATE: ret = responseVoid(p); break;
case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break;
case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break;
case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break;
case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break;
case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break;
case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break;
case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break;
case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break;
case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break;
case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break;
case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break;
case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseInts(p); break;
case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SET_SUBSCRIPTION: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break;
case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_TTY_MODE: ret = responseInts(p); break;
case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret = responseInts(p); break;
case RIL_REQUEST_CDMA_FLASH: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break;
case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break;
case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break;
case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break;
case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break;
case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break;
case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break;
case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
case 104: ret = responseInts(p); break; // RIL_REQUEST_VOICE_RADIO_TECH
case 105: ret = responseInts(p); break; // RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE
case 106: ret = responseStrings(p); break; // RIL_REQUEST_CDMA_PRL_VERSION
case 107: ret = responseInts(p); break; // RIL_REQUEST_IMS_REGISTRATION_STATE
case 108: ret = responseSMS(p); break; // RIL_REQUEST_IMS_SEND_SMS
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
}} catch (Throwable tr) {
// Exceptions here usually mean invalid RIL responses
Log.w(LOG_TAG, rr.serialString() + "< "
+ requestToString(rr.mRequest)
+ " exception, possible invalid RIL response", tr);
if (rr.mResult != null) {
AsyncResult.forMessage(rr.mResult, null, tr);
rr.mResult.sendToTarget();
}
rr.release();
return;
}
}
if (error != 0) {
rr.onError(error, ret);
rr.release();
return;
}
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();
}
rr.release();
}
@Override
protected void
processUnsolicited (Parcel p) {
int response;
Object ret;
response = p.readInt();
try {switch(response) {
/*
cat libs/telephony/ril_unsol_commands.h \
| egrep "^ *{RIL_" \
| sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
*/
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break;
case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break;
case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break;
case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_SIM_REFRESH: ret = responseInts(p); break;
case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break;
case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break;
case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseRaw(p); break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
case 1031: ret = responseVoid(p); break; // RIL_UNSOL_VOICE_RADIO_TECH_CHANGED
case 1032: ret = responseInts(p); break; // RIL_UNSOL_TETHERED_MODE_STATE_CHANGED
case 1033: ret = responseVoid(p); break; // RIL_UNSOL_RESPONSE_DATA_NETWORK_STATE_CHANGED
case 1034: ret = responseVoid(p); break; // RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED
case 1035: ret = responseVoid(p); break; // RIL_UNSOL_CDMA_PRL_CHANGED
case 1036: ret = responseVoid(p); break; // RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED
case 1037: ret = responseVoid(p); break; // RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE
default:
throw new RuntimeException("Unrecognized unsol response: " + response);
//break; (implied)
}} catch (Throwable tr) {
Log.e(LOG_TAG, "Exception processing unsol response: " + response +
"Exception:" + tr.toString());
return;
}
switch(response) {
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
int state = p.readInt();
setRadioStateFromRILInt(state);
break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
mCallStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
break;
case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
mNetworkStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
break;
case RIL_UNSOL_RESPONSE_NEW_SMS: {
if (RILJ_LOGD) unsljLog(response);
// FIXME this should move up a layer
String a[] = new String[2];
a[1] = (String)ret;
SmsMessage sms;
sms = SmsMessage.newFromCMT(a);
if (mSMSRegistrant != null) {
mSMSRegistrant
.notifyRegistrant(new AsyncResult(null, sms, null));
}
break;
}
case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mSmsStatusRegistrant != null) {
mSmsStatusRegistrant.notifyRegistrant(
new AsyncResult(null, ret, null));
}
break;
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
if (RILJ_LOGD) unsljLogRet(response, ret);
int[] smsIndex = (int[])ret;
if(smsIndex.length == 1) {
if (mSmsOnSimRegistrant != null) {
mSmsOnSimRegistrant.
notifyRegistrant(new AsyncResult(null, smsIndex, null));
}
} else {
if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length "
+ smsIndex.length);
}
break;
case RIL_UNSOL_ON_USSD:
String[] resp = (String[])ret;
if (resp.length < 2) {
resp = new String[2];
resp[0] = ((String[])ret)[0];
resp[1] = null;
}
if (RILJ_LOGD) unsljLogMore(response, resp[0]);
if (mUSSDRegistrant != null) {
mUSSDRegistrant.notifyRegistrant(
new AsyncResult (null, resp, null));
}
break;
case RIL_UNSOL_NITZ_TIME_RECEIVED:
if (RILJ_LOGD) unsljLogRet(response, ret);
// has bonus long containing milliseconds since boot that the NITZ
// time was received
long nitzReceiveTime = p.readLong();
Object[] result = new Object[2];
result[0] = ret;
result[1] = Long.valueOf(nitzReceiveTime);
if (mNITZTimeRegistrant != null) {
mNITZTimeRegistrant
.notifyRegistrant(new AsyncResult (null, result, null));
} else {
// in case NITZ time registrant isnt registered yet
mLastNITZTimeInfo = result;
}
break;
case RIL_UNSOL_SIGNAL_STRENGTH:
// Note this is set to "verbose" because it happens
// frequently
if (RILJ_LOGV) unsljLogvRet(response, ret);
if (mSignalStrengthRegistrant != null) {
mSignalStrengthRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
if (RILJ_LOGD) unsljLogRet(response, ret);
mDataConnectionRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
break;
case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mSsnRegistrant != null) {
mSsnRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_STK_SESSION_END:
if (RILJ_LOGD) unsljLog(response);
if (mStkSessionEndRegistrant != null) {
mStkSessionEndRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_STK_PROACTIVE_COMMAND:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mStkProCmdRegistrant != null) {
mStkProCmdRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_STK_EVENT_NOTIFY:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mStkEventRegistrant != null) {
mStkEventRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_STK_CALL_SETUP:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mStkCallSetUpRegistrant != null) {
mStkCallSetUpRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
if (RILJ_LOGD) unsljLog(response);
if (mIccSmsFullRegistrant != null) {
mIccSmsFullRegistrant.notifyRegistrant();
}
break;
case RIL_UNSOL_SIM_REFRESH:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mIccRefreshRegistrant != null) {
mIccRefreshRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_CALL_RING:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mRingRegistrant != null) {
mRingRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
if (RILJ_LOGD) unsljLogvRet(response, ret);
if (mRestrictedStateRegistrant != null) {
mRestrictedStateRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
if (RILJ_LOGD) unsljLog(response);
if (mIccStatusChangedRegistrants != null) {
mIccStatusChangedRegistrants.notifyRegistrants();
}
break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
if (RILJ_LOGD) unsljLog(response);
SmsMessage sms = (SmsMessage) ret;
if (mSMSRegistrant != null) {
mSMSRegistrant
.notifyRegistrant(new AsyncResult(null, sms, null));
}
break;
case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
if (RILJ_LOGD) unsljLog(response);
if (mGsmBroadcastSmsRegistrant != null) {
mGsmBroadcastSmsRegistrant
.notifyRegistrant(new AsyncResult(null, ret, null));
}
break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
if (RILJ_LOGD) unsljLog(response);
if (mIccSmsFullRegistrant != null) {
mIccSmsFullRegistrant.notifyRegistrant();
}
break;
case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
if (RILJ_LOGD) unsljLog(response);
if (mEmergencyCallbackModeRegistrant != null) {
mEmergencyCallbackModeRegistrant.notifyRegistrant();
}
break;
case RIL_UNSOL_CDMA_CALL_WAITING:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mCallWaitingInfoRegistrants != null) {
mCallWaitingInfoRegistrants.notifyRegistrants(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mOtaProvisionRegistrants != null) {
mOtaProvisionRegistrants.notifyRegistrants(
new AsyncResult (null, ret, null));
}
break;
case RIL_UNSOL_CDMA_INFO_REC:
ArrayList<CdmaInformationRecords> listInfoRecs;
try {
listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
} catch (ClassCastException e) {
Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
break;
}
for (CdmaInformationRecords rec : listInfoRecs) {
if (RILJ_LOGD) unsljLogRet(response, rec);
notifyRegistrantsCdmaInfoRec(rec);
}
break;
case RIL_UNSOL_OEM_HOOK_RAW:
if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret));
if (mUnsolOemHookRawRegistrant != null) {
mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
}
break;
case RIL_UNSOL_RINGBACK_TONE:
if (RILJ_LOGD) unsljLogvRet(response, ret);
if (mRingbackToneRegistrants != null) {
boolean playtone = (((int[])ret)[0] == 1);
mRingbackToneRegistrants.notifyRegistrants(
new AsyncResult (null, playtone, null));
}
break;
case RIL_UNSOL_RESEND_INCALL_MUTE:
if (RILJ_LOGD) unsljLogRet(response, ret);
if (mResendIncallMuteRegistrants != null) {
mResendIncallMuteRegistrants.notifyRegistrants(
new AsyncResult (null, ret, null));
}
break;
case 1031:
break;
case 1032:
break;
case 1033:
break;
case 1034:
break;
case 1035:
break;
case 1036:
break;
case 1037:
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;
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;
}
setRadioState(radioState);
break;
default:
throw new RuntimeException("Unrecognized RIL_RadioState: " + stateCode);
}
if (mInitialRadioStateChange) {
if (radioState.isOn()) {
Log.d(LOG_TAG, "Radio ON @ init; reset to OFF");
setRadioPower(false, null);
}
else {
setRadioState (radioState);
}
mInitialRadioStateChange = false;
}
else {
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 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);
}
}
}