在上一篇文章中,已经实现了信息的解调。由于信息可能含错,故而使用维特比算法进行纠错。这个维特比算法采用了以前介绍过的一个原创实现。纠错后的数据,还要执行去伪随机m序列,得到完整的以太网包数据。
1. 维特比纠错
采用维特比算法,对还原的数据进行纠错:
//外部定义
//Vit
const int pins [] = {165,133,171};
void * codec = LSMVIT::new_conv_codec(3,1,6,pins,0,VIT_WINLEN);
//3. decode
std::vector<int> code;
const int valid_syms = len*8 + 7;
for (int i=0;i<valid_syms+VIT_WINLEN;++i)
{
//fill code
//……
}
//维特比复位0态
LSMVIT::reset_status(codec);
//推入数据
LSMVIT::decode(codec,code.data(),code.size(),true);
//数据存储向量
std::vector<int> data;
data.resize(len*8);
//弹出结果
int poped = LSMVIT::pop_data(codec,data.data(),len*8);
该算法输入3个比特,输出1个比特。
2. 脱伪随机序列
为了避免全0造成的波形恶化,在数据发射前,对完整的以太网包进行了伪随机序列覆盖。这种覆盖只要原样再来一次就还原了:
//Output
std::vector<unsigned char> frame;
//xor code
unsigned char scm[15] = {1,0,1,1,0,0,1,1,1,1,0,0,1,1,0};
for (int i=0;i<len;++i)
{
unsigned char Byte = 0;
for (int j=0;j<8;++j)
{
const int ib = i *8 + j;
const int b = data[ib];
const int d = b ^ scm[ib % 15];
scm[ib%15] ^= (scm[(ib+13)%15] ^ scm[(ib+14)%15]);
Byte ^= (d << j);
}
frame.push_back(Byte);
}
//frame就是一个完整的以太网包
3. 向网卡传送
最终,把生成的数据,播放给网卡:
pcap_sendpacket(handle,packagedta.data(),packagedta.size());
这样,一个完成的收发流程就结束了。
只要具备2台设备,使用2个频率进行互相通信,一个从零开始的无线以太网就建成了。
4. 深入的话题
当然,这个例子只是从功能上实现了点对点的以太网连接。它相当于搭建了一个隐形的网线,直接沟通了两个网卡。
站在通信学科的角度,无论从频带利用效率、安全性、稳定性,或者对多终端的灵活应用、对功耗的控制,或者从基础的操作上来讲,这个例子都是粗陋的、原始的,停留在上个世纪60-70年代的启蒙水平。但是,站在工程的角度,这个例子又是完整的,它直观的告诉我们,最简单的全功能无线网络(双工、支持常见的上层协议)要具备哪些环节,完成怎样的数据处理。
有很多深入的话题,等待去学习、研究。
- 如何建立信道模型,评估最节约成本的可靠调制、编码方案;
- 如何进行环保的功率控制,在确保正确的同时,降低能源的开销;
- 如何让SDR设备在PC上处理更大的带宽
- VOLK/GPU/OpenMP/MPI的使用
- 向FPGA迁移,挑战更大的实用带宽和LDPC/Turbo等迭代译码。
学无止境。没必要太纠结,自娱自乐开开心心的把玩,民科也很精彩。
完整代码和发型版参考首篇链接。