Android热点连接管理(二)

来源:互联网 发布:下载 wp config.php 编辑:程序博客网 时间:2024/06/08 03:31

      接着上一篇一开始提出的问题,如何获取没有连接成功的客户端信息,主要指MAC地址,其他的信息未必拿得到。

WifiDevice类是指望不上了,因为它只代表连接成功的客户端。

     不过从前面的分析可以看出来,连接成功的客户端信息,全部来自于hostapd发送的消息中携带了我们所需的信息。

找找消息是从哪发来的?ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta, int authorized)

中发送的。

   

<pre name="code" class="java">         if (authorized) {wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s", buf);if (hapd->msg_ctx_parent &&    hapd->msg_ctx_parent != hapd->msg_ctx)wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,  AP_STA_CONNECTED "%s", buf);sta->flags |= WLAN_STA_AUTHORIZED;} else {wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);if (hapd->msg_ctx_parent &&    hapd->msg_ctx_parent != hapd->msg_ctx)wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,  AP_STA_DISCONNECTED "%s", buf);sta->flags &= ~WLAN_STA_AUTHORIZED;}

就这个里,什么时候发送connect和disconnect已经很清楚了,不过这里是连接成功的,连接失败的走不到这里,看看这段代码的上面。
        if (!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED))            return;
这个双非,真让人头晕有木有,不过意思就是判断当前这个sta有没有通过鉴权。没有通过的,就一律return,不让往后面走了。我们可以
在这个给那些没有通过鉴权的sta放放水,把消息传递下去吧。这块修改的办法很多,我这里给sta_info这个结构体增加了一个成员report_flags.
    struct sta_info {struct sta_info *next; /* next entry in sta list */struct sta_info *hnext; /* next entry in hash table list */u8 addr[6];u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */u32 flags; /* Bitfield of WLAN_STA_* */u16 capability;u16 listen_interval; /* or beacon_int for APs */u8 supported_rates[WLAN_SUPP_RATES_MAX];int supported_rates_len;u8 qosinfo; /* Valid when WLAN_STA_WMM is set */                     ........        u32 session_timeout; /* valid only if session_timeout_set == 1 */        u32 report_flags;    /**/     };
增加这个flag后,在以上的函数中增加一个新的消息:"AP-STA-REPORT"
    if(!(sta->flags & WLAN_STA_AUTHORIZED)&& !sta->report_flags){        wpa_printf(MSG_DEBUG, "report hal there is a sta associate");os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr));wpa_msg(hapd->msg_ctx, MSG_INFO, "AP-STA-REPORT " "%s", buf);sta->report_flags = 1;    }    if(!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED)){return;    }
如果此sta是没有通过鉴权的,先发送一个report消息给上层,然后就该干啥干啥,很简单。至于上层对于消息的处理,
就仿照其他消息一样处理了。一路消息都是透传的,么有什么处理,一直到Tethering.java中的interfaceMessageRecevied(String message)。
    public void interfaceMessageRecevied(String message) {        // if softap extension feature not enabled, do nothing        if (!mContext.getResources().getBoolean(com.android.internal.R.bool.config_softap_extention)) {            return;        }        if (DBG) Log.d(TAG, "interfaceMessageRecevied: message=" + message);        try {            WifiDevice device = new WifiDevice(message);          ......
message是在WifiDevice中分解的,先在WifiDevice中修改一下吧:
   
 public WifiDevice(String dataString) throws IllegalArgumentException {        String[] tokens = dataString.split(" ");        if (tokens.length < 2) {            throw new IllegalArgumentException();        }        if (tokens[0].indexOf(AP_STA_CONNECTED_STR) != -1) {            deviceState = CONNECTED;        } else if (tokens[0].indexOf(AP_STA_DISCONNECTED_STR) != -1) {            deviceState = DISCONNECTED;        }else if (tokens[0].indexOf(AP_STA_REPORT_STR) != -1) {            deviceState = BLACKLISTED;        } else {            throw new IllegalArgumentException();        }        deviceAddress = tokens[1];    }

     把携带“AP_STA_REPORT_STR”字段消息的device定义为BLACKLISTED,这个是本来类中定义的,但是没有用到,我暂用一下,

其实自己定义一个其他的更好。interfaceMessageRecevied()中再增加一个判断,将所有blacklist的设备存储到新定义的一个hashMap中。

     }else if(device.deviceState == WifiDevice.BLACKLISTED) {

          Log.d(TAG, "@@@@ put device to asscoation MAP,mac= " + device.deviceAddress);

          mAssocDeviceMap.put(device.deviceAddress, device);

   }

新增一个接口public List<WifiDevice> getTetherAsscoationStaAddr() ,用于查询关联过改热点,但是没有连接成功的sta。

    public List<WifiDevice> getTetherAsscoationStaAddr() {        Iterator it;         List<WifiDevice> TetherAsscoationStaList = new ArrayList<WifiDevice>();         if (mContext.getResources().getBoolean(com.android.internal.R.bool.config_softap_extention)) {            it = mAssocDeviceMap.keySet().iterator();            while(it.hasNext()) {                String key = (String)it.next();                WifiDevice device = (WifiDevice)mAssocDeviceMap.get(key);                               Log.d(TAG, "getTetherAsscoationStaAddr: addr=" + key + " name=" + device.deviceName);                TetherAsscoationStaList.add(device);            }        }        return TetherAsscoationStaList;    }
当然,如果是供上层调用,ConnectivityManager和ConnectivitySevic以及IConnectivityManager.aidl中都要同步增加接口。





0 0
原创粉丝点击