Linux Wireless netlink socket & nl80211

1.netlink socket可用于用户空间与内核间的通信,获取内核中的信息
2.用户的rssi数据实际上是由nl80211实现的,最终追溯到cfg80211和mac80211
3.关于nl80211:
wext(Wireless Extensions)和nl80211接口是Linux中的无线驱动接口标准,wext为旧的无线驱动框架,基于ioctl机制
Linux Wireless netlink socket & nl80211
Linux Wireless netlink socket & nl80211

- cfg80211: 用于对无线设备进行配置管理。与FullMAC, mac80211和nl80211一起工作。(Kernel态)
- mac80211: 是一个driver开发者可用于为SoftMAC无线设备写驱动的框架 (Kernel态),它是一个driver开发者可用于为SoftMAC无线设备写驱动的框架,mac80211为SoftMAC设备实现了cfg80211回调函数,且mac80211通过cfg80211实现了向网络子系统注册和配置。配置由cfg80211通过nl80211和wext实现。
SoftMAC:其MLME由软件实现,mac80211为SoftMAC实现提供了一个API。 即:SoftMAC设备允许对硬件执行更好地控制,允许用软件实现对802.11的帧管理,包括解析和产生802.11无线帧。目前大多数802.11设备为SoftMAC,而FullMAC设备较少。
4.nl80211.h
- nl80211.h是一个头文件,也是用户空间调用内核wifi相关功能的接口。其中定义了所有暴露给用户空间的API函数**索引**,以及这些函数采用的参数的格式和定义。用户通过netlink机制,将这些API函数索引和对应的参数封装到netlink的帧中,发送给内核,内核解析netlink帧后,读取帧中的内容,就知道用户需要调用哪个函数,以及该函数的参数,完成内核功能调用。
- 大致流程:
       nl_socket_alloc();                                                                            //生成netlink的socket(netlink相关内容参考上文给出的介绍)

       nl_socket_set_buffer_size(state->nl_sock, 8192, 8192);                //调整缓存大小

       genl_connect(state->nl_sock)                                                         //socket和内核连接(注意,这里用的genl的函数封装,具体可查参考(上文给出的地址))

       genl_ctrl_resolve(state->nl_sock, "nl80211");                                 //genl的概念,向内核查询一下协议族的标志

       msg = nlmsg_alloc();                                                                       //生成要发送往内核的帧(还没有填充内容)

       cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);  //生成回调函数,回调函数相关,见第一篇netlink的文档

       genlmsg_put(msg, 0, 0, state->nl80211_id, 0,                                 //往刚生成的帧中填充头部信息
   cmd->nl_msg_flags, cmd->cmd, 0);

       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);              //向刚生成的帧内部添加一个属性值

       nl_socket_set_cb(state->nl_sock, s_cb);                                         //设置回调函数

       nl_send_auto_complete(state->nl_sock, msg);                               //发送刚生成的帧给内核。自此,内核当收到该请求时就会执行在帧中填充的命令索引和参数。比如搜索无线网,帧中就会填充scan命令对应的索引和要扫描的信道作为参数。

while (err > 0)
       nl_recvmsgs(state->nl_sock, cb);                                                     //等待接收内核的反馈