diff --git a/Control/CallControl.cpp b/Control/CallControl.cpp index 8439369..ab8245a 100644 --- a/Control/CallControl.cpp +++ b/Control/CallControl.cpp @@ -315,6 +315,9 @@ bool callManagementDispatchGSM(TransactionEntry *transaction, GSM::LogicalChanne //if we disconnect, we don't get another //of these, wait here? -kurtis transaction->MODWaitForOK(); + //server can optionally send a 487 Request Terminated message + //handle it if they do + transaction->MODWaitFor487(); } return false; } @@ -518,6 +521,7 @@ bool updateSIPSignalling(TransactionEntry *transaction, GSM::LogicalChannel *LCH if (transaction->SIPFinished()) return true; bool GSMClearedOrClearing = GSMCleared || transaction->clearingGSM(); + //only checking for Clearing because the call is active at this state. Should not cancel if (transaction->MTDCheckBYE() == SIP::MTDClearing) { LOG(DEBUG) << "got SIP BYE " << *transaction; if (!GSMClearedOrClearing) { @@ -951,6 +955,7 @@ void Control::MTCStarter(TransactionEntry *transaction, GSM::LogicalChannel *LCH if (transaction->MTCCheckForCancel()==SIP::MTDCanceling) { LOG(INFO) << "call cancelled on SIP side"; transaction->MTDSendCANCELOK(); + //should probably send a 487 here // Cause 0x15 is "rejected" return abortAndRemoveCall(transaction,LCH,GSM::L3Cause(0x15)); } @@ -1015,6 +1020,7 @@ void Control::MTCController(TransactionEntry *transaction, GSM::TCHFACCHLogicalC if (transaction->MTCCheckForCancel()==SIP::MTDCanceling) { LOG(INFO) << "MTCCheckForCancel return Canceling"; transaction->MTDSendCANCELOK(); + //should probably send a 487 here -kurtis // Cause 0x15 is "rejected" return abortAndRemoveCall(transaction,TCH,GSM::L3Cause(0x15)); } @@ -1046,6 +1052,7 @@ void Control::MTCController(TransactionEntry *transaction, GSM::TCHFACCHLogicalC break; case SIP::MTDCanceling: state = transaction->MTDSendCANCELOK(); + //should probably send a 487 here // Cause 0x15 is "rejected" return abortAndRemoveCall(transaction,TCH,GSM::L3Cause(0x15)); default: diff --git a/Control/TransactionTable.cpp b/Control/TransactionTable.cpp index f19185c..0577b32 100644 --- a/Control/TransactionTable.cpp +++ b/Control/TransactionTable.cpp @@ -452,6 +452,14 @@ SIP::SIPState TransactionEntry::MODWaitForOK() return state; } +SIP::SIPState TransactionEntry::MODWaitFor487() +{ + ScopedLock lock(mLock); + SIP::SIPState state = mSIP.MODWaitFor487(); + echoSIPState(state); + return state; +} + SIP::SIPState TransactionEntry::MTDCheckBYE() { ScopedLock lock(mLock); diff --git a/Control/TransactionTable.h b/Control/TransactionTable.h index aaf4446..5d16bc6 100644 --- a/Control/TransactionTable.h +++ b/Control/TransactionTable.h @@ -204,6 +204,7 @@ class TransactionEntry { SIP::SIPState MODResendBYE(); SIP::SIPState MODResendCANCEL(); SIP::SIPState MODWaitForOK(); + SIP::SIPState MODWaitFor487(); SIP::SIPState MTDCheckBYE(); SIP::SIPState MTDSendBYEOK(); diff --git a/SIP/SIPEngine.cpp b/SIP/SIPEngine.cpp index 08eee45..3bf99e3 100644 --- a/SIP/SIPEngine.cpp +++ b/SIP/SIPEngine.cpp @@ -593,6 +593,38 @@ SIPState SIPEngine::MODResendCANCEL() return mState; } +/* there shouldn't be any more communications on this fifo, but we might + get a 487 RequestTerminated. We only need to respond and move on -kurtis */ +SIPState SIPEngine::MODWaitFor487() +{ + LOG(INFO) << "user " << mSIPUsername << " state " << mState; + osip_message_t * msg; + try { + msg = gSIPInterface.read(mCallID, gConfig.getNum("SIP.Timer.E")); + } + catch (SIPTimeout& e) { + LOG(NOTICE) << "487 Timeout"; + return mState; + } + //ok, message arrived + if (msg->status_code != 487){ + LOG(WARNING) << "unexpected " << msg->status_code << + " response to CANCEL, from proxy " << mProxyIP << ":" << mProxyPort; + return mState; + } else { + osip_message_t* ack = sip_ack( mRemoteDomain.c_str(), + mRemoteUsername.c_str(), + mSIPUsername.c_str(), + mSIPPort, mSIPIP.c_str(), mProxyIP.c_str(), + mMyToFromHeader, mRemoteToFromHeader, + mViaBranch.c_str(), mCallIDHeader, mCSeq + ); + gSIPInterface.write(&mProxyAddr,ack); + osip_message_free(ack); + return mState; + } +} + SIPState SIPEngine::MODWaitForOK() { LOG(INFO) << "user " << mSIPUsername << " state " << mState; diff --git a/SIP/SIPEngine.h b/SIP/SIPEngine.h index 73eb3bf..cecd61d 100644 --- a/SIP/SIPEngine.h +++ b/SIP/SIPEngine.h @@ -278,6 +278,8 @@ public: SIPState MODResendCANCEL(); SIPState MODWaitForOK(); + + SIPState MODWaitFor487(); //@} diff --git a/SIP/SIPInterface.cpp b/SIP/SIPInterface.cpp index 83048f7..ed59135 100644 --- a/SIP/SIPInterface.cpp +++ b/SIP/SIPInterface.cpp @@ -224,11 +224,6 @@ void SIPInterface::drive() // FIXME -- If we support USSD via SIP, we will need to check the map first. checkInvite(msg); - // FIXME -- Need to check for early BYE or CANCEL to stop paging. - // If it's a BYE, find the corresponding transaction table entry. - // If the Q931 state is "paging", or T3113 is expired, remove it. - // Otherwise, we will keep paging even though the call has ended. - // Multiplex out the received SIP message to active calls. // If we write to non-existent call_id.