From 0d5fc783c8f20b37cac575790e23a447166e7de8 Mon Sep 17 00:00:00 2001 From: yushimeng Date: Fri, 2 Feb 2024 19:49:38 +0800 Subject: [PATCH] fix GB28181: When camera restart, can not connect to SRS. #3944 --- trunk/src/app/srs_app_gb28181.cpp | 29 +++++++++++++++++++++++++++-- trunk/src/app/srs_app_gb28181.hpp | 6 ++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/trunk/src/app/srs_app_gb28181.cpp b/trunk/src/app/srs_app_gb28181.cpp index 99c9dbf0cd..5a69004e99 100644 --- a/trunk/src/app/srs_app_gb28181.cpp +++ b/trunk/src/app/srs_app_gb28181.cpp @@ -507,7 +507,7 @@ SrsLazyGbSipTcpConn::SrsLazyGbSipTcpConn(SrsLazyObjectWrapperenqueue(msg); } +void SrsLazyGbSipTcpConn::on_sip_disconnect() { + state_ = SrsGbSipStateDisconnect; + this->wake_up(); +} + void SrsLazyGbSipTcpConn::drive_state(SrsSipMessage* msg) { srs_error_t err = srs_success; @@ -622,6 +627,10 @@ void SrsLazyGbSipTcpConn::drive_state(SrsSipMessage* msg) srs_sip_state(ostate, state_).c_str()); \ } + if (state_ == SrsGbSipStateDisconnect) { + return; + } + //const char* mt = msg->type_ == HTTP_REQUEST ? "REQUEST" : "RESPONSE"; //const char* mm = msg->type_ == HTTP_REQUEST ? http_method_str(msg->method_) : "Response"; //int ms = msg->type_ == HTTP_REQUEST ? 200 : msg->status_; @@ -866,6 +875,11 @@ bool SrsLazyGbSipTcpConn::is_bye() return state_ == SrsGbSipStateBye; } +bool SrsLazyGbSipTcpConn::is_disconnect() +{ + return state_ == SrsGbSipStateDisconnect; +} + SrsGbSipState SrsLazyGbSipTcpConn::set_state(SrsGbSipState v) { SrsGbSipState state = state_; @@ -873,6 +887,11 @@ SrsGbSipState SrsLazyGbSipTcpConn::set_state(SrsGbSipState v) return state; } +void SrsLazyGbSipTcpConn::wake_up() +{ + srs_cond_signal(cond_); +} + const SrsContextId& SrsLazyGbSipTcpConn::get_id() { return trd_->cid(); @@ -952,7 +971,10 @@ srs_error_t SrsLazyGbSipTcpConn::do_cycle() } // TODO: Handle other messages. - srs_usleep(SRS_UTIME_NO_TIMEOUT); + int ret = srs_cond_timedwait(cond_, 10 * SRS_UTIME_SECONDS); + if (ret == -1) { + return srs_error_new(ret, "errno:%d", errno); + } } return err; @@ -1048,6 +1070,9 @@ srs_error_t SrsLazyGbSipTcpReceiver::cycle() // TODO: FIXME: Notify SIP transport to cleanup. if (err != srs_success) { srs_error("SIP: Receive err %s", srs_error_desc(err).c_str()); + if (sip_) { + sip_->on_sip_disconnect(); + } } return err; diff --git a/trunk/src/app/srs_app_gb28181.hpp b/trunk/src/app/srs_app_gb28181.hpp index 783842505f..b392d6f62b 100644 --- a/trunk/src/app/srs_app_gb28181.hpp +++ b/trunk/src/app/srs_app_gb28181.hpp @@ -86,6 +86,7 @@ enum SrsGbSipState SrsGbSipStateReinviting, SrsGbSipStateStable, SrsGbSipStateBye, + SrsGbSipStateDisconnect, }; std::string srs_gb_sip_state(SrsGbSipState state); @@ -206,6 +207,7 @@ class SrsLazyGbSipTcpConn : public SrsLazyObject, public ISrsResource, public IS SrsLazyGbSipTcpReceiver* receiver_; SrsLazyGbSipTcpSender* sender_; SrsCoroutine* trd_; + srs_cond_t cond_; private: friend class SrsLazyObjectWrapper; SrsLazyGbSipTcpConn(SrsLazyObjectWrapper* wrapper_root); @@ -224,6 +226,8 @@ class SrsLazyGbSipTcpConn : public SrsLazyObject, public ISrsResource, public IS public: // When got a SIP message. srs_error_t on_sip_message(SrsSipMessage* msg); + // When SIP connection lost. + void on_sip_disconnect(); // Enqueue a SIP message to send, which might be a request or response. void enqueue_sip_message(SrsSipMessage* msg); private: @@ -247,8 +251,10 @@ class SrsLazyGbSipTcpConn : public SrsLazyObject, public ISrsResource, public IS bool is_stable(); // Whether SIP is bye bye. bool is_bye(); + bool is_disconnect(); private: SrsGbSipState set_state(SrsGbSipState v); + void wake_up(); // Interface ISrsResource public: virtual const SrsContextId& get_id();