Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6e52061 authored by Danny Baumann's avatar Danny Baumann
Browse files

Work around some failures in Wrigley 3G RIL.

- The RIL sometimes forgets data connections that became inactive,
  making it return an empty list in the DATA_CALL_LIST RIL call
  instead of just marking those connections inactive. When framework
  then nevertheless tries to teardown those connections, the RIL chokes.
  Fix that by suppressing the DEACTIVATE_DATA_CALL call in those cases.

- Sometimes the RIL doesn't respond to SETUP_DATA_CALL requests. Catch
  that condition and convert it into an error so that frameworks retries
  the connection.
parent 94cd3e4c
Loading
Loading
Loading
Loading
+103 −7
Original line number Diff line number Diff line
@@ -17,9 +17,14 @@
package com.android.internal.telephony;

import android.content.Context;
import android.os.AsyncResult;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.util.Log;

import com.android.internal.telephony.DataCallState;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SETUP_DATA_CALL;
import com.android.internal.telephony.gsm.NetworkInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;

@@ -32,24 +37,40 @@ import java.util.ArrayList;
 * {@hide}
 */
public class MotoWrigley3GRIL extends RIL {
    private static final String TAG = "MotoWrigley3GRIL";

    private int mDataConnectionCount = -1;
    private RILRequest mSetupDataCallRequest;

    public MotoWrigley3GRIL(Context context) {
        super(context);
    }

    public MotoWrigley3GRIL(Context context, int networkMode, int cdmaSubscription) {
        super(context, networkMode, cdmaSubscription);
        mSender = new RILSender(mSenderThread.getLooper());
    }

    @Override
    protected RILRequest
    findAndRemoveRequestFromList(int serial) {
        RILRequest rr = super.findAndRemoveRequestFromList(serial);
        if (rr == mSetupDataCallRequest) {
            /*
             * either response arrived, or there was an error that was already handled -
             * either way, the upper layers were notified already
             */
            Log.d(TAG, "Got SETUP_DATA_CALL response");
            mSetupDataCallRequest = null;
        }
        return rr;
    }

    @Override
    protected 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();
        SuppServiceNotification notification =
                (SuppServiceNotification) super.responseSuppServiceNotification(p);

        /**
         * Moto's RIL seems to confuse code2 0 ('forwarded call') and
@@ -66,4 +87,79 @@ public class MotoWrigley3GRIL extends RIL {

        return notification;
    }

    @Override
    protected Object
    responseDataCallList(Parcel p) {
        ArrayList<DataCallState> response =
                (ArrayList<DataCallState>) super.responseDataCallList(p);
        mDataConnectionCount = response.size();
        Log.d(TAG, "Got data call list message, now has " + mDataConnectionCount + " connections");

        return response;
    }

    @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.mp.writeInt(7);

        rr.mp.writeString(radioTechnology);
        rr.mp.writeString(profile);
        rr.mp.writeString(apn);
        rr.mp.writeString(user);
        rr.mp.writeString(password);
        rr.mp.writeString(authType);
        rr.mp.writeString(protocol);

        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
                + requestToString(rr.mRequest) + " " + radioTechnology + " "
                + profile + " " + apn + " " + user + " "
                + password + " " + authType + " " + protocol);

        mSetupDataCallRequest = rr;

        send(rr);
    }

    @Override
    public void
    deactivateDataCall(int cid, Message result) {
        if (mDataConnectionCount == 0) {
            Log.w(TAG, "Received deactivateDataCall RIL call without an active data call, dropping");
            AsyncResult.forMessage(result, null, null);
            result.sendToTarget();
        } else {
            super.deactivateDataCall(cid, result);
        }
    }

    class RILSender extends RIL.RILSender {
        public RILSender(Looper looper) {
            super(looper);
        }

        @Override
        public void
        handleMessage(Message msg) {
            super.handleMessage(msg);

            if (msg.what == EVENT_WAKE_LOCK_TIMEOUT && mSetupDataCallRequest != null) {
                MotoWrigley3GRIL.super.findAndRemoveRequestFromList(mSetupDataCallRequest.mSerial);
                if (mSetupDataCallRequest.mResult != null) {
                    Log.e(TAG, "Got stale SETUP_DATA_CALL request, pretending radio not available");
                    CommandException ex = new CommandException(CommandException.Error.RADIO_NOT_AVAILABLE);
                    AsyncResult.forMessage(mSetupDataCallRequest.mResult, null, ex);
                    mSetupDataCallRequest.mResult.sendToTarget();
                }
                mSetupDataCallRequest.release();
                mSetupDataCallRequest = null;
            }
        }
    }
}