现在的位置: 首页 > 综合 > 正文

WifiService和wpa_supplicant的启动流程跟踪

2018年06月10日 ⁄ 综合 ⁄ 共 11903字 ⁄ 字号 评论关闭

这个图片是说明的是WifiService和wpa_supplicant的启动流程,我自己跟了一下代码,做了些记录。

public class SystemServer {
    private static final String TAG = "SystemServer";

    public static final int FACTORY_TEST_OFF = 0;
    public static final int FACTORY_TEST_LOW_LEVEL = 1;
    public static final int FACTORY_TEST_HIGH_LEVEL = 2;

    static Timer timer;
    static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr

    // The earliest supported time.  We pick one day into 1970, to
    // give any timezone code room without going into negative time.
    private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;

    /**
     * This method is called from Zygote to initialize the system. This will cause the native
     * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
     * up into init2() to start the Android services.
     */
    native public static void init1(String[] args);

    public static void main(String[] args) {
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            // If a device's clock is before 1970 (before 0), a lot of
            // APIs crash dealing with negative numbers, notably
            // java.io.File#setLastModified, so instead we fake it and
            // hope that time from cell towers or NTP fixes it
            // shortly.
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

        if (SamplingProfilerIntegration.isEnabled()) {
            SamplingProfilerIntegration.start();
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    SamplingProfilerIntegration.writeSnapshot("system_server", null);
                }
            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
        }

        // Mmmmmm... more memory!
        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();

        // The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        System.loadLibrary("android_servers");
        init1(args);
    }

    public static final void init2() {  //look init2 Android Service 
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();  //look 创建一个新的ServerThread线程
        thr.setName("android.server.ServerThread");
        thr.start();                      //look 启动这个ServerThread         
    }
}






hardware/libhardware_legacy/wifi/SystemServer.java

/**
 * This method is called from Zygote to initialize the system. This will cause the native
 * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
 * up into init2() to start the Android services.
 */
看这个注释,说明需要Zygote来初始化系统的时候会调用native services(包括SurfaceFlinger,AudioFlinger等),启动之后
会回调init2()来启动Android services


frameworks/base/serives/java/com/android/server/WifiService.java
public class WifiService extends IWifiManager.Stub {
    private static final String TAG = "WifiService";
    private static final boolean DBG = true;

    private final WifiStateMachine mWifiStateMachine;//look 注意这个!

    private Context mContext;

    private AlarmManager mAlarmManager;
    private PendingIntent mIdleIntent;
    private static final int IDLE_REQUEST = 0;
    private boolean mScreenOff;
    private boolean mDeviceIdle;
    private boolean mEmergencyCallbackMode = false;
    private int mPluggedType;

    /* Chipset supports background scan */
    private final boolean mBackgroundScanSupported;

    private final LockList mLocks = new LockList();
    // some wifi lock statistics
    private int mFullHighPerfLocksAcquired;
    private int mFullHighPerfLocksReleased;
    private int mFullLocksAcquired;
    private int mFullLocksReleased;
    private int mScanLocksAcquired;
    private int mScanLocksReleased;

    private final List<Multicaster> mMulticasters =
            new ArrayList<Multicaster>();
    private int mMulticastEnabled;
    private int mMulticastDisabled;

    private final IBatteryStats mBatteryStats;

	//..
	//..
	//..太多了

}

private final WifiStateMachine mWifiStateMachine;

    public synchronized boolean setWifiEnabled(boolean enable) {
        enforceChangePermission();
        if (DBG) {
            Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
        }

        if (enable) {
            reportStartWorkSource();
        }
        mWifiStateMachine.setWifiEnabled(enable); //look 这个是调用上面类里面那个mWifiStateMachine这个成员的一个函数去使能wifi
												  //我们去找这个实现
        /*
         * Caller might not have WRITE_SECURE_SETTINGS,
         * only CHANGE_WIFI_STATE is enforced
         */

        /* Avoids overriding of airplane state when wifi is already in the expected state */
        if (enable != mWifiEnabled) {
            long ident = Binder.clearCallingIdentity();
            persistWifiState(enable);
            Binder.restoreCallingIdentity(ident);
        }

        if (enable) {
            if (!mIsReceiverRegistered) {
                registerForBroadcasts();
                mIsReceiverRegistered = true;
            }
        } else if (mIsReceiverRegistered) {
            mContext.unregisterReceiver(mReceiver);
            mIsReceiverRegistered = false;
        }

        return true;
    }
    



frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java

    public void setWifiEnabled(boolean enable) {
        mLastEnableUid.set(Binder.getCallingUid());
        if (enable) {
            /* Argument is the state that is entered prior to load */
            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));//look
            sendMessage(CMD_START_SUPPLICANT);									//look 我们分成两路 1driver 2wap_supplicant
        } else {
            sendMessage(CMD_STOP_SUPPLICANT);
            /* Argument is the state that is entered upon success */
            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
        }
    }


第一步 load driver
------------------------------------------------------------------------------------
    class DriverLoadingState extends State { //注意这里DriverLoadingState 是Loading!!!后面还有Loaded
        @Override
        public void enter() {
            if (DBG) log(getName() + "\n");
            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());

            final Message message = new Message();
            message.copyFrom(getCurrentMessage());
            /* TODO: add a timeout to fail when driver load is hung.
             * Similarly for driver unload.
             */
            new Thread(new Runnable() {
                public void run() {
                    mWakeLock.acquire();
                    //enabling state
                    switch(message.arg1) {
                        case WIFI_STATE_ENABLING:
                            setWifiState(WIFI_STATE_ENABLING);
                            break;
                        case WIFI_AP_STATE_ENABLING:
                            setWifiApState(WIFI_AP_STATE_ENABLING);
                            break;
                    }

                    if(WifiNative.loadDriver()) { //look 去调用WifiNative的loaderDriver去加载驱动
                        if (DBG) log("Driver load successful");
                        sendMessage(CMD_LOAD_DRIVER_SUCCESS);
                    } else {
                        loge("Failed to load driver!");
                        switch(message.arg1) {
                            case WIFI_STATE_ENABLING:
                                setWifiState(WIFI_STATE_UNKNOWN);
                                break;
                            case WIFI_AP_STATE_ENABLING:
                                setWifiApState(WIFI_AP_STATE_FAILED);
                                break;
                        }
                        sendMessage(CMD_LOAD_DRIVER_FAILURE);
                    }
                    mWakeLock.release();
                }
            }).start();
        }

        @Override
        public boolean processMessage(Message message) {
            if (DBG) log(getName() + message.toString() + "\n");
            switch (message.what) {
                case CMD_LOAD_DRIVER_SUCCESS:
                    transitionTo(mDriverLoadedState);
                    break;
                case CMD_LOAD_DRIVER_FAILURE:
                    transitionTo(mDriverFailedState);
                    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_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;
        }
    }
    
WifiNative.loadDriver在
frameworks/base/wifi/java/android/net/wifi/WifiNative.java
public class WifiNative {

    static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0;
    static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
    static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;

    public native static String getErrorString(int errorCode);

    public native static boolean loadDriver(); //look 这个成员函数!就是我们需要的
    
    //..
    //..
    //..
    
 }
 
它的实现应该是在
frameworks/base/core/jni/android_net_wifi_wifi.cpp

static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
{
    return (jboolean)(::wifi_load_driver() == 0); //look wifi_loader_driver是我们需要的
}



wifi_loader_driver()在hardware/libhardware_legacy/wifi/wifi.c

int wifi_load_driver()
{
    LOGI("[semco] wifi_load_driver.");
#ifdef WIFI_DRIVER_MODULE_PATH
    char driver_status[PROPERTY_VALUE_MAX];
    int count = 100; /* wait at most 20 seconds for completion */
	
    if (is_wifi_driver_loaded()) {
        return 0;
    }
    if (insmod(WIFI_SDIO_DRIVER_MODULE_PATH, WIFI_SDIO_DRIVER_MODULE_ARG) < 0) //look 看看这insmod多熟悉 先安装SDIO驱动
    	{															//WIFI_SDIO_DRIVER_MODULE_PATH
        LOGE("[semco] cfg80211 module loading fail.");				//WIFI_SDIO_DRIVER_MODULE_ARG
        return -1;
    	}

    if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0)  //look 还有这个  再安装wifi驱动 
        return -1;											//DRIVER_MODULE_PATH  这几个宏我们都在BoardConfig.mk中定义了

    if (strcmp(FIRMWARE_LOADER,"") == 0) {
        usleep(WIFI_DRIVER_LOADER_DELAY);
        property_set(DRIVER_PROP_NAME, "ok");
    }
    else {
        property_set("ctl.start", FIRMWARE_LOADER);
    }
    sched_yield();
    while (count-- > 0) {
        if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
            if (strcmp(driver_status, "ok") == 0)
                return 0;
            else if (strcmp(driver_status, "failed") == 0) {
                wifi_unload_driver();
                return -1;
            }
        }
        usleep(200000);
    }
    property_set(DRIVER_PROP_NAME, "timeout");
    wifi_unload_driver();
    return -1;
#else
    property_set(DRIVER_PROP_NAME, "ok");
    return 0;
#endif
}

load driver end
--------------------------------------------------------------------------------------------

