Omnet ++ / INET:如何从802.11 NIC获取RSSI?

时间:2017-06-16 13:28:20

标签: omnet++ inet

我正在节点模型中实现无线路由协议,该模型使用Ieee80211Nic类型的网络接口卡,并且设置为在ad-hoc模式下工作(Ieee80211MgmtAdhoc)。我想使用来自NIC的RSSI值作为路由协议中的度量标准之一。
如何从NIC检索特定邻居节点(由其MAC地址标识)的RSSI值?

修改

在深入研究INET 3.6源代码后,我发现Ieee80211NIC组件由以下模块(或层)组成(自上而下):

  • 代理(仅在站STA中的基础结构模式下使用)
  • mgmt(可以是Ieee80211MgmtAP,Ieee80211MgmtSTA,Ieee80211MgmtAdhoc)
  • MAC
  • 无线电

我进一步分析了 Ieee80211MgmtSTA 源代码,发现它实现了以下方法,记录了接收信号强度( bss.setRxPower(ap-> rxPower)):

void Ieee80211MgmtSTA::sendScanConfirm()
{
    EV << "Scanning complete, found " << apList.size() << " APs, sending confirmation to agent\n";

    // copy apList contents into a ScanConfirm primitive and send it back
    int n = apList.size();
    Ieee80211Prim_ScanConfirm *confirm = new Ieee80211Prim_ScanConfirm();
    confirm->setBssListArraySize(n);
    auto it = apList.begin();
    //XXX filter for req'd bssid and ssid
    for (int i = 0; i < n; i++, it++) {
        APInfo *ap = &(*it);
        Ieee80211Prim_BSSDescription& bss = confirm->getBssList(i);
        bss.setChannelNumber(ap->channel);
        bss.setBSSID(ap->address);
        bss.setSSID(ap->ssid.c_str());
        bss.setSupportedRates(ap->supportedRates);
        bss.setBeaconInterval(ap->beaconInterval);
        bss.setRxPower(ap->rxPower);
    }
    sendConfirm(confirm, PRC_SUCCESS);
}

但是,如果是 Ieee80211MgmtAdhoc 类型,则不会实现频道扫描(由代理模块控制)。因此,无法检索特定节点的Rx功率。

是否有人设法在Adhoc模式下实施具有频道扫描的代理模块?
或者是否有另一种获取RSSI信息的方法?

2 个答案:

答案 0 :(得分:0)

那么,你完成了你的工作吗? 众所周知,存在一种记录接收信号强度bss.setRxPower(ap->rxPower)的实现方法 但是在同一个文件中我们可以发现ap的变量是storeAPInfo(const MACAddress& address, const Ieee80211BeaconFrameBody& body)函数的初始值 见下文:

void Ieee80211MgmtSTA::storeAPInfo(const MACAddress& address, const Ieee80211BeaconFrameBody& body)
{
    APInfo *ap = lookupAP(address);
    if (ap) {
        EV << "AP address=" << address << ", SSID=" << body.getSSID() << " already in our AP list, refreshing the info\n";
    }
    else {
        EV << "Inserting AP address=" << address << ", SSID=" << body.getSSID() << " into our AP list\n";
        apList.push_back(APInfo());
        ap = &apList.back();
    }

    ap->channel = body.getChannelNumber();
    ap->address = address;
    ap->ssid = body.getSSID();
    ap->supportedRates = body.getSupportedRates();
    ap->beaconInterval = body.getBeaconInterval();
    //XXX where to get this from?
    //ap->rxPower = 。。。
}

正如我们所看到的,ap-> rxPower没有初始值,这意味着我们在sendScanConfirm()函数中得到的值将始终为零。那么,还有其他方法可以获得RSSI吗?

答案 1 :(得分:0)

在深入研究源代码后,我发现了一个有趣的函数

 bool computeIsReceptionPossible(const IListening *listening, const IReception *reception, IRadioSignal::SignalPart part) const

在文件FlatReceiverBase中哪个路径可以是“#include”inet / physicallayer / base / packetlevel / FlatReceiverBase“。见下文:

bool FlatReceiverBase::computeIsReceptionPossible(const IListening *listening, const IReception *reception, IRadioSignal::SignalPart part) const
{
    if (!NarrowbandReceiverBase::computeIsReceptionPossible(listening, reception, part))
        return false;
    else {
        const FlatReceptionBase *flatReception = check_and_cast<const FlatReceptionBase *>(reception);
        W minReceptionPower = flatReception->computeMinPower(reception->getStartTime(part), reception->getEndTime(part));
        bool isReceptionPossible = minReceptionPower >= sensitivity;
        EV_DEBUG << "Computing whether reception is possible: minimum reception power = " << minReceptionPower << ", sensitivity = " << sensitivity << " -> reception is " << (isReceptionPossible ? "possible" : "impossible") << endl;
        return isReceptionPossible;
    }
}

因此,我们可以发现在这个函数中我们可以使用minReceptionPower变量获得接收功能。然后,我们可以使用嵌入式数学运算符mW2dBm将接收功率转换为RSSI值。 注意,如果跟踪源,我们可以发现该模块在Ieee80211Radio模块初始化。 我希望这对遇到同样问题的人有所帮助。