]> git.vomp.tv Git - vompclient.git/blob - vdr.cc
Display server names
[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   return recDir;
363 }
364
365 int VDR::deleteRecording(char* fileName)
366 {
367   if (!connected) return 0;
368
369   unsigned long totalLength = 8 + strlen(fileName) + 1;
370   UCHAR buffer[totalLength];
371
372   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
373   *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING);
374   strcpy((char*)&buffer[8], fileName);
375
376   pthread_mutex_lock(&mutex);
377   unsigned int a = tcp->sendPacket(buffer, totalLength);
378   if (a != totalLength)
379   {
380     pthread_mutex_unlock(&mutex);
381     return 0;
382   }
383
384   if (!getPacket())
385   {
386     pthread_mutex_unlock(&mutex);
387     return 0;
388   }
389
390   int toReturn = (int)extractULONG();
391   freePacket();
392   pthread_mutex_unlock(&mutex);
393
394   return toReturn;
395 }
396
397 char* VDR::getRecordingSummary(char* fileName)
398 {
399   if (!connected) return 0;
400
401   unsigned long totalLength = 8 + strlen(fileName) + 1;
402   UCHAR buffer[totalLength];
403
404   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
405   *(unsigned long*)&buffer[4] = htonl(VDR_GETSUMMARY);
406   strcpy((char*)&buffer[8], fileName);
407
408   pthread_mutex_lock(&mutex);
409   unsigned int a = tcp->sendPacket(buffer, totalLength);
410   if (a != totalLength)
411   {
412     pthread_mutex_unlock(&mutex);
413     return NULL;
414   }
415
416   if (!getPacket())
417   {
418     pthread_mutex_unlock(&mutex);
419     return NULL;
420   }
421   char* toReturn = extractString();
422   freePacket();
423   pthread_mutex_unlock(&mutex);
424
425   return toReturn;
426 }
427
428 ChannelList* VDR::getChannelsList(ULONG type)
429 {
430   if (!connected) return 0;
431
432   UCHAR buffer[8];
433
434   *(unsigned long*)&buffer[0] = htonl(4);
435   *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST);
436
437   pthread_mutex_lock(&mutex);
438   int a = tcp->sendPacket(buffer, 8);
439   if (a != 8)
440   {
441     pthread_mutex_unlock(&mutex);
442     return NULL;
443   }
444
445   // reply
446
447   if (!getPacket())
448   {
449     pthread_mutex_unlock(&mutex);
450     return NULL;
451   }
452
453   ChannelList* chanList = new ChannelList();
454
455   while (packetPos < packetLength)
456   {
457     Channel* chan = new Channel();
458     chan->number = extractULONG();
459     chan->type = extractULONG();
460     chan->name = extractString();
461
462     if (chan->type == type)
463     {
464       chanList->push_back(chan);
465       Log::getInstance()->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
466     }
467     else
468     {
469       delete chan;
470     }
471   }
472
473   freePacket();
474   pthread_mutex_unlock(&mutex);
475
476   return chanList;
477 }
478
479 int VDR::streamChannel(ULONG number)
480 {
481   if (!connected) return 0;
482
483   UCHAR buffer[12];
484
485   *(unsigned long*)&buffer[0] = htonl(8);
486   *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL);
487   *(unsigned long*)&buffer[8] = htonl(number);
488
489   pthread_mutex_lock(&mutex);
490   int a = tcp->sendPacket(buffer, 12);
491
492   if (a != 12)
493   {
494     pthread_mutex_unlock(&mutex);
495     return 0;
496   }
497
498   if (!getPacket())
499   {
500     pthread_mutex_unlock(&mutex);
501     return 0;
502   }
503
504   int toReturn = (int)extractULONG();
505   freePacket();
506   pthread_mutex_unlock(&mutex);
507
508   return toReturn;
509 }
510
511 int VDR::stopStreaming()
512 {
513   if (!connected) return 0;
514
515   UCHAR buffer[8];
516
517   *(unsigned long*)&buffer[0] = htonl(4);
518   *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING);
519
520   pthread_mutex_lock(&mutex);
521   int a = tcp->sendPacket(buffer, 8);
522
523   if (a != 8)
524   {
525     pthread_mutex_unlock(&mutex);
526     return 0;
527   }
528
529 printf("sent request\n");
530
531   if (!getPacket())
532   {
533     pthread_mutex_unlock(&mutex);
534     return 0;
535   }
536 printf("got reply\n");
537
538
539   int toReturn = (int)extractULONG();
540   freePacket();
541   pthread_mutex_unlock(&mutex);
542
543   return toReturn;
544 }
545
546 UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived)
547 {
548   if (!connected) return 0;
549
550   UCHAR buffer[20];
551
552   *(unsigned long*)&buffer[0] = htonl(16);
553   *(unsigned long*)&buffer[4] = htonl(VDR_GETBLOCK);
554   *(ULLONG*)&buffer[8]        = htonll(position);
555   *(unsigned long*)&buffer[16] = htonl(maxAmount);
556
557   pthread_mutex_lock(&mutex);
558   int a = tcp->sendPacket(buffer, 20);
559   if (a != 20)
560   {
561     pthread_mutex_unlock(&mutex);
562     return NULL;
563   }
564
565   if (!getPacket())
566   {
567     pthread_mutex_unlock(&mutex);
568     return NULL;
569   }
570
571   UCHAR* toReturn = packet;
572   *amountReceived = packetLength;
573   // Manually clean up instead of running freePacket to keep the block
574   packet = NULL;
575   packetLength = 0;
576   packetPos = 0;
577   pthread_mutex_unlock(&mutex);
578
579   return toReturn;
580 }
581
582 ULLONG VDR::streamRecording(Recording* rec)
583 {
584   if (!connected) return 0;
585
586   unsigned long totalLength = 8 + strlen(rec->fileName) + 1;
587   UCHAR buffer[totalLength];
588
589   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
590   *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
591   strcpy((char*)&buffer[8], rec->fileName);
592
593   pthread_mutex_lock(&mutex);
594   unsigned int a = tcp->sendPacket(buffer, totalLength);
595   if (a != totalLength)
596   {
597     pthread_mutex_unlock(&mutex);
598     return 0;
599   }
600
601   if (!getPacket())
602   {
603     pthread_mutex_unlock(&mutex);
604     return 0;
605   }
606
607   ULLONG recordingLength = extractULLONG();
608   freePacket();
609   pthread_mutex_unlock(&mutex);
610
611   Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
612
613   return recordingLength;
614 }
615
616 ULLONG VDR::rescanRecording()
617 {
618   if (!connected) return 0;
619
620   unsigned long totalLength = 8;
621   UCHAR buffer[totalLength];
622
623   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
624   *(unsigned long*)&buffer[4] = htonl(VDR_RESCANRECORDING);
625
626   pthread_mutex_lock(&mutex);
627   unsigned int a = tcp->sendPacket(buffer, totalLength);
628   if (a != totalLength)
629   {
630     pthread_mutex_unlock(&mutex);
631     return 0;
632   }
633
634   if (!getPacket())
635   {
636     pthread_mutex_unlock(&mutex);
637     return 0;
638   }
639
640   ULLONG recordingLength = extractULLONG();
641   freePacket();
642   pthread_mutex_unlock(&mutex);
643
644   Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
645
646   return recordingLength;
647 }
648
649 EventList* VDR::getChannelSchedule(ULONG number)
650 {
651   time_t now;
652   time(&now);
653   return getChannelSchedule(number, now, 24 * 60 * 60);
654 }
655
656 EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
657 {
658 // retrieve event list (vector of events) from vdr within filter window. duration is in seconds
659   if (!connected) return 0;
660
661   UCHAR buffer[20];
662
663   *(unsigned long*)&buffer[0] = htonl(16);
664   *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
665   *(unsigned long*)&buffer[8] = htonl(number);
666   *(unsigned long*)&buffer[12] = htonl(start);
667   *(unsigned long*)&buffer[16] = htonl(duration);
668
669   pthread_mutex_lock(&mutex);
670   int a = tcp->sendPacket(buffer, 20);
671
672   if (a != 20)
673   {
674     pthread_mutex_unlock(&mutex);
675     return NULL;
676   }
677
678   if (!getPacket())
679   {
680     pthread_mutex_unlock(&mutex);
681     return NULL;
682   }
683
684   if (serverError())
685   {
686     freePacket();
687     pthread_mutex_unlock(&mutex);
688     return NULL;
689   }
690
691
692   EventList* eventList = new EventList();
693
694   while (packetPos < packetLength)
695   {
696     Event* event = new Event();
697     event->id = extractULONG();
698     event->time = extractULONG();
699     event->duration = extractULONG();
700     event->title = extractString();
701     event->subtitle = extractString();
702     event->description = extractString();
703     eventList->push_back(event);
704 //    eventList->next();
705   }
706
707   freePacket();
708   pthread_mutex_unlock(&mutex);
709
710   Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule");
711
712
713   // debug
714 /*
715   Log* l = Log::getInstance();
716
717
718   l->log("VDR", Log::DEBUG, "datalength = %i count = %i", dataLength, count);
719
720   Event* currentEvent;
721   for(eventList->reset(); !eventList->eol(); eventList->next())
722   {
723     currentEvent = (Event*)eventList->getCurrent();
724     l->log("VDR", Log::DEBUG, "%lu %lu %lu %s %s %s", currentEvent->id, currentEvent->time, currentEvent->duration, currentEvent->title, currentEvent->subtitle, currentEvent->description);
725   }
726 */
727
728   return eventList;
729 }
730
731 ULLONG VDR::getResumePoint(char* fileName)
732 {
733   if (!connected) return 0;
734
735   char* resumeString = configLoad("ResumeData", fileName);
736   if (!resumeString) return 0;
737
738   ULLONG toReturn = strtoull(resumeString, NULL, 10);
739   delete[] resumeString;
740   return toReturn;
741 }
742
743 int VDR::configSave(char* section, char* key, const char* value)
744 {
745   if (!connected) return 0;
746
747   ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
748   UCHAR buffer[totalLength];
749
750   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
751   *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
752
753   int position = 8;
754   strcpy((char*)&buffer[position], section);
755   position += strlen(section) + 1;
756   strcpy((char*)&buffer[position], key);
757   position += strlen(key) + 1;
758   strcpy((char*)&buffer[position], value);
759
760   pthread_mutex_lock(&mutex);
761   unsigned int a = tcp->sendPacket(buffer, totalLength);
762   if (a != totalLength)
763   {
764     pthread_mutex_unlock(&mutex);
765     return 0;
766   }
767
768   if (!getPacket())
769   {
770     pthread_mutex_unlock(&mutex);
771     return 0;
772   }
773
774   int toReturn = (int)extractULONG();
775   freePacket();
776   pthread_mutex_unlock(&mutex);
777
778   return toReturn;
779 }
780
781 char* VDR::configLoad(char* section, char* key)
782 {
783   if (!connected) return 0;
784
785   ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
786   UCHAR buffer[totalLength];
787
788   *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
789   *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
790
791   int position = 8;
792   strcpy((char*)&buffer[position], section);
793   position += strlen(section) + 1;
794   strcpy((char*)&buffer[position], key);
795
796   pthread_mutex_lock(&mutex);
797   unsigned int a = tcp->sendPacket(buffer, totalLength);
798   if (a != totalLength)
799   {
800     pthread_mutex_unlock(&mutex);
801     return NULL;
802   }
803
804   if (!getPacket())
805   {
806     pthread_mutex_unlock(&mutex);
807     return NULL;
808   }
809   char* toReturn = extractString();
810   freePacket();
811   pthread_mutex_unlock(&mutex);
812
813   return toReturn;
814 }
815
816 RecTimerList* VDR::getRecTimersList()
817 {
818   if (!connected) return NULL;
819
820   UCHAR buffer[8];
821
822   *(unsigned long*)&buffer[0] = htonl(4);
823   *(unsigned long*)&buffer[4] = htonl(VDR_GETTIMERS);
824
825   pthread_mutex_lock(&mutex);
826   int a = tcp->sendPacket(buffer, 8);
827   if (a != 8)
828   {
829     pthread_mutex_unlock(&mutex);
830     return NULL;
831   }
832
833   // reply
834
835   if (!getPacket())
836   {
837     pthread_mutex_unlock(&mutex);
838     return NULL;
839   }
840
841   RecTimerList* recTimerList = new RecTimerList();
842
843   RecTimer* newRecTimer;
844   char* tempString;
845
846   while (packetPos < packetLength)
847   {
848     newRecTimer = new RecTimer();
849     newRecTimer->active = extractULONG();
850     newRecTimer->recording = extractULONG();
851     newRecTimer->pending = extractULONG();
852     newRecTimer->priority = extractULONG();
853     newRecTimer->lifeTime = extractULONG();
854     newRecTimer->channelNumber = extractULONG();
855     newRecTimer->startTime = extractULONG();
856     newRecTimer->stopTime = extractULONG();
857
858     tempString = extractString();
859     newRecTimer->setFile(tempString);
860     delete[] tempString;
861
862     newRecTimer->summary = extractString();
863
864     recTimerList->push_back(newRecTimer);
865     Log::getInstance()->log("VDR", Log::DEBUG, "TL: %lu %lu %lu %lu %lu %lu %lu %lu %s",
866       newRecTimer->active, newRecTimer->recording, newRecTimer->pending, newRecTimer->priority, newRecTimer->lifeTime,
867       newRecTimer->channelNumber, newRecTimer->startTime, newRecTimer->stopTime, newRecTimer->getFile());
868   }
869
870   freePacket();
871   pthread_mutex_unlock(&mutex);
872
873   // Sort the list
874
875   sort(recTimerList->begin(), recTimerList->end(), RecTimerSorter());
876
877   return recTimerList;
878 }