1. 前言

引用参考链接 1

对于射频通信而言,非常重要的一个问题即是通信频道是否可用。这里所谓的可用是指信道是否拥挤,在规定的频谱带上是否有其他的信号正在传输,且能否和本设备要发送和接收的信号区分开来。由于射频通信的介质是空气,这点不同于现有的互联网通信,通过的是电缆等物理设备。但是要做一个稳定、可靠的通信,就必须做一个传输介质(信道)的判忙处理。

CC1101提供的信道检测机制之一就是信道空闲评估,CCA。用于检测编程指定的信道是否处于可用的状态

CCA主要用于CC1101在信号发射之前进行的信道空闲评估,评估的内容包括:

1、信道的信号强度是否高于某一个阀值(如果信号强度低于这个阈值则认为信道是空闲的);

2、是否有和本设备设置的同样频率特征的数据正在被接收;

这两部分内容既可以都作为信号空闲评估的判断内容,也可分开各自使用,取决于我们对CCA工作模式的设置

2. Code

a. CCA

在 Veins 中 CCA Threshold 设置大小为 -65 dBm。这部分实现并没有想的那么简单,下面一点点来看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
bool Decider80211p::cca(simtime_t_cref time, AirFrame* exclude)
{

AirFrameVector airFrames;

// collect all AirFrames that intersect with [start, end]
getChannelInfo(time, time, airFrames);

// In the reference implementation only centerFrequenvy - 5e6 (half bandwidth) is checked!
// Although this is wrong, the same is done here to reproduce original results
double minPower = phy->getNoiseFloorValue();
bool isChannelIdle = minPower < ccaThreshold;
if (airFrames.size() > 0) {
size_t usedFreqIndex = airFrames.front()->getSignal().getSpectrum().indexOf(centerFrequency - 5e6);
isChannelIdle = SignalUtils::isChannelPowerBelowThreshold(time, airFrames, usedFreqIndex, ccaThreshold - minPower, exclude);
}

return isChannelIdle;
}

首先,这个函数承接了一个判断,即 CCA 返回一个 bool 值告诉我们当前信道是否 idle,这个判断会触发后面 phy 向 Mac 发送 control msg 以便 mac layer 来获取信道状态。

1
2
3
4
5
6
7
8
void Decider80211p::setChannelIdleStatus(bool isIdle)
{
isChannelIdle = isIdle;
if (isIdle)
phy->sendControlMsgToMac(new cMessage("ChannelStatus", Mac80211pToPhy11pInterface::CHANNEL_IDLE));
else
phy->sendControlMsgToMac(new cMessage("ChannelStatus", Mac80211pToPhy11pInterface::CHANNEL_BUSY));
}

接着说 CCA 的实现,Line 7 读取了目前所有信道中所有 Start-End 之间经过此时刻的 frames,Veins 中还定义了一个专门的类用来处理 Channel 中的 Interaction。

之后在 11 和 12 行简单判断了下 noise 的强度是否会使得信道空闲误判,config 文件中指定为 0 。noise floor 中文解释是噪声基底,也称为 Display Average Noise Level(DANL),代表接收信噪比为 0dB 时,接收机能够感知的最小信号强度。它是频谱灵敏度的表现,Nose Floor 越低表示频谱越能够辨识微弱的讯号。在这里 noiseFloorValue 为 0 表示基本所有的信号我们默认都可以辨识到。

1
double noiseFloorValue = 0; ///< Catch-all for all factors negatively impacting SINR (e.g., thermal noise, noise figure, ...)

然后在 13~15 行开始正式判断当前信道实际信号强度是否低于阈值,注意这里 airFrames 变量是 list 类型,而 C++ 中 list 的 front() 函数的作用是返回其第一个元素的引用。于是第 14 行的作用只是获取第一个 frame 中 signal 的 half bandwidth 频率的 index。至于这里为什么是这样?看注释也没有理解,先默认这样的实现是合理的吧😂。

b. isChannelPowerBelowThreshold

当进入 isChannelPowerBelowThreshold 之后便需要统计信道中的 signal 来判断是否低于给定阈值。分成几个部分吧

  1. 统计所有有交互的报文
  2. 判断报文之和是否小于阈值;
  3. 提取出所有的信道模型后分别过滤下所有的 signal 然后重新看 powerLevelSum 是否小于阈值

显然如果第 2 步小于阈值的话那么第 3 步经过信道 filter 之后也肯定小于阈值。这里不理解的是为什么在每个 analogueModel 中如果满足条件就直接返回呢?而不是进行完所以的之后再返回呢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
bool VEINS_API isChannelPowerBelowThreshold(simtime_t now, AirFrameVector& interfererFrames, size_t freqIndex, double threshold, AirFrame* exclude)
{
if (interfererFrames.empty()) {
// No interferers, so the channel interference is below any threshold
return true;
}

// extract valid signals on the channel at the time of interest
// TODO: possibly move this filtering outside of this function
std::vector<Signal*> interferers;
for (auto& interfererFrame : interfererFrames) {
Signal* interferer = &interfererFrame->getSignal();
if (interferer->getReceptionStart() <= now && interferer->getReceptionEnd() > now && interfererFrame != exclude) {
interferers.push_back(interferer);
}
}

// check once before applying analogModels
if (powerLevelSumAtFrequencyIndex(interferers, freqIndex) < threshold) {
return true;
}

// start applying analogue models
auto analogueModelCount = interfererFrames.front()->getSignal().getAnalogueModelList()->size();
for (auto signalPtr : interferers) {
ASSERT(analogueModelCount == signalPtr->getAnalogueModelList()->size());
}
for (size_t analogueModelIndex = 0; analogueModelIndex < analogueModelCount; ++analogueModelIndex) {
for (auto signalPtr : interferers) {
signalPtr->applyAnalogueModel(analogueModelIndex);
}
if (powerLevelSumAtFrequencyIndex(interferers, freqIndex) < threshold) {
return true;
}
}

// After all attenuation is performed, there interference is still higher than the threshold
ASSERT(powerLevelSumAtFrequencyIndex(interferers, freqIndex) >= threshold);
return false;
}

Reference

  1. (109条消息) CC1101之信道空闲评估(CCA:Clear Channel Assessment)_YaHa201286的博客-CSDN博客