summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authormethodus <methodus@web.de>2012-09-15 23:44:19 +0200
committermethodus <methodus@web.de>2012-09-15 23:44:19 +0200
commit159592eaa3b7ba9135bf01b4015af0d7914805bf (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /server
parent15139183fdea8f65af5a7dbfd354bcedf5886e80 (diff)
downloadvdr-plugin-upnp-159592eaa3b7ba9135bf01b4015af0d7914805bf.tar.gz
vdr-plugin-upnp-159592eaa3b7ba9135bf01b4015af0d7914805bf.tar.bz2
Master geleert
Diffstat (limited to 'server')
-rw-r--r--server/server.cpp371
-rw-r--r--server/webserver.cpp363
2 files changed, 0 insertions, 734 deletions
diff --git a/server/server.cpp b/server/server.cpp
deleted file mode 100644
index 56bf442..0000000
--- a/server/server.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * File: server.cpp
- * Author: savop
- *
- * Created on 19. April 2009, 17:42
- */
-
-#include <vdr/plugin.h>
-#include <stdlib.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <upnp/upnp.h>
-#include "server.h"
-#include "util.h"
-#include "config.h"
-#include "../common.h"
-#include "upnp/dlna.h"
-#include "object.h"
-
-/****************************************************
- *
- * The UPnP Server
- *
- * Handles incoming messages, UPnP connections
- * and so on.
- *
- ****************************************************/
-
-cConnectionManager* cUPnPServer::mConnectionManager = NULL;
-cContentDirectory* cUPnPServer::mContentDirectory = NULL;
-
-cUPnPServer::cUPnPServer() {
- this->mServerAddr = new sockaddr_in;
- // Bugfix: this was necessary because there were
- // some uninitialised bytes in the structure (Please recheck this!)
- memset(this->mServerAddr,0,sizeof(sockaddr_in));
- this->mServerAddr->sin_family = AF_INET;
- this->mServerAddr->sin_port = 0;
- this->mIsRunning = false;
- this->mIsAutoDetectionEnabled = true;
- this->mIsEnabled = false;
- this->mDeviceHandle = NULL;
- this->mMediaDatabase = NULL;
-}
-
-cUPnPServer::~cUPnPServer() {
- delete this->mServerAddr; this->mServerAddr = NULL;
- delete this->mMediaDatabase;
-}
-
-bool cUPnPServer::init(void){
-
- MESSAGE(VERBOSE_SDK, "Loading configuration...");
- cUPnPConfig* config = cUPnPConfig::get();
- this->enable(config->mEnable == 1 ? true : false);
- if(!config->mAutoSetup){
- if(config->mInterface)
- if(!this->setInterface(config->mInterface)){
- ERROR("Invalid network interface: %s", config->mInterface);
- return false;
- }
- if(config->mAddress)
- if(!this->setAddress(config->mAddress)){
- ERROR("Invalid IP address: %s", config->mAddress);
- return false;
- }
- if(!this->setServerPort((short)config->mPort)){
- ERROR("Invalid port: %d", config->mPort);
- return false;
- }
- }
- else {
- if(!this->setAutoDetection(config->mAutoSetup == 1 ? true : false)){
- ERROR("Invalid auto detection setting: %d", config->mAutoSetup);
- return false;
- }
- if(!this->autoDetectSettings()){
- ERROR("Error while auto detecting settings.");
- return false;
- }
- }
-
- MESSAGE(VERBOSE_SDK, "Initializing Intel UPnP SDK on %s:%d",inet_ntoa(this->mServerAddr->sin_addr), ntohs(this->mServerAddr->sin_port));
- int ret = 0;
- ret = UpnpInit(inet_ntoa(this->mServerAddr->sin_addr), ntohs(this->mServerAddr->sin_port));
-
- if (ret != UPNP_E_SUCCESS) {
- // test if SDK was allready initiated
- if (ret == UPNP_E_INIT) {
- WARNING("SDK was allready initiated (no problem) - Errorcode: %d", ret);
- } else {
- ERROR("Error while init Intel SDK - Errorcode: %d", ret);
- return false;
- }
- }
- else {
- if(!inet_aton(UpnpGetServerIpAddress(),&this->mServerAddr->sin_addr)){
- ERROR("Unable to set IP address");
- }
- this->mServerAddr->sin_port = htons(UpnpGetServerPort());
- MESSAGE(VERBOSE_SDK, "Initializing succesfully at %s:%d", UpnpGetServerIpAddress(), UpnpGetServerPort());
- }
-
- MESSAGE(VERBOSE_CUSTOM_OUTPUT, "Setting maximum packet size for SOAP requests");
- UpnpSetMaxContentLength(UPNP_SOAP_MAX_LEN);
-
- const char* httpdir = (cUPnPConfig::get()->mHTTPFolder) ? cUPnPConfig::get()->mHTTPFolder : cPluginUpnp::getConfigDirectory();
- //set the root directory of the webserver
- cString WebserverRootDir = cString::sprintf("%s%s", httpdir, UPNP_WEB_SERVER_ROOT_DIR);
-
- MESSAGE(VERBOSE_SDK, "Set web server root dir: %s", *WebserverRootDir );
- this->mWebServer = cUPnPWebServer::getInstance(WebserverRootDir);
- MESSAGE(VERBOSE_SDK, "Initializing web server.");
- if (!this->mWebServer->init()) {
- ERROR("Error while setting web server root dir - Errorcode: %d", ret);
- return false;
- }
-
- //register media server device to SDK
- cString URLBase = cString::sprintf("http://%s:%d", UpnpGetServerIpAddress(), UpnpGetServerPort());
-
- this->mDeviceDescription = cString(cDlna::getInstance()->getDeviceDescription(URLBase),true);
-
- MESSAGE(VERBOSE_SDK, "Register Media Server Device");
- ret = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC,
- this->mDeviceDescription, sizeof(this->mDeviceDescription), 1,
- &cUPnPServer::upnpActionCallback,
- &this->mDeviceHandle,
- &this->mDeviceHandle);
- if (ret != UPNP_E_SUCCESS) {
- ERROR("Error while registering device - Errorcode: %d", ret);
- return false;
- }
-
- MESSAGE(VERBOSE_CUSTOM_OUTPUT, "Unregister server to cleanup previously started servers");
- ret = UpnpUnRegisterRootDevice(this->mDeviceHandle);
- if (ret != UPNP_E_SUCCESS) {
- WARNING("Unregistering old devices failed");
- return false;
- }
-
- MESSAGE(VERBOSE_CUSTOM_OUTPUT, "Register Media Server Device");
- ret = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC,
- this->mDeviceDescription, sizeof(this->mDeviceDescription), 1,
- &cUPnPServer::upnpActionCallback,
- &this->mDeviceHandle,
- &this->mDeviceHandle);
- if (ret != UPNP_E_SUCCESS) {
- ERROR("Error while registering device - Errorcode: %d", ret);
- return false;
- }
-
- MESSAGE(VERBOSE_SDK, "Initializing media database");
- this->mMediaDatabase = new cMediaDatabase;
- if(!this->mMediaDatabase->init()){
- ERROR("Error while initializing database");
- return false;
- }
-
- MESSAGE(VERBOSE_SDK, "Initializing connection manager");
- cUPnPServer::mConnectionManager = new cConnectionManager(this->mDeviceHandle);
- MESSAGE(VERBOSE_SDK, "Initializing content directory");
- cUPnPServer::mContentDirectory = new cContentDirectory(this->mDeviceHandle, this->mMediaDatabase);
- if(!cUPnPServer::mContentDirectory->Start()){
- ERROR("Unable to start content directory thread");
- return false;
- }
-
- //send first advertisments
- MESSAGE(VERBOSE_SDK, "Send first advertisements to publish start in network");
- ret = UpnpSendAdvertisement(this->mDeviceHandle, UPNP_ANNOUNCE_MAX_AGE);
- if (ret != UPNP_E_SUCCESS) {
- ERROR("Error while sending first advertisments - Errorcode: %d", ret);
- return false;
- }
-
- return true;
-}
-
-bool cUPnPServer::uninit(void) {
- MESSAGE(VERBOSE_SDK, "Shuting down content directory");
- delete cUPnPServer::mContentDirectory; cUPnPServer::mContentDirectory = NULL;
-
- MESSAGE(VERBOSE_SDK, "Shuting down connection manager");
- delete cUPnPServer::mConnectionManager; cUPnPServer::mConnectionManager = NULL;
-
- MESSAGE(VERBOSE_SDK, "Closing metadata database");
- delete this->mMediaDatabase; this->mMediaDatabase = NULL;
-
- MESSAGE(VERBOSE_SDK, "Closing the web server");
- this->mWebServer->uninit();
- delete this->mWebServer;
-
- MESSAGE(VERBOSE_SDK, "Close Intel SDK");
- // unregiser media server device from UPnP SDK
- int ret = UpnpUnRegisterRootDevice(this->mDeviceHandle);
- if (ret != UPNP_E_SUCCESS) {
- WARNING("No device registered");
- }
- // send intel sdk message to shutdown
- ret = UpnpFinish();
-
- if (ret == UPNP_E_SUCCESS) {
- MESSAGE(VERBOSE_SDK, "Close Intel SDK Successfull");
- return true;
- } else {
- ERROR("Intel SDK unintialized or already closed - Errorcode: %d", ret);
- return false;
- }
-}
-
-int cUPnPServer::upnpActionCallback(Upnp_EventType eventtype, void *event, void *cookie) {
- // only to remove warning while compiling because cookie is unused
- cookie = NULL;
- Upnp_Subscription_Request* eventRequest = NULL;
- Upnp_Action_Request* actionRequest = NULL;
-
- //check committed event variable
- if (event == NULL) {
- ERROR("UPnP Callback - NULL request");
- return UPNP_E_BAD_REQUEST;
- }
-
- switch (eventtype) {
- case UPNP_CONTROL_ACTION_REQUEST:
- actionRequest = (Upnp_Action_Request*) event;
-
- //check that request is for this device
- if (strcmp(actionRequest->DevUDN, UPNP_DEVICE_UDN) != 0) {
- ERROR("UPnP Callback - actions request not for this device");
- return UPNP_E_BAD_REQUEST;
- }
-
- //find out which service was called
- if (strcmp(actionRequest->ServiceID, UPNP_CMS_SERVICE_ID) == 0) {
- // proceed action
- return cUPnPServer::mConnectionManager->execute(actionRequest);
-
- } else if (strcmp(actionRequest->ServiceID, UPNP_CDS_SERVICE_ID) == 0) {
- // proceed action
- return cUPnPServer::mContentDirectory->execute(actionRequest);
- } else {
- ERROR("UPnP Callback - unsupported service called for control");
- return UPNP_E_BAD_REQUEST;
- }
- case UPNP_EVENT_SUBSCRIPTION_REQUEST:
- eventRequest = (Upnp_Subscription_Request*) event;
-
- //check that request is for this device
- if (strcmp(eventRequest->UDN, UPNP_DEVICE_UDN) != 0) {
- ERROR("UPnP Callback - event request not for this device");
- return UPNP_E_BAD_REQUEST;
- }
-
- if (strcmp(eventRequest->ServiceId, UPNP_CMS_SERVICE_ID) == 0) {
- // handle event request
- return cUPnPServer::mConnectionManager->subscribe(eventRequest);
-
- } else if (strcmp(eventRequest->ServiceId, UPNP_CDS_SERVICE_ID) == 0) {
- // handle event request
- return cUPnPServer::mContentDirectory->subscribe(eventRequest);
- } else {
- ERROR("UPnP Callback - unsupported service called for eventing");
- return UPNP_E_BAD_REQUEST;
- }
-
- return UPNP_E_BAD_REQUEST;
- default:
- ERROR("UPnP Action Callback - Unsupported Event");
- return UPNP_E_BAD_REQUEST;
- }
-
- return UPNP_E_BAD_REQUEST;
-}
-
-bool cUPnPServer::autoDetectSettings(void){
- int count;
- char** Ifaces = getNetworkInterfaces(&count);
- int i=0;
- bool ret = false;
- MESSAGE(VERBOSE_CUSTOM_OUTPUT, "AUTODETECT: Found %d possible interfaces.", sizeof(Ifaces));
- while(Ifaces[i]){
- if(strcmp(Ifaces[i],"lo")!=0){
- // true || false == true
- // false || false == false
- ret = this->setInterface(strdup(Ifaces[i])) || ret;
- }
- i++;
- }
- delete [] Ifaces;
- if(!ret){
- MESSAGE(VERBOSE_CUSTOM_OUTPUT, "AUTODETECT: No suitable interface. Giving up.");
- return false;
- }
- this->setServerPort(0);
- return true;
-}
-
-bool cUPnPServer::start(void){
- if(!this->isRunning()){
- // Put all the stuff which shall be started with the server in here
- // if the startup failed due any reason return false!
- MESSAGE(VERBOSE_SDK, "Starting UPnP Server on %s:%d",inet_ntoa(this->getServerAddress()->sin_addr), ntohs(this->getServerAddress()->sin_port));
- MESSAGE(VERBOSE_SDK, "Using DLNA version: %s", DLNA_PROTOCOL_VERSION_STR);
- this->mIsRunning = true;
- // Start Media database thread
- this->mMediaDatabase->Start();
- }
- return true;
-}
-
-void cUPnPServer::stop(void){
- if(this->isRunning()){
- MESSAGE(VERBOSE_SDK, "Call upnpServer STOP");
- this->uninit();
- this->mIsRunning = false;
- }
- return;
-}
-
-bool cUPnPServer::restart(void){
- MESSAGE(VERBOSE_SDK, "Call upnpServer RESTART");
- this->stop();
- return this->start();
-}
-
-void cUPnPServer::enable(bool enabled){
- this->mIsEnabled = enabled;
-}
-
-bool cUPnPServer::setInterface(const char* Interface){
- if(Interface != NULL) this->mInterface = Interface;
-
- if(*this->mInterface!=NULL){
- MESSAGE(VERBOSE_CUSTOM_OUTPUT, "Try to retrieve address for NIC %s",Interface);
- const sockaddr_in* ipAddress = getIPFromInterface(Interface);
- if(ipAddress!=NULL){
- memcpy(&this->mServerAddr->sin_addr,&ipAddress->sin_addr,sizeof(ipAddress->sin_addr));
- MESSAGE(VERBOSE_CUSTOM_OUTPUT, "NIC %s has the following IP: %s", *this->mInterface, inet_ntoa(this->mServerAddr->sin_addr));
- this->stop();
- return true;
- }
- delete ipAddress;
- ERROR("Unable to obtain a valid IP address for NIC %s!",Interface);
- }
- this->mServerAddr = NULL;
- return false;
-}
-
-bool cUPnPServer::setServerPort(unsigned short port){
- // check if the port is in user range or 0
- if(port != 0 && port < SERVER_MIN_PORT) return false;
- this->stop();
- this->mServerAddr->sin_port = htons(port);
- return true;
-}
-
-bool cUPnPServer::setAddress(const char* Address){
- if(inet_aton(Address, &this->mServerAddr->sin_addr) == 0) return false;
- this->stop();
- return true;
-}
-
-bool cUPnPServer::setAutoDetection(bool enable){
- this->mIsAutoDetectionEnabled = enable;
- return true;
-}
-
-sockaddr_in* cUPnPServer::getServerAddress() {
- return this->mServerAddr;
-} \ No newline at end of file
diff --git a/server/webserver.cpp b/server/webserver.cpp
deleted file mode 100644
index 04fb44a..0000000
--- a/server/webserver.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * File: upnpwebserver.cpp
- * Author: savop
- *
- * Created on 30. Mai 2009, 18:13
- */
-
-#include <time.h>
-#include <vdr/channels.h>
-#include <map>
-#include <upnp/upnp.h>
-#include "webserver.h"
-#include "server.h"
-#include "livereceiver.h"
-#include "recplayer.h"
-#include "search.h"
-
-/* COPIED FROM INTEL UPNP TOOLS */
-/*******************************************************************************
- *
- * Copyright (c) 2000-2003 Intel Corporation
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************/
-/** @private */
-struct File_Info_
-{
- /** The length of the file. A length less than 0 indicates the size
- * is unknown, and data will be sent until 0 bytes are returned from
- * a read call. */
- off64_t file_length;
-
- /** The time at which the contents of the file was modified;
- * The time system is always local (not GMT). */
- time_t last_modified;
-
- /** If the file is a directory, {\bf is_directory} contains
- * a non-zero value. For a regular file, it should be 0. */
- int is_directory;
-
- /** If the file or directory is readable, this contains
- * a non-zero value. If unreadable, it should be set to 0. */
- int is_readable;
-
- /** The content type of the file. This string needs to be allocated
- * by the caller using {\bf ixmlCloneDOMString}. When finished
- * with it, the SDK frees the {\bf DOMString}. */
-
- DOMString content_type;
-
-};
-
-/** @private */
-struct cWebFileHandle {
- cString Filename;
- off64_t Size;
- cFileHandle* FileHandle;
-};
-
-/****************************************************
- *
- * The web server
- *
- * Handles the virtual directories and the
- * provision of data
- *
- * Interface between the channels/recordings of the
- * VDR and the outer world
- *
- ****************************************************/
-
-cUPnPWebServer::cUPnPWebServer(const char* root) : mRootdir(root) {
-}
-
-cUPnPWebServer::~cUPnPWebServer(){}
-
-cUPnPWebServer* cUPnPWebServer::mInstance = NULL;
-
-UpnpVirtualDirCallbacks cUPnPWebServer::mVirtualDirCallbacks = {
- cUPnPWebServer::getInfo,
- cUPnPWebServer::open,
- cUPnPWebServer::read,
- cUPnPWebServer::write,
- cUPnPWebServer::seek,
- cUPnPWebServer::close
-};
-
-bool cUPnPWebServer::init(){
- MESSAGE(VERBOSE_WEBSERVER, "Initialize callbacks for virtual directories.");
-
- if(UpnpSetWebServerRootDir(this->mRootdir) == UPNP_E_INVALID_ARGUMENT){
- ERROR("The root directory of the webserver is invalid.");
- return false;
- }
- MESSAGE(VERBOSE_WEBSERVER, "Setting up callbacks");
-
- if(UpnpSetVirtualDirCallbacks(&cUPnPWebServer::mVirtualDirCallbacks) == UPNP_E_INVALID_ARGUMENT){
- ERROR("The virtual directory callbacks are invalid.");
- return false;
- }
-
- if(UpnpIsWebserverEnabled() == FALSE){
- WARNING("The webserver has not been started. For whatever reason...");
- return false;
- }
-
- MESSAGE(VERBOSE_WEBSERVER, "Add virtual directories.");
- if(UpnpAddVirtualDir(UPNP_DIR_SHARES) == UPNP_E_INVALID_ARGUMENT){
- ERROR("The virtual directory %s is invalid.",UPNP_DIR_SHARES);
- return false;
- }
- return true;
-}
-
-bool cUPnPWebServer::uninit(){
- MESSAGE(VERBOSE_WEBSERVER, "Disabling the internal webserver");
- UpnpEnableWebserver(FALSE);
-
- return true;
-}
-
-cUPnPWebServer* cUPnPWebServer::getInstance(const char* rootdir){
- if(cUPnPWebServer::mInstance == NULL)
- cUPnPWebServer::mInstance = new cUPnPWebServer(rootdir);
-
- if(cUPnPWebServer::mInstance){
- return cUPnPWebServer::mInstance;
- }
- else return NULL;
-}
-
-int cUPnPWebServer::getInfo(const char* filename, File_Info* info){
- MESSAGE(VERBOSE_WEBSERVER, "Getting information of file '%s'", filename);
-
- propertyMap Properties;
- int Method;
- int Section;
-
- if(cPathParser::parse(filename, &Section, &Method, &Properties)){
- switch(Section){
- case 0:
- switch(Method){
- case UPNP_WEB_METHOD_STREAM:
- {
- MESSAGE(VERBOSE_WEBSERVER, "Stream request");
- propertyMap::iterator It = Properties.find("resId");
- unsigned int ResourceID = 0;
- if(It == Properties.end()){
- ERROR("No resourceID for stream request");
- return -1;
- }
- else {
- ResourceID = (unsigned)atoi(It->second);
- cUPnPResource* Resource = cUPnPResources::getInstance()->getResource(ResourceID);
- if(!Resource){
- ERROR("No such resource with ID (%d)", ResourceID);
- return -1;
- }
- else {
- File_Info_ finfo;
-
- finfo.content_type = ixmlCloneDOMString(Resource->getContentType());
- finfo.file_length = Resource->getFileSize();
- finfo.is_directory = 0;
- finfo.is_readable = 1;
- finfo.last_modified = Resource->getLastModification();
- memcpy(info, &finfo, sizeof(File_Info_));
-
- MESSAGE(VERBOSE_METADATA, "==== File info of Resource #%d ====", Resource->getID());
- MESSAGE(VERBOSE_METADATA, "Size: %lld", finfo.file_length);
- MESSAGE(VERBOSE_METADATA, "Dir: %s", finfo.is_directory?"yes":"no");
- MESSAGE(VERBOSE_METADATA, "Read: %s", finfo.is_readable?"allowed":"not allowed");
- MESSAGE(VERBOSE_METADATA, "Last modified: %s", ctime(&(finfo.last_modified)));
- MESSAGE(VERBOSE_METADATA, "Content-type: %s", finfo.content_type);
-
-#ifdef UPNP_HAVE_CUSTOMHEADERS
- UpnpAddCustomHTTPHeader("transferMode.dlna.org: Streaming");
- UpnpAddCustomHTTPHeader(
- "contentFeatures.dlna.org: "
- "DLNA.ORG_OP=00;"
- "DLNA.ORG_CI=0;"
- "DLNA.ORG_FLAGS=01700000000000000000000000000000"
- );
-#endif
- }
- }
- }
- break;
- case UPNP_WEB_METHOD_BROWSE:
- // break;
- case UPNP_WEB_METHOD_SHOW:
- // break;
- case UPNP_WEB_METHOD_SEARCH:
- case UPNP_WEB_METHOD_DOWNLOAD:
- default:
- ERROR("Unknown or unsupported method ID (%d)", Method);
- return -1;
- }
- break;
- default:
- ERROR("Unknown or unsupported section ID (%d).", Section);
- return -1;
- }
- }
- else {
- return -1;
- }
-
- return 0;
-}
-
-UpnpWebFileHandle cUPnPWebServer::open(const char* filename, UpnpOpenFileMode mode){
- MESSAGE(VERBOSE_WEBSERVER, "File %s was opened for %s.",filename,mode==UPNP_READ ? "reading" : "writing");
-
- propertyMap Properties;
- int Method;
- int Section;
- cWebFileHandle* WebFileHandle = NULL;
-
- if(cPathParser::parse(filename, &Section, &Method, &Properties)){
- switch(Section){
- case 0:
- switch(Method){
- case UPNP_WEB_METHOD_STREAM:
- {
- MESSAGE(VERBOSE_WEBSERVER, "Stream request");
- propertyMap::iterator It = Properties.find("resId");
- unsigned int ResourceID = 0;
- if(It == Properties.end()){
- ERROR("No resourceID for stream request");
- return NULL;
- }
- else {
- ResourceID = (unsigned)atoi(It->second);
- cUPnPResource* Resource = cUPnPResources::getInstance()->getResource(ResourceID);
- if(!Resource){
- ERROR("No such resource with ID (%d)", ResourceID);
- return NULL;
- }
- else {
- WebFileHandle = new cWebFileHandle;
- WebFileHandle->Filename = Resource->getResource();
- WebFileHandle->Size = Resource->getFileSize();
- switch(Resource->getResourceType()){
- case UPNP_RESOURCE_CHANNEL:
- {
- char* ChannelID = strtok(strdup(Resource->getResource()),":");
- int StreamID = atoi(strtok(NULL,":"));
- MESSAGE(VERBOSE_LIVE_TV, "Try to create Receiver for Channel %s with Stream ID %d", ChannelID, StreamID);
- cChannel* Channel = Channels.GetByChannelID(tChannelID::FromString(ChannelID));
- if(!Channel){
- ERROR("No such channel with ID %s", ChannelID);
- return NULL;
- }
- cLiveReceiver* Receiver = cLiveReceiver::newInstance(Channel,0);
- if(!Receiver){
- ERROR("Unable to tune channel. No available tuners?");
- return NULL;
- }
- WebFileHandle->FileHandle = Receiver;
- }
- break;
- case UPNP_RESOURCE_RECORDING:
- {
- const char* RecordFile = Resource->getResource();
- MESSAGE(VERBOSE_RECORDS, "Try to create Player for Record %s", RecordFile);
- cRecording* Recording = Recordings.GetByName(RecordFile);
- if(!Recording){
- ERROR("No such recording with file name %s", RecordFile);
- return NULL;
- }
- cRecordingPlayer* RecPlayer = cRecordingPlayer::newInstance(Recording);
- if(!RecPlayer){
- ERROR("Unable to start record player. No access?!");
- return NULL;
- }
- WebFileHandle->FileHandle = RecPlayer;
- }
- break;
- case UPNP_RESOURCE_FILE:
- // break;
- case UPNP_RESOURCE_URL:
- default:
- return NULL;
- }
- }
- }
- }
- break;
- case UPNP_WEB_METHOD_BROWSE:
- // break;
- case UPNP_WEB_METHOD_SHOW:
- // break;
- case UPNP_WEB_METHOD_SEARCH:
- case UPNP_WEB_METHOD_DOWNLOAD:
- default:
- ERROR("Unknown or unsupported method ID (%d)", Method);
- return NULL;
- }
- break;
- default:
- ERROR("Unknown or unsupported section ID (%d).", Section);
- return NULL;
- }
- }
- else {
- return NULL;
- }
- MESSAGE(VERBOSE_WEBSERVER, "Open the file handle");
- WebFileHandle->FileHandle->open(mode);
- return (UpnpWebFileHandle)WebFileHandle;
-}
-
-int cUPnPWebServer::write(UpnpWebFileHandle fh, char* buf, size_t buflen){
- cWebFileHandle* FileHandle = (cWebFileHandle*)fh;
- MESSAGE(VERBOSE_BUFFERS, "Writing to %s", *FileHandle->Filename);
- return FileHandle->FileHandle->write(buf, buflen);
-}
-
-int cUPnPWebServer::read(UpnpWebFileHandle fh, char* buf, size_t buflen){
- cWebFileHandle* FileHandle = (cWebFileHandle*)fh;
- MESSAGE(VERBOSE_BUFFERS, "Reading from %s", *FileHandle->Filename);
- return FileHandle->FileHandle->read(buf, buflen);
-}
-
-int cUPnPWebServer::seek(UpnpWebFileHandle fh, off_t offset, int origin){
- cWebFileHandle* FileHandle = (cWebFileHandle*)fh;
- MESSAGE(VERBOSE_BUFFERS, "Seeking on %s", *FileHandle->Filename);
- return FileHandle->FileHandle->seek(offset, origin);
-}
-
-int cUPnPWebServer::close(UpnpWebFileHandle fh){
- cWebFileHandle *FileHandle = (cWebFileHandle *)fh;
- MESSAGE(VERBOSE_WEBSERVER, "Closing file %s", *FileHandle->Filename);
- FileHandle->FileHandle->close();
- delete FileHandle->FileHandle;
- delete FileHandle;
- return 0;
-} \ No newline at end of file