]> git.vomp.tv Git - vompclient.git/blob - vdr.cc
User setting for TCP window size
[vompclient.git] / vdr.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "vdr.h"
22
23 VDR* VDR::instance = NULL;
24
25 VDR::VDR()
26 {
27   if (instance) return;
28   instance = this;
29   initted = 0;
30   findingServer = 0;
31   tcp = NULL;
32   pthread_mutex_init(&mutex, NULL);
33   packetLength = 0;
34   packetPos = 0;
35   packet = NULL;
36   connected = false;
37 }
38
39 VDR::~VDR()
40 {
41   instance = NULL;
42   if (initted) shutdown();
43 }
44
45 VDR* VDR::getInstance()
46 {
47   return instance;
48 }
49
50 int VDR::init(int tport)
51 {
52   if (initted) return 0;
53   initted = 1;
54   port = tport;
55   logger = Log::getInstance();
56   return 1;
57 }
58
59 int VDR::shutdown()
60 {
61   if (!initted) return 0;
62   initted = 0;
63   disconnect();
64   return 1;
65 }
66
67 void VDR::findServers(vector<VDRServer>& servers)
68 {
69   findingServer = 1;
70   char* message = "VOMP";
71   DatagramSocket ds(port);
72
73   int haveAtLeastOne = 0;
74   int retval;
75   int waitType = 1;
76   while(findingServer)
77   {
78     if (waitType == 1)
79     {
80       logger->log("VDR", Log::NOTICE, "Broadcasting for server");
81       ds.send("255.255.255.255", 3024, message, strlen(message));
82     }
83     retval = ds.waitforMessage(waitType);
84
85     if (retval == 2) // we got a reply
86     {
87       if (!strcmp(ds.getData(), "VOMP")) // echo.....
88       {
89         waitType = 2;
90       }
91       else
92       {
93         VDRServer newServer;
94         newServer.ip = new char[16];
95         strcpy(newServer.ip, ds.getFromIPA());
96
97         if (ds.getDataLength() == 0)
98         {
99           newServer.name = new char[1];
100           newServer.name[0] = '\0';
101         }
102         else
103         {
104           newServer.name = new char[strlen(ds.getData())+1];
105           strcpy(newServer.name, ds.getData());
106         }
107
108         servers.push_back(newServer);
109         waitType = 2;
110         haveAtLeastOne = 1;
111       }
112     }
113     else
114     {
115       if (haveAtLeastOne) break;
116       waitType = 1;
117     }
118   }
119   sort(servers.begin(), servers.end(), ServerSorter());
120 }
121
122 void VDR::cancelFindingServer()
123 {
124   findingServer = 0;
125 }
126
127 void VDR::setServerIP(char* newIP)
128 {
129   strcpy(serverIP, newIP);
130 }
131
132 int VDR::connect()
133 {
134   if (tcp) delete tcp;
135   tcp = new TCP();
136   if (tcp->connectTo(serverIP, 3024))
137   {
138     connected = true;
139     return 1;
140   }
141   else
142   {
143     return 0;
144   }
145 }
146
147 void VDR::disconnect()
148 {
149   if (tcp) delete tcp;
150   tcp = NULL;
151   connected = false;
152   Log::getInstance()->log("VDR", Log::DEBUG, "Disconnect");
153 }
154
155 void VDR::setReceiveWindow(size_t size)
156 {
157   tcp->setReceiveWindow(size);
158 }
159
160 ///////////////////////////////////////////////////////
161
162 int VDR::getPacket()
163 {
164   packet = (UCHAR*)tcp->receivePacket();
165   if (!packet) return 0;
166   packetLength = tcp->getDataLength();
167   return 1;
168 }
169
170 void VDR::freePacket()
171 {
172   // Must be called if getPacket return 1, except in getBlock
173   packetLength = 0;
174   packetPos = 0;
175   free(packet);
176   packet = NULL;
177 }
178
179 int VDR::serverError()
180 {
181   if ((packetPos == 0) && (packetLength == 4) && !ntohl(*(ULONG*)packet)) return 1;
182   else return 0;
183 }
184
185 char* VDR::extractString()
186 {
187   if (serverError()) return NULL;
188
189   int length = strlen((char*)&packet[packetPos]);
190   if ((packetPos + length) > packetLength) return NULL;
191   char* str = new char[length + 1];
192   strcpy(str, (char*)&packet[packetPos]);
193   packetPos += length + 1;
194   return str;
195 }
196
197 ULONG VDR::extractULONG()
198 {
199   if ((packetPos + sizeof(ULONG)) > packetLength) return 0;
200   ULONG ul = ntohl(*(ULONG*)&packet[packetPos]);
201   packetPos += sizeof(ULONG);
202   return ul;
203 }
204
205 ULLONG VDR::extractULLONG()
206 {
207   if ((packetPos + sizeof(ULLONG)) > packetLength) return 0;
208   ULLONG ull = ntohll(*(ULLONG*)&packet[packetPos]);
209   packetPos += sizeof(ULLONG);
210   return ull;
211 }
212
213 long VDR::extractLONG()
214 {
215   if ((packetPos + sizeof(long)) > packetLength) return 0;
216   long l = ntohl(*(long*)&packet[packetPos]);
217   packetPos += sizeof(long);
218   return l;
219 }
220
221 /////////////////////////////////////////////////////////////////////////////
222
223 int VDR::doLogin()
224 {
225   if (!connected) return 0;
226
227   UCHAR buffer[14];
228
229   *(unsigned long*)&buffer[0] = htonl(10);
230   *(unsigned long*)&buffer[4] = htonl(VDR_LOGIN);
231
232   tcp->getMAC((char*)&buffer[8]);
233
234
235   pthread_mutex_lock(&mutex);
236   int a = tcp->sendPacket(buffer, 14);
237   if (a != 14)
238   {
239     pthread_mutex_unlock(&mutex);
240     return 0;
241   }
242
243   // reply
244
245   if (!getPacket())
246   {
247     pthread_mutex_unlock(&mutex);
248     return 0;
249   }
250
251   ULONG vdrTime = extractULONG();
252   logger->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime);
253   long vdrTimeOffset = extractLONG();
254   logger->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
255
256   freePacket();
257   pthread_mutex_unlock(&mutex);
258
259
260   struct timespec currentTime;
261   currentTime.tv_sec = vdrTime;
262   currentTime.tv_nsec = 0;
263   int b = clock_settime(CLOCK_REALTIME, &currentTime);
264
265   logger->log("VDR", Log::DEBUG, "set clock = %u", b);
266
267   // now make a TZ variable and set it
268   char sign;
269   int hours;
270   int minutes;
271   if (vdrTimeOffset > 0) sign = '-';
272   else sign = '+';
273
274   vdrTimeOffset = abs(vdrTimeOffset);
275
276   hours = (int)vdrTimeOffset / 3600;
277   minutes = vdrTimeOffset % 3600;
278
279   logger->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
280
281   minutes = (int)minutes / 60;
282
283   logger->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
284
285   char newTZ[30];
286   sprintf(newTZ, "MVP%c%i:%i", sign, hours, minutes);
287   setenv("TZ", newTZ, 1);
288
289   logger->log("VDR", Log::DEBUG, "Timezone data: %s", newTZ);
290
291   return 1;
292 }
293
294 Directory* VDR::getRecordingsList()
295 {
296   if (!connected) return 0;
297
298   UCHAR buffer[8];
299
300   *(unsigned long*)&buffer[0] = htonl(4);
301   *(unsigned long*)&buffer[4] = htonl(VDR_GETRECORDINGLIST);
302
303   pthread_mutex_lock(&mutex);
304   int a = tcp->sendPacket(buffer, 8);
305   if (a != 8)
306   {
307     pthread_mutex_unlock(&mutex);
308     return NULL;
309   }
310
311   // reply
312
313   if (!getPacket())
314   {
315     pthread_mutex_unlock(&mutex);
316     return NULL;
317   }
318
319   Directory* recDir = new Directory();
320   recDir->setName("/");
321   recDir->isRoot = 1;
322
323   Directory::totalSpace = extractULONG();
324   Directory::freeSpace = extractULONG();
325   Directory::usedPercent = extractULONG();
326
327   char* string;
328
329   while (packetPos < packetLength)
330   {
331     Recording* rec = new Recording();
332
333     rec->start = extractULONG();
334
335     string = extractString();
336     rec->setName(string);
337     delete[] string;
338
339     rec->fileName = extractString();
340
341     if(rec->isInDir())
342     {
343       char* dirName = rec->getDirName();
344
345       Directory* d = recDir->getDirByName(dirName);
346       if (!d)
347       {
348         d = new Directory();
349         d->setName(dirName);
350         Log::getInstance()->log("VDR", Log::DEBUG, "Added a new directory = %s", d->name);
351         recDir->dirList.push_back(d);
352       }
353
354       d->recList.push_back(rec);
355     }
356     else
357     {
358       recDir->recList.push_back(rec);
359     }
360
361     Log::getInstance()->log("VDR", Log::DEBUG, "%s", rec->fileName);
362   }
363
364   freePacket();
365   pthread_mutex_unlock(&mutex);
366
367   // Sort the directory order
368   sort(recDir->dirList.begin(), recDir->dirList.end(), DirectorySorter());
369
370   // Sort all the sub lists
371
372   Directory* sortDir;
373   DirectoryList::iterator i;
374   for (i = recDir->dirList.begin(); i != recDir->dirList.end(); i++)
375   {
376     sortDir = *i;
377     sort(sortDir->recList.begin(), sortDir->recList.end(), RecordingSorter());
378   }
379
380   // Sort the root level list
381   sort(recDir->recList.begin(), recDir->recList.end(), RecordingSorter());
382
383   return recDir;
384 }
385
386 int VDR::deleteRecording(char* fileName)
387 {
388   if (!connected) return 0;
389
390   unsigned long totalLength = 8 + strlen(fileName) + 1;
391   UCHAR buffer[totalLength];
392
393   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
394   *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING);
395   strcpy((char*)&buffer[8], fileName);
396
397   pthread_mutex_lock(&mutex);
398   unsigned int a = tcp->sendPacket(buffer, totalLength);
399   if (a != totalLength)
400   {
401     pthread_mutex_unlock(&mutex);
402     return 0;
403   }
404
405   if (!getPacket())
406   {
407     pthread_mutex_unlock(&mutex);
408     return 0;
409   }
410
411   int toReturn = (int)extractULONG();
412   freePacket();
413   pthread_mutex_unlock(&mutex);
414
415   return toReturn;
416 }
417
418 char* VDR::getRecordingSummary(char* fileName)
419 {
420   if (!connected) return 0;
421
422   unsigned long totalLength = 8 + strlen(fileName) + 1;
423   UCHAR buffer[totalLength];
424
425   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
426   *(unsigned long*)&buffer[4] = htonl(VDR_GETSUMMARY);
427   strcpy((char*)&buffer[8], fileName);
428
429   pthread_mutex_lock(&mutex);
430   unsigned int a = tcp->sendPacket(buffer, totalLength);
431   if (a != totalLength)
432   {
433     pthread_mutex_unlock(&mutex);
434     return NULL;
435   }
436
437   if (!getPacket())
438   {
439     pthread_mutex_unlock(&mutex);
440     return NULL;
441   }
442   char* toReturn = extractString();
443   freePacket();
444   pthread_mutex_unlock(&mutex);
445
446   return toReturn;
447 }
448
449 ChannelList* VDR::getChannelsList(ULONG type)
450 {
451   if (!connected) return 0;
452
453   UCHAR buffer[8];
454
455   *(unsigned long*)&buffer[0] = htonl(4);
456   *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST);
457
458   pthread_mutex_lock(&mutex);
459   int a = tcp->sendPacket(buffer, 8);
460   if (a != 8)
461   {
462     pthread_mutex_unlock(&mutex);
463     return NULL;
464   }
465
466   // reply
467
468   if (!getPacket())
469   {
470     pthread_mutex_unlock(&mutex);
471     return NULL;
472   }
473
474   ChannelList* chanList = new ChannelList();
475
476   while (packetPos < packetLength)
477   {
478     Channel* chan = new Channel();
479     chan->number = extractULONG();
480     chan->type = extractULONG();
481     chan->name = extractString();
482
483     if (chan->type == type)
484     {
485       chanList->push_back(chan);
486       Log::getInstance()->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
487     }
488     else
489     {
490       delete chan;
491     }
492   }
493
494   freePacket();
495   pthread_mutex_unlock(&mutex);
496
497   return chanList;
498 }
499
500 int VDR::streamChannel(ULONG number)
501 {
502   if (!connected) return 0;
503
504   UCHAR buffer[12];
505
506   *(unsigned long*)&buffer[0] = htonl(8);
507   *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL);
508   *(unsigned long*)&buffer[8] = htonl(number);
509
510   pthread_mutex_lock(&mutex);
511   int a = tcp->sendPacket(buffer, 12);
512
513   if (a != 12)
514   {
515     pthread_mutex_unlock(&mutex);
516     return 0;
517   }
518
519   if (!getPacket())
520   {
521     pthread_mutex_unlock(&mutex);
522     return 0;
523   }
524
525   int toReturn = (int)extractULONG();
526   freePacket();
527   pthread_mutex_unlock(&mutex);
528
529   return toReturn;
530 }
531
532 int VDR::stopStreaming()
533 {
534   if (!connected) return 0;
535
536   UCHAR buffer[8];
537
538   *(unsigned long*)&buffer[0] = htonl(4);
539   *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING);
540
541   pthread_mutex_lock(&mutex);
542   int a = tcp->sendPacket(buffer, 8);
543
544   if (a != 8)
545   {
546     pthread_mutex_unlock(&mutex);
547     return 0;
548   }
549
550 printf("sent request\n");
551
552   if (!getPacket())
553   {
554     pthread_mutex_unlock(&mutex);
555     return 0;
556   }
557 printf("got reply\n");
558
559
560   int toReturn = (int)extractULONG();
561   freePacket();
562   pthread_mutex_unlock(&mutex);
563
564   return toReturn;
565 }
566
567 UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived)
568 {
569   if (!connected) return 0;
570
571   UCHAR buffer[20];
572
573   *(unsigned long*)&buffer[0] = htonl(16);
574   *(unsigned long*)&buffer[4] = htonl(VDR_GETBLOCK);
575   *(ULLONG*)&buffer[8]        = htonll(position);
576   *(unsigned long*)&buffer[16] = htonl(maxAmount);
577
578   pthread_mutex_lock(&mutex);
579   int a = tcp->sendPacket(buffer, 20);
580   if (a != 20)
581   {
582     pthread_mutex_unlock(&mutex);
583     return NULL;
584   }
585
586   if (!getPacket())
587   {
588     pthread_mutex_unlock(&mutex);
589     return NULL;
590   }
591
592   UCHAR* toReturn = packet;
593   *amountReceived = packetLength;
594   // Manually clean up instead of running freePacket to keep the block
595   packet = NULL;
596   packetLength = 0;
597   packetPos = 0;
598   pthread_mutex_unlock(&mutex);
599
600   return toReturn;
601 }
602
603 ULLONG VDR::streamRecording(Recording* rec)
604 {
605   if (!connected) return 0;
606
607   unsigned long totalLength = 8 + strlen(rec->fileName) + 1;
608   UCHAR buffer[totalLength];
609
610   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
611   *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
612   strcpy((char*)&buffer[8], rec->fileName);
613
614   pthread_mutex_lock(&mutex);
615   unsigned int a = tcp->sendPacket(buffer, totalLength);
616   if (a != totalLength)
617   {
618     pthread_mutex_unlock(&mutex);
619     return 0;
620   }
621
622   if (!getPacket())
623   {
624     pthread_mutex_unlock(&mutex);
625     return 0;
626   }
627
628   ULLONG recordingLength = extractULLONG();
629   freePacket();
630   pthread_mutex_unlock(&mutex);
631
632   Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
633
634   return recordingLength;
635 }
636
637 ULLONG VDR::rescanRecording()
638 {
639   if (!connected) return 0;
640
641   unsigned long totalLength = 8;
642   UCHAR buffer[totalLength];
643
644   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
645   *(unsigned long*)&buffer[4] = htonl(VDR_RESCANRECORDING);
646
647   pthread_mutex_lock(&mutex);
648   unsigned int a = tcp->sendPacket(buffer, totalLength);
649   if (a != totalLength)
650   {
651     pthread_mutex_unlock(&mutex);
652     return 0;
653   }
654
655   if (!getPacket())
656   {
657     pthread_mutex_unlock(&mutex);
658     return 0;
659   }
660
661   ULLONG recordingLength = extractULLONG();
662   freePacket();
663   pthread_mutex_unlock(&mutex);
664
665   Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
666
667   return recordingLength;
668 }
669
670 EventList* VDR::getChannelSchedule(ULONG number)
671 {
672   time_t now;
673   time(&now);
674   return getChannelSchedule(number, now, 24 * 60 * 60);
675 }
676
677 EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
678 {
679 // retrieve event list (vector of events) from vdr within filter window. duration is in seconds
680   if (!connected) return 0;
681
682   UCHAR buffer[20];
683
684   *(unsigned long*)&buffer[0] = htonl(16);
685   *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
686   *(unsigned long*)&buffer[8] = htonl(number);
687   *(unsigned long*)&buffer[12] = htonl(start);
688   *(unsigned long*)&buffer[16] = htonl(duration);
689
690   pthread_mutex_lock(&mutex);
691   int a = tcp->sendPacket(buffer, 20);
692
693   if (a != 20)
694   {
695     pthread_mutex_unlock(&mutex);
696     return NULL;
697   }
698
699   if (!getPacket())
700   {
701     pthread_mutex_unlock(&mutex);
702     return NULL;
703   }
704
705   if (serverError())
706   {
707     freePacket();
708     pthread_mutex_unlock(&mutex);
709     return NULL;
710   }
711
712
713   EventList* eventList = new EventList();
714
715   while (packetPos < packetLength)
716   {
717     Event* event = new Event();
718     event->id = extractULONG();
719     event->time = extractULONG();
720     event->duration = extractULONG();
721     event->title = extractString();
722     event->subtitle = extractString();
723     event->description = extractString();
724     eventList->push_back(event);
725 //    eventList->next();
726   }
727
728   freePacket();
729   pthread_mutex_unlock(&mutex);
730
731   Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule");
732
733
734   // debug
735 /*
736   Log* l = Log::getInstance();
737
738
739   l->log("VDR", Log::DEBUG, "datalength = %i count = %i", dataLength, count);
740
741   Event* currentEvent;
742   for(eventList->reset(); !eventList->eol(); eventList->next())
743   {
744     currentEvent = (Event*)eventList->getCurrent();
745     l->log("VDR", Log::DEBUG, "%lu %lu %lu %s %s %s", currentEvent->id, currentEvent->time, currentEvent->duration, currentEvent->title, currentEvent->subtitle, currentEvent->description);
746   }
747 */
748
749   return eventList;
750 }
751
752 ULLONG VDR::getResumePoint(char* fileName)
753 {
754   if (!connected) return 0;
755
756   char* resumeString = configLoad("ResumeData", fileName);
757   if (!resumeString) return 0;
758
759   ULLONG toReturn = strtoull(resumeString, NULL, 10);
760   delete[] resumeString;
761   return toReturn;
762 }
763
764 int VDR::configSave(char* section, char* key, const char* value)
765 {
766   if (!connected) return 0;
767
768   ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
769   UCHAR buffer[totalLength];
770
771   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
772   *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
773
774   int position = 8;
775   strcpy((char*)&buffer[position], section);
776   position += strlen(section) + 1;
777   strcpy((char*)&buffer[position], key);
778   position += strlen(key) + 1;
779   strcpy((char*)&buffer[position], value);
780
781   pthread_mutex_lock(&mutex);
782   unsigned int a = tcp->sendPacket(buffer, totalLength);
783   if (a != totalLength)
784   {
785     pthread_mutex_unlock(&mutex);
786     return 0;
787   }
788
789   if (!getPacket())
790   {
791     pthread_mutex_unlock(&mutex);
792     return 0;
793   }
794
795   int toReturn = (int)extractULONG();
796   freePacket();
797   pthread_mutex_unlock(&mutex);
798
799   return toReturn;
800 }
801
802 char* VDR::configLoad(char* section, char* key)
803 {
804   if (!connected) return 0;
805
806   ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
807   UCHAR buffer[totalLength];
808
809   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
810   *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
811
812   int position = 8;
813   strcpy((char*)&buffer[position], section);
814   position += strlen(section) + 1;
815   strcpy((char*)&buffer[position], key);
816
817   pthread_mutex_lock(&mutex);
818   unsigned int a = tcp->sendPacket(buffer, totalLength);
819   if (a != totalLength)
820   {
821     pthread_mutex_unlock(&mutex);
822     return NULL;
823   }
824
825   if (!getPacket())
826   {
827     pthread_mutex_unlock(&mutex);
828     return NULL;
829   }
830   char* toReturn = extractString();
831   freePacket();
832   pthread_mutex_unlock(&mutex);
833
834   return toReturn;
835 }
836
837 RecTimerList* VDR::getRecTimersList()
838 {
839   if (!connected) return NULL;
840
841   UCHAR buffer[8];
842
843   *(unsigned long*)&buffer[0] = htonl(4);
844   *(unsigned long*)&buffer[4] = htonl(VDR_GETTIMERS);
845
846   pthread_mutex_lock(&mutex);
847   int a = tcp->sendPacket(buffer, 8);
848   if (a != 8)
849   {
850     pthread_mutex_unlock(&mutex);
851     return NULL;
852   }
853
854   // reply
855
856   if (!getPacket())
857   {
858     pthread_mutex_unlock(&mutex);
859     return NULL;
860   }
861
862   RecTimerList* recTimerList = new RecTimerList();
863
864   RecTimer* newRecTimer;
865   char* tempString;
866
867   while (packetPos < packetLength)
868   {
869     newRecTimer = new RecTimer();
870     newRecTimer->active = extractULONG();
871     newRecTimer->recording = extractULONG();
872     newRecTimer->pending = extractULONG();
873     newRecTimer->priority = extractULONG();
874     newRecTimer->lifeTime = extractULONG();
875     newRecTimer->channelNumber = extractULONG();
876     newRecTimer->startTime = extractULONG();
877     newRecTimer->stopTime = extractULONG();
878
879     tempString = extractString();
880     newRecTimer->setFile(tempString);
881     delete[] tempString;
882
883     newRecTimer->summary = extractString();
884
885     recTimerList->push_back(newRecTimer);
886     Log::getInstance()->log("VDR", Log::DEBUG, "TL: %lu %lu %lu %lu %lu %lu %lu %lu %s",
887       newRecTimer->active, newRecTimer->recording, newRecTimer->pending, newRecTimer->priority, newRecTimer->lifeTime,
888       newRecTimer->channelNumber, newRecTimer->startTime, newRecTimer->stopTime, newRecTimer->getFile());
889   }
890
891   freePacket();
892   pthread_mutex_unlock(&mutex);
893
894   // Sort the list
895
896   sort(recTimerList->begin(), recTimerList->end(), RecTimerSorter());
897
898   return recTimerList;
899 }
900
901 ULONG VDR::setEventTimer(char* timerString)
902 {
903   if (!connected) return false;
904
905   unsigned long totalLength = 8 + strlen(timerString) + 1;
906   UCHAR buffer[totalLength];
907
908   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
909   *(unsigned long*)&buffer[4] = htonl(VDR_SETTIMER);
910   strcpy((char*)&buffer[8], timerString);
911
912   pthread_mutex_lock(&mutex);
913   unsigned int a = tcp->sendPacket(buffer, totalLength);
914   if (a != totalLength)
915   {
916     pthread_mutex_unlock(&mutex);
917     return 0;
918   }
919
920   if (!getPacket())
921   {
922     pthread_mutex_unlock(&mutex);
923     return 0;
924   }
925
926   ULONG toReturn = extractULONG();
927   freePacket();
928   pthread_mutex_unlock(&mutex);
929
930   return toReturn;
931 }