From 0c699308a11edc32105005e60f07e3e9eec0e3e7 Mon Sep 17 00:00:00 2001 From: "kurtis.heimerl" Date: Fri, 23 Nov 2012 08:35:46 +0000 Subject: [PATCH] r4408 in private: Add code from David to keep the transceiver running when OpenBTS crashes and check if it is running when starting up. git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@4512 19bc5d8c-e614-43d4-8b26-e1612bc8e597 --- CLI/CLI.cpp | 10 ++++++++++ CommonLibs/Sockets.cpp | 2 +- Control/SMSControl.cpp | 12 ++++++++++-- SMS/SMSMessages.h | 9 ++++++--- TRXManager/TRXManager.cpp | 17 +++++++++++------ TRXManager/TRXManager.h | 3 +++ apps/OpenBTS.cpp | 25 ++++++++++++++++++------- apps/OpenBTS.example.sql | 2 ++ 8 files changed, 61 insertions(+), 19 deletions(-) diff --git a/CLI/CLI.cpp b/CLI/CLI.cpp index db5a1a2..32f51d8 100644 --- a/CLI/CLI.cpp +++ b/CLI/CLI.cpp @@ -759,6 +759,15 @@ int noise(int argc, char** argv, ostream& os) return SUCCESS; } +int crashme(int argc, char** argv, ostream& os) +{ + char *nullp = 0x0; + // we actually have to output this, + // or the compiler will optimize it out + os << *nullp; + return FAILURE; +} + //@} // CLI commands @@ -790,6 +799,7 @@ void Parser::addCommands() addCommand("unconfig", unconfig, "key -- remove a config value"); addCommand("notices", notices, "-- show startup copyright and legal notices"); addCommand("endcall", endcall,"trans# -- terminate the given transaction"); + addCommand("crashme", crashme, "force crash of OpenBTS for testing purposes"); } diff --git a/CommonLibs/Sockets.cpp b/CommonLibs/Sockets.cpp index 992a486..b343b7e 100644 --- a/CommonLibs/Sockets.cpp +++ b/CommonLibs/Sockets.cpp @@ -180,7 +180,7 @@ int DatagramSocket::read(char* buffer) int DatagramSocket::read(char* buffer, unsigned timeout) { fd_set fds; - FD_SET(mSocketFD,&fds); + FD_ZERO(&fds); struct timeval tv; tv.tv_sec = timeout/1000; tv.tv_usec = (timeout%1000)*1000; diff --git a/Control/SMSControl.cpp b/Control/SMSControl.cpp index 41f6beb..f5fcb0a 100644 --- a/Control/SMSControl.cpp +++ b/Control/SMSControl.cpp @@ -220,6 +220,7 @@ void Control::MOSMSController(const GSM::L3CMServiceRequest *req, GSM::LogicalCh LOG(DEBUG) << "data from MS " << *CM; if (CM->MTI()!=CPMessage::DATA) { LOG(NOTICE) << "unexpected SMS CP message with TI=" << CM->MTI(); + delete CM; throw UnexpectedMessage(); } unsigned L3TI = CM->TI() | 0x08; @@ -241,7 +242,6 @@ void Control::MOSMSController(const GSM::L3CMServiceRequest *req, GSM::LogicalCh try { CPData data; data.parse(*CM); - delete CM; LOG(INFO) << "CPData " << data; // Transfer out the RPDU -> TPDU -> delivery. ref = data.RPDU().reference(); @@ -252,12 +252,15 @@ void Control::MOSMSController(const GSM::L3CMServiceRequest *req, GSM::LogicalCh LOG(WARNING) << "SMS parsing failed (above L3)"; // Cause 95, "semantically incorrect message". LCH->send(CPData(L3TI,RPError(95,ref)),3); + delete CM; throw UnexpectedMessage(); } catch (GSM::L3ReadError) { LOG(WARNING) << "SMS parsing failed (in L3)"; + delete CM; throw UnsupportedMessage(); } + delete CM; // Step 3 // Send CP-DATA containing RP-ACK and message reference. @@ -281,6 +284,7 @@ void Control::MOSMSController(const GSM::L3CMServiceRequest *req, GSM::LogicalCh LOG(DEBUG) << "ack from MS: " << *CM; CPAck ack; ack.parse(*CM); + delete CM; LOG(INFO) << "CPAck " << ack; /* MOSMS RLLP request */ @@ -386,8 +390,10 @@ bool Control::deliverSMSToMS(const char *callingPartyDigits, const char* message LOG(DEBUG) << "MTSMS: ack from MS " << *CM; if (CM->MTI()!=CPMessage::ACK) { LOG(WARNING) << "MS rejected our RP-DATA with CP message with TI=" << CM->MTI(); + delete CM; throw UnexpectedMessage(); } + delete CM; // Step 3 // Get CP-DATA containing RP-ACK and message reference. @@ -396,8 +402,10 @@ bool Control::deliverSMSToMS(const char *callingPartyDigits, const char* message LOG(DEBUG) << "MTSMS: data from MS " << *CM; if (CM->MTI()!=CPMessage::DATA) { LOG(NOTICE) << "Unexpected SMS CP message with TI=" << CM->MTI(); + delete CM; throw UnexpectedMessage(); } + // FIXME -- Check L3 TI. @@ -405,7 +413,6 @@ bool Control::deliverSMSToMS(const char *callingPartyDigits, const char* message CPData data; try { data.parse(*CM); - delete CM; LOG(DEBUG) << "CPData " << data; } catch (SMSReadError) { @@ -418,6 +425,7 @@ bool Control::deliverSMSToMS(const char *callingPartyDigits, const char* message LOG(WARNING) << "SMS parsing failed (in L3)"; throw UnsupportedMessage(); } + delete CM; // FIXME -- Check SMS reference. diff --git a/SMS/SMSMessages.h b/SMS/SMSMessages.h index 48b728b..447c7b8 100644 --- a/SMS/SMSMessages.h +++ b/SMS/SMSMessages.h @@ -251,7 +251,7 @@ class TLMessage { - 7 RP (9.2.3.17) */ //@{ - bool mMMS; ///< more messages to send + bool mMMS; ///< more messages to send (reversed-sense) bool mRD; ///< reject duplicates unsigned mVPF; ///< validity period format bool mSRR; ///< status report request @@ -277,14 +277,14 @@ class TLMessage { }; TLMessage() - :mMMS(false),mSRI(false),mRP(false) + :mMMS(true),mSRI(false),mRP(false) {} virtual ~TLMessage(){} virtual int MTI() const=0; - /** The bodtLength is everything beyond the header byte. */ + /** The bodyLength is everything beyond the header byte. */ virtual size_t l2BodyLength() const = 0; virtual size_t length() const { return 1+l2BodyLength(); } @@ -300,6 +300,9 @@ class TLMessage { virtual void text(std::ostream& os) const { os << MTI(); } + // Accessors + bool MMS() const { return mMMS; } + protected: /**@name Readers and writers for standard header bits. */ diff --git a/TRXManager/TRXManager.cpp b/TRXManager/TRXManager.cpp index 41af15c..fd04836 100644 --- a/TRXManager/TRXManager.cpp +++ b/TRXManager/TRXManager.cpp @@ -85,7 +85,7 @@ void* ClockLoopAdapter(TransceiverManager *transceiver) void TransceiverManager::clockHandler() { char buffer[MAX_UDP_LENGTH]; - int msgLen = mClockSocket.read(buffer,3000); + int msgLen = mClockSocket.read(buffer,gConfig.getNum("TRX.Timeout.Clock",10)*1000); // Did the transceiver die?? if (msgLen<0) { @@ -114,6 +114,11 @@ void TransceiverManager::clockHandler() +unsigned TransceiverManager::C0() const +{ + return mARFCNs.at(0)->ARFCN(); +} + @@ -253,9 +258,9 @@ int ::ARFCNManager::sendCommandPacket(const char* command, char* response) LOG(INFO) << "command " << command; mControlLock.lock(); - for (int retry=0; retry<10; retry++) { + for (int retry=0; retry<5; retry++) { mControlSocket.write(command); - msgLen = mControlSocket.read(response,3000); + msgLen = mControlSocket.read(response,1000); if (msgLen>0) { response[msgLen] = '\0'; break; @@ -264,14 +269,14 @@ int ::ARFCNManager::sendCommandPacket(const char* command, char* response) } mControlLock.unlock(); - LOG(DEBUG) << "response " << response; + LOG(INFO) << "response " << response; if ((msgLen>4) && (strncmp(response,"RSP ",4)==0)) { return msgLen; } - LOG(ALERT) << "lost control link to transceiver"; - SOCKET_ERROR; + LOG(NOTICE) << "lost control link to transceiver"; + return 0; } diff --git a/TRXManager/TRXManager.h b/TRXManager/TRXManager.h index ced618b..45d9332 100644 --- a/TRXManager/TRXManager.h +++ b/TRXManager/TRXManager.h @@ -85,6 +85,9 @@ class TransceiverManager { ARFCNManager* ARFCN(unsigned i) { assert(ipowerOn(); + //sleep(gConfig.getNum("TRX.Timeout.Start",2)); + bool haveTRX = gTRX.ARFCN(0)->powerOn(); + Thread transceiverThread; - transceiverThread.start((void*(*)(void*)) startTransceiver, NULL); + if (!gTRX.haveClock()) { + transceiverThread.start((void*(*)(void*)) startTransceiver, NULL); + // sleep to let the FPGA code load + // TODO: we should be "pinging" the radio instead of sleeping + sleep(5); + } else { + LOG(NOTICE) << "transceiver already running"; + } // Start the SIP interface. gSIPInterface.start(); @@ -182,9 +196,6 @@ int main(int argc, char *argv[]) // Configure the radio. // - // Start the transceiver interface. - // Sleep long enough for the USRP to bootload. - sleep(10); gTRX.start(); // Set up the interface to the radio. @@ -193,7 +204,7 @@ int main(int argc, char *argv[]) // Tuning. // Make sure its off for tuning. - C0radio->powerOff(); + //C0radio->powerOff(); // Get the ARFCN list. unsigned C0 = gConfig.getNum("GSM.Radio.C0"); unsigned numARFCNs = gConfig.getNum("GSM.Radio.ARFCNs"); @@ -370,7 +381,7 @@ int main(int argc, char *argv[]) LOG(EMERG) << "required configuration parameter " << e.key() << " not defined, aborting"; } - if (gTransceiverPid) kill(gTransceiverPid, SIGKILL); + //if (gTransceiverPid) kill(gTransceiverPid, SIGKILL); close(sock); } diff --git a/apps/OpenBTS.example.sql b/apps/OpenBTS.example.sql index 31f97c4..a8cc16a 100644 --- a/apps/OpenBTS.example.sql +++ b/apps/OpenBTS.example.sql @@ -123,5 +123,7 @@ INSERT INTO "CONFIG" VALUES('SubscriberRegistry.Port','5064',0,0,'Port used by t INSERT INTO "CONFIG" VALUES('TRX.IP','127.0.0.1',1,0,'IP address of the transceiver application. Static.'); INSERT INTO "CONFIG" VALUES('TRX.Port','5700',1,0,'IP port of the transceiver application. Static.'); INSERT INTO "CONFIG" VALUES('TRX.RadioFrequencyOffset','128',1,0,'Fine-tuning adjustment for the transceiver master clock. Roughly 170 Hz/step. Set at the factory. Do not adjust without proper calibration. Static.'); +INSERT INTO "CONFIG" VALUES('TRX.Timeout.Clock','10',0,1,'How long to wait during a read operation from the transceiver before giving up.'); +INSERT INTO "CONFIG" VALUES('TRX.Timeout.Start','2',0,1,'How long to wait during system startup before checking to see if the transceiver can be reached.'); INSERT INTO "CONFIG" VALUES('TRX.TxAttenOffset','2',1,0,'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. Static.'); COMMIT;