目录

一,iw应用层

二,cfg80211层

三,mac80211层

四,无线驱动层


本章以指令:iw dev wlan0 scan为例,带你走进iw层,cfg80211层,mac80211cfg,驱动层细节流程。

一,iw应用层

1,其实是两条命令
分析scan.c文件,跟踪TOPLEVEL(scan, "[-u] xx", 0, 0, CIB_NETDEV, handle_scan_combined, "xxx");
从handle_scan_combined()函数可知,最终运行下面两条指令。

iw dev wlan0 scan trigger
对应的netlink消息:NL80211_CMD_TRIGGER_SCANiw dev wlan0 scan dump
对应的netlink消息:NL80211_CMD_GET_SCAN

二,cfg80211层

1,netlink接收到 NL80211_CMD_TRIGGER_SCAN,执行下面函数

static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
{//调用mac80211注册的cfg80211_ops对应的函数.scanrdev_scan(rdev, request);-->ret = rdev->ops->scan(&rdev->wiphy, request);  //mac80211实现//构造netlink消息,回复给iwnl80211_send_scan_start(rdev, wdev);-->nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);-->nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,NL80211_CMD_TRIGGER_SCAN) < 0)-->nl80211hdr_put(msg, portid, seq, flags, cmd);-->nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);-->nl80211_add_scan_req(msg, rdev);-->genlmsg_end(msg, hdr);--genlmsg_multicast_netns()
}

2,netlink接收到 NL80211_CMD_GET_SCAN,执行下面函数

static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
{nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);cfg80211_bss_expire(rdev);list_for_each_entry(scan, &rdev->bss_list, list) {nl80211_send_bss(skb, cb,cb->nlh->nlmsg_seq, NLM_F_MULTI,rdev, wdev, scan); //从bss段中取出数据}
}

三,mac80211层

1,从cfg80211层中,可知调用的是.scan函数

const struct cfg80211_ops mac80211_config_ops = {.add_virtual_intf = ieee80211_add_iface,.del_virtual_intf = ieee80211_del_iface,.....scan = ieee80211_scan,.abort_scan = ieee80211_abort_scan,....
};static int ieee80211_scan(struct wiphy *wiphy,struct cfg80211_scan_request *req)
{ieee80211_request_scan(sdata, req);-->__ieee80211_start_scan(sdata, req);//软件扫描方式--->ieee80211_start_sw_scan(local, sdata);  ---->drv_sw_scan_start(local, sdata, local->scan_addr);------->local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr); //ath9k实现//延时调用ieee80211_scan_work,调用前需要初始化---->ieee80211_queue_delayed_work(&local->hw,&local->scan_work, 0);    //local->scan_work()的实现如下local->scan_work-->ieee80211_scan_work()--->__ieee80211_scan_completed()---->drv_sw_scan_complete()----->.sw_scan_complete//ath9k实现
}

2,延时调用ieee80211_scan_work()的初始化过程在ieee80211_alloc_hw_nm()函数

struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,const struct ieee80211_ops *ops,const char *requested_name)
{INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);  // 这里使用的是INIT_DELAYED_WORK()那么之后// 我们就会调用schedule_delayed_work(),这两是一对// 表示经过一段延时然后在执行某个函数。
}
EXPORT_SYMBOL(ieee80211_alloc_hw_nm);//以下是ieee80211_scan_work()的实现细节
void ieee80211_scan_work(struct work_struct *work)
{__ieee80211_scan_completed(&local->hw, aborted);
}static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
{drv_sw_scan_complete(local, scan_sdata);
}static inline void drv_sw_scan_complete(struct ieee80211_local *local,struct ieee80211_sub_if_data *sdata)
{local->ops->sw_scan_complete(&local->hw, &sdata->vif);
}void ieee80211_scan_work(struct work_struct *work)
{__ieee80211_scan_completed(&local->hw, aborted);
}static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
{drv_sw_scan_complete(local, scan_sdata);
}static inline void drv_sw_scan_complete(struct ieee80211_local *local,struct ieee80211_sub_if_data *sdata)
{local->ops->sw_scan_complete(&local->hw, &sdata->vif);
}

四,无线驱动层

1,从mac80211层可知,调用的是.sw_scan_start()和.sw_scan_complete()函数

struct ieee80211_ops ath9k_htc_ops = {.tx                 = ath9k_htc_tx,.start              = ath9k_htc_start,.stop               = ath9k_htc_stop,.add_interface      = ath9k_htc_add_interface,.....sw_scan_start      = ath9k_htc_sw_scan_start,.sw_scan_complete   = ath9k_htc_sw_scan_complete,....
};

