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线路或其他的联网线路,则又被称为“热点 ...
随机推荐
- prometheus-dashboard-to-grafana
https://prometheus.io/docs/visualization/grafana/ https://www.digitalocean.com/community/tutorials/h ...
- [Windows Azure] Building worker role A (email scheduler) for the Windows Azure Email Service application - 4 of 5.
Building worker role A (email scheduler) for the Windows Azure Email Service application - 4 of 5. T ...
- FFmpeg Basics学习笔记(1)ffmpeg基础
1 FFmpeg的由来 FFmpeg缩写中,FF指的是Fast Forward,mpeg是 Moving Pictures Experts Group的缩写.官网:ffmpeg.org 编译好的可执行 ...
- CentOS 6.5 yum安装mysql5.6或其他版本【默认yum只能安装mysql 5.1】 by jason
by jason [备份配置文件] CentOS 6.5 默认yum只能安装mysql 5.1 安装前要检查机器原来是否安装过mysql,如有安装需要先进行数据备份.清理. [root@snails ...
- LeetCode: Pascal's Triangle II 解题报告
Pascal's Triangle II Total Accepted: 19384 Total Submissions: 63446 My Submissions Question Solution ...
- LeetCode: Palindrome Partitioning 解题报告
Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...
- 练习1 Just Java
任务:做这样一个界面,选择数量,自动计算价格.超级简单.. <?xml version="1.0" encoding="utf-8"?> <a ...
- MySQL5.7 利用keepalived来实现mysql双主高可用方案的详细过程
Reference: http://blog.csdn.net/mchdba/article/details/51377989 服务器准备 Keepalived:192.168.13.15 Keep ...
- C#正则表达式提取HTML中IMG标签的SRC地址
一般来说一个 HTML 文档有很多标签,比如“<html>”.“<body>”.“<table>”等,想把文档中的 img 标签提取出来并不是一件容易的事.由于 i ...
- JAVA-数据库之JDBC连接MySQL数据库
相关资料:<21天学通Java Web开发> JDBC连接MySQL数据库1.如果需要通过JDBC来连接MySQL数据库,还必须先在MySQL数据库服务器中创建数据库和表. Connect ...