ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

WiFi信道状态信息采集:Intel 5300 CSI Tool搭建实战

WiFi信道状态信息采集:Intel 5300 CSI Tool搭建实战 1. 项目概览为什么要折腾Intel 5300的CSI Tool如果你不是做无线感知方向的研究第一次听到“WiFi信道状态信息”和“CSI Tool”这两个词大概率是懵的。简单点说WiFi信号在空气中传播时经过墙壁、人体、家具这些障碍物会发生反射、散射和衰减接收端收到的信号已经包含了所有这些“环境痕迹”。而信道状态信息Channel State InformationCSI就是把这些痕迹以子载波级别的复数形式一条条记录下来。相比传统RSSI只能给一个粗粒度信号强度CSI能精细到OFDM每个子载波的幅度和相位所以这两年在人体行为识别、姿态估计、老人跌倒检测、室内定位这些方向上是实实在在的“硬通货”。我最初接触CSI Tool是读书时做人体动作识别课题导师直接甩给我一块Intel 5300网卡扔下一句“把环境搭起来”。当时网上资料少官方Wiki写得又简略我前前后后踩了两周的坑才把这套环境完全跑通。现在回头再看这套工具的原理和安装路径其实已经很清晰了只是缺少一篇把关键步骤和坑都讲透的文章。这篇博文就基于我当时的实操经验完整梳理基于Intel 5300的CSI Tool的安装与使用过程第一篇先讲到数据采集通后续再展开深入的数据处理和项目实战。先说结论适合正在准备做WiFi感知实验、人体行为识别、室内定位等相关课题的研究生和工程师也适合想做无线信号分析的技术极客。内容偏实操原理部分我会用通俗的方式讲清楚保证你跟着步骤走能一次跑通。2. 整体技术链路这套工具到底是怎么工作的2.1 CSI的获取原理与方案选型要拿到CSI数据业界主流有三条路用Intel 5300网卡跑CSI Tool、用Atheros网卡跑Atheros CSI Tool、以及在博通网卡上用Nexmon固件提取。三选一我为什么最终锁定Intel 5300核心原因是这套方案最成熟社区资料多而且工具链完整。Atheros方案需要自己打固件补丁配置复杂度高出一个量级Nexmon方案虽然支持较新网卡和5GHz频段但安装分支很多文档又散。Intel 5300配合CSI Tool是最多人走过的路踩坑成本最低。CSI Tool能提取CSI的原理是在Linux的iwlwifi无线驱动这一层做了改动。正常驱动收到一个802.11n数据帧之后把帧交给协议栈就完事了但打了补丁的驱动会在帧经过的时候额外把物理层PHY测量出来的信道频率响应复制一份连同接收信号的RSSI、AGC增益、噪声等元数据一起打包通过netlink套接字发送到用户态。用户态这边跑一个接收程序如log_to_file、recvCSI就能把这些数据落盘。整个过程可以类比成快递分拣普通驱动只负责把包裹数据帧送进门协议栈CSI Tool则是在进门的同时给包裹的“运输路径状况”拍了一张X光片。这张X光片就是CSI。2.2 数据形态与关键参数Intel 5300的CSI Tool工作频段是2.4GHz支持20MHz和40MHz两种带宽模式。在20MHz模式下OFDM会把信道划分成56个子载波但5300这套方案并非全部提取而是从中选30个“有代表性”的子载波输出。每根天线对应一组30个复数值每个复数8字节实部虚部各4字节数据包里还会附带时间戳、帧控制字段、RSSI等信息。如果网卡接了3根天线一组CSI就是3×3090个复数。这些复数里的幅度信息反映信号经过多条路径叠加后的强弱变化相位信息则记录不同路径的时延差异。一个典型的CSI数据包结构大致是4字节时间戳、8字节TSF时间、2字节长度、2字节RSSI、1字节AGC、1字节速率、1字节信道带宽然后是若干字节的CSI矩阵主体。这个格式一定要记牢后面用Matlab或Python解析时全靠它。2.3 为什么很多新手卡在安装这一步CSI Tool的安装过程不像普通软件那样“./configure make make install”三连就完事。它需要你重新编译一个打过补丁的Linux内核再替换掉系统中的iwlwifi驱动模块同时改掉Intel无线网卡的微码ucode。这三个操作任何一个版本不匹配都会导致环境起不来。而且它官方推荐的还是Ubuntu 14.04/16.04那个年代的版本和内核现在新版的Ubuntu直接用大概率编译报错或者模块加载失败。所以你在动手之前心里要有个整体概念这个环境的关键链路是“内核驱动固件用户态工具”四件套。不是让你全从零写代码而是把这四样东西按照官方Wiki的版本组合重新拼装一遍。只要版本匹配安装时间可以控制在半天以内。3. 硬件选型与系统环境准备最容易被忽略的一步3.1 网卡选择不是所有Intel 5300都能用这里的“Intel 5300”全称是Intel WiFi Link 5300属于802.11n时代的老网卡Mini PCIe接口。买的时候不要只看名字一定要看网卡的天线接口数量。CSI Tool要提取完整的MIMO信道信息最好是3根天线这样能看到3×30的子载波矩阵信息量最大。2根天线的版本也能用但数据维度少部分实验做不了。买卡之前强烈建议你用lspci -nn命令查一下硬件ID确认设备型号是8086:4235Intel 5300的PCI设备ID。这个步骤别省我见过有人买回来一张代号看着像但其实设备ID完全不同的卡折腾半天驱动不认白浪费时间。3.2 系统版本选择为什么老系统反而是最优解CSI Tool官方仓库github.com/dhalperi/linux-80211n-csitool里推荐的搭配是Ubuntu 14.04.2搭配内核3.16.0以及Ubuntu 16.04搭配内核4.4.0。我自己测试下来Ubuntu 14.04.2加3.16.0内核组合最稳。很多初学者不理解为什么不能用Ubuntu 22.04或者内核6.x因为CSITool补丁是基于老内核的driver写的新内核的iwlwifi驱动代码经过了大量重构补丁根本打不上。强行打补丁会报conflict甚至编译出无法启动的内核。老系统虽然界面丑、软件源旧但它就是CSI环境的温床——稳定得一批。如果你机器上已经装了新版Ubuntu建议直接用VirtualBox建一个14.04虚拟机来搞磁盘分配40GB以上内存4GB起步。采集数据时虚拟机连USB网卡透传的兼容性问题其实不大实测数据质量与物理机无明显差异。3.3 编译环境与依赖检查清单安装内核和模块编译工具之前先把基础环境装全避免编译到一半发现缺东西。你的虚拟机里需要准备sudo apt-get update sudo apt-get install -y gcc make build-essential linux-headers-$(uname -r) git iw其中linux-headers用于编译内核模块iw用于无线设备配置。还有一个非常容易漏的地方编译内核需要安装libncurses5-dev和libssl-dev前者是make menuconfig要用的后者是内核编译时生成签名所需的。sudo apt-get install -y libncurses5-dev libssl-dev注意Ubuntu 16.04的软件源里可能没有libncurses5-dev需要装libncurses-dev。装完之后再检查一下磁盘空间内核编译东西多最好预留20GB以上别等编译到一半磁盘满了直接报废。4. 内核替换与驱动补丁的完整实操记录4.1 下载源码并给内核打补丁环境准备好之后第一步是下载CSITool仓库以及仓库里引用的内核源码补丁。这里有个小技巧仓库内的下载脚本会帮你拉取对应版本的内核源码但考虑到下载速度和网络环境你也可以去kernel.org直接下载3.16.0的内核压缩包放到home目录下解压tar -xvf linux-3.16.0.tar.xz cd linux-3.16.0接下来拉取CSITool代码并打补丁git clone https://github.com/dhalperi/linux-80211n-csitool.git cd linux-3.16.0 patch -p1 ../linux-80211n-csitool/patches/kernel.patch这里如果提示patch找不到先安装sudo apt-get install -y patch4.2 编译并安装内核打补丁之后用仓库里附带的config文件生成内核配置。这一步建议直接用CSI Tool作者推荐的配置避免手动去menuconfig里一个个勾选项cp ../linux-80211n-csitool/patches/config-3.16.0 .config make -j4make -j4是指用4个CPU核心并行编译如果你虚拟机分配的CPU核心多可以-j8甚至-j12。编译核心和模块大约需要20到40分钟取决于机器性能。中间如果出现类似“No rule to make target”的错误大概率是patch没打上或者config版本不匹配回头检查一下。编译完成后依次安装sudo make modules_install sudo make install这里有一个坑make install会自动更新GRUB引导项把新内核追加为默认启动项同时保留旧内核。为了防止新内核引导失败后进不了系统建议手动检查一下/boot/grub/grub.cfg里默认启动项的序号必要时用GRUB_DEFAULT改成旧内核序号。等你确认CSI Tool环境正常了再切默认。4.3 替换iwlwifi驱动模块并加载固件内核编译好之后下一步是替换无线驱动。CSI Tool仓库里有一份修改过的iwlwifi驱动需要单独编译成一个模块然后替换系统的同名模块。先进入仓库的驱动目录cd ../linux-80211n-csitool/drivers/net/wireless/iwlwifi make -j4 sudo make install完成后系统里会多出一个iwlwifi.ko模块。这个模块默认放在额外的lib目录下为了保险把它拷贝到系统标准模块目录sudo cp iwlwifi.ko /lib/modules/3.16.0/kernel/drivers/net/wireless/intel/iwlwifi/ sudo depmod -a接下来处理固件。Intel 5300的无线网卡在驱动加载之前需要刷入微码ucodeCSI Tool需要的是一个特定版本、允许上报所有子载波信息的固件。仓库里给了两个固件版本分别是5000和5150系列我们把对应的固件拷贝到/lib/firmwarecd ../linux-80211n-csitool sudo cp linux-firmware/iwlwifi-5000-*.ucode /lib/firmware/这里建议先把系统原有的iwlwifi-5000-*.ucode备份一下sudo mv /lib/firmware/iwlwifi-5000-2.ucode /lib/firmware/iwlwifi-5000-2.ucode.bak4.4 设置驱动的CSI调试开关CSI数据默认是不输出的需要给iwlwifi驱动传一个debug参数开启CSI采集功能。这个参数叫debug0x14000。最简单的设置方法是新建一个modprobe配置文件echo options iwlwifi debug0x14000 | sudo tee /etc/modprobe.d/iwlwifi.conf注意这里有个细节如果这个参数不生效CSI数据会被驱动过滤掉用户态程序收到的是全是0的假数据。所以到时候要重点检查dmesg里有没有包含iwlwifi字样并且能看到CSI debug日志的输出。设好之后重启进入新内核sudo reboot重启后执行uname -r确认当前内核是3.16.0。然后加载驱动看看sudo modprobe iwlwifi dmesg | grep iwlwifi如果看到类似“iwlwifi 0000:03:00.0: Detected Intel Wireless WiFi Link 5300”的输出驱动加载就成功了。5. 数据采集全流程从Monitor模式到CSI文件落盘5.1 建立Monitor模式并配置信道驱动加载成功后先关机状态把天线插好然后开机。WiFi网卡通常默认是managed模式也就是连接路由器用的模式。CSI采集需要网卡处于monitor模式这样才能抓空中的无关帧来观察信道。确认网卡接口名一般是wlan0或者eth1。用iw dev查看一下iw dev找到物理接口后比如phy0创建一个monitor模式的虚拟接口sudo iw dev wlan0 interface add mon0 type monitor sudo ip link set mon0 up如果提示“command failed: Device or resource busy”说明网卡被网络管理工具占用了。先停掉NetworkManager或者直接sudo rfkill unblock wifi再试。接下来把网卡固定到一个信道。CSI Tool用的是20MHz带宽默认会落在2.4GHz频段的某个信道上。你可以固定到家里比较干净的信道比如6sudo iw dev mon0 set channel 6 HT20如果你想扫描整个2.4GHz频段的CSI变化可以后续写脚本循环切信道这里先固定信道验证数据链路是否通畅。5.2 使用官方接收程序采集数据CSI Tool仓库里自带了一个用户态接收程序源码在linux-80211n-csitool-supplementary里需要单独编译。这个工具可以从netlink socket读取驱动发过来的CSI数据并写到一个二进制文件里。下载并编译git clone https://github.com/dhalperi/linux-80211n-csitool-supplementary.git cd linux-80211n-csitool-supplementary make编译完后log_to_file这个可执行文件就是我们的主力工具。开启数据记录sudo ./log_to_file /tmp/csi_data.dat程序会进入一个实时打印模式持续输出收到的CSI数据行直到你用CtrlC停止。这个时候整个环境的接收链路已经完全打通了。对新手来说看到屏幕上不断滚动的数据行就说明CSI数据从网卡到驱动到用户态整个管道work了。5.3 用ping制造流量验证数据实时性如果看不到数据别急着怀疑环境坏了大概率是当前信道没有无线帧经过。CSI采集本质上是被动监听必须要有报文在空中流动才会触发测量。最简单的验证方法是另开一个终端ping一下路由器或者任意局域网内设备ping -i 0.1 192.168.1.1-i 0.1表示每0.1秒发一个ICMP报文。因为monitor模式下网卡能捕捉到这些帧CSI数据就会跟着报文的节奏刷出来。这个技巧我每次调试都在用比什么花里胡哨的测试脚本都直接。如果你要做的实验需要主动发送数据包CSI Tool还支持用packet injection模式发自定义帧这里先不展开。5.4 用Matlab/Octave解析采集的数据数据落盘后怎么把它变成能分析的CSI矩阵CSI Tool官方提供了Matlab脚本在linux-80211n-csitool-supplementary/matlab目录下。把采集文件和脚本放到同一目录Matlab里执行csi_trace read_bf_file(csi_data.dat); csi_entry csi_trace{1}; csi get_scaled_csi(csi_entry);csi是一个维度为天线数×子载波数×空间流的复数矩阵。比如3根天线、30个子载波、1个空间流csi就是3×30×1。画个幅度图plot(abs(squeeze(csi).));看到幅度随子载波变化的曲线就说明你已经拿到了完整的CSI。如果你想在Python里处理也可以用struct按之前说的数据格式逐字节解析但首推Matlab脚本省事且验证过。6. 常见问题与排查技巧实录CSI Tool的安装和调试坑是真的多。我把自己和身边同学踩过的坑汇总了一下整理成速查表现象可能原因解决方法patch命令报错补丁基线不匹配确认内核版本是3.16.0且还没有打过补丁编译内核时报错缺少头文件依赖包不全安装linux-headers、libssl-dev、libncurses-dev系统重启后进不了桌面内核启动参数有问题GRUB里选旧内核启动确认新内核能起来再切默认modprobe iwlwifi找不到模块模块未正确安装手动拷贝iwlwifi.ko到标准目录并depmod -admesg提示固件加载失败ucode版本不对或缺失检查/lib/firmware/iwlwifi-5000-*.ucode是否存在monitor模式创建失败网卡被网络管理占用停掉NetworkManager或rfkill unblock wifilog_to_file无输出信道太安静另开终端ping制造流量CSI数据大量为0debug参数未生效检查/etc/modprobe.d/iwlwifi.conf的debug0x14000重启后CSI数据仍为0固件版本太新被驱动过滤替换成仓库自带的iwwlwifi-5000固件除了表格里这些问题我还有一个切身经验要分享CSI数据文件建议分段保存比如每30秒一个小文件别一个文件录几个小时。后面处理数据时你会感谢自己这么做的因为一个巨大的二进制文件在Matlab里加载非常慢而且中途程序崩了以前的全部数据就废了。另外刚才没忍住还是想说一句多根天线的角度和间距对CSI幅度和相位影响非常大。如果你后续做基于CSI的定位实验天线之间的距离最好不要小于半个波长2.4GHz大约是6.25厘米否则天线间的信道相关性太高空间分集效果会大打折扣。这是硬件层面最容易被忽视的坑。我个人实际使用中的习惯是每次采集前固定把网卡的天线朝向和摆放位置拍照存档同时采集一段空房间的数据作为基准。后面分析时减去这个基准能把静态路径的干扰很大程度抑制掉。这个习惯帮我少走了很多弯路也强烈建议你从第一次采集就养成。环境搭通只是第一步后续的数据清洗、动态路径提取、特征构建才是更花时间的地方我们下一篇再接着聊。
返回列表