linux下wifi编程(基于netlink和nl80211.h)

写用户空间程序时,现在官方推荐的唯一编程方式就是基于netlink的nl80211.h编程。

netlink是一种linux下的用户空间和内核空间通信的方式,传输的都是一个个的帧。用户空间程序通过生成预定义好的结构帧,与内核达到传递消息的目的。

nl80211.h是一个头文件,也是用户空间调用内核wifi相关功能的接口。其中定义了所有暴露给用户空间的API函数索引(不是函数本身),以及这些函数采用的参数的格式和定义。用户程序通过netlink机制,将这些API函数索引和对应的参数封装到netlink的帧中,发送给内核,内核解析netlink帧后,读取帧中的内容,就知道用户需要调用哪个函数,以及该函数的参数,完成内核功能调用。

说实话,这么折腾还不如直接调用API。。。。鬼让人家定义了这个唯一框架,就这么样吧。。。。。

先主要说一下netlink:

有人已经写的很详细了:http://www.carisma.slowglass.com/~tgr/libnl/doc/core.html#core_cb

这里面没有提到调用nl80211.h用到的libnl-genl。这是libnl的一个高层扩展,就是说libnl也可以直接完成这个库的功能。由于libnl的帧种类越来越多,所以就有必要给这些帧种类分类,所以出现了好多个protocol family。。。为了能统一不同的协议族,定义了libnl-genl这么个通用接口。其实代码量很小,只是小小封装了一下。由于iw(linux下的wifi配置程序)用的这个库,所以有必要提一下。

libgl的使用流程方法见源文件:http://harmattan-dev.nokia.com/docs/platform-api-reference/xml/daily-docs/libnl-doc/genl_8c_source.html

netlink各个模块的函数和结构体参考见:http://harmattan-dev.nokia.com/docs/platform-api-reference/xml/daily-docs/libnl-doc/modules.html

再说一下nl80211.h的使用:

不得不说,此部分的文档烂的出奇,或者说是根本没有文档。作为给出的唯一接口,你的文档仅限于代码注释,你好意思嚒。。。。

http://lwn.net/Articles/211209/这里有个2006年的文档,已经过时,但是可以略知一二。看看没坏处。

想要两节nl80211.h的调用方法,推荐看一下iw的源代码。

大体流程如下:(只是逻辑关系,从iw源代码中抽取)

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); //等待接收内核的反馈

我走得很慢!但我从不后退!

linux下wifi编程(基于netlink和nl80211.h)

相关文章:

你感兴趣的文章:

标签云: