sync of openbts

git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@6168 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
Kurtis Heimerl
2013-08-14 00:52:14 +00:00
parent 1baba59e14
commit 5289a229d9
219 changed files with 42413 additions and 4213 deletions

View File

@@ -3,24 +3,16 @@
/*
* Copyright 2008, 2010 Free Software Foundation, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribuion.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@@ -37,6 +29,7 @@
#include <SIPEngine.h>
#include <SIPInterface.h>
#include <Sgsn.h>
#include <Logger.h>
#include <Reporting.h>
@@ -60,25 +53,29 @@ L3Message* getMessageCore(LogicalChannel *LCH, unsigned SAPI)
unsigned timeout_ms = LCH->N200() * T200ms;
L3Frame *rcv = LCH->recv(timeout_ms,SAPI);
if (rcv==NULL) {
LOG(NOTICE) << "timeout";
LOG(NOTICE) << "L3 read timeout";
throw ChannelReadTimeout();
}
LOG(DEBUG) << "received " << *rcv;
Primitive primitive = rcv->primitive();
if (primitive!=DATA) {
LOG(NOTICE) << "unexpected primitive " << primitive;
LOG(ERR) << "unexpected primitive " << primitive;
delete rcv;
throw UnexpectedPrimitive();
}
L3Message *msg = parseL3(*rcv);
delete rcv;
if (msg==NULL) {
LOG(NOTICE) << "unparsed message";
throw UnsupportedMessage();
LOG(WARNING) << "unparsed message:" << *rcv;
delete rcv;
return NULL;
//throw UnsupportedMessage();
}
delete rcv;
LOG(DEBUG) << *msg;
return msg;
}
// FIXME -- getMessage should return an L3Frame, not an L3Message.
// This will mean moving all of the parsing into the control layer.
// FIXME -- This needs an adjustable timeout.
@@ -86,13 +83,33 @@ L3Message* getMessageCore(LogicalChannel *LCH, unsigned SAPI)
L3Message* Control::getMessage(LogicalChannel *LCH, unsigned SAPI)
{
L3Message *msg = getMessageCore(LCH,SAPI);
// Handsets should not be sending us GPRS suspension requests.
// Handsets should not be sending us GPRS suspension requests when GPRS support is not enabled.
// But if they do, we should ignore them.
// They should not send more than one in any case, but we need to be
// ready for whatever crazy behavior they throw at us.
// The suspend procedure includes MS<->BSS and BSS<->SGSN messages.
// GSM44.018 3.4.25 GPRS Suspension Procedure and 9.1.13b: GPRS Suspension Request message.
// Also 23.060 16.2.1.1 Suspend/Resume procedure general.
// GSM08.18: Suspend Procedure talks about communication between the BSS and SGSN,
// and is not applicable to us when using the internal SGSN.
// Note: When call is finished the RR is supposed to include a GPRS resumption IE, but if it does not,
// 23.060 16.2.1.1.1 says the MS will do a GPRS RoutingAreaUpdate to get the
// GPRS service back, so we are not worrying about it.
// (pat 3-2012) Send the message to the internal SGSN.
// It returns true if GPRS and the internal SGSN are enabled.
// If we are using an external SGSN, we could send the GPRS suspend request to the SGSN via the BSSG,
// but that has no hope of doing anything useful. See ticket #613.
// First, We are supposed to automatically detect when we should do the Resume procedure.
// Second: An RA-UPDATE, which gets send to the SGSN, does something to the CC state
// that I dont understand yet.
// We dont do any of the above.
unsigned count = gConfig.getNum("GSM.Control.GPRSMaxIgnore");
while (count && dynamic_cast<const GSM::L3GPRSSuspensionRequest*>(msg)) {
LOG(NOTICE) << "ignoring GPRS suspension request";
const GSM::L3GPRSSuspensionRequest *srmsg;
while (count && (srmsg = dynamic_cast<const GSM::L3GPRSSuspensionRequest*>(msg))) {
if (! SGSN::Sgsn::handleGprsSuspensionRequest(srmsg->mTLLI,srmsg->mRaId)) {
LOG(NOTICE) << "ignoring GPRS suspension request";
}
msg = getMessageCore(LCH,SAPI);
count--;
}
@@ -100,6 +117,10 @@ L3Message* Control::getMessage(LogicalChannel *LCH, unsigned SAPI)
}
/* Resolve a mobile ID to an IMSI and return TMSI if it is assigned. */
unsigned Control::resolveIMSI(bool sameLAI, L3MobileIdentity& mobileID, LogicalChannel* LCH)
{
@@ -108,7 +129,10 @@ unsigned Control::resolveIMSI(bool sameLAI, L3MobileIdentity& mobileID, Logical
LOG(DEBUG) << "resolving mobile ID " << mobileID << ", sameLAI: " << sameLAI;
// IMSI already? See if there's a TMSI already, too.
if (mobileID.type()==IMSIType) return gTMSITable.TMSI(mobileID.digits());
if (mobileID.type()==IMSIType) {
GPRS::GPRSNotifyGsmActivity(mobileID.digits());
return gTMSITable.TMSI(mobileID.digits());
}
// IMEI? WTF?!
// FIXME -- Should send MM Reject, cause 0x60, "invalid mandatory information".
@@ -121,6 +145,7 @@ unsigned Control::resolveIMSI(bool sameLAI, L3MobileIdentity& mobileID, Logical
if (sameLAI) IMSI = gTMSITable.IMSI(TMSI);
if (IMSI) {
// We assigned this TMSI already; the TMSI/IMSI pair is already in the table.
GPRS::GPRSNotifyGsmActivity(IMSI);
mobileID = L3MobileIdentity(IMSI);
LOG(DEBUG) << "resolving mobile ID (table): " << mobileID;
free(IMSI);
@@ -153,16 +178,15 @@ unsigned Control::resolveIMSI(bool sameLAI, L3MobileIdentity& mobileID, Logical
void Control::resolveIMSI(L3MobileIdentity& mobileIdentity, LogicalChannel* LCH)
{
// Are we done already?
if (mobileIdentity.type()==IMSIType){
//Cause the tmsi table to be touched
gTMSITable.TMSI(mobileIdentity.digits());
return;
}
if (mobileIdentity.type()==IMSIType) return;
// If we got a TMSI, find the IMSI.
if (mobileIdentity.type()==TMSIType) {
char *IMSI = gTMSITable.IMSI(mobileIdentity.TMSI());
if (IMSI) mobileIdentity = L3MobileIdentity(IMSI);
if (IMSI) {
GPRS::GPRSNotifyGsmActivity(IMSI);
mobileIdentity = L3MobileIdentity(IMSI);
}
free(IMSI);
}
@@ -178,6 +202,9 @@ void Control::resolveIMSI(L3MobileIdentity& mobileIdentity, LogicalChannel* LCH
throw UnexpectedMessage();
}
mobileIdentity = resp->mobileID();
if (mobileIdentity.type()==IMSIType) {
GPRS::GPRSNotifyGsmActivity(mobileIdentity.digits());
}
delete msg;
}