mirror of
https://github.com/fairwaves/OpenBTS-UMTS.git
synced 2025-10-23 07:41:59 +00:00
Supported devices includes USRP N200/N210/USRP2, B200/B210, X300/X310. Other Ettus devices are not supported due to bandwidth limitations. There is no direct embedded device support at this time. The UHD transceiver device operating rate is fixed at 6.25 Msps, which interfaces with the UMTS chip rate of 3.84 Mcps through a combined polyphase resampling and RRC pulse-shaping filterbank. The effective oversampling factor is approximate 1.63 samples per symbol. Tested against Agilent 89600 VSA for appropriate EVM and ACP values. Signed-off-by: Tom Tsou <tom@tsou.cc>
224 lines
5.6 KiB
C++
224 lines
5.6 KiB
C++
/*
|
|
* OpenBTS provides an open source alternative to legacy telco protocols and
|
|
* traditionally complex, proprietary hardware systems.
|
|
*
|
|
* Copyright 2008, 2009 Free Software Foundation, Inc.
|
|
* Copyright 2010 Kestrel Signal Processing, Inc.
|
|
* Copyright 2014 Range Networks, Inc.
|
|
*
|
|
* This software is distributed under the terms of the GNU General Public
|
|
* License version 3. See the COPYING and NOTICE files in the current
|
|
* directory for licensing information.
|
|
*
|
|
* This use of this software may be subject to additional restrictions.
|
|
* See the LEGAL file in the main directory for details.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <signal.h>
|
|
#include <Logger.h>
|
|
#include <UMTSCommon.h>
|
|
#include <Configuration.h>
|
|
|
|
#include "Transceiver.h"
|
|
#include "UHDDevice.h"
|
|
|
|
/* Default maximum expected delay spread in symbols */
|
|
#define DEFAULT_MAX_DELAY 50
|
|
|
|
/* Sample rate for all devices */
|
|
#define DEVICE_RATE 6.25e6
|
|
|
|
ConfigurationKeyMap getConfigurationKeys2();
|
|
ConfigurationTable gConfig("/etc/OpenBTS/OpenBTS-UMTS.db",
|
|
"transceiver", getConfigurationKeys2());
|
|
|
|
volatile bool gbShutdown = false;
|
|
|
|
static void shutdown_handler(int signo)
|
|
{
|
|
std::cout << std::endl << "** Received shutdown signal" << std::endl;
|
|
gbShutdown = true;
|
|
}
|
|
|
|
static void register_signal_handlers()
|
|
{
|
|
if (signal(SIGINT, shutdown_handler) == SIG_ERR) {
|
|
std::cerr << "** Failed to install SIGINT signal handler" << std::endl;
|
|
exit(1);
|
|
}
|
|
|
|
if (signal(SIGTERM, shutdown_handler) == SIG_ERR) {
|
|
std::cerr << "** Failed to install SIGTERM signal handler" << std::endl;
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/* Logging check in the configuration is mandatory */
|
|
static bool init_config()
|
|
{
|
|
try {
|
|
std::cout << "** Configuring logger" << std::endl;
|
|
gLogInit("transceiver", gConfig.getStr("Log.Level").c_str(), LOG_LOCAL7);
|
|
} catch (ConfigurationTableKeyNotFound e) {
|
|
LOG(EMERG) << "** Required configuration parameter " << e.key()
|
|
<< " not defined, aborting";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* Optional expected delay spread (default 50 symbols) */
|
|
static int init_max_delay()
|
|
{
|
|
int max_delay;
|
|
|
|
try {
|
|
max_delay = gConfig.getNum("UMTS.Radio.MaxExpectedDelaySpread");
|
|
} catch (ConfigurationTableKeyNotFound e) {
|
|
max_delay = DEFAULT_MAX_DELAY;
|
|
}
|
|
|
|
return max_delay;
|
|
}
|
|
|
|
/* Optional external reference enable (default off) */
|
|
static bool init_extref()
|
|
{
|
|
int enable;
|
|
|
|
try {
|
|
enable = gConfig.getNum("TRX.Reference");
|
|
} catch (ConfigurationTableKeyNotFound e) {
|
|
enable = 0;
|
|
}
|
|
|
|
return enable != 0;
|
|
}
|
|
|
|
/* Optional device hint (default none) */
|
|
static std::string init_devaddr()
|
|
{
|
|
std::string addr;
|
|
|
|
try {
|
|
addr = gConfig.getNum("UMTS.Radio.UHD.DeviceAddress");
|
|
} catch (ConfigurationTableKeyNotFound e) {
|
|
addr = "";
|
|
}
|
|
|
|
return addr;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
UHDDevice *usrp = NULL;
|
|
RadioDevice *dev = NULL;
|
|
Transceiver *trx = NULL;
|
|
RadioInterface *radio = NULL;
|
|
|
|
int max_delay;
|
|
bool found, extref;
|
|
std::string devaddr;
|
|
|
|
/* Capture termination signals */
|
|
register_signal_handlers();
|
|
|
|
/* Fail if we don't have logging */
|
|
if (!init_config())
|
|
goto shutdown;
|
|
|
|
/* Optional parameters */
|
|
max_delay = init_max_delay();
|
|
extref = init_extref();
|
|
devaddr = init_devaddr();
|
|
|
|
srandom(time(NULL));
|
|
|
|
if (extref)
|
|
std::cout << "** Using external clock reference" << std::endl;
|
|
else
|
|
std::cout << "** Using internal clock reference" << std::endl;
|
|
|
|
std::cout << "** Searching for USRP device " << devaddr << std::endl;
|
|
usrp = new UHDDevice(DEVICE_RATE);
|
|
found = usrp->open(devaddr, extref);
|
|
|
|
if (found) {
|
|
std::cout << "** Device ready" << std::endl;
|
|
dev = (RadioDevice *) usrp;
|
|
} else {
|
|
std::cout << "** Device not available" << std::endl;
|
|
goto shutdown;
|
|
}
|
|
|
|
radio = new RadioInterface(dev, 0);
|
|
if (!radio->init()) {
|
|
std::cout << "** Radio failed to initialize" << std::endl;
|
|
goto shutdown;
|
|
}
|
|
|
|
trx = new Transceiver(5700, "127.0.0.1", UMTS::Time(4, 0), radio);
|
|
trx->receiveFIFO(radio->receiveFIFO());
|
|
trx->init(max_delay);
|
|
|
|
while (!gbShutdown)
|
|
sleep(1);
|
|
|
|
shutdown:
|
|
delete trx;
|
|
delete radio;
|
|
delete usrp;
|
|
|
|
return 0;
|
|
}
|
|
|
|
ConfigurationKeyMap getConfigurationKeys2()
|
|
{
|
|
extern ConfigurationKeyMap getConfigurationKeys();
|
|
ConfigurationKeyMap map = getConfigurationKeys();
|
|
ConfigurationKey *tmp;
|
|
|
|
tmp = new ConfigurationKey("TRX.RadioFrequencyOffset","128",
|
|
"~170Hz steps",
|
|
ConfigurationKey::FACTORY,
|
|
ConfigurationKey::VALRANGE,
|
|
"96:160",// educated guess
|
|
true,
|
|
"Fine-tuning adjustment for the transceiver master clock. "
|
|
"Roughly 170 Hz/step. "
|
|
"Set at the factory. "
|
|
"Do not adjust without proper calibration."
|
|
);
|
|
map[tmp->getName()] = *tmp;
|
|
delete tmp;
|
|
|
|
tmp = new ConfigurationKey("TRX.TxAttenOffset","0",
|
|
"dB of attenuation",
|
|
ConfigurationKey::FACTORY,
|
|
ConfigurationKey::VALRANGE,
|
|
"0:100",// educated guess
|
|
true,
|
|
"Hardware-specific gain adjustment for transmitter, matched to the power amplifier, expessed as an attenuationi in dB. "
|
|
"Set at the factory. "
|
|
"Do not adjust without proper calibration."
|
|
);
|
|
map[tmp->getName()] = *tmp;
|
|
delete tmp;
|
|
|
|
tmp = new ConfigurationKey("TRX.RadioNumber","0",
|
|
"",
|
|
ConfigurationKey::FACTORY,
|
|
ConfigurationKey::VALRANGE,
|
|
"0:9", // Not likely to have 10 radios on the same computer. Not likely to have >1
|
|
true,
|
|
"If non-0, use multiple radios on the same cpu, numbered 1-9. Must change TRX.Port also. Provide a separate config file for each OpenBTS+Radio combination using the environment variable or --config command line option."
|
|
);
|
|
map[tmp->getName()] = *tmp;
|
|
delete(tmp);
|
|
|
|
return map;
|
|
}
|