mbcch sdcch 8可以走业务吗

[][Date Next][][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r11667 - in openbts/trunk: . CLI CommonLibs Control GS
dburgess00
[Commit-gnuradio] r11667 - in openbts/trunk: . CLI CommonLibs Control GSM Globals HLR SIP SMS TRXManager Transceiver Transceiver52M apps smqueue
Wed, 30 Dec :20 -0700 (MST)
Author: dburgess00
21:21:20 -0700 (Wed, 30 Dec 2009)
New Revision: 11667
openbts/trunk/AUTHORS
openbts/trunk/CLI/CLI.cpp
openbts/trunk/CLI/CLI.h
openbts/trunk/CLI/Makefile.am
openbts/trunk/CLI/Makefile.in
openbts/trunk/CommonLibs/BitVector.cpp
openbts/trunk/CommonLibs/BitVector.h
openbts/trunk/CommonLibs/Configuration.cpp
openbts/trunk/CommonLibs/Configuration.h
openbts/trunk/CommonLibs/ConfigurationTest.cpp
openbts/trunk/CommonLibs/F16.h
openbts/trunk/CommonLibs/Interthread.h
openbts/trunk/CommonLibs/LogTest.cpp
openbts/trunk/CommonLibs/Logger.cpp
openbts/trunk/CommonLibs/Logger.h
openbts/trunk/CommonLibs/Makefile.am
openbts/trunk/CommonLibs/Sockets.cpp
openbts/trunk/CommonLibs/Sockets.h
openbts/trunk/Control/CallControl.cpp
openbts/trunk/Control/ControlCommon.cpp
openbts/trunk/Control/ControlCommon.h
openbts/trunk/Control/Makefile.am
openbts/trunk/Control/MobilityManagement.cpp
openbts/trunk/Control/RadioResource.cpp
openbts/trunk/Control/SMSControl.cpp
openbts/trunk/GSM/GSMCommon.cpp
openbts/trunk/GSM/GSMCommon.h
openbts/trunk/GSM/GSMConfig.cpp
openbts/trunk/GSM/GSMConfig.h
openbts/trunk/GSM/GSML1FEC.cpp
openbts/trunk/GSM/GSML1FEC.h
openbts/trunk/GSM/GSML2LAPDm.cpp
openbts/trunk/GSM/GSML3CCElements.cpp
openbts/trunk/GSM/GSML3CCElements.h
openbts/trunk/GSM/GSML3MMElements.h
openbts/trunk/GSM/GSML3RRElements.cpp
openbts/trunk/GSM/GSML3RRElements.h
openbts/trunk/GSM/GSML3RRMessages.cpp
openbts/trunk/GSM/GSML3RRMessages.h
openbts/trunk/GSM/GSMLogicalChannel.cpp
openbts/trunk/GSM/GSMLogicalChannel.h
openbts/trunk/GSM/GSMTDMA.cpp
openbts/trunk/GSM/GSMTransfer.h
openbts/trunk/GSM/Makefile.am
openbts/trunk/Globals/Globals.cpp
openbts/trunk/Globals/Makefile.am
openbts/trunk/Globals/Makefile.in
openbts/trunk/HLR/Makefile.am
openbts/trunk/HLR/Makefile.in
openbts/trunk/LEGAL
openbts/trunk/Makefile.am
openbts/mon
openbts/trunk/README
openbts/trunk/SIP/SIPEngine.cpp
openbts/trunk/SIP/SIPEngine.h
openbts/trunk/SIP/SIPInterface.cpp
openbts/trunk/SIP/SIPInterface.h
openbts/trunk/SMS/Makefile.am
openbts/trunk/TRXManager/Makefile.am
openbts/trunk/TRXManager/TRXManager.cpp
openbts/trunk/TRXManager/TRXManager.h
openbts/trunk/Transceiver/Makefile.am
openbts/trunk/Transceiver52M/Makefile.am
openbts/trunk/Transceiver52M/Makefile.in
openbts/trunk/Transceiver52M/Transceiver.cpp
openbts/trunk/Transceiver52M/USRPDevice.cpp
openbts/trunk/Transceiver52M/USRPDevice.h
openbts/trunk/Transceiver52M/USRPping.cpp
openbts/trunk/Transceiver52M/radioInterface.cpp
openbts/trunk/Transceiver52M/radioInterface.h
openbts/trunk/Transceiver52M/sigProcLib.cpp
openbts/trunk/apps/Makefile.am
openbts/trunk/apps/OpenBTS.config.example
openbts/trunk/apps/OpenBTS.cpp
openbts/trunk/configure.ac
openbts/trunk/smqueue/Makefile.in
openbts/trunk/smqueue/smqueue.config.example
openbts/trunk/smqueue/smqueue.cpp
Inter-release update.
Beyond 2.5 but not yet releasing 2.6.
Modified: openbts/trunk/AUTHORS
===================================================================
--- openbts/trunk/AUTHORS
03:03:10 UTC (rev 11666)
+++ openbts/trunk/AUTHORS
04:21:20 UTC (rev 11667)
@@ -184,3 +184,9 @@
SMS/TLProcessor.cpp
SMS/TLProcessor.h
TRXManager/TRXManager.h
+Alon Levy, address@hidden
RRLPMessages.cpp
RRLPMessages.h
RRLPTest.cpp
Modified: openbts/trunk/CLI/CLI.cpp
===================================================================
--- openbts/trunk/CLI/CLI.cpp
03:03:10 UTC (rev 11666)
+++ openbts/trunk/CLI/CLI.cpp
04:21:20 UTC (rev 11667)
@@ -22,21 +22,24 @@
+#include &iostream&
+#include &fstream&
+#include &iterator&
+#include &string.h&
+#include &stdlib.h&
+#include &math.h&
#include &config.h&
#include &CLI.h&
#include &Logger.h&
#include &Globals.h&
-#include &string.h&
-#include &iostream&
-#include &fstream&
#include &GSMConfig.h&
#include &GSMLogicalChannel.h&
#include &ControlCommon.h&
+#include &TRXManager.h&
+#include &PowerManager.h&
using namespace CommandL
@@ -47,6 +50,8 @@
#define TOO_MANY_ARGS 4
#define FAILURE 5
+extern TransceiverManager gTRX;
/** Standard responses in the CLI, much mach erorrCode enum. */
static const char* standardResponses[] = {
&success&, // 0
@@ -180,6 +185,7 @@
if (argc!=1) return BAD_NUM_ARGS;
ParseTable::const_iterator cp = gParser.begin();
os && &Type \&help\& followed by the command name for help on that
command.& &&
while (cp != gParser.end()) {
os && cp-&first && '\t';
@@ -220,41 +226,89 @@
os && tp-&second && & 0x& && std::hex && tp-&first && std::dec
os && endl && gTMSITable.size() && & TMSIs in table&;
return SUCCESS;
+int findIMSI(int argc, char** argv, ostream& os, istream& is)
if (argc!=2) {
os && &usage: findimsi &imsiprefix&\n&;
return BAD_VALUE;
Control::TMSIMap::const_iterator tp = gTMSITable.begin();
char buf[50]; // max size in decimal digits plus 1 plus RandomPositive
while (tp != gTMSITable.end()) {
sprintf(buf, &%d&, tp-&first);
std::string imsi =
target.assign(imsi, 0, strlen(argv[1]));
if (target == argv[1])
os && tp-&second && & 0x& && std::hex && tp-&first &&
std::dec &&
return SUCCESS;
+int dumpTMSIs(int argc, char** argv, ostream& os, istream& is)
if (argc != 2) {
os && &usage: dumptmsis &filename&\n&;
return BAD_VALUE;
char* subargv[] = {&tmsis&, NULL};
int subargc = 1;
fileout.open(argv[1], ios::out); // erases existing!
printTMSIs(subargc, subargv, fileout, is);
return SUCCESS;
/** Submit an SMS for delivery to an IMSI. */
int sendSMS(int argc, char** argv, ostream& os, istream& is)
// FIXME -- Replace this with initiateMTTransaction.
if (argc!=3) return BAD_NUM_ARGS;
os && &enter text to send: &;
char txtBuf[161];
cin.getline(txtBuf,160,'\n');
char *IMSI = argv[1];
char *srcAddr = argv[2];
Control::TransactionEntry transaction(
GSM::L3MobileIdentity(IMSI),
GSM::L3CMServiceType::MobileTerminatedShortMessage,
GSM::L3CallingPartyBCDNumber(srcAddr),
transaction.Q931State(Control::TransactionEntry::Paging);
Control::initiateMTTransaction(transaction,GSM::SDCCHType,30000);
os && &message submitted for delivery& &&
return SUCCESS;
+/** DEBUGGING: Sends a special sms that triggers a RRLP message to an IMSI. */
+int sendRRLP(int argc, char** argv, ostream& os, istream& is)
if (argc!=3) return BAD_NUM_ARGS;
char *IMSI = argv[1];
UDPSocket sock(0,&127.0.0.1&,gConfig.getNum(&SIP.Port&));
unsigned port = sock.port();
unsigned callID = random();
//unsigned port = gConfig.getNum(&SMSLoopback.Port&);
// Just fake out a SIP message.
const char form[] = &MESSAGE sip:address@hidden SIP/2.0\nVia:
SIP/2.0/UDP 127.0.0.1;branch=z9hG4bK776sgdkse\nMax-Forwards: 2\nFrom: %s
&sip:address@hidden&:%d;tag=49583\nTo: sip:address@hidden:
address@hidden:5063\nCSeq: 1 MESSAGE\nContent-Type: text/plain\nContent-Length:
%d\n\n%s\n&;
const char form[] = &MESSAGE sip:address@hidden SIP/2.0\nVia:
SIP/2.0/TCPbranch=z9hG4bK776sgdkse\nMax-Forwards: 2\nFrom:
address@hidden:%d;tag=49583\nTo: sip:address@hidden: address@hidden:5063\nCSeq:
1 MESSAGE\nContent-Type: text/plain\nContent-Length: %lu\n\n%s\n&;
os && &enter text to send: &;
char txtBuf[161];
cin.getline(txtBuf,160,'\n');
sprintf(txtBuf,&RRLP%s&,argv[2]);
char outbuf[2048];
sprintf(outbuf,form,IMSI,srcAddr,srcAddr,port,IMSI,callID,strlen(txtBuf),txtBuf);
//UDPSocket sock(port,&127.0.0.1&,gConfig.getNum(&SIP.Port&));
sprintf(outbuf,form,IMSI,port,IMSI,callID,strlen(txtBuf),txtBuf);
sock.write(outbuf);
sock.write(outbuf);
sock.close();
os && &message submitted for delivery& &&
os && &RRLP Triggering message submitted for delivery& &&
return SUCCESS;
@@ -266,6 +320,12 @@
os && &SDCCH load: & && gBTS.SDCCHActive() && '/' && gBTS.SDCCHTotal()
os && &TCH/F load: & && gBTS.TCHActive() && '/' && gBTS.TCHTotal() &&
os && &AGCH/PCH load: & && gBTS.AGCHLoad() && '/' && gBTS.PCHLoad() &&
// paging table size
os && &Paging table size: & && gBTS.pager().pagingEntryListSize() &&
os && &Transactions/TMSIs: & && gTransactionTable.size() && &/& &&
gTMSITable.size() &&
// 3122 timer current value (the number of seconds an MS should hold
off the next RACH)
os && &T3122: & && gBTS.T3122() && & ms& &&
return SUCCESS;
@@ -343,17 +403,40 @@
os && count && & transactions in table& &&
os && endl && count && & transactions in table& &&
return SUCCESS;
/** Print current configuration table. */
-int printConfig(int argc, char** argv, ostream& os, istream& is)
+int config(int argc, char** argv, ostream& os, istream& is)
if (argc!=1) return BAD_NUM_ARGS;
gConfig.dump(os);
// no args, just print
if (argc==1) {
gConfig.dump(os);
return SUCCESS;
// one arg, pattern match
if (argc==2) {
StringMap::const_iterator p = gConfig.begin();
while (p != gConfig.end()) {
if (strstr(p-&first.c_str(),argv[1]))
os && p-&first && &: & && p-&second &&
return SUCCESS;
// &1 args: set new value
for (int i=2; i& i++) val.append(argv[i]);
if (!gConfig.set(argv[1],val)) {
os && argv[1] && & is static and connot be altered after
initialization& &&
return BAD_VALUE;
gBTS.regenerateBeacon();
return SUCCESS;
@@ -427,6 +510,16 @@
return SUCCESS;
+/** Print the list of alarms kept by the logger, i.e. the last LOG(ALARM) &&
+int printAlarms(int argc, char** argv, ostream& os, istream& is)
std::ostream_iterator&std::string& output( os, &\n& );
std::list&std::string& alarms = gGetLoggerAlarms();
std::copy( alarms.begin(), alarms.end(), output );
return SUCCESS;
/** Version string. */
int version(int argc, char **argv, ostream& os, istream& is)
@@ -435,20 +528,25 @@
return SUCCESS;
int page(int argc, char **argv, ostream& os, istream& is)
if (argc==1) {
gBTS.pager().dump(os);
return SUCCESS;
if (argc!=3) return BAD_NUM_ARGS;
char *IMSI = argv[1];
if (strlen(IMSI)!=15) {
if (strlen(IMSI)&15) {
os && IMSI && & is not a valid IMSI& &&
return BAD_VALUE;
gBTS.pager().addID(GSM::L3MobileIdentity(IMSI),GSM::SDCCHType,0,1000*atoi(argv[2]));
Control::TransactionE
gBTS.pager().addID(GSM::L3MobileIdentity(IMSI),GSM::SDCCHType,dummy,1000*atoi(argv[2]));
return SUCCESS;
int testcall(int argc, char **argv, ostream& os, istream& is)
if (argc!=3) return BAD_NUM_ARGS;
@@ -500,16 +598,34 @@
+void printChanInfo(const GSM::LogicalChannel* chan, ostream& os)
os && chan-&TN() && & & && chan-&typeAndOffset() && & &;
os && (int)round(chan-&FER()*100) && & &;
os && (int)round(chan-&RSSI()) && & &;
os && chan-&actualMSPower() && & & && chan-&actualMSTiming() &&
const GSM::L3MeasurementResults& meas =
chan-&SACCH()-&measurementResults();
if (meas.MEAS_VALID()) {
os && meas.RXLEV_FULL_SERVING_CELL() && & &;
os && meas.RXQUAL_FULL_SERVING_CELL() && & &;
-int fer(int argc, char **argv, ostream& os, istream& is)
+int chans(int argc, char **argv, ostream& os, istream& is)
if (argc!=1) return BAD_NUM_ARGS;
os && &TN chan FER RSSI TXPWR TXTA RXLEV RXQUAL& &&
os && &TN type \%
GSM::TCHList::const_iterator tChanItr = gBTS.TCHPool().begin();
while (tChanItr != gBTS.TCHPool().end()) {
const GSM::TCHFACCHLogicalChannel* tChan = *tChanI
if (tChan-&active()) os && tChan-&TN() && & & &&
tChan-&typeAndOffset() && & & && tChan-&FER() &&
if (tChan-&active()) printChanInfo(tChan,os);
@@ -517,7 +633,7 @@
GSM::SDCCHList::const_iterator sChanItr = gBTS.SDCCHPool().begin();
while (sChanItr != gBTS.SDCCHPool().end()) {
const GSM::SDCCHLogicalChannel* sChan = *sChanI
if (sChan-&active()) os && sChan-&TN() && & & &&
sChan-&typeAndOffset() && & & && sChan-&FER() &&
if (sChan-&active()) printChanInfo(sChan,os);
@@ -527,6 +643,38 @@
+int power(int argc, char **argv, ostream& os, istream& is)
os && &current downlink power & && gBTS.powerManager().power() && & dB
wrt full scale& &&
os && &current attenuation bounds &
&& gConfig.getNum(&GSM.PowerManager.MinAttenDB&)
&& gConfig.getNum(&GSM.PowerManager.MaxAttenDB&)
&& & dB& &&
if (argc==1) return SUCCESS;
if (argc!=3) return BAD_NUM_ARGS;
int min = atoi(argv[1]);
int max = atoi(argv[2]);
if (min&max) return BAD_VALUE;
gConfig.set(&GSM.PowerManager.MinAttenDB&,argv[1]);
gConfig.set(&GSM.PowerManager.MaxAttenDB&,argv[2]);
os && &new attenuation bounds &
&& gConfig.getNum(&GSM.PowerManager.MinAttenDB&)
&& gConfig.getNum(&GSM.PowerManager.MaxAttenDB&)
&& & dB& &&
return SUCCESS;
//@} // CLI commands
@@ -540,21 +688,26 @@
addCommand(&help&, getHelp, &[command] -- list available commands or
gets help on a specific command.&);
addCommand(&exit&, dummy, &-- exit the application.&);
addCommand(&tmsis&, printTMSIs, &[\&clear\&] -- print/clear the TMSI
addCommand(&findimsi&, findIMSI, &-- [IMSIPrefix] - prints all imsi's
that are prefixed by IMSIPrefix&);
addCommand(&dumptmsis&, dumpTMSIs, &-- dump TMSI table to &);
addCommand(&sendsms&, sendSMS, &&IMSI& &src& -- send SMS to &IMSI&,
addressed from &src&, after prompting.&);
addCommand(&sendrrlp&, sendRRLP, &&IMSI& &hexstring& -- send RRLP
message &hexstring& to &IMSI&.&);
addCommand(&load&, printStats, &-- print the current activity loads.&);
addCommand(&cellid&, cellID, &[MCC MNC LAC CI] -- get/set location area
identity (MCC, MNC, LAC) and cell ID (CI)&);
addCommand(&assignment&, assignmentType, &[type] -- get/set assignment
type (early, veryearly)&);
addCommand(&calls&, printTransactions, &-- print the transaction
addCommand(&config&, printConfig, &-- print the current configuration&);
addCommand(&config&, config, &[] OR [patt] OR [key val(s)] -- print the
current configuration, print configuration values matching a pattern, or
set/change a configuration value&);
addCommand(&configsave&, dumpConfig, &&path& -- write the current
configuration to a file&);
addCommand(&regperiod&, configRegistration, &[GSM] [SIP] -- get/set the
registration period (GSM T3212), in MINUTES&);
addCommand(&shortname&, shortName, &[name] -- get/set the network short
addCommand(&alarms&, printAlarms, &-- show latest alarms&);
addCommand(&version&, version,&-- print the version string&);
addCommand(&page&, page, &IMSI time -- page the given IMSI for the
given period&);
addCommand(&testcall&, testcall, &IMSI time -- initiate a test call to
a given IMSI with a given paging time&);
addCommand(&endcall&, endcall,&trans# -- terminate the given
transaction&);
addCommand(&rolllac&, rolllac, &[LAC] -- increment the LAC or set a net
addCommand(&fer&, fer, &-- report FER for active channels&);
addCommand(&chans&, chans, &-- report PHY status for active channels&);
addCommand(&power&, power, &[minAtten maxAtten] -- report current
attentuation or set min/max bounds&);
// TODO -- Commands to add: FER, CI.
Modified: openbts/trunk/CLI/CLI.h
===================================================================
--- openbts/trunk/CLI/CLI.h
03:03:10 UTC (rev 11666)
+++ openbts/trunk/CLI/CLI.h
04:21:20 UTC (rev 11667)
@@ -70,7 +70,6 @@
/** Parse and execute a command string. */
int execute(char* line, std::ostream& os, std::istream& is)
Modified: openbts/trunk/CLI/Makefile.am
===================================================================
--- openbts/trunk/CLI/Makefile.am
03:03:10 UTC (rev 11666)
+++ openbts/trunk/CLI/Makefile.am
04:21:20 UTC (rev 11667)
@@ -23,6 +23,7 @@
EXTRA_DIST = \
README.CLI
+AM_CXXFLAGS = -Wall
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
noinst_LTLIBRARIES = libcli.la
Modified: openbts/trunk/CLI/Makefile.in
===================================================================
--- openbts/trunk/CLI/Makefile.in
03:03:10 UTC (rev 11666)
+++ openbts/trunk/CLI/Makefile.in
04:21:20 UTC (rev 11667)
@@ -237,6 +237,7 @@
TRX_INCLUDEDIR = $(top_srcdir)/TRXManager
GLOBALS_INCLUDEDIR = $(top_srcdir)/Globals
CLI_INCLUDEDIR = $(top_srcdir)/CLI
+#SQL_INCLUDEDIR = $(top_srcdir)/SQL
HLR_INCLUDEDIR = $(top_srcdir)/HLR
STD_DEFINES_AND_INCLUDES = \
-I$(COMMON_INCLUDEDIR) \
@@ -249,6 +250,7 @@
-I$(CLI_INCLUDEDIR) \
-I$(HLR_INCLUDEDIR)
-I$(SQL_INCLUDEDIR)
COMMON_LA = $(top_builddir)/CommonLibs/libcommon.la
GSM_LA = $(top_builddir)/GSM/libGSM.la
SIP_LA = $(top_builddir)/SIP/libSIP.la
@@ -258,10 +260,12 @@
GLOBALS_LA = $(top_builddir)/Globals/libglobals.la
CLI_LA = $(top_builddir)/CLI/libcli.la
HLR_LA = $(top_builddir)/HLR/libHLR.la
+#SQL_LA = $(top_builddir)/SQL/libSQL.la
MOSTLYCLEANFILES = *~
EXTRA_DIST = \
README.CLI
+AM_CXXFLAGS = -Wall
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
noinst_LTLIBRARIES = libcli.la
libcli_la_SOURCES = \
Modified: openbts/trunk/CommonLibs/BitVector.cpp
===================================================================
--- openbts/trunk/CommonLibs/BitVector.cpp
03:03:10 UTC (rev
+++ openbts/trunk/CommonLibs/BitVector.cpp
04:21:20 UTC (rev
@@ -1,5 +1,5 @@
-* Copyright 2008 Free Software Foundation, Inc.
+* Copyright
Free Software Foundation, Inc.
* This software is distributed under the terms of the GNU Public License.
* See the COPYING file in the main directory for details.
@@ -476,7 +476,7 @@
const float *dp = mS
for (size_t i=0; i& i++) {
// pVal is the probability that a bit is correct.
// ipVal is the probability that a bit is correct.
// ipVal is the probability that a bit is incorrect.
float pVal = dp[i];
if (pVal&0.5F) pVal = 1.0F-pV
float ipVal = 1.0F-pV
Modified: openbts/trunk/CommonLibs/BitVector.h
===================================================================
--- openbts/trunk/CommonLibs/BitVector.h
03:03:10 UTC (rev
+++ openbts/trunk/CommonLibs/BitVector.h
04:21:20 UTC (rev
@@ -1,5 +1,5 @@
-* Copyright 2008 Free Software Foundation, Inc.
+* Copyright
Free Software Foundation, Inc.
* This software is distributed under the terms of the GNU Public License.
* See the COPYING file in the main directory for details.
Modified: openbts/trunk/CommonLibs/Configuration.cpp
===================================================================
--- openbts/trunk/CommonLibs/Configuration.cpp
03:03:10 UTC (rev
+++ openbts/trunk/CommonLibs/Configuration.cpp
04:21:20 UTC (rev
@@ -35,7 +35,7 @@
ifstream configFile(filename);
if (!configFile) {
LOG(WARN) && &cannot open configuration file & &&
cerr && &cannot open configuration file & && filename &&
while (configFile) {
@@ -49,13 +49,19 @@
if (thisLine[i]=='#')
// Skip blank lines
if (thisLine[i]=='\0')
// Catch directives
if (thisLine[i]=='$') {
processDirective(thisLine);
// Tokenize and put in the table.
string::size_type pos = thisLine.find_first_of(& &,i);
string key = thisLine.substr(i,pos);
if (pos==string::npos) {
mTable[thisLine]=&&;
mTable[key]=&&;
LOG(DEBUG) && &configuring & && key && & with empty
string key = thisLine.substr(0,pos);
string value = thisLine.substr(pos+1);
mTable[key]=
LOG(DEBUG) && &configuring & && key && & = & &&
@@ -65,7 +71,21 @@
+void ConfigurationTable::processDirective(const string& thisLine)
string::size_type pos = thisLine.find_first_of(& &);
string directive = thisLine.substr(1,pos-1);
if (directive==&static&) {
string key = thisLine.substr(pos+1);
mStatic[key] =
LOG(DEBUG) && &configuring & && key && & as static&;
cerr && &invalid configuration directive: & && thisLine &&
bool ConfigurationTable::defines(const string& key) const
StringMap::const_iterator where = mTable.find(key);
@@ -74,6 +94,15 @@
+bool ConfigurationTable::isStatic(const string& key) const
StringBoolMap::const_iterator where = mStatic.find(key);
if (where==mStatic.end())
return where-&
const char* ConfigurationTable::getStr(const string& key) const
StringMap::const_iterator where = mTable.find(key);
@@ -108,11 +137,18 @@
-void ConfigurationTable::set(const string& key, long value)
+bool ConfigurationTable::set(const string& key, const string& value)
if (isStatic(key))
mTable[key]=
+bool ConfigurationTable::set(const string& key, long value)
char buffer[30];
sprintf(buffer,&%ld&,value);
set(key,buffer);
return set(key,buffer);
Modified: openbts/trunk/CommonLibs/Configuration.h
===================================================================
--- openbts/trunk/CommonLibs/Configuration.h
03:03:10 UTC (rev
+++ openbts/trunk/CommonLibs/Configuration.h
04:21:20 UTC (rev
@@ -55,6 +55,7 @@
typedef std::map&std::string,std::string& StringM
+typedef std::map&std::string,bool& StringBoolM
@@ -68,8 +69,11 @@
StringMap mT
StringMap mT
///& The configuration table
StringBoolMap mS
///& Flags to indicate static config
// Static config values cannot be modified after initial file read.
bool readFile(const char* filename);
@@ -82,6 +86,9 @@
bool defines(const std::string& key)
/** Return true if this key is identified as static. */
bool isStatic(const std::string& key)
Get a string parameter from the table.
Throw ConfigurationTableKeyNotFound if not found.
@@ -100,14 +107,24 @@
std::vector&unsigned& getVector(const std::string& key)
/** Set or change a value in the table.
void set(const std::string& key, const std::string& value)
{ mTable[key]= }
bool set(const std::string& key, const std::string& value);
void set(const std::string& key, long value);
bool set(const std::string& key, long value);
/** Dump the table to a stream. */
void dump(std::ostream&)
/** Raw iterator. */
StringMap::const_iterator begin() const { return mTable.begin(); }
/** End check. */
StringMap::const_iterator end() const { return mTable.end(); }
void processDirective(const std::string& line);
Modified: openbts/trunk/CommonLibs/ConfigurationTest.cpp
===================================================================
--- openbts/trunk/CommonLibs/ConfigurationTest.cpp
03:03:10 UTC
(rev 11666)
+++ openbts/trunk/CommonLibs/ConfigurationTest.cpp
04:21:20 UTC
(rev 11667)
@@ -46,6 +46,6 @@
std::vector&unsigned& vect = config.getVector(&key5&);
cout && &vect length & && vect.size() && &: &;
for (int i=0; i&vect.size(); i++) cout && & & && vect[i];
for (unsigned i=0; i&vect.size(); i++) cout && & & && vect[i];
Modified: openbts/trunk/CommonLibs/F16.h
===================================================================
--- openbts/trunk/CommonLibs/F16.h
03:03:10 UTC (rev 11666)
+++ openbts/trunk/CommonLibs/F16.h
04:21:20 UTC (rev 11667)
@@ -26,7 +26,7 @@
#ifndef F16_H
#define F16_H
+#include &stdint.h&
#include &ostream&
@@ -75,6 +75,7 @@
F16 operator=(int i)
mV = i&&16;
F16 operator=(const F16& other)
Modified: openbts/trunk/CommonLibs/Interthread.h
===================================================================
--- openbts/trunk/CommonLibs/Interthread.h
03:03:10 UTC (rev
+++ openbts/trunk/CommonLibs/Interthread.h
04:21:20 UTC (rev
@@ -159,7 +159,7 @@
~InterthreadQueueWithWait()
virtual ~InterthreadQueueWithWait()
{ clear(); }
Modified: openbts/trunk/CommonLibs/LogTest.cpp
===================================================================
--- openbts/trunk/CommonLibs/LogTest.cpp
03:03:10 UTC (rev
+++ openbts/trunk/CommonLibs/LogTest.cpp
04:21:20 UTC (rev
@@ -22,8 +22,18 @@
+#include &iostream&
+#include &iterator&
#include &Logger.h&
+void printAlarms()
std::ostream_iterator&std::string& output( std::cout, &\n& );
std::list&std::string& alarms = gGetLoggerAlarms();
std::cout && &#alarms = & && alarms.size() && std::
std::copy( alarms.begin(), alarms.end(), output );
int main(int argc, char *argv[])
@@ -34,6 +44,17 @@
LOG(INFO) && & testing the logger.&;
LOG(DEBUG) && & testing the logger.&;
LOG(DEEPDEBUG) && & testing the logger.&;
std::cout && &\n\n\n&;
std::cout && &testing Alarms - you should run apps/showalarms.py to check
LOG(ALARM) && & testing the logger alarm.&;
std::cout && &you should see one line:& && std::
printAlarms();
std::cout && &----------- generating 20 alarms ----------& && std::
for (int i = 0 ; i & 20 ; ++i) {
LOG(ALARM) &&
std::cout && &you should see ten line with the numbers 10..19:& &&
printAlarms();
Modified: openbts/trunk/CommonLibs/Logger.cpp
===================================================================
--- openbts/trunk/CommonLibs/Logger.cpp
03:03:10 UTC (rev 11666)
+++ openbts/trunk/CommonLibs/Logger.cpp
04:21:20 UTC (rev 11667)
@@ -22,13 +22,16 @@
-#include &stdio.h&
+#include &string.h&
+#include &cstdio&
+#include &fstream&
+#include &Configuration.h&
+#include &Sockets.h&
#include &Logger.h&
#include &Timeval.h&
-#include &string.h&
@@ -39,6 +42,19 @@
/** The global logging lock. */
static Mutex gLogL
+/**@ The global alarms table. */
+const unsigned
gMaxAlarms = 10;
+list&string&
gAddAlarm(const string&);
+const unsigned int DEFAULT_ALARM_TARGET_PORT = 10101;
+const char*
DEFAULT_ALARM_TARGET_IP = &127.0.0.1&;
+unsigned int
gAlarmTargetPort = DEFAULT_ALARM_TARGET_PORT;
+std::string
gAlarmTargetIP = DEFAULT_ALARM_TARGET_IP;
/** The current global logging level. */
static Log::Level gLoggingLevel = Log::LOG_WARN;
@@ -102,8 +118,30 @@
return retV
+void gSetAlarmTargetPort(unsigned int port)
LOG(INFO) && &setting ALARM target port to & &&
gAlarmTargetPort =
+void gSetAlarmTargetIP(const char* ip)
LOG(INFO) && &setting ALARM target IP to & &&
gAlarmTargetIP =
+// copies the alarm list and returns it. list supposed to be small.
+std::list&std::string& gGetLoggerAlarms()
gAlarmsLock.lock();
std::list&std::string&
// excuse the &complexity&, but to use std::copy with a list you need
// an insert_iterator - copy technically overwrites, doesn't insert.
std::insert_iterator& std::list&std::string& & ii(ret, ret.begin());
std::copy(gAlarmsList.begin(), gAlarmsList.end(), ii);
gAlarmsLock.unlock();
ostream& operator&&(ostream& os, Log::Level level)
@@ -112,11 +150,30 @@
+// Add an alarm to the alarm list, and send it out via udp
+// On the first call we read the ip and port from the configuration
+// TODO - is there any global setup function where this should be done? -- Alon
+void gAddAlarm(const string& s)
gAlarmsLock.lock();
// Socket open and close on every alarm - wise?
// Probably.
That way we are sure to pick up changes in the target
// Alarms should not happen often.
UDPSocket alarmsocket(0, gAlarmTargetIP.c_str(), gAlarmTargetPort);
alarmsocket.write(s.c_str());
// append to list and reduce list to gMaxAlarms
gAlarmsList.push_back(s);
while (gAlarmsList.size() & gMaxAlarms) gAlarmsList.pop_front();
gAlarmsLock.unlock();
Log::~Log()
gLogLock.lock();
// XXX always handle alarms, even if the logging level is too low
if (mReportLevel == LOG_ALARM) gAddAlarm(mStream.str().c_str());
if (mReportLevel&gLoggingLevel)
mStream && std::
fprintf(gLoggingFile, &%s&, mStream.str().c_str());
Modified: openbts/trunk/CommonLibs/Logger.h
===================================================================
--- openbts/trunk/CommonLibs/Logger.h
03:03:10 UTC (rev 11666)
+++ openbts/trunk/CommonLibs/Logger.h
04:21:20 UTC (rev 11667)
@@ -27,6 +27,8 @@
#define LOGGER_H
#include &sstream&
+#include &list&
+#include &string&
#include &Threads.h&
@@ -69,7 +71,6 @@
static FILE *sF
Log(Level wReportLevel = LOG_WARN)
@@ -84,6 +85,10 @@
std::ostringstream& operator&&(std::ostringstream& os, Log::Level);
+std::list&std::string& gGetLoggerAlarms();
///& Get a copy of the
recent alarm list.
/**@ Global logging level control. */
void gSetLogLevel(Log::Level);
@@ -98,7 +103,13 @@
bool gSetLogFile(const char*);
+/address@hidden Global logging alarm target host control. */
+void gSetAlarmTargetPort(unsigned int);
+void gSetAlarmTargetIP(const char*);
// vim: ts=4 sw=4
Modified: openbts/trunk/CommonLibs/Makefile.am
===================================================================
--- openbts/trunk/CommonLibs/Makefile.am
03:03:10 UTC (rev
+++ openbts/trunk/CommonLibs/Makefile.am
04:21:20 UTC (rev
@@ -21,7 +21,7 @@
include $(top_srcdir)/mon
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
-AM_CXXFLAGS = -O3 -g -lpthread
+AM_CXXFLAGS = -Wall -O3 -g -lpthread
EXTRA_DIST = \
example.config \
Modified: openbts/trunk/CommonLibs/Sockets.cpp
===================================================================
--- openbts/trunk/CommonLibs/Sockets.cpp
03:03:10 UTC (rev
+++ openbts/trunk/CommonLibs/Sockets.cpp
04:21:20 UTC (rev
@@ -24,6 +24,9 @@
+#include &unistd.h&
+#include &fcntl.h&
+#include &cstdio&
#include &Threads.h&
#include &Sockets.h&
@@ -65,6 +68,10 @@
fcntl(mSocketFD,F_SETFL,O_NONBLOCK);
+void DatagramSocket::blocking()
fcntl(mSocketFD,F_SETFL,0);
void DatagramSocket::close()
Modified: openbts/trunk/CommonLibs/Sockets.h
===================================================================
--- openbts/trunk/CommonLibs/Sockets.h
03:03:10 UTC (rev 11666)
+++ openbts/trunk/CommonLibs/Sockets.h
04:21:20 UTC (rev 11667)
@@ -114,6 +114,9 @@
/** Make the socket non-blocking. */
void nonblocking();
/** Make the socket blocking (the default). */
void blocking();
/** Close the socket. */
void close();
Modified: openbts/trunk/Control/CallControl.cpp
===================================================================
--- openbts/trunk/Control/CallControl.cpp
03:03:10 UTC (rev
+++ openbts/trunk/Control/CallControl.cpp
04:21:20 UTC (rev
@@ -66,7 +66,7 @@
unsigned allocateRTPPorts()
// FIXME -- We need a real port allocator (bug #82).
// FIXME -- We need a real port allocator.
const unsigned base = gConfig.getNum(&RTP.Start&);
const unsigned range = gConfig.getNum(&RTP.Range&);
const unsigned top = base+
@@ -172,25 +172,24 @@
bool assignTCHF(TransactionEntry& transaction, SDCCHLogicalChannel *SDCCH,
TCHFACCHLogicalChannel *TCH)
TCH-&open();
// Try twice to send the assignment.
// (The spec says just try once...)
for (int i=0; i&2; i++) {
LOG(INFO) && &sending AssignmentCommand for & && TCH && & on &
SDCCH-&send(L3AssignmentCommand(TCH-&channelDescription(),L3ChannelMode(L3ChannelMode::SpeechV1)));
// This read is SUPPOSED to time out if the assignment was
successful.
// Pad the timeout just in case there's a large latency
somewhere.
L3Frame *result = SDCCH-&recv(T3107ms+2000);
if (result==NULL) {
LOG(INFO) && &completing normally&;
SDCCH-&send(HARDRELEASE);
LOG(NOTICE) && &received & && *
TCH-&setPhy(*SDCCH);
// Send the assignment.
LOG(INFO) && &assignTCHF sending AssignmentCommand for & && TCH && & on
& && SDCCH;
SDCCH-&send(L3AssignmentCommand(TCH-&channelDescription(),L3ChannelMode(L3ChannelMode::SpeechV1)));
// This read is SUPPOSED to time out if the assignment was successful.
// Pad the timeout just in case there's a large latency somewhere.
L3Frame *result = SDCCH-&recv(T3107ms+2000);
if (result==NULL) {
LOG(INFO) && &assignmentTCHF exiting normally&;
SDCCH-&send(RELEASE);
// If we got here, the assignment failed.
LOG(NOTICE) && &assignTCHF received & && *
// Turn off the TCH.
TCH-&send(RELEASE);
@@ -502,6 +501,7 @@
// See if the radio link disappeared.
if (TCH-&radioFailure()) {
LOG(NOTICE) && &radio link failure, dropped call&;
forceSIPClearing(transaction);
clearTransactionHistory(transaction);
@@ -72,10 @@
-void Control::initiateMTTransaction(const TransactionEntry& transaction,
GSM::ChannelType chanType, unsigned pageTime)
+void Control::initiateMTTransaction(TransactionEntry& transaction,
GSM::ChannelType chanType, unsigned pageTime)
gTransactionTable.add(transaction);
gBTS.pager().addID(transaction.subscriber(),chanType,transaction.ID(),pageTime);
gBTS.pager().addID(transaction.subscriber(),chanType,transaction,pageTime);
Modified: openbts/trunk/Control/ControlCommon.cpp
===================================================================
--- openbts/trunk/Control/ControlCommon.cpp
03:03:10 UTC (rev
+++ openbts/trunk/Control/ControlCommon.cpp
04:21:20 UTC (rev
@@ -60,16 +60,17 @@
mT301(T301ms), mT302(T302ms), mT303(T303ms),
mT304(T304ms), mT305(T305ms), mT308(T308ms),
mT310(T310ms), mT313(T313ms),
mT3113(GSM::T3113ms),
mTR1M(GSM::TR1Mms)
mT3113(gConfig.getNum(&GSM.T3113&)),
mTR1M(TR1Mms)
mMessage[0]='\0';
// Form for MT transactions.
-TransactionEntry::TransactionEntry(const GSM::L3MobileIdentity& wSubscriber,
const GSM::L3CMServiceType& wService,
const GSM::L3CallingPartyBCDNumber& wCalling)
+TransactionEntry::TransactionEntry(const L3MobileIdentity& wSubscriber,
const L3CMServiceType& wService,
const L3CallingPartyBCDNumber& wCalling,
const char *wMessage)
:mID(gTransactionTable.newID()),
mSubscriber(wSubscriber),mService(wService),
mTIFlag(1), mTIValue(0),
@@ -78,17 +79,18 @@
mT301(T301ms), mT302(T302ms), mT303(T303ms),
mT304(T304ms), mT305(T305ms), mT308(T308ms),
mT310(T310ms), mT313(T313ms),
mT3113(GSM::T3113ms),
mTR1M(GSM::TR1Mms)
mT3113(gConfig.getNum(&GSM.T3113&)),
mTR1M(TR1Mms)
mMessage[0]='\0';
if (wMessage) strncpy(mMessage,wMessage,160);
else mMessage[0]='\0';
// Form for MO transactions.
-TransactionEntry::TransactionEntry(const GSM::L3MobileIdentity& wSubscriber,
const GSM::L3CMServiceType& wService,
+TransactionEntry::TransactionEntry(const L3MobileIdentity& wSubscriber,
const L3CMServiceType& wService,
unsigned wTIValue,
const GSM::L3CalledPartyBCDNumber& wCalled)
const L3CalledPartyBCDNumber& wCalled)
:mID(gTransactionTable.newID()),
mSubscriber(wSubscriber),mService(wService),
mTIFlag(0), mTIValue(wTIValue),
@@ -97,17 +99,17 @@
mT301(T301ms), mT302(T302ms), mT303(T303ms),
mT304(T304ms), mT305(T305ms), mT308(T308ms),
mT310(T310ms), mT313(T313ms),
mT3113(GSM::T3113ms),
mTR1M(GSM::TR1Mms)
mT3113(gConfig.getNum(&GSM.T3113&)),
mTR1M(TR1Mms)
mMessage[0]='\0';
// Form for MT transactions.
-TransactionEntry::TransactionEntry(const GSM::L3MobileIdentity& wSubscriber,
const GSM::L3CMServiceType& wService,
+TransactionEntry::TransactionEntry(const L3MobileIdentity& wSubscriber,
const L3CMServiceType& wService,
unsigned wTIValue,
const GSM::L3CallingPartyBCDNumber& wCalling)
const L3CallingPartyBCDNumber& wCalling)
:mID(gTransactionTable.newID()),
mSubscriber(wSubscriber),mService(wService),
mTIFlag(1),mTIValue(wTIValue),mCalling(wCalling),
@@ -115,8 +117,8 @@
mT301(T301ms), mT302(T302ms), mT303(T303ms),
mT304(T304ms), mT305(T305ms), mT308(T308ms),
mT310(T310ms), mT313(T313ms),
mT3113(GSM::T3113ms),
mTR1M(GSM::TR1Mms)
mT3113(gConfig.getNum(&GSM.T3113&)),
mTR1M(TR1Mms)
mMessage[0]='\0';
@@ -184,7 +186,7 @@
bool TransactionEntry::dead() const
if (mQ931State==NullState)
if ((mQ931State==Paging)&&mT3113.expired())
if ((mQ931State==Paging) && mT3113.expired())
@@ -193,7 +195,7 @@
switch (state) {
case TransactionEntry::NullState: os && &null&;
case TransactionEntry::Paging: os && &MTC paging&;
case TransactionEntry::Paging: os && &paging&;
case TransactionEntry::MOCInitiated: os && &MOC initiated&;
case TransactionEntry::MOCProceeding: os && &MOC proceeding&;
case TransactionEntry::MTCConfirmed: os && &MTC confirmed&;
@@ -220,6 +222,7 @@
if (entry.calling().digits()[0]) os && & from=& &&
entry.calling().digits();
os && & Q.931State=& && entry.Q931State();
os && & SIPState=& && entry.SIP().state();
os && & (& && (entry.stateAge()+500)/1000 && & sec)&;
if (entry.message()[0]) os && & message=\&& && entry.message() && &\&&;
@@ -338,9 +341,12 @@
return foundIt;
+size_t TransactionTable::size()
return mTable.size();
void Control::clearTransactionHistory( TransactionEntry& transaction )
SIP::SIPEngine& engine = transaction.SIP();
@@ -354,7 +360,11 @@
if (transactionID==0)
TransactionE
if (gTransactionTable.find(transactionID,transaction))
clearTransactionHistory(transaction);
if (gTransactionTable.find(transactionID,transaction)) {
clearTransactionHistory(transaction);
LOG(INFO) && &clearTransactionHistory didn't find & &&
transactionID && &(size = & && gTransactionTable.size() && &)&;
Modified: openbts/trunk/Control/ControlCommon.h
===================================================================
--- openbts/trunk/Control/ControlCommon.h
03:03:10 UTC (rev
+++ openbts/trunk/Control/ControlCommon.h
04:21:20 UTC (rev
@@ -156,7 +156,9 @@
/address@hidden Functions for radio resource operations. */
/** Decode RACH bits and send an immediate assignment. */
-void AccessGrantResponder(unsigned requestReference, const GSM::Time& when,
float timingError);
+void AccessGrantResponder(
unsigned requestReference, const GSM::Time& when,
float RSSI, float timingError);
/** Find and compelte the in-process transaction associated with a paging
repsonse. */
void PagingResponseHandler(const GSM::L3PagingResponse*, GSM::LogicalChannel*);
/** Find and compelte the in-process transaction associated with a completed
assignment. */
@@ -206,7 +208,7 @@
/** Create a new transaction entry and start paging. */
-void initiateMTTransaction(const TransactionEntry& transaction,
+void initiateMTTransaction(TransactionEntry& transaction,
GSM::ChannelType chanType, unsigned pageTime);
@@ -270,7 +272,7 @@
const GSM::L3MobileIdentity& ID() const { return mID; }
/** Access the channel type needed. */
const GSM::ChannelType type() const { return mT }
GSM::ChannelType type() const { return mT }
unsigned transactionID() const { return mTransactionID; }
@@ -315,13 +317,14 @@
Add a mobile ID to the paging list.
@param addID The mobile ID to be paged.
@param chanType The channel type to be requested.
@param transaction The transaction record, which will be
@param wLife The paging duration in ms, default based on SIP
INVITE retry preiod, Timer A.
void addID(
const GSM::L3MobileIdentity& addID,
GSM::ChannelType chanType,
unsigned wTransactionID,
unsigned wLife=gConfig.getNum(&SIP.Timer.A&)
TransactionEntry& transaction,
unsigned wLife=2*gConfig.getNum(&SIP.Timer.A&)
@@ -344,6 +347,14 @@
/** C-style adapter. */
friend void *PagerServiceLoopAdapter(Pager*);
/** return size of PagingEntryList */
size_t pagingEntryListSize();
/** Dump the paging list to an ostream. */
void dump(std::ostream&)
@@ -387,7 +398,7 @@
unsigned mID;
the internal transaction ID, assigned by a TransactionTable
unsigned mID;
internal transaction ID, assigned by a TransactionTable
GSM::L3MobileIdentity mS
///& some kind of
subscriber ID, preferably IMSI
GSM::L3CMServiceType mS
///& the associated
service type
@@ -396,8 +407,9 @@
GSM::L3CalledPartyBCDNumber mC
///& the associated called
party number, if known
GSM::L3CallingPartyBCDNumber mC
///& the associated calling
party number, if known
SIP::SIPEngine mSIP;
the SIP IETF RFC-3621 protocol engine
Q931CallState mQ931S
the GSM/ISDN/Q.931 call state
SIP::SIPEngine mSIP;
///& the SIP
IETF RFC-3621 protocol engine
Q931CallState mQ931S
GSM/ISDN/Q.931 call state
Timeval mStateT
///& timestamp
of last state change.
char mMessage[256];
text messaging payload
@@ -421,10 +433,11 @@
TransactionEntry();
/** This form is used for MTC with TI set to 0. */
/** This form is used for MTC or MT-SMS with TI set to 0. */
TransactionEntry(const GSM::L3MobileIdentity& wSubscriber,
const GSM::L3CMServiceType& wService,
const GSM::L3CallingPartyBCDNumber& wCalling);
const GSM::L3CallingPartyBCDNumber& wCalling,
const char *wMessage = NULL);
/** This form is used for MOC. */
TransactionEntry(const GSM::L3MobileIdentity& wSubscriber,
@@ -466,9 +479,16 @@
SIP::SIPEngine& SIP() { return mSIP; }
const SIP::SIPEngine& SIP() const { return mSIP; }
void Q931State(Q931CallState wState) { mQ931State=wS }
void Q931State(Q931CallState wState)
mStateTimer.now();
mQ931State=wS
Q931CallState Q931State() const { return mQ931S }
unsigned stateAge() const { return mStateTimer.elapsed(); }
/address@hidden Timer access. */
// TODO -- If we were clever, this would be a table.
@@ -587,9 +607,11 @@
/address@hidden to raw map. */
TransactionMap::const_iterator begin() const { return mTable.begin(); }
TransactionMap::const_iterator begin() { clearDeadEntries(); return
mTable.begin(); }
TransactionMap::const_iterator end() const { return mTable.end(); }
size_t size();
//@} // Transaction Table
@@ -652,7 +674,14 @@
/** Clear the table completely. */
void clear() { mMap.clear(); }
size_t size() const {
mLock.lock();
size_t retVal = mMap.size();
mLock.unlock();
return retV
TMSIMap::const_iterator begin() const { return mMap.begin(); }
TMSIMap::const_iterator end() const { return mMap.end(); }
@@ -746,7 +775,6 @@
// vim: ts=4 sw=4
Modified: openbts/trunk/Control/Makefile.am
===================================================================
--- openbts/trunk/Control/Makefile.am
03:03:10 UTC (rev 11666)
+++ openbts/trunk/Control/Makefile.am
04:21:20 UTC (rev 11667)
@@ -21,6 +21,7 @@
include $(top_srcdir)/mon
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
+AM_CXXFLAGS = -Wall -O3
EXTRA_DIST = README.Control
@@ -32,7 +33,13 @@
ControlCommon.cpp \
MobilityManagement.cpp \
RadioResource.cpp \
DCCHDispatch.cpp
DCCHDispatch.cpp \
CollectMSInfo.cpp \
RRLPQueryController.cpp
+# TODO - move CollectMSInfo.cpp and RRLPQueryController.cpp to RRLP directory.
noinst_HEADERS = \
ControlCommon.h
ControlCommon.h \
CollectMSInfo.h \
RRLPQueryController.h
Modified: openbts/trunk/Control/MobilityManagement.cpp
===================================================================
--- openbts/trunk/Control/MobilityManagement.cpp
03:03:10 UTC
(rev 11666)
+++ openbts/trunk/Control/MobilityManagement.cpp
04:21:20 UTC
(rev 11667)
@@ -24,10 +24,8 @@
+#include &Timeval.h&
#include &ControlCommon.h&
#include &GSMLogicalChannel.h&
#include &GSML3RRMessages.h&
@@ -35,6 +33,8 @@
#include &GSML3CCMessages.h&
#include &GSMConfig.h&
+#include &CollectMSInfo.h&
#include &SIPInterface.h&
@@ -48,9 +48,6 @@
using namespace C
/** Controller for CM Service requests, dispatches out to multiple possible
transaction controllers. */
void Control::CMServiceResponder(const L3CMServiceRequest* cmsrq,
LogicalChannel* DCCH)
@@ -126,7 +123,6 @@
Controller for the Location Updating transaction, GSM 04.08 4.4.4.
@param lur The location updating request.
@@ -163,6 +159,8 @@
LOG(ALARM) &SIP registration timed out.
Is Asterisk running?&;
// Reject with a &network failure& cause code, 0x11.
SDCCH-&send(L3LocationUpdatingReject(0x11));
// HACK -- wait long enough for a response
// Release the channel and return.
SDCCH-&send(L3ChannelRelease());
@@ -178,8 +176,18 @@
if (!success && !openRegistration) {
LOG(INFO) && &registration FAILED: & && mobID;
SDCCH-&send(L3LocationUpdatingReject(gConfig.getNum(&GSM.LURejectCause&)));
// Get position information anyhow. Slightly Evil.
bool withRRLP = gConfig.defines(&GSM.RRLP&) &&
(gConfig.getNum(&GSM.RRLP&) == 1) &&
gConfig.defines(&RRLP.LocationUpdate&) &&
(gConfig.getNum(&RRLP.LocationUpdate&) == 1);
LOG(INFO) && &Collecting MS Info withRRLP = & && withRRLP;
GSM::RRLP::collectMSInfo(mobID, SDCCH, withRRLP);
sendWelcomeMessage( &Control.FailedRegistrationWelcomeMessage&,
&Control.FailedRegistrationWelcomeShortCode&, SDCCH);
// Release the channel and return.
SDCCH-&send(L3ChannelRelease());
// If success is true, we had a normal registration.
@@ -194,8 +202,19 @@
// TODO -- Set the handset clock in this message, too.
SDCCH-&send(L3MMInformation(gBTS.shortName()));
// Accept. Make a TMSI assignment, too, if needed.
if (assignedTMSI) SDCCH-&send(L3LocationUpdatingAccept(gBTS.LAI()));
SDCCH-&send(L3LocationUpdatingAccept(gBTS.LAI(),gTMSITable.assign(mobID.digits())));
if (assignedTMSI) {
SDCCH-&send(L3LocationUpdatingAccept(gBTS.LAI()));
SDCCH-&send(L3LocationUpdatingAccept(gBTS.LAI(),gTMSITable.assign(mobID.digits())));
L3Frame* resp = SDCCH-&recv(1000); // wait for the MM TMSI
REALLOCATION COMPLETE message
if (!resp) {
LOG(INFO) && &LocationUpdatingController no response to
TMSI assignment&;
LOG(INFO) && &LocationUpdatingController got back a &
// If this is an IMSI attach, send a welcome message.
if (IMSIAttach) {
if (success) {
@@ -207,6 +226,11 @@
GSM::RRLP::collectMSInfo(mobID, SDCCH, false/* no RRLP */);
// HACK -- wait long enough for a response
// Release the channel and return.
SDCCH-&send(L3ChannelRelease());
@@ -215,5 +239,4 @@
// vim: ts=4 sw=4
Modified: openbts/trunk/Control/RadioResource.cpp
===================================================================
--- openbts/trunk/Control/RadioResource.cpp
03:03:10 UTC (rev
+++ openbts/trunk/Control/RadioResource.cpp
04:21:20 UTC (rev
@@ -1,7 +1,7 @@
/address@hidden GSM Radio Resource procedures, GSM 04.18 and GSM 04.08. */
-* Copyright 2008 Free Software Foundation, Inc.
+* Copyright
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
@@ -46,44 +46,11 @@
-/address@hidden Mechanisms for exponential backoff of T3122, the access
holdoff timer. */
-unsigned curT3122ms = 5000;
-Mutex curT3122L
Get latest value of T3122 and apply exponential backoff.
@return Current T3122 value in ms.
-unsigned curT3122()
curT3122Lock.lock();
unsigned retVal = curT3122
// Apply exponential back-off.
curT3122ms += (random() % curT3122ms) / 2;
unsigned max = gConfig.getNum(&GSM.T3122Max&);
if (curT3122ms&max) curT3122ms=
curT3122Lock.unlock();
return retV
-/** Restore T3122 to the base value.
-void restoreT3122()
curT3122Lock.lock();
curT3122ms = gConfig.getNum(&GSM.T3122Min&);
curT3122Lock.unlock();
Determine the channel type needed.
This is based on GSM 04.08 9.1.8, Table 9.3 and 9.3a.
The following is assumed about the global BTS capabilities:
- We do not support &new establishment causes& and NECI is 0.
- We do not support call reestablishment.
- We do not support GPRS.
@param RA The request reference from the channel request message.
@@ -91,47 +58,67 @@
ChannelType decodeChannelNeeded(unsigned RA)
// These values assume NECI is 0.
// This code is formatted in the same order as GSM 04.08 Table 9.9.
// Emergency
// This code is based on GSM 04.08 Table 9.9.
unsigned RA4 = RA&&4;
unsigned RA5 = RA&&5;
// FIXME -- Use SDCCH to start emergency call, since some handsets
don't support VEA.
if ((RA&&5) == 0x05) return TCHFT
// emergency
// skip re-establishment cases
// &Answer to paging&
// We do not send the &any channel& paging indication, just SDCCH and
// Cases where we sent SDCCH.
if ((RA&&4) == 0x01) return SDCCHT
// answer to
paging, SDCCH
// Cases where we sent TCH/F.
if ((RA&&5) == 0x04) return TCHFT
// answer to
paging, any channel
if ((RA&&4) == 0x02) return TCHFT
// answer to
paging, TCH/F
// We don't send TCH/[FH], either.
// MOC or SDCCH procedures.
if ((RA&&5) == 0x07) return SDCCHT
// MOC or SDCCH
procedures
// Location updating.
if ((RA&&5) == 0x00) return SDCCHT
// location
// skip packet (GPRS) cases
// skip LMU case
// skip reserved cases
if (RA5 == 0x05) return TCHFT
// emergency call
// Answer to paging, Table 9.9a.
// We don't support TCH/H, so it's wither SDCCH or TCH/F.
// The spec allows for &SDCCH-only& MS.
We won't support that here.
// FIXME -- So we probably should not use &any channel& in the paging
indications.
if (RA5 == 0x04) return TCHFT
// any channel or any
if (RA4 == 0x01) return SDCCHT
if (RA4 == 0x02) return TCHFT
if (RA4 == 0x03) return TCHFT
int NECI = gConfig.getNum(&GSM.CS.NECI&);
if (NECI==0) {
if (RA5 == 0x07) return SDCCHT
// MOC or SDCCH
procedures
if (RA5 == 0x00) return SDCCHT
// location
assert(NECI==1);
bool veryEarly = gConfig.getNum(&GSM.AssignmentType&);
if (veryEarly) {
if (RA5 == 0x07) return TCHFT
if (RA4 == 0x04) return TCHFT
TCH/H sufficient
if (RA5 == 0x07) return SDCCHT
if (RA4 == 0x04) return SDCCHT
TCH/H sufficient
if (RA4 == 0x00) return SDCCHT
// location
if (RA4 == 0x01) return SDCCHT
procedures on SDCCH
// Anything else falls through to here.
// We are still ignoring data calls, GPRS, LMU.
return UndefinedCHT
-void Control::AccessGrantResponder(unsigned RA, const GSM::Time& when, float
timingError)
+/** Return true is RA indicates LUR. */
+bool requestingLUR(unsigned RA)
unsigned RA4 = RA&&4;
unsigned RA5 = RA&&5;
int NECI = gConfig.getNum(&GSM.CS.NECI&);
if (NECI==0) {
if (RA5 == 0x00)
assert(NECI==1);
if (RA4 == 0x00)
+void Control::AccessGrantResponder(
unsigned RA, const GSM::Time& when,
float RSSI, float timingError)
// RR Establishment.
// Immediate Assignment procedure, &Answer from the Network&
// GSM 04.08 3.3.1.1.3.
@@ -140,19 +127,17 @@
// This GSM's version of medium access control.
// Papa Legba, open that door...
// FIXME -- Need to deal with initial timing advance, too.
// Check &when& against current clock to see if we're too late.
// Calculate maximum number of frames of delay.
// See GSM 04.08 3.3.1.1.2 for the logic here.
static const unsigned txInteger = gConfig.getNum(&GSM.RACH.TxInteger&);
static const unsigned maxAge = GSM::RACHSpreadSlots[txInteger] +
GSM::RACHWaitSParam[txInteger];
static const int maxAge = GSM::RACHSpreadSlots[txInteger] +
GSM::RACHWaitSParam[txInteger];
// Check burst age.
int age = gBTS.time() -
LOG(INFO) && &RA=0x& && hex && RA && dec
&& & when=& && when && & age=& && age && & TOA=& && timingE
if (age&maxAge) {
LOG(NOTICE) && &ignoring RACH bust with age & &&
LOG(WARN) && &ignoring RACH bust with age & &&
@@ -161,13 +146,32 @@
if (timingError & gConfig.getNum(&GSM.MaxRACHDelay&))
// Get an AGCH to send on.
CCCHLogicalChannel *AGCH = gBTS.getAGCH();
// Someone had better have created a least one AGCH.
assert(AGCH);
// Check for location update.
// This gives LUR a lower priority than other services.
if (requestingLUR(RA)) {
(gBTS.SDCCHAvailable()&=gConfig.getNum(&GSM.PagingReservations&)) {
unsigned waitTime = gBTS.growT3122()/1000;
LOG(NOTICE) && &AccessGrantResponder: LUR congestion,
RA=& && RA && & T3122=& && waitT
const L3ImmediateAssignmentReject
reject(L3RequestReference(RA,when),waitTime);
LOG(DEBUG) && &AccessGrantResponder: LUR rejection,
sending & &&
if (AGCH-&load()&gConfig.getNum(&GSM.AGCHMaxQueue&))
AGCH-&send(reject);
else LOG(NOTICE) &AccessGrantResponder: AGCH
congestion&;
// Allocate the channel according to the needed type indicated by RA.
// The returned channel is already open and ready for the transaction.
LogicalChannel *LCH = NULL;
switch (decodeChannelNeeded(RA)) {
case TCHFType: LCH = gBTS.getTCH();
case SDCCHType: LCH = gBTS.getSDCCH();
// FIXME -- Should probably assign to an SDCCH and then send a
reject of some kind.
// If we don't support the service, assign to an SDCCH and we
can reject it in L3.
case UndefinedCHType:
LOG(NOTICE) && &RACH burst for unsupported service&;
@@ -177,23 +181,22 @@
default: assert(0);
// Get an AGCH to send on.
CCCHLogicalChannel *AGCH = gBTS.getAGCH();
// Someone had better have created a least one AGCH.
assert(AGCH);
// Nothing available?
if (!LCH) {
// Rejection, GSM 04.08 3.3.1.1.3.2.
// BTW, emergency calls are not subject to T3122 hold-off.
unsigned waitTime = curT3122()/1000;
LOG(NOTICE) && &CONGESTION, T3122=& && waitT
unsigned waitTime = gBTS.growT3122()/1000;
LOG(NOTICE) && &AccessGrantResponder: congestion, RA=& && RA &&
& T3122=& && waitT
const L3ImmediateAssignmentReject
reject(L3RequestReference(RA,when),waitTime);
LOG(DEBUG) && &rejection, sending & &&
AGCH-&send(reject);
if (AGCH-&load()&gConfig.getNum(&GSM.AGCHMaxQueue&))
AGCH-&send(reject);
else LOG(NOTICE) &AccessGrantResponder: AGCH congestion&;
// Set the channel physical parameters from the RACH burst.
LCH-&setPhy(RSSI,timingError);
// Assignment, GSM 04.08 3.3.1.1.3.1.
// Create the ImmediateAssignment message.
int initialTA = (int)(timingError + 0.5F);
@@ -207,8 +210,8 @@
LOG(INFO) && &sending & &&
AGCH-&send(assign);
// Reset exponential back-off upon successful allocation.
restoreT3122();
// On successful allocation, shrink T3122.
gBTS.shrinkT3122();
@@ -320,15 +323,17 @@
void Pager::addID(const L3MobileIdentity& newID, ChannelType chanType,
unsigned wTransactionID, unsigned wLife)
TransactionEntry& transaction, unsigned wLife)
transaction.Q931State(TransactionEntry::Paging);
transaction.T3113().set(wLife);
gTransactionTable.update(transaction);
// Add a mobile ID to the paging list for a given lifetime.
mLock.lock();
// If this ID is already in the list, just reset its timer.
// Uhg, another linear time search.
// This would be faster if the paging list were ordered by ID.
// But the list should usually be short, so it may not be worth the
bool renewed =
for (PagingEntryList::iterator lp = mPageIDs.begin(); lp !=
mPageIDs.end(); ++lp) {
if (lp-&ID()==newID) {
LOG(DEBUG) && newID && & already in table&;
@@ -339,7 +344,7 @@
// If this ID is new, put it in the list.
mPageIDs.push_back(PagingEntry(newID,chanType,wTransactionID,wLife));
mPageIDs.push_back(PagingEntry(newID,chanType,transaction.ID(),wLife));
LOG(INFO) && newID && & added to table&;
mPageSignal.signal();
mLock.unlock();
@@ -396,16 +401,14 @@
// HACK -- So we send every page twice.
// That will probably mean a different Pager for each
subchannel.
// See GSM 04.08 10.5.2.11 and GSM 05.02 6.5.2.
CCCHLogicalChannel *PCH = gBTS.getPCH();
assert(PCH);
const L3MobileIdentity& id1 = lp-&ID();
ChannelType type1 = lp-&type();
if (lp==mPageIDs.end()) {
// Just one ID left?
LOG(DEBUG) && &paging & && id1;
PCH-&send(L3PagingRequestType1(id1,type1));
PCH-&send(L3PagingRequestType1(id1,type1));
gBTS.getPCH(0)-&send(L3PagingRequestType1(id1,type1));
gBTS.getPCH(0)-&send(L3PagingRequestType1(id1,type1));
// Page by pairs when possible.
@@ -413,8 +416,8 @@
ChannelType type2 = lp-&type();
LOG(DEBUG) && &paging & && id1 && & and & && id2;
PCH-&send(L3PagingRequestType1(id1,type1,id2,type2));
PCH-&send(L3PagingRequestType1(id1,type1,id2,type2));
gBTS.getPCH(0)-&send(L3PagingRequestType1(id1,type1,id2,type2));
gBTS.getPCH(0)-&send(L3PagingRequestType1(id1,type1,id2,type2));
mLock.unlock();
@@ -422,8 +425,11 @@
return mPageIDs.size();
+size_t Pager::pagingEntryListSize()
return mPageIDs.size();
void Pager::start()
if (mRunning)
@@ -443,25 +449,33 @@
while (mRunning) {
LOG(DEBUG) && &Pager blocking for signal&;
mLock.lock();
while (mPageIDs.size()==0) mPageSignal.wait(mLock);
mLock.unlock();
// page everything
pageAll();
// Wait for pending activity to clear the channel.
// This wait is what causes PCH to have lower priority than
unsigned load = gBTS.getPCH()-&load();
LOG(DEBUG) && &Pager waiting for & && load && & multiframes&;
if (load) sleepFrames(51*load);
// Page the list.
// If there is nothing to page,
// wait for a new entry in the list.
if (!pageAll()) {
LOG(DEBUG) && &Pager blocking for signal&;
mLock.lock();
while (mPageIDs.size()==0) mPageSignal.wait(mLock);
mLock.unlock();
+void Pager::dump(ostream& os) const
PagingEntryList::const_iterator lp = mPageIDs.begin();
while (lp != mPageIDs.end()) {
os && lp-&ID() && & & && lp-&type() && & & && lp-&expired() &&
// vim: ts=4 sw=4
Modified: openbts/trunk/Control/SMSControl.cpp
===================================================================
--- openbts/trunk/Control/SMSControl.cpp
03:03:10 UTC (rev
+++ openbts/trunk/Control/SMSControl.cpp
04:21:20 UTC (rev
@@ -61,6 +61,7 @@
#include &SIPEngine.h&
using namespace SIP;
+#include &CollectMSInfo.h&
Read an L3Frame from SAP3.
@@ -404,6 +405,15 @@
ack.parse(*CM);
LOG(INFO) && &CPAck & &&
// RRLP Here if enabled
if (gConfig.defines(&GSM.RRLP&) && gConfig.getNum(&GSM.RRLP&) == 1 &&
gConfig.defines(&RRLP.LocationUpdate&) &&
gConfig.getNum(&RRLP.LocationUpdate&) == 1 /* RRLP? */)
RRLP::collectMSInfo(mobileIdentity, LCH, true /* DO RRLP */);
LOG(INFO) && &submitSMS with RRLP took & && start.elapsed() &&
& for IMSI & && mobileI
LOG(INFO) && &closing&;
LCH-&send(L3ChannelRelease());
@@ -438,7 +448,7 @@
RPData(reference,
RPAddress(gConfig.getStr(&SMS.FakeSrcSMSC&)),
TLDeliver(callingPartyDigits,message,TLPID)));
LOG(DEBUG) && &MTSMS: sending & &&
LOG(INFO) && &sending & &&
LCH-&send(deliver,3);
@@ -499,12 +509,52 @@
+// Some utils for the RRLP hack below
+int hexchr2int(char c)
if (c &= '0' && c &= '9')
return c - '0';
if (c &= 'a' && c &= 'z')
return c - 'a' + 10;
if (c &= 'A' && c &= 'Z')
return c - 'A' + 10;
return -10000;
+BitVector hex2bitvector(const char* s)
BitVector ret(strlen(s)*4);
size_t write_pos = 0;
for (;*s != 0 && *(s+1) != 0; s+= 2) {
ret.writeField(write_pos, hexchr2int(*s), 4);
ret.writeField(write_pos, hexchr2int(*(s+1)), 4);
void Control::MTSMSController(TransactionEntry& transaction,
LogicalChannel *LCH)
assert(LCH);
// HACK: At this point if the message starts with &RRLP& then we don't
do SMS at all,
// but instead to an RRLP transaction over the already allocated
LogicalChannel.
const char* m = transaction.message(); // NOTE - not very nice, my way
of checking.
if ((strlen(m) & 4) && (std::string(&RRLP&) == std::string(m, m+4))) {
BitVector rrlp_position_request =
hex2bitvector(transaction.message() + 4);
LOG(INFO) && &MTSMS: Sending RRLP&;
// TODO - how to get mobID here?
L3MobileIdentity mobID = L3MobileIdentity(&000&);
RRLP::PositionResult pr = GSM::RRLP::doRRLPQuery(mobID, LCH,
rrlp_position_request);
if (pr.mValid) // in this case we only want to log the results
which contain lat/lon
logMSInfo(LCH, pr, mobID);
LOG(INFO) && &MTSMS: Closing channel after RRLP&;
LCH-&send(L3ChannelRelease());
clearTransactionHistory(transaction);
// See GSM 04.11 Arrow Diagram A5 for the transaction
Network-&MS
CP-DATA containing RP-DATA
MS-&Network
Modified: openbts/trunk/GSM/GSMCommon.cpp
===================================================================
--- openbts/trunk/GSM/GSMCommon.cpp
03:03:10 UTC (rev 11666)
+++ openbts/trunk/GSM/GSMCommon.cpp
04:21:20 UTC (rev 11667)
@@ -333,6 +333,13 @@
+void Z100Timer::set(long wLimitTime)
mLimitTime = wLimitT
long Z100Timer::remaining() const
if (!mActive) return 0;
Modified: openbts/trunk/GSM/GSMCommon.h
===================================================================
--- openbts/trunk/GSM/GSMCommon.h
03:03:10 UTC (rev 11666)
+++ openbts/trunk/GSM/GSMCommon.h
04:21:20 UTC (rev 11667)
@@ -116,9 +116,8 @@
const unsigned T3101ms = 4000;
///& L1 timeout for SDCCH assignment
const unsigned T3107ms = 3000;
///& L1 timeout for TCH/FACCH assignment
-const unsigned T3109ms = 10000;
///& L1 timeout for an existing
+const unsigned T3109ms = 30000;
///& L1 timeout for an existing
const unsigned T3111ms = 2*T200
///& L1 timeout for reassignment of a
-const unsigned T3113ms = 10000;
///& timeout for paging response
/address@hidden GSM timeouts for mobility management, GSM 04.08 11.2. */
@@ -558,6 +557,9 @@
/** Start or restart the timer. */
void set();
/** Start or restart the timer, possibly specifying a new limit. */
void set(long wLimitTime);
/** Stop the timer. */
void reset() { mActive = }
Modified: openbts/trunk/GSM/GSMConfig.cpp
===================================================================
--- openbts/trunk/GSM/GSMConfig.cpp
03:03:10 UTC (rev 11666)
+++ openbts/trunk/GSM/GSMConfig.cpp
04:21:20 UTC (rev 11667)
@@ -36,16 +36,24 @@
GSMConfig::GSMConfig()
:mSI5Frame(UNIT_DATA),mSI6Frame(UNIT_DATA),
:mBand((GSMBand)gConfig.getNum(&GSM.Band&)),
mSI5Frame(UNIT_DATA),mSI6Frame(UNIT_DATA),
mT3122(gConfig.getNum(&GSM.T3122Min&)),
mStartTime(::time(NULL))
mBand = (GSMBand)gConfig.getNum(&GSM.Band&);
regenerateBeacon();
+void GSMConfig::start()
mPowerManager.start();
// Do not call this until the paging channels are installed.
mPager.start();
void GSMConfig::regenerateBeacon()
// Update everything from the configuration.
@@ -177,39 +185,45 @@
-template &class ChanType& bool chanAvailable(const vector&ChanType*&& chanList)
+template &class ChanType& size_t chanAvailable(const vector&ChanType*&&
size_t count = 0;
for (unsigned i=0; i&chanList.size(); i++) {
ChanType *chan = chanList[i];
if (chanList[i]-&recyclable())
if (chanList[i]-&recyclable()) count++;
-bool GSMConfig::SDCCHAvailable() const
+size_t GSMConfig::SDCCHAvailable() const
mLock.lock();
bool retVal = chanAvailable&SDCCHLogicalChannel&(mSDCCHPool);
size_t retVal = chanAvailable&SDCCHLogicalChannel&(mSDCCHPool);
mLock.unlock();
return retV
-bool GSMConfig::TCHAvailable() const
+size_t GSMConfig::TCHAvailable() const
mLock.lock();
bool retVal = chanAvailable&TCHFACCHLogicalChannel&(mTCHPool);
size_t retVal = chanAvailable&TCHFACCHLogicalChannel&(mTCHPool);
mLock.unlock();
return retV
+size_t GSMConfig::totalLoad(const CCCHList& chanList) const
size_t total = 0;
for (int i=0; i&chanList.size(); i++) {
total += chanList[i]-&load();
template &class ChanType& unsigned countActive(const vector&ChanType*&&
unsigned active = 0;
@@ -233,4 +247,37 @@
+unsigned GSMConfig::T3122() const
mLock.lock();
unsigned retVal = mT3122;
mLock.unlock();
return retV
+unsigned GSMConfig::growT3122()
unsigned max = gConfig.getNum(&GSM.T3122Max&);
mLock.lock();
unsigned retVal = mT3122;
mT3122 += (random() % mT3122) / 2;
if (mT3122&max) mT3122=
mLock.unlock();
return retV
+unsigned GSMConfig::shrinkT3122()
unsigned min = gConfig.getNum(&GSM.T3122Min&);
mLock.lock();
unsigned retVal = mT3122;
mT3122 -= (random() % mT3122) / 2;
if (mT3122&min) mT3122=
mLock.unlock();
return retV
// vim: ts=4 sw=4
Modified: openbts/trunk/GSM/GSMConfig.h
===================================================================
--- openbts/trunk/GSM/GSMConfig.h
03:03:10 UTC (rev 11666)
+++ openbts/trunk/GSM/GSMConfig.h
04:21:20 UTC (rev 11667)
@@ -29,7 +29,8 @@
#include &vector&
-#include &ControlCommon.h&
+#include &ControlCommon.h&
+#include &PowerManager.h&
#include &GSML3RRElements.h&
#include &GSML3CommonElements.h&
@@ -59,6 +60,8 @@
/** The paging mechanism is built-in. */
Control::Pager mP
PowerManager mPowerM
mutable Mutex mL
multithread access control
/address@hidden Groups of CCCH subchannels -- may intersect. */
@@ -97,17 +100,23 @@
L3Frame mSI6F
int mT3122;
time_t mStartT
L3LocationAreaIdentity mLAI;
char mShortName[94]; // GSM 03.38 6.1.2.2.1
/** All parameters come from gConfig. */
GSMConfig();
/** Start the internal control loops. */
void start();
/address@hidden Get references to L2 frames for BCCH SI messages. */
@@ -139,9 +148,6 @@
/** Return the BSIC, NCC:BCC. */
unsigned BSIC() const { return (mNCC&&3) | mBCC; }
/** RSSI target for closed loop power control. */
int RSSITarget() const { return -10; }
Re-encode the L2Frames for system information messages.
Called whenever a beacon parameter is changed.
@@ -153,8 +159,14 @@
/** Find a minimum-load CCCH from a list. */
CCCHLogicalChannel* minimumLoad(CCCHList &chanList);
/** Return the total load of a CCCH list. */
size_t totalLoad(const CCCHList &chanList)
size_t AGCHLoad() { return totalLoad(mAGCHPool); }
size_t PCHLoad() { return totalLoad(mPCHPool); }
/address@hidden Manage CCCH subchannels. */
/** The add method is not mutex protected and should only be used
during initialization. */
@@ -166,6 +178,12 @@
CCCHLogicalChannel* getAGCH() { return minimumLoad(mAGCHPool); }
/** Return a minimum-load PCH. */
CCCHLogicalChannel* getPCH() { return minimumLoad(mPCHPool); }
/** Return a specific PCH. */
CCCHLogicalChannel* getPCH(size_t index)
assert(index&mPCHPool.size());
return mPCHPool[index];
@@ -177,7 +195,7 @@
/** Return a pointer to a usable channel. */
SDCCHLogicalChannel *getSDCCH();
/** Return true if an SDCCH is available, but do not allocate it. */
bool SDCCHAvailable()
size_t SDCCHAvailable()
/** Return number of total SDCCH. */
unsigned SDCCHTotal() const { return mSDCCHPool.size(); }
/** Return number of active SDCCH. */
@@ -193,7 +211,7 @@
/** Return a pointer to a usable channel. */
TCHFACCHLogicalChannel *getTCH();
/** Return true if an TCH is available, but do not allocate it. */
bool TCHAvailable()
size_t TCHAvailable()
/** Return number of total TCH. */
unsigned TCHTotal() const { return mTCHPool.size(); }
/** Return number of active TCH. */
@@ -202,9 +220,18 @@
const TCHList& TCHPool() const { return mTCHP }
/address@hidden T3122 management */
unsigned T3122()
unsigned growT3122();
unsigned shrinkT3122();
/** Return number of seconds since starting. */
time_t uptime() const { return ::time(NULL)-mStartT }
/** Get a handle to the power manager. */
PowerManager& powerManager() { return mPowerM }
Modified: openbts/trunk/GSM/GSML1FEC.cpp
===================================================================
--- openbts/trunk/GSM/GSML1FEC.cpp
03:03:10 UTC (rev 11666)
+++ openbts/trunk/GSM/GSML1FEC.cpp
04:21:20 UTC (rev 11667)
@@ -31,9 +31,11 @@
#include &GSMSAPMux.h&
#include &GSMConfig.h&
#include &GSMTDMA.h&
+#include &GSMTAPDump.h&
#include &TRXManager.h&
#include &Logger.h&
#include &assert.h&
+#include &math.h&
using namespace GSM;
@@ -102,7 +104,7 @@
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
36, 24, 23
0, 36, 24, 23
/** Power control codes for PCS1900 from GSM 05.05 4.1.1. */
@@ -119,6 +121,27 @@
+int decodePower(unsigned code)
const int *table = NULL;
switch (gBTS.band()) {
case GSM850:
case EGSM900:
table = powerCommandLowB
case DCS1800:
table = powerCommand1800;
case PCS1900:
table = powerCommand1900;
default: assert(0);
return table[code];
/** Given a power level in dBm, encode the control code. */
unsigned encodePower(int power)
@@ -204,7 +227,7 @@
void L1Encoder::open()
OBJLOG(DEBUG) && &L1Encoder::open&;
OBJLOG(DEBUG) && &L1Encoder&;
mLock.lock();
if (!mRunning) start();
mTotalBursts=0;
@@ -217,7 +240,7 @@
void L1Encoder::close()
// Don't return until the channel is fully closed.
OBJLOG(DEBUG) && &L1Encoder::close&;
OBJLOG(DEBUG) && &L1Encodere&;
mLock.lock();
sendIdleFill();
@@ -236,6 +259,22 @@
+void L1Decoder::setPhy(float wRSSI, float wTimingError)
mRSSI=wRSSI;
mTimingError=wTimingE
+void SACCHL1Decoder::setPhy(const SACCHL1Decoder& other)
mActualMSPower = other.mActualMSP
mActualMSTiming = other.mActualMST
L1Decoder::setPhy(other.mRSSI,other.mTimingError);
L1Decoder* L1Encoder::sibling()
if (!mParent) return NULL;
@@ -256,12 +295,12 @@
// get it caught up to something reasonable.
Time now = gBTS.time();
int32_t delta = mNextWriteTime-
OBJLOG(DEEPDEBUG) && &L1Encoder::resync() next=& && mNextWriteTime && &
now=& && now && & delta=& &&
OBJLOG(DEEPDEBUG) && &L1Encoder next=& && mNextWriteTime && & now=& &&
now && & delta=& &&
if ((delta&0) || (delta&(51*26))) {
mNextWriteTime =
mNextWriteTime.TN(mTN);
mNextWriteTime.rollForward(mMapping.frameMapping(mTotalBursts),mMapping.repeatLength());
OBJLOG(DEEPDEBUG) &&&L1Encoder::resync() RESYNC next=& &&
mNextWriteTime && & now=& &&
OBJLOG(DEEPDEBUG) &&&L1Encoder RESYNC next=& && mNextWriteTime
&& & now=& &&
@@ -353,7 +392,7 @@
static const float a = 1.0F / ((float)mFERMemory);
static const float b = 1.0F -
OBJLOG(DEEPDEBUG) &&&L1Decoder::countGoodFrame FER=& && mFER;
OBJLOG(DEEPDEBUG) &&&L1Decoder FER=& && mFER;
@@ -362,7 +401,7 @@
static const float a = 1.0F / ((float)mFERMemory);
static const float b = 1.0F -
mFER = b*mFER +
OBJLOG(DEEPDEBUG) &&&L1Decoder::countBadFrame FER=& && mFER;
OBJLOG(DEEPDEBUG) &&&L1Decoder FER=& && mFER;
@@ -469,8 +508,9 @@
countGoodFr}

我要回帖

更多关于 gsm sdcch 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信