[vlc-commits] chromecast: Simplify and fix packets recv & heartbeat management

Hugo Beauzée-Luyssen git at videolan.org
Tue Feb 21 14:00:57 CET 2017


vlc | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Mon Feb 20 14:42:39 2017 +0100| [366b06e40c74d9845ee57b655b33a5bd64891e56] | committer: Hugo Beauzée-Luyssen

chromecast: Simplify and fix packets recv & heartbeat management

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=366b06e40c74d9845ee57b655b33a5bd64891e56
---

 modules/stream_out/chromecast/chromecast.h         | 11 +--
 .../chromecast/chromecast_communication.cpp        | 88 +++++++---------------
 modules/stream_out/chromecast/chromecast_ctrl.cpp  | 54 ++++++-------
 3 files changed, 59 insertions(+), 94 deletions(-)

diff --git a/modules/stream_out/chromecast/chromecast.h b/modules/stream_out/chromecast/chromecast.h
index ac4bc2c..b3fba6f 100644
--- a/modules/stream_out/chromecast/chromecast.h
+++ b/modules/stream_out/chromecast/chromecast.h
@@ -55,10 +55,6 @@ static const std::string NAMESPACE_RECEIVER         = "urn:x-cast:com.google.cas
 #define CHROMECAST_CONTROL_PORT 8009
 #define HTTP_PORT               8010
 
-/* deadline regarding pings sent from receiver */
-#define PING_WAIT_TIME 6000
-#define PING_WAIT_RETRIES 0
-
 #define PACKET_MAX_LEN 10 * 1024
 
 // Media player Chromecast app id
@@ -114,9 +110,7 @@ public:
                         const std::string & currentTime );
     void msgPlayerSetVolume( const std::string& destinationId, const std::string& mediaSessionId,
                              float volume, bool mute);
-    int recvPacket( bool *b_msgReceived, uint32_t &i_payloadSize,
-                   unsigned *pi_received, uint8_t *p_data, bool *pb_pingTimeout,
-                   int *pi_wait_delay, int *pi_wait_retries );
+    ssize_t recvPacket( uint8_t *p_data);
 private:
     int sendMessage(const castchannel::CastMessage &msg);
 
@@ -240,6 +234,9 @@ private:
 
     /* shared structure with the demux-filter */
     chromecast_common      m_common;
+
+    /* Heartbeat */
+    uint8_t m_pingRetriesLeft;
 };
 
 #endif /* VLC_CHROMECAST_H */
diff --git a/modules/stream_out/chromecast/chromecast_communication.cpp b/modules/stream_out/chromecast/chromecast_communication.cpp
index daa41da..3d0068d 100644
--- a/modules/stream_out/chromecast/chromecast_communication.cpp
+++ b/modules/stream_out/chromecast/chromecast_communication.cpp
@@ -32,9 +32,8 @@
 # include <poll.h>
 #endif
 
-/* deadline regarding pong we expect after pinging the receiver */
-#define PONG_WAIT_TIME 500
-#define PONG_WAIT_RETRIES 2
+/* deadline regarding pings sent from receiver */
+#define PING_WAIT_TIME 6000
 
 ChromecastCommunication::ChromecastCommunication( vlc_object_t* p_module, const char* targetIP, unsigned int devicePort )
     : m_module( p_module )
