laforge
/
openbts-osmo
Archived
1
0
Fork 0

propagate 'nextWriteTime' signal from L1 upwards

We drive it via SAPmux through OsmoLogicalChannel up into OsmoThreadMux
This commit is contained in:
Harald Welte 2011-11-13 15:21:58 +01:00
parent 086a6a61cb
commit 3cabf472d9
11 changed files with 66 additions and 21 deletions

View File

@ -180,6 +180,7 @@ unsigned encodePower(int power)
L1Encoder::L1Encoder(unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent) L1Encoder::L1Encoder(unsigned wTN, const TDMAMapping& wMapping, L1FEC *wParent)
:mDownstream(NULL), :mDownstream(NULL),
mUpstream(NULL),
mMapping(wMapping),mTN(wTN), mMapping(wMapping),mTN(wTN),
mTSC(gBTSL1.BCC()), // Note that TSC is hardcoded to the BCC. mTSC(gBTSL1.BCC()), // Note that TSC is hardcoded to the BCC.
mParent(wParent), mParent(wParent),
@ -203,8 +204,14 @@ void L1Encoder::rollForward()
mPrevWriteTime = mNextWriteTime; mPrevWriteTime = mNextWriteTime;
mTotalBursts++; mTotalBursts++;
mNextWriteTime.rollForward(mMapping.frameMapping(mTotalBursts),mMapping.repeatLength()); mNextWriteTime.rollForward(mMapping.frameMapping(mTotalBursts),mMapping.repeatLength());
signalNextWtime();
} }
void L1Encoder::signalNextWtime()
{
if (mUpstream)
mUpstream->signalNextWtime(mNextWriteTime);
}
unsigned L1Encoder::ARFCN() const unsigned L1Encoder::ARFCN() const
{ {

View File

@ -85,6 +85,7 @@ class L1Encoder {
ARFCNManager *mDownstream; ARFCNManager *mDownstream;
TxBurst mBurst; ///< a preformatted burst template TxBurst mBurst; ///< a preformatted burst template
TxBurst mFillerBurst; ///< the filler burst for this channel TxBurst mFillerBurst; ///< the filler burst for this channel
SAPMux *mUpstream;
/**@name Config items that don't change. */ /**@name Config items that don't change. */
//@{ //@{
@ -130,6 +131,14 @@ class L1Encoder {
mDownstream=wDownstream; mDownstream=wDownstream;
} }
/** Set the SAPMux pointer. */
virtual void upstream(SAPMux *wSapmux)
{
assert(mUpstream==NULL); // Don't call this twice.
mUpstream=wSapmux;
}
/**@name Accessors. */ /**@name Accessors. */
//@{ //@{
const TDMAMapping& mapping() const { return mMapping; } const TDMAMapping& mapping() const { return mMapping; }
@ -165,6 +174,8 @@ class L1Encoder {
/** Start the service loop thread, if there is one. */ /** Start the service loop thread, if there is one. */
virtual void start() { mRunning=true; } virtual void start() { mRunning=true; }
void signalNextWtime();
protected: protected:
/** Roll write times forward to the next positions. */ /** Roll write times forward to the next positions. */
@ -359,7 +370,8 @@ class L1FEC {
/** Attach L1 to an upstream SAPI mux and L2. */ /** Attach L1 to an upstream SAPI mux and L2. */
void upstream(SAPMux* mux) void upstream(SAPMux* mux)
{ if (mDecoder) mDecoder->upstream(mux); } { if (mDecoder) mDecoder->upstream(mux);
if (mEncoder) mEncoder->upstream(mux); }
/**@name Ganged actions. */ /**@name Ganged actions. */
//@{ //@{

View File

@ -65,7 +65,8 @@ class SAPMux {
virtual void writeHighSide(const L2Frame& frame); virtual void writeHighSide(const L2Frame& frame);
virtual void writeLowSide(const L2Frame& frame); virtual void writeLowSide(const L2Frame& frame);
virtual void signalNextWtime(GSM::Time &time) {};
virtual void upstream( L2DL * wUpstream, unsigned wSAPI=0 ) virtual void upstream( L2DL * wUpstream, unsigned wSAPI=0 )
{ assert(mUpstream[wSAPI]==NULL); mUpstream[wSAPI]=wUpstream; } { assert(mUpstream[wSAPI]==NULL); mUpstream[wSAPI]=wUpstream; }
void downstream( L1FEC * wDownstream ) void downstream( L1FEC * wDownstream )

View File

@ -21,7 +21,7 @@
include $(top_srcdir)/Makefile.common include $(top_srcdir)/Makefile.common
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
AM_CXXFLAGS = -O2 -g AM_CXXFLAGS = -O0 -g
noinst_LTLIBRARIES = libGSML1.la libGSM.la noinst_LTLIBRARIES = libGSML1.la libGSM.la
@ -35,6 +35,7 @@ libGSML1_la_SOURCES = \
GSMSAPMux.cpp \ GSMSAPMux.cpp \
OsmoSAPMux.cpp \ OsmoSAPMux.cpp \
OsmoLogicalChannel.cpp \ OsmoLogicalChannel.cpp \
OsmoThreadMuxer.cpp \
GSMTAPDump.cpp GSMTAPDump.cpp
libGSM_la_SOURCES = \ libGSM_la_SOURCES = \

View File

@ -98,6 +98,11 @@ ostream& GSM::operator<<(ostream& os, const OsmoLogicalChannel& lchan)
os << "(" << trx_nr << "," << ts_nr << "," << ss_nr << ")"; os << "(" << trx_nr << "," << ts_nr << "," << ss_nr << ")";
} }
void OsmoLogicalChannel::signalNextWtime(GSM::Time &time)
{
if (mTM)
mTM->signalNextWtime(time);
}
void OsmoLogicalChannel::downstream(ARFCNManager* radio) void OsmoLogicalChannel::downstream(ARFCNManager* radio)
{ {

View File

@ -84,9 +84,12 @@ protected:
unsigned int mTN; unsigned int mTN;
OsmoTS *mTS[8]; OsmoTS *mTS[8];
public: public:
OsmoTRX(TransceiverManager &TRXmgr, unsigned int trx_nr) { OsmoTRX(TransceiverManager &TRXmgr, unsigned int trx_nr,
OsmoThreadMuxer *thread_mux)
{
mTRXmgr = &TRXmgr; mTRXmgr = &TRXmgr;
mTN = trx_nr; mTN = trx_nr;
mThreadMux = thread_mux;
} }
TransceiverManager *getTRXmgr() const { return mTRXmgr; } TransceiverManager *getTRXmgr() const { return mTRXmgr; }
@ -151,6 +154,9 @@ public:
unsigned int SSnr() const { return mSS; } unsigned int SSnr() const { return mSS; }
//@} //@}
virtual void writeLowSide(const L2Frame& frame);
virtual void signalNextWtime(GSM::Time &time);
/**@name Pass-throughs. */ /**@name Pass-throughs. */
//@{ //@{
@ -167,14 +173,6 @@ public:
mSACCHL1->setPhy(*other.SACCH()); mSACCHL1->setPhy(*other.SACCH());
} }
//@}
/**@name L3 interfaces */
//@{
//
virtual void writeLowSide(const L2Frame& frame);
//@} // passthrough //@} // passthrough
/**@name Channel stats from the physical layer */ /**@name Channel stats from the physical layer */

View File

@ -50,6 +50,12 @@ void OsmoSAPMux::writeLowSide(const L2Frame& frame)
mLchan->writeLowSide(frame); mLchan->writeLowSide(frame);
} }
void OsmoSAPMux::signalNextWtime(GSM::Time &time)
{
assert(mLchan);
mLchan->signalNextWtime(time);
}
void OsmoSAPMux::dispatch() void OsmoSAPMux::dispatch()
{ {
L2Frame *frame; L2Frame *frame;

View File

@ -52,13 +52,15 @@ class OsmoSAPMux : public SAPMux {
public: public:
OsmoSAPMux() { OsmoSAPMux()
:mLchan(NULL){
} }
virtual ~OsmoSAPMux() {} virtual ~OsmoSAPMux() {}
virtual void writeHighSide(const L2Frame& frame); virtual void writeHighSide(const L2Frame& frame);
virtual void writeLowSide(const L2Frame& frame); virtual void writeLowSide(const L2Frame& frame);
virtual void signalNextWtime(GSM::Time &time);
void upstream(OsmoLogicalChannel *lchan) { void upstream(OsmoLogicalChannel *lchan) {
assert(mLchan == NULL); assert(mLchan == NULL);

View File

@ -34,12 +34,17 @@ using namespace std;
using namespace GSM; using namespace GSM;
OsmoThreadMuxer::writeLowSide(const L2Frame& frame, void OsmoThreadMuxer::writeLowSide(const L2Frame& frame,
struct OsmoLogicalChannel *lchan) struct OsmoLogicalChannel *lchan)
{ {
OBJLOG(DEEPDEBUG) << "OsmoThreadMuxer::writeLowSide" << lchan << " " << frame; OBJLOG(INFO) << "OsmoThreadMuxer::writeLowSide" << lchan << " " << frame;
/* resolve SAPI, SS, TS, TRX numbers */ /* resolve SAPI, SS, TS, TRX numbers */
/* build primitive that we can put into the up-queue */ /* 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 // vim: ts=4 sw=4

View File

@ -30,7 +30,6 @@
namespace GSM { namespace GSM {
/* The idea of this monster is to provide an interface between the /* The idea of this monster is to provide an interface between the
* heavily multi-threaded OpenBTS architecture and the single-threaded * heavily multi-threaded OpenBTS architecture and the single-threaded
* osmo-bts architecture. * osmo-bts architecture.
@ -54,7 +53,9 @@ protected:
unsigned int mNumTRX; unsigned int mNumTRX;
public: public:
OsmoThreadMuxer() { OsmoThreadMuxer()
:mNumTRX(0)
{
int rc; int rc;
rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, mSockFd); rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, mSockFd);
@ -64,17 +65,22 @@ public:
return mSockFd[1]; 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 */ /* for now we only support a single TRX */
assert(mNumTRX == 0); assert(mNumTRX == 0);
OsmoTRX *otrx = new OsmoTRX(trx_mgr, trx_nr); OsmoTRX *otrx = new OsmoTRX(trx_mgr, trx_nr, this);
mTRX[mNumTRX++] = otrx; mTRX[mNumTRX++] = otrx;
return *otrx;
} }
/* receive frame synchronously from L1Decoder->OsmoSAPMux and /* receive frame synchronously from L1Decoder->OsmoSAPMux and
* euqneue it towards osmo-bts */ * euqneue it towards osmo-bts */
virtual void writeLowSide(const L2Frame& frame, virtual void writeLowSide(const L2Frame& frame,
OsmoLogicalChannel *lchan); OsmoLogicalChannel *lchan);
/* L1 informs us about the next TDMA time for which it needs
* data */
virtual void signalNextWtime(GSM::Time &time);
}; };
}; // GSM }; // GSM

View File

@ -31,6 +31,7 @@
#include <GSMSAPMux.h> #include <GSMSAPMux.h>
#include <GSML3RRMessages.h> #include <GSML3RRMessages.h>
#include <OsmoLogicalChannel.h> #include <OsmoLogicalChannel.h>
#include <OsmoThreadMuxer.h>
#include <Globals.h> #include <Globals.h>
@ -549,7 +550,8 @@ int main(int argc, char *argv[])
// Set Receiver Gain // Set Receiver Gain
radio->setRxGain(gConfig.getNum("GSM.RxGain")); radio->setRxGain(gConfig.getNum("GSM.RxGain"));
OsmoTRX TRX0(gTRX, 0); OsmoThreadMuxer ThreadMux;
OsmoTRX &TRX0 = ThreadMux.addTRX(gTRX, 0);
OsmoComb5TS TS0(TRX0, 0); OsmoComb5TS TS0(TRX0, 0);
OsmoComb1TS TS1(TRX0, 1); OsmoComb1TS TS1(TRX0, 1);