summaryrefslogtreecommitdiff
path: root/vdr-smarttvweb
diff options
context:
space:
mode:
authorthlo <smarttv640@gmail.com>2013-03-17 09:41:35 +0100
committerthlo <t.lohmar@gmx.de>2013-03-17 09:41:35 +0100
commitb183afb04050143a3f9faccf6ff52219e60c34d6 (patch)
tree7c32b63c7f5c175005186e68ff55edafc1ac36e3 /vdr-smarttvweb
parentd48d64273d5da9bf596b239bb0aec622086655f0 (diff)
downloadvdr-plugin-smarttvweb-b183afb04050143a3f9faccf6ff52219e60c34d6.tar.gz
vdr-plugin-smarttvweb-b183afb04050143a3f9faccf6ff52219e60c34d6.tar.bz2
First step of repo restructuring
Diffstat (limited to 'vdr-smarttvweb')
-rw-r--r--vdr-smarttvweb/Makefile109
-rwxr-xr-xvdr-smarttvweb/httpresource.c2905
-rwxr-xr-xvdr-smarttvweb/httpresource.h187
-rw-r--r--vdr-smarttvweb/log.c85
-rw-r--r--vdr-smarttvweb/log.h50
-rwxr-xr-xvdr-smarttvweb/smarttvfactory.c408
-rw-r--r--vdr-smarttvweb/smarttvfactory.h84
-rw-r--r--vdr-smarttvweb/smarttvweb.c152
-rw-r--r--vdr-smarttvweb/smarttvweb.conf28
-rwxr-xr-xvdr-smarttvweb/stvw_cfg.c196
-rwxr-xr-xvdr-smarttvweb/stvw_cfg.h75
-rw-r--r--vdr-smarttvweb/url.c340
-rw-r--r--vdr-smarttvweb/url.h50
-rwxr-xr-xvdr-smarttvweb/web/Data.js296
-rwxr-xr-xvdr-smarttvweb/web/Server.js180
-rwxr-xr-xvdr-smarttvweb/web/favicon.icobin1502 -> 0 bytes
-rwxr-xr-xvdr-smarttvweb/web/index.html104
-rw-r--r--vdr-smarttvweb/widget.conf11
18 files changed, 0 insertions, 5260 deletions
diff --git a/vdr-smarttvweb/Makefile b/vdr-smarttvweb/Makefile
deleted file mode 100644
index b04d143..0000000
--- a/vdr-smarttvweb/Makefile
+++ /dev/null
@@ -1,109 +0,0 @@
-#
-# Makefile for a Video Disk Recorder plugin
-#
-#
-# The official name of this plugin.
-# This name will be used in the '-P...' option of VDR to load the plugin.
-# By default the main source file also carries this name.
-#
-PLUGIN = smarttvweb
-
-### The version number of this plugin (taken from the main source file):
-
-VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
-
-### The C++ compiler and options:
-
-
-CXX ?= g++
-ifdef DEBUG
-CXXFLAGS ?= -g -O0 -fPIC -Wall -Woverloaded-virtual #-Werror
-else
-CXXFLAGS ?= -fPIC -Wall -Woverloaded-virtual #-Werror
-#CXXFLAGS ?= -O2 -fPIC -Wall -Woverloaded-virtual #-Werror
-endif
-
-### The directory environment:
-
-#VDRDIR = ../../..
-VDRDIR = /usr/include/vdr
-LIBDIR = .
-#LIBDIR = ../../lib
-TMPDIR = /tmp
-
-### Allow user defined options to overwrite defaults:
-
-#-include $(VDRDIR)/Make.config
-
-### read standlone settings if there
--include .standalone
-
-### The version number of VDR (taken from VDR's "config.h"):
-
-VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
-APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
-
-### The name of the distribution archive:
-
-ARCHIVE = $(PLUGIN)-$(VERSION)
-PACKAGE = vdr-$(ARCHIVE)
-
-### Includes and Defines (add further entries here):
-
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
-
-DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
-DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
-
-### The object files (add further files here):
-
-OBJS = $(PLUGIN).o smarttvfactory.o httpresource.o log.o url.o stvw_cfg.o
-
-OBJS2 =
-
-### Implicit rules:
-
-%.o: %.c
- $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
-
-# Dependencies:
-
-MAKEDEP = g++ -MM -MG
-DEPFILE = .dependencies
-$(DEPFILE): Makefile
- @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
-
--include $(DEPFILE)
-
-### Targets:
-
-all: allbase libvdr-$(PLUGIN).so
-standalone: standalonebase smarttvweb-standalone
-
-objectsstandalone: $(OBJS)
-objects: $(OBJS) $(OBJS2)
-
-allbase:
- ( if [ -f .standalone ] ; then ( rm -f .standalone; make clean ; make objects ) ; else exit 0 ;fi )
-standalonebase:
- ( if [ ! -f .standalone ] ; then ( make clean; echo "DEFINES+=-DSTANDALONE" > .standalone; echo "DEFINES+=-D_FILE_OFFSET_BITS=64" >> .standalone; make objectsstandalone ) ; else exit 0 ;fi )
-
-libvdr-$(PLUGIN).so: objects
- $(CXX) $(CXXFLAGS) -shared $(OBJS) $(OBJS2) -o $@
- @cp $@ $(LIBDIR)/$@.$(APIVERSION)
-
-smarttvweb-standalone: objectsstandalone
- $(CXX) $(CXXFLAGS) $(OBJS) -lpthread -o $@
- chmod u+x $@
-
-dist: clean
- @-rm -rf $(TMPDIR)/$(ARCHIVE)
- @mkdir $(TMPDIR)/$(ARCHIVE)
- @cp -a * $(TMPDIR)/$(ARCHIVE)
- @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
- @-rm -rf $(TMPDIR)/$(ARCHIVE)
- @echo Distribution package created as $(PACKAGE).tgz
-
-clean:
- rm -f $(OBJS) $(OBJS2) $(DEPFILE) libvdr*.so.* *.tgz core* *~ .standalone smarttvweb-standalone
-
diff --git a/vdr-smarttvweb/httpresource.c b/vdr-smarttvweb/httpresource.c
deleted file mode 100755
index 79d39bc..0000000
--- a/vdr-smarttvweb/httpresource.c
+++ /dev/null
@@ -1,2905 +0,0 @@
-/*
- * httpresource.c: VDR on Smart TV plugin
- *
- * Copyright (C) 2012, 2013 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-
-#include <string>
-#include <cstring>
-#include <iostream>
-#include <vector>
-#include "httpresource.h"
-#include "smarttvfactory.h"
-#include "stvw_cfg.h"
-
-#include "url.h"
-
-#ifndef STANDALONE
-#include <vdr/recording.h>
-#include <vdr/channels.h>
-#include <vdr/timers.h>
-#include <vdr/videodir.h>
-#include <vdr/epg.h>
-
-#endif
-
-#define PROTOCOL "HTTP/1.1"
-#define RFC1123FMT "%a, %d %b %Y %H:%M:%S GMT"
-
-#define MAXLEN 4096
-#define OKAY 0
-#define ERROR (-1)
-#define DEBUG_REGHEADERS
-#define DEBUGPREFIX "mReqId= " << mReqId << " fd= " << mFd
-#define DEBUGHDR " " << __PRETTY_FUNCTION__ << " (" << __LINE__ << ") "
-
-#define DEBUG
-
-#define SEGMENT_DURATION 10
-
-using namespace std;
-
-class cResumeEntry {
- public:
- string mFilename;
- float mResume;
-
- friend ostream& operator<<(ostream& out, const cResumeEntry& o) {
- out << "mFilename= " << o.mFilename << " mResume= " << o.mResume << endl;
- return out;
- };
- cResumeEntry():mFilename(), mResume(-1.0) {};
-};
-
-
-struct sVdrFileEntry {
- uint64_t sSize;
- uint64_t sFirstOffset;
- int sIdx;
-
- sVdrFileEntry () {};
- sVdrFileEntry (uint64_t s, uint64_t t, int i)
- : sSize(s), sFirstOffset(t), sIdx(i) {};
-};
-
-
-struct sTimerEntry {
- string name;
- time_t startTime;
- int duration;
-sTimerEntry(string t, time_t s, int d) : name(t), startTime(s), duration(d) {};
-};
-
-// 8 Byte Per Entry
-struct tIndexPes {
- uint32_t offset;
- uchar type;
- uchar number;
- uint16_t reserved;
- };
-
-
-// 8 Byte per entry
-struct tIndexTs {
- uint64_t offset:40; // up to 1TB per file (not using long long int here - must definitely be exactly 64 bit!)
- int reserved:7; // reserved for future use
- int independent:1; // marks frames that can be displayed by themselves (for trick modes)
- uint16_t number:16; // up to 64K files per recording
- };
-
-
-/*
-union tIndexRead {
- struct tIndexTs in;
- char buf[8];
-};
-*/
-
-cHttpResource::cHttpResource(int f, int id, int port, SmartTvServer* factory): mFactory(factory), mLog(),
- mServerPort(port), mFd(f), mReqId(id), mConnTime(0), mHandleReadCount(0),
- mConnected(true), mConnState(WAITING), mContentType(NYD), mReadBuffer(),
- mMethod(), mResponseMessagePos(0), mBlkData(NULL), mBlkPos(0), mBlkLen(0),
- mPath(), mVersion(), protocol(), mReqContentLength(0),
- mPayload(), mUserAgent(),
- mAcceptRanges(true), rangeHdr(), mFileSize(-1), mStreamToEnd(false), mRemLength(0), mFile(NULL), mVdrIdx(1), mFileStructure(),
- mIsRecording(false), mRecProgress(0.0) {
-
- mLog = Log::getInstance();
- mPath = "";
- mConnTime = time(NULL);
- setNonBlocking();
- mBlkData = new char[MAXLEN];
-
- //#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " cHttpResource created" << endl;
- //#endif
-}
-
-
-cHttpResource::~cHttpResource() {
- //#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " Destructor of cHttpResource called"
- << endl;
- //#endif
- delete[] mBlkData;
- if (mFile != NULL) {
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: mFile still open. Closing now..." << endl;
- fclose(mFile);
- mFile = NULL;
- }
-
-}
-
-int cHttpResource::checkStatus() {
- time_t now = time(NULL);
-
- switch (mConnState) {
- case WAITING:
- case READHDR:
- case READPAYLOAD:
- if (now - mConnTime > 2) {
- *(mLog->log()) << DEBUGPREFIX
- << " checkStatus: no activity for 2sec "
- << "mmConnState= " << getConnStateName()
- << endl;
- return ERROR;
- }
- break;
- case TOCLOSE:
- return ERROR;
- break;
- case SERVING:
- break;
- }
-
- // check for how much time the
- return OKAY;
-}
-
-void cHttpResource::setNonBlocking() {
- int oldflags = fcntl(mFd, F_GETFL, 0);
- oldflags |= O_NONBLOCK;
- fcntl(mFd, F_SETFL, oldflags);
-}
-
-
-int cHttpResource::handleRead() {
- mHandleReadCount ++;
- if (mConnState == SERVING) {
- *(mLog->log())<< DEBUGPREFIX
- << " handleRead() in wrong state= " << getConnStateName()
- << endl;
- return OKAY;
- }
- if (mConnState == TOCLOSE) {
- *(mLog->log())<< DEBUGPREFIX
- << " handleRead() in wrong state= " << getConnStateName()
- << endl;
- return ERROR;
- }
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " handleRead() state= " << getConnStateName()
- << endl;
-#endif
-
- char buf[MAXLEN];
- int buflen = sizeof(buf);
-
- int line_count = 0;
- // bool is_req = true;
- string rem_hdr = "";
-
- buflen = read(mFd, buf, sizeof(buf));
-
- if (buflen == -1) {
- *(mLog->log())<< " Some Error, no data received" << endl;
- return ERROR; // Nothing to read
- }
-
- // if (( mConnState == WAITING) and ((time(NULL) - mConnTime) > 1)) {
- if (( mConnState == WAITING) and (mHandleReadCount > 1000)) {
- *(mLog->log()) << DEBUGPREFIX << " hmm, handleRead() no data since 1sec -> closing. mHandleReadCount= " << mHandleReadCount << endl;
- return ERROR; // Nothing to read
- }
-
- if ( ((mConnState == READHDR) or (mConnState == READPAYLOAD)) and (mHandleReadCount > 5000)) {
- *(mLog->log()) << DEBUGPREFIX << " ERROR Still not finished after mHandleReadCount= " << mHandleReadCount << endl;
- return ERROR; // Nothing to read
- }
-
- if (buflen == 0) {
- return OKAY; // Nothing to read
- }
-
- if (mConnState == READPAYLOAD) {
- mPayload += string(buf, buflen);
- if (mPayload.size() == mReqContentLength) {
- //Done
- mConnState = SERVING;
- return processRequest();
- }
- }
-
- if (mConnState == WAITING) {
- mConnState = READHDR;
- }
-
- string req_line = mReadBuffer + string(buf, buflen);
- buflen += rem_hdr.size();
-
- size_t last_pos = 0;
- // Parse http header lines
- while (true) {
- line_count ++;
- size_t pos = req_line.find ("\r\n", last_pos);
-
- if ((pos > buflen) or (pos == string::npos)) {
- mReadBuffer = req_line.substr(last_pos, buflen - last_pos);
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX << " No HdrEnd Found, read more data. rem_hdr= " << mReadBuffer.size()
- << " buflen= " << buflen
- << DEBUGHDR << endl;
- *(mLog->log())<< cUrlEncode::hexDump(mReadBuffer) << endl;
-#endif
- return OKAY;
- }
-
- if ((last_pos - pos) == 0) {
- // Header End
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX << " ---- Header End Found" << DEBUGHDR << endl;
-#endif
-
- if (mReqContentLength != 0) {
- mConnState = READPAYLOAD;
- mPayload = req_line.substr(pos +2, buflen - (pos +2));
- if (mPayload.size() != mReqContentLength)
- return OKAY;
- else {
- mConnState = SERVING;
- return processRequest();
- }
- } // if(content_length != 0)
- else {
- mConnState = SERVING;
- return processRequest();
- }
- } // if (header end)
-
- string line = req_line.substr(last_pos, (pos-last_pos));
-#ifdef DEBUG_REQHEADERS
- *(mLog->log())<< " Line= " << line << endl;
-#endif
- last_pos = pos +2;
- if (mPath.size() == 0) {
-#ifndef DEBUG
- *(mLog->log())<< " parsing Request Line= " << line << endl;
-#endif
- // is_req = false;
- // Parse the request line
- if (parseHttpRequestLine(line) != OKAY) {
- return ERROR;
- };
- }
- else {
- parseHttpHeaderLine (line);
- }
- }
- return OKAY;
-}
-
-int cHttpResource::processRequest() {
- // do stuff based on the request and the query
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX << " processRequest for mPath= " << mPath << DEBUGHDR << endl;
-#endif
- struct stat statbuf;
- bool ok_to_serve = false;
-
- if (mMethod.compare("POST")==0) {
- return handlePost();
- }
-
- if (!((strcasecmp(mMethod.c_str(), "GET") == 0) or (strcasecmp(mMethod.c_str(), "HEAD") == 0))) {
- sendError(501, "Not supported", NULL, "Method is not supported.");
- return OKAY;
- }
-
-#ifndef STANDALONE
- if (mPath.compare("/recordings.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- sendRecordingsXml( &statbuf);
- return OKAY;
- }
-
- if (mPath.compare("/channels.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- sendChannelsXml( &statbuf);
- return OKAY;
- }
-
- if (mPath.compare("/epg.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- sendEpgXml( &statbuf);
- return OKAY;
- }
-
- if (mPath.compare("/setResume.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- receiveResume();
- return OKAY;
- }
-
- if (mPath.compare("/getResume.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- sendResumeXml();
- return OKAY;
- }
-
- if (mPath.compare("/vdrstatus.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- sendVdrStatusXml( &statbuf);
- return OKAY;
- }
-
-
-#endif
-
- if (mPath.compare("/media.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
- sendMediaXml( &statbuf);
- return OKAY;
- }
-
- if (mPath.compare("/widget.conf") == 0) {
- mPath = mFactory->getConfigDir() + "/widget.conf";
-
- if (stat(mPath.c_str(), &statbuf) < 0) {
- sendError(404, "Not Found", NULL, "File not found.");
- return OKAY;
- }
- if (handleHeadRequest() != 0)
- return OKAY;
-
- mFileSize = statbuf.st_size;
- mContentType = SINGLEFILE;
- return sendFile(&statbuf);
- }
-
- if (mPath.compare("/favicon.ico") == 0) {
- mPath = mFactory->getConfigDir() + "/web/favicon.ico";
-
- if (stat(mPath.c_str(), &statbuf) < 0) {
- sendError(404, "Not Found", NULL, "File not found.");
- return OKAY;
- }
- if (handleHeadRequest() != 0)
- return OKAY;
-
- mFileSize = statbuf.st_size;
- mContentType = SINGLEFILE;
- return sendFile(&statbuf);
- }
-
-
- if (mPath.size() > 8) {
- if (mPath.compare(mPath.size() -8, 8, "-seg.mpd") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
- sendManifest( &statbuf, false);
- return OKAY;
- }
- }
-
- if (mPath.size() > 9) {
- if (mPath.compare(mPath.size() -9, 9, "-seg.m3u8") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
- sendManifest( &statbuf, true);
- return OKAY;
- }
- }
-
- if (mPath.size() > 7) {
- if (mPath.compare(mPath.size() -7, 7, "-seg.ts") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- sendMediaSegment( &statbuf);
- return OKAY;
- }
- }
-
- if (mPath.find("/web/") == 0) {
- mPath = mFactory->getConfigDir() + mPath;
- *(mLog->log())<< DEBUGPREFIX
- << " Found web request. serving " << mPath << endl;
- ok_to_serve = true;
- }
-
-
- if (stat(mPath.c_str(), &statbuf) < 0) {
- // checking, whether the file or directory exists
- *(mLog->log())<< DEBUGPREFIX
- << " File Not found " << mPath << endl;
- sendError(404, "Not Found", NULL, "File not found.");
-
- return OKAY;
- }
-
- if (S_ISDIR(statbuf.st_mode)) {
- // Do Folder specific checkings
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " processRequest: isDir - mPath: " << mPath.c_str() << endl;
-#endif
-
- if (mPath.size() >4) {
- if (mPath.compare(mPath.size() - 4, 4, ".rec") == 0) {
- // Handle any recording directory specifically
- if (handleHeadRequest() != 0)
- return OKAY;
-
- mContentType = VDRDIR;
- return sendVdrDir( &statbuf);
- }
- }
-
- if (!((ok_to_serve) or (mPath.compare(0, (mFactory->getConfig()->getMediaFolder()).size(), mFactory->getConfig()->getMediaFolder()) == 0))) {
- // No directory access outside of MediaFolder (and also VDRCONG/web)
- sendError(404, "Not Found", NULL, "File not found.");
- return OKAY;
- }
- if (handleHeadRequest() != 0)
- return OKAY;
-
- mContentType = MEMBLOCK;
- sendDir( &statbuf);
- return OKAY;
- }
- else {
- // mPath is not a folder, thus it is a file
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " processRequest: file send\n";
-#endif
-
- // Check, if requested file is in Media Directory
- if (!((ok_to_serve) or (mPath.compare(0, (mFactory->getConfig()->getMediaFolder()).size(), mFactory->getConfig()->getMediaFolder()) == 0))) {
- sendError(404, "Not Found", NULL, "File not found.");
- return OKAY;
- }
- if (handleHeadRequest() != 0)
- return OKAY;
- mFileSize = statbuf.st_size;
- mContentType = SINGLEFILE;
- return sendFile(&statbuf);
- }
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " processRequest: Not Handled SHOULD not be here\n";
-#endif
- return ERROR;
-}
-
-
-int cHttpResource::handleWrite() {
-
- if (mConnState == TOCLOSE) {
- *(mLog->log())<< DEBUGPREFIX
- << " handleWrite() in wrong state= " << getConnStateName()
- << endl;
- return ERROR;
- }
-
- if (mConnState != SERVING) {
- return OKAY;
- }
-
- if (mBlkLen == mBlkPos) {
- // note the mBlk may be filled with header info first.
- if (fillDataBlk() != OKAY) {
- return ERROR;
- }
- }
-
- int this_write = write(mFd, &mBlkData[mBlkPos], mBlkLen - mBlkPos);
- if (this_write <=0) {
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR after write: Stopped (Client terminated Connection)"
- << " mBlkPos= " << mBlkPos << " mBlkLen= " << mBlkLen
- << DEBUGHDR << endl;
-#endif
- mConnState = TOCLOSE;
- mConnected = false;
- return ERROR;
- }
- mBlkPos += this_write;
-
- return OKAY;
-}
-
-
-int cHttpResource::fillDataBlk() {
- char pathbuf[4096];
-
- mBlkPos = 0;
- int to_read = 0;
-
- switch(mContentType) {
- case NYD:
-
- break;
- case VDRDIR:
- // Range requests are assumed to be all open
- if (mFile == NULL) {
- *(mLog->log()) << DEBUGPREFIX << " no open file anymore "
- << "--> Done " << endl;
- return ERROR;
- }
- if ((mRemLength == 0) && !mStreamToEnd){
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX << " mRemLength is zero "
- << "--> Done " << endl;
-#endif
- fclose(mFile);
- mFile = NULL;
- return ERROR;
- }
- if (!mStreamToEnd)
- to_read = ((mRemLength > MAXLEN) ? MAXLEN : mRemLength);
- else
- to_read = MAXLEN;
-
- mBlkLen = fread(mBlkData, 1, to_read, mFile);
- if (!mStreamToEnd)
- mRemLength -= mBlkLen;
-
- if ((mRemLength == 0) && (!mStreamToEnd)) {
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX << " last Block read "
- << "--> Almost Done " << endl;
-#endif
- return OKAY;
- }
-
- // if (mBlkLen != MAXLEN) { // thlo verify
- if (mBlkLen != to_read) {
- fclose(mFile);
- mFile = NULL;
- mVdrIdx ++;
-
- snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), mDir.c_str(), mVdrIdx);
- mPath = pathbuf;
-
- if (openFile(pathbuf) != OKAY) {
- *(mLog->log())<< DEBUGPREFIX << " Failed to open file= " << pathbuf << " mRemLength= " << mRemLength<< endl;
- mFile = NULL;
- if (mBlkLen == 0) {
- *(mLog->log()) << DEBUGPREFIX << " mBlkLen is zero --> Done " << endl;
- return ERROR;
- }
- else
- *(mLog->log()) << DEBUGPREFIX << " Still data to send mBlkLen= " << mBlkLen <<" --> continue " << endl;
- return OKAY;
- } // Error: Open next file failed
-
- if (mBlkLen == 0) {
- if (!mStreamToEnd)
- to_read = ((mRemLength > MAXLEN) ? MAXLEN : mRemLength);
- else
- to_read = MAXLEN;
- mBlkLen = fread(mBlkData, 1, to_read, mFile);
- if (!mStreamToEnd)
- mRemLength -= mBlkLen ;
- }
- }
- break;
- case SINGLEFILE:
-
- to_read = ((mRemLength > MAXLEN) ? MAXLEN : mRemLength);
- mBlkLen = fread(mBlkData, 1, to_read, mFile);
- mRemLength -= mBlkLen;
- if (mBlkLen == 0) {
-
- // read until EOF
- fclose(mFile);
- mFile = NULL;
- return ERROR;
- }
- break;
- case MEMBLOCK:
- int rem_len = mResponseMessage->size() - mResponseMessagePos;
- if (rem_len == 0) {
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX << " fillDataBlock: MEMBLOCK done" << endl;
-#endif
- delete mResponseMessage;
- mResponseMessagePos = 0;
- mConnState = TOCLOSE;
- return ERROR;
- }
- if (rem_len > MAXLEN)
- rem_len = MAXLEN;
-
- string sub_msg = mResponseMessage->substr(mResponseMessagePos, rem_len);
- mResponseMessagePos += rem_len;
- mBlkLen = sub_msg.size();
- memcpy(mBlkData, sub_msg.c_str(), rem_len);
- break;
- }
-
- return OKAY;
-}
-
-
-int cHttpResource::parseResume(cResumeEntry &entry, string &id) {
- bool done = false;
- size_t cur_pos = 0;
-
- // The asset_id should the the filename, which is provided by the link element in the xml
- // the link is url-safe encoded.
-
- // bool have_devid = false;
- bool have_filename = false;
- bool have_resume = false;
-
- while (!done) {
- size_t pos = mPayload.find('\n', cur_pos);
- if (pos == string::npos) {
- done = true;
- continue;
- }
- size_t pos_col = mPayload.find(':', cur_pos);
- string attr= mPayload.substr(cur_pos, (pos_col- cur_pos));
- string val = mPayload.substr(pos_col +1, (pos - pos_col-1));
-
- /* if (attr== "devid") {
- have_devid = true;
- id = val;
- }
- else */
- if (attr == "filename") {
- have_filename = true;
- entry.mFilename = cUrlEncode::doXmlSaveDecode(val);
- *(mLog->log())<< DEBUGPREFIX
- << " filename= " << entry.mFilename
- << endl;
- }
- else if (attr == "resume") {
- have_resume = true;
- entry.mResume = atof(val.c_str());
- *(mLog->log())<< DEBUGPREFIX
- << " mResume= " << entry.mResume
- << endl;
- }
- else {
- *(mLog->log())<< DEBUGPREFIX
- << " parseResume: ERROR: Unknown attr= " << attr
- << " with val= " << val
- << endl;
- }
- cur_pos = pos +1;
- if (cur_pos >= mPayload.size())
- done= true;
- }
- if (have_resume && have_filename )
- return OKAY;
- else
- return ERROR;
-}
-
-int cHttpResource::handleHeadRequest() {
- if (mMethod.compare("HEAD") != 0) {
- return 0;
- }
- *(mLog->log())<< DEBUGPREFIX
- << " Handle HEAD Request for Url " << mPath << endl;
- mConnState = SERVING;
- mContentType = MEMBLOCK;
-
- // sent an empty response message with just the OK header
- mResponseMessage = new string();
- *mResponseMessage = "";
- mResponseMessagePos = 0;
-
- sendHeaders(200, "OK", NULL, NULL, -1, -1);
- return 1;
-}
-
-int cHttpResource::handlePost() {
- mConnState = SERVING;
- mContentType = MEMBLOCK;
-
- // sent an empty response message with just the OK header
- mResponseMessage = new string();
- *mResponseMessage = "";
- mResponseMessagePos = 0;
-
- if (mPath.compare("/log") == 0) {
- *(mLog->log())<< mPayload
- << endl;
-
- sendHeaders(200, "OK", NULL, NULL, -1, -1);
- return OKAY;
- }
-
- if (mPath.compare("/getResume.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- // sendResumeXml( &statbuf);
- sendResumeXml( );
- return OKAY;
- }
-
- if (mPath.compare("/setResume.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- receiveResume();
- return OKAY;
- }
-
- if (mPath.compare("/deleteRecording.xml") == 0) {
- if (handleHeadRequest() != 0)
- return OKAY;
-
- deleteRecording();
- return OKAY;
- }
-
- // Should not reach the end of the function
- return ERROR;
-}
-
-
-void cHttpResource::sendError(int status, const char *title, const char *extra, const char *text) {
- char f[400];
-
- mConnState = SERVING;
- mContentType = MEMBLOCK;
- mResponseMessage = new string();
- *mResponseMessage = "";
- mResponseMessagePos = 0;
-
- string hdr = "";
- // sendHeaders(status, title, extra, "text/html", -1, -1);
- sendHeaders(status, title, extra, "text/plain", -1, -1);
-
- /* snprintf(f, sizeof(f), "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\r\n", status, title);
- hdr += f;
- snprintf(f, sizeof(f), "<BODY><H4>%d %s</H4>\r\n", status, title);
- hdr += f;
-*/
- snprintf(f, sizeof(f), "%s\r\n", text);
- hdr += f;
- /* snprintf(f, sizeof(f), "</BODY></HTML>\r\n");
- hdr += f;
-*/
-
- strcpy(&(mBlkData[mBlkLen]), hdr.c_str());
- mBlkLen += hdr.size();
-
-}
-
-
-int cHttpResource::sendDir(struct stat *statbuf) {
- char pathbuf[4096];
- char f[400];
- int len;
-
- mConnState = SERVING;
-
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX << " sendDir: mPath= " << mPath << endl;
-#endif
- len = mPath.length();
- // int ret = OKAY;
-
- if (len == 0 || mPath[len - 1] != '/') {
- snprintf(pathbuf, sizeof(pathbuf), "Location: %s/", mPath.c_str());
- sendError(302, "Found", pathbuf, "Directories must end with a slash.");
- return OKAY;
- }
-
- snprintf(pathbuf, sizeof(pathbuf), "%sindex.html", mPath.c_str());
- if (stat(pathbuf, statbuf) >= 0) {
- mPath = pathbuf;
- mFileSize = statbuf->st_size;
- mContentType = SINGLEFILE;
- return sendFile(statbuf);
- }
-
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX << " sendDir: create index.html " << endl;
-#endif
- DIR *dir;
- struct dirent *de;
-
- mResponseMessage = new string();
- mResponseMessagePos = 0;
- *mResponseMessage = "";
-
- string hdr = "";
- snprintf(f, sizeof(f), "<HTML><HEAD><TITLE>Index of %s</TITLE></HEAD>\r\n<BODY>", mPath.c_str());
- hdr += f;
- snprintf(f, sizeof(f), "<H4>Index of %s</H4>\r\n<PRE>\n", mPath.c_str());
- hdr += f;
- snprintf(f, sizeof(f), "Name Last Modified Size\r\n");
- hdr += f;
- snprintf(f, sizeof(f), "<HR>\r\n");
- hdr += f;
-
- *mResponseMessage += hdr;
- hdr = "";
-
- if (len > 1) {
- snprintf(f, sizeof(f), "<A HREF=\"..\">..</A>\r\n");
- hdr += f;
- }
- *mResponseMessage += hdr;
-
- dir = opendir(mPath.c_str());
- while ((de = readdir(dir)) != NULL) {
- char timebuf[32];
- struct tm *tm;
- strcpy(pathbuf, mPath.c_str());
- // printf (" -Entry: %s\n", de->d_name);
- strcat(pathbuf, de->d_name);
-
- stat(pathbuf, statbuf);
- tm = gmtime(&(statbuf->st_mtime));
- strftime(timebuf, sizeof(timebuf), "%d-%b-%Y %H:%M:%S", tm);
-
- hdr = "";
- snprintf(f, sizeof(f), "<A HREF=\"%s%s\">", de->d_name, S_ISDIR(statbuf->st_mode) ? "/" : "");
- hdr += f;
-
- snprintf(f, sizeof(f), "%s%s", de->d_name, S_ISDIR(statbuf->st_mode) ? "/</A>" : "</A> ");
- hdr += f;
-
- if (strlen(de->d_name) < 32) {
- snprintf(f, sizeof(f), "%*s", 32 - strlen(de->d_name), "");
- hdr += f;
- }
- if (S_ISDIR(statbuf->st_mode)) {
- snprintf(f, sizeof(f), "%s\r\n", timebuf);
- hdr += f;
- }
- else {
- snprintf(f, sizeof(f), "%s\r\n", timebuf);
- hdr += f;
- }
-
- *mResponseMessage += hdr;
- }
- closedir(dir);
- snprintf(f, sizeof(f), "</PRE>\r\n<HR>\r\n<ADDRESS>%s</ADDRESS>\r\n</BODY></HTML>\r\n", SERVER);
- *mResponseMessage += f;
-
- sendHeaders(200, "OK", NULL, "text/html", mResponseMessage->size(), statbuf->st_mtime);
-
- mRemLength = 0;
- return OKAY;
-}
-
-
-int cHttpResource::writeXmlItem(string name, string link, string programme, string desc, string guid, int no, time_t start, int dur, double fps, int is_pes, int is_new) {
- string hdr = "";
- char f[400];
-
- hdr += "<item>\n";
- // snprintf(f, sizeof(f), "%s - %s", );
- hdr += "<title>" + name +"</title>\n";
- hdr += "<link>" +link + "</link>\n";
- hdr += "<enclosure url=\"" +link + "\" type=\"video/mpeg\" />\n";
-
- hdr += "<guid>" + guid + "</guid>\n";
-
- snprintf(f, sizeof(f), "%d", no);
- hdr += "<number>";
- hdr += f;
- hdr += "</number>\n";
-
- hdr += "<programme>" + programme +"</programme>\n";
- hdr += "<description>" + desc + "</description>\n";
-
- snprintf(f, sizeof(f), "%ld", start);
- hdr += "<start>";
- hdr += f;
- hdr += "</start>\n";
-
- snprintf(f, sizeof(f), "%d", dur);
- hdr += "<duration>";
- hdr += f;
- hdr += "</duration>\n";
-
- if (fps != -1)
- snprintf(f, sizeof(f), "<fps>%.2f</fps>\n", fps);
- else
- snprintf(f, sizeof(f), "<fps>unknown</fps>\n");
- hdr += f;
-
- switch (is_pes){
- case -1:
- // unknown
- hdr += "<ispes>unknown</ispes>\n";
- break;
- case 0:
- // true
- hdr += "<ispes>true</ispes>\n";
- break;
- case 1:
- // false
- hdr += "<ispes>false</ispes>\n";
- break;
- default:
- break;
- }
-
- switch (is_new){
- case -1:
- // unknown
- hdr += "<isnew>unknown</isnew>\n";
- break;
- case 0:
- // true
- hdr += "<isnew>true</isnew>\n";
- break;
- case 1:
- // false
- hdr += "<isnew>false</isnew>\n";
- break;
- default:
- break;
- }
-
- hdr += "</item>\n";
-
- *mResponseMessage += hdr;
-
-
-
-
- // return writeToClient(hdr.c_str(), hdr.size());
- return OKAY;
-}
-
-int cHttpResource::parseQueryLine (vector<sQueryAVP> *avps) {
- bool done = false;
- size_t cur_pos = 0;
- while (!done) {
- size_t end_pos = mQuery.find('&', cur_pos);
- size_t pos_eq = mQuery.find('=', cur_pos);
-
- if (pos_eq != cur_pos) {
- avps->push_back(sQueryAVP(mQuery.substr(cur_pos, (pos_eq -cur_pos)), mQuery.substr(pos_eq+1, (end_pos -pos_eq-1)) ));
- }
- if (end_pos == string::npos)
- done = true;
- else
- cur_pos = end_pos +1;
- }
-
- return OKAY;
-}
-
-int cHttpResource::getQueryAttributeValue(vector<sQueryAVP> *avps, string attr, string &val) {
- int found = ERROR;
- for (uint i = 0; i < avps->size(); i++) {
- if ((*avps)[i].attribute == attr) {
- val = (*avps)[i].value;
- found = OKAY;
- }
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " a= "
- << (*avps)[i].attribute
- << " v= " << (*avps)[i].value
- << endl;
-#endif
- }
- return found;
-}
-
-int cHttpResource::parseFiles(vector<sFileEntry> *entries, string prefix, string dir_base, string dir_name, struct stat *statbuf) {
- char pathbuf[4096];
- string link;
- DIR *dir;
- struct dirent *de;
- string dir_comp;
- dir_comp = dir_base + dir_name + "/";
-
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX
- << " parseFiles: Prefix= " << prefix
- << " base= " << dir_base
- << " dir= " << dir_name
- << " comp= " << dir_comp
- << endl;
-#endif
-
- dir = opendir(dir_comp.c_str());
- if (stat(dir_comp.c_str(), statbuf) < 0)
- return ERROR;
-
- while ((de = readdir(dir)) != NULL) {
- if ((strcmp(de->d_name, ".") == 0) or (strcmp(de->d_name, "..") == 0)) {
- continue;
- }
-
- strcpy(pathbuf, dir_comp.c_str());
- strcat(pathbuf, de->d_name);
-
- stat(pathbuf, statbuf);
-
- if (S_ISDIR(statbuf->st_mode)) {
- if (strcmp(&(pathbuf[strlen(pathbuf)-4]), ".rec") == 0) {
- // vdr folder
- time_t now = time(NULL);
- struct tm tm_r;
- struct tm t = *localtime_r(&now, &tm_r);
- t.tm_isdst = -1;
- // char [20] rest;
- int start = -1;
- sscanf(de->d_name, "%4d-%02d-%02d.%02d.%02d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min);
-
- // sscanf(de->d_name, "%4d-%02d-%02d.%02d%.%02d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min);
- t.tm_year -= 1900;
- t.tm_mon--;
- t.tm_sec = 0;
- start = mktime(&t);
-
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX
- << " Vdr Folder Found: " << pathbuf << " start= " << start << endl;
-#endif
-
- entries->push_back(sFileEntry(dir_name, pathbuf, start));
- }
- else {
- // regular file
- parseFiles(entries, prefix + de->d_name + "~", dir_comp, de->d_name, statbuf);
- }
- }
- else {
- if ((de->d_name)[0] != '.' )
- entries->push_back(sFileEntry(prefix+de->d_name, pathbuf, 1));
- }
- }
- closedir(dir);
- return OKAY;
-}
-
-int cHttpResource::sendManifest (struct stat *statbuf, bool is_hls) {
-#ifndef STANDALONE
-
- size_t pos = mPath.find_last_of ("/");
-
- mDir = mPath.substr(0, pos);
- string mpd_name = mPath.substr(pos+1);
-
- float seg_dur = mFactory->getConfig()->getSegmentDuration() *1.0;
-
- cRecordings* recordings = &Recordings;
- cRecording* rec = recordings->GetByName(mDir.c_str());
- double duration = rec->NumFrames() / rec->FramesPerSecond();
-
- int bitrate = (int)((getVdrFileSize() *8.0 * mFactory->getConfig()->getHasBitrateCorrection()/ duration) +0.5);
-
- time_t now = time(NULL);
-
- if (rec->Info() != NULL){
- if (rec->Info()->GetEvent() != NULL) {
- if (rec->Info()->GetEvent()->EndTime() > now) {
-
- float corr = (now - rec->Info()->GetEvent()->StartTime()) - duration;
- duration = rec->Info()->GetEvent()->Duration() -int(corr);
- *(mLog->log()) << DEBUGPREFIX
- << " is Recording: Duration= " << duration << " sec"
- << " correction: " << int(corr)
- << endl;
- }
- }
- else
- *(mLog->log()) << DEBUGPREFIX << " WARNING: rec-Info()->GetEvent() is NULL " << endl;
- }
- else
- *(mLog->log()) << DEBUGPREFIX << " WARNING: rec-Info() is NULL " << endl;
-
- // duration is now either the actual duration of the asset or the target duration of the asset
- int end_seg = int (duration / seg_dur) +1;
-
- *(mLog->log()) << DEBUGPREFIX
- << " Manifest for mDir= " << mDir
- << " duration= " << duration
- << " seg_dur= " << seg_dur
- << " end_seg= " << end_seg
- << endl;
-
-
-
- if (is_hls) {
- writeM3U8(duration, bitrate, seg_dur, end_seg);
- }
- else {
- writeMPD(duration, bitrate, seg_dur, end_seg);
- }
-
-#endif
- return OKAY;
-}
-
-void cHttpResource::writeM3U8(double duration, int bitrate, float seg_dur, int end_seg) {
- mResponseMessage = new string();
- mResponseMessagePos = 0;
- *mResponseMessage = "";
- mContentType = MEMBLOCK;
-
- mConnState = SERVING;
- char buf[30];
-
- string hdr = "";
-
-
- *mResponseMessage += "#EXTM3U\n";
- // snprintf(buf, sizeof(buf), "#EXT-X-TARGETDURATION:%d\n", (seg_dur-1));
- snprintf(buf, sizeof(buf), "#EXT-X-TARGETDURATION:%d\n", int(seg_dur));
- hdr = buf;
- *mResponseMessage += hdr;
-
- *mResponseMessage += "#EXT-X-MEDIA-SEQUENCE:1\n";
- *mResponseMessage += "#EXT-X-KEY:METHOD=NONE\n";
-
- for (int i = 1; i < end_seg; i++){
- // snprintf(buf, sizeof(buf), "#EXTINF:%.1f,\n", (seg_dur-0.5));
- snprintf(buf, sizeof(buf), "#EXTINF:%.2f,\n", seg_dur);
- hdr = buf;
- *mResponseMessage += hdr;
-
- snprintf(buf, sizeof(buf), "%d-seg.ts\n", i);
- hdr = buf;
- *mResponseMessage += hdr;
- }
- *mResponseMessage += "#EXT-X-ENDLIST\n";
-
- sendHeaders(200, "OK", NULL, "application/x-mpegURL", mResponseMessage->size(), -1);
-}
-
-
-void cHttpResource::writeMPD(double duration, int bitrate, float seg_dur, int end_seg) {
- mResponseMessage = new string();
- mResponseMessagePos = 0;
- *mResponseMessage = "";
- mContentType = MEMBLOCK;
-
- mConnState = SERVING;
- char buf[30];
- char line[400];
-
- string hdr = "";
-
- *mResponseMessage += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
-
- snprintf(line, sizeof(line), "<MPD type=\"OnDemand\" minBufferTime=\"PT%dS\" mediaPresentationDuration=\"PT%.1fS\"",
- mFactory->getConfig()->getHasMinBufferTime(), duration);
- *mResponseMessage = *mResponseMessage + line;
-
- *mResponseMessage += " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:mpeg:mpegB:schema:DASH:MPD:DIS2011\" ";
- *mResponseMessage += "xsi:schemaLocation=\"urn:mpeg:mpegB:schema:DASH:MPD:DIS2011\">\n";
- *mResponseMessage += "<ProgramInformation>\n";
- *mResponseMessage += "<ChapterDataURL/>\n";
- *mResponseMessage += "</ProgramInformation>\n";
- *mResponseMessage += "<Period start=\"PT0S\" segmentAlignmentFlag=\"True\">\n";
- // SD: 720x 576
- // HD: 1280x 720
- // snprintf(line, sizeof(line), "<Representation id=\"0\" mimeType=\"video/mpeg\" bandwidth=\"%d\" startWithRAP=\"True\" width=\"1280\" height=\"720\" group=\"0\">\n", mFactory->getConfig()->getHasBitrate());
- snprintf(line, sizeof(line), "<Representation id=\"0\" mimeType=\"video/mpeg\" bandwidth=\"%d\" startWithRAP=\"True\" %s group=\"0\">\n",
- bitrate, ((bitrate < 10000000)? "width=\"720\" height=\"576\"" : "width=\"1280\" height=\"720\""));
- *mResponseMessage = *mResponseMessage + line;
-
- hdr = "<SegmentInfo duration=";
- snprintf(buf, sizeof(buf), "\"PT%.1fS\"", (seg_dur*1.0));
- hdr = hdr + buf + " >\n";
- *mResponseMessage += hdr;
-
- snprintf(buf, sizeof(buf), "\"%d\"", end_seg);
- *mResponseMessage += "<UrlTemplate sourceURL=\"$Index$-seg.ts\" startIndex=\"1\" endIndex=";
- hdr = buf ;
- *mResponseMessage += hdr + " />\n";
-
- *mResponseMessage += "</SegmentInfo>\n";
- *mResponseMessage += "</Representation>\n";
- *mResponseMessage += "</Period>\n";
- *mResponseMessage += "</MPD>";
-
- sendHeaders(200, "OK", NULL, "application/x-mpegURL", mResponseMessage->size(), -1);
-}
-
-int cHttpResource::sendMediaSegment (struct stat *statbuf) {
-#ifndef STANDALONE
-
- *(mLog->log()) << DEBUGPREFIX << " sendMediaSegment " << mPath << endl;
- size_t pos = mPath.find_last_of ("/");
-
- mDir = mPath.substr(0, pos);
- string seg_name = mPath.substr(pos+1);
- int seg_number;
-
- int seg_dur = mFactory->getConfig()->getSegmentDuration();
- int frames_per_seg = 0;
-
- sscanf(seg_name.c_str(), "%d-seg.ts", &seg_number);
-
- //FIXME: Do some consistency checks on the seg_number
- //* Does the segment exist
-
- cRecordings* recordings = &Recordings;
- cRecording* rec = recordings->GetByName(mDir.c_str());
- if (rec != NULL) {
- frames_per_seg = seg_dur * rec->FramesPerSecond();
- }
- else {
- *(mLog->log()) << DEBUGPREFIX << " ERROR: Ooops, rec is NULL, assuming 25 fps " << endl;
- frames_per_seg = seg_dur * 25;
- }
- //FIXME: HD Fix
- // frames_per_seg = seg_dur * 25;
-
- *(mLog->log()) << DEBUGPREFIX
- << " mDir= " << mDir
- << " seg_name= " << seg_name
- << " seg_number= "<< seg_number
- << " fps= " << rec->FramesPerSecond()
- << " frames_per_seg= " << frames_per_seg
- << endl;
- int start_frame_count = (seg_number -1) * frames_per_seg;
-
- FILE* idx_file = fopen((mDir +"/index").c_str(), "r");
- if (idx_file == NULL){
- *(mLog->log()) << DEBUGPREFIX
- << " failed to open idx file = "<< (mDir +"/index").c_str()
- << endl;
- sendError(404, "Not Found", NULL, "Failed to open Index file");
- return OKAY;
- }
-
- char *index_buf = new char[(frames_per_seg +3) *8];
-
- // fseek to start_frame_count * sizeof(in_read)
- fseek(idx_file, start_frame_count * 8, SEEK_SET);
-
- // read to (seg_number * frames_per_seg +1) * sizeof(in_read)
- // buffersize is frames_per_seg * seg_number * sizeof(in_read)
- int buffered_indexes = fread(index_buf, 8, (frames_per_seg +2), idx_file);
-
- fclose(idx_file);
-
- if(buffered_indexes <= 0 ) {
- *(mLog->log())<<DEBUGPREFIX
- << " issue while reading" << endl;
- delete[] index_buf;
- sendError(404, "Not Found", NULL, "Failed to read Index file");
- return OKAY;
- }
-
- // Reading the segment
- mFileStructure = "%s/%05d.ts";
- int start_offset = -1;
- int start_idx = -1;
-
- tIndexTs in_read_ts;
- memcpy (&in_read_ts, &(index_buf[0]), 8);
-
- start_offset = in_read_ts.offset;
- start_idx = in_read_ts.number;
-
- char seg_fn[200];
- mVdrIdx = start_idx;
-
- snprintf(seg_fn, sizeof(seg_fn), mFileStructure.c_str(), mDir.c_str(), mVdrIdx);
- mPath = seg_fn;
-
- /*
- * Now we determine the end of the segment
- */
- memcpy (&in_read_ts, &(index_buf[(frames_per_seg)*8]), 8);
-
- int end_idx = in_read_ts.number;
- int end_offset = in_read_ts.offset;
-
- /*#ifndef DEBUG*/
- *(mLog->log()) << DEBUGPREFIX
- << " GenSegment: start (no/idx)= " << start_idx << " / " << start_offset
- << " to (no/idx)= " << end_idx << " / " << end_offset
- << endl;
- /*#endif*/
-
- delete[] index_buf;
-
- int rem_len = 0;
- bool error = false;
- if (start_idx == end_idx){
- mRemLength = (end_offset - start_offset);
-
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX
- << " start_idx == end_idx: mRemLength= " <<mRemLength
- << endl;
-#endif
- }
- else {
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX
- << " start_idx < end_idx "
- << endl;
-#endif
- snprintf(seg_fn, sizeof(seg_fn), mFileStructure.c_str(), mDir.c_str(), mVdrIdx);
- if (stat(seg_fn, statbuf) < 0) {
- *(mLog->log()) << DEBUGPREFIX
- << " file= " <<seg_fn << " does not exist"
- << endl;
- error= true;
- // issue:
- }
- rem_len = statbuf->st_size - start_offset; // remaining length of the first segment
-
- // loop over all idx files between start_idx and end_idx
- for (int idx = (start_idx+1); idx < end_idx; idx ++) {
- snprintf(seg_fn, sizeof(seg_fn), mFileStructure.c_str(), mDir.c_str(), idx);
- if (stat(seg_fn, statbuf) < 0) {
- *(mLog->log()) << DEBUGPREFIX
- << " for loop file= " <<seg_fn << " does not exist"
- << endl;
- error = true;
- break;
- // issue:
- }
- rem_len += statbuf->st_size; // remaining length of the first segment
- }
- rem_len += end_offset; //
- mRemLength = rem_len;
- snprintf(seg_fn, sizeof(seg_fn), mFileStructure.c_str(), mDir.c_str(), mVdrIdx);
-
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX
- << " start_idx= " << start_idx << " != end_idx= "<< end_idx <<": mRemLength= " <<mRemLength
- << endl;
-#endif
- }
-
- if (error){
- sendError(404, "Not Found", NULL, "Not all inputs exists");
- return OKAY;
- }
-
- mContentType = VDRDIR;
-
- if (openFile(seg_fn) != OKAY) {
- *(mLog->log())<< DEBUGPREFIX << " Failed to open file= " << seg_fn
- << " mRemLength= " << mRemLength<< endl;
- sendError(404, "Not Found", NULL, "File not found.");
- return OKAY;
- }
- fseek(mFile, start_offset, SEEK_SET);
-
- sendHeaders(200, "OK", NULL, "video/mpeg", mRemLength, -1);
-
-#endif
- return OKAY;
-}
-
-int cHttpResource::sendMediaXml (struct stat *statbuf) {
- char pathbuf[4096];
- string link;
- string media_folder = mFactory->getConfig()->getMediaFolder();
-
- mResponseMessage = new string();
- mResponseMessagePos = 0;
- *mResponseMessage = "";
- mContentType = MEMBLOCK;
-
- mConnState = SERVING;
-
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX << " sendMedia " << endl;
-#endif
-
- string own_ip = getOwnIp(mFd);
- *(mLog->log()) << " OwnIP= " << own_ip << endl;
-
- vector<sFileEntry> entries;
-
- if (parseFiles(&entries, "", media_folder, "", statbuf) == ERROR) {
- sendError(404, "Not Found", NULL, "Media Folder likely not configured.");
- return OKAY;
- }
-
- string hdr = "";
- hdr += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- hdr += "<rss version=\"2.0\">\n";
- hdr+= "<channel>\n";
-
- *mResponseMessage += hdr;
-
- hdr = "";
-
- for (uint i=0; i < entries.size(); i++) {
-
- // snprintf(pathbuf, sizeof(pathbuf), "http://%s:%d%s", mServerAddr.c_str(), mServerPort,
- snprintf(pathbuf, sizeof(pathbuf), "http://%s:%d%s", own_ip.c_str(), mServerPort,
- cUrlEncode::doUrlSaveEncode(entries[i].sPath).c_str());
- if (writeXmlItem(cUrlEncode::doXmlSaveEncode(entries[i].sName), pathbuf, "NA", "NA", "-",
- -1, entries[i].sStart, -1, -1, -1, -1) == ERROR)
- return ERROR;
-
- }
-
- hdr = "</channel>\n";
- hdr += "</rss>\n";
- *mResponseMessage += hdr;
- sendHeaders(200, "OK", NULL, "application/xml", mResponseMessage->size(), statbuf->st_mtime);
-
- return OKAY;
-}
-
-int cHttpResource::sendVdrStatusXml (struct stat *statbuf) {
-
-#ifndef STANDALONE
-
- char f[400];
- mResponseMessage = new string();
- *mResponseMessage = "";
- mResponseMessagePos = 0;
- mContentType = MEMBLOCK;
-
- mConnState = SERVING;
-
- int free;
- int used;
- int percent;
-
- percent = VideoDiskSpace(&free, &used);
-
- *mResponseMessage += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- *mResponseMessage += "<vdrstatus>\n";
-
- *mResponseMessage += "<diskspace>\n";
- snprintf(f, sizeof(f), "<free>%d</free>", free);
- *mResponseMessage += f;
-
- snprintf(f, sizeof(f), "<used>%d</used>", used);
- *mResponseMessage += f;
- snprintf(f, sizeof(f), "<percent>%d</percent>", percent);
- *mResponseMessage += f;
- *mResponseMessage += "</diskspace>\n";
-
- *mResponseMessage += "</vdrstatus>\n";
-
- sendHeaders(200, "OK", NULL, "application/xml", mResponseMessage->size(), -1);
-
-#endif
- return OKAY;
-}
-
-int cHttpResource::sendEpgXml (struct stat *statbuf) {
-#ifndef STANDALONE
-
- char f[400];
- mResponseMessage = new string();
- *mResponseMessage = "";
- mResponseMessagePos = 0;
- mContentType = MEMBLOCK;
-
- mConnState = SERVING;
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " generating /epg.xml"
- << DEBUGHDR << endl;
-#endif
- vector<sQueryAVP> avps;
- parseQueryLine(&avps);
- string id = "S19.2E-1-1107-17500";
- string mode = "";
- bool add_desc = true;
-
- if (getQueryAttributeValue(&avps, "id", id) == ERROR){
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: id not found"
- << DEBUGHDR << endl;
- delete mResponseMessage;
- sendError(400, "Bad Request", NULL, "no id in query line");
- return OKAY;
- }
-
- if (getQueryAttributeValue(&avps, "mode", mode) == OKAY){
- if (mode == "nodesc") {
- add_desc = false;
- *(mLog->log())<< DEBUGPREFIX
- << " **** Mode: No Description ****"
- << endl;
- }
- }
-
- /* for (int i = 0; i < avps.size(); i++) {
- if (avps[i].attribute == "id")
- id = avps[i].value;
- *(mLog->log())<< DEBUGPREFIX
- << " a= "
- << avps[i].attribute
- << " v= " << avps[i].value
- << endl;
- }*/
- tChannelID chan_id = tChannelID::FromString (id.c_str());
- if ( chan_id == tChannelID::InvalidID) {
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: Not possible to get the ChannelId from the string"
- << DEBUGHDR << endl;
- delete mResponseMessage;
- sendError(400, "Bad Request", NULL, "Invalid Channel ID.");
- return OKAY;
- }
-
- cSchedulesLock * lock = new cSchedulesLock(false, 500);
- const cSchedules *schedules = cSchedules::Schedules(*lock);
-
- const cSchedule *schedule = schedules->GetSchedule(chan_id);
- if (schedule == NULL) {
- *(mLog->log())<< DEBUGPREFIX
- << "ERROR: Schedule is zero for guid= " << id
- << endl;
- delete mResponseMessage;
- sendError(500, "Internal Server Error", NULL, "Schedule is zero.");
- return OKAY;
- }
-
- time_t now = time(NULL);
- const cEvent *ev = NULL;
- for(cEvent* e = schedule->Events()->First(); e; e = schedule->Events()->Next(e)) {
- if ( (e->StartTime() <= now) && (e->EndTime() > now)) {
- ev = e;
-
- } else if (e->StartTime() > now + 3600) {
- break;
- }
- }
-
- // const cEvent * ev = schedule->GetPresentEvent();
-
- if (ev == NULL) {
- *(mLog->log())<< DEBUGPREFIX
- << "ERROR: Event is zero for guid= " << id
- << endl;
- delete mResponseMessage;
- sendError(500, "Internal Server Error", NULL, "Event is zero.");
- return OKAY;
- }
-
- string hdr = "";
- hdr += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- hdr += "<tv version=\"2.0\">\n";
- hdr+= "<programme>\n";
-
- *mResponseMessage += hdr;
- // Payload here
-
- hdr = "";
- if (ev->Title() != NULL) {
- string title = cUrlEncode::doXmlSaveEncode(ev->Title());
- hdr += "<title>" + title +"</title>\n";
- }
- else {
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: title is zero for guid= " << id << endl;
- hdr += "<title>Empty</title>\n";
-
- delete mResponseMessage;
- sendError(500, "Internal Server Error", NULL, "Title is zero.");
- return OKAY;
- }
-
- hdr += "<guid>" + id + "</guid>\n";
-
- *(mLog->log())<< DEBUGPREFIX
- << " guid= " << id
- << " title= " << ev->Title()
- << " start= " << ev->StartTime()
- << " end= " << ev->EndTime()
- << " now= " << now
- << endl;
- if (add_desc) {
- hdr += "<desc>";
- if (ev->Description() != NULL) {
- hdr += cUrlEncode::doXmlSaveEncode(ev->Description());
- }
- else {
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: description is zero for guid= " << id << endl;
-
- delete mResponseMessage;
- sendError(500, "Internal Server Error", NULL, "Description is zero.");
- return OKAY;
- }
- hdr += "</desc>\n";
- }
- else {
- hdr += "<desc>No Description Available</desc>\n";
- }
- snprintf(f, sizeof(f), "<start>%ld</start>\n", ev->StartTime());
- hdr += f ;
-
- snprintf(f, sizeof(f), "<end>%ld</end>\n", ev->EndTime());
- hdr += f;
-
- snprintf(f, sizeof(f), "<duration>%d</duration>\n", ev->Duration());
- hdr += f;
- *mResponseMessage += hdr;
-
- hdr = "</programme>\n";
- hdr += "</tv>\n";
-
- *mResponseMessage += hdr;
-
- delete lock;
-
- sendHeaders(200, "OK", NULL, "application/xml", mResponseMessage->size(), -1);
-
-#endif
- return OKAY;
-}
-
-int cHttpResource::sendChannelsXml (struct stat *statbuf) {
-#ifndef STANDALONE
-
- char f[400];
- mResponseMessage = new string();
- *mResponseMessage = "";
- mResponseMessagePos = 0;
- mContentType = MEMBLOCK;
-
- mConnState = SERVING;
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " generating /channels.xml"
- << DEBUGHDR << endl;
-#endif
- string own_ip = getOwnIp(mFd);
- *(mLog->log()) << " OwnIP= " << own_ip << endl;
-
- vector<sQueryAVP> avps;
- parseQueryLine(&avps);
- string mode = "";
- bool add_desc = true;
-
- string no_channels_str = "";
- int no_channels = -1;
- string group_sep = "";
-
- if (getQueryAttributeValue(&avps, "mode", mode) == OKAY){
- if (mode == "nodesc") {
- add_desc = false;
- *(mLog->log())<< DEBUGPREFIX
- << " Mode: No Description"
- << endl;
- }
- else {
- *(mLog->log())<< DEBUGPREFIX
- << " Mode: Unknown"
- << endl;
- }
- }
- if (getQueryAttributeValue(&avps, "channels", no_channels_str) == OKAY){
- no_channels = atoi(no_channels_str.c_str()) ;
- }
-
-
- string hdr = "";
- hdr += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- hdr += "<rss version=\"2.0\">\n";
- hdr+= "<channel>\n";
- hdr+= "<title>VDR Channels List</title>\n";
-
-
- *mResponseMessage += hdr;
-
- int count = mFactory->getConfig()->getLiveChannels();
- if (no_channels > 0)
- count = no_channels +1;
-
- cSchedulesLock * lock = new cSchedulesLock(false, 500);
- const cSchedules *schedules = cSchedules::Schedules(*lock);
-
- for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) {
- if (channel->GroupSep()) {
- if (mFactory->getConfig()->getGroupSep() != IGNORE) {
- // if emtpyFolderDown, always.
- // otherwise, only when not empty
- if (!((strcmp(channel->Name(), "") == 0) && (mFactory->getConfig()->getGroupSep() == EMPTYIGNORE)))
- group_sep = cUrlEncode::doXmlSaveEncode(channel->Name());
-
- }
- continue;
- }
- if (--count == 0) {
- break;
- }
-
- // snprintf(f, sizeof(f), "http://%s:3000/%s.ts", mServerAddr.c_str(), *(channel->GetChannelID()).ToString());
- snprintf(f, sizeof(f), "http://%s:3000/%s.ts", own_ip.c_str(), *(channel->GetChannelID()).ToString());
- string link = f;
-
- const cSchedule *schedule = schedules->GetSchedule(channel->GetChannelID());
- string desc = "No description available";
- string title = "Not available";
- time_t start_time = 0;
- int duration = 0;
-
- if (schedule != NULL) {
- const cEvent *ev = schedule->GetPresentEvent();
- if (ev != NULL) {
- if ((ev->Description() != NULL) && add_desc)
- desc = cUrlEncode::doXmlSaveEncode(ev->Description());
-
- if ((ev->Title() != NULL) && add_desc)
- title = cUrlEncode::doXmlSaveEncode(ev->Title());
- start_time = ev->StartTime();
- duration = ev->Duration();
- }
- else {
- *(mLog->log())<< DEBUGPREFIX
- << " Event Info is Zero for Count= "
- << count
- << " Name= " << channel->Name() << endl;
- }
- }
- else {
- *(mLog->log())<< DEBUGPREFIX
- << " Schedule is Zero for Count= "
- << count
- << " Name= " << channel->Name() << endl;
- }
-
- string c_name = (group_sep != "") ? (group_sep + "~" + cUrlEncode::doXmlSaveEncode(channel->Name()))
- : cUrlEncode::doXmlSaveEncode(channel->Name());
- // if (writeXmlItem(channel->Name(), link, title, desc, *(channel->GetChannelID()).ToString(), start_time, duration) == ERROR)
- if (writeXmlItem(c_name, link, title, desc, *(channel->GetChannelID()).ToString(), channel->Number(), start_time, duration, -1, -1, -1) == ERROR)
- return ERROR;
-
- }
-
- hdr = "</channel>\n";
- hdr += "</rss>\n";
-
- *mResponseMessage += hdr;
- delete lock;
- sendHeaders(200, "OK", NULL, "application/xml", mResponseMessage->size(), statbuf->st_mtime);
-
-#endif
- return OKAY;
-}
-
-int cHttpResource::receiveResume() {
- string dev_id;
- cResumeEntry entry;
- if (parseResume(entry, dev_id) == ERROR) {
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR parsing resume"
- << endl;
- }
-
- *(mLog->log())<< DEBUGPREFIX
- << " Resume: id= " << dev_id
- << " resume= " << entry << endl;
-
- vector<sQueryAVP> avps;
- parseQueryLine(&avps);
- string guid;
- string resume_str;
-
- if (getQueryAttributeValue(&avps, "guid", guid) == OKAY){
- entry.mFilename = guid;
- *(mLog->log())<< DEBUGPREFIX
- << " Found a id Parameter: " << guid
- << endl;
- }
- if (getQueryAttributeValue(&avps, "resume", resume_str) == OKAY){
- entry.mResume = atof(resume_str.c_str());
- *(mLog->log())<< DEBUGPREFIX
- << " Found a resume Parameter: " << entry.mResume
- << endl;
- }
-
-
-
-
-#ifndef STANDALONE
- cRecording *rec = Recordings.GetByName(entry.mFilename.c_str());
- if (rec == NULL) {
- //Error 404
- sendError(404, "Not Found", NULL, "Failed to find recording.");
- return OKAY;
- }
-
- cResumeFile resume(entry.mFilename.c_str(), rec->IsPesRecording());
- *(mLog->log())<< DEBUGPREFIX
- << " Resume: " << entry.mFilename
- << " saving Index= " << int(entry.mResume * rec->FramesPerSecond() )
- << " mResume= " <<entry.mResume
- << " fpr= " << rec->FramesPerSecond()
- << endl;
-
- resume.Save(int(entry.mResume * rec->FramesPerSecond() ));
-#endif
-
- sendHeaders(200, "OK", NULL, NULL, -1, -1);
- return OKAY;
-}
-
-//int cHttpResource::sendResumeXml (struct stat *statbuf) {
-int cHttpResource::sendResumeXml () {
-#ifndef STANDALONE
-
- mResponseMessage = new string();
- *mResponseMessage = "";
- mResponseMessagePos = 0;
- mContentType = MEMBLOCK;
-
- mConnState = SERVING;
-
- char f[400];
-
- cResumeEntry entry;
- string id;
-
- parseResume(entry, id);
-
- vector<sQueryAVP> avps;
- parseQueryLine(&avps);
- string guid;
-
- if (getQueryAttributeValue(&avps, "guid", guid) == OKAY){
- entry.mFilename = guid;
- *(mLog->log())<< DEBUGPREFIX
- << " Found a id Parameter: " << guid
- << endl;
- }
-
-
- cRecording *rec = Recordings.GetByName(entry.mFilename.c_str());
- if (rec == NULL) {
- //Error 404
- *(mLog->log())<< DEBUGPREFIX
- << " sendResume: File Not Found filename= " << entry.mFilename << endl;
- sendError(404, "Not Found", NULL, "Failed to find recording.");
- return OKAY;
- }
- if (rec->IsNew()) {
- *(mLog->log())<< DEBUGPREFIX
- << " sendResume: file is new " << endl;
- sendError(400, "Bad Request", NULL, "File is new.");
- return OKAY;
- }
- cResumeFile resume(entry.mFilename.c_str(), rec->IsPesRecording());
-
- *(mLog->log())<< DEBUGPREFIX
- << " resume request for " << entry.mFilename
- << " resume= " << resume.Read()
- << " (" << resume.Read() *1.0 / rec->FramesPerSecond() << "sec)"
- << endl;
-
- *mResponseMessage += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- *mResponseMessage += "<resume>";
- snprintf(f, sizeof(f), "%.02f", resume.Read() *1.0 / rec->FramesPerSecond());
- *mResponseMessage += f;
- *mResponseMessage += "</resume>\n";
-
-
- sendHeaders(200, "OK", NULL, "application/xml", mResponseMessage->size(), -1);
-
- return OKAY;
-#endif
-}
-
-int cHttpResource::deleteRecording() {
- vector<sQueryAVP> avps;
- parseQueryLine(&avps);
- string id = "";
-
- if (getQueryAttributeValue(&avps, "id", id) == ERROR){
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: id not found in query."
- << DEBUGHDR << endl;
- sendError(400, "Bad Request", NULL, "no id in query line");
- return OKAY;
- }
- mPath = cUrlEncode::doUrlSaveDecode(id);
-
- cRecording* rec = Recordings.GetByName(mPath.c_str());
- if (rec == NULL) {
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: Recording not found. Deletion failed: mPath= " << mPath
- << endl;
- sendError(404, "Not Found.", NULL, "Recording not found. Deletion failed!");
- return OKAY;
- }
- if ( rec->Delete() ) {
- Recordings.DelByName(rec->FileName());
- // Recordings.DelByName(mPath.c_str());
- }
- else {
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: rec->Delete() returns false. mPath= " << mPath
- << endl;
- sendError(500, "Internal Server Error", NULL, "deletion failed!");
- return OKAY;
- }
-
- *(mLog->log())<< DEBUGPREFIX
- << " Deleted."
- << endl;
- sendHeaders(200, "OK", NULL, NULL, -1, -1);
- return OKAY;
-}
-
-
-int cHttpResource::sendRecordingsXml(struct stat *statbuf) {
-#ifndef STANDALONE
-
- mResponseMessage = new string();
- *mResponseMessage = "";
- mResponseMessagePos = 0;
- mContentType = MEMBLOCK;
-
- mConnState = SERVING;
-
- string own_ip = getOwnIp(mFd);
- *(mLog->log()) << " OwnIP= " << own_ip << endl;
-
- vector<sQueryAVP> avps;
- parseQueryLine(&avps);
- string model = "";
- string link_ext = "";
- string type = "";
- string has_4_hd_str = "";
- bool has_4_hd = true;
- string mode = "";
- bool add_desc = true;
-
- if (getQueryAttributeValue(&avps, "model", model) == OKAY){
- *(mLog->log())<< DEBUGPREFIX
- << " Found a Model Parameter: " << model
- << endl;
- }
-
- if (getQueryAttributeValue(&avps, "type", type) == OKAY){
- *(mLog->log())<< DEBUGPREFIX
- << " Found a Type Parameter: " << type
- << endl;
- if (type == "hls") {
- if (model == "samsung")
- link_ext = "/manifest-seg.m3u8|COMPONENT=HLS";
- else
- link_ext = "/manifest-seg.m3u8";
- }
- if (type == "has") {
- if (model == "samsung")
- link_ext = "/manifest-seg.mpd|COMPONENT=HAS";
- else
- link_ext = "/manifest-seg.mpd";
- }
- }
-
- if (getQueryAttributeValue(&avps, "mode", mode) == OKAY){
- if (mode == "nodesc") {
- add_desc = false;
- *(mLog->log())<< DEBUGPREFIX
- << " Mode: No Description"
- << endl;
- }
- }
-
- if (getQueryAttributeValue(&avps, "has4hd", has_4_hd_str) == OKAY){
- *(mLog->log())<< DEBUGPREFIX
- << " Found a Has4Hd Parameter: " << has_4_hd_str
- << endl;
- if (has_4_hd_str == "false")
- has_4_hd = false;
- }
-
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " generating /recordings.xml"
- << DEBUGHDR << endl;
-#endif
- sendHeaders(200, "OK", NULL, "application/xml", -1, statbuf->st_mtime);
-
- string hdr = "";
- hdr += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- hdr += "<rss version=\"2.0\">\n";
- hdr+= "<channel>\n";
- hdr+= "<title>VDR Recordings List</title>\n";
-
- *mResponseMessage += hdr;
-
- /*
- if (writeXmlItem("HAS - Big Bugs Bunny", "http://192.168.1.122/sm/BBB-DASH/HAS_BigBuckTS.xml|COMPONENT=HAS", "NA", "Big Bucks Bunny - HAS",
- "-", 0, 0) == ERROR)
- return ERROR;
-
- if (writeXmlItem("HLS - Big Bugs Bunny", "http://192.168.1.122/sm/BBB-DASH/HLS_BigBuckTS.m3u8|COMPONENT=HLS", "NA", "Big Bucks Bunny - HLS",
- "-", 0, 0) == ERROR)
- return ERROR;
- if (writeXmlItem("HAS - Big Bugs Bunny", "http://192.168.1.122:8000/hd2/mpeg/BBB-DASH/HAS_BigBuckTS.xml|COMPONENT=HAS", "NA", "Big Bucks Bunny - HAS from own Server",
- "-", 0, 0) == ERROR)
- return ERROR;
-*/
- //--------------------
- cRecordings* recordings = &Recordings;
- char f[600];
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " recordings->Count()= " << recordings->Count()
- << DEBUGHDR << endl;
-#endif
-
- // List of recording timer
- time_t now = time(NULL);
-
- vector<sTimerEntry> act_rec;
- /*#ifndef DEBUG*/
- *(mLog->log())<< DEBUGPREFIX
- << " checking avtive timer"
- << endl;
- /*#endif*/
- for (cTimer * ti = Timers.First(); ti; ti = Timers.Next(ti)){
- ti->Matches();
-
- /* *(mLog->log()) << DEBUGPREFIX
- << " Active Timer: " << ti->File()
- << " EvStart= " << ti->Event()->StartTime()
- << " EvDuration= " << ti->Event()->Duration()
- << endl;*/
- /* *(mLog->log()) << DEBUGPREFIX
- << " TiStart= " << ti->StartTime()
- << " TiDuration= " << (ti->StopTime() - ti->StartTime())
- << endl;
-*/
- if (ti->HasFlags(tfRecording) ) {
- /*
- if (ti->Event() == NULL) {
- *(mLog->log()) << DEBUGPREFIX
- << " WARNING: Active recording for " << ti->File()
- << " is skipped (No Event()" << endl;
- continue;
- }
- */
- /* *(mLog->log()) << DEBUGPREFIX
- << " Active Timer: " << ti->File()
- << " Start= " << ti->Event()->StartTime()
- << " Duration= " << ti->Event()->Duration()
- << endl;
-*/
- *(mLog->log()) << DEBUGPREFIX
- << " Active Timer: " << ti->File()
- << " Start= " << ti->StartTime()
- << " Duration= " << (ti->StopTime() - ti->StartTime())
- << endl;
- // act_rec.push_back(sTimerEntry(ti->File(), ti->Event()->StartTime(), ti->Event()->Duration()));
- act_rec.push_back(sTimerEntry(ti->File(), ti->StartTime(), (ti->StopTime() - ti->StartTime())));
- }
- }
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " Found " << act_rec.size()
- << " running timers"
- << endl;
-#endif
-
- int rec_dur = 0;
- for (cRecording *recording = recordings->First(); recording; recording = recordings->Next(recording)) {
- hdr = "";
-
- if (recording->IsPesRecording() or ((recording->FramesPerSecond() > 30.0) and !has_4_hd ))
- // snprintf(f, sizeof(f), "http://%s:%d%s", mServerAddr.c_str(), mServerPort,
- snprintf(f, sizeof(f), "http://%s:%d%s", own_ip.c_str(), mServerPort,
- cUrlEncode::doUrlSaveEncode(recording->FileName()).c_str());
- else
- // snprintf(f, sizeof(f), "http://%s:%d%s%s", mServerAddr.c_str(), mServerPort,
- snprintf(f, sizeof(f), "http://%s:%d%s%s", own_ip.c_str(), mServerPort,
- cUrlEncode::doUrlSaveEncode(recording->FileName()).c_str(), link_ext.c_str());
-
- string link = f;
- string desc = "No description available";
- rec_dur = recording->LengthInSeconds();
-
- string name = recording->Name();
-
- for (uint x = 0; x < act_rec.size(); x++) {
- if (act_rec[x].name == name) {
-
- /* *(mLog->log())<< DEBUGPREFIX
- << " !!!!! Found active Recording !!! "
- << endl;
-*/
- rec_dur += (act_rec[x].startTime + act_rec[x].duration - now);
-
-
- }
- } // for
-
- if (recording->Info() != NULL) {
- if ((recording->Info()->Description() != NULL) && add_desc) {
- desc = cUrlEncode::doXmlSaveEncode(recording->Info()->Description());
- }
- }
-
- if (writeXmlItem(cUrlEncode::doXmlSaveEncode(recording->Name()), link, "NA", desc,
- cUrlEncode::doUrlSaveEncode(recording->FileName()).c_str(),
- -1,
- recording->Start(), rec_dur, recording->FramesPerSecond(),
- (recording->IsPesRecording() ? 0: 1), (recording->IsNew() ? 0: 1)) == ERROR)
- // Better Internal Server Error
- return ERROR;
-
- }
-
- hdr = "</channel>\n";
- hdr += "</rss>\n";
-
- *mResponseMessage += hdr;
-
-
-#endif
- return OKAY;
-}
-
-bool cHttpResource::isTimeRequest(struct stat *statbuf) {
-
- vector<sQueryAVP> avps;
- parseQueryLine(&avps);
- string time_str = "";
- string mode = "";
- float time = 0.0;
-
- if (getQueryAttributeValue(&avps, "time", time_str) != OKAY){
- return false;
- }
-
- if (getQueryAttributeValue(&avps, "mode", mode) == OKAY){
- if (mode.compare ("streamtoend") ==0) {
- mStreamToEnd = true;
- }
- }
-
- if (mIsRecording)
- mStreamToEnd = true;
-
- time = atof(time_str.c_str());
- *(mLog->log())<< DEBUGPREFIX
- << " Found a Time Parameter: " << time
- << " streamToEnd= " << ((mStreamToEnd) ? "true" : "false")
- << endl;
-
- mDir = mPath;
- cRecording *rec = Recordings.GetByName(mPath.c_str());
- if (rec == NULL) {
- *(mLog->log())<< DEBUGPREFIX
- << " Error: Did not find recording= " << mPath << endl;
- sendError(404, "Not Found", NULL, "File not found.");
- return true;
- }
-
- double fps = rec->FramesPerSecond();
- double dur = rec->NumFrames() * fps;
- bool is_pes = rec->IsPesRecording();
- if (dur < time) {
- sendError(400, "Bad Request", NULL, "Time to large.");
- return true;
- }
-
- int start_frame = int(time * fps) -25;
-
- FILE* idx_file= NULL;
-
- if (is_pes){
- idx_file = fopen((mDir +"/index.vdr").c_str(), "r");
- // sendError(400, "Bad Request", NULL, "PES not yet supported.");
- // return true;
- }
- else {
- idx_file = fopen((mDir +"/index").c_str(), "r");
- }
-
- if (idx_file == NULL){
- *(mLog->log()) << DEBUGPREFIX
- << " failed to open idx file = "<< (mDir +"/index").c_str()
- << endl;
- sendError(404, "Not Found", NULL, "Failed to open Index file");
- return OKAY;
- }
-
- int buffered_frames = 50;
- char *index_buf = new char[8 *buffered_frames]; // 50 indexes
-
- *(mLog->log()) << DEBUGPREFIX
- << " seeking to start_frame= " << start_frame
- << " fps= " << fps << endl;
- fseek(idx_file, start_frame * 8, SEEK_SET);
-
- int buffered_indexes = fread(index_buf, 8, (buffered_frames), idx_file);
-
- fclose(idx_file);
-
- if(buffered_indexes <= 0 ) {
- *(mLog->log())<<DEBUGPREFIX
- << " issue while reading, buffered_indexes <=0" << endl;
- delete[] index_buf;
- sendError(404, "Not Found", NULL, "Failed to read Index file");
- return OKAY;
- }
-
- *(mLog->log()) << DEBUGPREFIX
- << " Finding I-Frame now" << endl;
-
-
- bool found_it = false;
- int i = 0;
-
- uint32_t offset = 0;
- int idx =0;
- int type =0;
-
- for (i= 0; i < buffered_indexes; i++){
- if (is_pes) {
- tIndexPes in_read_pes;
- memcpy (&in_read_pes, &(index_buf[i*8]), 8);
- type = in_read_pes.type == 1;
- idx = in_read_pes.number;
- offset = in_read_pes.offset;
- }
- else{
- tIndexTs in_read_ts;
- memcpy (&in_read_ts, &(index_buf[i*8]), 8);
- type = in_read_ts.independent;
- idx = in_read_ts.number;
- offset = in_read_ts.offset;
- }
-
- *(mLog->log()) << DEBUGPREFIX
- << " Frame= " << i
- << " idx= "<< idx
- << " offset= " << offset
- << " type= " << type
- << endl;
- if (type){
- found_it = true;
- break;
- }
- }
-
- if (!found_it) {
- delete[] index_buf;
- sendError(404, "Not Found", NULL, "Failed to read Index file");
- return OKAY;
- }
-
- mVdrIdx = idx;
-
- *(mLog->log()) << DEBUGPREFIX
- << " idx= "<< mVdrIdx
- << " offset= " << offset
- << endl;
-
- delete[] index_buf;
-
- char pathbuf[4096];
- snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), mPath.c_str(), mVdrIdx);
-
- *(mLog->log()) << DEBUGPREFIX
- << " Opening Path= "
- << pathbuf << endl;
- if (openFile(pathbuf) != OKAY) {
- sendError(403, "Forbidden", NULL, "Access denied.");
- return true;
- }
-
- fseek(mFile, offset, SEEK_SET);
-
- if (mStreamToEnd) {
- sendHeaders(200, "OK", NULL, "video/mpeg", -1, -1);
- return true;
- }
-
- uint64_t file_size = 0;
- bool more_to_go = true;
- int vdr_idx = mVdrIdx;
- while (more_to_go) {
- snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), mPath.c_str(), vdr_idx);
- if (stat(pathbuf, statbuf) >= 0) {
- *(mLog->log())<< " found for " << pathbuf << endl;
- file_size += statbuf->st_size;
- }
- else {
- more_to_go = false;
- }
- vdr_idx ++;
- }
- mRemLength = file_size - offset;
-
- *(mLog->log()) << DEBUGPREFIX
- << " Done. Start Streaming "
- << endl;
-
- if (rangeHdr.isRangeRequest) {
- snprintf(pathbuf, sizeof(pathbuf), "Content-Range: bytes 0-%lld/%lld", (mRemLength -1), mRemLength);
- sendHeaders(206, "Partial Content", pathbuf, "video/mpeg", mRemLength, statbuf->st_mtime);
- }
- else {
- sendHeaders(200, "OK", NULL, "video/mpeg", mRemLength, -1);
- }
- return true;
-}
-
-int cHttpResource::sendVdrDir(struct stat *statbuf) {
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX << " *** sendVdrDir mPath= " << mPath << endl;
-#endif
- char pathbuf[4096];
- char f[400];
- int vdr_idx = 0;
- uint64_t total_file_size = 0;
- // int ret = OKAY;
- string vdr_dir = mPath;
- vector<sVdrFileEntry> file_sizes;
- bool more_to_go = true;
-
- checkRecording();
-
- mVdrIdx = 1;
- mFileStructure = "%s/%03d.vdr";
-
- snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), mPath.c_str(), 1);
- if (stat(pathbuf, statbuf) < 0) {
- mFileStructure = "%s/%05d.ts";
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX << " using dir format: " << mFileStructure.c_str() << endl;
-#endif
- }
-
- // The range request functions are activated, when a time header is detected
- if (isTimeRequest(statbuf)) {
- *(mLog->log())<< DEBUGPREFIX
- << " isTimeRequest is true"
- << endl;
- return OKAY;
- }
-
- // --- looup all vdr files in the dir ---
- while (more_to_go) {
- vdr_idx ++;
- snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), mPath.c_str(), vdr_idx);
- if (stat(pathbuf, statbuf) >= 0) {
-#ifndef DEBUG
- *(mLog->log())<< " found for " << pathbuf << endl;
-#endif
- file_sizes.push_back(sVdrFileEntry(statbuf->st_size, total_file_size, vdr_idx));
- total_file_size += statbuf->st_size;
- }
- else {
- more_to_go = false;
- }
- }
- if (file_sizes.size() < 1) {
- // There seems to be vdr video file in the directory
- *(mLog->log())<< DEBUGPREFIX
- << " No video file in the directory"
- << DEBUGHDR << endl;
- sendError(404, "Not Found", NULL, "File not found.");
- return OKAY;
- }
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " vdr filesize list "
- << DEBUGHDR << endl;
- for (uint i = 0; i < file_sizes.size(); i++)
- *(mLog->log())<< " i= " << i << " size= " << file_sizes[i].sSize << " firstOffset= " << file_sizes[i].sFirstOffset << endl;
- *(mLog->log())<< " total_file_size= " << total_file_size << endl << endl;
-#endif
-
- // total_file_size (on disk)
-
- // ---------------- file sizes ---------------------
-
- uint cur_idx = 0;
-
-#ifndef DEBUG
- if (mIsRecording) {
- snprintf(f, sizeof(f), " CurFileSize= %lld mRecProgress= %f ExtFileSize= %lld", total_file_size, mRecProgress, (long long int)(mRecProgress * total_file_size));
- *(mLog->log()) << DEBUGPREFIX
- << endl << " isRecording: " << f
- << endl;
- }
-#endif
-
- if (!rangeHdr.isRangeRequest) {
- snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), mPath.c_str(), file_sizes[cur_idx].sIdx);
-
- if (openFile(pathbuf) != OKAY) {
- sendError(403, "Forbidden", NULL, "Access denied.");
- return OKAY;
- }
-
- mRemLength = total_file_size;
-
- sendHeaders(200, "OK", NULL, "video/mpeg", ((mIsRecording) ? (mRecProgress * total_file_size): total_file_size ), statbuf->st_mtime);
- }
- else { // Range request
- // idenify the first file
-#ifndef DEBUG
- *(mLog->log()) << DEBUGPREFIX
- << endl <<" --- Range Request Handling ---"
- << DEBUGHDR << endl;
-#endif
- if (mIsRecording && (rangeHdr.begin > total_file_size)) {
- *(mLog->log()) << DEBUGPREFIX
- << " ERROR: Not yet available" << endl;
- sendError(404, "Not Found", NULL, "File not found.");
- return OKAY;
- }
- cur_idx = file_sizes.size() -1;
- for (uint i = 1; i < file_sizes.size(); i++) {
- if (rangeHdr.begin < file_sizes[i].sFirstOffset ) {
- cur_idx = i -1;
- break;
- }
- }
-
-#ifndef DEBUG
- *(mLog->log())<< " Identified Record i= " << cur_idx << " file_sizes[i].sFirstOffset= "
- << file_sizes[cur_idx].sFirstOffset << " rangeHdr.begin= " << rangeHdr.begin
- << " vdr_no= " << file_sizes[cur_idx].sIdx << endl;
-#endif
-
- mVdrIdx = file_sizes[cur_idx].sIdx;
- snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), mPath.c_str(), file_sizes[cur_idx].sIdx);
-#ifndef DEBUG
- *(mLog->log())<< " file identified= " << pathbuf << endl;
-#endif
- if (openFile(pathbuf) != OKAY) {
- *(mLog->log())<< "----- fopen failed dump ----------" << endl;
- *(mLog->log())<< DEBUGPREFIX
- << " vdr filesize list "
- << DEBUGHDR << endl;
- for (uint i = 0; i < file_sizes.size(); i++)
- *(mLog->log())<< " i= " << i << " size= " << file_sizes[i].sSize << " firstOffset= " << file_sizes[i].sFirstOffset << endl;
- *(mLog->log())<< " total_file_size= " << total_file_size << endl << endl;
-
- *(mLog->log())<< " Identified Record i= " << cur_idx << " file_sizes[i].sFirstOffset= "
- << file_sizes[cur_idx].sFirstOffset << " rangeHdr.begin= " << rangeHdr.begin
- << " vdr_no= " << file_sizes[cur_idx].sIdx << endl;
- *(mLog->log())<< "---------------" << endl;
- sendError(403, "Forbidden", NULL, "Access denied.");
- return OKAY;
- }
- mDir = mPath;
- mPath = pathbuf;
-#ifndef DEBUG
- *(mLog->log())<< " Seeking into file= " << (rangeHdr.begin - file_sizes[cur_idx].sFirstOffset)
- << " cur_idx= " << cur_idx
- << " file_sizes[cur_idx].sFirstOffset= " << file_sizes[cur_idx].sFirstOffset
- << endl;
-#endif
- fseek(mFile, (rangeHdr.begin - file_sizes[cur_idx].sFirstOffset), SEEK_SET);
- if (rangeHdr.end == 0)
- rangeHdr.end = ((mIsRecording) ? (mRecProgress * total_file_size): total_file_size);
-
- mRemLength = (rangeHdr.end-rangeHdr.begin);
-
- snprintf(f, sizeof(f), "Content-Range: bytes %lld-%lld/%lld", rangeHdr.begin, (rangeHdr.end -1),
- ((mIsRecording) ? (long long int)(mRecProgress * total_file_size): total_file_size));
-
- sendHeaders(206, "Partial Content", f, "video/mpeg", (rangeHdr.end-rangeHdr.begin), statbuf->st_mtime);
- }
-
-#ifndef DEBUG
- *(mLog->log())<< " ***** Yes, vdr dir found ***** mPath= " << mPath<< endl;
-#endif
-
- return OKAY; // handleRead() done
-}
-
-void cHttpResource::sendHeaders(int status, const char *title, const char *extra, const char *mime,
- long long int length, time_t date) {
-
- time_t now;
- char timebuf[128];
- char f[400];
-
- string hdr = "";
- snprintf(f, sizeof(f), "%s %d %s\r\n", PROTOCOL, status, title);
- hdr += f;
- snprintf(f, sizeof(f), "Server: %s\r\n", SERVER);
- hdr += f;
- now = time(NULL);
- strftime(timebuf, sizeof(timebuf), RFC1123FMT, gmtime(&now));
- snprintf(f, sizeof(f), "Date: %s\r\n", timebuf);
- hdr += f;
- if (extra) {
- snprintf(f, sizeof(f), "%s\r\n", extra);
- *(mLog->log())<< DEBUGPREFIX << " " << f;
- hdr += f;
- }
- if (mime) {
- snprintf(f, sizeof(f), "Content-Type: %s\r\n", mime);
- hdr += f;
- }
- if (length >= 0) {
- snprintf(f, sizeof(f), "Content-Length: %lld\r\n", length);
- // *(mLog->log())<< DEBUGPREFIX << " " << f << endl;
- hdr += f;
- }
- if (date != -1) {
- strftime(timebuf, sizeof(timebuf), RFC1123FMT, gmtime(&date));
- snprintf(f, sizeof(f), "Last-Modified: %s\r\n", timebuf);
- hdr += f;
- }
- if (mAcceptRanges) {
- snprintf(f, sizeof(f), "Accept-Ranges: bytes\r\n");
- hdr += f;
- }
- snprintf(f, sizeof(f), "Connection: close\r\n");
- hdr += f;
-
- snprintf(f, sizeof(f), "\r\n");
- hdr += f;
-
-
- if (mBlkLen != 0) {
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR in SendHeader: mBlkLen != 0!!! --> Overwriting" << endl;
- }
- mBlkLen = hdr.size();
- strcpy(mBlkData, hdr.c_str());
-
-}
-
-int cHttpResource::sendFile(struct stat *statbuf32) {
- // Send the First Datachunk, incl all headers
- struct stat64 statbuf;
-
- if (stat64(mPath.c_str(), &statbuf) < 0) {
- sendError(404, "Not Found", NULL, "File not found.");
- return OKAY;
- }
- *(mLog->log())<< DEBUGPREFIX
- << mReqId << " SendFile mPath= " << mPath
- << endl;
-
- char f[400];
-
- if (openFile(mPath.c_str()) == ERROR) {
- sendError(403, "Forbidden", NULL, "Access denied.");
- return OKAY;
- }
- mFile = fopen(mPath.c_str(), "r");
- // int ret = OKAY;
-
- if (!mFile) {
- sendError(403, "Forbidden", NULL, "Access denied.");
- return OKAY;
- }
-
- mFileSize = S_ISREG(statbuf.st_mode) ? statbuf.st_size : -1;
-
- *(mLog->log())<< "fd= " << mFd << " mReqId= "<< mReqId
- << " mFileSize= " <<mFileSize << endl;
-
- if (!rangeHdr.isRangeRequest) {
- mRemLength = mFileSize;
- sendHeaders(200, "OK", NULL, getMimeType(mPath.c_str()), mFileSize, statbuf.st_mtime);
- }
- else { // Range request
- fseeko64(mFile, rangeHdr.begin, SEEK_SET);
- if (rangeHdr.end == 0)
- rangeHdr.end = mFileSize;
- mRemLength = (rangeHdr.end-rangeHdr.begin);
- *(mLog->log())<< "fd= " << mFd << " mReqId= "<< mReqId
- << " rangeHdr.begin= " <<rangeHdr.begin << " rangeHdr.end= " << rangeHdr.end
- << " Content-Length= " << mRemLength << endl;
-
- snprintf(f, sizeof(f), "Content-Range: bytes %lld-%lld/%lld", rangeHdr.begin, (rangeHdr.end -1), mFileSize);
- sendHeaders(206, "Partial Content", f, getMimeType(mPath.c_str()), (rangeHdr.end-rangeHdr.begin), statbuf.st_mtime);
- }
-
-#ifndef DEBUG
- *(mLog->log())<< "fd= " << mFd << " mReqId= "<< mReqId
- << ": Done mRemLength= "<< mRemLength << " mContentType= " << mContentType
- << endl;
-#endif
- mConnState = SERVING;
-
- return OKAY;
-
-}
-
-const char *cHttpResource::getMimeType(const char *name) {
- char *ext = strrchr((char*)name, '.');
- if (!ext)
- return NULL;
- // if (ext.compare(".html") || ext.compare(".htm")) return "text/html";
- if (strcmp(ext, ".html") == 0 || strcmp(ext, ".htm") == 0) return "text/html";
- if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) return "image/jpeg";
- if (strcmp(ext, ".gif") == 0) return "image/gif";
- if (strcmp(ext, ".png") == 0) return "image/png";
- if (strcmp(ext, ".xml") == 0) return "application/xml";
- if (strcmp(ext, ".css") == 0) return "text/css";
- if (strcmp(ext, ".js") == 0) return "text/javascript";
- if (strcmp(ext, ".au") == 0) return "audio/basic";
- if (strcmp(ext, ".wav") == 0) return "audio/wav";
- if (strcmp(ext, ".avi") == 0) return "video/x-msvideo";
- if (strcmp(ext, ".mp4") == 0) return "video/mp4";
- if (strcmp(ext, ".vdr") == 0) return "video/mpeg";
- if (strcmp(ext, ".ts") == 0) return "video/mpeg";
- if (strcmp(ext, ".mpeg") == 0 || strcmp(ext, ".mpg") == 0) return "video/mpeg";
- if (strcmp(ext, ".mp3") == 0) return "audio/mpeg";
- if (strcmp(ext, ".mpd") == 0) return "application/dash+xml";
- if (strcmp(ext, ".m3u8") == 0) return "application/x-mpegURL";
-
- return NULL;
-}
-
-
-string cHttpResource::getConnStateName() {
- string state_string;
- switch (mConnState) {
- case WAITING:
- state_string = "WAITING";
- break;
- case READHDR:
- state_string = "READ Req HDR";
- break;
- case READPAYLOAD:
- state_string = "READ Req Payload";
- break;
- case SERVING:
- state_string = "SERVING";
- break;
- case TOCLOSE:
- state_string = "TOCLOSE";
- break;
- default:
- state_string = "UNKNOWN";
- break;
- }
- return state_string;
-}
-
-
-string cHttpResource::getOwnIp(int fd) {
- struct sockaddr_in sock;
- socklen_t len_inet = sizeof(sock);
- int ret = getsockname(fd, (struct sockaddr *)&sock, &len_inet);
- if ( ret == -1 ) {
- *(mLog->log()) << "Error: Cannot obtain own ip address" << endl;
- return string("0.0.0.0");
- // exit(1); /* Failed */
- }
- return string (inet_ntoa(sock.sin_addr));
-}
-
-uint64_t cHttpResource::getVdrFileSize() {
- // iter over all vdr files and get file size
- struct stat statbuf;
- string file_structure = "%s/%05d.ts"; // Only ts supported for HLS and HAS
- char pathbuf[4096];
- int vdr_idx = 0;
- uint64_t total_file_size = 0;
- bool more_to_go = true;
-
- while (more_to_go) {
- vdr_idx ++;
- snprintf(pathbuf, sizeof(pathbuf), file_structure.c_str(), mDir.c_str(), vdr_idx);
- if (stat(pathbuf, &statbuf) >= 0) {
- total_file_size += statbuf.st_size;
- }
- else {
- more_to_go = false;
- }
- }
- return total_file_size;
-}
-
-int cHttpResource::parseHttpRequestLine(string line) {
- mMethod = line.substr(0, line.find_first_of(" "));
- mRequest = line.substr(line.find_first_of(" ") +1, (line.find_last_of(" ") - line.find_first_of(" ") -1));
- mVersion = line.substr(line.find_last_of(" ") +1);
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " ReqLine= " << line << endl;
-#endif
- if (mVersion.compare(0, 4, "HTTP") != 0) {
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " ERROR: No HTTP request -> Closing Connection" << line << endl;
-#endif
- return ERROR;
- }
-
- size_t pos = mRequest.find('?');
- if (pos != string::npos)
- mQuery = mRequest.substr (pos+1, string::npos);
- mPath = cUrlEncode::doUrlSaveDecode(mRequest.substr(0, mRequest.find('?')));
- *(mLog->log())<< DEBUGPREFIX
- << " mMethod= " << mMethod
- << " mPath= " << mPath
- << " mVer= " << mVersion
- << " mQuery= " << mQuery
- // << " HexDump= " << endl << cUrlEncode::hexDump(mPath) << endl
- << endl;
- return OKAY;
-}
-
-int cHttpResource::parseHttpHeaderLine (string line) {
- string hdr_name = line.substr(0, line.find_first_of(":"));
- string hdr_val = line.substr(line.find_first_of(":") +2);
-
- if (hdr_name.compare("Range") == 0) {
- parseRangeHeaderValue(hdr_val);
- *(mLog->log()) << DEBUGPREFIX
- << " Range: Begin= " << rangeHdr.begin
- << " End= " << rangeHdr.end
- << endl;
- }
- if (hdr_name.compare("User-Agent") == 0) {
- mUserAgent = hdr_val;
- *(mLog->log())<< " User-Agent: " << hdr_val
- << endl;
- }
- if (hdr_name.compare("Content-Length") == 0) {
- mReqContentLength = atoll(hdr_val.c_str());
- //#ifndef DEBUG
- *(mLog->log())<< " Content-Length: " << mReqContentLength
- << endl;
- //#endif
- }
- return 0;
-}
-
-void cHttpResource::checkRecording() {
- // sets mIsRecording to true when the recording is still on-going
- mIsRecording = false;
- time_t now = time(NULL);
-
-#ifndef STANDALONE
-
- // cRecordings* recordings = mFactory->getRecordings();
- cRecordings* recordings = &Recordings;
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " GetByName(" <<mPath.c_str() << ")"
- << endl;
-#endif
- cRecording* rec = recordings->GetByName(mPath.c_str());
- if (rec != NULL) {
- const cEvent *ev = rec->Info()->GetEvent();
- if (ev != NULL) {
- if (now < ev->EndTime()) {
- // still recording
- mIsRecording = true;
-
- // mRecProgress * curFileSize = estimated File Size
- mRecProgress = (ev->EndTime() - ev->StartTime()) *1.1 / (rec->NumFrames() / rec->FramesPerSecond());
- // mRecProgress = (ev->EndTime() - ev->StartTime()) *1.0/ (now - ev->StartTime());
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " **** is still recording for mIsRecording= "
- << mIsRecording
- << " mRecProgress= " << mRecProgress << endl;
-#endif
- }
- }
-
-#ifndef DEBUG
- *(mLog->log())<< DEBUGPREFIX
- << " checking, whether recording is on-going"
- << " now= " << now << " start= " << rec->Start()
- << " curDur= " << rec->LengthInSeconds()
- << endl;
-#endif
- }
-#ifndef DEBUG
- else {
- *(mLog->log())<< DEBUGPREFIX
- << " **** Recording Entry Not found **** " << endl;
- }
-#endif
-#endif
-}
-
-int cHttpResource::parseRangeHeaderValue(string val) {
- rangeHdr.isRangeRequest = true;
- size_t pos_equal = val.find_first_of('=');
- size_t pos_minus = val.find_first_of('-');
-
- string range_type = val.substr(0, pos_equal);
- string first_val= val.substr(pos_equal+1, pos_minus -(pos_equal+1));
- rangeHdr.begin = atoll(first_val.c_str());
-
- string sec_val = "";
- if ((pos_minus +1)< val.size()){
- sec_val = val.substr(pos_minus+1);
- rangeHdr.end = atoll(sec_val.c_str());
- }
- return 0;
-}
-
-int cHttpResource::openFile(const char *name) {
- mFile = fopen(name, "r");
- if (!mFile) {
- *(mLog->log())<< DEBUGPREFIX
- << " fopen failed pathbuf= " << name
- << endl;
- // sendError(403, "Forbidden", NULL, "Access denied.");
- return ERROR;
- }
- return OKAY;
-}
-
diff --git a/vdr-smarttvweb/httpresource.h b/vdr-smarttvweb/httpresource.h
deleted file mode 100755
index fbbab4d..0000000
--- a/vdr-smarttvweb/httpresource.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * httpresource.h: VDR on Smart TV plugin
- *
- * Copyright (C) 2012, 2013 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-#ifndef __HTTPREQUEST_H__
-#define __HTTPREQUEST_H__
-
-#include <string>
-#include <cstring>
-#include <pthread.h>
-#include "log.h"
-
-using namespace std;
-
-struct cRange {
-cRange(): isRangeRequest(false), begin(0), end(0) {};
- bool isRangeRequest;
- unsigned long long begin;
- unsigned long long end;
-};
-
-struct sQueryAVP {
- string attribute;
- string value;
-sQueryAVP(string a, string v) : attribute (a), value(v) {};
-};
-
-
-enum eConnState {
- WAITING,
- READHDR,
- READPAYLOAD,
- SERVING,
- TOCLOSE
-};
-
-enum eContentType {
- NYD, // Not Yet Defined
- VDRDIR,
- SINGLEFILE,
- MEMBLOCK
-};
-
-struct sFileEntry {
- string sName;
- string sPath;
- int sStart;
-
-sFileEntry(string n, string l, int s) : sName(n), sPath(l), sStart(s) {
- };
-};
-
-class SmartTvServer;
-class cResumeEntry;
-
-class cHttpResource {
-
- public:
- cHttpResource(int, int, int, SmartTvServer*);
- virtual ~cHttpResource();
-
- int handleRead();
- int handleWrite();
-
- int checkStatus();
-
- int readFromClient();
- void threadLoop();
- int run();
-
- private:
- SmartTvServer* mFactory;
- Log* mLog;
-
- int mServerPort;
- int mFd;
- int mReqId;
-
- time_t mConnTime;
- int mHandleReadCount;
- bool mConnected;
- eConnState mConnState;
- eContentType mContentType;
-
- string mReadBuffer;
- string mMethod;
-
- string *mResponseMessage;
- int mResponseMessagePos;
- char* mBlkData;
- int mBlkPos;
- int mBlkLen;
-
- string mRequest;
- string mQuery;
- string mPath;
- string mDir;
- string mVersion;
- string protocol;
- unsigned long long mReqContentLength;
- string mPayload;
- string mUserAgent;
-
- bool mAcceptRanges;
- cRange rangeHdr;
- unsigned long long mFileSize;
- bool mStreamToEnd;
- uint64_t mRemLength;
- FILE *mFile;
- int mVdrIdx;
- string mFileStructure;
- bool mIsRecording;
- float mRecProgress;
-
- void setNonBlocking();
- int fillDataBlk();
-
- int handlePost();
- int handleHeadRequest();
- int processRequest();
- int processHttpHeaderNew();
-
- int readRequestPayload();
- void sendError(int status, const char *title, const char *extra, const char *text);
- int sendDir(struct stat *statbuf);
- int sendVdrDir(struct stat *statbuf);
- int sendRecordingsXml (struct stat *statbuf);
- int sendChannelsXml (struct stat *statbuf);
- int sendResumeXml ();
- int sendVdrStatusXml (struct stat *statbuf);
- int sendEpgXml (struct stat *statbuf);
- int sendMediaXml (struct stat *statbuf);
-
- int sendManifest (struct stat *statbuf, bool is_hls = true);
-
- int receiveResume();
- int deleteRecording();
-
- void writeM3U8(double duration, int bitrate, float seg_dur, int end_seg);
- void writeMPD(double duration, int bitrate, float seg_dur, int end_seg);
-
-
- int sendMediaSegment (struct stat *statbuf);
-
- void sendHeaders(int status, const char *title, const char *extra, const char *mime,
- long long int length, time_t date);
-
- int sendFile(struct stat *statbuf);
-
- // Helper Functions
- const char *getMimeType(const char *name);
- string getConnStateName();
- string getOwnIp(int fd);
- uint64_t getVdrFileSize();
- void checkRecording();
- bool isTimeRequest(struct stat *statbuf);
- int parseRangeHeaderValue(string);
- int parseHttpRequestLine(string);
- int parseHttpHeaderLine (string);
- int parseQueryLine (vector<sQueryAVP> *avps);
- int parseResume(cResumeEntry &entry, string &id);
-
- int parseFiles(vector<sFileEntry> *entries, string prefix, string dir_base, string dir_name, struct stat *statbuf);
-
- int getQueryAttributeValue(vector<sQueryAVP> *avps, string id, string &val);
- int openFile(const char *name);
- int writeXmlItem(string title, string link, string programme, string desc, string guid, int no, time_t start, int dur, double fps, int is_pes, int is_new);
-};
-#endif
diff --git a/vdr-smarttvweb/log.c b/vdr-smarttvweb/log.c
deleted file mode 100644
index 685bce3..0000000
--- a/vdr-smarttvweb/log.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * log.c: VDR on Smart TV plugin
- *
- * Copyright (C) 2012 Thorsten Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-
-#include "log.h"
-#include <time.h>
-#include <cstring>
-
-Log* Log::instance = NULL;
-
-Log::Log() {
- if (instance)
- return;
- instance = this;
- mLogFile = NULL;
-}
-
-Log::~Log() {
- instance = NULL;
-}
-
-Log* Log::getInstance() {
- return instance;
-}
-int Log::init(string fileName) {
- char timebuf[128];
- time_t now = time(NULL);
- strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
-
- if (fileName != "") {
- mLogFile = new ofstream();
-
- mLogFile->open(fileName.c_str(), ios::out );
- *mLogFile << "Log Created: " << timebuf << endl;
- }
- else
- mLogFile = new ofstream("/dev/null");
- return 0;
-}
-
-int Log::init(char* fileName) {
-
- char timebuf[128];
- time_t now = time(NULL);
- strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
-
- if (strcmp(fileName, "") !=0) {
- mLogFile = new ofstream();
- mLogFile->open(fileName, ios::out );
- *mLogFile << "Log Created: " << timebuf << endl;
- }
- else
- mLogFile = new ofstream("/dev/null");
- return 0;
-}
-
-int Log::shutdown() {
- if (mLogFile)
- mLogFile->close();
- return 1;
-}
-
-ofstream* Log::log() {
- return mLogFile;
-}
-
diff --git a/vdr-smarttvweb/log.h b/vdr-smarttvweb/log.h
deleted file mode 100644
index 8a09fe3..0000000
--- a/vdr-smarttvweb/log.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * log.h.h: VDR on Smart TV plugin
- *
- * Copyright (C) 2012 Thorsten Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-
-#ifndef LOG_H
-#define LOG_H
-
-#include <iostream>
-#include <fstream>
-
-using namespace std;
-
-class Log
-{
- public:
- Log();
- ~Log();
- static Log* getInstance();
-
- int init(char* fileName);
- int init(string fileName);
- int shutdown();
- ofstream* log();
-
- private:
- static Log* instance;
-
- ofstream *mLogFile;
-};
-
-#endif
diff --git a/vdr-smarttvweb/smarttvfactory.c b/vdr-smarttvweb/smarttvfactory.c
deleted file mode 100755
index 3478e9d..0000000
--- a/vdr-smarttvweb/smarttvfactory.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * smarttvfactory.h: VDR on Smart TV plugin
- *
- * Copyright (C) 2012 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-#ifndef STANDALONE
-#include <vdr/recording.h>
-#include <vdr/videodir.h>
-#endif
-
-#include <iostream>
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-
-#include <iostream>
-#include <fstream>
-
-
-#include "smarttvfactory.h"
-
-#ifndef STANDALONE
-#define PORT 8000
-#else
-#define PORT 9000
-#endif
-
-#define OKAY 0
-#define ERROR (-1)
-
-#define DEBUG
-
-
-using namespace std;
-
-void SmartTvServerStartThread(void* arg) {
- SmartTvServer* m = (SmartTvServer*)arg;
- m->threadLoop();
- delete m;
- pthread_exit(NULL);
-}
-
-SmartTvServer::SmartTvServer(): mRequestCount(0), isInited(false), serverPort(PORT), mServerFd(-1),
- mSegmentDuration(10), mHasMinBufferTime(40), mLiveChannels(20),
- clientList(), mActiveSessions(0), mConfig(NULL) {
-}
-
-
-SmartTvServer::~SmartTvServer() {
-
- if (mConfig != NULL)
- delete mConfig;
-}
-
-void SmartTvServer::cleanUp() {
- // close listening ports
- for (uint idx= 0; idx < clientList.size(); idx++) {
- if (clientList[idx] != NULL) {
- close(idx);
- delete clientList[idx];
- clientList[idx] = NULL;
- }
- }
-
- // close server port
- close(mServerFd);
-
- // Leave thread
- pthread_cancel(mThreadId);
- pthread_join(mThreadId, NULL);
-
- mLog.shutdown();
-}
-
-int SmartTvServer::runAsThread() {
- int res = pthread_create(&mThreadId, NULL, (void*(*)(void*))SmartTvServerStartThread, (void *)this);
- if (res != 0) {
- *(mLog.log()) << " Error creating thread. res= " << res
- << endl;
- return 0;
- }
- return 1;
-}
-
-void SmartTvServer::threadLoop() {
- *(mLog.log()) << " SmartTvServer Thread Started " << endl;
-
- loop();
-
- *(mLog.log()) << " SmartTvServer Thread Stopped " << endl;
-}
-
-
-void SmartTvServer::loop() {
- socklen_t addr_size = 0;
- int rfd;
- sockaddr_in sadr;
- int req_id = 0;
- int ret = 0;
- struct timeval timeout;
-
- int maxfd;
-
- fd_set read_set;
- fd_set write_set;
-
- FD_ZERO(&read_set);
- FD_ZERO(&write_set);
-
- FD_ZERO(&mReadState);
- FD_ZERO(&mWriteState);
-
- FD_SET(mServerFd, &mReadState);
- maxfd = mServerFd;
-
- *(mLog.log()) << "mServerFd= " << mServerFd << endl;
-
- int handeled_fds = 0;
-
- for (;;) {
- FD_ZERO(&read_set);
- FD_ZERO(&write_set);
- read_set = mReadState;
- write_set = mWriteState;
-
- if (ret != handeled_fds) {
- // Only ok, when the server has closed a handing HTTP connection
- *(mLog.log()) << "WARNING: Select-ret= " << ret
- << " != handeled_fds= " << handeled_fds << endl;
- /* FD_ZERO(&mReadState);
- FD_ZERO(&mWriteState);
- FD_SET(mServerFd, &mReadState);
- maxfd = mServerFd;
-
- read_set = mReadState;
- write_set = mWriteState;
- for (uint idx= 0; idx < clientList.size(); idx++) {
- if (clientList[idx] != NULL) {
- close(idx);
- delete clientList[idx];
- clientList[idx] = NULL;
- }
- }
- mActiveSessions = 0;
-*/
- }
-
- handeled_fds = 0;
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
-
- ret = select(maxfd + 1, &read_set, &write_set, NULL, &timeout);
-
- if (ret == 0) {
- // timeout: Check for dead TCP connections
- for (uint idx= 0; idx < clientList.size(); idx++) {
- if (clientList[idx] != NULL)
- if (clientList[idx]->checkStatus() == ERROR) {
- close(idx);
- delete clientList[idx];
- clientList[idx] = NULL;
- mActiveSessions--;
- FD_CLR(idx, &mReadState); /* dead client */
- FD_CLR(idx, &mWriteState);
- *(mLog.log()) << "WARNING: Timeout - Dead Client fd=" << idx << endl;
- }
- }
- continue;
- } // timeout
-
- if (ret < 0){
- *(mLog.log()) << "ERROR: select error " << errno << endl;
- continue;
- } // Error
-
- // new accept
- if (FD_ISSET(mServerFd, &read_set)) {
- handeled_fds ++;
- if((rfd = accept(mServerFd, (sockaddr*)&sadr, &addr_size))!= -1){
- req_id ++;
-
-#ifndef DEBUG
- *(mLog.log()) << "fd= " << rfd
- << " --------------------- Received connection ---------------------" << endl;
-#endif
-
- FD_SET(rfd, &mReadState);
- FD_SET(rfd, &mWriteState);
-
- if (rfd > maxfd) {
- maxfd = rfd;
- }
-
- if (clientList.size() < (rfd+1)) {
- clientList.resize(rfd+1, NULL); // Check.
- }
- clientList[rfd] = new cHttpResource(rfd, req_id, serverPort, this);
- mActiveSessions ++;
- *(mLog.log()) << " + mActiveSessions= " << mActiveSessions << endl;
- }
- else{
- *(mLog.log()) << "Error accepting " << errno << endl;
- }
- }
-
- // Check for data on already accepted connections
- for (rfd = 0; rfd < clientList.size(); rfd++) {
- if (clientList[rfd] == NULL)
- continue;
- if (FD_ISSET(rfd, &read_set)) {
- handeled_fds ++;
- // HandleRead
- if (clientList[rfd] == NULL) {
- *(mLog.log()) << "ERROR in Check Read: oops - no cHttpResource anymore fd= " << rfd << endl;
- close(rfd);
- FD_CLR(rfd, &mReadState); /* remove dead client */
- FD_CLR(rfd, &mWriteState);
- continue;
- }
- if ( clientList[rfd]->handleRead() < 0){
-#ifndef DEBUG
- *(mLog.log()) << "fd= " << rfd << " --------------------- Check Read: Closing ---------------------" << endl;
-#endif
- close(rfd);
- delete clientList[rfd];
- clientList[rfd] = NULL;
- mActiveSessions--;
- *(mLog.log()) << " - Check Read: mActiveSessions= " << mActiveSessions << endl;
- FD_CLR(rfd, &mReadState); /* dead client */
- FD_CLR(rfd, &mWriteState);
- }
- }
- }
-
- // Check for write
- for (rfd = 0; rfd < clientList.size(); rfd++) {
- if (clientList[rfd] == NULL)
- continue;
- if (FD_ISSET(rfd, &write_set)) {
- handeled_fds++;
- // HandleWrite
- if (clientList[rfd] == NULL) {
- close(rfd);
- FD_CLR(rfd, &mReadState);
- FD_CLR(rfd, &mWriteState);
- continue;
- }
- if ( clientList[rfd]->handleWrite() < 0){
-#ifndef DEBUG
- *(mLog.log()) << "fd= " << rfd << " --------------------- Check Write: Closing ---------------------" << endl;
-#endif
- close(rfd);
- delete clientList[rfd];
- clientList[rfd] = NULL;
- mActiveSessions--;
- *(mLog.log()) << " - Check Write: mActiveSessions= " << mActiveSessions << endl;
- FD_CLR(rfd, &mReadState);
- FD_CLR(rfd, &mWriteState);
- }
- }
- }
-
- // selfcheck
- /* *(mLog.log()) << "Select Summary: ret= " << ret
- << " handeled_fds=" << handeled_fds
- << " mActiveSessions= " << mActiveSessions
- << " clientList.size()= " << clientList.size()
- << endl;
-*/
- //Check for active sessions
- /*
- *(mLog.log()) << "checking number of active sessions clientList.size()= " << clientList.size() << endl;
-
- int act_ses = 0;
- for (uint idx= 0; idx < clientList.size(); idx++) {
- if (clientList[idx] != NULL)
- act_ses++;
- }
- if (act_ses != mActiveSessions) {
- *(mLog.log()) << "ERROR: Lost somewhere a session: "
- << "mActiveSessions= " << mActiveSessions
- << "act_ses= " << act_ses
- << endl;
- mActiveSessions = act_ses;
- }
- *(mLog.log()) << "checking number of active sessions - done mActiveSessions= " << mActiveSessions << endl;
-*/
- } // for (;;)
-} // org bracket
-
-int SmartTvServer::isServing() {
- return (mActiveSessions != 0 ? true : false);
-}
-
-void SmartTvServer::initServer(string dir) {
- /* This function initialtes the listening socket for the server
- * and sets isInited to true
- */
- mConfigDir = dir;
- int ret;
- struct sockaddr_in sock;
- int yes = 1;
-
-
-#ifndef STANDALONE
- mConfig = new cSmartTvConfig(dir);
- mLog.init(mConfig->getLogFile());
- esyslog("SmartTvWeb: Logfile created");
-
- *(mLog.log()) << mConfig->getLogFile() << endl;
-
-#else
- mConfig = new cSmartTvConfig(".");
- mLog.init(mConfig->getLogFile());
- cout << "SmartTvWeb: Logfile created" << endl;
- cout << "SmartTvWeb: Listening on port= " << PORT << endl;
-
-#endif
-
- // mConfig->printConfig();
-
- mSegmentDuration= mConfig->getSegmentDuration();
- mHasMinBufferTime= mConfig->getHasMinBufferTime();
- mLiveChannels = mConfig->getLiveChannels();
-
- *(mLog.log()) <<"HTTP server listening on port " << serverPort << endl;
-
- mServerFd = socket(PF_INET, SOCK_STREAM, 0);
- if (mServerFd <0) {
- *(mLog.log()) << "Error: Cannot create serving socket, exit" << endl;
- exit(1);
- }
-
- ret = setsockopt(mServerFd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
- if (ret <0) {
- *(mLog.log()) << "Error: Cannot set sockopts on serving socket, exit" << endl;
- exit(1);
- }
-
- memset((char *) &sock, 0, sizeof(sock));
- sock.sin_family = AF_INET;
-
- if (mConfig->getServerAddress() == "")
- sock.sin_addr.s_addr = htonl(INADDR_ANY);
- else {
- *(mLog.log()) << "Binding Server to " << mConfig->getServerAddress() << endl;
- sock.sin_addr.s_addr = inet_addr(mConfig->getServerAddress().c_str());
- }
- sock.sin_port = htons(serverPort);
-
- ret = bind(mServerFd, (struct sockaddr *) &sock, sizeof(sock));
- if (ret !=0) {
- *(mLog.log()) << "Error: Cannot bind serving socket, exit" << endl;
- exit(1);
- }
-
- /*
- struct ifreq ifr;
-
- ifr.ifr_addr.sa_family = AF_INET;
- strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
- ioctl(mServerFd, SIOCGIFADDR, &ifr);
- string own_ip = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
- *(mLog.log()) << " own if ip= " << own_ip << endl;
-*/
-
- ret = listen(mServerFd, 5);
- if (ret <0) {
- *(mLog.log()) << "Error: Cannot set listening on serving socket, exit" << endl;
- exit(1);
- }
-
- isInited = true;
-}
-
-
-
-
diff --git a/vdr-smarttvweb/smarttvfactory.h b/vdr-smarttvweb/smarttvfactory.h
deleted file mode 100644
index 1073ab0..0000000
--- a/vdr-smarttvweb/smarttvfactory.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * smarttvfactory.h: VDR on Smart TV plugin
- *
- * Copyright (C) 2012 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-
-#ifndef __SMARTTVSERVER_H__
-#define __SMARTTVSERVER_H__
-
-#include <string>
-#include <cstring>
-#include <vector>
-#include <list>
-#include "httpresource.h"
-#include "log.h"
-#include "stvw_cfg.h"
-
-#ifndef STANDALONE
-#include <vdr/recording.h>
-#endif
-
-using namespace std;
-
-#define PLG_VERSION "0.9.6"
-#define SERVER "SmartTvWeb/0.9.6"
-
-class SmartTvServer {
- public:
- SmartTvServer();
- virtual ~SmartTvServer();
-
- void initServer(string c_dir);
- void loop();
- void cleanUp();
- int runAsThread();
- void threadLoop();
-
- Log mLog;
-
- void readRecordings();
- int isServing();
-
- string getConfigDir() { return mConfigDir; };
- cSmartTvConfig* getConfig() { return mConfig; };
-
- private:
- pthread_t mThreadId;
- int mRequestCount;
- bool isInited;
- int serverPort;
- int mServerFd;
- unsigned int mSegmentDuration;
- int mHasMinBufferTime;
- int mLiveChannels;
-
- vector<cHttpResource*> clientList;
- int mActiveSessions;
- string mConfigDir;
- cSmartTvConfig *mConfig;
-
- int mMaxFd;
- fd_set mReadState;
- fd_set mWriteState;
-};
-
-
-#endif
diff --git a/vdr-smarttvweb/smarttvweb.c b/vdr-smarttvweb/smarttvweb.c
deleted file mode 100644
index 9e3269e..0000000
--- a/vdr-smarttvweb/smarttvweb.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * smarttvweb.c: VDR on Smart TV plugin
- *
- * Copyright (C) 2012 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-
-#ifndef STANDALONE
-#include <vdr/plugin.h>
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <errno.h>
-
-#include <dirent.h>
-
-#include "smarttvfactory.h"
-
-
-static const char *VERSION = PLG_VERSION;
-static const char *DESCRIPTION = "SmartTV Web Server";
-
-
-using namespace std;
-
-#ifndef STANDALONE
-class cPluginSmartTvWeb : public cPlugin
-{
-public:
- cPluginSmartTvWeb(void);
- virtual ~cPluginSmartTvWeb();
- virtual const char *Version(void) { return VERSION; }
- virtual const char *Description(void) { return DESCRIPTION; }
- virtual const char *CommandLineHelp(void);
- virtual bool ProcessArgs(int argc, char *argv[]);
- virtual bool Initialize(void);
- virtual bool Start(void);
- virtual bool SetupParse(const char *Name, const char *Value);
-#if VDRVERSNUM > 10300
- virtual cString Active(void);
-#endif
-
-private:
- SmartTvServer mServer;
- string mConfigDir;
-};
-
-cPluginSmartTvWeb::cPluginSmartTvWeb(void) {
- // Initialize any member variables here.
- // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
- // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
- mConfigDir = "";
-}
-
-bool cPluginSmartTvWeb::Start(void) {
- // Start any background activities the plugin shall perform.
-
- if (mConfigDir.compare("") == 0) {
- const char* dir_name = cPlugin::ConfigDirectory(Name());
- if (!dir_name) {
- dsyslog("SmartTvWeb: Could not get config dir from VDR");
- }
- else
- mConfigDir = string(dir_name);
- }
-
- mServer.initServer(mConfigDir);
- int success = mServer.runAsThread();
-
- esyslog("SmartTvWeb: started %s", (success == 1) ? "sucessfully" : "failed!!!!");
-
- return ((success == 1) ? true: false);
-}
-
-cPluginSmartTvWeb::~cPluginSmartTvWeb() {
- // Clean up after yourself!
- mServer.cleanUp();
-}
-
-const char *cPluginSmartTvWeb::CommandLineHelp(void)
-{
- // Return a string that describes all known command line options.
- return " \n";
-}
-
-bool cPluginSmartTvWeb::ProcessArgs(int argc, char *argv[]) {
- // Implement command line argument processing here if applicable.
- return true;
-}
-
-bool cPluginSmartTvWeb::Initialize(void) {
- // Initialize any background activities the plugin shall perform.
- esyslog("SmartTvWeb: Initialize called");
-
- return true;
-}
-
-bool cPluginSmartTvWeb::SetupParse(const char *Name, const char *Value)
-{
- // Parse your own setup parameters and store their values.
- return false;
-}
-
-#if VDRVERSNUM > 10300
-
-cString cPluginSmartTvWeb::Active(void) {
- esyslog("SmartTvWeb: Active called Checkme");
- if (mServer.isServing())
- return tr("SmartTV client(s) serving");
- else
- return NULL;
-}
-
-#endif
-
-VDRPLUGINCREATOR(cPluginSmartTvWeb); // Don't touch this!
-
-#else //VOMPSTANDALONE
-
-
-int main(int argc, char *argv[]) {
- printf ("Starting up\n");
-
- SmartTvServer server;
- server.initServer(".");
- server.loop();
-}
-#endif
diff --git a/vdr-smarttvweb/smarttvweb.conf b/vdr-smarttvweb/smarttvweb.conf
deleted file mode 100644
index 07920dc..0000000
--- a/vdr-smarttvweb/smarttvweb.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-
-LogFile /tmp/smarttvweb.txt
-
-MediaFolder /multimedia/video
-
-# Media Segment Duration for HLS/ DASH
-SegmentDuration 10
-
-# minBufferTime value for the DASH MPD
-HasMinBufferTime 30
-
-# Bitrate correction parameter for Hls and DASH MPD
-HasBitrateCorrection 1.1
-
-# Default number of Live Channel entries included in the channels.xml, when not requested specifically.
-LiveChannels 30
-
-# Influence behavior, when you channels.conf contain group separators
-# Valid Values (case sensitive):
-# - Ignore : Ignore group separators)
-# - EmptyIgnore : Ignore empty group separators (which might be set to assign channel numbers)
-# - EmptyFolderDown : Interpretes an empty group channel as "cd ..", so that subsequent channels are not part of the group.
-GroupSeparators Ignore
-
-# Bind the web server to a specific IP address. Otherwise, the Web Server is listening on ALL interfaces.
-#ServerAddress 127.0.0.1
-
diff --git a/vdr-smarttvweb/stvw_cfg.c b/vdr-smarttvweb/stvw_cfg.c
deleted file mode 100755
index 75b8de6..0000000
--- a/vdr-smarttvweb/stvw_cfg.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * stvw_cfg.h: VDR on Smart TV plugin
- *
- * Copyright (C) 2012, 2013 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-#include "stvw_cfg.h"
-
-#ifndef STANDALONE
-#include <vdr/plugin.h>
-#endif
-
-#include <iostream>
-#include <fstream>
-#include <cstdio>
-#include <cstdlib>
-
-cSmartTvConfig::cSmartTvConfig(string d): mConfigDir(d), mLog(NULL), mCfgFile(NULL),
- mLogFile(), mMediaFolder(), mSegmentDuration(), mHasMinBufferTime(), mHasBitrateCorrection(),
- mLiveChannels(), mGroupSep(IGNORE), mServerAddress("") {
-
-#ifndef STANDALONE
- mLogFile= "";
-#else
- mLogFile= "./smartvvweblog-standalone.txt";
-#endif
-
- // Defaults
- mMediaFolder= "/hd2/mpeg";
- mSegmentDuration = 10;
- mHasMinBufferTime = 40;
- mHasBitrateCorrection = 1.1;
- mLiveChannels = 30;
-
- readConfig();
-}
-
-cSmartTvConfig::~cSmartTvConfig() {
-}
-
-void cSmartTvConfig::printConfig() {
- mLog = Log::getInstance();
-
-
- *(mLog->log()) << "printConfig: " << endl;
- *(mLog->log()) << " ConfigDir: " << mConfigDir << endl;
- *(mLog->log()) << " LogFile: " << mLogFile << endl;
- *(mLog->log()) << " MediaFolder:" << mMediaFolder << endl;
- *(mLog->log()) << " SegmentDuration: " << mSegmentDuration << endl;
- *(mLog->log()) << " HasMinBufferTime: " << mHasMinBufferTime << endl;
- *(mLog->log()) << " HasBitrateCorrection: " << mHasBitrateCorrection << endl;
- *(mLog->log()) << " LiveChannels: " << mLiveChannels << endl;
- *(mLog->log()) << " GroupSeparators: " << ((mGroupSep==IGNORE)? "Ignore" : ((mGroupSep==EMPTYIGNORE)? "EmptyIgnore": "EmptyFolderDown")) << endl;
- *(mLog->log()) << " ServerAddress: " << mServerAddress << endl;
-}
-
-
-void cSmartTvConfig::readConfig() {
- string line;
- char attr[200];
- char value[200];
-
- ifstream myfile ((mConfigDir +"/smarttvweb.conf").c_str());
-
- if (!myfile.is_open()) {
-#ifndef STANDALONE
- esyslog ("ERROR in SmartTvWeb: Cannot open config file. Expecting %s", (mConfigDir +"/smarttvweb.conf").c_str() );
-#else
- cout << "ERROR: Cannot open config file. Expecting "<< (mConfigDir +"/smarttvweb.conf") << endl;
-#endif
- return;
- }
-
- while ( myfile.good() ) {
- getline (myfile, line);
-
- if ((line == "") or (line[0] == '#'))
- continue;
-
- sscanf(line.c_str(), "%s %s", attr, value);
-
- if (strcmp(attr, "LogFile")==0) {
- mLogFile = string(value);
- // cout << " Found mLogFile= " << mLogFile << endl;
- continue;
- }
-
- if (strcmp(attr, "MediaFolder") == 0) {
- mMediaFolder = string (value);
- // cout << " Found mMediaFolder= " << mMediaFolder << endl;
- continue;
- }
- if (strcmp(attr, "SegmentDuration") == 0) {
- mSegmentDuration = atoi(value);
- // cout << " Found mSegmentDuration= " << mSegmentDuration << endl;
- continue;
- }
-
- if (strcmp(attr, "HasMinBufferTime") == 0) {
- mHasMinBufferTime = atoi(value);
- // cout << " Found mHasMinBufferTime= " << mHasMinBufferTime << endl;
- continue;
- }
- if (strcmp(attr, "HasBitrateCorrection") == 0) {
- mHasBitrateCorrection = atof(value);
- // cout << " Found mHasBitrate= " <<mHasBitrate << endl;
- continue;
- }
- if (strcmp(attr, "LiveChannels") == 0) {
- mLiveChannels = atoi(value);
- // cout << " Found mLiveChannels= " <<mLiveChannels << endl;
- continue;
- }
-
- if (strcmp(attr, "GroupSeparators") == 0) {
- if (strcmp (value, "EmptyIgnore") == 0) {
- mGroupSep = EMPTYIGNORE;
- }
- else if ( strcmp(value, "EmptyFolderDown") == 0) {
- mGroupSep = EMPTYFOLDERDOWN;
- }
- continue;
- }
-
- if (strcmp(attr, "ServerAddress") == 0) {
- mServerAddress = value;
- // cout << " Found mLiveChannels= " <<mLiveChannels << endl;
- continue;
- }
-
-
-#ifndef STANDALONE
- esyslog("WARNING in SmartTvWeb: Attribute= %s with value= %s was not processed, thus ignored.", attr, value);
-#else
- cout << "WARNING: Attribute= "<< attr << " with value= " << value << " was not processed, thus ignored." << endl;
-#endif
- }
- myfile.close();
-}
-
- /*
-cResumes* cSmartTvConfig::readConfig(string f) {
-
-
- string line;
- ifstream myfile ("example.txt");
-
- if (myfile.is_open()) {
- while ( myfile.good() ) {
- getline (myfile,line);
- *(mLog->log()) << " readConfig: " << line << endl;
- if (line == "")
- continue;
-
- string t;
- time_t st;
- int r;
- time_t lv;
- int count = scanf (line.c_str(), "%s %lld %d %lld", &t, &st, &r, &lv);
- if (count == 4) {
- *(mLog->log()) << " read: " << t << " st= " << st << " r= " << r << " lv= " << lv << endl;
- }
- // first title
-
-
- }
- myfile.close();
- }
-
- else {
- *(mLog->log()) << " readConfig: Cannot open file " << f << endl;
- return NULL;
- }
-
-
- // open the file
- // read the lines
- return NULL;
-}
-*/
diff --git a/vdr-smarttvweb/stvw_cfg.h b/vdr-smarttvweb/stvw_cfg.h
deleted file mode 100755
index d894820..0000000
--- a/vdr-smarttvweb/stvw_cfg.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * stvw_cfg.h: VDR on Smart TV plugin
- *
- * Copyright (C) 2012, 2013 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-
-#ifndef __SMARTTV_CONFIG_H__
-#define __SMARTTV_CONFIG_H__
-
-#include <string>
-#include <cstring>
-#include <vector>
-#include <ctime>
-#include "log.h"
-
-using namespace std;
-
-
-enum eGroupSep {
- IGNORE,
- EMPTYIGNORE,
- EMPTYFOLDERDOWN
-};
-
-class cSmartTvConfig {
- private:
- string mConfigDir;
- Log* mLog;
- FILE *mCfgFile;
-
- string mLogFile;
- string mMediaFolder;
- unsigned int mSegmentDuration;
- int mHasMinBufferTime;
- float mHasBitrateCorrection;
- int mLiveChannels;
-
- eGroupSep mGroupSep;
- string mServerAddress;
-
- public:
- cSmartTvConfig(string dir);
- ~cSmartTvConfig();
-
- void readConfig();
- void printConfig();
-
- string getLogFile() { return mLogFile; };
- string getMediaFolder() { return mMediaFolder; };
- unsigned int getSegmentDuration() {return mSegmentDuration; };
- int getHasMinBufferTime() { return mHasMinBufferTime; };
- float getHasBitrateCorrection() { return mHasBitrateCorrection; };
- int getLiveChannels() {return mLiveChannels; };
- eGroupSep getGroupSep() { return mGroupSep; };
- string getServerAddress() { return mServerAddress; };
-};
-
-#endif
diff --git a/vdr-smarttvweb/url.c b/vdr-smarttvweb/url.c
deleted file mode 100644
index 6446654..0000000
--- a/vdr-smarttvweb/url.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * url.c: VDR on Smart TV plugin
- *
- * Copyright (C) 2012, 2013 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-#include <cstdio>
-#include"url.h"
-
-
-//http://www.blooberry.com/indexdot/html/topics/urlencoding.htm
-string cUrlEncode::doUrlSaveEncode(string in) {
- string res = "";
- unsigned char num = 0;
- char buf[5];
-
- bool done = false;
- unsigned int idx = 0;
- while (!done) {
- if (idx == in.size()) {
- done = true;
- continue;
- }
- num = in[idx];
- switch (num) {
- case '&':
- res += "%26";
- break;
- case '%':
- res += "%25";
- break;
- case '#':
- // break;
- if (in.compare(idx, 3, "#3F") == 0) {
- res += "%3F";
- idx +=3;
- continue;
- }
- if (in.compare(idx, 3, "#3A") == 0) {
- res += "%3A";
- idx += 3;
- continue;
- }
- if (in.compare(idx, 3, "#2F") == 0) {
- res += "%2F";
- idx += 3;
- continue;
- }
- res += "%23"; // just a '#' char
- break;
- default:
- // Copy the normal chars
- if (num < 128)
- res += char(num);
- else {
- sprintf (buf, "%02hhX", num);
- res += "%";
- res += buf;
- }
- break;
- } // switch
-
- idx ++;
- }
- return res;
-}
-
-
-string cUrlEncode::doUrlSaveDecode(string input) {
- string res = "";
- unsigned int idx = 0;
- int x;
- while (idx < input.size()){
- if (input[idx] == '%') {
- string num = input.substr(idx+1, 2);
- sscanf(num.c_str(), "%X", &x);
- idx+= 3;
- switch (x) {
- case 0x23: // '#'
- res += "#";
- break;
- case 0x25: // '%'
- res += "%";
- break;
- case 0x2f: // '/'
- res += "#2F";
- break;
- case 0x3a: // ':'
- res += "#3A";
- break;
- case 63: // '?'
- res += "#3F";
- break;
- default:
- res += char(x);
- break;
- }
- }
- else {
- res += input[idx];
- idx ++;
- }
- }
- return res;
-}
-
-string cUrlEncode::doXmlSaveEncode(string in) {
- string res = "";
- unsigned char num = 0;
- // char buf[5];
-
- bool done = false;
- unsigned int idx = 0;
- while (!done) {
- if (idx == in.size()) {
- done = true;
- continue;
- }
- num = in[idx];
- switch (num) {
- case 0x26: // '&':
- res += "&amp;";
- break;
- case 0x27: // '\'':
- res += "&apos;";
- break;
- case 0x3c: // '<':
- res += "&lt;";
- break;
- case 0x3e: // '>':
- res += "&gt;";
- break;
- case 0x22: // '\"':
- res += "&quot;";
- break;
-
- /* case 0xc4: // Ä
- res += "&#196;";
- break;
- case 0xe4: //'ä':
- res += "&#228;";
- break;
- case 0xd6: // Ö
- res += "&#214;";
- break;
- case 0xf6: // 'ö':
- res += "&#246;";
- break;
- case 0xdc: //'Ü':
- res += "&#220;";
- break;
- case 0xfc: //'ü':
- res += "&#252;";
- break;
- case 0xdf: //'ß':
- res += "&#223;";
- break;
-*/
- default:
- // Copy the normal chars
- res += char(num);
- break;
- } // switch
-
- idx ++;
- }
- return res;
-}
-
-string cUrlEncode::doXmlSaveDecode(string input) {
- string res = "";
- unsigned int idx = 0;
- while (idx < input.size()){
- if (input[idx] == '&') {
- if (input.compare(idx, 4, "&lt;") == 0){
- res += "<";
- idx += 4;
- }
- else if (input.compare(idx, 4, "&gt;") == 0){
- res += ">";
- idx += 4;
- }
- else if (input.compare(idx, 5, "&amp;") == 0){
- res += "&";
- idx += 5;
- }
- else if (input.compare(idx, 6, "&quot;") == 0){
- res += "\"";
- idx += 6;
- }
- else if (input.compare(idx, 6, "&apos;") == 0){
- res += "\'";
- idx += 6;
- }
- else {
- // ERROR
- idx = input.size();
- res = "";
- }
- }
- else {
- res += input[idx];
- idx ++;
- }
-
- }
- return res;
-}
-
-string cUrlEncode::removeEtChar(string line, bool xml) {
- bool done = false;
- size_t cur_pos = 0;
- size_t pos = 0;
- string res = "";
-
- int end_after_done = 0;
-
- while (!done) {
- pos = line.find('&', cur_pos);
- if (pos == string::npos) {
- done = true;
- res += line.substr(cur_pos);
- break;
- }
- if (pos >= 0) {
- if (xml)
- res += line.substr(cur_pos, (pos-cur_pos)) + "&#38;"; // xml save encoding
- else
- res += line.substr(cur_pos, (pos-cur_pos)) + "%26"; // url save encoding
- // cur_pos = cur_pos+ pos +1;
- cur_pos = pos +1;
- end_after_done ++;
- }
- }
- return res;
-}
-
-string cUrlEncode::hexDump(char *line, int line_len) {
- string res = "";
- string ascii = "";
- char buf[10];
-
- int line_count = 0;
- for (unsigned int i = 0; i < line_len; i++) {
- unsigned char num = line[i];
- sprintf (buf, "%02hhX", num);
- res += buf;
- if ((num >= 32) && (num < 127)) {
- ascii += char(num);
- }
- else
- ascii += '.';
-
- line_count++;
- switch (line_count) {
- case 8:
- res += " ";
- ascii += " ";
- break;
- case 17:
- res += " " + ascii;
- res += "\r\n";
- ascii = "";
- line_count = 0;
- break;
- default:
- res += " ";
- break;
- }
- }
- if (line_count != 0) {
- for (int i = 0; i < ((17 - line_count) * 3 ); i++)
- res += " ";
- if (line_count >= 8)
- res += " ";
-
- res += " ";
- res += ascii;
- }
- return res;
-}
-
-string cUrlEncode::hexDump(string in) {
- string res = "";
- string ascii = "";
- char buf[10];
-
- int line_count = 0;
- for (unsigned int i = 0; i < in.size(); i++) {
- unsigned char num = in[i];
- sprintf (buf, "%02hhX", num);
- res += buf;
- if ((num >= 32) && (num < 127)) {
- ascii += char(num);
- }
- else
- ascii += '.';
-
- line_count++;
- switch (line_count) {
- case 8:
- res += " ";
- ascii += " ";
- break;
- case 16:
- res += " " + ascii;
- res += "\r\n";
- ascii = "";
- line_count = 0;
- break;
- default:
- res += " ";
- break;
- }
- }
- if (line_count != 0) {
- for (int i = 0; i < ((16 - line_count) * 3 ); i++)
- res += " ";
- if (line_count >= 8)
- res += " ";
- res += ascii;
- }
- return res;
-}
diff --git a/vdr-smarttvweb/url.h b/vdr-smarttvweb/url.h
deleted file mode 100644
index 4656a2a..0000000
--- a/vdr-smarttvweb/url.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * url.h: VDR on Smart TV plugin
- *
- * Copyright (C) 2012 T. Lohmar
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- */
-
-
-#ifndef __URL_H__
-#define __URL_H__
-
-#include <string>
-
-using namespace std;
-
-class cUrlEncode {
-
- public:
- cUrlEncode() {};
- cUrlEncode(string &) {};
-
- static string doUrlSaveEncode (string);
- static string doUrlSaveDecode (string);
-
- static string doXmlSaveEncode (string);
- static string doXmlSaveDecode (string);
- static string removeEtChar(string line, bool xml=true);
- static string hexDump(char *line, int line_len);
- static string hexDump(string);
-
- private:
-
-};
-
-#endif
diff --git a/vdr-smarttvweb/web/Data.js b/vdr-smarttvweb/web/Data.js
deleted file mode 100755
index 49e9026..0000000
--- a/vdr-smarttvweb/web/Data.js
+++ /dev/null
@@ -1,296 +0,0 @@
-//Diff:
-// getNumString
-// createJQMDomTree
-
-var Data =
-{
- assets : new Item,
- folderList : [],
-};
-
-Array.prototype.remove = function(from, to) {
- var rest = this.slice((to || from) + 1 || this.length);
- this.length = from < 0 ? this.length + from : from;
- return this.push.apply(this, rest);
-};
-
-Data.reset = function() {
- this.assets = null;
- this.assets = new Item;
-
- this.folderList = [];
-
-// this.folderList.push({item : this.assets, id: 0});
-// Main.log("Data.reset: folderList.push. this.folderList.length= " + this.folderList.length);
-};
-
-Data.completed= function(sort) {
- if (sort == true)
- this.assets.sortPayload();
-
- this.folderList.push({item : this.assets, id: 0});
-// Main.log("Data.completed: folderList.push. this.folderList.length= " + this.folderList.length);
-// Main.log ("Data.completed()= " +this.folderList.length);
-
-};
-
-Data.selectFolder = function (idx, first_idx) {
- this.folderList.push({item : this.getCurrentItem().childs[idx], id: idx, first:first_idx});
-// Main.log("Data.selectFolder: folderList.push. this.folderList.length= " + this.folderList.length);
-};
-
-Data.folderUp = function () {
- itm = this.folderList.pop();
-// Main.log("Data.folderUp: folderList.pop. this.folderList.length= " + this.folderList.length);
- return itm;
-// return itm.id;
-};
-
-Data.isRootFolder = function() {
-// Main.log("Data.isRootFolder: this.folderList.length= " + this.folderList.length);
- if (this.folderList.length == 1)
- return true;
- else
- return false;
-};
-
-Data.addItem = function(t_list, pyld) {
- this.assets.addChild(t_list, pyld, 0);
-};
-
-Data.dumpFolderStruct = function(){
- Main.log("---------- dumpFolderStruct ------------");
- this.assets.print(0);
- Main.log("---------- dumpFolderStruct Done -------");
-};
-
-Data.createJQMDomTree = function () {
- return this.assets.createJQMDomTree(0);
-};
-
-Data.findEpgUpdateTime = function() {
- return this.assets.findEpgUpdateTime(Display.GetEpochTime() + 10000, "", 0);
- // min, guid, level
-};
-
-Data.updateEpg = function (guid, entry) {
- this.assets.updateEpgEntry(guid, entry, 0);
-};
-
-Data.getCurrentItem = function () {
- return this.folderList[this.folderList.length-1].item;
-};
-
-Data.getVideoCount = function() {
- return this.folderList[this.folderList.length-1].item.childs.length;
-};
-
-Data.getNumString =function(num, fmt) {
- var res = "";
-
- if (num < 10) {
- for (var i = 1; i < fmt; i ++) {
- res += "0";
- };
- } else if (num < 100) {
- for (var i = 2; i < fmt; i ++) {
- res += "0";
- };
- }
-
- res = res + num;
-
- return res;
-};
-
-Data.deleteElm = function (pos) {
- Data.getCurrentItem().childs.remove(pos);
-};
-//-----------------------------------------
-function Item() {
- this.title = "root";
- this.isFolder = true;
- this.childs = [];
- this.payload = ""; // only set, if (isFolder == false)
-}
-
-Item.prototype.isFolder = function() {
- return this.isFolder;
-};
-
-Item.prototype.getTitle = function () {
- return this.title;
-};
-
-Item.prototype.getPayload = function () {
- if (this.isFolder == true) {
- Main.log("WARNING: getting payload on a folder title=" +this.title);
- }
- return this.payload;
-};
-
-Item.prototype.getItem = function (title) {
- for (var i = 0; i < this.childs.length; i++) {
- if (this.childs[i].title == title) {
- return this.childs[i];
- }
- }
- return 0;
-};
-
-Item.prototype.addChild = function (key, pyld, level) {
- if (key.length == 1) {
- var folder = new Item;
-// folder.title = pyld.startstr + " - " + key;
- folder.title = key[0];
- folder.payload = pyld;
- folder.isFolder = false;
- this.childs.push(folder);
-// this.titles.push({title: pyld.startstr + " - " + key , pyld : pyld});
- }
- else {
- if (level > 10) {
- Main.log(" too many levels");
- return;
- }
- var t = key.shift();
- var found = false;
- for (var i = 0; i < this.childs.length; i++) {
- if (this.childs[i].title == t) {
- this.childs[i].addChild(key, pyld, level +1);
- found = true;
- break;
- }
- }
- if (found == false) {
- var folder = new Item;
- folder.title = t;
- folder.addChild(key, pyld, level+1);
- this.childs.push(folder);
- }
- }
-};
-
-Item.prototype.findEpgUpdateTime = function (min, guid, level) {
- var prefix= "";
- for (var i = 0; i < level; i++)
- prefix += "-";
-
- for (var i = 0; i < this.childs.length; i++) {
- if (this.childs[i].isFolder == true) {
- var res = this.childs[i].findEpgUpdateTime(min, guid, level+1);
- min = res.min;
- guid = res.guid;
- }
- else {
- var digi =new Date(this.childs[i].payload['start'] * 1000);
- var str = digi.getHours() + ":" + digi.getMinutes();
-
-// Main.log(prefix + "min= " + min+ " start= " + this.childs[i].payload['start'] + " (" + str+ ") title= " + this.childs[i].title);
-
- if ((this.childs[i].payload['start'] != 0) && ((this.childs[i].payload['start'] + this.childs[i].payload['dur']) < min)) {
- min = this.childs[i].payload['start'] + this.childs[i].payload['dur'];
- guid = this.childs[i].payload['guid'] ;
-// Main.log(prefix + "New Min= " + min + " new id= " + guid + " title= " + this.childs[i].title);
-// Main.logToServer(prefix + "New Min= " + min + " new id= " + guid + " title= " + this.childs[i].title);
- }
- }
- }
-
- return { "min": min, "guid" : guid};
-};
-
-Item.prototype.updateEpgEntry = function (guid, entry, level) {
- var prefix= "";
- for (var i = 0; i < level; i++)
- prefix += "-";
- for (var i = 0; i < this.childs.length; i++) {
- if (this.childs[i].isFolder == true) {
- var res = this.childs[i].updateEpgEntry(guid, entry, level+1);
- if (res == true)
- return true;
- }
- else {
- if (this.childs[i].payload['guid'] == guid) {
- Main.log("updateEpgEntry: Found " + this.childs[i].title);
- this.childs[i].payload.prog = entry.prog;
- this.childs[i].payload.desc = entry.desc;
- this.childs[i].payload.start = entry.start;
- this.childs[i].payload.dur = entry.dur;
- return true;
- }
- }
- }
- return false;
-};
-
-Item.prototype.print = function(level) {
- var prefix= "";
- for (var i = 0; i < level; i++)
- prefix += " ";
-
- for (var i = 0; i < this.childs.length; i++) {
- Main.log(prefix + this.childs[i].title);
- if (this.childs[i].isFolder == true) {
- Main.log(prefix+"Childs:");
- this.childs[i].print(level +1);
- }
- }
-};
-
-Item.prototype.createJQMDomTree = function(level) {
- var mydiv = $('<ul />');
-// if (level == 0) {
- mydiv.attr('data-role', 'listview');
- mydiv.attr('data-inset', 'true');
-// };
-//, id:'dyncreated'
- for (var i = 0; i < this.childs.length; i++) {
- if (this.childs[i].isFolder == true) {
- var myh = $('<div>', {text: this.childs[i].title});
- var myli = $('<li>');
- myli.append(myh);
- var mycount = $('<p>', {class: 'ui-li-count', text: this.childs[i].childs.length});
- myli.append(mycount);
- myli.append(this.childs[i].createJQMDomTree(level+1));
- mydiv.append(myli);
- }
- else {
- // Links
- var digi = new Date(this.childs[i].payload['start'] *1000);
- var mon = Data.getNumString ((digi.getMonth()+1), 2);
- var day = Data.getNumString (digi.getDate(), 2);
- var hour = Data.getNumString (digi.getHours(), 2);
- var min = Data.getNumString (digi.getMinutes(), 2);
-
- var d_str = mon + "/" + day + " " + hour + ":" + min;
- var mya = $('<a>', { text: d_str + " - " + this.childs[i].title,
- href: this.childs[i].payload['link'],
- rel: 'external'} );
- var myli = $('<li class="item"/>');
- myli.attr('data-icon', 'false');
- myli.attr('data-theme', 'c');
-
- myli.append(mya);
- mydiv.append(myli);
- }
- }
- return mydiv;
-};
-
-Item.prototype.sortPayload = function() {
- for (var i = 0; i < this.childs.length; i++) {
- if (this.childs[i].isFolder == true) {
- this.childs[i].sortPayload();
- }
- }
- this.childs.sort(function(a,b) {
- if (a.title == b.title) {
- return (b.payload.start - a.payload.start);
- }
- else {
- return ((a.title < b.title) ? -1 : 1);
- }
- });
-};
-
diff --git a/vdr-smarttvweb/web/Server.js b/vdr-smarttvweb/web/Server.js
deleted file mode 100755
index 1ab6d0a..0000000
--- a/vdr-smarttvweb/web/Server.js
+++ /dev/null
@@ -1,180 +0,0 @@
-var Server = {
- dataReceivedCallback : null,
- errorCallback : null,
- doSort : false,
- retries : 0,
-
- XHRObj : null
-};
-
-Server.init = function()
-{
- var success = true;
-
- if (this.XHRObj) {
- this.XHRObj.destroy();
- this.XHRObj = null;
- }
-
- return success;
-};
-
-Server.setSort = function (val) {
- this.doSort = val;
-};
-//---------------------------------------------
-Server.fetchVideoList = function(url) {
-
- $.ajax({
- url: url,
- type : "GET",
- success : function(data, status, XHR ) {
-// Main.log("Server.fetchVideoList Success Response - status= " + status + " mime= " + XHR.responseType + " data= "+ data);
-
- $(data).find("item").each(function () {
- var title = $(this).find('title').text();
-// var link = $(this).find('link').text();
- var link = $(this).find('enclosure').attr('url');
- var guid = $(this).find('guid').text();
- var programme = $(this).find('programme').text();
- var description = $(this).find('description').text();
- var startVal = parseInt($(this).find('start').text());
- var durVal = parseInt($(this).find('duration').text());
- var fps = parseFloat($(this).find('fps').text());
- var ispes = $(this).find('ispes').text();
- var isnew = $(this).find('isnew').text();
-// Main.log("Server.fetchVideoList: title= " + title + " start= " + startVal + " dur= " + durVal + " fps= " + fps);
-
-/* if (Main.state == Main.eLIVE) {
- Epg.guidTitle[guid] = title;
- }
-*/
- var title_list = title.split("~");
- Data.addItem( title_list, {link : link, prog: programme, desc: description, guid : guid, start: startVal,
- dur: durVal, ispes : ispes, isnew : isnew, fps : fps});
-
- }); // each
-
- Data.completed(Server.doSort);
-
- if (Server.dataReceivedCallback) {
- Server.dataReceivedCallback();
- }
-
- },
- error : function (jqXHR, status, error) {
-// Main.logToServer("Server.fetchVideoList Error Response - status= " + status + " error= "+ error);
-// Display.showPopup("Error with XML File: " + status);
- Server.retries ++;
- },
- parsererror : function () {
- // Main.logToServer("Server.fetchVideoList parserError " );
- // Display.showPopup("Error in XML File");
- Server.retries ++;
- if (Server.errorCallback != null) {
- Server.errorCallback("XmlError");
- }
-
- }
- });
-};
-
-
-//---------------------------------------------
-
-Server.updateVdrStatus = function (){
- Main.log ("get VDR Status");
- $.ajax({
- url: Config.serverUrl + "/vdrstatus.xml",
- type : "GET",
- success : function(data, status, XHR){
- var free = $(data).find('free').text() / 1024.0;
- var used = $(data).find('used').text() / 1024.0;
- var percent = $(data).find('percent').text();
-
- var unit = "GB";
- var free_str = free.toFixed(2);
- if (free_str.length > 6) {
- free = free / 1024.0;
- free_str = free.toFixed(2);
- unit = "TB";
- }
- $("#logoDisk").text("Free: " +free_str + unit);
- $("#selectDisk").text("Free: " +free_str + unit);
- },
- error: function(jqXHR, status, error){
- Main.log("VdrStatus: Error");
- }
- });
-}
-
-
-Server.getResume = function (guid) {
-// Main.log ("***** getResume *****");
- $.ajax({
- url: Config.serverUrl + "/getResume.xml",
- type : "POST",
- data : "filename:" + guid +"\n",
- success : function(data, status, XHR ) {
- Main.log("**** Resome Success Response - status= " + status + " mime= " + XHR.responseType + " data= "+ data);
-
- var resume_str = $(data).find("resume").text();
- if (resume_str != "") {
- var resume_val = parseFloat(resume_str);
- Main.log("resume val= " + resume_val );
- Main.logToServer("resume val= " + resume_val );
- Player.resumePos = resume_val;
- Player.playVideo( resume_val);
- }
- else {
- Display.hide();
- Display.showProgress();
- Player.playVideo(-1);
- }
-
- },
- error : function (jqXHR, status, error) {
- Main.log("**** Resome Error Response - status= " + status + " error= "+ error);
- Display.hide();
- Display.showProgress();
- Player.playVideo(-1);
- }
- });
-};
-
-Server.saveResume = function() {
- var msg = "";
- msg += "filename:" + Data.getCurrentItem().childs[Main.selectedVideo].payload.guid + "\n";
- msg += "resume:"+ (Player.curPlayTime/1000) + "\n" ;
-
- $.post(Config.serverUrl + "/setResume.xml", msg, function(data, textStatus, XHR) {
- Main.logToServer("SaveResume Status= " + XHR.status );
- }, "text");
-
-};
-
-Server.deleteRecording = function(guid) {
- Main.log("Server.deleteRecording guid=" + guid);
- Main.logToServer("Server.deleteRecording guid=" + guid);
- Notify.handlerShowNotify("Deleting...", false);
-
- $.ajax({
- url: Config.serverUrl + "/deleteRecording.xml?id=" +guid,
- type : "POST",
- success : function(data, status, XHR ) {
- Notify.showNotify("Deleted", true);
- Data.deleteElm(Main.selectedVideo);
- if (Main.selectedVideo >= Data.getVideoCount())
- Main.selectedVideo = Data.getVideoCount() -1;
- Server.updateVdrStatus();
- Display.setVideoList(Main.selectedVideo, (Main.selectedVideo - Display.currentWindow));
- Main.logToServer("Server.deleteRecording: Success" );
- },
- error : function (XHR, status, error) {
- Main.logToServer("Server.deleteRecording: Error" );
-
- // show popup
- Notify.showNotify("Error", true);
- }
- });
-};
diff --git a/vdr-smarttvweb/web/favicon.ico b/vdr-smarttvweb/web/favicon.ico
deleted file mode 100755
index 2236569..0000000
--- a/vdr-smarttvweb/web/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/vdr-smarttvweb/web/index.html b/vdr-smarttvweb/web/index.html
deleted file mode 100755
index f396ed4..0000000
--- a/vdr-smarttvweb/web/index.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta name="viewport" content="width=device-width, initial-scale=1">
-<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
-<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
-<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
-<script language="javascript" type="text/javascript" src="Server.js"></script>
-<script language="javascript" type="text/javascript" src="Data.js"></script>
-<script>
-$(document).ready(function(){
- var state = 'rec'; // Rec
-
- Server.init();
-
- Server.dataReceivedCallback = function() {
- console.log("Loaded");
- $("#anchor").append(Data.createJQMDomTree()).trigger('create');
- $.mobile.loading('hide');
- //http://jquerymobile.com/
-
- // end of dataReceivedCallBack
- };
- Server.errorCallback = function (msg) {
- alert (msg);
- buttonHandler('rec');
- };
-
- $.mobile.loading('show');
- Server.setSort(true);
- Server.fetchVideoList("/recordings.xml?mode=nodesc");
-
- removeDomTree = function () {
- // parent should not be deleted.
- $("#anchor").children().remove();
- };
-
- buttonHandler = function(btn) {
- console.log("Click: " + btn);
- if (state == btn) {
- console.log("No Change");
- };
- $.mobile.loading('show');
- Data.reset();
- removeDomTree();
- switch (btn) {
- case 'rec':
- state = 'rec';
- $('#recbtn').addClass('ui-btn-active');
- $('#medbtn').removeClass('ui-btn-active');
- $('#chnbtn').removeClass('ui-btn-active');
- Server.setSort(true);
- Server.fetchVideoList("/recordings.xml?mode=nodesc");
- break;
- case 'med':
- state = 'med';
- $('#medbtn').addClass('ui-btn-active');
- $('#recbtn').removeClass('ui-btn-active');
- $('#chnbtn').removeClass('ui-btn-active');
- Server.setSort(true);
- Server.fetchVideoList("/media.xml");
- break;
- case 'chn':
- state = 'chn';
- $('#chnbtn').addClass('ui-btn-active');
- $('#medbtn').removeClass('ui-btn-active');
- $('#recbtn').removeClass('ui-btn-active');
- Server.setSort(false);
- Server.fetchVideoList("/channels.xml?mode=nodesc");
- break;
- };
- };
-
-});
-</script>
-<style type="text/css" >
-h2 { margin:1.2em 0 .4em 0; }
- }
-</style>
-</head>
-
-<body>
- <div data-role="page" class="type-interior">
-
- <div data-role="header" data-theme="b">
- <h1>Recordings</h1>
- </div> <!-- /header -->
-
- <div data-role="content">
- <div class="content-primary" >
-
- <div data-role="controlgroup" data-type="horizontal" data-mini="true">
- <a href="#" id="recbtn" data-role="button" data-transition="fade" class="ui-btn-active" onclick="return buttonHandler('rec')">Recordings</a>
- <a href="#" id="medbtn" data-role="button" data-transition="fade" onclick="return buttonHandler('med')">Media</a>
- <a href="#" id="chnbtn" data-role="button" data-transition="fade" onclick="return buttonHandler('chn')">Channels</a>
- </div>
-
- <div id="anchor"/>
- </div>
- </div>
-</div>
- </body>
-</html>
-
diff --git a/vdr-smarttvweb/widget.conf b/vdr-smarttvweb/widget.conf
deleted file mode 100644
index da4a006..0000000
--- a/vdr-smarttvweb/widget.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<config>
-<format>hls</format>
-<tgtBufferBitrate>6000000</tgtBufferBitrate>
-<totalBufferDuration>40</totalBufferDuration>
-<initialBuffer>5</initialBuffer>
-<pendingBuffer>5</pendingBuffer>
-<initialTimeOut>5</initialTimeOut>
-<skipDuration>30</skipDuration>
-<liveChannels>20</liveChannels>
-</config>