欢迎订阅公众号【从零开始学无线】,一起学习交流!

wifi底层学习之路:四,iw指令剖析相关推荐

  1. wifi底层学习之路:二,无线配置管理服务cfg80211

    目录 1,什么是cfg80211?wiphy又是什么? 2,cfg80211工作流程是什么? 3,cfg80211如何通过netlink与iw进行交互? 4,cfg80211怎么与mac80211进行 ...

  2. wifi底层学习之路:三,Linux内核子系统mac80211

    1,mac80211是什么? mac80211是linux内核子系统,是驱动开发者可用于为softmac无线设备写驱动的框架.mac80211在内核空间实现STA模式.在用户空间实现AP模式. 2,m ...

  3. ESP8266 WIFI模块学习之路(2)——模块与单片机连接进行远程操作

    上一个博客:ESP8266 WIFI模块学习之路(1)是关于对串口连接的,简单验证ESP8266是怎么样连接及其功能验证,下面将通过单片机连接,和手机进行远程操作. ESP8266和单片机的连接,我这 ...

  4. Java多线程学习之路(四)---死锁(DeadLock)

    Java多线程学习之路(四)-死锁(DeadLock) 1.定义 死锁就是多个线程在竞争共享资源的时候,相互阻塞,不能脱身的状态(个人理解).其实死锁一定程度上可以看成一个死循环. 举个现实生活中的例 ...

  5. typescript学习之路(四) —— ts类的继承(包含es5以及es6的类继承)

    上一文已经写了es5,es6等类的定义,所以本章主要写es5和es6的继承,由于es6的继承和ts的继承如出一辙,只是加了类型定义而已,所以ts的继承稍微写下,不会太详细. 文章目录 es5继承 原型 ...

  6. ESP8266 WIFI模块学习之路(10)——手机远程关闭电脑

    在博文ESP8266 WIFI模块学习之路(9)中已经实现了电脑读出USB串口的数据,如图 在博文C语言实现电脑关机程序中学习了如何实现电脑关机及其它的一些功能. 因此,通过这两个博文完全可以实现手机 ...

  7. ESP8266 WIFI模块学习之路(7)——自写Android手机APP接受单片机数据

    上一篇是写关于自写Android手机APP给单片机下发数据的,这次我将写一下APP如何接受单片机数据. 其实使用调试助手,或者别人开的的APP同样能够实现接受单片机数据,但想学习的,我还是建议能够自己 ...

  8. android 8 esp8266,ESP8266 WIFI模块学习之路(8)——自写Android手机APP控制直流电机正反转...

    本次向通过Android远程控制直流电机正反转,在这之前可以看一下我写的"STC单片机简单控制直流电机正反转"有助刚学的同学理解. 可以看一下我的硬件连接电路,如图: 单片机硬件程 ...

  9. vue2 学习之路 常见的指令!

    文件夹 和 文件夹含义. 主要的文件及其含义? node_modules 下载的第三方包 安装目录 public/index.html  浏览器运行的网页 src/main.js webpack打包的 ...

最新文章

  1. MySQL 实战 定时备份数据库
  2. 深度学习概述:当你没有方向时的加油站
  3. php 对象赋值后改变成员变量影响赋值对象
  4. 动手学CV-目标检测入门教程4:模型结构
  5. Quartz的定时任务实现
  6. 微服务架构开发实战:如何实现微服务的自动扩展?
  7. TCL_事务控制语言
  8. PicoDet的学习笔记
  9. lnmp编译安装mysql_LNMP编译安装教程
  10. 三级等级保护之安全管理中心
  11. iOS模拟器找不到证书?
  12. Ensembl数据库简介
  13. C语言求21000内最大素数(20983)
  14. CUBA 7 新特性(上篇)
  15. 漫谈京东(一)——自营手机类商品数据分析
  16. PS|001制作1寸照片
  17. Big Faceless Java PDF Library[bfopdf]
  18. 月记 18.11.08
  19. 重学Mysql之Mysql8.0修改密码策略
  20. 硬件负载均衡和软件负载均衡

热门文章

  1. 《MLB棒球创造营》:走近棒球运动·奥克兰运动家队
  2. 小白求答疑,在vs连接数据库的一段配置代码有问题
  3. 把VOB格式转换成其它格式的工具
  4. 『强烈推荐2个网站』这才是Win10官方原版正确下载姿势
  5. 数据结构与算法-平衡二叉搜索树
  6. 流程图软件lauto_流程图软件(Iauto)
  7. Vscode中报错 CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
  8. 音乐手记之民谣一:Empyrium
  9. 从底特律的覆灭,反思“珠三角”未来
  10. 贸易融资实务:出口押汇与进口押汇