上一节讲到WifiNative.java中setupInterfaceForClientMode()调用的几个方法:
startHal()
startSupplicant()
WificondControl.setupInterfaceForClientMode()
SupplicantStaIfaceHal.setupIface()
WifiMonitor.startMonitoring()
下面逐一展开进行分析,这里要涉及aidl-cpp通信这一概念,也就是说客户端是Java文件而服务是cpp文件。
继续上一节的startSupplicant(),我们找到server.cpp文件
路径:system/connectivity/wificond/server.cpp
//
Status Server::enableSupplicant(bool* success) {
*success = supplicant_manager_->StartSupplicant();
return Status::ok();
}
// 初始化
Server::Server(unique_ptr<InterfaceTool> if_tool,
unique_ptr<SupplicantManager> supplicant_manager,
unique_ptr<HostapdManager> hostapd_manager,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils)
: if_tool_(std::move(if_tool)),
supplicant_manager_(std::move(supplicant_manager)),
hostapd_manager_(std::move(hostapd_manager)),
netlink_utils_(netlink_utils),
scan_utils_(scan_utils) {
}
//引入
using android::wifi_system::SupplicantManager;
很明显,server.cpp里的enableSupplicant()方法调用了SupplicantManager的StartSupplicant()方法(细心一点你会发现这里的StartSupplicant()首部是大写的,按照书写规范来讲,明显不是java文件)
using android::wifi_system::SupplicantManager;
对应文件:frameworks/opt/net/wifi/libwifi_system/supplicant_manager.cpp
//
const char kSupplicantInitProperty[] = "init.svc.wpa_supplicant";
const char kSupplicantServiceName[] = "wpa_supplicant";
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 */
//查询名称为“init.svc.wpa_supplicant”的属性信息,返回状态
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); } //启动名称为"wpa_supplicant"的属性服务 property_set("ctl.start", kSupplicantServiceName); sched_yield(); ... }
每个属性都有一个名称和值,他们都是字符串格式。属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性。
在系统初始化时,Android将分配一个共享内存区来存储的属性。这些是由“init”守护进程完成的,其源代码位于:device/system/init。“init”守护进程将启动一个属性服务。
属性服务在“init”守护进程中运行。每一个客户端想要设置属性时,必须连接属性服务,再向其发送信息。属性服务将会在共享内存区中修改和创建属性。任何客户端想获得属性信息,可以从共享内存直接读取。这提高了读取性能。客户端应用程序可以调用libcutils中的API函数以GET/SET属性信息。libcutils的源代码位于:device/libs/cutils。API函数是:
int property_get(const char *key, char *value, const char *default_value);
int property_set(const char *key, const char *value);
而libcutils又调用libc中的 __system_property_xxx 函数获得共享内存中的属性。libc的源代码位于:device/system/bionic。
属性服务调用libc中的__system_property_init函数来初始化属性系统的共享内存。当启动属性服务时,将从以下文件中加载默认属性:
/default.prop
/system/build.prop
/system/default.prop
/data/local.prop
属性将会以上述顺序加载。后加载的属性将覆盖原先的值。这些属性加载之后,最后加载的属性会被保持在/data/property中。
特别属性如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。
如果属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)
属性“ ctl.start ”和“ ctl.stop ”是用来启动和停止服务。
每一项服务必须在/init.rc中定义.系统启动时,与init守护进程将解析init.rc和启动属性服务。一旦收到设置“ ctl.start ”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中 。客户端应用程序可以轮询那个属性值,以确定结果。
下面看startHal()方法
/** Helper method invoked to start supplicant if there were no ifaces */ private boolean startHal() { synchronized (mLock) { if (!mIfaceMgr.hasAnyIface()) { if (mWifiVendorHal.isVendorHalSupported()) { if (!mWifiVendorHal.startVendorHal()) { Log.e(TAG, "Failed to start vendor HAL"); return false; } } else { Log.i(TAG, "Vendor Hal not supported, ignoring start."); } } return true; } }
isVendorHalSupported()和startVendorHal()分别调用了HalDeviceManager的isSupported()和start()方法。
路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java
/**
* Returns whether the vendor HAL is supported on this device or not.
*/
public boolean isSupported() {
return isSupportedInternal();
}
/**
* Uses the IServiceManager to query if the vendor HAL is present in the VINTF for the device
* or not.
* @return true if supported, false otherwise.
*/
private boolean isSupportedInternal() {
if (VDBG) Log.d(TAG, "isSupportedInternal");
...
try {
return (mServiceManager.getTransport(IWifi.kInterfaceName, HAL_INSTANCE_NAME)
!= IServiceManager.Transport.EMPTY);
} catch (RemoteException e) {
Log.wtf(TAG, "Exception while operating on IServiceManager: " + e);
return false;
}
}
}
//引入
import android.hidl.manager.V1_0.IServiceManager;
/**
* Attempts to start Wi-Fi (using HIDL). Returns the success (true) or failure (false) or
* the start operation. Will also dispatch any registered ManagerStatusCallback.onStart() on
* success.
*
* Note: direct call to HIDL.
*/
public boolean start() {
return startWifi();
}
private boolean startWifi() {
if (VDBG) Log.d(TAG, "startWifi");
synchronized (mLock) {
try {
if (mWifi == null) {
Log.w(TAG, "startWifi called but mWifi is null!?");
return false;
} else {
int triedCount = 0;
while (triedCount <= START_HAL_RETRY_TIMES) {
WifiStatus status = mWifi.start();
if (status.code == WifiStatusCode.SUCCESS) {
initIWifiChipDebugListeners();
managerStatusListenerDispatch();
...
...
//引入
import android.hardware.wifi.V1_0.IWifi;
路径:system/libhidl/transport/manager/1.0/IServiceManager.hal
/** * Get the transport of a service. * * @param fqName Fully-qualified interface name. * @param name Instance name. Same as in IServiceManager::add * * @return transport Transport of service if known. */ getTransport(string fqName, string name) generates (Transport transport);
对应实现
路径:system/hwservicemanager/ServiceManager.cpp
Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName, const hidl_string& name) { using ::android::hardware::getTransport; pid_t pid = IPCThreadState::self()->getCallingPid(); if (!mAcl.canGet(fqName, pid)) { return Transport::EMPTY; } switch (getTransport(fqName, name)) { case vintf::Transport::HWBINDER: return Transport::HWBINDER; case vintf::Transport::PASSTHROUGH: return Transport::PASSTHROUGH; case vintf::Transport::EMPTY: default: return Transport::EMPTY; } }
路径:hardware/interfaces/wifi/1.0/IWifi.hal
/** * Perform any setup that is required to make use of the module. If the module * is already started then this must be a noop. * Must trigger |IWifiEventCallback.onStart| on success. * * @return status WifiStatus of the operation. * Possible status codes: * |WifiStatusCode.SUCCESS|, * |WifiStatusCode.NOT_AVAILABLE|, * |WifiStatusCode.UNKNOWN| */ @entry @callflow(next={"registerEventCallback", "start", "stop", "getChip"}) start() generates (WifiStatus status);
对应实现
路径:hardware/interfaces/wifi/1.2/default/wifi.cpp
Return<void> Wifi::start(start_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal, hidl_status_cb); } //引用 using hidl_return_util::validateAndCall;
路径:hardware/interfaces/wifi/1.2/default/hidl_return_util.h
// Use for HIDL methods which return instance of WifiStatus and a single return // value. template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args> Return<void> validateAndCall( ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb, Args&&... args) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (obj->isValid()) { const auto& ret_pair = (obj->*work)(std::forward<Args>(args)...); const WifiStatus& status = std::get<0>(ret_pair); const auto& ret_value = std::get<1>(ret_pair); hidl_cb(status, ret_value); } else { hidl_cb(createWifiStatus(status_code_if_invalid), typename std::remove_reference<ReturnT>::type()); } return Void(); } // Use for HIDL methods which return instance of WifiStatus and 2 return // values. template <typename ObjT, typename WorkFuncT, typename ReturnT1, typename ReturnT2, typename... Args> Return<void> validateAndCall( ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb, Args&&... args) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (obj->isValid()) { const auto& ret_tuple = (obj->*work)(std::forward<Args>(args)...); const WifiStatus& status = std::get<0>(ret_tuple); const auto& ret_value1 = std::get<1>(ret_tuple); const auto& ret_value2 = std::get<2>(ret_tuple); hidl_cb(status, ret_value1, ret_value2); } else { hidl_cb(createWifiStatus(status_code_if_invalid), typename std::remove_reference<ReturnT1>::type(), typename std::remove_reference<ReturnT2>::type()); } return Void(); }
下面看WificondControl.setupInterfaceForClientMode()方法
/** * Setup interface for client mode via wificond. * @return An IClientInterface as wificond client interface binder handler. * Returns null on failure. */ public IClientInterface setupInterfaceForClientMode(@NonNull String ifaceName) { ... IClientInterface clientInterface = null; try { clientInterface = mWificond.createClientInterface(ifaceName); } catch (RemoteException e1) { Log.e(TAG, "Failed to get IClientInterface due to remote exception"); return null; } ... Binder.allowBlocking(clientInterface.asBinder()); // Refresh Handlers mClientInterfaces.put(ifaceName, clientInterface); try { IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); if (wificondScanner == null) { Log.e(TAG, "Failed to get WificondScannerImpl"); return null; } mWificondScanners.put(ifaceName, wificondScanner); Binder.allowBlocking(wificondScanner.asBinder()); ScanEventHandler scanEventHandler = new ScanEventHandler(ifaceName); mScanEventHandlers.put(ifaceName, scanEventHandler); wificondScanner.subscribeScanEvents(scanEventHandler); PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(ifaceName); mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); } catch (RemoteException e) { Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); } return clientInterface; }
路径:system/connectivity/wificond/server.cpp
Status Server::createClientInterface(const std::string& iface_name, sp<IClientInterface>* created_interface) { InterfaceInfo interface; if (!SetupInterface(iface_name, &interface)) { return Status::ok(); // Logging was done internally } unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl( wiphy_index_, interface.name, interface.index, interface.mac_address, if_tool_.get(), netlink_utils_, scan_utils_)); *created_interface = client_interface->GetBinder(); BroadcastClientInterfaceReady(client_interface->GetBinder()); client_interfaces_[iface_name] = std::move(client_interface); return Status::ok(); }
GetBinder()
路径:system/connectivity/wificond/client_interface_impl.cpp
sp<android::net::wifi::IClientInterface> ClientInterfaceImpl::GetBinder() const { return binder_; } //初始化 binder_(new ClientInterfaceBinder(this))
路径:system/connectivity/wificond/client_interface_binder.cpp
WifiMonitor.startMonitoring():这一步主要是在WifiMonitor中建立与wpa_supplicant通信的socket通道、创建一个线程接收底层事件并分发处理。这里会创建两个socket通道与wpa_s通信,一个用于下发指令,另一个用于接收事件。成功后WifiMonitor会向WifiStateMachine发送一个代表socket通信建立成功的消息:SUP_CONNECTION_EVENT;收到这个消息就表示Wifi已经启动成功了。
wpa_supplicant分析
链接:https://www.cnblogs.com/oracleloyal/p/5328897.html