1 扫描方式

手机扫描结果的获取有两种方式:被动和主动
1,AP隔固定时间会发送Beacon帧,Beacon帧中有AP的SSID BSSID等基本信息,手机接收到Beacon帧就认为搜索到该AP创建的网络
2,手机主动发出probe request帧,AP接收到probe request帧后会发送probe response帧,手机接收到response帧后,就认为扫描到该网络。
在手机wlan界面中,点击刷新既采用的第二种方式(当然扫描结果中也会包含部分方式1中扫描到的网络)

2 扫描结果在wap_s中的存储

为了提高处理效率,驱动在接收到相关扫描结果时,是不会对帧中的信息进行解析的,80211管理帧的构成请查阅相关资料。帧传递到wpa_s时会经过强制类型转换成struct wpa_scan_res,帧头会转换成结构体总的元素,帧的载荷会作为ie(information element信息元素)存储在紧跟结构体后面的内存中,wpa_s中有专门方法获取ie域中的相关信息。

存储驱动上报的扫描结果的结构体

struct wpa_scan_res {unsigned int flags;         //BSS/IBSS标记u8 bssid[ETH_ALEN];int freq;u16 beacon_int;             //beacon间隔u16 caps;                   int qual;int noise;int level;u64 tsf;                    //时间戳//时间,单位ms,用于计算update time,unsigned int age;           //struct wpa_scan_results中存储的featch time减去age就是update timesize_t ie_len;size_t beacon_ie_len;
//紧跟的IE(information element)数据长度,例如ssid,p2p一类的//数据组成为type(4 u8),element长度(u8),element内容//在每个res结构体指针后(res+1)通过比对每个element的type类型获取
};

一个扫描结果被认为是一个bss网络,经初步解析后会转变为wpa_bss的结构体,该结构体的信息包含了一些ie中的信息,因此包含的信息更加的的详细。wpa_bss会存储在struct wpa_supplicant结构体的链表bss和bss_id中。

存储一个bss的结构体

struct wpa_bss {struct dl_list list;               //bssid的链表struct dl_list list_id;            //内部id的链表unsigned int id;                   //idunsigned int scan_miss_count;      //扫描结果中不包含该bss的次数unsigned int last_update_idx;      //上次扫描更新(不懂)unsigned int flags;                //标记BSS/IBSS (WPA_BSS_*)u8 bssid[ETH_ALEN];                //bssid,mac地址u8 hessid[ETH_ALEN];               //16进制ssid?u8 ssid[32];                       size_t ssid_len;                   //网络名,最长32个字符int freq;                          //网络信道u16 beacon_int;                    //beacon间隔,AP设置,一般为100ms/** Capability information field in host byte order */u16 caps;                          //Capability,AP设置int qual;                          //信号质量,怎么确定?int noise;                         //背景噪声int level;                         //信号强度 dbu64 tsf;                           //Timestamp of last Beacon/Probe Response frame */struct os_reltime last_update;     //上次由Beacon or Probe Response RX更新的时间struct wpa_bss_anqp *anqp;         //ANQP与安全相关size_t ie_len;                     //Probe Response中IE域的长度size_t beacon_ie_len;              //Beacon IE field
};

3 bss列表初始化

每隔10秒都会刷新一下struct wpa_supplicant中的bss列表

int wpa_bss_init(struct wpa_supplicant *wpa_s)
{//更新对应连的链表wpa_s->bss   wpa_s->bss_id//使用eloop_register_timeout注册超时函数,时间为10秒wpa_bss_timeout{//通过对比当前的时间与wpa_s bss链表中每个bss存储的时间//删除掉超过bss_expiration_age(默认值180)秒未更新(未扫描到)的bsswpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);//使用eloop_register_timeout注册超时函数wpa_bss_timeout,时间为10秒//这样每隔10秒都会调用wpa_bss_flush_by_age更新时间}
}

4 wpa_s->bss链表更新

接收到扫描结果时:更新bss按如下顺序调用

wpa_bss_update_start(wpa_s);
//每次只能更新一次扫描结果
wpa_bss_update_scan_res(wpa_s, scan_res->res[i], &scan_res->fetch_time);
wpa_bss_update_end(wpa_s, info, new_scan);

