2 Copyright 2004-2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include "vdrrequestpacket.h"
32 #include "vdrresponsepacket.h"
35 #include "mediaprovider.h"
36 #include "mediaproviderids.h"
37 #include "vdrcommand.h"
40 #include "movieinfo.h"
41 #include "seriesinfo.h"
43 #define VOMP_PROTOCOLL_VERSION 0x00000302
45 VDR* VDR::instance = NULL;
47 //will create a request package from a command variable and fill this
48 //caller has to destroy buffer
49 static SerializeBuffer * prepareRequest(VDR_Command *cmd) {
50 SerializeBuffer *buf=new SerializeBuffer(512,false,true);
51 if (cmd->serialize(buf) != 0) {
58 //handle request/response
59 //TODO avoid copy of buffer (needs extension of requestpacket)
60 //TODO avoid command 2x (needs some more restructuring)
61 SerializeBuffer * VDR::doRequestResponse(SerializeBuffer *rq,int cmd) {
62 VDR_RequestPacket *rt=new VDR_RequestPacket;
67 if (! rt->init(cmd,true,rq->getCurrent()-rq->getStart())) {
72 if (! rt->copyin(rq->getStart(),(ULONG)(rq->getCurrent()-rq->getStart()))) {
78 VDR_ResponsePacket *rp=RequestResponse(rt);
79 logger->log("doRequestResponse",Log::DEBUG,"got response %p",rp);
84 SerializeBuffer *buf=new SerializeBuffer(rp->getUserData(),rp->getUserDataLength(),true,true,false);
91 //deserialize a received response
94 static int decodeResponse(SerializeBuffer *rp,VDR_Command *c) {
95 ULONG expected=c->command;
96 if (c->deserialize(rp) != 0) {
98 Log::getInstance()->log("VDR", Log::ERR, "decodeResponse unable to deserialize for command %lu",expected);
102 if (c->command != expected) {
103 Log::getInstance()->log("VDR", Log::ERR, "decodeResponse unexpected response received 0x%lx, expected 0x%lx",c->command,expected);
106 Log::getInstance()->log("VDR", Log::DEBUG, "decodeResponse successfully decoded command 0x%lx",expected);
114 if (instance) return;
120 maxChannelNumber = 0;
121 channelNumberWidth = 1;
122 doVDRShutdown = false;
123 TEMP_SINGLE_VDR_PR = NULL;
124 providerId=MPROVIDERID_VDR;
125 subRange=MPROVIDERRANGE_VDR;
126 MediaPlayerRegister::getInstance()->registerMediaProvider(this,MPROVIDERID_VDR,MPROVIDERRANGE_VDR);
132 if (initted) shutdown();
135 VDR* VDR::getInstance()
140 int VDR::init(int tport)
142 if (initted) return 0;
145 logger = Log::getInstance();
151 if (!initted) return 0;
157 void VDR::findServers(vector<VDRServer>& servers)
159 Wol* wol = Wol::getInstance();
162 memset(message, 0, 15);
163 strcpy(message, "VDP-0001");
164 /*tcp->getMAC(&message[9]); put mac here when TCP modified to do this*/
166 DatagramSocket ds(0);
167 int haveAtLeastOne = 0;
170 bool firstloop = true;
177 logger->log("VDR", Log::NOTICE, "Broadcasting for server");
178 ds.send("255.255.255.255", 51051, message, 15);
179 ds.send("255.255.255.255", 51052, message, 15);
180 ds.send("255.255.255.255", 51053, message, 15);
181 ds.send("255.255.255.255", 51054, message, 15);
182 ds.send("255.255.255.255", 51055, message, 15);
183 if(!firstloop) wol->doWakeUp();
185 retval = ds.waitforMessage(waitType);
187 if (retval == 2) // we got a reply
191 char* vdpreply = ds.getData();
192 if ((ds.getDataLength() >= 24) && !strncmp(vdpreply, "VDP-0002", 8))
195 // FIXME upgrade this to look for a return IP in the reply packet
196 newServer.ip = new char[16];
197 strcpy(newServer.ip, ds.getFromIPA());
199 USHORT newServerPort;
200 memcpy(&newServerPort, &vdpreply[26], 2);
201 newServer.port = ntohs(newServerPort);
203 ULONG newServerVersion;
204 memcpy(&newServerVersion, &vdpreply[28], 4);
205 newServer.version = ntohl(newServerVersion);
207 int newServerNameLength = ds.getDataLength() - 32;
208 newServer.name = new char[newServerNameLength];
209 strcpy(newServer.name, &vdpreply[32]);
211 servers.push_back(newServer);
217 if (haveAtLeastOne) break;
221 { VDRServer newServer;
222 newServer.ip = new char[16];
223 strcpy(newServer.ip, "192.168.1.7");
224 newServer.name = new char[6];
225 strcpy(newServer.name,"debug");
226 servers.push_back(newServer);
228 haveAtLeastOne = 1;}/ * */
234 logger->log("VDR", Log::NOTICE, "END loop");
235 sort(servers.begin(), servers.end(), ServerSorter());
238 void VDR::cancelFindingServer()
243 void VDR::setServerIP(char* newIP)
245 strcpy(serverIP, newIP);
248 void VDR::setServerPort(USHORT newPort)
250 serverPort = newPort;
255 maxChannelNumber = 0;
256 channelNumberWidth = 1;
260 if (tcp->connectTo(serverIP, serverPort))
272 void VDR::disconnect()
278 logger->log("VDR", Log::DEBUG, "Disconnect");
281 void VDR::setReceiveWindow(size_t size)
283 if (connected && size) tcp->setReceiveWindow(size);
286 ///////////////////////////////////////////////////////
288 void VDR::threadMethod()
290 logger->log("VDR", Log::DEBUG, "VDR RUN");
292 threadSetKillable(); // FIXME - change this to deal with the EDRs
297 ULONG userDataLength;
303 VDR_ResponsePacket* vresp;
306 ULONG lastKAsent = 0;
307 ULONG lastKArecv = time(NULL);
312 timeNow = time(NULL);
314 readSuccess = tcp->readData((UCHAR*)&channelID, sizeof(ULONG)); // 2s timeout atm
318 //logger->log("VDR", Log::DEBUG, "Net read timeout");
319 if (!tcp->isConnected()) { connectionDied(); return; } // return to stop this thread
324 if (!lastKAsent) // have not sent a KA
326 if (lastKArecv < (timeNow - 5))
328 logger->log("VDR", Log::DEBUG, "Sending KA packet");
329 if (!sendKA(timeNow))
331 logger->log("VDR", Log::DEBUG, "Could not send KA, calling connectionDied");
335 lastKAsent = timeNow;
340 if (lastKAsent <= (timeNow - 10))
342 logger->log("VDR", Log::DEBUG, "lastKA over 10s ago, calling connectionDied");
348 if (!readSuccess) continue; // no data was read but the connection is ok.
352 channelID = ntohl(channelID);
354 if (channelID == CHANNEL_REQUEST_RESPONSE)
356 if (!tcp->readData((UCHAR*)&requestID, sizeof(ULONG))) break;
357 requestID = ntohl(requestID);
358 if (!tcp->readData((UCHAR*)&userDataLength, sizeof(ULONG))) break;
359 userDataLength = ntohl(userDataLength);
360 if (userDataLength > 5000000) break; // how big can these packets get?
362 if (userDataLength > 0)
364 userData = (UCHAR*)malloc(userDataLength);
365 if (!userData) break;
366 if (!tcp->readData(userData, userDataLength)) break;
369 vresp = new VDR_ResponsePacket();
370 vresp->setResponse(requestID, userData, userDataLength);
371 logger->log("VDR", Log::DEBUG, "Rxd a response packet, requestID=%lu, len=%lu", requestID, userDataLength);
373 if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
375 // If edFindAndCall returns true, edr was called and vresp was handed off.
376 // else, delete vresp here.
380 else if (channelID == CHANNEL_STREAM || channelID == CHANNEL_TVMEDIA)
382 if (!tcp->readData((UCHAR*)&streamID, sizeof(ULONG))) break;
383 streamID = ntohl(streamID);
385 if (!tcp->readData((UCHAR*)&flag, sizeof(ULONG))) break;
388 if (!tcp->readData((UCHAR*)&userDataLength, sizeof(ULONG))) break;
389 userDataLength = ntohl(userDataLength);
391 if (userDataLength > 0)
393 userData = (UCHAR*)malloc(userDataLength);
394 if (!userData) break;
395 if (!tcp->readData(userData, userDataLength)) break;
398 vresp = new VDR_ResponsePacket();
399 vresp->setStream(streamID, flag, userData, userDataLength, channelID);
400 //logger->log("VDR", Log::DEBUG, "Rxd a stream packet, streamID=%lu, flag=%lu, len=%lu", streamID, flag, userDataLength);
402 if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
404 // If edFindAndCall returns true, edr was called and vresp was handed off.
405 // else, delete vresp here.
409 else if (channelID == CHANNEL_KEEPALIVE)
412 if (!tcp->readData((UCHAR*)&KAreply, sizeof(ULONG))) break;
413 KAreply = (ULONG)ntohl(KAreply);
414 if (KAreply == lastKAsent) // successful KA response
417 lastKArecv = KAreply;
418 logger->log("VDR", Log::DEBUG, "Rxd correct KA reply");
423 logger->log("VDR", Log::ERR, "Rxd a response packet on channel %lu !!", channelID);
429 // Who deletes vresp?
430 // If RR, the individual protocol functions must delete vresp.
431 // If stream, the data and length is taken out in ed_cb_call and vresp is deleted there.
437 void VDR::connectionDied()
439 // Called from within threadMethod to do cleanup if it decides the connection has died
441 connected = false; // though actually it could still be connected until someone calls vdr->disconnect
443 // Need to wake up any waiting channel 1 request-response threads
444 // Normally this is done by a packet coming in with channelid and requestid
445 // Instead, go through the list and for each channel 1 edr, make an empty vresp
446 // An empty vresp will have userData == NULL, which means vresp->noResponse() == true
448 // If it's a stream receiver, generate a stream packet with flag == connection_lost
451 VDR_PacketReceiver* vdrpr;
452 VDR_ResponsePacket* vresp;
453 while(receivers.size())
455 vdrpr = (VDR_PacketReceiver*) *(receivers.begin());
456 if (vdrpr->receiverChannel == CHANNEL_REQUEST_RESPONSE)
458 vresp = new VDR_ResponsePacket();
459 vresp->setResponse(vdrpr->requestSerialNumber, NULL, 0);
460 logger->log("VDR", Log::DEBUG, "Timeouts: created blank response packet for request serial %lu", vdrpr->requestSerialNumber);
462 if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
464 // If edFindAndCall returns true, edr was called and vresp was handed off.
465 // else, delete vresp here.
466 logger->log("VDR", Log::ERR, "Timeouts: no waiting thread found for request serial %lu !!!", vdrpr->requestSerialNumber);
471 else if (vdrpr->receiverChannel == CHANNEL_STREAM || vdrpr->receiverChannel == CHANNEL_TVMEDIA)
473 vresp = new VDR_ResponsePacket();
474 vresp->setStream(vdrpr->streamID, 2 /* connection-lost flag */ , NULL, 0, vdrpr->receiverChannel);
475 logger->log("VDR", Log::DEBUG, "Timeouts: created blank response packet for streamid %lu", vdrpr->streamID);
477 if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
479 // If edFindAndCall returns true, edr was called and vresp was handed off.
480 // else, delete vresp here.
481 logger->log("VDR", Log::ERR, "Timeouts: no waiting stream receiver found for streamid %lu !!!", vdrpr->streamID);
486 for(EDRL::iterator i = receivers.begin(); i != receivers.end(); i++)
487 if ((VDR_PacketReceiver*)*i == vdrpr) { receivers.erase(i); break; }
491 // Ok, all event receviers should be dealt with. just in case there weren't any, inform command
492 logger->log("VDR", Log::DEBUG, "edUnlock at end of connectionDied");
494 Command::getInstance()->connectionLost();
497 bool VDR::ed_cb_find(EDReceiver* edr, void* userTag)
499 // edr is a VDR_PacketReceiver object made in VDR::RequestResponse
500 // userTag is a VDR_ResponsePacket made in threadMethod
502 VDR_PacketReceiver* vdrpr = (VDR_PacketReceiver*)edr;
503 VDR_ResponsePacket* vresp = (VDR_ResponsePacket*)userTag;
505 // Is vresp for vdrpr ?
507 ULONG packetChannel = vresp->getChannelID();
508 //logger->log("VDR", Log::DEBUG, "TVMedia debug %d %d %x", vdrpr->receiverChannel,packetChannel,vdrpr);
509 if (vdrpr->receiverChannel != packetChannel) return false;
511 if (packetChannel == CHANNEL_REQUEST_RESPONSE)
513 if (vdrpr->requestSerialNumber == vresp->getRequestID()) return true;
515 else if (packetChannel == CHANNEL_STREAM)
517 if (vdrpr->streamID == vresp->getStreamID()) return true;
518 } else if (packetChannel == CHANNEL_TVMEDIA)
526 VDR_ResponsePacket* VDR::RequestResponse(VDR_RequestPacket* vrp)
528 //logger->log("VDR", Log::DEBUG, "RR %lu", vrp->getOpcode());
532 logger->log("VDR", Log::DEBUG, "RR when !connected");
533 VDR_ResponsePacket* vresp = new VDR_ResponsePacket();
534 return vresp; // "no-response" return
537 // ED make new VDR and register
538 // make a VDR_PacketReceiver
539 // - init with serial number of request packet
541 VDR_PacketReceiver vdrpr;
542 // vdrpr.requestTime = time(NULL);
543 vdrpr.receiverChannel = VDR::CHANNEL_REQUEST_RESPONSE;
544 vdrpr.requestSerialNumber = vrp->getSerial();
550 if ((ULONG)tcp->sendData(vrp->getPtr(), vrp->getLen()) != vrp->getLen())
553 edUnregister(&vdrpr);
554 VDR_ResponsePacket* vresp = new VDR_ResponsePacket();
555 return vresp; // "no-response" return
558 // Sleep and block this thread. The sleep unlocks the mutex
559 logger->log("VDR", Log::DEBUG, "RR sleep - opcode %lu", vrp->getOpcode());
560 edSleepThisReceiver(&vdrpr);
561 logger->log("VDR", Log::DEBUG, "RR unsleep");
563 // Woken because a response packet has arrived, mutex will be locked
564 logger->log("VDR", Log::DEBUG, "Packet delivered to me, requestID: %lu", vdrpr.save_vresp->getRequestID());
567 return vdrpr.save_vresp;
570 bool VDR::sendKA(ULONG timeStamp)
575 ULONG ul=CHANNEL_KEEPALIVE;
576 buffer[pos++]=(ul>>24)&0xff;
577 buffer[pos++]=(ul>>16)&0xff;
578 buffer[pos++]=(ul>>8)&0xff;
579 buffer[pos++]=ul &0xff;
581 buffer[pos++]=(ul>>24)&0xff;
582 buffer[pos++]=(ul>>16)&0xff;
583 buffer[pos++]=(ul>>8)&0xff;
584 buffer[pos++]=ul &0xff;
585 if ((ULONG)tcp->sendData(buffer, 8) != 8) return false;
589 /////////////////////////////////////////////////////////////////////////////
591 // Here VDR takes a break for the VDR_PacketReceiver helper class
593 bool VDR_PacketReceiver::call(void* userTag, bool & deleteme)
595 if (receiverChannel == VDR::CHANNEL_REQUEST_RESPONSE)
597 // It's a RR. Save vresp and, signal the waiting thread and return.
598 // VDR::RequestResponse will be blocking waiting for this to happen.
599 // That function has a pointer to this object and can read save_vresp.
600 save_vresp = (VDR_ResponsePacket*)userTag;
602 return true; // Signals ED to remove edr from receivers and wake up edr thread
605 if (receiverChannel == VDR::CHANNEL_STREAM)
607 // It's a stream packet.
608 VDR_ResponsePacket* vresp = (VDR_ResponsePacket*)userTag;
609 streamReceiver->streamReceive(vresp->getFlag(), vresp->getUserData(), vresp->getUserDataLength());
614 if (receiverChannel == VDR::CHANNEL_TVMEDIA)
617 VDR_ResponsePacket* vresp = (VDR_ResponsePacket*)userTag;
618 Log::getInstance()->log("VDR", Log::DEBUG, "TVMedia Pictures arrived VDR");
619 OsdVector *osd=dynamic_cast<OsdVector*>(Osd::getInstance());
620 if (osd) osd->getPictReader()->receivePicture(vresp);
621 else delete vresp; //nonsense
627 abort(); // unknown receiverChannel, should not happen
630 /////////////////////////////////////////////////////////////////////////////
632 int VDR::doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client)
634 VDR_RequestPacket vrp;
635 if (!vrp.init(VDR_LOGIN, true, 6)) return 0;
638 tcp->getMAC((char*)mactemp);
639 if (!vrp.copyin((UCHAR*)mactemp, 6)) return 0;
641 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
642 if (vresp->noResponse()) { delete vresp; return 0; }
644 ULONG vdrTime = vresp->extractULONG();
645 logger->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime);
646 long vdrTimeOffset = vresp->extractLONG();
647 logger->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
649 unsigned int version_min=vresp->extractULONG();
651 *v_server_min=version_min;
652 unsigned int version_max=vresp->extractULONG();
653 *v_server_max=version_max;
654 *v_client=VOMP_PROTOCOLL_VERSION;
658 if ((version_min > VOMP_PROTOCOLL_VERSION)
659 || (version_max < VOMP_PROTOCOLL_VERSION) ) {
665 // Set the time and zone on the MVP only
667 #if !defined(WIN32) && !defined(__ANDROID__)
668 struct timespec currentTime;
669 currentTime.tv_sec = vdrTime;
670 currentTime.tv_nsec = 0;
672 int b = clock_settime(CLOCK_REALTIME, ¤tTime);
674 logger->log("VDR", Log::DEBUG, "set clock = %u", b);
676 // now make a TZ variable and set it
680 if (vdrTimeOffset > 0) sign = '-';
683 vdrTimeOffset = abs(vdrTimeOffset);
685 hours = (int)vdrTimeOffset / 3600;
686 minutes = vdrTimeOffset % 3600;
688 logger->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
690 minutes = (int)minutes / 60;
692 logger->log("VDR", Log::DEBUG, "%c %i %i", sign, hours, minutes);
695 sprintf(newTZ, "MVP%c%i:%i", sign, hours, minutes);
696 setenv("TZ", newTZ, 1);
698 logger->log("VDR", Log::DEBUG, "Timezone data: %s", newTZ);
701 setCharset(Osd::getInstance()->charSet());
706 bool VDR::LogExtern(const char* logString)
708 if (!connected) return false;
709 int stringLength = strlen(logString);
710 int packetLength = stringLength + 8;
711 char *buffer=new char[packetLength + 1];
713 ULONG ul=CHANNEL_NETLOG;
714 buffer[pos++]=(ul>>24)&0xff;
715 buffer[pos++]=(ul>>16)&0xff;
716 buffer[pos++]=(ul>>8)&0xff;
717 buffer[pos++]=ul &0xff;
719 buffer[pos++]=(ul>>24)&0xff;
720 buffer[pos++]=(ul>>16)&0xff;
721 buffer[pos++]=(ul>>8)&0xff;
722 buffer[pos++]=ul &0xff;
724 strcpy(&buffer[8], logString);
726 if (tcp->sendData(buffer, packetLength) != packetLength)
728 connected = false; // stop the rest of the connection
736 bool VDR::setCharset(int charset)
738 VDR_RequestPacket vrp;
739 if (!vrp.init(VDR_SETCHARSET, true, sizeof(ULONG))) return false;
740 if (!vrp.addULONG(charset)) return false;
742 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
743 if (vresp->noResponse()) { delete vresp; return false; }
745 ULONG success = vresp->extractULONG();
748 if (!success) return false;
753 bool VDR::getRecordingsList(RecMan* recman)
755 VDR_RequestPacket vrp;
756 if (!vrp.init(VDR_GETRECORDINGLIST, true, 0)) return false;
758 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
759 if (vresp->noResponse()) { delete vresp; return false; }
761 ULONG totalSpace = vresp->extractULONG();
762 ULONG freeSpace = vresp->extractULONG();
763 ULONG percent = vresp->extractULONG();
765 recman->setStats(totalSpace, freeSpace, percent);
772 while (!vresp->end())
774 start = vresp->extractULONG();
775 isNew = vresp->extractUCHAR();
776 name = vresp->extractString();
777 fileName = vresp->extractString();
778 recman->addEntry(isNew, start, name, fileName);
787 int VDR::deleteRecording(char* fileName)
789 VDR_RequestPacket vrp;
790 if (!vrp.init(VDR_DELETERECORDING, true, strlen(fileName) + 1)) return 0;
791 if (!vrp.addString(fileName)) return 0;
793 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
794 if (vresp->noResponse()) { delete vresp; return 0; }
796 int toReturn = (int)vresp->extractULONG();
802 char* VDR::moveRecording(char* fileName, char* newPath)
804 VDR_RequestPacket vrp;
805 if (!vrp.init(VDR_MOVERECORDING, true, strlen(fileName) + 1 + strlen(newPath) + 1)) return NULL;
806 if (!vrp.addString(fileName)) return NULL;
807 if (!vrp.addString(newPath)) return NULL;
809 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
810 if (vresp->noResponse()) { delete vresp; return NULL; }
812 char* toReturn = NULL;
813 int success = (int)vresp->extractULONG();
816 toReturn = vresp->extractString();
824 ChannelList* VDR::getChannelsList(ULONG type)
826 VDR_RequestPacket vrp;
827 if (!vrp.init(VDR_GETCHANNELLIST, true, 0)) return NULL;
829 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
830 if (vresp->noResponse()) { delete vresp; return NULL; }
832 ChannelList* chanList = new ChannelList();
834 bool h264support=Video::getInstance()->supportsh264();
835 bool mpeg2support=Video::getInstance()->supportsmpeg2();
837 while (!vresp->end())
839 Channel* chan = new Channel();
840 chan->number = vresp->extractULONG();
841 chan->type = vresp->extractULONG();
842 chan->name = vresp->extractString();
843 chan->vstreamtype = vresp->extractULONG();
845 if (chan->type == type && ((chan->vstreamtype==0x1b && h264support)|| (chan->vstreamtype!=0x1b &&mpeg2support)) )
847 chanList->push_back(chan);
848 logger->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
849 if (chan->number > maxChannelNumber) maxChannelNumber = chan->number;
859 if (maxChannelNumber > 99999)
860 channelNumberWidth = 6;
861 else if (maxChannelNumber > 9999)
862 channelNumberWidth = 5;
863 else if (maxChannelNumber > 999)
864 channelNumberWidth = 4;
865 else if (maxChannelNumber > 99)
866 channelNumberWidth = 3;
867 else if (maxChannelNumber > 9)
868 channelNumberWidth = 2;
870 channelNumberWidth = 1;
875 int VDR::streamChannel(ULONG number, StreamReceiver* tstreamReceiver)
877 VDR_RequestPacket vrp;
878 if (!vrp.init(VDR_STREAMCHANNEL, true, sizeof(ULONG))) return 0;
879 if (!vrp.addULONG(number)) return 0;
882 VDR_PacketReceiver* vdrpr = new VDR_PacketReceiver();
883 vdrpr->receiverChannel = VDR::CHANNEL_STREAM;
884 vdrpr->streamID = vrp.getSerial();
885 vdrpr->streamReceiver = tstreamReceiver;
887 TEMP_SINGLE_VDR_PR = vdrpr;
889 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
890 if (vresp->noResponse())
898 int toReturn = (int)vresp->extractULONG();
899 logger->log("VDR", Log::DEBUG, "VDR said %lu to start streaming request", toReturn);
905 int VDR::stopStreaming()
907 VDR_RequestPacket vrp;
908 if (!vrp.init(VDR_STOPSTREAMING, true, 0)) return 0;
910 if (TEMP_SINGLE_VDR_PR) // this block only needs to be done if it was a live stream
911 // TEMP_SINGLE_VDR_PR will not be set unless we are streaming a channel
913 edUnregister(TEMP_SINGLE_VDR_PR);
914 delete TEMP_SINGLE_VDR_PR;
915 TEMP_SINGLE_VDR_PR = NULL;
918 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
919 if (vresp->noResponse()) { delete vresp; return 0; }
921 int toReturn = (int)vresp->extractULONG();
927 UCHAR* VDR::getBlock(ULLONG position, UINT maxAmount, UINT* amountReceived)
929 VDR_RequestPacket vrp;
930 if (!vrp.init(VDR_GETBLOCK, true, sizeof(ULLONG) + sizeof(ULONG))) return NULL;
931 if (!vrp.addULLONG(position)) return NULL;
932 if (!vrp.addULONG(maxAmount)) return NULL;
934 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
935 if (vresp->noResponse()) { delete vresp; return NULL; }
937 if (vresp->serverError())
939 logger->log("VDR", Log::DEBUG, "Detected getblock 0");
944 // Special handling for getblock
945 UCHAR* toReturn = vresp->getUserData();
946 *amountReceived = vresp->getUserDataLength();
953 ULLONG VDR::streamRecording(char* fileName, ULONG* totalFrames, bool* IsPesRecording)
955 VDR_RequestPacket vrp;
956 if (!vrp.init(VDR_STREAMRECORDING, true, strlen(fileName) + 1)) return 0;
957 if (!vrp.addString(fileName)) return 0;
959 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
960 if (vresp->noResponse()) { delete vresp; return 0; }
962 ULLONG lengthBytes = vresp->extractULLONG();
963 ULONG lengthFrames = vresp->extractULONG();
964 UCHAR isPesRecording = vresp->extractUCHAR();
967 *totalFrames = lengthFrames;
968 *IsPesRecording = (isPesRecording);//convert Uchar to bool
970 logger->log("VDR", Log::DEBUG, "VDR said length is: %llu %lu, IsPesRecording %x", lengthBytes, lengthFrames, *IsPesRecording);
975 ULLONG VDR::positionFromFrameNumber(ULONG frameNumber)
977 VDR_RequestPacket vrp;
978 if (!vrp.init(VDR_POSFROMFRAME, true, sizeof(ULONG))) return 0;
979 if (!vrp.addULONG(frameNumber)) return 0;
981 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
982 if (vresp->noResponse()) { delete vresp; return 0; }
984 ULLONG position = vresp->extractULLONG();
987 logger->log("VDR", Log::DEBUG, "VDR said new position is: %llu", position);
992 ULONG VDR::frameNumberFromPosition(ULLONG position)
994 VDR_RequestPacket vrp;
995 if (!vrp.init(VDR_FRAMEFROMPOS, true, sizeof(ULLONG))) return 0;
996 if (!vrp.addULLONG(position)) return 0;
998 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
999 if (vresp->noResponse()) { delete vresp; return 0; }
1001 ULONG framenumber = vresp->extractULONG();
1004 logger->log("VDR", Log::DEBUG, "VDR said new framenumber is: %u", framenumber);
1009 bool VDR::getNextIFrame(ULONG frameNumber, ULONG direction, ULLONG* rfilePosition, ULONG* rframeNumber, ULONG* rframeLength)
1011 VDR_RequestPacket vrp;
1012 if (!vrp.init(VDR_GETNEXTIFRAME, true, sizeof(ULONG)*2)) return false;
1013 if (!vrp.addULONG(frameNumber)) return false;
1014 if (!vrp.addULONG(direction)) return false;
1016 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1017 if (vresp->noResponse()) { delete vresp; return false; }
1019 if (vresp->serverError())
1021 logger->log("VDR", Log::DEBUG, "Detected getNextIFrame error");
1026 *rfilePosition = vresp->extractULLONG();
1027 *rframeNumber = vresp->extractULONG();
1028 *rframeLength = vresp->extractULONG();
1032 logger->log("VDR", Log::DEBUG, "VDR GNIF said %llu %lu %lu", *rfilePosition, *rframeNumber, *rframeLength);
1037 EventList* VDR::getChannelSchedule(ULONG number)
1041 return getChannelSchedule(number, now, 24 * 60 * 60);
1044 EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
1046 // retrieve event list (vector of events) from vdr within filter window. duration is in seconds
1048 VDR_RequestPacket vrp;
1049 if (!vrp.init(VDR_GETCHANNELSCHEDULE, true, sizeof(ULONG)*3)) return NULL;
1050 if (!vrp.addULONG(number)) return NULL;
1051 if (!vrp.addULONG(start)) return NULL;
1052 if (!vrp.addULONG(duration)) return NULL;
1054 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1055 if (vresp->noResponse()) { delete vresp; return NULL; }
1057 // received a ulong(0) - schedules error in the plugin
1058 if (vresp->serverError())
1064 EventList* eventList = new EventList();
1066 while (!vresp->end())
1068 Event* event = new Event();
1069 event->id = vresp->extractULONG();
1070 event->time = vresp->extractULONG();
1071 event->duration = vresp->extractULONG();
1072 event->title = vresp->extractString();
1073 event->subtitle = vresp->extractString();
1074 event->description = vresp->extractString();
1075 eventList->push_back(event);
1080 logger->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule");
1084 int VDR::configSave(const char* section, const char* key, const char* value)
1086 VDR_RequestPacket vrp;
1087 if (!vrp.init(VDR_CONFIGSAVE, false, 0)) return 0;
1088 if (!vrp.addString(section)) return 0;
1089 if (!vrp.addString(key)) return 0;
1090 if (!vrp.addString(value)) return 0;
1092 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1093 if (vresp->noResponse()) { delete vresp; return 0; }
1095 int toReturn = (int)vresp->extractULONG();
1101 char* VDR::configLoad(const char* section, const char* key)
1103 VDR_RequestPacket vrp;
1104 if (!vrp.init(VDR_CONFIGLOAD, false, 0)) return NULL;
1105 if (!vrp.addString(section)) return NULL;
1106 if (!vrp.addString(key)) return NULL;
1108 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1109 if (vresp->noResponse()) { delete vresp; return NULL; }
1111 char* toReturn = vresp->extractString();
1117 RecTimerList* VDR::getRecTimersList()
1119 VDR_RequestPacket vrp;
1120 if (!vrp.init(VDR_GETTIMERS, true, 0)) return NULL;
1122 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1123 if (vresp->noResponse()) { delete vresp; return NULL; }
1125 RecTimerList* recTimerList = new RecTimerList();
1127 ULONG numTimers = vresp->extractULONG();
1130 RecTimer* newRecTimer;
1133 while (!vresp->end())
1135 newRecTimer = new RecTimer();
1136 newRecTimer->active = vresp->extractULONG();
1137 newRecTimer->recording = vresp->extractULONG();
1138 newRecTimer->pending = vresp->extractULONG();
1139 newRecTimer->priority = vresp->extractULONG();
1140 newRecTimer->lifeTime = vresp->extractULONG();
1141 newRecTimer->channelNumber = vresp->extractULONG();
1142 newRecTimer->startTime = vresp->extractULONG();
1143 newRecTimer->stopTime = vresp->extractULONG();
1144 newRecTimer->day = vresp->extractULONG();
1145 newRecTimer->weekDays = vresp->extractULONG();
1147 tempString = vresp->extractString();
1148 newRecTimer->setFile(tempString);
1149 delete[] tempString;
1151 recTimerList->push_back(newRecTimer);
1152 logger->log("VDR", Log::DEBUG, "TL: %lu %lu %lu %lu %lu %lu %lu %lu %s",
1153 newRecTimer->active, newRecTimer->recording, newRecTimer->pending, newRecTimer->priority, newRecTimer->lifeTime,
1154 newRecTimer->channelNumber, newRecTimer->startTime, newRecTimer->stopTime, newRecTimer->getFile());
1160 sort(recTimerList->begin(), recTimerList->end(), RecTimerSorter());
1162 return recTimerList;
1165 ULONG VDR::setEventTimer(char* timerString)
1167 VDR_RequestPacket vrp;
1168 if (!vrp.init(VDR_SETTIMER, true, strlen(timerString) + 1)) return 0;
1169 if (!vrp.addString(timerString)) return 0;
1171 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1172 if (vresp->noResponse()) { delete vresp; return 0; }
1174 ULONG toReturn = vresp->extractULONG();
1180 RecInfo* VDR::getRecInfo(char* fileName)
1182 VDR_RequestPacket vrp;
1183 if (!vrp.init(VDR_GETRECINFO, true, strlen(fileName) + 1)) return NULL;
1184 if (!vrp.addString(fileName)) return NULL;
1185 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1187 if (vresp->noResponse()) { delete vresp; return NULL; }
1189 if (vresp->serverError())
1191 logger->log("VDR", Log::DEBUG, "Could not get rec info");
1196 RecInfo* recInfo = new RecInfo();
1198 recInfo->timerStart = vresp->extractULONG();
1199 recInfo->timerEnd = vresp->extractULONG();
1200 recInfo->resumePoint = vresp->extractULONG();
1201 recInfo->summary = vresp->extractString();
1203 ULONG numComponents = vresp->extractULONG();
1206 recInfo->setNumComponents(numComponents);
1207 for (ULONG i = 0; i < numComponents; i++)
1209 recInfo->streams[i] = vresp->extractUCHAR();
1210 recInfo->types[i] = vresp->extractUCHAR();
1211 recInfo->languages[i] = vresp->extractString();
1212 recInfo->descriptions[i] = vresp->extractString();
1215 recInfo->fps=vresp->extractdouble();
1216 recInfo->title=vresp->extractString();
1226 ULLONG VDR::rescanRecording(ULONG* totalFrames)
1228 VDR_RequestPacket vrp;
1229 if (!vrp.init(VDR_RESCANRECORDING, true, 0)) return 0;
1231 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1232 if (vresp->noResponse()) { delete vresp; return 0; }
1234 ULLONG lengthBytes = vresp->extractULLONG();
1235 ULONG lengthFrames = vresp->extractULONG();
1238 logger->log("VDR", Log::DEBUG, "VDR said length is: %llu %lu", lengthBytes, lengthFrames);
1240 *totalFrames = lengthFrames;
1244 MarkList* VDR::getMarks(char* fileName)
1246 VDR_RequestPacket vrp;
1247 if (!vrp.init(VDR_GETMARKS, true, strlen(fileName) + 1)) return NULL;
1248 if (!vrp.addString(fileName)) return NULL;
1250 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1251 if (vresp->noResponse()) { delete vresp; return NULL; }
1253 if (vresp->serverError())
1259 MarkList* markList = new MarkList();
1261 while (!vresp->end())
1263 Mark* mark = new Mark();
1264 mark->pos = vresp->extractULONG();
1266 markList->push_back(mark);
1267 logger->log("VDR", Log::DEBUG, "Have added a mark to list. %lu", mark->pos);
1275 void VDR::getChannelPids(Channel* channel)
1277 VDR_RequestPacket vrp;
1278 if (!vrp.init(VDR_GETCHANNELPIDS, true, sizeof(ULONG))) return ;
1279 if (!vrp.addULONG(channel->number)) return ;
1281 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1282 if (vresp->noResponse()) { delete vresp; return ; }
1284 // Format of response
1292 channel->vpid = vresp->extractULONG();
1293 channel->vstreamtype = vresp->extractULONG();
1294 channel->numAPids = vresp->extractULONG();
1296 for (ULONG i = 0; i < channel->numAPids; i++)
1299 newapid.pid = vresp->extractULONG();
1300 char * name=vresp->extractString();
1301 strncpy(newapid.desc,name,9);
1303 channel->apids.push_back(newapid);
1306 channel->numDPids = vresp->extractULONG();
1308 for (ULONG i = 0; i < channel->numDPids; i++)
1311 newdpid.pid = vresp->extractULONG();
1312 char * name=vresp->extractString();
1313 strncpy(newdpid.desc,name,9);
1315 channel->dpids.push_back(newdpid);
1318 channel->numSPids = vresp->extractULONG();
1320 for (ULONG i = 0; i < channel->numSPids; i++)
1323 newspid.pid = vresp->extractULONG();
1324 char * name=vresp->extractString();
1325 strncpy(newspid.desc,name,9);
1327 channel->spids.push_back(newspid);
1329 channel->tpid = vresp->extractULONG();
1331 for (ULONG i = 0; i < channel->numAPids; i++)
1333 channel->apids[i].type = vresp->extractULONG();
1335 for (ULONG i = 0; i < channel->numDPids; i++)
1337 channel->dpids[i].type = vresp->extractULONG();
1339 for (ULONG i = 0; i < channel->numSPids; i++)
1341 channel->spids[i].type = vresp->extractULONG();
1342 channel->spids[i].data1 = vresp->extractULONG();
1343 channel->spids[i].data2 = vresp->extractULONG();
1352 MediaList * VDR::getRootList() {
1353 return getMediaList(NULL);
1356 * media List Request:
1358 * Media List response:
1361 MediaList* VDR::getMediaList(const MediaURI * root)
1363 logger->log("VDR", Log::DEBUG, "getMediaList %s,d=%s, prov=%d", (root?root->getName():"NULL"),
1364 ((root && root->hasDisplayName())?root->getDisplayName():"NULL"),
1365 (root?root->getProvider():providerId));
1366 MediaURI remoteURI(root);
1367 VDR_GetMediaListRequest request(&remoteURI);
1368 SerializeBuffer *vrp=prepareRequest(&request);
1370 logger->log("VDR", Log::ERR, "getMediaList unable to create command");
1374 SerializeBuffer* vresp = doRequestResponse(vrp,request.command);
1376 Command::getInstance()->connectionLost();
1380 MediaList *rt=new MediaList(NULL);
1382 VDR_GetMediaListResponse resp(&rtflags,rt);
1383 if (decodeResponse(vresp,&resp) != 0) {
1390 * get image Request:
1392 * get media response:
1396 int VDR::openMedium(ULONG channel,const MediaURI *uri, ULLONG * size, ULONG x, ULONG y)
1398 MediaURI remoteURI(uri);
1399 VDR_OpenMediumRequest request(&channel,&remoteURI,&x,&y);
1401 SerializeBuffer *vrp=prepareRequest(&request);
1403 logger->log("VDR", Log::ERR, "openMedium unable to create command");
1406 SerializeBuffer* vresp = doRequestResponse(vrp,request.command);
1408 Command::getInstance()->connectionLost();
1412 VDR_OpenMediumResponse response(&flags,size);
1413 if (decodeResponse(vresp,&response) != 0) {
1416 logger->log("VDR", Log::DEBUG, "openMedia len=%llu", *size);
1421 * getMediaBlock - no separate response class - simple data block
1425 int VDR::getMediaBlock(ULONG channel, ULLONG position, ULONG maxAmount, ULONG* amountReceived, unsigned char **buffer)
1428 VDR_GetMediaBlockRequest request(&channel,&position,&maxAmount);
1429 SerializeBuffer *vrp=prepareRequest(&request);
1431 logger->log("VDR", Log::ERR, "getMediaBlock unable to create command");
1434 SerializeBuffer* vresp = doRequestResponse(vrp,request.command);
1436 Command::getInstance()->connectionLost();
1440 // Special handling for getblock
1441 *amountReceived = (ULONG)(vresp->getEnd()-vresp->getStart());
1442 *buffer = vresp->steelBuffer();
1455 int VDR::getMediaInfo(ULONG channel, MediaInfo * result) {
1456 if (! result) return -1;
1457 VDR_GetMediaInfoRequest request(&channel);
1458 SerializeBuffer *vrp=prepareRequest(&request);
1460 logger->log("VDR", Log::ERR, "getMediaInfo unable to create command");
1463 SerializeBuffer* vresp = doRequestResponse(vrp,request.command);
1465 Command::getInstance()->connectionLost();
1470 VDR_GetMediaInfoResponse response(&flags,result);
1471 if (decodeResponse(vresp,&response) != 0) {
1484 int VDR::closeMediaChannel(ULONG channel) {
1485 VDR_CloseMediaChannelRequest request(&channel);
1486 SerializeBuffer *vrp=prepareRequest(&request);
1488 logger->log("VDR", Log::ERR, "closeMediaChannel unable to create command");
1491 SerializeBuffer* vresp = doRequestResponse(vrp,request.command);
1493 Command::getInstance()->connectionLost();
1497 VDR_CloseMediaChannelResponse response(&flags);
1498 if (decodeResponse(vresp,&response) != 0) return -1;
1499 return (flags != 0)?-1:0;
1505 int VDR::deleteTimer(RecTimer* delTimer)
1507 logger->log("VDR", Log::DEBUG, "Delete timer called");
1509 VDR_RequestPacket vrp;
1510 if (!vrp.init(VDR_DELETETIMER, false, 0)) return 0;
1511 if (!vrp.addULONG(delTimer->channelNumber)) return 0;
1512 if (!vrp.addULONG(delTimer->weekDays)) return 0;
1513 if (!vrp.addULONG(delTimer->day)) return 0;
1514 if (!vrp.addULONG(delTimer->startTime)) return 0;
1515 if (!vrp.addULONG(delTimer->stopTime)) return 0;
1517 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1518 if (vresp->noResponse()) { delete vresp; return 0; }
1520 int toReturn = (int)vresp->extractULONG();
1526 I18n::lang_code_list VDR::getLanguageList()
1528 I18n::lang_code_list CodeList;
1529 CodeList["en"] = "English"; // Default entry
1530 VDR_RequestPacket vrp;
1531 if (!vrp.init(VDR_GETLANGUAGELIST, false, 0)) return CodeList;
1532 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1533 if (vresp->noResponse() || vresp->end())
1539 while (!vresp->end())
1541 char* c_code = vresp->extractString();
1542 char* c_name = vresp->extractString();
1543 string code = c_code;
1544 string name = c_name;
1545 CodeList[code] = name;
1553 int VDR::getLanguageContent(const std::string code, I18n::trans_table& texts)
1555 VDR_RequestPacket vrp;
1556 if (!vrp.init(VDR_GETLANGUAGECONTENT, false, 0)) return 0;
1557 if (!vrp.addString(code.c_str())) return 0;
1558 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1559 if (vresp->noResponse()) { delete vresp; return 0; }
1561 while (!vresp->end())
1563 char* c_key = vresp->extractString();
1564 char* c_text = vresp->extractString();
1566 string text = c_text;
1575 void VDR::shutdownVDR()
1578 logger->log("VDR", Log::DEBUG, "Shutting down vdr");
1580 logger->log("VDR", Log::DEBUG, "Shutting down vomp only");
1582 if(!doVDRShutdown || !connected)
1585 VDR_RequestPacket vrp;
1586 logger->log("VDR", Log::DEBUG, "Sending shutdown");
1587 if (!vrp.init(VDR_SHUTDOWN, false, 0)) return;
1588 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1591 logger->log("VDR", Log::DEBUG, "VDR shutdown");
1594 void VDR::getScraperEventType(char * fileName, int & movieID,
1595 int & seriesID, int & episodeID )
1600 VDR_RequestPacket vrp;
1601 if (!vrp.init(VDR_GETRECSCRAPEREVENTTYPE, true, strlen(fileName) + 1)) return;
1602 if (!vrp.addString(fileName)) return ;
1603 Log::getInstance()->log("Recording", Log::DEBUG, "Before Response ");
1604 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1605 Log::getInstance()->log("Recording", Log::DEBUG, "After Response ");
1606 if (vresp->noResponse()) { delete vresp; return ; }
1607 int type = vresp->extractUCHAR();
1608 if (type == 0) //serie
1610 seriesID = vresp->extractLONG();
1611 episodeID = vresp->extractLONG();
1612 } else if (type == 1) //movie
1614 movieID = vresp->extractLONG();
1620 MovieInfo *VDR::getScraperMovieInfo(int movieID)
1622 VDR_RequestPacket vrp;
1623 if (!vrp.init(VDR_GETSCRAPERMOVIEINFO, false, 0)) return NULL;
1624 if (!vrp.addULONG(movieID)) return NULL;
1625 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1626 if (vresp->noResponse()) { delete vresp; return NULL; }
1627 MovieInfo * movieinf= new MovieInfo();
1629 movieinf->id=movieID;
1630 movieinf->title = vresp->extractStdString();
1631 movieinf->originalTitle = vresp->extractStdString();
1632 movieinf->tagline = vresp->extractStdString();
1633 movieinf->overview = vresp->extractStdString();
1634 movieinf->adult = vresp->extractUCHAR();
1635 movieinf->collectionName = vresp->extractStdString();
1637 movieinf->budget = vresp->extractLONG();
1638 movieinf->revenue = vresp->extractLONG();
1639 movieinf->genres = vresp->extractStdString();
1640 movieinf->homepage = vresp->extractStdString();
1641 movieinf->releaseDate = vresp->extractStdString();
1642 movieinf->runtime = vresp->extractLONG();
1643 movieinf->popularity = vresp->extractdouble();
1644 movieinf->voteAverage = vresp->extractdouble();
1645 movieinf->poster.width = vresp->extractULONG();
1646 movieinf->poster.height = vresp->extractULONG();
1647 movieinf->poster.info.setMovieInfo(movieinf);
1648 movieinf->poster.info.setElement(0,0);
1649 movieinf->fanart.width = vresp->extractULONG();
1650 movieinf->fanart.height = vresp->extractULONG();
1651 movieinf->fanart.info.setMovieInfo(movieinf);
1652 movieinf->fanart.info.setElement(1,0);
1653 movieinf->collectionPoster.width = vresp->extractULONG();
1654 movieinf->collectionPoster.height = vresp->extractULONG();
1655 movieinf->collectionPoster.info.setMovieInfo(movieinf);
1656 movieinf->collectionPoster.info.setElement(2,0);
1657 movieinf->collectionFanart.width = vresp->extractULONG();
1658 movieinf->collectionFanart.height = vresp->extractULONG();
1659 movieinf->collectionFanart.info.setMovieInfo(movieinf);
1660 movieinf->collectionFanart.info.setElement(3,0);
1661 ULONG num_actors = vresp->extractULONG();
1662 movieinf->actors.clear();
1663 movieinf->actors.reserve(num_actors);
1664 for (ULONG acty=0; acty < num_actors; acty++) {
1666 new_act.name = vresp->extractStdString();
1667 new_act.role = vresp->extractStdString();
1668 new_act.thumb.width = vresp->extractULONG();
1669 new_act.thumb.height = vresp->extractULONG();
1670 new_act.thumb.info.setMovieInfo(movieinf);
1671 new_act.thumb.info.setElement(4,acty);
1672 movieinf->actors.push_back(new_act);
1681 SeriesInfo *VDR::getScraperSeriesInfo(int seriesID, int episodeID)
1683 VDR_RequestPacket vrp;
1684 if (!vrp.init(VDR_GETSCRAPERSERIESINFO, false, 0)) return NULL;
1685 if (!vrp.addULONG(seriesID)) return NULL;
1686 if (!vrp.addULONG(episodeID)) return NULL;
1688 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1689 if (vresp->noResponse()) { delete vresp; return 0; }
1690 SeriesInfo * seriesinf= new SeriesInfo();
1692 seriesinf->id=seriesID;
1695 seriesinf->name = vresp->extractStdString();
1696 seriesinf->overview = vresp->extractStdString();
1697 seriesinf->firstAired = vresp->extractStdString();
1698 seriesinf->network = vresp->extractStdString();
1699 seriesinf->genre = vresp->extractStdString();
1700 seriesinf->rating = vresp->extractdouble();
1701 seriesinf->status = vresp->extractStdString();
1704 seriesinf->episode.episodeid=episodeID;
1705 seriesinf->episode.number = vresp->extractLONG();
1706 seriesinf->episode.season = vresp->extractLONG();
1707 seriesinf->episode.name = vresp->extractStdString();
1708 seriesinf->episode.firstAired = vresp->extractStdString();
1709 seriesinf->episode.guestStars = vresp->extractStdString();
1710 seriesinf->episode.overview = vresp->extractStdString();
1711 seriesinf->episode.rating = vresp->extractdouble();
1712 seriesinf->episode.image.width = vresp->extractULONG();
1713 seriesinf->episode.image.height = vresp->extractULONG();
1714 seriesinf->episode.image.info.setSeriesInfo(seriesinf);
1715 seriesinf->episode.image.info.setElement(0,0);
1718 ULONG num_actors = vresp->extractULONG();
1719 seriesinf->actors.clear();
1720 seriesinf->actors.reserve(num_actors);
1721 for (ULONG acty=0; acty < num_actors; acty++) {
1723 new_act.name = vresp->extractStdString();
1724 new_act.role = vresp->extractStdString();
1725 new_act.thumb.width = vresp->extractULONG();
1726 new_act.thumb.height = vresp->extractULONG();
1727 new_act.thumb.info.setSeriesInfo(seriesinf);
1728 new_act.thumb.info.setElement(1,acty);
1729 seriesinf->actors.push_back(new_act);
1731 ULONG num_posters = vresp->extractULONG();
1732 for (ULONG medias = 0; medias < num_posters; medias++ ) {
1734 media.info.setSeriesInfo(seriesinf);
1735 media.info.setElement(2,medias);
1736 media.width = vresp->extractULONG();
1737 media.height = vresp->extractULONG();
1738 seriesinf->posters.push_back(media);
1741 ULONG num_banners = vresp->extractULONG();
1742 for (ULONG medias = 0; medias < num_banners; medias++ ) {
1744 media.info.setSeriesInfo(seriesinf);
1745 media.info.setElement(3,medias);
1746 media.width = vresp->extractULONG();
1747 media.height = vresp->extractULONG();
1748 seriesinf->banners.push_back(media);
1750 ULONG num_fanarts = vresp->extractULONG();
1751 for (ULONG medias = 0; medias < num_fanarts; medias++ ) {
1753 media.info.setSeriesInfo(seriesinf);
1754 media.info.setElement(4,medias);
1755 media.width = vresp->extractULONG();
1756 media.height = vresp->extractULONG();
1757 seriesinf->fanart.push_back(media);
1759 seriesinf->seasonposter.width = vresp->extractULONG();
1760 seriesinf->seasonposter.height = vresp->extractULONG();
1761 seriesinf->seasonposter.info.setSeriesInfo(seriesinf);
1762 seriesinf->seasonposter.info.setElement(5,0);
1769 ULONG VDR::loadTVMedia(TVMediaInfo& tvmedia)
1772 VDR_RequestPacket vrp;
1774 if (!vrp.init(VDR_LOADTVMEDIA, false, 0)) return -1;
1775 if (!vrp.addULONG(tvmedia.type)) return -1;
1776 if (!vrp.addULONG(tvmedia.primary_id)) return -1;
1777 if (!vrp.addULONG(tvmedia.secondary_id)) return -1;
1778 if (!vrp.addULONG(tvmedia.type_pict)) return -1;
1779 if (!vrp.addULONG(tvmedia.container)) return -1;
1780 if (!vrp.addULONG(tvmedia.container_member)) return -1;
1781 Log::getInstance()->log("VDR", Log::DEBUG, "TVMedia with ID %d %d; %d %d %d %d;%d",
1782 tvmedia.primary_id,tvmedia.secondary_id,tvmedia.type,tvmedia.type_pict,
1783 tvmedia.container,tvmedia.container_member,vrp.getSerial());
1786 VDR_PacketReceiver* vdrpr = new VDR_PacketReceiver();
1787 vdrpr->receiverChannel = VDR::CHANNEL_TVMEDIA;
1788 vdrpr->streamID = vrp.getSerial();
1789 vdrpr->streamReceiver = NULL;
1793 VDR_ResponsePacket* vresp = RequestResponse(&vrp);
1794 //if (vresp->noResponse()) { delete vresp; return -1; }
1797 return vrp.getSerial();