<p>Hoernchen has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-trx/+/17805">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">transceiver: get rid of the ctrl thread<br><br>There is no need to have n threads handle n ctrl sockets, since they all<br>will immediately respond to commands, so handle them from the existing<br>main osmo select loop.<br><br>Care must be taken to ensure that calls from within the command handler<br>do not block, or at least don't block too long, which currently is the<br>case.<br><br>Change-Id: I642a34451e1825eafecf71a902df916ccee7944c<br>---<br>M Transceiver52M/Transceiver.cpp<br>M Transceiver52M/Transceiver.h<br>M Transceiver52M/osmo-trx.cpp<br>3 files changed, 155 insertions(+), 94 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/05/17805/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp</span><br><span>index dc218d7..da8db75 100644</span><br><span>--- a/Transceiver52M/Transceiver.cpp</span><br><span>+++ b/Transceiver52M/Transceiver.cpp</span><br><span>@@ -45,6 +45,8 @@</span><br><span> </span><br><span> using namespace GSM;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+Transceiver *transceiver;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define USB_LATENCY_INTRVL           10,0</span><br><span> </span><br><span> /* Number of running values use in noise average */</span><br><span>@@ -151,20 +153,28 @@</span><br><span>     close(mClockSocket);</span><br><span> </span><br><span>   for (size_t i = 0; i < mChans; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-    if (mControlServiceLoopThreads[i]) {</span><br><span style="color: hsl(0, 100%, 40%);">-      mControlServiceLoopThreads[i]->cancel();</span><br><span style="color: hsl(0, 100%, 40%);">-      mControlServiceLoopThreads[i]->join();</span><br><span style="color: hsl(0, 100%, 40%);">-      delete mControlServiceLoopThreads[i];</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>     mTxPriorityQueues[i].clear();</span><br><span style="color: hsl(0, 100%, 40%);">-    if (mCtrlSockets[i] >= 0)</span><br><span style="color: hsl(0, 100%, 40%);">-      close(mCtrlSockets[i]);</span><br><span>     if (mDataSockets[i] >= 0)</span><br><span>       close(mDataSockets[i]);</span><br><span>   }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int Transceiver::ctrl_sock_cb(struct osmo_fd *bfd, unsigned int flags)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   int chan = static_cast<int>(reinterpret_cast<uintptr_t>(bfd->data));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (flags & BSC_FD_READ)</span><br><span style="color: hsl(120, 100%, 40%);">+          rc = driveControl(bfd, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (flags & BSC_FD_WRITE)</span><br><span style="color: hsl(120, 100%, 40%);">+         rc = ctrl_sock_write(bfd, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*</span><br><span>  * Initialize transceiver</span><br><span>  *</span><br><span>@@ -193,8 +203,7 @@</span><br><span>   mEdge = edge;</span><br><span> </span><br><span>   mDataSockets.resize(mChans, -1);</span><br><span style="color: hsl(0, 100%, 40%);">-  mCtrlSockets.resize(mChans, -1);</span><br><span style="color: hsl(0, 100%, 40%);">-  mControlServiceLoopThreads.resize(mChans);</span><br><span style="color: hsl(120, 100%, 40%);">+  mCtrlSockets.resize(mChans);</span><br><span>   mTxPriorityQueueServiceLoopThreads.resize(mChans);</span><br><span>   mRxServiceLoopThreads.resize(mChans);</span><br><span> </span><br><span>@@ -221,19 +230,27 @@</span><br><span>     d_srcport = mBasePort + 2 * i + 2;</span><br><span>     d_dstport = mBasePort + 2 * i + 102;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    mCtrlSockets[i] = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,</span><br><span style="color: hsl(120, 100%, 40%);">+    int rv = osmo_sock_init2_ofd(&mCtrlSockets[i].conn_bfd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,</span><br><span>                                       mLocalAddr.c_str(), c_srcport,</span><br><span>                                       mRemoteAddr.c_str(), c_dstport,</span><br><span>                                  OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (mCtrlSockets[i] < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rv < 0)</span><br><span>       return false;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    mCtrlSockets[i].conn_bfd.cb = ctrl_sock_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+    mCtrlSockets[i].conn_bfd.data = reinterpret_cast<void*>(i);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     mDataSockets[i] = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,</span><br><span>                                       mLocalAddr.c_str(), d_srcport,</span><br><span>                                       mRemoteAddr.c_str(), d_dstport,</span><br><span>                                       OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (mCtrlSockets[i] < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+    if (mDataSockets[i] < 0)</span><br><span>       return false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (i && filler == FILLER_DUMMY)</span><br><span style="color: hsl(120, 100%, 40%);">+      filler = FILLER_ZERO;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    mStates[i].init(filler, mSPSTx, txFullScale, rtsc, rach_delay);</span><br><span>   }</span><br><span> </span><br><span>   /* Randomize the central clock */</span><br><span>@@ -243,19 +260,10 @@</span><br><span>   mLastClockUpdateTime = startTime;</span><br><span>   mLatencyUpdateTime = startTime;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /* Start control threads */</span><br><span>   for (size_t i = 0; i < mChans; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-    TrxChanThParams *params = (TrxChanThParams *)malloc(sizeof(struct TrxChanThParams));</span><br><span style="color: hsl(0, 100%, 40%);">-    params->trx = this;</span><br><span style="color: hsl(0, 100%, 40%);">-    params->num = i;</span><br><span style="color: hsl(0, 100%, 40%);">-    mControlServiceLoopThreads[i] = new Thread(stackSize);</span><br><span style="color: hsl(0, 100%, 40%);">-    mControlServiceLoopThreads[i]->start((void * (*)(void*))</span><br><span style="color: hsl(0, 100%, 40%);">-                                 ControlServiceLoopAdapter, (void*) params);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (i && filler == FILLER_DUMMY)</span><br><span style="color: hsl(0, 100%, 40%);">-      filler = FILLER_ZERO;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    mStates[i].init(filler, mSPSTx, txFullScale, rtsc, rach_delay);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (i && filler == FILLER_DUMMY)</span><br><span style="color: hsl(120, 100%, 40%);">+        filler = FILLER_ZERO;</span><br><span style="color: hsl(120, 100%, 40%);">+     mStates[i].init(filler, mSPSTx, txFullScale, rtsc, rach_delay);</span><br><span>   }</span><br><span> </span><br><span>   return true;</span><br><span>@@ -719,8 +727,6 @@</span><br><span> }</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define MAX_PACKET_LENGTH 100</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /**</span><br><span>  * Matches a buffer with a command.</span><br><span>  * @param  buf    a buffer to look command in</span><br><span>@@ -750,19 +756,72 @@</span><br><span>   return true;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-bool Transceiver::driveControl(size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+int Transceiver::ctrl_sock_send(ctrl_msg& m, int chan)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  char buffer[MAX_PACKET_LENGTH + 1];</span><br><span style="color: hsl(0, 100%, 40%);">-  char response[MAX_PACKET_LENGTH + 1];</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_fd *conn_bfd;</span><br><span style="color: hsl(120, 100%, 40%);">+     conn_bfd = &transceiver->mCtrlSockets[chan].conn_bfd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (conn_bfd->fd <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return -EIO;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   transceiver->mCtrlSockets[chan].txmsgqueue.push_back(m);</span><br><span style="color: hsl(120, 100%, 40%);">+   conn_bfd->when |= BSC_FD_WRITE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int Transceiver::ctrl_sock_write(struct osmo_fd *bfd, int chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   while (transceiver->mCtrlSockets[chan].txmsgqueue.size()) {</span><br><span style="color: hsl(120, 100%, 40%);">+                const ctrl_msg m = transceiver->mCtrlSockets[chan].txmsgqueue.front();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           bfd->when &= ~BSC_FD_WRITE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* try to send it over the socket */</span><br><span style="color: hsl(120, 100%, 40%);">+          rc = write(bfd->fd, m.data, strlen(m.data) + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                  goto close;</span><br><span style="color: hsl(120, 100%, 40%);">+           if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (errno == EAGAIN) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                bfd->when |= BSC_FD_WRITE;</span><br><span style="color: hsl(120, 100%, 40%);">+                         break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     goto close;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           transceiver->mCtrlSockets[chan].txmsgqueue.pop_front();</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+close:</span><br><span style="color: hsl(120, 100%, 40%);">+   LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets write(" << transceiver->mCtrlSockets[chan].conn_bfd.fd << ") failed: " << rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_signal_dispatch(SS_MAIN, S_MAIN_STOP_REQUIRED, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool Transceiver::driveControl(struct osmo_fd *bfd, int chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  ctrl_msg cmd_received;</span><br><span style="color: hsl(120, 100%, 40%);">+  ctrl_msg cmd_to_send;</span><br><span style="color: hsl(120, 100%, 40%);">+  char *buffer = cmd_received.data;</span><br><span style="color: hsl(120, 100%, 40%);">+  char *response = cmd_to_send.data;</span><br><span>   char *command, *params;</span><br><span>   int msgLen;</span><br><span> </span><br><span>   /* Attempt to read from control socket */</span><br><span style="color: hsl(0, 100%, 40%);">-  msgLen = read(mCtrlSockets[chan], buffer, MAX_PACKET_LENGTH);</span><br><span style="color: hsl(120, 100%, 40%);">+  msgLen = read(bfd->fd, buffer, sizeof(cmd_received.data));</span><br><span>   if (msgLen <= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-    LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets read(" << mCtrlSockets[chan] << ") failed: " << msgLen;</span><br><span style="color: hsl(0, 100%, 40%);">-    return false;</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets read(" << transceiver->mCtrlSockets[chan].conn_bfd.fd << ") failed: " << msgLen;</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_signal_dispatch(SS_MAIN, S_MAIN_STOP_REQUIRED, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+    return -EIO;</span><br><span>   }</span><br><span style="color: hsl(120, 100%, 40%);">+  if (msgLen < 0 && errno == EAGAIN)</span><br><span style="color: hsl(120, 100%, 40%);">+          return false; /* Try again later */</span><br><span> </span><br><span>   /* Zero-terminate received string */</span><br><span>   buffer[msgLen] = '\0';</span><br><span>@@ -778,16 +837,16 @@</span><br><span>   LOGCHAN(chan, DTRXCTRL, INFO) << "command is '" << command << "'";</span><br><span> </span><br><span>   if (match_cmd(command, "POWEROFF", NULL)) {</span><br><span style="color: hsl(0, 100%, 40%);">-    stop();</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->stop();</span><br><span>     sprintf(response,"RSP POWEROFF 0");</span><br><span>   } else if (match_cmd(command, "POWERON", NULL)) {</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!start()) {</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!transceiver->start()) {</span><br><span>       sprintf(response,"RSP POWERON 1");</span><br><span>     } else {</span><br><span>       sprintf(response,"RSP POWERON 0");</span><br><span>       for (int i = 0; i < 8; i++) {</span><br><span>         for (int j = 0; j < 8; j++)</span><br><span style="color: hsl(0, 100%, 40%);">-          mHandover[i][j] = false;</span><br><span style="color: hsl(120, 100%, 40%);">+          transceiver->mHandover[i][j] = false;</span><br><span>       }</span><br><span>     }</span><br><span>   } else if (match_cmd(command, "HANDOVER", &params)) {</span><br><span>@@ -796,7 +855,7 @@</span><br><span>     if (ts > 7 || ss > 7) {</span><br><span>       sprintf(response, "RSP HANDOVER 1 %u %u", ts, ss);</span><br><span>     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-      mHandover[ts][ss] = true;</span><br><span style="color: hsl(120, 100%, 40%);">+      transceiver->mHandover[ts][ss] = true;</span><br><span>       sprintf(response, "RSP HANDOVER 0 %u %u", ts, ss);</span><br><span>     }</span><br><span>   } else if (match_cmd(command, "NOHANDOVER", &params)) {</span><br><span>@@ -805,32 +864,32 @@</span><br><span>     if (ts > 7 || ss > 7) {</span><br><span>       sprintf(response, "RSP NOHANDOVER 1 %u %u", ts, ss);</span><br><span>     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-      mHandover[ts][ss] = false;</span><br><span style="color: hsl(120, 100%, 40%);">+      transceiver->mHandover[ts][ss] = false;</span><br><span>       sprintf(response, "RSP NOHANDOVER 0 %u %u", ts, ss);</span><br><span>     }</span><br><span>   } else if (match_cmd(command, "SETMAXDLY", &params)) {</span><br><span>     //set expected maximum time-of-arrival</span><br><span>     int maxDelay;</span><br><span>     sscanf(params, "%d", &maxDelay);</span><br><span style="color: hsl(0, 100%, 40%);">-    mMaxExpectedDelayAB = maxDelay; // 1 GSM symbol is approx. 1 km</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->mMaxExpectedDelayAB = maxDelay; // 1 GSM symbol is approx. 1 km</span><br><span>     sprintf(response,"RSP SETMAXDLY 0 %d",maxDelay);</span><br><span>   } else if (match_cmd(command, "SETMAXDLYNB", &params)) {</span><br><span>     //set expected maximum time-of-arrival</span><br><span>     int maxDelay;</span><br><span>     sscanf(params, "%d", &maxDelay);</span><br><span style="color: hsl(0, 100%, 40%);">-    mMaxExpectedDelayNB = maxDelay; // 1 GSM symbol is approx. 1 km</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->mMaxExpectedDelayNB = maxDelay; // 1 GSM symbol is approx. 1 km</span><br><span>     sprintf(response,"RSP SETMAXDLYNB 0 %d",maxDelay);</span><br><span>   } else if (match_cmd(command, "SETRXGAIN", &params)) {</span><br><span>     //set expected maximum time-of-arrival</span><br><span>     int newGain;</span><br><span>     sscanf(params, "%d", &newGain);</span><br><span style="color: hsl(0, 100%, 40%);">-    newGain = mRadioInterface->setRxGain(newGain, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+    newGain =transceiver-> mRadioInterface->setRxGain(newGain, chan);</span><br><span>     sprintf(response,"RSP SETRXGAIN 0 %d",newGain);</span><br><span>   } else if (match_cmd(command, "NOISELEV", NULL)) {</span><br><span style="color: hsl(0, 100%, 40%);">-    if (mOn) {</span><br><span style="color: hsl(0, 100%, 40%);">-      float lev = mStates[chan].mNoiseLev;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (transceiver->mOn) {</span><br><span style="color: hsl(120, 100%, 40%);">+      float lev = transceiver->mStates[chan].mNoiseLev;</span><br><span>       sprintf(response,"RSP NOISELEV 0 %d",</span><br><span style="color: hsl(0, 100%, 40%);">-              (int) round(20.0 * log10(rxFullScale / lev)));</span><br><span style="color: hsl(120, 100%, 40%);">+              (int) round(20.0 * log10(transceiver->rxFullScale / lev)));</span><br><span>     }</span><br><span>     else {</span><br><span>       sprintf(response,"RSP NOISELEV 1  0");</span><br><span>@@ -838,22 +897,22 @@</span><br><span>   } else if (match_cmd(command, "SETPOWER", &params)) {</span><br><span>     int power;</span><br><span>     sscanf(params, "%d", &power);</span><br><span style="color: hsl(0, 100%, 40%);">-    power = mRadioInterface->setPowerAttenuation(power, chan);</span><br><span style="color: hsl(0, 100%, 40%);">-    mStates[chan].mPower = power;</span><br><span style="color: hsl(120, 100%, 40%);">+    power = transceiver->mRadioInterface->setPowerAttenuation(power, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->mStates[chan].mPower = power;</span><br><span>     sprintf(response, "RSP SETPOWER 0 %d", power);</span><br><span>   } else if (match_cmd(command, "ADJPOWER", &params)) {</span><br><span>     int power, step;</span><br><span>     sscanf(params, "%d", &step);</span><br><span style="color: hsl(0, 100%, 40%);">-    power = mStates[chan].mPower + step;</span><br><span style="color: hsl(0, 100%, 40%);">-    power = mRadioInterface->setPowerAttenuation(power, chan);</span><br><span style="color: hsl(0, 100%, 40%);">-    mStates[chan].mPower = power;</span><br><span style="color: hsl(120, 100%, 40%);">+    power = transceiver->mStates[chan].mPower + step;</span><br><span style="color: hsl(120, 100%, 40%);">+    power = transceiver->mRadioInterface->setPowerAttenuation(power, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->mStates[chan].mPower = power;</span><br><span>     sprintf(response, "RSP ADJPOWER 0 %d", power);</span><br><span>   } else if (match_cmd(command, "RXTUNE", &params)) {</span><br><span>     // tune receiver</span><br><span>     int freqKhz;</span><br><span>     sscanf(params, "%d", &freqKhz);</span><br><span style="color: hsl(0, 100%, 40%);">-    mRxFreq = freqKhz * 1e3;</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!mRadioInterface->tuneRx(mRxFreq, chan)) {</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->mRxFreq = freqKhz * 1e3;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!transceiver->mRadioInterface->tuneRx(transceiver->mRxFreq, chan)) {</span><br><span>        LOGCHAN(chan, DTRXCTRL, FATAL) << "RX failed to tune";</span><br><span>        sprintf(response,"RSP RXTUNE 1 %d",freqKhz);</span><br><span>     }</span><br><span>@@ -863,8 +922,8 @@</span><br><span>     // tune txmtr</span><br><span>     int freqKhz;</span><br><span>     sscanf(params, "%d", &freqKhz);</span><br><span style="color: hsl(0, 100%, 40%);">-    mTxFreq = freqKhz * 1e3;</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!mRadioInterface->tuneTx(mTxFreq, chan)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   transceiver-> mTxFreq = freqKhz * 1e3;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!transceiver->mRadioInterface->tuneTx(transceiver->mTxFreq, chan)) {</span><br><span>        LOGCHAN(chan, DTRXCTRL, FATAL) << "TX failed to tune";</span><br><span>        sprintf(response,"RSP TXTUNE 1 %d",freqKhz);</span><br><span>     }</span><br><span>@@ -877,8 +936,8 @@</span><br><span>     if (TSC > 7) {</span><br><span>       sprintf(response, "RSP SETTSC 1 %d", TSC);</span><br><span>     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-      LOGC(DTRXCTRL, NOTICE) << "Changing TSC from " << mTSC << " to " << TSC;</span><br><span style="color: hsl(0, 100%, 40%);">-      mTSC = TSC;</span><br><span style="color: hsl(120, 100%, 40%);">+      LOGC(DTRXCTRL, NOTICE) << "Changing TSC from " << transceiver->mTSC << " to " << TSC;</span><br><span style="color: hsl(120, 100%, 40%);">+      transceiver->mTSC = TSC;</span><br><span>       sprintf(response,"RSP SETTSC 0 %d", TSC);</span><br><span>     }</span><br><span>   } else if (match_cmd(command, "SETSLOT", &params)) {</span><br><span>@@ -891,8 +950,8 @@</span><br><span>       sprintf(response,"RSP SETSLOT 1 %d %d",timeslot,corrCode);</span><br><span>       return true;</span><br><span>     }</span><br><span style="color: hsl(0, 100%, 40%);">-    mStates[chan].chanType[timeslot] = (ChannelCombination) corrCode;</span><br><span style="color: hsl(0, 100%, 40%);">-    setModulus(timeslot, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->mStates[chan].chanType[timeslot] = (ChannelCombination) corrCode;</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->setModulus(timeslot, chan);</span><br><span>     sprintf(response,"RSP SETSLOT 0 %d %d",timeslot,corrCode);</span><br><span>   } else if (match_cmd(command, "SETFORMAT", &params)) {</span><br><span>     // set TRXD protocol version</span><br><span>@@ -905,7 +964,7 @@</span><br><span>       sprintf(response, "RSP SETFORMAT %u %u", TRX_DATA_FORMAT_VER, version_recv);</span><br><span>     } else {</span><br><span>       LOGCHAN(chan, DTRXCTRL, NOTICE) << "switching to TRXD version " << version_recv;</span><br><span style="color: hsl(0, 100%, 40%);">-      mVersionTRXD[chan] = version_recv;</span><br><span style="color: hsl(120, 100%, 40%);">+      transceiver->mVersionTRXD[chan] = version_recv;</span><br><span>       sprintf(response, "RSP SETFORMAT %u %u", version_recv, version_recv);</span><br><span>     }</span><br><span>   } else if (match_cmd(command, "_SETBURSTTODISKMASK", &params)) {</span><br><span>@@ -913,7 +972,7 @@</span><br><span>     // set a mask which bursts to dump to disk</span><br><span>     int mask;</span><br><span>     sscanf(params, "%d", &mask);</span><br><span style="color: hsl(0, 100%, 40%);">-    mWriteBurstToDiskMask = mask;</span><br><span style="color: hsl(120, 100%, 40%);">+    transceiver->mWriteBurstToDiskMask = mask;</span><br><span>     sprintf(response,"RSP _SETBURSTTODISKMASK 0 %d",mask);</span><br><span>   } else {</span><br><span>     LOGCHAN(chan, DTRXCTRL, NOTICE) << "bogus command " << command << " on control interface.";</span><br><span>@@ -921,9 +980,9 @@</span><br><span>   }</span><br><span> </span><br><span>   LOGCHAN(chan, DTRXCTRL, INFO) << "response is '" << response << "'";</span><br><span style="color: hsl(0, 100%, 40%);">-  msgLen = write(mCtrlSockets[chan], response, strlen(response) + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+  msgLen = transceiver->ctrl_sock_send(cmd_to_send, chan);</span><br><span>   if (msgLen <= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-    LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets write(" << mCtrlSockets[chan] << ") failed: " << msgLen;</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGCHAN(chan, DTRXCTRL, NOTICE) << "mCtrlSockets write(" << transceiver->mCtrlSockets[chan].conn_bfd.fd << ") failed: " << msgLen;</span><br><span>     return false;</span><br><span>   }</span><br><span>   return true;</span><br><span>@@ -940,7 +999,7 @@</span><br><span>   // check data socket</span><br><span>   msgLen = read(mDataSockets[chan], buffer, sizeof(buffer));</span><br><span>   if (msgLen <= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-    LOGCHAN(chan, DTRXDDL, NOTICE) << "mDataSockets read(" << mCtrlSockets[chan] << ") failed: " << msgLen;</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGCHAN(chan, DTRXDDL, NOTICE) << "mDataSockets read(" << mDataSockets[chan] << ") failed: " << msgLen;</span><br><span>     return false;</span><br><span>   }</span><br><span> </span><br><span>@@ -1179,28 +1238,6 @@</span><br><span>   return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void *ControlServiceLoopAdapter(TrxChanThParams *params)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  char thread_name[16];</span><br><span style="color: hsl(0, 100%, 40%);">-  Transceiver *trx = params->trx;</span><br><span style="color: hsl(0, 100%, 40%);">-  size_t num = params->num;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  free(params);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  snprintf(thread_name, 16, "CtrlService%zu", num);</span><br><span style="color: hsl(0, 100%, 40%);">-  set_selfthread_name(thread_name);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  while (1) {</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!trx->driveControl(num)) {</span><br><span style="color: hsl(0, 100%, 40%);">-      LOGCHAN(num, DTRXCTRL, FATAL) << "Something went wrong in thread " << thread_name << ", requesting stop";</span><br><span style="color: hsl(0, 100%, 40%);">-      osmo_signal_dispatch(SS_MAIN, S_MAIN_STOP_REQUIRED, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-      break;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-    pthread_testcancel();</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-  return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> void *TxUpperLoopAdapter(TrxChanThParams *params)</span><br><span> {</span><br><span>   char thread_name[16];</span><br><span>diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h</span><br><span>index ed063dd..76416c3 100644</span><br><span>--- a/Transceiver52M/Transceiver.h</span><br><span>+++ b/Transceiver52M/Transceiver.h</span><br><span>@@ -33,11 +33,14 @@</span><br><span> </span><br><span> extern "C" {</span><br><span> #include <osmocom/core/signal.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span> #include "config_defs.h"</span><br><span> }</span><br><span> </span><br><span> class Transceiver;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+extern Transceiver *transceiver;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /** Channel descriptor for transceiver object and channel number pair */</span><br><span> struct TrxChanThParams {</span><br><span>  Transceiver *trx;</span><br><span>@@ -142,12 +145,34 @@</span><br><span>   } ChannelCombination;</span><br><span> </span><br><span> private:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ctrl_msg {</span><br><span style="color: hsl(120, 100%, 40%);">+  char data[101];</span><br><span style="color: hsl(120, 100%, 40%);">+  ctrl_msg() {};</span><br><span style="color: hsl(120, 100%, 40%);">+  ctrl_msg(char* src) {</span><br><span style="color: hsl(120, 100%, 40%);">+         strncpy(data,src,99);</span><br><span style="color: hsl(120, 100%, 40%);">+         data[100] = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ctrl_sock_state {</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_fd conn_bfd;</span><br><span style="color: hsl(120, 100%, 40%);">+  std::deque<ctrl_msg> txmsgqueue;</span><br><span style="color: hsl(120, 100%, 40%);">+  ~ctrl_sock_state() {</span><br><span style="color: hsl(120, 100%, 40%);">+      if(conn_bfd.fd > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          close(conn_bfd.fd);</span><br><span style="color: hsl(120, 100%, 40%);">+          conn_bfd.fd = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_fd_unregister(&conn_bfd);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   int mBasePort;</span><br><span>   std::string mLocalAddr;</span><br><span>   std::string mRemoteAddr;</span><br><span> </span><br><span>   std::vector<int> mDataSockets;  ///< socket for writing to/reading from GSM core</span><br><span style="color: hsl(0, 100%, 40%);">-  std::vector<int> mCtrlSockets;  ///< socket for writing/reading control commands from GSM core</span><br><span style="color: hsl(120, 100%, 40%);">+  std::vector<ctrl_sock_state> mCtrlSockets;  ///< socket for writing/reading control commands from GSM core</span><br><span>   int mClockSocket;               ///< socket for writing clock updates to GSM core</span><br><span> </span><br><span>   std::vector<VectorQueue> mTxPriorityQueues;   ///< priority queue of transmit bursts received from GSM core</span><br><span>@@ -156,7 +181,6 @@</span><br><span>   std::vector<Thread *> mRxServiceLoopThreads;  ///< thread to pull bursts into receive FIFO</span><br><span>   Thread *mRxLowerLoopThread;                   ///< thread to pull bursts into receive FIFO</span><br><span>   Thread *mTxLowerLoopThread;                   ///< thread to push bursts into transmit FIFO</span><br><span style="color: hsl(0, 100%, 40%);">-  std::vector<Thread *> mControlServiceLoopThreads;         ///< thread to process control messages from GSM core</span><br><span>   std::vector<Thread *> mTxPriorityQueueServiceLoopThreads; ///< thread to process transmit bursts from GSM core</span><br><span> </span><br><span>   GSM::Time mTransmitLatency;             ///< latency between basestation clock and transmit deadline clock</span><br><span>@@ -193,6 +217,12 @@</span><br><span>   /** send messages over the clock socket */</span><br><span>   bool writeClockInterface(void);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  static int ctrl_sock_cb(struct osmo_fd *bfd, unsigned int flags);</span><br><span style="color: hsl(120, 100%, 40%);">+  static int ctrl_sock_write(struct osmo_fd *bfd, int chan);</span><br><span style="color: hsl(120, 100%, 40%);">+  static int ctrl_sock_send(ctrl_msg& m, int chan);</span><br><span style="color: hsl(120, 100%, 40%);">+  /** drive handling of control messages from GSM core */</span><br><span style="color: hsl(120, 100%, 40%);">+  static bool driveControl(struct osmo_fd *bfd, int chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   int mSPSTx;                          ///< number of samples per Tx symbol</span><br><span>   int mSPSRx;                          ///< number of samples per Rx symbol</span><br><span>   size_t mChans;</span><br><span>@@ -229,9 +259,6 @@</span><br><span>   /** drive transmission of GSM bursts */</span><br><span>   void driveTxFIFO();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /** drive handling of control messages from GSM core */</span><br><span style="color: hsl(0, 100%, 40%);">-  bool driveControl(size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>   /**</span><br><span>     drive modulation and sorting of GSM bursts from GSM core</span><br><span>     @return true if a burst was transferred successfully</span><br><span>@@ -242,7 +269,7 @@</span><br><span>   friend void *TxUpperLoopAdapter(TrxChanThParams *params);</span><br><span>   friend void *RxLowerLoopAdapter(Transceiver *transceiver);</span><br><span>   friend void *TxLowerLoopAdapter(Transceiver *transceiver);</span><br><span style="color: hsl(0, 100%, 40%);">-  friend void *ControlServiceLoopAdapter(TrxChanThParams *params);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span> </span><br><span>   void reset();</span><br><span>@@ -256,8 +283,5 @@</span><br><span> void *RxLowerLoopAdapter(Transceiver *transceiver);</span><br><span> void *TxLowerLoopAdapter(Transceiver *transceiver);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/** control message handler thread loop */</span><br><span style="color: hsl(0, 100%, 40%);">-void *ControlServiceLoopAdapter(TrxChanThParams *params);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /** transmit queueing thread loop */</span><br><span> void *TxUpperLoopAdapter(TrxChanThParams *params);</span><br><span>diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp</span><br><span>index 0ad60ef..de504c6 100644</span><br><span>--- a/Transceiver52M/osmo-trx.cpp</span><br><span>+++ b/Transceiver52M/osmo-trx.cpp</span><br><span>@@ -79,7 +79,7 @@</span><br><span> </span><br><span> static RadioDevice *usrp;</span><br><span> static RadioInterface *radio;</span><br><span style="color: hsl(0, 100%, 40%);">-static Transceiver *transceiver;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span> /* Create radio interface</span><br><span>  *     The interface consists of sample rate changes, frequency shifts,</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-trx/+/17805">change 17805</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-trx/+/17805"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-trx </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I642a34451e1825eafecf71a902df916ccee7944c </div>
<div style="display:none"> Gerrit-Change-Number: 17805 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Hoernchen <ewild@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>