在end函数中会对wpas中的bss链表做一次更新,
如果当前bss正在使用 || 包含在扫描结果中,则不作处理
如果当前bss的更新次数(last_update_idx)< 整个bss链表的更新次数(last_update_idx),说明是首次没有扫描到,那么计数器+1
如果没有扫描的次数超过了 wpa_s->conf->bss_expiration_scan_count,该值一般为2,那么会从链表中删除该bss

void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, struct wpa_scan_res *res, struct os_reltime *fetch_time)
{//获取ie中存储的ssid,如果ssid长度大于32,直接returnu8* ssid = wpa_scan_get_ie(res, WLAN_EID_SSID);//获取p2p信息,如果ssid前缀为“DIRECT-”, 是P2P listen discovery results,直接return。p2p = wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE);//查询wpa_s中的bss列表是否有该bss,需要bssid和ssid全部一致bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]);//无,直接添加bss = wpa_bss_add(wpa_s, ssid + 2, ssid[1], res, fetch_time);//添加过程{//分配内存bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);//将ssid信息复制到bss中os_memcpy(bss->ssid, ssid, ssid_len);//将res后面的ie空间和beacon ie拷贝到bss后的内存os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);//从ie中获取hessidwpa_bss_set_hessid(bss);//将bss添加到wpa_s对应链表中中dl_list_add_tail(&wpa_s->bss, &bss->list);dl_list_add_tail(&wpa_s->bss_id, &bss->list_id);//向上发送bss添加的eventwpas_notify_bss_added(wpa_s, bss->bssid, bss->id);}//有,更新信息,主要更新信号值和后面的ie域bss = wpa_bss_update(wpa_s, bss, res, fetch_time);//将bss添加到wpa_s->last_scan_res中
}

5 获取扫描结果bss

wpa_s定义了多种方式获取bss链表中的元素,通过bssid匹配,ssid匹配,获取id等等(id的含义等再详细看看代码,目前还不清楚)

struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
通过bssid获取bssid结构体struct wpa_bss * wpa_bss_get_bssid_latest(struct wpa_supplicant *wpa_s, const u8 *bssid)
获取最后一次更新bss。获取钱会与wpa_s->bssid_filter比对,如果该bss包含在filter中,则返回NULL,该filter通过上层的SET命令设置。struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
通过P2P Device Addr 获取bss,P2P Device Addr存储处在bss指针后的ie域中。struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
通过identifier获取bssstruct wpa_bss * wpa_bss_get_id_range(struct wpa_supplicant *wpa_s, unsigned int idf, unsigned int idl)
给定id的最小值idf和最大值idl,获取这个范围的bss

当FMKS获取扫描结果时,就是获取的bss(wpa_s->bss)链表的元素。通常使用的命令有
‘SCAN_RESULTS’获取所有的扫描结果和“BSS RANGE=5- MASK=0x29d87”获取一部分id(>5)范围的扫描结果。

6 获取帧信息ie域

const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie)
通过ie的类型获取对应的iestruct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss, u32 vendor_type)
通过type获取ieconst u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type)
每一个vendor ie都有对应的type,通过每个type获取对应的ieconst u8 * wpa_bss_get_vendor_ie_beacon(const struct wpa_bss *bss, u32 vendor_type)
根据type从beacon ie域中获取信息struct wpabuf * wpa_bss_get_vendor_ie_multi_beacon(const struct wpa_bss *bss, u32 vendor_type)
获取beacon中的ie

7 其他方法

刷新:wpa_bss_flush(struct wpa_supplicant *wpa_s)除了wpa_s正在使用(连接,关联)的bss,删除掉wpa_s->bss所有的bss元素清除bss数据:wpa_bss_deinit(struct wpa_supplicant *wpa_s)去掉超时函数wpa_bss_timeout清除不在使用的bss  wpa_bss_flush。获取速率
int wpa_bss_get_max_rate(const struct wpa_bss *bss)
获取maximum legacy TX rate,存储在ie域中int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates)
获取支持速率的长度

