2 Copyright 2004-2005 Chris Tallon
4 This file is part of VOMP.
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.
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.
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
24 VDR* VDR::instance = NULL;
27 #define MUTEX_LOCK(mutex) pthread_mutex_lock(mutex)
28 #define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(mutex)
30 #define MUTEX_LOCK(mutex) WaitForSingleObject(*(mutex), INFINITE )
31 #define MUTEX_UNLOCK(mutex) ReleaseMutex(*(mutex))
43 pthread_mutex_init(&mutex, NULL);
45 mutex=CreateMutex(NULL,FALSE,NULL);
52 channelNumberWidth = 1;
61 if (initted) shutdown();
64 VDR* VDR::getInstance()
69 int VDR::init(int tport)
71 if (initted) return 0;
74 logger = Log::getInstance();
80 if (!initted) return 0;
86 void VDR::findServers(vector<VDRServer>& servers)
88 Wol* wol = Wol::getInstance();
90 char* message = "VOMP";
92 DatagramSocket ds(port);
93 int haveAtLeastOne = 0;
96 bool firstloop = true;
103 logger->log("VDR", Log::NOTICE, "Broadcasting for server");
104 ds.send("255.255.255.255", 3024, message, strlen(message));
105 if(!firstloop) wol->doWakeUp();
107 retval = ds.waitforMessage(waitType);
109 if (retval == 2) // we got a reply
111 if (!strcmp(ds.getData(), "VOMP")) // echo.....
118 newServer.ip = new char[16];
119 strcpy(newServer.ip, ds.getFromIPA());
121 if (ds.getDataLength() == 0)
123 newServer.name = new char[1];
124 newServer.name[0] = '\0';
128 newServer.name = new char[strlen(ds.getData())+1];
129 strcpy(newServer.name, ds.getData());
132 servers.push_back(newServer);
139 if (haveAtLeastOne) break;
144 sort(servers.begin(), servers.end(), ServerSorter());
147 void VDR::cancelFindingServer()
152 void VDR::setServerIP(char* newIP)
154 strcpy(serverIP, newIP);
159 maxChannelNumber = 0;
160 channelNumberWidth = 1;
164 if (tcp->connectTo(serverIP, 3024))
175 void VDR::disconnect()
180 Log::getInstance()->log("VDR", Log::DEBUG, "Disconnect");
183 void VDR::setReceiveWindow(size_t size)
185 if (connected) tcp->setReceiveWindow(size);
188 ///////////////////////////////////////////////////////
192 packet = (UCHAR*)tcp->receivePacket();
198 packetLength = tcp->getDataLength();
202 void VDR::freePacket()
204 // Must be called if getPacket return 1, except in getBlock
211 int VDR::serverError()
213 if ((packetPos == 0) && (packetLength == 4) && !ntohl(*(ULONG*)packet)) return 1;
217 char* VDR::extractString()
219 if (serverError()) return NULL;
221 int length = strlen((char*)&packet[packetPos]);
222 if ((packetPos + length) > packetLength) return NULL;
223 char* str = new char[length + 1];
224 strcpy(str, (char*)&packet[packetPos]);
225 packetPos += length + 1;
229 UCHAR VDR::extractUCHAR()
231 if ((packetPos + sizeof(UCHAR)) > packetLength) return 0;
232 UCHAR uc = packet[packetPos];
233 packetPos += sizeof(UCHAR);
237 ULONG VDR::extractULONG()
239 if ((packetPos + sizeof(ULONG)) > packetLength) return 0;
240 ULONG ul = ntohl(*(ULONG*)&packet[packetPos]);
241 packetPos += sizeof(ULONG);
245 ULLONG VDR::extractULLONG()
247 if ((packetPos + sizeof(ULLONG)) > packetLength) return 0;
248 ULLONG ull = ntohll(*(ULLONG*)&packet[packetPos]);
249 packetPos += sizeof(ULLONG);
253 long VDR::extractLONG()
255 if ((packetPos + sizeof(long)) > packetLength) return 0;
256 long l = ntohl(*(long*)&packet[packetPos]);
257 packetPos += sizeof(long);
261 /////////////////////////////////////////////////////////////////////////////
267 *(unsigned long*)&buffer[0] = htonl(10);
268 *(unsigned long*)&buffer[4] = htonl(VDR_LOGIN);
270 tcp->getMAC((char*)&buffer[8]);
276 MUTEX_UNLOCK(&mutex);
280 int a = tcp->sendPacket(buffer, 14);
284 MUTEX_UNLOCK(&mutex);
292 MUTEX_UNLOCK(&mutex);
296 ULONG vdrTime = extractULONG();
297 logger->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime);
298 long vdrTimeOffset = extractLONG();
299 logger->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
302 MUTEX_UNLOCK(&mutex);
304 // Set the time and zone on the MVP
307 struct timespec currentTime;
308 currentTime.tv_sec = vdrTime;
309 currentTime.tv_nsec = 0;
310 int b = clock_settime(CLOCK_REALTIME, ¤tTime);
312 logger->log("VDR", Log::DEBUG, "set clock = %u", b);
314 // now make a TZ variable and set it
318 if (vdrTimeOffset > 0) sign = '-';
321 vdrTimeOffset = abs(vdrTimeOffset);
323 hours = (int)vdrTimeOffset / 3600;
324 minutes = vdrTimeOffset % 3600;
326 logger->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
328 minutes = (int)minutes / 60;
330 logger->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
333 sprintf(newTZ, "MVP%c%i:%i", sign, hours, minutes);
334 setenv("TZ", newTZ, 1);
336 logger->log("VDR", Log::DEBUG, "Timezone data: %s", newTZ);
342 bool VDR::getRecordingsList(RecMan* recman)
346 *(unsigned long*)&buffer[0] = htonl(4);
347 *(unsigned long*)&buffer[4] = htonl(VDR_GETRECORDINGLIST);
352 MUTEX_UNLOCK(&mutex);
356 int a = tcp->sendPacket(buffer, 8);
360 MUTEX_UNLOCK(&mutex);
368 MUTEX_UNLOCK(&mutex);
372 ULONG totalSpace = extractULONG();
373 ULONG freeSpace = extractULONG();
374 ULONG percent = extractULONG();
375 recman->setStats(totalSpace, freeSpace, percent);
381 while (packetPos < packetLength)
383 start = extractULONG();
384 name = extractString();
385 fileName = extractString();
387 recman->addEntry(start, name, fileName);
394 MUTEX_UNLOCK(&mutex);
399 int VDR::deleteRecording(char* fileName)
401 unsigned long totalLength = 8 + strlen(fileName) + 1;
402 UCHAR* buffer = new UCHAR[totalLength];
404 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
405 *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING);
406 strcpy((char*)&buffer[8], fileName);
409 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
411 unsigned int a = tcp->sendPacket(buffer, totalLength);
414 if (a != totalLength)
417 MUTEX_UNLOCK(&mutex);
423 MUTEX_UNLOCK(&mutex);
427 int toReturn = (int)extractULONG();
429 MUTEX_UNLOCK(&mutex);
434 char* VDR::moveRecording(char* fileName, char* newPath)
436 unsigned long totalLength = 8 + strlen(fileName) + 1 + strlen(newPath) + 1;
437 UCHAR* buffer = new UCHAR[totalLength];
439 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
440 *(unsigned long*)&buffer[4] = htonl(VDR_MOVERECORDING);
441 strcpy((char*)&buffer[8], fileName);
442 strcpy((char*)&buffer[8 + strlen(fileName) + 1], newPath);
445 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
447 unsigned int a = tcp->sendPacket(buffer, totalLength);
450 if (a != totalLength)
453 MUTEX_UNLOCK(&mutex);
459 MUTEX_UNLOCK(&mutex);
463 char* toReturn = NULL;
464 int success = (int)extractULONG();
467 toReturn = extractString();
471 MUTEX_UNLOCK(&mutex);
476 ChannelList* VDR::getChannelsList(ULONG type)
480 *(unsigned long*)&buffer[0] = htonl(4);
481 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST);
484 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
486 int a = tcp->sendPacket(buffer, 8);
490 MUTEX_UNLOCK(&mutex);
498 MUTEX_UNLOCK(&mutex);
502 ChannelList* chanList = new ChannelList();
504 while (packetPos < packetLength)
506 Channel* chan = new Channel();
507 chan->number = extractULONG();
508 chan->type = extractULONG();
509 chan->name = extractString();
511 if (chan->type == type)
513 chanList->push_back(chan);
514 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
515 if (chan->number > maxChannelNumber) maxChannelNumber = chan->number;
524 MUTEX_UNLOCK(&mutex);
526 if (maxChannelNumber > 99999)
527 channelNumberWidth = 6;
528 else if (maxChannelNumber > 9999)
529 channelNumberWidth = 5;
530 else if (maxChannelNumber > 999)
531 channelNumberWidth = 4;
532 else if (maxChannelNumber > 99)
533 channelNumberWidth = 3;
534 else if (maxChannelNumber > 9)
535 channelNumberWidth = 2;
537 channelNumberWidth = 1;
542 int VDR::streamChannel(ULONG number)
546 *(unsigned long*)&buffer[0] = htonl(8);
547 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL);
548 *(unsigned long*)&buffer[8] = htonl(number);
551 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
553 int a = tcp->sendPacket(buffer, 12);
558 MUTEX_UNLOCK(&mutex);
564 MUTEX_UNLOCK(&mutex);
568 int toReturn = (int)extractULONG();
570 MUTEX_UNLOCK(&mutex);
575 int VDR::stopStreaming()
579 *(unsigned long*)&buffer[0] = htonl(4);
580 *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING);
583 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
585 int a = tcp->sendPacket(buffer, 8);
590 MUTEX_UNLOCK(&mutex);
596 MUTEX_UNLOCK(&mutex);
600 int toReturn = (int)extractULONG();
602 MUTEX_UNLOCK(&mutex);
607 UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived)
611 *(unsigned long*)&buffer[0] = htonl(16);
612 *(unsigned long*)&buffer[4] = htonl(VDR_GETBLOCK);
613 *(ULLONG*)&buffer[8] = htonll(position);
614 *(unsigned long*)&buffer[16] = htonl(maxAmount);
617 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
619 int a = tcp->sendPacket(buffer, 20);
623 MUTEX_UNLOCK(&mutex);
629 MUTEX_UNLOCK(&mutex);
635 Log::getInstance()->log("VDR", Log::DEBUG, "Detected getblock 0");
637 MUTEX_UNLOCK(&mutex);
641 UCHAR* toReturn = packet;
642 *amountReceived = packetLength;
643 // Manually clean up instead of running freePacket to keep the block
647 MUTEX_UNLOCK(&mutex);
653 ULLONG VDR::streamRecording(char* fileName, ULONG* totalFrames)
655 unsigned long totalLength = 8 + strlen(fileName) + 1;
656 UCHAR* buffer = new UCHAR[totalLength];
658 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
659 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
660 strcpy((char*)&buffer[8], fileName);
663 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
665 unsigned int a = tcp->sendPacket(buffer, totalLength);
668 if (a != totalLength)
671 MUTEX_UNLOCK(&mutex);
677 MUTEX_UNLOCK(&mutex);
681 ULLONG lengthBytes = extractULLONG();
682 ULONG lengthFrames = extractULONG();
684 MUTEX_UNLOCK(&mutex);
686 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu %lu", lengthBytes, lengthFrames);
688 *totalFrames = lengthFrames;
692 ULLONG VDR::positionFromFrameNumber(ULONG frameNumber)
694 unsigned long totalLength = 12;
695 UCHAR* buffer = new UCHAR[totalLength];
697 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
698 *(unsigned long*)&buffer[4] = htonl(VDR_POSFROMFRAME);
699 *(unsigned long*)&buffer[8] = htonl(frameNumber);
702 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
704 unsigned int a = tcp->sendPacket(buffer, totalLength);
707 if (a != totalLength)
710 MUTEX_UNLOCK(&mutex);
716 MUTEX_UNLOCK(&mutex);
720 ULLONG position = extractULLONG();
722 MUTEX_UNLOCK(&mutex);
724 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said new position is: %llu", position);
729 ULONG VDR::frameNumberFromPosition(ULLONG position)
731 unsigned long totalLength = 16;
732 UCHAR* buffer = new UCHAR[totalLength];
734 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
735 *(unsigned long*)&buffer[4] = htonl(VDR_FRAMEFROMPOS);
736 *(ULLONG*)&buffer[8] = htonll(position);
739 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
741 unsigned int a = tcp->sendPacket(buffer, totalLength);
744 if (a != totalLength)
747 MUTEX_UNLOCK(&mutex);
753 MUTEX_UNLOCK(&mutex);
757 ULONG framenumber = extractULONG();
759 MUTEX_UNLOCK(&mutex);
761 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said new framenumber is: %u", framenumber);
766 bool VDR::getNextIFrame(ULONG frameNumber, ULONG direction, ULLONG* rfilePosition, ULONG* rframeNumber, ULONG* rframeLength)
768 unsigned long totalLength = 16;
769 UCHAR* buffer = new UCHAR[totalLength];
771 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
772 *(unsigned long*)&buffer[4] = htonl(VDR_GETNEXTIFRAME);
773 *(unsigned long*)&buffer[8] = htonl(frameNumber);
774 *(unsigned long*)&buffer[12] = htonl(direction);
777 if (!connected) { MUTEX_UNLOCK(&mutex); return false; }
779 unsigned int a = tcp->sendPacket(buffer, totalLength);
782 if (a != totalLength)
785 MUTEX_UNLOCK(&mutex);
791 MUTEX_UNLOCK(&mutex);
797 Log::getInstance()->log("VDR", Log::DEBUG, "Detected getNextIFrame error");
799 MUTEX_UNLOCK(&mutex);
803 *rfilePosition = extractULLONG();
804 *rframeNumber = extractULONG();
805 *rframeLength = extractULONG();
808 MUTEX_UNLOCK(&mutex);
810 // Log::getInstance()->log("VDR", Log::DEBUG, "VDR GNIF said %llu %lu %lu", *rfilePosition, *rframeNumber, *rframeLength);
815 EventList* VDR::getChannelSchedule(ULONG number)
819 return getChannelSchedule(number, now, 24 * 60 * 60);
822 EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
824 // retrieve event list (vector of events) from vdr within filter window. duration is in seconds
827 *(unsigned long*)&buffer[0] = htonl(16);
828 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
829 *(unsigned long*)&buffer[8] = htonl(number);
830 *(unsigned long*)&buffer[12] = htonl(start);
831 *(unsigned long*)&buffer[16] = htonl(duration);
834 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
836 int a = tcp->sendPacket(buffer, 20);
841 MUTEX_UNLOCK(&mutex);
847 MUTEX_UNLOCK(&mutex);
851 // received a ulong(0) - schedules error in the plugin
855 MUTEX_UNLOCK(&mutex);
859 EventList* eventList = new EventList();
861 while (packetPos < packetLength)
863 Event* event = new Event();
864 event->id = extractULONG();
865 event->time = extractULONG();
866 event->duration = extractULONG();
867 event->title = extractString();
868 event->subtitle = extractString();
869 event->description = extractString();
870 eventList->push_back(event);
874 MUTEX_UNLOCK(&mutex);
876 Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule");
880 int VDR::configSave(char* section, char* key, const char* value)
882 ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
883 UCHAR* buffer = new UCHAR[totalLength];
885 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
886 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
889 strcpy((char*)&buffer[position], section);
890 position += strlen(section) + 1;
891 strcpy((char*)&buffer[position], key);
892 position += strlen(key) + 1;
893 strcpy((char*)&buffer[position], value);
896 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
898 unsigned int a = tcp->sendPacket(buffer, totalLength);
901 if (a != totalLength)
904 MUTEX_UNLOCK(&mutex);
910 MUTEX_UNLOCK(&mutex);
914 int toReturn = (int)extractULONG();
916 MUTEX_UNLOCK(&mutex);
921 char* VDR::configLoad(char* section, char* key)
923 ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
924 UCHAR* buffer = new UCHAR[totalLength];
926 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
927 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
930 strcpy((char*)&buffer[position], section);
931 position += strlen(section) + 1;
932 strcpy((char*)&buffer[position], key);
935 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
937 unsigned int a = tcp->sendPacket(buffer, totalLength);
940 if (a != totalLength)
943 MUTEX_UNLOCK(&mutex);
949 MUTEX_UNLOCK(&mutex);
952 char* toReturn = extractString();
954 MUTEX_UNLOCK(&mutex);
959 RecTimerList* VDR::getRecTimersList()
963 *(unsigned long*)&buffer[0] = htonl(4);
964 *(unsigned long*)&buffer[4] = htonl(VDR_GETTIMERS);
967 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
969 int a = tcp->sendPacket(buffer, 8);
973 MUTEX_UNLOCK(&mutex);
981 MUTEX_UNLOCK(&mutex);
985 RecTimerList* recTimerList = new RecTimerList();
987 ULONG numTimers = extractULONG();
990 RecTimer* newRecTimer;
993 while (packetPos < packetLength)
995 newRecTimer = new RecTimer();
996 newRecTimer->active = extractULONG();
997 newRecTimer->recording = extractULONG();
998 newRecTimer->pending = extractULONG();
999 newRecTimer->priority = extractULONG();
1000 newRecTimer->lifeTime = extractULONG();
1001 newRecTimer->channelNumber = extractULONG();
1002 newRecTimer->startTime = extractULONG();
1003 newRecTimer->stopTime = extractULONG();
1005 tempString = extractString();
1006 newRecTimer->setFile(tempString);
1007 delete[] tempString;
1009 recTimerList->push_back(newRecTimer);
1010 Log::getInstance()->log("VDR", Log::DEBUG, "TL: %lu %lu %lu %lu %lu %lu %lu %lu %s",
1011 newRecTimer->active, newRecTimer->recording, newRecTimer->pending, newRecTimer->priority, newRecTimer->lifeTime,
1012 newRecTimer->channelNumber, newRecTimer->startTime, newRecTimer->stopTime, newRecTimer->getFile());
1017 MUTEX_UNLOCK(&mutex);
1019 sort(recTimerList->begin(), recTimerList->end(), RecTimerSorter());
1021 return recTimerList;
1024 ULONG VDR::setEventTimer(char* timerString)
1026 unsigned long totalLength = 8 + strlen(timerString) + 1;
1027 UCHAR* buffer = new UCHAR[totalLength];
1029 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1030 *(unsigned long*)&buffer[4] = htonl(VDR_SETTIMER);
1031 strcpy((char*)&buffer[8], timerString);
1034 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
1036 unsigned int a = tcp->sendPacket(buffer, totalLength);
1039 if (a != totalLength)
1042 MUTEX_UNLOCK(&mutex);
1048 MUTEX_UNLOCK(&mutex);
1052 ULONG toReturn = extractULONG();
1054 MUTEX_UNLOCK(&mutex);
1059 RecInfo* VDR::getRecInfo(char* fileName)
1061 unsigned long totalLength = 8 + strlen(fileName) + 1;
1062 UCHAR* buffer = new UCHAR[totalLength];
1064 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1065 *(unsigned long*)&buffer[4] = htonl(VDR_GETRECINFO);
1066 strcpy((char*)&buffer[8], fileName);
1069 if (!connected) { MUTEX_UNLOCK(&mutex); return NULL; }
1071 unsigned int a = tcp->sendPacket(buffer, totalLength);
1074 if (a != totalLength)
1077 MUTEX_UNLOCK(&mutex);
1083 MUTEX_UNLOCK(&mutex);
1089 Log::getInstance()->log("VDR", Log::DEBUG, "Could not get rec info");
1091 MUTEX_UNLOCK(&mutex);
1095 TCP::dump(packet, packetLength);
1097 RecInfo* recInfo = new RecInfo();
1099 recInfo->timerStart = extractULONG();
1100 recInfo->timerEnd = extractULONG();
1101 recInfo->resumePoint = extractULONG();
1102 recInfo->summary = extractString();
1104 ULONG numComponents = extractULONG();
1107 recInfo->setNumComponents(numComponents);
1108 for (ULONG i = 0; i < numComponents; i++)
1110 recInfo->streams[i] = extractUCHAR();
1111 recInfo->types[i] = extractUCHAR();
1112 recInfo->languages[i] = extractString();
1113 recInfo->descriptions[i] = extractString();
1120 MUTEX_UNLOCK(&mutex);
1125 ULLONG VDR::rescanRecording(ULONG* totalFrames)
1127 unsigned long totalLength = 8;
1128 UCHAR* buffer = new UCHAR[totalLength];
1130 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1131 *(unsigned long*)&buffer[4] = htonl(VDR_RESCANRECORDING);
1134 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
1136 unsigned int a = tcp->sendPacket(buffer, totalLength);
1139 if (a != totalLength)
1142 MUTEX_UNLOCK(&mutex);
1148 MUTEX_UNLOCK(&mutex);
1152 ULLONG lengthBytes = extractULLONG();
1153 ULONG lengthFrames = extractULONG();
1155 MUTEX_UNLOCK(&mutex);
1157 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu %lu", lengthBytes, lengthFrames);
1159 *totalFrames = lengthFrames;
1163 MarkList* VDR::getMarks(char* fileName)
1165 unsigned long totalLength = 8 + strlen(fileName) + 1;
1166 UCHAR* buffer = new UCHAR[totalLength];
1168 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1169 *(unsigned long*)&buffer[4] = htonl(VDR_GETMARKS);
1170 strcpy((char*)&buffer[8], fileName);
1173 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
1175 unsigned int a = tcp->sendPacket(buffer, totalLength);
1178 if (a != totalLength)
1181 MUTEX_UNLOCK(&mutex);
1187 MUTEX_UNLOCK(&mutex);
1193 MUTEX_UNLOCK(&mutex);
1197 MarkList* markList = new MarkList();
1199 while (packetPos < packetLength)
1201 Mark* mark = new Mark();
1202 mark->pos = extractULONG();
1204 markList->push_back(mark);
1205 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a mark to list. %lu", mark->pos);
1209 MUTEX_UNLOCK(&mutex);
1214 void VDR::getChannelPids(Channel* channel)
1218 *(unsigned long*)&buffer[0] = htonl(8);
1219 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELPIDS);
1220 *(unsigned long*)&buffer[8] = htonl(channel->number);
1223 if (!connected) { MUTEX_UNLOCK(&mutex); return ; }
1225 int a = tcp->sendPacket(buffer, 12);
1230 MUTEX_UNLOCK(&mutex);
1236 MUTEX_UNLOCK(&mutex);
1240 // Format of response
1248 channel->vpid = extractULONG();
1249 channel->numAPids = extractULONG();
1251 for (ULONG i = 0; i < channel->numAPids; i++)
1254 newapid.pid = extractULONG();
1255 newapid.name = extractString();
1256 channel->apids.push_back(newapid);
1260 MUTEX_UNLOCK(&mutex);