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 + -
显示快捷键?