Compare commits

...

18 Commits
0.1 ... 0.3.4

Author SHA1 Message Date
Dennis Hamester
3a6f4eb7b5 Bump version to 0.3.4 2016-11-18 10:28:37 +01:00
Dennis Hamester
2067aba378 OctonetData: Remove unused variable 2016-11-16 12:32:36 +01:00
Dennis Hamester
b52f50ef30 OctonetData: Fix missing EPG data for the first channel 2016-11-16 12:31:27 +01:00
Dennis Hamester
d1f9af2225 OctonetData: Fix computing last_end in getEPG() 2016-11-14 11:36:51 +01:00
Julian Scheel
880d313bef Unify Digital Devices naming
Always write Digital Devices with a blank in between.

Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-11 20:49:27 +01:00
Julian Scheel
94eb166783 README: Add AppVeyor badge
Add a badge for AppVeyor (Windows) build status.

Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-10 17:54:14 +01:00
Dennis Hamester
ba7e50e79c client: Clear incoming signalStatus before filling it 2016-11-10 17:23:47 +01:00
Julian Scheel
5fc6fc2ebc README: Add build status
Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-10 17:20:24 +01:00
Julian Scheel
8778ebe422 Increment version to 0.3.1
Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-10 14:05:46 +01:00
Dennis Hamester
0adb1ade91 Pass channel name to rtsp_client 2016-11-10 11:33:56 +01:00
Dennis Hamester
844a5c3cd4 OctonetData: Add getter for channel name 2016-11-10 11:27:31 +01:00
Dennis Hamester
838c0094b7 Pass signal quality and snr to Kodi core 2016-11-10 10:52:33 +01:00
Dennis Hamester
c5b90f130b rtsp_client: Parse RTCP APP packets 2016-11-09 15:40:40 +01:00
Dennis Hamester
415d2c98ac rtsp_client: Open and close rtcp socket as well 2016-11-09 15:32:39 +01:00
Julian Scheel
2aa320ee2d Add debian package build files
Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-09 10:24:25 +01:00
Julian Scheel
de0bf9c847 Increment version to 0.3.1
Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-08 11:15:45 +01:00
Julian Scheel
9abe9180b6 Notify on channel load error not success
Do not queue a notification when loading channels was successful, but
only when it failed. While at it make the message string translatable.

Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-08 11:14:24 +01:00
Julian Scheel
4665b282a2 Unify naming and fix typo
Use same addon names in client.cpp and addon.xml.

Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-08 08:35:48 +01:00
16 changed files with 256 additions and 17 deletions

View File

