]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Upgrade to protocol
authorChris Tallon <chris@vomp.tv>
Fri, 16 Nov 2007 22:38:56 +0000 (22:38 +0000)
committerChris Tallon <chris@vomp.tv>
Fri, 16 Nov 2007 22:38:56 +0000 (22:38 +0000)
vdr.cc
vdr.h
vdrrequestpacket.cc [new file with mode: 0644]
vdrrequestpacket.h [new file with mode: 0644]
vdrresponsepacket.cc [new file with mode: 0644]
vdrresponsepacket.h [new file with mode: 0644]

diff --git a/vdr.cc b/vdr.cc
index af0be4609996f11f3ebe3b402ef50a609f8881a0..00aba3b0e4f744d1dd729e400357748435988656 100644 (file)
--- 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 97513a149502992f7290643556bf303663a6742b..6fcfe88445384a5a6c810c3ebe56bcb9eb7235c2 100644 (file)
--- a/vdr.h
+++ b/vdr.h
 
 #include <stdio.h>
 #include <time.h>
-#ifndef WIN32
-  #include <pthread.h>
-#else
-  //Find threading replacements
-#endif
 #include <vector>
 #include <algorithm>
 
+#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<VDRServer>& 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 (file)
index 0000000..125b756
--- /dev/null
@@ -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 <arpa/inet.h>
+
+#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 (file)
index 0000000..52d2d06
--- /dev/null
@@ -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 <stdlib.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+#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 (file)
index 0000000..abf167c
--- /dev/null
@@ -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 (file)
index 0000000..b1f6e8e
--- /dev/null
@@ -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 <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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
+