前言:之前在(五十) Android O WiFi的扫描流程梳理 中梳理到wificond,就是找不到wificond对应的具体实现类,本文在现有发现上继续梳理,服务端是由cpp实现的,这种aidl实现方式被Google成为aidl-cpp
在梳理WiFi 扫描流程的时候遇到如下方法,然后找不到对应服务端的实现类,现在专门梳理下找到的线索。
mWificond = mWifiInjector.makeWificond();
public IWificond makeWificond() {
// We depend on being able to refresh our binder in WifiStateMachine, so don't cache it.
IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME);
return IWificond.Stub.asInterface(binder);
}
clientInterface = mWificond.createClientInterface()
mWificondScanner = mClientInterface.getWifiScannerImpl();
最终会调用mWificondScanner的scan方法来进行WiFi搜索。
具体相关代码存放路径:
aidl存放路径:
./system/connectivity/wificond/aidl/android/net/wifi/IWifiScannerImpl.aidl
./system/connectivity/wificond/aidl/android/net/wifi/IWificond.aidl
aidl对应的.h文件存放路径:
aidl对应的.cpp文件存放路径:
/out/target/product/xxxxxx/obj/STATIC_LIBRARIES/libwificond_ipc_intermediates/aidl-generated/src/aidl/android/net/wifi/IWificond.cpp
另外./system/connectivity/wificond对应的模块为wificond
可以通过“make wificond”编译出如下的执行文件,在system/bin下
参考https://www.jianshu.com/p/5f2ae92291af 或者 https://android.googlesource.com/platform/system/tools/aidl/+/brillo-m10-dev/docs/aidl-cpp.md
是有aidl-cpp这回事的,可以完成java和C++之间的IPC通信。
./system/connectivity/wificond/aidl/android/net/wifi/IWificond.aidl
package android.net.wifi;
import android.net.wifi.IApInterface;
import android.net.wifi.IClientInterface;
import android.net.wifi.IInterfaceEventCallback;
// Service interface that exposes primitives for controlling the WiFi
// subsystems of a device.
interface IWificond {
// Create a network interface suitable for use as an AP.
@nullable IApInterface createApInterface();
// Create a network interface suitable for use as a WiFi client.
@nullable IClientInterface createClientInterface();
// Tear down all existing interfaces. This should enable clients to create
// future interfaces immediately after this method returns.
void tearDownInterfaces();
// @return list of the currently configured IClientInterface instances.
List GetClientInterfaces();
// @return list of the currently configured IApInterface instances.
List GetApInterfaces();
// Register a callback to receive interface status updates.
//
// Multiple callbacks can be registered simultaneously.
// Duplicate registrations of the same callback will be ignored.
//
// @param callback object to add to the set of registered callbacks.
oneway void RegisterCallback(IInterfaceEventCallback callback);
// Remove a callback from the set of registered callbacks.
//
// This must be the same instance as previously registered.
// Requests to remove unknown callbacks will be ignored.
//
// @param callback object to remove from the set of registered callbacks.
oneway void UnregisterCallback(IInterfaceEventCallback callback);
}
/out/target/product/xxxxx/obj/STATIC_LIBRARIES/libwificond_ipc_intermediates/aidl-generated/include/android/net/wifi/IWificond.h
#ifndef AIDL_GENERATED_ANDROID_NET_WIFI_I_WIFICOND_H_
#define AIDL_GENERATED_ANDROID_NET_WIFI_I_WIFICOND_H_
#include
#include
#include
#include
#include
#include
#include
#include
namespace android {
namespace net {
namespace wifi {
class IWificond : public ::android::IInterface {
public:
DECLARE_META_INTERFACE(Wificond)
virtual ::android::binder::Status createApInterface(::android::sp<::android::net::wifi::IApInterface>* _aidl_return) = 0;
virtual ::android::binder::Status createClientInterface(::android::sp<::android::net::wifi::IClientInterface>* _aidl_return) = 0;
virtual ::android::binder::Status tearDownInterfaces() = 0;
virtual ::android::binder::Status GetClientInterfaces(::std::vector<::android::sp<::android::IBinder>>* _aidl_return) = 0;
virtual ::android::binder::Status GetApInterfaces(::std::vector<::android::sp<::android::IBinder>>* _aidl_return) = 0;
virtual ::android::binder::Status RegisterCallback(const ::android::sp<::android::net::wifi::IInterfaceEventCallback>& callback) = 0;
virtual ::android::binder::Status UnregisterCallback(const ::android::sp<::android::net::wifi::IInterfaceEventCallback>& callback) = 0;
enum Call {
CREATEAPINTERFACE = ::android::IBinder::FIRST_CALL_TRANSACTION + 0,
CREATECLIENTINTERFACE = ::android::IBinder::FIRST_CALL_TRANSACTION + 1,
TEARDOWNINTERFACES = ::android::IBinder::FIRST_CALL_TRANSACTION + 2,
GETCLIENTINTERFACES = ::android::IBinder::FIRST_CALL_TRANSACTION + 3,
GETAPINTERFACES = ::android::IBinder::FIRST_CALL_TRANSACTION + 4,
REGISTERCALLBACK = ::android::IBinder::FIRST_CALL_TRANSACTION + 5,
UNREGISTERCALLBACK = ::android::IBinder::FIRST_CALL_TRANSACTION + 6,
};
}; // class IWificond
} // namespace wifi
} // namespace net
} // namespace android
#endif // AIDL_GENERATED_ANDROID_NET_WIFI_I_WIFICOND_H_
/out/target/product/xxxxxx/obj/STATIC_LIBRARIES/libwificond_ipc_intermediates/aidl-generated/src/aidl/android/net/wifi/IWificond.cpp
#include
#include
namespace android {
namespace net {
namespace wifi {
IMPLEMENT_META_INTERFACE(Wificond, "android.net.wifi.IWificond")
} // namespace wifi
} // namespace net
} // namespace android
#include
#include
namespace android {
namespace net {
namespace wifi {
BpWificond::BpWificond(const ::android::sp<::android::IBinder>& _aidl_impl)
: BpInterface(_aidl_impl){
}
::android::binder::Status BpWificond::createApInterface(::android::sp<::android::net::wifi::IApInterface>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(IWificond::CREATEAPINTERFACE, _aidl_data, &_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpWificond::createClientInterface(::android::sp<::android::net::wifi::IClientInterface>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(IWificond::CREATECLIENTINTERFACE, _aidl_data, &_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpWificond::tearDownInterfaces() {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(IWificond::TEARDOWNINTERFACES, _aidl_data, &_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpWificond::GetClientInterfaces(::std::vector<::android::sp<::android::IBinder>>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(IWificond::GETCLIENTINTERFACES, _aidl_data, &_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readStrongBinderVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpWificond::GetApInterfaces(::std::vector<::android::sp<::android::IBinder>>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(IWificond::GETAPINTERFACES, _aidl_data, &_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readStrongBinderVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpWificond::RegisterCallback(const ::android::sp<::android::net::wifi::IInterfaceEventCallback>& callback) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeStrongBinder(::android::net::wifi::IInterfaceEventCallback::asBinder(callback));
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(IWificond::REGISTERCALLBACK, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpWificond::UnregisterCallback(const ::android::sp<::android::net::wifi::IInterfaceEventCallback>& callback) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeStrongBinder(::android::net::wifi::IInterfaceEventCallback::asBinder(callback));
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(IWificond::UNREGISTERCALLBACK, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
} // namespace wifi
} // namespace net
} // namespace android
#include
#include
namespace android {
namespace net {
namespace wifi {
::android::status_t BnWificond::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
case Call::CREATEAPINTERFACE:
{
::android::sp<::android::net::wifi::IApInterface> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::binder::Status _aidl_status(createApInterface(&_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinder(::android::net::wifi::IApInterface::asBinder(_aidl_return));
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case Call::CREATECLIENTINTERFACE:
{
::android::sp<::android::net::wifi::IClientInterface> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::binder::Status _aidl_status(createClientInterface(&_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinder(::android::net::wifi::IClientInterface::asBinder(_aidl_return));
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case Call::TEARDOWNINTERFACES:
{
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::binder::Status _aidl_status(tearDownInterfaces());
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
}
break;
case Call::GETCLIENTINTERFACES:
{
::std::vector<::android::sp<::android::IBinder>> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::binder::Status _aidl_status(GetClientInterfaces(&_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinderVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case Call::GETAPINTERFACES:
{
::std::vector<::android::sp<::android::IBinder>> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::binder::Status _aidl_status(GetApInterfaces(&_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinderVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case Call::REGISTERCALLBACK:
{
::android::sp<::android::net::wifi::IInterfaceEventCallback> in_callback;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readStrongBinder(&in_callback);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(RegisterCallback(in_callback));
}
break;
case Call::UNREGISTERCALLBACK:
{
::android::sp<::android::net::wifi::IInterfaceEventCallback> in_callback;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readStrongBinder(&in_callback);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(UnregisterCallback(in_callback));
}
break;
default:
{
_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
}
break;
}
if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
}
return _aidl_ret_status;
}
} // namespace wifi
} // namespace net
} // namespace android
前面三个类比于java中的aidl和自动生成的实现类,c++多了.h和.cpp,对应于.java。
./system/sepolicy/public/wificond.te
# wificond
type wificond, domain;
type wificond_exec, exec_type, file_type;
binder_use(wificond)
binder_call(wificond, system_server)
add_service(wificond, wificond_service)
set_prop(wificond, wifi_prop)
set_prop(wificond, ctl_default_prop)
# create sockets to set interfaces up and down
allow wificond self:udp_socket create_socket_perms;
# setting interface state up/down is a privileged ioctl
allowxperm wificond self:udp_socket ioctl { SIOCSIFFLAGS };
allow wificond self:capability { net_admin net_raw };
# allow wificond to speak to nl80211 in the kernel
allow wificond self:netlink_socket create_socket_perms_no_ioctl;
# newer kernels (e.g. 4.4 but not 4.1) have a new class for sockets
allow wificond self:netlink_generic_socket create_socket_perms_no_ioctl;
r_dir_file(wificond, proc_net)
# wificond writes out configuration files for wpa_supplicant/hostapd.
# wificond also reads pid files out of this directory
allow wificond wifi_data_file:dir rw_dir_perms;
allow wificond wifi_data_file:file create_file_perms;
# allow wificond to check permission for dumping logs
allow wificond permission_service:service_manager find;
# dumpstate support
allow wificond dumpstate:fd use;
allow wificond dumpstate:fifo_file write;
这边看起来是添加wificond服务。
#ifndef AIDL_GENERATED_ANDROID_NET_WIFI_BN_WIFICOND_H_
#define AIDL_GENERATED_ANDROID_NET_WIFI_BN_WIFICOND_H_
#include
#include
namespace android {
namespace net {
namespace wifi {
class BnWificond : public ::android::BnInterface {
public:
::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags = 0) override;
}; // class BnWificond
} // namespace wifi
} // namespace net
} // namespace android
#endif // AIDL_GENERATED_ANDROID_NET_WIFI_BN_WIFICOND_H_
暂且认为 BnWificond.h继承了IWificond.h,c++这块需要很好地补习一下。这里不是很懂,C++当时就学了个入门,都好多年没碰了。
那么如下server.h很满足服务端的条件。
/system/connectivity/wificond/server.h
#include "android/net/wifi/BnWificond.h"
#include "android/net/wifi/IApInterface.h"
#include "android/net/wifi/IClientInterface.h"
#include "android/net/wifi/IInterfaceEventCallback.h"
#include "wificond/ap_interface_impl.h"
#include "wificond/client_interface_impl.h"
namespace android {
namespace wificond {
class NL80211Packet;
class NetlinkUtils;
class ScanUtils;
struct InterfaceInfo;
class Server : public android::net::wifi::BnWificond {
public:
Server(std::unique_ptr if_tool,
std::unique_ptr supplicant_man,
std::unique_ptr hostapd_man,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils);
~Server() override = default;
android::binder::Status RegisterCallback(
const android::sp&
callback) override;
android::binder::Status UnregisterCallback(
const android::sp&
callback) override;
android::binder::Status createApInterface(
android::sp*
created_interface) override;
android::binder::Status createClientInterface(
android::sp*
created_interface) override;
android::binder::Status tearDownInterfaces() override;
android::binder::Status GetClientInterfaces(
std::vector>* out_client_ifs) override;
...
对应的cpp文件
Status Server::createClientInterface(sp* created_interface) {
InterfaceInfo interface;
if (!SetupInterface(&interface)) {
return Status::ok(); // Logging was done internally
}
unique_ptr client_interface(new ClientInterfaceImpl(
wiphy_index_,
interface.name,
interface.index,
interface.mac_address,
if_tool_.get(),
supplicant_manager_.get(),
netlink_utils_,
scan_utils_));
*created_interface = client_interface->GetBinder();
client_interfaces_.push_back(std::move(client_interface));
BroadcastClientInterfaceReady(client_interfaces_.back()->GetBinder());
return Status::ok();
}
搜一下getWifiScannerImpl方法实现
这里看到只有client_interface_binder.cpp有对应实现
Status ClientInterfaceBinder::getWifiScannerImpl(
sp* out_wifi_scanner_impl) {
if (impl_ == nullptr) {
*out_wifi_scanner_impl = nullptr;
return Status::ok();
}
*out_wifi_scanner_impl = impl_->GetScanner();
return Status::ok();
}
这边传入的参数还不知晓,只知道是IWifiScannerImpl的实现类,而impl_应该就是ClientInterfaceImpl。
而GetScanner方法:
./client_interface_impl.h:82: const android::sp
直接返回scanner_,所以看下ClientInterfaceImpl的scanner初始化为什么?
ClientInterfaceImpl::ClientInterfaceImpl(
uint32_t wiphy_index,
const std::string& interface_name,
uint32_t interface_index,
const std::vector& interface_mac_addr,
InterfaceTool* if_tool,
SupplicantManager* supplicant_manager,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils)
: wiphy_index_(wiphy_index),
interface_name_(interface_name),
interface_index_(interface_index),
interface_mac_addr_(interface_mac_addr),
if_tool_(if_tool),
supplicant_manager_(supplicant_manager),
netlink_utils_(netlink_utils),
scan_utils_(scan_utils),
offload_service_utils_(new OffloadServiceUtils()),
mlme_event_handler_(new MlmeEventHandlerImpl(this)),
binder_(new ClientInterfaceBinder(this)),
is_associated_(false) {
netlink_utils_->SubscribeMlmeEvent(
interface_index_,
mlme_event_handler_.get());
if (!netlink_utils_->GetWiphyInfo(wiphy_index_,
&band_info_,
&scan_capabilities_,
&wiphy_features_)) {
LOG(ERROR) << "Failed to get wiphy info from kernel";
}
LOG(INFO) << "create scanner for interface with index: "
<< (int)interface_index_;
scanner_ = new ScannerImpl(wiphy_index,
interface_index_,
scan_capabilities_,
wiphy_features_,
this,
netlink_utils_,
scan_utils_,
offload_service_utils_);
}
ScannerImpl是IWifiScannerImpl的实现类(?)和Wificond应该是一样的。
namespace android {
namespace wificond {
class ClientInterfaceImpl;
class OffloadServiceUtils;
class ScanUtils;
class OffloadScanCallbackInterfaceImpl;
class OffloadScanManager;
class ScannerImpl : public android::net::wifi::BnWifiScannerImpl {
貌似流程对上了,继续看下ScannerImpl的构造方法
./scanning/scanner_impl.h:41: ScannerImpl(uint32_t wiphy_index, uint32_t interface_index,
./scanning/scanner_impl.h:47: ~ScannerImpl();
./scanning/scanner_impl.cpp:49:ScannerImpl::ScannerImpl(uint32_t wiphy_index, uint32_t interface_index,
./scanning/scanner_impl.cpp:89:ScannerImpl::~ScannerImpl() {}
namespace android {
namespace wificond {
ScannerImpl::ScannerImpl(uint32_t wiphy_index, uint32_t interface_index,
const ScanCapabilities& scan_capabilities,
const WiphyFeatures& wiphy_features,
ClientInterfaceImpl* client_interface,
NetlinkUtils* netlink_utils, ScanUtils* scan_utils,
weak_ptr offload_service_utils)
: valid_(true),
scan_started_(false),
pno_scan_started_(false),
offload_scan_supported_(false),
pno_scan_running_over_offload_(false),
pno_scan_results_from_offload_(false),
wiphy_index_(wiphy_index),
interface_index_(interface_index),
scan_capabilities_(scan_capabilities),
wiphy_features_(wiphy_features),
client_interface_(client_interface),
netlink_utils_(netlink_utils),
scan_utils_(scan_utils),
scan_event_handler_(nullptr) {
// Subscribe one-shot scan result notification from kernel.
LOG(INFO) << "subscribe scan result for interface with index: "
<< (int)interface_index_;
scan_utils_->SubscribeScanResultNotification(
interface_index_,
std::bind(&ScannerImpl::OnScanResultsReady, this, _1, _2, _3, _4));
// Subscribe scheduled scan result notification from kernel.
scan_utils_->SubscribeSchedScanResultNotification(
interface_index_,
std::bind(&ScannerImpl::OnSchedScanResultsReady,
this,
_1, _2));
std::shared_ptr
offload_scan_callback_interface =
offload_service_utils.lock()->GetOffloadScanCallbackInterface(this);
offload_scan_manager_ = offload_service_utils.lock()->GetOffloadScanManager(
offload_service_utils, offload_scan_callback_interface);
offload_scan_supported_ = offload_service_utils.lock()->IsOffloadScanSupported();
}
看下这个类的scan方法
Status ScannerImpl::scan(const SingleScanSettings& scan_settings,
bool* out_success) {
if (!CheckIsValid()) {
*out_success = false;
return Status::ok();
}
if (scan_started_) {
LOG(WARNING) << "Scan already started";
}
// Only request MAC address randomization when station is not associated.
bool request_random_mac = wiphy_features_.supports_random_mac_oneshot_scan &&
!client_interface_->IsAssociated();
// Initialize it with an empty ssid for a wild card scan.
vector> ssids = {{}};
vector> skipped_scan_ssids;
for (auto& network : scan_settings.hidden_networks_) {
if (ssids.size() + 1 > scan_capabilities_.max_num_scan_ssids) {
skipped_scan_ssids.emplace_back(network.ssid_);
continue;
}
ssids.push_back(network.ssid_);
}
LogSsidList(skipped_scan_ssids, "Skip scan ssid for single scan");
vector freqs;
for (auto& channel : scan_settings.channel_settings_) {
freqs.push_back(channel.frequency_);
}
int error_code = 0;
if (!scan_utils_->Scan(interface_index_, request_random_mac, ssids, freqs,
&error_code)) {
CHECK(error_code != ENODEV) << "Driver is in a bad state, restarting wificond";
*out_success = false;
return Status::ok();
}
scan_started_ = true;
*out_success = true;
return Status::ok();
}
这边会调用到scan_utils方法:
bool ScanUtils::Scan(uint32_t interface_index,
bool request_random_mac,
const vector>& ssids,
const vector& freqs,
int* error_code) {
NL80211Packet trigger_scan(
netlink_manager_->GetFamilyId(),
NL80211_CMD_TRIGGER_SCAN,
netlink_manager_->GetSequenceNumber(),
getpid());
// If we do not use NLM_F_ACK, we only receive a unicast repsonse
// when there is an error. If everything is good, scan results notification
// will only be sent through multicast.
// If NLM_F_ACK is set, there will always be an unicast repsonse, either an
// ERROR or an ACK message. The handler will always be called and removed by
// NetlinkManager.
trigger_scan.AddFlag(NLM_F_ACK);
NL80211Attr if_index_attr(NL80211_ATTR_IFINDEX, interface_index);
NL80211NestedAttr ssids_attr(NL80211_ATTR_SCAN_SSIDS);
for (size_t i = 0; i < ssids.size(); i++) {
ssids_attr.AddAttribute(NL80211Attr>(i, ssids[i]));
}
NL80211NestedAttr freqs_attr(NL80211_ATTR_SCAN_FREQUENCIES);
for (size_t i = 0; i < freqs.size(); i++) {
freqs_attr.AddAttribute(NL80211Attr(i, freqs[i]));
}
trigger_scan.AddAttribute(if_index_attr);
trigger_scan.AddAttribute(ssids_attr);
// An absence of NL80211_ATTR_SCAN_FREQUENCIES attribue informs kernel to
// scan all supported frequencies.
if (!freqs.empty()) {
trigger_scan.AddAttribute(freqs_attr);
}
if (request_random_mac) {
trigger_scan.AddAttribute(
NL80211Attr(NL80211_ATTR_SCAN_FLAGS,
NL80211_SCAN_FLAG_RANDOM_ADDR));
}
// We are receiving an ERROR/ACK message instead of the actual
// scan results here, so it is OK to expect a timely response because
// kernel is supposed to send the ERROR/ACK back before the scan starts.
vector> response;
if (!netlink_manager_->SendMessageAndGetAckOrError(trigger_scan,
error_code)) {
// Logging is done inside |SendMessageAndGetAckOrError|.
return false;
}
if (*error_code != 0) {
LOG(ERROR) << "NL80211_CMD_TRIGGER_SCAN failed: " << strerror(*error_code);
return false;
}
return true;
}
这边的方法已经不是很懂了,看起来是下发一个trigger_scan的命令,下面的逻辑只和命令下发有关,具体操作最终只看packet这个参数了。
搜了下
NetlinkManager: 接收来自kernel的3种UEVENT消息,并通过command listener转发给Java层的NetworkManagementService
什么鬼,我们是下发,可不是上报呀。。。这里先牵强附会的觉得是将命令下发到kernel吧=-=
bool NetlinkManager::SendMessageAndGetAckOrError(const NL80211Packet& packet,
int* error_code) {
unique_ptr response;
if (!SendMessageAndGetSingleResponseOrError(packet, &response)) {
return false;
}
uint16_t type = response->GetMessageType();
if (type != NLMSG_ERROR) {
LOG(ERROR) << "Receive unexpected message type :" << type;
return false;
}
*error_code = response->GetErrorCode();
return true;
}
bool NetlinkManager::SendMessageAndGetSingleResponseOrError(
const NL80211Packet& packet,
unique_ptr* response) {
vector> response_vec;
if (!SendMessageAndGetResponses(packet, &response_vec)) {
return false;
}
if (response_vec.size() != 1) {
LOG(ERROR) << "Unexpected response size: " << response_vec.size();
return false;
}
*response = std::move(response_vec[0]);
return true;
}
bool NetlinkManager::SendMessageAndGetResponses(
const NL80211Packet& packet,
vector>* response) {
if (!SendMessageInternal(packet, sync_netlink_fd_.get())) {
return false;
}
// Polling netlink socket, waiting for GetFamily reply.
struct pollfd netlink_output;
memset(&netlink_output, 0, sizeof(netlink_output));
netlink_output.fd = sync_netlink_fd_.get();
netlink_output.events = POLLIN;
uint32_t sequence = packet.GetMessageSequence();
int time_remaining = kMaximumNetlinkMessageWaitMilliSeconds;
// Multipart messages may come with seperated datagrams, ending with a
// NLMSG_DONE message.
// ReceivePacketAndRunHandler() will remove the handler after receiving a
// NLMSG_DONE message.
message_handlers_[sequence] = std::bind(AppendPacket, response, _1);
while (time_remaining > 0 &&
message_handlers_.find(sequence) != message_handlers_.end()) {
nsecs_t interval = systemTime(SYSTEM_TIME_MONOTONIC);
int poll_return = poll(&netlink_output,
1,
time_remaining);
if (poll_return == 0) {
LOG(ERROR) << "Failed to poll netlink fd: time out ";
message_handlers_.erase(sequence);
return false;
} else if (poll_return == -1) {
LOG(ERROR) << "Failed to poll netlink fd: " << strerror(errno);
message_handlers_.erase(sequence);
return false;
}
ReceivePacketAndRunHandler(sync_netlink_fd_.get());
interval = systemTime(SYSTEM_TIME_MONOTONIC) - interval;
time_remaining -= static_cast(ns2ms(interval));
}
if (time_remaining <= 0) {
LOG(ERROR) << "Timeout waiting for netlink reply messages";
message_handlers_.erase(sequence);
return false;
}
return true;
}
bool NetlinkManager::SendMessageInternal(const NL80211Packet& packet, int fd) {
const vector& data = packet.GetConstData();
ssize_t bytes_sent =
TEMP_FAILURE_RETRY(send(fd, data.data(), data.size(), 0));
if (bytes_sent == -1) {
LOG(ERROR) << "Failed to send netlink message: " << strerror(errno);
return false;
}
return true;
}
这次WiFi扫描的梳理艰难地到达了C++,这块具体怎么称呼也不清楚,梳理的地方回头看起来有不少牵强附会的地方,可以确定的是C++和java直接是可以通过aidl-cpp完成服务端和客户端交互的,WiFi的搜索命令也通过该机制下发到C++层继续实现。下阶段目标:重新复习下C++。。。