mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
synced 2025-11-14 10:55:42 +00:00
Compare commits
7 Commits
whytek/ocs
...
fairwaves/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e5520660d | ||
|
|
a7143bf7a1 | ||
|
|
4ffdca10d4 | ||
|
|
1a26b4f085 | ||
|
|
c5d5586fbd | ||
|
|
cc971aa1a6 | ||
|
|
748d8edbf8 |
@@ -73,7 +73,7 @@ static const struct log_info_cat default_categories[] = {
|
||||
.name = "DDEV",
|
||||
.description = "Device/Driver specific code",
|
||||
.color = NULL,
|
||||
.enabled = 1, .loglevel = LOGL_INFO,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DDEVDRV] = {
|
||||
.name = "DDEVDRV",
|
||||
|
||||
@@ -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 (mCtrlSockets[i] < 0)
|
||||
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)
|
||||
@@ -940,7 +990,7 @@ bool Transceiver::driveTxPriorityQueue(size_t chan)
|
||||
// check data socket
|
||||
msgLen = read(mDataSockets[chan], buffer, sizeof(buffer));
|
||||
if (msgLen <= 0) {
|
||||
LOGCHAN(chan, DTRXDDL, NOTICE) << "mDataSockets read(" << mCtrlSockets[chan] << ") failed: " << msgLen;
|
||||
LOGCHAN(chan, DTRXDDL, NOTICE) << "mDataSockets read(" << mDataSockets[chan] << ") failed: " << msgLen;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -51,6 +51,11 @@ AC_PROG_INSTALL
|
||||
AC_PATH_PROG([RM_PROG], [rm])
|
||||
AC_LANG([C++])
|
||||
|
||||
dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang
|
||||
AS_CASE(["$LD"],[*clang*],
|
||||
[AS_CASE(["${host_os}"],
|
||||
[*linux*],[archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'])])
|
||||
|
||||
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
|
||||
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
|
||||
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
|
||||
|
||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,3 +1,9 @@
|
||||
osmo-trx (1.2.0-fw.1) unstable; urgency=medium
|
||||
|
||||
* relocated to master:a7143bf7a12e
|
||||
|
||||
-- Kirill Zakharenko <kirill.zakharenko@fairwaves.co> Fri, 1 May 2020 18:23:29 +0300
|
||||
|
||||
osmo-trx (1.2.0) unstable; urgency=medium
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
|
||||
@@ -12,7 +12,6 @@ line vty
|
||||
trx
|
||||
bind-ip 127.0.0.1
|
||||
remote-ip 127.0.0.1
|
||||
base-port 5700
|
||||
egprs disable
|
||||
tx-sps 4
|
||||
rx-sps 4
|
||||
|
||||
@@ -12,7 +12,6 @@ line vty
|
||||
trx
|
||||
bind-ip 127.0.0.1
|
||||
remote-ip 127.0.0.1
|
||||
base-port 5700
|
||||
egprs disable
|
||||
tx-sps 4
|
||||
rx-sps 4
|
||||
|
||||
@@ -12,7 +12,6 @@ line vty
|
||||
trx
|
||||
bind-ip 127.0.0.1
|
||||
remote-ip 127.0.0.1
|
||||
base-port 5700
|
||||
dev-args addr=192.168.10.2,pa=NONE,pa_power_max_dbm=23,fifo_ctrl_window=0,status_port=12345
|
||||
egprs disable
|
||||
tx-sps 4
|
||||
|
||||
@@ -12,8 +12,10 @@ line vty
|
||||
trx
|
||||
bind-ip 127.0.0.1
|
||||
remote-ip 127.0.0.1
|
||||
base-port 5700
|
||||
egprs disable
|
||||
! 28 dB offset below is valid only for the B2xx in 1800 MHz band, see
|
||||
! https://osmocom.org/issues/4468 for more details
|
||||
rssi-offset 28.000000
|
||||
tx-sps 4
|
||||
rx-sps 4
|
||||
clock-ref external
|
||||
|
||||
Reference in New Issue
Block a user