nl80211实例

http://book.2cto.com/201405/43292.html

3.nl80211实例
2014-05-26 13:10:24      我来说两句 
收藏   我要投稿   
本书是经典畅销书深入理解Android系列的新作,由资深Android系统专家邓凡平先生撰写。从通信专业知识和Android系统代码实现的角度,对Netd、Wi-Fi、NFC和GPS等模块的代码进行深入的剖析,旨在深刻揭示其实现原理   立即去当当网订购

了解netlink和libnl之后,现在来看nl80211。简单来说,nl80211的核心就是通过netlink机制向Kernel中的无线网卡驱动发送特定的消息。只不过这些消息的类型、参数等都由nl80211.h定义。此处通过一个案例,学习如何通过nl80211触发网卡进行无线网络扫描。
[-->driver_nl80211.c::wpa_driver_nl80211_scan]
static int wpa_driver_nl80211_scan(void *priv,
           struct wpa_driver_scan_params *params)
{
    struct i802_bss *bss = priv;
    struct wpa_driver_nl80211_data *drv = bss->drv;
    int ret = -1, timeout;
    struct nl_msg *msg, *rates = NULL; // 定义两个nl_msg对象,rates和P2P有关,读者可忽略它

    drv->scan_for_auth = 0;
    // 创建nl80211消息,其中NL80211_CMD_TRIGGER_SCAN是Nl80211定义的命令,用于触发网络扫描
    msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params);
    ......// P2P 处理
    // 发送netlink消息
    ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    msg = NULL;
    if (ret)
        goto nla_put_failure;
    ......// wpa_supplicant其他处理
    ......// 错误处理
    return ret;
}

上面代码中构造无线网络扫描nl_msg的重要函数nl80211_scan_common代码如下所示。
[-->driver_nl80211.c::nl80211_scan_common]
static struct nl_msg * nl80211_scan_common
            (struct wpa_driver_nl80211_data *drv, u8 cmd,
            struct wpa_driver_scan_params *params)
{
    struct nl_msg *msg;
    int err;
    size_t i;
    // 分配一个nl_msg对象
    msg = nlmsg_alloc();
    /*
       调用nl80211_cmd函数填充nl_msg中的信息,其内部代码如下。
       static void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
              struct nl_msg *msg, int flags, uint8_t cmd){
             return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,0, flags, cmd, 0);
        }
    */
    nl80211_cmd(drv, msg, 0, cmd);
    /*
     nl80211消息的参数通过netlink中的nlattr来存储。NL80211_ATTR_IFINDEX代表
     此次操作所指定的网络设备编号。
    */
    nla_put_u32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);

    if (params->num_ssids) {
        struct nl_msg *ssids = nlmsg_alloc();
        for (i = 0; i < params->num_ssids; i++) {
         nla_put(ssids, i + 1, params->ssids[i].ssid_len,params->ssids[i].ssid);
         ......
       }
        // netlink支持消息嵌套,即属性中携带的数据可以是另外一个nl_msg消息
        err = nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
        nlmsg_free(ssids);
        ......
    }
     ......// 其他处理
    return msg;
    ......// 错误处理
}

由上面的例子可知,nl80211其实就是利用netlink机制将一些802.11相关的命令和参数发送给驱动去执行。这些命令和参数信息可通过nl80211头文件查询。

提示 本书后续章节将分析wpa_supplicant8,读者可参考external/wpa_supplicant8/wpa_supplicant/src/drivers/nl80211_copy.h。

首先,nl80211_copy.h定义其支持的命令,如下所示。
[-->nl80211_copy.h]
enum nl80211_commands {
    NL80211_CMD_UNSPEC,
    NL80211_CMD_GET_WIPHY,
    NL80211_CMD_SET_WIPHY,
    ......
    NL80211_CMD_GET_INTERFACE,   
    NL80211_CMD_SET_INTERFACE,
    ......
    NL80211_CMD_SET_BSS,
    NL80211_CMD_SET_REG,
    ......// 一共定义了94条命令
}

然后定义属性的取值,如下所示。
enum nl80211_attrs {
    NL80211_ATTR_UNSPEC,
    NL80211_ATTR_WIPHY,
    NL80211_ATTR_WIPHY_NAME,
    NL80211_ATTR_IFINDEX,
    NL80211_ATTR_IFNAME,
    NL80211_ATTR_IFTYPE,
    NL80211_ATTR_MAC,
    ......// 一共定义了155条属性
}

头文件中对命令、属性等信息的注释都非常详细。本节不赘述,请读者自行阅读该文件。

提示 相比wext而言,nl80211的使用难度明显要复杂,其中重要原因是它是基于netlink编程的。而且,如果没有libnl的支持,相信使用难度会更大。但从Wi-Fi角度来看,nl80211和wext到没有太大区别,二者都是紧紧围绕MAC层service来设计数据结构的。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值