Permalink
Browse files

Merge branch 'PR51'. closes #51

  • Loading branch information...
2 parents c24b64a + 11dfc93 commit e425e9f166adf73aed6d38570fb00ea652abc7ed @opdenkamp committed Oct 9, 2012
View
1 addons/Makefile.am
@@ -1,6 +1,7 @@
SUBDIRS = pvr.demo \
pvr.hts \
pvr.mediaportal.tvserver \
+ pvr.nextpvr \
pvr.vdr.vnsi \
pvr.njoy \
pvr.vuplus
View
24 addons/pvr.nextpvr/Makefile.am
@@ -0,0 +1,24 @@
+#
+# Makefile for the NextPVR add-on for XBMC PVR
+#
+# See the README for copyright information and
+# how to reach the author.
+#
+
+ADDONBINNAME = XBMC_NextPVR
+ADDONNAME = pvr.nextpvr
+LIBNAME = libnextpvr-addon
+lib_LTLIBRARIES = libnextpvr-addon.la
+
+LIBS = @abs_top_srcdir@/lib/tinyxml/libtinyxml.la
+
+include ../Makefile.include.am
+
+INCLUDES+=-Isrc
+
+libnextpvr_addon_la_SOURCES = src/client.cpp \
+ src/pvrclient-nextpvr.cpp \
+ src/Socket.cpp \
+ src/uri.cpp \
+ src/md5.cpp \
+ src/RingBuffer.cpp
View
22 addons/pvr.nextpvr/addon/addon.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<addon
+ id="pvr.nextpvr"
+ version="1.0.0.0"
+ name="NextPVR PVR Client"
+ provider-name="Graeme Blackley">
+ <requires>
+ <c-pluff version="0.1"/>
+ </requires>
+ <extension
+ point="xbmc.pvrclient"
+ library_linux="XBMC_NextPVR.pvr"
+ library_osx="XBMC_NextPVR.pvr"
+ library_wingl="XBMC_NextPVR_win32.pvr"
+ library_windx="XBMC_NextPVR_win32.pvr"/>
+ <extension point="xbmc.addon.metadata">
+ <summary>XBMC frontend for the NextPVR</summary>
+ <description>NextPVR frontend. Supports streaming of Live TV &amp; Recordings, listening to Radio channels and EPG.</description>
+ <disclaimer>This is a work in progress. Use at your own risk.</disclaimer>
+ <platform>all</platform>
+ </extension>
+</addon>
View
2 addons/pvr.nextpvr/addon/changelog.txt
@@ -0,0 +1,2 @@
+v1.0.0.0
+- Created
View
BIN addons/pvr.nextpvr/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
65 addons/pvr.nextpvr/addon/resources/language/English/strings.po
@@ -0,0 +1,65 @@
+# XBMC Media Center language file
+# Addon Name: NextPVR PVR addon
+# Addon id: pvr.nextpvr
+# Addon version: 1.2.3.114
+# Addon Provider: Graeme Blackley
+msgid ""
+msgstr ""
+"Project-Id-Version: pvr.nextpvr-Frodo\n"
+"Report-Msgid-Bugs-To: nowhere@nowhere.com\n"
+"POT-Creation-Date: 2012-06-03 16:35+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"
+
+msgctxt "Addon Summary"
+msgid "XBMC frontend for the NextPVR"
+msgstr ""
+
+msgctxt "Addon Description"
+msgid "NextPVR frontend. Supports streaming of Live TV &amp; Recordings, listening to Radio channels and EPG. "
+msgstr ""
+
+msgctxt "Addon Disclaimer"
+msgid "This is unstable software! The authors are in no way responsible for failed recordings, incorrect timers, wasted hours, or any other undesirable effects."
+msgstr ""
+
+# Settings labels
+###########################
+
+msgctxt "#30000"
+msgid "NextPVR Hostname"
+msgstr ""
+
+msgctxt "#30001"
+msgid "NextPVR Port (usually 8866 or 7799)"
+msgstr ""
+
+msgctxt "#30002"
+msgid "NextPVR PinCode"
+msgstr ""
+
+# Category labels
+###########################
+msgctxt "#30040"
+msgid "Connection"
+msgstr ""
+
+# on-screen error messages
+###########################
+msgctxt "#30050"
+msgid "NextPVR server is too old."
+msgstr ""
+
+msgctxt "#30051"
+msgid "Upgrade to '2.5.8' or higher!"
+msgstr ""
+
+msgctxt "#30052"
+msgid "Connection failed. Incorrect PIN?"
+msgstr ""
View
9 addons/pvr.nextpvr/addon/resources/settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<settings>
+ <!-- Connection -->
+ <category label="30040">
+ <setting id="host" type="text" label="30000" option="urlencoded" default="127.0.0.1" />
+ <setting id="port" type="number" label="30001" default="8866" />
+ <setting id="pin" type="text" label="30002" default="0000" />
+ </category>
+</settings>
View
140 addons/pvr.nextpvr/project/VS2010Express/XBMC_NextPVR.vcxproj
@@ -0,0 +1,140 @@
+<?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">
+ <ProjectName>pvr.nextpvr</ProjectName>
+ <ProjectGuid>{AAE3A937-C7CA-4A43-BCFC-C39C253820CC}</ProjectGuid>
+ <RootNamespace>XBMC_MPTV</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\addon\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</IgnoreImportLibrary>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</PostBuildEventUseInBuild>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\addon\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">XBMC_NextPVR_win32</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.pvr</TargetExt>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">XBMC_NextPVR_win32</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.pvr</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\..\xbmc;..\..\..\..\lib;..\..\..\..\lib\platform\windows;..\..\src</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>TARGET_WINDOWS;_WINSOCKAPI_;_DEBUG;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <PostBuildEvent>
+ <Command>
+ </Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\..\xbmc;..\..\..\..\lib;..\..\..\..\lib\platform\windows;..\..\src</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>TARGET_WINDOWS;_WINSOCKAPI_;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>TurnOffAllWarnings</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>
+ </OptimizeReferences>
+ <EnableCOMDATFolding>
+ </EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\..\project\VS2010Express\platform\platform.vcxproj">
+ <Project>{fe4573f6-a794-4ad3-b37f-49e51f1140e6}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\project\VS2010Express\tinyxml\tinyxml.vcxproj">
+ <Project>{bdc7d21d-9fd9-41aa-bec8-8b70e1448c50}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\client.cpp" />
+ <ClCompile Include="..\..\src\md5.cpp" />
+ <ClCompile Include="..\..\src\pvrclient-nextpvr.cpp" />
+ <ClCompile Include="..\..\src\RingBuffer.cpp" />
+ <ClCompile Include="..\..\src\Socket.cpp" />
+ <ClCompile Include="..\..\src\uri.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\client.h" />
+ <ClInclude Include="..\..\src\md5.h" />
+ <ClInclude Include="..\..\src\pvrclient-nextpvr.h" />
+ <ClInclude Include="..\..\src\RingBuffer.h" />
+ <ClInclude Include="..\..\src\Socket.h" />
+ <ClInclude Include="..\..\src\uri.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
View
53 addons/pvr.nextpvr/project/VS2010Express/XBMC_NextPVR.vcxproj.filters
@@ -0,0 +1,53 @@
+<?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;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>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\client.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\Socket.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\uri.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\pvrclient-nextpvr.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\md5.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\RingBuffer.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\client.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\Socket.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\uri.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\pvrclient-nextpvr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\RingBuffer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\md5.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
View
10 addons/pvr.nextpvr/src/FileUtils.h
@@ -0,0 +1,10 @@
+#include <string>
+
+namespace OS
+{
+ class CFile
+ {
+ public:
+ static bool Exists(const std::string& strFileName);
+ };
+};
View
22 addons/pvr.nextpvr/src/README
@@ -0,0 +1,22 @@
+XBMC NextPVR Add-on
+----------------------------------------------
+Written by: Graeme Blackley
+HomePage: http://www.nextpvr.com
+Contact: http://www.nextpvr.com/contact/
+
+----------------------------------------------
+Supported platforms:
+- Windows
+- Linux
+- OSX (should work, not tested by me)
+
+Dependencies:
+- NextPVR 2.6. May work also 2.5.8 (which is 2.5 + extra patches)
+
+This addon 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
+any later version.
+See the file LICENSE.GPL for more information.
+
+
View
245 addons/pvr.nextpvr/src/RingBuffer.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2010 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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 "RingBuffer.h"
+
+#include <cstring>
+#include <cstdlib>
+#include <algorithm>
+
+/* Constructor */
+CRingBuffer::CRingBuffer()
+{
+ m_buffer = NULL;
+ m_size = 0;
+ m_readPtr = 0;
+ m_writePtr = 0;
+ m_fillCount = 0;
+}
+
+/* Destructor */
+CRingBuffer::~CRingBuffer()
+{
+ Destroy();
+}
+
+/* Create a ring buffer with the specified 'size' */
+bool CRingBuffer::Create(unsigned int size)
+{
+ m_buffer = (char*)malloc(size);
+ if (m_buffer != NULL)
+ {
+ m_size = size;
+ return true;
+ }
+ return false;
+}
+
+/* Free the ring buffer and set all values to NULL or 0 */
+void CRingBuffer::Destroy()
+{
+ if (m_buffer != NULL)
+ {
+ free(m_buffer);
+ m_buffer = NULL;
+ }
+ m_size = 0;
+ m_readPtr = 0;
+ m_writePtr = 0;
+ m_fillCount = 0;
+}
+
+/* Clear the ring buffer */
+void CRingBuffer::Clear()
+{
+ m_readPtr = 0;
+ m_writePtr = 0;
+ m_fillCount = 0;
+}
+
+/* Read in data from the ring buffer to the supplied buffer 'buf'. The amount
+ * read in is specified by 'size'.
+ */
+bool CRingBuffer::ReadData(char *buf, unsigned int size)
+{
+ if (size > m_fillCount)
+ {
+ return false;
+ }
+ if (size + m_readPtr > m_size)
+ {
+ unsigned int chunk = m_size - m_readPtr;
+ memcpy(buf, m_buffer + m_readPtr, chunk);
+ memcpy(buf + chunk, m_buffer, size - chunk);
+ m_readPtr = size - chunk;
+ }
+ else
+ {
+ memcpy(buf, m_buffer + m_readPtr, size);
+ m_readPtr += size;
+ }
+ if (m_readPtr == m_size)
+ m_readPtr = 0;
+ m_fillCount -= size;
+ return true;
+}
+
+/* Read in data from the ring buffer to another ring buffer object specified by
+ * 'rBuf'.
+ */
+bool CRingBuffer::ReadData(CRingBuffer &rBuf, unsigned int size)
+{
+ if (rBuf.getBuffer() == NULL)
+ rBuf.Create(size);
+
+ bool bOk = size <= rBuf.getMaxWriteSize() && size <= getMaxReadSize();
+ if (bOk)
+ {
+ unsigned int chunksize = std::min(size, m_size - m_readPtr);
+ bOk = rBuf.WriteData(&getBuffer()[m_readPtr], chunksize);
+ if (bOk && chunksize < size)
+ bOk = rBuf.WriteData(&getBuffer()[0], size - chunksize);
+ if (bOk)
+ SkipBytes(size);
+ }
+
+ return bOk;
+}
+
+/* Write data to ring buffer from buffer specified in 'buf'. Amount read in is
+ * specified by 'size'.
+ */
+bool CRingBuffer::WriteData(char *buf, unsigned int size)
+{
+ if (size > m_size - m_fillCount)
+ {
+ return false;
+ }
+ if (size + m_writePtr > m_size)
+ {
+ unsigned int chunk = m_size - m_writePtr;
+ memcpy(m_buffer + m_writePtr, buf, chunk);
+ memcpy(m_buffer, buf + chunk, size - chunk);
+ m_writePtr = size - chunk;
+ }
+ else
+ {
+ memcpy(m_buffer + m_writePtr, buf, size);
+ m_writePtr += size;
+ }
+ if (m_writePtr == m_size)
+ m_writePtr = 0;
+ m_fillCount += size;
+ return true;
+}
+
+/* Write data to ring buffer from another ring buffer object specified by
+ * 'rBuf'.
+ */
+bool CRingBuffer::WriteData(CRingBuffer &rBuf, unsigned int size)
+{
+ if (m_buffer == NULL)
+ Create(size);
+
+ bool bOk = size <= rBuf.getMaxReadSize() && size <= getMaxWriteSize();
+ if (bOk)
+ {
+ unsigned int readpos = rBuf.getReadPtr();
+ unsigned int chunksize = std::min(size, rBuf.getSize() - readpos);
+ bOk = WriteData(&rBuf.getBuffer()[readpos], chunksize);
+ if (bOk && chunksize < size)
+ bOk = WriteData(&rBuf.getBuffer()[0], size - chunksize);
+ }
+
+ return bOk;
+}
+
+/* Skip bytes in buffer to be read */
+bool CRingBuffer::SkipBytes(int skipSize)
+{
+ if (skipSize < 0)
+ {
+ return false; // skipping backwards is not supported
+ }
+
+ unsigned int size = skipSize;
+ if (size > m_fillCount)
+ {
+ return false;
+ }
+ if (size + m_readPtr > m_size)
+ {
+ unsigned int chunk = m_size - m_readPtr;
+ m_readPtr = size - chunk;
+ }
+ else
+ {
+ m_readPtr += size;
+ }
+ if (m_readPtr == m_size)
+ m_readPtr = 0;
+ m_fillCount -= size;
+ return true;
+}
+
+/* Append all content from ring buffer 'rBuf' to this ring buffer */
+bool CRingBuffer::Append(CRingBuffer &rBuf)
+{
+ return WriteData(rBuf, rBuf.getMaxReadSize());
+}
+
+/* Copy all content from ring buffer 'rBuf' to this ring buffer overwriting any existing data */
+bool CRingBuffer::Copy(CRingBuffer &rBuf)
+{
+ Clear();
+ return Append(rBuf);
+}
+
+/* Our various 'get' methods */
+char *CRingBuffer::getBuffer()
+{
+ return m_buffer;
+}
+
+unsigned int CRingBuffer::getSize()
+{
+ return m_size;
+}
+
+unsigned int CRingBuffer::getReadPtr()
+{
+ return m_readPtr;
+}
+
+unsigned int CRingBuffer::getWritePtr()
+{
+ return m_writePtr;
+}
+
+unsigned int CRingBuffer::getMaxReadSize()
+{
+ return m_fillCount;
+}
+
+unsigned int CRingBuffer::getMaxWriteSize()
+{
+ return m_size - m_fillCount;
+}
View
50 addons/pvr.nextpvr/src/RingBuffer.h
@@ -0,0 +1,50 @@
+#pragma once
+/*
+ * Copyright (C) 2010 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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
+ *
+ */
+
+
+class CRingBuffer
+{
+ char *m_buffer;
+ unsigned int m_size;
+ unsigned int m_readPtr;
+ unsigned int m_writePtr;
+ unsigned int m_fillCount;
+public:
+ CRingBuffer();
+ ~CRingBuffer();
+ bool Create(unsigned int size);
+ void Destroy();
+ void Clear();
+ bool ReadData(char *buf, unsigned int size);
+ bool ReadData(CRingBuffer &rBuf, unsigned int size);
+ bool WriteData(char *buf, unsigned int size);
+ bool WriteData(CRingBuffer &rBuf, unsigned int size);
+ bool SkipBytes(int skipSize);
+ bool Append(CRingBuffer &rBuf);
+ bool Copy(CRingBuffer &rBuf);
+ char *getBuffer();
+ unsigned int getSize();
+ unsigned int getReadPtr();
+ unsigned int getWritePtr();
+ unsigned int getMaxReadSize();
+ unsigned int getMaxWriteSize();
+};
View
781 addons/pvr.nextpvr/src/Socket.cpp
@@ -0,0 +1,781 @@
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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 of the License, 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "libXBMC_addon.h"
+#include <string>
+#include "platform/os.h"
+#include "client.h"
+#include "Socket.h"
+
+using namespace std;
+using namespace ADDON;
+using namespace NextPVR;
+
+namespace NextPVR
+{
+
+/* Master defines for client control */
+#define RECEIVE_TIMEOUT 6 //sec
+
+Socket::Socket(const enum SocketFamily family, const enum SocketDomain domain, const enum SocketType type, const enum SocketProtocol protocol)
+{
+ _sd = INVALID_SOCKET;
+ _family = family;
+ _domain = domain;
+ _type = type;
+ _protocol = protocol;
+ memset (&_sockaddr, 0, sizeof( _sockaddr ) );
+}
+
+
+Socket::Socket()
+{
+ // Default constructor, default settings
+ _sd = INVALID_SOCKET;
+ _family = af_inet;
+ _domain = pf_inet;
+ _type = sock_stream;
+ _protocol = tcp;
+ memset (&_sockaddr, 0, sizeof( _sockaddr ) );
+}
+
+
+Socket::~Socket()
+{
+ close();
+}
+
+bool Socket::setHostname ( const std::string& host )
+{
+ if (isalpha(host.c_str()[0]))
+ {
+ // host address is a name
+ struct hostent *he = NULL;
+ if ((he = gethostbyname( host.c_str() )) == 0)
+ {
+ errormessage( getLastError(), "Socket::setHostname");
+ return false;
+ }
+
+ _sockaddr.sin_addr = *((in_addr *) he->h_addr);
+ }
+ else
+ {
+ _sockaddr.sin_addr.s_addr = inet_addr(host.c_str());
+ }
+ return true;
+}
+
+bool Socket::read_ready()
+{
+ fd_set fdset;
+
+ FD_ZERO(&fdset);
+ FD_SET(_sd, &fdset);
+
+ struct timeval tv;
+ tv.tv_sec = 1;
+
+ int retVal = select(_sd+1, &fdset, NULL, NULL, &tv);
+ if (retVal > 0)
+ return true;
+ return false;
+}
+
+
+bool Socket::close()
+{
+ if (is_valid())
+ {
+ if (_sd != SOCKET_ERROR)
+#ifdef TARGET_WINDOWS
+ closesocket(_sd);
+#else
+ ::close(_sd);
+#endif
+ _sd = INVALID_SOCKET;
+ osCleanup();
+ return true;
+ }
+ return false;
+}
+
+bool Socket::create()
+{
+ if( is_valid() )
+ {
+ close();
+ }
+
+ if(!osInit())
+ {
+ return false;
+ }
+
+ _sd = socket(_family, _type, _protocol );
+ //0 indicates that the default protocol for the type selected is to be used.
+ //For example, IPPROTO_TCP is chosen for the protocol if the type was set to
+ //SOCK_STREAM and the address family is AF_INET.
+
+ if (_sd == INVALID_SOCKET)
+ {
+ errormessage( getLastError(), "Socket::create" );
+ return false;
+ }
+
+ return true;
+}
+
+
+bool Socket::bind ( const unsigned short port )
+{
+
+ if (!is_valid())
+ {
+ return false;
+ }
+
+ _sockaddr.sin_family = _family;
+ _sockaddr.sin_addr.s_addr = INADDR_ANY; //listen to all
+ _sockaddr.sin_port = htons( port );
+
+ int bind_return = ::bind(_sd, (sockaddr*)(&_sockaddr), sizeof(_sockaddr));
+
+ if ( bind_return == -1 )
+ {
+ errormessage( getLastError(), "Socket::bind" );
+ return false;
+ }
+
+ return true;
+}
+
+
+bool Socket::listen() const
+{
+
+ if (!is_valid())
+ {
+ return false;
+ }
+
+ int listen_return = ::listen (_sd, SOMAXCONN);
+ //This is defined as 5 in winsock.h, and 0x7FFFFFFF in winsock2.h.
+ //linux 128//MAXCONNECTIONS =1
+
+ if (listen_return == -1)
+ {
+ errormessage( getLastError(), "Socket::listen" );
+ return false;
+ }
+
+ return true;
+}
+
+
+bool Socket::accept ( Socket& new_socket ) const
+{
+ if (!is_valid())
+ {
+ return false;
+ }
+
+ socklen_t addr_length = sizeof( _sockaddr );
+ new_socket._sd = ::accept(_sd, const_cast<sockaddr*>( (const sockaddr*) &_sockaddr), &addr_length );
+
+ if (new_socket._sd <= 0)
+ {
+ errormessage( getLastError(), "Socket::accept" );
+ return false;
+ }
+
+ return true;
+}
+
+
+int Socket::send ( const std::string& data )
+{
+ if (!is_valid())
+ {
+ return 0;
+ }
+
+ int status = Socket::send( (const char*) data.c_str(), (const unsigned int) data.size());
+
+ return status;
+}
+
+
+int Socket::send ( const char* data, const unsigned int len )
+{
+ fd_set set_w, set_e;
+ struct timeval tv;
+ int result;
+
+ if (!is_valid())
+ {
+ return 0;
+ }
+
+ // fill with new data
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ FD_ZERO(&set_w);
+ FD_ZERO(&set_e);
+ FD_SET(_sd, &set_w);
+ FD_SET(_sd, &set_e);
+
+ result = select(FD_SETSIZE, &set_w, NULL, &set_e, &tv);
+
+ if (result < 0)
+ {
+ XBMC->Log(LOG_ERROR, "Socket::send - select failed");
+ _sd = INVALID_SOCKET;
+ return 0;
+ }
+ if (FD_ISSET(_sd, &set_w))
+ {
+ XBMC->Log(LOG_ERROR, "Socket::send - failed to send data");
+ _sd = INVALID_SOCKET;
+ return 0;
+ }
+
+ int status = ::send(_sd, data, len, 0 );
+
+ if (status == -1)
+ {
+ errormessage( getLastError(), "Socket::send");
+ XBMC->Log(LOG_ERROR, "Socket::send - failed to send data");
+ _sd = INVALID_SOCKET;
+ }
+ return status;
+}
+
+
+int Socket::sendto ( const char* data, unsigned int size, bool sendcompletebuffer)
+{
+ int sentbytes = 0;
+ int i;
+
+ do
+ {
+ i = ::sendto(_sd, data, size, 0, (const struct sockaddr*) &_sockaddr, sizeof( _sockaddr ) );
+
+ if (i <= 0)
+ {
+ errormessage( getLastError(), "Socket::sendto");
+ osCleanup();
+ return i;
+ }
+ sentbytes += i;
+ } while ( (sentbytes < (int) size) && (sendcompletebuffer == true));
+
+ return i;
+}
+
+
+int Socket::receive ( std::string& data, unsigned int minpacketsize ) const
+{
+ char * buf = NULL;
+ int status = 0;
+
+ if (!is_valid())
+ {
+ return 0;
+ }
+
+ buf = new char [ minpacketsize + 1 ];
+ memset ( buf, 0, minpacketsize + 1 );
+
+ status = receive( buf, minpacketsize, minpacketsize );
+
+ data = buf;
+
+ delete[] buf;
+ return status;
+}
+
+//Receive until error or \n
+bool Socket::ReadResponse (int &code, vector<string> &lines)
+{
+ fd_set set_r, set_e;
+ timeval timeout;
+ int result;
+ int retries = 6;
+ char buffer[2048];
+ char cont = 0;
+ string line;
+ size_t pos1 = 0, pos2 = 0, pos3 = 0;
+
+ code = 0;
+
+ while (true)
+ {
+ while ((pos1 = line.find("\r\n", pos3)) != std::string::npos)
+ {
+ pos2 = line.find(cont);
+
+ lines.push_back(line.substr(pos2+1, pos1-pos2-1));
+
+ line.erase(0, pos1 + 2);
+ pos3 = 0;
+ return true;
+ }
+
+ // we only need to recheck 1 byte
+ if (line.size() > 0)
+ {
+ pos3 = line.size() - 1;
+ }
+ else
+ {
+ pos3 = 0;
+ }
+
+ if (cont == ' ')
+ {
+ break;
+ }
+
+ timeout.tv_sec = RECEIVE_TIMEOUT;
+ timeout.tv_usec = 0;
+
+ // fill with new data
+ FD_ZERO(&set_r);
+ FD_ZERO(&set_e);
+ FD_SET(_sd, &set_r);
+ FD_SET(_sd, &set_e);
+ result = select(FD_SETSIZE, &set_r, NULL, &set_e, &timeout);
+
+ if (result < 0)
+ {
+ XBMC->Log(LOG_DEBUG, "CVTPTransceiver::ReadResponse - select failed");
+ lines.push_back("ERROR: Select failed");
+ code = 1; //error
+ _sd = INVALID_SOCKET;
+ return false;
+ }
+
+ if (result == 0)
+ {
+ if (retries != 0)
+ {
+ XBMC->Log(LOG_DEBUG, "CVTPTransceiver::ReadResponse - timeout waiting for response, retrying... (%i)", retries);
+ retries--;
+ continue;
+ } else {
+ XBMC->Log(LOG_DEBUG, "CVTPTransceiver::ReadResponse - timeout waiting for response. Failed after 10 retries.");
+ lines.push_back("ERROR: Failed after 10 retries");
+ code = 1; //error
+ _sd = INVALID_SOCKET;
+ return false;
+ }
+ }
+
+ result = recv(_sd, buffer, sizeof(buffer) - 1, 0);
+ if (result < 0)
+ {
+ XBMC->Log(LOG_DEBUG, "CVTPTransceiver::ReadResponse - recv failed");
+ lines.push_back("ERROR: Recv failed");
+ code = 1; //error
+ _sd = INVALID_SOCKET;
+ return false;
+ }
+ buffer[result] = 0;
+
+ line.append(buffer);
+ }
+
+ return true;
+}
+
+int Socket::receive ( std::string& data) const
+{
+ char buf[MAXRECV + 1];
+ int status = 0;
+
+ if ( !is_valid() )
+ {
+ return 0;
+ }
+
+ memset ( buf, 0, MAXRECV + 1 );
+ status = receive( buf, MAXRECV, 0 );
+ data = buf;
+
+ return status;
+}
+
+int Socket::receive ( char* data, const unsigned int buffersize, const unsigned int minpacketsize ) const
+{
+
+ unsigned int receivedsize = 0;
+ int status = 0;
+
+ if ( !is_valid() )
+ {
+ return 0;
+ }
+
+ while ( (receivedsize <= minpacketsize) && (receivedsize < buffersize) )
+ {
+ status = ::recv(_sd, data+receivedsize, (buffersize - receivedsize), 0 );
+
+ if ( status == SOCKET_ERROR )
+ {
+ int lasterror = getLastError();
+#if defined(TARGET_LINUX) || defined(TARGET_OSX)
+ if ( lasterror != EAGAIN && lasterror != EWOULDBLOCK )
+ errormessage( lasterror, "Socket::receive" );
+#else
+ if ( lasterror != WSAEWOULDBLOCK)
+ errormessage( lasterror, "Socket::receive" );
+#endif
+ return status;
+ }
+
+ receivedsize += status;
+
+ if (receivedsize >= minpacketsize)
+ break;
+ }
+
+ return receivedsize;
+}
+
+
+int Socket::recvfrom ( char* data, const int buffersize, const int minpacketsize, struct sockaddr* from, socklen_t* fromlen) const
+{
+ int status = ::recvfrom(_sd, data, buffersize, 0, from, fromlen);
+
+ return status;
+}
+
+
+bool Socket::connect ( const std::string& host, const unsigned short port )
+{
+ if ( !is_valid() )
+ {
+ return false;
+ }
+
+ _sockaddr.sin_family = _family;
+ _sockaddr.sin_port = htons ( port );
+
+ if ( !setHostname( host ) )
+ {
+ XBMC->Log(LOG_ERROR, "Socket::setHostname(%s) failed.\n", host.c_str());
+ return false;
+ }
+
+ int status = ::connect ( _sd, reinterpret_cast<sockaddr*>(&_sockaddr), sizeof ( _sockaddr ) );
+
+ if ( status == SOCKET_ERROR )
+ {
+ XBMC->Log(LOG_ERROR, "Socket::connect %s:%u\n", host.c_str(), port);
+ errormessage( getLastError(), "Socket::connect" );
+ return false;
+ }
+
+ return true;
+}
+
+bool Socket::reconnect()
+{
+ if ( _sd != INVALID_SOCKET )
+ {
+ return true;
+ }
+
+ if( !create() )
+ return false;
+
+ int status = ::connect ( _sd, reinterpret_cast<sockaddr*>(&_sockaddr), sizeof ( _sockaddr ) );
+
+ if ( status == SOCKET_ERROR )
+ {
+ errormessage( getLastError(), "Socket::connect" );
+ return false;
+ }
+
+ return true;
+}
+
+bool Socket::is_valid() const
+{
+ return (_sd != INVALID_SOCKET);
+}
+
+#if defined(TARGET_WINDOWS)
+bool Socket::set_non_blocking ( const bool b )
+{
+ u_long iMode;
+
+ if ( b )
+ iMode = 1; // enable non_blocking
+ else
+ iMode = 0; // disable non_blocking
+
+ if (ioctlsocket(_sd, FIONBIO, &iMode) == -1)
+ {
+ XBMC->Log(LOG_ERROR, "Socket::set_non_blocking - Can't set socket condition to: %i", iMode);
+ return false;
+ }
+
+ return true;
+}
+
+void Socket::errormessage( int errnum, const char* functionname) const
+{
+ const char* errmsg = NULL;
+
+ switch (errnum)
+ {
+ case WSANOTINITIALISED:
+ errmsg = "A successful WSAStartup call must occur before using this function.";
+ break;
+ case WSAENETDOWN:
+ errmsg = "The network subsystem or the associated service provider has failed";
+ break;
+ case WSA_NOT_ENOUGH_MEMORY:
+ errmsg = "Insufficient memory available";
+ break;
+ case WSA_INVALID_PARAMETER:
+ errmsg = "One or more parameters are invalid";
+ break;
+ case WSA_OPERATION_ABORTED:
+ errmsg = "Overlapped operation aborted";
+ break;
+ case WSAEINTR:
+ errmsg = "Interrupted function call";
+ break;
+ case WSAEBADF:
+ errmsg = "File handle is not valid";
+ break;
+ case WSAEACCES:
+ errmsg = "Permission denied";
+ break;
+ case WSAEFAULT:
+ errmsg = "Bad address";
+ break;
+ case WSAEINVAL:
+ errmsg = "Invalid argument";
+ break;
+ case WSAENOTSOCK:
+ errmsg = "Socket operation on nonsocket";
+ break;
+ case WSAEDESTADDRREQ:
+ errmsg = "Destination address required";
+ break;
+ case WSAEMSGSIZE:
+ errmsg = "Message too long";
+ break;
+ case WSAEPROTOTYPE:
+ errmsg = "Protocol wrong type for socket";
+ break;
+ case WSAENOPROTOOPT:
+ errmsg = "Bad protocol option";
+ break;
+ case WSAEPFNOSUPPORT:
+ errmsg = "Protocol family not supported";
+ break;
+ case WSAEAFNOSUPPORT:
+ errmsg = "Address family not supported by protocol family";
+ break;
+ case WSAEADDRINUSE:
+ errmsg = "Address already in use";
+ break;
+ case WSAECONNRESET:
+ errmsg = "Connection reset by peer";
+ break;
+ case WSAHOST_NOT_FOUND:
+ errmsg = "Authoritative answer host not found";
+ break;
+ case WSATRY_AGAIN:
+ errmsg = "Nonauthoritative host not found, or server failure";
+ break;
+ case WSAEISCONN:
+ errmsg = "Socket is already connected";
+ break;
+ case WSAETIMEDOUT:
+ errmsg = "Connection timed out";
+ break;
+ case WSAECONNREFUSED:
+ errmsg = "Connection refused";
+ break;
+ case WSANO_DATA:
+ errmsg = "Valid name, no data record of requested type";
+ break;
+ default:
+ errmsg = "WSA Error";
+ }
+ XBMC->Log(LOG_ERROR, "%s: (Winsock error=%i) %s\n", functionname, errnum, errmsg);
+}
+
+int Socket::getLastError() const
+{
+ return WSAGetLastError();
+}
+
+int Socket::win_usage_count = 0; //Declared static in Socket class
+
+bool Socket::osInit()
+{
+ win_usage_count++;
+ // initialize winsock:
+ if (WSAStartup(MAKEWORD(2,2),&_wsaData) != 0)
+ {
+ return false;
+ }
+
+ WORD wVersionRequested = MAKEWORD(2,2);
+
+ // check version
+ if (_wsaData.wVersion != wVersionRequested)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void Socket::osCleanup()
+{
+ win_usage_count--;
+ if(win_usage_count == 0)
+ {
+ WSACleanup();
+ }
+}
+
+#elif defined TARGET_LINUX || defined TARGET_DARWIN
+bool Socket::set_non_blocking ( const bool b )
+{
+ int opts;
+
+ opts = fcntl(_sd, F_GETFL);
+
+ if ( opts < 0 )
+ {
+ return false;
+ }
+
+ if ( b )
+ opts = ( opts | O_NONBLOCK );
+ else
+ opts = ( opts & ~O_NONBLOCK );
+
+ if(fcntl (_sd , F_SETFL, opts) == -1)
+ {
+ XBMC->Log(LOG_ERROR, "Socket::set_non_blocking - Can't set socket flags to: %i", opts);
+ return false;
+ }
+ return true;
+}
+
+void Socket::errormessage( int errnum, const char* functionname) const
+{
+ const char* errmsg = NULL;
+
+ switch ( errnum )
+ {
+ case EAGAIN: //same as EWOULDBLOCK
+ errmsg = "EAGAIN: The socket is marked non-blocking and the requested operation would block";
+ break;
+ case EBADF:
+ errmsg = "EBADF: An invalid descriptor was specified";
+ break;
+ case ECONNRESET:
+ errmsg = "ECONNRESET: Connection reset by peer";
+ break;
+ case EDESTADDRREQ:
+ errmsg = "EDESTADDRREQ: The socket is not in connection mode and no peer address is set";
+ break;
+ case EFAULT:
+ errmsg = "EFAULT: An invalid userspace address was specified for a parameter";
+ break;
+ case EINTR:
+ errmsg = "EINTR: A signal occurred before data was transmitted";
+ break;
+ case EINVAL:
+ errmsg = "EINVAL: Invalid argument passed";
+ break;
+ case ENOTSOCK:
+ errmsg = "ENOTSOCK: The argument is not a valid socket";
+ break;
+ case EMSGSIZE:
+ errmsg = "EMSGSIZE: The socket requires that message be sent atomically, and the size of the message to be sent made this impossible";
+ break;
+ case ENOBUFS:
+ errmsg = "ENOBUFS: The output queue for a network interface was full";
+ break;
+ case ENOMEM:
+ errmsg = "ENOMEM: No memory available";
+ break;
+ case EPIPE:
+ errmsg = "EPIPE: The local end has been shut down on a connection oriented socket";
+ break;
+ case EPROTONOSUPPORT:
+ errmsg = "EPROTONOSUPPORT: The protocol type or the specified protocol is not supported within this domain";
+ break;
+ case EAFNOSUPPORT:
+ errmsg = "EAFNOSUPPORT: The implementation does not support the specified address family";
+ break;
+ case ENFILE:
+ errmsg = "ENFILE: Not enough kernel memory to allocate a new socket structure";
+ break;
+ case EMFILE:
+ errmsg = "EMFILE: Process file table overflow";
+ break;
+ case EACCES:
+ errmsg = "EACCES: Permission to create a socket of the specified type and/or protocol is denied";
+ break;
+ case ECONNREFUSED:
+ errmsg = "ECONNREFUSED: A remote host refused to allow the network connection (typically because it is not running the requested service)";
+ break;
+ case ENOTCONN:
+ errmsg = "ENOTCONN: The socket is associated with a connection-oriented protocol and has not been connected";
+ break;
+ //case E:
+ // errmsg = "";
+ // break;
+ default:
+ break;
+ }
+ XBMC->Log(LOG_ERROR, "%s: (errno=%i) %s\n", functionname, errnum, errmsg);
+}
+
+int Socket::getLastError() const
+{
+ return errno;
+}
+
+bool Socket::osInit()
+{
+ // Not needed for Linux
+ return true;
+}
+
+void Socket::osCleanup()
+{
+ // Not needed for Linux
+}
+#endif //TARGET_WINDOWS || TARGET_LINUX || TARGET_DARWIN
+
+} //namespace MPTV
View
309 addons/pvr.nextpvr/src/Socket.h
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+namespace NextPVR
+{
+
+//Include platform specific datatypes, header files, defines and constants:
+#if defined TARGET_WINDOWS
+ #define WIN32_LEAN_AND_MEAN // Enable LEAN_AND_MEAN support
+ #pragma warning(disable:4005) // Disable "warning C4005: '_WINSOCKAPI_' : macro redefinition"
+ #include <winsock2.h>
+ #pragma warning(default:4005)
+ #include <windows.h>
+
+ #ifndef NI_MAXHOST
+ #define NI_MAXHOST 1025
+ #endif
+
+ #ifndef socklen_t
+ typedef int socklen_t;
+ #endif
+ #ifndef ipaddr_t
+ typedef unsigned long ipaddr_t;
+ #endif
+ #ifndef port_t
+ typedef unsigned short port_t;
+ #endif
+#elif defined TARGET_LINUX || defined TARGET_DARWIN
+#ifdef SOCKADDR_IN
+#undef SOCKADDR_IN
+#endif
+ #include <sys/types.h> /* for socket,connect */
+ #include <sys/socket.h> /* for socket,connect */
+ #include <sys/un.h> /* for Unix socket */
+ #include <arpa/inet.h> /* for inet_pton */
+ #include <netdb.h> /* for gethostbyname */
+ #include <netinet/in.h> /* for htons */
+ #include <unistd.h> /* for read, write, close */
+ #include <errno.h>
+ #include <fcntl.h>
+
+ typedef int SOCKET;
+ typedef sockaddr SOCKADDR;
+ typedef sockaddr_in SOCKADDR_IN;
+ #ifndef INVALID_SOCKET
+ #define INVALID_SOCKET (-1)
+ #endif
+ #define SOCKET_ERROR (-1)
+#else
+ #error Platform specific socket support is not yet available on this platform!
+#endif
+
+using namespace std;
+
+#include <vector>
+
+#define MAXCONNECTIONS 1 ///< Maximum number of pending connections before "Connection refused"
+#define MAXRECV 1500 ///< Maximum packet size
+
+enum SocketFamily
+{
+ #ifdef CONFIG_SOCKET_IPV6
+ af_inet6 = AF_INET6,
+ af_unspec = AF_UNSPEC, ///< Either INET or INET6
+ #endif
+ af_inet = AF_INET
+};
+
+enum SocketDomain
+{
+ #if defined TARGET_LINUX || defined TARGET_DARWIN
+ pf_unix = PF_UNIX,
+ pf_local = PF_LOCAL,
+ #endif
+ #ifdef CONFIG_SOCKET_IPV6
+ pf_inet6 = PF_INET6,
+ pf_unspec = PF_UNSPEC, //< Either INET or INET6
+ #endif
+ pf_inet = PF_INET
+};
+
+enum SocketType
+{
+ sock_stream = SOCK_STREAM,
+ sock_dgram = SOCK_DGRAM
+};
+
+enum SocketProtocol
+{
+ tcp = IPPROTO_TCP,
+ udp = IPPROTO_UDP
+ #ifdef CONFIG_SOCKET_IPV6
+ , ipv6 = IPPROTO_IPV6
+ #endif
+};
+
+class Socket
+{
+ public:
+
+ /*!
+ * An unconnected socket may be created directly on the local
+ * machine. The socket type (SOCK_STREAM, SOCK_DGRAM) and
+ * protocol may also be specified.
+ * If the socket cannot be created, an exception is thrown.
+ *
+ * \param family Socket family (IPv4 or IPv6)
+ * \param domain The domain parameter specifies a communications domain within which communication will take place;
+ * this selects the protocol family which should be used.
+ * \param type base type and protocol family of the socket.
+ * \param protocol specific protocol to apply.
+ */
+ Socket(const enum SocketFamily family, const enum SocketDomain domain, const enum SocketType type, const enum SocketProtocol protocol = tcp);
+ Socket(void);
+ virtual ~Socket();
+
+ //Socket settings
+
+ /*!
+ * Socket setFamily
+ * \param family Can be af_inet or af_inet6. Default: af_inet
+ */
+ void setFamily(const enum SocketFamily family)
+ {
+ _family = family;
+ };
+
+ /*!
+ * Socket setDomain
+ * \param domain Can be pf_unix, pf_local, pf_inet or pf_inet6. Default: pf_inet
+ */
+ void setDomain(const enum SocketDomain domain)
+ {
+ _domain = domain;
+ };
+
+ /*!
+ * Socket setType
+ * \param type Can be sock_stream or sock_dgram. Default: sock_stream.
+ */
+ void setType(const enum SocketType type)
+ {
+ _type = type;
+ };
+
+ /*!
+ * Socket setProtocol
+ * \param protocol Can be tcp or udp. Default: tcp.
+ */
+ void setProtocol(const enum SocketProtocol protocol)
+ {
+ _protocol = protocol;
+ };
+
+ /*!
+ * Socket setPort
+ * \param port port number for socket communication
+ */
+ void setPort (const unsigned short port)
+ {
+ _sockaddr.sin_port = htons ( port );
+ };
+
+ bool setHostname ( const std::string& host );
+
+ // Server initialization
+
+ /*!
+ * Socket create
+ * Create a new socket
+ * \return True if succesful
+ */
+ bool create();
+
+ /*!
+ * Socket close
+ * Close the socket
+ * \return True if succesful
+ */
+ bool close();
+
+ /*!
+ * Socket bind
+ */
+ bool bind ( const unsigned short port );
+ bool listen() const;
+ bool accept ( Socket& socket ) const;
+
+ // Client initialization
+ bool connect ( const std::string& host, const unsigned short port );
+
+ bool reconnect();
+
+ // Data Transmission
+
+ /*!
+ * Socket send function
+ *
+ * \param data Reference to a std::string with the data to transmit
+ * \return Number of bytes send or -1 in case of an error
+ */
+ int send ( const std::string& data );
+
+ /*!
+ * Socket send function
+ *
+ * \param data Pointer to a character array of size 'size' with the data to transmit
+ * \param size Length of the data to transmit
+ * \return Number of bytes send or -1 in case of an error
+ */
+ int send ( const char* data, const unsigned int size );
+
+ /*!
+ * Socket sendto function
+ *
+ * \param data Reference to a std::string with the data to transmit
+ * \param size Length of the data to transmit
+ * \param sendcompletebuffer If 'true': do not return until the complete buffer is transmitted
+ * \return Number of bytes send or -1 in case of an error
+ */
+ int sendto ( const char* data, unsigned int size, bool sendcompletebuffer = false);
+ // Data Receive
+
+ /*!
+ * Socket receive function
+ *
+ * \param data Reference to a std::string for storage of the received data.
+ * \param minpacketsize The minimum number of bytes that should be received before returning from this function
+ * \return Number of bytes received or SOCKET_ERROR
+ */
+ int receive ( std::string& data, unsigned int minpacketsize ) const;
+
+ /*!
+ * Socket receive function
+ *
+ * \param data Reference to a std::string for storage of the received data.
+ * \return Number of bytes received or SOCKET_ERROR
+ */
+ int receive ( std::string& data ) const;
+
+ /*!
+ * Socket receive function
+ *
+ * \param data Pointer to a character array of size buffersize. Used to store the received data.
+ * \param buffersize Size of the 'data' buffer
+ * \param minpacketsize Specifies the minimum number of bytes that need to be received before returning
+ * \return Number of bytes received or SOCKET_ERROR
+ */
+ int receive ( char* data, const unsigned int buffersize, const unsigned int minpacketsize ) const;
+
+ /*!
+ * Socket recvfrom function
+ *
+ * \param data Pointer to a character array of size buffersize. Used to store the received data.
+ * \param buffersize Size of the 'data' buffer
+ * \param minpacketsize Do not return before at least 'minpacketsize' bytes are in the buffer.
+ * \param from Optional: pointer to a sockaddr struct that will get the address from which the data is received
+ * \param fromlen Optional, only required if 'from' is given: length of from struct
+ * \return Number of bytes received or SOCKET_ERROR
+ */
+ int recvfrom ( char* data, const int buffersize, const int minpacketsize, struct sockaddr* from = NULL, socklen_t* fromlen = NULL) const;
+
+ bool set_non_blocking ( const bool );
+
+ bool ReadResponse (int &code, vector<string> &lines);
+
+ bool is_valid() const;
+
+ bool read_ready();
+
+ private:
+
+ SOCKET _sd; ///< Socket Descriptor
+ SOCKADDR_IN _sockaddr; ///< Socket Address
+
+ enum SocketFamily _family; ///< Socket Address Family
+ enum SocketProtocol _protocol; ///< Socket Protocol
+ enum SocketType _type; ///< Socket Type
+ enum SocketDomain _domain; ///< Socket domain
+
+ #ifdef TARGET_WINDOWS
+ WSADATA _wsaData; ///< Windows Socket data
+ static int win_usage_count; ///< Internal Windows usage counter used to prevent a global WSACleanup when more than one Socket object is used
+ #endif
+
+ void errormessage( int errornum, const char* functionname = NULL) const;
+ int getLastError(void) const;
+ bool osInit();
+ void osCleanup();
+};
+
+} //namespace MPTV
View
650 addons/pvr.nextpvr/src/client.cpp
@@ -0,0 +1,650 @@
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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 of the License, 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "client.h"
+#include "xbmc_pvr_dll.h"
+#include "pvrclient-nextpvr.h"
+#include "uri.h"
+
+using namespace std;
+using namespace ADDON;
+
+#define PVR_MIN_API_VERSION "1.2.0"
+
+/* User adjustable settings are saved here.
+ * Default values are defined inside client.h
+ * and exported to the other source files.
+ */
+std::string g_szHostname = DEFAULT_HOST; ///< The Host name or IP of the NextPVR server
+std::string g_szPin = DEFAULT_HOST; ///< The Host name or IP of the NextPVR server
+int g_iPort = DEFAULT_PORT; ///< The web listening port (default: 8866)
+
+/* Client member variables */
+ADDON_STATUS m_CurStatus = ADDON_STATUS_UNKNOWN;
+cPVRClientNextPVR *g_client = NULL;
+std::string g_szUserPath = "";
+std::string g_szClientPath = "";
+CHelper_libXBMC_addon *XBMC = NULL;
+CHelper_libXBMC_pvr *PVR = NULL;
+
+extern "C" {
+
+void ADDON_ReadSettings(void);
+
+/***********************************************************
+ * Standard AddOn related public library functions
+ ***********************************************************/
+
+//-- Create -------------------------------------------------------------------
+// Called after loading of the dll, all steps to become Client functional
+// must be performed here.
+//-----------------------------------------------------------------------------
+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_UNKNOWN;
+ }
+
+ PVR = new CHelper_libXBMC_pvr;
+ if (!PVR->RegisterMe(hdl))
+ {
+ SAFE_DELETE(PVR);
+ SAFE_DELETE(XBMC);
+ return ADDON_STATUS_UNKNOWN;
+ }
+
+ XBMC->Log(LOG_INFO, "Creating NextPVR PVR-Client");
+
+ m_CurStatus = ADDON_STATUS_UNKNOWN;
+ g_szUserPath = pvrprops->strUserPath;
+ g_szClientPath = pvrprops->strClientPath;
+
+ ADDON_ReadSettings();
+
+ /* Create connection to MediaPortal XBMC TV client */
+ g_client = new cPVRClientNextPVR();
+ if (!g_client->Connect())
+ {
+ SAFE_DELETE(g_client);
+ SAFE_DELETE(PVR);
+ SAFE_DELETE(XBMC);
+ m_CurStatus = ADDON_STATUS_LOST_CONNECTION;
+ return m_CurStatus;
+ }
+
+ m_CurStatus = ADDON_STATUS_OK;
+
+ return m_CurStatus;
+}
+
+//-- Destroy ------------------------------------------------------------------
+// Used during destruction of the client, all steps to do clean and safe Create
+// again must be done.
+//-----------------------------------------------------------------------------
+void ADDON_Destroy()
+{
+ SAFE_DELETE(g_client);
+ SAFE_DELETE(PVR);
+ SAFE_DELETE(XBMC);
+
+ m_CurStatus = ADDON_STATUS_UNKNOWN;
+}
+
+//-- GetStatus ----------------------------------------------------------------
+// Report the current Add-On Status to XBMC
+//-----------------------------------------------------------------------------
+ADDON_STATUS ADDON_GetStatus()
+{
+ /* check whether we're still connected */
+ if (m_CurStatus == ADDON_STATUS_OK && g_client && !g_client->IsUp())
+ m_CurStatus = ADDON_STATUS_LOST_CONNECTION;
+
+ return m_CurStatus;
+}
+
+//-- HasSettings --------------------------------------------------------------
+// Report "true", yes this AddOn have settings
+//-----------------------------------------------------------------------------
+bool ADDON_HasSettings()
+{
+ return true;
+}
+
+unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet)
+{
+ return 0;
+}
+
+void ADDON_ReadSettings(void)
+{
+ /* Read setting "host" from settings.xml */
+ char buffer[1024];
+
+ if (!XBMC)
+ return;
+
+ /* Connection settings */
+ /***********************/
+ if (XBMC->GetSetting("host", &buffer))
+ {
+ g_szHostname = buffer;
+ uri::decode(g_szHostname);
+ }
+ 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 "port" from settings.xml */
+ if (!XBMC->GetSetting("port", &g_iPort))
+ {
+ /* If setting is unknown fallback to defaults */
+ XBMC->Log(LOG_ERROR, "Couldn't get 'port' setting, falling back to '8866' as default");
+ g_iPort = DEFAULT_PORT;
+ }
+
+ /* Read setting "pin" from settings.xml */
+ if (XBMC->GetSetting("pin", &buffer))
+ {
+ g_szPin = buffer;
+ }
+ else
+ {
+ g_szPin = DEFAULT_PIN;
+ }
+
+ /* Log the current settings for debugging purposes */
+ XBMC->Log(LOG_DEBUG, "settings: host='%s', port=%i", g_szHostname.c_str(), g_iPort);
+}
+
+//-- SetSetting ---------------------------------------------------------------
+// Called everytime a setting is changed by the user and to inform AddOn about
+// new setting and to do required stuff to apply it.
+//-----------------------------------------------------------------------------
+ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
+{
+ string str = settingName;
+
+ // SetSetting can occur when the addon is enabled, but TV support still
+ // disabled. In that case the addon is not loaded, so we should not try
+ // to change its settings.
+ if (!XBMC)
+ return ADDON_STATUS_OK;
+
+ 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 == "port")
+ {
+ XBMC->Log(LOG_INFO, "Changed Setting 'port' from %u to %u", g_iPort, *(int*) settingValue);
+ if (g_iPort != *(int*) settingValue)
+ {
+ g_iPort = *(int*) settingValue;
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ }
+ else if (str == "pin")
+ {
+ XBMC->Log(LOG_INFO, "Changed Setting 'pin'");
+ string tmp_sPin;
+ tmp_sPin = g_szPin;
+ g_szPin = (const char*) settingValue;
+ if (tmp_sPin != g_szPin)
+ return ADDON_STATUS_NEED_RESTART;
+ }
+ return ADDON_STATUS_OK;
+}
+
+void ADDON_Stop()
+{
+ ADDON_Destroy();
+}
+
+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 = PVR_MIN_API_VERSION;
+ return strMinApiVersion;
+}
+
+//-- GetAddonCapabilities -----------------------------------------------------
+// Tell XBMC our requirements
+//-----------------------------------------------------------------------------
+PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES *pCapabilities)
+{
+ XBMC->Log(LOG_DEBUG, "->GetProperties()");
+
+ //pCapabilities->bSupportsTimeshift = true; //removed from Frodo API
+ pCapabilities->bSupportsEPG = true;
+ pCapabilities->bSupportsRecordings = true;
+ pCapabilities->bSupportsTimers = true;
+ pCapabilities->bSupportsTV = true;
+ pCapabilities->bSupportsRadio = false;
+ pCapabilities->bSupportsChannelGroups = true;
+ pCapabilities->bHandlesInputStream = true;
+ pCapabilities->bHandlesDemuxing = false;
+ pCapabilities->bSupportsChannelScan = false;
+ pCapabilities->bSupportsLastPlayedPosition = false;
+
+ return PVR_ERROR_NO_ERROR;
+}
+
+PVR_ERROR GetStreamProperties(PVR_STREAM_PROPERTIES *pProperties)
+{
+ return PVR_ERROR_NOT_IMPLEMENTED;
+}
+
+//-- GetBackendName -----------------------------------------------------------
+// Return the Name of the Backend
+//-----------------------------------------------------------------------------
+const char * GetBackendName(void)
+{
+ if (g_client)
+ return g_client->GetBackendName();
+ else
+ return "";
+}
+
+//-- GetBackendVersion --------------------------------------------------------
+// Return the Version of the Backend as String
+//-----------------------------------------------------------------------------
+const char * GetBackendVersion(void)
+{
+ if (g_client)
+ return g_client->GetBackendVersion();
+ else
+ return "";
+}
+
+//-- GetConnectionString ------------------------------------------------------
+// Return a String with connection info, if available
+//-----------------------------------------------------------------------------
+const char * GetConnectionString(void)
+{
+ if (g_client)
+ return g_client->GetConnectionString();
+ else
+ return "addon error!";
+}
+
+//-- GetDriveSpace ------------------------------------------------------------
+// Return the Total and Free Drive space on the PVR Backend
+//-----------------------------------------------------------------------------
+PVR_ERROR GetDriveSpace(long long *iTotal, long long *iUsed)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->GetDriveSpace(iTotal, iUsed);
+}
+
+PVR_ERROR GetBackendTime(time_t *localTime, int *gmtOffset)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->GetBackendTime(localTime, gmtOffset);
+}
+
+PVR_ERROR DialogChannelScan()
+{
+ return PVR_ERROR_NOT_IMPLEMENTED;
+}
+
+PVR_ERROR CallMenuHook(const PVR_MENUHOOK &menuhook)
+{
+ return PVR_ERROR_NOT_IMPLEMENTED;
+}
+
+
+/*******************************************/
+/** PVR EPG Functions **/
+
+PVR_ERROR GetEPGForChannel(ADDON_HANDLE handle, const PVR_CHANNEL &channel, time_t iStart, time_t iEnd)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->GetEpg(handle, channel, iStart, iEnd);
+}
+
+
+/*******************************************/
+/** PVR Channel Functions **/
+
+int GetChannelsAmount()
+{
+ if (!g_client)
+ return 0;
+ else
+ return g_client->GetNumChannels();
+}
+
+PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->GetChannels(handle, bRadio);
+}
+
+PVR_ERROR DeleteChannel(const PVR_CHANNEL &channel)
+{
+ return PVR_ERROR_NOT_IMPLEMENTED;
+}
+
+PVR_ERROR RenameChannel(const PVR_CHANNEL &channel)
+{
+ return PVR_ERROR_NOT_IMPLEMENTED;
+}
+
+PVR_ERROR DialogChannelSettings(const PVR_CHANNEL &channelinfo)
+{
+ return PVR_ERROR_NOT_IMPLEMENTED;
+}
+
+PVR_ERROR DialogAddChannel(const PVR_CHANNEL &channelinfo)
+{
+ return PVR_ERROR_NOT_IMPLEMENTED;
+}
+
+
+/*******************************************/
+/** PVR Channel group Functions **/
+
+int GetChannelGroupsAmount(void)
+{
+ if (!g_client)
+ return 0;
+ else
+ return g_client->GetChannelGroupsAmount();
+}
+
+PVR_ERROR GetChannelGroups(ADDON_HANDLE handle, bool bRadio)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->GetChannelGroups(handle, bRadio);
+}
+
+PVR_ERROR GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP &group)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->GetChannelGroupMembers(handle, group);
+}
+
+
+/*******************************************/
+/** PVR Recording Functions **/
+
+int GetRecordingsAmount(void)
+{
+ if (!g_client)
+ return 0;
+ else
+ return g_client->GetNumRecordings();
+}
+
+PVR_ERROR GetRecordings(ADDON_HANDLE handle)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->GetRecordings(handle);
+}
+
+PVR_ERROR DeleteRecording(const PVR_RECORDING &recording)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->DeleteRecording(recording);
+}
+
+PVR_ERROR RenameRecording(const PVR_RECORDING &recording)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->RenameRecording(recording);
+}
+
+
+/*******************************************/
+/** PVR Timer Functions **/
+
+int GetTimersAmount(void)
+{
+ if (!g_client)
+ return 0;
+ else
+ return g_client->GetNumTimers();
+}
+
+PVR_ERROR GetTimers(ADDON_HANDLE handle)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->GetTimers(handle);
+}
+
+PVR_ERROR AddTimer(const PVR_TIMER &timer)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->AddTimer(timer);
+}
+
+PVR_ERROR DeleteTimer(const PVR_TIMER &timer, bool bForceDelete)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->DeleteTimer(timer, bForceDelete);
+}
+
+PVR_ERROR UpdateTimer(const PVR_TIMER &timer)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->UpdateTimer(timer);
+}
+
+
+/*******************************************/
+/** PVR Live Stream Functions **/
+
+bool OpenLiveStream(const PVR_CHANNEL &channelinfo)
+{
+ if (!g_client)
+ return false;
+ else
+ return g_client->OpenLiveStream(channelinfo);
+}
+
+void CloseLiveStream()
+{
+ if (g_client)
+ g_client->CloseLiveStream();
+}
+
+int ReadLiveStream(unsigned char *pBuffer, unsigned int iBufferSize)
+{
+ if (!g_client)
+ return 0;
+ else
+ return g_client->ReadLiveStream(pBuffer, iBufferSize);
+}
+
+long long SeekLiveStream(long long iPosition, int iWhence)
+{
+ if (!g_client)
+ return -1;
+ else
+ return g_client->SeekLiveStream(iPosition, iWhence);
+}
+
+long long PositionLiveStream(void)
+{
+ if (!g_client)
+ return -1;
+ else
+ return g_client->PositionLiveStream();
+}
+
+long long LengthLiveStream(void)
+{
+ if (!g_client)
+ return -1;
+ else
+ return g_client->LengthLiveStream();
+}
+
+int GetCurrentClientChannel()
+{
+ if (!g_client)
+ return 0;
+ else
+ return g_client->GetCurrentClientChannel();
+}
+
+bool SwitchChannel(const PVR_CHANNEL &channelinfo)
+{
+ if (!g_client)
+ return false;
+ else
+ return g_client->SwitchChannel(channelinfo);
+}
+
+PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS &signalStatus)
+{
+ if (!g_client)
+ return PVR_ERROR_SERVER_ERROR;
+ else
+ return g_client->SignalStatus(signalStatus);
+}
+
+/*******************************************/
+/** PVR Recording Stream Functions **/
+
+bool OpenRecordedStream(const PVR_RECORDING &recording)
+{
+ if (!g_client)
+ return false;
+ else
+ return g_client->OpenRecordedStream(recording);
+}
+
+void CloseRecordedStream(void)
+{
+ if (g_client)
+ g_client->CloseRecordedStream();
+}
+
+int ReadRecordedStream(unsigned char *pBuffer, unsigned int iBufferSize)
+{
+ if (!g_client)
+ return 0;
+ else
+ return g_client->ReadRecordedStream(pBuffer, iBufferSize);
+}
+
+long long SeekRecordedStream(long long iPosition, int iWhence)
+{
+ if (!g_client)
+ return -1;
+ else
+ return g_client->SeekRecordedStream(iPosition, iWhence);
+}
+
+long long PositionRecordedStream(void)
+{
+ if (!g_client)
+ return -1;
+ else
+ return g_client->PositionRecordedStream();
+}
+
+long long LengthRecordedStream(void)
+{
+ if (!g_client)
+ return -1;
+ else
+ return g_client->LengthRecordedStream();
+}
+
+const char * GetLiveStreamURL(const PVR_CHANNEL &channel)
+{
+ if (!g_client)
+ return "";
+ else
+ return g_client->GetLiveStreamURL(channel);
+}
+
+/** UNUSED API FUNCTIONS */
+PVR_ERROR MoveChannel(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; }
+DemuxPacket* DemuxRead(void) { return NULL; }
+void DemuxAbort(void) {}
+void DemuxReset(void) {}
+void DemuxFlush(void) {}
+
+PVR_ERROR SetRecordingPlayCount(const PVR_RECORDING &recording, int count) { return PVR_ERROR_NOT_IMPLEMENTED; }
+PVR_ERROR SetRecordingLastPlayedPosition(const PVR_RECORDING &recording, int lastplayedposition) { return PVR_ERROR_NOT_IMPLEMENTED; }
+int GetRecordingLastPlayedPosition(const PVR_RECORDING &recording) { return -1; }
+unsigned int GetChannelSwitchDelay(void) { return 0; }
+void PauseStream(bool bPaused) {}
+bool CanPauseStream(void) { return false; }
+bool CanSeekStream(void) { return false; }
+} //end extern "C"
View
86 addons/pvr.nextpvr/src/client.h
@@ -0,0 +1,86 @@
+#pragma once
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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
+ *
+ */
+
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#include "platform/util/StdString.h"
+#include "libXBMC_addon.h"
+#include "libXBMC_pvr.h"
+
+enum eStreamingMethod
+{
+ TSReader = 0,
+ ffmpeg = 1
+};
+
+#define DEFAULT_HOST "127.0.0.1"
+#define DEFAULT_PORT 8866
+#define DEFAULT_PIN "0000"
+#define DEFAULT_FTA_ONLY false
+#define DEFAULT_RADIO true
+#define DEFAULT_TIMEOUT 10
+#define DEFAULT_HANDLE_MSG false
+#define DEFAULT_RESOLVE_RTSP_HOSTNAME false
+#define DEFAULT_READ_GENRE false
+#define DEFAULT_SLEEP_RTSP_URL 0
+#define DEFAULT_USE_REC_DIR false
+#define DEFAULT_TVGROUP ""
+#define DEFAULT_RADIOGROUP ""
+#define DEFAULT_DIRECT_TS_FR false
+#define DEFAULT_SMBUSERNAME "Guest"
+#define DEFAULT_SMBPASSWORD ""
+
+extern std::string g_szUserPath; ///< The Path to the user directory inside user profile
+extern std::string g_szClientPath; ///< The Path where this driver is located
+
+/* Client Settings */
+extern std::string g_szHostname;
+extern int g_iPort;
+extern std::string g_szPin;
+extern int g_iConnectTimeout;
+extern int g_iSleepOnRTSPurl;
+extern bool g_bOnlyFTA;
+extern bool g_bRadioEnabled;
+extern bool g_bHandleMessages;
+extern bool g_bResolveRTSPHostname;
+extern bool g_bReadGenre;
+extern bool g_bFastChannelSwitch;
+extern bool g_bUseRTSP; ///< Use RTSP streaming when using the tsreader
+extern std::string g_szTVGroup;
+extern std::string g_szRadioGroup;
+extern std::string g_szSMBusername;
+extern std::string g_szSMBpassword;