mirror of
				https://github.com/RangeNetworks/openbts.git
				synced 2025-11-03 21:33:15 +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:
		@@ -68,6 +68,9 @@ class L3CMServiceType : public L3ProtocolElement {
 | 
			
		||||
 | 
			
		||||
	bool operator==(const L3CMServiceType& other) const
 | 
			
		||||
		{ return mType == other.mType; }
 | 
			
		||||
 | 
			
		||||
	bool operator!=(const L3CMServiceType& other) const
 | 
			
		||||
		{ return mType != other.mType; }
 | 
			
		||||
	
 | 
			
		||||
	size_t lengthV() const { return 0; }	
 | 
			
		||||
	void writeV(L3Frame&, size_t&) const { assert(0); }
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@
 | 
			
		||||
 | 
			
		||||
#include "SIPUtility.h"
 | 
			
		||||
#include "SIPInterface.h"
 | 
			
		||||
#include "SIPMessage.h"
 | 
			
		||||
 | 
			
		||||
#include <Logger.h>
 | 
			
		||||
 | 
			
		||||
@@ -159,6 +160,7 @@ void SIPInterface::write(const struct sockaddr_in* dest, osip_message_t *msg)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	//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;
 | 
			
		||||
	if (msg->sip_method && 
 | 
			
		||||
	    (!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)
 | 
			
		||||
{
 | 
			
		||||
@@ -307,10 +327,10 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
 | 
			
		||||
 | 
			
		||||
	// Check for INVITE or MESSAGE methods.
 | 
			
		||||
	// Check channel availability now, too.
 | 
			
		||||
	// even if we are not actually assigning the channel yet.
 | 
			
		||||
	GSM::ChannelType requiredChannel;
 | 
			
		||||
	bool channelAvailable = false;
 | 
			
		||||
	GSM::L3CMServiceType serviceType;
 | 
			
		||||
	// pretty sure strings are garbage collected
 | 
			
		||||
	string proxy = get_return_address(msg);
 | 
			
		||||
	if (strcmp(method,"INVITE") == 0) {
 | 
			
		||||
		// INVITE is for MTC.
 | 
			
		||||
@@ -343,6 +363,7 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
 | 
			
		||||
	if (!IMSI) {
 | 
			
		||||
		// FIXME -- Send appropriate error (404) on SIP interface.
 | 
			
		||||
		LOG(WARNING) << "Incoming INVITE/MESSAGE with no IMSI";
 | 
			
		||||
		sendEarlyError(msg,proxy.c_str(),404,"Not Found");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	L3MobileIdentity mobileID(IMSI);
 | 
			
		||||
@@ -352,12 +373,14 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
 | 
			
		||||
	if (!callIDNum) {
 | 
			
		||||
		// FIXME -- Send appropriate error on SIP interface.
 | 
			
		||||
		LOG(WARNING) << "Incoming INVITE/MESSAGE with no call ID";
 | 
			
		||||
		sendEarlyError(msg,proxy.c_str(),400,"Bad Request");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Find any active transaction for this IMSI with an assigned TCH or SDCCH.
 | 
			
		||||
	GSM::LogicalChannel *chan = gTransactionTable.findChannel(mobileID);
 | 
			
		||||
	//will go
 | 
			
		||||
	bool userBusy = false;
 | 
			
		||||
	if (chan) {
 | 
			
		||||
		// 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();
 | 
			
		||||
		} else {
 | 
			
		||||
			// FIXME -- This will change to support multiple transactions.
 | 
			
		||||
		 	//will go
 | 
			
		||||
			userBusy = (serviceType==L3CMServiceType::MobileTerminatedCall) && !(chan->recyclable());
 | 
			
		||||
			chan = NULL;
 | 
			
		||||
		}
 | 
			
		||||
@@ -381,6 +405,7 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
 | 
			
		||||
			mSIPMap.remove(callIDNum);
 | 
			
		||||
			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 (!transaction->sameINVITE(msg)){
 | 
			
		||||
			/* don't cancel the call */
 | 
			
		||||
@@ -391,8 +416,10 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
 | 
			
		||||
			//transaction->MODWaitForERRORACK(false); //don't cancel the call
 | 
			
		||||
			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.
 | 
			
		||||
		if (!chan) {
 | 
			
		||||
			LOG(INFO) << "repeated SIP INVITE/MESSAGE, repaging for transaction " << *transaction; 
 | 
			
		||||
@@ -401,17 +428,25 @@ bool SIPInterface::checkInvite( osip_message_t * msg)
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// So we will need a new channel.
 | 
			
		||||
	// So we will need ay new channel.
 | 
			
		||||
	// Check gBTS for channel availability.
 | 
			
		||||
	if (!chan && !channelAvailable) {
 | 
			
		||||
		// FIXME -- Send 503 "Service Unavailable" response on SIP interface.
 | 
			
		||||
		// Don't forget the retry-after header.
 | 
			
		||||
		LOG(NOTICE) << "MTC CONGESTION, no " << requiredChannel << " availble for assignment";
 | 
			
		||||
        	LOG(CRIT) << "MTC CONGESTION, no " << requiredChannel << " availble";
 | 
			
		||||
		// FIXME -- We need the retry-after header.
 | 
			
		||||
		sendEarlyError(msg,proxy.c_str(),600,"Busy Everywhere");
 | 
			
		||||
		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; }
 | 
			
		||||
 | 
			
		||||
	/* 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.
 | 
			
		||||
	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;
 | 
			
		||||
	gTransactionTable.add(transaction); 
 | 
			
		||||
 | 
			
		||||
	//will go -kurtis
 | 
			
		||||
	if (userBusy) {
 | 
			
		||||
        	transaction->MODSendERROR(msg, 486, "Busy Here", false);
 | 
			
		||||
        	return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -173,6 +173,12 @@ public:
 | 
			
		||||
	*/
 | 
			
		||||
	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.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user