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("Core", 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()
128 long VDR::getSimpleReply()
130 unsigned char* p = (unsigned char*)tcp->receivePacket();
133 Log::getInstance()->log("VDR", Log::DEBUG, "tcp data length = %i", tcp->getDataLength());
135 if (tcp->getDataLength() != 4)
141 ULONG reply = ntohl(*(ULONG*)p);
143 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said %li", reply);
150 char* VDR::getStringReply()
152 unsigned char* p = (unsigned char*)tcp->receivePacket();
155 int dataLength = tcp->getDataLength();
157 Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
164 tLength = strlen((char*)&p[count]);
165 returnText = new char[tLength + 1];
166 strcpy(returnText, (char*)&p[count]);
167 count += tLength + 1;
174 /////////////////////////////////////////////////////////////////////////////
180 *(unsigned long*)&buffer[0] = htonl(4);
181 *(unsigned long*)&buffer[4] = htonl(VDR_LOGIN);
183 pthread_mutex_lock(&mutex);
184 int a = tcp->sendPacket(buffer, 8);
187 pthread_mutex_unlock(&mutex);
193 UCHAR* p = tcp->receivePacket();
194 pthread_mutex_unlock(&mutex);
199 unsigned long vdrTime = ntohl(*(unsigned long*)&p[count]);
200 count += sizeof(unsigned long);
201 Log::getInstance()->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime);
203 struct timespec currentTime;
204 currentTime.tv_sec = vdrTime;
205 currentTime.tv_nsec = 0;
206 int b = clock_settime(CLOCK_REALTIME, ¤tTime);
208 Log::getInstance()->log("VDR", Log::DEBUG, "set clock = %u", b);
210 // now make a TZ variable and set it
211 signed int vdrTimeOffset = ntohl(*(signed int*)&p[count]);
212 Log::getInstance()->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
217 if (vdrTimeOffset > 0) sign = '-';
220 vdrTimeOffset = abs(vdrTimeOffset);
222 hours = (int)vdrTimeOffset / 3600;
223 minutes = vdrTimeOffset % 3600;
225 Log::getInstance()->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
227 minutes = (int)minutes / 60;
229 Log::getInstance()->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
232 sprintf(newTZ, "MVP%c%i:%i", sign, hours, minutes);
233 setenv("TZ", newTZ, 1);
235 Log::getInstance()->log("VDR", Log::DEBUG, "Timezone data: %s", newTZ);
241 Directory* VDR::getRecordingsList()
245 *(unsigned long*)&buffer[0] = htonl(4);
246 *(unsigned long*)&buffer[4] = htonl(VDR_GETRECORDINGLIST);
248 pthread_mutex_lock(&mutex);
249 int a = tcp->sendPacket(buffer, 8);
252 pthread_mutex_unlock(&mutex);
258 unsigned char* p = (unsigned char*)tcp->receivePacket();
259 pthread_mutex_unlock(&mutex);
262 Directory* recDir = new Directory();
263 recDir->setName("/");
266 int dataLength = tcp->getDataLength();
268 Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
272 Directory::totalSpace = (*(ULONG*)&p[count]);
273 count += sizeof(ULONG);
274 Directory::freeSpace = (*(ULONG*)&p[count]);
275 count += sizeof(ULONG);
276 Directory::usedPercent = (*(ULONG*)&p[count]);
277 count += sizeof(ULONG);
281 while (count < dataLength)
283 Recording* rec = new Recording();
284 rec->start = ntohl(*(unsigned long*)&p[count]);
287 tLength = strlen((char*)&p[count]);
288 rec->setName((char*)&p[count]);
290 // rec->name = new char[tLength + 1];
291 // strcpy(rec->name, (char*)&p[count]);
292 count += tLength + 1;
294 tLength = strlen((char*)&p[count]);
295 rec->fileName = new char[tLength + 1];
296 strcpy(rec->fileName, (char*)&p[count]);
297 count += tLength + 1;
301 char* dirName = rec->getDirName();
303 Directory* d = recDir->getDirByName(dirName);
308 Log::getInstance()->log("VDR", Log::DEBUG, "Added a new directory = %s", d->name);
309 recDir->dirList->add(d);
312 d->recList->add(rec);
317 recDir->recList->add(rec);
318 recDir->recList->next();
321 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a recording to list. %lu %s", rec->start, rec->getProgName());
329 int VDR::deleteRecording(char* fileName)
331 unsigned long totalLength = 8 + strlen(fileName) + 1;
332 UCHAR buffer[totalLength];
334 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
335 *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING);
336 strcpy((char*)&buffer[8], fileName);
338 pthread_mutex_lock(&mutex);
339 unsigned int a = tcp->sendPacket(buffer, totalLength);
340 if (a != totalLength)
342 pthread_mutex_unlock(&mutex);
346 int toReturn = getSimpleReply();
347 pthread_mutex_unlock(&mutex);
351 char* VDR::getRecordingSummary(char* fileName)
353 unsigned long totalLength = 8 + strlen(fileName) + 1;
354 UCHAR buffer[totalLength];
356 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
357 *(unsigned long*)&buffer[4] = htonl(VDR_GETSUMMARY);
358 strcpy((char*)&buffer[8], fileName);
360 pthread_mutex_lock(&mutex);
361 unsigned int a = tcp->sendPacket(buffer, totalLength);
362 if (a != totalLength)
364 pthread_mutex_unlock(&mutex);
368 char* toReturn = getStringReply();
369 pthread_mutex_unlock(&mutex);
373 List* VDR::getChannelsList(ULONG type)
377 *(unsigned long*)&buffer[0] = htonl(4);
378 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST);
380 pthread_mutex_lock(&mutex);
381 int a = tcp->sendPacket(buffer, 8);
384 pthread_mutex_unlock(&mutex);
390 unsigned char* p = (unsigned char*)tcp->receivePacket();
391 pthread_mutex_unlock(&mutex);
394 List* chanList = new List();
396 int dataLength = tcp->getDataLength();
398 Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
404 while (count < dataLength)
406 Channel* chan = new Channel();
407 chan->number = ntohl(*(unsigned long*)&p[count]);
409 chan->type = ntohl(*(unsigned long*)&p[count]);
412 tLength = strlen((char*)&p[count]);
413 chan->name = new char[tLength + 1];
414 strcpy(chan->name, (char*)&p[count]);
415 count += tLength + 1;
417 if (chan->type == type)
421 Log::getInstance()->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
434 int VDR::streamChannel(ULONG number)
438 *(unsigned long*)&buffer[0] = htonl(8);
439 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL);
440 *(unsigned long*)&buffer[8] = htonl(number);
442 pthread_mutex_lock(&mutex);
443 int a = tcp->sendPacket(buffer, 12);
447 pthread_mutex_unlock(&mutex);
451 int toReturn = getSimpleReply();
452 pthread_mutex_unlock(&mutex);
456 int VDR::stopStreaming()
460 *(unsigned long*)&buffer[0] = htonl(4);
461 *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING);
463 pthread_mutex_lock(&mutex);
464 int a = tcp->sendPacket(buffer, 8);
468 pthread_mutex_unlock(&mutex);
472 int toReturn = getSimpleReply();
473 pthread_mutex_unlock(&mutex);
477 int VDR::getBlock(UCHAR* buf, ULLONG position, int amount)
481 *(unsigned long*)&buffer[0] = htonl(16);
482 *(unsigned long*)&buffer[4] = htonl(VDR_GETBLOCK);
483 *(ULLONG*)&buffer[8] = htonll(position);
484 *(unsigned long*)&buffer[16] = htonl(amount);
486 pthread_mutex_lock(&mutex);
487 int a = tcp->sendPacket(buffer, 20);
490 pthread_mutex_unlock(&mutex);
494 unsigned char* p = (unsigned char*)tcp->receivePacket();
495 pthread_mutex_unlock(&mutex);
497 int dataLength = tcp->getDataLength();
499 memcpy(buf, p, dataLength);
504 ULLONG VDR::streamRecording(Recording* rec)
506 unsigned long totalLength = 8 + strlen(rec->fileName) + 1;
507 UCHAR buffer[totalLength];
509 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
510 *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
511 strcpy((char*)&buffer[8], rec->fileName);
513 pthread_mutex_lock(&mutex);
514 unsigned int a = tcp->sendPacket(buffer, totalLength);
515 if (a != totalLength)
517 pthread_mutex_unlock(&mutex);
521 unsigned char* p = (unsigned char*)tcp->receivePacket();
522 pthread_mutex_unlock(&mutex);
525 if (tcp->getDataLength() != 8)
531 ULLONG recordingLength = ntohll(*(ULLONG*)p);
533 Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
536 return recordingLength;
539 int VDR::getChannelSchedule(ULONG number)
543 *(unsigned long*)&buffer[0] = htonl(8);
544 *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
545 *(unsigned long*)&buffer[8] = htonl(number);
547 pthread_mutex_lock(&mutex);
548 int a = tcp->sendPacket(buffer, 12);
552 pthread_mutex_unlock(&mutex);
556 unsigned char* p = (unsigned char*)tcp->receivePacket();
557 pthread_mutex_unlock(&mutex);
560 int dataLength = tcp->getDataLength();
568 ULONG data = ntohl(*(ULONG*)p);
571 Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule %lu", data);
576 ULLONG VDR::getResumePoint(char* fileName)
578 char* resumeString = configLoad("ResumeData", fileName);
579 if (!resumeString) return 0;
581 ULLONG toReturn = strtoull(resumeString, NULL, 10);
582 delete[] resumeString;
586 int VDR::configSave(char* section, char* key, char* value)
588 ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
589 UCHAR buffer[totalLength];
591 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
592 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
595 strcpy((char*)&buffer[position], section);
596 position += strlen(section) + 1;
597 strcpy((char*)&buffer[position], key);
598 position += strlen(key) + 1;
599 strcpy((char*)&buffer[position], value);
601 pthread_mutex_lock(&mutex);
602 unsigned int a = tcp->sendPacket(buffer, totalLength);
603 if (a != totalLength)
605 pthread_mutex_unlock(&mutex);
609 int toReturn = getSimpleReply();
610 pthread_mutex_unlock(&mutex);
614 char* VDR::configLoad(char* section, char* key)
616 ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
617 UCHAR buffer[totalLength];
619 *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
620 *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
623 strcpy((char*)&buffer[position], section);
624 position += strlen(section) + 1;
625 strcpy((char*)&buffer[position], key);
627 pthread_mutex_lock(&mutex);
628 unsigned int a = tcp->sendPacket(buffer, totalLength);
629 if (a != totalLength)
631 pthread_mutex_unlock(&mutex);
635 char* toReturn = getStringReply();
636 pthread_mutex_unlock(&mutex);