/* * Copyright (C) 2014 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.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.AsyncResult; import android.os.HandlerThread; import android.os.Message; import android.os.Parcel; import android.os.SystemProperties; import android.telephony.Rlog; import android.telephony.SignalStrength; import java.io.IOException; import java.io.InputStream; import com.android.internal.telephony.uicc.IccConstants; import com.android.internal.telephony.uicc.IccIoResult; public class SproutRIL extends RIL implements CommandsInterface { static final int RIL_REQUEST_SET_3G_CAPABILITY = 128; public SproutRIL(Context context, int networkMode, int cdmaSubscription) { super(context, networkMode, cdmaSubscription, null); } public SproutRIL(Context context, int networkMode, int cdmaSubscription, Integer instanceId) { super(context, networkMode, cdmaSubscription, instanceId); } private static int readRilMessage(InputStream is, byte[] buffer) throws IOException { int countRead; int offset; int remaining; int messageLength; // First, read in the length of the message offset = 0; remaining = 4; do { countRead = is.read(buffer, offset, remaining); if (countRead < 0 ) { Rlog.e(RILJ_LOG_TAG, "Hit EOS reading message length"); return -1; } offset += countRead; remaining -= countRead; } while (remaining > 0); messageLength = ((buffer[0] & 0xff) << 24) | ((buffer[1] & 0xff) << 16) | ((buffer[2] & 0xff) << 8) | (buffer[3] & 0xff); // Then, re-use the buffer and read in the message itself offset = 0; remaining = messageLength; do { countRead = is.read(buffer, offset, remaining); if (countRead < 0 ) { Rlog.e(RILJ_LOG_TAG, "Hit EOS reading message. messageLength=" + messageLength + " remaining=" + remaining); return -1; } offset += countRead; remaining -= countRead; } while (remaining > 0); return messageLength; } protected RILReceiver createRILReceiver() { return new MTKRILReceiver(); } protected class MTKRILReceiver extends RILReceiver { byte[] buffer; protected MTKRILReceiver() { buffer = new byte[RIL_MAX_COMMAND_BYTES]; } @Override public void run() { int retryCount = 0; String rilSocket = "rild"; try {for (;;) { LocalSocket s = null; LocalSocketAddress l; if (mInstanceId == null || mInstanceId == 0 ) { rilSocket = SOCKET_NAME_RIL[0]; } else { rilSocket = SOCKET_NAME_RIL[mInstanceId]; } int currentSim; if (mInstanceId == null || mInstanceId ==0) { currentSim = 0; } else { currentSim = mInstanceId; } int m3GsimId = 0; m3GsimId = SystemProperties.getInt("gsm.3gswitch", 0); if((m3GsimId > 0) && (m3GsimId <= 2)) { --m3GsimId; } else { m3GsimId=0; } if (m3GsimId >= 1) { if (currentSim == 0) { rilSocket = SOCKET_NAME_RIL[m3GsimId]; } else if(currentSim == m3GsimId) { rilSocket = SOCKET_NAME_RIL[0]; } if (RILJ_LOGD) riljLog("Capability switched, swap sockets [" + currentSim + ", " + rilSocket + "]"); } try { s = new LocalSocket(); l = new LocalSocketAddress(rilSocket, LocalSocketAddress.Namespace.RESERVED); s.connect(l); } catch (IOException ex){ try { if (s != null) { s.close(); } } catch (IOException ex2) { //ignore failure to close after failure to connect } // don't print an error message after the the first time // or after the 8th time if (retryCount == 8) { Rlog.e (RILJ_LOG_TAG, "Couldn't find '" + rilSocket + "' socket after " + retryCount + " times, continuing to retry silently"); } else if (retryCount > 0 && retryCount < 8) { Rlog.i (RILJ_LOG_TAG, "Couldn't find '" + rilSocket + "' socket; retrying after timeout"); } try { Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); } catch (InterruptedException er) { } retryCount++; continue; } retryCount = 0; mSocket = s; Rlog.i(RILJ_LOG_TAG, "Connected to '" + rilSocket + "' socket"); /* Compatibility with qcom's DSDS (Dual SIM) stack */ if (needsOldRilFeature("qcomdsds")) { String str = "SUB1"; byte[] data = str.getBytes(); try { mSocket.getOutputStream().write(data); Rlog.i(RILJ_LOG_TAG, "Data sent!!"); } catch (IOException ex) { Rlog.e(RILJ_LOG_TAG, "IOException", ex); } catch (RuntimeException exc) { Rlog.e(RILJ_LOG_TAG, "Uncaught exception ", exc); } } int length = 0; try { InputStream is = mSocket.getInputStream(); for (;;) { Parcel p; length = readRilMessage(is, buffer); if (length < 0) { // End-of-stream reached break; } p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); //Rlog.v(RILJ_LOG_TAG, "Read packet: " + length + " bytes"); processResponse(p); p.recycle(); } } catch (java.io.IOException ex) { Rlog.i(RILJ_LOG_TAG, "'" + rilSocket + "' socket closed", ex); } catch (Throwable tr) { Rlog.e(RILJ_LOG_TAG, "Uncaught exception read length=" + length + "Exception:" + tr.toString()); } Rlog.i(RILJ_LOG_TAG, "Disconnected from '" + rilSocket + "' socket"); setRadioState (RadioState.RADIO_UNAVAILABLE); try { mSocket.close(); } catch (IOException ex) { } mSocket = null; RILRequest.resetSerial(); // Clear request list on close clearRequestList(RADIO_NOT_AVAILABLE, false); }} catch (Throwable tr) { Rlog.e(RILJ_LOG_TAG,"Uncaught exception", tr); } /* We're disconnected so we don't know the ril version */ notifyRegistrantsRilConnectionChanged(-1); } } protected RILRequest processSolicited (Parcel p) { int serial, error; boolean found = false; serial = p.readInt(); error = p.readInt(); RILRequest rr; rr = findAndRemoveRequestFromList(serial); if (rr == null) { Rlog.w(RILJ_LOG_TAG, "Unexpected solicited response! sn: " + serial + " error: " + error); return null; } 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_DEPERSONALIZATION_CODE: 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: { if (mTestingEmergencyCall.getAndSet(false)) { if (mEmergencyCallbackModeRegistrant != null) { riljLog("testing emergency call, notify ECM Registrants"); mEmergencyCallbackModeRegistrant.notifyRegistrant(); } } 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_VOICE_REGISTRATION_STATE: ret = responseStrings(p); break; case RIL_REQUEST_DATA_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 = responseSetupDataCall(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 = responseOperatorInfos(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 = responseGetPreferredNetworkType(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_SOURCE: 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 RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break; case RIL_REQUEST_GET_DATA_CALL_PROFILE: ret = responseGetDataCallProfile(p); break; case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break; case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break; case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break; case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break; case RIL_REQUEST_GET_CELL_INFO_LIST: ret = responseCellInfoList(p); break; case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: ret = responseVoid(p); break; case RIL_REQUEST_SET_INITIAL_ATTACH_APN: ret = responseVoid(p); break; case RIL_REQUEST_IMS_REGISTRATION_STATE: ret = responseInts(p); break; case RIL_REQUEST_IMS_SEND_SMS: ret = responseSMS(p); break; case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: ret = responseICC_IO(p); break; case RIL_REQUEST_SIM_OPEN_CHANNEL: ret = responseInts(p); break; case RIL_REQUEST_SIM_CLOSE_CHANNEL: ret = responseVoid(p); break; case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: ret = responseICC_IO(p); break; case RIL_REQUEST_SIM_GET_ATR: ret = responseString(p); break; case RIL_REQUEST_NV_READ_ITEM: ret = responseString(p); break; case RIL_REQUEST_SET_3G_CAPABILITY: ret = responseInts(p); break; case RIL_REQUEST_NV_WRITE_ITEM: ret = responseVoid(p); break; case RIL_REQUEST_NV_WRITE_CDMA_PRL: ret = responseVoid(p); break; case RIL_REQUEST_NV_RESET_CONFIG: ret = responseVoid(p); break; case RIL_REQUEST_SET_UICC_SUBSCRIPTION: ret = responseVoid(p); break; case RIL_REQUEST_ALLOW_DATA: ret = responseVoid(p); break; case RIL_REQUEST_GET_HARDWARE_CONFIG: ret = responseHardwareConfig(p); break; case RIL_REQUEST_SIM_AUTHENTICATION: ret = responseICC_IOBase64(p); break; case RIL_REQUEST_SHUTDOWN: ret = responseVoid(p); break; default: throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest); //break; }} catch (Throwable tr) { // Exceptions here usually mean invalid RIL responses Rlog.w(RILJ_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(); } return rr; } } if (rr.mRequest == RIL_REQUEST_SHUTDOWN) { // Set RADIO_STATE to RADIO_UNAVAILABLE to continue shutdown process // regardless of error code to continue shutdown procedure. riljLog("Response to RIL_REQUEST_SHUTDOWN received. Error is " + error + " Setting Radio State to Unavailable regardless of error."); setRadioState(RadioState.RADIO_UNAVAILABLE); } // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789. // This is needed otherwise we don't automatically transition to the main lock // screen when the pin or puk is entered incorrectly. switch (rr.mRequest) { case RIL_REQUEST_ENTER_SIM_PUK: case RIL_REQUEST_ENTER_SIM_PUK2: if (mIccStatusChangedRegistrants != null) { if (RILJ_LOGD) { riljLog("ON enter sim puk fakeSimStatusChanged: reg count=" + mIccStatusChangedRegistrants.size()); } mIccStatusChangedRegistrants.notifyRegistrants(); } break; } if (error != 0) { switch (rr.mRequest) { case RIL_REQUEST_ENTER_SIM_PIN: case RIL_REQUEST_ENTER_SIM_PIN2: case RIL_REQUEST_CHANGE_SIM_PIN: case RIL_REQUEST_CHANGE_SIM_PIN2: case RIL_REQUEST_SET_FACILITY_LOCK: if (mIccStatusChangedRegistrants != null) { if (RILJ_LOGD) { riljLog("ON some errors fakeSimStatusChanged: reg count=" + mIccStatusChangedRegistrants.size()); } mIccStatusChangedRegistrants.notifyRegistrants(); } break; } rr.onError(error, ret); } else { 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; } static String requestToString(int request) { /* cat libs/telephony/ril_commands.h \ | egrep "^ *{RIL_" \ | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/' */ switch(request) { case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS"; case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN"; case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK"; case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2"; case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2"; case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN"; case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2"; case RIL_REQUEST_ENTER_DEPERSONALIZATION_CODE: return "ENTER_DEPERSONALIZATION_CODE"; case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS"; case RIL_REQUEST_DIAL: return "DIAL"; case RIL_REQUEST_GET_IMSI: return "GET_IMSI"; case RIL_REQUEST_HANGUP: return "HANGUP"; case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND"; case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND"; case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE"; case RIL_REQUEST_CONFERENCE: return "CONFERENCE"; case RIL_REQUEST_UDUB: return "UDUB"; case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE"; case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH"; case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE"; case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE"; case RIL_REQUEST_OPERATOR: return "OPERATOR"; case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER"; case RIL_REQUEST_DTMF: return "DTMF"; case RIL_REQUEST_SEND_SMS: return "SEND_SMS"; case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE"; case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL"; case RIL_REQUEST_SIM_IO: return "SIM_IO"; case RIL_REQUEST_SEND_USSD: return "SEND_USSD"; case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD"; case RIL_REQUEST_GET_CLIR: return "GET_CLIR"; case RIL_REQUEST_SET_CLIR: return "SET_CLIR"; case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS"; case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD"; case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING"; case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING"; case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE"; case RIL_REQUEST_GET_IMEI: return "GET_IMEI"; case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV"; case RIL_REQUEST_ANSWER: return "ANSWER"; case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL"; case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK"; case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK"; case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD"; case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE"; case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC"; case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL"; case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS "; case RIL_REQUEST_DTMF_START: return "DTMF_START"; case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP"; case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION"; case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION"; case RIL_REQUEST_SET_MUTE: return "SET_MUTE"; case RIL_REQUEST_GET_MUTE: return "GET_MUTE"; case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP"; case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE"; case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST"; case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO"; case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW"; case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS"; case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE"; case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION"; case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM"; case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM"; case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE"; case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE"; case RIL_REQUEST_STK_GET_PROFILE: return "REQUEST_STK_GET_PROFILE"; case RIL_REQUEST_STK_SET_PROFILE: return "REQUEST_STK_SET_PROFILE"; case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "REQUEST_STK_SEND_ENVELOPE_COMMAND"; case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "REQUEST_STK_SEND_TERMINAL_RESPONSE"; case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM"; case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER"; case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "REQUEST_SET_PREFERRED_NETWORK_TYPE"; case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE"; case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS"; case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES"; case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE"; case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE"; case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE"; case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE"; case RIL_REQUEST_QUERY_TTY_MODE: return "RIL_REQUEST_QUERY_TTY_MODE"; case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE"; case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE"; case RIL_REQUEST_CDMA_FLASH: return "RIL_REQUEST_CDMA_FLASH"; case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF"; case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS"; case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE"; case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG"; case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG"; case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG"; case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG"; case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION"; case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY"; case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION"; case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION"; case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM"; case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM"; case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY"; case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS"; case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS"; case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE"; case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS"; case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING"; case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE"; case RIL_REQUEST_GET_DATA_CALL_PROFILE: return "RIL_REQUEST_GET_DATA_CALL_PROFILE"; case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION"; case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU"; case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS"; case RIL_REQUEST_VOICE_RADIO_TECH: return "RIL_REQUEST_VOICE_RADIO_TECH"; case RIL_REQUEST_GET_CELL_INFO_LIST: return "RIL_REQUEST_GET_CELL_INFO_LIST"; case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return "RIL_REQUEST_SET_CELL_INFO_LIST_RATE"; case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN"; case RIL_REQUEST_IMS_REGISTRATION_STATE: return "RIL_REQUEST_IMS_REGISTRATION_STATE"; case RIL_REQUEST_IMS_SEND_SMS: return "RIL_REQUEST_IMS_SEND_SMS"; case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC"; case RIL_REQUEST_SIM_OPEN_CHANNEL: return "RIL_REQUEST_SIM_OPEN_CHANNEL"; case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "RIL_REQUEST_SIM_CLOSE_CHANNEL"; case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL"; case RIL_REQUEST_NV_READ_ITEM: return "RIL_REQUEST_NV_READ_ITEM"; case RIL_REQUEST_NV_WRITE_ITEM: return "RIL_REQUEST_NV_WRITE_ITEM"; case RIL_REQUEST_NV_WRITE_CDMA_PRL: return "RIL_REQUEST_NV_WRITE_CDMA_PRL"; case RIL_REQUEST_NV_RESET_CONFIG: return "RIL_REQUEST_NV_RESET_CONFIG"; case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "RIL_REQUEST_SET_UICC_SUBSCRIPTION"; case RIL_REQUEST_ALLOW_DATA: return "RIL_REQUEST_ALLOW_DATA"; case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG"; case RIL_REQUEST_SET_3G_CAPABILITY: return "RIL_REQUEST_SET_3G_CAPABILITY"; case RIL_REQUEST_SIM_AUTHENTICATION: return "RIL_REQUEST_SIM_AUTHENTICATION"; case RIL_REQUEST_SHUTDOWN: return "RIL_REQUEST_SHUTDOWN"; default: return ""; } } private byte[] stringToBcd(String input) { int len = input.length(); byte[] result = new byte[(len + 1) / 2]; int pos = 0; for (int i = 0; i < len; i++) { int value = ((int) input.charAt(i)) - '0'; if ((i & 1) != 0) { int temp = (result[pos] & 0xf) | ((value & 0xf) << 4); result[pos] = (byte)temp; pos++; } else { int temp = (0xf0 | (value & 0xf)); result[pos] = (byte)temp; } } return result; } @Override public void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3, String data, String pin2, String aid, Message result) { if (fileid == IccConstants.EF_ICCID) { String iccId = SystemProperties.get("ril.iccid.sim" + (mInstanceId + 1)); byte lenLow = (byte) (iccId.length() >> 8); byte lenHigh = (byte) (iccId.length() & 0xff); byte[] payload = {0, 0, lenHigh, lenLow, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}; if(p3==0) AsyncResult.forMessage(result, new IccIoResult(0x90, 0, payload), null); else AsyncResult.forMessage(result, new IccIoResult(0x90, 0, stringToBcd(iccId)), null); result.sendToTarget(); return; } //Note: This RIL request has not been renamed to ICC, // but this request is also valid for SIM and RUIM RILRequest rr = RILRequest.obtain(RIL_REQUEST_SIM_IO, result); rr.mParcel.writeInt(command); rr.mParcel.writeInt(fileid); rr.mParcel.writeString(path); rr.mParcel.writeInt(p1); rr.mParcel.writeInt(p2); rr.mParcel.writeInt(p3); rr.mParcel.writeString(data); rr.mParcel.writeString(pin2); rr.mParcel.writeString(aid); if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest) + " 0x" + Integer.toHexString(command) + " 0x" + Integer.toHexString(fileid) + " " + " path: " + path + "," + p1 + "," + p2 + "," + p3 + " aid: " + aid); send(rr); } public void setDataAllowed(boolean allowed, Message result) { handle3GSwitch(); RILRequest rr = RILRequest.obtain(125, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + allowed); rr.mParcel.writeInt(1); rr.mParcel.writeInt(allowed ? 1 : 0); send(rr); } public void handle3GSwitch() { int simId = mInstanceId == null ? 0 : mInstanceId; int newsim = SystemProperties.getInt("gsm.3gswitch", 0); newsim = newsim-1; if(!(simId==newsim)) { int prop = SystemProperties.getInt("gsm.3gswitch", 0); if (RILJ_LOGD) riljLog("Setting data subscription on SIM"+(simId+1)+" mInstanceid="+mInstanceId+" gsm.3gswitch="+prop); RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_3G_CAPABILITY, null); rr.mParcel.writeInt(1); int realsim = simId + 1; rr.mParcel.writeInt(realsim); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); try { Thread.sleep(1000); } catch (InterruptedException er) { } resetRadio(null); try { Thread.sleep(4*1000); } catch (InterruptedException er) { } } else { if (RILJ_LOGD) riljLog("Not setting data subscription on same SIM"); } } }