]> git.vomp.tv Git - vompclient.git/blob - vdr.cc
Sort recordings from VDR 1.3, patch from Dave
[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 ///////////////////////////////////////////////////////
156
157 int VDR::getPacket()
158 {
159   packet = (UCHAR*)tcp->receivePacket();
160   if (!packet) return 0;
161   packetLength = tcp->getDataLength();
162   return 1;
163 }
164
165 void VDR::freePacket()
166 {
167   // Must be called if getPacket return 1, except in getBlock
168   packetLength = 0;
169   packetPos = 0;
170   free(packet);
171   packet = NULL;
172 }
173
174 int VDR::serverError()
175 {
176   if ((packetPos == 0) && (packetLength == 4) && !ntohl(*(ULONG*)packet)) return 1;
177   else return 0;
178 }
179
180 char* VDR::extractString()
181 {
182   if (serverError()) return NULL;
183
184   int length = strlen((char*)&packet[packetPos]);
185   if ((packetPos + length) > packetLength) return NULL;
186   char* str = new char[length + 1];
187   strcpy(str, (char*)&packet[packetPos]);
188   packetPos += length + 1;
189   return str;
190 }
191
192 ULONG VDR::extractULONG()
193 {
194   if ((packetPos + sizeof(ULONG)) > packetLength) return 0;
195   ULONG ul = ntohl(*(ULONG*)&packet[packetPos]);
196   packetPos += sizeof(ULONG);
197   return ul;
198 }
199
200 ULLONG VDR::extractULLONG()
201 {
202   if ((packetPos + sizeof(ULLONG)) > packetLength) return 0;
203   ULLONG ull = ntohll(*(ULLONG*)&packet[packetPos]);
204   packetPos += sizeof(ULLONG);
205   return ull;
206 }
207
208 long VDR::extractLONG()
209 {
210   if ((packetPos + sizeof(long)) > packetLength) return 0;
211   long l = ntohl(*(long*)&packet[packetPos]);
212   packetPos += sizeof(long);
213   return l;
214 }
215
216 /////////////////////////////////////////////////////////////////////////////
217
218 int VDR::doLogin()
219 {
220   if (!connected) return 0;
221
222   UCHAR buffer[14];
223
224   *(unsigned long*)&buffer[0] = htonl(10);
225   *(unsigned long*)&buffer[4] = htonl(VDR_LOGIN);
226
227   tcp->getMAC((char*)&buffer[8]);
228
229
230   pthread_mutex_lock(&mutex);
231   int a = tcp->sendPacket(buffer, 14);
232   if (a != 14)
233   {
234     pthread_mutex_unlock(&mutex);
235     return 0;
236   }
237
238   // reply
239
240   if (!getPacket())
241   {
242     pthread_mutex_unlock(&mutex);
243     return 0;
244   }
245
246   ULONG vdrTime = extractULONG();
247   logger->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime);
248   long vdrTimeOffset = extractLONG();
249   logger->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
250
251   freePacket();
252   pthread_mutex_unlock(&mutex);
253
254
255   struct timespec currentTime;
256   currentTime.tv_sec = vdrTime;
257   currentTime.tv_nsec = 0;
258   int b = clock_settime(CLOCK_REALTIME, &currentTime);
259
260   logger->log("VDR", Log::DEBUG, "set clock = %u", b);
261
262   // now make a TZ variable and set it
263   char sign;
264   int hours;
265   int minutes;
266   if (vdrTimeOffset > 0) sign = '-';
267   else sign = '+';
268
269   vdrTimeOffset = abs(vdrTimeOffset);
270
271   hours = (int)vdrTimeOffset / 3600;
272   minutes = vdrTimeOffset % 3600;
273
274   logger->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
275
276   minutes = (int)minutes / 60;
277
278   logger->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
279
280   char newTZ[30];
281   sprintf(newTZ, "MVP%c%i:%i", sign, hours, minutes);
282   setenv("TZ", newTZ, 1);
283
284   logger->log("VDR", Log::DEBUG, "Timezone data: %s", newTZ);
285
286   return 1;
287 }
288
289 Directory* VDR::getRecordingsList()
290 {
291   if (!connected) return 0;
292
293   UCHAR buffer[8];
294
295   *(unsigned long*)&buffer[0] = htonl(4);
296   *(unsigned long*)&buffer[4] = htonl(VDR_GETRECORDINGLIST);
297
298   pthread_mutex_lock(&mutex);
299   int a = tcp->sendPacket(buffer, 8);
300   if (a != 8)
301   {
302     pthread_mutex_unlock(&mutex);
303     return NULL;
304   }
305
306   // reply
307
308   if (!getPacket())
309   {
310     pthread_mutex_unlock(&mutex);
311     return NULL;
312   }
313
314   Directory* recDir = new Directory();
315   recDir->setName("/");
316   recDir->isRoot = 1;
317
318   Directory::totalSpace = extractULONG();
319   Directory::freeSpace = extractULONG();
320   Directory::usedPercent = extractULONG();
321
322   char* string;
323
324   while (packetPos < packetLength)
325   {
326     Recording* rec = new Recording();
327
328     rec->start = extractULONG();
329
330     string = extractString();
331     rec->setName(string);
332     delete[] string;
333
334     rec->fileName = extractString();
335
336     if(rec->isInDir())
337     {
338       char* dirName = rec->getDirName();
339
340       Directory* d = recDir->getDirByName(dirName);
341       if (!d)
342       {
343         d = new Directory();
344         d->setName(dirName);
345         Log::getInstance()->log("VDR", Log::DEBUG, "Added a new directory = %s", d->name);
346         recDir->dirList.push_back(d);
347       }
348
349       d->recList.push_back(rec);
350     }
351     else
352     {
353       recDir->recList.push_back(rec);
354     }
355
356     Log::getInstance()->log("VDR", Log::DEBUG, "%s", rec->fileName);
357   }
358
359   freePacket();
360   pthread_mutex_unlock(&mutex);
361
362   sort(recDir->recList.begin(), recDir->recList.end(), RecordingSorter());
363
364   return recDir;
365 }
366
367 int VDR::deleteRecording(char* fileName)
368 {
369   if (!connected) return 0;
370
371   unsigned long totalLength = 8 + strlen(fileName) + 1;
372   UCHAR buffer[totalLength];
373
374   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
375   *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING);
376   strcpy((char*)&buffer[8], fileName);
377
378   pthread_mutex_lock(&mutex);
379   unsigned int a = tcp->sendPacket(buffer, totalLength);
380   if (a != totalLength)
381   {
382     pthread_mutex_unlock(&mutex);
383     return 0;
384   }
385
386   if (!getPacket())
387   {
388     pthread_mutex_unlock(&mutex);
389     return 0;
390   }
391
392   int toReturn = (int)extractULONG();
393   freePacket();
394   pthread_mutex_unlock(&mutex);
395
396   return toReturn;
397 }
398
399 char* VDR::getRecordingSummary(char* fileName)
400 {
401   if (!connected) return 0;
402
403   unsigned long totalLength = 8 + strlen(fileName) + 1;
404   UCHAR buffer[totalLength];
405
406   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
407   *(unsigned long*)&buffer[4] = htonl(VDR_GETSUMMARY);
408   strcpy((char*)&buffer[8], fileName);
409
410   pthread_mutex_lock(&mutex);
411   unsigned int a = tcp->sendPacket(buffer, totalLength);
412   if (a != totalLength)
413   {
414     pthread_mutex_unlock(&mutex);
415     return NULL;
416   }
417
418   if (!getPacket())
419   {
420     pthread_mutex_unlock(&mutex);
421     return NULL;
422   }
423   char* toReturn = extractString();
424   freePacket();
425   pthread_mutex_unlock(&mutex);
426
427   return toReturn;
428 }
429
430 ChannelList* VDR::getChannelsList(ULONG type)
431 {
432   if (!connected) return 0;
433
434   UCHAR buffer[8];
435
436   *(unsigned long*)&buffer[0] = htonl(4);
437   *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST);
438
439   pthread_mutex_lock(&mutex);
440   int a = tcp->sendPacket(buffer, 8);
441   if (a != 8)
442   {
443     pthread_mutex_unlock(&mutex);
444     return NULL;
445   }
446
447   // reply
448
449   if (!getPacket())
450   {
451     pthread_mutex_unlock(&mutex);
452     return NULL;
453   }
454
455   ChannelList* chanList = new ChannelList();
456
457   while (packetPos < packetLength)
458   {
459     Channel* chan = new Channel();
460     chan->number = extractULONG();
461     chan->type = extractULONG();
462     chan->name = extractString();
463
464     if (chan->type == type)
465     {
466       chanList->push_back(chan);
467       Log::getInstance()->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
468     }
469     else
470     {
471       delete chan;
472     }
473   }
474
475   freePacket();
476   pthread_mutex_unlock(&mutex);
477
478   return chanList;
479 }
480
481 int VDR::streamChannel(ULONG number)
482 {
483   if (!connected) return 0;
484
485   UCHAR buffer[12];
486
487   *(unsigned long*)&buffer[0] = htonl(8);
488   *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL);
489   *(unsigned long*)&buffer[8] = htonl(number);
490
491   pthread_mutex_lock(&mutex);
492   int a = tcp->sendPacket(buffer, 12);
493
494   if (a != 12)
495   {
496     pthread_mutex_unlock(&mutex);
497     return 0;
498   }
499
500   if (!getPacket())
501   {
502     pthread_mutex_unlock(&mutex);
503     return 0;
504   }
505
506   int toReturn = (int)extractULONG();
507   freePacket();
508   pthread_mutex_unlock(&mutex);
509
510   return toReturn;
511 }
512
513 int VDR::stopStreaming()
514 {
515   if (!connected) return 0;
516
517   UCHAR buffer[8];
518
519   *(unsigned long*)&buffer[0] = htonl(4);
520   *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING);
521
522   pthread_mutex_lock(&mutex);
523   int a = tcp->sendPacket(buffer, 8);
524
525   if (a != 8)
526   {
527     pthread_mutex_unlock(&mutex);
528     return 0;
529   }
530
531 printf("sent request\n");
532
533   if (!getPacket())
534   {
535     pthread_mutex_unlock(&mutex);
536     return 0;
537   }
538 printf("got reply\n");
539
540
541   int toReturn = (int)extractULONG();
542   freePacket();
543   pthread_mutex_unlock(&mutex);
544
545   return toReturn;
546 }
547
548 UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived)
549 {
550   if (!connected) return 0;
551
552   UCHAR buffer[20];
553
554   *(unsigned long*)&buffer[0] = htonl(16);
555   *(unsigned long*)&buffer[4] = htonl(VDR_GETBLOCK);
556   *(ULLONG*)&buffer[8]        = htonll(position);
557   *(unsigned long*)&buffer[16] = htonl(maxAmount);
558
559   pthread_mutex_lock(&mutex);
560   int a = tcp->sendPacket(buffer, 20);
561   if (a != 20)
562   {
563     pthread_mutex_unlock(&mutex);
564     return NULL;
565   }
566
567   if (!getPacket())
568   {
569     pthread_mutex_unlock(&mutex);
570     return NULL;
571   }
572
573   UCHAR* toReturn = packet;
574   *amountReceived = packetLength;
575   // Manually clean up instead of running freePacket to keep the block
576   packet = NULL;
577   packetLength = 0;
578   packetPos = 0;
579   pthread_mutex_unlock(&mutex);
580
581   return toReturn;
582 }
583
584 ULLONG VDR::streamRecording(Recording* rec)
585 {
586   if (!connected) return 0;
587
588   unsigned long totalLength = 8 + strlen(rec->fileName) + 1;
589   UCHAR buffer[totalLength];
590
591   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
592   *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
593   strcpy((char*)&buffer[8], rec->fileName);
594
595   pthread_mutex_lock(&mutex);
596   unsigned int a = tcp->sendPacket(buffer, totalLength);
597   if (a != totalLength)
598   {
599     pthread_mutex_unlock(&mutex);
600     return 0;
601   }
602
603   if (!getPacket())
604   {
605     pthread_mutex_unlock(&mutex);
606     return 0;
607   }
608
609   ULLONG recordingLength = extractULLONG();
610   freePacket();
611   pthread_mutex_unlock(&mutex);
612
613   Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
614
615   return recordingLength;
616 }
617
618 ULLONG VDR::rescanRecording()
619 {
620   if (!connected) return 0;
621
622   unsigned long totalLength = 8;
623   UCHAR buffer[totalLength];
624
625   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
626   *(unsigned long*)&buffer[4] = htonl(VDR_RESCANRECORDING);
627
628   pthread_mutex_lock(&mutex);
629   unsigned int a = tcp->sendPacket(buffer, totalLength);
630   if (a != totalLength)
631   {
632     pthread_mutex_unlock(&mutex);
633     return 0;
634   }
635
636   if (!getPacket())
637   {
638     pthread_mutex_unlock(&mutex);
639     return 0;
640   }
641
642   ULLONG recordingLength = extractULLONG();
643   freePacket();
644   pthread_mutex_unlock(&mutex);
645
646   Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
647
648   return recordingLength;
649 }
650
651 EventList* VDR::getChannelSchedule(ULONG number)
652 {
653   time_t now;
654   time(&now);
655   return getChannelSchedule(number, now, 24 * 60 * 60);
656 }
657
658 EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
659 {
660 // retrieve event list (vector of events) from vdr within filter window. duration is in seconds
661   if (!connected) return 0;
662
663   UCHAR buffer[20];
664
665   *(unsigned long*)&buffer[0] = htonl(16);
666   *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
667   *(unsigned long*)&buffer[8] = htonl(number);
668   *(unsigned long*)&buffer[12] = htonl(start);
669   *(unsigned long*)&buffer[16] = htonl(duration);
670
671   pthread_mutex_lock(&mutex);
672   int a = tcp->sendPacket(buffer, 20);
673
674   if (a != 20)
675   {
676     pthread_mutex_unlock(&mutex);
677     return NULL;
678   }
679
680   if (!getPacket())
681   {
682     pthread_mutex_unlock(&mutex);
683     return NULL;
684   }
685
686   if (serverError())
687   {
688     freePacket();
689     pthread_mutex_unlock(&mutex);
690     return NULL;
691   }
692
693
694   EventList* eventList = new EventList();
695
696   while (packetPos < packetLength)
697   {
698     Event* event = new Event();
699     event->id = extractULONG();
700     event->time = extractULONG();
701     event->duration = extractULONG();
702     event->title = extractString();
703     event->subtitle = extractString();
704     event->description = extractString();
705     eventList->push_back(event);
706 //    eventList->next();
707   }
708
709   freePacket();
710   pthread_mutex_unlock(&mutex);
711
712   Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule");
713
714
715   // debug
716 /*
717   Log* l = Log::getInstance();
718
719
720   l->log("VDR", Log::DEBUG, "datalength = %i count = %i", dataLength, count);
721
722   Event* currentEvent;
723   for(eventList->reset(); !eventList->eol(); eventList->next())
724   {
725     currentEvent = (Event*)eventList->getCurrent();
726     l->log("VDR", Log::DEBUG, "%lu %lu %lu %s %s %s", currentEvent->id, currentEvent->time, currentEvent->duration, currentEvent->title, currentEvent->subtitle, currentEvent->description);
727   }
728 */
729
730   return eventList;
731 }
732
733 ULLONG VDR::getResumePoint(char* fileName)
734 {
735   if (!connected) return 0;
736
737   char* resumeString = configLoad("ResumeData", fileName);
738   if (!resumeString) return 0;
739
740   ULLONG toReturn = strtoull(resumeString, NULL, 10);
741   delete[] resumeString;
742   return toReturn;
743 }
744
745 int VDR::configSave(char* section, char* key, const char* value)
746 {
747   if (!connected) return 0;
748
749   ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
750   UCHAR buffer[totalLength];
751
752   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
753   *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
754
755   int position = 8;
756   strcpy((char*)&buffer[position], section);
757   position += strlen(section) + 1;
758   strcpy((char*)&buffer[position], key);
759   position += strlen(key) + 1;
760   strcpy((char*)&buffer[position], value);
761
762   pthread_mutex_lock(&mutex);
763   unsigned int a = tcp->sendPacket(buffer, totalLength);
764   if (a != totalLength)
765   {
766     pthread_mutex_unlock(&mutex);
767     return 0;
768   }
769
770   if (!getPacket())
771   {
772     pthread_mutex_unlock(&mutex);
773     return 0;
774   }
775
776   int toReturn = (int)extractULONG();
777   freePacket();
778   pthread_mutex_unlock(&mutex);
779
780   return toReturn;
781 }
782
783 char* VDR::configLoad(char* section, char* key)
784 {
785   if (!connected) return 0;
786
787   ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
788   UCHAR buffer[totalLength];
789
790   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
791   *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
792
793   int position = 8;
794   strcpy((char*)&buffer[position], section);
795   position += strlen(section) + 1;
796   strcpy((char*)&buffer[position], key);
797
798   pthread_mutex_lock(&mutex);
799   unsigned int a = tcp->sendPacket(buffer, totalLength);
800   if (a != totalLength)
801   {
802     pthread_mutex_unlock(&mutex);
803     return NULL;
804   }
805
806   if (!getPacket())
807   {
808     pthread_mutex_unlock(&mutex);
809     return NULL;
810   }
811   char* toReturn = extractString();
812   freePacket();
813   pthread_mutex_unlock(&mutex);
814
815   return toReturn;
816 }
817
818 RecTimerList* VDR::getRecTimersList()
819 {
820   if (!connected) return NULL;
821
822   UCHAR buffer[8];
823
824   *(unsigned long*)&buffer[0] = htonl(4);
825   *(unsigned long*)&buffer[4] = htonl(VDR_GETTIMERS);
826
827   pthread_mutex_lock(&mutex);
828   int a = tcp->sendPacket(buffer, 8);
829   if (a != 8)
830   {
831     pthread_mutex_unlock(&mutex);
832     return NULL;
833   }
834
835   // reply
836
837   if (!getPacket())
838   {
839     pthread_mutex_unlock(&mutex);
840     return NULL;
841   }
842
843   RecTimerList* recTimerList = new RecTimerList();
844
845   RecTimer* newRecTimer;
846   char* tempString;
847
848   while (packetPos < packetLength)
849   {
850     newRecTimer = new RecTimer();
851     newRecTimer->active = extractULONG();
852     newRecTimer->recording = extractULONG();
853     newRecTimer->pending = extractULONG();
854     newRecTimer->priority = extractULONG();
855     newRecTimer->lifeTime = extractULONG();
856     newRecTimer->channelNumber = extractULONG();
857     newRecTimer->startTime = extractULONG();
858     newRecTimer->stopTime = extractULONG();
859
860     tempString = extractString();
861     newRecTimer->setFile(tempString);
862     delete[] tempString;
863
864     newRecTimer->summary = extractString();
865
866     recTimerList->push_back(newRecTimer);
867     Log::getInstance()->log("VDR", Log::DEBUG, "TL: %lu %lu %lu %lu %lu %lu %lu %lu %s",
868       newRecTimer->active, newRecTimer->recording, newRecTimer->pending, newRecTimer->priority, newRecTimer->lifeTime,
869       newRecTimer->channelNumber, newRecTimer->startTime, newRecTimer->stopTime, newRecTimer->getFile());
870   }
871
872   freePacket();
873   pthread_mutex_unlock(&mutex);
874
875   // Sort the list
876
877   sort(recTimerList->begin(), recTimerList->end(), RecTimerSorter());
878
879   return recTimerList;
880 }