美文网首页
Wifi笔记 | Android P 启动流程之startSup

Wifi笔记 | Android P 启动流程之startSup

作者: 力卉编程 | 来源:发表于2020-01-12 11:22 被阅读0次

    一、WifiNative

    WifiNative 主要工作:

    • startHal
    • startSupplicant
    • createStaIface

    这里主要讲第二点:startSupplicant

    二、

    2.1 startSupplicant

    private boolean startSupplicant() {
            synchronized (mLock) {
                if (!mIfaceMgr.hasAnyStaIface()) {
                    if (!mWificondControl.enableSupplicant()) {
                        Log.e(TAG, "Failed to enable supplicant");
                        return false;
                    }
                    if (!waitForSupplicantConnection()) {
                        Log.e(TAG, "Failed to connect to supplicant");
                        return false;
                    }
                    if (!mSupplicantStaIfaceHal.registerDeathHandler(
                            new SupplicantDeathHandlerInternal())) {
                        Log.e(TAG, "Failed to register supplicant death handler");
                        return false;
                    }
                }
                return true;
            }
        }
    private boolean waitForSupplicantConnection() {
            // Start initialization if not already started.
            if (!mSupplicantStaIfaceHal.isInitializationStarted()
                    && !mSupplicantStaIfaceHal.initialize()) {
                return false;
            }
            boolean connected = false;
            int connectTries = 0;
            while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
                // Check if the initialization is complete.
                connected = mSupplicantStaIfaceHal.isInitializationComplete();
                if (connected) {
                    break;
                }
                try {
                    Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
                } catch (InterruptedException ignore) {
                }
            }
            return connected;
        }
    

    2.1 WificondControl::enableSupplicant

     /**
        * Enable wpa_supplicant via wificond.
        * @return Returns true on success.
        */
        public boolean enableSupplicant() {
            if (!retrieveWificondAndRegisterForDeath()) {
                return false;
            }
            try {
                return mWificond.enableSupplicant();
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to enable supplicant due to remote exception");
            }
            return false;
        }
    

    2.2 Server::enableSupplicant

    //system/connectivity/wificond/server.cpp
    Status Server::enableSupplicant(bool* success) {
      *success = supplicant_manager_->StartSupplicant();
      return Status::ok();
    }
    

    2.3 SupplicantManager::StartSupplicant()

    启动的两行代码:
    property_set("ctl.start", kSupplicantServiceName);
    sched_yield(); //---这个应当是异步调用直接返回的意思

    //frameworks/opt/net/wifi/libwifi_system/supplicant_manager.cpp
    bool SupplicantManager::StartSupplicant() {
      char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
      int count = 200; /* wait at most 20 seconds for completion */
      const prop_info* pi;
      unsigned serial = 0;
     
      /* Check whether already running */
      if (property_get(kSupplicantInitProperty, supp_status, NULL) &&
          strcmp(supp_status, "running") == 0) {
        return true;
      }
     /*
       * 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(kSupplicantInitProperty);
      if (pi != NULL) {
        serial = __system_property_serial(pi);
      }
     
      property_set("ctl.start", kSupplicantServiceName);
      sched_yield();
     
      while (count-- > 0) {
        if (pi == NULL) {
          pi = __system_property_find(kSupplicantInitProperty);
        }
        if (pi != NULL) {
          /*
           * property serial updated means that init process is scheduled
           * after we sched_yield, further property status checking is based on this
           */
          if (__system_property_serial(pi) != serial) {
            __system_property_read(pi, NULL, supp_status);
            if (strcmp(supp_status, "running") == 0) {
              return true;
            } else if (strcmp(supp_status, "stopped") == 0) {
              return false;
            }
          }
        }
        usleep(100000);
      }
      return false;
    }
    

    2.4 总结

    startSupplicant 是启动WIFI的协议栈登录认证接口,通过WificondControl::enableSupplicant调用Server::enableSupplicant,Server端启动了一个SupplicantManager来处理启动事件,最后调用
    property_set("ctl.start", kSupplicantServiceName);
    sched_yield();
    通过 pi = __system_property_find(kSupplicantInitProperty); 来获取状态返回给上层等待函数:waitForSupplicantConnection。
    这样就是一个完整的协议栈(startSupplicant)启动流程

    完~~~
    文 | 力卉编程

    相关文章

      网友评论

          本文标题:Wifi笔记 | Android P 启动流程之startSup

          本文链接:https://www.haomeiwen.com/subject/qepiactx.html