Changeset 3810
- Timestamp:
- 06/19/2012 03:22:20 PM (11 months ago)
- Location:
- openbts/trunk
- Files:
-
- 8 modified
-
Control/CallControl.cpp (modified) (3 diffs)
-
Control/TransactionTable.cpp (modified) (3 diffs)
-
Control/TransactionTable.h (modified) (2 diffs)
-
SIP/SIPEngine.cpp (modified) (10 diffs)
-
SIP/SIPEngine.h (modified) (5 diffs)
-
SIP/SIPInterface.cpp (modified) (1 diff)
-
SIP/SIPMessage.cpp (modified) (2 diffs)
-
SIP/SIPMessage.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
openbts/trunk/Control/CallControl.cpp
r3677 r3810 138 138 else { //we received, respond and then don't send ok 139 139 //changed state immediately to canceling 140 transaction->MODSend UNAVAIL();140 transaction->MODSendERROR(NULL, 480, "Temporarily Unavailable", true); 141 141 //then canceled 142 transaction->MODWaitFor UNAVAILACK();142 transaction->MODWaitForERRORACK(true); 143 143 } 144 144 } … … 338 338 } 339 339 else { //if we received it, send a 4** instead 340 transaction->MODSend UNAVAIL();341 transaction->MODWaitFor UNAVAILACK();340 transaction->MODSendERROR(NULL, 480, "Temporarily Unavailable", true); 341 transaction->MODWaitForERRORACK(true); 342 342 } 343 343 transaction->GSMState(GSM::NullState); … … 867 867 break; 868 868 case SIP::Timeout: 869 LOG( NOTICE) << "SIP:Timeout, reinvite";869 LOG(ALERT) << "MOC INVITE Timed out. Is SIP.Proxy.Speech (" << gConfig.getStr("SIP.Proxy.Speech") << ") configured correctly?"; 870 870 state = transaction->MOCResendINVITE(); 871 871 break; -
openbts/trunk/Control/TransactionTable.cpp
r3677 r3810 421 421 } 422 422 423 SIP::SIPState TransactionEntry::MODSend UNAVAIL()424 { 425 ScopedLock lock(mLock); 426 SIP::SIPState state = mSIP.MODSend UNAVAIL();423 SIP::SIPState TransactionEntry::MODSendERROR(osip_message_t * cause, int code, const char * reason, bool cancel) 424 { 425 ScopedLock lock(mLock); 426 SIP::SIPState state = mSIP.MODSendERROR(cause, code, reason, cancel); 427 427 echoSIPState(state); 428 428 return state; … … 453 453 } 454 454 455 SIP::SIPState TransactionEntry::MODResend UNAVAIL()456 { 457 ScopedLock lock(mLock); 458 SIP::SIPState state = mSIP.MODResend UNAVAIL();455 SIP::SIPState TransactionEntry::MODResendERROR(bool cancel) 456 { 457 ScopedLock lock(mLock); 458 SIP::SIPState state = mSIP.MODResendERROR(cancel); 459 459 echoSIPState(state); 460 460 return state; … … 477 477 } 478 478 479 SIP::SIPState TransactionEntry::MODWaitFor UNAVAILACK()480 { 481 ScopedLock lock(mLock); 482 SIP::SIPState state = mSIP.MODWaitFor UNAVAILACK();479 SIP::SIPState TransactionEntry::MODWaitForERRORACK(bool cancel) 480 { 481 ScopedLock lock(mLock); 482 SIP::SIPState state = mSIP.MODWaitForERRORACK(cancel); 483 483 echoSIPState(state); 484 484 return state; -
openbts/trunk/Control/TransactionTable.h
r3677 r3810 203 203 204 204 SIP::SIPState MODSendBYE(); 205 SIP::SIPState MODSend UNAVAIL();205 SIP::SIPState MODSendERROR(osip_message_t * cause, int code, const char * reason, bool cancel); 206 206 SIP::SIPState MODSendCANCEL(); 207 207 SIP::SIPState MODResendBYE(); 208 208 SIP::SIPState MODResendCANCEL(); 209 SIP::SIPState MODResend UNAVAIL();209 SIP::SIPState MODResendERROR(bool cancel); 210 210 SIP::SIPState MODWaitForBYEOK(); 211 211 SIP::SIPState MODWaitForCANCELOK(); 212 SIP::SIPState MODWaitFor UNAVAILACK();212 SIP::SIPState MODWaitForERRORACK(bool cancel); 213 213 SIP::SIPState MODWaitFor487(); 214 214 … … 242 242 { ScopedLock lock(mLock); mSIP.saveBYE(bye,local); } 243 243 244 bool sameINVITE(osip_message_t * msg) 245 { ScopedLock lock(mLock); return mSIP.sameINVITE(msg); } 246 244 247 //@} 245 248 -
openbts/trunk/SIP/SIPEngine.cpp
r3700 r3810 97 97 mSIPIP(gConfig.getStr("SIP.Local.IP")), 98 98 mINVITE(NULL), mLastResponse(NULL), mBYE(NULL), 99 mCANCEL(NULL), m UNAVAIL(NULL), mSession(NULL),99 mCANCEL(NULL), mERROR(NULL), mSession(NULL), 100 100 mTxTime(0), mRxTime(0), mState(NullState), 101 101 mDTMF('\0'),mDTMFDuration(0) … … 134 134 if (mBYE!=NULL) osip_message_free(mBYE); 135 135 if (mCANCEL!=NULL) osip_message_free(mCANCEL); 136 if (m UNAVAIL!=NULL) osip_message_free(mUNAVAIL);136 if (mERROR!=NULL) osip_message_free(mERROR); 137 137 // FIXME -- Do we need to dispose of the RtpSesion *mSesison? 138 138 } … … 202 202 } 203 203 204 void SIPEngine::save UNAVAIL(const osip_message_t *UNAVAIL, bool mine)204 void SIPEngine::saveERROR(const osip_message_t *ERROR, bool mine) 205 205 { 206 206 // Instead of cloning, why not just keep the old one? 207 207 // Because that doesn't work in all calling contexts. 208 208 // This simplifies the call-handling logic. 209 if (m UNAVAIL!=NULL) osip_message_free(mUNAVAIL);210 osip_message_clone( UNAVAIL,&mUNAVAIL);209 if (mERROR!=NULL) osip_message_free(mERROR); 210 osip_message_clone(ERROR,&mERROR); 211 211 } 212 212 … … 579 579 } 580 580 581 SIPState SIPEngine::MODSendUNAVAIL() 582 { 583 LOG(INFO) << "user " << mSIPUsername << " state " << mState; 584 assert(mINVITE); 585 586 osip_message_t * unavail = sip_temporarily_unavailable(mINVITE, mSIPIP.c_str(), 587 mSIPUsername.c_str(), mSIPPort); 581 SIPState SIPEngine::MODSendERROR(osip_message_t * cause, int code, const char * reason, bool cancel) 582 { 583 LOG(INFO) << "user " << mSIPUsername << " state " << mState; 584 if (NULL == cause){ 585 assert(mINVITE); 586 cause = mINVITE; 587 } 588 589 /* 480 is unavail */ 590 osip_message_t * unavail = sip_error(cause, mSIPIP.c_str(), 591 mSIPUsername.c_str(), mSIPPort, 592 code, reason); 588 593 gSIPInterface.write(&mProxyAddr,unavail); 589 save UNAVAIL(unavail, true);594 saveERROR(unavail, true); 590 595 osip_message_free(unavail); 591 mState = MODCanceling; 596 if (cancel){ 597 mState = MODCanceling; 598 } 592 599 return mState; 593 600 } … … 626 633 } 627 634 628 SIPState SIPEngine::MODResendUNAVAIL() 629 { 630 LOG(INFO) << "user " << mSIPUsername << " state " << mState; 631 assert(mState==MODCanceling); 632 assert(mUNAVAIL); 633 gSIPInterface.write(&mProxyAddr,mUNAVAIL); 635 SIPState SIPEngine::MODResendERROR(bool cancel) 636 { 637 LOG(INFO) << "user " << mSIPUsername << " state " << mState; 638 if (cancel){ 639 if (mState!=MODCanceling) LOG(ERR) << "incorrect state for this method"; 640 } 641 assert(mERROR); 642 gSIPInterface.write(&mProxyAddr,mERROR); 634 643 return mState; 635 644 } … … 727 736 } 728 737 729 SIPState SIPEngine::MODWaitFor UNAVAILACK()738 SIPState SIPEngine::MODWaitForERRORACK(bool cancel) 730 739 { 731 740 LOG(INFO) << "user " << mSIPUsername << " state " << mState; … … 738 747 saveResponse(ack); 739 748 if ((NULL == ack->sip_method) || !strncmp(ack->sip_method,"ACK", 4)) { 740 LOG(WARNING) << "unexpected response to UNAVAIL, from proxy " << mProxyIP << ":" << mProxyPort << ". Assuming other end has cleared";749 LOG(WARNING) << "unexpected response to ERROR, from proxy " << mProxyIP << ":" << mProxyPort << ". Assuming other end has cleared"; 741 750 } 742 751 osip_message_free(ack); … … 744 753 } 745 754 catch (SIPTimeout& e) { 746 LOG(NOTICE) << "response timeout, resending UNAVAIL";747 MODResend UNAVAIL();755 LOG(NOTICE) << "response timeout, resending ERROR"; 756 MODResendERROR(cancel); 748 757 } 749 758 } … … 751 760 if (!responded) { LOG(ALERT) << "lost contact with proxy " << mProxyIP << ":" << mProxyPort; } 752 761 753 mState = Canceled; 762 if (cancel){ 763 mState = Canceled; 764 } 754 765 755 766 return mState; … … 1213 1224 }; 1214 1225 1215 1216 1226 /* reinvite stuff */ 1227 /* return true if this is the same invite as the one we have stored */ 1228 bool SIPEngine::sameINVITE(osip_message_t * msg){ 1229 assert(mINVITE); 1230 if (NULL == msg){ 1231 return false; 1232 } 1233 char* old_inv; 1234 size_t old_len; 1235 char* new_inv; 1236 size_t new_len; 1237 int res = 0; //does not match 1238 //this sometimes fails even though mINVITE is real. No idea -k 1239 osip_message_to_str(mINVITE, &old_inv, &old_len); 1240 osip_message_to_str(msg, &new_inv, &new_len); 1241 if (old_inv && new_inv){ 1242 res = !(strncmp(old_inv, new_inv, old_len)); 1243 } 1244 if (old_inv){ 1245 free(old_inv); 1246 } 1247 if (new_inv){ 1248 free(new_inv); 1249 } 1250 return res; 1251 } 1217 1252 1218 1253 // vim: ts=4 sw=4 -
openbts/trunk/SIP/SIPEngine.h
r3677 r3810 114 114 osip_message_t * mBYE; ///< the BYE message for this transaction 115 115 osip_message_t * mCANCEL; ///< the CANCEL message for this transaction 116 osip_message_t * m UNAVAIL; ///< the UNAVAILmessage for this transaction116 osip_message_t * mERROR; ///< the ERROR message for this transaction 117 117 //@} 118 118 … … 280 280 SIPState MODSendBYE(); 281 281 282 SIPState MODSend UNAVAIL();282 SIPState MODSendERROR(osip_message_t * cause, int code, const char * reason, bool cancel); 283 283 284 284 SIPState MODSendCANCEL(); … … 288 288 SIPState MODResendCANCEL(); 289 289 290 SIPState MODResend UNAVAIL();290 SIPState MODResendERROR(bool cancel); 291 291 292 292 SIPState MODWaitForBYEOK(); … … 294 294 SIPState MODWaitForCANCELOK(); 295 295 296 SIPState MODWaitFor UNAVAILACK();296 SIPState MODWaitForERRORACK(bool cancel); 297 297 298 298 SIPState MODWaitFor487(); … … 356 356 void saveCANCEL(const osip_message_t *CANCEL, bool mine); 357 357 358 /** Save a copy of a UNAVAIL message in the engine. */ 359 void saveUNAVAIL(const osip_message_t *UNAVAIL, bool mine); 360 361 358 /** Save a copy of a ERROR message in the engine. */ 359 void saveERROR(const osip_message_t *ERROR, bool mine); 360 361 362 /** Determine if this invite matches the saved one */ 363 bool sameINVITE(osip_message_t * msg); 362 364 363 365 private: -
openbts/trunk/SIP/SIPInterface.cpp
r3361 r3810 380 380 return false; 381 381 } 382 //if this is not the saved invite, it's a RE-invite. Respond saying we don't support it. 383 if (!transaction->sameINVITE(msg)){ 384 /* don't cancel the call */ 385 transaction->MODSendERROR(msg, 488, "Not Acceptable Here", false); 386 /* I think we'd need to create a new transaction for this ack. Right now, just assume the ack makes it back. 387 if not, we'll hear another INVITE */ 388 //transaction->MODWaitForERRORACK(false); //don't cancel the call 389 return false; 390 } 382 391 // There is transaction already. Send trying. 383 392 transaction->MTCSendTrying(); -
openbts/trunk/SIP/SIPMessage.cpp
r3270 r3810 600 600 } 601 601 602 osip_message_t * SIP::sip_ temporarily_unavailable( osip_message_t * invite, const char * host, const char * username, short port)602 osip_message_t * SIP::sip_error(osip_message_t * invite, const char * host, const char * username, short port, short code, const char* reason) 603 603 { 604 604 … … 611 611 unavail->message_property = 2; 612 612 //header stuff first 613 unavail->status_code = 480;614 unavail->reason_phrase = strdup( "Temporarily Unavailable");613 unavail->status_code = code; 614 unavail->reason_phrase = strdup(reason); 615 615 osip_message_set_version(unavail, strdup("SIP/2.0")); 616 616 -
openbts/trunk/SIP/SIPMessage.h
r3264 r3810 56 56 osip_message_t * sip_okay( osip_message_t * inv, const char * sip_username, const char * local_ip, short wlocal_port); 57 57 58 osip_message_t * sip_ temporarily_unavailable( osip_message_t * invite, const char * host, const char * username, short port);58 osip_message_t * sip_error( osip_message_t * invite, const char * host, const char * username, short port, short code, const char* reason); 59 59 60 60 osip_message_t * sip_info(unsigned info, const char *dialed_number, short rtp_port,const char * sip_username, short local_port, const char * local_ip, const char * proxy_ip, const char * from_tag, const char * via_branch, const osip_call_id_t* call_id_header, int cseq); … … 70 70 }; 71 71 #endif 72
![(please configure the [header_logo] section in trac.ini)](http://wush.net/trac/rangepublic/raw-attachment/wiki/WikiStart/PublicReleaseLogo.png)
