参考网上教程,断断续续弄了很长时间,终于实现了用intel 5300网卡在monitor模式下进行长时间的收发包,特留此贴记录,后续的数据标注等问题等做到再更新,如有问题敬请指正。
文章目录
-
- 硬件准备
- Ubuntu 安装
- CSI tool 安装
- 收发包
- 数据处理
一、硬件准备
1.主板为Centerm J1800迷你主机(双核双线程,性能不足,建议换J1900的四核四线程)。
2.网卡为半高的Intel 5300,连接外置天线
二、Ubuntu 安装(版本14.04.1)
1.下载Ubuntu 14.04.1的镜像文件(iso)
在网址:http://old-releases.ubuntu.com/releases/14.04.2/ubuntu-14.04.1-desktop-amd64.iso中下载如图所示的Ubuntu 14.0.1的镜像文件(iso)
2.下载UltralSO 制作系统U盘
软件网址:最新UltraISO官方免费下载 - UltraISO软碟通中文官方网站,安装完后进入软件:“文件-打开”选中下载的Ubuntu系统,等待加载完毕,“启动-写入磁盘映像”,点击写入(写入会格式化U盘),等待3-5分钟即可,刻录完如图。
3.安装Ubuntu
将制刻录好的U盘插入我们的主机中,启动主机,在显示器亮起时按F12,使用光标上下键,到第二个Install Ubuntu。
启动完进入Welcome界面,下滑选择语言中文简体,之后一直点继续即可,直到“安装类型”页面,选择“其他选项“”,点击继续,进行磁盘分区。
分区完成后进行Ubuntu安装,安装完后完善用户信息重启即可。
三、CSI TOOL 安装
这部分参考了这位博主的教程:
Linux CSI Tool 完整使用说明(一发一收,monitor模式)(权威版 已成功测试)_csitool-CSDN博客
1.安装依赖,顺序执行:
sudo apt-get update
sudo apt-get -y install git-core kernel-package fakeroot build-essential ncurses-dev
sudo apt-get -y install libnl-dev libssl-dev
sudo apt-get -y install iw
2.下载并编译内核,添加启动时的内核选项
使用U盘拷贝下载好的精简版内核到主板上,下载地址为:https://download.csdn.net/download/u014645508/10579514,之后顺序执行:
tar -xvf /home/intel-5300-csi-github-master.tar.gz # 解压内核
cd intel-5300-csi-github
make oldconfig # 一直回车即可
make menuconfig # 在弹出的窗口中选择Save,然后OK,再选Exit
make -j4 # 编译内核,J1800大概需要4-5h
sudo make install modules_install # 安装kernel module,大约15分钟
sudo make install # 忽略出现的报错,下一步会解决
sudo make install modules_install # 再次安装
sudo mkinitramfs -o /boot/initrd.img-`cat include/config/kernel.release` `cat include/config/kernel.release`
make headers_install
sudo mkdir /usr/src/linux-headers-`cat include/config/kernel.release`
sudo cp -rf usr/include /usr/src/linux-headers-`cat include/config/kernel.release`/include
cd /etc/default
sudo gedit grub # 在弹出的窗口中,找到下面一行:GRUB_HIDDEN_TIMEOUT=0,并在前面添加#,保存
sudo update-grub # 更新grub
重启系统,在启动时的 “*Ubuntu高级选项”中选择版本为4.2.0的内核,回车(后来发现这个版本的Ubuntu其实开机时不操作也会默认选择4.2.0的内核),开机后能正常使用WiFi进行联网就成功了。
3.替换固件(需联网)
git clone https://github.com/dhalperi/linux-80211n-csitool-supplementary.git
# 失败的话在github.com前加上:gitclone.com/
for file in /lib/firmware/iwlwifi-5000-*.ucode; do sudo mv $file $file.orig; done
sudo cp linux-80211n-csitool-supplementary/firmware/iwlwifi-5000-2.ucode.sigcomm2010 /lib/firmware/
sudo ln -s iwlwifi-5000-2.ucode.sigcomm2010 /lib/firmware/iwlwifi-5000-2.ucode
四、收发包
Monitor模式,即两台装有intel 5300网卡的设备进行发包与收包,按下面流程操作一遍后,后续收数只需先在接收端执行步骤2中第(6)步操作进入待收包状态,然后在发送端运行发包脚本也就是步骤3中的(5)。
收不到包的话,可以尝试接外置天线,使用本文的setup_monitor_csi.sh脚本与setup_inject.sh脚本,或降低发包频率。
按下面流程操作后收发包还卡住多的话多重启试几次就行。
1、收发端共同操作(需联网)
cd ~
sudo apt-get install libpcap-dev
git clone https://github.com/dhalperi/lorcon-old.git
# 失败的话在github.com前加上:gitclone.com/
cd lorcon-old
./configure
make
sudo make install
2、接收端准备
(1)编译收包代码
cd ~
cd linux-80211n-csitool-supplementary/netlink/
make
(2)修改Socket接收缓冲区的大小
内核为每个socket分配了缓冲区,用于存储从网络接口接收到的数据包,其由默认值net.core.rmem_default决定,所有socket接收缓冲区的最大值不会超过net.core.rmem_max。
在进行收发包时,数据包通过网络接口到达系统,被放入内核中的socket接收缓冲区,然后程序脚本通过调用recv函数,从内核的socket接收缓冲区中读取数据到用户空间。因此,socket接收缓冲区影响着数据包在内核中的排队与存储。
为此在这里修改最大接收缓存区 rmem_max 与默认接收缓冲区rmem_default的大小,rmem_max从 212992字节 改成了 21299200字节,rmem_default修改为2129920字节。
sysctl net.core.rmem_max # 查看当前最大接收缓存区大小
sudo gedit /etc/sysctl.conf
# 在打开的窗口中修改或添加:
# net.core.rmem_max=新的最大接收缓冲区大小
# net.core.rmem_default=新的最大接收缓冲区大小
sudo sysctl -p # 使修改生效
(3)修改路径 linux-80211n-csitool-supplementary/netlink/ 下的log_to_file.c
本文的log_to_file.c代码在setup_monitor_csi.sh脚本启动时只创建一个输出文件,文件名由命令行参数指定,所有数据包都写入同一个文件,每个数据包包含8字节时间戳(毫秒)、2字节长度和实际内容,程序会一直运行直到被中断信号(Ctrl+C)终止,并且每100个数据包会打印一次状态信息,包括写入的字节数、数据包计数和时间戳。
代码链接:https://download.csdn.net/download/m0_72082832/89739390
# 替换原本的log_to_file.c代码后,重新编译
cd linux-80211n-csitool-supplementary/netlink/
make clean
make
(4)修改路径 linux-80211n-csitool-supplementary/injection/ 下的setup_monitor_csi.sh脚本,代码如下:
#!/usr/bin/sudo /bin/bash
sudo modprobe -r iwlwifi mac80211
sudo modprobe iwlwifi connector_log=0x1
sudo service network-manager stop
WLAN_INTERFACE=$1
SLEEP_TIME=2
modprobe iwlwifi debug=0x40000
if [ "$#" -ne 3 ]; then
echo "Going to use default settings!"
chn=64
bw=HT20
else
chn=$2
bw=$3
fi
sleep $SLEEP_TIME
ifconfig $WLAN_INTERFACE 2>/dev/null 1>/dev/null
while [ $? -ne 0 ]
do
ifconfig $WLAN_INTERFACE 2>/dev/null 1>/dev/null
done
sleep $SLEEP_TIME
echo "Add monitor mon0....."
iw dev $WLAN_INTERFACE interface add mon0 type monitor
sleep $SLEEP_TIME
echo "Bringing $WLAN_INTERFACE down....."
ifconfig $WLAN_INTERFACE down
while [ $? -ne 0 ]
do
ifconfig $WLAN_INTERFACE down
done
sleep $SLEEP_TIME
echo "Bringing mon0 up....."
ifconfig mon0 up
while [ $? -ne 0 ]
do
ifconfig mon0 up
done
sleep $SLEEP_TIME
echo "Set channel $chn $bw....."
iw mon0 set channel $chn $bw
(5)确定所装的Intel 5300网卡接口名称,我这里为wlan2,注意一定要用当前设备的网卡名称
iwconfig
(6)进入待收包状态
收包端进入monitor模式:
cd linux-80211n-csitool-supplementary/injection/
sudo bash ./setup_monitor_csi.sh wlan2 64 HT20
# wlan2为网卡名称,64为信道,收发端要一致 (64对应5.32Ghz,13对应2.4Ghz)
结果如图:
进行收包,新开个终端窗口(好看结果),创建收包文件,以防卡住,增加 `log_to_file.c` 进程的调度优先级,使用最高调度优先级( nice -n <优先级> )运行收包代码,然后便可进行发包。
cd linux-80211n-csitool-supplementary/netlink/
sudo nice -n -20 ./log_to_file test.dat #test.dat为数据包文件,自行命名
补充:
J1800性能不足,只能收3分钟左右的包,之后便会卡住,就是其他博主说的数组栓塞问题。
我们这边需要收集连续的动作数据,故尝试了缓存修改、非阻塞、多线程、更改调度优先级、定期刷新输出文件缓冲区以确保数据被写入磁盘,主循环添加超时机制防止卡住等一系列操作,最后发现对于J1800这个设备来说提升不大,而更换J1900后能收10分钟以上的包,收包速度也能赶上发送端。
最终使用J1900收包的结果如下,1000HZ下发送100w个包(差不多1000秒)的数据大小为574.5M,后续使用MATLAB处理数据电脑要有足够内存才行。
3、发送端准备
(1)编译发包代码
cd ~
cd linux-80211n-csitool-supplementary/injection/
make
(2)1000Hz 发包频率下发包也会卡住或突然停止,故修改最大发送缓存区 rmem_max 的大小(也从212992字节改成了21299200字节,增大100倍)
sysctl net.core.wmem_max # 查看当前最大接收缓存区大小
sudo gedit /etc/sysctl.conf # 在打开的窗口中修改或添加net.core.wmem_max=新的最大接收缓冲区大小
sudo sysctl -p # 使修改生效
(3)修改路径 linux-80211n-csitool-supplementary/injection/ 下的发包脚本:setup_inject.sh
原先每次发包还要执行几个步骤,这里整合到了代码里,并增加了断点续发、发包量与系统监测功能,最后目的是主机开机自动执行脚本发包无需任何操作。
如有需要可修改发包总量、发包天线数、发包间隔,具体都在代码中注释了。
#!/usr/bin/sudo /bin/bash
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> packet_sender.log
}
# 全局变量,用于跟踪已发送的包数量
TOTAL_PACKETS_SENT=0
TOTAL_PACKETS_TO_SEND=1000000 # 设置你的总发包量
# 初始化函数
initialize() {
log "开始初始化..."
sudo service network-manager stop
WLAN_INTERFACE=$1
SLEEP_TIME=2
modprobe iwlwifi debug=0x40000
if [ "$#" -ne 3 ]; then
echo "Going to use default settings!"
chn=64
bw=HT20
else
chn=$2
bw=$3
fi
sleep $SLEEP_TIME
ifconfig $WLAN_INTERFACE 2>/dev/null 1>/dev/null
while [ $? -ne 0 ]
do
ifconfig $WLAN_INTERFACE 2>/dev/null 1>/dev/null
done
sleep $SLEEP_TIME
echo "Add monitor mon0....."
iw dev $WLAN_INTERFACE interface add mon0 type monitor
sleep $SLEEP_TIME
echo "Bringing $WLAN_INTERFACE down....."
ifconfig $WLAN_INTERFACE down
while [ $? -ne 0 ]
do
ifconfig $WLAN_INTERFACE down
done
sleep $SLEEP_TIME
echo "Bringing mon0 up....."
ifconfig mon0 up
while [ $? -ne 0 ]
do
ifconfig mon0 up
done
sleep $SLEEP_TIME
echo "Set channel $chn $bw....."
iw mon0 set channel $chn $bw
# 设置发包的天线数,这里是一根天线发包
echo 0x1c113 | sudo tee `sudo find /sys -name monitor_tx_rate`
cd ~/linux-80211n-csitool-supplementary/injection/
log "初始化完成"
}
# 改进的发包函数
send_packets() {
local packets_to_send=$((TOTAL_PACKETS_TO_SEND - TOTAL_PACKETS_SENT))
if [ $packets_to_send -le 0 ]; then
log "已达到预设发包量,停止发包"
exit 0
fi
log "开始发包... 剩余包数: $packets_to_send"
# 设置发包间隔:100 1 1000分别为包长度、发包模式、发包间隔(微秒)
# 现在发包间隔为1000微妙,也就是每秒发1000个包,发包频率1000Hz,丢包严重或卡住可调高间隔
sudo ./random_packets $packets_to_send 100 1 1000 2>&1 | tee -a packet_sender.log
if [ ${PIPESTATUS[0]} -eq 0 ]; then
TOTAL_PACKETS_SENT=$TOTAL_PACKETS_TO_SEND
log "发包完成"
else
log "发包过程中出现错误"
fi
}
# 改进的检查发包状态的函数
check_sending_status() {
if pgrep -f "random_packets" > /dev/null; then
# 检查进程是否真的在工作
if [ "$(ps -o etimes= -p $(pgrep -f "random_packets"))" -gt 10 ]; then
return 0
else
log "发包进程存在但可能已停止工作"
return 1
fi
else
return 1
fi
}
# 检查系统资源
check_resources() {
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
local mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
log "CPU使用率: ${cpu_usage}%, 内存使用率: ${mem_usage}%"
if (( $(echo "$cpu_usage > 90" | bc -l) )) || (( $(echo "$mem_usage > 90" | bc -l) )); then
log "系统资源不足,暂停发包"
return 1
# 主函数
main() {
initialize $1 $2 $3
local retry_count=0
local max_retries=5
while [ $TOTAL_PACKETS_SENT -lt $TOTAL_PACKETS_TO_SEND ]; do
if ! check_resources; then
sleep 5 # 如果资源不足,等待30秒再检查
continue
fi
if ! check_sending_status; then
if [ $retry_count -ge $max_retries ]; then
log "达到最大重试次数,重新初始化网络接口"
initialize $1 $2 $3
retry_count=0
fi
log "开始新的发包周期"
send_packets &
retry_count=$((retry_count + 1))
else
retry_count=0
fi
sleep 2 # 每2秒检查一次状态
done
log "已发送预设数量的包,程序结束"
}
# 运行主函数
main $1 $2 $3
(4)同样要确定所装的Intel 5300网卡接口名称,这里为wlan0
iwconfig
(5)进行发包:执行发包脚本 setup_inject.sh
cd linux-80211n-csitool-supplementary/injection/
sudo bash ./setup_inject.sh wlan0 64 HT20
# wlan0为网卡名称,64为信道,收发端要一致 (64对应5.32Ghz,13对应2.4Ghz)
成功发包后,会不断有小点输出,一个点是1000个包,这时候查看接收端是否打印出收到包的信息,不用纠结iwconfig看到的信息中网卡的发包量,我这里发包成功了也还是显示发包为0。
运行结果如图:
五、数据处理(MATLAB)
1、CSI数据可视化
将 linux-80211n-csitool-supplementary/matlab 这个matlab文件夹拷贝到装有MATLAB的电脑上,用MATLAB打开文件夹,修改CSI数据读取文件read_bf_file.m以匹配我们的数据格式:https://download.csdn.net/download/m0_72082832/89753958?spm=1001.2014.3001.5501。
然后修改可视化文件read.m:https://download.csdn.net/download/m0_72082832/89753924?spm=1001.2014.3001.5501, 这里修改了可视化代码以匹配我们的数据格式,在显示原1x3的幅度-包号CSI图像上的基础上增加了幅度-时间的图像,并增加了总收包时长的统计,可在图底看出。
read.m运行结果:
2、Hampel identifier去除异常点,卡尔曼平滑滤波平滑曲线,小波变换去噪三合一
之前各分开处理了,现在想合一块看看效果。
运行结果如下(颜色再说,先这样)
(1)原图与总处理结果对比
(2)3根天线各30个子载波的处理结果对比