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):
|
### The object files (add further files here):
|
||||||
|
|
||||||
OBJS = $(PLUGIN).o common.o config.o device.o discover.o param.o poller.o \
|
OBJS = $(PLUGIN).o common.o config.o device.o discover.o msearch.o param.o \
|
||||||
rtp.o rtcp.o rtsp.o sectionfilter.o server.o setup.o socket.o \
|
poller.o rtp.o rtcp.o rtsp.o sectionfilter.o server.o setup.o socket.o \
|
||||||
statistics.o tuner.o
|
statistics.o tuner.o
|
||||||
|
|
||||||
### The main target:
|
### The main target:
|
||||||
|
110
discover.c
110
discover.c
@ -18,13 +18,6 @@
|
|||||||
|
|
||||||
cSatipDiscover *cSatipDiscover::instanceS = NULL;
|
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)
|
cSatipDiscover *cSatipDiscover::GetInstance(void)
|
||||||
{
|
{
|
||||||
if (!instanceS)
|
if (!instanceS)
|
||||||
@ -126,8 +119,9 @@ int cSatipDiscover::DebugCallback(CURL *handleP, curl_infotype typeP, char *data
|
|||||||
cSatipDiscover::cSatipDiscover()
|
cSatipDiscover::cSatipDiscover()
|
||||||
: cThread("SAT>IP discover"),
|
: cThread("SAT>IP discover"),
|
||||||
mutexM(),
|
mutexM(),
|
||||||
|
msearchM(),
|
||||||
|
probeUrlListM(),
|
||||||
handleM(curl_easy_init()),
|
handleM(curl_easy_init()),
|
||||||
socketM(new cSatipSocket()),
|
|
||||||
sleepM(),
|
sleepM(),
|
||||||
probeIntervalM(0),
|
probeIntervalM(0),
|
||||||
serversM(new cSatipServers())
|
serversM(new cSatipServers())
|
||||||
@ -141,11 +135,11 @@ cSatipDiscover::~cSatipDiscover()
|
|||||||
Deactivate();
|
Deactivate();
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
// Free allocated memory
|
// Free allocated memory
|
||||||
DELETENULL(socketM);
|
|
||||||
DELETENULL(serversM);
|
DELETENULL(serversM);
|
||||||
if (handleM)
|
if (handleM)
|
||||||
curl_easy_cleanup(handleM);
|
curl_easy_cleanup(handleM);
|
||||||
handleM = NULL;
|
handleM = NULL;
|
||||||
|
probeUrlListM.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipDiscover::Activate(void)
|
void cSatipDiscover::Activate(void)
|
||||||
@ -166,84 +160,50 @@ void cSatipDiscover::Deactivate(void)
|
|||||||
void cSatipDiscover::Action(void)
|
void cSatipDiscover::Action(void)
|
||||||
{
|
{
|
||||||
debug("cSatipDiscover::%s(): entering", __FUNCTION__);
|
debug("cSatipDiscover::%s(): entering", __FUNCTION__);
|
||||||
|
probeIntervalM.Set(eProbeIntervalMs);
|
||||||
|
msearchM.Probe();
|
||||||
// Do the thread loop
|
// Do the thread loop
|
||||||
while (Running()) {
|
while (Running()) {
|
||||||
|
cStringList tmp;
|
||||||
|
|
||||||
if (probeIntervalM.TimedOut()) {
|
if (probeIntervalM.TimedOut()) {
|
||||||
probeIntervalM.Set(eProbeIntervalMs);
|
probeIntervalM.Set(eProbeIntervalMs);
|
||||||
Probe();
|
msearchM.Probe();
|
||||||
Janitor();
|
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
|
// to avoid busy loop and reduce cpu load
|
||||||
sleepM.Wait(10);
|
sleepM.Wait(eSleepTimeoutMs);
|
||||||
}
|
}
|
||||||
debug("cSatipDiscover::%s(): exiting", __FUNCTION__);
|
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);
|
cMutexLock MutexLock(&mutexM);
|
||||||
if (serversM)
|
probeUrlListM.Insert(strdup(urlP));
|
||||||
serversM->Cleanup(eProbeIntervalMs * 2);
|
sleepM.Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipDiscover::Probe(void)
|
void cSatipDiscover::Fetch(const char *urlP)
|
||||||
{
|
{
|
||||||
debug("cSatipDiscover::%s()", __FUNCTION__);
|
debug("cSatipDiscover::%s(%s)", __FUNCTION__, urlP);
|
||||||
if (socketM && socketM->Open(eDiscoveryPort)) {
|
if (handleM && !isempty(urlP)) {
|
||||||
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)) {
|
|
||||||
long rc = 0;
|
long rc = 0;
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
#ifdef DEBUG
|
#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));
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s", PLUGIN_NAME_I18N, VERSION));
|
||||||
|
|
||||||
// Set URL
|
// Set URL
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_URL, location);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_URL, urlP);
|
||||||
|
|
||||||
// Fetch the data
|
// Fetch the data
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
@ -276,10 +236,6 @@ void cSatipDiscover::Read(void)
|
|||||||
if (rc != 200)
|
if (rc != 200)
|
||||||
error("Discovery detected invalid status code: %ld", rc);
|
error("Discovery detected invalid status code: %ld", rc);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char * descP)
|
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/thread.h>
|
||||||
#include <vdr/tools.h>
|
#include <vdr/tools.h>
|
||||||
|
|
||||||
|
#include "msearch.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
@ -37,29 +38,25 @@ class cSatipDiscoverServers : public cList<cSatipDiscoverServer> {
|
|||||||
class cSatipDiscover : public cThread {
|
class cSatipDiscover : public cThread {
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
|
eSleepTimeoutMs = 500, // in milliseconds
|
||||||
eConnectTimeoutMs = 1500, // in milliseconds
|
eConnectTimeoutMs = 1500, // in milliseconds
|
||||||
eDiscoveryPort = 1900,
|
|
||||||
eProbeBufferSize = 1024, // in bytes
|
|
||||||
eProbeTimeoutMs = 2000, // in milliseconds
|
eProbeTimeoutMs = 2000, // in milliseconds
|
||||||
eProbeIntervalMs = 60000 // in milliseconds
|
eProbeIntervalMs = 60000 // in milliseconds
|
||||||
};
|
};
|
||||||
static cSatipDiscover *instanceS;
|
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 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);
|
static int DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP);
|
||||||
cMutex mutexM;
|
cMutex mutexM;
|
||||||
|
cSatipMsearch msearchM;
|
||||||
|
cStringList probeUrlListM;
|
||||||
CURL *handleM;
|
CURL *handleM;
|
||||||
cSatipSocket *socketM;
|
|
||||||
cCondWait sleepM;
|
cCondWait sleepM;
|
||||||
cTimeMs probeIntervalM;
|
cTimeMs probeIntervalM;
|
||||||
cSatipServers *serversM;
|
cSatipServers *serversM;
|
||||||
void Activate(void);
|
void Activate(void);
|
||||||
void Deactivate(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 AddServer(const char *addrP, const char *modelP, const char *descP);
|
||||||
|
void Fetch(const char *urlP);
|
||||||
// constructor
|
// constructor
|
||||||
cSatipDiscover();
|
cSatipDiscover();
|
||||||
// to prevent copy constructor and assignment
|
// to prevent copy constructor and assignment
|
||||||
@ -74,6 +71,7 @@ public:
|
|||||||
static bool Initialize(cSatipDiscoverServers *serversP);
|
static bool Initialize(cSatipDiscoverServers *serversP);
|
||||||
static void Destroy(void);
|
static void Destroy(void);
|
||||||
virtual ~cSatipDiscover();
|
virtual ~cSatipDiscover();
|
||||||
|
void Probe(const char *urlP);
|
||||||
void TriggerScan(void) { probeIntervalM.Set(0); }
|
void TriggerScan(void) { probeIntervalM.Set(0); }
|
||||||
int GetServerCount(void);
|
int GetServerCount(void);
|
||||||
cSatipServer *GetServer(int sourceP, int transponderP = 0, int systemP = -1);
|
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)
|
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
|
||||||
error("Unable to initialize CURL");
|
error("Unable to initialize CURL");
|
||||||
SatipConfig.SetConfigDirectory(cPlugin::ResourceDirectory(PLUGIN_NAME_I18N));
|
SatipConfig.SetConfigDirectory(cPlugin::ResourceDirectory(PLUGIN_NAME_I18N));
|
||||||
cSatipDiscover::GetInstance()->Initialize(serversM);
|
|
||||||
cSatipPoller::GetInstance()->Initialize();
|
cSatipPoller::GetInstance()->Initialize();
|
||||||
|
cSatipDiscover::GetInstance()->Initialize(serversM);
|
||||||
return cSatipDevice::Initialize(deviceCountM);
|
return cSatipDevice::Initialize(deviceCountM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +142,8 @@ void cPluginSatip::Stop(void)
|
|||||||
debug("cPluginSatip::%s()", __FUNCTION__);
|
debug("cPluginSatip::%s()", __FUNCTION__);
|
||||||
// Stop any background activities the plugin is performing.
|
// Stop any background activities the plugin is performing.
|
||||||
cSatipDevice::Shutdown();
|
cSatipDevice::Shutdown();
|
||||||
cSatipPoller::GetInstance()->Destroy();
|
|
||||||
cSatipDiscover::GetInstance()->Destroy();
|
cSatipDiscover::GetInstance()->Destroy();
|
||||||
|
cSatipPoller::GetInstance()->Destroy();
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user