mirror of
https://github.com/fairwaves/openbts-2.8.git
synced 2025-11-02 13:03:14 +00:00
r4230 in private: Do not create a new transaction if a call error condition can be identified early enough in SIPInterface::checkInvite.
r4229 in private: Added accessor for L3 CC Call State element. git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@4354 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
@@ -69,6 +69,9 @@ class L3CMServiceType : public L3ProtocolElement {
|
|||||||
bool operator==(const L3CMServiceType& other) const
|
bool operator==(const L3CMServiceType& other) const
|
||||||
{ return mType == other.mType; }
|
{ return mType == other.mType; }
|
||||||
|
|
||||||
|
bool operator!=(const L3CMServiceType& other) const
|
||||||
|
{ return mType != other.mType; }
|
||||||
|
|
||||||
size_t lengthV() const { return 0; }
|
size_t lengthV() const { return 0; }
|
||||||
void writeV(L3Frame&, size_t&) const { assert(0); }
|
void writeV(L3Frame&, size_t&) const { assert(0); }
|
||||||
void parseV(const L3Frame &src, size_t &rp);
|
void parseV(const L3Frame &src, size_t &rp);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include "SIPUtility.h"
|
#include "SIPUtility.h"
|
||||||
#include "SIPInterface.h"
|
#include "SIPInterface.h"
|
||||||
|
#include "SIPMessage.h"
|
||||||
|
|
||||||
#include <Logger.h>
|
#include <Logger.h>
|
||||||
|
|
||||||
@@ -159,6 +160,7 @@ void SIPInterface::write(const struct sockaddr_in* dest, osip_message_t *msg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//if it's any of these transactions, record it in the database
|
//if it's any of these transactions, record it in the database
|
||||||
|
// FIXME - We should really remove all direct access to the SR
|
||||||
string name = osip_message_get_from(msg)->url->username;
|
string name = osip_message_get_from(msg)->url->username;
|
||||||
if (msg->sip_method &&
|
if (msg->sip_method &&
|
||||||
(!strncmp(msg->sip_method, "INVITE", 6) ||
|
(!strncmp(msg->sip_method, "INVITE", 6) ||
|
||||||
@@ -292,6 +294,24 @@ const char* extractCallID(const osip_message_t* msg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SIPInterface::sendEarlyError(osip_message_t * cause,
|
||||||
|
const char *proxy,
|
||||||
|
int code, const char * reason)
|
||||||
|
{
|
||||||
|
const char *user = extractIMSI(cause);
|
||||||
|
unsigned port = mSIPSocket.port();
|
||||||
|
struct ::sockaddr_in remote;
|
||||||
|
if (!resolveAddress(&remote,proxy)) {
|
||||||
|
LOG(ALERT) << "cannot resolve IP address for " << proxy;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
osip_message_t * error = sip_error(cause, gConfig.getStr("SIP.Local.IP").c_str(),
|
||||||
|
user, port,
|
||||||
|
code, reason);
|
||||||
|
write(&remote,error);
|
||||||
|
osip_message_free(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SIPInterface::checkInvite( osip_message_t * msg)
|
bool SIPInterface::checkInvite( osip_message_t * msg)
|
||||||
{
|
{
|
||||||
@@ -307,10 +327,10 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
|
|||||||
|
|
||||||
// Check for INVITE or MESSAGE methods.
|
// Check for INVITE or MESSAGE methods.
|
||||||
// Check channel availability now, too.
|
// Check channel availability now, too.
|
||||||
|
// even if we are not actually assigning the channel yet.
|
||||||
GSM::ChannelType requiredChannel;
|
GSM::ChannelType requiredChannel;
|
||||||
bool channelAvailable = false;
|
bool channelAvailable = false;
|
||||||
GSM::L3CMServiceType serviceType;
|
GSM::L3CMServiceType serviceType;
|
||||||
// pretty sure strings are garbage collected
|
|
||||||
string proxy = get_return_address(msg);
|
string proxy = get_return_address(msg);
|
||||||
if (strcmp(method,"INVITE") == 0) {
|
if (strcmp(method,"INVITE") == 0) {
|
||||||
// INVITE is for MTC.
|
// INVITE is for MTC.
|
||||||
@@ -343,6 +363,7 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
|
|||||||
if (!IMSI) {
|
if (!IMSI) {
|
||||||
// FIXME -- Send appropriate error (404) on SIP interface.
|
// FIXME -- Send appropriate error (404) on SIP interface.
|
||||||
LOG(WARNING) << "Incoming INVITE/MESSAGE with no IMSI";
|
LOG(WARNING) << "Incoming INVITE/MESSAGE with no IMSI";
|
||||||
|
sendEarlyError(msg,proxy.c_str(),404,"Not Found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
L3MobileIdentity mobileID(IMSI);
|
L3MobileIdentity mobileID(IMSI);
|
||||||
@@ -352,12 +373,14 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
|
|||||||
if (!callIDNum) {
|
if (!callIDNum) {
|
||||||
// FIXME -- Send appropriate error on SIP interface.
|
// FIXME -- Send appropriate error on SIP interface.
|
||||||
LOG(WARNING) << "Incoming INVITE/MESSAGE with no call ID";
|
LOG(WARNING) << "Incoming INVITE/MESSAGE with no call ID";
|
||||||
|
sendEarlyError(msg,proxy.c_str(),400,"Bad Request");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Find any active transaction for this IMSI with an assigned TCH or SDCCH.
|
// Find any active transaction for this IMSI with an assigned TCH or SDCCH.
|
||||||
GSM::LogicalChannel *chan = gTransactionTable.findChannel(mobileID);
|
GSM::LogicalChannel *chan = gTransactionTable.findChannel(mobileID);
|
||||||
|
//will go
|
||||||
bool userBusy = false;
|
bool userBusy = false;
|
||||||
if (chan) {
|
if (chan) {
|
||||||
// If the type is TCH and the service is SMS, get the SACCH.
|
// If the type is TCH and the service is SMS, get the SACCH.
|
||||||
@@ -366,6 +389,7 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
|
|||||||
chan = chan->SACCH();
|
chan = chan->SACCH();
|
||||||
} else {
|
} else {
|
||||||
// FIXME -- This will change to support multiple transactions.
|
// FIXME -- This will change to support multiple transactions.
|
||||||
|
//will go
|
||||||
userBusy = (serviceType==L3CMServiceType::MobileTerminatedCall) && !(chan->recyclable());
|
userBusy = (serviceType==L3CMServiceType::MobileTerminatedCall) && !(chan->recyclable());
|
||||||
chan = NULL;
|
chan = NULL;
|
||||||
}
|
}
|
||||||
@@ -381,6 +405,7 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
|
|||||||
mSIPMap.remove(callIDNum);
|
mSIPMap.remove(callIDNum);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
LOG(INFO) << "pre-existing transaction record: " << *transaction;
|
||||||
//if this is not the saved invite, it's a RE-invite. Respond saying we don't support it.
|
//if this is not the saved invite, it's a RE-invite. Respond saying we don't support it.
|
||||||
if (!transaction->sameINVITE(msg)){
|
if (!transaction->sameINVITE(msg)){
|
||||||
/* don't cancel the call */
|
/* don't cancel the call */
|
||||||
@@ -391,8 +416,10 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
|
|||||||
//transaction->MODWaitForERRORACK(false); //don't cancel the call
|
//transaction->MODWaitForERRORACK(false); //don't cancel the call
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// There is transaction already. Send trying.
|
|
||||||
transaction->MTCSendTrying();
|
// Send trying, if appropriate.
|
||||||
|
if (serviceType != L3CMServiceType::MobileTerminatedShortMessage) transaction->MTCSendTrying();
|
||||||
|
|
||||||
// And if no channel is established yet, page again.
|
// And if no channel is established yet, page again.
|
||||||
if (!chan) {
|
if (!chan) {
|
||||||
LOG(INFO) << "repeated SIP INVITE/MESSAGE, repaging for transaction " << *transaction;
|
LOG(INFO) << "repeated SIP INVITE/MESSAGE, repaging for transaction " << *transaction;
|
||||||
@@ -401,17 +428,25 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// So we will need a new channel.
|
// So we will need ay new channel.
|
||||||
// Check gBTS for channel availability.
|
// Check gBTS for channel availability.
|
||||||
if (!chan && !channelAvailable) {
|
if (!chan && !channelAvailable) {
|
||||||
// FIXME -- Send 503 "Service Unavailable" response on SIP interface.
|
LOG(CRIT) << "MTC CONGESTION, no " << requiredChannel << " availble";
|
||||||
// Don't forget the retry-after header.
|
// FIXME -- We need the retry-after header.
|
||||||
LOG(NOTICE) << "MTC CONGESTION, no " << requiredChannel << " availble for assignment";
|
sendEarlyError(msg,proxy.c_str(),600,"Busy Everywhere");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (chan) { LOG(INFO) << "using existing channel " << chan->descriptiveString(); }
|
if (chan) { LOG(INFO) << "using existing channel " << chan->descriptiveString(); }
|
||||||
else { LOG(INFO) << "set up MTC paging for channel=" << requiredChannel; }
|
else { LOG(INFO) << "set up MTC paging for channel=" << requiredChannel; }
|
||||||
|
|
||||||
|
/* Not yet moved over -kurtis
|
||||||
|
// Check for new user busy condition.
|
||||||
|
if (!chan && gTransactionTable.isBusy(mobileID)) {
|
||||||
|
LOG(NOTICE) << "user busy: " << mobileID;
|
||||||
|
sendEarlyError(msg,proxy.c_str(),486,"Busy Here");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Add an entry to the SIP Map to route inbound SIP messages.
|
// Add an entry to the SIP Map to route inbound SIP messages.
|
||||||
addCall(callIDNum);
|
addCall(callIDNum);
|
||||||
@@ -472,6 +507,7 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
|
|||||||
LOG(INFO) << "MTC MTSMS make transaction and add to transaction table: "<< *transaction;
|
LOG(INFO) << "MTC MTSMS make transaction and add to transaction table: "<< *transaction;
|
||||||
gTransactionTable.add(transaction);
|
gTransactionTable.add(transaction);
|
||||||
|
|
||||||
|
//will go -kurtis
|
||||||
if (userBusy) {
|
if (userBusy) {
|
||||||
transaction->MODSendERROR(msg, 486, "Busy Here", false);
|
transaction->MODSendERROR(msg, 486, "Busy Here", false);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -173,6 +173,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool checkInvite( osip_message_t *);
|
bool checkInvite( osip_message_t *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Send an error response before a transaction is even created.
|
||||||
|
*/
|
||||||
|
void sendEarlyError(osip_message_t * cause,
|
||||||
|
const char *proxy,
|
||||||
|
int code, const char * reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Schedule SMS for delivery.
|
Schedule SMS for delivery.
|
||||||
|
|||||||
Reference in New Issue
Block a user