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

Commit 320a4bed authored by Irfan Sheriff's avatar Irfan Sheriff Committed by Android (Google) Code Review
Browse files

Merge "Handle supplicant stop correctly"

parents 957e9ca2 96071a70
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -121,7 +121,7 @@ static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz)
    return (jboolean)(::wifi_start_supplicant() == 0);
}

static jboolean android_net_wifi_stopSupplicant(JNIEnv* env, jobject clazz)
static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject clazz)
{
    return (jboolean)(::wifi_stop_supplicant() == 0);
}
@@ -533,6 +533,11 @@ static jboolean android_net_wifi_reloadConfigCommand(JNIEnv* env, jobject clazz)
    return doBooleanCommand("RECONFIGURE", "OK");
}

static jboolean android_net_wifi_terminateCommand(JNIEnv* env, jobject clazz)
{
    return doBooleanCommand("TERMINATE", "OK");
}

static jboolean android_net_wifi_setScanResultHandlingCommand(JNIEnv* env, jobject clazz, jint mode)
{
    char cmdstr[BUF_SIZE];
@@ -605,7 +610,7 @@ static JNINativeMethod gWifiMethods[] = {
    { "isDriverLoaded", "()Z",  (void *)android_net_wifi_isDriverLoaded},
    { "unloadDriver", "()Z",  (void *)android_net_wifi_unloadDriver },
    { "startSupplicant", "()Z",  (void *)android_net_wifi_startSupplicant },
    { "stopSupplicant", "()Z",  (void *)android_net_wifi_stopSupplicant },
    { "killSupplicant", "()Z",  (void *)android_net_wifi_killSupplicant },
    { "connectToSupplicant", "()Z",  (void *)android_net_wifi_connectToSupplicant },
    { "closeSupplicantConnection", "()V",  (void *)android_net_wifi_closeSupplicantConnection },

@@ -647,6 +652,7 @@ static JNINativeMethod gWifiMethods[] = {
    { "getMacAddressCommand", "()Ljava/lang/String;", (void*) android_net_wifi_getMacAddressCommand },
    { "saveConfigCommand", "()Z", (void*) android_net_wifi_saveConfigCommand },
    { "reloadConfigCommand", "()Z", (void*) android_net_wifi_reloadConfigCommand },
    { "terminateCommand", "()Z", (void*) android_net_wifi_terminateCommand },
    { "setScanResultHandlingCommand", "(I)Z", (void*) android_net_wifi_setScanResultHandlingCommand },
    { "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
    { "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
+3 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ public class WifiNative {

    public native static boolean startSupplicant();
    
    public native static boolean stopSupplicant();
    public native static boolean killSupplicant();

    public native static boolean connectToSupplicant();

@@ -80,6 +80,8 @@ public class WifiNative {

    public native static boolean disconnectCommand();

    public native static boolean terminateCommand();

    public native static String statusCommand();

    public native static int getRssiCommand();
+94 −23
Original line number Diff line number Diff line
@@ -126,6 +126,18 @@ public class WifiStateMachine extends HierarchicalStateMachine {
     */
    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;

    /**
     * Delay between supplicant restarts upon failure to establish connection
     */
    private static final int SUPPLICANT_RESTART_INTERVAL_MSECS = 5000;

    /**
     * Number of times we attempt to restart supplicant
     */
    private static final int SUPPLICANT_RESTART_TRIES = 5;

    private int mSupplicantRestartCount = 0;

    /**
     * Instance of the bluetooth headset helper. This needs to be created
     * early because there is a delay before it actually 'connects', as
@@ -365,10 +377,11 @@ public class WifiStateMachine extends HierarchicalStateMachine {
    /* Driver loaded */
    private HierarchicalState mDriverLoadedState = new DriverLoadedState();
    /* Driver loaded, waiting for supplicant to start */
    private HierarchicalState mWaitForSupState = new WaitForSupState();

    private HierarchicalState mSupplicantStartingState = new SupplicantStartingState();
    /* Driver loaded and supplicant ready */
    private HierarchicalState mDriverSupReadyState = new DriverSupReadyState();
    private HierarchicalState mSupplicantStartedState = new SupplicantStartedState();
    /* Waiting for supplicant to stop and monitor to exit */
    private HierarchicalState mSupplicantStoppingState = new SupplicantStoppingState();
    /* Driver start issued, waiting for completed event */
    private HierarchicalState mDriverStartingState = new DriverStartingState();
    /* Driver started */
@@ -513,10 +526,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                addState(mDriverFailedState, mDriverUnloadedState);
            addState(mDriverLoadingState, mDefaultState);
            addState(mDriverLoadedState, mDefaultState);
                addState(mWaitForSupState, mDriverLoadedState);
            addState(mDriverSupReadyState, mDefaultState);
                addState(mDriverStartingState, mDriverSupReadyState);
                addState(mDriverStartedState, mDriverSupReadyState);
            addState(mSupplicantStartingState, mDefaultState);
            addState(mSupplicantStartedState, mDefaultState);
                addState(mDriverStartingState, mSupplicantStartedState);
                addState(mDriverStartedState, mSupplicantStartedState);
                    addState(mScanModeState, mDriverStartedState);
                    addState(mConnectModeState, mDriverStartedState);
                        addState(mConnectingState, mConnectModeState);
@@ -524,8 +537,9 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                        addState(mDisconnectingState, mConnectModeState);
                        addState(mDisconnectedState, mConnectModeState);
                        addState(mWaitForWpsCompletionState, mConnectModeState);
                addState(mDriverStoppingState, mDriverSupReadyState);
                addState(mDriverStoppedState, mDriverSupReadyState);
                addState(mDriverStoppingState, mSupplicantStartedState);
                addState(mDriverStoppedState, mSupplicantStartedState);
            addState(mSupplicantStoppingState, mDefaultState);
            addState(mSoftApStartedState, mDefaultState);

        setInitialState(mInitialState);
@@ -1742,7 +1756,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                        Log.d(TAG, "Supplicant start successful");
                        mWifiMonitor.startMonitoring();
                        setWifiState(WIFI_STATE_ENABLED);
                        transitionTo(mWaitForSupState);
                        transitionTo(mSupplicantStartingState);
                    } else {
                        Log.e(TAG, "Failed to start supplicant!");
                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
@@ -1888,7 +1902,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
    }


    class WaitForSupState extends HierarchicalState {
    class SupplicantStartingState extends HierarchicalState {
        @Override
        public void enter() {
            if (DBG) Log.d(TAG, getName() + "\n");
@@ -1900,6 +1914,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
            switch(message.what) {
                case SUP_CONNECTION_EVENT:
                    Log.d(TAG, "Supplicant connection established");
                    mSupplicantRestartCount = 0;
                    mSupplicantStateTracker.resetSupplicantState();
                    /* Initialize data structures */
                    mLastBssid = null;
@@ -1919,10 +1934,18 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                    transitionTo(mDriverStartedState);
                    break;
                case SUP_DISCONNECTION_EVENT:
                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
                        Log.e(TAG, "Failed to setup control channel, restart supplicant");
                    WifiNative.stopSupplicant();
                        WifiNative.killSupplicant();
                        transitionTo(mDriverLoadedState);
                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
                    } else {
                        mSupplicantRestartCount = 0;
                        Log.e(TAG, "Failed " + mSupplicantRestartCount +
                                " times to start supplicant, unload driver");
                        transitionTo(mDriverLoadedState);
                    sendMessageAtFrontOfQueue(CMD_START_SUPPLICANT);
                        sendMessage(CMD_UNLOAD_DRIVER);
                    }
                    break;
                case CMD_LOAD_DRIVER:
                case CMD_UNLOAD_DRIVER:
@@ -1951,7 +1974,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
        }
    }

    class DriverSupReadyState extends HierarchicalState {
    class SupplicantStartedState extends HierarchicalState {
        @Override
        public void enter() {
            if (DBG) Log.d(TAG, getName() + "\n");
@@ -1966,23 +1989,26 @@ public class WifiStateMachine extends HierarchicalStateMachine {
            switch(message.what) {
                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
                    Log.d(TAG, "Stop supplicant received");
                    WifiNative.closeSupplicantConnection();
                    WifiNative.stopSupplicant();
                    Log.d(TAG, "send terminate command to supplicant");
                    if (!WifiNative.terminateCommand()) {
                        Log.e(TAG, "Failed to terminate cleanly, issue kill");
                        WifiNative.killSupplicant();
                    }
                    handleNetworkDisconnect();
                    sendSupplicantConnectionChangedBroadcast(false);
                    mSupplicantStateTracker.resetSupplicantState();
                    transitionTo(mDriverLoadedState);
                    transitionTo(mSupplicantStoppingState);
                    break;
                case SUP_DISCONNECTION_EVENT:  /* Supplicant died */
                case SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
                    Log.e(TAG, "Supplicant died, restarting");
                    Log.e(TAG, "Connection lost, restart supplicant");
                    WifiNative.killSupplicant();
                    WifiNative.closeSupplicantConnection();
                    handleNetworkDisconnect();
                    sendSupplicantConnectionChangedBroadcast(false);
                    mSupplicantStateTracker.resetSupplicantState();
                    transitionTo(mDriverLoadedState);
                    sendMessageAtFrontOfQueue(CMD_START_SUPPLICANT); /* restart */
                    sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
                    break;
                case SCAN_RESULTS_EVENT:
                    setScanResults(WifiNative.scanResultsCommand());
@@ -2058,6 +2084,51 @@ public class WifiStateMachine extends HierarchicalStateMachine {
        }
    }

    class SupplicantStoppingState extends HierarchicalState {
        @Override
        public void enter() {
            if (DBG) Log.d(TAG, getName() + "\n");
            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
        }
        @Override
        public boolean processMessage(Message message) {
            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
            switch(message.what) {
                case SUP_CONNECTION_EVENT:
                    Log.e(TAG, "Supplicant connection received while stopping");
                    break;
                case SUP_DISCONNECTION_EVENT:
                    Log.d(TAG, "Supplicant connection lost");
                    WifiNative.closeSupplicantConnection();
                    transitionTo(mDriverLoadedState);
                    break;
                case CMD_LOAD_DRIVER:
                case CMD_UNLOAD_DRIVER:
                case CMD_START_SUPPLICANT:
                case CMD_STOP_SUPPLICANT:
                case CMD_START_AP:
                case CMD_STOP_AP:
                case CMD_START_DRIVER:
                case CMD_STOP_DRIVER:
                case CMD_SET_SCAN_MODE:
                case CMD_SET_SCAN_TYPE:
                case CMD_SET_HIGH_PERF_MODE:
                case CMD_SET_BLUETOOTH_COEXISTENCE:
                case CMD_SET_BLUETOOTH_SCAN_MODE:
                case CMD_SET_COUNTRY_CODE:
                case CMD_SET_FREQUENCY_BAND:
                case CMD_START_PACKET_FILTERING:
                case CMD_STOP_PACKET_FILTERING:
                    deferMessage(message);
                    break;
                default:
                    return NOT_HANDLED;
            }
            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
            return HANDLED;
        }
    }

    class DriverStartingState extends HierarchicalState {
        @Override
        public void enter() {