Android wpa_supplicant源码分析--bss扫描结果相关推荐

  1. Android wpa_supplicant源码分析---nl80211内核通信Generic Netlink

    代码位置: kernel/net/netlink/genetlink.c kernel/include/net/genetlink.h GENL简介 netlink仅支持32种协议类型,这在实际应用中 ...

  2. Android wpa_supplicant源码分析--conf配置文件

    http://blog.csdn.net/cuijiyue/article/details/51428835 1 配置文件 conf文件作为wpa_supplicant的配置文件,一般叫做 wpa_s ...

  3. Android wpa_supplicant源码分析--启动之全局初始化

    1. wpa_supplicant简介 wpa_supplicant是用来用来支持无线中各种加密方式的,包括WEP.WPA/WPA2和WAPI(中国特有).EAP(8021x).wpa_s通过sock ...

  4. wpa_supplicant 源码分析 --conf 配置文件

    原文:wpa_supplicant源码分析--conf配置文件 | Winddoing's Notes 解析 wpa_supplicant 的配置文件,一般叫做 wpa_supplicant.conf ...

  5. Android HandlerThread 源码分析

    HandlerThread 简介: 我们知道Thread线程是一次性消费品,当Thread线程执行完一个耗时的任务之后,线程就会被自动销毁了.如果此时我们又有一 个耗时任务需要执行,我们不得不重新创建 ...

  6. Android ADB 源码分析(三)

    前言 之前分析的两篇文章 Android Adb 源码分析(一) 嵌入式Linux:Android root破解原理(二) 写完之后,都没有写到相关的实现代码,这篇文章写下ADB的通信流程的一些细节 ...

  7. 【Android SDM660源码分析】- 02 - UEFI XBL QcomChargerApp充电流程代码分析

    [Android SDM660源码分析]- 02 - UEFI XBL QcomChargerApp充电流程代码分析 一.加载 UEFI 默认应用程序 1.1 LaunchDefaultBDSApps ...

  8. 【Android SDM660源码分析】- 03 - UEFI XBL GraphicsOutput BMP图片显示流程

    [Android SDM660源码分析]- 03 - UEFI XBL GraphicsOutput BMP图片显示流程 1. GraphicsOutput.h 2. 显示驱动初化 DisplayDx ...

  9. 【Android SDM660源码分析】- 01 - 如何创建 UEFI XBL Protocol DXE_DRIVER 驱动及UEFI_APPLICATION 应用程序

    [Android SDM660源码分析]- 01 - 如何创建 UEFI XBL Protocol DXE_DRIVER 驱动及UEFI_APPLICATION 应用程序 一.创建DXE_DRIVER ...

最新文章

  1. 解决 Android 中出现依赖多个版本支持库的问题
  2. 如何定期备份网站数据
  3. Spring Roo 简介
  4. 如何在linux下通过ssh运行X图形软件
  5. [vue] 组件中写name选项有什么作用?
  6. 网游服务器端设计思考:心跳设计
  7. ngingx安装错误 ./configure: error: the HTTP rewrite module requires the PCRE library.
  8. 拿下 Gartner 容器产品第一,阿里云打赢云原生关键一战
  9. 刚发布!开发者调查报告:机器学习/深度学习算法工程师急缺
  10. 【转】UINavigationController 直接返回到第一级目录
  11. 数据结构与算法(三)-线性表之静态链表
  12. python map()
  13. CouchBase简单介绍
  14. 聊聊nacos server的PushService
  15. 双向可控硅晶片光耦(TLP160J TLP260J TLP525G)基本原理及应用实例
  16. 曹金明:Zynga大败局--数据控是如何把游戏做败的
  17. 电脑主板元件判断方法
  18. FPGA图像处理的仿真测试激励该如何写?
  19. 3-订单持续时间的计算
  20. 胡巴动态表情包 捉妖记胡巴QQ表情无水印下载

热门文章

  1. 梵蒂冈网站 DDoS 被匿名者攻击
  2. 搭建流媒体服务器,完成属于自己的直播服务
  3. Gstreamer 简介
  4. Parajumpers Gobi Royal Blue Ladies Winter down Coats
  5. 英伟达史上最大手笔!70亿美元拟收购Mellanox,全球芯片整合大潮拍岸
  6. mysqld: Too many arguments (first extra is 'start').
  7. Oanda外汇账户2013总结 - MT4平台
  8. 一、sql利用错位相减的方式得到相同利率下的连续时间的时间区间
  9. 扫码转账提示已停止访问该网页解决办法
  10. matlab函数wgn awgn用法整理,matlab函数wgn,awgn用法整理