版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/h784707460/article/details/79788344,未经博主允许不得转载。
基于用户需求、功耗优化等,Softap功能常常会在原生Android基础上做一些定制,比如:STA的接入/断开通知;获取当前接入的STA个数和列表;softap的休眠机制等。这些定制都离不开一个基础,就是Android softap中STA接入断开的消息传递机制。掌握了消息传递机制,这些定制只是在该机制中加入一些边边角角,so easy~
我们从softap的管理核心SoftApManager开始看分析,然后分别分析向上层的消息传递,下层上来的通知等。
1. Softap管理核心SoftApManager.java
private static class InterfaceEventHandler extends IInterfaceEventCallback.Stub
public void OnSoftApClientEvent(byte[] mac_address, boolean connect_status)
// 监听到底层有sta连接状态变化,送Softap状态机处理
mSoftApStateMachine.sendMessage(SoftApStateMachine.CMD_SOFTAP_CLIENT_CONNECT_STATUS_CHANGED, connect_status ? 1 : 0, 0, msg.obj);
Softap状态机只有两种状态:IdleState,StartedState
// startedState中对改消息进行处理,消息发送到上层WifiSoftApNotificationMAnager处理。
private class StartedState extends State
case CMD_SOFTAP_CLIENT_CONNECT_STATUS_CHANGED:
mWifiSoftApNotificationManager.connectionStatusChange(message);
2. 上层消息处理WifiSoftApNotificationManager.java
public void connectionStatusChange(Message message)
interfaceMessageRecevied((String) message.obj,isConnected);
//这里可以实现一些对用户的通知,界面更新等,更新接入列表和个数等softap扩展特性
private void interfaceMessageRecevied(String message , boolean isConnected)
// if softap extension feature not enabled, do nothing
3. SoftApManager是如何知道sta接入状态变化的呢?--wificond
3.1 Android aidl通信方式
system/connectivity/wificond/aidl/android/net/wifi/IInterfaceEventCallback.aidl
//aidl interface call to send sta mac and status to framework
oneway void OnSoftApClientEvent(in byte[] client_mac_addr, boolean connect_status);
3.2 wificond server广播接入断开消息
system/connectivity/wificond/server.cpp
void Server::BroadcastSoftApClientConnectStatus(const vector<uint8_t>& mac_address, bool connect_status)
for (auto& it : interface_event_callbacks_)
it->OnSoftApClientEvent(mac_address, connect_status);
3.3 收到NEW_STATION/DEL_STATION消息后,处理接入个数统计及向上发送广播消息
system/connectivity/wificond/ap_interface_impl.cpp
void ApInterfaceImpl::OnStationEvent(StationEvent event, const vector<uint8_t>& mac_address)
if (event == NEW_STATION) {
number_of_associated_stations_++;
client_conn_status = true;
} else if (event == DEL_STATION) {
number_of_associated_stations_--;
}
server_->BroadcastSoftApClientConnectStatus(mac_address, client_conn_status);
3.4 wificond根据收到底层的NL80211_CMD_NEW_STATION/ NL80211_CMD_DEL_STATION消息,向上发NEW_STATION/DEL_STATION消息。
wificond/net/netlink_manager.h
typedef std::function<void(
StationEvent event,
const std::vector<uint8_t>& mac_address)> OnStationEventHandler;
std::map<uint32_t, OnStationEventHandler> on_station_event_handler_;
/wificond/net/netlink_manager.cpp
void NetlinkManager::BroadcastHandler(unique_ptr<const NL80211Packet> packet)
const auto handler = on_station_event_handler_.find(if_index);
if (command == NL80211_CMD_NEW_STATION) {
handler->second(NEW_STATION, mac_address);
} else {
if (command == NL80211_CMD_DEL_STATION) {
handler->second(DEL_STATION, mac_address);}
}
在向下就是WifiHAL、kernel 802.11协议了。
定制修改一般在settings、以及framework。比如1>在settings界面实现一些对用户的通知,界面更新等,比如通过toast、弹框等通知用户有设备接入或断开;2>在settings界面实现展示接入个数和列表,接入个数可以通过该接口获取:IApInterface.getNumberOfAssociatedStations();3>Softap的休眠机制,可以通过Android定时任务Timer、AlarmManager等调用WiFiMAnager.stopSoftAp()来实现softap的定时关闭。等等。