228 lines
6.6 KiB
C++
228 lines
6.6 KiB
C++
/*
|
|
* (C) 2022 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
|
* All Rights Reserved
|
|
*
|
|
* Author: Eric Wild <ewild@sysmocom.de>
|
|
*
|
|
* 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/>.
|
|
*
|
|
*/
|
|
|
|
#include <radioInterface.h>
|
|
#include "ms_rx_upper.h"
|
|
#include "syncthing.h"
|
|
|
|
void upper_trx::driveControl()
|
|
{
|
|
#ifdef IPCIF
|
|
auto m = pop_c();
|
|
if (!m)
|
|
return;
|
|
#else
|
|
TRX_C cmd;
|
|
|
|
socklen_t addr_len = sizeof(ctrlsrc);
|
|
int rdln = recvfrom(mCtrlSockets, (void *)cmd.cmd, sizeof(cmd) - 1, 0, &ctrlsrc, &addr_len);
|
|
if (rdln < 0 && errno == EAGAIN) {
|
|
std::cerr << "fuck, send ctrl?" << std::endl;
|
|
exit(0);
|
|
}
|
|
|
|
TRX_C *m = &cmd;
|
|
#endif
|
|
|
|
auto response = (TRX_C *)malloc(sizeof(TRX_C));
|
|
response->cmd[0] = '\0';
|
|
commandhandler(m->cmd, response->cmd);
|
|
#ifdef IPCIF
|
|
free(m);
|
|
#endif
|
|
std::clog << "response is " << response->cmd << std::endl;
|
|
#ifdef IPCIF
|
|
push_c(response);
|
|
#else
|
|
|
|
int rv = sendto(mCtrlSockets, response, strlen(response->cmd) + 1, 0, &ctrlsrc, sizeof(struct sockaddr_in));
|
|
if (rv < 0) {
|
|
std::cerr << "fuck, rcv ctrl?" << std::endl;
|
|
exit(0);
|
|
}
|
|
free(response);
|
|
|
|
#endif
|
|
}
|
|
|
|
void upper_trx::commandhandler(char *buffer, char *response)
|
|
{
|
|
int MAX_PACKET_LENGTH = TRXC_BUF_SIZE;
|
|
|
|
char cmdcheck[4];
|
|
char command[MAX_PACKET_LENGTH];
|
|
|
|
sscanf(buffer, "%3s %s", cmdcheck, command);
|
|
|
|
if (strcmp(cmdcheck, "CMD") != 0) {
|
|
LOG(WARNING) << "bogus message on control interface";
|
|
return;
|
|
}
|
|
std::clog << "command is " << buffer << std::endl << std::flush;
|
|
|
|
if (strcmp(command, "MEASURE") == 0) {
|
|
msleep(100);
|
|
int freq;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &freq);
|
|
sprintf(response, "RSP MEASURE 0 %d -80", freq);
|
|
} else if (strcmp(command, "ECHO") == 0) {
|
|
msleep(100);
|
|
sprintf(response, "RSP ECHO 0");
|
|
} else if (strcmp(command, "POWEROFF") == 0) {
|
|
set_ta(0);
|
|
// turn off transmitter/demod
|
|
// set_upper_ready(false);
|
|
|
|
sprintf(response, "RSP POWEROFF 0");
|
|
} else if (strcmp(command, "POWERON") == 0) {
|
|
// turn on transmitter/demod
|
|
if (!mTxFreq || !mRxFreq)
|
|
sprintf(response, "RSP POWERON 1");
|
|
else {
|
|
sprintf(response, "RSP POWERON 0");
|
|
if (!mOn) {
|
|
// Prepare for thread start
|
|
mPower = -20;
|
|
// start_ms();
|
|
set_upper_ready(true);
|
|
|
|
writeClockInterface();
|
|
mOn = true;
|
|
}
|
|
}
|
|
} else if (strcmp(command, "SETMAXDLY") == 0) {
|
|
//set expected maximum time-of-arrival
|
|
int maxDelay;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &maxDelay);
|
|
mMaxExpectedDelay = maxDelay; // 1 GSM symbol is approx. 1 km
|
|
sprintf(response, "RSP SETMAXDLY 0 %d", maxDelay);
|
|
} else if (strcmp(command, "SETRXGAIN") == 0) {
|
|
//set expected maximum time-of-arrival
|
|
int newGain;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &newGain);
|
|
newGain = setRxGain(newGain);
|
|
sprintf(response, "RSP SETRXGAIN 0 %d", newGain);
|
|
} else if (strcmp(command, "NOISELEV") == 0) {
|
|
if (mOn) {
|
|
float lev = 0; //mStates[chan].mNoiseLev;
|
|
sprintf(response, "RSP NOISELEV 0 %d", (int)round(20.0 * log10(rxFullScale / lev)));
|
|
} else {
|
|
sprintf(response, "RSP NOISELEV 1 0");
|
|
}
|
|
} else if (!strcmp(command, "SETPOWER")) {
|
|
// set output power in dB
|
|
int dbPwr;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &dbPwr);
|
|
if (!mOn)
|
|
sprintf(response, "RSP SETPOWER 1 %d", dbPwr);
|
|
else {
|
|
mPower = dbPwr;
|
|
setPowerAttenuation(mPower);
|
|
sprintf(response, "RSP SETPOWER 0 %d", dbPwr);
|
|
}
|
|
} else if (!strcmp(command, "ADJPOWER")) {
|
|
// adjust power in dB steps
|
|
int dbStep;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &dbStep);
|
|
if (!mOn)
|
|
sprintf(response, "RSP ADJPOWER 1 %d", mPower);
|
|
else {
|
|
mPower += dbStep;
|
|
setPowerAttenuation(mPower);
|
|
sprintf(response, "RSP ADJPOWER 0 %d", mPower);
|
|
}
|
|
} else if (strcmp(command, "RXTUNE") == 0) {
|
|
// tune receiver
|
|
int freqKhz;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &freqKhz);
|
|
mRxFreq = freqKhz * 1e3;
|
|
if (!tuneRx(mRxFreq)) {
|
|
LOG(ALERT) << "RX failed to tune";
|
|
sprintf(response, "RSP RXTUNE 1 %d", freqKhz);
|
|
} else
|
|
sprintf(response, "RSP RXTUNE 0 %d", freqKhz);
|
|
} else if (strcmp(command, "TXTUNE") == 0) {
|
|
// tune txmtr
|
|
int freqKhz;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &freqKhz);
|
|
mTxFreq = freqKhz * 1e3;
|
|
if (!tuneTx(mTxFreq)) {
|
|
LOG(ALERT) << "TX failed to tune";
|
|
sprintf(response, "RSP TXTUNE 1 %d", freqKhz);
|
|
} else
|
|
sprintf(response, "RSP TXTUNE 0 %d", freqKhz);
|
|
} else if (!strcmp(command, "SETTSC")) {
|
|
// set TSC
|
|
unsigned TSC;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &TSC);
|
|
if (mOn)
|
|
sprintf(response, "RSP SETTSC 1 %d", TSC);
|
|
// else if (chan && (TSC != mTSC))
|
|
// sprintf(response, "RSP SETTSC 1 %d", TSC);
|
|
else {
|
|
mTSC = TSC;
|
|
//generateMidamble(rx_sps, TSC);
|
|
sprintf(response, "RSP SETTSC 0 %d", TSC);
|
|
}
|
|
} else if (!strcmp(command, "GETBSIC")) {
|
|
if (mBSIC < 0)
|
|
sprintf(response, "RSP GETBSIC 1");
|
|
else
|
|
sprintf(response, "RSP GETBSIC 0 %d", mBSIC);
|
|
} else if (strcmp(command, "SETSLOT") == 0) {
|
|
// set TSC
|
|
int corrCode;
|
|
int timeslot;
|
|
sscanf(buffer, "%3s %s %d %d", cmdcheck, command, ×lot, &corrCode);
|
|
if ((timeslot < 0) || (timeslot > 7)) {
|
|
LOG(WARNING) << "bogus message on control interface";
|
|
sprintf(response, "RSP SETSLOT 1 %d %d", timeslot, corrCode);
|
|
return;
|
|
}
|
|
sprintf(response, "RSP SETSLOT 0 %d %d", timeslot, corrCode);
|
|
} else if (!strcmp(command, "SETRXMASK")) {
|
|
int slot;
|
|
unsigned long long mask;
|
|
sscanf(buffer, "%3s %s %d 0x%llx", cmdcheck, command, &slot, &mask);
|
|
if ((slot < 0) || (slot > 7)) {
|
|
sprintf(response, "RSP SETRXMASK 1");
|
|
} else {
|
|
mRxSlotMask[slot] = mask;
|
|
sprintf(response, "RSP SETRXMASK 0 %d 0x%llx", slot, mask);
|
|
}
|
|
} else if (!strcmp(command, "SYNC")) {
|
|
// msleep(10);
|
|
sprintf(response, "RSP SYNC 0");
|
|
mMaxExpectedDelay = 48;
|
|
// setRxGain(30);
|
|
// msleep(10);
|
|
} else if (!strcmp(command, "SETTA")) {
|
|
int ta;
|
|
sscanf(buffer, "%3s %s %d", cmdcheck, command, &ta);
|
|
set_ta(ta);
|
|
sprintf(response, "RSP SETTA 0 %d", ta);
|
|
} else {
|
|
LOG(WARNING) << "bogus command " << command << " on control interface.";
|
|
}
|
|
|
|
//mCtrlSockets[chan]->write(response, strlen(response) + 1);
|
|
}
|