aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Transceiver52M/Transceiver.cpp158
-rw-r--r--Transceiver52M/Transceiver.h40
-rw-r--r--Transceiver52M/osmo-trx.cpp1
3 files changed, 124 insertions, 75 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 36cfa7d..d9bda1d 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -45,6 +45,8 @@ extern "C" {
using namespace GSM;
+Transceiver *transceiver;
+
#define USB_LATENCY_INTRVL 10,0
/* Number of running values use in noise average */
@@ -151,20 +153,30 @@ Transceiver::~Transceiver()
close(mClockSocket);
for (size_t i = 0; i < mChans; i++) {
- if (mControlServiceLoopThreads[i]) {
- mControlServiceLoopThreads[i]->cancel();
- mControlServiceLoopThreads[i]->join();
- delete mControlServiceLoopThreads[i];
- }
-
mTxPriorityQueues[i].clear();
- if (mCtrlSockets[i] >= 0)
- close(mCtrlSockets[i]);
if (mDataSockets[i] >= 0)
close(mDataSockets[i]);
}
}
+int Transceiver::ctrl_sock_cb(struct osmo_fd *bfd, unsigned int flags)
+{
+ int rc = 0;
+ int chan = static_cast<int>(reinterpret_cast<uintptr_t>(bfd->data));
+
+ if (flags & OSMO_FD_READ)
+ rc = transceiver->ctrl_sock_handle_rx(chan);
+ if (rc < 0)
+ osmo_signal_dispatch(SS_MAIN, S_MAIN_STOP_REQUIRED, NULL);
+
+ if (flags & OSMO_FD_WRITE)
+ rc = transceiver->ctrl_sock_write(chan);
+ if (rc < 0)
+ osmo_signal_dispatch(SS_MAIN, S_MAIN_STOP_REQUIRED, NULL);
+
+ return rc;
+}
+
/*
* Initialize transceiver
*
@@ -193,8 +205,7 @@ bool Transceiver::init(FillerType filler, size_t rtsc, unsigned rach_delay,
mEdge = edge;
mDataSockets.resize(mChans, -1);
- mCtrlSockets.resize(mChans, -1);
- mControlServiceLoopThreads.resize(mChans);
+ mCtrlSockets.resize(mChans);
mTxPriorityQueueServiceLoopThreads.resize(mChans);
mRxServiceLoopThreads.resize(mChans);
@@ -216,24 +227,34 @@ bool Transceiver::init(FillerType filler, size_t rtsc, unsigned rach_delay,
return false;
for (size_t i = 0; i < mChans; i++) {
+ int rv;
c_srcport = mBasePort + 2 * i + 1;
c_dstport = mBasePort + 2 * i + 101;
d_srcport = mBasePort + 2 * i + 2;
d_dstport = mBasePort + 2 * i + 102;
- mCtrlSockets[i] = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
+ rv = osmo_sock_init2_ofd(&mCtrlSockets[i].conn_bfd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
mLocalAddr.c_str(), c_srcport,
mRemoteAddr.c_str(), c_dstport,
OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT);
- if (mCtrlSockets[i] < 0)
+ if (rv < 0)
return false;
+ mCtrlSockets[i].conn_bfd.cb = ctrl_sock_cb;
+ mCtrlSockets[i].conn_bfd.data = reinterpret_cast<void*>(i);
+
+
mDataSockets[i] = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
mLocalAddr.c_str(), d_srcport,
mRemoteAddr.c_str(), d_dstport,
OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT);
if (mDataSockets[i] < 0)
return false;
+
+ if (i && filler == FILLER_DUMMY)
+ filler = FILLER_ZERO;
+
+ mStates[i].init(filler, mSPSTx, txFullScale, rtsc, rach_delay);
}
/* Randomize the central clock */
@@ -243,21 +264,6 @@ bool Transceiver::init(FillerType filler, size_t rtsc, unsigned rach_delay,
mLastClockUpdateTime = startTime;
mLatencyUpdateTime = startTime;
- /* Start control threads */
- for (size_t i = 0; i < mChans; i++) {
- TrxChanThParams *params = (TrxChanThParams *)malloc(sizeof(struct TrxChanThParams));
- params->trx = this;
- params->num = i;
- mControlServiceLoopThreads[i] = new Thread(stackSize);
- mControlServiceLoopThreads[i]->start((void * (*)(void*))
- ControlServiceLoopAdapter, (void*) params);
-
- if (i && filler == FILLER_DUMMY)
- filler = FILLER_ZERO;
-
- mStates[i].init(filler, mSPSTx, txFullScale, rtsc, rach_delay);
- }
-
return true;
}
@@ -719,8 +725,6 @@ void Transceiver::reset()
}
-#define MAX_PACKET_LENGTH 100
-
/**
* Matches a buffer with a command.
* @param buf a buffer to look command in
@@ -750,27 +754,77 @@ static bool match_cmd(char *buf,
return true;
}
-bool Transceiver::driveControl(size_t chan)
+void Transceiver::ctrl_sock_send(ctrl_msg& m, int chan)
{
- char buffer[MAX_PACKET_LENGTH + 1];
- char response[MAX_PACKET_LENGTH + 1];
+ ctrl_sock_state& s = mCtrlSockets[chan];
+ struct osmo_fd *conn_bfd = &s.conn_bfd;
+
+ s.txmsgqueue.push_back(m);
+ conn_bfd->when |= OSMO_FD_WRITE;
+}
+
+int Transceiver::ctrl_sock_write(int chan)
+{
+ int rc;
+ ctrl_sock_state& s = mCtrlSockets[chan];
+
+ if (s.conn_bfd.fd < 0) {
+ return -EIO;
+ }
+
+ while (s.txmsgqueue.size()) {
+ const ctrl_msg m = s.txmsgqueue.front();
+
+ s.conn_bfd.when &= ~OSMO_FD_WRITE;
+
+ /* try to send it over the socket */
+ rc = write(s.conn_bfd.fd, m.data, strlen(m.data) + 1);
+ if (rc == 0)
+ goto close;
+ if (rc < 0) {
+ if (errno == EAGAIN) {
+ s.conn_bfd.when |= OSMO_FD_WRITE;
+ break;
+ }
+ goto close;
+ }
+
+ s.txmsgqueue.pop_front();
+ }
+ return 0;
+
+close:
+ LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets write(" << s.conn_bfd.fd << ") failed: " << rc;
+ return -1;
+}
+
+int Transceiver::ctrl_sock_handle_rx(int chan)
+{
+ ctrl_msg cmd_received;
+ ctrl_msg cmd_to_send;
+ char *buffer = cmd_received.data;
+ char *response = cmd_to_send.data;
char *command, *params;
int msgLen;
+ ctrl_sock_state& s = mCtrlSockets[chan];
/* Attempt to read from control socket */
- msgLen = read(mCtrlSockets[chan], buffer, MAX_PACKET_LENGTH);
+ msgLen = read(s.conn_bfd.fd, buffer, sizeof(cmd_received.data)-1);
+ if (msgLen < 0 && errno == EAGAIN)
+ return 0; /* Try again later */
if (msgLen <= 0) {
- LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets read(" << mCtrlSockets[chan] << ") failed: " << msgLen;
- return false;
+ LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets read(" << s.conn_bfd.fd << ") failed: " << msgLen;
+ return -EIO;
}
+
/* Zero-terminate received string */
buffer[msgLen] = '\0';
/* Verify a command signature */
if (strncmp(buffer, "CMD ", 4)) {
LOGCHAN(chan, DTRXCTRL, NOTICE) << "bogus message on control interface";
- return false;
+ return -EIO;
}
/* Set command pointer */
@@ -889,7 +943,7 @@ bool Transceiver::driveControl(size_t chan)
if ((timeslot < 0) || (timeslot > 7)) {
LOGCHAN(chan, DTRXCTRL, NOTICE) << "bogus message on control interface";
sprintf(response,"RSP SETSLOT 1 %d %d",timeslot,corrCode);
- return true;
+ return 0;
}
mStates[chan].chanType[timeslot] = (ChannelCombination) corrCode;
setModulus(timeslot, chan);
@@ -921,12 +975,8 @@ bool Transceiver::driveControl(size_t chan)
}
LOGCHAN(chan, DTRXCTRL, INFO) << "response is '" << response << "'";
- msgLen = write(mCtrlSockets[chan], response, strlen(response) + 1);
- if (msgLen <= 0) {
- LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets write(" << mCtrlSockets[chan] << ") failed: " << msgLen;
- return false;
- }
- return true;
+ transceiver->ctrl_sock_send(cmd_to_send, chan);
+ return 0;
}
bool Transceiver::driveTxPriorityQueue(size_t chan)
@@ -1179,28 +1229,6 @@ void *TxLowerLoopAdapter(Transceiver *transceiver)
return NULL;
}
-void *ControlServiceLoopAdapter(TrxChanThParams *params)
-{
- char thread_name[16];
- Transceiver *trx = params->trx;
- size_t num = params->num;
-
- free(params);
-
- snprintf(thread_name, 16, "CtrlService%zu", num);
- set_selfthread_name(thread_name);
-
- while (1) {
- if (!trx->driveControl(num)) {
- LOGCHAN(num, DTRXCTRL, FATAL) << "Something went wrong in thread " << thread_name << ", requesting stop";
- osmo_signal_dispatch(SS_MAIN, S_MAIN_STOP_REQUIRED, NULL);
- break;
- }
- pthread_testcancel();
- }
- return NULL;
-}
-
void *TxUpperLoopAdapter(TrxChanThParams *params)
{
char thread_name[16];
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index ed063dd..6e0d157 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -33,11 +33,14 @@
extern "C" {
#include <osmocom/core/signal.h>
+#include <osmocom/core/select.h>
#include "config_defs.h"
}
class Transceiver;
+extern Transceiver *transceiver;
+
/** Channel descriptor for transceiver object and channel number pair */
struct TrxChanThParams {
Transceiver *trx;
@@ -142,12 +145,33 @@ public:
} ChannelCombination;
private:
+
+struct ctrl_msg {
+ char data[101];
+ ctrl_msg() {};
+};
+
+struct ctrl_sock_state {
+ osmo_fd conn_bfd;
+ std::deque<ctrl_msg> txmsgqueue;
+ ctrl_sock_state() {
+ conn_bfd.fd = -1;
+ }
+ ~ctrl_sock_state() {
+ if(conn_bfd.fd >= 0) {
+ close(conn_bfd.fd);
+ conn_bfd.fd = -1;
+ osmo_fd_unregister(&conn_bfd);
+ }
+ }
+};
+
int mBasePort;
std::string mLocalAddr;
std::string mRemoteAddr;
std::vector<int> mDataSockets; ///< socket for writing to/reading from GSM core
- std::vector<int> mCtrlSockets; ///< socket for writing/reading control commands from GSM core
+ std::vector<ctrl_sock_state> mCtrlSockets; ///< socket for writing/reading control commands from GSM core
int mClockSocket; ///< socket for writing clock updates to GSM core
std::vector<VectorQueue> mTxPriorityQueues; ///< priority queue of transmit bursts received from GSM core
@@ -156,7 +180,6 @@ private:
std::vector<Thread *> mRxServiceLoopThreads; ///< thread to pull bursts into receive FIFO
Thread *mRxLowerLoopThread; ///< thread to pull bursts into receive FIFO
Thread *mTxLowerLoopThread; ///< thread to push bursts into transmit FIFO
- std::vector<Thread *> mControlServiceLoopThreads; ///< thread to process control messages from GSM core
std::vector<Thread *> mTxPriorityQueueServiceLoopThreads; ///< thread to process transmit bursts from GSM core
GSM::Time mTransmitLatency; ///< latency between basestation clock and transmit deadline clock
@@ -193,6 +216,12 @@ private:
/** send messages over the clock socket */
bool writeClockInterface(void);
+ static int ctrl_sock_cb(struct osmo_fd *bfd, unsigned int flags);
+ int ctrl_sock_write(int chan);
+ void ctrl_sock_send(ctrl_msg& m, int chan);
+ /** drive handling of control messages from GSM core */
+ int ctrl_sock_handle_rx(int chan);
+
int mSPSTx; ///< number of samples per Tx symbol
int mSPSRx; ///< number of samples per Rx symbol
size_t mChans;
@@ -229,9 +258,6 @@ protected:
/** drive transmission of GSM bursts */
void driveTxFIFO();
- /** drive handling of control messages from GSM core */
- bool driveControl(size_t chan);
-
/**
drive modulation and sorting of GSM bursts from GSM core
@return true if a burst was transferred successfully
@@ -242,7 +268,6 @@ protected:
friend void *TxUpperLoopAdapter(TrxChanThParams *params);
friend void *RxLowerLoopAdapter(Transceiver *transceiver);
friend void *TxLowerLoopAdapter(Transceiver *transceiver);
- friend void *ControlServiceLoopAdapter(TrxChanThParams *params);
void reset();
@@ -256,8 +281,5 @@ void *RxUpperLoopAdapter(TrxChanThParams *params);
void *RxLowerLoopAdapter(Transceiver *transceiver);
void *TxLowerLoopAdapter(Transceiver *transceiver);
-/** control message handler thread loop */
-void *ControlServiceLoopAdapter(TrxChanThParams *params);
-
/** transmit queueing thread loop */
void *TxUpperLoopAdapter(TrxChanThParams *params);
diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp
index 0ad60ef..9f625eb 100644
--- a/Transceiver52M/osmo-trx.cpp
+++ b/Transceiver52M/osmo-trx.cpp
@@ -79,7 +79,6 @@ static struct ctrl_handle *g_ctrlh;
static RadioDevice *usrp;
static RadioInterface *radio;
-static Transceiver *transceiver;
/* Create radio interface
* The interface consists of sample rate changes, frequency shifts,