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
23 VDR* VDR::instance = NULL;
32 pthread_mutex_init(&mutex, NULL);
38 if (initted) shutdown();
41 VDR* VDR::getInstance()
46 int VDR::init(int tport)
48 if (initted) return 0;
51 logger = Log::getInstance();
57 if (!initted) return 0;
63 void VDR::findServers(std::vector<char*>& serverIPs)
66 char* message = "VOMP CLIENT";
67 DatagramSocket ds(port);
69 int haveAtLeastOne = 0;
77 logger->log("VDR", Log::NOTICE, "Broadcasting for server");
78 ds.send("255.255.255.255", 3024, message, strlen(message));
80 retval = ds.waitforMessage(waitType);
82 if (retval == 2) // we got a reply
84 if (strcmp(ds.getData(), "VOMP SERVER")) // echo.....
91 strcpy(newIP, ds.getFromIPA());
92 serverIPs.push_back(newIP);
99 if (haveAtLeastOne) break;
105 void VDR::cancelFindingServer()
110 void VDR::setServerIP(char* newIP)
112 strcpy(serverIP, newIP);
119 return tcp->connectTo(serverIP, 3024);
122 void VDR::disconnect()
126 Log::getInstance()->log("VDR", Log::DEBUG, "Disconnect");
129 long VDR::getSimpleReply()
131 unsigned char* p = (unsigned char*)tcp->receivePacket();
134 Log::getInstance()->log("VDR", Log::DEBUG, "tcp data length = %i", tcp->getDataLength());
136 if (tcp->getDataLength() != 4)
142 ULONG reply = ntohl(*(ULONG*)p);
144 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said %li", reply);
151 char* VDR::getStringReply()
153 unsigned char* p = (unsigned char*)tcp->receivePacket();
156 int dataLength = tcp->getDataLength();
158 // Log::getInstance()->log("VDR", Log::DEBUG, "GSR Data length %u", dataLength);
160 if ((dataLength == 4) && (p[0] == '\0'))
162 Log::getInstance()->log("VDR", Log::DEBUG, "GSR returning null no string returned");
164 return NULL; // no string returned
170 tLength = strlen((char*)p);
171 returnText = new char[tLength + 1];
172 strcpy(returnText, (char*)p);
179 /////////////////////////////////////////////////////////////////////////////
185 *(unsigned long*)&buffer[0] = htonl(4);
186 *(unsigned long*)&buffer[4] = htonl(VDR_LOGIN);
188 pthread_mutex_lock(&mutex);
189 int a = tcp->sendPacket(buffer, 8);
192 pthread_mutex_unlock(&mutex);
198 UCHAR* p = tcp->receivePacket();
199 pthread_mutex_unlock(&mutex);
204 unsigned long vdrTime = ntohl(*(unsigned long*)&p[count]);
205 count += sizeof(unsigned long);
206 Log::getInstance()->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime);
208 struct timespec currentTime;
209 currentTime.tv_sec = vdrTime;
210 currentTime.tv_nsec = 0;
211 int b = clock_settime(CLOCK_REALTIME, ¤tTime);
213 Log::getInstance()->log("VDR", Log::DEBUG, "set clock = %u", b);
215 // now make a TZ variable and set it
216 signed int vdrTimeOffset = ntohl(*(signed int*)&p[count]);
217 Log::getInstance()->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
222 if (vdrTimeOffset > 0) sign = '-';
225 vdrTimeOffset = abs(vdrTimeOffset);
227 hours = (int)vdrTimeOffset / 3600;
228 minutes = vdrTimeOffset % 3600;
230 Log::getInstance()->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
232 minutes = (int)minutes / 60;
234 Log::getInstance()->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
237 sprintf(newTZ, "MVP%c%i:%i", sign, hours, minutes);
238 setenv("TZ", newTZ, 1);
240 Log::getInstance()->log("VDR", Log::DEBUG, "Timezone data: %s", newTZ);
246 Directory* VDR::getRecordingsList()
250 *(unsigned long*)&buffer[0] = htonl(4);
251 *(unsigned long*)&buffer[4] = htonl(VDR_GETRECORDINGLIST);
253 pthread_mutex_lock(&mutex);
254 int a = tcp->sendPacket(buffer, 8);
257 pthread_mutex_unlock(&mutex);
263 unsigned char* p = (unsigned char*)tcp->receivePacket();
264 pthread_mutex_unlock(&mutex);
267 Directory* recDir = new Directory();
268 recDir->setName("/");
271 int dataLength = tcp->getDataLength();
273 Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
277 Directory::totalSpace = (*(ULONG*)&p[count]);
278 count += sizeof(ULONG);
279 Directory::freeSpace = (*(ULONG*)&p[count]);
280 count += sizeof(ULONG);
281 Directory::usedPercent = (*(ULONG*)&p[count]);
282 count += sizeof(ULONG);
286 while (count < dataLength)
288 Recording* rec = new Recording();
289 rec->start = ntohl(*(unsigned long*)&p[count]);
292 tLength = strlen((char*)&p[count]);
293 rec->setName((char*)&p[count]);
295 // rec->name = new char[tLength + 1];
296 // strcpy(rec->name, (char*)&p[count]);
297 count += tLength + 1;
299 tLength = strlen((char*)&p[count]);
300 rec->fileName = new char[tLength + 1];
301 strcpy(rec->fileName, (char*)&p[count]);
302 count += tLength + 1;
306 char* dirName = rec->getDirName();
308 Directory* d = recDir->getDirByName(dirName);
313 Log::getInstance()->log("VDR", Log::DEBUG, "Added a new directory = %s", d->name);
314 recDir->dirList->add(d);
317 d->recList->add(rec);
322 recDir->recList->add(rec);
323 recDir->recList->next();
326 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a recording to list. %lu %s", rec->start, rec->getProgName());
334 int VDR::deleteRecording(char* fileName)
336 unsigned long totalLength = 8 + strlen(fileName) + 1;
337 UCHAR buffer[totalLength];
339 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
340 *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING);
341 strcpy((char*)&buffer[8], fileName);
343 pthread_mutex_lock(&mutex);
344 unsigned int a = tcp->sendPacket(buffer, totalLength);
345 if (a != totalLength)
347 pthread_mutex_unlock(&mutex);
351 int toReturn = getSimpleReply();
352 if (toReturn == -1) toReturn = 0; // error is same as 0=bad in this case
353 pthread_mutex_unlock(&mutex);
357 char* VDR::getRecordingSummary(char* fileName)
359 unsigned long totalLength = 8 + strlen(fileName) + 1;
360 UCHAR buffer[totalLength];
362 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
363 *(unsigned long*)&buffer[4] = htonl(VDR_GETSUMMARY);
364 strcpy((char*)&buffer[8], fileName);
366 pthread_mutex_lock(&mutex);
367 unsigned int a = tcp->sendPacket(buffer, totalLength);
368 if (a != totalLength)
370 pthread_mutex_unlock(&mutex);
374 char* toReturn = getStringReply();
375 pthread_mutex_unlock(&mutex);
379 List* VDR::getChannelsList(ULONG type)
383 *(unsigned long*)&buffer[0] = htonl(4);
384 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST);
386 pthread_mutex_lock(&mutex);
387 int a = tcp->sendPacket(buffer, 8);
390 pthread_mutex_unlock(&mutex);
396 unsigned char* p = (unsigned char*)tcp->receivePacket();
397 pthread_mutex_unlock(&mutex);
400 List* chanList = new List();
402 int dataLength = tcp->getDataLength();
404 Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
410 while (count < dataLength)
412 Channel* chan = new Channel();
413 chan->number = ntohl(*(unsigned long*)&p[count]);
415 chan->type = ntohl(*(unsigned long*)&p[count]);
418 tLength = strlen((char*)&p[count]);
419 chan->name = new char[tLength + 1];
420 strcpy(chan->name, (char*)&p[count]);
421 count += tLength + 1;
423 if (chan->type == type)
427 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
440 int VDR::streamChannel(ULONG number)
444 *(unsigned long*)&buffer[0] = htonl(8);
445 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL);
446 *(unsigned long*)&buffer[8] = htonl(number);
448 pthread_mutex_lock(&mutex);
449 int a = tcp->sendPacket(buffer, 12);
453 pthread_mutex_unlock(&mutex);
457 int toReturn = getSimpleReply();
458 if (toReturn == -1) toReturn = 0; // change error to bad
459 pthread_mutex_unlock(&mutex);
463 int VDR::stopStreaming()
467 *(unsigned long*)&buffer[0] = htonl(4);
468 *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING);
470 pthread_mutex_lock(&mutex);
471 int a = tcp->sendPacket(buffer, 8);
475 pthread_mutex_unlock(&mutex);
479 int toReturn = getSimpleReply();
480 if (toReturn == -1) toReturn = 0; // change error to bad
481 pthread_mutex_unlock(&mutex);
485 UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived)
489 *(unsigned long*)&buffer[0] = htonl(16);
490 *(unsigned long*)&buffer[4] = htonl(VDR_GETBLOCK);
491 *(ULLONG*)&buffer[8] = htonll(position);
492 *(unsigned long*)&buffer[16] = htonl(maxAmount);
494 pthread_mutex_lock(&mutex);
495 int a = tcp->sendPacket(buffer, 20);
498 pthread_mutex_unlock(&mutex);
502 unsigned char* p = (unsigned char*)tcp->receivePacket();
503 pthread_mutex_unlock(&mutex);
505 *amountReceived = tcp->getDataLength();
509 ULLONG VDR::streamRecording(Recording* rec)
511 unsigned long totalLength = 8 + strlen(rec->fileName) + 1;
512 UCHAR buffer[totalLength];
514 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
515 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
516 strcpy((char*)&buffer[8], rec->fileName);
518 pthread_mutex_lock(&mutex);
519 unsigned int a = tcp->sendPacket(buffer, totalLength);
520 if (a != totalLength)
522 pthread_mutex_unlock(&mutex);
526 unsigned char* p = (unsigned char*)tcp->receivePacket();
527 pthread_mutex_unlock(&mutex);
530 if (tcp->getDataLength() != 8)
536 ULLONG recordingLength = ntohll(*(ULLONG*)p);
538 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
541 return recordingLength;
544 ULLONG VDR::rescanRecording()
546 unsigned long totalLength = 8;
547 UCHAR buffer[totalLength];
549 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
550 *(unsigned long*)&buffer[4] = htonl(VDR_RESCANRECORDING);
552 pthread_mutex_lock(&mutex);
553 unsigned int a = tcp->sendPacket(buffer, totalLength);
554 if (a != totalLength)
556 pthread_mutex_unlock(&mutex);
560 unsigned char* p = (unsigned char*)tcp->receivePacket();
561 pthread_mutex_unlock(&mutex);
564 if (tcp->getDataLength() != 8)
570 ULLONG recordingLength = ntohll(*(ULLONG*)p);
572 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
575 return recordingLength;
578 int VDR::getChannelSchedule(ULONG number)
582 *(unsigned long*)&buffer[0] = htonl(8);
583 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
584 *(unsigned long*)&buffer[8] = htonl(number);
586 pthread_mutex_lock(&mutex);
587 int a = tcp->sendPacket(buffer, 12);
591 pthread_mutex_unlock(&mutex);
595 unsigned char* p = (unsigned char*)tcp->receivePacket();
596 pthread_mutex_unlock(&mutex);
599 int dataLength = tcp->getDataLength();
607 ULONG data = ntohl(*(ULONG*)p);
610 Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule %lu", data);
615 ULLONG VDR::getResumePoint(char* fileName)
617 char* resumeString = configLoad("ResumeData", fileName);
618 if (!resumeString) return 0;
620 ULLONG toReturn = strtoull(resumeString, NULL, 10);
621 delete[] resumeString;
625 int VDR::configSave(char* section, char* key, char* value)
627 ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
628 UCHAR buffer[totalLength];
630 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
631 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
634 strcpy((char*)&buffer[position], section);
635 position += strlen(section) + 1;
636 strcpy((char*)&buffer[position], key);
637 position += strlen(key) + 1;
638 strcpy((char*)&buffer[position], value);
640 pthread_mutex_lock(&mutex);
641 unsigned int a = tcp->sendPacket(buffer, totalLength);
642 if (a != totalLength)
644 pthread_mutex_unlock(&mutex);
648 int toReturn = getSimpleReply();
649 if (toReturn == -1) toReturn = 0; // change error to bad
650 pthread_mutex_unlock(&mutex);
654 char* VDR::configLoad(char* section, char* key)
656 ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
657 UCHAR buffer[totalLength];
659 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
660 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
663 strcpy((char*)&buffer[position], section);
664 position += strlen(section) + 1;
665 strcpy((char*)&buffer[position], key);
667 pthread_mutex_lock(&mutex);
668 unsigned int a = tcp->sendPacket(buffer, totalLength);
669 if (a != totalLength)
671 pthread_mutex_unlock(&mutex);
675 char* toReturn = getStringReply();
676 pthread_mutex_unlock(&mutex);