mirror of
https://github.com/RangeNetworks/openbts.git
synced 2025-10-24 00:23:50 +00:00
Adding MultiARFCN support to core.
git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@3688 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
@@ -710,7 +710,7 @@ int rxgain(int argc, char** argv, ostream& os, istream& is)
|
||||
if (argc==1) return SUCCESS;
|
||||
if (argc!=2) return BAD_NUM_ARGS;
|
||||
|
||||
int newGain = gTRX.ARFCN()->setRxGain(atoi(argv[1]));
|
||||
int newGain = gTRX.ARFCN(0)->setRxGain(atoi(argv[1]));
|
||||
os << "new RX gain is " << newGain << " dB" << endl;
|
||||
|
||||
gConfig.set("GSM.Radio.RxGain",newGain);
|
||||
@@ -722,7 +722,7 @@ int noise(int argc, char** argv, ostream& os, istream& is)
|
||||
{
|
||||
if (argc!=1) return BAD_NUM_ARGS;
|
||||
|
||||
int noise = gTRX.ARFCN()->getNoiseLevel();
|
||||
int noise = gTRX.ARFCN(0)->getNoiseLevel();
|
||||
os << "noise RSSI is -" << noise << " dB wrt full scale" << endl;
|
||||
os << "MS RSSI target is " << gConfig.getNum("GSM.Radio.RSSITarget") << " dB wrt full scale" << endl;
|
||||
|
||||
|
||||
@@ -287,18 +287,18 @@ void GSMConfig::createCombination0(TransceiverManager& TRX, unsigned TN)
|
||||
// This should not be applied to C0T0.
|
||||
LOG_ASSERT(TN!=0);
|
||||
LOG(NOTICE) << "Configuring dummy filling on C0T " << TN;
|
||||
ARFCNManager *radio = TRX.ARFCN();
|
||||
ARFCNManager *radio = TRX.ARFCN(0);
|
||||
radio->setSlot(TN,0);
|
||||
}
|
||||
|
||||
|
||||
void GSMConfig::createCombinationI(TransceiverManager& TRX, unsigned TN)
|
||||
void GSMConfig::createCombinationI(TransceiverManager& TRX, unsigned CN, unsigned TN)
|
||||
{
|
||||
LOG_ASSERT(TN!=0);
|
||||
LOG(NOTICE) << "Configuring combination I on C0T" << TN;
|
||||
ARFCNManager *radio = TRX.ARFCN();
|
||||
LOG_ASSERT((CN!=0)||(TN!=0));
|
||||
LOG(NOTICE) << "Configuring combination I on C" << CN << "T" << TN;
|
||||
ARFCNManager *radio = TRX.ARFCN(CN);
|
||||
radio->setSlot(TN,1);
|
||||
TCHFACCHLogicalChannel* chan = new TCHFACCHLogicalChannel(TN,gTCHF_T[TN]);
|
||||
TCHFACCHLogicalChannel* chan = new TCHFACCHLogicalChannel(CN,TN,gTCHF_T[TN]);
|
||||
chan->downstream(radio);
|
||||
Thread* thread = new Thread;
|
||||
thread->start((void*(*)(void*))Control::DCCHDispatcher,chan);
|
||||
@@ -308,14 +308,14 @@ void GSMConfig::createCombinationI(TransceiverManager& TRX, unsigned TN)
|
||||
}
|
||||
|
||||
|
||||
void GSMConfig::createCombinationVII(TransceiverManager& TRX, unsigned TN)
|
||||
void GSMConfig::createCombinationVII(TransceiverManager& TRX, unsigned CN, unsigned TN)
|
||||
{
|
||||
LOG_ASSERT(TN!=0);
|
||||
LOG(NOTICE) << "Configuring combination VII on C0T" << TN;
|
||||
ARFCNManager *radio = TRX.ARFCN();
|
||||
LOG_ASSERT((CN!=0)||(TN!=0));
|
||||
LOG(NOTICE) << "Configuring combination VII on C" << CN << "T" << TN;
|
||||
ARFCNManager *radio = TRX.ARFCN(CN);
|
||||
radio->setSlot(TN,7);
|
||||
for (int i=0; i<8; i++) {
|
||||
SDCCHLogicalChannel* chan = new SDCCHLogicalChannel(TN,gSDCCH8[i]);
|
||||
SDCCHLogicalChannel* chan = new SDCCHLogicalChannel(CN,TN,gSDCCH8[i]);
|
||||
chan->downstream(radio);
|
||||
Thread* thread = new Thread;
|
||||
thread->start((void*(*)(void*))Control::DCCHDispatcher,chan);
|
||||
|
||||
@@ -268,9 +268,9 @@ class GSMConfig {
|
||||
/** Combination 0 is a idle slot, as opposed to a non-transmitting one. */
|
||||
void createCombination0(TransceiverManager &TRX, unsigned TN);
|
||||
/** Combination I is full rate traffic. */
|
||||
void createCombinationI(TransceiverManager &TRX, unsigned TN);
|
||||
void createCombinationI(TransceiverManager &TRX, unsigned CN, unsigned TN);
|
||||
/** Combination VII is 8 SDCCHs. */
|
||||
void createCombinationVII(TransceiverManager &TRX, unsigned TN);
|
||||
void createCombinationVII(TransceiverManager &TRX, unsigned CN, unsigned TN);
|
||||
//@}
|
||||
|
||||
/** Return number of seconds since starting. */
|
||||
|
||||
@@ -181,9 +181,9 @@ unsigned encodePower(int power)
|
||||
*/
|
||||
|
||||
|
||||
L1Encoder::L1Encoder(unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent)
|
||||
L1Encoder::L1Encoder(unsigned wCN, unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent)
|
||||
:mDownstream(NULL),
|
||||
mTN(wTN),
|
||||
mCN(wCN),mTN(wTN),
|
||||
mMapping(wMapping),
|
||||
mTSC(gBTS.BCC()), // Note that TSC is hardcoded to the BCC.
|
||||
mParent(wParent),
|
||||
@@ -192,6 +192,7 @@ L1Encoder::L1Encoder(unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent)
|
||||
mNextWriteTime(gBTS.time().FN(),wTN),
|
||||
mRunning(false),mActive(false)
|
||||
{
|
||||
assert(mCN<gConfig.getNum("GSM.Radio.ARFCNs"));
|
||||
assert(mMapping.allowedSlot(mTN));
|
||||
assert(mMapping.downlink());
|
||||
mNextWriteTime.rollForward(mMapping.frameMapping(0),mMapping.repeatLength());
|
||||
@@ -200,7 +201,7 @@ L1Encoder::L1Encoder(unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent)
|
||||
// Build the descriptive string.
|
||||
ostringstream ss;
|
||||
ss << wMapping.typeAndOffset();
|
||||
sprintf(mDescriptiveString,"C0T%d %s", wTN, ss.str().c_str());
|
||||
sprintf(mDescriptiveString,"C%dT%d %s", wCN, wTN, ss.str().c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -297,6 +298,7 @@ void L1Encoder::sendIdleFill()
|
||||
// For C0, that's the dummy burst.
|
||||
// For Cn, don't do anything.
|
||||
resync();
|
||||
if (mCN!=0) return;
|
||||
for (unsigned i=0; i<mMapping.numFrames(); i++) {
|
||||
mFillerBurst.time(mNextWriteTime);
|
||||
mDownstream->writeHighSide(mFillerBurst);
|
||||
@@ -522,10 +524,11 @@ void RACHL1Decoder::writeLowSide(const RxBurst& burst)
|
||||
|
||||
|
||||
XCCHL1Decoder::XCCHL1Decoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC *wParent)
|
||||
:L1Decoder(wTN,wMapping,wParent),
|
||||
:L1Decoder(wCN,wTN,wMapping,wParent),
|
||||
mBlockCoder(0x10004820009ULL, 40, 224),
|
||||
mC(456), mU(228),
|
||||
mP(mU.segment(184,40)),mDP(mU.head(224)),mD(mU.head(184))
|
||||
@@ -730,10 +733,11 @@ void SACCHL1Decoder::handleGoodFrame()
|
||||
|
||||
|
||||
XCCHL1Encoder::XCCHL1Encoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC* wParent)
|
||||
:L1Encoder(wTN,wMapping,wParent),
|
||||
:L1Encoder(wCN,wTN,wMapping,wParent),
|
||||
mBlockCoder(0x10004820009ULL, 40, 224),
|
||||
mC(456), mU(228),
|
||||
mD(mU.head(184)),mP(mU.segment(184,40))
|
||||
@@ -918,7 +922,7 @@ void GeneratorL1Encoder::serviceLoop()
|
||||
|
||||
|
||||
SCHL1Encoder::SCHL1Encoder(L1FEC* wParent)
|
||||
:GeneratorL1Encoder(0,gSCHMapping,wParent),
|
||||
:GeneratorL1Encoder(0,0,gSCHMapping,wParent),
|
||||
mBlockCoder(0x0575,10,25),
|
||||
mU(25+10+4), mE(78),
|
||||
mD(mU.head(25)),mP(mU.segment(25,10)),
|
||||
@@ -965,7 +969,7 @@ void SCHL1Encoder::generate()
|
||||
|
||||
|
||||
FCCHL1Encoder::FCCHL1Encoder(L1FEC *wParent)
|
||||
:GeneratorL1Encoder(0,gFCCHMapping,wParent)
|
||||
:GeneratorL1Encoder(0,0,gFCCHMapping,wParent)
|
||||
{
|
||||
mBurst.zero();
|
||||
mFillerBurst.zero();
|
||||
@@ -1036,10 +1040,11 @@ void BCCHL1Encoder::generate()
|
||||
|
||||
|
||||
TCHFACCHL1Decoder::TCHFACCHL1Decoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC *wParent)
|
||||
:XCCHL1Decoder(wTN, wMapping, wParent),
|
||||
:XCCHL1Decoder(wCN,wTN, wMapping, wParent),
|
||||
mTCHU(189),mTCHD(260),
|
||||
mClass1_c(mC.head(378)),mClass1A_d(mTCHD.head(50)),mClass2_c(mC.segment(378,78)),
|
||||
mTCHParity(0x0b,3,50)
|
||||
@@ -1241,10 +1246,11 @@ void GSM::TCHFACCHL1EncoderRoutine( TCHFACCHL1Encoder * encoder )
|
||||
|
||||
|
||||
TCHFACCHL1Encoder::TCHFACCHL1Encoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC *wParent)
|
||||
:XCCHL1Encoder(wTN, wMapping, wParent),
|
||||
:XCCHL1Encoder(wCN, wTN, wMapping, wParent),
|
||||
mPreviousFACCH(false),mOffset(0),
|
||||
mTCHU(189),mTCHD(260),
|
||||
mClass1_c(mC.head(378)),mClass1A_d(mTCHD.head(50)),mClass2_d(mTCHD.segment(182,78)),
|
||||
@@ -1525,8 +1531,8 @@ void SACCHL1Encoder::setPhy(const SACCHL1Encoder& other)
|
||||
|
||||
|
||||
|
||||
SACCHL1Encoder::SACCHL1Encoder(unsigned wTN, const TDMAMapping& wMapping, SACCHL1FEC *wParent)
|
||||
:XCCHL1Encoder(wTN,wMapping,(L1FEC*)wParent),
|
||||
SACCHL1Encoder::SACCHL1Encoder(unsigned wCN, unsigned wTN, const TDMAMapping& wMapping, SACCHL1FEC *wParent)
|
||||
:XCCHL1Encoder(wCN,wTN,wMapping,(L1FEC*)wParent),
|
||||
mSACCHParent(wParent),
|
||||
mOrderedMSPower(33),mOrderedMSTiming(0)
|
||||
{ }
|
||||
|
||||
@@ -92,6 +92,7 @@ class L1Encoder {
|
||||
/**@name Config items that don't change. */
|
||||
//@{
|
||||
const TDMAMapping& mMapping; ///< multiplexing description
|
||||
unsigned mCN; ///< carrier index
|
||||
unsigned mTN; ///< timeslot number to use
|
||||
unsigned mTSC; ///< training sequence for this channel
|
||||
L1FEC *mParent; ///< a containing L1FEC, if any
|
||||
@@ -119,11 +120,12 @@ class L1Encoder {
|
||||
|
||||
/**
|
||||
The basic encoder constructor.
|
||||
@param wCN carrier index.
|
||||
@param wTN TDMA timeslot number.
|
||||
@param wMapping TDMA mapping onto the timeslot -- MUST PERSIST.
|
||||
@param wParent The containing L1FEC, for sibling access -- may be NULL.
|
||||
*/
|
||||
L1Encoder(unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent);
|
||||
L1Encoder(unsigned wCN, unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent);
|
||||
|
||||
virtual ~L1Encoder() {}
|
||||
|
||||
@@ -139,6 +141,7 @@ class L1Encoder {
|
||||
const TDMAMapping& mapping() const { return mMapping; }
|
||||
/**@name Components of the channel description. */
|
||||
//@{
|
||||
unsigned CN() const { return mCN; }
|
||||
unsigned TN() const { return mTN; }
|
||||
unsigned TSC() const { return mTSC; }
|
||||
unsigned ARFCN() const;
|
||||
@@ -231,6 +234,7 @@ class L1Decoder {
|
||||
|
||||
/**@name Parameters fixed by the constructor, not requiring mutex protection. */
|
||||
//@{
|
||||
unsigned mCN; ///< carrier index
|
||||
unsigned mTN; ///< timeslot number
|
||||
const TDMAMapping& mMapping; ///< demux parameters
|
||||
L1FEC* mParent; ///< a containing L1 processor, if any
|
||||
@@ -247,13 +251,13 @@ class L1Decoder {
|
||||
@param wMapping Demux parameters, MUST BE PERSISTENT.
|
||||
@param wParent The containing L1FEC, for sibling access.
|
||||
*/
|
||||
L1Decoder(unsigned wTN, const TDMAMapping& wMapping, L1FEC* wParent)
|
||||
L1Decoder(unsigned wCN, unsigned wTN, const TDMAMapping& wMapping, L1FEC* wParent)
|
||||
:mUpstream(NULL),
|
||||
mT3101(T3101ms),mT3109(T3109ms),mT3111(T3111ms),
|
||||
mActive(false),
|
||||
mRunning(false),
|
||||
mFER(0.0F),
|
||||
mTN(wTN),
|
||||
mCN(wCN),mTN(wTN),
|
||||
mMapping(wMapping),mParent(wParent)
|
||||
{
|
||||
// Start T3101 so that the channel will
|
||||
@@ -383,6 +387,9 @@ class L1FEC {
|
||||
unsigned TN() const
|
||||
{ assert(mEncoder); return mEncoder->TN(); }
|
||||
|
||||
unsigned CN() const
|
||||
{ assert(mEncoder); return mEncoder->CN(); }
|
||||
|
||||
unsigned TSC() const
|
||||
{ assert(mEncoder); return mEncoder->TSC(); }
|
||||
|
||||
@@ -458,7 +465,7 @@ class RACHL1Decoder : public L1Decoder {
|
||||
|
||||
RACHL1Decoder(const TDMAMapping &wMapping,
|
||||
L1FEC *wParent)
|
||||
:L1Decoder(0,wMapping,wParent),
|
||||
:L1Decoder(0,0,wMapping,wParent),
|
||||
mParity(0x06f,6,8),mU(18),mD(mU.head(8))
|
||||
{ }
|
||||
|
||||
@@ -500,7 +507,7 @@ class XCCHL1Decoder : public L1Decoder {
|
||||
|
||||
public:
|
||||
|
||||
XCCHL1Decoder(unsigned wTN, const TDMAMapping& wMapping,
|
||||
XCCHL1Decoder(unsigned wCN, unsigned wTN, const TDMAMapping& wMapping,
|
||||
L1FEC *wParent);
|
||||
|
||||
protected:
|
||||
@@ -548,10 +555,11 @@ class SDCCHL1Decoder : public XCCHL1Decoder {
|
||||
public:
|
||||
|
||||
SDCCHL1Decoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC *wParent)
|
||||
:XCCHL1Decoder(wTN,wMapping,wParent)
|
||||
:XCCHL1Decoder(wCN,wTN,wMapping,wParent)
|
||||
{ }
|
||||
|
||||
ChannelType channelType() const { return SDCCHType; }
|
||||
@@ -579,10 +587,11 @@ class SACCHL1Decoder : public XCCHL1Decoder {
|
||||
public:
|
||||
|
||||
SACCHL1Decoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
SACCHL1FEC *wParent)
|
||||
:XCCHL1Decoder(wTN,wMapping,(L1FEC*)wParent),
|
||||
:XCCHL1Decoder(wCN,wTN,wMapping,(L1FEC*)wParent),
|
||||
mSACCHParent(wParent),
|
||||
mRSSICounter(0)
|
||||
{
|
||||
@@ -653,6 +662,7 @@ class XCCHL1Encoder : public L1Encoder {
|
||||
public:
|
||||
|
||||
XCCHL1Encoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC* wParent);
|
||||
@@ -720,7 +730,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
TCHFACCHL1Encoder(unsigned wTN,
|
||||
TCHFACCHL1Encoder(unsigned wCN, unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC* wParent);
|
||||
|
||||
@@ -780,7 +790,7 @@ class TCHFACCHL1Decoder : public XCCHL1Decoder {
|
||||
|
||||
public:
|
||||
|
||||
TCHFACCHL1Decoder(unsigned wTN,
|
||||
TCHFACCHL1Decoder(unsigned wCN, unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC *wParent);
|
||||
|
||||
@@ -836,10 +846,11 @@ class GeneratorL1Encoder : public L1Encoder {
|
||||
public:
|
||||
|
||||
GeneratorL1Encoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC* wParent)
|
||||
:L1Encoder(wTN,wMapping,wParent)
|
||||
:L1Encoder(wCN,wTN,wMapping,wParent)
|
||||
{ }
|
||||
|
||||
void start();
|
||||
@@ -924,10 +935,11 @@ class NDCCHL1Encoder : public XCCHL1Encoder {
|
||||
|
||||
|
||||
NDCCHL1Encoder(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const TDMAMapping& wMapping,
|
||||
L1FEC *wParent)
|
||||
:XCCHL1Encoder(wTN, wMapping, wParent)
|
||||
:XCCHL1Encoder(wCN, wTN, wMapping, wParent)
|
||||
{ }
|
||||
|
||||
void start();
|
||||
@@ -954,7 +966,7 @@ class BCCHL1Encoder : public NDCCHL1Encoder {
|
||||
public:
|
||||
|
||||
BCCHL1Encoder(L1FEC *wParent)
|
||||
:NDCCHL1Encoder(0,gBCCHMapping,wParent)
|
||||
:NDCCHL1Encoder(0,0,gBCCHMapping,wParent)
|
||||
{}
|
||||
|
||||
private:
|
||||
@@ -983,7 +995,7 @@ class SACCHL1Encoder : public XCCHL1Encoder {
|
||||
|
||||
public:
|
||||
|
||||
SACCHL1Encoder(unsigned wTN, const TDMAMapping& wMapping, SACCHL1FEC *wParent);
|
||||
SACCHL1Encoder(unsigned wCN, unsigned wTN, const TDMAMapping& wMapping, SACCHL1FEC *wParent);
|
||||
|
||||
void orderedMSPower(int power) { mOrderedMSPower = power; }
|
||||
void orderedMSTiming(int timing) { mOrderedMSTiming = timing; }
|
||||
@@ -1021,12 +1033,29 @@ class CCCHL1Encoder : public XCCHL1Encoder {
|
||||
|
||||
CCCHL1Encoder(const TDMAMapping& wMapping,
|
||||
L1FEC* wParent)
|
||||
:XCCHL1Encoder(0,wMapping,wParent)
|
||||
:XCCHL1Encoder(0,0,wMapping,wParent)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Cell Broadcast Channel (CBCH). */
|
||||
class CBCHL1Encoder : public XCCHL1Encoder {
|
||||
|
||||
public:
|
||||
|
||||
CBCHL1Encoder(const TDMAMapping& wMapping,
|
||||
L1FEC* wParent)
|
||||
:XCCHL1Encoder(0,0,wMapping,wParent)
|
||||
{}
|
||||
|
||||
/** Override sendFrame to meet sync requirements of GSM 05.02 6.5.4. */
|
||||
virtual void sendFrame(const L2Frame&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1035,12 +1064,13 @@ class SDCCHL1FEC : public L1FEC {
|
||||
public:
|
||||
|
||||
SDCCHL1FEC(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const MappingPair& wMapping)
|
||||
:L1FEC()
|
||||
{
|
||||
mEncoder = new SDCCHL1Encoder(wTN,wMapping.downlink(),this);
|
||||
mDecoder = new SDCCHL1Decoder(wTN,wMapping.uplink(),this);
|
||||
mEncoder = new SDCCHL1Encoder(wCN,wTN,wMapping.downlink(),this);
|
||||
mDecoder = new SDCCHL1Decoder(wCN,wTN,wMapping.uplink(),this);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1049,6 +1079,21 @@ class SDCCHL1FEC : public L1FEC {
|
||||
|
||||
|
||||
|
||||
class CBCHL1FEC : public L1FEC {
|
||||
|
||||
public:
|
||||
|
||||
CBCHL1FEC(const MappingPair& wMapping)
|
||||
:L1FEC()
|
||||
{
|
||||
mEncoder = new CBCHL1Encoder(wMapping.downlink(),this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1065,13 +1110,14 @@ public:
|
||||
|
||||
|
||||
TCHFACCHL1FEC(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const MappingPair& wMapping)
|
||||
:L1FEC()
|
||||
{
|
||||
mTCHEncoder = new TCHFACCHL1Encoder(wTN, wMapping.downlink(), this );
|
||||
mTCHEncoder = new TCHFACCHL1Encoder(wCN, wTN, wMapping.downlink(), this );
|
||||
mEncoder = mTCHEncoder;
|
||||
mTCHDecoder = new TCHFACCHL1Decoder(wTN, wMapping.uplink(), this );
|
||||
mTCHDecoder = new TCHFACCHL1Decoder(wCN, wTN, wMapping.uplink(), this );
|
||||
mDecoder = mTCHDecoder;
|
||||
}
|
||||
|
||||
@@ -1107,13 +1153,14 @@ class SACCHL1FEC : public L1FEC {
|
||||
public:
|
||||
|
||||
SACCHL1FEC(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const MappingPair& wMapping)
|
||||
:L1FEC()
|
||||
{
|
||||
mSACCHEncoder = new SACCHL1Encoder(wTN,wMapping.downlink(),this);
|
||||
mSACCHEncoder = new SACCHL1Encoder(wCN,wTN,wMapping.downlink(),this);
|
||||
mEncoder = mSACCHEncoder;
|
||||
mSACCHDecoder = new SACCHL1Decoder(wTN,wMapping.uplink(),this);
|
||||
mSACCHDecoder = new SACCHL1Decoder(wCN,wTN,wMapping.uplink(),this);
|
||||
mDecoder = mSACCHDecoder;
|
||||
}
|
||||
|
||||
@@ -1142,11 +1189,11 @@ class LoopbackL1FEC : public L1FEC {
|
||||
|
||||
public:
|
||||
|
||||
LoopbackL1FEC(unsigned wTN)
|
||||
LoopbackL1FEC(unsigned wCN, unsigned wTN)
|
||||
:L1FEC()
|
||||
{
|
||||
mEncoder = new XCCHL1Encoder(wTN,gLoopbackTestFullMapping,this);
|
||||
mDecoder = new SDCCHL1Decoder(wTN,gLoopbackTestFullMapping,this);
|
||||
mEncoder = new XCCHL1Encoder(wCN,wTN,gLoopbackTestFullMapping,this);
|
||||
mDecoder = new SDCCHL1Decoder(wCN,wTN,gLoopbackTestFullMapping,this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -163,10 +163,11 @@ L3ChannelDescription LogicalChannel::channelDescription() const
|
||||
|
||||
|
||||
SDCCHLogicalChannel::SDCCHLogicalChannel(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const CompleteMapping& wMapping)
|
||||
{
|
||||
mL1 = new SDCCHL1FEC(wTN,wMapping.LCH());
|
||||
mL1 = new SDCCHL1FEC(wCN,wTN,wMapping.LCH());
|
||||
// SAP0 is RR/MM/CC, SAP3 is SMS
|
||||
// SAP1 and SAP2 are not used.
|
||||
L2LAPDm *SAP0L2 = new SDCCHL2(1,0);
|
||||
@@ -175,7 +176,7 @@ SDCCHLogicalChannel::SDCCHLogicalChannel(
|
||||
SAP3L2->master(SAP0L2);
|
||||
mL2[0] = SAP0L2;
|
||||
mL2[3] = SAP3L2;
|
||||
mSACCH = new SACCHLogicalChannel(wTN,wMapping.SACCH());
|
||||
mSACCH = new SACCHLogicalChannel(wCN,wTN,wMapping.SACCH());
|
||||
connect();
|
||||
}
|
||||
|
||||
@@ -184,11 +185,12 @@ SDCCHLogicalChannel::SDCCHLogicalChannel(
|
||||
|
||||
|
||||
SACCHLogicalChannel::SACCHLogicalChannel(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const MappingPair& wMapping)
|
||||
: mRunning(false)
|
||||
{
|
||||
mSACCHL1 = new SACCHL1FEC(wTN,wMapping);
|
||||
mSACCHL1 = new SACCHL1FEC(wCN,wTN,wMapping);
|
||||
mL1 = mSACCHL1;
|
||||
// SAP0 is RR, SAP3 is SMS
|
||||
// SAP1 and SAP2 are not used.
|
||||
@@ -349,16 +351,17 @@ int LogicalChannel::actualMSTiming() const
|
||||
|
||||
|
||||
TCHFACCHLogicalChannel::TCHFACCHLogicalChannel(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const CompleteMapping& wMapping)
|
||||
{
|
||||
mTCHL1 = new TCHFACCHL1FEC(wTN,wMapping.LCH());
|
||||
mTCHL1 = new TCHFACCHL1FEC(wCN,wTN,wMapping.LCH());
|
||||
mL1 = mTCHL1;
|
||||
// SAP0 is RR/MM/CC, SAP3 is SMS
|
||||
// SAP1 and SAP2 are not used.
|
||||
mL2[0] = new FACCHL2(1,0);
|
||||
mL2[3] = new FACCHL2(1,3);
|
||||
mSACCH = new SACCHLogicalChannel(wTN,wMapping.SACCH());
|
||||
mSACCH = new SACCHLogicalChannel(wCN,wTN,wMapping.SACCH());
|
||||
connect();
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ public:
|
||||
/**@name Channel stats from the physical layer */
|
||||
//@{
|
||||
/** Carrier index. */
|
||||
unsigned CN() const { return 0; }
|
||||
unsigned CN() const { assert(mL1); return mL1->CN(); }
|
||||
/** Slot number. */
|
||||
unsigned TN() const { assert(mL1); return mL1->TN(); }
|
||||
/** Receive FER. */
|
||||
@@ -296,6 +296,7 @@ class SDCCHLogicalChannel : public LogicalChannel {
|
||||
public:
|
||||
|
||||
SDCCHLogicalChannel(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const CompleteMapping& wMapping);
|
||||
|
||||
@@ -360,6 +361,7 @@ class SACCHLogicalChannel : public LogicalChannel {
|
||||
public:
|
||||
|
||||
SACCHLogicalChannel(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const MappingPair& wMapping);
|
||||
|
||||
@@ -466,6 +468,7 @@ class TCHFACCHLogicalChannel : public LogicalChannel {
|
||||
public:
|
||||
|
||||
TCHFACCHLogicalChannel(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const CompleteMapping& wMapping);
|
||||
|
||||
@@ -531,6 +534,7 @@ class SDCCHLogicalChannel_LB : public SDCCHLogicalChannel
|
||||
{
|
||||
public :
|
||||
SDCCHLogicalChannel_LB(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const CompleteMapping& wMapping);
|
||||
};
|
||||
@@ -541,6 +545,7 @@ class TCHFACCHLogicalChannel_UPLINK : public TCHFACCHLogicalChannel
|
||||
public:
|
||||
/** Custom constructor, L2 is Uplink instead of downlink. */
|
||||
TCHFACCHLogicalChannel_UPLINK(
|
||||
unsigned wCN,
|
||||
unsigned wTN,
|
||||
const CompleteMapping& wMapping);
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ void* GSM::PowerManagerServiceLoopAdapter(PowerManager *pm)
|
||||
|
||||
void PowerManager::start()
|
||||
{
|
||||
mRadio = gTRX.ARFCN();
|
||||
mRadio = gTRX.ARFCN(0);
|
||||
mRadio->setPower(mAtten);
|
||||
mThread.start((void*(*)(void*))PowerManagerServiceLoopAdapter,this);
|
||||
}
|
||||
|
||||
@@ -45,12 +45,16 @@ using namespace GSM;
|
||||
using namespace std;
|
||||
|
||||
|
||||
TransceiverManager::TransceiverManager(const char* wTRXAddress, int wBasePort)
|
||||
TransceiverManager::TransceiverManager(int numARFCNs,
|
||||
const char* wTRXAddress, int wBasePort)
|
||||
:mHaveClock(false),
|
||||
mClockSocket(wBasePort+100)
|
||||
{
|
||||
// set up the ARFCN manager
|
||||
mARFCN = new ::ARFCNManager(wTRXAddress,wBasePort+1,*this);
|
||||
// set up the ARFCN managers
|
||||
for (int i=0; i<numARFCNs; i++) {
|
||||
int thisBasePort = wBasePort + 1 + 2*i;
|
||||
mARFCNs.push_back(new ::ARFCNManager(wTRXAddress,thisBasePort,*this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +62,9 @@ TransceiverManager::TransceiverManager(const char* wTRXAddress, int wBasePort)
|
||||
void TransceiverManager::start()
|
||||
{
|
||||
mClockThread.start((void*(*)(void*))ClockLoopAdapter,this);
|
||||
mARFCN->start();
|
||||
for (unsigned i=0; i<mARFCNs.size(); i++) {
|
||||
mARFCNs[i]->start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ class TransceiverManager {
|
||||
|
||||
private:
|
||||
|
||||
/// the ARFCN mananger under this TRX
|
||||
ARFCNManager* mARFCN;
|
||||
/// the ARFCN manangers under this TRX
|
||||
std::vector<ARFCNManager*> mARFCNs;
|
||||
|
||||
/// set true when the first CLOCK packet is received
|
||||
volatile bool mHaveClock;
|
||||
@@ -73,16 +73,23 @@ class TransceiverManager {
|
||||
|
||||
/**
|
||||
Construct a TransceiverManager.
|
||||
@param numARFCNs Number of ARFCNs supported by the transceiver.
|
||||
@param wTRXAddress IP address of the transceiver.
|
||||
@param wBasePort The base port for the interface, as defined in README.TRX.
|
||||
*/
|
||||
TransceiverManager(const char* wTRXAddress, int wBasePort);
|
||||
TransceiverManager(int numARFCNs,
|
||||
const char* wTRXAddress, int wBasePort);
|
||||
|
||||
/**@name Accessors. */
|
||||
//@{
|
||||
ARFCNManager* ARFCN() { return mARFCN; }
|
||||
ARFCNManager* ARFCN(unsigned i) { assert(i<mARFCNs.size()); return mARFCNs.at(i); }
|
||||
//@}
|
||||
|
||||
unsigned numARFCNs() const { return mARFCNs.size(); }
|
||||
|
||||
/** Block until the clock is set over the UDP link. */
|
||||
//void waitForClockInit() const;
|
||||
|
||||
/** Start the clock management thread and all ARFCN managers. */
|
||||
void start();
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ SIP::SIPInterface gSIPInterface;
|
||||
GSMConfig gBTS;
|
||||
|
||||
// Our interface to the software-defined radio.
|
||||
TransceiverManager gTRX(gConfig.getStr("TRX.IP").c_str(), gConfig.getNum("TRX.Port"));
|
||||
TransceiverManager gTRX(gConfig.getNum("GSM.Radio.ARFCNs"), gConfig.getStr("TRX.IP").c_str(), gConfig.getNum("TRX.Port"));
|
||||
|
||||
// Subscriber registry
|
||||
SubscriberRegistry gSubscriberRegistry;
|
||||
@@ -116,7 +116,7 @@ void startTransceiver()
|
||||
// Start the transceiver binary, if the path is defined.
|
||||
// If the path is not defined, the transceiver must be started by some other process.
|
||||
char TRXnumARFCN[4];
|
||||
sprintf(TRXnumARFCN,"%1d",1);
|
||||
sprintf(TRXnumARFCN,"%1d",gConfig.getNum("GSM.Radio.ARFCNs"));
|
||||
LOG(NOTICE) << "starting transceiver " << transceiverPath << " " << TRXnumARFCN;
|
||||
gTransceiverPid = vfork();
|
||||
LOG_ASSERT(gTransceiverPid>=0);
|
||||
@@ -175,17 +175,21 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Set up the interface to the radio.
|
||||
// Get a handle to the C0 transceiver interface.
|
||||
ARFCNManager* C0radio = gTRX.ARFCN();
|
||||
ARFCNManager* C0radio = gTRX.ARFCN(0);
|
||||
|
||||
// Tuning.
|
||||
// Make sure its off for tuning.
|
||||
C0radio->powerOff();
|
||||
// Get the ARFCN list.
|
||||
unsigned C0 = gConfig.getNum("GSM.Radio.C0");
|
||||
// Tune the radio.
|
||||
LOG(INFO) << "tuning TRX to ARFCN " << C0;
|
||||
ARFCNManager* radio = gTRX.ARFCN();
|
||||
radio->tune(C0);
|
||||
unsigned numARFCNs = gConfig.getNum("GSM.Radio.ARFCNs");
|
||||
for (unsigned i=0; i<numARFCNs; i++) {
|
||||
// Tune the radios.
|
||||
unsigned ARFCN = C0 + i*2;
|
||||
LOG(INFO) << "tuning TRX " << i << " to ARFCN " << ARFCN;
|
||||
ARFCNManager* radio = gTRX.ARFCN(i);
|
||||
radio->tune(ARFCN);
|
||||
}
|
||||
|
||||
// Set TSC same as BCC everywhere.
|
||||
C0radio->setTSC(gBTS.BCC());
|
||||
@@ -239,10 +243,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
// C-V C0T0 SDCCHs
|
||||
SDCCHLogicalChannel C0T0SDCCH[4] = {
|
||||
SDCCHLogicalChannel(0,gSDCCH_4_0),
|
||||
SDCCHLogicalChannel(0,gSDCCH_4_1),
|
||||
SDCCHLogicalChannel(0,gSDCCH_4_2),
|
||||
SDCCHLogicalChannel(0,gSDCCH_4_3),
|
||||
SDCCHLogicalChannel(0,0,gSDCCH_4_0),
|
||||
SDCCHLogicalChannel(0,0,gSDCCH_4_1),
|
||||
SDCCHLogicalChannel(0,0,gSDCCH_4_2),
|
||||
SDCCHLogicalChannel(0,0,gSDCCH_4_3),
|
||||
};
|
||||
Thread C0T0SDCCHControlThread[4];
|
||||
for (int i=0; i<4; i++) {
|
||||
@@ -263,21 +267,21 @@ int main(int argc, char *argv[])
|
||||
if (gConfig.defines("GSM.Channels.C1sFirst")) {
|
||||
// Create C-I slots.
|
||||
for (int i=0; i<gConfig.getNum("GSM.Channels.NumC1s"); i++) {
|
||||
gBTS.createCombinationI(gTRX,sCount);
|
||||
gBTS.createCombinationI(gTRX,sCount/8,sCount%8);
|
||||
sCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Create C-VII slots.
|
||||
for (int i=0; i<gConfig.getNum("GSM.Channels.NumC7s"); i++) {
|
||||
gBTS.createCombinationVII(gTRX,sCount);
|
||||
gBTS.createCombinationVII(gTRX,sCount/8,sCount%8);
|
||||
sCount++;
|
||||
}
|
||||
|
||||
if (!gConfig.defines("GSM.Channels.C1sFirst")) {
|
||||
// Create C-I slots.
|
||||
for (int i=0; i<gConfig.getNum("GSM.Channels.NumC1s"); i++) {
|
||||
gBTS.createCombinationI(gTRX,sCount);
|
||||
gBTS.createCombinationI(gTRX,sCount/8,sCount%8);
|
||||
sCount++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user