propagate 'nextWriteTime' signal from L1 upwards
We drive it via SAPmux through OsmoLogicalChannel up into OsmoThreadMuxmaster
parent
086a6a61cb
commit
3cabf472d9
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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. */
|
||||
//@{
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 = \
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <GSMSAPMux.h>
|
||||
#include <GSML3RRMessages.h>
|
||||
#include <OsmoLogicalChannel.h>
|
||||
#include <OsmoThreadMuxer.h>
|
||||
|
||||
#include <Globals.h>
|
||||
|
||||
|
@ -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);
|
||||
|
|
Reference in New Issue