mirror of
https://github.com/RangeNetworks/openbts.git
synced 2025-11-09 08:05:39 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user