/************************************************************************ PhySciMsgMpdu.cpp - Copyright buret Here you can write a license for your code, some comments or any other information you want to have in your generated code. To to this simply configure the "headings" directory in uml to point to a directory where you have your heading files. or you can just replace the contents of this file with your own. If you want to do this, this file is located at /usr/share/apps/umbrello/headings/heading.cpp -->Code Generators searches for heading files based on the file extension i.e. it will look for a file name ending in ".h" to include in C++ header files, and for a file name ending in ".java" to include in all generated java code. If you name the file "heading.", Code Generator will always choose this file even if there are other files with the same extension in the directory. If you name the file something else, it must be the only one with that extension in the directory to guarantee that Code Generator will choose it. you can use variables in your heading files which are replaced at generation time. possible variables are : author, date, time, filename and filepath. just write %variable_name% This file was generated on %date% at %time% The original location of this file is /home/buret/eclipse/maximus/phy/src/PhySciMsgMpdu.cpp **************************************************************************/ #include "PhySciMsgMpdu.h" #include "PhySciMsgPre.h" #include "PhySciMsgFc.h" #include "IPhy.h" #include "Error.h" #include "Logger.h" // for 'getpid()' #include #include using namespace std; // Constructors/Destructors // PhySciMsgMpdu::PhySciMsgMpdu ( IPhy * p_phy_processor ) : PhySciMsg ( p_phy_processor ), mPayloadLength(0), mpPayload(NULL), mpPre(NULL), mpFc(NULL), mNbOfPbsInLastMsg(0) { logFunction(); initAttributes(p_phy_processor); } PhySciMsgMpdu::PhySciMsgMpdu ( PhySciMsg & phy_sci_msg ) : PhySciMsg ( phy_sci_msg.getPhyProcessor() ), mPayloadLength(0), mpPayload(NULL), mpPre(NULL), mpFc(NULL), mNbOfPbsInLastMsg(0) { logFunction(); // Initialize PHY SCI message MPDU attributes initAttributes(phy_sci_msg.getPhyProcessor()); // Copy SCI message attributes SciMsg::setSciMsgHeader(*phy_sci_msg.getSciMsgHeader()); // Copy PHY SCI message attributes PhySciMsg::setSpecializedSciMsgHeader(phy_sci_msg.getSpecializedSciMsgHeader()); PhySciMsg::setSpecializedSciMsgDataLength(phy_sci_msg.getSpecializedSciMsgDataLength()); PhySciMsg::setSpecializedSciMsgData(phy_sci_msg.getSpecializedSciMsgData()); // Copy PHY SCI message MPDU attributes setMpdu(PhySciMsg::getSpecializedSciMsgDataLength(), PhySciMsg::getSpecializedSciMsgData()); } void PhySciMsgMpdu::initAttributes ( IPhy * p_phy_processor ) { logFunction(); // Create PREAMBLE message mpPre = new PhySciMsgPre(p_phy_processor); if (NULL == mpPre) { throw Error(__PRETTY_FUNCTION__, "PHY SCI message PREAMBLE pointer is NULL"); } // Create FC message mpFc = new PhySciMsgFc(p_phy_processor); if (NULL == mpFc) { throw Error(__PRETTY_FUNCTION__, "PHY SCI message FC pointer is NULL"); } memset(mPbsArray, '\0', MAC_MAX_PB_PER_MPDU*MAC_PB520_BYTES); memset(mPbsHeadersArray, '\0', MAC_MAX_PB_PER_MPDU * sizeof(uint32_t)); // Set PHY SCI message type PhySciMsg::setSpecializedSciMsgType(PHY_TYPE_MPDU_PAYLOAD); } PhySciMsgMpdu::~PhySciMsgMpdu ( ) { logFunction(); if (NULL != mpPayload) { delete [] mpPayload; mpPayload = NULL; } if (NULL != mpPre) { delete (mpPre); mpPre = NULL; } if (NULL != mpFc) { delete (mpFc); mpFc = NULL; } } // // Methods // // Other methods // // public methods // bool PhySciMsgMpdu::segment ( ) { logFunction(); bool bSegment = false; if ( MAC_PB136_BYTES < getPayloadLength() ) // MPDU is composed of 512-octet PBs { // Set PB size bSegment = PhySciMsg::setPbSize(MAC_PB520_BYTES); /* Calculate total number of PBs. */ unsigned short int totalNbOfPbs = getPayloadLength() / PhySciMsg::getPbSize(); if ( 0 != getPayloadLength() % PhySciMsg::getPbSize() ) { totalNbOfPbs++; } if (MAC_MAX_PB_PER_MPDU < totalNbOfPbs) { throw Error(__PRETTY_FUNCTION__, "Total number of PBs exceeds maximum number of PBs per MPDU"); } /* Calculate number of PHY SCI messages needed to transmit all PBs, * and number of PBs to transmit in each PHY SCI message. */ unsigned short int nbOfMsgs = 1; unsigned short int nbOfPbs = totalNbOfPbs; unsigned short int nbOfPbsInLastMsg = totalNbOfPbs; if ( PHY_PB_MAX_NB < totalNbOfPbs ) // MPDU is composed of several PHY SCI messages { nbOfMsgs = totalNbOfPbs / PHY_PB_MAX_NB; nbOfPbs = PHY_PB_MAX_NB; nbOfPbsInLastMsg = totalNbOfPbs % PHY_PB_MAX_NB; if ( 0 != nbOfPbsInLastMsg ) { nbOfMsgs++; } else { nbOfPbsInLastMsg = nbOfPbs; } } // Set number of PHY SCI messages bSegment &= PhySciMsg::setNbOfMsgs(nbOfMsgs); // Set number of PBs bSegment &= PhySciMsg::setNbOfPbs(nbOfPbs); // Set number of PBs into the last PHY SCI message bSegment &= setNbOfPbsInLastMsg(nbOfPbsInLastMsg); // Reset PBs array memset(mPbsArray, '\0', MAC_MAX_PB_PER_MPDU*MAC_PB520_BYTES); // Set PBs array for (int i = 0; i < nbOfMsgs-1; i++) { memcpy(&mPbsArray[i*PHY_PB_MAX_NB*MAC_PB520_BYTES], getPayload()+i*PHY_PB_MAX_NB*MAC_PB520_BYTES, PHY_PB_MAX_NB*MAC_PB520_BYTES); } memcpy(&mPbsArray[(nbOfMsgs-1)*PHY_PB_MAX_NB*MAC_PB520_BYTES], getPayload()+(nbOfMsgs-1)*PHY_PB_MAX_NB*MAC_PB520_BYTES, getPayloadLength()-((nbOfMsgs-1)*PHY_PB_MAX_NB*MAC_PB520_BYTES)); } else // MPDU is composed of one 128-octet PB { // Set PB size bSegment = PhySciMsg::setPbSize(MAC_PB136_BYTES); // Set number of PHY SCI messages bSegment &= PhySciMsg::setNbOfMsgs(1); // Set number of PBs bSegment &= PhySciMsg::setNbOfPbs(1); // Set number of PBs into the last PHY SCI message bSegment &= setNbOfPbsInLastMsg(1); // Set PBs array memcpy(mPbsArray, getPayload(), getPayloadLength()); } return bSegment; } bool PhySciMsgMpdu::prepare ( Network_Clock_Id clock_id ) { logFunction(); bool bPrepare = false; if ((0 == clock_id) || (PhySciMsg::getNbOfMsgs() < clock_id)) { throw Error(__PRETTY_FUNCTION__, "Network Clock ID is out-of-range"); } else if (PhySciMsg::getNbOfMsgs() == clock_id) // This is the last PHY SCI message composing the MPDU { // Set number of PBs bPrepare = PhySciMsg::setNbOfPbs(getNbOfPbsInLastMsg()); // Indicate that MPDU transmission is finished bPrepare &= PhySciMsg::setIsSent(true); } /* For a PHY message of type MPDU_PAYLOAD, * PHY SCI message data only contain MPDU payload * ('nb_of_pbs' PBs of 128 or 512 octets depending on PHY_FLAG_PB512). */ // Set length of PHY SCI message data = PB number * PB size bPrepare = SciMsg::setSpecializedSciMsgDataLength(PhySciMsg::getNbOfPbs()*PhySciMsg::getPbSize()); // Set PHY SCI message data bPrepare &= SciMsg::setSpecializedSciMsgData(getPbs(clock_id-1)); return bPrepare; } // private methods // // protected methods // // Accessor methods // // public attribute accessor methods // // private attribute accessor methods // const unsigned long PhySciMsgMpdu::getPayloadLength ( ) const { return mPayloadLength; } const unsigned char * PhySciMsgMpdu::getPayload ( ) const { if (NULL == mpPayload) { throw Error(__PRETTY_FUNCTION__, "MPDU payload pointer is NULL"); } return mpPayload; } bool PhySciMsgMpdu::setMpdu ( const unsigned long length, const unsigned char * p_payload ) { logFunction(); bool bSetMpdu = false; /* If MPDU payload has already been set, * delete the previous MPDU payload. */ if (NULL != mpPayload) { delete [] mpPayload; mpPayload = NULL; } if ((0 != length) && (NULL != p_payload)) { // Set MPDU payload length mPayloadLength = length; // Allocate and set MPDU payload mpPayload = new unsigned char [length]; bSetMpdu = (NULL != memcpy(mpPayload, p_payload, length)); } else { mPayloadLength = 0; mpPayload = NULL; } return bSetMpdu; } PhySciMsgPre * PhySciMsgMpdu::getPre ( ) const { if (NULL == mpPre) { throw Error(__PRETTY_FUNCTION__, "PHY SCI message PREAMBLE pointer is NULL"); } return mpPre; } PhySciMsgFc * PhySciMsgMpdu::getFc ( ) const { if (NULL == mpFc) { throw Error(__PRETTY_FUNCTION__, "PHY SCI message FC pointer is NULL"); } return mpFc; } const unsigned short int PhySciMsgMpdu::getNbOfPbsInLastMsg ( ) const { if ((0 == mNbOfPbsInLastMsg) || (PHY_PB_MAX_NB < mNbOfPbsInLastMsg)) { throw Error(__PRETTY_FUNCTION__, "Number of PBs into the last PHY SCI message is out-of-range"); } return mNbOfPbsInLastMsg; } bool PhySciMsgMpdu::setNbOfPbsInLastMsg ( const unsigned short int nb_of_pbs_in_last_msg ) { if ( (0 == nb_of_pbs_in_last_msg) || (PHY_PB_MAX_NB < nb_of_pbs_in_last_msg)) { throw Error(__PRETTY_FUNCTION__, "Number of PBs into the last PHY SCI message is out-of-range"); } mNbOfPbsInLastMsg = nb_of_pbs_in_last_msg; return true; } const unsigned char * PhySciMsgMpdu::getPbs ( const unsigned short int n ) const { if (PHY_MSG_MAX_NB_PER_MPDU <= n) { throw Error(__PRETTY_FUNCTION__, "PBs array index exceeds PBs array size"); } return &mPbsArray[n*PHY_PB_MAX_NB*MAC_PB520_BYTES]; } const bool PhySciMsgMpdu::isSent ( ) const { return (PhySciMsg::isSent() || getFc()->isSent()); } const bool PhySciMsgMpdu::isReceived ( const unsigned short int nb_of_received_msgs ) const { return (nb_of_received_msgs == PhySciMsg::getNbOfMsgs()); } bool PhySciMsgMpdu::setFcMode ( const Phy_Fc_Mode fc_mode ) { bool bSetFcMode = false; bSetFcMode = getPre()->setFcMode(fc_mode); bSetFcMode &= getFc()->setFcMode(fc_mode); bSetFcMode &= PhySciMsg::setFcMode(fc_mode); return bSetFcMode; } bool PhySciMsgMpdu::setShortPpdu ( const Phy_Short_Ppdu short_ppdu ) { bool bSetShort; bSetShort = getPre()->setShortPpdu(short_ppdu); bSetShort &= getFc()->setShortPpdu(short_ppdu); bSetShort &= PhySciMsg::setShortPpdu(short_ppdu); return bSetShort; } bool PhySciMsgMpdu::setMod ( const Phy_Mod mod ) { bool bSetMod = false; bSetMod = getPre()->setMod(mod); bSetMod &= getFc()->setMod(mod); bSetMod &= PhySciMsg::setMod(mod); return bSetMod; } bool PhySciMsgMpdu::setFecrate ( const Phy_Fecrate fecrate ) { bool bSetFecrate = false; bSetFecrate = getPre()->setFecrate(fecrate); bSetFecrate &= getFc()->setFecrate(fecrate); bSetFecrate &= PhySciMsg::setFecrate(fecrate); return bSetFecrate; } bool PhySciMsgMpdu::setGil ( const Phy_Gil gil ) { bool bSetGil = false; bSetGil = getPre()->setGil(gil); bSetGil &= getFc()->setGil(gil); bSetGil &= PhySciMsg::setGil(gil); return bSetGil; } bool PhySciMsgMpdu::setFlags ( const Phy_Flags flags ) { bool bSetFlags = false; bSetFlags = getPre()->setFlags(flags); bSetFlags &= getFc()->setFlags(flags); bSetFlags &= PhySciMsg::setFlags(flags); return bSetFlags; } const uint32_t PhySciMsgMpdu::getFc10 ( ) const { return getFc()->getFc10(); } bool PhySciMsgMpdu::setFc10 ( const uint32_t fc_10 ) { return getFc()->setFc10(fc_10); } const uint32_t * PhySciMsgMpdu::getFcAv ( ) const { return getFc()->getFcAv(); } bool PhySciMsgMpdu::setFcAv ( const uint32_t fc_av[4] ) { return getFc()->setFcAv(fc_av); } const uint32_t * PhySciMsgMpdu::getPbsHeaders ( const unsigned short int n ) const { if (PHY_MSG_MAX_NB_PER_MPDU <= n) { throw Error(__PRETTY_FUNCTION__, "PBs Headers array index exceeds PBs Headers array size"); } return &mPbsHeadersArray[n*PHY_PB_MAX_NB]; } bool PhySciMsgMpdu::setPbsHeaders ( const unsigned short int n, const uint32_t pb_header ) { if (MAC_MAX_PB_PER_MPDU <= n) { throw Error(__PRETTY_FUNCTION__, "PB number is out-of-range"); } else { mPbsHeadersArray[n] = pb_header; } return true; } // protected attribute accessor methods //