mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 13:37:42 +02:00
Refactored device discovery.
This commit is contained in:
parent
443dd9706a
commit
f5015bcfba
4
Makefile
4
Makefile
@ -88,8 +88,8 @@ all-redirect: all
|
||||
|
||||
### The object files (add further files here):
|
||||
|
||||
OBJS = $(PLUGIN).o common.o config.o device.o discover.o param.o poller.o \
|
||||
rtp.o rtcp.o rtsp.o sectionfilter.o server.o setup.o socket.o \
|
||||
OBJS = $(PLUGIN).o common.o config.o device.o discover.o msearch.o param.o \
|
||||
poller.o rtp.o rtcp.o rtsp.o sectionfilter.o server.o setup.o socket.o \
|
||||
statistics.o tuner.o
|
||||
|
||||
### The main target:
|
||||
|
110
discover.c
110
discover.c
@ -18,13 +18,6 @@
|
||||
|
||||
cSatipDiscover *cSatipDiscover::instanceS = NULL;
|
||||
|
||||
const char *cSatipDiscover::bcastAddressS = "239.255.255.250";
|
||||
const char *cSatipDiscover::bcastMessageS = "M-SEARCH * HTTP/1.1\r\n" \
|
||||
"HOST: 239.255.255.250:1900\r\n" \
|
||||
"MAN: \"ssdp:discover\"\r\n" \
|
||||
"ST: urn:ses-com:device:SatIPServer:1\r\n" \
|
||||
"MX: 2\r\n\r\n";
|
||||
|
||||
cSatipDiscover *cSatipDiscover::GetInstance(void)
|
||||
{
|
||||
if (!instanceS)
|
||||
@ -126,8 +119,9 @@ int cSatipDiscover::DebugCallback(CURL *handleP, curl_infotype typeP, char *data
|
||||
cSatipDiscover::cSatipDiscover()
|
||||
: cThread("SAT>IP discover"),
|
||||
mutexM(),
|
||||
msearchM(),
|
||||
probeUrlListM(),
|
||||
handleM(curl_easy_init()),
|
||||
socketM(new cSatipSocket()),
|
||||
sleepM(),
|
||||
probeIntervalM(0),
|
||||
serversM(new cSatipServers())
|
||||
@ -141,11 +135,11 @@ cSatipDiscover::~cSatipDiscover()
|
||||
Deactivate();
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
// Free allocated memory
|
||||
DELETENULL(socketM);
|
||||
DELETENULL(serversM);
|
||||
if (handleM)
|
||||
curl_easy_cleanup(handleM);
|
||||
handleM = NULL;
|
||||
probeUrlListM.Clear();
|
||||
}
|
||||
|
||||
void cSatipDiscover::Activate(void)
|
||||
@ -166,84 +160,50 @@ void cSatipDiscover::Deactivate(void)
|
||||
void cSatipDiscover::Action(void)
|
||||
{
|
||||
debug("cSatipDiscover::%s(): entering", __FUNCTION__);
|
||||
probeIntervalM.Set(eProbeIntervalMs);
|
||||
msearchM.Probe();
|
||||
// Do the thread loop
|
||||
while (Running()) {
|
||||
cStringList tmp;
|
||||
|
||||
if (probeIntervalM.TimedOut()) {
|
||||
probeIntervalM.Set(eProbeIntervalMs);
|
||||
Probe();
|
||||
Janitor();
|
||||
msearchM.Probe();
|
||||
mutexM.Lock();
|
||||
if (serversM)
|
||||
serversM->Cleanup(eProbeIntervalMs * 2);
|
||||
mutexM.Unlock();
|
||||
}
|
||||
mutexM.Lock();
|
||||
if (probeUrlListM.Size()) {
|
||||
for (int i = 0; i < probeUrlListM.Size(); ++i)
|
||||
tmp.Insert(strdup(probeUrlListM.At(i)));
|
||||
probeUrlListM.Clear();
|
||||
}
|
||||
mutexM.Unlock();
|
||||
if (tmp.Size()) {
|
||||
for (int i = 0; i < tmp.Size(); ++i)
|
||||
Fetch(tmp.At(i));
|
||||
tmp.Clear();
|
||||
}
|
||||
// to avoid busy loop and reduce cpu load
|
||||
sleepM.Wait(10);
|
||||
sleepM.Wait(eSleepTimeoutMs);
|
||||
}
|
||||
debug("cSatipDiscover::%s(): exiting", __FUNCTION__);
|
||||
}
|
||||
|
||||
void cSatipDiscover::Janitor(void)
|
||||
void cSatipDiscover::Probe(const char *urlP)
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
debug("cSatipDiscover::%s(%s)", __FUNCTION__, urlP);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
if (serversM)
|
||||
serversM->Cleanup(eProbeIntervalMs * 2);
|
||||
probeUrlListM.Insert(strdup(urlP));
|
||||
sleepM.Signal();
|
||||
}
|
||||
|
||||
void cSatipDiscover::Probe(void)
|
||||
void cSatipDiscover::Fetch(const char *urlP)
|
||||
{
|
||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
if (socketM && socketM->Open(eDiscoveryPort)) {
|
||||
cTimeMs timeout(eProbeTimeoutMs);
|
||||
socketM->Write(bcastAddressS, reinterpret_cast<const unsigned char *>(bcastMessageS), strlen(bcastMessageS));
|
||||
while (Running() && !timeout.TimedOut()) {
|
||||
Read();
|
||||
// to avoid busy loop and reduce cpu load
|
||||
sleepM.Wait(100);
|
||||
}
|
||||
socketM->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void cSatipDiscover::Read(void)
|
||||
{
|
||||
//debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
if (socketM) {
|
||||
unsigned char *buf = MALLOC(unsigned char, eProbeBufferSize + 1);
|
||||
if (buf) {
|
||||
memset(buf, 0, eProbeBufferSize + 1);
|
||||
int len = socketM->Read(buf, eProbeBufferSize);
|
||||
if (len > 0) {
|
||||
//debug("cSatipDiscover::%s(): len=%d", __FUNCTION__, len);
|
||||
bool status = false, valid = false;
|
||||
char *s, *p = reinterpret_cast<char *>(buf), *location = NULL;
|
||||
char *r = strtok_r(p, "\r\n", &s);
|
||||
while (r) {
|
||||
//debug("cSatipDiscover::%s(): %s", __FUNCTION__, r);
|
||||
// Check the status code
|
||||
// HTTP/1.1 200 OK
|
||||
if (!status && startswith(r, "HTTP/1.1 200 OK")) {
|
||||
status = true;
|
||||
}
|
||||
if (status) {
|
||||
// Check the location data
|
||||
// LOCATION: http://192.168.0.115:8888/octonet.xml
|
||||
if (startswith(r, "LOCATION:")) {
|
||||
location = compactspace(r + 9);
|
||||
debug("cSatipDiscover::%s(): location='%s'", __FUNCTION__, location);
|
||||
}
|
||||
// Check the source type
|
||||
// ST: urn:ses-com:device:SatIPServer:1
|
||||
else if (startswith(r, "ST:")) {
|
||||
char *st = compactspace(r + 3);
|
||||
if (strstr(st, "urn:ses-com:device:SatIPServer:1"))
|
||||
valid = true;
|
||||
debug("cSatipDiscover::%s(): st='%s'", __FUNCTION__, st);
|
||||
}
|
||||
// Check whether all the required data is found
|
||||
if (valid && !isempty(location))
|
||||
break;
|
||||
}
|
||||
r = strtok_r(NULL, "\r\n", &s);
|
||||
}
|
||||
if (handleM && valid && !isempty(location)) {
|
||||
debug("cSatipDiscover::%s(%s)", __FUNCTION__, urlP);
|
||||
if (handleM && !isempty(urlP)) {
|
||||
long rc = 0;
|
||||
CURLcode res = CURLE_OK;
|
||||
#ifdef DEBUG
|
||||
@ -268,7 +228,7 @@ void cSatipDiscover::Read(void)
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s", PLUGIN_NAME_I18N, VERSION));
|
||||
|
||||
// Set URL
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_URL, location);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_URL, urlP);
|
||||
|
||||
// Fetch the data
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
@ -277,10 +237,6 @@ void cSatipDiscover::Read(void)
|
||||
error("Discovery detected invalid status code: %ld", rc);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char * descP)
|
||||
{
|
||||
|
14
discover.h
14
discover.h
@ -13,6 +13,7 @@
|
||||
#include <vdr/thread.h>
|
||||
#include <vdr/tools.h>
|
||||
|
||||
#include "msearch.h"
|
||||
#include "server.h"
|
||||
#include "socket.h"
|
||||
|
||||
@ -37,29 +38,25 @@ class cSatipDiscoverServers : public cList<cSatipDiscoverServer> {
|
||||
class cSatipDiscover : public cThread {
|
||||
private:
|
||||
enum {
|
||||
eSleepTimeoutMs = 500, // in milliseconds
|
||||
eConnectTimeoutMs = 1500, // in milliseconds
|
||||
eDiscoveryPort = 1900,
|
||||
eProbeBufferSize = 1024, // in bytes
|
||||
eProbeTimeoutMs = 2000, // in milliseconds
|
||||
eProbeIntervalMs = 60000 // in milliseconds
|
||||
};
|
||||
static cSatipDiscover *instanceS;
|
||||
static const char *bcastAddressS;
|
||||
static const char *bcastMessageS;
|
||||
static size_t WriteCallback(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;
|
||||
cSatipMsearch msearchM;
|
||||
cStringList probeUrlListM;
|
||||
CURL *handleM;
|
||||
cSatipSocket *socketM;
|
||||
cCondWait sleepM;
|
||||
cTimeMs probeIntervalM;
|
||||
cSatipServers *serversM;
|
||||
void Activate(void);
|
||||
void Deactivate(void);
|
||||
void Janitor(void);
|
||||
void Probe(void);
|
||||
void Read(void);
|
||||
void AddServer(const char *addrP, const char *modelP, const char *descP);
|
||||
void Fetch(const char *urlP);
|
||||
// constructor
|
||||
cSatipDiscover();
|
||||
// to prevent copy constructor and assignment
|
||||
@ -74,6 +71,7 @@ public:
|
||||
static bool Initialize(cSatipDiscoverServers *serversP);
|
||||
static void Destroy(void);
|
||||
virtual ~cSatipDiscover();
|
||||
void Probe(const char *urlP);
|
||||
void TriggerScan(void) { probeIntervalM.Set(0); }
|
||||
int GetServerCount(void);
|
||||
cSatipServer *GetServer(int sourceP, int transponderP = 0, int systemP = -1);
|
||||
|
94
msearch.c
Normal file
94
msearch.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* msearch.c: SAT>IP plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "discover.h"
|
||||
#include "poller.h"
|
||||
#include "msearch.h"
|
||||
|
||||
const char *cSatipMsearch::bcastAddressS = "239.255.255.250";
|
||||
const char *cSatipMsearch::bcastMessageS = "M-SEARCH * HTTP/1.1\r\n" \
|
||||
"HOST: 239.255.255.250:1900\r\n" \
|
||||
"MAN: \"ssdp:discover\"\r\n" \
|
||||
"ST: urn:ses-com:device:SatIPServer:1\r\n" \
|
||||
"MX: 2\r\n\r\n";
|
||||
|
||||
cSatipMsearch::cSatipMsearch(void)
|
||||
: bufferLenM(eProbeBufferSize),
|
||||
bufferM(MALLOC(unsigned char, bufferLenM)),
|
||||
registeredM(false)
|
||||
{
|
||||
if (bufferM)
|
||||
memset(bufferM, 0, bufferLenM);
|
||||
else
|
||||
error("Cannot create Msearch buffer!");
|
||||
if (!Open(eDiscoveryPort))
|
||||
error("Cannot open Msearch port!");
|
||||
}
|
||||
|
||||
cSatipMsearch::~cSatipMsearch()
|
||||
{
|
||||
}
|
||||
|
||||
void cSatipMsearch::Probe(void)
|
||||
{
|
||||
debug("cSatipMsearch::%s()", __FUNCTION__);
|
||||
if (!registeredM) {
|
||||
cSatipPoller::GetInstance()->Register(*this);
|
||||
registeredM = true;
|
||||
}
|
||||
Write(bcastAddressS, reinterpret_cast<const unsigned char *>(bcastMessageS), strlen(bcastMessageS));
|
||||
}
|
||||
|
||||
int cSatipMsearch::GetFd(void)
|
||||
{
|
||||
return Fd();
|
||||
}
|
||||
|
||||
void cSatipMsearch::Process(int fdP)
|
||||
{
|
||||
//debug("cSatipMsearch::%s()", __FUNCTION__);
|
||||
if (bufferM) {
|
||||
int length = Read(bufferM, bufferLenM);
|
||||
if (length > 0) {
|
||||
bufferM[min(length, int(bufferLenM - 1))] = 0;
|
||||
//debug("cSatipMsearch::%s(): len=%d buf=%s", __FUNCTION__, length, bufferM);
|
||||
bool status = false, valid = false;
|
||||
char *s, *p = reinterpret_cast<char *>(bufferM), *location = NULL;
|
||||
char *r = strtok_r(p, "\r\n", &s);
|
||||
while (r) {
|
||||
//debug("cSatipMsearch::%s(): %s", __FUNCTION__, r);
|
||||
// Check the status code
|
||||
// HTTP/1.1 200 OK
|
||||
if (!status && startswith(r, "HTTP/1.1 200 OK"))
|
||||
status = true;
|
||||
if (status) {
|
||||
// Check the location data
|
||||
// LOCATION: http://192.168.0.115:8888/octonet.xml
|
||||
if (startswith(r, "LOCATION:")) {
|
||||
location = compactspace(r + 9);
|
||||
debug("cSatipMsearch::%s(): location='%s'", __FUNCTION__, location);
|
||||
}
|
||||
// Check the source type
|
||||
// ST: urn:ses-com:device:SatIPServer:1
|
||||
else if (startswith(r, "ST:")) {
|
||||
char *st = compactspace(r + 3);
|
||||
if (strstr(st, "urn:ses-com:device:SatIPServer:1"))
|
||||
valid = true;
|
||||
debug("cSatipMsearch::%s(): st='%s'", __FUNCTION__, st);
|
||||
}
|
||||
// Check whether all the required data is found
|
||||
if (valid && !isempty(location)) {
|
||||
cSatipDiscover::GetInstance()->Probe(location);
|
||||
break;
|
||||
}
|
||||
}
|
||||
r = strtok_r(NULL, "\r\n", &s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
37
msearch.h
Normal file
37
msearch.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* msearch.h: SAT>IP plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SATIP_MSEARCH_H_
|
||||
#define __SATIP_MSEARCH_H_
|
||||
|
||||
#include "socket.h"
|
||||
#include "pollerif.h"
|
||||
|
||||
class cSatipMsearch : public cSatipSocket, public cSatipPollerIf {
|
||||
private:
|
||||
enum {
|
||||
eProbeBufferSize = 1024, // in bytes
|
||||
eDiscoveryPort = 1900,
|
||||
};
|
||||
static const char *bcastAddressS;
|
||||
static const char *bcastMessageS;
|
||||
unsigned int bufferLenM;
|
||||
unsigned char *bufferM;
|
||||
bool registeredM;
|
||||
|
||||
public:
|
||||
cSatipMsearch(void);
|
||||
virtual ~cSatipMsearch();
|
||||
void Probe(void);
|
||||
|
||||
// for internal poller interface
|
||||
public:
|
||||
virtual int GetFd(void);
|
||||
virtual void Process(int fdP);
|
||||
};
|
||||
|
||||
#endif /* __SATIP_MSEARCH_H_ */
|
4
satip.c
4
satip.c
@ -117,8 +117,8 @@ bool cPluginSatip::Initialize(void)
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
|
||||
error("Unable to initialize CURL");
|
||||
SatipConfig.SetConfigDirectory(cPlugin::ResourceDirectory(PLUGIN_NAME_I18N));
|
||||
cSatipDiscover::GetInstance()->Initialize(serversM);
|
||||
cSatipPoller::GetInstance()->Initialize();
|
||||
cSatipDiscover::GetInstance()->Initialize(serversM);
|
||||
return cSatipDevice::Initialize(deviceCountM);
|
||||
}
|
||||
|
||||
@ -142,8 +142,8 @@ void cPluginSatip::Stop(void)
|
||||
debug("cPluginSatip::%s()", __FUNCTION__);
|
||||
// Stop any background activities the plugin is performing.
|
||||
cSatipDevice::Shutdown();
|
||||
cSatipPoller::GetInstance()->Destroy();
|
||||
cSatipDiscover::GetInstance()->Destroy();
|
||||
cSatipPoller::GetInstance()->Destroy();
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user