Added support for X-SATIP-RTSP-Port header.

This commit is contained in:
Rolf Ahrenberg 2016-02-22 17:58:33 +02:00
parent 23e2b4d54d
commit 4c216d81c8
8 changed files with 118 additions and 25 deletions

View File

@ -13,6 +13,8 @@
#include <vdr/config.h>
#include <vdr/i18n.h>
#define SATIP_DEFAULT_RTSP_PORT 554
#define SATIP_MAX_DEVICES MAXDEVICES
#define SATIP_BUFFER_SIZE KILOBYTE(1024)

View File

@ -32,7 +32,7 @@ bool cSatipDiscover::Initialize(cSatipDiscoverServers *serversP)
if (instanceS) {
if (serversP) {
for (cSatipDiscoverServer *s = serversP->First(); s; s = serversP->Next(s))
instanceS->AddServer(s->IpAddress(), s->Model(), s->Description());
instanceS->AddServer(s->IpAddress(), s->IpPort(), s->Model(), s->Description());
}
else
instanceS->Activate();
@ -47,6 +47,18 @@ void cSatipDiscover::Destroy(void)
instanceS->Deactivate();
}
size_t cSatipDiscover::HeaderCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP)
{
cSatipDiscover *obj = reinterpret_cast<cSatipDiscover *>(dataP);
size_t len = sizeP * nmembP;
debug16("%s len=%zu", __PRETTY_FUNCTION__, len);
if (obj && (len > 0))
obj->headerBufferM.Add(ptrP, len);
return len;
}
size_t cSatipDiscover::DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP)
{
cSatipDiscover *obj = reinterpret_cast<cSatipDiscover *>(dataP);
@ -91,6 +103,7 @@ int cSatipDiscover::DebugCallback(CURL *handleP, curl_infotype typeP, char *data
cSatipDiscover::cSatipDiscover()
: cThread("SATIP discover"),
mutexM(),
headerBufferM(),
dataBufferM(),
msearchM(*this),
probeUrlListM(),
@ -176,7 +189,9 @@ void cSatipDiscover::Fetch(const char *urlP)
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_DEBUGFUNCTION, cSatipDiscover::DebugCallback);
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_DEBUGDATA, this);
// Set callback
// Set header and data callbacks
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipDiscover::HeaderCallback);
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipDiscover::DataCallback);
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
@ -199,7 +214,8 @@ void cSatipDiscover::Fetch(const char *urlP)
SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc);
SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_PRIMARY_IP, &addr);
if (rc == 200) {
ParseDeviceInfo(addr);
ParseDeviceInfo(addr, ParseRtspPort());
headerBufferM.Reset();
dataBufferM.Reset();
}
else
@ -207,9 +223,32 @@ void cSatipDiscover::Fetch(const char *urlP)
}
}
void cSatipDiscover::ParseDeviceInfo(const char *addrP)
int cSatipDiscover::ParseRtspPort(void)
{
debug1("%s (%s)", __PRETTY_FUNCTION__, addrP);
debug1("%s", __PRETTY_FUNCTION__);
char *s, *p = headerBufferM.Data();
char *r = strtok_r(p, "\r\n", &s);
int port = SATIP_DEFAULT_RTSP_PORT;
while (r) {
debug16("%s (%zu): %s", __PRETTY_FUNCTION__, headerBufferM.Size(), r);
r = skipspace(r);
if (strstr(r, "X-SATIP-RTSP-Port")) {
int tmp = -1;
if (sscanf(r, "X-SATIP-RTSP-Port:%11d", &tmp) == 1) {
port = tmp;
break;
}
}
r = strtok_r(NULL, "\r\n", &s);
}
return port;
}
void cSatipDiscover::ParseDeviceInfo(const char *addrP, const int portP)
{
debug1("%s (%s, %d)", __PRETTY_FUNCTION__, addrP, portP);
const char *desc = NULL, *model = NULL;
#ifdef USE_TINYXML
TiXmlDocument doc;
@ -232,12 +271,12 @@ void cSatipDiscover::ParseDeviceInfo(const char *addrP)
model = modelNode.text().as_string("DVBS2-1");
}
#endif
AddServer(addrP, model, desc);
AddServer(addrP, portP, model, desc);
}
void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char * descP)
void cSatipDiscover::AddServer(const char *addrP, const int portP, const char *modelP, const char * descP)
{
debug1("%s (%s, %s, %s)", __PRETTY_FUNCTION__, addrP, modelP, descP);
debug1("%s (%s, %d, %s, %s)", __PRETTY_FUNCTION__, addrP, portP, modelP, descP);
cMutexLock MutexLock(&mutexM);
if (SatipConfig.GetUseSingleModelServers() && modelP && !isempty(modelP)) {
int n = 0;
@ -246,7 +285,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char
while (r) {
r = skipspace(r);
cString desc = cString::sprintf("%s #%d", !isempty(descP) ? descP : "MyBrokenHardware", n++);
cSatipServer *tmp = new cSatipServer(addrP, r, desc);
cSatipServer *tmp = new cSatipServer(addrP, portP, r, desc);
if (!serversM.Update(tmp)) {
info("Adding server '%s|%s|%s' CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
serversM.Add(tmp);
@ -258,7 +297,7 @@ void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char
FREE_POINTER(p);
}
else {
cSatipServer *tmp = new cSatipServer(addrP, modelP, descP);
cSatipServer *tmp = new cSatipServer(addrP, portP, modelP, descP);
if (!serversM.Update(tmp)) {
info("Adding server '%s|%s|%s' CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none");
serversM.Add(tmp);
@ -352,6 +391,13 @@ cString cSatipDiscover::GetServerAddress(cSatipServer *serverP)
return serversM.GetAddress(serverP);
}
int cSatipDiscover::GetServerPort(cSatipServer *serverP)
{
debug16("%s", __PRETTY_FUNCTION__);
cMutexLock MutexLock(&mutexM);
return serversM.GetPort(serverP);
}
int cSatipDiscover::NumProvidedSystems(void)
{
debug16("%s", __PRETTY_FUNCTION__);

View File

@ -21,14 +21,16 @@
class cSatipDiscoverServer : public cListObject {
private:
int ipPortM;
cString ipAddressM;
cString descriptionM;
cString modelM;
public:
cSatipDiscoverServer(const char *ipAddressP, const char *modelP, const char *descriptionP)
cSatipDiscoverServer(const char *ipAddressP, const int ipPortP, const char *modelP, const char *descriptionP)
{
ipAddressM = ipAddressP; modelM = modelP; descriptionM = descriptionP;
ipAddressM = ipAddressP; ipPortM = ipPortP; modelM = modelP; descriptionM = descriptionP;
}
int IpPort(void) { return ipPortM; }
const char *IpAddress(void) { return *ipAddressM; }
const char *Model(void) { return *modelM; }
const char *Description(void) { return *descriptionM; }
@ -47,9 +49,11 @@ private:
eCleanupTimeoutMs = 124000 // in milliseoonds
};
static cSatipDiscover *instanceS;
static size_t HeaderCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP);
static size_t DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP);
static int DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP);
cMutex mutexM;
cSatipMemoryBuffer headerBufferM;
cSatipMemoryBuffer dataBufferM;
cSatipMsearch msearchM;
cStringList probeUrlListM;
@ -59,8 +63,9 @@ private:
cSatipServers serversM;
void Activate(void);
void Deactivate(void);
void ParseDeviceInfo(const char *addrP);
void AddServer(const char *addrP, const char *modelP, const char *descP);
int ParseRtspPort(void);
void ParseDeviceInfo(const char *addrP, const int portP);
void AddServer(const char *addrP, const int portP, const char *modelP, const char *descP);
void Fetch(const char *urlP);
// constructor
cSatipDiscover();
@ -88,6 +93,7 @@ public:
bool IsServerQuirk(cSatipServer *serverP, int quirkP);
bool HasServerCI(cSatipServer *serverP);
cString GetServerAddress(cSatipServer *serverP);
int GetServerPort(cSatipServer *serverP);
cString GetServerList(void);
int NumProvidedSystems(void);

14
satip.c
View File

@ -84,7 +84,7 @@ const char *cPluginSatip::CommandLineHelp(void)
// Return a string that describes all known command line options.
return " -d <num>, --devices=<number> set number of devices to be created\n"
" -t <mode>, --trace=<mode> set the tracing mode\n"
" -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>|<model2>|<desc2>\n"
" -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2:port>|<model2>|<desc2>\n"
" define hard-coded SAT>IP server(s)\n"
" -D, --detach set the detached mode on\n"
" -S, --single set the single model server mode on\n"
@ -233,6 +233,7 @@ void cPluginSatip::ParseServer(const char *paramP)
r = skipspace(r);
debug3("%s server[%d]=%s", __PRETTY_FUNCTION__, n, r);
cString serverAddr, serverModel, serverDescription;
int serverPort = SATIP_DEFAULT_RTSP_PORT;
int n2 = 0;
char *s2, *p2 = r;
char *r2 = strtok_r(p2, "|", &s2);
@ -240,7 +241,14 @@ void cPluginSatip::ParseServer(const char *paramP)
debug3("%s param[%d]=%s", __PRETTY_FUNCTION__, n2, r2);
switch (n2++) {
case 0:
{
serverAddr = r2;
char *r3 = strchr(r2, ':');
if (r3) {
serverPort = strtol(r3 + 1, NULL, 0);
serverAddr = serverAddr.Truncate(r3 - r2);
}
}
break;
case 1:
serverModel = r2;
@ -254,10 +262,10 @@ void cPluginSatip::ParseServer(const char *paramP)
r2 = strtok_r(NULL, "|", &s2);
}
if (*serverAddr && *serverModel && *serverDescription) {
debug1("%s ipaddr=%s model=%s desc=%s", __PRETTY_FUNCTION__, *serverAddr, *serverModel, *serverDescription);
debug1("%s ipaddr=%s port=%d model=%s desc=%s", __PRETTY_FUNCTION__, *serverAddr, serverPort, *serverModel, *serverDescription);
if (!serversM)
serversM = new cSatipDiscoverServers();
serversM->Add(new cSatipDiscoverServer(*serverAddr, *serverModel, *serverDescription));
serversM->Add(new cSatipDiscoverServer(*serverAddr, serverPort, *serverModel, *serverDescription));
}
++n;
r = strtok_r(NULL, ";", &s);

View File

@ -80,11 +80,12 @@ bool cSatipFrontends::Detach(int deviceIdP, int transponderP)
// --- cSatipServer -----------------------------------------------------------
cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char *descriptionP)
cSatipServer::cSatipServer(const char *addressP, const int portP, const char *modelP, const char *descriptionP)
: addressM((addressP && *addressP) ? addressP : "0.0.0.0"),
modelM((modelP && *modelP) ? modelP : "DVBS-1"),
descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"),
quirksM(""),
portM(portP),
quirkM(eSatipQuirkNone),
hasCiM(false),
createdM(time(NULL)),
@ -374,6 +375,18 @@ cString cSatipServers::GetAddress(cSatipServer *serverP)
return address;
}
int cSatipServers::GetPort(cSatipServer *serverP)
{
int port = SATIP_DEFAULT_RTSP_PORT;
for (cSatipServer *s = First(); s; s = Next(s)) {
if (s == serverP) {
port = s->Port();
break;
}
}
return port;
}
cString cSatipServers::GetString(cSatipServer *serverP)
{
cString list = "";

View File

@ -59,6 +59,7 @@ private:
cString descriptionM;
cString quirksM;
cSatipFrontends frontendsM[eSatipFrontendCount];
int portM;
int quirkM;
bool hasCiM;
time_t createdM;
@ -72,7 +73,7 @@ public:
eSatipQuirkForceLock = 0x04,
eSatipQuirkMask = 0x0F
};
cSatipServer(const char *addressP, const char *modelP, const char *descriptionP);
cSatipServer(const char *addressP, const int portP, const char *modelP, const char *descriptionP);
virtual ~cSatipServer();
virtual int Compare(const cListObject &listObjectP) const;
bool Assign(int deviceIdP, int sourceP, int systemP, int transponderP);
@ -89,6 +90,7 @@ public:
const char *Model(void) { return *modelM; }
const char *Description(void) { return *descriptionM; }
const char *Quirks(void) { return *quirksM; }
int Port(void) { return portM; }
bool Quirk(int quirkP) { return ((quirkP & eSatipQuirkMask) & quirkM); }
bool HasQuirk(void) { return (quirkM != eSatipQuirkNone); }
bool HasCI(void) { return hasCiM; }
@ -112,6 +114,7 @@ public:
void Cleanup(uint64_t intervalMsP = 0);
cString GetAddress(cSatipServer *serverP);
cString GetString(cSatipServer *serverP);
int GetPort(cSatipServer *serverP);
cString List(void);
int NumProvidedSystems(void);
};