第二步 start supplicant
--------------------------------------------------------------------------------------------
CMD_START_SUPPLICANT之后我们来到了这里


frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java


    class DriverLoadedState extends State {  //look 这里注意,这里是DriverLoadedState  loaded!!!说明driver已经insmod了
        @Override
        public void enter() {
            if (DBG) log(getName() + "\n");
            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
        }
        @Override
        public boolean processMessage(Message message) {
            if (DBG) log(getName() + message.toString() + "\n");
            switch(message.what) {
                case CMD_UNLOAD_DRIVER:
                    transitionTo(mDriverUnloadingState);
                    break;
                case CMD_START_SUPPLICANT:
		      //from semco
                    //try {
                    //    mNwService.wifiFirmwareReload(mInterfaceName, "STA");
                    //} catch (Exception e) {
                    //    loge("Failed to reload STA firmware " + e);
                        // continue
                    //}
                   try {
                       //A runtime crash can leave the interface up and
                       //this affects connectivity when supplicant starts up.
                       //Ensure interface is down before a supplicant start.
                        mNwService.setInterfaceDown(mInterfaceName);
                        //Set privacy extensions
                        mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
                    } catch (RemoteException re) {
                        loge("Unable to change interface settings: " + re);
                    } catch (IllegalStateException ie) {
                        loge("Unable to change interface settings: " + ie);
                    }

                    if(WifiNative.startSupplicant()) {  //look 调用WifiNative.startSupplicant()
                        if (DBG) log("Supplicant start successful");
                        mWifiMonitor.startMonitoring();
                        transitionTo(mSupplicantStartingState);
                    } else {
                        loge("Failed to start supplicant!");
                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
                    }
                    break;
                case CMD_START_AP:
                    transitionTo(mSoftApStartingState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
            return HANDLED;
        }
    }


WifiNative.startSupplicant()在哪?
frameworks/base/core/jni/android_net_wifi_wifi.cpp

static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject)
{
    return (jboolean)(::wifi_start_supplicant() == 0);
}

它调用wifi.c中的wifi_start_supplicant(),
wifi_loader_driver()在hardware/libhardware_legacy/wifi/wifi.c

int wifi_start_supplicant()
{
    LOGI("[semco] wifi_start_supplicant!");
    return wifi_start_supplicant_common(SUPP_CONFIG_FILE);
}

int wifi_start_supplicant_common(const char *config_file)
{
    char daemon_cmd[PROPERTY_VALUE_MAX];
    char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
    int count = 200; /* wait at most 20 seconds for completion */
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    const prop_info *pi;
    unsigned serial = 0;
#endif

    /* Check whether already running */
    if (property_get(SUPP_PROP_NAME, supp_status, NULL)
            && strcmp(supp_status, "running") == 0) {
        return 0;
    }

    /* Before starting the daemon, make sure its config file exists */
    if (ensure_config_file_exists(config_file) < 0) {
        LOGE("Wi-Fi will not be enabled");
        return -1;
    }

    if (ensure_entropy_file_exists() < 0) {
        LOGE("Wi-Fi entropy file was not created");
    }

    /* Clear out any stale socket files that might be left over. */
    wifi_wpa_ctrl_cleanup();

#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    /*
     * Get a reference to the status property, so we can distinguish
     * the case where it goes stopped => running => stopped (i.e.,
     * it start up, but fails right away) from the case in which
     * it starts in the stopped state and never manages to start
     * running at all.
     */
    pi = __system_property_find(SUPP_PROP_NAME);
    if (pi != NULL) {
        serial = pi->serial;
    }
#endif
//from semco
//    property_get("wifi.interface", iface, WIFI_TEST_INTERFACE);
//    snprintf(daemon_cmd, PROPERTY_VALUE_MAX, "%s:-i%s -c%s", SUPPLICANT_NAME, iface, config_file);
    property_set("ctl.start", SUPPLICANT_NAME);   //look 在这里是启动了
    sched_yield();

    while (count-- > 0) {
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
        if (pi == NULL) {
            pi = __system_property_find(SUPP_PROP_NAME);
        }
        if (pi != NULL) {
            __system_property_read(pi, NULL, supp_status);
            if (strcmp(supp_status, "running") == 0) {
                return 0;
            } else if (pi->serial != serial &&
                    strcmp(supp_status, "stopped") == 0) {
                return -1;
            }
        }
#else
        if (property_get(SUPP_PROP_NAME, supp_status, NULL)) {
            if (strcmp(supp_status, "running") == 0)
                return 0;
        }
#endif
        usleep(100000);
    }
    return -1;
}
--------------------------------------------------------------------------------------------
start supplicant end


抱歉!评论已关闭.