diff options
Diffstat (limited to 'Transceiver52M')
-rw-r--r-- | Transceiver52M/Transceiver.cpp | 158 | ||||
-rw-r--r-- | Transceiver52M/Transceiver.h | 40 | ||||
-rw-r--r-- | Transceiver52M/osmo-trx.cpp | 1 |
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, |