WiMax
内核中有一个rfkill子系统,使用这个可以关闭任何一个射频收发器。Linux中倾向于通用架构子系统,各个设备其实都是实现这个子系统规定的函数。这些子系统向上就提供操作同类函数的完整接口。这就是类似于面向对象编程的Interface概念。
Wifi
PHY层
版本概要:
802.11-2007是目前的基础版本,之前的过时版本不考虑。
2009是较新的版本,就是目前最普及的802.11n。(100Mb/s)
2012就是传说中的802.11ac,工作在5G,速度牛逼哄哄的,但穿透力不咋的。
各种PHY总览:
2007里给出了5种PHY,也就是5种编码与调制方法,每种PHY对应的PHY帧格式都是不同的。也就是说,虽然这个wifi标准对外的接口(MAC)是一样的,但是根据底层采用的不同PHY,底层的从帧格式到编码、调制都是不一样的。5种PHY分别是:直序扩频(DSSS)、跳频扩频(FHSS)、正交频分复用(OFDM)、高速率直序扩频(HR/DSSS)、红外(TR)。另外,还给出一个叫ERP的增强版本的PHY,改变了调制方法,增强了DSSS和OFDM的速率。
2009里又多了一种:高吞吐(HT OFDM),就是在原来的OFDM基础上改进得来。
最新的802.11ac里又多了一种:超高吞吐(VHT OFDM),还是改进OFDM得来。
两个改进的OFDM都支持MIMO,就是多天线。这玩意能提高不少速率,原理略过。
各PHY分别介绍:
FHSS和DSSS属于扩频通信,就是把原来在较小带宽传送的信号用较大的带宽来传送。为什么要这样浪费带宽呢?窄带容易被干扰,把窄带信号分布到大带宽上就不易被干扰了。真的浪费带宽吗?同样的带宽能传输的数据速度还不一定谁快呢。
FHSS就是在一系列窄频上同步跳跃;DSSS就是将相对大功率的窄频信号扩展到相对低功率的宽带信号。 两种扩频方式各有优劣,FHSS在移动性上更好,DSSS在静止速度上更快。所以,速度为主要考虑因素,会选择DSSS,移动性为主要考虑因素,会选用FHSS。目前,wifi上用户需求最大的是速度,所以DSSS发展较好。
HR/DSSS是增强版的DSSS,原理很简单,只是改变了编码方式,和缩减了帧头部长度。从而增加了速度。
ERP也是那么回事,通过对DSSS、OFDM编码的改进提高速度。
OFDM是一种很神奇的技术。能提高频谱利用率,简单的说就是调制和复用的结合,提高信道吞吐。
而2009里说的HT OFDM就是增加一些MIMO(多天线)相关技术。用多根天线来增加速率。
而802.11ac里说的VHT OFDM就是更高的带宽,更多OFDM子载波。技术上没有本质的变化,都是OFDM+MIMO的不断增强。
PHY整体对外接口:
PHY的上层是MAC,各个版本的PHY需要向MAC提供统一的调用接口,就是原语。原语包括以下几类:
1、基本特性。包括:MIB管理(PLME-GET、PLME-SET)、复位(PLME-RESET)、特性参数查询(PLME-CHARACTERISTICS)、DSSS进入测试模式(PLME-DSSSTESTMODE)、发送时间估计(PLME-TXTIME)
2、数据首发。包括:数据传输(PHY-DATA)、发送控制(PHY-TXSTART、PHY-TXEND)、信道空闲检测(PHY-CCARESET、PHY-CCA)、接收控制(PHY-RXSTART、PHY-RXEND)
PHY内部结构:
最下层叫PMD(物理介质依赖),与实际的物理介质打交道
中间层叫PLCP(物理层聚合),把MAC层传下来要发送的数据变成对应的实际物理层PHY要发送的数据(经过调制和编码,肯定和MAC层原来的不同了),送给PMD
最上层叫PHY SAP,就是上段定义的对MAC的服务接口。是MAC可以直接调用的稳定接口,不论具体的PHY是什么,这些接口都是可用的,而且只可以调用这些接口。
说白了,SAP就是通过PLCP将各个不同的物理介质PMD以统一的接口对外展现。
当然,结构中还包括一个信息库MIB,存储属性参数。
MAC层
MAC层是802.11的主要功能部分。上层应用通过调用MAC层提供的接口原语调用MAC层的功能。
MAC一共向上提供了2大类接口原语,共30种。数据(1)和管理(29)。数据部分就是提供普通数据包的收发接口,管理部分是主要功能部分,例如发起认证、连接、信道扫描等其它所有管理功能,如下表所示:(并非所有的原语都是可调用的,一部分是indication形式的向上通知。有request的是可以调用的())
数据部分 数据 MA-UNITDATA 管理部分 电源管理 MLME-POWERMGT 信道扫描 MLME-SCAN 时间同步 MLME-JOIN 认证 MLME-AUTHENTICATE 断开认证 MLME-DEAUTHENTICATE 建立连接 MLME-ASSOCIATE 重新连接 MLME-REASSOCIATE 断开连接 MLME-DISASSOCIATE 复位 MLME-RESET 网络开始 MLME-START 测量 MLME-MREQUEST 信道测量 MLME-MEASURE 测量报告 MLME-MREPORT 信道切换 MLME-CHANNELSWITCH 发送功率通知 MLME-TPCADAPT 设置密钥 MLME-SETKEYS 删除密钥 MLME-DELETEKEYS 迈克尔失败事件 MLME-MICHAELMICFAILURE 可扩展局域网认证协议帧 MLME-EAPOL 点对点连接请求 MLME-PeerKeySTART 设置发送或接收的安全保护 MLME-SETPROTECTION 帧密钥错误丢弃通知 MLME-PROTECTEDFRAMEDROPPED 交通流(TS)管理接口 MLME-ADDTS
MLME-DELTS直接连接管理 MLME-DLS
MLME-DLSTearDown高层同步支持 MLME-HL-SYNC 合并ACK帧管理 MLME-ADDBA
MLME-DELBAQos调度变更通知 MLME-SCHEDULE 发行商特有 MLME-VSPECIFIC MIB管理 MLME-SET
MLME-GET
以上的所有的原语构成了MAC对外提供的可操作接口。
在内部,MAC由除了函数还有数据,叫MIB,存储MAC的各种参数。还有个专业术语叫SME的,其实是一个单独的模块,用来跟接口函数功能互动,完成各函数之间的关联操作和配合响应。属于配合接口正常运作的角色,对外不提供接口。
以上的接口原语,按照功能模块,可以归纳出MAC主要包括如下功能:
1、信道管理。包括:信道扫描(MLME-SCAN)、信道测量(MLME-MREQUEST、MLME-MEASURE、MLME-MREPORT)、信道切换(MLME-CHANNELSWITCH)
2、连接管理。包括:认证(MLME-AUTHENTICATE)、断开认证(MLME-DEAUTHENTICATE)、建立连接(MLME-ASSOCIATE)、重新连接(MLME-REASSOCIATE)、断开连接(MLME-DEASSOCIATE)、开始网络(MLME-START)、点对点连接请求(MLME-PeerKeySTART)、直接连接管理(MLME-DLS、MLME-DLSTearDown)、
3、服务质量(Qos):交通流(TS)管理接口(MLME-ADDTS、MLME-DELTS)、Qos调度变更通知(MLME-SCHEDULE)、
4、功率控制。包括:电源管理(MLME-POWERMGT)、发送功率通知(MLME-TPCADAPT)
5、安全。包括:密钥管理(MLME-SETKEYS、MLME-DELETEKEYS)、迈克尔失败事件(MLME-MICHAELMICFAILURE)、EAPOL(MLME-EAPOL)、帧密钥错误丢弃通知(MLME-PROTECTEDFRAMEDROPPED)
6、时间同步。包括:时间同步(MLME-JOIN)、高层同步支持(MLME-HL-SYNC)、
7、特性。包括:合并ACK帧管理(MLME-ADDBA、MLME-DELBA)、发行商特有(MLME-VSPECIFIC)、MIB管理(MLME-SET、MLME-GET)
信道接入方式
信道接入看起来是PHY的活,但是这是一个算法,不是一个操作,所以是MAC的活,信道接入的几种方式就属于MAC层的功能了。
wi-fi的信道接入模式包括两种:CSMA/CA、节点协调模式。在无Qos的情况下,两种原生态的就可以了。在有Qos下,在两种的基础上分别定义了优先级来实现Qos传输。
CSMA/CA就是传说中的载波监听冲突检测,最基本的无线接入方式。IEEE 的无线标准大都以这种接入为基本方法,就是监听信道,没有正在传输的就传,有就随机退避一段时间再监听信道。标准给了它一个很蛋疼的名字:DCF(Distributed Coordination Function),意思是协调是分布的,大家平等来商量谁接入网络。
节点协调模式:无线路由器安排特定的节点在特定的时间通信,从而造成无阻塞的信道。这种方式采用的帧发送间隔比DCF小,从而保证在DCF和本模式同时存在的网络,本模式具有较高的接入优先级。标准给了它另外一个蛋疼的名字:PCF(Poing Coordination Function),意思是由某一个节点来“协调”谁接入网络,这个节点就是AP啦。
在有Qos的情况下,DCF变成了EDCA,PCF变成了HCCA。别管这些破名字,起这名字的目的我估么着就是让大家迷糊的,就是代号就是了。意思就是为了实现Qos的的帧差别对待,给定义了优先级。
Linux下Wifi编程
写用户空间程序时,现在官方推荐的唯一编程方式就是基于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); //等待接收内核的反馈