phy_802_15_4.cpp

来自「802.15.4协议的物理层c文件和header文件」· C++ 代码 · 共 2,109 行 · 第 1/5 页

CPP
2,109
字号
// Copyright (c) 2001-2008, Scalable Network Technologies, Inc.  All Rights Reserved.//                          6701 Center Drive West//                          Suite 520//                          Los Angeles, CA 90045//                          sales@scalable-networks.com//// This source code is licensed, not sold, and is subject to a written// license agreement.  Among other things, no portion of this source// code may be copied, transmitted, disclosed, displayed, distributed,// translated, used as the basis for a derivative work, or used, in// whole or in part, for any program or purpose other than its intended// use in compliance with the license agreement as part of the QualNet// software.  This source code and certain of the algorithms contained// within it are confidential trade secrets of Scalable Network// Technologies, Inc. and may not be used as the basis for any other// software, hardware, product or service.#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "api.h"#include "antenna.h"#include "phy_802_15_4.h"#define DEBUG 0#define DYNAMIC_STATS 0// /**// FUNCTION   :: Phy802_15_4ReportExtendedStatusToMac// LAYER      :: PHY// PURPOSE    :: Report extended status of the PHY to MAC upon change// PARAMETERS ::// + node      : Node*         : Pointer to node.// + phyNum    : int           : Index of the PHY// + status    : PhyStatusType : New status of the PHY// + receivingDuration : clocktype : If receiving status, duration of recv// + potentialIncomingPacket : Message* : If recving status, potential//                                        packet// RETURN     :: void : NULL// **/staticvoid Phy802_15_4ReportExtendedStatusToMac(        Node *node,        int phyNum,        PhyStatusType status,        clocktype receiveDuration,        const Message* potentialIncomingPacket){    PhyData* thisPhy = node->phyData[phyNum];    PhyData802_15_4* phy802_15_4 = (PhyData802_15_4*)thisPhy->phyVar;    assert(status == phy802_15_4->mode);    MAC_ReceivePhyStatusChangeNotification(        node, thisPhy->macInterfaceIndex,        phy802_15_4->previousMode, status,        receiveDuration, potentialIncomingPacket);}// /**// FUNCTION   :: Phy802_15_4ChangeState// LAYER      :: PHY// PURPOSE    :: Change status of the PHY// PARAMETERS ::// + node      : Node*         : Pointer to node.// + phyNum    : int           : Index of the PHY// + status    : PhyStatusType : New status of the PHY// RETURN     :: void : NULL// **/staticvoid Phy802_15_4ChangeState(        Node* node,        int phyIndex,        PhyStatusType newStatus){    PhyData* thisPhy = node->phyData[phyIndex];    PhyData802_15_4 *phy802_15_4 = (PhyData802_15_4 *)thisPhy->phyVar;    phy802_15_4->previousMode = phy802_15_4->mode;    phy802_15_4->mode = newStatus;    Phy_ReportStatusToEnergyModel(        node,        phyIndex,        phy802_15_4->previousMode,        newStatus);}// /**// FUNCTION   :: Phy802_15_4ReportStatusToMac// LAYER      :: PHY// PURPOSE    :: Report status of the PHY to MAC// PARAMETERS ::// + node      : Node*         : Pointer to node.// + phyNum    : int           : Index of the PHY// + status    : PhyStatusType : New status of the PHY// RETURN     :: void : NULL// **/static /*inline*/void Phy802_15_4ReportStatusToMac(        Node *node,        int phyNum,        PhyStatusType status){    Phy802_15_4ReportExtendedStatusToMac(        node,        phyNum,        status,        0,        NULL);}//**// FUNCTION   :: Phy802_15_4LockSignal// LAYER      :: PHY// PURPOSE    :: Lock the signal// PARAMETERS ::// + node      : Node*         : Pointer to node.// + phy802_15_4   : PhyData802_15_4*  : Pointer to PHY data// + msg          :  Message*          : Pointer to Message// + rxPower_mW    : double            : Received signal power in mW// + rxEndTime     : clocktype         : Rx end time// RETURN     :: void : NULL// **/static //inline//void Phy802_15_4LockSignal(        Node* node,        PhyData802_15_4* phy802_15_4,        Message *msg,        double rxPower_mW,        clocktype rxEndTime){    phy802_15_4->rxMsg = msg;    phy802_15_4->rxMsgError = FALSE;    phy802_15_4->rxMsgPower_mW = rxPower_mW;    phy802_15_4->rxTimeEvaluated = getSimTime(node);    phy802_15_4->rxEndTime = rxEndTime;    phy802_15_4->stats.totalSignalsLocked++;}// /**// FUNCTION   :: Phy802_15_4UnlockSignal// LAYER      :: PHY// PURPOSE    :: Unlock the signal// PARAMETERS ::// + phy802_15_4   : PhyData802_15_4*  : Pointer to PHY data// RETURN     :: void : NULL// **/static //inline//void Phy802_15_4UnlockSignal(    PhyData802_15_4* phy802_15_4){    phy802_15_4->rxMsg = NULL;    phy802_15_4->rxMsgError = FALSE;    phy802_15_4->rxMsgPower_mW = 0.0;    phy802_15_4->rxTimeEvaluated = 0;    phy802_15_4->rxEndTime = 0;    phy802_15_4->linkQuality = 0.0;}// /**// FUNCTION   :: Phy802_15_4CarrierSensing// LAYER      :: PHY// PURPOSE    :: check if the channel is busy// PARAMETERS ::// + phy802_15_4   : PhyData802_15_4*  : Pointer to PHY data// RETURN     :: BOOL : TRUE if channel is busy, FALSE otherwise// **/static /*inline*/BOOL Phy802_15_4CarrierSensing(        Node* node,        PhyData802_15_4* phy802_15_4){    double rxSensitivity_mW = phy802_15_4->rxSensitivity_mW;    if (phy802_15_4->interferencePower_mW > rxSensitivity_mW*100)    {        return TRUE;    }    return FALSE;}// /**// FUNCTION   :: Phy802_15_4MediumIsIdle// LAYER      :: PHY// PURPOSE    :: check if Medium Is Idle// PARAMETERS ::// + node      : Node*         : Pointer to node.// + phyIndex  : int           : Index of the PHY// RETURN     :: BOOL : TRUE if medium is idle, FALSE otherwise// **/BOOL Phy802_15_4MediumIsIdle(        Node *node,        int phyIndex){    BOOL mediumIsIdle = TRUE;    PhyData* thisPhy = node->phyData[phyIndex];    PhyData802_15_4* phy802_15_4 = (PhyData802_15_4*) thisPhy->phyVar;    double ED_threshold_mW = phy802_15_4->EDthreshold_mW;    double rxSensitivity_mW = phy802_15_4->rxSensitivity_mW;    if ( phy802_15_4->CCAmode == ENERGY_ABOVE_THRESHOLD)    {        if (phy802_15_4->interferencePower_mW > ED_threshold_mW)        {            mediumIsIdle = FALSE;        }    }    else if (phy802_15_4->CCAmode == CARRIER_SENSE)    {        if (phy802_15_4->interferencePower_mW > rxSensitivity_mW)        {            mediumIsIdle = FALSE;        }    }    else if (phy802_15_4->CCAmode ==             CARRIER_SENSE_WITH_ENERGY_ABOVE_THRESHOLD)    {        if ((phy802_15_4->interferencePower_mW > ED_threshold_mW) &&           (phy802_15_4->interferencePower_mW > rxSensitivity_mW))        {            mediumIsIdle = FALSE;        }    }    else    {        ERROR_ReportError(                "PHY802.15.4: Illegal CCA mode\n");    }    return mediumIsIdle;}// /**// FUNCTION   :: combinationCalculation// LAYER      :: PHY// PURPOSE    :: Function used to calculate BER// PARAMETERS ::// + n         : int      : Pointer to node.// + k         : int      : Index of the PHY// RETURN     :: double   : calculate result// **/staticdouble combinationCalculation(int n, int k){    double combination;    double numerator = 1.0;    double denominator = 1.0;    int i;    for (i = 1; i < k + 1; i ++)        denominator = denominator * i;    for (i = n-k+1; i < n+1; i++)        numerator = numerator * i;    combination = numerator / denominator;    return combination;}// /**// FUNCTION   :: O_QPSKberCalculation// LAYER      :: PHY// PURPOSE    :: Function used to calculate BER for O_QPSK// PARAMETERS ::// + sinr            : double     : Pointer to node.// + exponentfactor  : double     : Index of the PHY// RETURN     :: double           : ber result// **/staticdouble O_QPSKberCalculation ( double sinr, double exponentfactor){    double ber = 0.0;    double combinationpart;    double exponentpart;    double exponent;    int    upperBound;    int i;    upperBound = PHY802_15_4_BER_UPPER_BOUND_SUMMATION;    for(i = 2; i < upperBound; i++){        exponent = exponentfactor * sinr * ((1.0 / (double) i) - 1.0);        combinationpart = combinationCalculation(upperBound - 1, i);        exponentpart = exp(exponent);        ber = ber + pow(-1.0, (double) i)*combinationpart * exponentpart;    }    ber = ber * PHY802_15_4_BER_CONSTANT;    return ber;}// /**// FUNCTION   :: Phy802_15_4CheckRxPacketError// LAYER      :: PHY// PURPOSE    :: Check packet reception quality// PARAMETERS ::// + node           : Node*             : Pointer to node.// + phy802_15_4    : PhyData802_15_4*  : Pointer to PHY data// + sinrp          : double*           : Pointer to double// + phyIndex       : int               : Index of the PHY// RETURN     :: void : NULL// **/static //inline//BOOL Phy802_15_4CheckRxPacketError(        Node* node,        PhyData802_15_4* phy802_15_4,        double *sinrp,        int phyIndex){    double sinr;    double BER = 0.0;    BOOL packeterror = FALSE;    int channelIndex;    double exponentFactor;    PhyData *thisPhy = node->phyData[phyIndex];    assert(phy802_15_4->rxMsgError == FALSE);    PHY_GetTransmissionChannel(node, phyIndex, &channelIndex);    PropProfile *propProfile = node->propChannel[channelIndex].profile;    sinr = phy802_15_4->rxMsgPower_mW /        (phy802_15_4->interferencePower_mW +         phy802_15_4->noisePower_mW);    if (thisPhy->phyRxModel == BER_BASED) {        BER = PHY_BER(phy802_15_4->thisPhy,                      0,                      sinr);    }    else if (thisPhy->phyRxModel == RX_802_15_4) {        exponentFactor = PHY802_15_4_DEFAULT_EXPONENT_FACTOR;        if ((propProfile->frequency >= 2400000000U) &&            (propProfile->frequency <= 2483500000U))        {            exponentFactor = PHY802_15_4_2400MHZ_DEFAULT_EXPONENT_FACTOR;        }        if ((propProfile->frequency >= 2400000000U) &&            (propProfile->frequency <= 2483500000U))        {            BER = O_QPSKberCalculation ( sinr, exponentFactor);        }        else if((propProfile->frequency >= 902000000) &&                (propProfile->frequency <= 928000000))        {            if (phy802_15_4->modulation == BPSK)            {                BER = 0.5 * exp(-11.25 * sinr);            }            else if(phy802_15_4->modulation == O_QPSK)            {                BER = O_QPSKberCalculation (sinr, exponentFactor);            }            else if (phy802_15_4->modulation == ASK)            {                BER = 0.7668 * exp(-21.93 * sinr) -                        12.85 * exp(-27.53 * sinr);                if (BER < 0.0) {                    BER = PHY802_15_4_DEFAULT_BER_CONSTANT;                }            }            else {                ERROR_ReportError(                    "PHY802.15.4: Illegal modulation scheme\n");            }        }        else if((propProfile->frequency >= 868000000) &&                (propProfile->frequency <= 868600000))        {            if (phy802_15_4->modulation == BPSK)            {                BER = 0.5 * exp(-11.25 * sinr);            }            else if (phy802_15_4->modulation == O_QPSK)            {                BER = O_QPSKberCalculation (sinr, exponentFactor);            }            else if (phy802_15_4->modulation == ASK)            {                BER = 0.4146 * exp(-6.0871 * sinr);            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?