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

Commit 8a9f3161 authored by Mike Kasick's avatar Mike Kasick
Browse files

Fix support for CDMA devices in SamsungRIL.

These fixes are ported from jt1134's fascinatemtd patches and CM7.  For
CM9, the fixes are applied to SamsungRIL directly instead of elsewhere in
the telephony framework.  They include:

- Signal strength reporting: pass raw integer values.
- Voice registration: convert base station values from hex to dec.
- Data call setup/deactivate: start/stop pppd_cdma service and pull network
  parameters from pppd ip-up script.
- CDMA subscription: add missing PRL version from system properties.

Changes from CM7:

Note use of "ril.cdma.data_state" property instead of
"ril.cdma.data_ready".  This property has three states:

- Disconnect(ed): ril.cdma.data_state=0: stop pppd_cdma service.
- Connecting:     ril.cdma.data_state=1: (re)start pppd_cdma.
- Connected:      ril.cdma.data_state=2: pppd_cdma has responded.

The disconnect (0) and connecting (1) states are set by SamsungRIL on the
deactivation and setup, respectively, of a data call.  Prior to setting the
connecting (1) state, SamsungRIL sets the "net.cdma.datalinkinterface" for
pppd_runner's use.

After setting to the connecting (1) state, SamsungRIL waits for pppd_cdma
to respond by (itself) setting the connected (2) state.  This should be
done at the end of a /system/etc/ppp/ip-up script, after that script sets
the following interface values, which SamsungRIL uses to complete the data
call state:

- net.cdma.ppp.interface: $IFNAME (typically "ppp0")
- net.$IFNAME.local-ip:   pppd's local IPv4 address
- net.$IFNAME.remote-ip:  pppd's remote IPv4 address
- net.$IFNAME.dns1:       pppd's primary DNS address
- net.$IFNAME.dns2:       pppd's secondary DNS address
parent 57dd8c88
Loading
Loading
Loading
Loading
+103 −6
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public class SamsungRIL extends RIL implements CommandsInterface {
            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_VOICE_REGISTRATION_STATE: ret =  responseVoiceRegistrationState(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;
@@ -144,7 +144,7 @@ public class SamsungRIL extends RIL implements CommandsInterface {
            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_DEACTIVATE_DATA_CALL: ret =  responseDeactivateDataCall(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;
@@ -198,7 +198,7 @@ public class SamsungRIL extends RIL implements CommandsInterface {
            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_SUBSCRIPTION: ret =  responseCdmaSubscription(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;
@@ -792,6 +792,10 @@ public class SamsungRIL extends RIL implements CommandsInterface {
            response[i] = -1;
        }

        if (mIsSamsungCdma)
            // Framework takes care of the rest for us.
            return response;

        /* Matching Samsung signal strength to asu.
		   Method taken from Samsungs cdma/gsmSignalStateTracker */
        if(mSignalbarCount)
@@ -813,6 +817,20 @@ public class SamsungRIL extends RIL implements CommandsInterface {
        return response;
    }

    protected Object
    responseVoiceRegistrationState(Parcel p) {
        String response[] = (String[])responseStrings(p);

        if (mIsSamsungCdma && response.length > 6) {
            // These values are provided in hex, convert to dec.
            response[4] = Integer.toString(Integer.parseInt(response[4], 16)); // baseStationId
            response[5] = Integer.toString(Integer.parseInt(response[5], 16)); // baseStationLatitude
            response[6] = Integer.toString(Integer.parseInt(response[6], 16)); // baseStationLongitude
        }

        return response;
    }

    protected Object
    responseNetworkType(Parcel p) {
        int response[] = (int[]) responseInts(p);
@@ -834,11 +852,30 @@ public class SamsungRIL extends RIL implements CommandsInterface {

        if (strings.length >= 2) {
            dataCall.cid = Integer.parseInt(strings[0]);

            if (mIsSamsungCdma) {
                // We're responsible for starting/stopping the pppd_cdma service.
                if (!startPppdCdmaService(strings[1])) {
                    // pppd_cdma service didn't respond timely.
                    dataCall.status = FailCause.ERROR_UNSPECIFIED.getErrorCode();
                    return dataCall;
                }

                // pppd_cdma service responded, pull network parameters set by ip-up script.
                dataCall.ifname = SystemProperties.get("net.cdma.ppp.interface");
                String   ifprop = "net." + dataCall.ifname;

                dataCall.addresses = new String[] {SystemProperties.get(ifprop + ".local-ip")};
                dataCall.gateways  = new String[] {SystemProperties.get(ifprop + ".remote-ip")};
                dataCall.dnses     = new String[] {SystemProperties.get(ifprop + ".dns1"),
                                                   SystemProperties.get(ifprop + ".dns2")};
            } else {
                dataCall.ifname = strings[1];

                if (strings.length >= 3) {
                    dataCall.addresses = strings[2].split(" ");
                }
            }
        } else {
            dataCall.status = FailCause.ERROR_UNSPECIFIED.getErrorCode(); // Who knows?
        }
@@ -846,6 +883,66 @@ public class SamsungRIL extends RIL implements CommandsInterface {
        return dataCall;
    }

    private boolean startPppdCdmaService(String ttyname) {
        SystemProperties.set("net.cdma.datalinkinterface", ttyname);

        // Connecting: Set ril.cdma.data_state=1 to (re)start pppd_cdma service,
        // which responds by setting ril.cdma.data_state=2 once connection is up.
        SystemProperties.set("ril.cdma.data_state", "1");
        Log.d(LOG_TAG, "Set ril.cdma.data_state=1, waiting for ril.cdma.data_state=2.");

        // Typically takes < 200 ms on my Epic, so sleep in 100 ms intervals.
        for (int i = 0; i < 10; i++) {
            try {Thread.sleep(100);} catch (InterruptedException e) {}

            if (SystemProperties.getInt("ril.cdma.data_state", 1) == 2) {
                Log.d(LOG_TAG, "Got ril.cdma.data_state=2, connected.");
                return true;
            }
        }

        // Taking > 1 s here, try up to 10 s, which is hopefully long enough.
        for (int i = 1; i < 10; i++) {
            try {Thread.sleep(1000);} catch (InterruptedException e) {}

            if (SystemProperties.getInt("ril.cdma.data_state", 1) == 2) {
                Log.d(LOG_TAG, "Got ril.cdma.data_state=2, connected.");
                return true;
            }
        }

        // Disconnect: Set ril.cdma.data_state=0 to stop pppd_cdma service.
        Log.d(LOG_TAG, "Didn't get ril.cdma.data_state=2 timely, aborting.");
        SystemProperties.set("ril.cdma.data_state", "0");

        return false;
    }

    protected Object
    responseDeactivateDataCall(Parcel p) {
        if (mIsSamsungCdma) {
            // Disconnect: Set ril.cdma.data_state=0 to stop pppd_cdma service.
            Log.d(LOG_TAG, "Set ril.cdma.data_state=0.");
            SystemProperties.set("ril.cdma.data_state", "0");
        }

        return null;
    }

    protected Object
    responseCdmaSubscription(Parcel p) {
        String response[] = (String[])responseStrings(p);

        if (/* mIsSamsungCdma && */ response.length == 4) {
            // PRL version is missing in subscription parcel, add it from properties.
            String prlVersion = SystemProperties.get("ril.prl_ver_1").split(":")[1];
            response          = new String[] {response[0], response[1], response[2],
                                              response[3], prlVersion};
        }

        return response;
    }

    protected class SamsungDriverCall extends DriverCall {
        @Override
        public String