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, "Data length %u", dataLength);
165 tLength = strlen((char*)&p[count]);
166 returnText = new char[tLength + 1];
167 strcpy(returnText, (char*)&p[count]);
168 count += tLength + 1;
175 /////////////////////////////////////////////////////////////////////////////
181 *(unsigned long*)&buffer[0] = htonl(4);
182 *(unsigned long*)&buffer[4] = htonl(VDR_LOGIN);
184 pthread_mutex_lock(&mutex);
185 int a = tcp->sendPacket(buffer, 8);
188 pthread_mutex_unlock(&mutex);
194 UCHAR* p = tcp->receivePacket();
195 pthread_mutex_unlock(&mutex);
200 unsigned long vdrTime = ntohl(*(unsigned long*)&p[count]);
201 count += sizeof(unsigned long);
202 Log::getInstance()->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime);
204 struct timespec currentTime;
205 currentTime.tv_sec = vdrTime;
206 currentTime.tv_nsec = 0;
207 int b = clock_settime(CLOCK_REALTIME, ¤tTime);
209 Log::getInstance()->log("VDR", Log::DEBUG, "set clock = %u", b);
211 // now make a TZ variable and set it
212 signed int vdrTimeOffset = ntohl(*(signed int*)&p[count]);
213 Log::getInstance()->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
218 if (vdrTimeOffset > 0) sign = '-';
221 vdrTimeOffset = abs(vdrTimeOffset);
223 hours = (int)vdrTimeOffset / 3600;
224 minutes = vdrTimeOffset % 3600;
226 Log::getInstance()->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
228 minutes = (int)minutes / 60;
230 Log::getInstance()->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
233 sprintf(newTZ, "MVP%c%i:%i", sign, hours, minutes);
234 setenv("TZ", newTZ, 1);
236 Log::getInstance()->log("VDR", Log::DEBUG, "Timezone data: %s", newTZ);
242 Directory* VDR::getRecordingsList()
246 *(unsigned long*)&buffer[0] = htonl(4);
247 *(unsigned long*)&buffer[4] = htonl(VDR_GETRECORDINGLIST);
249 pthread_mutex_lock(&mutex);
250 int a = tcp->sendPacket(buffer, 8);
253 pthread_mutex_unlock(&mutex);
259 unsigned char* p = (unsigned char*)tcp->receivePacket();
260 pthread_mutex_unlock(&mutex);
263 Directory* recDir = new Directory();
264 recDir->setName("/");
267 int dataLength = tcp->getDataLength();
269 Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
273 Directory::totalSpace = (*(ULONG*)&p[count]);
274 count += sizeof(ULONG);
275 Directory::freeSpace = (*(ULONG*)&p[count]);
276 count += sizeof(ULONG);
277 Directory::usedPercent = (*(ULONG*)&p[count]);
278 count += sizeof(ULONG);
282 while (count < dataLength)
284 Recording* rec = new Recording();
285 rec->start = ntohl(*(unsigned long*)&p[count]);
288 tLength = strlen((char*)&p[count]);
289 rec->setName((char*)&p[count]);
291 // rec->name = new char[tLength + 1];
292 // strcpy(rec->name, (char*)&p[count]);
293 count += tLength + 1;
295 tLength = strlen((char*)&p[count]);
296 rec->fileName = new char[tLength + 1];
297 strcpy(rec->fileName, (char*)&p[count]);
298 count += tLength + 1;
302 char* dirName = rec->getDirName();
304 Directory* d = recDir->getDirByName(dirName);
309 Log::getInstance()->log("VDR", Log::DEBUG, "Added a new directory = %s", d->name);
310 recDir->dirList->add(d);
313 d->recList->add(rec);
318 recDir->recList->add(rec);
319 recDir->recList->next();
322 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a recording to list. %lu %s", rec->start, rec->getProgName());
330 int VDR::deleteRecording(char* fileName)
332 unsigned long totalLength = 8 + strlen(fileName) + 1;
333 UCHAR buffer[totalLength];
335 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
336 *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING);
337 strcpy((char*)&buffer[8], fileName);
339 pthread_mutex_lock(&mutex);
340 unsigned int a = tcp->sendPacket(buffer, totalLength);
341 if (a != totalLength)
343 pthread_mutex_unlock(&mutex);
347 int toReturn = getSimpleReply();
348 pthread_mutex_unlock(&mutex);
352 char* VDR::getRecordingSummary(char* fileName)
354 unsigned long totalLength = 8 + strlen(fileName) + 1;
355 UCHAR buffer[totalLength];
357 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
358 *(unsigned long*)&buffer[4] = htonl(VDR_GETSUMMARY);
359 strcpy((char*)&buffer[8], fileName);
361 pthread_mutex_lock(&mutex);
362 unsigned int a = tcp->sendPacket(buffer, totalLength);
363 if (a != totalLength)
365 pthread_mutex_unlock(&mutex);
369 char* toReturn = getStringReply();
370 pthread_mutex_unlock(&mutex);
374 List* VDR::getChannelsList(ULONG type)
378 *(unsigned long*)&buffer[0] = htonl(4);
379 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST);
381 pthread_mutex_lock(&mutex);
382 int a = tcp->sendPacket(buffer, 8);
385 pthread_mutex_unlock(&mutex);
391 unsigned char* p = (unsigned char*)tcp->receivePacket();
392 pthread_mutex_unlock(&mutex);
395 List* chanList = new List();
397 int dataLength = tcp->getDataLength();
399 Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
405 while (count < dataLength)
407 Channel* chan = new Channel();
408 chan->number = ntohl(*(unsigned long*)&p[count]);
410 chan->type = ntohl(*(unsigned long*)&p[count]);
413 tLength = strlen((char*)&p[count]);
414 chan->name = new char[tLength + 1];
415 strcpy(chan->name, (char*)&p[count]);
416 count += tLength + 1;
418 if (chan->type == type)
422 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
435 int VDR::streamChannel(ULONG number)
439 *(unsigned long*)&buffer[0] = htonl(8);
440 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL);
441 *(unsigned long*)&buffer[8] = htonl(number);
443 pthread_mutex_lock(&mutex);
444 int a = tcp->sendPacket(buffer, 12);
448 pthread_mutex_unlock(&mutex);
452 int toReturn = getSimpleReply();
453 pthread_mutex_unlock(&mutex);
457 int VDR::stopStreaming()
461 *(unsigned long*)&buffer[0] = htonl(4);
462 *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING);
464 pthread_mutex_lock(&mutex);
465 int a = tcp->sendPacket(buffer, 8);
469 pthread_mutex_unlock(&mutex);
473 int toReturn = getSimpleReply();
474 pthread_mutex_unlock(&mutex);
478 int VDR::getBlock(UCHAR* buf, ULLONG position, int amount)
482 *(unsigned long*)&buffer[0] = htonl(16);
483 *(unsigned long*)&buffer[4] = htonl(VDR_GETBLOCK);
484 *(ULLONG*)&buffer[8] = htonll(position);
485 *(unsigned long*)&buffer[16] = htonl(amount);
487 pthread_mutex_lock(&mutex);
488 int a = tcp->sendPacket(buffer, 20);
491 pthread_mutex_unlock(&mutex);
495 unsigned char* p = (unsigned char*)tcp->receivePacket();
496 pthread_mutex_unlock(&mutex);
498 int dataLength = tcp->getDataLength();
500 memcpy(buf, p, dataLength);
505 ULLONG VDR::streamRecording(Recording* rec)
507 unsigned long totalLength = 8 + strlen(rec->fileName) + 1;
508 UCHAR buffer[totalLength];
510 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
511 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
512 strcpy((char*)&buffer[8], rec->fileName);
514 pthread_mutex_lock(&mutex);
515 unsigned int a = tcp->sendPacket(buffer, totalLength);
516 if (a != totalLength)
518 pthread_mutex_unlock(&mutex);
522 unsigned char* p = (unsigned char*)tcp->receivePacket();
523 pthread_mutex_unlock(&mutex);
526 if (tcp->getDataLength() != 8)
532 ULLONG recordingLength = ntohll(*(ULLONG*)p);
534 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
537 return recordingLength;
540 int VDR::getChannelSchedule(ULONG number)
544 *(unsigned long*)&buffer[0] = htonl(8);
545 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
546 *(unsigned long*)&buffer[8] = htonl(number);
548 pthread_mutex_lock(&mutex);
549 int a = tcp->sendPacket(buffer, 12);
553 pthread_mutex_unlock(&mutex);
557 unsigned char* p = (unsigned char*)tcp->receivePacket();
558 pthread_mutex_unlock(&mutex);
561 int dataLength = tcp->getDataLength();
569 ULONG data = ntohl(*(ULONG*)p);
572 Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule %lu", data);
577 ULLONG VDR::getResumePoint(char* fileName)
579 char* resumeString = configLoad("ResumeData", fileName);
580 if (!resumeString) return 0;
582 ULLONG toReturn = strtoull(resumeString, NULL, 10);
583 delete[] resumeString;
587 int VDR::configSave(char* section, char* key, char* value)
589 ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
590 UCHAR buffer[totalLength];
592 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
593 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
596 strcpy((char*)&buffer[position], section);
597 position += strlen(section) + 1;
598 strcpy((char*)&buffer[position], key);
599 position += strlen(key) + 1;
600 strcpy((char*)&buffer[position], value);
602 pthread_mutex_lock(&mutex);
603 unsigned int a = tcp->sendPacket(buffer, totalLength);
604 if (a != totalLength)
606 pthread_mutex_unlock(&mutex);
610 int toReturn = getSimpleReply();
611 pthread_mutex_unlock(&mutex);
615 char* VDR::configLoad(char* section, char* key)
617 ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
618 UCHAR buffer[totalLength];
620 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
621 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
624 strcpy((char*)&buffer[position], section);
625 position += strlen(section) + 1;
626 strcpy((char*)&buffer[position], key);
628 pthread_mutex_lock(&mutex);
629 unsigned int a = tcp->sendPacket(buffer, totalLength);
630 if (a != totalLength)
632 pthread_mutex_unlock(&mutex);
636 char* toReturn = getStringReply();
637 pthread_mutex_unlock(&mutex);