/* * Copyright (C) 2006 The Android Open Source 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 static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE; import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS; import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS; import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA; import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA; import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.LocalSocket; import android.net.LocalSocketAddress; 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.os.PowerManager; import android.os.SystemProperties; import android.os.PowerManager.WakeLock; import android.telephony.CellInfo; import android.telephony.NeighboringCellInfo; import android.telephony.PhoneNumberUtils; import android.telephony.Rlog; import android.telephony.SignalStrength; import android.telephony.SmsManager; import android.telephony.SmsMessage; import android.text.TextUtils; import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; import com.android.internal.telephony.gsm.SuppServiceNotification; import com.android.internal.telephony.uicc.IccCardApplicationStatus; import com.android.internal.telephony.uicc.IccCardStatus; import com.android.internal.telephony.uicc.IccIoResult; import com.android.internal.telephony.uicc.IccRefreshResponse; import com.android.internal.telephony.uicc.IccUtils; import com.android.internal.telephony.cdma.CdmaCallWaitingNotification; import com.android.internal.telephony.cdma.CdmaInformationRecords; import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo; import com.android.internal.telephony.dataconnection.DcFailCause; import com.android.internal.telephony.dataconnection.DataCallResponse; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.concurrent.atomic.AtomicBoolean; /** * {@hide} */ class RILRequest { static final String LOG_TAG = "RilRequest"; //***** Class Variables static int sNextSerial = 0; static Object sSerialMonitor = new Object(); private static Object sPoolSync = new Object(); private static RILRequest sPool = null; private static int sPoolSize = 0; private static final int MAX_POOL_SIZE = 4; //***** Instance Variables int mSerial; int mRequest; Message mResult; Parcel mParcel; RILRequest mNext; /** * Retrieves a new RILRequest instance from the pool. * * @param request RIL_REQUEST_* * @param result sent when operation completes * @return a RILRequest instance from the pool. */ static RILRequest obtain(int request, Message result) { RILRequest rr = null; synchronized(sPoolSync) { if (sPool != null) { rr = sPool; sPool = rr.mNext; rr.mNext = null; sPoolSize--; } } if (rr == null) { rr = new RILRequest(); } synchronized(sSerialMonitor) { rr.mSerial = sNextSerial++; } rr.mRequest = request; rr.mResult = result; rr.mParcel = Parcel.obtain(); if (result != null && result.getTarget() == null) { throw new NullPointerException("Message target must not be null"); } // first elements in any RIL Parcel rr.mParcel.writeInt(request); rr.mParcel.writeInt(rr.mSerial); return rr; } /** * Returns a RILRequest instance to the pool. * * Note: This should only be called once per use. */ void release() { synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { mNext = sPool; sPool = this; sPoolSize++; mResult = null; } } } private RILRequest() { } static void resetSerial() { synchronized(sSerialMonitor) { sNextSerial = 0; } } String serialString() { //Cheesy way to do %04d StringBuilder sb = new StringBuilder(8); String sn; sn = Integer.toString(mSerial); //sb.append("J["); sb.append('['); for (int i = 0, s = sn.length() ; i < 4 - s; i++) { sb.append('0'); } sb.append(sn); sb.append(']'); return sb.toString(); } void onError(int error, Object ret) { CommandException ex; ex = CommandException.fromRilErrno(error); if (RIL.RILJ_LOGD) Rlog.d(LOG_TAG, serialString() + "< " + RIL.requestToString(mRequest) + " error: " + ex); if (mResult != null) { AsyncResult.forMessage(mResult, ret, ex); mResult.sendToTarget(); } if (mParcel != null) { mParcel.recycle(); mParcel = null; } } } /** * RIL implementation of the CommandsInterface. * * {@hide} */ public final class RIL extends BaseCommands implements CommandsInterface { static final String RILJ_LOG_TAG = "RILJ"; static final boolean RILJ_LOGD = true; static final boolean RILJ_LOGV = false; // STOPSHIP if true /** * Wake lock timeout should be longer than the longest timeout in * the vendor ril. */ private static final int DEFAULT_WAKE_LOCK_TIMEOUT = 60000; //***** Instance Variables LocalSocket mSocket; HandlerThread mSenderThread; RILSender mSender; Thread mReceiverThread; RILReceiver mReceiver; WakeLock mWakeLock; int mWakeLockTimeout; // The number of requests pending to be sent out, it increases before calling // EVENT_SEND and decreases while handling EVENT_SEND. It gets cleared while // WAKE_LOCK_TIMEOUT occurs. int mRequestMessagesPending; // The number of requests sent out but waiting for response. It increases while // sending request and decreases while handling response. It should match // mRequestList.size() unless there are requests no replied while // WAKE_LOCK_TIMEOUT occurs. int mRequestMessagesWaiting; //I'd rather this be LinkedList or something ArrayList mRequestList = new ArrayList(); Object mLastNITZTimeInfo; // When we are testing emergency calls AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false); //***** Events static final int EVENT_SEND = 1; static final int EVENT_WAKE_LOCK_TIMEOUT = 2; //***** Constants // match with constant in ril.cpp static final int RIL_MAX_COMMAND_BYTES = (8 * 1024); static final int RESPONSE_SOLICITED = 0; static final int RESPONSE_UNSOLICITED = 1; static final String SOCKET_NAME_RIL = "rild"; static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000; // The number of the required config values for broadcast SMS stored in the C struct // RIL_CDMA_BroadcastServiceInfo private static final int CDMA_BSI_NO_OF_INTS_STRUCT = 3; private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31; BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { sendScreenState(true); } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { sendScreenState(false); } else { Rlog.w(RILJ_LOG_TAG, "RIL received unexpected Intent: " + intent.getAction()); } } }; class RILSender extends Handler implements Runnable { public RILSender(Looper looper) { super(looper); } // Only allocated once byte[] dataLength = new byte[4]; //***** Runnable implementation @Override public void run() { //setup if needed } //***** Handler implementation @Override public void handleMessage(Message msg) { RILRequest rr = (RILRequest)(msg.obj); RILRequest req = null; switch (msg.what) { case EVENT_SEND: /** * mRequestMessagePending++ already happened for every * EVENT_SEND, thus we must make sure * mRequestMessagePending-- happens once and only once */ boolean alreadySubtracted = false; try { LocalSocket s; s = mSocket; if (s == null) { rr.onError(RADIO_NOT_AVAILABLE, null); rr.release(); if (mRequestMessagesPending > 0) mRequestMessagesPending--; alreadySubtracted = true; return; } synchronized (mRequestList) { mRequestList.add(rr); mRequestMessagesWaiting++; } if (mRequestMessagesPending > 0) mRequestMessagesPending--; alreadySubtracted = true; byte[] data; data = rr.mParcel.marshall(); rr.mParcel.recycle(); rr.mParcel = null; if (data.length > RIL_MAX_COMMAND_BYTES) { throw new RuntimeException( "Parcel larger than max bytes allowed! " + data.length); } // parcel length in big endian dataLength[0] = dataLength[1] = 0; dataLength[2] = (byte)((data.length >> 8) & 0xff); dataLength[3] = (byte)((data.length) & 0xff); //Rlog.v(RILJ_LOG_TAG, "writing packet: " + data.length + " bytes"); s.getOutputStream().write(dataLength); s.getOutputStream().write(data); } catch (IOException ex) { Rlog.e(RILJ_LOG_TAG, "IOException", ex); req = findAndRemoveRequestFromList(rr.mSerial); // make sure this request has not already been handled, // eg, if RILReceiver cleared the list. if (req != null || !alreadySubtracted) { rr.onError(RADIO_NOT_AVAILABLE, null); rr.release(); } } catch (RuntimeException exc) { Rlog.e(RILJ_LOG_TAG, "Uncaught exception ", exc); req = findAndRemoveRequestFromList(rr.mSerial); // make sure this request has not already been handled, // eg, if RILReceiver cleared the list. if (req != null || !alreadySubtracted) { rr.onError(GENERIC_FAILURE, null); rr.release(); } } finally { // Note: We are "Done" only if there are no outstanding // requests or replies. Thus this code path will only release // the wake lock on errors. releaseWakeLockIfDone(); } if (!alreadySubtracted && mRequestMessagesPending > 0) { mRequestMessagesPending--; } break; case EVENT_WAKE_LOCK_TIMEOUT: // Haven't heard back from the last request. Assume we're // not getting a response and release the wake lock. synchronized (mWakeLock) { if (mWakeLock.isHeld()) { // The timer of WAKE_LOCK_TIMEOUT is reset with each // new send request. So when WAKE_LOCK_TIMEOUT occurs // all requests in mRequestList already waited at // least DEFAULT_WAKE_LOCK_TIMEOUT but no response. // Reset mRequestMessagesWaiting to enable // releaseWakeLockIfDone(). // // Note: Keep mRequestList so that delayed response // can still be handled when response finally comes. if (mRequestMessagesWaiting != 0) { Rlog.d(RILJ_LOG_TAG, "NOTE: mReqWaiting is NOT 0 but" + mRequestMessagesWaiting + " at TIMEOUT, reset!" + " There still msg waitng for response"); mRequestMessagesWaiting = 0; if (RILJ_LOGD) { synchronized (mRequestList) { int count = mRequestList.size(); Rlog.d(RILJ_LOG_TAG, "WAKE_LOCK_TIMEOUT " + " mRequestList=" + count); for (int i = 0; i < count; i++) { rr = mRequestList.get(i); Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] " + requestToString(rr.mRequest)); } } } } // mRequestMessagesPending shows how many // requests are waiting to be sent (and before // to be added in request list) since star the // WAKE_LOCK_TIMEOUT timer. Since WAKE_LOCK_TIMEOUT // is the expected time to get response, all requests // should already sent out (i.e. // mRequestMessagesPending is 0 )while TIMEOUT occurs. if (mRequestMessagesPending != 0) { Rlog.e(RILJ_LOG_TAG, "ERROR: mReqPending is NOT 0 but" + mRequestMessagesPending + " at TIMEOUT, reset!"); mRequestMessagesPending = 0; } mWakeLock.release(); } } break; } } } /** * Reads in a single RIL message off the wire. A RIL message consists * of a 4-byte little-endian length and a subsequent series of bytes. * The final message (length header omitted) is read into * buffer and the length of the final message (less header) * is returned. A return value of -1 indicates end-of-stream. * * @param is non-null; Stream to read from * @param buffer Buffer to fill in. Must be as large as maximum * message size, or an ArrayOutOfBounds exception will be thrown. * @return Length of message less header, or -1 on end of stream. * @throws IOException */ 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; } class RILReceiver implements Runnable { byte[] buffer; RILReceiver() { buffer = new byte[RIL_MAX_COMMAND_BYTES]; } @Override public void run() { int retryCount = 0; try {for (;;) { LocalSocket s = null; LocalSocketAddress l; try { s = new LocalSocket(); l = new LocalSocketAddress(SOCKET_NAME_RIL, 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 '" + SOCKET_NAME_RIL + "' socket after " + retryCount + " times, continuing to retry silently"); } else if (retryCount > 0 && retryCount < 8) { Rlog.i (RILJ_LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL + "' 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 '" + SOCKET_NAME_RIL + "' socket"); 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, "'" + SOCKET_NAME_RIL + "' 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 '" + SOCKET_NAME_RIL + "' 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); } } //***** Constructors public RIL(Context context, int preferredNetworkType, int cdmaSubscription) { super(context); if (RILJ_LOGD) { riljLog("RIL(context, preferredNetworkType=" + preferredNetworkType + " cdmaSubscription=" + cdmaSubscription + ")"); } mCdmaSubscription = cdmaSubscription; mPreferredNetworkType = preferredNetworkType; mPhoneType = RILConstants.NO_PHONE; PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_LOG_TAG); mWakeLock.setReferenceCounted(false); mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT, DEFAULT_WAKE_LOCK_TIMEOUT); mRequestMessagesPending = 0; mRequestMessagesWaiting = 0; mSenderThread = new HandlerThread("RILSender"); mSenderThread.start(); Looper looper = mSenderThread.getLooper(); mSender = new RILSender(looper); ConnectivityManager cm = (ConnectivityManager)context.getSystemService( Context.CONNECTIVITY_SERVICE); if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) { riljLog("Not starting RILReceiver: wifi-only"); } else { riljLog("Starting RILReceiver"); mReceiver = new RILReceiver(); mReceiverThread = new Thread(mReceiver, "RILReceiver"); mReceiverThread.start(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); context.registerReceiver(mIntentReceiver, filter); } } //***** CommandsInterface implementation @Override public void getVoiceRadioTechnology(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_RADIO_TECH, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void setOnNITZTime(Handler h, int what, Object obj) { super.setOnNITZTime(h, what, obj); // Send the last NITZ time if we have it if (mLastNITZTimeInfo != null) { mNITZTimeRegistrant .notifyRegistrant( new AsyncResult (null, mLastNITZTimeInfo, null)); mLastNITZTimeInfo = null; } } @Override public void getIccCardStatus(Message result) { //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_GET_SIM_STATUS, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void supplyIccPin(String pin, Message result) { supplyIccPinForApp(pin, null, result); } @Override public void supplyIccPinForApp(String pin, String aid, Message result) { //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_ENTER_SIM_PIN, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeInt(2); rr.mParcel.writeString(pin); rr.mParcel.writeString(aid); send(rr); } @Override public void supplyIccPuk(String puk, String newPin, Message result) { supplyIccPukForApp(puk, newPin, null, result); } @Override public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) { //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_ENTER_SIM_PUK, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeInt(3); rr.mParcel.writeString(puk); rr.mParcel.writeString(newPin); rr.mParcel.writeString(aid); send(rr); } @Override public void supplyIccPin2(String pin, Message result) { supplyIccPin2ForApp(pin, null, result); } @Override public void supplyIccPin2ForApp(String pin, String aid, Message result) { //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_ENTER_SIM_PIN2, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeInt(2); rr.mParcel.writeString(pin); rr.mParcel.writeString(aid); send(rr); } @Override public void supplyIccPuk2(String puk2, String newPin2, Message result) { supplyIccPuk2ForApp(puk2, newPin2, null, result); } @Override public void supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) { //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_ENTER_SIM_PUK2, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeInt(3); rr.mParcel.writeString(puk); rr.mParcel.writeString(newPin2); rr.mParcel.writeString(aid); send(rr); } @Override public void changeIccPin(String oldPin, String newPin, Message result) { changeIccPinForApp(oldPin, newPin, null, result); } @Override public void changeIccPinForApp(String oldPin, String newPin, String aid, Message result) { //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_CHANGE_SIM_PIN, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeInt(3); rr.mParcel.writeString(oldPin); rr.mParcel.writeString(newPin); rr.mParcel.writeString(aid); send(rr); } @Override public void changeIccPin2(String oldPin2, String newPin2, Message result) { changeIccPin2ForApp(oldPin2, newPin2, null, result); } @Override public void changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) { //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_CHANGE_SIM_PIN2, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeInt(3); rr.mParcel.writeString(oldPin2); rr.mParcel.writeString(newPin2); rr.mParcel.writeString(aid); send(rr); } @Override public void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeInt(3); rr.mParcel.writeString(facility); rr.mParcel.writeString(oldPwd); rr.mParcel.writeString(newPwd); send(rr); } @Override public void supplyNetworkDepersonalization(String netpin, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeInt(1); rr.mParcel.writeString(netpin); send(rr); } @Override public void getCurrentCalls (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override @Deprecated public void getPDPContextList(Message result) { getDataCallList(result); } @Override public void getDataCallList(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_CALL_LIST, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void dial (String address, int clirMode, Message result) { dial(address, clirMode, null, result); } @Override public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); rr.mParcel.writeString(address); rr.mParcel.writeInt(clirMode); 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 public void getIMSI(Message result) { getIMSIForApp(null, result); } @Override public void getIMSIForApp(String aid, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result); rr.mParcel.writeInt(1); rr.mParcel.writeString(aid); if (RILJ_LOGD) riljLog(rr.serialString() + "> getIMSI: " + requestToString(rr.mRequest) + " aid: " + aid); send(rr); } @Override public void getIMEI(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEI, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getIMEISV(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEISV, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void hangupConnection (int gsmIndex, Message result) { if (RILJ_LOGD) riljLog("hangupConnection: gsmIndex=" + gsmIndex); RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + gsmIndex); rr.mParcel.writeInt(1); rr.mParcel.writeInt(gsmIndex); send(rr); } @Override public void hangupWaitingOrBackground (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void hangupForegroundResumeBackground (Message result) { RILRequest rr = RILRequest.obtain( RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void switchWaitingOrHoldingAndActive (Message result) { RILRequest rr = RILRequest.obtain( RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void conference (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CONFERENCE, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void setPreferredVoicePrivacy(boolean enable, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, result); rr.mParcel.writeInt(1); rr.mParcel.writeInt(enable ? 1:0); send(rr); } @Override public void getPreferredVoicePrivacy(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, result); send(rr); } @Override public void separateConnection (int gsmIndex, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SEPARATE_CONNECTION, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + gsmIndex); rr.mParcel.writeInt(1); rr.mParcel.writeInt(gsmIndex); send(rr); } @Override public void acceptCall (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_ANSWER, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void rejectCall (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_UDUB, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void explicitCallTransfer (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getLastCallFailCause (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * @deprecated */ @Deprecated @Override public void getLastPdpFailCause (Message result) { getLastDataCallFailCause (result); } /** * The preferred new alternative to getLastPdpFailCause */ @Override public void getLastDataCallFailCause (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void setMute (boolean enableMute, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_MUTE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + enableMute); rr.mParcel.writeInt(1); rr.mParcel.writeInt(enableMute ? 1 : 0); send(rr); } @Override public void getMute (Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_MUTE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getSignalStrength (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getVoiceRegistrationState (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_REGISTRATION_STATE, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getDataRegistrationState (Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getOperator(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_OPERATOR, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void sendDtmf(char c, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DTMF, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeString(Character.toString(c)); send(rr); } @Override public void startDtmf(char c, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DTMF_START, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeString(Character.toString(c)); send(rr); } @Override public void stopDtmf(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DTMF_STOP, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void sendBurstDtmf(String dtmfString, int on, int off, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BURST_DTMF, result); rr.mParcel.writeInt(3); rr.mParcel.writeString(dtmfString); rr.mParcel.writeString(Integer.toString(on)); rr.mParcel.writeString(Integer.toString(off)); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " : " + dtmfString); send(rr); } @Override public void sendSMS (String smscPDU, String pdu, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result); rr.mParcel.writeInt(2); rr.mParcel.writeString(smscPDU); rr.mParcel.writeString(pdu); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void sendCdmaSms(byte[] pdu, Message result) { int address_nbr_of_digits; int subaddr_nbr_of_digits; int bearerDataLength; ByteArrayInputStream bais = new ByteArrayInputStream(pdu); DataInputStream dis = new DataInputStream(bais); RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SEND_SMS, result); try { rr.mParcel.writeInt(dis.readInt()); //teleServiceId rr.mParcel.writeByte((byte) dis.readInt()); //servicePresent rr.mParcel.writeInt(dis.readInt()); //serviceCategory rr.mParcel.writeInt(dis.read()); //address_digit_mode rr.mParcel.writeInt(dis.read()); //address_nbr_mode rr.mParcel.writeInt(dis.read()); //address_ton rr.mParcel.writeInt(dis.read()); //address_nbr_plan address_nbr_of_digits = (byte) dis.read(); rr.mParcel.writeByte((byte) address_nbr_of_digits); for(int i=0; i < address_nbr_of_digits; i++){ rr.mParcel.writeByte(dis.readByte()); // address_orig_bytes[i] } rr.mParcel.writeInt(dis.read()); //subaddressType rr.mParcel.writeByte((byte) dis.read()); //subaddr_odd subaddr_nbr_of_digits = (byte) dis.read(); rr.mParcel.writeByte((byte) subaddr_nbr_of_digits); for(int i=0; i < subaddr_nbr_of_digits; i++){ rr.mParcel.writeByte(dis.readByte()); //subaddr_orig_bytes[i] } bearerDataLength = dis.read(); rr.mParcel.writeInt(bearerDataLength); for(int i=0; i < bearerDataLength; i++){ rr.mParcel.writeByte(dis.readByte()); //bearerData[i] } }catch (IOException ex){ if (RILJ_LOGD) riljLog("sendSmsCdma: conversion from input stream to object failed: " + ex); } if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void deleteSmsOnSim(int index, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DELETE_SMS_ON_SIM, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(index); if (RILJ_LOGV) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + index); send(rr); } @Override public void deleteSmsOnRuim(int index, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(index); if (RILJ_LOGV) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + index); send(rr); } @Override public void writeSmsToSim(int status, String smsc, String pdu, Message response) { status = translateStatus(status); RILRequest rr = RILRequest.obtain(RIL_REQUEST_WRITE_SMS_TO_SIM, response); rr.mParcel.writeInt(status); rr.mParcel.writeString(pdu); rr.mParcel.writeString(smsc); if (RILJ_LOGV) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + status); send(rr); } @Override public void writeSmsToRuim(int status, String pdu, Message response) { status = translateStatus(status); RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, response); rr.mParcel.writeInt(status); rr.mParcel.writeString(pdu); if (RILJ_LOGV) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + status); send(rr); } /** * Translates EF_SMS status bits to a status value compatible with * SMS AT commands. See TS 27.005 3.1. */ private int translateStatus(int status) { switch(status & 0x7) { case SmsManager.STATUS_ON_ICC_READ: return 1; case SmsManager.STATUS_ON_ICC_UNREAD: return 0; case SmsManager.STATUS_ON_ICC_SENT: return 3; case SmsManager.STATUS_ON_ICC_UNSENT: return 2; } // Default to READ. return 1; } @Override public void setupDataCall(String radioTechnology, String profile, String apn, String user, String password, String authType, String protocol, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result); rr.mParcel.writeInt(7); rr.mParcel.writeString(radioTechnology); rr.mParcel.writeString(profile); rr.mParcel.writeString(apn); rr.mParcel.writeString(user); rr.mParcel.writeString(password); rr.mParcel.writeString(authType); rr.mParcel.writeString(protocol); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + radioTechnology + " " + profile + " " + apn + " " + user + " " + password + " " + authType + " " + protocol); send(rr); } @Override public void deactivateDataCall(int cid, int reason, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result); rr.mParcel.writeInt(2); rr.mParcel.writeString(Integer.toString(cid)); rr.mParcel.writeString(Integer.toString(reason)); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + cid + " " + reason); send(rr); } @Override public void setRadioPower(boolean on, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result); rr.mParcel.writeInt(1); rr.mParcel.writeInt(on ? 1 : 0); if (RILJ_LOGD) { riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + (on ? " on" : " off")); } send(rr); } @Override public void setSuppServiceNotifications(boolean enable, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result); rr.mParcel.writeInt(1); rr.mParcel.writeInt(enable ? 1 : 0); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result); rr.mParcel.writeInt(2); rr.mParcel.writeInt(success ? 1 : 0); rr.mParcel.writeInt(cause); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + success + " " + cause); send(rr); } @Override public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result); rr.mParcel.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass // cause code according to X.S004-550E rr.mParcel.writeInt(cause); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + success + " " + cause); send(rr); } @Override public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result); rr.mParcel.writeInt(2); rr.mParcel.writeString(success ? "1" : "0"); rr.mParcel.writeString(ackPdu); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + ' ' + success + " [" + ackPdu + ']'); send(rr); } @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, null, 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) { //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); } @Override public void getCLIR(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CLIR, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void setCLIR(int clirMode, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_CLIR, result); // count ints rr.mParcel.writeInt(1); rr.mParcel.writeInt(clirMode); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + clirMode); send(rr); } @Override public void queryCallWaiting(int serviceClass, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_WAITING, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(serviceClass); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + serviceClass); send(rr); } @Override public void setCallWaiting(boolean enable, int serviceClass, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_CALL_WAITING, response); rr.mParcel.writeInt(2); rr.mParcel.writeInt(enable ? 1 : 0); rr.mParcel.writeInt(serviceClass); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + enable + ", " + serviceClass); send(rr); } @Override public void setNetworkSelectionModeAutomatic(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void setNetworkSelectionModeManual(String operatorNumeric, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + operatorNumeric); rr.mParcel.writeString(operatorNumeric); send(rr); } @Override public void getNetworkSelectionMode(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getAvailableNetworks(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void setCallForward(int action, int cfReason, int serviceClass, String number, int timeSeconds, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_CALL_FORWARD, response); rr.mParcel.writeInt(action); rr.mParcel.writeInt(cfReason); rr.mParcel.writeInt(serviceClass); rr.mParcel.writeInt(PhoneNumberUtils.toaFromString(number)); rr.mParcel.writeString(number); rr.mParcel.writeInt (timeSeconds); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + action + " " + cfReason + " " + serviceClass + timeSeconds); send(rr); } @Override public void queryCallForwardStatus(int cfReason, int serviceClass, String number, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, response); rr.mParcel.writeInt(2); // 2 is for query action, not in used anyway rr.mParcel.writeInt(cfReason); rr.mParcel.writeInt(serviceClass); rr.mParcel.writeInt(PhoneNumberUtils.toaFromString(number)); rr.mParcel.writeString(number); rr.mParcel.writeInt (0); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + cfReason + " " + serviceClass); send(rr); } @Override public void queryCLIP(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_CLIP, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getBasebandVersion (Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_BASEBAND_VERSION, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void queryFacilityLock(String facility, String password, int serviceClass, Message response) { queryFacilityLockForApp(facility, password, serviceClass, null, response); } @Override public void queryFacilityLockForApp(String facility, String password, int serviceClass, String appId, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " [" + facility + " " + serviceClass + " " + appId + "]"); // count strings rr.mParcel.writeInt(4); rr.mParcel.writeString(facility); rr.mParcel.writeString(password); rr.mParcel.writeString(Integer.toString(serviceClass)); rr.mParcel.writeString(appId); send(rr); } @Override public void setFacilityLock (String facility, boolean lockState, String password, int serviceClass, Message response) { setFacilityLockForApp(facility, lockState, password, serviceClass, null, response); } @Override public void setFacilityLockForApp(String facility, boolean lockState, String password, int serviceClass, String appId, Message response) { String lockString; RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " [" + facility + " " + lockState + " " + serviceClass + " " + appId + "]"); // count strings rr.mParcel.writeInt(5); rr.mParcel.writeString(facility); lockString = (lockState)?"1":"0"; rr.mParcel.writeString(lockString); rr.mParcel.writeString(password); rr.mParcel.writeString(Integer.toString(serviceClass)); rr.mParcel.writeString(appId); send(rr); } @Override public void sendUSSD (String ussdString, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SEND_USSD, response); if (RILJ_LOGD) { String logUssdString = "*******"; if (RILJ_LOGV) logUssdString = ussdString; riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + logUssdString); } rr.mParcel.writeString(ussdString); send(rr); } // inherited javadoc suffices @Override public void cancelPendingUssd (Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CANCEL_USSD, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void resetRadio(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_RESET_RADIO, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void invokeOemRilRequestRaw(byte[] data, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_RAW, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + "[" + IccUtils.bytesToHexString(data) + "]"); rr.mParcel.writeByteArray(data); send(rr); } @Override public void invokeOemRilRequestStrings(String[] strings, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_STRINGS, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeStringArray(strings); send(rr); } /** * Assign a specified band for RF configuration. * * @param bandMode one of BM_*_BAND * @param response is callback message */ @Override public void setBandMode (int bandMode, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_BAND_MODE, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(bandMode); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + bandMode); send(rr); } /** * Query the list of band mode supported by RF. * * @param response is callback message * ((AsyncResult)response.obj).result is an int[] with every * element representing one avialable BM_*_BAND */ @Override public void queryAvailableBandMode (Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void sendTerminalResponse(String contents, Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeString(contents); send(rr); } /** * {@inheritDoc} */ @Override public void sendEnvelope(String contents, Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mParcel.writeString(contents); send(rr); } /** * {@inheritDoc} */ @Override public void sendEnvelopeWithStatus(String contents, Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + '[' + contents + ']'); rr.mParcel.writeString(contents); send(rr); } /** * {@inheritDoc} */ @Override public void handleCallSetupRequestFromSim( boolean accept, Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); int[] param = new int[1]; param[0] = accept ? 1 : 0; rr.mParcel.writeIntArray(param); send(rr); } /** * {@inheritDoc} */ @Override public void setCurrentPreferredNetworkType() { if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType: " + mSetPreferredNetworkType); setPreferredNetworkType(mSetPreferredNetworkType, null); } private int mSetPreferredNetworkType; /** * {@inheritDoc} */ @Override public void setPreferredNetworkType(int networkType , Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(networkType); mSetPreferredNetworkType = networkType; mPreferredNetworkType = networkType; if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " : " + networkType); send(rr); } /** * {@inheritDoc} */ @Override public void getPreferredNetworkType(Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void getNeighboringCids(Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void setLocationUpdates(boolean enable, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_LOCATION_UPDATES, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(enable ? 1 : 0); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + ": " + enable); send(rr); } /** * {@inheritDoc} */ @Override public void getSmscAddress(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SMSC_ADDRESS, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void setSmscAddress(String address, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_SMSC_ADDRESS, result); rr.mParcel.writeString(address); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " : " + address); send(rr); } /** * {@inheritDoc} */ @Override public void reportSmsMemoryStatus(boolean available, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result); rr.mParcel.writeInt(1); rr.mParcel.writeInt(available ? 1 : 0); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + ": " + available); send(rr); } /** * {@inheritDoc} */ @Override public void reportStkServiceIsRunning(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void getGsmBroadcastConfig(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, response); int numOfConfig = config.length; rr.mParcel.writeInt(numOfConfig); for(int i = 0; i < numOfConfig; i++) { rr.mParcel.writeInt(config[i].getFromServiceId()); rr.mParcel.writeInt(config[i].getToServiceId()); rr.mParcel.writeInt(config[i].getFromCodeScheme()); rr.mParcel.writeInt(config[i].getToCodeScheme()); rr.mParcel.writeInt(config[i].isSelected() ? 1 : 0); } if (RILJ_LOGD) { riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " with " + numOfConfig + " configs : "); for (int i = 0; i < numOfConfig; i++) { riljLog(config[i].toString()); } } send(rr); } /** * {@inheritDoc} */ @Override public void setGsmBroadcastActivation(boolean activate, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(activate ? 0 : 1); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } //***** Private Methods private void sendScreenState(boolean on) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SCREEN_STATE, null); rr.mParcel.writeInt(1); rr.mParcel.writeInt(on ? 1 : 0); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + ": " + on); send(rr); } @Override protected void onRadioAvailable() { // In case screen state was lost (due to process crash), // this ensures that the RIL knows the correct screen state. PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); sendScreenState(pm.isScreenOn()); } private RadioState getRadioStateFromInt(int stateInt) { RadioState state; /* RIL_RadioState ril.h */ switch(stateInt) { case 0: state = RadioState.RADIO_OFF; break; case 1: state = RadioState.RADIO_UNAVAILABLE; break; case 10: state = RadioState.RADIO_ON; break; default: throw new RuntimeException( "Unrecognized RIL_RadioState: " + stateInt); } return state; } private void switchToRadioState(RadioState newState) { setRadioState(newState); } /** * Holds a PARTIAL_WAKE_LOCK whenever * a) There is outstanding RIL request sent to RIL deamon and no replied * b) There is a request pending to be sent out. * * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't * happen often. */ private void acquireWakeLock() { synchronized (mWakeLock) { mWakeLock.acquire(); mRequestMessagesPending++; mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); Message msg = mSender.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT); mSender.sendMessageDelayed(msg, mWakeLockTimeout); } } private void releaseWakeLockIfDone() { synchronized (mWakeLock) { if (mWakeLock.isHeld() && (mRequestMessagesPending == 0) && (mRequestMessagesWaiting == 0)) { mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); mWakeLock.release(); } } } private void send(RILRequest rr) { Message msg; if (mSocket == null) { rr.onError(RADIO_NOT_AVAILABLE, null); rr.release(); return; } msg = mSender.obtainMessage(EVENT_SEND, rr); acquireWakeLock(); msg.sendToTarget(); } private void processResponse (Parcel p) { int type; type = p.readInt(); if (type == RESPONSE_UNSOLICITED) { processUnsolicited (p); } else if (type == RESPONSE_SOLICITED) { processSolicited (p); } releaseWakeLockIfDone(); } /** * Release each request in mRequestList then clear the list * @param error is the RIL_Errno sent back * @param loggable true means to print all requests in mRequestList */ private void clearRequestList(int error, boolean loggable) { RILRequest rr; synchronized (mRequestList) { int count = mRequestList.size(); if (RILJ_LOGD && loggable) { Rlog.d(RILJ_LOG_TAG, "WAKE_LOCK_TIMEOUT " + " mReqPending=" + mRequestMessagesPending + " mRequestList=" + count); } for (int i = 0; i < count ; i++) { rr = mRequestList.get(i); if (RILJ_LOGD && loggable) { Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] " + requestToString(rr.mRequest)); } rr.onError(error, null); rr.release(); } mRequestList.clear(); mRequestMessagesWaiting = 0; } } private RILRequest findAndRemoveRequestFromList(int serial) { synchronized (mRequestList) { for (int i = 0, s = mRequestList.size() ; i < s ; i++) { RILRequest rr = mRequestList.get(i); if (rr.mSerial == serial) { mRequestList.remove(i); if (mRequestMessagesWaiting > 0) mRequestMessagesWaiting--; return rr; } } } return null; } private void 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; } 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: { 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_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; 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(); } rr.release(); return; } } // 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); 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(); } private String retToString(int req, Object ret) { if (ret == null) return ""; switch (req) { // Don't log these return values, for privacy's sake. case RIL_REQUEST_GET_IMSI: case RIL_REQUEST_GET_IMEI: case RIL_REQUEST_GET_IMEISV: if (!RILJ_LOGV) { // If not versbose logging just return and don't display IMSI and IMEI, IMEISV return ""; } } StringBuilder sb; String s; int length; if (ret instanceof int[]){ int[] intArray = (int[]) ret; length = intArray.length; sb = new StringBuilder("{"); if (length > 0) { int i = 0; sb.append(intArray[i++]); while ( i < length) { sb.append(", ").append(intArray[i++]); } } sb.append("}"); s = sb.toString(); } else if (ret instanceof String[]) { String[] strings = (String[]) ret; length = strings.length; sb = new StringBuilder("{"); if (length > 0) { int i = 0; sb.append(strings[i++]); while ( i < length) { sb.append(", ").append(strings[i++]); } } sb.append("}"); s = sb.toString(); }else if (req == RIL_REQUEST_GET_CURRENT_CALLS) { ArrayList calls = (ArrayList) ret; sb = new StringBuilder(" "); for (DriverCall dc : calls) { sb.append("[").append(dc).append("] "); } s = sb.toString(); } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) { ArrayList cells; cells = (ArrayList) ret; sb = new StringBuilder(" "); for (NeighboringCellInfo cell : cells) { sb.append(cell).append(" "); } s = sb.toString(); } else { s = ret.toString(); } return s; } private 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_VOICE_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 = responseSimRefresh(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 RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break; case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break; case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break; case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret = responseInts(p); break; case RIL_UNSOL_CELL_INFO_LIST: ret = responseCellInfoList(p); break; default: throw new RuntimeException("Unrecognized unsol response: " + response); //break; (implied) }} catch (Throwable tr) { Rlog.e(RILJ_LOG_TAG, "Exception processing unsol response: " + response + "Exception:" + tr.toString()); return; } switch(response) { case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: /* has bonus radio state int */ RadioState newState = getRadioStateFromInt(p.readInt()); if (RILJ_LOGD) unsljLogMore(response, newState.toString()); switchToRadioState(newState); 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_VOICE_NETWORK_STATE_CHANGED: if (RILJ_LOGD) unsljLog(response); mVoiceNetworkStateRegistrants .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 (mGsmSmsRegistrant != null) { mGsmSmsRegistrant .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); boolean ignoreNitz = SystemProperties.getBoolean( TelephonyProperties.PROPERTY_IGNORE_NITZ, false); if (ignoreNitz) { if (RILJ_LOGD) riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED"); } else { 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); mDataNetworkStateRegistrants.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 (mCatSessionEndRegistrant != null) { mCatSessionEndRegistrant.notifyRegistrant( new AsyncResult (null, ret, null)); } break; case RIL_UNSOL_STK_PROACTIVE_COMMAND: if (RILJ_LOGD) unsljLogRet(response, ret); if (mCatProCmdRegistrant != null) { mCatProCmdRegistrant.notifyRegistrant( new AsyncResult (null, ret, null)); } break; case RIL_UNSOL_STK_EVENT_NOTIFY: if (RILJ_LOGD) unsljLogRet(response, ret); if (mCatEventRegistrant != null) { mCatEventRegistrant.notifyRegistrant( new AsyncResult (null, ret, null)); } break; case RIL_UNSOL_STK_CALL_SETUP: if (RILJ_LOGD) unsljLogRet(response, ret); if (mCatCallSetUpRegistrant != null) { mCatCallSetUpRegistrant.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 (mIccRefreshRegistrants != null) { mIccRefreshRegistrants.notifyRegistrants( 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 (mCdmaSmsRegistrant != null) { mCdmaSmsRegistrant .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 listInfoRecs; try { listInfoRecs = (ArrayList)ret; } catch (ClassCastException e) { Rlog.e(RILJ_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 RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: if (RILJ_LOGD) unsljLogRet(response, ret); if (mVoiceRadioTechChangedRegistrants != null) { mVoiceRadioTechChangedRegistrants.notifyRegistrants( new AsyncResult(null, ret, null)); } break; case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: if (RILJ_LOGD) unsljLogRet(response, ret); if (mCdmaSubscriptionChangedRegistrants != null) { mCdmaSubscriptionChangedRegistrants.notifyRegistrants( new AsyncResult (null, ret, null)); } break; case RIL_UNSOl_CDMA_PRL_CHANGED: if (RILJ_LOGD) unsljLogRet(response, ret); if (mCdmaPrlChangedRegistrants != null) { mCdmaPrlChangedRegistrants.notifyRegistrants( new AsyncResult (null, ret, null)); } break; case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: if (RILJ_LOGD) unsljLogRet(response, ret); if (mExitEmergencyCallbackModeRegistrants != null) { mExitEmergencyCallbackModeRegistrants.notifyRegistrants( new AsyncResult (null, null, null)); } break; case RIL_UNSOL_RIL_CONNECTED: { if (RILJ_LOGD) unsljLogRet(response, ret); // Initial conditions setRadioPower(false, null); setPreferredNetworkType(mPreferredNetworkType, null); setCdmaSubscriptionSource(mCdmaSubscription, null); setCellInfoListRate(Integer.MAX_VALUE, null); notifyRegistrantsRilConnectionChanged(((int[])ret)[0]); break; } case RIL_UNSOL_CELL_INFO_LIST: { if (RILJ_LOGD) unsljLogRet(response, ret); if (mRilCellInfoListRegistrants != null) { mRilCellInfoListRegistrants.notifyRegistrants( new AsyncResult (null, ret, null)); } break; } } } /** * Notifiy all registrants that the ril has connected or disconnected. * * @param rilVer is the version of the ril or -1 if disconnected. */ private void notifyRegistrantsRilConnectionChanged(int rilVer) { mRilVersion = rilVer; if (mRilConnectedRegistrants != null) { mRilConnectedRegistrants.notifyRegistrants( new AsyncResult (null, new Integer(rilVer), null)); } } private Object responseInts(Parcel p) { int numInts; int response[]; numInts = p.readInt(); response = new int[numInts]; for (int i = 0 ; i < numInts ; i++) { response[i] = p.readInt(); } return response; } private Object responseVoid(Parcel p) { return null; } private Object responseCallForward(Parcel p) { int numInfos; CallForwardInfo infos[]; numInfos = p.readInt(); infos = new CallForwardInfo[numInfos]; for (int i = 0 ; i < numInfos ; i++) { infos[i] = new CallForwardInfo(); infos[i].status = p.readInt(); infos[i].reason = p.readInt(); infos[i].serviceClass = p.readInt(); infos[i].toa = p.readInt(); infos[i].number = p.readString(); infos[i].timeSeconds = p.readInt(); } return infos; } private Object responseSuppServiceNotification(Parcel p) { SuppServiceNotification notification = new SuppServiceNotification(); notification.notificationType = p.readInt(); notification.code = p.readInt(); notification.index = p.readInt(); notification.type = p.readInt(); notification.number = p.readString(); return notification; } private Object responseCdmaSms(Parcel p) { SmsMessage sms; sms = SmsMessage.newFromParcel(p); return sms; } private Object responseString(Parcel p) { String response; response = p.readString(); return response; } private Object responseStrings(Parcel p) { int num; String response[]; response = p.readStringArray(); return response; } private Object responseRaw(Parcel p) { int num; byte response[]; response = p.createByteArray(); return response; } private Object responseSMS(Parcel p) { int messageRef, errorCode; String ackPDU; messageRef = p.readInt(); ackPDU = p.readString(); errorCode = p.readInt(); SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode); return response; } private Object responseICC_IO(Parcel p) { int sw1, sw2; byte data[] = null; Message ret; sw1 = p.readInt(); sw2 = p.readInt(); String s = p.readString(); if (RILJ_LOGV) riljLog("< iccIO: " + " 0x" + Integer.toHexString(sw1) + " 0x" + Integer.toHexString(sw2) + " " + s); return new IccIoResult(sw1, sw2, s); } private 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()); cardStatus.mApplications[i] = appStatus; } return cardStatus; } private Object responseSimRefresh(Parcel p) { IccRefreshResponse response = new IccRefreshResponse(); response.refreshResult = p.readInt(); response.efId = p.readInt(); response.aid = p.readString(); return response; } private Object responseCallList(Parcel p) { int num; int voiceSettings; ArrayList response; DriverCall dc; num = p.readInt(); response = new ArrayList(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(); 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()); 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); if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) { if (mEmergencyCallbackModeRegistrant != null) { riljLog("responseCallList: call ended, testing emergency call," + " notify ECM Registrants"); mEmergencyCallbackModeRegistrant.notifyRegistrant(); } } return response; } private DataCallResponse getDataCallResponse(Parcel p, int version) { DataCallResponse dataCall = new DataCallResponse(); 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(" "); } } 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 == DcFailCause.NONE.getErrorCode()) && TextUtils.isEmpty(dataCall.ifname)) { throw new RuntimeException("getDataCallResponse, 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; } private Object responseDataCallList(Parcel p) { ArrayList response; int ver = p.readInt(); int num = p.readInt(); riljLog("responseDataCallList ver=" + ver + " num=" + num); response = new ArrayList(num); for (int i = 0; i < num; i++) { response.add(getDataCallResponse(p, ver)); } return response; } private Object responseSetupDataCall(Parcel p) { int ver = p.readInt(); int num = p.readInt(); if (RILJ_LOGV) riljLog("responseSetupDataCall ver=" + ver + " num=" + num); DataCallResponse dataCall; if (ver < 5) { dataCall = new DataCallResponse(); dataCall.version = ver; dataCall.cid = Integer.parseInt(p.readString()); dataCall.ifname = p.readString(); if (TextUtils.isEmpty(dataCall.ifname)) { throw new RuntimeException( "RIL_REQUEST_SETUP_DATA_CALL response, no ifname"); } String addresses = p.readString(); if (!TextUtils.isEmpty(addresses)) { dataCall.addresses = addresses.split(" "); } if (num >= 4) { String dnses = p.readString(); if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses); if (!TextUtils.isEmpty(dnses)) { dataCall.dnses = dnses.split(" "); } } if (num >= 5) { String gateways = p.readString(); if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways); if (!TextUtils.isEmpty(gateways)) { dataCall.gateways = gateways.split(" "); } } } else { if (num != 1) { throw new RuntimeException( "RIL_REQUEST_SETUP_DATA_CALL response expecting 1 RIL_Data_Call_response_v5" + " got " + num); } dataCall = getDataCallResponse(p, ver); } return dataCall; } private Object responseOperatorInfos(Parcel p) { String strings[] = (String [])responseStrings(p); ArrayList ret; if (strings.length % 4 != 0) { throw new RuntimeException( "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got " + strings.length + " strings, expected multible of 4"); } ret = new ArrayList(strings.length / 4); for (int i = 0 ; i < strings.length ; i += 4) { ret.add ( new OperatorInfo( strings[i+0], strings[i+1], strings[i+2], strings[i+3])); } return ret; } private Object responseCellList(Parcel p) { int num, rssi; String location; ArrayList response; NeighboringCellInfo cell; num = p.readInt(); response = new ArrayList(); // Determine the radio access type String radioString = SystemProperties.get( TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, "unknown"); int radioType; if (radioString.equals("GPRS")) { radioType = NETWORK_TYPE_GPRS; } else if (radioString.equals("EDGE")) { radioType = NETWORK_TYPE_EDGE; } else if (radioString.equals("UMTS")) { radioType = NETWORK_TYPE_UMTS; } else if (radioString.equals("HSDPA")) { radioType = NETWORK_TYPE_HSDPA; } else if (radioString.equals("HSUPA")) { radioType = NETWORK_TYPE_HSUPA; } else if (radioString.equals("HSPA")) { radioType = NETWORK_TYPE_HSPA; } else { radioType = NETWORK_TYPE_UNKNOWN; } // Interpret the location based on radio access type if (radioType != NETWORK_TYPE_UNKNOWN) { for (int i = 0 ; i < num ; i++) { rssi = p.readInt(); location = p.readString(); cell = new NeighboringCellInfo(rssi, location, radioType); response.add(cell); } } return response; } private Object responseGetPreferredNetworkType(Parcel p) { int [] response = (int[]) responseInts(p); if (response.length >= 1) { // Since this is the response for getPreferredNetworkType // we'll assume that it should be the value we want the // vendor ril to take if we reestablish a connection to it. mPreferredNetworkType = response[0]; } return response; } private Object responseGmsBroadcastConfig(Parcel p) { int num; ArrayList response; SmsBroadcastConfigInfo info; num = p.readInt(); response = new ArrayList(num); for (int i = 0; i < num; i++) { int fromId = p.readInt(); int toId = p.readInt(); int fromScheme = p.readInt(); int toScheme = p.readInt(); boolean selected = (p.readInt() == 1); info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme, toScheme, selected); response.add(info); } return response; } private Object responseCdmaBroadcastConfig(Parcel p) { int numServiceCategories; int response[]; numServiceCategories = p.readInt(); if (numServiceCategories == 0) { // TODO: The logic of providing default values should // not be done by this transport layer. And needs to // be done by the vendor ril or application logic. int numInts; numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1; response = new int[numInts]; // Faking a default record for all possible records. response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES; // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as // default language and selection status to false for all. for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) { response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT; response[i + 1] = 1; response[i + 2] = 0; } } else { int numInts; numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1; response = new int[numInts]; response[0] = numServiceCategories; for (int i = 1 ; i < numInts; i++) { response[i] = p.readInt(); } } return response; } private Object responseSignalStrength(Parcel p) { // Assume this is gsm, but doesn't matter as ServiceStateTracker // sets the proper value. SignalStrength signalStrength = SignalStrength.makeSignalStrengthFromRilParcel(p); return signalStrength; } private ArrayList responseCdmaInformationRecord(Parcel p) { int numberOfInfoRecs; ArrayList response; /** * Loop through all of the information records unmarshalling them * and converting them to Java Objects. */ numberOfInfoRecs = p.readInt(); response = new ArrayList(numberOfInfoRecs); for (int i = 0; i < numberOfInfoRecs; i++) { CdmaInformationRecords InfoRec = new CdmaInformationRecords(p); response.add(InfoRec); } return response; } private Object responseCdmaCallWaiting(Parcel p) { CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification(); notification.number = p.readString(); notification.numberPresentation = CdmaCallWaitingNotification.presentationFromCLIP(p.readInt()); notification.name = p.readString(); notification.namePresentation = notification.numberPresentation; notification.isPresent = p.readInt(); notification.signalType = p.readInt(); notification.alertPitch = p.readInt(); notification.signal = p.readInt(); notification.numberType = p.readInt(); notification.numberPlan = p.readInt(); return notification; } private Object responseCallRing(Parcel p){ char response[] = new char[4]; response[0] = (char) p.readInt(); // isPresent response[1] = (char) p.readInt(); // signalType response[2] = (char) p.readInt(); // alertPitch response[3] = (char) p.readInt(); // signal return response; } private void notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) { int response = RIL_UNSOL_CDMA_INFO_REC; if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) { if (mDisplayInfoRegistrants != null) { if (RILJ_LOGD) unsljLogRet(response, infoRec.record); mDisplayInfoRegistrants.notifyRegistrants( new AsyncResult (null, infoRec.record, null)); } } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) { if (mSignalInfoRegistrants != null) { if (RILJ_LOGD) unsljLogRet(response, infoRec.record); mSignalInfoRegistrants.notifyRegistrants( new AsyncResult (null, infoRec.record, null)); } } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) { if (mNumberInfoRegistrants != null) { if (RILJ_LOGD) unsljLogRet(response, infoRec.record); mNumberInfoRegistrants.notifyRegistrants( new AsyncResult (null, infoRec.record, null)); } } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) { if (mRedirNumInfoRegistrants != null) { if (RILJ_LOGD) unsljLogRet(response, infoRec.record); mRedirNumInfoRegistrants.notifyRegistrants( new AsyncResult (null, infoRec.record, null)); } } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) { if (mLineControlInfoRegistrants != null) { if (RILJ_LOGD) unsljLogRet(response, infoRec.record); mLineControlInfoRegistrants.notifyRegistrants( new AsyncResult (null, infoRec.record, null)); } } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) { if (mT53ClirInfoRegistrants != null) { if (RILJ_LOGD) unsljLogRet(response, infoRec.record); mT53ClirInfoRegistrants.notifyRegistrants( new AsyncResult (null, infoRec.record, null)); } } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) { if (mT53AudCntrlInfoRegistrants != null) { if (RILJ_LOGD) unsljLogRet(response, infoRec.record); mT53AudCntrlInfoRegistrants.notifyRegistrants( new AsyncResult (null, infoRec.record, null)); } } } private ArrayList responseCellInfoList(Parcel p) { int numberOfInfoRecs; ArrayList response; /** * Loop through all of the information records unmarshalling them * and converting them to Java Objects. */ numberOfInfoRecs = p.readInt(); response = new ArrayList(numberOfInfoRecs); for (int i = 0; i < numberOfInfoRecs; i++) { CellInfo InfoRec = CellInfo.CREATOR.createFromParcel(p); response.add(InfoRec); } return response; } 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_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION"; 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_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"; default: return ""; } } static String responseToString(int request) { /* cat libs/telephony/ril_unsol_commands.h \ | egrep "^ *{RIL_" \ | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/' */ switch(request) { case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS"; case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT"; case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM"; case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD"; case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST"; case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED"; case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH"; case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED"; case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION"; case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END"; case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND"; case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY"; case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP"; case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL"; case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH"; case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING"; case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED"; case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS"; case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS"; case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL"; case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED"; case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE"; case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING"; case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS"; case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC"; case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW"; case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE"; case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE"; case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "CDMA_SUBSCRIPTION_SOURCE_CHANGED"; case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED"; case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE"; case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED"; case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED"; case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST"; default: return ""; } } private void riljLog(String msg) { Rlog.d(RILJ_LOG_TAG, msg); } private void riljLogv(String msg) { Rlog.v(RILJ_LOG_TAG, msg); } private void unsljLog(int response) { riljLog("[UNSL]< " + responseToString(response)); } private void unsljLogMore(int response, String more) { riljLog("[UNSL]< " + responseToString(response) + " " + more); } private void unsljLogRet(int response, Object ret) { riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret)); } private void unsljLogvRet(int response, Object ret) { riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret)); } // ***** Methods for CDMA support @Override public void getDeviceIdentity(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DEVICE_IDENTITY, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void getCDMASubscription(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SUBSCRIPTION, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructor if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType); mPhoneType = phoneType; } /** * {@inheritDoc} */ @Override public void queryCdmaRoamingPreference(Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(cdmaRoamingType); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " : " + cdmaRoamingType); send(rr); } /** * {@inheritDoc} */ @Override public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(cdmaSubscription); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " : " + cdmaSubscription); send(rr); } /** * {@inheritDoc} */ @Override public void getCdmaSubscriptionSource(Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void queryTTYMode(Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void setTTYMode(int ttyMode, Message response) { RILRequest rr = RILRequest.obtain( RILConstants.RIL_REQUEST_SET_TTY_MODE, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(ttyMode); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " : " + ttyMode); send(rr); } /** * {@inheritDoc} */ @Override public void sendCDMAFeatureCode(String FeatureCode, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response); rr.mParcel.writeString(FeatureCode); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " : " + FeatureCode); send(rr); } @Override public void getCdmaBroadcastConfig(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, response); send(rr); } @Override public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response); // Convert to 1 service category per config (the way RIL takes is) ArrayList processedConfigs = new ArrayList(); for (CdmaSmsBroadcastConfigInfo config : configs) { for (int i = config.getFromServiceCategory(); i <= config.getToServiceCategory(); i++) { processedConfigs.add(new CdmaSmsBroadcastConfigInfo(i, i, config.getLanguage(), config.isSelected())); } } CdmaSmsBroadcastConfigInfo[] rilConfigs = processedConfigs.toArray(configs); rr.mParcel.writeInt(rilConfigs.length); for(int i = 0; i < rilConfigs.length; i++) { rr.mParcel.writeInt(rilConfigs[i].getFromServiceCategory()); rr.mParcel.writeInt(rilConfigs[i].getLanguage()); rr.mParcel.writeInt(rilConfigs[i].isSelected() ? 1 : 0); } if (RILJ_LOGD) { riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " with " + rilConfigs.length + " configs : "); for (int i = 0; i < rilConfigs.length; i++) { riljLog(rilConfigs[i].toString()); } } send(rr); } @Override public void setCdmaBroadcastActivation(boolean activate, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(activate ? 0 :1); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void exitEmergencyCallbackMode(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } @Override public void requestIsimAuthentication(String nonce, Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_ISIM_AUTHENTICATION, response); rr.mParcel.writeString(nonce); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void getCellInfoList(Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CELL_INFO_LIST, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /** * {@inheritDoc} */ @Override public void setCellInfoListRate(int rateInMillis, Message response) { if (RILJ_LOGD) riljLog("setCellInfoListRate: " + rateInMillis); RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, response); rr.mParcel.writeInt(1); rr.mParcel.writeInt(rateInMillis); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); } /* (non-Javadoc) * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall() */ @Override public void testingEmergencyCall() { if (RILJ_LOGD) riljLog("testingEmergencyCall"); mTestingEmergencyCall.set(true); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("RIL: " + this); pw.println(" mSocket=" + mSocket); pw.println(" mSenderThread=" + mSenderThread); pw.println(" mSender=" + mSender); pw.println(" mReceiverThread=" + mReceiverThread); pw.println(" mReceiver=" + mReceiver); pw.println(" mWakeLock=" + mWakeLock); pw.println(" mWakeLockTimeout=" + mWakeLockTimeout); synchronized (mRequestList) { pw.println(" mRequestMessagesPending=" + mRequestMessagesPending); pw.println(" mRequestMessagesWaiting=" + mRequestMessagesWaiting); int count = mRequestList.size(); pw.println(" mRequestList count=" + count); for (int i = 0; i < count; i++) { RILRequest rr = mRequestList.get(i); pw.println(" [" + rr.mSerial + "] " + requestToString(rr.mRequest)); } } pw.println(" mLastNITZTimeInfo=" + mLastNITZTimeInfo); pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get()); } }