From db771a00af5b9774996bad6bb03df44687771fba Mon Sep 17 00:00:00 2001
From: Eloi BAIL <eloi.bail@savoirfairelinux.com>
Date: Fri, 4 Sep 2015 14:22:19 -0400
Subject: [PATCH] rtp: ensure to synchronously update seq number

When bitrate is changed, new RTP session created must rely
on RTP sequence of previous RTP session in order to provide
continous sequence numbers.
This patchset ensures to keep last RTP sequence updated correctly
ensuring that no new packet will be sent when bitrate change is performed.

Issue: #80058
Change-Id: Ia7fbecd19aa0ec648327307de3ce3f8eace163a0
Signed-off-by: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
---
 src/media/audio/audio_rtp_session.cpp | 10 +++++++---
 src/media/socket_pair.cpp             | 11 +++++++++++
 src/media/socket_pair.h               |  3 +++
 src/media/video/video_rtp_session.cpp | 15 +++++++++------
 4 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/src/media/audio/audio_rtp_session.cpp b/src/media/audio/audio_rtp_session.cpp
index cbb063064e..afe335846d 100644
--- a/src/media/audio/audio_rtp_session.cpp
+++ b/src/media/audio/audio_rtp_session.cpp
@@ -382,7 +382,14 @@ AudioRtpSession::startSender()
     if (sender_)
         RING_WARN("Restarting audio sender");
 
+
+    // be sure to not send any packets before saving last RTP seq value
+    socketPair_->stopSendOp();
+    if (sender_)
+        initSeqVal_ = sender_->getLastSeqValue() + 1;
     try {
+        sender_.reset();
+        socketPair_->stopSendOp(false);
         sender_.reset(new AudioSender(callID_, getRemoteRtpUri(), send_,
                                       *socketPair_, initSeqVal_));
     } catch (const MediaEncoderException &e) {
@@ -395,9 +402,6 @@ void
 AudioRtpSession::restartSender()
 {
     std::lock_guard<std::recursive_mutex> lock(mutex_);
-
-    // continue on last sequence number
-    initSeqVal_ = sender_->getLastSeqValue() + 1;
     startSender();
 }
 
diff --git a/src/media/socket_pair.cpp b/src/media/socket_pair.cpp
index 9873a247ee..cadd00102b 100644
--- a/src/media/socket_pair.cpp
+++ b/src/media/socket_pair.cpp
@@ -260,6 +260,12 @@ SocketPair::interrupt()
     cv_.notify_all();
 }
 
+void
+SocketPair::stopSendOp(bool state)
+{
+    noWrite_ = state;
+}
+
 void
 SocketPair::closeSockets()
 {
@@ -463,10 +469,15 @@ SocketPair::writeData(uint8_t* buf, int buf_size)
         if (ret < 0)
             return ret;
 
+        if (noWrite_)
+            return buf_size;
         return sendto(fd, reinterpret_cast<const char*>(buf), buf_size, 0,
                       reinterpret_cast<sockaddr*>(&dest_addr), dest_addr_len);
     }
 
+    if (noWrite_)
+        return buf_size;
+
     // IceSocket
     if (isRTCP)
         return rtcp_sock_->send(buf, buf_size);
diff --git a/src/media/socket_pair.h b/src/media/socket_pair.h
index bdada9d644..f5992e6312 100644
--- a/src/media/socket_pair.h
+++ b/src/media/socket_pair.h
@@ -93,6 +93,8 @@ class SocketPair {
         void createSRTP(const char* out_suite, const char* out_params,
                         const char* in_suite, const char* in_params);
 
+        void stopSendOp(bool state = true);
+
     private:
         NON_COPYABLE(SocketPair);
 
@@ -119,6 +121,7 @@ class SocketPair {
         sockaddr_storage rtcpDestAddr_;
         socklen_t rtcpDestAddrLen_;
         std::atomic_bool interrupted_ {false};
+        std::atomic_bool noWrite_ {false};
         std::unique_ptr<SRTPProtoContext> srtpContext_;
 };
 
diff --git a/src/media/video/video_rtp_session.cpp b/src/media/video/video_rtp_session.cpp
index 05808c4681..01b7fecc0d 100644
--- a/src/media/video/video_rtp_session.cpp
+++ b/src/media/video/video_rtp_session.cpp
@@ -89,11 +89,16 @@ void VideoRtpSession::startSender()
             }
         }
 
+
+        // be sure to not send any packets before saving last RTP seq value
+        socketPair_->stopSendOp();
+        if (sender_)
+            initSeqVal_ = sender_->getLastSeqValue() + 1;
         try {
-            sender_.reset(
-                new VideoSender(getRemoteRtpUri(), localVideoParams_,
-                    send_, *socketPair_, initSeqVal_)
-            );
+            sender_.reset();
+            socketPair_->stopSendOp(false);
+            sender_.reset(new VideoSender(getRemoteRtpUri(), localVideoParams_,
+                                          send_, *socketPair_, initSeqVal_));
         } catch (const MediaEncoderException &e) {
             RING_ERR("%s", e.what());
             send_.enabled = false;
@@ -106,8 +111,6 @@ VideoRtpSession::restartSender()
 {
     std::lock_guard<std::recursive_mutex> lock(mutex_);
 
-    // continue on last sequence number
-    initSeqVal_ = sender_->getLastSeqValue() + 1;
     startSender();
 
     if (sender_) {
-- 
GitLab