Android 8 wifi blakclist
在连接wifi的时候,认证或者关联失败,有时会加入黑名单中。记录wpa_supplicant中blacklist的原理。
分析可以看到,如果是机器自己断开,是不会把AP加入黑名单的,只有AP侧出了问题,才有可能加入黑名单。
首先看一下blacklist的结构体。
external\wpa_supplicant_8\wpa_supplicant\blacklist.h
struct wpa_blacklist {
struct wpa_blacklist *next;
u8 bssid[ETH_ALEN];
int count;
};
external\wpa_supplicant_8\wpa_supplicant\blacklist.c
/**
* wpa_blacklist_get - Get the blacklist entry for a BSSID
* @wpa_s: Pointer to wpa_supplicant data
* @bssid: BSSID
* Returns: Matching blacklist entry for the BSSID or %NULL if not found
*/
struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
const u8 *bssid)
{
struct wpa_blacklist *e;
if (wpa_s == NULL || bssid == NULL)
return NULL;
e = wpa_s->blacklist;
while (e) {
if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0)
return e;
e = e->next;
}
return NULL;
}
/**
* wpa_blacklist_add - Add an BSSID to the blacklist
* @wpa_s: Pointer to wpa_supplicant data
* @bssid: BSSID to be added to the blacklist
* Returns: Current blacklist count on success, -1 on failure
*
* This function adds the specified BSSID to the blacklist or increases the
* blacklist count if the BSSID was already listed. It should be called when
* an association attempt fails either due to the selected BSS rejecting
* association or due to timeout.
*
* This blacklist is used to force %wpa_supplicant to go through all available
* BSSes before retrying to associate with an BSS that rejected or timed out
* association. It does not prevent the listed BSS from being used; it only
* changes the order in which they are tried.
*/
int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_blacklist *e;
if (wpa_s == NULL || bssid == NULL)
return -1;
e = wpa_blacklist_get(wpa_s, bssid);
if (e) { // 如果blacklist中已经存在这个ssid,,count++
e->count++;
wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count "
"incremented to %d",
MAC2STR(bssid), e->count);
return e->count;
}
// 不存在就添加到blacklist链表中
e = os_zalloc(sizeof(*e));
if (e == NULL)
return -1;
// 这个插入方式应该是从链表头插入
os_memcpy(e->bssid, bssid, ETH_ALEN);
e->count = 1;
e->next = wpa_s->blacklist;
wpa_s->blacklist = e;
wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist",
MAC2STR(bssid));
return e->count;
}
/**
* wpa_blacklist_del - Remove an BSSID from the blacklist
* @wpa_s: Pointer to wpa_supplicant data
* @bssid: BSSID to be removed from the blacklist
* Returns: 0 on success, -1 on failure
*/
int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_blacklist *e, *prev = NULL;
if (wpa_s == NULL || bssid == NULL)
return -1;
e = wpa_s->blacklist;
while (e) {
if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) {
if (prev == NULL) {
wpa_s->blacklist = e->next;
} else {
prev->next = e->next;
}
wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
"blacklist", MAC2STR(bssid));
os_free(e);
return 0;
}
prev = e;
e = e->next;
}
return -1;
}
/**
* wpa_blacklist_clear - Clear the blacklist of all entries
* @wpa_s: Pointer to wpa_supplicant data
*/
void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
{
struct wpa_blacklist *e, *prev;
int max_count = 0;
e = wpa_s->blacklist;
wpa_s->blacklist = NULL;
while (e) {
// 获取count的最大值
if (e->count > max_count)
max_count = e->count;
prev = e;
e = e->next;
wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
"blacklist (clear)", MAC2STR(prev->bssid));
os_free(prev);
}
// 临时的计数,判断删除最后一条blacklist是否有失败。
wpa_s->extra_blacklist_count += max_count;
}
wpa_supplicant.c
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
int timeout;
int count;
int *freqs = NULL;
wpas_connect_work_done(wpa_s);
/*
* Remove possible authentication timeout since the connection failed.
*/
eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
// 如果断开连接是机器自己产生的,就不会把AP加入到blacklist中,直接返回。
/*
* There is no point in blacklisting the AP if this event is
* generated based on local request to disconnect.
*/
if (wpa_s->own_disconnect_req) {
wpa_s->own_disconnect_req = 0;
wpa_dbg(wpa_s, MSG_DEBUG,
"Ignore connection failure due to local request to disconnect");
return;
}
if (wpa_s->disconnected) {
wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
"indication since interface has been put into "
"disconnected state");
return;
}
// 将BSSID加入blacklist中,加速扫描其他可以连接并且关联过的AP。
// 并且对这个BSSID的扫描间隔增加延时,避免连续多次扫描。
/*
* Add the failed BSSID into the blacklist and speed up next scan
* attempt if there could be other APs that could accept association.
* The current blacklist count indicates how many times we have tried
* connecting to this AP and multiple attempts mean that other APs are
* either not available or has already been tried, so that we can start
* increasing the delay here to avoid constant scanning.
*/
// 加入黑名单,并获取在黑名单的计数
count = wpa_blacklist_add(wpa_s, bssid);
if (count == 1 && wpa_s->current_bss) {
//这个BSS以前没有在blacklist中,如果在同一个ESS中有另外的BSS,
// 那么另外一个BSS我们也要进行尝试
// 并且在这之前,对这个BSS进行在进行一个尝试,不过还不行,count再加一。
/*
* This BSS was not in the blacklist before. If there is
* another BSS available for the same ESS, we should try that
* next. Otherwise, we may as well try this one once more
* before allowing other, likely worse, ESSes to be considered.
*/
freqs = get_bss_freqs_in_ess(wpa_s);
if (freqs) {
wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
"has been seen; try it next");
wpa_blacklist_add(wpa_s, bssid);
/*
* On the next scan, go through only the known channels
* used in this ESS based on previous scans to speed up
* common load balancing use case.
*/
os_free(wpa_s->next_scan_freqs);
wpa_s->next_scan_freqs = freqs;
}
}
/*
* Add previous failure count in case the temporary blacklist was
* cleared due to no other BSSes being available.
*/
count += wpa_s->extra_blacklist_count;
// count大于3,直接设置认证失败。
if (count > 3 && wpa_s->current_ssid) {
wpa_printf(MSG_DEBUG, "Continuous association failures - "
"consider temporary network disabling");
wpas_auth_failed(wpa_s, "CONN_FAILED");
}
switch (count) {
case 1:
timeout = 100;
break;
case 2:
timeout = 500;
break;
case 3:
timeout = 1000;
break;
case 4:
timeout = 5000;
break;
default:
timeout = 10000;
break;
}
wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
"ms", count, timeout);
// 进行下一次扫描,后面两个参数是扫描的时间
/*
* TODO: if more than one possible AP is available in scan results,
* could try the other ones before requesting a new scan.
*/
// 例如timeout=10000, 那么再次扫描的时间10000/1000+1000*(10000%1000) = 10s
wpa_supplicant_req_scan(wpa_s, timeout / 1000,
1000 * (timeout % 1000));
}
Android 8 wifi blakclist的更多相关文章
- 【Android】wifi开发
WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为“热点 ...
- android.net.wifi的简单使用方法
获取Wifi的控制类WifiManager. WifiManager wm=(WifiManager)getSystemService(Context.WIFI_SERVICE); 接下来可以对w ...
- android开发 wifi开发工具类
import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Iterator; import j ...
- Android打开WIFI或者移动网络的代码实现
MainActivity如下: package wy.testnetwork; import java.lang.reflect.Field; import java.lang.reflect.Inv ...
- 【移动开发】Android中WIFI开发总结(二)
搞了好几天终于有点眉目了,这里接着总结一下Android中WiFi的使用,在前面(http://smallwoniu.blog.51cto.com/3911954/1334951)我们已经简单了解了W ...
- 【移动开发】Android中WIFI开发总结(一)
WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为“热 ...
- Android 连接Wifi和创建Wifi热点 demo
android的热点功能不可见,用了反射的技术搞定之外. Eclipse设置语言为utf-8才能查看中文注释 上代码: MainActivity.java package com.widget.hot ...
- Android的WiFi开启与关闭
注意:要首先注册开启和关闭WiFi的权限, <?xml version="1.0" encoding="utf-8"?> <manifest ...
- android之wifi开发
WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为“热点 ...
随机推荐
- Shell脚本判断内容为None的方式
1.判断变量 read -p "input a word :" word if [ ! -n "$word" ] ;then echo "you ha ...
- 如何使用ILSpy 把发布版本反编译成源码
有时候,看法别人写的代码比较好,想看看他们的代码到底是如何写的,于是就找方法,看看能否把发布版本变成源码.后来终于发现一个词“反编译”,我终于知道怎么办了. 工具:ILSpy 百度下载一个,该工具 ...
- (原创)C++11改进我们的程序之右值引用
本次主要讲c++11中的右值引用,后面还会讲到右值引用如何结合std::move优化我们的程序. c++11增加了一个新的类型,称作右值引用(R-value reference),标记为T & ...
- 【Spring】Spring Session的简单搭建与源码阅读
搭建一个简单的Spring Session例子 引入依赖包 <dependencies> <dependency> <groupId>org.springframe ...
- 分享几个免费IP地址查询API接口
几个免费IP地址查询API接口 1.IP地址查询接口:http://apis.juhe.cn/ip/ip2addr要先去https://www.juhe.cn/docs/api/...申请APPKEY ...
- docker 错误:Error response from daemon: cannot stop container: connect: connection refused": unknown
docker 错误:Error response from daemon: cannot stop container: 795e4102b2de: Cannot kill container 795 ...
- signal函数的原型声明void (*signal(int signo, void (*fun(int))))(int)分析
转:http://blog.sina.com.cn/s/blog_4850a7880100hnam.html void (*signal(int signo, void (*fun(int))))(i ...
- 三者互ping,PC,虚拟机,uboot,nfs网络文件系统搭建
要想实现三者互ping,韦老师虽然专门出了视频说明,但是在自己配置过程还是出现了问题,这里记录一下解决办法,虽然我也不知道原因,但是解决了出现的问题也实现了三者互ping. 首先,我的硬件设备是PC通 ...
- html页面去掉滚动条
有时候特别需要,个别网页要去掉横向滚动条和竖向滚动条,那该怎么去掉呢,很简单,看代码: 让竖条没有: <body style=`overflow:-Scroll;overflow-y:hidde ...
- wamp安装xdebug特殊情况win7 64位安装32位wamp
在wamp上安装xdebug网上很多文章都介绍了方法,但是我这里遇到了一个很特殊的情况,在网上很少有人提及: 我机器是win7 64位的,安装的wamp1.7.4是32位的,这是后来导致出现奇怪现象的 ...