24
tuner.c
View File

@ -25,6 +25,7 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
rtcpM(*this),
streamAddrM(""),
streamParamM(""),
streamPortM(SATIP_DEFAULT_RTSP_PORT),
currentServerM(NULL, deviceP.GetId(), 0),
nextServerM(NULL, deviceP.GetId(), 0),
mutexM(),
@ -208,7 +209,7 @@ bool cSatipTuner::Connect(void)
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
if (!isempty(*streamAddrM)) {
cString connectionUri = cString::sprintf("rtsp://%s/", *streamAddrM);
cString connectionUri = GetBaseUrl(*streamAddrM, streamPortM);
// Just retune
if (streamIdM >= 0) {
cString uri = cString::sprintf("%sstream=%d?%s", *connectionUri, streamIdM, *streamParamM);
@ -247,7 +248,7 @@ bool cSatipTuner::Disconnect(void)
debug1("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
if (!isempty(*streamAddrM) && (streamIdM >= 0)) {
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
cString uri = cString::sprintf("%sstream=%d", *GetBaseUrl(*streamAddrM, streamPortM), streamIdM);
rtspM.Teardown(*uri);
// some devices requires a teardown for TCP connection also
rtspM.Reset();
@ -362,6 +363,16 @@ void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
}
cString cSatipTuner::GetBaseUrl(const char *addressP, const int portP)
{
debug16("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, addressP, portP, deviceIdM);
if (portP != SATIP_DEFAULT_RTSP_PORT)
return cString::sprintf("rtsp://%s:%d/", addressP, portP);
return cString::sprintf("rtsp://%s/", addressP);
}
int cSatipTuner::GetId(void)
{
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
@ -378,6 +389,7 @@ bool cSatipTuner::SetSource(cSatipServer *serverP, const int transponderP, const
// Update stream address and parameter
streamAddrM = rtspM.RtspUnescapeString(*nextServerM.GetAddress());
streamParamM = rtspM.RtspUnescapeString(parameterP);
streamPortM = nextServerM.GetPort();
// Reconnect
RequestState(tsSet, smExternal);
}
@ -416,7 +428,7 @@ bool cSatipTuner::UpdatePids(bool forceP)
cMutexLock MutexLock(&mutexM);
if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) &&
!isempty(*streamAddrM) && (streamIdM > 0)) {
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
cString uri = cString::sprintf("%sstream=%d", *GetBaseUrl(*streamAddrM, streamPortM), streamIdM);
bool useci = (SatipConfig.GetCIExtension() && currentServerM.HasCI());
bool usedummy = currentServerM.IsQuirk(cSatipServer::eSatipQuirkPlayPids);
if (forceP || usedummy) {
@ -466,7 +478,7 @@ bool cSatipTuner::KeepAlive(bool forceP)
forceP = true;
}
if (forceP && !isempty(*streamAddrM)) {
cString uri = cString::sprintf("rtsp://%s/", *streamAddrM);
cString uri = GetBaseUrl(*streamAddrM, streamPortM);
if (!rtspM.Options(*uri))
return false;
}
@ -483,7 +495,7 @@ bool cSatipTuner::ReadReceptionStatus(bool forceP)
forceP = true;
}
if (forceP && !isempty(*streamAddrM) && (streamIdM > 0)) {
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
cString uri = cString::sprintf("%sstream=%d", *GetBaseUrl(*streamAddrM, streamPortM), streamIdM);
if (rtspM.Describe(*uri))
return true;
}
@ -618,5 +630,5 @@ cString cSatipTuner::GetSignalStatus(void)
cString cSatipTuner::GetInformation(void)
{
debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM);
return (currentStateM >= tsTuned) ? cString::sprintf("rtsp://%s/?%s [stream=%d]", *streamAddrM, *streamParamM, streamIdM) : "connection failed";
return (currentStateM >= tsTuned) ? cString::sprintf("%s?%s [stream=%d]", *GetBaseUrl(*streamAddrM, streamPortM), *streamParamM, streamIdM) : "connection failed";
}

View File

@ -69,6 +69,7 @@ public:
void Set(cSatipServer *serverP, const int transponderP) { serverM = serverP; transponderM = transponderP; }
void Reset(void) { serverM = NULL; transponderM = 0; }
cString GetAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerAddress(serverM) : ""; }
int GetPort(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerPort(serverM) : SATIP_DEFAULT_RTSP_PORT; }
cString GetInfo(void) { return cString::sprintf("server=%s deviceid=%d transponder=%d", serverM ? "assigned" : "null", deviceIdM, transponderM); }
};
@ -98,6 +99,7 @@ private:
cSatipRtcp rtcpM;
cString streamAddrM;
cString streamParamM;
int streamPortM;
cSatipTunerServer currentServerM;
cSatipTunerServer nextServerM;
cMutex mutexM;
@ -130,6 +132,7 @@ private:
bool RequestState(eTunerState stateP, eStateMode modeP);
const char *StateModeString(eStateMode modeP);
const char *TunerStateString(eTunerState stateP);
cString GetBaseUrl(const char *addressP, const int portP);
protected:
virtual void Action(void);