diff options
author | Thomas Tsou <tom@tsou.cc> | 2013-09-05 05:48:49 -0400 |
---|---|---|
committer | Thomas Tsou <tom@tsou.cc> | 2013-09-05 06:07:50 -0400 |
commit | 91ac9347493cee880f3233409241955d19a4bb4e (patch) | |
tree | 1e6e82ad9cd0844b572a54fba4d76d8c047ac0b9 /Transceiver52M/runTransceiver.cpp | |
parent | 7398a756eae6cb0135ced0288678d97bc3dffdfc (diff) |
Transceiver52M: Verify global config sanity at start
The configuration table is instantiated as a global variable with
no means to check constructor status. This means various types
of database failure conditions (e.g. file existence, permissions,
etc.) are not reported. This patch performs a small number of
checks to make sure that the configuration is sane.
Signed-off-by: Thomas Tsou <tom@tsou.cc>
Diffstat (limited to 'Transceiver52M/runTransceiver.cpp')
-rw-r--r-- | Transceiver52M/runTransceiver.cpp | 116 |
1 files changed, 95 insertions, 21 deletions
diff --git a/Transceiver52M/runTransceiver.cpp b/Transceiver52M/runTransceiver.cpp index 0fed868..1f05f6b 100644 --- a/Transceiver52M/runTransceiver.cpp +++ b/Transceiver52M/runTransceiver.cpp @@ -28,6 +28,7 @@ #include "Transceiver.h" #include "radioDevice.h" #include "DummyLoad.h" +#include <fstream> #include <time.h> #include <signal.h> @@ -36,23 +37,90 @@ #include <Logger.h> #include <Configuration.h> -using namespace std; +#define CONFIGDB "/etc/OpenBTS/OpenBTS.db" -ConfigurationTable gConfig("/etc/OpenBTS/OpenBTS.db"); +using namespace std; +ConfigurationTable gConfig(CONFIGDB); volatile bool gbShutdown = false; + static void ctrlCHandler(int signo) { cout << "Received shutdown signal" << endl;; gbShutdown = true; } +/* + * Attempt to open and test the database file before + * accessing the configuration table. We do this because + * the global table constructor cannot provide notification + * in the event of failure. + */ +int testConfig(const char *filename) +{ + int rc, val = 9999; + bool status; + sqlite3 *db; + std::string result; + std::string test = "sadf732zdvj2"; + + const char *keys[3] = { + "Log.Level", + "TRX.Port", + "TRX.IP", + }; + + /* Check for file existence */ + std::ifstream file(filename); + if (!file.good()) { + std::cerr << "Config: File not readable \"" + << filename << "\"" << std::endl; + return -1; + } else { + file.close(); + } + + /* Try to open the database */ + rc = sqlite3_open(filename, &db); + if (rc || !db) { + std::cerr << "Config: Database could not be opened" << std::endl; + return -1; + } else { + sqlite3_close(db); + } + + /* Attempt to set a value in the global config */ + if (!gConfig.set(test, val)) { + std::cerr << "Config: Failed to set test key - " + << "permission to access the database?" << std::endl; + return -1; + } else { + gConfig.remove(test); + } + + /* Attempt to query */ + for (int i = 0; i < 3; i++) { + try { + result = gConfig.getStr(keys[i]); + } catch (...) { + std::cerr << "Config: Failed query on " << keys[i] << std::endl; + return -1; + } + } + + return 0; +} int main(int argc, char *argv[]) { - std::string deviceArgs; - std::string txAntenna, rxAntenna; + int trxPort; + std::string deviceArgs, logLevel, trxAddr, txAntenna, rxAntenna; + + RadioDevice *usrp; + RadioInterface* radio; + DriveLoop *drive; + Transceiver *trx; if (argc == 3) { @@ -74,22 +142,18 @@ int main(int argc, char *argv[]) cerr << "Couldn't install signal handler for SIGTERM" << endl; exit(1); } - // Configure logger. - gLogInit("transceiver",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7); - - int numARFCN=1; - - LOG(NOTICE) << "starting transceiver with " << numARFCN << " ARFCNs (argc=" << argc << ")"; - srandom(time(NULL)); - - RadioDevice *usrp = RadioDevice::make(SAMPSPERSYM); - int radioType = usrp->open(deviceArgs); - if (radioType < 0) { - LOG(ALERT) << "Transceiver exiting..." << std::endl; + // Configure logger. + if (testConfig(CONFIGDB) < 0) { + std::cerr << "Config: Database failure" << std::endl; return EXIT_FAILURE; } + logLevel = gConfig.getStr("Log.Level"); + trxPort = gConfig.getNum("TRX.Port"); + trxAddr = gConfig.getStr("TRX.IP"); + gLogInit("transceiver", logLevel.c_str(), LOG_LOCAL7); + if (gConfig.defines("GSM.Radio.TxAntenna")) txAntenna = gConfig.getStr("GSM.Radio.TxAntenna").c_str(); if (gConfig.defines("GSM.Radio.RxAntenna")) @@ -103,7 +167,15 @@ int main(int argc, char *argv[]) LOG(INFO) << "transceiver using transmit antenna " << usrp->getRxAntenna(); LOG(INFO) << "transceiver using receive antenna " << usrp->getTxAntenna(); - RadioInterface* radio; + srandom(time(NULL)); + + usrp = RadioDevice::make(SAMPSPERSYM); + int radioType = usrp->open(deviceArgs); + if (radioType < 0) { + LOG(ALERT) << "Transceiver exiting..." << std::endl; + return EXIT_FAILURE; + } + switch (radioType) { case RadioDevice::NORMAL: radio = new RadioInterface(usrp, 3, SAMPSPERSYM, false); @@ -114,10 +186,12 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - int port = gConfig.getNum("TRX.Port"); - const char *addr = gConfig.getStr("TRX.IP").c_str(); - DriveLoop *drive = new DriveLoop(SAMPSPERSYM,GSM::Time(3,0),radio); - Transceiver *trx = new Transceiver(port, addr, SAMPSPERSYM, radio, drive, 0); + drive = new DriveLoop(SAMPSPERSYM, GSM::Time(3,0), radio); + if (!drive->init()) { + LOG(ALERT) << "Failed to initialize drive loop"; + } + + trx = new Transceiver(trxPort, trxAddr.c_str(), SAMPSPERSYM, radio, drive, 0); radio->activateChan(0); if (!trx->init()) { LOG(ALERT) << "Failed to initialize transceiver"; |