wificond 启动hostapd,wpa_supplicant以及扫描
1、main启动创建各种实例
NetlinkManager::Start()
bool NetlinkManager::Start() {
if (started_) {
LOG(DEBUG) << "NetlinkManager is already started";
return true;
}
bool setup_rt = SetupSocket(&sync_netlink_fd_);//创建同步socket
if (!setup_rt) {
LOG(ERROR) << "Failed to setup synchronous netlink socket";
return false;
}
setup_rt = SetupSocket(&async_netlink_fd_);//创建异步socket
if (!setup_rt) {
LOG(ERROR) << "Failed to setup asynchronous netlink socket";
return false;
}
// Request family id for nl80211 messages.
if (!DiscoverFamilyId()) {
return false;
}
// Watch socket.
if (!WatchSocket(&async_netlink_fd_)) {//监听socket
return false;
}
// Subscribe kernel NL80211 broadcast of regulatory changes.
if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_REG)) {
return false;
}
// Subscribe kernel NL80211 broadcast of scanning events.
if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_SCAN)) {
return false;
}
// Subscribe kernel NL80211 broadcast of MLME events.
if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_MLME)) {
return false;
}
started_ = true;
return true;
}
SetupSocket: 创建一个socket并bind一个地址
bool NetlinkManager::SetupSocket(unique_fd* netlink_fd) {
struct sockaddr_nl nladdr;
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
netlink_fd->reset(
socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_GENERIC));
if (netlink_fd->get() < 0) {
LOG(ERROR) << "Failed to create netlink socket: " << strerror(errno);
return false;
}
// Set maximum receive buffer size.
// Datagram which is larger than this size will be discarded.
if (setsockopt(netlink_fd->get(),
SOL_SOCKET,
SO_RCVBUFFORCE,
&kReceiveBufferSize,
sizeof(kReceiveBufferSize)) < 0) {
LOG(ERROR) << "Failed to set uevent socket SO_RCVBUFFORCE option: " << strerror(errno);
return false;
}
if (bind(netlink_fd->get(),
reinterpret_cast<struct sockaddr*>(&nladdr),
sizeof(nladdr)) < 0) {
LOG(ERROR) << "Failed to bind netlink socket: " << strerror(errno);
return false;
}
return true;
}
2 service与wificond交互类图
wificond进程 主要管理三大功能:启动关闭wpa_supplicant, 启动关闭hostapd, 向驱动发起扫描并获取扫描信息。
1、在WifiService(java进程):中通过IWificond.Stub.asInterface(binder)获取wificond的客户端binder对象
2、wificond进程:编译IWifiCond AIDL文件,生成服务的的BnBinder. 服务端的Service类继承BnWificond类
实现服务端的binder通信。
3、wificond进程通过socket和系统属性的propertys 与驱动交互 (比如enableSupplicant)
3、wificond内部交互类图
对应的类:SupplicantManager strat或者stop supplicant。
HostapdManager start或者stop hostapd。
NetlinkManager:通过socket向驱动n80211发送消息并接受驱动回复的状态数据。
4、enableSupplicant时序
5、扫描类交互图