Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial official version of DVBLink Connect! Server PVR Add-on

(Cleaned code to be compliant with XBMC coding style)
  • Loading branch information...
commit b2260d06cf72f7dba7bfdbe4d81739cbde84e6d7 1 parent d3671de
@zeroniak authored
Showing with 23,993 additions and 116 deletions.
  1. +1 −0  addons/Makefile.am
  2. +23 −0 addons/pvr.dvblink/Makefile.am
  3. +23 −0 addons/pvr.dvblink/addon/addon.xml.in
  4. +48 −0 addons/pvr.dvblink/addon/changelog.txt
  5. BIN  addons/pvr.dvblink/addon/icon.png
  6. +130 −0 addons/pvr.dvblink/addon/resources/language/Danish/strings.po
  7. +42 −0 addons/pvr.dvblink/addon/resources/language/Danish/strings.xml
  8. +145 −0 addons/pvr.dvblink/addon/resources/language/English/strings.po
  9. +42 −0 addons/pvr.dvblink/addon/resources/language/English/strings.xml
  10. +27 −0 addons/pvr.dvblink/addon/resources/settings.xml
  11. +118 −0 addons/pvr.dvblink/project/VS2010Express/pvrclient_dvblink.vcxproj
  12. +45 −0 addons/pvr.dvblink/project/VS2010Express/pvrclient_dvblink.vcxproj.filters
  13. +659 −0 addons/pvr.dvblink/src/DVBLinkClient.cpp
  14. +76 −0 addons/pvr.dvblink/src/DVBLinkClient.h
  15. +235 −0 addons/pvr.dvblink/src/HttpPostClient.cpp
  16. +28 −0 addons/pvr.dvblink/src/HttpPostClient.h
  17. +131 −0 addons/pvr.dvblink/src/base64.cpp
  18. +4 −0 addons/pvr.dvblink/src/base64.h
  19. +718 −0 addons/pvr.dvblink/src/client.cpp
  20. +64 −0 addons/pvr.dvblink/src/client.h
  21. +5 −1 configure.ac
  22. +1 −1  lib/Makefile.am
  23. +5 −0 lib/libdvblinkremote/COPYING
  24. +35 −0 lib/libdvblinkremote/Makefile.am
  25. +165 −0 lib/libdvblinkremote/channel.cpp
  26. +311 −0 lib/libdvblinkremote/curlhttpclient.cpp
  27. +75 −0 lib/libdvblinkremote/curlhttpclient.h
  28. +54 −0 lib/libdvblinkremote/dvblinkremote.cpp
  29. +494 −0 lib/libdvblinkremote/dvblinkremote.h
  30. +356 −0 lib/libdvblinkremote/dvblinkremotecommunication.cpp
  31. +85 −0 lib/libdvblinkremote/dvblinkremoteconnection.h
  32. +78 −0 lib/libdvblinkremote/dvblinkremotehttp.cpp
  33. +200 −0 lib/libdvblinkremote/dvblinkremotehttp.h
  34. +49 −0 lib/libdvblinkremote/dvblinkremoteserialization.h
  35. +261 −0 lib/libdvblinkremote/epg.cpp
  36. +95 −0 lib/libdvblinkremote/generic_response.cpp
  37. +46 −0 lib/libdvblinkremote/generic_response.h
  38. +255 −0 lib/libdvblinkremote/item_metadata.cpp
  39. +54 −0 lib/libdvblinkremote/m3u_playlist.cpp
  40. +134 −0 lib/libdvblinkremote/parental_lock.cpp
  41. +119 −0 lib/libdvblinkremote/playback_container.cpp
  42. +245 −0 lib/libdvblinkremote/playback_item.cpp
  43. +200 −0 lib/libdvblinkremote/playback_object.cpp
  44. +70 −0 lib/libdvblinkremote/program.cpp
  45. +20 −0 lib/libdvblinkremote/project/VS2010Express/libdvblinkremote.sln
  46. +144 −0 lib/libdvblinkremote/project/VS2010Express/libdvblinkremote.vcxproj
  47. +132 −0 lib/libdvblinkremote/project/VS2010Express/libdvblinkremote.vcxproj.filters
  48. +208 −0 lib/libdvblinkremote/recording.cpp
  49. +109 −0 lib/libdvblinkremote/recording_settings.cpp
  50. +57 −0 lib/libdvblinkremote/remove_playback_object_request.cpp
  51. +1,213 −0 lib/libdvblinkremote/request.h
  52. +1,288 −0 lib/libdvblinkremote/response.h
  53. +479 −0 lib/libdvblinkremote/scheduling.cpp
  54. +290 −0 lib/libdvblinkremote/scheduling.h
  55. +74 −0 lib/libdvblinkremote/stop_stream_request.cpp
  56. +88 −0 lib/libdvblinkremote/stream.cpp
  57. +172 −0 lib/libdvblinkremote/stream_request.cpp
  58. +94 −0 lib/libdvblinkremote/streaming_capabilities.cpp
  59. +42 −0 lib/libdvblinkremote/transcoded_video_stream_request.cpp
  60. +78 −0 lib/libdvblinkremote/transcoding_options.cpp
  61. +211 −0 lib/libdvblinkremote/util.cpp
  62. +56 −0 lib/libdvblinkremote/util.h
  63. +30 −0 lib/libdvblinkremote/version.h
  64. +412 −0 lib/libdvblinkremote/xml_object_serializer.h
  65. +181 −0 lib/libdvblinkremote/xml_object_serializer_factory.cpp
  66. +84 −0 lib/tinyxml2/CMakeLists.txt
  67. +7 −0 lib/tinyxml2/Makefile.am
  68. +1,800 −0 lib/tinyxml2/dox
  69. +308 −0 lib/tinyxml2/readme.md
  70. +4,546 −0 lib/tinyxml2/resources/dream.xml
  71. +11 −0 lib/tinyxml2/resources/utf8test.xml
  72. +11 −0 lib/tinyxml2/resources/utf8testverify.xml
  73. +107 −0 lib/tinyxml2/setversion.py
  74. +2,101 −0 lib/tinyxml2/tinyxml2.cpp
  75. +1,911 −0 lib/tinyxml2/tinyxml2.h
  76. +10 −0 lib/tinyxml2/tinyxml2.pc.in
  77. +20 −0 lib/tinyxml2/tinyxml2.sln
  78. +165 −0 lib/tinyxml2/tinyxml2/tinyxml2.vcxproj
  79. +27 −0 lib/tinyxml2/tinyxml2/tinyxml2.vcxproj.filters
  80. +204 −0 lib/tinyxml2/tinyxml2/tinyxml2.xcodeproj/project.pbxproj
  81. +1,051 −0 lib/tinyxml2/xmltest.cpp
  82. +129 −0 lib/tinyxml2/xmltest.h
  83. +172 −114 project/VS2010Express/xbmc-pvr-addons.sln
