From 3da6ae734e6b3caf6a02984688b8405db060df57 Mon Sep 17 00:00:00 2001 From: Frank Schmirler Date: Sat, 3 Mar 2012 23:24:30 +0100 Subject: [PATCH] Timout for network operations now configurable in streamdev-client setup --- HISTORY | 1 + README | 3 + client/po/de_DE.po | 5 +- client/po/es_ES.po | 5 +- client/po/fi_FI.po | 5 +- client/po/fr_FR.po | 5 +- client/po/it_IT.po | 5 +- client/po/lt_LT.po | 5 +- client/po/ru_RU.po | 5 +- client/po/sk_SK.po | 5 +- client/setup.c | 4 + client/setup.h | 1 + client/socket.c | 185 ++++++++++++++++++++------------------------- client/socket.h | 20 ++--- 14 files changed, 132 insertions(+), 122 deletions(-) diff --git a/HISTORY b/HISTORY index 54d215c..c02329b 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,7 @@ VDR Plugin 'streamdev' Revision History --------------------------------------- +- Timout for network operations now configurable in streamdev-client setup - Added timeout to Connect() - Report the server-side HTTP status "503 Service unavailable" instead of the client-side error "409 Conflict" when a channel is unavailable diff --git a/README b/README index 84bba75..15638ba 100644 --- a/README +++ b/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 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 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. diff --git a/client/po/de_DE.po b/client/po/de_DE.po index 401a2f8..5635b96 100644 --- a/client/po/de_DE.po +++ b/client/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: streamdev 0.5.0\n" "Report-Msgid-Bugs-To: \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" "Last-Translator: Frank Schmirler \n" "Language-Team: German \n" @@ -40,6 +40,9 @@ msgstr "IP der Gegenseite" msgid "Remote Port" msgstr "Port der Gegenseite" +msgid "Timeout (s)" +msgstr "Timeout (s)" + msgid "Filter Streaming" msgstr "Filter-Daten streamen" diff --git a/client/po/es_ES.po b/client/po/es_ES.po index 0917c72..89c0503 100644 --- a/client/po/es_ES.po +++ b/client/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: streamdev 0.5.0\n" "Report-Msgid-Bugs-To: \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" "Last-Translator: Javier Bradineras \n" "Language-Team: Spanish \n" @@ -40,6 +40,9 @@ msgstr "Indicar IP del Servidor" msgid "Remote Port" msgstr "Indicar puerto remoto del Servidor" +msgid "Timeout (s)" +msgstr "" + msgid "Filter Streaming" msgstr "Filtrar transmisión" diff --git a/client/po/fi_FI.po b/client/po/fi_FI.po index a554164..ca1dc1c 100644 --- a/client/po/fi_FI.po +++ b/client/po/fi_FI.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: streamdev 0.5.0\n" "Report-Msgid-Bugs-To: \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" "Last-Translator: Rolf Ahrenberg\n" "Language-Team: Finnish \n" @@ -40,6 +40,9 @@ msgstr "Etäkoneen IP-osoite" msgid "Remote Port" msgstr "Etäkoneen portti" +msgid "Timeout (s)" +msgstr "" + msgid "Filter Streaming" msgstr "Suodatetun tiedon suoratoisto" diff --git a/client/po/fr_FR.po b/client/po/fr_FR.po index 392fb86..1a01535 100644 --- a/client/po/fr_FR.po +++ b/client/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: streamdev 0.5.0\n" "Report-Msgid-Bugs-To: \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" "Last-Translator: micky979 \n" "Language-Team: French \n" @@ -40,6 +40,9 @@ msgstr "Adresse IP du serveur" msgid "Remote Port" msgstr "Port du serveur" +msgid "Timeout (s)" +msgstr "" + msgid "Filter Streaming" msgstr "Filtre streaming" diff --git a/client/po/it_IT.po b/client/po/it_IT.po index ec98940..355238c 100644 --- a/client/po/it_IT.po +++ b/client/po/it_IT.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: streamdev 0.5.0\n" "Report-Msgid-Bugs-To: \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" "Last-Translator: Diego Pierotto \n" "Language-Team: Italian \n" @@ -42,6 +42,9 @@ msgstr "Indirizzo IP del Server" msgid "Remote Port" msgstr "Porta Server Remoto" +msgid "Timeout (s)" +msgstr "" + msgid "Filter Streaming" msgstr "Filtra trasmissione" diff --git a/client/po/lt_LT.po b/client/po/lt_LT.po index 71e6641..02929f8 100644 --- a/client/po/lt_LT.po +++ b/client/po/lt_LT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: streamdev 0.5.0\n" "Report-Msgid-Bugs-To: \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" "Last-Translator: Valdemaras Pipiras \n" "Language-Team: Lithuanian \n" @@ -40,6 +40,9 @@ msgstr "Nuotolinis IP adresas" msgid "Remote Port" msgstr "Nuotolinis portas" +msgid "Timeout (s)" +msgstr "" + msgid "Filter Streaming" msgstr "Filtruoti transliavimÄ…" diff --git a/client/po/ru_RU.po b/client/po/ru_RU.po index 4fbdafb..14d30ae 100644 --- a/client/po/ru_RU.po +++ b/client/po/ru_RU.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: streamdev 0.5.0\n" "Report-Msgid-Bugs-To: \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" "Last-Translator: Oleg Roitburd \n" "Language-Team: Russian \n" @@ -40,6 +40,9 @@ msgstr " msgid "Remote Port" msgstr "ÃÔÐÛÕÝÝëÙ ßÞàâ" +msgid "Timeout (s)" +msgstr "" + msgid "Filter Streaming" msgstr "ÄØÛìâà ßÞâÞÚÐ" diff --git a/client/po/sk_SK.po b/client/po/sk_SK.po index 2bb8a25..2deffc1 100644 --- a/client/po/sk_SK.po +++ b/client/po/sk_SK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: streamdev_SK\n" "Report-Msgid-Bugs-To: \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" "Last-Translator: Milan Hrala \n" "Language-Team: Slovak \n" @@ -42,6 +42,9 @@ msgstr "Vzdialen msgid "Remote Port" msgstr "Vzdialený port" +msgid "Timeout (s)" +msgstr "" + msgid "Filter Streaming" msgstr "filtrova» prúdy" diff --git a/client/setup.c b/client/setup.c index 10e705e..9d4452e 100644 --- a/client/setup.c +++ b/client/setup.c @@ -12,6 +12,7 @@ cStreamdevClientSetup StreamdevClientSetup; cStreamdevClientSetup::cStreamdevClientSetup(void) { StartClient = false; RemotePort = 2004; + Timeout = 2; StreamFilters = false; HideMenuEntry = false; MinPriority = -1; @@ -31,6 +32,7 @@ bool cStreamdevClientSetup::SetupParse(const char *Name, const char *Value) { strcpy(RemoteIp, 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, "HideMenuEntry") == 0) HideMenuEntry = 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 cMenuEditIpItem (tr("Remote IP"), m_NewSetup.RemoteIp)); 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 cMenuEditIntItem (tr("Minimum Priority"), &m_NewSetup.MinPriority, -1, MAXPRIORITY)); Add(new cMenuEditIntItem (tr("Maximum Priority"), &m_NewSetup.MaxPriority, -1, MAXPRIORITY)); @@ -75,6 +78,7 @@ void cStreamdevClientMenuSetupPage::Store(void) { else SetupStore("RemoteIp", m_NewSetup.RemoteIp); SetupStore("RemotePort", m_NewSetup.RemotePort); + SetupStore("Timeout", m_NewSetup.Timeout); SetupStore("StreamFilters", m_NewSetup.StreamFilters); SetupStore("HideMenuEntry", m_NewSetup.HideMenuEntry); SetupStore("MinPriority", m_NewSetup.MinPriority); diff --git a/client/setup.h b/client/setup.h index ba2b9d0..591bbd2 100644 --- a/client/setup.h +++ b/client/setup.h @@ -15,6 +15,7 @@ struct cStreamdevClientSetup { int StartClient; char RemoteIp[20]; int RemotePort; + int Timeout; int StreamFilters; int HideMenuEntry; int MinPriority; diff --git a/client/socket.c b/client/socket.c index 2d5103b..727ffb6 100644 --- a/client/socket.c +++ b/client/socket.c @@ -11,8 +11,11 @@ #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/setup.h" #include "common.h" cClientSocket ClientSocket; @@ -21,6 +24,7 @@ cClientSocket::cClientSocket(void) { memset(m_DataSockets, 0, sizeof(cTBSocket*) * si_Count); m_Prio = false; + m_Abort = false; m_LastSignalUpdate = 0; m_LastSignalStrength = -1; m_LastSignalQuality = -1; @@ -45,43 +49,53 @@ cTBSocket *cClientSocket::DataSocket(eSocketId Id) const { 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"; Dprintf("OUT: |%s|\n", Command.c_str()); - cTimeMs starttime; - if (!TimedWrite(pkt.c_str(), pkt.size(), TimeoutMs)) { - esyslog("Streamdev: Lost connection to %s:%d: %s", RemoteIp().c_str(), RemotePort(), - strerror(errno)); + errno = 0; + if (!TimedWrite(pkt.c_str(), pkt.size(), WRITE_TIMEOUT_MS)) { + esyslog("ERROR: streamdev-client: Failed sending command '%s' to %s:%d: %s", + Command.c_str(), RemoteIp().c_str(), RemotePort(), strerror(errno)); Close(); return false; } - - uint64_t elapsed = starttime.Elapsed(); - if (Expected != 0) { // XXX+ What if elapsed > TimeoutMs? - TimeoutMs -= elapsed; - return Expect(Expected, NULL, TimeoutMs); - } - return true; } -bool cClientSocket::Expect(uint Expected, std::string *Result, uint TimeoutMs) { - char *endptr; +#define TIMEOUT_MS 1000 +bool cClientSocket::Receive(const std::string &Command, uint *Code, std::string *Result, uint TimeoutMs) { int bufcount; - bool res; - - errno = 0; - - if ((bufcount = ReadUntil(m_Buffer, sizeof(m_Buffer) - 1, "\012", TimeoutMs)) == -1) { - esyslog("Streamdev: Lost connection to %s:%d: %s", RemoteIp().c_str(), RemotePort(), - strerror(errno)); - Close(); - return false; - } + do + { + errno = 0; + bufcount = ReadUntil(m_Buffer, sizeof(m_Buffer) - 1, "\012", TimeoutMs < TIMEOUT_MS ? TimeoutMs : TIMEOUT_MS); + if (bufcount == -1) { + if (m_Abort) + return false; + if (errno != ETIMEDOUT || TimeoutMs <= TIMEOUT_MS) { + 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') --bufcount; m_Buffer[bufcount] = '\0'; @@ -89,9 +103,9 @@ bool cClientSocket::Expect(uint Expected, std::string *Result, uint TimeoutMs) { if (Result != NULL) *Result = m_Buffer; - - res = strtoul(m_Buffer, &endptr, 10) == Expected; - return res; + if (Code != NULL) + *Code = strtoul(m_Buffer, NULL, 10); + return true; } bool cClientSocket::CheckConnection(void) { @@ -115,10 +129,10 @@ bool cClientSocket::CheckConnection(void) { Close(); } - if (!Connect(StreamdevClientSetup.RemoteIp, StreamdevClientSetup.RemotePort)){ + if (!Connect(StreamdevClientSetup.RemoteIp, StreamdevClientSetup.RemotePort, StreamdevClientSetup.Timeout * 1000)){ static time_t lastTime = 0; 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, StreamdevClientSetup.RemotePort, strerror(errno)); lastTime = time(NULL); @@ -126,18 +140,20 @@ bool cClientSocket::CheckConnection(void) { return false; } - if (!Expect(220)) { - if (errno == 0) - esyslog("ERROR: Streamdev: Didn't receive greeting from %s:%d", - RemoteIp().c_str(), RemotePort()); + uint code = 0; + std::string buffer; + if (!Receive("", &code, &buffer)) { + 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(); return false; } if (!Command("CAPS TSPIDS", 220)) { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't negotiate capabilities on %s:%d", - RemoteIp().c_str(), RemotePort()); Close(); return false; } @@ -152,7 +168,7 @@ bool cClientSocket::CheckConnection(void) { 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); return true; } @@ -164,14 +180,16 @@ bool cClientSocket::ProvidesChannel(const cChannel *Channel, int Priority) { std::string command = (std::string)"PROV " + (const char*)itoa(Priority) + " " + (const char*)Channel->GetChannelID().ToString(); - if (!Command(command)) + if (!Send(command)) return false; + uint code; std::string buffer; - if (!Expect(220, &buffer)) { - if (buffer.substr(0, 3) != "560" && errno == 0) - esyslog("ERROR: Streamdev: Couldn't check if %s:%d provides channel %s", - RemoteIp().c_str(), RemotePort(), Channel->Name()); + if (!Receive(command, &code, &buffer)) + return false; + if (code != 220 && code != 560) { + esyslog("streamdev-client: Unexpected reply to '%s' from %s:%d: %s", + command.c_str(), RemoteIp().c_str(), RemotePort(), buffer.c_str()); return false; } return true; @@ -186,7 +204,7 @@ bool cClientSocket::CreateDataConnection(eSocketId Id) { DELETENULL(m_DataSockets[Id]); 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)); return false; } @@ -201,13 +219,8 @@ bool cClientSocket::CreateDataConnection(eSocketId Id) { CMD_LOCK; - 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()); + if (!Command(command, 220)) return false; - } /* The server SHOULD do the following: * - get PORT command @@ -217,7 +230,7 @@ bool cClientSocket::CreateDataConnection(eSocketId Id) { m_DataSockets[Id] = new cTBSocket; 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 ? "" : ": ", errno == 0 ? "" : strerror(errno)); DELETENULL(m_DataSockets[Id]); @@ -228,18 +241,12 @@ bool cClientSocket::CreateDataConnection(eSocketId Id) { } bool cClientSocket::CloseDataConnection(eSocketId Id) { - //if (!CheckConnection()) return false; - CMD_LOCK; if(Id == siLive || Id == siLiveFilter) if (m_DataSockets[Id] != NULL) { std::string command = (std::string)"ABRT " + (const char*)itoa(Id); - if (!Command(command, 220)) { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't cleanly close data connection"); - //return false; - } + Command(command, 220); DELETENULL(m_DataSockets[Id]); } return true; @@ -252,12 +259,8 @@ bool cClientSocket::SetChannelDevice(const cChannel *Channel) { std::string command = (std::string)"TUNE " + (const char*)Channel->GetChannelID().ToString(); - if (!Command(command, 220, 10000)) { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't tune %s:%d to channel %s", - RemoteIp().c_str(), RemotePort(), Channel->Name()); + if (!Command(command, 220)) return false; - } m_LastSignalUpdate = 0; return true; @@ -269,13 +272,7 @@ bool cClientSocket::SetPriority(int Priority) { CMD_LOCK; std::string command = (std::string)"PRIO " + (const char*)itoa(Priority); - if (!Command(command, 220)) { - if (errno == 0) - esyslog("Streamdev: Failed to update priority on %s:%d", RemoteIp().c_str(), - RemotePort()); - return false; - } - return true; + return Command(command, 220); } bool cClientSocket::GetSignal(int *SignalStrength, int *SignalQuality) { @@ -284,8 +281,10 @@ bool cClientSocket::GetSignal(int *SignalStrength, int *SignalQuality) { CMD_LOCK; if (m_LastSignalUpdate != time(NULL)) { + uint code = 0; 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) { m_LastSignalStrength = -1; m_LastSignalQuality = -1; @@ -305,13 +304,7 @@ bool cClientSocket::SetPid(int Pid, bool On) { CMD_LOCK; std::string command = (std::string)(On ? "ADDP " : "DELP ") + (const char*)itoa(Pid); - if (!Command(command, 220)) { - if (errno == 0) - esyslog("Streamdev: Pid %d not available from %s:%d", Pid, RemoteIp().c_str(), - RemotePort()); - return false; - } - return true; + return Command(command, 220); } 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) + " " + (const char*)itoa(Tid) + " " + (const char*)itoa(Mask); - if (!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; + return Command(command, 220); } bool cClientSocket::CloseDvr(void) { @@ -337,27 +324,20 @@ bool cClientSocket::CloseDvr(void) { if (m_DataSockets[siLive] != NULL) { std::string command = (std::string)"ABRT " + (const char*)itoa(siLive); - if (!Command(command, 220)) { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't cleanly close data connection"); + if (!Command(command, 220)) return false; - } - DELETENULL(m_DataSockets[siLive]); } return true; } bool cClientSocket::Quit(void) { - bool res; + m_Abort = true; + if (!IsOpen()) return false; - if (!CheckConnection()) return false; - - if (!(res = Command("QUIT", 221))) { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't quit command connection to %s:%d", - RemoteIp().c_str(), RemotePort()); - } + CMD_LOCK; + std::string command("QUIT"); + bool res = Send(command) && Receive(command, NULL, NULL, QUIT_TIMEOUT_MS); Close(); return res; } @@ -367,10 +347,5 @@ bool cClientSocket::SuspendServer(void) { CMD_LOCK; - if (!Command("SUSP", 220)) { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't suspend server"); - return false; - } - return true; + return Command("SUSP", 220); } diff --git a/client/socket.h b/client/socket.h index 42d7574..01d7a0f 100644 --- a/client/socket.h +++ b/client/socket.h @@ -8,6 +8,7 @@ #include #include "common.h" +#include "client/setup.h" #include @@ -21,22 +22,23 @@ private: cMutex m_Mutex; char m_Buffer[BUFSIZ + 1]; // various uses bool m_Prio; // server supports command PRIO + bool m_Abort; // quit command pending time_t m_LastSignalUpdate; int m_LastSignalStrength; int m_LastSignalQuality; protected: /* Send Command, and return true if the command results in Expected. - Returns false on failure, setting errno appropriately if it has been - a system failure. If Expected is zero, returns immediately after - sending the command. */ - bool Command(const std::string &Command, uint Expected = 0, uint TimeoutMs = 1500); + Returns false on failure. */ + bool Command(const std::string &Command, uint Expected); - /* Fetch results from an ongoing Command called with Expected == 0. Returns - true if the response has the code Expected, returning an internal buffer - in the array pointer pointed to by Result. Returns false on failure, - setting errno appropriately if it has been a system failure. */ - bool Expect(uint Expected, std::string *Result = NULL, uint TimeoutMs = 1500); + /* Send the given command. Returns false on failure. */ + bool Send(const std::string &Command); + + /* Fetch results from an ongoing Command. The status code and the + 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: cClientSocket(void);