blob: 9a20ee60744b4d306022a67d5de7abe9293caf96 [file] [log] [blame]
dburgessb3a0ca42011-10-12 07:44:40 +00001/*
2* Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
3* Copyright 2010 Kestrel Signal Processing, Inc.
4*
5* This software is distributed under the terms of the GNU Affero Public License.
6* See the COPYING file in the main directory for details.
7*
8* This use of this software may be subject to additional restrictions.
9* See the LEGAL file in the main directory for details.
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU Affero General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU Affero General Public License for more details.
20
21 You should have received a copy of the GNU Affero General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23
24*/
25
26
27
28#include "Transceiver.h"
kurtis.heimerl67e3d5a2011-11-26 03:19:13 +000029#include "radioDevice.h"
dburgessb3a0ca42011-10-12 07:44:40 +000030#include "DummyLoad.h"
31
32#include <time.h>
33#include <signal.h>
34
35#include <GSMCommon.h>
36#include <Logger.h>
37#include <Configuration.h>
38
Thomas Tsouddd6def2013-07-30 18:47:30 +020039#define CONFIGDB "/etc/OpenBTS/OpenBTS.db"
40
Thomas Tsoufe269fe2013-10-14 23:56:51 -040041/* Samples-per-symbol for downlink path
42 * 4 - Uses precision modulator (more computation, less distortion)
43 * 1 - Uses minimized modulator (less computation, more distortion)
44 *
45 * Other values are invalid. Receive path (uplink) is always
46 * downsampled to 1 sps
47 */
48#define SPS 4
49
dburgessb3a0ca42011-10-12 07:44:40 +000050using namespace std;
51
Thomas Tsouddd6def2013-07-30 18:47:30 +020052ConfigurationTable gConfig(CONFIGDB);
dburgessb3a0ca42011-10-12 07:44:40 +000053
54volatile bool gbShutdown = false;
Thomas Tsouddd6def2013-07-30 18:47:30 +020055
dburgessb3a0ca42011-10-12 07:44:40 +000056static void ctrlCHandler(int signo)
57{
58 cout << "Received shutdown signal" << endl;;
59 gbShutdown = true;
60}
61
Thomas Tsouddd6def2013-07-30 18:47:30 +020062/*
63 * Attempt to open and test the database file before
64 * accessing the configuration table. We do this because
65 * the global table constructor cannot provide notification
66 * in the event of failure.
67 */
68int testConfig(const char *filename)
69{
70 int rc, val = 9999;
71 sqlite3 *db;
72 std::string test = "sadf732zdvj2";
73
74 const char *keys[3] = {
75 "Log.Level",
76 "TRX.Port",
77 "TRX.IP",
78 };
79
80 /* Try to open the database */
81 rc = sqlite3_open(filename, &db);
82 if (rc || !db) {
83 std::cerr << "Config: Database could not be opened" << std::endl;
84 return -1;
85 } else {
86 sqlite3_close(db);
87 }
88
89 /* Attempt to set a value in the global config */
90 if (!gConfig.set(test, val)) {
91 std::cerr << "Config: Failed to set test key - "
92 << "permission to access the database?" << std::endl;
93 return -1;
94 } else {
95 gConfig.remove(test);
96 }
97
98 /* Attempt to query */
99 for (int i = 0; i < 3; i++) {
100 try {
101 gConfig.getStr(keys[i]);
102 } catch (...) {
103 std::cerr << "Config: Failed query on " << keys[i] << std::endl;
104 return -1;
105 }
106 }
107
108 return 0;
109}
dburgessb3a0ca42011-10-12 07:44:40 +0000110
111int main(int argc, char *argv[])
112{
Thomas Tsouddd6def2013-07-30 18:47:30 +0200113 int trxPort;
114 std::string deviceArgs, logLevel, trxAddr;
ttsouf60dafa2012-10-22 00:07:14 +0000115
116 if (argc == 3)
117 {
118 deviceArgs = std::string(argv[2]);
119 }
120 else
121 {
122 deviceArgs = "";
123 }
124
dburgessb3a0ca42011-10-12 07:44:40 +0000125 if ( signal( SIGINT, ctrlCHandler ) == SIG_ERR )
126 {
127 cerr << "Couldn't install signal handler for SIGINT" << endl;
128 exit(1);
129 }
130
131 if ( signal( SIGTERM, ctrlCHandler ) == SIG_ERR )
132 {
133 cerr << "Couldn't install signal handler for SIGTERM" << endl;
134 exit(1);
135 }
Thomas Tsouddd6def2013-07-30 18:47:30 +0200136
dburgessb3a0ca42011-10-12 07:44:40 +0000137 // Configure logger.
Thomas Tsouddd6def2013-07-30 18:47:30 +0200138 if (testConfig(CONFIGDB) < 0) {
139 std::cerr << "Config: Database failure" << std::endl;
140 return EXIT_FAILURE;
141 }
dburgessb3a0ca42011-10-12 07:44:40 +0000142
Thomas Tsouddd6def2013-07-30 18:47:30 +0200143 logLevel = gConfig.getStr("Log.Level");
144 trxPort = gConfig.getNum("TRX.Port");
145 trxAddr = gConfig.getStr("TRX.IP");
146 gLogInit("transceiver", logLevel.c_str(), LOG_LOCAL7);
dburgessb3a0ca42011-10-12 07:44:40 +0000147
148 srandom(time(NULL));
149
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400150 RadioDevice *usrp = RadioDevice::make(SPS);
Thomas Tsoucb69f082013-04-08 14:18:26 -0400151 int radioType = usrp->open(deviceArgs);
152 if (radioType < 0) {
kurtis.heimerle3320322011-11-28 06:26:08 +0000153 LOG(ALERT) << "Transceiver exiting..." << std::endl;
kurtis.heimerl67e3d5a2011-11-26 03:19:13 +0000154 return EXIT_FAILURE;
155 }
dburgessb3a0ca42011-10-12 07:44:40 +0000156
Thomas Tsoucb69f082013-04-08 14:18:26 -0400157 RadioInterface* radio;
158 switch (radioType) {
159 case RadioDevice::NORMAL:
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400160 radio = new RadioInterface(usrp, 3, SPS, false);
Thomas Tsoucb69f082013-04-08 14:18:26 -0400161 break;
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400162 case RadioDevice::RESAMP_64M:
163 case RadioDevice::RESAMP_100M:
164 radio = new RadioInterfaceResamp(usrp, 3, SPS, false);
Thomas Tsoucb69f082013-04-08 14:18:26 -0400165 break;
166 default:
167 LOG(ALERT) << "Unsupported configuration";
168 return EXIT_FAILURE;
169 }
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400170 if (!radio->init(radioType)) {
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400171 LOG(ALERT) << "Failed to initialize radio interface";
172 }
Thomas Tsoucb69f082013-04-08 14:18:26 -0400173
Thomas Tsouddd6def2013-07-30 18:47:30 +0200174 Transceiver *trx = new Transceiver(trxPort, trxAddr.c_str(),
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400175 SPS, GSM::Time(3,0), radio);
Thomas Tsoue57004d2013-08-20 18:55:33 -0400176 if (!trx->init()) {
177 LOG(ALERT) << "Failed to initialize transceiver";
178 }
dburgessb3a0ca42011-10-12 07:44:40 +0000179 trx->receiveFIFO(radio->receiveFIFO());
dburgessb3a0ca42011-10-12 07:44:40 +0000180 trx->start();
Thomas Tsou96794cb2013-07-30 16:32:14 +0200181
182 while (!gbShutdown) {
183 sleep(1);
184 }
dburgessb3a0ca42011-10-12 07:44:40 +0000185
186 cout << "Shutting down transceiver..." << endl;
187
dburgessb3a0ca42011-10-12 07:44:40 +0000188 delete trx;
dburgessb3a0ca42011-10-12 07:44:40 +0000189}