@@ -1,5 +1,10 @@
# Octonet PVR
DigitalDevices [Octonet] (http://www.digital-devices.eu/shop/de/netzwerk-tv/) PVR client addon for [Kodi] (http://kodi.tv)
Digital Devices [Octonet] (http://www.digital-devices.eu/shop/de/netzwerk-tv/) PVR client addon for [Kodi] (http://kodi.tv)
| Platform | Status |
|----------|--------|
| Linux + OS X (Travis) | [![Build Status](https://travis-ci.org/julianscheel/pvr.octonet.svg?branch=master)](https://travis-ci.org/julianscheel/pvr.octonet) |
| Windows (AppVeyor) | [![Build status](https://ci.appveyor.com/api/projects/status/m7dhmpmuf5coir5h?svg=true)](https://ci.appveyor.com/project/julianscheel/pvr-octonet) |
# Building

7
debian/changelog.in vendored Normal file
View File

@@ -0,0 +1,7 @@
kodi-pvr-octonet (#PACKAGEVERSION#-#TAGREV#~#DIST#) #DIST#; urgency=low
[ kodi ]
* autogenerated dummy changelog
-- Nobody <nobody@kodi.tv> Sat, 01 Jun 2013 00:59:22 +0200

1
debian/compat vendored Normal file
View File

@@ -0,0 +1 @@
9

22
debian/control vendored Normal file
View File

@@ -0,0 +1,22 @@
Source: kodi-pvr-octonet
Priority: extra
Maintainer: Julian Scheel <julian@jusst.de>
Build-Depends: debhelper (>= 9.0.0), cmake, libjsoncpp-dev, kodi-pvr-dev,
libkodiplatform-dev (>= 16.0.0), kodi-addon-dev
Standards-Version: 3.9.4
Section: libs
Homepage: https://github.com/DigitalDevices/pvr.octonet
Package: kodi-pvr-octonet
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Digital Devices Octopus NET PVR for Kodi
Digital Devices Octopus NET PVR for Kodi
Package: kodi-pvr-octonet-dbg
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: debug symbols for Digital Devices Octopus NET PVR for Kodi
debug symbols for Digital Devices Octopus NET PVR for Kodi

46
debian/copyright vendored Normal file
View File

@@ -0,0 +1,46 @@
Format: http://dep.debian.net/deps/dep5
Upstream-Name: pvr.octonet
Source: https://github.com/DigitalDevices/pvr.octonet
Files: *
Copyright: 2015-2016 Julian Scheel
2015-2016 jusst technologies GmbH
2005-2013 Team XBMC
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
Files: debian/*
Copyright: 2016 Julian Scheel <julian@jusst.de>
2015 Jean-Luc Barriere
2015 wsnipex <wsnipex@a1.net>
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

2
debian/kodi-pvr-octonet.install vendored Normal file
View File

@@ -0,0 +1,2 @@
usr/lib/
usr/share/

24
debian/rules vendored Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
override_dh_auto_configure:
# USE_LTO breaks build
dh_auto_configure -- -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1
override_dh_strip:
dh_strip -pkodi-pvr-octonet --dbg-package=kodi-pvr-octonet-dbg
override_dh_installdocs:
dh_installdocs --link-doc=kodi-pvr-octonet

1
debian/source/format vendored Normal file
View File

@@ -0,0 +1 @@
3.0 (quilt)

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.octonet"
version="0.3"
name="PVR DigitalDevices Octonet Client"
version="0.3.4"
name="Digital Devices Octopus NET Client"
provider-name="digitaldevices">
<requires>
<c-pluff version="0.1" />
@@ -16,8 +16,8 @@
library_windx="pvr.octonet.dll"
library_android="libpvr.octonet.so" />
<extension point="xbmc.addon.metadata">
<summary lang="de_DE">Kodi PVR Addon für DigitalDevices Octonet Streams</summary>
<summary lang="en_US">Kodi PVR Addon for DigitalDevices Octonet Streams</summary>
<summary lang="de_DE">Kodi PVR Addon für Digital Devices Octopus NET Streams</summary>
<summary lang="en_US">Kodi PVR Addon for Digital Devices Octopus NET Streams</summary>
<platform>all</platform>
</extension>
</addon>

View File

@@ -19,3 +19,7 @@ msgstr ""
msgctxt "#30000"
msgid "Octonet Server Address"
msgstr ""
msgctxt "#30001"
msgid "Could not load chanellist"
msgstr ""

View File

@@ -19,3 +19,7 @@ msgstr ""
msgctxt "#30000"
msgid "Octonet Server Address"
msgstr ""
msgctxt "#30001"
msgid "Could not load chanellist"
msgstr ""

View File

@@ -41,8 +41,8 @@ OctonetData::OctonetData()
groups.clear();
lastEpgLoad = 0;
if (loadChannelList())
kodi->QueueNotification(QUEUE_INFO, "%d channels loaded.", channels.size());
if (!loadChannelList())
kodi->QueueNotification(QUEUE_ERROR, kodi->GetLocalizedString(30001), channels.size());
}
OctonetData::~OctonetData(void)
@@ -125,7 +125,6 @@ OctonetChannel* OctonetData::findChannel(int64_t nativeId)
time_t OctonetData::parseDateTime(std::string date)
{
struct tm timeinfo;
time_t time;
memset(&timeinfo, 0, sizeof(timeinfo));
@@ -237,20 +236,23 @@ PVR_ERROR OctonetData::getChannels(ADDON_HANDLE handle, bool bRadio)
PVR_ERROR OctonetData::getEPG(ADDON_HANDLE handle, const PVR_CHANNEL &channel, time_t start, time_t end)
{
bool needs_reload = false;
for (unsigned int i = 0; i < channels.size(); i++)
{
OctonetChannel &chan = channels.at(i);
if (channel.iUniqueId != chan.id)
continue;
if(chan.epg.empty()) {
loadEPG();
}
// FIXME: Check if reload is needed!?
std::vector<OctonetEpgEntry>::iterator it;
time_t last_end = 0;
for (it = chan.epg.begin(); it < chan.epg.end(); ++it) {
if (end > last_end)
last_end = end;
for (it = chan.epg.begin(); it != chan.epg.end(); ++it) {
if (it->end > last_end)
last_end = it->end;
if (it->end < start || it->start > end) {
continue;
@@ -271,6 +273,24 @@ PVR_ERROR OctonetData::getEPG(ADDON_HANDLE handle, const PVR_CHANNEL &channel, t
if (last_end < end)
loadEPG();
for (it = chan.epg.begin(); it != chan.epg.end(); ++it) {
if (it->end < start || it->start > end) {
continue;
}
EPG_TAG entry;
memset(&entry, 0, sizeof(EPG_TAG));
entry.iChannelNumber = i;
entry.iUniqueBroadcastId = it->id;
entry.strTitle = it->title.c_str();
entry.strPlotOutline = it->subtitle.c_str();
entry.startTime = it->start;
entry.endTime = it->end;
pvr->TransferEpgEntry(handle, &entry);
}
}
return PVR_ERROR_NO_ERROR;
@@ -286,6 +306,16 @@ const std::string& OctonetData::getUrl(int id) const {
return channels[0].url;
}
const std::string& OctonetData::getName(int id) const {
for(std::vector<OctonetChannel>::const_iterator iter = channels.begin(); iter != channels.end(); ++iter) {
if(iter->id == id) {
return iter->name;
}
}
return channels[0].name;
}
int OctonetData::getGroupCount(void)
{
return groups.size();

View File

@@ -71,6 +71,7 @@ class OctonetData : public P8PLATFORM::CThread
virtual PVR_ERROR getEPG(ADDON_HANDLE handle, const PVR_CHANNEL &channel, time_t start, time_t end);
const std::string& getUrl(int id) const;
const std::string& getName(int id) const;
protected:
virtual bool loadChannelList(void);

View File

@@ -157,7 +157,7 @@ PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES *pCapabilities)
const char* GetBackendName(void)
{
return "DigitalDevice Octonet PVR Addon";
return "Digital Devices Octopus NET Client";
}
const char* GetBackendVersion(void)
@@ -249,7 +249,7 @@ PVR_ERROR UpdateTimer(const PVR_TIMER& timer) { return PVR_ERROR_NOT_IMPLEMENTED
/* entirely unused, as we use standard RTSP+TS mux, which can be handlded by
* Kodi core */
bool OpenLiveStream(const PVR_CHANNEL& channel) {
return rtsp_open(data->getUrl(channel.iUniqueId));
return rtsp_open(data->getName(channel.iUniqueId), data->getUrl(channel.iUniqueId));
}
int ReadLiveStream(unsigned char* pBuffer, unsigned int iBufferSize) {
@@ -270,7 +270,12 @@ bool SwitchChannel(const PVR_CHANNEL& channel) {
return OpenLiveStream(channel);
}
PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS& signalStatus) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS& signalStatus) {
memset(&signalStatus, 0, sizeof(PVR_SIGNAL_STATUS));
rtsp_fill_signal_status(signalStatus);
return PVR_ERROR_NO_ERROR;
}
const char* GetLiveStreamURL(const PVR_CHANNEL& channel) { return NULL; }
PVR_ERROR GetStreamProperties(PVR_STREAM_PROPERTIES* pProperties) { return PVR_ERROR_NOT_IMPLEMENTED; }

View File

@@ -37,6 +37,7 @@ int asprintf(char **sptr, char *fmt, ...) {
#define KEEPALIVE_INTERVAL 60
#define KEEPALIVE_MARGIN 5
#define UDP_ADDRESS_LEN 16
#define RTCP_BUFFER_SIZE 1024
using namespace std;
using namespace ADDON;
@@ -66,12 +67,17 @@ struct rtsp_client {
Socket tcp_sock;
Socket udp_sock;
Socket rtcp_sock;
enum rtsp_state state;
int cseq;
size_t fifo_size;
uint16_t last_seq_nr;
string name;
int level;
int quality;
};
struct url {
@@ -81,6 +87,16 @@ struct url {
string path;
};
struct rtcp_app {
uint8_t subtype;
uint8_t pt;
uint16_t len;
uint32_t ssrc;
char name[4];
uint16_t identifier;
uint16_t string_len;
};
static rtsp_client *rtsp = NULL;
static url parse_url(const std::string& str) {
@@ -109,6 +125,16 @@ static url parse_url(const std::string& str) {
return result;
}
void split_string(const string& s, char delim, vector<string>& elems) {
stringstream ss;
ss.str(s);
string item;
while(getline(ss, item, delim)) {
elems.push_back(item);
}
}
static int tcp_sock_read_line(string &line) {
static string buf;
@@ -266,7 +292,7 @@ static enum rtsp_result rtsp_handle() {
return (enum rtsp_result)rtsp_result;
}
bool rtsp_open(const string& url_str)
bool rtsp_open(const string& name, const string& url_str)
{
string setup_url_str;
const char *psz_setup_url;
@@ -279,6 +305,10 @@ bool rtsp_open(const string& url_str)
if (rtsp == NULL)
return false;
rtsp->name = name;
rtsp->level = 0;
rtsp->quality = 0;
kodi->Log(LOG_DEBUG, "try to open '%s'", url_str.c_str());
url dst = parse_url(url_str);
@@ -342,6 +372,14 @@ bool rtsp_open(const string& url_str)
goto error;
}
rtsp->rtcp_sock = Socket(af_inet, pf_inet, sock_dgram, udp);
if(!rtsp->rtcp_sock.bind(rtsp->udp_port + 1)) {
goto error;
}
if(!rtsp->rtcp_sock.set_non_blocking(true)) {
goto error;
}
return true;
error:
@@ -349,11 +387,49 @@ error:
return false;
}
static void parse_rtcp(const char *buf, int size) {
int offset = 0;
while(size > 4) {
const rtcp_app *app = reinterpret_cast<const rtcp_app *>(buf + offset);
uint16_t len = 4 * (ntohs(app->len) + 1);
if((app->pt != 204) || (memcmp(app->name, "SES1", 4) != 0)) {
size -= len;
offset += len;
continue;
}
uint16_t string_len = ntohs(app->string_len);
string app_data(&buf[offset + sizeof(rtcp_app)], string_len);
vector<string> elems;
split_string(app_data, ';', elems);
if(elems.size() != 4) {
return;
}
vector<string> tuner;
split_string(elems[2], ',', tuner);
if(tuner.size() < 4) {
return;
}
rtsp->level = atoi(tuner[1].c_str());
rtsp->quality = atoi(tuner[3].c_str());
return;
}
}
int rtsp_read(void *buf, unsigned buf_size) {
sockaddr addr;
socklen_t addr_len = sizeof(addr);
int ret = rtsp->udp_sock.recvfrom((char *)buf, buf_size, (sockaddr *)&addr, &addr_len);
char rtcp_buf[RTCP_BUFFER_SIZE];
int rtcp_len = rtsp->rtcp_sock.recvfrom(rtcp_buf, RTCP_BUFFER_SIZE, (sockaddr *)&addr, &addr_len);
parse_rtcp(rtcp_buf, rtcp_len);
// TODO: check ip
return ret;
@@ -389,7 +465,16 @@ void rtsp_close()
rtsp_teardown();
rtsp->tcp_sock.close();
rtsp->udp_sock.close();
rtsp->rtcp_sock.close();
delete rtsp;
rtsp = NULL;
}
}
void rtsp_fill_signal_status(PVR_SIGNAL_STATUS& signal_status) {
if(rtsp) {
strncpy(signal_status.strServiceName, rtsp->name.c_str(), PVR_ADDON_NAME_STRING_LENGTH - 1);
signal_status.iSNR = 0x1111 * rtsp->quality;
signal_status.iSignal = 0x101 * rtsp->level;
}
}

View File

@@ -2,9 +2,11 @@
#define _RTSP_CLIENT_HPP_
#include <string>
#include <xbmc_pvr_types.h>
bool rtsp_open(const std::string& url_str);
bool rtsp_open(const std::string& name, const std::string& url_str);
void rtsp_close();
int rtsp_read(void *buf, unsigned buf_size);
void rtsp_fill_signal_status(PVR_SIGNAL_STATUS& signal_status);
#endif