From 3cabf472d9b867603b9957de84be11496f814d87 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 13 Nov 2011 15:21:58 +0100 Subject: [PATCH] propagate 'nextWriteTime' signal from L1 upwards We drive it via SAPmux through OsmoLogicalChannel up into OsmoThreadMux --- public-trunk/GSM/GSML1FEC.cpp | 7 +++++++ public-trunk/GSM/GSML1FEC.h | 14 +++++++++++++- public-trunk/GSM/GSMSAPMux.h | 3 ++- public-trunk/GSM/Makefile.am | 3 ++- public-trunk/GSM/OsmoLogicalChannel.cpp | 5 +++++ public-trunk/GSM/OsmoLogicalChannel.h | 16 +++++++--------- public-trunk/GSM/OsmoSAPMux.cpp | 6 ++++++ public-trunk/GSM/OsmoSAPMux.h | 4 +++- public-trunk/GSM/OsmoThreadMuxer.cpp | 11 ++++++++--- public-trunk/GSM/OsmoThreadMuxer.h | 14 ++++++++++---- public-trunk/apps/TrueBTS.cpp | 4 +++- 11 files changed, 66 insertions(+), 21 deletions(-) diff --git a/public-trunk/GSM/GSML1FEC.cpp b/public-trunk/GSM/GSML1FEC.cpp index 9d04b86..61e1a3a 100644 --- a/public-trunk/GSM/GSML1FEC.cpp +++ b/public-trunk/GSM/GSML1FEC.cpp @@ -180,6 +180,7 @@ unsigned encodePower(int power) L1Encoder::L1Encoder(unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent) :mDownstream(NULL), + mUpstream(NULL), mMapping(wMapping),mTN(wTN), mTSC(gBTSL1.BCC()), // Note that TSC is hardcoded to the BCC. mParent(wParent), @@ -203,8 +204,14 @@ void L1Encoder::rollForward() mPrevWriteTime = mNextWriteTime; mTotalBursts++; mNextWriteTime.rollForward(mMapping.frameMapping(mTotalBursts),mMapping.repeatLength()); + signalNextWtime(); } +void L1Encoder::signalNextWtime() +{ + if (mUpstream) + mUpstream->signalNextWtime(mNextWriteTime); +} unsigned L1Encoder::ARFCN() const { diff --git a/public-trunk/GSM/GSML1FEC.h b/public-trunk/GSM/GSML1FEC.h index bf402da..01eb9c1 100644 --- a/public-trunk/GSM/GSML1FEC.h +++ b/public-trunk/GSM/GSML1FEC.h @@ -85,6 +85,7 @@ class L1Encoder { ARFCNManager *mDownstream; TxBurst mBurst; ///< a preformatted burst template TxBurst mFillerBurst; ///< the filler burst for this channel + SAPMux *mUpstream; /**@name Config items that don't change. */ //@{ @@ -130,6 +131,14 @@ class L1Encoder { mDownstream=wDownstream; } + /** Set the SAPMux pointer. */ + virtual void upstream(SAPMux *wSapmux) + { + assert(mUpstream==NULL); // Don't call this twice. + mUpstream=wSapmux; + } + + /**@name Accessors. */ //@{ const TDMAMapping& mapping() const { return mMapping; } @@ -165,6 +174,8 @@ class L1Encoder { /** Start the service loop thread, if there is one. */ virtual void start() { mRunning=true; } + void signalNextWtime(); + protected: /** Roll write times forward to the next positions. */ @@ -359,7 +370,8 @@ class L1FEC { /** Attach L1 to an upstream SAPI mux and L2. */ void upstream(SAPMux* mux) - { if (mDecoder) mDecoder->upstream(mux); } + { if (mDecoder) mDecoder->upstream(mux); + if (mEncoder) mEncoder->upstream(mux); } /**@name Ganged actions. */ //@{ diff --git a/public-trunk/GSM/GSMSAPMux.h b/public-trunk/GSM/GSMSAPMux.h index deeb29b..ceab97e 100644 --- a/public-trunk/GSM/GSMSAPMux.h +++ b/public-trunk/GSM/GSMSAPMux.h @@ -65,7 +65,8 @@ class SAPMux { virtual void writeHighSide(const L2Frame& frame); virtual void writeLowSide(const L2Frame& frame); - + virtual void signalNextWtime(GSM::Time &time) {}; + virtual void upstream( L2DL * wUpstream, unsigned wSAPI=0 ) { assert(mUpstream[wSAPI]==NULL); mUpstream[wSAPI]=wUpstream; } void downstream( L1FEC * wDownstream ) diff --git a/public-trunk/GSM/Makefile.am b/public-trunk/GSM/Makefile.am index c73c010..67b74bb 100644 --- a/public-trunk/GSM/Makefile.am +++ b/public-trunk/GSM/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) -AM_CXXFLAGS = -O2 -g +AM_CXXFLAGS = -O0 -g noinst_LTLIBRARIES = libGSML1.la libGSM.la @@ -35,6 +35,7 @@ libGSML1_la_SOURCES = \ GSMSAPMux.cpp \ OsmoSAPMux.cpp \ OsmoLogicalChannel.cpp \ + OsmoThreadMuxer.cpp \ GSMTAPDump.cpp libGSM_la_SOURCES = \ diff --git a/public-trunk/GSM/OsmoLogicalChannel.cpp b/public-trunk/GSM/OsmoLogicalChannel.cpp index b317701..ae10eb4 100644 --- a/public-trunk/GSM/OsmoLogicalChannel.cpp +++ b/public-trunk/GSM/OsmoLogicalChannel.cpp @@ -98,6 +98,11 @@ ostream& GSM::operator<<(ostream& os, const OsmoLogicalChannel& lchan) os << "(" << trx_nr << "," << ts_nr << "," << ss_nr << ")"; } +void OsmoLogicalChannel::signalNextWtime(GSM::Time &time) +{ + if (mTM) + mTM->signalNextWtime(time); +} void OsmoLogicalChannel::downstream(ARFCNManager* radio) { diff --git a/public-trunk/GSM/OsmoLogicalChannel.h b/public-trunk/GSM/OsmoLogicalChannel.h index f385cde..5361f4b 100644 --- a/public-trunk/GSM/OsmoLogicalChannel.h +++ b/public-trunk/GSM/OsmoLogicalChannel.h @@ -84,9 +84,12 @@ protected: unsigned int mTN; OsmoTS *mTS[8]; public: - OsmoTRX(TransceiverManager &TRXmgr, unsigned int trx_nr) { + OsmoTRX(TransceiverManager &TRXmgr, unsigned int trx_nr, + OsmoThreadMuxer *thread_mux) + { mTRXmgr = &TRXmgr; mTN = trx_nr; + mThreadMux = thread_mux; } TransceiverManager *getTRXmgr() const { return mTRXmgr; } @@ -151,6 +154,9 @@ public: unsigned int SSnr() const { return mSS; } //@} + virtual void writeLowSide(const L2Frame& frame); + virtual void signalNextWtime(GSM::Time &time); + /**@name Pass-throughs. */ //@{ @@ -167,14 +173,6 @@ public: mSACCHL1->setPhy(*other.SACCH()); } - //@} - - - /**@name L3 interfaces */ - //@{ - // - virtual void writeLowSide(const L2Frame& frame); - //@} // passthrough /**@name Channel stats from the physical layer */ diff --git a/public-trunk/GSM/OsmoSAPMux.cpp b/public-trunk/GSM/OsmoSAPMux.cpp index eb6009d..652a60e 100644 --- a/public-trunk/GSM/OsmoSAPMux.cpp +++ b/public-trunk/GSM/OsmoSAPMux.cpp @@ -50,6 +50,12 @@ void OsmoSAPMux::writeLowSide(const L2Frame& frame) mLchan->writeLowSide(frame); } +void OsmoSAPMux::signalNextWtime(GSM::Time &time) +{ + assert(mLchan); + mLchan->signalNextWtime(time); +} + void OsmoSAPMux::dispatch() { L2Frame *frame; diff --git a/public-trunk/GSM/OsmoSAPMux.h b/public-trunk/GSM/OsmoSAPMux.h index 240f1f1..b031751 100644 --- a/public-trunk/GSM/OsmoSAPMux.h +++ b/public-trunk/GSM/OsmoSAPMux.h @@ -52,13 +52,15 @@ class OsmoSAPMux : public SAPMux { public: - OsmoSAPMux() { + OsmoSAPMux() + :mLchan(NULL){ } virtual ~OsmoSAPMux() {} virtual void writeHighSide(const L2Frame& frame); virtual void writeLowSide(const L2Frame& frame); + virtual void signalNextWtime(GSM::Time &time); void upstream(OsmoLogicalChannel *lchan) { assert(mLchan == NULL); diff --git a/public-trunk/GSM/OsmoThreadMuxer.cpp b/public-trunk/GSM/OsmoThreadMuxer.cpp index 45e407d..fb28ea5 100644 --- a/public-trunk/GSM/OsmoThreadMuxer.cpp +++ b/public-trunk/GSM/OsmoThreadMuxer.cpp @@ -34,12 +34,17 @@ using namespace std; using namespace GSM; -OsmoThreadMuxer::writeLowSide(const L2Frame& frame, - struct OsmoLogicalChannel *lchan) +void OsmoThreadMuxer::writeLowSide(const L2Frame& frame, + struct OsmoLogicalChannel *lchan) { - OBJLOG(DEEPDEBUG) << "OsmoThreadMuxer::writeLowSide" << lchan << " " << frame; + OBJLOG(INFO) << "OsmoThreadMuxer::writeLowSide" << lchan << " " << frame; /* resolve SAPI, SS, TS, TRX numbers */ /* build primitive that we can put into the up-queue */ } +void OsmoThreadMuxer::signalNextWtime(GSM::Time &time) +{ + OBJLOG(DEBUG) << "NextWriteTime: " << time; +} + // vim: ts=4 sw=4 diff --git a/public-trunk/GSM/OsmoThreadMuxer.h b/public-trunk/GSM/OsmoThreadMuxer.h index 7eb1528..5763dcb 100644 --- a/public-trunk/GSM/OsmoThreadMuxer.h +++ b/public-trunk/GSM/OsmoThreadMuxer.h @@ -30,7 +30,6 @@ namespace GSM { - /* The idea of this monster is to provide an interface between the * heavily multi-threaded OpenBTS architecture and the single-threaded * osmo-bts architecture. @@ -54,7 +53,9 @@ protected: unsigned int mNumTRX; public: - OsmoThreadMuxer() { + OsmoThreadMuxer() + :mNumTRX(0) + { int rc; rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, mSockFd); @@ -64,17 +65,22 @@ public: return mSockFd[1]; } - int addTRX(TransceiverManager &trx_mgr, unsigned int trx_nr) { + OsmoTRX &addTRX(TransceiverManager &trx_mgr, unsigned int trx_nr) { /* for now we only support a single TRX */ assert(mNumTRX == 0); - OsmoTRX *otrx = new OsmoTRX(trx_mgr, trx_nr); + OsmoTRX *otrx = new OsmoTRX(trx_mgr, trx_nr, this); mTRX[mNumTRX++] = otrx; + return *otrx; } /* receive frame synchronously from L1Decoder->OsmoSAPMux and * euqneue it towards osmo-bts */ virtual void writeLowSide(const L2Frame& frame, OsmoLogicalChannel *lchan); + + /* L1 informs us about the next TDMA time for which it needs + * data */ + virtual void signalNextWtime(GSM::Time &time); }; }; // GSM diff --git a/public-trunk/apps/TrueBTS.cpp b/public-trunk/apps/TrueBTS.cpp index 9b0004d..efd3945 100644 --- a/public-trunk/apps/TrueBTS.cpp +++ b/public-trunk/apps/TrueBTS.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -549,7 +550,8 @@ int main(int argc, char *argv[]) // Set Receiver Gain radio->setRxGain(gConfig.getNum("GSM.RxGain")); - OsmoTRX TRX0(gTRX, 0); + OsmoThreadMuxer ThreadMux; + OsmoTRX &TRX0 = ThreadMux.addTRX(gTRX, 0); OsmoComb5TS TS0(TRX0, 0); OsmoComb1TS TS1(TRX0, 1);