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::getImageBlock(ULONG position, UINT maxAmount, UINT* amountReceived)
609 return getBlock(position, maxAmount, amountReceived, VDR_GETIMAGEBLOCK);
612 UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived)
614 return getBlock(position, maxAmount, amountReceived, VDR_GETBLOCK);
617 UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived, ULONG cmd)
621 *(unsigned long*)&buffer[0] = htonl(16);
622 *(unsigned long*)&buffer[4] = htonl(cmd);
623 *(ULLONG*)&buffer[8] = htonll(position);
624 *(unsigned long*)&buffer[16] = htonl(maxAmount);
627 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
629 int a = tcp->sendPacket(buffer, 20);
633 MUTEX_UNLOCK(&mutex);
639 MUTEX_UNLOCK(&mutex);
645 Log::getInstance()->log("VDR", Log::DEBUG, "Detected getblock 0");
647 MUTEX_UNLOCK(&mutex);
651 UCHAR* toReturn = packet;
652 *amountReceived = packetLength;
653 // Manually clean up instead of running freePacket to keep the block
657 MUTEX_UNLOCK(&mutex);
663 ULLONG VDR::streamRecording(char* fileName, ULONG* totalFrames)
665 unsigned long totalLength = 8 + strlen(fileName) + 1;
666 UCHAR* buffer = new UCHAR[totalLength];
668 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
669 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
670 strcpy((char*)&buffer[8], fileName);
673 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
675 unsigned int a = tcp->sendPacket(buffer, totalLength);
678 if (a != totalLength)
681 MUTEX_UNLOCK(&mutex);
687 MUTEX_UNLOCK(&mutex);
691 ULLONG lengthBytes = extractULLONG();
692 ULONG lengthFrames = extractULONG();
694 MUTEX_UNLOCK(&mutex);
696 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu %lu", lengthBytes, lengthFrames);
698 *totalFrames = lengthFrames;
702 ULLONG VDR::positionFromFrameNumber(ULONG frameNumber)
704 unsigned long totalLength = 12;
705 UCHAR* buffer = new UCHAR[totalLength];
707 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
708 *(unsigned long*)&buffer[4] = htonl(VDR_POSFROMFRAME);
709 *(unsigned long*)&buffer[8] = htonl(frameNumber);
712 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
714 unsigned int a = tcp->sendPacket(buffer, totalLength);
717 if (a != totalLength)
720 MUTEX_UNLOCK(&mutex);
726 MUTEX_UNLOCK(&mutex);
730 ULLONG position = extractULLONG();
732 MUTEX_UNLOCK(&mutex);
734 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said new position is: %llu", position);
739 ULONG VDR::frameNumberFromPosition(ULLONG position)
741 unsigned long totalLength = 16;
742 UCHAR* buffer = new UCHAR[totalLength];
744 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
745 *(unsigned long*)&buffer[4] = htonl(VDR_FRAMEFROMPOS);
746 *(ULLONG*)&buffer[8] = htonll(position);
749 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
751 unsigned int a = tcp->sendPacket(buffer, totalLength);
754 if (a != totalLength)
757 MUTEX_UNLOCK(&mutex);
763 MUTEX_UNLOCK(&mutex);
767 ULONG framenumber = extractULONG();
769 MUTEX_UNLOCK(&mutex);
771 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said new framenumber is: %u", framenumber);
776 bool VDR::getNextIFrame(ULONG frameNumber, ULONG direction, ULLONG* rfilePosition, ULONG* rframeNumber, ULONG* rframeLength)
778 unsigned long totalLength = 16;
779 UCHAR* buffer = new UCHAR[totalLength];
781 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
782 *(unsigned long*)&buffer[4] = htonl(VDR_GETNEXTIFRAME);
783 *(unsigned long*)&buffer[8] = htonl(frameNumber);
784 *(unsigned long*)&buffer[12] = htonl(direction);
787 if (!connected) { MUTEX_UNLOCK(&mutex); return false; }
789 unsigned int a = tcp->sendPacket(buffer, totalLength);
792 if (a != totalLength)
795 MUTEX_UNLOCK(&mutex);
801 MUTEX_UNLOCK(&mutex);
807 Log::getInstance()->log("VDR", Log::DEBUG, "Detected getNextIFrame error");
809 MUTEX_UNLOCK(&mutex);
813 *rfilePosition = extractULLONG();
814 *rframeNumber = extractULONG();
815 *rframeLength = extractULONG();
818 MUTEX_UNLOCK(&mutex);
820 // Log::getInstance()->log("VDR", Log::DEBUG, "VDR GNIF said %llu %lu %lu", *rfilePosition, *rframeNumber, *rframeLength);
825 EventList* VDR::getChannelSchedule(ULONG number)
829 return getChannelSchedule(number, now, 24 * 60 * 60);
832 EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
834 // retrieve event list (vector of events) from vdr within filter window. duration is in seconds
837 *(unsigned long*)&buffer[0] = htonl(16);
838 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
839 *(unsigned long*)&buffer[8] = htonl(number);
840 *(unsigned long*)&buffer[12] = htonl(start);
841 *(unsigned long*)&buffer[16] = htonl(duration);
844 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
846 int a = tcp->sendPacket(buffer, 20);
851 MUTEX_UNLOCK(&mutex);
857 MUTEX_UNLOCK(&mutex);
861 // received a ulong(0) - schedules error in the plugin
865 MUTEX_UNLOCK(&mutex);
869 EventList* eventList = new EventList();
871 while (packetPos < packetLength)
873 Event* event = new Event();
874 event->id = extractULONG();
875 event->time = extractULONG();
876 event->duration = extractULONG();
877 event->title = extractString();
878 event->subtitle = extractString();
879 event->description = extractString();
880 eventList->push_back(event);
884 MUTEX_UNLOCK(&mutex);
886 Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule");
890 int VDR::configSave(char* section, char* key, const char* value)
892 ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
893 UCHAR* buffer = new UCHAR[totalLength];
895 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
896 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
899 strcpy((char*)&buffer[position], section);
900 position += strlen(section) + 1;
901 strcpy((char*)&buffer[position], key);
902 position += strlen(key) + 1;
903 strcpy((char*)&buffer[position], value);
906 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
908 unsigned int a = tcp->sendPacket(buffer, totalLength);
911 if (a != totalLength)
914 MUTEX_UNLOCK(&mutex);
920 MUTEX_UNLOCK(&mutex);
924 int toReturn = (int)extractULONG();
926 MUTEX_UNLOCK(&mutex);
931 char* VDR::configLoad(char* section, char* key)
933 ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
934 UCHAR* buffer = new UCHAR[totalLength];
936 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
937 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
940 strcpy((char*)&buffer[position], section);
941 position += strlen(section) + 1;
942 strcpy((char*)&buffer[position], key);
945 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
947 unsigned int a = tcp->sendPacket(buffer, totalLength);
950 if (a != totalLength)
953 MUTEX_UNLOCK(&mutex);
959 MUTEX_UNLOCK(&mutex);
962 char* toReturn = extractString();
964 MUTEX_UNLOCK(&mutex);
969 RecTimerList* VDR::getRecTimersList()
973 *(unsigned long*)&buffer[0] = htonl(4);
974 *(unsigned long*)&buffer[4] = htonl(VDR_GETTIMERS);
977 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
979 int a = tcp->sendPacket(buffer, 8);
983 MUTEX_UNLOCK(&mutex);
991 MUTEX_UNLOCK(&mutex);
995 RecTimerList* recTimerList = new RecTimerList();
997 ULONG numTimers = extractULONG();
1000 RecTimer* newRecTimer;
1003 while (packetPos < packetLength)
1005 newRecTimer = new RecTimer();
1006 newRecTimer->active = extractULONG();
1007 newRecTimer->recording = extractULONG();
1008 newRecTimer->pending = extractULONG();
1009 newRecTimer->priority = extractULONG();
1010 newRecTimer->lifeTime = extractULONG();
1011 newRecTimer->channelNumber = extractULONG();
1012 newRecTimer->startTime = extractULONG();
1013 newRecTimer->stopTime = extractULONG();
1015 tempString = extractString();
1016 newRecTimer->setFile(tempString);
1017 delete[] tempString;
1019 recTimerList->push_back(newRecTimer);
1020 Log::getInstance()->log("VDR", Log::DEBUG, "TL: %lu %lu %lu %lu %lu %lu %lu %lu %s",
1021 newRecTimer->active, newRecTimer->recording, newRecTimer->pending, newRecTimer->priority, newRecTimer->lifeTime,
1022 newRecTimer->channelNumber, newRecTimer->startTime, newRecTimer->stopTime, newRecTimer->getFile());
1027 MUTEX_UNLOCK(&mutex);
1029 sort(recTimerList->begin(), recTimerList->end(), RecTimerSorter());
1031 return recTimerList;
1034 ULONG VDR::setEventTimer(char* timerString)
1036 unsigned long totalLength = 8 + strlen(timerString) + 1;
1037 UCHAR* buffer = new UCHAR[totalLength];
1039 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1040 *(unsigned long*)&buffer[4] = htonl(VDR_SETTIMER);
1041 strcpy((char*)&buffer[8], timerString);
1044 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
1046 unsigned int a = tcp->sendPacket(buffer, totalLength);
1049 if (a != totalLength)
1052 MUTEX_UNLOCK(&mutex);
1058 MUTEX_UNLOCK(&mutex);
1062 ULONG toReturn = extractULONG();
1064 MUTEX_UNLOCK(&mutex);
1069 RecInfo* VDR::getRecInfo(char* fileName)
1071 unsigned long totalLength = 8 + strlen(fileName) + 1;
1072 UCHAR* buffer = new UCHAR[totalLength];
1074 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1075 *(unsigned long*)&buffer[4] = htonl(VDR_GETRECINFO);
1076 strcpy((char*)&buffer[8], fileName);
1079 if (!connected) { MUTEX_UNLOCK(&mutex); return NULL; }
1081 unsigned int a = tcp->sendPacket(buffer, totalLength);
1084 if (a != totalLength)
1087 MUTEX_UNLOCK(&mutex);
1093 MUTEX_UNLOCK(&mutex);
1099 Log::getInstance()->log("VDR", Log::DEBUG, "Could not get rec info");
1101 MUTEX_UNLOCK(&mutex);
1105 TCP::dump(packet, packetLength);
1107 RecInfo* recInfo = new RecInfo();
1109 recInfo->timerStart = extractULONG();
1110 recInfo->timerEnd = extractULONG();
1111 recInfo->resumePoint = extractULONG();
1112 recInfo->summary = extractString();
1114 ULONG numComponents = extractULONG();
1117 recInfo->setNumComponents(numComponents);
1118 for (ULONG i = 0; i < numComponents; i++)
1120 recInfo->streams[i] = extractUCHAR();
1121 recInfo->types[i] = extractUCHAR();
1122 recInfo->languages[i] = extractString();
1123 recInfo->descriptions[i] = extractString();
1130 MUTEX_UNLOCK(&mutex);
1135 ULLONG VDR::rescanRecording(ULONG* totalFrames)
1137 unsigned long totalLength = 8;
1138 UCHAR* buffer = new UCHAR[totalLength];
1140 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1141 *(unsigned long*)&buffer[4] = htonl(VDR_RESCANRECORDING);
1144 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
1146 unsigned int a = tcp->sendPacket(buffer, totalLength);
1149 if (a != totalLength)
1152 MUTEX_UNLOCK(&mutex);
1158 MUTEX_UNLOCK(&mutex);
1162 ULLONG lengthBytes = extractULLONG();
1163 ULONG lengthFrames = extractULONG();
1165 MUTEX_UNLOCK(&mutex);
1167 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu %lu", lengthBytes, lengthFrames);
1169 *totalFrames = lengthFrames;
1173 MarkList* VDR::getMarks(char* fileName)
1175 unsigned long totalLength = 8 + strlen(fileName) + 1;
1176 UCHAR* buffer = new UCHAR[totalLength];
1178 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1179 *(unsigned long*)&buffer[4] = htonl(VDR_GETMARKS);
1180 strcpy((char*)&buffer[8], fileName);
1183 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
1185 unsigned int a = tcp->sendPacket(buffer, totalLength);
1188 if (a != totalLength)
1191 MUTEX_UNLOCK(&mutex);
1197 MUTEX_UNLOCK(&mutex);
1203 MUTEX_UNLOCK(&mutex);
1207 MarkList* markList = new MarkList();
1209 while (packetPos < packetLength)
1211 Mark* mark = new Mark();
1212 mark->pos = extractULONG();
1214 markList->push_back(mark);
1215 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a mark to list. %lu", mark->pos);
1219 MUTEX_UNLOCK(&mutex);
1224 void VDR::getChannelPids(Channel* channel)
1228 *(unsigned long*)&buffer[0] = htonl(8);
1229 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELPIDS);
1230 *(unsigned long*)&buffer[8] = htonl(channel->number);
1233 if (!connected) { MUTEX_UNLOCK(&mutex); return ; }
1235 int a = tcp->sendPacket(buffer, 12);
1240 MUTEX_UNLOCK(&mutex);
1246 MUTEX_UNLOCK(&mutex);
1250 // Format of response
1258 channel->vpid = extractULONG();
1259 channel->numAPids = extractULONG();
1261 for (ULONG i = 0; i < channel->numAPids; i++)
1264 newapid.pid = extractULONG();
1265 newapid.name = extractString();
1266 channel->apids.push_back(newapid);
1270 MUTEX_UNLOCK(&mutex);
1276 * media List Request:
1278 * 4 VDR_GETMEDIALIST
1279 * 4 flags (currently unused)
1282 * Media List response:
1290 * 4 strlen (incl. 0 Byte)
1294 MediaList* VDR::getMediaList(const char* parent,int mediaType)
1296 Log::getInstance()->log("VDR", Log::DEBUG, "getMediaList %s,type=%d",
1297 (parent?parent:"NULL"), mediaType);
1298 unsigned long totalLength = 12;
1299 if (parent) totalLength+=strlen(parent) + 1;
1300 UCHAR* buffer = new UCHAR[totalLength];
1302 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1303 *(unsigned long*)&buffer[4] = htonl(VDR_GETMEDIALIST);
1305 for (int i=8;i<12;i++) buffer[i]=0;
1308 strcpy((char*)&buffer[12], parent);
1309 buffer[totalLength-1]=0;
1312 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
1314 unsigned int a = tcp->sendPacket(buffer, totalLength);
1317 if (a != totalLength)
1320 MUTEX_UNLOCK(&mutex);
1326 MUTEX_UNLOCK(&mutex);
1332 MUTEX_UNLOCK(&mutex);
1335 if (packetLength < 12) {
1336 Log::getInstance()->log("VDR", Log::ERR, "receiveMediaList packet too short, expected 12, got %d", packetLength);
1338 MUTEX_UNLOCK(&mutex);
1341 MediaList* mediaList = new MediaList();
1343 code=extractULONG();
1344 ULONG numEntries=extractULONG();
1345 Log::getInstance()->log("VDR", Log::DEBUG, "receiveMediaList with %d entries",numEntries);
1346 while (packetPos < packetLength && numEntries >0)
1348 Media* m = new Media();
1349 ULONG mtype = extractULONG();
1350 ULONG mtime=extractULONG();
1352 flags=extractULONG();
1353 ULONG stsize=extractULONG();
1354 char * name=extractString();
1355 if (! name || stsize != (strlen(name)+1)) {
1356 Log::getInstance()->log("VDR", Log::ERR, "receiveMediaList invalid packet entry, read size %d, strlen %d", stsize, strlen(name)+1);
1360 MUTEX_UNLOCK(&mutex);
1363 //ignore . and .. entries
1364 if (strcmp(name,".") == 0 || strcmp(name,"..")==0) {
1368 m->setFileName(name);
1370 m->setMediaType(mtype);
1371 mediaList->push_back(m);
1372 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a media to list. %s, type=%d, time=%d", name,mtype,mtime);
1377 MUTEX_UNLOCK(&mutex);
1382 * get image Request:
1385 * 4 flags (currently unused)
1390 * get image response:
1395 ULONG VDR::loadImage(const char* fileName, ULONG x, ULONG y)
1397 unsigned long totalLength = 20 + strlen(fileName) + 1;
1398 UCHAR* buffer = new UCHAR[totalLength];
1400 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
1401 *(unsigned long*)&buffer[4] = htonl(VDR_GETIMAGE);
1402 *(unsigned long*)&buffer[8] = htonl(0);
1403 *(unsigned long*)&buffer[8] = htonl(x);
1404 *(unsigned long*)&buffer[8] = htonl(y);
1405 strcpy((char*)&buffer[12], fileName);
1408 if (!connected) { MUTEX_UNLOCK(&mutex); return 0; }
1410 unsigned int a = tcp->sendPacket(buffer, totalLength);
1413 if (a != totalLength)
1416 MUTEX_UNLOCK(&mutex);
1422 MUTEX_UNLOCK(&mutex);
1427 ULONG lengthBytes = extractULONG();
1429 MUTEX_UNLOCK(&mutex);
1431 Log::getInstance()->log("VDR", Log::DEBUG, "getImage %s: %lu", fileName,lengthBytes);