1
0
mirror of https://github.com/rofafor/vdr-plugin-iptv.git synced 2023-10-10 11:37:03 +00:00

Compare commits

...

19 Commits

Author SHA1 Message Date
Rolf Ahrenberg
06506c41f6 Fixed TCP socket connection and silenced compilation warnings. 2012-04-26 21:32:20 +03:00
Rolf Ahrenberg
c33b05076a Incremented version number and updated HISTORY. 2012-04-26 00:29:46 +03:00
Rolf Ahrenberg
38bd9a21f6 Fixed response header parsing in HTTP protocol. 2012-04-26 00:27:24 +03:00
Rolf Ahrenberg
4c7b2ea69b Added cIptvDevice::DeviceType() and updated HISTORY. 2012-04-02 19:15:53 +03:00
Rolf Ahrenberg
c475b26515 Changed UDP protocol to always utilize the source address validation. 2012-04-02 00:35:32 +03:00
Rolf Ahrenberg
9145fb8bb8 Silenced a warning in the HTTP protocol. 2012-04-01 22:47:50 +03:00
Rolf Ahrenberg
7a8b2962b2 Added support for a service interface. 2012-04-01 22:46:08 +03:00
Rolf Ahrenberg
626d0402c2 Updated the disable ca updates patch. 2012-03-31 20:43:10 +03:00
Rolf Ahrenberg
b3b06e569f Fixed some channel switching bugs. 2012-03-31 20:32:04 +03:00
Rolf Ahrenberg
ff84c54d50 Fixed channel switching in UDP protocol. 2012-03-30 19:01:46 +03:00
Rolf Ahrenberg
4c39d8cf72 Updated device name. 2012-03-30 18:22:10 +03:00
Rolf Ahrenberg
0b790260fa Updated for vdr-1.7.27. 2012-03-25 16:42:06 +03:00
Rolf Ahrenberg
79113bbe09 Updated default CXXFLAGS. 2012-03-25 16:03:22 +03:00
Rolf Ahrenberg
30de763a4b Updated for vdr-1.7.26. 2012-03-10 23:22:20 +02:00
Rolf Ahrenberg
868865c47d Updated for vdr-1.7.25. 2012-03-03 15:18:59 +02:00
Rolf Ahrenberg
a73921041f Added a GIT tag into the version string. 2012-02-26 22:54:45 +02:00
Rolf Ahrenberg
49e3a9e23a Silenced compilation warnings. 2012-02-19 19:14:10 +02:00
Rolf Ahrenberg
73311873bc Updated Makefile. 2012-02-19 17:47:43 +02:00
Rolf Ahrenberg
816c357065 Updated the patch. 2012-02-19 17:43:43 +02:00
27 changed files with 163 additions and 83 deletions

14
HISTORY
View File

@@ -158,3 +158,17 @@ VDR Plugin 'iptv' Revision History
- Canonicalized the configuration directory.
- Added support for LDFLAGS.
- Added cppcheck target into Makefile.
2012-04-02: Version 0.5.1
- Updated for vdr-1.7.27.
- Updated Makefile.
- Silenced compilation warnings.
- Fixed channel switching bugs.
- Added support for a service interface.
- Changed UDP protocol to always utilize the source address
validation.
2012-04-26: Version 0.5.2
- Fixed connection problems in HTTP protocol.

View File

