mirror of
https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
synced 2023-10-10 19:16:51 +02:00
Timout for network operations now configurable in streamdev-client setup
This commit is contained in:
parent
c1dc1453c5
commit
3da6ae734e
1
HISTORY
1
HISTORY
@ -1,6 +1,7 @@
|
|||||||
VDR Plugin 'streamdev' Revision History
|
VDR Plugin 'streamdev' Revision History
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
- Timout for network operations now configurable in streamdev-client setup
|
||||||
- Added timeout to Connect()
|
- Added timeout to Connect()
|
||||||
- Report the server-side HTTP status "503 Service unavailable" instead of
|
- Report the server-side HTTP status "503 Service unavailable" instead of
|
||||||
the client-side error "409 Conflict" when a channel is unavailable
|
the client-side error "409 Conflict" when a channel is unavailable
|
||||||
|
3
README
3
README
@ -387,6 +387,9 @@ during an active transfer. This makes it possible to switch languages, receive
|
|||||||
additional channels (for recording on the client) and use plugins that use
|
additional channels (for recording on the client) and use plugins that use
|
||||||
receivers themselves (like osdteletext).
|
receivers themselves (like osdteletext).
|
||||||
|
|
||||||
|
The default timeout of 2 seconds for network operations should be sufficient in
|
||||||
|
most cases. Increase "Timeout" if you get frequent timeout errors in the log.
|
||||||
|
|
||||||
With "Filter Streaming" enabled, the client will receive meta information like
|
With "Filter Streaming" enabled, the client will receive meta information like
|
||||||
EPG data and service information, just as if the client had its own DVB card.
|
EPG data and service information, just as if the client had its own DVB card.
|
||||||
Link channels and even a client-side EPG scan have been reported to work.
|
Link channels and even a client-side EPG scan have been reported to work.
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: streamdev 0.5.0\n"
|
"Project-Id-Version: streamdev 0.5.0\n"
|
||||||
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
||||||
"POT-Creation-Date: 2011-02-16 08:49+0100\n"
|
"POT-Creation-Date: 2012-03-03 23:12+0100\n"
|
||||||
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
|
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
|
||||||
"Last-Translator: Frank Schmirler <vdrdev@schmirler.de>\n"
|
"Last-Translator: Frank Schmirler <vdrdev@schmirler.de>\n"
|
||||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||||
@ -40,6 +40,9 @@ msgstr "IP der Gegenseite"
|
|||||||
msgid "Remote Port"
|
msgid "Remote Port"
|
||||||
msgstr "Port der Gegenseite"
|
msgstr "Port der Gegenseite"
|
||||||
|
|
||||||
|
msgid "Timeout (s)"
|
||||||
|
msgstr "Timeout (s)"
|
||||||
|
|
||||||
msgid "Filter Streaming"
|
msgid "Filter Streaming"
|
||||||
msgstr "Filter-Daten streamen"
|
msgstr "Filter-Daten streamen"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: streamdev 0.5.0\n"
|
"Project-Id-Version: streamdev 0.5.0\n"
|
||||||
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
||||||
"POT-Creation-Date: 2011-12-11 10:48+0100\n"
|
"POT-Creation-Date: 2012-03-03 23:12+0100\n"
|
||||||
"PO-Revision-Date: 2010-06-19 03:58+0100\n"
|
"PO-Revision-Date: 2010-06-19 03:58+0100\n"
|
||||||
"Last-Translator: Javier Bradineras <jbradi@hotmail.com>\n"
|
"Last-Translator: Javier Bradineras <jbradi@hotmail.com>\n"
|
||||||
"Language-Team: Spanish <vdr@linuxtv.org>\n"
|
"Language-Team: Spanish <vdr@linuxtv.org>\n"
|
||||||
@ -40,6 +40,9 @@ msgstr "Indicar IP del Servidor"
|
|||||||
msgid "Remote Port"
|
msgid "Remote Port"
|
||||||
msgstr "Indicar puerto remoto del Servidor"
|
msgstr "Indicar puerto remoto del Servidor"
|
||||||
|
|
||||||
|
msgid "Timeout (s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Filter Streaming"
|
msgid "Filter Streaming"
|
||||||
msgstr "Filtrar transmisión"
|
msgstr "Filtrar transmisión"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: streamdev 0.5.0\n"
|
"Project-Id-Version: streamdev 0.5.0\n"
|
||||||
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
||||||
"POT-Creation-Date: 2011-12-11 10:48+0100\n"
|
"POT-Creation-Date: 2012-03-03 23:12+0100\n"
|
||||||
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
|
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
|
||||||
"Last-Translator: Rolf Ahrenberg\n"
|
"Last-Translator: Rolf Ahrenberg\n"
|
||||||
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
||||||
@ -40,6 +40,9 @@ msgstr "Etäkoneen IP-osoite"
|
|||||||
msgid "Remote Port"
|
msgid "Remote Port"
|
||||||
msgstr "Etäkoneen portti"
|
msgstr "Etäkoneen portti"
|
||||||
|
|
||||||
|
msgid "Timeout (s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Filter Streaming"
|
msgid "Filter Streaming"
|
||||||
msgstr "Suodatetun tiedon suoratoisto"
|
msgstr "Suodatetun tiedon suoratoisto"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: streamdev 0.5.0\n"
|
"Project-Id-Version: streamdev 0.5.0\n"
|
||||||
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
||||||
"POT-Creation-Date: 2011-12-11 10:48+0100\n"
|
"POT-Creation-Date: 2012-03-03 23:12+0100\n"
|
||||||
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
|
"PO-Revision-Date: 2008-03-30 02:11+0200\n"
|
||||||
"Last-Translator: micky979 <micky979@free.fr>\n"
|
"Last-Translator: micky979 <micky979@free.fr>\n"
|
||||||
"Language-Team: French <vdr@linuxtv.org>\n"
|
"Language-Team: French <vdr@linuxtv.org>\n"
|
||||||
@ -40,6 +40,9 @@ msgstr "Adresse IP du serveur"
|
|||||||
msgid "Remote Port"
|
msgid "Remote Port"
|
||||||
msgstr "Port du serveur"
|
msgstr "Port du serveur"
|
||||||
|
|
||||||
|
msgid "Timeout (s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Filter Streaming"
|
msgid "Filter Streaming"
|
||||||
msgstr "Filtre streaming"
|
msgstr "Filtre streaming"
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: streamdev 0.5.0\n"
|
"Project-Id-Version: streamdev 0.5.0\n"
|
||||||
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
||||||
"POT-Creation-Date: 2011-12-11 10:48+0100\n"
|
"POT-Creation-Date: 2012-03-03 23:12+0100\n"
|
||||||
"PO-Revision-Date: 2010-06-19 03:58+0100\n"
|
"PO-Revision-Date: 2010-06-19 03:58+0100\n"
|
||||||
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
|
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
|
||||||
"Language-Team: Italian <vdr@linuxtv.org>\n"
|
"Language-Team: Italian <vdr@linuxtv.org>\n"
|
||||||
@ -42,6 +42,9 @@ msgstr "Indirizzo IP del Server"
|
|||||||
msgid "Remote Port"
|
msgid "Remote Port"
|
||||||
msgstr "Porta Server Remoto"
|
msgstr "Porta Server Remoto"
|
||||||
|
|
||||||
|
msgid "Timeout (s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Filter Streaming"
|
msgid "Filter Streaming"
|
||||||
msgstr "Filtra trasmissione"
|
msgstr "Filtra trasmissione"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: streamdev 0.5.0\n"
|
"Project-Id-Version: streamdev 0.5.0\n"
|
||||||
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
||||||
"POT-Creation-Date: 2011-12-11 10:48+0100\n"
|
"POT-Creation-Date: 2012-03-03 23:12+0100\n"
|
||||||
"PO-Revision-Date: 2009-11-26 21:57+0200\n"
|
"PO-Revision-Date: 2009-11-26 21:57+0200\n"
|
||||||
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
|
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
|
||||||
"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
|
"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
|
||||||
@ -40,6 +40,9 @@ msgstr "Nuotolinis IP adresas"
|
|||||||
msgid "Remote Port"
|
msgid "Remote Port"
|
||||||
msgstr "Nuotolinis portas"
|
msgstr "Nuotolinis portas"
|
||||||
|
|
||||||
|
msgid "Timeout (s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Filter Streaming"
|
msgid "Filter Streaming"
|
||||||
msgstr "Filtruoti transliavimą"
|
msgstr "Filtruoti transliavimą"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: streamdev 0.5.0\n"
|
"Project-Id-Version: streamdev 0.5.0\n"
|
||||||
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
||||||
"POT-Creation-Date: 2011-12-11 10:48+0100\n"
|
"POT-Creation-Date: 2012-03-03 23:12+0100\n"
|
||||||
"PO-Revision-Date: 2008-06-26 15:36+0100\n"
|
"PO-Revision-Date: 2008-06-26 15:36+0100\n"
|
||||||
"Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
|
"Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
|
||||||
"Language-Team: Russian <vdr@linuxtv.org>\n"
|
"Language-Team: Russian <vdr@linuxtv.org>\n"
|
||||||
@ -40,6 +40,9 @@ msgstr "
|
|||||||
msgid "Remote Port"
|
msgid "Remote Port"
|
||||||
msgstr "ÃÔÐÛÕÝÝëÙ ßÞàâ"
|
msgstr "ÃÔÐÛÕÝÝëÙ ßÞàâ"
|
||||||
|
|
||||||
|
msgid "Timeout (s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Filter Streaming"
|
msgid "Filter Streaming"
|
||||||
msgstr "ÄØÛìâà ßÞâÞÚÐ"
|
msgstr "ÄØÛìâà ßÞâÞÚÐ"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: streamdev_SK\n"
|
"Project-Id-Version: streamdev_SK\n"
|
||||||
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
"Report-Msgid-Bugs-To: <http://www.vdr-developer.org/mantisbt/>\n"
|
||||||
"POT-Creation-Date: 2011-12-11 10:48+0100\n"
|
"POT-Creation-Date: 2012-03-03 23:12+0100\n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
|
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
|
||||||
"Language-Team: Slovak <hrala.milan@gmail.com>\n"
|
"Language-Team: Slovak <hrala.milan@gmail.com>\n"
|
||||||
@ -42,6 +42,9 @@ msgstr "Vzdialen
|
|||||||
msgid "Remote Port"
|
msgid "Remote Port"
|
||||||
msgstr "Vzdialený port"
|
msgstr "Vzdialený port"
|
||||||
|
|
||||||
|
msgid "Timeout (s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Filter Streaming"
|
msgid "Filter Streaming"
|
||||||
msgstr "filtrova» prúdy"
|
msgstr "filtrova» prúdy"
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ cStreamdevClientSetup StreamdevClientSetup;
|
|||||||
cStreamdevClientSetup::cStreamdevClientSetup(void) {
|
cStreamdevClientSetup::cStreamdevClientSetup(void) {
|
||||||
StartClient = false;
|
StartClient = false;
|
||||||
RemotePort = 2004;
|
RemotePort = 2004;
|
||||||
|
Timeout = 2;
|
||||||
StreamFilters = false;
|
StreamFilters = false;
|
||||||
HideMenuEntry = false;
|
HideMenuEntry = false;
|
||||||
MinPriority = -1;
|
MinPriority = -1;
|
||||||
@ -31,6 +32,7 @@ bool cStreamdevClientSetup::SetupParse(const char *Name, const char *Value) {
|
|||||||
strcpy(RemoteIp, Value);
|
strcpy(RemoteIp, Value);
|
||||||
}
|
}
|
||||||
else if (strcmp(Name, "RemotePort") == 0) RemotePort = atoi(Value);
|
else if (strcmp(Name, "RemotePort") == 0) RemotePort = atoi(Value);
|
||||||
|
else if (strcmp(Name, "Timeout") == 0) Timeout = atoi(Value);
|
||||||
else if (strcmp(Name, "StreamFilters") == 0) StreamFilters = atoi(Value);
|
else if (strcmp(Name, "StreamFilters") == 0) StreamFilters = atoi(Value);
|
||||||
else if (strcmp(Name, "HideMenuEntry") == 0) HideMenuEntry = atoi(Value);
|
else if (strcmp(Name, "HideMenuEntry") == 0) HideMenuEntry = atoi(Value);
|
||||||
else if (strcmp(Name, "MinPriority") == 0) MinPriority = atoi(Value);
|
else if (strcmp(Name, "MinPriority") == 0) MinPriority = atoi(Value);
|
||||||
@ -49,6 +51,7 @@ cStreamdevClientMenuSetupPage::cStreamdevClientMenuSetupPage(void) {
|
|||||||
Add(new cMenuEditBoolItem(tr("Start Client"), &m_NewSetup.StartClient));
|
Add(new cMenuEditBoolItem(tr("Start Client"), &m_NewSetup.StartClient));
|
||||||
Add(new cMenuEditIpItem (tr("Remote IP"), m_NewSetup.RemoteIp));
|
Add(new cMenuEditIpItem (tr("Remote IP"), m_NewSetup.RemoteIp));
|
||||||
Add(new cMenuEditIntItem (tr("Remote Port"), &m_NewSetup.RemotePort, 0, 65535));
|
Add(new cMenuEditIntItem (tr("Remote Port"), &m_NewSetup.RemotePort, 0, 65535));
|
||||||
|
Add(new cMenuEditIntItem (tr("Timeout (s)"), &m_NewSetup.Timeout, 1, 15));
|
||||||
Add(new cMenuEditBoolItem(tr("Filter Streaming"), &m_NewSetup.StreamFilters));
|
Add(new cMenuEditBoolItem(tr("Filter Streaming"), &m_NewSetup.StreamFilters));
|
||||||
Add(new cMenuEditIntItem (tr("Minimum Priority"), &m_NewSetup.MinPriority, -1, MAXPRIORITY));
|
Add(new cMenuEditIntItem (tr("Minimum Priority"), &m_NewSetup.MinPriority, -1, MAXPRIORITY));
|
||||||
Add(new cMenuEditIntItem (tr("Maximum Priority"), &m_NewSetup.MaxPriority, -1, MAXPRIORITY));
|
Add(new cMenuEditIntItem (tr("Maximum Priority"), &m_NewSetup.MaxPriority, -1, MAXPRIORITY));
|
||||||
@ -75,6 +78,7 @@ void cStreamdevClientMenuSetupPage::Store(void) {
|
|||||||
else
|
else
|
||||||
SetupStore("RemoteIp", m_NewSetup.RemoteIp);
|
SetupStore("RemoteIp", m_NewSetup.RemoteIp);
|
||||||
SetupStore("RemotePort", m_NewSetup.RemotePort);
|
SetupStore("RemotePort", m_NewSetup.RemotePort);
|
||||||
|
SetupStore("Timeout", m_NewSetup.Timeout);
|
||||||
SetupStore("StreamFilters", m_NewSetup.StreamFilters);
|
SetupStore("StreamFilters", m_NewSetup.StreamFilters);
|
||||||
SetupStore("HideMenuEntry", m_NewSetup.HideMenuEntry);
|
SetupStore("HideMenuEntry", m_NewSetup.HideMenuEntry);
|
||||||
SetupStore("MinPriority", m_NewSetup.MinPriority);
|
SetupStore("MinPriority", m_NewSetup.MinPriority);
|
||||||
|
@ -15,6 +15,7 @@ struct cStreamdevClientSetup {
|
|||||||
int StartClient;
|
int StartClient;
|
||||||
char RemoteIp[20];
|
char RemoteIp[20];
|
||||||
int RemotePort;
|
int RemotePort;
|
||||||
|
int Timeout;
|
||||||
int StreamFilters;
|
int StreamFilters;
|
||||||
int HideMenuEntry;
|
int HideMenuEntry;
|
||||||
int MinPriority;
|
int MinPriority;
|
||||||
|
185
client/socket.c
185
client/socket.c
@ -11,8 +11,11 @@
|
|||||||
|
|
||||||
#define MINLOGREPEAT 10 //don't log connect failures too often (seconds)
|
#define MINLOGREPEAT 10 //don't log connect failures too often (seconds)
|
||||||
|
|
||||||
|
// timeout for writing to command socket
|
||||||
|
#define WRITE_TIMEOUT_MS 200
|
||||||
|
#define QUIT_TIMEOUT_MS 500
|
||||||
|
|
||||||
#include "client/socket.h"
|
#include "client/socket.h"
|
||||||
#include "client/setup.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
cClientSocket ClientSocket;
|
cClientSocket ClientSocket;
|
||||||
@ -21,6 +24,7 @@ cClientSocket::cClientSocket(void)
|
|||||||
{
|
{
|
||||||
memset(m_DataSockets, 0, sizeof(cTBSocket*) * si_Count);
|
memset(m_DataSockets, 0, sizeof(cTBSocket*) * si_Count);
|
||||||
m_Prio = false;
|
m_Prio = false;
|
||||||
|
m_Abort = false;
|
||||||
m_LastSignalUpdate = 0;
|
m_LastSignalUpdate = 0;
|
||||||
m_LastSignalStrength = -1;
|
m_LastSignalStrength = -1;
|
||||||
m_LastSignalQuality = -1;
|
m_LastSignalQuality = -1;
|
||||||
@ -45,43 +49,53 @@ cTBSocket *cClientSocket::DataSocket(eSocketId Id) const {
|
|||||||
return m_DataSockets[Id];
|
return m_DataSockets[Id];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::Command(const std::string &Command, uint Expected, uint TimeoutMs)
|
bool cClientSocket::Command(const std::string &Command, uint Expected)
|
||||||
{
|
{
|
||||||
errno = 0;
|
uint code = 0;
|
||||||
|
std::string buffer;
|
||||||
|
if (Send(Command) && Receive(Command, &code, &buffer)) {
|
||||||
|
if (code == Expected)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
dsyslog("streamdev-client: Command '%s' rejected by %s:%d: %s",
|
||||||
|
Command.c_str(), RemoteIp().c_str(), RemotePort(), buffer.c_str());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool cClientSocket::Send(const std::string &Command)
|
||||||
|
{
|
||||||
std::string pkt = Command + "\015\012";
|
std::string pkt = Command + "\015\012";
|
||||||
Dprintf("OUT: |%s|\n", Command.c_str());
|
Dprintf("OUT: |%s|\n", Command.c_str());
|
||||||
|
|
||||||
cTimeMs starttime;
|
errno = 0;
|
||||||
if (!TimedWrite(pkt.c_str(), pkt.size(), TimeoutMs)) {
|
if (!TimedWrite(pkt.c_str(), pkt.size(), WRITE_TIMEOUT_MS)) {
|
||||||
esyslog("Streamdev: Lost connection to %s:%d: %s", RemoteIp().c_str(), RemotePort(),
|
esyslog("ERROR: streamdev-client: Failed sending command '%s' to %s:%d: %s",
|
||||||
strerror(errno));
|
Command.c_str(), RemoteIp().c_str(), RemotePort(), strerror(errno));
|
||||||
Close();
|
Close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t elapsed = starttime.Elapsed();
|
|
||||||
if (Expected != 0) { // XXX+ What if elapsed > TimeoutMs?
|
|
||||||
TimeoutMs -= elapsed;
|
|
||||||
return Expect(Expected, NULL, TimeoutMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::Expect(uint Expected, std::string *Result, uint TimeoutMs) {
|
#define TIMEOUT_MS 1000
|
||||||
char *endptr;
|
bool cClientSocket::Receive(const std::string &Command, uint *Code, std::string *Result, uint TimeoutMs) {
|
||||||
int bufcount;
|
int bufcount;
|
||||||
bool res;
|
do
|
||||||
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
bufcount = ReadUntil(m_Buffer, sizeof(m_Buffer) - 1, "\012", TimeoutMs < TIMEOUT_MS ? TimeoutMs : TIMEOUT_MS);
|
||||||
if ((bufcount = ReadUntil(m_Buffer, sizeof(m_Buffer) - 1, "\012", TimeoutMs)) == -1) {
|
if (bufcount == -1) {
|
||||||
esyslog("Streamdev: Lost connection to %s:%d: %s", RemoteIp().c_str(), RemotePort(),
|
if (m_Abort)
|
||||||
strerror(errno));
|
return false;
|
||||||
Close();
|
if (errno != ETIMEDOUT || TimeoutMs <= TIMEOUT_MS) {
|
||||||
return false;
|
esyslog("ERROR: streamdev-client: Failed reading reply to '%s' from %s:%d: %s",
|
||||||
}
|
Command.c_str(), RemoteIp().c_str(), RemotePort(), strerror(errno));
|
||||||
|
Close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TimeoutMs -= TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
} while (bufcount == -1);
|
||||||
if (m_Buffer[bufcount - 1] == '\015')
|
if (m_Buffer[bufcount - 1] == '\015')
|
||||||
--bufcount;
|
--bufcount;
|
||||||
m_Buffer[bufcount] = '\0';
|
m_Buffer[bufcount] = '\0';
|
||||||
@ -89,9 +103,9 @@ bool cClientSocket::Expect(uint Expected, std::string *Result, uint TimeoutMs) {
|
|||||||
|
|
||||||
if (Result != NULL)
|
if (Result != NULL)
|
||||||
*Result = m_Buffer;
|
*Result = m_Buffer;
|
||||||
|
if (Code != NULL)
|
||||||
res = strtoul(m_Buffer, &endptr, 10) == Expected;
|
*Code = strtoul(m_Buffer, NULL, 10);
|
||||||
return res;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::CheckConnection(void) {
|
bool cClientSocket::CheckConnection(void) {
|
||||||
@ -115,10 +129,10 @@ bool cClientSocket::CheckConnection(void) {
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Connect(StreamdevClientSetup.RemoteIp, StreamdevClientSetup.RemotePort)){
|
if (!Connect(StreamdevClientSetup.RemoteIp, StreamdevClientSetup.RemotePort, StreamdevClientSetup.Timeout * 1000)){
|
||||||
static time_t lastTime = 0;
|
static time_t lastTime = 0;
|
||||||
if (time(NULL) - lastTime > MINLOGREPEAT) {
|
if (time(NULL) - lastTime > MINLOGREPEAT) {
|
||||||
esyslog("ERROR: Streamdev: Couldn't connect to %s:%d: %s",
|
esyslog("ERROR: streamdev-client: Couldn't connect to %s:%d: %s",
|
||||||
(const char*)StreamdevClientSetup.RemoteIp,
|
(const char*)StreamdevClientSetup.RemoteIp,
|
||||||
StreamdevClientSetup.RemotePort, strerror(errno));
|
StreamdevClientSetup.RemotePort, strerror(errno));
|
||||||
lastTime = time(NULL);
|
lastTime = time(NULL);
|
||||||
@ -126,18 +140,20 @@ bool cClientSocket::CheckConnection(void) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Expect(220)) {
|
uint code = 0;
|
||||||
if (errno == 0)
|
std::string buffer;
|
||||||
esyslog("ERROR: Streamdev: Didn't receive greeting from %s:%d",
|
if (!Receive("<connect>", &code, &buffer)) {
|
||||||
RemoteIp().c_str(), RemotePort());
|
Close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (code != 220) {
|
||||||
|
esyslog("ERROR: streamdev-client: Didn't receive greeting from %s:%d: %s",
|
||||||
|
RemoteIp().c_str(), RemotePort(), buffer.c_str());
|
||||||
Close();
|
Close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Command("CAPS TSPIDS", 220)) {
|
if (!Command("CAPS TSPIDS", 220)) {
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't negotiate capabilities on %s:%d",
|
|
||||||
RemoteIp().c_str(), RemotePort());
|
|
||||||
Close();
|
Close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -152,7 +168,7 @@ bool cClientSocket::CheckConnection(void) {
|
|||||||
m_Prio = true;
|
m_Prio = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
isyslog("Streamdev: Connected to server %s:%d using capabilities TSPIDS%s%s",
|
isyslog("streamdev-client: Connected to server %s:%d using capabilities TSPIDS%s%s",
|
||||||
RemoteIp().c_str(), RemotePort(), Filters, Prio);
|
RemoteIp().c_str(), RemotePort(), Filters, Prio);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -164,14 +180,16 @@ bool cClientSocket::ProvidesChannel(const cChannel *Channel, int Priority) {
|
|||||||
|
|
||||||
std::string command = (std::string)"PROV " + (const char*)itoa(Priority) + " "
|
std::string command = (std::string)"PROV " + (const char*)itoa(Priority) + " "
|
||||||
+ (const char*)Channel->GetChannelID().ToString();
|
+ (const char*)Channel->GetChannelID().ToString();
|
||||||
if (!Command(command))
|
if (!Send(command))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
uint code;
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
if (!Expect(220, &buffer)) {
|
if (!Receive(command, &code, &buffer))
|
||||||
if (buffer.substr(0, 3) != "560" && errno == 0)
|
return false;
|
||||||
esyslog("ERROR: Streamdev: Couldn't check if %s:%d provides channel %s",
|
if (code != 220 && code != 560) {
|
||||||
RemoteIp().c_str(), RemotePort(), Channel->Name());
|
esyslog("streamdev-client: Unexpected reply to '%s' from %s:%d: %s",
|
||||||
|
command.c_str(), RemoteIp().c_str(), RemotePort(), buffer.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -186,7 +204,7 @@ bool cClientSocket::CreateDataConnection(eSocketId Id) {
|
|||||||
DELETENULL(m_DataSockets[Id]);
|
DELETENULL(m_DataSockets[Id]);
|
||||||
|
|
||||||
if (!listen.Listen(LocalIp(), 0, 1)) {
|
if (!listen.Listen(LocalIp(), 0, 1)) {
|
||||||
esyslog("ERROR: Streamdev: Couldn't create data connection: %s",
|
esyslog("ERROR: streamdev-client: Couldn't create data connection: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -201,13 +219,8 @@ bool cClientSocket::CreateDataConnection(eSocketId Id) {
|
|||||||
|
|
||||||
CMD_LOCK;
|
CMD_LOCK;
|
||||||
|
|
||||||
if (!Command(command, 220)) {
|
if (!Command(command, 220))
|
||||||
Dprintf("error: %m\n");
|
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't establish data connection to %s:%d",
|
|
||||||
RemoteIp().c_str(), RemotePort());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/* The server SHOULD do the following:
|
/* The server SHOULD do the following:
|
||||||
* - get PORT command
|
* - get PORT command
|
||||||
@ -217,7 +230,7 @@ bool cClientSocket::CreateDataConnection(eSocketId Id) {
|
|||||||
|
|
||||||
m_DataSockets[Id] = new cTBSocket;
|
m_DataSockets[Id] = new cTBSocket;
|
||||||
if (!m_DataSockets[Id]->Accept(listen)) {
|
if (!m_DataSockets[Id]->Accept(listen)) {
|
||||||
esyslog("ERROR: Streamdev: Couldn't establish data connection to %s:%d%s%s",
|
esyslog("ERROR: streamdev-client: Couldn't establish data connection to %s:%d%s%s",
|
||||||
RemoteIp().c_str(), RemotePort(), errno == 0 ? "" : ": ",
|
RemoteIp().c_str(), RemotePort(), errno == 0 ? "" : ": ",
|
||||||
errno == 0 ? "" : strerror(errno));
|
errno == 0 ? "" : strerror(errno));
|
||||||
DELETENULL(m_DataSockets[Id]);
|
DELETENULL(m_DataSockets[Id]);
|
||||||
@ -228,18 +241,12 @@ bool cClientSocket::CreateDataConnection(eSocketId Id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::CloseDataConnection(eSocketId Id) {
|
bool cClientSocket::CloseDataConnection(eSocketId Id) {
|
||||||
//if (!CheckConnection()) return false;
|
|
||||||
|
|
||||||
CMD_LOCK;
|
CMD_LOCK;
|
||||||
|
|
||||||
if(Id == siLive || Id == siLiveFilter)
|
if(Id == siLive || Id == siLiveFilter)
|
||||||
if (m_DataSockets[Id] != NULL) {
|
if (m_DataSockets[Id] != NULL) {
|
||||||
std::string command = (std::string)"ABRT " + (const char*)itoa(Id);
|
std::string command = (std::string)"ABRT " + (const char*)itoa(Id);
|
||||||
if (!Command(command, 220)) {
|
Command(command, 220);
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't cleanly close data connection");
|
|
||||||
//return false;
|
|
||||||
}
|
|
||||||
DELETENULL(m_DataSockets[Id]);
|
DELETENULL(m_DataSockets[Id]);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -252,12 +259,8 @@ bool cClientSocket::SetChannelDevice(const cChannel *Channel) {
|
|||||||
|
|
||||||
std::string command = (std::string)"TUNE "
|
std::string command = (std::string)"TUNE "
|
||||||
+ (const char*)Channel->GetChannelID().ToString();
|
+ (const char*)Channel->GetChannelID().ToString();
|
||||||
if (!Command(command, 220, 10000)) {
|
if (!Command(command, 220))
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't tune %s:%d to channel %s",
|
|
||||||
RemoteIp().c_str(), RemotePort(), Channel->Name());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
m_LastSignalUpdate = 0;
|
m_LastSignalUpdate = 0;
|
||||||
return true;
|
return true;
|
||||||
@ -269,13 +272,7 @@ bool cClientSocket::SetPriority(int Priority) {
|
|||||||
CMD_LOCK;
|
CMD_LOCK;
|
||||||
|
|
||||||
std::string command = (std::string)"PRIO " + (const char*)itoa(Priority);
|
std::string command = (std::string)"PRIO " + (const char*)itoa(Priority);
|
||||||
if (!Command(command, 220)) {
|
return Command(command, 220);
|
||||||
if (errno == 0)
|
|
||||||
esyslog("Streamdev: Failed to update priority on %s:%d", RemoteIp().c_str(),
|
|
||||||
RemotePort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::GetSignal(int *SignalStrength, int *SignalQuality) {
|
bool cClientSocket::GetSignal(int *SignalStrength, int *SignalQuality) {
|
||||||
@ -284,8 +281,10 @@ bool cClientSocket::GetSignal(int *SignalStrength, int *SignalQuality) {
|
|||||||
CMD_LOCK;
|
CMD_LOCK;
|
||||||
|
|
||||||
if (m_LastSignalUpdate != time(NULL)) {
|
if (m_LastSignalUpdate != time(NULL)) {
|
||||||
|
uint code = 0;
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
if (!Command("SGNL") || !Expect(220, &buffer)
|
std::string command("SGNL");
|
||||||
|
if (!Send(command) || !Receive(command, &code, &buffer) || code != 220
|
||||||
|| sscanf(buffer.c_str(), "%*d %*d %d:%d", &m_LastSignalStrength, &m_LastSignalQuality) != 2) {
|
|| sscanf(buffer.c_str(), "%*d %*d %d:%d", &m_LastSignalStrength, &m_LastSignalQuality) != 2) {
|
||||||
m_LastSignalStrength = -1;
|
m_LastSignalStrength = -1;
|
||||||
m_LastSignalQuality = -1;
|
m_LastSignalQuality = -1;
|
||||||
@ -305,13 +304,7 @@ bool cClientSocket::SetPid(int Pid, bool On) {
|
|||||||
CMD_LOCK;
|
CMD_LOCK;
|
||||||
|
|
||||||
std::string command = (std::string)(On ? "ADDP " : "DELP ") + (const char*)itoa(Pid);
|
std::string command = (std::string)(On ? "ADDP " : "DELP ") + (const char*)itoa(Pid);
|
||||||
if (!Command(command, 220)) {
|
return Command(command, 220);
|
||||||
if (errno == 0)
|
|
||||||
esyslog("Streamdev: Pid %d not available from %s:%d", Pid, RemoteIp().c_str(),
|
|
||||||
RemotePort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On) {
|
bool cClientSocket::SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On) {
|
||||||
@ -321,13 +314,7 @@ bool cClientSocket::SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On) {
|
|||||||
|
|
||||||
std::string command = (std::string)(On ? "ADDF " : "DELF ") + (const char*)itoa(Pid)
|
std::string command = (std::string)(On ? "ADDF " : "DELF ") + (const char*)itoa(Pid)
|
||||||
+ " " + (const char*)itoa(Tid) + " " + (const char*)itoa(Mask);
|
+ " " + (const char*)itoa(Tid) + " " + (const char*)itoa(Mask);
|
||||||
if (!Command(command, 220)) {
|
return Command(command, 220);
|
||||||
if (errno == 0)
|
|
||||||
esyslog("Streamdev: Filter %hu, %hhu, %hhu not available from %s:%d",
|
|
||||||
Pid, Tid, Mask, RemoteIp().c_str(), RemotePort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::CloseDvr(void) {
|
bool cClientSocket::CloseDvr(void) {
|
||||||
@ -337,27 +324,20 @@ bool cClientSocket::CloseDvr(void) {
|
|||||||
|
|
||||||
if (m_DataSockets[siLive] != NULL) {
|
if (m_DataSockets[siLive] != NULL) {
|
||||||
std::string command = (std::string)"ABRT " + (const char*)itoa(siLive);
|
std::string command = (std::string)"ABRT " + (const char*)itoa(siLive);
|
||||||
if (!Command(command, 220)) {
|
if (!Command(command, 220))
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't cleanly close data connection");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
DELETENULL(m_DataSockets[siLive]);
|
DELETENULL(m_DataSockets[siLive]);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::Quit(void) {
|
bool cClientSocket::Quit(void) {
|
||||||
bool res;
|
m_Abort = true;
|
||||||
|
if (!IsOpen()) return false;
|
||||||
|
|
||||||
if (!CheckConnection()) return false;
|
CMD_LOCK;
|
||||||
|
std::string command("QUIT");
|
||||||
if (!(res = Command("QUIT", 221))) {
|
bool res = Send(command) && Receive(command, NULL, NULL, QUIT_TIMEOUT_MS);
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't quit command connection to %s:%d",
|
|
||||||
RemoteIp().c_str(), RemotePort());
|
|
||||||
}
|
|
||||||
Close();
|
Close();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -367,10 +347,5 @@ bool cClientSocket::SuspendServer(void) {
|
|||||||
|
|
||||||
CMD_LOCK;
|
CMD_LOCK;
|
||||||
|
|
||||||
if (!Command("SUSP", 220)) {
|
return Command("SUSP", 220);
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't suspend server");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <tools/socket.h>
|
#include <tools/socket.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "client/setup.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -21,22 +22,23 @@ private:
|
|||||||
cMutex m_Mutex;
|
cMutex m_Mutex;
|
||||||
char m_Buffer[BUFSIZ + 1]; // various uses
|
char m_Buffer[BUFSIZ + 1]; // various uses
|
||||||
bool m_Prio; // server supports command PRIO
|
bool m_Prio; // server supports command PRIO
|
||||||
|
bool m_Abort; // quit command pending
|
||||||
|
|
||||||
time_t m_LastSignalUpdate;
|
time_t m_LastSignalUpdate;
|
||||||
int m_LastSignalStrength;
|
int m_LastSignalStrength;
|
||||||
int m_LastSignalQuality;
|
int m_LastSignalQuality;
|
||||||
protected:
|
protected:
|
||||||
/* Send Command, and return true if the command results in Expected.
|
/* Send Command, and return true if the command results in Expected.
|
||||||
Returns false on failure, setting errno appropriately if it has been
|
Returns false on failure. */
|
||||||
a system failure. If Expected is zero, returns immediately after
|
bool Command(const std::string &Command, uint Expected);
|
||||||
sending the command. */
|
|
||||||
bool Command(const std::string &Command, uint Expected = 0, uint TimeoutMs = 1500);
|
|
||||||
|
|
||||||
/* Fetch results from an ongoing Command called with Expected == 0. Returns
|
/* Send the given command. Returns false on failure. */
|
||||||
true if the response has the code Expected, returning an internal buffer
|
bool Send(const std::string &Command);
|
||||||
in the array pointer pointed to by Result. Returns false on failure,
|
|
||||||
setting errno appropriately if it has been a system failure. */
|
/* Fetch results from an ongoing Command. The status code and the
|
||||||
bool Expect(uint Expected, std::string *Result = NULL, uint TimeoutMs = 1500);
|
buffer holding the server's response are stored in Code and Result
|
||||||
|
if non-NULL. Returns false on failure. */
|
||||||
|
bool Receive(const std::string &Command, uint *Code = NULL, std::string *Result = NULL, uint TimeoutMs = StreamdevClientSetup.Timeout * 1000);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cClientSocket(void);
|
cClientSocket(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user