/* * Copyright 2008-2010 Free Software Foundation, Inc. * Copyright 2010 Kestrel Signal Processing, Inc. * Copyright 2012 Range Networks, Inc. * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing * information for this specific distribuion. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef GSMCONFIG_H #define GSMCONFIG_H #include "Defines.h" #include #include //#include #include #include #include "GSML3RRElements.h" #include "GSML3CommonElements.h" #include "GSML3RRMessages.h" #include "TRXManager.h" namespace GSM { // From GSM 05.02 6.5. const unsigned sMax_BS_PA_MFRMS = 9; class CCCHLogicalChannel; class SDCCHLogicalChannel; class CBCHLogicalChannel; class TCHFACCHLogicalChannel; class CCCHList : public std::vector {}; class SDCCHList : public std::vector {}; class TCHList : public std::vector {}; /** This object carries the top-level GSM air interface configuration. It serves as a central clearinghouse to get access to everything else in the GSM code. */ class GSMConfig { private: /** The paging mechanism is built-in. */ Control::Pager mPager; PowerManager mPowerManager; mutable Mutex mLock; ///< multithread access control /**@name Groups of CCCH subchannels -- may intersect. */ //@{ CCCHList mAGCHPool; ///< access grant CCCH subchannels CCCHList mPCHPool; ///< paging CCCH subchannels //@} CBCHLogicalChannel* mCBCH; /**@name Allocatable channel pools. */ //@{ SDCCHList mSDCCHPool; TCHList mTCHPool; //@} /**@name BSIC. */ //@{ unsigned mNCC; ///< network color code unsigned mBCC; ///< basestation color code //@} GSMBand mBand; ///< BTS operating band, or 0 for custom band Clock mClock; ///< local copy of BTS master clock /**@name Encoded L2 frames to be sent on the BCCH. */ //@{ L2Frame mSI1Frame; L2Frame mSI2Frame; L2Frame mSI3Frame; L2Frame mSI4Frame; L2Frame mSI13Frame; // pat added for GPRS //@} /**@name Encoded L3 frames to be sent on the SACCH. */ //@{ L3Frame mSI5Frame; L3Frame mSI6Frame; //@} /**@name Copies of system information messages as they were most recently generated. */ //@{ L3SystemInformationType1* mSI1; L3SystemInformationType2* mSI2; L3SystemInformationType3* mSI3; L3SystemInformationType4* mSI4; L3SystemInformationType5* mSI5; L3SystemInformationType6* mSI6; //@} int mT3122; time_t mStartTime; L3LocationAreaIdentity mLAI; bool mHold; ///< If true, do not respond to RACH bursts. InterthreadQueue mChannelRequestQueue; Thread mAccessGrantThread; unsigned mChangemark; void crackPagingFromImsi(unsigned imsiMod1000,unsigned &ccch_group,unsigned &paging_Index);; public: GSMConfig(); /** Initialize with parameters from gConfig. */ void init(); /** Start the internal control loops. */ void start(); /**@name Get references to L2 frames for BCCH SI messages. */ //@{ const L2Frame& SI1Frame() const { return mSI1Frame; } const L2Frame& SI2Frame() const { return mSI2Frame; } const L2Frame& SI3Frame() const { return mSI3Frame; } const L2Frame& SI4Frame() const { return mSI4Frame; } const L2Frame& SI13Frame() const { return mSI13Frame; } // pat added for GPRS //@} /**@name Get references to L3 frames for SACCH SI messages. */ //@{ const L3Frame& SI5Frame() const { return mSI5Frame; } const L3Frame& SI6Frame() const { return mSI6Frame; } //@} /**@name Get the messages themselves. */ //@{ const L3SystemInformationType1* SI1() const { return mSI1; } const L3SystemInformationType2* SI2() const { return mSI2; } const L3SystemInformationType3* SI3() const { return mSI3; } const L3SystemInformationType4* SI4() const { return mSI4; } const L3SystemInformationType5* SI5() const { return mSI5; } const L3SystemInformationType6* SI6() const { return mSI6; } //@} /** Get the current master clock value. */ Time time() const { return mClock.get(); } /**@name Accessors. */ //@{ Control::Pager& pager() { return mPager; } GSMBand band() const { return mBand; } unsigned BCC() const { return mBCC; } unsigned NCC() const { return mNCC; } GSM::Clock& clock() { return mClock; } const L3LocationAreaIdentity& LAI() const { return mLAI; } unsigned changemark() const { return mChangemark; } //@} /** Return the BSIC, NCC:BCC. */ unsigned BSIC() const { return (mNCC<<3) | mBCC; } /** Re-encode the L2Frames for system information messages. Called whenever a beacon parameter is changed. */ void regenerateBeacon(); /** Hold off on channel allocations; don't answer RACH. @param val true to hold, false to clear hold */ void hold(bool val); /** Return true if we are holding off channel allocation. */ bool hold() const; protected: /** Find a minimum-load CCCH from a list. */ CCCHLogicalChannel* minimumLoad(CCCHList &chanList); /** Return the total load of a CCCH list. */ size_t totalLoad(const CCCHList &chanList) const; public: size_t AGCHLoad() { return totalLoad(mAGCHPool); } size_t PCHLoad() { return totalLoad(mPCHPool); } /**@name Manage CCCH subchannels. */ //@{ /** The add method is not mutex protected and should only be used during initialization. */ void addAGCH(CCCHLogicalChannel* wCCCH) { mAGCHPool.push_back(wCCCH); } /** The add method is not mutex protected and should only be used during initialization. */ void addPCH(CCCHLogicalChannel* wCCCH) { mPCHPool.push_back(wCCCH); } /** Return a minimum-load AGCH. */ // (pat) TODO: This strategy needs to change. // There needs to be a common message queue for all CCCH timeslots from which the // FEC can pull the next AGCH message if there is no paging message at that paging slot. // And if someone besides pat works on this, note that gprs also wants // to be able cancel messages after sending them in case conditions have changed, // and also needs to know, a-priori, the exact frame number when the message // is going to be sent, none of which works properly at the moment. CCCHLogicalChannel* getAGCH() { return minimumLoad(mAGCHPool); } #if ENABLE_PAGING_CHANNELS ///< (pat) Send a paging message for the specified imsi. // This function should be used instead of getPCH(), etc. which should then be made private. void sendPCH(const L3RRMessage& msg,unsigned imsiMod1000); ///< (pat) Return the approximate time of the next PCH message for this imsi. // This routine should be elided after DRX mode in GPRS is fixed. Time getPchSendTime(imsiMod1000); ///< (pat) Send a message on the avail AGCH. void sendAGCH(const L3RRMessage& msg); #endif /** Return a minimum-load PCH. */ CCCHLogicalChannel* getPCH() { return minimumLoad(mPCHPool); } /** Return a specific PCH. */ CCCHLogicalChannel* getPCH(size_t index) { assert(index