From 45e45aa3baa6043e05264b908f8f3e4fb51284c1 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Fri, 16 Nov 2007 22:38:56 +0000 Subject: [PATCH] Upgrade to protocol --- vdr.cc | 1167 ++++++++++++------------------------------ vdr.h | 108 ++-- vdrrequestpacket.cc | 124 +++++ vdrrequestpacket.h | 59 +++ vdrresponsepacket.cc | 109 ++++ vdrresponsepacket.h | 61 +++ 6 files changed, 727 insertions(+), 901 deletions(-) create mode 100644 vdrrequestpacket.cc create mode 100644 vdrrequestpacket.h create mode 100644 vdrresponsepacket.cc create mode 100644 vdrresponsepacket.h diff --git a/vdr.cc b/vdr.cc index af0be46..00aba3b 100644 --- a/vdr.cc +++ b/vdr.cc @@ -28,6 +28,8 @@ #include "channel.h" #include "event.h" #include "wol.h" +#include "vdrrequestpacket.h" +#include "vdrresponsepacket.h" VDR* VDR::instance = NULL; @@ -52,9 +54,6 @@ VDR::VDR() #else mutex=CreateMutex(NULL,FALSE,NULL); #endif - packetLength = 0; - packetPos = 0; - packet = NULL; connected = false; maxChannelNumber = 0; channelNumberWidth = 1; @@ -195,119 +194,66 @@ void VDR::setReceiveWindow(size_t size) /////////////////////////////////////////////////////// -int VDR::getPacket() +void VDR::threadMethod() { - packet = (UCHAR*)tcp->receivePacket(); - if (!packet) - { - disconnect(); - return 0; - } - packetLength = tcp->getDataLength(); - return 1; -} - -void VDR::freePacket() -{ - // Must be called if getPacket return 1, except in getBlock - packetLength = 0; - packetPos = 0; - free(packet); - packet = NULL; -} - -int VDR::serverError() -{ - if ((packetPos == 0) && (packetLength == 4) && !ntohl(*(ULONG*)packet)) return 1; - else return 0; } -char* VDR::extractString() +VDR_ResponsePacket* VDR::RequestResponse(VDR_RequestPacket* vrp) { - if (serverError()) return NULL; - - int length = strlen((char*)&packet[packetPos]); - if ((packetPos + length) > packetLength) return NULL; - char* str = new char[length + 1]; - strcpy(str, (char*)&packet[packetPos]); - packetPos += length + 1; - return str; -} - -UCHAR VDR::extractUCHAR() -{ - if ((packetPos + sizeof(UCHAR)) > packetLength) return 0; - UCHAR uc = packet[packetPos]; - packetPos += sizeof(UCHAR); - return uc; -} - -ULONG VDR::extractULONG() -{ - if ((packetPos + sizeof(ULONG)) > packetLength) return 0; - ULONG ul = ntohl(*(ULONG*)&packet[packetPos]); - packetPos += sizeof(ULONG); - return ul; -} - -ULLONG VDR::extractULLONG() -{ - if ((packetPos + sizeof(ULLONG)) > packetLength) return 0; - ULLONG ull = ntohll(*(ULLONG*)&packet[packetPos]); - packetPos += sizeof(ULLONG); - return ull; -} - -long VDR::extractLONG() -{ - if ((packetPos + sizeof(long)) > packetLength) return 0; - long l = ntohl(*(long*)&packet[packetPos]); - packetPos += sizeof(long); - return l; -} - -///////////////////////////////////////////////////////////////////////////// - -int VDR::doLogin() -{ - UCHAR buffer[14]; - - *(unsigned long*)&buffer[0] = htonl(10); - *(unsigned long*)&buffer[4] = htonl(VDR_LOGIN); - - tcp->getMAC((char*)&buffer[8]); - - + logger->log("VDR", Log::DEBUG, "RR"); MUTEX_LOCK(&mutex); + if (!connected) { MUTEX_UNLOCK(&mutex); - return 0; + return NULL; } - int a = tcp->sendPacket(buffer, 14); - if (a != 14) + waitingRequestThread = Thread_TYPE::thisThreadID(); + if ((ULONG)tcp->sendPacket(vrp->getPtr(), vrp->getLen()) != vrp->getLen()) { disconnect(); MUTEX_UNLOCK(&mutex); - return 0; + return NULL; } - // reply - - if (!getPacket()) + UCHAR* packet = (UCHAR*)tcp->receivePacket(); + if (!packet) { + disconnect(); MUTEX_UNLOCK(&mutex); - return 0; + return NULL; } + ULONG packetLength = (ULONG)tcp->getDataLength(); + + MUTEX_UNLOCK(&mutex); + + VDR_ResponsePacket* vresp = new VDR_ResponsePacket(); + vresp->set(packet, packetLength); + + return vresp; +} + +///////////////////////////////////////////////////////////////////////////// + +int VDR::doLogin() +{ + VDR_RequestPacket vrp; + if (!vrp.init(VDR_LOGIN, true, 6)) return 0; - ULONG vdrTime = extractULONG(); + char* mactemp[6]; + tcp->getMAC((char*)mactemp); + if (!vrp.copyin((UCHAR*)mactemp, 6)) return 0; + + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + ULONG vdrTime = vresp->extractULONG(); logger->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime); - long vdrTimeOffset = extractLONG(); + long vdrTimeOffset = vresp->extractLONG(); logger->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset); - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; // Set the time and zone on the MVP @@ -349,48 +295,26 @@ int VDR::doLogin() bool VDR::getRecordingsList(RecMan* recman) { - UCHAR buffer[8]; - - *(unsigned long*)&buffer[0] = htonl(4); - *(unsigned long*)&buffer[4] = htonl(VDR_GETRECORDINGLIST); + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETRECORDINGLIST, true, 0)) return false; - MUTEX_LOCK(&mutex); - if (!connected) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - int a = tcp->sendPacket(buffer, 8); - if (a != 8) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return false; - } - - // reply - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return false; - } - - ULONG totalSpace = extractULONG(); - ULONG freeSpace = extractULONG(); - ULONG percent = extractULONG(); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return false; + + ULONG totalSpace = vresp->extractULONG(); + ULONG freeSpace = vresp->extractULONG(); + ULONG percent = vresp->extractULONG(); recman->setStats(totalSpace, freeSpace, percent); ULONG start; char* name; char* fileName; - while (packetPos < packetLength) + while (!vresp->end()) { - start = extractULONG(); - name = extractString(); - fileName = extractString(); + start = vresp->extractULONG(); + name = vresp->extractString(); + fileName = vresp->extractString(); recman->addEntry(start, name, fileName); @@ -398,123 +322,64 @@ bool VDR::getRecordingsList(RecMan* recman) delete[] fileName; } - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; return true; } int VDR::deleteRecording(char* fileName) { - unsigned long totalLength = 8 + strlen(fileName) + 1; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING); - strcpy((char*)&buffer[8], fileName); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - int toReturn = (int)extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_RequestPacket vrp; + if (!vrp.init(VDR_DELETERECORDING, true, strlen(fileName) + 1)) return 0; + if (!vrp.addString(fileName)) return 0; + + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + int toReturn = (int)vresp->extractULONG(); + delete vresp; return toReturn; } char* VDR::moveRecording(char* fileName, char* newPath) { - unsigned long totalLength = 8 + strlen(fileName) + 1 + strlen(newPath) + 1; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_MOVERECORDING); - strcpy((char*)&buffer[8], fileName); - strcpy((char*)&buffer[8 + strlen(fileName) + 1], newPath); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - + VDR_RequestPacket vrp; + if (!vrp.init(VDR_MOVERECORDING, true, strlen(fileName) + 1 + strlen(newPath) + 1)) return NULL; + if (!vrp.addString(fileName)) return NULL; + if (!vrp.addString(newPath)) return NULL; + + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; + char* toReturn = NULL; - int success = (int)extractULONG(); + int success = (int)vresp->extractULONG(); if (success == 1) { - toReturn = extractString(); + toReturn = vresp->extractString(); } - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; return toReturn; } ChannelList* VDR::getChannelsList(ULONG type) { - UCHAR buffer[8]; - - *(unsigned long*)&buffer[0] = htonl(4); - *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - int a = tcp->sendPacket(buffer, 8); - if (a != 8) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return NULL; - } - - // reply - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return NULL; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETCHANNELLIST, true, 0)) return NULL; + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; + ChannelList* chanList = new ChannelList(); - while (packetPos < packetLength) + while (!vresp->end()) { Channel* chan = new Channel(); - chan->number = extractULONG(); - chan->type = extractULONG(); - chan->name = extractString(); + chan->number = vresp->extractULONG(); + chan->type = vresp->extractULONG(); + chan->name = vresp->extractString(); if (chan->type == type) { @@ -528,8 +393,7 @@ ChannelList* VDR::getChannelsList(ULONG type) } } - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; if (maxChannelNumber > 99999) channelNumberWidth = 6; @@ -549,65 +413,29 @@ ChannelList* VDR::getChannelsList(ULONG type) int VDR::streamChannel(ULONG number) { - UCHAR buffer[12]; - - *(unsigned long*)&buffer[0] = htonl(8); - *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL); - *(unsigned long*)&buffer[8] = htonl(number); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - int a = tcp->sendPacket(buffer, 12); - - if (a != 12) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - int toReturn = (int)extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_RequestPacket vrp; + if (!vrp.init(VDR_STREAMCHANNEL, true, sizeof(ULONG))) return 0; + if (!vrp.addULONG(number)) return 0; + + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + int toReturn = (int)vresp->extractULONG(); + delete vresp; return toReturn; } int VDR::stopStreaming() { - UCHAR buffer[8]; - - *(unsigned long*)&buffer[0] = htonl(4); - *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - int a = tcp->sendPacket(buffer, 8); - - if (a != 8) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_STOPSTREAMING, true, 0)) return 0; - int toReturn = (int)extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + int toReturn = (int)vresp->extractULONG(); + delete vresp; return toReturn; } @@ -624,82 +452,42 @@ UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived) UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived, ULONG cmd) { - UCHAR buffer[20]; + VDR_RequestPacket vrp; + if (!vrp.init(cmd, true, sizeof(ULLONG) + sizeof(ULONG))) return NULL; + if (!vrp.addULLONG(position)) return NULL; + if (!vrp.addULONG(maxAmount)) return NULL; - *(unsigned long*)&buffer[0] = htonl(16); - *(unsigned long*)&buffer[4] = htonl(cmd); - *(ULLONG*)&buffer[8] = htonll(position); - *(unsigned long*)&buffer[16] = htonl(maxAmount); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - int a = tcp->sendPacket(buffer, 20); - if (a != 20) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return NULL; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return NULL; - } + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; - if (serverError()) + if (vresp->serverError()) { Log::getInstance()->log("VDR", Log::DEBUG, "Detected getblock 0"); - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; return NULL; } - UCHAR* toReturn = packet; - *amountReceived = packetLength; - // Manually clean up instead of running freePacket to keep the block - packet = NULL; - packetLength = 0; - packetPos = 0; - MUTEX_UNLOCK(&mutex); - - + // Special handling for getblock + UCHAR* toReturn = vresp->getBlock_getPacket(); + *amountReceived = vresp->getLength(); + + delete vresp; + return toReturn; } ULLONG VDR::streamRecording(char* fileName, ULONG* totalFrames) { - unsigned long totalLength = 8 + strlen(fileName) + 1; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING); - strcpy((char*)&buffer[8], fileName); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_STREAMRECORDING, true, strlen(fileName) + 1)) return 0; + if (!vrp.addString(fileName)) return 0; - ULLONG lengthBytes = extractULLONG(); - ULONG lengthFrames = extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + ULLONG lengthBytes = vresp->extractULLONG(); + ULONG lengthFrames = vresp->extractULONG(); + delete vresp; Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu %lu", lengthBytes, lengthFrames); @@ -709,36 +497,16 @@ ULLONG VDR::streamRecording(char* fileName, ULONG* totalFrames) ULLONG VDR::positionFromFrameNumber(ULONG frameNumber) { - unsigned long totalLength = 12; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_POSFROMFRAME); - *(unsigned long*)&buffer[8] = htonl(frameNumber); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - ULLONG position = extractULLONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_RequestPacket vrp; + if (!vrp.init(VDR_POSFROMFRAME, true, sizeof(ULONG))) return 0; + if (!vrp.addULONG(frameNumber)) return 0; + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + ULLONG position = vresp->extractULLONG(); + delete vresp; + Log::getInstance()->log("VDR", Log::DEBUG, "VDR said new position is: %llu", position); return position; @@ -746,36 +514,16 @@ ULLONG VDR::positionFromFrameNumber(ULONG frameNumber) ULONG VDR::frameNumberFromPosition(ULLONG position) { - unsigned long totalLength = 16; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_FRAMEFROMPOS); - *(ULLONG*)&buffer[8] = htonll(position); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - ULONG framenumber = extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_RequestPacket vrp; + if (!vrp.init(VDR_FRAMEFROMPOS, true, sizeof(ULLONG))) return 0; + if (!vrp.addULLONG(position)) return 0; + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + ULONG framenumber = vresp->extractULONG(); + delete vresp; + Log::getInstance()->log("VDR", Log::DEBUG, "VDR said new framenumber is: %u", framenumber); return framenumber; @@ -783,47 +531,26 @@ ULONG VDR::frameNumberFromPosition(ULLONG position) bool VDR::getNextIFrame(ULONG frameNumber, ULONG direction, ULLONG* rfilePosition, ULONG* rframeNumber, ULONG* rframeLength) { - unsigned long totalLength = 16; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_GETNEXTIFRAME); - *(unsigned long*)&buffer[8] = htonl(frameNumber); - *(unsigned long*)&buffer[12] = htonl(direction); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return false; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return false; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return false; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETNEXTIFRAME, true, sizeof(ULONG)*2)) return false; + if (!vrp.addULONG(frameNumber)) return false; + if (!vrp.addULONG(direction)) return false; - if (serverError()) + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return false; + + if (vresp->serverError()) { Log::getInstance()->log("VDR", Log::DEBUG, "Detected getNextIFrame error"); - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; return false; } - *rfilePosition = extractULLONG(); - *rframeNumber = extractULONG(); - *rframeLength = extractULONG(); + *rfilePosition = vresp->extractULLONG(); + *rframeNumber = vresp->extractULONG(); + *rframeLength = vresp->extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; // Log::getInstance()->log("VDR", Log::DEBUG, "VDR GNIF said %llu %lu %lu", *rfilePosition, *rframeNumber, *rframeLength); @@ -840,56 +567,38 @@ EventList* VDR::getChannelSchedule(ULONG number) EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration) { // retrieve event list (vector of events) from vdr within filter window. duration is in seconds - UCHAR buffer[20]; - - *(unsigned long*)&buffer[0] = htonl(16); - *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE); - *(unsigned long*)&buffer[8] = htonl(number); - *(unsigned long*)&buffer[12] = htonl(start); - *(unsigned long*)&buffer[16] = htonl(duration); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - int a = tcp->sendPacket(buffer, 20); - - if (a != 20) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return NULL; - } - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return NULL; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETCHANNELSCHEDULE, true, sizeof(ULONG)*3)) return NULL; + if (!vrp.addULONG(number)) return NULL; + if (!vrp.addULONG(start)) return NULL; + if (!vrp.addULONG(duration)) return NULL; + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; + // received a ulong(0) - schedules error in the plugin - if (serverError()) + if (vresp->serverError()) { - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; return NULL; } EventList* eventList = new EventList(); - while (packetPos < packetLength) + while (!vresp->end()) { Event* event = new Event(); - event->id = extractULONG(); - event->time = extractULONG(); - event->duration = extractULONG(); - event->title = extractString(); - event->subtitle = extractString(); - event->description = extractString(); + event->id = vresp->extractULONG(); + event->time = vresp->extractULONG(); + event->duration = vresp->extractULONG(); + event->title = vresp->extractString(); + event->subtitle = vresp->extractString(); + event->description = vresp->extractString(); eventList->push_back(event); } - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule"); return eventList; @@ -897,132 +606,68 @@ EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration) int VDR::configSave(const char* section, const char* key, const char* value) { - ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE); - - int position = 8; - strcpy((char*)&buffer[position], section); - position += strlen(section) + 1; - strcpy((char*)&buffer[position], key); - position += strlen(key) + 1; - strcpy((char*)&buffer[position], value); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete[] buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_CONFIGSAVE, false, 0)) return 0; + if (!vrp.addString(section)) return 0; + if (!vrp.addString(key)) return 0; + if (!vrp.addString(value)) return 0; - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - int toReturn = (int)extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + int toReturn = (int)vresp->extractULONG(); + delete vresp; return toReturn; } char* VDR::configLoad(const char* section, const char* key) { - ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD); - - int position = 8; - strcpy((char*)&buffer[position], section); - position += strlen(section) + 1; - strcpy((char*)&buffer[position], key); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_CONFIGLOAD, false, 0)) return NULL; + if (!vrp.addString(section)) return NULL; + if (!vrp.addString(key)) return NULL; - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete[] buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return NULL; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return NULL; - } - char* toReturn = extractString(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; + + char* toReturn = vresp->extractString(); + delete vresp; return toReturn; } RecTimerList* VDR::getRecTimersList() { - UCHAR buffer[8]; - - *(unsigned long*)&buffer[0] = htonl(4); - *(unsigned long*)&buffer[4] = htonl(VDR_GETTIMERS); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - int a = tcp->sendPacket(buffer, 8); - if (a != 8) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return NULL; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETTIMERS, true, 0)) return NULL; - // reply - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return NULL; - } + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; RecTimerList* recTimerList = new RecTimerList(); - ULONG numTimers = extractULONG(); + ULONG numTimers = vresp->extractULONG(); if (numTimers > 0) { RecTimer* newRecTimer; char* tempString; - while (packetPos < packetLength) + while (!vresp->end()) { newRecTimer = new RecTimer(); - newRecTimer->active = extractULONG(); - newRecTimer->recording = extractULONG(); - newRecTimer->pending = extractULONG(); - newRecTimer->priority = extractULONG(); - newRecTimer->lifeTime = extractULONG(); - newRecTimer->channelNumber = extractULONG(); - newRecTimer->startTime = extractULONG(); - newRecTimer->stopTime = extractULONG(); - newRecTimer->day = extractULONG(); - newRecTimer->weekDays = extractULONG(); - - tempString = extractString(); + newRecTimer->active = vresp->extractULONG(); + newRecTimer->recording = vresp->extractULONG(); + newRecTimer->pending = vresp->extractULONG(); + newRecTimer->priority = vresp->extractULONG(); + newRecTimer->lifeTime = vresp->extractULONG(); + newRecTimer->channelNumber = vresp->extractULONG(); + newRecTimer->startTime = vresp->extractULONG(); + newRecTimer->stopTime = vresp->extractULONG(); + newRecTimer->day = vresp->extractULONG(); + newRecTimer->weekDays = vresp->extractULONG(); + + tempString = vresp->extractString(); newRecTimer->setFile(tempString); delete[] tempString; @@ -1033,8 +678,7 @@ RecTimerList* VDR::getRecTimersList() } } - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; sort(recTimerList->begin(), recTimerList->end(), RecTimerSorter()); @@ -1043,137 +687,74 @@ RecTimerList* VDR::getRecTimersList() ULONG VDR::setEventTimer(char* timerString) { - unsigned long totalLength = 8 + strlen(timerString) + 1; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_SETTIMER); - strcpy((char*)&buffer[8], timerString); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_SETTIMER, true, strlen(timerString) + 1)) return 0; + if (!vrp.addString(timerString)) return 0; - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - ULONG toReturn = extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + ULONG toReturn = vresp->extractULONG(); + delete vresp; return toReturn; } RecInfo* VDR::getRecInfo(char* fileName) { - unsigned long totalLength = 8 + strlen(fileName) + 1; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_GETRECINFO); - strcpy((char*)&buffer[8], fileName); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return NULL; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return NULL; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return NULL; - } - - if (serverError()) + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETRECINFO, true, strlen(fileName) + 1)) return NULL; + if (!vrp.addString(fileName)) return NULL; + + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; + + if (vresp->serverError()) { Log::getInstance()->log("VDR", Log::DEBUG, "Could not get rec info"); - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; return NULL; } - TCP::dump(packet, packetLength); - RecInfo* recInfo = new RecInfo(); - recInfo->timerStart = extractULONG(); - recInfo->timerEnd = extractULONG(); - recInfo->resumePoint = extractULONG(); - recInfo->summary = extractString(); + recInfo->timerStart = vresp->extractULONG(); + recInfo->timerEnd = vresp->extractULONG(); + recInfo->resumePoint = vresp->extractULONG(); + recInfo->summary = vresp->extractString(); - ULONG numComponents = extractULONG(); + ULONG numComponents = vresp->extractULONG(); if (numComponents) { recInfo->setNumComponents(numComponents); for (ULONG i = 0; i < numComponents; i++) { - recInfo->streams[i] = extractUCHAR(); - recInfo->types[i] = extractUCHAR(); - recInfo->languages[i] = extractString(); - recInfo->descriptions[i] = extractString(); + recInfo->streams[i] = vresp->extractUCHAR(); + recInfo->types[i] = vresp->extractUCHAR(); + recInfo->languages[i] = vresp->extractString(); + recInfo->descriptions[i] = vresp->extractString(); } } recInfo->print(); - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; return recInfo; } // FIXME obselete ULLONG VDR::rescanRecording(ULONG* totalFrames) { - unsigned long totalLength = 8; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_RESCANRECORDING); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - ULLONG lengthBytes = extractULLONG(); - ULONG lengthFrames = extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_RequestPacket vrp; + if (!vrp.init(VDR_RESCANRECORDING, true, 0)) return 0; + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + ULLONG lengthBytes = vresp->extractULLONG(); + ULONG lengthFrames = vresp->extractULONG(); + delete vresp; + Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu %lu", lengthBytes, lengthFrames); *totalFrames = lengthFrames; @@ -1182,81 +763,44 @@ ULLONG VDR::rescanRecording(ULONG* totalFrames) MarkList* VDR::getMarks(char* fileName) { - unsigned long totalLength = 8 + strlen(fileName) + 1; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_GETMARKS); - strcpy((char*)&buffer[8], fileName); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return NULL; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETMARKS, true, strlen(fileName) + 1)) return NULL; + if (!vrp.addString(fileName)) return NULL; - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return NULL; - } - - if (serverError()) + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; + + if (vresp->serverError()) { - MUTEX_UNLOCK(&mutex); + delete vresp; return NULL; } MarkList* markList = new MarkList(); - while (packetPos < packetLength) + while (!vresp->end()) { Mark* mark = new Mark(); - mark->pos = extractULONG(); + mark->pos = vresp->extractULONG(); markList->push_back(mark); Log::getInstance()->log("VDR", Log::DEBUG, "Have added a mark to list. %lu", mark->pos); } - freePacket(); - MUTEX_UNLOCK(&mutex); - + delete vresp; + return markList; } void VDR::getChannelPids(Channel* channel) { - UCHAR buffer[12]; - - *(unsigned long*)&buffer[0] = htonl(8); - *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELPIDS); - *(unsigned long*)&buffer[8] = htonl(channel->number); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return ; } - - int a = tcp->sendPacket(buffer, 12); - - if (a != 12) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return ; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return ; - } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETCHANNELPIDS, true, sizeof(ULONG))) return ; + if (!vrp.addULONG(channel->number)) return ; + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return ; + // Format of response // vpid // number of apids @@ -1265,27 +809,24 @@ void VDR::getChannelPids(Channel* channel) // lang string // } - channel->vpid = extractULONG(); - channel->numAPids = extractULONG(); + channel->vpid = vresp->extractULONG(); + channel->numAPids = vresp->extractULONG(); for (ULONG i = 0; i < channel->numAPids; i++) { apid newapid; - newapid.pid = extractULONG(); - newapid.name = extractString(); + newapid.pid = vresp->extractULONG(); + newapid.name = vresp->extractString(); channel->apids.push_back(newapid); } - freePacket(); - MUTEX_UNLOCK(&mutex); - + delete vresp; + return ; } /** * media List Request: - * 4 length - * 4 VDR_GETMEDIALIST * 4 flags (currently unused) * n dirname * n+1 0 @@ -1303,71 +844,52 @@ void VDR::getChannelPids(Channel* channel) */ MediaList* VDR::getMediaList(const char* parent,int mediaType) { - Log::getInstance()->log("VDR", Log::DEBUG, "getMediaList %s,type=%d", - (parent?parent:"NULL"), mediaType); - unsigned long totalLength = 12; - if (parent) totalLength+=strlen(parent) + 1; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_GETMEDIALIST); - //unused flags - for (int i=8;i<12;i++) buffer[i]=0; - //name - if (parent) { - strcpy((char*)&buffer[12], parent); - buffer[totalLength-1]=0; - } - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } + Log::getInstance()->log("VDR", Log::DEBUG, "getMediaList %s,type=%d", (parent?parent:"NULL"), mediaType); - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETMEDIALIST, false, 0)) return NULL; + if (!vrp.addULONG(0)) return NULL; // unused flags - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return NULL; + //name + if (parent) { + if (!vrp.addString(parent)) return NULL; } - - if (!getPacket()) + + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return NULL; + + if (vresp->serverError()) { - MUTEX_UNLOCK(&mutex); + delete vresp; return NULL; } - - if (serverError()) + + if (vresp->getLength() < 12) { - MUTEX_UNLOCK(&mutex); + Log::getInstance()->log("VDR", Log::ERR, "receiveMediaList packet too short, expected 12, got %d", vresp->getLength()); + delete vresp; return NULL; } - if (packetLength < 12) { - Log::getInstance()->log("VDR", Log::ERR, "receiveMediaList packet too short, expected 12, got %d", packetLength); - freePacket(); - MUTEX_UNLOCK(&mutex); - return NULL; - } + MediaList* mediaList = new MediaList(); ULONG code=0; - code=extractULONG(); - ULONG numEntries=extractULONG(); + code = vresp->extractULONG(); + ULONG numEntries = vresp->extractULONG(); Log::getInstance()->log("VDR", Log::DEBUG, "receiveMediaList with %d entries",numEntries); - while (packetPos < packetLength && numEntries >0) + while (!vresp->end() && numEntries >0) { Media* m = new Media(); - ULONG mtype = extractULONG(); - ULONG mtime=extractULONG(); + ULONG mtype = vresp->extractULONG(); + ULONG mtime=vresp->extractULONG(); ULONG flags=0; - flags=extractULONG(); - ULONG stsize=extractULONG(); - char * name=extractString(); + flags=vresp->extractULONG(); + ULONG stsize=vresp->extractULONG(); + char * name=vresp->extractString(); if (! name || stsize != (strlen(name)+1)) { Log::getInstance()->log("VDR", Log::ERR, "receiveMediaList invalid packet entry, read size %d, strlen %d", stsize, strlen(name)+1); delete m; delete mediaList; - freePacket(); - MUTEX_UNLOCK(&mutex); + delete vresp; return NULL; } //ignore . and .. entries @@ -1383,15 +905,12 @@ MediaList* VDR::getMediaList(const char* parent,int mediaType) numEntries--; } - freePacket(); - MUTEX_UNLOCK(&mutex); - + delete vresp; return mediaList; } + /** * get image Request: - * 4 length - * 4 VDR_GETIMAGE * 4 flags (currently unused) * 4 x size * 4 y size @@ -1404,42 +923,21 @@ MediaList* VDR::getMediaList(const char* parent,int mediaType) */ ULONG VDR::loadImage(const char* fileName, ULONG x, ULONG y) { - unsigned long totalLength = 20 + strlen(fileName) + 1; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_GETIMAGE); - *(unsigned long*)&buffer[8] = htonl(0); - *(unsigned long*)&buffer[8] = htonl(x); - *(unsigned long*)&buffer[8] = htonl(y); - strcpy((char*)&buffer[12], fileName); - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETIMAGE, false, 0)) return 0; + if (!vrp.addULONG(0)) return 0; // unused flags + if (!vrp.addULONG(x)) return 0; + if (!vrp.addULONG(y)) return 0; + if (!vrp.addString(fileName)) return 0; - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - ULONG cmd=0; - cmd=extractULONG(); - ULONG lengthBytes = extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); - - Log::getInstance()->log("VDR", Log::DEBUG, "getImage %s: %lu", fileName,lengthBytes); + ULONG cmd = vresp->extractULONG(); + ULONG lengthBytes = vresp->extractULONG(); + delete vresp; + Log::getInstance()->log("VDR", Log::DEBUG, "getImage %s: cmd=%lu len=%lu", fileName, cmd, lengthBytes); return lengthBytes; } @@ -1447,40 +945,19 @@ int VDR::deleteTimer(RecTimer* delTimer) { Log::getInstance()->log("VDR", Log::DEBUG, "Delete timer called"); - unsigned long totalLength = 28; - UCHAR* buffer = new UCHAR[totalLength]; - - *(unsigned long*)&buffer[0] = htonl(totalLength - 4); - *(unsigned long*)&buffer[4] = htonl(VDR_DELETETIMER); - *(unsigned long*)&buffer[8] = htonl(delTimer->channelNumber); - *(unsigned long*)&buffer[12] = htonl(delTimer->weekDays); - *(unsigned long*)&buffer[16] = htonl(delTimer->day); - *(unsigned long*)&buffer[20] = htonl(delTimer->startTime); - *(unsigned long*)&buffer[24] = htonl(delTimer->stopTime); + VDR_RequestPacket vrp; + if (!vrp.init(VDR_DELETETIMER, false, 0)) return 0; + if (!vrp.addULONG(delTimer->channelNumber)) return 0; + if (!vrp.addULONG(delTimer->weekDays)) return 0; + if (!vrp.addULONG(delTimer->day)) return 0; + if (!vrp.addULONG(delTimer->startTime)) return 0; + if (!vrp.addULONG(delTimer->stopTime)) return 0; - - MUTEX_LOCK(&mutex); - if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } - - unsigned int a = tcp->sendPacket(buffer, totalLength); - delete []buffer; - - if (a != totalLength) - { - disconnect(); - MUTEX_UNLOCK(&mutex); - return 0; - } - - if (!getPacket()) - { - MUTEX_UNLOCK(&mutex); - return 0; - } - - int toReturn = (int)extractULONG(); - freePacket(); - MUTEX_UNLOCK(&mutex); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + if (!vresp) return 0; + + int toReturn = (int)vresp->extractULONG(); + delete vresp; return toReturn; } diff --git a/vdr.h b/vdr.h index 97513a1..6fcfe88 100644 --- a/vdr.h +++ b/vdr.h @@ -23,14 +23,14 @@ #include #include -#ifndef WIN32 - #include -#else - //Find threading replacements -#endif #include #include +#ifdef WIN32 +#include "threadwin.h" +#else +#include "threadp.h" +#endif #include "defines.h" #include "rectimer.h" #include "mark.h" @@ -41,6 +41,8 @@ class Log; class RecInfo; class Event; class Channel; +class VDR_RequestPacket; +class VDR_ResponsePacket; using namespace std; @@ -77,6 +79,9 @@ class VDR { public: + const static ULONG VIDEO = 1; + const static ULONG RADIO = 2; + VDR(); ~VDR(); static VDR* getInstance(); @@ -87,13 +92,12 @@ class VDR void findServers(vector& servers); void cancelFindingServer(); void setServerIP(char*); + void setReceiveWindow(size_t size); int connect(); void disconnect(); bool isConnected() { return connected; } ULONG getChannelNumberWidth() { return channelNumberWidth; } - void setReceiveWindow(size_t size); - // protocol functions // for the following, if result == false then the connection has died // doLogin @@ -112,52 +116,43 @@ class VDR // configSave // setEventTimer - int doLogin(); - - bool getRecordingsList(RecMan* recman); - RecInfo* getRecInfo(char* fileName); - int deleteRecording(char* fileName); - char* moveRecording(char* fileName, char* newPath); - ULLONG streamRecording(char* fileName, ULONG* lengthFrames); - ULLONG positionFromFrameNumber(ULONG frameNumber); - ULONG frameNumberFromPosition(ULLONG position); - bool getNextIFrame(ULONG frameNumber, ULONG direction, ULLONG* rfilePosition, ULONG* rframeNumber, ULONG* rframeLength); - // Direction: 0=backwards, 1=forwards - MarkList* getMarks(char* fileName); - int deleteTimer(RecTimer* delTimer); - - ChannelList* getChannelsList(ULONG type); - int streamChannel(ULONG number); - void getChannelPids(Channel* channel); - - UCHAR* getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived); - //get image blocks separate - we can do this in parallel - UCHAR* getImageBlock(ULONG position, UINT maxAmount, UINT* amountReceived); - int stopStreaming(); - EventList* getChannelSchedule(ULONG number); - EventList* getChannelSchedule(ULONG number, time_t start, ULONG duration); - int configSave(const char* section, const char* key, const char* value); - char* configLoad(const char* section, const char* key); - ULONG setEventTimer(char* timerString); - + int doLogin(); + bool getRecordingsList(RecMan* recman); + RecInfo* getRecInfo(char* fileName); + int deleteRecording(char* fileName); + char* moveRecording(char* fileName, char* newPath); + ULLONG streamRecording(char* fileName, ULONG* lengthFrames); + ULLONG positionFromFrameNumber(ULONG frameNumber); + ULONG frameNumberFromPosition(ULLONG position); + bool getNextIFrame(ULONG frameNumber, ULONG direction, ULLONG* rfilePosition, ULONG* rframeNumber, ULONG* rframeLength); + // Direction: 0=backwards, 1=forwards + MarkList* getMarks(char* fileName); + int deleteTimer(RecTimer* delTimer); + ChannelList* getChannelsList(ULONG type); + int streamChannel(ULONG number); + void getChannelPids(Channel* channel); + UCHAR* getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived); + //get image blocks separate - we can do this in parallel + UCHAR* getImageBlock(ULONG position, UINT maxAmount, UINT* amountReceived); + int stopStreaming(); + EventList* getChannelSchedule(ULONG number); + EventList* getChannelSchedule(ULONG number, time_t start, ULONG duration); + int configSave(const char* section, const char* key, const char* value); + char* configLoad(const char* section, const char* key); + ULONG setEventTimer(char* timerString); RecTimerList* getRecTimersList(); /** * ge a list of media entries * if parent==NULL this is the configured base list */ - MediaList* getMediaList(const char* parent=NULL,int mediaType=MEDIA_TYPE_ALL); + MediaList* getMediaList(const char* parent=NULL,int mediaType=MEDIA_TYPE_ALL); /** * start loading a JPEG image * return size, 0 if not found */ - ULONG loadImage(const char * filename, ULONG xsize=0,ULONG ysize=0); - - // end - - const static ULONG VIDEO = 1; - const static ULONG RADIO = 2; - + ULONG loadImage(const char * filename, ULONG xsize=0,ULONG ysize=0); + // end protocol functions // obselete @@ -166,8 +161,11 @@ class VDR private: - UCHAR* getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived, ULONG cmd); static VDR* instance; + + VDR_ResponsePacket* RequestResponse(VDR_RequestPacket* request); + UCHAR* getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived, ULONG cmd); + Log* logger; int initted; int findingServer; @@ -175,7 +173,6 @@ class VDR int port; char serverIP[16]; bool connected; - ULONG maxChannelNumber; ULONG channelNumberWidth; @@ -185,9 +182,13 @@ class VDR HANDLE mutex; #endif - UCHAR* packet; - ULONG packetLength; - ULONG packetPos; + +#ifndef WIN32 + // KIS for now + pthread_t waitingRequestThread; +#else + // FIXME - Marten +#endif const static ULONG VDR_LOGIN = 1; const static ULONG VDR_GETRECORDINGLIST = 2; @@ -214,14 +215,9 @@ class VDR const static ULONG VDR_GETMEDIALIST = 30; const static ULONG VDR_GETIMAGE = 31; const static ULONG VDR_GETIMAGEBLOCK = 32; - int getPacket(); - void freePacket(); - int serverError(); - char* extractString(); - UCHAR extractUCHAR(); - ULONG extractULONG(); - ULLONG extractULLONG(); - long extractLONG(); + + protected: + void threadMethod(); }; #endif diff --git a/vdrrequestpacket.cc b/vdrrequestpacket.cc new file mode 100644 index 0000000..125b756 --- /dev/null +++ b/vdrrequestpacket.cc @@ -0,0 +1,124 @@ +/* + Copyright 2007 Chris Tallon + + This file is part of VOMP. + + VOMP 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. + + VOMP 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 VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include "vdrrequestpacket.h" + +#include "vdr.h" + +/* Packet format for an RR channel request: + +4 bytes = channel ID = 1 (request/response channel) +4 bytes = request ID (from serialNumber) +4 bytes = opcode +4 bytes = length of the rest of the packet +? bytes = rest of packet. depends on packet +*/ + +ULONG VDR_RequestPacket::serialNumber = 1; + +VDR_RequestPacket::VDR_RequestPacket() +{ + buffer = NULL; + bufSize = 0; + bufUsed = 0; + lengthSet = false; +} + +VDR_RequestPacket::~VDR_RequestPacket() +{ + free(buffer); +} + +bool VDR_RequestPacket::init(ULONG opcode, bool setUserDataLength, ULONG userDataLength) +{ + if (buffer) return false; + + if (setUserDataLength) + { + bufSize = headerLength + userDataLength; + lengthSet = true; + } + else + { + bufSize = 512; + userDataLength = 0; // so the below will write a zero + } + + buffer = (UCHAR*)malloc(bufSize); + if (!buffer) return false; + *(ULONG*)&buffer[0] = htonl(1); + *(ULONG*)&buffer[4] = htonl(serialNumber++); + *(ULONG*)&buffer[8] = htonl(opcode); + *(ULONG*)&buffer[12] = htonl(userDataLength); + bufUsed = headerLength; + + return true; +} + +bool VDR_RequestPacket::copyin(const UCHAR* src, ULONG len) +{ + if (!checkExtend(len)) return false; + memcpy(buffer + bufUsed, src, len); + bufUsed += len; + if (!lengthSet) *(ULONG*)&buffer[12] = htonl(bufUsed - headerLength); + return true; +} + +bool VDR_RequestPacket::addString(const char* string) +{ + ULONG len = strlen(string) + 1; + if (!checkExtend(len)) return false; + memcpy(buffer + bufUsed, string, len); + bufUsed += len; + if (!lengthSet) *(ULONG*)&buffer[12] = htonl(bufUsed - headerLength); + return true; +} + +bool VDR_RequestPacket::addULONG(ULONG ul) +{ + if (!checkExtend(sizeof(ULONG))) return false; + *(ULONG*)&buffer[bufUsed] = htonl(ul); + bufUsed += sizeof(ULONG); + if (!lengthSet) *(ULONG*)&buffer[12] = htonl(bufUsed - headerLength); + return true; +} + +bool VDR_RequestPacket::addULLONG(ULLONG ull) +{ + if (!checkExtend(sizeof(ULLONG))) return false; + *(ULLONG*)&buffer[bufUsed] = htonll(ull); + bufUsed += sizeof(ULLONG); + if (!lengthSet) *(ULONG*)&buffer[12] = htonl(bufUsed - headerLength); + return true; +} + +bool VDR_RequestPacket::checkExtend(ULONG by) +{ + if (lengthSet) return true; + if ((bufUsed + by) < bufSize) return true; + UCHAR* newBuf = (UCHAR*)realloc(buffer, bufSize + 512); + if (!newBuf) return false; + buffer = newBuf; + bufSize += 512; + return true; +} + diff --git a/vdrrequestpacket.h b/vdrrequestpacket.h new file mode 100644 index 0000000..52d2d06 --- /dev/null +++ b/vdrrequestpacket.h @@ -0,0 +1,59 @@ +/* + Copyright 2007 Chris Tallon + + This file is part of VOMP. + + VOMP 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. + + VOMP 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 VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef VDRREQUESTPACKET_H +#define VDRREQUESTPACKET_H + +#include +#include +#include + +#include "defines.h" + +class VDR_RequestPacket +{ + public: + VDR_RequestPacket(); + ~VDR_RequestPacket(); + + bool init(ULONG opcode, bool setUserDataLength, ULONG userDataLength); + bool copyin(const UCHAR* src, ULONG len); + bool addString(const char* string); + bool addULONG(ULONG ul); + bool addULLONG(ULLONG ull); + + UCHAR* getPtr() { return buffer; } + ULONG getLen() { return bufUsed; } + + private: + static ULONG serialNumber; + + UCHAR* buffer; + ULONG bufSize; + ULONG bufUsed; + bool lengthSet; + + bool checkExtend(ULONG by); + + const static ULONG headerLength = 16; +}; + +#endif + diff --git a/vdrresponsepacket.cc b/vdrresponsepacket.cc new file mode 100644 index 0000000..abf167c --- /dev/null +++ b/vdrresponsepacket.cc @@ -0,0 +1,109 @@ +/* + Copyright 2007 Chris Tallon + + This file is part of VOMP. + + VOMP 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. + + VOMP 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 VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "vdrresponsepacket.h" + +VDR_ResponsePacket::VDR_ResponsePacket() +{ + packetLength = 0; + packetPos = 0; + packet = NULL; + getBlockRelease = false; +} + +VDR_ResponsePacket::~VDR_ResponsePacket() +{ + if (getBlockRelease) return; // don't free if it's a getblock + + free(packet); +} + +void VDR_ResponsePacket::set(UCHAR* tpacket, ULONG tpacketLength) +{ + packet = tpacket; + packetLength = tpacketLength; +} + +ULONG VDR_ResponsePacket::getLength() +{ + return packetLength; +} + +bool VDR_ResponsePacket::end() +{ + return (packetPos >= packetLength); +} + +int VDR_ResponsePacket::serverError() +{ + if ((packetPos == 0) && (packetLength == 4) && !ntohl(*(ULONG*)packet)) return 1; + else return 0; +} + +char* VDR_ResponsePacket::extractString() +{ + if (serverError()) return NULL; + + int length = strlen((char*)&packet[packetPos]); + if ((packetPos + length) > packetLength) return NULL; + char* str = new char[length + 1]; + strcpy(str, (char*)&packet[packetPos]); + packetPos += length + 1; + return str; +} + +UCHAR VDR_ResponsePacket::extractUCHAR() +{ + if ((packetPos + sizeof(UCHAR)) > packetLength) return 0; + UCHAR uc = packet[packetPos]; + packetPos += sizeof(UCHAR); + return uc; +} + +ULONG VDR_ResponsePacket::extractULONG() +{ + if ((packetPos + sizeof(ULONG)) > packetLength) return 0; + ULONG ul = ntohl(*(ULONG*)&packet[packetPos]); + packetPos += sizeof(ULONG); + return ul; +} + +ULLONG VDR_ResponsePacket::extractULLONG() +{ + if ((packetPos + sizeof(ULLONG)) > packetLength) return 0; + ULLONG ull = ntohll(*(ULLONG*)&packet[packetPos]); + packetPos += sizeof(ULLONG); + return ull; +} + +long VDR_ResponsePacket::extractLONG() +{ + if ((packetPos + sizeof(long)) > packetLength) return 0; + long l = ntohl(*(long*)&packet[packetPos]); + packetPos += sizeof(long); + return l; +} + +UCHAR* VDR_ResponsePacket::getBlock_getPacket() +{ + getBlockRelease = true; + return packet; +} + diff --git a/vdrresponsepacket.h b/vdrresponsepacket.h new file mode 100644 index 0000000..b1f6e8e --- /dev/null +++ b/vdrresponsepacket.h @@ -0,0 +1,61 @@ +/* + Copyright 2007 Chris Tallon + + This file is part of VOMP. + + VOMP 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. + + VOMP 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 VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef VDRRESPONSEPACKET_H +#define VDRRESPONSEPACKET_H + +#include +#include +#include + +#include "defines.h" + +class VDR_ResponsePacket +{ + public: + VDR_ResponsePacket(); + ~VDR_ResponsePacket(); + + void set(UCHAR* packet, ULONG packetLength); + + int serverError(); + ULONG getLength(); + + char* extractString(); + UCHAR extractUCHAR(); + ULONG extractULONG(); + ULLONG extractULLONG(); + long extractLONG(); + + bool end(); + + // Do this a better way? + UCHAR* getBlock_getPacket(); + + private: + UCHAR* packet; + ULONG packetLength; + ULONG packetPos; + + bool getBlockRelease; +}; + +#endif + -- 2.39.2