[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