Commit 40886529 authored by Steve Lhomme's avatar Steve Lhomme Committed by Jean-Baptiste Kempf

chromecast: move the message sending in the communication handler

Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 6147305c
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#endif #endif
#include <vlc_sout.h> #include <vlc_sout.h>
#include <vlc_tls.h>
#include <vlc_url.h> #include <vlc_url.h>
#include <vlc_threads.h> #include <vlc_threads.h>
...@@ -46,13 +45,11 @@ ...@@ -46,13 +45,11 @@
#include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/coded_stream.h>
#define PACKET_MAX_LEN 10 * 1024 #define PACKET_MAX_LEN 10 * 1024
#define PACKET_HEADER_LEN 4
struct sout_stream_sys_t struct sout_stream_sys_t
{ {
sout_stream_sys_t(intf_sys_t *intf) sout_stream_sys_t(intf_sys_t *intf)
: p_tls(NULL) : p_out(NULL)
, p_out(NULL)
, p_intf(intf) , p_intf(intf)
{ {
} }
...@@ -64,7 +61,6 @@ struct sout_stream_sys_t ...@@ -64,7 +61,6 @@ struct sout_stream_sys_t
int i_sock_fd; int i_sock_fd;
vlc_tls_creds_t *p_creds; vlc_tls_creds_t *p_creds;
vlc_tls_t *p_tls;
vlc_thread_t chromecastThread; vlc_thread_t chromecastThread;
...@@ -95,7 +91,6 @@ static void Close(vlc_object_t *); ...@@ -95,7 +91,6 @@ static void Close(vlc_object_t *);
static void Clean(sout_stream_t *p_stream); static void Clean(sout_stream_t *p_stream);
static int connectChromecast(sout_stream_t *p_stream, char *psz_ipChromecast); static int connectChromecast(sout_stream_t *p_stream, char *psz_ipChromecast);
static void disconnectChromecast(sout_stream_t *p_stream); static void disconnectChromecast(sout_stream_t *p_stream);
static int sendMessages(sout_stream_t *p_stream);
static void *chromecastThread(void *data); static void *chromecastThread(void *data);
...@@ -315,7 +310,7 @@ static void Close(vlc_object_t *p_this) ...@@ -315,7 +310,7 @@ static void Close(vlc_object_t *p_this)
case CHROMECAST_AUTHENTICATED: case CHROMECAST_AUTHENTICATED:
p_sys->p_intf->msgReceiverClose(DEFAULT_CHOMECAST_RECEIVER); p_sys->p_intf->msgReceiverClose(DEFAULT_CHOMECAST_RECEIVER);
// Send the just added close messages. // Send the just added close messages.
sendMessages(p_stream); p_sys->p_intf->sendMessages();
// ft // ft
default: default:
break; break;
...@@ -362,10 +357,10 @@ static int connectChromecast(sout_stream_t *p_stream, char *psz_ipChromecast) ...@@ -362,10 +357,10 @@ static int connectChromecast(sout_stream_t *p_stream, char *psz_ipChromecast)
return -1; return -1;
} }
p_sys->p_tls = vlc_tls_ClientSessionCreate(p_sys->p_creds, fd, psz_ipChromecast, p_sys->p_intf->p_tls = vlc_tls_ClientSessionCreate(p_sys->p_creds, fd, psz_ipChromecast,
"tcps", NULL, NULL); "tcps", NULL, NULL);
if (p_sys->p_tls == NULL) if (p_sys->p_intf->p_tls == NULL)
{ {
vlc_tls_Delete(p_sys->p_creds); vlc_tls_Delete(p_sys->p_creds);
return -1; return -1;
...@@ -382,69 +377,16 @@ static void disconnectChromecast(sout_stream_t *p_stream) ...@@ -382,69 +377,16 @@ static void disconnectChromecast(sout_stream_t *p_stream)
{ {
sout_stream_sys_t *p_sys = p_stream->p_sys; sout_stream_sys_t *p_sys = p_stream->p_sys;
if (p_sys->p_tls) if (p_sys->p_intf->p_tls)
{ {
vlc_tls_SessionDelete(p_sys->p_tls); vlc_tls_SessionDelete(p_sys->p_intf->p_tls);
vlc_tls_Delete(p_sys->p_creds); vlc_tls_Delete(p_sys->p_creds);
p_sys->p_tls = NULL; p_sys->p_intf->p_tls = NULL;
p_sys->p_intf->setConnectionStatus(CHROMECAST_DISCONNECTED); p_sys->p_intf->setConnectionStatus(CHROMECAST_DISCONNECTED);
} }
} }
/**
* @brief Send a message to the Chromecast
* @param p_stream the sout_stream_t structure
* @param msg the CastMessage to send
* @return the number of bytes sent or -1 on error
*/
static int sendMessage(sout_stream_t *p_stream, castchannel::CastMessage &msg)
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
uint32_t i_size = msg.ByteSize();
uint32_t i_sizeNetwork = hton32(i_size);
char *p_data = new(std::nothrow) char[PACKET_HEADER_LEN + i_size];
if (p_data == NULL)
return -1;
memcpy(p_data, &i_sizeNetwork, PACKET_HEADER_LEN);
msg.SerializeWithCachedSizesToArray((uint8_t *)(p_data + PACKET_HEADER_LEN));
int i_ret = tls_Send(p_sys->p_tls, p_data, PACKET_HEADER_LEN + i_size);
delete[] p_data;
return i_ret;
}
/**
* @brief Send all the messages in the pending queue to the Chromecast
* @param p_stream the sout_stream_t structure
* @param msg the CastMessage to send
* @return the number of bytes sent or -1 on error
*/
static int sendMessages(sout_stream_t *p_stream)
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
int i_ret = 0;
while (!p_sys->p_intf->messagesToSend.empty())
{
unsigned i_retSend = sendMessage(p_stream, p_sys->p_intf->messagesToSend.front());
if (i_retSend <= 0)
return i_retSend;
p_sys->p_intf->messagesToSend.pop();
i_ret += i_retSend;
}
return i_ret;
}
/** /**
* @brief Receive a data packet from the Chromecast * @brief Receive a data packet from the Chromecast
...@@ -577,7 +519,7 @@ static void* chromecastThread(void* p_data) ...@@ -577,7 +519,7 @@ static void* chromecastThread(void* p_data)
int i_retries = PING_WAIT_RETRIES; int i_retries = PING_WAIT_RETRIES;
p_sys->p_intf->msgAuth(); p_sys->p_intf->msgAuth();
sendMessages(p_stream); p_sys->p_intf->sendMessages();
vlc_restorecancel(canc); vlc_restorecancel(canc);
while (1) while (1)
...@@ -585,7 +527,7 @@ static void* chromecastThread(void* p_data) ...@@ -585,7 +527,7 @@ static void* chromecastThread(void* p_data)
bool b_msgReceived = false; bool b_msgReceived = false;
uint32_t i_payloadSize = 0; uint32_t i_payloadSize = 0;
int i_ret = recvPacket(p_stream, b_msgReceived, i_payloadSize, p_sys->i_sock_fd, int i_ret = recvPacket(p_stream, b_msgReceived, i_payloadSize, p_sys->i_sock_fd,
p_sys->p_tls, &i_received, p_packet, &b_pingTimeout, p_sys->p_intf->p_tls, &i_received, p_packet, &b_pingTimeout,
&i_waitdelay, &i_retries); &i_waitdelay, &i_retries);
canc = vlc_savecancel(); canc = vlc_savecancel();
...@@ -616,21 +558,7 @@ static void* chromecastThread(void* p_data) ...@@ -616,21 +558,7 @@ static void* chromecastThread(void* p_data)
p_sys->p_intf->processMessage(msg); p_sys->p_intf->processMessage(msg);
} }
// Send the answer messages if there is any. p_sys->p_intf->handleMessages();
if (!p_sys->p_intf->messagesToSend.empty())
{
i_ret = sendMessages(p_stream);
#if defined(_WIN32)
if ((i_ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) || (i_ret == 0))
#else
if ((i_ret < 0 && errno != EAGAIN) || i_ret == 0)
#endif
{
msg_Err(p_stream, "The connection to the Chromecast died.");
vlc_mutex_locker locker(&p_sys->p_intf->lock);
p_sys->p_intf->setConnectionStatus(CHROMECAST_CONNECTION_DEAD);
}
}
vlc_mutex_lock(&p_sys->p_intf->lock); vlc_mutex_lock(&p_sys->p_intf->lock);
if ( p_sys->p_intf->getConnectionStatus() == CHROMECAST_CONNECTION_DEAD ) if ( p_sys->p_intf->getConnectionStatus() == CHROMECAST_CONNECTION_DEAD )
......
...@@ -32,11 +32,14 @@ ...@@ -32,11 +32,14 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_sout.h> #include <vlc_sout.h>
#include <vlc_tls.h>
#include <queue> #include <queue>
#include "cast_channel.pb.h" #include "cast_channel.pb.h"
#define PACKET_HEADER_LEN 4
// Media player Chromecast app id // Media player Chromecast app id
static const std::string DEFAULT_CHOMECAST_RECEIVER = "receiver-0"; static const std::string DEFAULT_CHOMECAST_RECEIVER = "receiver-0";
static const std::string NAMESPACE_DEVICEAUTH = "urn:x-cast:com.google.cast.tp.deviceauth"; static const std::string NAMESPACE_DEVICEAUTH = "urn:x-cast:com.google.cast.tp.deviceauth";
...@@ -67,12 +70,17 @@ struct intf_sys_t ...@@ -67,12 +70,17 @@ struct intf_sys_t
std::string serverIP; std::string serverIP;
std::string appTransportId; std::string appTransportId;
vlc_tls_t *p_tls;
vlc_mutex_t lock; vlc_mutex_t lock;
vlc_cond_t loadCommandCond; vlc_cond_t loadCommandCond;
void msgAuth(); void msgAuth();
void msgReceiverClose(std::string destinationId); void msgReceiverClose(std::string destinationId);
void handleMessages();
int sendMessages();
connection_status getConnectionStatus() const connection_status getConnectionStatus() const
{ {
return conn_status; return conn_status;
...@@ -104,6 +112,8 @@ struct intf_sys_t ...@@ -104,6 +112,8 @@ struct intf_sys_t
void processMessage(const castchannel::CastMessage &msg); void processMessage(const castchannel::CastMessage &msg);
private: private:
int sendMessage(castchannel::CastMessage &msg);
enum connection_status conn_status; enum connection_status conn_status;
unsigned i_requestId; unsigned i_requestId;
......
...@@ -73,6 +73,7 @@ static castchannel::CastMessage buildMessage(std::string namespace_, ...@@ -73,6 +73,7 @@ static castchannel::CastMessage buildMessage(std::string namespace_,
intf_sys_t::intf_sys_t(sout_stream_t * const p_this) intf_sys_t::intf_sys_t(sout_stream_t * const p_this)
: p_stream(p_this) : p_stream(p_this)
, p_tls(NULL)
, conn_status(CHROMECAST_DISCONNECTED) , conn_status(CHROMECAST_DISCONNECTED)
, i_requestId(0) , i_requestId(0)
{ {
...@@ -353,3 +354,67 @@ void intf_sys_t::msgPlayerLoad() ...@@ -353,3 +354,67 @@ void intf_sys_t::msgPlayerLoad()
messagesToSend.push(msg); messagesToSend.push(msg);
} }
/**
* @brief Send a message to the Chromecast
* @param msg the CastMessage to send
* @return the number of bytes sent or -1 on error
*/
int intf_sys_t::sendMessage(castchannel::CastMessage &msg)
{
uint32_t i_size = msg.ByteSize();
uint32_t i_sizeNetwork = hton32(i_size);
char *p_data = new(std::nothrow) char[PACKET_HEADER_LEN + i_size];
if (p_data == NULL)
return -1;
memcpy(p_data, &i_sizeNetwork, PACKET_HEADER_LEN);
msg.SerializeWithCachedSizesToArray((uint8_t *)(p_data + PACKET_HEADER_LEN));
int i_ret = tls_Send(p_tls, p_data, PACKET_HEADER_LEN + i_size);
delete[] p_data;
return i_ret;
}
/**
* @brief Send all the messages in the pending queue to the Chromecast
* @param msg the CastMessage to send
* @return the number of bytes sent or -1 on error
*/
int intf_sys_t::sendMessages()
{
int i_ret = 0;
while (!messagesToSend.empty())
{
unsigned i_retSend = sendMessage(messagesToSend.front());
if (i_retSend <= 0)
return i_retSend;
messagesToSend.pop();
i_ret += i_retSend;
}
return i_ret;
}
void intf_sys_t::handleMessages()
{
int i_ret;
// Send the answer messages if there is any.
if (!messagesToSend.empty())
{
i_ret = sendMessages();
#if defined(_WIN32)
if ((i_ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) || (i_ret == 0))
#else
if ((i_ret < 0 && errno != EAGAIN) || i_ret == 0)
#endif
{
msg_Err(p_stream, "The connection to the Chromecast died.");
vlc_mutex_locker locker(&lock);
setConnectionStatus(CHROMECAST_CONNECTION_DEAD);
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment