mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
				synced 2025-11-04 06:03:17 +00:00 
			
		
		
		
	osmo-trx: Add osmo_signal to stop whole transceiver chain correctly on error
Transceiver::stop() can only be called from either CTRL iface thread or from main thread (running osmocom loop). That's because stop attempts to cancel and then join all the other threads, which would then lock if attempting to stop from some of them. As a result, the best option is to indicate to the user of the transceiver option (osmo-trx.cpp) to stop it in a correct fashion by destroying the object from the main thread. Change-Id: Iac1d2dbe2328e735db2d4b933cb67b1af1babca1
This commit is contained in:
		@@ -49,4 +49,5 @@ noinst_HEADERS = \
 | 
				
			|||||||
	Logger.h \
 | 
						Logger.h \
 | 
				
			||||||
	trx_vty.h \
 | 
						trx_vty.h \
 | 
				
			||||||
	debug.h \
 | 
						debug.h \
 | 
				
			||||||
 | 
						osmo_signal.h \
 | 
				
			||||||
	config_defs.h
 | 
						config_defs.h
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										35
									
								
								CommonLibs/osmo_signal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								CommonLibs/osmo_signal.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/* Generic signalling/notification infrastructure */
 | 
				
			||||||
 | 
					/* (C) 2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/signal.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Signalling subsystems */
 | 
				
			||||||
 | 
					enum signal_subsystems {
 | 
				
			||||||
 | 
						SS_TRANSC,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* SS_TRANSC signals */
 | 
				
			||||||
 | 
					enum SS_TRANSC {
 | 
				
			||||||
 | 
						S_TRANSC_STOP_REQUIRED, /* Transceiver fatal error, it should be stopped */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -27,6 +27,10 @@
 | 
				
			|||||||
#include "Transceiver.h"
 | 
					#include "Transceiver.h"
 | 
				
			||||||
#include <Logger.h>
 | 
					#include <Logger.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#include "osmo_signal.h"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_CONFIG_H
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -115,7 +119,7 @@ Transceiver::Transceiver(int wBasePort,
 | 
				
			|||||||
  : mBasePort(wBasePort), mLocalAddr(TRXAddress), mRemoteAddr(GSMcoreAddress),
 | 
					  : mBasePort(wBasePort), mLocalAddr(TRXAddress), mRemoteAddr(GSMcoreAddress),
 | 
				
			||||||
    mClockSocket(TRXAddress, wBasePort, GSMcoreAddress, wBasePort + 100),
 | 
					    mClockSocket(TRXAddress, wBasePort, GSMcoreAddress, wBasePort + 100),
 | 
				
			||||||
    mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
 | 
					    mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
 | 
				
			||||||
    rssiOffset(wRssiOffset),
 | 
					    rssiOffset(wRssiOffset), sig_cbfn(NULL),
 | 
				
			||||||
    mSPSTx(tx_sps), mSPSRx(rx_sps), mChans(chans), mEdge(false), mOn(false), mForceClockInterface(false),
 | 
					    mSPSTx(tx_sps), mSPSRx(rx_sps), mChans(chans), mEdge(false), mOn(false), mForceClockInterface(false),
 | 
				
			||||||
    mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelayAB(0), mMaxExpectedDelayNB(0),
 | 
					    mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelayAB(0), mMaxExpectedDelayNB(0),
 | 
				
			||||||
    mWriteBurstToDiskMask(0)
 | 
					    mWriteBurstToDiskMask(0)
 | 
				
			||||||
@@ -219,6 +223,17 @@ bool Transceiver::init(FillerType filler, size_t rtsc, unsigned rach_delay, bool
 | 
				
			|||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Transceiver::setSignalHandler(osmo_signal_cbfn cbfn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (this->sig_cbfn)
 | 
				
			||||||
 | 
					    osmo_signal_unregister_handler(SS_TRANSC, this->sig_cbfn, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (cbfn) {
 | 
				
			||||||
 | 
					    this->sig_cbfn = cbfn;
 | 
				
			||||||
 | 
					    osmo_signal_register_handler(SS_TRANSC, this->sig_cbfn, NULL);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Start the transceiver
 | 
					 * Start the transceiver
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -885,8 +900,12 @@ bool Transceiver::driveTxPriorityQueue(size_t chan)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Transceiver::driveReceiveRadio()
 | 
					void Transceiver::driveReceiveRadio()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (!mRadioInterface->driveReceiveRadio()) {
 | 
					  int rc = mRadioInterface->driveReceiveRadio();
 | 
				
			||||||
 | 
					  if (rc == 0) {
 | 
				
			||||||
    usleep(100000);
 | 
					    usleep(100000);
 | 
				
			||||||
 | 
					  } else if (rc < 0) {
 | 
				
			||||||
 | 
					    LOG(FATAL) << "radio Interface receive failed, requesting stop.";
 | 
				
			||||||
 | 
					    osmo_signal_dispatch(SS_TRANSC, S_TRANSC_STOP_REQUIRED, this);
 | 
				
			||||||
  } else if (mForceClockInterface || mTransmitDeadlineClock > mLastClockUpdateTime + GSM::Time(216,0)) {
 | 
					  } else if (mForceClockInterface || mTransmitDeadlineClock > mLastClockUpdateTime + GSM::Time(216,0)) {
 | 
				
			||||||
    mForceClockInterface = false;
 | 
					    mForceClockInterface = false;
 | 
				
			||||||
    writeClockInterface();
 | 
					    writeClockInterface();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,6 +31,7 @@
 | 
				
			|||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#include <osmocom/core/signal.h>
 | 
				
			||||||
#include "config_defs.h"
 | 
					#include "config_defs.h"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,6 +129,8 @@ public:
 | 
				
			|||||||
  /** accessor for number of channels */
 | 
					  /** accessor for number of channels */
 | 
				
			||||||
  size_t numChans() const { return mChans; };
 | 
					  size_t numChans() const { return mChans; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setSignalHandler(osmo_signal_cbfn cbfn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Codes for channel combinations */
 | 
					  /** Codes for channel combinations */
 | 
				
			||||||
  typedef enum {
 | 
					  typedef enum {
 | 
				
			||||||
    FILL,               ///< Channel is transmitted, but unused
 | 
					    FILL,               ///< Channel is transmitted, but unused
 | 
				
			||||||
@@ -177,6 +180,8 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  double rssiOffset;                      ///< RSSI to dBm conversion offset
 | 
					  double rssiOffset;                      ///< RSSI to dBm conversion offset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  osmo_signal_cbfn *sig_cbfn;              ///< Registered Signal Handler to announce events.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** modulate and add a burst to the transmit queue */
 | 
					  /** modulate and add a burst to the transmit queue */
 | 
				
			||||||
  void addRadioVector(size_t chan, BitVector &bits,
 | 
					  void addRadioVector(size_t chan, BitVector &bits,
 | 
				
			||||||
                      int RSSI, GSM::Time &wTime);
 | 
					                      int RSSI, GSM::Time &wTime);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,6 +55,7 @@ extern "C" {
 | 
				
			|||||||
#include "convert.h"
 | 
					#include "convert.h"
 | 
				
			||||||
#include "trx_vty.h"
 | 
					#include "trx_vty.h"
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					#include "osmo_signal.h"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEFAULT_CONFIG_FILE	"osmo-trx.cfg"
 | 
					#define DEFAULT_CONFIG_FILE	"osmo-trx.cfg"
 | 
				
			||||||
@@ -112,6 +113,20 @@ RadioInterface *makeRadioInterface(struct trx_ctx *trx,
 | 
				
			|||||||
	return radio;
 | 
						return radio;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Callback function to be called every time we receive a signal from TRANSC */
 | 
				
			||||||
 | 
					static int transc_sig_cb(unsigned int subsys, unsigned int signal,
 | 
				
			||||||
 | 
							     void *handler_data, void *signal_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (signal) {
 | 
				
			||||||
 | 
						case S_TRANSC_STOP_REQUIRED:
 | 
				
			||||||
 | 
							gshutdown = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Create transceiver core
 | 
					/* Create transceiver core
 | 
				
			||||||
 *     The multi-threaded modem core operates at multiples of the GSM rate of
 | 
					 *     The multi-threaded modem core operates at multiples of the GSM rate of
 | 
				
			||||||
 *     270.8333 ksps and consists of GSM specific modulation, demodulation,
 | 
					 *     270.8333 ksps and consists of GSM specific modulation, demodulation,
 | 
				
			||||||
@@ -132,6 +147,8 @@ int makeTransceiver(struct trx_ctx *trx, RadioInterface *radio)
 | 
				
			|||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        transceiver->setSignalHandler(transc_sig_cb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (size_t i = 0; i < trx->cfg.num_chans; i++) {
 | 
						for (size_t i = 0; i < trx->cfg.num_chans; i++) {
 | 
				
			||||||
		fifo = radio->receiveFIFO(i);
 | 
							fifo = radio->receiveFIFO(i);
 | 
				
			||||||
		if (fifo && transceiver->receiveFIFO(fifo, i))
 | 
							if (fifo && transceiver->receiveFIFO(fifo, i))
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user