@@ -19,18 +19,19 @@ PLUGIN = iptv
### The version number of this plugin (taken from the main source file):
VERSION = $(shell grep 'const char VERSION\[\] *=' $(PLUGIN).c | awk '{ print $$5 }' | sed -e 's/[";]//g')
GITTAG = $(shell git describe --always 2>/dev/null)
### The C++ compiler and options:
CXX ?= g++
CXXFLAGS ?= -fPIC -g -O3 -Wall -Wextra -Wswitch-default -Wfloat-equal -Wundef -Wpointer-arith -Wconversion -Wcast-align -Wredundant-decls -Wno-unused-parameter -Woverloaded-virtual -Wno-parentheses
CXXFLAGS ?= -fPIC -g -O3 -Wall -Wextra -Wswitch-default -Wfloat-equal -Wundef -Wpointer-arith -Wconversion -Wcast-align -Wredundant-decls -Wno-unused-parameter -Werror=overloaded-virtual -Wno-parentheses
LDFLAGS ?= -Wl,--as-needed
### The directory environment:
VDRDIR = ../../..
LIBDIR = ../../lib
TMPDIR = /tmp
VDRDIR ?= ../../..
LIBDIR ?= ../../lib
TMPDIR ?= /tmp
### Make sure that necessary options are included:
@@ -59,6 +60,10 @@ ifdef IPTV_DEBUG
DEFINES += -DDEBUG
endif
ifneq ($(strip $(GITTAG)),)
DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"'
endif
.PHONY: all all-redirect
all-redirect: all

3
README
View File

@@ -161,9 +161,6 @@ Notes:
- EIT scanning functionality can be disabled for all IPTV channels by applying
the "disable_eitscan" patch to the VDR.
- Source address validation can be enabled for UDP protocol separated by
adding the source address after a ';' character: "U=239.192.0.1;239.192.0.2"
- Section id and pid scanners should be disabled after the correct data is
found. This can be made via VDR's channel editor.

View File

@@ -30,6 +30,8 @@
#define IPTV_DEVICE_INFO_GENERAL 1
#define IPTV_DEVICE_INFO_PIDS 2
#define IPTV_DEVICE_INFO_FILTERS 3
#define IPTV_DEVICE_INFO_PROTOCOL 4
#define IPTV_DEVICE_INFO_BITRATE 5
#define IPTV_STATS_ACTIVE_PIDS_COUNT 10
#define IPTV_STATS_ACTIVE_FILTERS_COUNT 10

View File

@@ -42,6 +42,6 @@ void cIptvConfig::SetDisabledFilters(unsigned int Index, int Number)
void cIptvConfig::SetConfigDirectory(const char *directoryP)
{
debug("cIptvConfig::SetConfigDirectory(%s)", directoryP);
debug("cIptvConfig::SetConfigDirectory(%s)\n", directoryP);
ERROR_IF(!realpath(directoryP, configDirectory), "Cannot canonicalize configuration directory");
}

View File