View
1  addons/Makefile.am
@@ -11,6 +11,7 @@ SUBDIRS = pvr.demo \
pvr.njoy \
pvr.vuplus \
pvr.argustv \
+ pvr.dvblink \
$(ADDITIONAL_SUBDIRS)
clean:
View
23 addons/pvr.dvblink/Makefile.am
@@ -0,0 +1,23 @@
+#
+# Makefile for the DVBLink add-on for XBMC PVR
+#
+# See the README for copyright information and
+# how to reach the author.
+#
+
+ADDONBINNAME = XBMC_DVBLink
+ADDONNAME = pvr.dvblink
+LIBNAME = libdvblink-addon
+lib_LTLIBRARIES = libdvblink-addon.la
+
+LIBS = @abs_top_srcdir@/lib/libdvblinkremote/libdvblinkremote.la
+
+include ../Makefile.include.am
+
+INCLUDES+=-Isrc
+
+libdvblink_addon_la_SOURCES = src/client.cpp \
+ src/HttpPostClient.cpp \
+ src/DVBLinkClient.cpp
+libdvblink_addon_la_LDFLAGS = @TARGET_LDFLAGS@
+
View
23 addons/pvr.dvblink/addon/addon.xml.in
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<addon
+ id="pvr.dvblink"
+ version="1.6.0.11"
+ name="PVR DVBLink Client"
+ provider-name="Barcode Madness">
+ <requires>
+ <c-pluff version="0.1"/>
+ </requires>
+ <extension
+ point="xbmc.pvrclient"
+ library_linux="XBMC_DVBLink.pvr"
+ library_osx="XBMC_DVBLink.pvr"
+ library_wingl="XBMC_DVBLink_win32.dll"
+ library_windx="XBMC_DVBLink_win32.dll"
+ library_android="libXBMC_DVBLink.so"/>
+ <extension point="xbmc.addon.metadata">
+ <summary lang="en">PVR Plugin for DVBLink</summary>
+ <description lang="en">PVR Plugin for DVBLink from DvbLogic.com; supporting streaming of Live TV &amp; Recordings, EPG, Timers</description>
+ <disclaimer lang="en">This is unstable software! The authors are in no way responsible for failed recordings, incorrect timers, wasted hours, or any other undesirable effects..</disclaimer>
+ <platform>@OS@</platform>
+ </extension>
+</addon>
View
48 addons/pvr.dvblink/addon/changelog.txt
@@ -0,0 +1,48 @@
+[B]Version 1.6.0.11[/B]
+Removed wrong danish language from addon description
+
+[B]Version 1.6.0.10[/B]
+Fixed: Timer related crash when addon could not find program information for EPG based timers
+
+[B]Version 1.6.0.9[/B]
+Added: Better notification and logging of status / error information
+
+[B]Version 1.6.0.8[/B]
+Fixed: Not all schedules shown
+Fixed: Not able to use username/password (Windows only)
+
+[B]Version 1.6.0.7[/B]
+Builds for all major os: windows,linux and osx
+Updated to XBMC Frodo Beta 2
+Updated to newest libdvblinkremote api
+Enabled editing of timers
+Updated version number to reflect other pvr addons
+Removed dependency on libcurl
+
+[B]0.0.6[/B]
+Fixed: Bug where addon did not show channels / EPG when using MCE Recorder
+
+[B]0.0.5[/B]
+Fixed: Bug where dvblink port from setting was not used
+
+[B]0.0.4[/B]
+Fixed: EPG data from when using MCE recorder
+Added: Preliminary (Have not been tested) support for transcoding
+Changed: Reordered settings
+
+[B]0.0.3[/B]
+Added: Fix for using channel handle instead of client id when stopping channels
+
+[B]0.0.2[/B]
+Added: Scheduling of recordings using EPG based timers
+Added: Enabled removal of timers
+Added: Listing of recordings (using DVBLink build in recorder)
+Added: Playback of recordings (using DVBLink build in recorder)
+Added: Enabled removal of recordings (using DVBLink build in recorder)
+Fixed: Memory several leaks
+Removed: Not yet implemented steaming and timeout options
+
+[B]0.0.1[/B]
+Beta release
+Playback of live tv and radio using raw http
+Listing of EPG
View
BIN  addons/pvr.dvblink/addon/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
130 addons/pvr.dvblink/addon/resources/language/Danish/strings.po
@@ -0,0 +1,130 @@
+# XBMC Media Center language file
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC-Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: 2012-12-11 20:52+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+msgctxt "#30000"
+msgid "General"
+msgstr "Generelt"
+
+msgctxt "#30001"
+msgid "Server Address"
+msgstr "Server adresse"
+
+msgctxt "#30002"
+msgid "Server Port"
+msgstr "Server Port"
+
+msgctxt "#30003"
+msgid "Client name"
+msgstr "Klient navn"
+
+msgctxt "#30004"
+msgid "Connection timeout (s)"
+msgstr "Forbindelse timeout"
+
+msgctxt "#30005"
+msgid "Username"
+msgstr "Brugernavn"
+
+msgctxt "#30006"
+msgid "Password"
+msgstr "Kodeord"
+
+msgctxt "#30100"
+msgid "Stream"
+msgstr "Stream"
+
+msgctxt "#30102"
+msgid "Stream format"
+msgstr "Stream format"
+
+msgctxt "#30103"
+msgid "Height"
+msgstr "Højde"
+
+msgctxt "#30104"
+msgid "Width"
+msgstr "Brede"
+
+msgctxt "#30105"
+msgid "Bitrate"
+msgstr "Bitrate"
+
+msgctxt "#30106"
+msgid "Audio track"
+msgstr "Lyd spor"
+
+msgctxt "#30107"
+msgid "HTTP"
+msgstr "HTTP"
+
+msgctxt "#30108"
+msgid "RTP"
+msgstr "RTP"
+
+msgctxt "#30109"
+msgid "HLS"
+msgstr "HLS"
+
+msgctxt "#30110"
+msgid "ASF"
+msgstr "ASF"
+
+msgctxt "#30200"
+msgid "Advanced"
+msgstr "Advanceret"
+
+msgctxt "#30201"
+msgid "Use channel handle instead of client id"
+msgstr "Brug kanal handle istedet for klient id"
+
+msgctxt "#30202"
+msgid "Show information messages"
+msgstr "Vis infomations beskeder"
+
+msgctxt "#32001"
+msgid "Connected to DVBLink Server '%s'"
+msgstr "Forbundet til DVBLink Server '%s'"
+
+msgctxt "#32002"
+msgid "Found '%d' channels"
+msgstr "Fundet'%d' kanaler"
+
+msgctxt "#32003"
+msgid "Could not connect to DVBLink Server '%s' (Error code : %d)"
+msgstr "Kunne ikke forbinde til DVBLink Server '%s' (Fejl kode : %d)"
+
+msgctxt "#32004"
+msgid "Could not get recordings (Error code : %d)"
+msgstr "Kunne ikke hente optagelser (Fejl kode : %d)"
+
+msgctxt "#32006"
+msgid "Could not get timers(Error code : %d)"
+msgstr "Kunne ikke hente timers (Fejl kode : %d)"
+
+msgctxt "#32007"
+msgid "Found %d EPG timers"
+msgstr "Fundet %d EPG timers"
+
+msgctxt "#32008"
+msgid "Found %d manual timers"
+msgstr "Fundet %d manual timers"
+
+msgctxt "#32009"
+msgid "Found %d recordings"
+msgstr "Fundet %d optagelser"
+
+msgctxt "#32010"
+msgid "Could not get stream for channel %s (Error code : %d)"
+msgstr "Kunne ikke få stream til kanal %s (Fejl kode : %d)"
View
42 addons/pvr.dvblink/addon/resources/language/Danish/strings.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings>
+ <!-- settings labels -->
+ <string id="30001">Server adresse</string>
+ <string id="30002">Server Port</string>
+ <string id="30003">Klient navn</string>
+ <string id="30004">Forbindelse timeout</string>
+ <string id="30005">Brugernavn</string>
+ <string id="30006">Kodeord</string>
+
+
+
+ <string id="30102">Stream format</string>
+ <string id="30103">Højde</string>
+ <string id="30104">Brede</string>
+ <string id="30105">Bitrate</string>
+ <string id="30106">Lyd spor</string>
+ <string id="30107">HTTP</string>
+ <string id="30108">RTP</string>
+ <string id="30109">HLS</string>
+ <string id="30110">ASF</string>
+
+ <string id="30201">Brug kanal handle istedet for klient id</string>
+ <string id="30202">Vis infomations beskeder</string>
+
+ <!-- category labels -->
+ <string id="30000">Generelt</string>
+ <string id="30100">Stream</string>
+ <string id="30200">Advanceret</string>
+
+ <!-- Messages labels -->
+
+ <string id="32001">Forbundet til DVBLink Server '%s'</string>
+ <string id="32002">Fundet'%d' kanaler</string>
+ <string id="32003">Kunne ikke forbinde til DVBLink Server '%s' (Fejl kode : %d)</string>
+ <string id="32004">Kunne ikke hente optagelser (Fejl kode : %d)</string>
+ <string id="32006">Kunne ikke hente timers (Fejl kode : %d)</string>
+ <string id="32007">Fundet %d EPG timers</string>
+ <string id="32008">Fundet %d manual timers</string>
+ <string id="32009">Fundet %d optagelser</string>
+ <string id="32010">Kunne ikke få stream til kanal %s (Fejl kode : %d)</string>
+</strings>
View
145 addons/pvr.dvblink/addon/resources/language/English/strings.po
@@ -0,0 +1,145 @@
+# XBMC Media Center language file
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC-Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: 2012-12-11 20:52+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#settings labels
+
+msgctxt "#30000"
+msgid "General"
+msgstr ""
+
+msgctxt "#30001"
+msgid "Server Address"
+msgstr ""
+
+msgctxt "#30002"
+msgid "Server Port"
+msgstr ""
+
+msgctxt "#30003"
+msgid "Client name"
+msgstr ""
+
+msgctxt "#30004"
+msgid "Connection timeout (s)"
+msgstr ""
+
+msgctxt "#30005"
+msgid "Username"
+msgstr ""
+
+msgctxt "#30006"
+msgid "Password"
+msgstr ""
+
+#empty strings from id 30007 to 30099
+
+msgctxt "#30100"
+msgid "Stream"
+msgstr ""
+
+#empty string with id 30101
+
+msgctxt "#30102"
+msgid "Stream format"
+msgstr ""
+
+msgctxt "#30103"
+msgid "Height"
+msgstr ""
+
+msgctxt "#30104"
+msgid "Width"
+msgstr ""
+
+msgctxt "#30105"
+msgid "Bitrate"
+msgstr ""
+
+msgctxt "#30106"
+msgid "Audio track"
+msgstr ""
+
+msgctxt "#30107"
+msgid "HTTP"
+msgstr ""
+
+msgctxt "#30108"
+msgid "RTP"
+msgstr ""
+
+msgctxt "#30109"
+msgid "HLS"
+msgstr ""
+
+msgctxt "#30110"
+msgid "ASF"
+msgstr ""
+
+#empty strings from id 30111 to 30199
+
+msgctxt "#30200"
+msgid "Advanced"
+msgstr ""
+
+#Messages labels
+
+msgctxt "#30201"
+msgid "Use channel handle instead of client id"
+msgstr ""
+
+msgctxt "#30202"
+msgid "Show information messages"
+msgstr ""
+
+#category labels
+#empty strings from id 30203 to 32000
+
+msgctxt "#32001"
+msgid "Connected to DVBLink Server '%s'"
+msgstr ""
+
+msgctxt "#32002"
+msgid "Found '%d' channels"
+msgstr ""
+
+msgctxt "#32003"
+msgid "Could not connect to DVBLink Server '%s' (Error code : %d)"
+msgstr ""
+
+msgctxt "#32004"
+msgid "Could not get recordings (Error code : %d)"
+msgstr ""
+
+#empty string with id 32005
+
+msgctxt "#32006"
+msgid "Could not get timers(Error code : %d)"
+msgstr ""
+
+msgctxt "#32007"
+msgid "Found %d EPG timers"
+msgstr ""
+
+msgctxt "#32008"
+msgid "Found %d manual timers"
+msgstr ""
+
+msgctxt "#32009"
+msgid "Found %d recordings"
+msgstr ""
+
+msgctxt "#32010"
+msgid "Could not get stream for channel %s (Error code : %d)"
+msgstr ""
View
42 addons/pvr.dvblink/addon/resources/language/English/strings.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings>
+ <!-- settings labels -->
+ <string id="30001">Server Address</string>
+ <string id="30002">Server Port</string>
+ <string id="30003">Client name</string>
+ <string id="30004">Connection timeout (s)</string>
+ <string id="30005">Username</string>
+ <string id="30006">Password</string>
+
+
+
+ <string id="30102">Stream format</string>
+ <string id="30103">Height</string>
+ <string id="30104">Width</string>
+ <string id="30105">Bitrate</string>
+ <string id="30106">Audio track</string>
+ <string id="30107">HTTP</string>
+ <string id="30108">RTP</string>
+ <string id="30109">HLS</string>
+ <string id="30110">ASF</string>
+
+ <string id="30201">Use channel handle instead of client id</string>
+ <string id="30202">Show information messages</string>
+
+ <!-- category labels -->
+ <string id="30000">General</string>
+ <string id="30100">Stream</string>
+ <string id="30200">Advanced</string>
+
+ <!-- Messages labels -->
+
+ <string id="32001">Connected to DVBLink Server '%s'</string>
+ <string id="32002">Found '%d' channels</string>
+ <string id="32003">Could not connect to DVBLink Server '%s' (Error code : %d)</string>
+ <string id="32004">Could not get recordings (Error code : %d)</string>
+ <string id="32006">Could not get timers(Error code : %d)</string>
+ <string id="32007">Found %d EPG timers</string>
+ <string id="32008">Found %d manual timers</string>
+ <string id="32009">Found %d recordings</string>
+ <string id="32010">Could not get stream for channel %s (Error code : %d)</string>
+</strings>
View
27 addons/pvr.dvblink/addon/resources/settings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<settings>
+ <!-- Connection -->
+ <category label="30000">
+ <setting id="host" type="text" label="30001" option="urlencoded" default="127.0.0.1" />
+ <setting id="port" type="number" option="int" label="30002" default="8080" />
+ <setting id="timeout" visible="false" type="enum" label="30004" values="0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20" default="10"/>
+ <setting id="client" type="text" label="30003" default="xbmc" />
+ <setting id="username" type="text" label="30005" default="" />
+ <setting id="password" type="text" label="30006" default="" option="hidden" enable="!eq(-1,)" />
+
+ </category>
+ <!-- Stream -->
+ <category label="30100">
+ <setting id="streamtype" type="enum" label="30102" lvalues="30107|30108|30109|30110" default="0" />
+ <setting id="height" enable="gt(-1,0)" type="number" label="30103" default="720" />
+ <setting id="width" enable="gt(-2,0)" type="number" label="30104" default="576" />
+ <setting id="bitrate" enable="gt(-3,0)" type="number" label="30105" default="512" />
+ <setting id="audiotrack" enable="gt(-4,0)" type="text" label="30106" default="eng" />
+ </category>
+ <!-- Advanced -->
+ <category label="30200">
+
+ <setting id="ch_handle" type="bool" label="30201" default="true" />
+ <setting id="showinfomsg" type="bool" label="30202" default="false" />
+</category>
+</settings>
View
118 addons/pvr.dvblink/project/VS2010Express/pvrclient_dvblink.vcxproj
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{F9F3E7B6-EF4C-4BD8-A921-3DE4C4268945}</ProjectGuid>
+ <RootNamespace>pvrclient_dvblink</RootNamespace>
+ <ProjectName>pvr.dvblink</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>..\..\addon\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetExt>.dll</TargetExt>
+ <TargetName>XBMC_DVBLink_win32</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>..\..\addon\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetExt>.dll</TargetExt>
+ <TargetName>XBMC_DVBLink_win32</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\..\xbmc;..\..\..\..\lib;..\..\..\..\lib\platform\windows;../../../../project/BuildDependencies/include;</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINDLL;TARGET_WINDOWS;TSREADER;_WINSOCKAPI_;_USE_32BIT_TIME_T;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)\</AdditionalLibraryDirectories>
+ </Link>
+ <ProjectReference>
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <AdditionalIncludeDirectories>..\..\..\..\xbmc;..\..\..\..\lib;..\..\..\..\lib\platform\windows;../../../../project/BuildDependencies/include;</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINDLL;TARGET_WINDOWS;TSREADER;_WINSOCKAPI_;_USE_32BIT_TIME_T;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>
+ </AdditionalLibraryDirectories>
+ <IgnoreAllDefaultLibraries>
+ </IgnoreAllDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\base64.cpp" />
+ <ClCompile Include="..\..\src\client.cpp" />
+ <ClCompile Include="..\..\src\DVBLinkClient.cpp" />
+ <ClCompile Include="..\..\src\HttpPostClient.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\base64.h" />
+ <ClInclude Include="..\..\src\client.h" />
+ <ClInclude Include="..\..\src\DVBLinkClient.h" />
+ <ClInclude Include="..\..\src\HttpPostClient.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\..\lib\libdvblinkremote\project\VS2010Express\libdvblinkremote.vcxproj">
+ <Project>{db826a81-e848-4e39-be17-e779a49e2960}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\lib\tinyxml2\tinyxml2\tinyxml2.vcxproj">
+ <Project>{16a1d446-5415-444e-a7b4-f35b7da7ee8c}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\project\VS2010Express\platform\platform.vcxproj">
+ <Project>{fe4573f6-a794-4ad3-b37f-49e51f1140e6}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
View
45 addons/pvr.dvblink/project/VS2010Express/pvrclient_dvblink.vcxproj.filters
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\client.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\DVBLinkClient.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\HttpPostClient.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\base64.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\client.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\DVBLinkClient.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\HttpPostClient.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\base64.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
View
659 addons/pvr.dvblink/src/DVBLinkClient.cpp
@@ -0,0 +1,659 @@
+#include "DVBLinkClient.h"
+#include "platform/util/StdString.h"
+
+bool DVBLinkClient::LoadChannelsFromFile()
+{
+ CStdString channelfile("special://userdata/addon_data/pvr.dvblink/channels");
+
+ // do we already have the icon file?
+ if (!XBMC->FileExists(channelfile, false))
+ {
+ return false;
+ }
+
+ CStdString strResult;
+ void* fileHandle = XBMC->OpenFile(channelfile, 0);
+ if (fileHandle)
+ {
+ char buffer[1024];
+ while (int bytesRead = XBMC->ReadFile(fileHandle, buffer, 1024))
+ strResult.append(buffer, bytesRead);
+ XBMC->CloseFile(fileHandle);
+ }
+ return true;
+}
+
+
+DVBLinkClient::DVBLinkClient(CHelper_libXBMC_addon *XBMC, CHelper_libXBMC_pvr *PVR,std::string clientname, std::string hostname, long port,bool showinfomsg, std::string username, std::string password)
+{
+ this->PVR = PVR;
+ this->XBMC = XBMC;
+ m_clientname = clientname;
+ m_hostname = hostname;
+ m_connected = false;
+ m_currentChannelId = 0;
+ m_showinfomsg = showinfomsg;
+ m_httpClient = new HttpPostClient(XBMC,hostname,port, username, password);
+ m_dvblinkRemoteCommunication = DVBLinkRemote::Connect((HttpClient&)*m_httpClient, m_hostname.c_str(), 8080, username.c_str(), password.c_str());
+
+ DVBLinkRemoteStatusCode status;
+ m_timerCount = -1;
+ m_recordingCount = -1;
+
+ m_stream = new Stream();
+
+ GetChannelsRequest request;
+ m_channels = new ChannelList();
+
+ if ((status = m_dvblinkRemoteCommunication->GetChannels(request, *m_channels)) == DVBLINK_REMOTE_STATUS_OK)
+ {
+ int iChannelUnique = 0;
+ for (std::vector<Channel*>::iterator it = m_channels->begin(); it < m_channels->end(); it++)
+ {
+ Channel* channel = (*it);
+ m_channelMap[++iChannelUnique] = channel;
+ }
+ m_connected = true;
+
+ XBMC->Log(LOG_INFO, "Connected to DVBLink Server '%s'", m_hostname.c_str());
+ if (m_showinfomsg)
+ {
+ XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32001), m_hostname.c_str());
+ XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32002), m_channelMap.size());
+ }
+ }
+ else
+ {
+ XBMC->QueueNotification(QUEUE_ERROR, XBMC->GetLocalizedString(32003), m_hostname.c_str(), (int)status);
+ std::string error;
+ m_dvblinkRemoteCommunication->GetLastError(error);
+ XBMC->Log(LOG_ERROR, "Could not connect to DVBLink Server '%s' on port '%i' with username '%s' (Error code : %d Description : %s)", hostname.c_str(), port, username.c_str(), (int)status,error.c_str());
+ }
+}
+
+bool DVBLinkClient::GetStatus()
+{
+ return m_connected;
+}
+
+int DVBLinkClient::GetChannelsAmount()
+{
+ return m_channelMap.size();
+}
+
+PVR_ERROR DVBLinkClient::GetChannels(ADDON_HANDLE handle, bool bRadio)
+{
+ XBMC->Log(LOG_INFO, "Getting channels (%d channels on server)", m_channelMap.size());
+ for (std::map<int,Channel*>::iterator it=m_channelMap.begin(); it!=m_channelMap.end(); ++it)
+ {
+ Channel* channel = (*it).second;
+
+ bool isRadio = (channel->GetChannelType() == Channel::CHANNEL_TYPE_RADIO);
+
+ if (isRadio == bRadio)
+ {
+ PVR_CHANNEL xbmcChannel;
+ memset(&xbmcChannel, 0, sizeof(PVR_CHANNEL));
+ xbmcChannel.bIsRadio = isRadio;
+ xbmcChannel.iChannelNumber =channel->Number;
+ xbmcChannel.iEncryptionSystem = 0;
+ xbmcChannel.iUniqueId = (*it).first;
+ PVR_STRCPY(xbmcChannel.strChannelName,channel->GetName().c_str());
+ CStdString stream;
+ if (isRadio)
+ stream.Format("pvr://stream/radio/%i.ts", channel->GetDvbLinkID());
+ else
+ stream.Format("pvr://stream/tv/%i.ts", channel->GetDvbLinkID());
+
+ PVR_STRCPY(xbmcChannel.strStreamURL, stream.c_str());
+ PVR_STRCPY(xbmcChannel.strInputFormat, "video/x-mpegts");
+ //pvrchannel.strIconPath = "";
+ PVR->TransferChannelEntry(handle, &xbmcChannel);
+ }
+ }
+ return PVR_ERROR_NO_ERROR;
+}
+
+int DVBLinkClient::GetTimersAmount()
+{
+ return m_timerCount;
+}
+
+
+int DVBLinkClient::GetInternalUniqueIdFromChannelId(const std::string& channelId)
+{
+ for (std::map<int,Channel*>::iterator it=m_channelMap.begin(); it!=m_channelMap.end(); ++it)
+ {
+ Channel * channel = (*it).second;
+ int id = (*it).first;
+ if (channelId.compare(channel->GetID()) == 0)
+ {
+ return id;
+ }
+ }
+ return 0;
+}
+
+PVR_ERROR DVBLinkClient::GetTimers(ADDON_HANDLE handle)
+{
+ PVR_ERROR result = PVR_ERROR_FAILED;
+ PLATFORM::CLockObject critsec(m_mutex);
+
+ GetSchedulesRequest getSchedulesRequest;
+ StoredSchedules sschedules;
+
+ DVBLinkRemoteStatusCode status;
+ int count = 0;
+ if ((status = m_dvblinkRemoteCommunication->GetSchedules(getSchedulesRequest, sschedules)) != DVBLINK_REMOTE_STATUS_OK)
+ {
+ std::string error;
+ m_dvblinkRemoteCommunication->GetLastError(error);
+ XBMC->Log(LOG_ERROR, "Could not get timers (Error code : %d Description : %s)", (int)status,error.c_str());
+ XBMC->QueueNotification(QUEUE_ERROR, XBMC->GetLocalizedString(32006), (int)status);
+ return result;
+ }
+
+ XBMC->Log(LOG_INFO, "Found %d epg timers", sschedules.GetEpgSchedules().size());
+
+ if (m_showinfomsg)
+ {
+ XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32007), sschedules.GetEpgSchedules().size());
+ }
+
+ for (std::vector<StoredEpgSchedule*>::iterator it = sschedules.GetEpgSchedules().begin(); it < sschedules.GetEpgSchedules().end(); it++)
+ {
+ StoredEpgSchedule* schedule = (StoredEpgSchedule*)*it;
+ PVR_TIMER xbmcTimer;
+ memset(&xbmcTimer, 0, sizeof(PVR_TIMER));
+ PVR_STR2INT(xbmcTimer.iClientIndex, schedule->GetID().c_str());
+
+ xbmcTimer.iClientChannelUid = GetInternalUniqueIdFromChannelId(schedule->GetChannelID());
+ xbmcTimer.state = PVR_TIMER_STATE_SCHEDULED;
+ xbmcTimer.bIsRepeating = schedule->Repeat;
+ PVR_STR2INT(xbmcTimer.iEpgUid, schedule->GetProgramID().c_str());
+ EpgSearchResult epgSearchResult;
+ if (DoEPGSearch(epgSearchResult,schedule->GetChannelID(), -1, -1, schedule->GetProgramID()))
+ {
+ if (epgSearchResult.size() < 1 || epgSearchResult[0]->GetEpgData().size() < 1)
+ {
+ XBMC->Log(LOG_INFO, "No EPG program data for timer '%s' on channel '%s' with program id '%s'", schedule->GetID().c_str(),schedule->GetChannelID().c_str(),schedule->GetProgramID().c_str());
+ continue;
+ }
+ ChannelEpgData * channelepgdata = epgSearchResult[0];
+ Program * program = channelepgdata->GetEpgData()[0];
+
+ xbmcTimer.startTime =program->GetStartTime();
+ xbmcTimer.endTime = program->GetStartTime() + program->GetDuration();
+ PVR_STRCPY(xbmcTimer.strTitle, program->GetTitle().c_str());
+ PVR_STRCPY(xbmcTimer.strSummary, program->ShortDescription.c_str());
+ PVR->TransferTimerEntry(handle, &xbmcTimer);
+ XBMC->Log(LOG_INFO, "Added EPG timer : %s", program->GetTitle().c_str());
+
+ count++;
+ }
+
+ }
+
+ XBMC->Log(LOG_INFO, "Found %d manual timers", sschedules.GetManualSchedules().size());
+
+ if (m_showinfomsg)
+ {
+ XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32008), sschedules.GetManualSchedules().size());
+ }
+
+ for (std::vector<StoredManualSchedule*>::iterator it = sschedules.GetManualSchedules().begin(); it < sschedules.GetManualSchedules().end(); it++)
+ {
+ StoredManualSchedule* schedule = (StoredManualSchedule*)*it;
+ PVR_TIMER xbmcTimer;
+ memset(&xbmcTimer, 0, sizeof(PVR_TIMER));
+ PVR_STR2INT(xbmcTimer.iClientIndex, schedule->GetID().c_str());
+
+ xbmcTimer.iClientChannelUid = GetInternalUniqueIdFromChannelId(schedule->GetChannelID());
+
+
+ xbmcTimer.state = PVR_TIMER_STATE_SCHEDULED;
+ xbmcTimer.startTime = schedule->GetStartTime();
+ xbmcTimer.endTime = schedule->GetStartTime() + schedule->GetDuration();
+ PVR_STRCPY(xbmcTimer.strTitle, schedule->Title.c_str());
+ //TODO: PAE: Add weekdays
+ XBMC->Log(LOG_INFO, "Added manual timer : %s", schedule->Title.c_str());
+ PVR->TransferTimerEntry(handle, &xbmcTimer);
+ count++;
+ }
+ m_timerCount = count;
+ result = PVR_ERROR_NO_ERROR;
+ return result;
+}
+
+PVR_ERROR DVBLinkClient::AddTimer(const PVR_TIMER &timer)
+{
+ PVR_ERROR result = PVR_ERROR_FAILED;
+ PLATFORM::CLockObject critsec(m_mutex);
+ DVBLinkRemoteStatusCode status;
+ AddScheduleRequest * addScheduleRequest = NULL;
+ std::string channelId = m_channelMap[timer.iClientChannelUid]->GetID();
+ if (timer.iEpgUid != 0)
+ {
+ char programId [33];
+ PVR_INT2STR(programId,timer.iEpgUid);
+ addScheduleRequest = new AddScheduleByEpgRequest(channelId, programId, timer.bIsRepeating);
+ }
+ else
+ {
+ //TODO: Fix day mask
+ addScheduleRequest = new AddManualScheduleRequest(channelId, timer.startTime, timer.endTime - timer.startTime, -1, timer.strTitle);
+ }
+
+ if ((status = m_dvblinkRemoteCommunication->AddSchedule(*addScheduleRequest)) == DVBLINK_REMOTE_STATUS_OK)
+ {
+ XBMC->Log(LOG_INFO, "Timer added");
+ PVR->TriggerTimerUpdate();
+ result = PVR_ERROR_NO_ERROR;
+ }
+ else
+ {
+ result = PVR_ERROR_FAILED;
+ std::string error;
+ m_dvblinkRemoteCommunication->GetLastError(error);
+ XBMC->Log(LOG_ERROR, "Could not add timer (Error code : %d Description : %s)", (int)status, error.c_str());
+ }
+ SAFE_DELETE(addScheduleRequest);
+ return result;
+}
+
+PVR_ERROR DVBLinkClient::DeleteTimer(const PVR_TIMER &timer)
+{
+ PVR_ERROR result = PVR_ERROR_FAILED;
+ PLATFORM::CLockObject critsec(m_mutex);
+ DVBLinkRemoteStatusCode status;
+ char scheduleId [33];
+ PVR_INT2STR(scheduleId, timer.iClientIndex);
+
+ RemoveScheduleRequest removeSchedule(scheduleId);
+
+
+ if ((status = m_dvblinkRemoteCommunication->RemoveSchedule(removeSchedule)) == DVBLINK_REMOTE_STATUS_OK)
+ {
+ XBMC->Log(LOG_INFO, "Timer deleted");
+ PVR->TriggerTimerUpdate();
+ result = PVR_ERROR_NO_ERROR;
+ }
+ else
+ {
+ std::string error;
+ m_dvblinkRemoteCommunication->GetLastError(error);
+ XBMC->Log(LOG_ERROR, "Timer could not be deleted (Error code : %d Description : %s)", (int)status, error.c_str());
+ }
+ return result;
+}
+
+PVR_ERROR DVBLinkClient::UpdateTimer(const PVR_TIMER &timer)
+{
+ PVR_ERROR deleteResult = DeleteTimer(timer);
+ if (deleteResult == PVR_ERROR_NO_ERROR)
+ {
+ return AddTimer(timer);
+ }
+ return deleteResult;
+}
+
+int DVBLinkClient::GetRecordingsAmount()
+{
+
+ return m_recordingCount;
+}
+
+std::string DVBLinkClient::GetBuildInRecorderObjectID()
+{
+ std::string result = "";
+ DVBLinkRemoteStatusCode status;
+ GetPlaybackObjectRequest getPlaybackObjectRequest(m_hostname.c_str(), "");
+ getPlaybackObjectRequest.RequestedObjectType = GetPlaybackObjectRequest::REQUESTED_OBJECT_TYPE_ALL;
+ getPlaybackObjectRequest.RequestedItemType = GetPlaybackObjectRequest::REQUESTED_ITEM_TYPE_ALL;
+ getPlaybackObjectRequest.IncludeChildrenObjectsForRequestedObject = true;
+ GetPlaybackObjectResponse getPlaybackObjectResponse;
+ if ((status = m_dvblinkRemoteCommunication->GetPlaybackObject(getPlaybackObjectRequest, getPlaybackObjectResponse)) == DVBLINK_REMOTE_STATUS_OK)
+ {
+ for (std::vector<PlaybackContainer*>::iterator it = getPlaybackObjectResponse.GetPlaybackContainers().begin(); it < getPlaybackObjectResponse.GetPlaybackContainers().end(); it++)
+ {
+ PlaybackContainer * container = (PlaybackContainer *) *it;
+ if (strcmp(container->SourceID.c_str(), DVBLINK_BUILD_IN_RECORDER_SOURCE_ID) == 0)
+ {
+ result = container->GetObjectID();
+ break;
+ }
+
+ }
+ }
+ return result;
+}
+
+
+std::string DVBLinkClient::GetRecordedTVByDateObjectID(const std::string& buildInRecoderObjectID)
+{
+ std::string result = "";
+ DVBLinkRemoteStatusCode status;
+
+ GetPlaybackObjectRequest getPlaybackObjectRequest(m_hostname.c_str(), buildInRecoderObjectID);
+ getPlaybackObjectRequest.IncludeChildrenObjectsForRequestedObject = true;
+ GetPlaybackObjectResponse getPlaybackObjectResponse;
+
+
+ if ((status = m_dvblinkRemoteCommunication->GetPlaybackObject(getPlaybackObjectRequest, getPlaybackObjectResponse)) == DVBLINK_REMOTE_STATUS_OK)
+ {
+ for (std::vector<PlaybackContainer*>::iterator it = getPlaybackObjectResponse.GetPlaybackContainers().begin(); it < getPlaybackObjectResponse.GetPlaybackContainers().end(); it++)
+ {
+ PlaybackContainer * container = (PlaybackContainer *) *it;
+ if (strcmp(container->GetName().c_str(), "By Date") == 0)
+ {
+ result = container->GetObjectID();
+ break;
+ }
+ }
+ }
+ return result;
+
+}
+
+PVR_ERROR DVBLinkClient::DeleteRecording(const PVR_RECORDING& recording)
+{
+ PLATFORM::CLockObject critsec(m_mutex);
+ PVR_ERROR result = PVR_ERROR_FAILED;
+ DVBLinkRemoteStatusCode status;
+ RemovePlaybackObjectRequest remoteObj(recording.strRecordingId);
+
+ if ((status = m_dvblinkRemoteCommunication->RemovePlaybackObject(remoteObj)) != DVBLINK_REMOTE_STATUS_OK)
+{
+ std::string error;
+ m_dvblinkRemoteCommunication->GetLastError(error);
+ XBMC->Log(LOG_ERROR, "Recording %s could not be deleted (Error code: %d Description : %s)", recording.strTitle, (int)status, error.c_str());
+ return result;
+ }
+
+ XBMC->Log(LOG_INFO, "Recording %s deleted", recording.strTitle);
+ PVR->TriggerRecordingUpdate();
+ result = PVR_ERROR_NO_ERROR;
+ return result;
+}
+
+
+PVR_ERROR DVBLinkClient::GetRecordings(ADDON_HANDLE handle)
+{
+ PLATFORM::CLockObject critsec(m_mutex);
+ PVR_ERROR result = PVR_ERROR_FAILED;
+ DVBLinkRemoteStatusCode status;
+
+ std::string recoderObjectId = GetBuildInRecorderObjectID();
+ std::string recordingsByDateObjectId = GetRecordedTVByDateObjectID(recoderObjectId);
+
+ GetPlaybackObjectRequest getPlaybackObjectRequest(m_hostname.c_str(), recordingsByDateObjectId);
+ getPlaybackObjectRequest.IncludeChildrenObjectsForRequestedObject = true;
+ GetPlaybackObjectResponse getPlaybackObjectResponse;
+
+ if ((status = m_dvblinkRemoteCommunication->GetPlaybackObject(getPlaybackObjectRequest, getPlaybackObjectResponse)) != DVBLINK_REMOTE_STATUS_OK)
+ {
+ std::string error;
+ m_dvblinkRemoteCommunication->GetLastError(error);
+ XBMC->Log(LOG_ERROR,"Could not get recordings (Error code : %d Description : %s)", (int)status, error.c_str());
+ XBMC->QueueNotification(QUEUE_ERROR, XBMC->GetLocalizedString(32004), (int)status);
+ return result;
+ }
+
+ XBMC->Log(LOG_INFO, "Found %d recordings", getPlaybackObjectResponse.GetPlaybackItems().size());
+
+ if (m_showinfomsg)
+ {
+ XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32009), getPlaybackObjectResponse.GetPlaybackItems().size());
+ }
+
+ for (std::vector<PlaybackItem*>::iterator it = getPlaybackObjectResponse.GetPlaybackItems().begin(); it < getPlaybackObjectResponse.GetPlaybackItems().end(); it++)
+ {
+ RecordedTvItem * tvitem = (RecordedTvItem *) *it;
+ PVR_RECORDING xbmcRecording;
+ memset(&xbmcRecording, 0, sizeof(PVR_RECORDING));
+
+ PVR_STRCPY(xbmcRecording.strRecordingId,tvitem->GetObjectID().c_str());
+
+ PVR_STRCPY(xbmcRecording.strTitle,tvitem->GetMetadata().GetTitle().c_str());
+
+ xbmcRecording.recordingTime = tvitem->GetMetadata().GetStartTime();
+ PVR_STRCPY(xbmcRecording.strPlot, tvitem->GetMetadata().ShortDescription.c_str());
+ PVR_STRCPY(xbmcRecording.strStreamURL, tvitem->GetPlaybackUrl().c_str());
+ xbmcRecording.iDuration = tvitem->GetMetadata().GetDuration();
+ PVR_STRCPY(xbmcRecording.strChannelName, tvitem->ChannelName.c_str());
+ PVR_STRCPY(xbmcRecording.strThumbnailPath, tvitem->GetThumbnailUrl().c_str());
+ PVR->TransferRecordingEntry(handle, &xbmcRecording);
+
+ }
+ m_recordingCount = getPlaybackObjectResponse.GetPlaybackItems().size();
+ result = PVR_ERROR_NO_ERROR;
+ return result;
+}
+
+long DVBLinkClient::GetFreeDiskSpace()
+{
+ PLATFORM::CLockObject critsec(m_mutex);
+ GetRecordingSettingsRequest recordingsettingsrequest;
+
+ RecordingSettings settings;
+ DVBLinkRemoteStatusCode status;
+ if ((status = m_dvblinkRemoteCommunication->GetRecordingSettings(recordingsettingsrequest, settings)) != DVBLINK_REMOTE_STATUS_OK)
+ {
+ return (settings.TotalSpace - settings.AvailableSpace) * 1024;
+ }
+ return 0;
+}
+
+long DVBLinkClient::GetTotalDiskSpace()
+{
+ PLATFORM::CLockObject critsec(m_mutex);
+ GetRecordingSettingsRequest recordingsettingsrequest;
+
+ RecordingSettings settings;
+ DVBLinkRemoteStatusCode status;
+ if ((status = m_dvblinkRemoteCommunication->GetRecordingSettings(recordingsettingsrequest, settings)) != DVBLINK_REMOTE_STATUS_OK)
+ {
+ return settings.TotalSpace * 1024;
+ }
+ return 0;
+}
+
+int DVBLinkClient::GetCurrentChannelId()
+{
+ return m_currentChannelId;
+}
+
+const char * DVBLinkClient::GetLiveStreamURL(const PVR_CHANNEL &channel, DVBLINK_STREAMTYPE streamtype, int width, int height, int bitrate, std::string audiotrack)
+{
+ PLATFORM::CLockObject critsec(m_mutex);
+ StreamRequest* streamRequest = NULL;
+ TranscodingOptions options(width, height);
+ options.SetBitrate(bitrate);
+ options.SetAudioTrack(audiotrack);
+ Channel * c = m_channelMap[channel.iUniqueId];
+ DVBLinkRemoteStatusCode status;
+ switch (streamtype)
+ {
+ case HTTP:
+ streamRequest = new RawHttpStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str());
+ break;
+ case RTP:
+ streamRequest = new RealTimeTransportProtocolStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
+ break;
+ case HLS:
+ streamRequest = new HttpLiveStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
+ break;
+ case ASF:
+ streamRequest = new WindowsMediaStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
+ break;
+ }
+
+ if ((status = m_dvblinkRemoteCommunication->PlayChannel(*streamRequest, *m_stream)) != DVBLINK_REMOTE_STATUS_OK)
+ {
+ std::string error;
+ m_dvblinkRemoteCommunication->GetLastError(error);
+ XBMC->Log(LOG_ERROR, "Could not get stream for channel %i (Error code : %d)", channel.iUniqueId, (int)status,error.c_str());
+ XBMC->QueueNotification(QUEUE_ERROR, XBMC->GetLocalizedString(32010), channel.strChannelName, (int)status);
+ SAFE_DELETE(streamRequest);
+ return "";
+ }
+ else
+ {
+ m_currentChannelId = channel.iUniqueId;
+ SAFE_DELETE(streamRequest);
+ return m_stream->GetUrl().c_str();
+ }
+}
+
+void DVBLinkClient::StopStreaming(bool bUseChlHandle)
+{
+ PLATFORM::CLockObject critsec(m_mutex);
+ StopStreamRequest * request;
+
+ if (bUseChlHandle)
+ {
+ request = new StopStreamRequest(m_stream->GetChannelHandle());
+ }
+ else
+ {
+ request = new StopStreamRequest(m_clientname);
+ }
+
+ DVBLinkRemoteStatusCode status;
+ if ((status = m_dvblinkRemoteCommunication->StopChannel(*request)) != DVBLINK_REMOTE_STATUS_OK)
+ {
+ std::string error;
+ m_dvblinkRemoteCommunication->GetLastError(error);
+ XBMC->Log(LOG_ERROR, "Could not stop stream (Error code : %d Description : %s)", (int)status, error.c_str());
+ }
+ SAFE_DELETE(request);
+}
+
+void DVBLinkClient::SetEPGGenre(Program *program, EPG_TAG *tag)
+{
+ if (program->IsCatNews)
+ {
+ tag->iGenreType = 0x20;
+ tag->iGenreSubType = 0x02;
+ }
+ if (program->IsCatDocumentary)
+ {
+ tag->iGenreType = 0x20;
+ tag->iGenreSubType = 0x03;
+ }
+
+ if (program->IsCatEducational)
+ {
+ tag->iGenreType = 0x90;
+ }
+
+ if (program->IsCatSports)
+ {
+ tag->iGenreType = 0x40;
+ }
+
+ if (program->IsCatMovie)
+ {
+ tag->iGenreType = 0x10;
+ tag->iGenreSubType = program->IsCatComedy ? 0x04 : 0;
+ tag->iGenreSubType = program->IsCatRomance ? 0x06 : 0;
+ tag->iGenreSubType = program->IsCatDrama ? 0x08 : 0;
+ tag->iGenreSubType = program->IsCatThriller ? 0x01 : 0;
+ tag->iGenreSubType = program->IsCatScifi ? 0x03 : 0;
+ tag->iGenreSubType = program->IsCatSoap ? 0x05 : 0;
+ tag->iGenreSubType = program->IsCatHorror ? 0x03 : 0;
+ }
+
+ if (program->IsCatKids)
+ {
+ tag->iGenreType = 0x50;
+ }
+
+ if (program->IsCatMusic)
+ {
+ tag->iGenreType = 0x60;
+ }
+
+ if (program->IsCatSpecial)
+ {
+ tag->iGenreType = 0xB0;
+ }
+}
+
+bool DVBLinkClient::DoEPGSearch(EpgSearchResult& epgSearchResult, const std::string& channelId, const long startTime, const long endTime, const std::string& programId)
+{
+ PLATFORM::CLockObject critsec(m_mutex);
+ EpgSearchRequest epgSearchRequest(channelId, startTime, endTime);
+ if (programId.compare("") != 0)
+ {
+ epgSearchRequest.ProgramID = programId;
+ }
+
+ DVBLinkRemoteStatusCode status;
+
+ if ((status = m_dvblinkRemoteCommunication->SearchEpg(epgSearchRequest, epgSearchResult)) == DVBLINK_REMOTE_STATUS_OK)
+ {
+ return true;
+ }
+ return false;
+}
+
+PVR_ERROR DVBLinkClient::GetEPGForChannel(ADDON_HANDLE handle, const PVR_CHANNEL& channel, time_t iStart, time_t iEnd)
+{
+ PVR_ERROR result = PVR_ERROR_FAILED;
+ PLATFORM::CLockObject critsec(m_mutex);
+ Channel * c = m_channelMap[channel.iUniqueId];
+ EpgSearchResult epgSearchResult;
+
+ if (DoEPGSearch(epgSearchResult,c->GetID(), iStart, iEnd))
+ {
+ for (std::vector<ChannelEpgData*>::iterator it = epgSearchResult.begin(); it < epgSearchResult.end(); it++)
+ {
+ ChannelEpgData* channelEpgData = (ChannelEpgData*)*it;
+ EpgData& epgData = channelEpgData->GetEpgData();
+ for (std::vector<Program*>::iterator pIt = epgData.begin(); pIt < epgData.end(); pIt++)
+ {
+ Program* p = (Program*)*pIt;
+ EPG_TAG broadcast;
+ memset(&broadcast, 0, sizeof(EPG_TAG));
+
+ PVR_STR2INT(broadcast.iUniqueBroadcastId, p->GetID().c_str() );
+ broadcast.strTitle = p->GetTitle().c_str();
+ broadcast.iChannelNumber = channel.iChannelNumber;
+ broadcast.startTime = p->GetStartTime();
+ broadcast.endTime = p->GetStartTime() + p->GetDuration();
+ broadcast.strPlotOutline = p->SubTitle.c_str();
+ broadcast.strPlot = p->ShortDescription.c_str();
+
+ broadcast.strIconPath = p->Image.c_str();
+ broadcast.iGenreType = 0;
+ broadcast.iGenreSubType = 0;
+ broadcast.strGenreDescription = "";
+ broadcast.firstAired = 0;
+ broadcast.iParentalRating = 0;
+ broadcast.iStarRating = p->Rating;
+ broadcast.bNotify = false;
+ broadcast.iSeriesNumber = 0;
+ broadcast.iEpisodeNumber = p->EpisodeNumber;
+ broadcast.iEpisodePartNumber = 0;
+ broadcast.strEpisodeName = "";
+ SetEPGGenre(p, &broadcast);
+ PVR->TransferEpgEntry(handle, &broadcast);
+ }
+ }
+ result = PVR_ERROR_NO_ERROR;
+ }
+ else
+ {
+ XBMC->Log(LOG_NOTICE, "Not EPG data found for channel : %s with id : %i", channel.strChannelName, channel.iUniqueId);
+ }
+ return result;
+}
+
+DVBLinkClient::~DVBLinkClient(void)
+{
+ SAFE_DELETE(m_dvblinkRemoteCommunication);
+ SAFE_DELETE(m_httpClient);
+ SAFE_DELETE(m_channels);
+ SAFE_DELETE(m_stream);
+}
View
76 addons/pvr.dvblink/src/DVBLinkClient.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include "platform/os.h"
+#include "libdvblinkremote/dvblinkremote.h"
+#include "HttpPostClient.h"
+#include "xbmc_pvr_types.h"
+#include "libXBMC_addon.h"
+#include "libXBMC_pvr.h"
+#include "client.h"
+#include "platform/threads/mutex.h"
+#include <map>
+
+using namespace dvblinkremote;
+using namespace dvblinkremotehttp;
+using namespace ADDON;
+
+#define DVBLINK_BUILD_IN_RECORDER_SOURCE_ID "8F94B459-EFC0-4D91-9B29-EC3D72E92677"
+
+class DVBLinkClient
+{
+public:
+ DVBLinkClient(CHelper_libXBMC_addon *XBMC, CHelper_libXBMC_pvr *PVR, std::string clientname, std::string hostname, long port, bool showinfomsg, std::string username, std::string password);
+ ~DVBLinkClient(void);
+ int GetChannelsAmount();
+ PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio);
+ PVR_ERROR GetEPGForChannel(ADDON_HANDLE handle, const PVR_CHANNEL& channel, time_t iStart, time_t iEnd);
+ int GetRecordingsAmount();
+ PVR_ERROR GetRecordings(ADDON_HANDLE handle);
+ PVR_ERROR DeleteRecording(const PVR_RECORDING& recording);
+ int GetTimersAmount();
+ PVR_ERROR GetTimers(ADDON_HANDLE handle);
+ PVR_ERROR AddTimer(const PVR_TIMER &timer);
+ PVR_ERROR DeleteTimer(const PVR_TIMER &timer);
+ PVR_ERROR UpdateTimer(const PVR_TIMER &timer);
+ bool GetStatus();
+ const char * GetLiveStreamURL(const PVR_CHANNEL &channel, DVBLINK_STREAMTYPE streamtype, int width, int height, int bitrate, std::string audiotrack);
+ void StopStreaming(bool bUseChlHandle);
+ int GetCurrentChannelId();
+ long GetFreeDiskSpace();
+ long GetTotalDiskSpace();
+
+private:
+ bool DoEPGSearch(EpgSearchResult& epgSearchResult, const std::string& channelId, const long startTime, const long endTime, const std::string & programId = "");
+ bool LoadChannelsFromFile();
+ void SetEPGGenre(Program *program, EPG_TAG *tag);
+ std::string GetBuildInRecorderObjectID();
+ std::string GetRecordedTVByDateObjectID(const std::string& buildInRecoderObjectID);
+ int GetInternalUniqueIdFromChannelId(const std::string& channelId);
+
+
+ HttpPostClient* m_httpClient;
+ IDVBLinkRemoteConnection* m_dvblinkRemoteCommunication;
+ bool m_connected;
+ std::map<int,Channel *> m_channelMap;
+ Stream * m_stream;
+ int m_currentChannelId;
+ ChannelList* m_channels;
+ long m_timerCount;
+ long m_recordingCount;
+ PLATFORM::CMutex m_mutex;
+ CHelper_libXBMC_pvr *PVR;
+ CHelper_libXBMC_addon *XBMC;
+ DVBLINK_STREAMTYPE m_streamtype;
+ std::string m_clientname;
+ std::string m_hostname;
+ bool m_showinfomsg;
+};
+
+/*!
+ * @brief PVR macros
+ */
+#define PVR_STRCPY(dest, source) do { strncpy(dest, source, sizeof(dest)-1); dest[sizeof(dest)-1] = '\0'; } while(0)
+#define PVR_STRCLR(dest) memset(dest, 0, sizeof(dest))
+#define PVR_INT2STR(dest, source) sprintf(dest, "%d", source)
+#define PVR_STR2INT(dest, source) dest = atoi(source)
+#define SAFE_DELETE(p) do { delete (p); (p)=NULL; } while (0)
View
235 addons/pvr.dvblink/src/HttpPostClient.cpp
@@ -0,0 +1,235 @@
+#include "HttpPostClient.h"
+#include "base64.h"
+
+#ifdef _WIN32
+#include <Winsock2.h>
+#else
+ #include <netdb.h>
+#endif
+
+#define SEND_RQ(MSG) \
+ /*cout<<send_str;*/ \
+ send(sock,MSG,strlen(MSG),0);
+
+
+/* Converts a hex character to its integer value */
+char from_hex(char ch)
+{
+ return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
+}
+
+/* Converts an integer value to its hex character*/
+char to_hex(char code)
+{
+ static char hex[] = "0123456789abcdef";
+ return hex[code & 15];
+}
+
+/* Returns a url-encoded version of str */
+/* IMPORTANT: be sure to free() the returned string after use */
+char *url_encode(const char *str)
+{
+ char *pstr = (char*) str, *buf = (char *)malloc(strlen(str) * 3 + 1), *pbuf = buf;
+ while (*pstr)
+{
+ if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
+ *pbuf++ = *pstr;
+ else if (*pstr == ' ')
+ *pbuf++ = '+';
+ else
+ *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
+ pstr++;
+ }
+ *pbuf = '\0';
+ return buf;
+}
+
+/* Returns a url-decoded version of str */
+/* IMPORTANT: be sure to free() the returned string after use */
+char *url_decode(const char *str)
+{
+ char *pstr = (char *)str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
+ while (*pstr)
+{
+ if (*pstr == '%')
+{
+ if (pstr[1] && pstr[2])
+{
+ *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
+ pstr += 2;
+ }
+ } else if (*pstr == '+')
+{
+ *pbuf++ = ' ';
+ } else {
+ *pbuf++ = *pstr;
+ }
+ pstr++;
+ }
+ *pbuf = '\0';
+ return buf;
+}
+
+
+HttpPostClient::HttpPostClient(CHelper_libXBMC_addon *XBMC, const std::string& server, const int serverport, const std::string& username, const std::string& password)
+{
+ this->XBMC = XBMC;
+ m_server = server;
+ m_serverport = serverport;
+ m_username = username;
+ m_password = password;
+}
+
+int HttpPostClient::SendPostRequest(HttpWebRequest& request)
+{
+ std::string buffer;
+ std::string message;
+ char content_header[100];
+
+ buffer.append("POST /cs/ HTTP/1.0\r\n");
+ sprintf(content_header,"Host: %s:%d\r\n",m_server.c_str(),(int)m_serverport);
+ buffer.append(content_header);
+ buffer.append("Content-Type: application/x-www-form-urlencoded\r\n");
+ if (m_username.compare("") != 0)
+ {
+ sprintf(content_header,"%s:%s",m_username.c_str(),m_password.c_str());
+ sprintf(content_header, "Authorization: Basic %s\r\n",base64_encode((const char*)content_header,strlen(content_header)).c_str());
+ buffer.append(content_header);
+ }
+ sprintf(content_header,"Content-Length: %d\r\n",request.ContentLength);
+ buffer.append(content_header);
+ buffer.append("\r\n");
+ buffer.append(request.GetRequestData());
+
+ #ifdef _WIN32
+ {
+ WSADATA WsaData;
+ WSAStartup(0x0101, &WsaData);
+ }
+ #endif
+
+ sockaddr_in sin;
+ int sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock == -1)
+ {
+ return -100;
+ }
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons((unsigned short)m_serverport);
+
+ struct hostent * host_addr = gethostbyname(m_server.c_str());
+ if (host_addr==NULL)
+ {
+ return -103;
+ }
+ sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ;
+
+ if (connect(sock, (const struct sockaddr *)&sin, sizeof(sockaddr_in)) == -1 )
+ {
+ return -101;
+ }
+
+ SEND_RQ(buffer.c_str());
+
+ char c1[1];
+ int l,line_length;
+ bool loop = true;
+ bool bHeader = false;
+
+
+ while (loop)
+ {
+ l = recv(sock, c1, 1, 0);
+ if (l<0) loop = false;
+ if (c1[0]=='\n')
+ {
+ if (line_length == 0)
+ loop = false;
+ line_length = 0;
+ if (message.find("200") != 0)
+ bHeader = true;
+ }
+ else if (c1[0]!='\r')
+ {
+ line_length++;
+ }
+ message += c1[0];
+ }
+
+ message="";
+ if (bHeader)
+ {
+ char p[1024];
+ while ((l = recv(sock,p,1023,0)) > 0) {
+ p[l] = '\0';
+ message += p;
+ }
+ }
+ else
+ {
+ return -102;
+ }
+
+
+
+
+ //TODO: Use xbmc file code when it allows to post content-type application/x-www-form-urlencoded and authentication
+ /*
+ void* hFile = XBMC->OpenFileForWrite(request.GetUrl().c_str(), 0);
+ if (hFile != NULL)
+ {
+
+ int rc = XBMC->WriteFile(hFile, buffer.c_str(), buffer.length());
+ if (rc >= 0)
+ {
+ std::string result;
+ result.clear();
+ char buffer[1024];
+ while (XBMC->ReadFileString(hFile, buffer, 1023))
+ result.append(buffer);
+
+ }
+ else
+ {
+ XBMC->Log(LOG_ERROR, "can not write to %s",request.GetUrl().c_str());
+ }
+
+ XBMC->CloseFile(hFile);
+ }
+ else
+ {
+ XBMC->Log(LOG_ERROR, "can not open %s for write", request.GetUrl().c_str());
+ }
+
+ */
+ m_responseData.clear();
+ m_responseData.append(message);
+ return 200;
+}
+
+bool HttpPostClient::SendRequest(HttpWebRequest& request)
+{
+ m_lastReqeuestErrorCode = SendPostRequest(request);
+ return (m_lastReqeuestErrorCode == 200);
+}
+
+HttpWebResponse* HttpPostClient::GetResponse()
+{
+ if (m_lastReqeuestErrorCode != 200)
+ {
+ return NULL;
+ }
+ HttpWebResponse* response = new HttpWebResponse(200, m_responseData);
+ return response;
+}
+
+void HttpPostClient::GetLastError(std::string& err)
+{
+
+}
+
+void HttpPostClient::UrlEncode(const std::string& str, std::string& outEncodedStr)
+{
+ outEncodedStr.append(url_encode(str.c_str()));
+}
+
View
28 addons/pvr.dvblink/src/HttpPostClient.h
@@ -0,0 +1,28 @@
+
+#include "libdvblinkremote/dvblinkremote.h"
+#include "libdvblinkremote/dvblinkremotehttp.h"
+#include "libXBMC_addon.h"
+
+using namespace dvblinkremotehttp;
+using namespace ADDON;
+
+class HttpPostClient : public HttpClient
+{
+public :
+ bool SendRequest(HttpWebRequest& request);
+ HttpWebResponse* GetResponse();
+ void GetLastError(std::string& err);
+ void UrlEncode(const std::string& str, std::string& outEncodedStr);
+ HttpPostClient(CHelper_libXBMC_addon *XBMC, const std::string& server, const int serverport, const std::string& username, const std::string& password);
+
+private :
+ int SendPostRequest(HttpWebRequest& request);
+ std::string m_server;
+ long m_serverport;
+ std::string m_username;
+ std::string m_password;
+ CHelper_libXBMC_addon *XBMC;
+ std::string m_responseData;
+ int m_lastReqeuestErrorCode;
+
+};
View
131 addons/pvr.dvblink/src/base64.cpp
@@ -0,0 +1,131 @@
+/*
+ base64.cpp and base64.h
+
+ Copyright (C) 2004-2008 René Nyffenegger
+
+ This source code is provided 'as-is', without any express or implied
+ warranty. In no event will the author be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this source code must not be misrepresented; you must not
+ claim that you wrote the original source code. If you use this source code
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original source code.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ René Nyffenegger rene.nyffenegger@adp-gmbh.ch
+
+ Code modified to meet XBMC stand coding style by Palle Ehmsen (Palle@barcodemadness.com) 2012
+*/
+
+#include "base64.h"
+#include <iostream>
+
+static const std::string BASE64_CHARS =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+
+static inline bool is_base64(unsigned char c)
+{
+ return (isalnum(c) || (c == '+') || (c == '/'));
+}
+
+std::string base64_encode(char const* bytes_to_encode, unsigned int in_len)
+{
+ std::string ret;
+ int i = 0;
+ int j = 0;
+ unsigned char char_array_3[3];
+ unsigned char char_array_4[4];
+
+ while (in_len--)
+ {
+ char_array_3[i++] = *(bytes_to_encode++);
+ if (i == 3)
+ {
+ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+ char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+ char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+ char_array_4[3] = char_array_3[2] & 0x3f;
+
+ for (i = 0; (i <4) ; i++)
+ ret += BASE64_CHARS[char_array_4[i]];
+ i = 0;
+ }
+ }
+
+ if (i)
+ {
+ for (j = i; j < 3; j++)
+ char_array_3[j] = '\0';
+
+ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+ char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+ char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+ char_array_4[3] = char_array_3[2] & 0x3f;
+
+ for (j = 0; (j < i + 1); j++)
+ ret += BASE64_CHARS[char_array_4[j]];
+
+ while ((i++ < 3))
+ ret += '=';
+
+ }
+ return ret;
+}
+
+std::string base64_decode(std::string const& encoded_string)
+{
+ int in_len = encoded_string.size();
+ int i = 0;
+ int j = 0;
+ int in_ = 0;
+ unsigned char char_array_4[4], char_array_3[3];
+ std::string ret;
+
+ while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_]))
+ {
+ char_array_4[i++] = encoded_string[in_]; in_++;
+ if (i ==4)
+ {
+ for (i = 0; i <4; i++)
+ char_array_4[i] = BASE64_CHARS.find(char_array_4[i]);
+
+ char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+ for (i = 0; (i < 3); i++)
+ ret += char_array_3[i];
+ i = 0;
+ }
+ }
+
+ if (i)
+ {
+ for (j = i; j <4; j++)
+ char_array_4[j] = 0;
+
+ for (j = 0; j <4; j++)
+ char_array_4[j] = BASE64_CHARS.find(char_array_4[j]);
+
+ char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+ for (j = 0; (j < i - 1); j++)
+ ret += char_array_3[j];
+ }
+
+ return ret;
+}
View
4 addons/pvr.dvblink/src/base64.h
@@ -0,0 +1,4 @@
+#include <string>
+
+std::string base64_encode(char const* , unsigned int len);
+std::string base64_decode(std::string const& s);
View
718 addons/pvr.dvblink/src/client.cpp
@@ -0,0 +1,718 @@
+/*
+ * Copyright (C) 2012 Barcode Madness
+ * http://www.barcodemadness.com
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "client.h"
+#include "xbmc_pvr_dll.h"
+#include "DVBLinkClient.h"
+#include "platform/util/util.h"
+
+//#include "curl/curl.h"
+
+using namespace std;
+using namespace ADDON;
+
+
+#ifdef TARGET_WINDOWS
+#define snprintf _snprintf
+#endif
+
+bool m_bCreated = false;
+ADDON_STATUS m_CurStatus = ADDON_STATUS_UNKNOWN;
+
+
+std::string g_strUserPath = "";
+std::string g_strClientPath = "";
+
+DVBLinkClient* dvblinkclient = NULL;
+
+std::string g_szHostname = DEFAULT_HOST; ///< The Host name or IP of the DVBLink Server
+long g_lPort = DEFAULT_PORT; ///< The DVBLink Connect Server listening port (default: 8080)
+int g_iConnectTimeout = DEFAULT_TIMEOUT; ///< The Socket connection timeout
+DVBLINK_STREAMTYPE g_eStreamType = DEFAULT_STREAMTYPE; ///< Stream type used by video stream
+std::string g_szClientname = DEFAULT_CLIENTNAME; ///< Name of dvblink client
+std::string g_szUsername = DEFAULT_USERNAME; ///< Username
+std::string g_szPassword = DEFAULT_PASSWORD; ///< Password
+bool g_bUseChlHandle = DEFAULT_USECHLHANDLE; ///< Use channel handle instead of client id
+bool g_bShowInfoMSG = DEFAULT_SHOWINFOMSG; ///< Show information messages
+int g_iHeight = DEFAULT_HEIGHT; ///< Height of stream when using transcoding
+int g_iWidth = DEFAULT_WIDTH; ///< Width of stream when using transcoding
+int g_iBitrate = DEFAULT_BITRATE; ///< Bitrate of stream when using transcoding
+std::string g_szAudiotrack = DEFAULT_AUDIOTRACK; ///< Audiotrack to include in stream when using transcoding
+
+
+CHelper_libXBMC_addon *XBMC = NULL;
+CHelper_libXBMC_pvr *PVR = NULL;
+
+extern "C" {
+
+
+ADDON_STATUS ADDON_Create(void* hdl, void* props)
+{
+ if (!hdl || !props)
+ return ADDON_STATUS_UNKNOWN;
+
+ PVR_PROPERTIES* pvrprops = (PVR_PROPERTIES*)props;
+
+ XBMC = new CHelper_libXBMC_addon;
+ if (!XBMC->RegisterMe(hdl))
+ {
+ SAFE_DELETE(XBMC);
+ return ADDON_STATUS_PERMANENT_FAILURE;
+ }
+
+ PVR = new CHelper_libXBMC_pvr;
+ if (!PVR->RegisterMe(hdl))
+ {
+ SAFE_DELETE(PVR);
+ SAFE_DELETE(XBMC);
+ return ADDON_STATUS_PERMANENT_FAILURE;
+ }
+
+ XBMC->Log(LOG_DEBUG, "%s - Creating the PVR DVBlink add-on", __FUNCTION__);
+
+ m_CurStatus = ADDON_STATUS_UNKNOWN;
+ g_strUserPath = pvrprops->strUserPath;
+ g_strClientPath = pvrprops->strClientPath;
+
+ char * buffer = (char*) malloc(128);
+ buffer[0] = 0;
+
+ /* Connection settings */
+ /***********************/
+
+ if (XBMC->GetSetting("host", buffer))
+ {
+ g_szHostname = buffer;
+ }
+ else
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'host' setting, falling back to '127.0.0.1' as default");
+ g_szHostname = DEFAULT_HOST;
+ }
+
+ /* Read setting "client" from settings.xml */
+ if (XBMC->GetSetting("client", buffer))
+ {
+ g_szClientname = buffer;
+ }
+ else
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'clientname' setting, falling back to 'xbmc' as default");
+ g_szClientname = DEFAULT_CLIENTNAME;
+ }
+
+ /* Read setting "username" from settings.xml */
+ if (XBMC->GetSetting("username", buffer))
+ {
+ g_szUsername = buffer;
+ }
+ else
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'username' setting, falling back to '' as default");
+ g_szUsername = DEFAULT_USERNAME;
+ }
+
+ /* Read setting "password" from settings.xml */
+ if (XBMC->GetSetting("password", buffer))
+ {
+ g_szPassword = buffer;
+ }
+ else
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'password' setting, falling back to '' as default");
+ g_szPassword = DEFAULT_PASSWORD;
+ }
+
+ /* Read setting "streamtype" from settings.xml */
+ if (!XBMC->GetSetting("streamtype", &g_eStreamType))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'streamtype' setting, falling back to 'http' as default");
+ g_eStreamType = DEFAULT_STREAMTYPE;
+ }
+
+ /* Read setting "port" from settings.xml */
+ if (!XBMC->GetSetting("port", &g_lPort))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'port' setting, falling back to '8080' as default");
+ g_lPort = DEFAULT_PORT;
+ }
+
+ /* Read setting "timeout" from settings.xml */
+ if (!XBMC->GetSetting("timeout", &g_iConnectTimeout))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'timeout' setting, falling back to %i seconds as default", DEFAULT_TIMEOUT);
+ g_iConnectTimeout = DEFAULT_TIMEOUT;
+ }
+
+ /* Read setting "ch_handle" from settings.xml */
+ if (!XBMC->GetSetting("ch_handle", &g_bUseChlHandle))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'ch_handle' setting, falling back to 'true' as default");
+ g_bUseChlHandle = DEFAULT_USECHLHANDLE;
+ }
+
+ /* Read setting "ch_handle" from settings.xml */
+ if (!XBMC->GetSetting("showinfomsg", &g_bShowInfoMSG))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'showinfomsg' setting, falling back to 'true' as default");
+ g_bShowInfoMSG = DEFAULT_SHOWINFOMSG;
+ }
+
+ /* Read setting "height" from settings.xml */
+ if (!XBMC->GetSetting("height", &g_iHeight))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'Height' setting, falling back to '720' as default");
+ g_iHeight = DEFAULT_HEIGHT;
+ }
+
+ /* Read setting "width" from settings.xml */
+ if (!XBMC->GetSetting("width", &g_iWidth))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'Width' setting, falling back to '576' as default");
+ g_iWidth = DEFAULT_WIDTH;
+ }
+
+ /* Read setting "bitrate" from settings.xml */
+ if (!XBMC->GetSetting("bitrate", &g_iBitrate))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'Biterate' setting, falling back to '512' as default");
+ g_iBitrate = DEFAULT_BITRATE;
+ }
+
+ /* Read setting "audiotrack" from settings.xml */
+ if (XBMC->GetSetting("audiotrack", buffer))
+ {
+ g_szAudiotrack = buffer;
+ }else
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'Audiotrack' setting, falling back to 'eng' as default");
+ g_szAudiotrack = DEFAULT_AUDIOTRACK;
+ }
+
+ /* Log the current settings for debugging purposes */
+ XBMC->Log(LOG_DEBUG, "settings: streamtype='%i' host='%s', port=%i, timeout=%i", g_eStreamType, g_szHostname.c_str(), g_lPort, g_iConnectTimeout);
+
+ dvblinkclient = new DVBLinkClient(XBMC,PVR, g_szClientname, g_szHostname, g_lPort, g_bShowInfoMSG, g_szUsername,g_szPassword);
+
+ m_CurStatus = ADDON_STATUS_OK;
+ m_bCreated = true;
+ return m_CurStatus;
+}
+
+ADDON_STATUS ADDON_GetStatus()
+{
+ return m_CurStatus;
+}
+
+void ADDON_Destroy()
+{
+ delete dvblinkclient;
+ m_bCreated = false;
+ m_CurStatus = ADDON_STATUS_UNKNOWN;
+}
+
+bool ADDON_HasSettings()
+{
+ return true;
+}
+
+unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet)
+{
+ return 0;
+}
+
+ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
+{
+ string str = settingName;
+
+ if (str == "host")
+ {
+ string tmp_sHostname;
+ XBMC->Log(LOG_INFO, "Changed Setting 'host' from %s to %s", g_szHostname.c_str(), (const char*) settingValue);
+ tmp_sHostname = g_szHostname;
+ g_szHostname = (const char*) settingValue;
+ if (tmp_sHostname != g_szHostname)
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ else if (str == "client")
+ {
+ string tmp_sClientname;
+ XBMC->Log(LOG_INFO, "Changed Setting 'client' from %s to %s", g_szClientname.c_str(), (const char*) settingValue);
+ tmp_sClientname = g_szClientname;
+ g_szClientname = (const char*) settingValue;
+ if (tmp_sClientname != g_szClientname)
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ else if (str == "username")
+ {
+ string tmp_sUsername;
+ XBMC->Log(LOG_INFO, "Changed Setting 'username' from %s to %s", g_szUsername.c_str(), (const char*) settingValue);
+ tmp_sUsername = g_szUsername;
+ g_szUsername = (const char*) settingValue;
+ if (tmp_sUsername != g_szUsername)
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ else if (str == "password")
+ {
+ string tmp_sPassword;
+ XBMC->Log(LOG_INFO, "Changed Setting 'password' from %s to %s", g_szPassword.c_str(), (const char*) settingValue);
+ tmp_sPassword = g_szPassword;
+ g_szPassword = (const char*) settingValue;
+ if (tmp_sPassword != g_szPassword)
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ else if (str == "streamtype")
+ {
+ DVBLINK_STREAMTYPE tmp_eStreamtype;
+ XBMC->Log(LOG_INFO, "Changed Setting 'streamtype' from %i to %i", g_eStreamType, *(const DVBLINK_STREAMTYPE *) settingValue);
+ tmp_eStreamtype = g_eStreamType;
+ g_eStreamType = *((const DVBLINK_STREAMTYPE *)settingValue);
+ if (tmp_eStreamtype != g_eStreamType)
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ else if (str == "port")
+ {
+ XBMC->Log(LOG_INFO, "Changed Setting 'port' from %i to %i", g_lPort, *(int*) settingValue);
+ if (g_lPort != (long)(*(int*) settingValue))
+ {
+ g_lPort = (long)(*(int*) settingValue);
+ XBMC->Log(LOG_INFO, "Changed Setting 'port' to %i", g_lPort);
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ }
+ else if (str == "timeout")
+ {
+ XBMC->Log(LOG_INFO, "Changed setting 'timeout' from %u to %u", g_iConnectTimeout, *(int*) settingValue);
+ g_iConnectTimeout = *(int*) settingValue;
+ }
+ else if (str == "ch_handle")
+ {
+ XBMC->Log(LOG_INFO, "Changed Setting 'ch_handle' from %u to %u", g_bUseChlHandle, *(int*) settingValue);
+ g_bUseChlHandle = *(bool*) settingValue;
+ }
+ else if (str == "showinfomsg")
+ {
+ XBMC->Log(LOG_INFO, "Changed Setting 'showinfomsg' from %u to %u", g_bShowInfoMSG, *(int*) settingValue);
+ g_bShowInfoMSG = *(bool*) settingValue;
+ }
+ else if (str == "height")
+ {
+ XBMC->Log(LOG_INFO, "Changed Setting 'height' from %u to %u", g_iHeight, *(int*) settingValue);
+ g_iHeight = *(int*) settingValue;
+ }
+ else if (str == "width")
+ {
+ XBMC->Log(LOG_INFO, "Changed Setting 'width' from %u to %u", g_iWidth, *(int*) settingValue);
+ g_iWidth = *(int*) settingValue;
+ }
+ else if (str == "bitrate")
+ {
+ XBMC->Log(LOG_INFO, "Changed Setting 'bitrate' from %u to %u", g_iBitrate, *(int*) settingValue);
+ g_iBitrate = *(int*) settingValue;
+ }
+ else if (str == "audiotrack")
+ {
+ string tmp_sAudiotrack;
+ XBMC->Log(LOG_INFO, "Changed Setting 'audiotrack' from %s to %s", g_szAudiotrack.c_str(), (const char*) settingValue);
+ tmp_sAudiotrack = g_szAudiotrack;
+ g_szAudiotrack = (const char*) settingValue;
+ if (tmp_sAudiotrack != g_szAudiotrack)
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ return ADDON_STATUS_OK;
+}
+
+void ADDON_Stop()
+{
+}
+
+void ADDON_FreeSettings()
+{
+}
+
+/***********************************************************
+ * PVR Client AddOn specific public library functions
+ ***********************************************************/
+
+const char* GetPVRAPIVersion(void)
+{
+ static const char *strApiVersion = XBMC_PVR_API_VERSION;
+ return strApiVersion;
+}
+
+const char* GetMininumPVRAPIVersion(void)
+{
+ static const char *strMinApiVersion = XBMC_PVR_MIN_API_VERSION;
+ return strMinApiVersion;
+}
+
+PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES* pCapabilities)
+{
+ pCapabilities->bSupportsEPG = true;
+ pCapabilities->bSupportsRecordings = true; //TODO: ADD when possible to see recording
+ pCapabilities->bSupportsTimers = true;
+ pCapabilities->bSupportsTV = true;
+ pCapabilities->bSupportsRadio = true;
+ pCapabilities->bHandlesInputStream = true;
+ return PVR_ERROR_NO_ERROR;
+}
+
+const char *GetBackendName(void)
+{
+ static const char *strBackendName = "DVBLink Connect! Server";
+ return strBackendName;
+}
+
+const char *GetBackendVersion(void)
+{
+ static const char * strBackendVersion = "0.2";
+ return strBackendVersion;
+}
+
+const char *GetConnectionString(void)
+{
+ return g_szHostname.c_str();
+}
+
+PVR_ERROR GetDriveSpace(long long *iTotal, long long *iUsed)
+{
+ if (dvblinkclient)
+ {
+ *iTotal = dvblinkclient->GetTotalDiskSpace();
+ *iUsed = (*iTotal) - dvblinkclient->GetFreeDiskSpace();
+ return PVR_ERROR_NO_ERROR;
+ }
+ else
+ {
+ *iTotal = 0;
+ *iUsed = 0;
+ return PVR_ERROR_SERVER_ERROR;
+ }
+}
+
+PVR_ERROR GetEPGForChannel(ADDON_HANDLE handle, const PVR_CHANNEL &channel, time_t iStart, time_t iEnd)
+{
+ if (dvblinkclient)
+ return dvblinkclient->GetEPGForChannel(handle, channel, iStart, iEnd);
+
+ return PVR_ERROR_SERVER_ERROR;
+}
+
+int GetChannelsAmount(void)
+{
+ if (dvblinkclient)
+ return dvblinkclient->GetChannelsAmount();
+
+ return -1;
+}
+
+PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio)
+{
+ if (dvblinkclient)
+ return dvblinkclient->GetChannels(handle, bRadio);
+
+ return PVR_ERROR_SERVER_ERROR;
+}
+
+bool OpenLiveStream(const PVR_CHANNEL &channel)
+{
+ return false;
+}
+
+void CloseLiveStream(void)
+{
+ dvblinkclient->StopStreaming(g_bUseChlHandle);
+}
+
+const char * GetLiveStreamURL(const PVR_CHANNEL &channel)
+{
+ return dvblinkclient->GetLiveStreamURL(channel, g_eStreamType, g_iWidth, g_iHeight, g_iBitrate, g_szAudiotrack);
+}
+
+int GetTimersAmount(void)
+{
+ if (dvblinkclient)