@@ -123,11 +122,10 @@ void ChromecastCommunication::buildMessage(const std::string & namespace_,
  * @param i_payloadSize returns the payload size of the message received
  * @return the number of bytes received of -1 on error
  */
-int ChromecastCommunication::recvPacket(bool *b_msgReceived,
-                          uint32_t &i_payloadSize,
-                          unsigned *pi_received, uint8_t *p_data, bool *pb_pingTimeout,
-                          int *pi_wait_delay, int *pi_wait_retries)
+ssize_t ChromecastCommunication::recvPacket( uint8_t *p_data )
 {
+    uint32_t i_received = 0;
+    ssize_t i_payloadSize = -1;
     struct pollfd ufd[1];
     ufd[0].fd = m_sock_fd;
     ufd[0].events = POLLIN;
@@ -136,37 +134,15 @@ int ChromecastCommunication::recvPacket(bool *b_msgReceived,
      * If we do not receive one after 6 seconds, we send a PING.
      * If after this PING, we do not receive a PONG, then we consider the
      * connection as dead. */
-    ssize_t val = vlc_poll_i11e(ufd, 1, *pi_wait_delay);
-    if ( val == -1 && errno != EINTR )
-        return -1;
-
-    if (val == 0)
-    {
-        if (*pb_pingTimeout)
-        {
-            if (!*pi_wait_retries)
-            {
-                msg_Err( m_module, "No PONG answer received from the Chromecast");
-                return 0; // Connection died
-            }
-            (*pi_wait_retries)--;
-        }
-        else
-        {
-            /* now expect a pong */
-            *pi_wait_delay = PONG_WAIT_TIME;
-            *pi_wait_retries = PONG_WAIT_RETRIES;
-            msg_Warn( m_module, "No PING received from the Chromecast, sending a PING");
-        }
-        *pb_pingTimeout = true;
-    }
-    else
+    ssize_t val = vlc_poll_i11e(ufd, 1, PING_WAIT_TIME);
+    if ( val == -1 )
     {
-        *pb_pingTimeout = false;
-        /* reset to default ping waiting */
-        *pi_wait_delay = PING_WAIT_TIME;
-        *pi_wait_retries = PING_WAIT_RETRIES;
+        if ( errno != EINTR )
+            return -1;
+        return 0;
     }
+    if ( val == 0 )
+        return 0;
 
     int i_ret = 0;
     if ( ufd[0].revents & POLLIN )
@@ -177,13 +153,13 @@ int ChromecastCommunication::recvPacket(bool *b_msgReceived,
          * +------------------------------------+------------------------------+
          * | Payload size (uint32_t big endian) |         Payload data         |
          * +------------------------------------+------------------------------+ */
-        while (*pi_received < PACKET_HEADER_LEN)
+        while (i_received < PACKET_HEADER_LEN)
         {
             // We receive the header.
-            i_ret = tls_Recv(m_tls, p_data + *pi_received, PACKET_HEADER_LEN - *pi_received);
+            i_ret = tls_Recv(m_tls, p_data + i_received, PACKET_HEADER_LEN - i_received);
             if (i_ret <= 0)
-                return i_ret;
-            *pi_received += i_ret;
+                return -1;
+            i_received += i_ret;
         }
 
         // We receive the payload.
@@ -197,42 +173,34 @@ int ChromecastCommunication::recvPacket(bool *b_msgReceived,
             // Error case: the packet sent by the Chromecast is too long: we drop it.
             msg_Err( m_module, "Packet too long: droping its data");
 
-            uint32_t i_size = i_payloadSize - (*pi_received - PACKET_HEADER_LEN);
+            uint32_t i_size = i_payloadSize - (i_received - PACKET_HEADER_LEN);
             if (i_size > i_maxPayloadSize)
                 i_size = i_maxPayloadSize;
 
             i_ret = tls_Recv(m_tls, p_data + PACKET_HEADER_LEN, i_size);
             if (i_ret <= 0)
-                return i_ret;
-            *pi_received += i_ret;
+                return -1;
+            i_received += i_ret;
 
-            if (*pi_received < i_payloadSize + PACKET_HEADER_LEN)
+            if (i_received < i_payloadSize + PACKET_HEADER_LEN)
                 return i_ret;
 
-            *pi_received = 0;
             return -1;
         }
 
         // Normal case
-        i_ret = tls_Recv(m_tls, p_data + *pi_received,
-                         i_payloadSize - (*pi_received - PACKET_HEADER_LEN));
+        i_ret = tls_Recv(m_tls, p_data + i_received,
+                         i_payloadSize - (i_received - PACKET_HEADER_LEN));
         if (i_ret <= 0)
-            return i_ret;
-        *pi_received += i_ret;
+            return -1;
+        i_received += i_ret;
 
-        if (*pi_received < i_payloadSize + PACKET_HEADER_LEN)
-            return i_ret;
+        if (i_received < i_payloadSize + PACKET_HEADER_LEN)
+            return -1;
 
-        assert(*pi_received == i_payloadSize + PACKET_HEADER_LEN);
-        *pi_received = 0;
-        *b_msgReceived = true;
+        assert(i_received == i_payloadSize + PACKET_HEADER_LEN);
     }
-
-    if ( val == -1 && errno == EINTR )
-        /* we have stuff to send */
-        i_ret = 1;
-
-    return i_ret;
+    return i_payloadSize;
 }
 
 
diff --git a/modules/stream_out/chromecast/chromecast_ctrl.cpp b/modules/stream_out/chromecast/chromecast_ctrl.cpp
index 9ff2731..55acada 100644
--- a/modules/stream_out/chromecast/chromecast_ctrl.cpp
+++ b/modules/stream_out/chromecast/chromecast_ctrl.cpp
@@ -40,7 +40,7 @@
 
 /* deadline regarding pings sent from receiver */
 #define PING_WAIT_TIME 6000
-#define PING_WAIT_RETRIES 0
+#define PING_WAIT_RETRIES 1
 
 static const mtime_t SEEK_FORWARD_OFFSET = 1000000;
 
@@ -91,6 +91,7 @@ intf_sys_t::intf_sys_t(vlc_object_t * const p_this, int port, std::string device
  , m_length( VLC_TS_INVALID )
  , m_chromecast_start_time( VLC_TS_INVALID )
  , m_seek_request_time( VLC_TS_INVALID )
+ , m_pingRetriesLeft( PING_WAIT_RETRIES )
 {
     vlc_mutex_init(&m_lock);
     vlc_cond_init( &m_stateChangedCond );
@@ -279,6 +280,7 @@ void intf_sys_t::processHeartBeatMessage( const castchannel::CastMessage& msg )
     else if (type == "PONG")
     {
         msg_Dbg( m_module, "PONG received from the Chromecast");
+        m_pingRetriesLeft = PING_WAIT_RETRIES;
     }
     else
     {
@@ -544,15 +546,8 @@ void intf_sys_t::processConnectionMessage( const castchannel::CastMessage& msg )
 
 bool intf_sys_t::handleMessages()
 {
-    unsigned i_received = 0;
     uint8_t p_packet[PACKET_MAX_LEN];
-    bool b_pingTimeout = false;
-
-    int i_waitdelay = PING_WAIT_TIME;
-    int i_retries = PING_WAIT_RETRIES;
-
-    bool b_msgReceived = false;
-    uint32_t i_payloadSize = 0;
+    ssize_t i_payloadSize = 0;
 
     if ( m_requested_stop.exchange(false) && !m_mediaSessionId.empty() )
     {
@@ -573,35 +568,40 @@ bool intf_sys_t::handleMessages()
         m_communication.msgPlayerSeek( m_appTransportId, m_mediaSessionId, current_time );
     }
 
-    int i_ret = m_communication.recvPacket( &b_msgReceived, i_payloadSize,
-                            &i_received, p_packet, &b_pingTimeout,
-                            &i_waitdelay, &i_retries);
-
-
+    i_payloadSize = m_communication.recvPacket( p_packet );
 #if defined(_WIN32)
-    if ((i_ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) || (i_ret == 0))
+    if ( i_payloadSize < 0 && WSAGetLastError() != WSAEWOULDBLOCK )
 #else
-    if ((i_ret < 0 && errno != EAGAIN) || i_ret == 0)
+    if ( i_payloadSize < 0 )
 #endif
     {
+        // An error occured, we give up
         msg_Err( m_module, "The connection to the Chromecast died (receiving).");
         vlc_mutex_locker locker(&m_lock);
         setState( Dead );
         return false;
     }
-
-    if (b_pingTimeout)
-    {
-        m_communication.msgPing();
-        m_communication.msgReceiverGetStatus();
-    }
-
-    if (b_msgReceived)
+    if ( i_payloadSize == 0 )
     {
-        castchannel::CastMessage msg;
-        msg.ParseFromArray(p_packet + PACKET_HEADER_LEN, i_payloadSize);
-        processMessage(msg);
+        // If no commands were queued to be sent, we timed out. Let's ping the chromecast
+        if ( m_requested_seek == false && m_requested_stop == false )
+        {
+            if ( m_pingRetriesLeft == 0 )
+            {
+                vlc_mutex_locker locker(&m_lock);
+                m_state = Dead;
+                msg_Warn( m_module, "No PING response from the chromecast" );
+                return false;
+            }
+            --m_pingRetriesLeft;
+            m_communication.msgPing();
+            m_communication.msgReceiverGetStatus();
+        }
+        return true;
     }
+    castchannel::CastMessage msg;
+    msg.ParseFromArray(p_packet + PACKET_HEADER_LEN, i_payloadSize);
+    processMessage(msg);
     return true;
 }
 



More information about the vlc-commits mailing list