@@ -123,7 +123,7 @@ cIptvDevice *cIptvDevice::GetIptvDevice(int CardIndex)
cString cIptvDevice::GetGeneralInformation(void)
{
//debug("cIptvDevice::GetGeneralInformation(%d)\n", deviceIndex);
return cString::sprintf("IPTV device: %d\nCardIndex: %d\n%s%s%sChannel: %s",
return cString::sprintf("IPTV device: %d\nCardIndex: %d\nStream: %s\nStream bitrate: %s\n%sChannel: %s",
deviceIndex, CardIndex(),
pIptvStreamer ? *pIptvStreamer->GetInformation() : "",
pIptvStreamer ? *pIptvStreamer->GetStreamerStatistic() : "",
@@ -169,6 +169,12 @@ cString cIptvDevice::GetInformation(unsigned int Page)
case IPTV_DEVICE_INFO_FILTERS:
info = GetFiltersInformation();
break;
case IPTV_DEVICE_INFO_PROTOCOL:
info = pIptvStreamer ? *pIptvStreamer->GetInformation() : "";
break;
case IPTV_DEVICE_INFO_BITRATE:
info = pIptvStreamer ? *pIptvStreamer->GetStreamerStatistic() : "";
break;
default:
info = cString::sprintf("%s%s%s",
*GetGeneralInformation(),
@@ -179,6 +185,18 @@ cString cIptvDevice::GetInformation(unsigned int Page)
return info;
}
cString cIptvDevice::DeviceType(void) const
{
debug("cIptvDevice::DeviceType(%d)\n", deviceIndex);
return "IPTV";
}
cString cIptvDevice::DeviceName(void) const
{
debug("cIptvDevice::DeviceName(%d)\n", deviceIndex);
return cString::sprintf("IPTV %d", deviceIndex);
}
int cIptvDevice::SignalStrength(void) const
{
debug("cIptvDevice::SignalStrength(%d)\n", deviceIndex);

View File

@@ -76,6 +76,8 @@ private:
bool IsBlackListed(u_short Pid, u_char Tid, u_char Mask) const;
// for channel info
virtual cString DeviceType(void) const;
virtual cString DeviceName(void) const;
virtual int SignalStrength(void) const;
virtual int SignalQuality(void) const;

25
iptv.c
View File

@@ -11,12 +11,17 @@
#include "config.h"
#include "setup.h"
#include "device.h"
#include "iptvservice.h"
#if defined(APIVERSNUM) && APIVERSNUM < 10721
#error "VDR-1.7.21 API version or greater is required!"
#if defined(APIVERSNUM) && APIVERSNUM < 10727
#error "VDR-1.7.27 API version or greater is required!"
#endif
const char VERSION[] = "0.5.0";
#ifndef GITVERSION
#define GITVERSION ""
#endif
const char VERSION[] = "0.5.2" GITVERSION;
static const char DESCRIPTION[] = trNOOP("Experience the IPTV");
class cPluginIptv : public cPlugin {
@@ -196,8 +201,18 @@ bool cPluginIptv::SetupParse(const char *Name, const char *Value)
bool cPluginIptv::Service(const char *Id, void *Data)
{
//debug("cPluginIptv::Service()\n");
// Handle custom service requests from other plugins
debug("cPluginIptv::Service()\n");
if (strcmp(Id,"IptvService-v1.0") == 0) {
if (Data) {
IptvService_v1_0 *data = (IptvService_v1_0*)Data;
cIptvDevice *dev = cIptvDevice::GetIptvDevice(data->cardIndex);
if (!dev)
return false;
data->protocol = dev->GetInformation(IPTV_DEVICE_INFO_PROTOCOL);
data->bitrate = dev->GetInformation(IPTV_DEVICE_INFO_BITRATE);
}
return true;
}
return false;
}

22
iptvservice.h Normal file
View File

@@ -0,0 +1,22 @@
/*
* iptvservice.h: IPTV plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#ifndef __IPTVSERVICE_H
#define __IPTVSERVICE_H
#include <vdr/tools.h>
#define stIptv ('I' << 24)
struct IptvService_v1_0 {
unsigned int cardIndex;
cString protocol;
cString bitrate;
};
#endif //__IPTVSERVICE_H

View File

@@ -1,6 +1,6 @@
diff -Nru vdr-1.7.23-vanilla/pat.c vdr-1.7.23-disable_ca_updates/pat.c
--- vdr-1.7.23-vanilla/pat.c 2012-01-15 20:26:29.000000000 +0200
+++ vdr-1.7.23-disable_ca_updates/pat.c 2012-02-02 18:48:23.000000000 +0200
diff -Nru vdr-1.7.27-vanilla/pat.c vdr-1.7.27-disable_ca_updates/pat.c
--- vdr-1.7.27-vanilla/pat.c 2012-03-25 15:17:57.000000000 +0300
+++ vdr-1.7.27-disable_ca_updates/pat.c 2012-03-31 20:42:14.000000000 +0300
@@ -537,6 +537,7 @@
}
if (Setup.UpdateChannels >= 2) {

View File

@@ -5,7 +5,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-iptv 0.5.0\n"
"Project-Id-Version: vdr-iptv 0.5.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-02-02 02:02+0300\n"
"PO-Revision-Date: 2012-02-02 02:02+0300\n"

View File

@@ -5,7 +5,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-iptv 0.5.0\n"
"Project-Id-Version: vdr-iptv 0.5.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-02-02 02:02+0300\n"
"PO-Revision-Date: 2012-02-02 02:02+0300\n"

View File

@@ -6,7 +6,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-iptv 0.5.0\n"
"Project-Id-Version: vdr-iptv 0.5.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-02-02 02:02+0300\n"
"PO-Revision-Date: 2010-09-09 09:09+0300\n"

View File

@@ -5,7 +5,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-iptv 0.5.0\n"
"Project-Id-Version: vdr-iptv 0.5.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-02-02 02:02+0300\n"
"PO-Revision-Date: 2012-02-02 02:02+0300\n"

View File

@@ -5,7 +5,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-iptv 0.5.0\n"
"Project-Id-Version: vdr-iptv 0.5.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-02-02 02:02+0300\n"
"PO-Revision-Date: 2012-02-02 02:02+0300\n"

View File

@@ -5,7 +5,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-iptv 0.5.0\n"
"Project-Id-Version: vdr-iptv 0.5.2\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-02-02 02:02+0300\n"
"PO-Revision-Date: 2010-09-09 09:09+0300\n"

View File

@@ -22,7 +22,8 @@
cIptvProtocolExt::cIptvProtocolExt()
: pid(-1),
scriptFile(""),
scriptParameter(0)
scriptParameter(0),
streamPort(0)
{
debug("cIptvProtocolExt::cIptvProtocolExt()\n");
}
@@ -53,7 +54,7 @@ void cIptvProtocolExt::ExecuteScript(void)
for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++)
close(i);
// Execute the external script
cString cmd = cString::sprintf("%s %d %d", *scriptFile, scriptParameter, socketPort);
cString cmd = cString::sprintf("%s %d %d", *scriptFile, scriptParameter, streamPort);
debug("cIptvProtocolExt::ExecuteScript(child): %s\n", *cmd);
if (execl("/bin/bash", "sh", "-c", *cmd, (char *)NULL) == -1) {
error("Script execution failed: %s", *cmd);
@@ -113,7 +114,7 @@ bool cIptvProtocolExt::Open(void)
if (!strlen(*scriptFile))
return false;
// Create the listening socket
OpenSocket(socketPort);
OpenSocket(streamPort);
// Execute the external script
ExecuteScript();
isActive = true;
@@ -149,7 +150,7 @@ bool cIptvProtocolExt::Set(const char* Location, const int Parameter, const int
}
scriptParameter = Parameter;
// Update listen port
socketPort = IptvConfig.GetExtProtocolBasePort() + Index;
streamPort = IptvConfig.GetExtProtocolBasePort() + Index;
}
return true;
}

View File

@@ -17,6 +17,7 @@ private:
int pid;
cString scriptFile;
int scriptParameter;
int streamPort;
private:
void TerminateScript(void);

View File

@@ -20,7 +20,8 @@
cIptvProtocolHttp::cIptvProtocolHttp()
: streamAddr(strdup("")),
streamPath(strdup("/"))
streamPath(strdup("/")),
streamPort(0)
{
debug("cIptvProtocolHttp::cIptvProtocolHttp()\n");
}
@@ -41,7 +42,7 @@ bool cIptvProtocolHttp::Connect(void)
// Check that stream address is valid
if (!isActive && !isempty(streamAddr) && !isempty(streamPath)) {
// Ensure that socket is valid and connect
OpenSocket(socketPort, streamAddr);
OpenSocket(streamPort, streamAddr);
if (!ConnectSocket()) {
CloseSocket();
return false;
@@ -127,15 +128,19 @@ bool cIptvProtocolHttp::ProcessHeaders(void)
{
debug("cIptvProtocolHttp::ProcessHeaders()\n");
unsigned int lineLength = 0;
int response = 0;
int version = 0, response = 0;
bool responseFound = false;
char fmt[32];
char buf[4096];
// Generate HTTP response format string with 2 arguments
snprintf(fmt, sizeof(fmt), "HTTP/1.%%%zui %%%zui ", sizeof(version) - 1, sizeof(response) - 1);
while (!responseFound || lineLength != 0) {
memset(buf, '\0', sizeof(buf));
if (!GetHeaderLine(buf, sizeof(buf), lineLength))
return false;
if (!responseFound && sscanf(buf, "HTTP/1.%*i %i ", &response) != 1) {
if (!responseFound && sscanf(buf, fmt, &version, &response) != 2) {
error("Expected HTTP header not found\n");
continue;
}
@@ -185,8 +190,8 @@ bool cIptvProtocolHttp::Set(const char* Location, const int Parameter, const int
}
else
streamPath = strcpyrealloc(streamPath, "/");
socketPort = Parameter;
//debug("http://%s:%d%s\n", streamAddr, socketPort, streamPath);
streamPort = Parameter;
//debug("http://%s:%d%s\n", streamAddr, streamPort, streamPath);
// Re-connect the socket
Connect();
}
@@ -196,5 +201,5 @@ bool cIptvProtocolHttp::Set(const char* Location, const int Parameter, const int
cString cIptvProtocolHttp::GetInformation(void)
{
//debug("cIptvProtocolHttp::GetInformation()");
return cString::sprintf("http://%s:%d%s", streamAddr, socketPort, streamPath);
return cString::sprintf("http://%s:%d%s", streamAddr, streamPort, streamPath);
}

View File

@@ -16,6 +16,7 @@ class cIptvProtocolHttp : public cIptvTcpSocket, public cIptvProtocolIf {
private:
char* streamAddr;
char* streamPath;
int streamPort;
private:
bool Connect(void);

View File

@@ -20,7 +20,7 @@
cIptvProtocolUdp::cIptvProtocolUdp()
: streamAddr(strdup("")),
sourceAddr(strdup(""))
streamPort(0)
{
debug("cIptvProtocolUdp::cIptvProtocolUdp()\n");
}
@@ -32,33 +32,32 @@ cIptvProtocolUdp::~cIptvProtocolUdp()
cIptvProtocolUdp::Close();
// Free allocated memory
free(streamAddr);
free(sourceAddr);
}
bool cIptvProtocolUdp::Open(void)
{
debug("cIptvProtocolUdp::Open()\n");
OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr));
debug("cIptvProtocolUdp::Open(): streamAddr=%s\n", streamAddr);
OpenSocket(streamPort, inet_addr(streamAddr));
if (!isempty(streamAddr)) {
// Join a new multicast group
JoinMulticast(inet_addr(streamAddr));
JoinMulticast();
}
return true;
}
bool cIptvProtocolUdp::Close(void)
{
debug("cIptvProtocolUdp::Close()\n");
debug("cIptvProtocolUdp::Close(): streamAddr=%s\n", streamAddr);
if (!isempty(streamAddr)) {
// Drop the multicast group
OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr));
DropMulticast(inet_addr(streamAddr));
OpenSocket(streamPort, inet_addr(streamAddr));
DropMulticast();
}
// Close the socket
CloseSocket();
// Reset stream and source addresses
streamAddr = strcpyrealloc(streamAddr, "");
sourceAddr = strcpyrealloc(sourceAddr, "");
// Do NOT reset stream and source addresses
//streamAddr = strcpyrealloc(streamAddr, "");
//streamPort = 0;
return true;
}
@@ -73,23 +72,16 @@ bool cIptvProtocolUdp::Set(const char* Location, const int Parameter, const int
if (!isempty(Location)) {
// Drop the multicast group
if (!isempty(streamAddr)) {
OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr));
DropMulticast(inet_addr(streamAddr));
OpenSocket(streamPort, inet_addr(streamAddr));
DropMulticast();
}
// Update stream address and port
streamAddr = strcpyrealloc(streamAddr, Location);
char *p = strstr(streamAddr, ";");
if (p) {
sourceAddr = strcpyrealloc(sourceAddr, p + 1);
*p = 0;
}
else
sourceAddr = strcpyrealloc(sourceAddr, "");
socketPort = Parameter;
streamPort = Parameter;
// Join a new multicast group
if (!isempty(streamAddr)) {
OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr));
JoinMulticast(inet_addr(streamAddr));
OpenSocket(streamPort, inet_addr(streamAddr));
JoinMulticast();
}
}
return true;
@@ -98,5 +90,5 @@ bool cIptvProtocolUdp::Set(const char* Location, const int Parameter, const int
cString cIptvProtocolUdp::GetInformation(void)
{
//debug("cIptvProtocolUdp::GetInformation()");
return cString::sprintf("udp://%s:%d", streamAddr, socketPort);
return cString::sprintf("udp://%s:%d", streamAddr, streamPort);
}

View File

@@ -15,7 +15,7 @@
class cIptvProtocolUdp : public cIptvUdpSocket, public cIptvProtocolIf {
private:
char* streamAddr;
char* sourceAddr;
int streamPort;
public:
cIptvProtocolUdp();

View File

@@ -138,7 +138,7 @@ int cIptvSectionFilter::CopyDump(const uint8_t *buf, uint8_t len)
return 0;
memcpy(secbuf_base + tsfeedp, buf, len);
tsfeedp += len;
tsfeedp = uint16_t(tsfeedp + len);
limit = tsfeedp;
if (limit > DMX_MAX_SECFEED_SIZE)
@@ -154,7 +154,7 @@ int cIptvSectionFilter::CopyDump(const uint8_t *buf, uint8_t len)
seclen = seclen_local;
if (pusi_seen)
Feed();
secbufp += seclen_local;
secbufp = uint16_t(secbufp + seclen_local);
secbuf += seclen_local;
}
return 0;

View File

@@ -18,8 +18,8 @@
#include "socket.h"
cIptvSocket::cIptvSocket()
: socketDesc(-1),
socketPort(0),
: socketPort(0),
socketDesc(-1),
isActive(false)
{
debug("cIptvSocket::cIptvSocket()\n");
@@ -89,7 +89,7 @@ void cIptvSocket::CloseSocket(void)
// UDP socket class
cIptvUdpSocket::cIptvUdpSocket()
: sourceAddr(INADDR_ANY)
: streamAddr(INADDR_ANY)
{
debug("cIptvUdpSocket::cIptvUdpSocket()\n");
}
@@ -99,28 +99,28 @@ cIptvUdpSocket::~cIptvUdpSocket()
debug("cIptvUdpSocket::~cIptvUdpSocket()\n");
}
bool cIptvUdpSocket::OpenSocket(const int Port, const in_addr_t SourceAddr)
bool cIptvUdpSocket::OpenSocket(const int Port, const in_addr_t StreamAddr)
{
debug("cIptvUdpSocket::OpenSocket()\n");
sourceAddr = SourceAddr;
streamAddr = StreamAddr;
return cIptvSocket::OpenSocket(Port, true);
}
void cIptvUdpSocket::CloseSocket(void)
{
debug("cIptvUdpSocket::CloseSocket()\n");
sourceAddr = INADDR_ANY;
streamAddr = INADDR_ANY;
cIptvSocket::CloseSocket();
}
bool cIptvUdpSocket::JoinMulticast(const in_addr_t StreamAddr)
bool cIptvUdpSocket::JoinMulticast(void)
{
debug("cIptvUdpSocket::JoinMulticast()\n");
// Check if socket exists
if (!isActive && (socketDesc >= 0)) {
// Join a new multicast group
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = StreamAddr;
mreq.imr_multiaddr.s_addr = streamAddr;
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
ERROR_IF_RET(setsockopt(socketDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_ADD_MEMBERSHIP)", return false);
// Update multicasting flag
@@ -129,14 +129,14 @@ bool cIptvUdpSocket::JoinMulticast(const in_addr_t StreamAddr)
return true;
}
bool cIptvUdpSocket::DropMulticast(const in_addr_t StreamAddr)
bool cIptvUdpSocket::DropMulticast(void)
{
debug("cIptvUdpSocket::DropMulticast()\n");
// Check if socket exists
if (isActive && (socketDesc >= 0)) {
// Drop the existing multicast group
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = StreamAddr;
mreq.imr_multiaddr.s_addr = streamAddr;
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
ERROR_IF_RET(setsockopt(socketDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_DROP_MEMBERSHIP)", return false);
// Update multicasting flag
@@ -180,10 +180,10 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
}
else if (len > 0) {
// Process auxiliary received data and validate source address
for (cmsg = CMSG_FIRSTHDR(&msgh); (sourceAddr != INADDR_ANY) && (cmsg != NULL); cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
for (cmsg = CMSG_FIRSTHDR(&msgh); (streamAddr != INADDR_ANY) && (cmsg != NULL); cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)) {
struct in_pktinfo *i = (struct in_pktinfo *)CMSG_DATA(cmsg);
if (i->ipi_addr.s_addr != sourceAddr) {
if (i->ipi_addr.s_addr != streamAddr) {
//debug("Discard packet due to invalid source address: %s", inet_ntoa(i->ipi_addr));
return 0;
}
@@ -238,6 +238,9 @@ bool cIptvTcpSocket::OpenSocket(const int Port, const char *StreamAddr)
{
debug("cIptvTcpSocket::OpenSocket()\n");
// Socket must be opened before setting the host address
bool retval = cIptvSocket::OpenSocket(Port, false);
// First try only the IP address
sockAddr.sin_addr.s_addr = inet_addr(StreamAddr);
@@ -256,7 +259,7 @@ bool cIptvTcpSocket::OpenSocket(const int Port, const char *StreamAddr)
sockAddr.sin_addr.s_addr = inet_addr(*host->h_addr_list);
}
return cIptvSocket::OpenSocket(Port, false);
return retval;
}
void cIptvTcpSocket::CloseSocket(void)

View File

@@ -11,9 +11,11 @@
#include <arpa/inet.h>
class cIptvSocket {
private:
int socketPort;
protected:
int socketDesc;
int socketPort;
struct sockaddr_in sockAddr;
bool isActive;
@@ -28,16 +30,16 @@ public:
class cIptvUdpSocket : public cIptvSocket {
private:
in_addr_t sourceAddr;
in_addr_t streamAddr;
public:
cIptvUdpSocket();
virtual ~cIptvUdpSocket();
virtual int Read(unsigned char* BufferAddr, unsigned int BufferLen);
bool OpenSocket(const int Port, const in_addr_t SourceAddr = INADDR_ANY);
bool OpenSocket(const int Port, const in_addr_t StreamAddr = INADDR_ANY);
void CloseSocket(void);
bool JoinMulticast(const in_addr_t StreamAddr);
bool DropMulticast(const in_addr_t StreamAddr);
bool JoinMulticast(void);
bool DropMulticast(void);
};
class cIptvTcpSocket : public cIptvSocket {

View File

@@ -148,7 +148,7 @@ cString cIptvStreamerStatistics::GetStreamerStatistic()
long bitrate = elapsed ? (long)(1000.0L * dataBytes / KILOBYTE(1) / elapsed) : 0L;
if (!IptvConfig.GetUseBytes())
bitrate *= 8;
cString info = cString::sprintf("Stream bitrate: %ld k%s/s\n", bitrate, IptvConfig.GetUseBytes() ? "B" : "bit");
cString info = cString::sprintf("%ld k%s/s", bitrate, IptvConfig.GetUseBytes() ? "B" : "bit");
dataBytes = 0;
return info;
}

View File

@@ -108,8 +108,8 @@ bool cIptvStreamer::Set(const char* Location, const int Parameter, const int Ind
cString cIptvStreamer::GetInformation(void)
{
//debug("cIptvStreamer::GetInformation()");
cString info("Stream:");
cString info;
if (protocol)
info = cString::sprintf("%s %s", *info, *protocol->GetInformation());
return cString::sprintf("%s\n", *info);
info = protocol->GetInformation();
return info;
}