diff -Nru vdr-plugin-vnsiserver-1.3.1/bitstream.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/bitstream.c --- vdr-plugin-vnsiserver-1.3.1/bitstream.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/bitstream.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,8 +22,6 @@ * */ -#include -#include #include "bitstream.h" cBitstream::cBitstream(uint8_t *data, int bits) diff -Nru vdr-plugin-vnsiserver-1.3.1/bitstream.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/bitstream.h --- vdr-plugin-vnsiserver-1.3.1/bitstream.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/bitstream.h 2016-04-06 23:08:27.000000000 +0000 @@ -25,6 +25,8 @@ #ifndef VNSI_BITSTREAM_H #define VNSI_BITSTREAM_H +#include + class cBitstream { private: diff -Nru vdr-plugin-vnsiserver-1.3.1/channelfilter.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/channelfilter.c --- vdr-plugin-vnsiserver-1.3.1/channelfilter.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/channelfilter.c 2016-04-06 23:08:27.000000000 +0000 @@ -309,18 +309,30 @@ void cVNSIChannelFilter::SortChannels() { +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_WRITE; + for (cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel)) +#else Channels.IncBeingEdited(); Channels.Lock(true); - for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) +#endif { if(!PassFilter(*channel)) { +#if VDRVERSNUM >= 20301 + for (cChannel *whitechan = Channels->Next(channel); whitechan; whitechan = Channels->Next(whitechan)) +#else for (cChannel *whitechan = Channels.Next(channel); whitechan; whitechan = Channels.Next(whitechan)) +#endif { if(PassFilter(*whitechan)) { +#if VDRVERSNUM >= 20301 + Channels->Move(whitechan, channel); +#else Channels.Move(whitechan, channel); +#endif channel = whitechan; break; } @@ -328,9 +340,13 @@ } } +#if VDRVERSNUM >= 20301 + Channels->SetModifiedByUser(); +#else Channels.SetModified(true); Channels.Unlock(); Channels.DecBeingEdited(); +#endif } cVNSIChannelFilter VNSIChannelFilter; diff -Nru vdr-plugin-vnsiserver-1.3.1/channelscancontrol.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/channelscancontrol.c --- vdr-plugin-vnsiserver-1.3.1/channelscancontrol.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/channelscancontrol.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,12 +22,12 @@ * */ -#include -#include - #include "channelscancontrol.h" #include "vnsiclient.h" +#include +#include + using namespace WIRBELSCAN_SERVICE; /*! @@ -54,8 +54,6 @@ #define SCANDONE 2 #define CHECKVERSION(a,b,c) p=strchr((char *) m_scanInformation->a,'#') + 1; sscanf(p,"%d ",&version); if (version < b) c = true; #define CHECKLIMITS(a,v,_min,_max,_def) a=v; if ((a<_min) || (a>_max)) a=_def; -#define freeAndNull(p) if(p) { free(p); p=NULL; } -#define deleteAndNull(p) if(p) { delete(p); p=NULL; } CScanControl::CScanControl(cVNSIClient *client) : m_client(client), @@ -71,10 +69,9 @@ CScanControl::~CScanControl() { - if (m_scanInformation) - delete m_scanInformation; - freeAndNull(m_cbuf); - freeAndNull(m_sbuf); + delete m_scanInformation; + free(m_cbuf); + free(m_sbuf); } bool CScanControl::IsSupported() @@ -198,7 +195,14 @@ m_setup.scanflags |= data.scan_fta ? SCAN_FTA : 0; m_setup.scanflags |= data.scan_hd ? SCAN_HD : 0; +#if VDRVERSNUM >= 20301 + { + LOCK_CHANNELS_READ; + m_lastChannelCount = Channels->Count(); + } +#else m_lastChannelCount = Channels.Count(); +#endif char *s; if (asprintf(&s, "%sSet%s", SPlugin, SSetup) < 0) @@ -291,12 +295,36 @@ m_client->processSCAN_SetDeviceInfo(m_scanStatus.curr_device); m_client->processSCAN_SetTransponder(m_scanStatus.transponder); - for (int i = 0; i < Channels.Count()-m_lastChannelCount; i++) + + int noOfChannels; +#if VDRVERSNUM >= 20301 + { + LOCK_CHANNELS_READ; + noOfChannels = Channels->Count(); + } +#else + noOfChannels = Channels.Count(); +#endif + + for (int i = 0; i < noOfChannels-m_lastChannelCount; i++) { +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + const cChannel *channel = Channels->GetByNumber(Channels->Count()-i); +#else cChannel *channel = Channels.GetByNumber(Channels.Count()-i); +#endif m_client->processSCAN_NewChannel(channel->Name(), channel->Vpid() == 0, channel->Ca() > 0, channel->Vtype() > 2); } - m_lastChannelCount = Channels.Count(); + +#if VDRVERSNUM >= 20301 + { + LOCK_CHANNELS_READ; + m_lastChannelCount = Channels->Count(); + } +#else + m_lastChannelCount = Channels.Count(); +#endif if (m_scanStatus.status == StatusStopped) { diff -Nru vdr-plugin-vnsiserver-1.3.1/config.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/config.h --- vdr-plugin-vnsiserver-1.3.1/config.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/config.h 2016-04-06 23:08:27.000000000 +0000 @@ -34,19 +34,19 @@ // log output configuration #ifdef CONSOLEDEBUG -#define DEBUGLOG(x...) printf("VNSI: "x) +#define DEBUGLOG(x...) printf("VNSI: " x) #elif defined DEBUG -#define DEBUGLOG(x...) dsyslog("VNSI: "x) +#define DEBUGLOG(x...) dsyslog("VNSI: " x) #else #define DEBUGLOG(x...) #endif #ifdef CONSOLEDEBUG -#define INFOLOG(x...) printf("VNSI: "x) -#define ERRORLOG(x...) printf("VNSI-Error: "x) +#define INFOLOG(x...) printf("VNSI: " x) +#define ERRORLOG(x...) printf("VNSI-Error: " x) #else -#define INFOLOG(x...) isyslog("VNSI: "x) -#define ERRORLOG(x...) esyslog("VNSI-Error: "x) +#define INFOLOG(x...) isyslog("VNSI: " x) +#define ERRORLOG(x...) esyslog("VNSI-Error: " x) #endif // default settings diff -Nru vdr-plugin-vnsiserver-1.3.1/cxsocket.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/cxsocket.c --- vdr-plugin-vnsiserver-1.3.1/cxsocket.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/cxsocket.c 2016-04-06 23:08:27.000000000 +0000 @@ -31,6 +31,9 @@ * */ +#include "cxsocket.h" +#include "config.h" + #define __STDC_FORMAT_MACROS #include @@ -46,9 +49,6 @@ #include #include -#include "config.h" -#include "cxsocket.h" - #ifndef MSG_MORE #define MSG_MORE 0 #endif @@ -99,7 +99,7 @@ { if(!m_pollerWrite->Poll(timeout_ms)) { - ERRORLOG("cxSocket::write: poll() failed"); + ERRORLOG("cxSocket::write(fd=%d): poll() failed", m_fd); return written-size; } @@ -109,11 +109,11 @@ { if (errno == EINTR || errno == EAGAIN) { - DEBUGLOG("cxSocket::write: EINTR during write(), retrying"); + DEBUGLOG("cxSocket::write(fd=%d): EINTR during write(), retrying", m_fd); continue; } else if (errno != EPIPE) - ERRORLOG("cxSocket::write: write() error"); + ERRORLOG("cxSocket::write(fd=%d): write() error", m_fd); return p; } @@ -138,7 +138,7 @@ { if(!m_pollerRead->Poll(timeout_ms)) { - ERRORLOG("cxSocket::read: poll() failed at %d/%d", (int)(size-missing), (int)size); + ERRORLOG("cxSocket::read(fd=%d): poll() failed at %d/%d", m_fd, (int)(size-missing), (int)size); return size-missing; } @@ -148,16 +148,16 @@ { if (retryCounter < 10 && (errno == EINTR || errno == EAGAIN)) { - DEBUGLOG("cxSocket::read: EINTR/EAGAIN during read(), retrying"); + DEBUGLOG("cxSocket::read(fd=%d): EINTR/EAGAIN during read(), retrying", m_fd); retryCounter++; continue; } - ERRORLOG("cxSocket::read: read() error at %d/%d", (int)(size-missing), (int)size); + ERRORLOG("cxSocket::read(fd=%d): read() error at %d/%d", m_fd, (int)(size-missing), (int)size); return 0; } else if (p == 0) { - INFOLOG("cxSocket::read: eof, connection closed"); + INFOLOG("cxSocket::read(fd=%d): eof, connection closed", m_fd); return 0; } diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/changelog vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/changelog --- vdr-plugin-vnsiserver-1.3.1/debian/changelog 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/changelog 2016-04-06 23:08:35.000000000 +0000 @@ -1,33 +1,989 @@ -vdr-plugin-vnsiserver (1:1.3.1-2) unstable; urgency=medium +vdr-plugin-vnsiserver (1:1.3.1-901~c63d8e8-xenial) xenial; urgency=medium - * Fixing FTBFS with GCC 6 (Closes: #811949) + * [c63d8e8d8602f587c2fed403c14f1c267f6a0cc2] + add proto9 method for timer types + + + * [076cb69023d7b63efa0ca5e07bbd835f972d5462] + fix compilation error against vdr < 2.3.1 + + + * [3048b84ec0fbe33b5561fdc011cbcc0bb1f7a637] + send response on stream close cmd + + + * [3d6e4be7ae055790eba806f88bd6debc6d7a2903] + adapt to kodi API changes - protocol 9 + + + * [ad19c0da482c1a78b96e95d99fc05d7105ee6c89] + fix segfault on delete of recording + + + * [c3f558a219aa80d872f1e24e86e33901b81e4f93] + use distinct thread names + + Use distinct thread names for cVNSIServer, cVNSIClient and cVNSIStatus. + + + * [e215812051eaa24e426b91c215b8b74927aebad6] + cxSocket: log with fd + + + * [7a7bf0788ec43af66db9611ecd293ca828bd7354] + vnsiclient: fix thread shutdown + + Allow to cancel a client thread gracefully. + 1. Use shutdown() to close a connection - let poll() return + (see cxSocket::read()). + 2. Stop accepting new connections and spawning new client threads before + destroying the existing ones - stop cVNSIServer before cVNSIStatus. + + + * [92a8859454eddd856f0059c362928488eb93d8b6] + Don't send "Shutting down in ..." to OSD over and over + + + * [af9216caca3c8e42c1e2119b806bef61b2618cdc] + C++11 requires a mandatory space when concatenating string literals + + + * [74fb8d2292b8f62c194e1372247cc13f5de1183f] + vnsiclient: "timeout" is optional in ChannelStream_Open() + + Current pvr.vdr.vnsi causes the "Malformed VNSI packet" error to be + triggered because it omits the "timeout" in the ChannelStream_Open + packet. It's hard to tell what's right and what's wrong, because + there is no VNSI protocol definition. This worked before (due to lack + of error handling), so let's make the "timeout" optional. + + + * [178a4d7fa589076a7ca5b7275abba20f4ad10a53] + requestpacket: throw exception on error + + Instead of returning bogus data, throw an exception to jump right to + the error handler. + + This adds verification to all packet parsers. As a side effect, this + fixes various NULL pointer dereferences and other critical bugs. + + + * [110fba4a93877fdcc065530c812e035ced245208] + vnsiclient: use strcpy() instead of strncpy() + + The use of strncpy() pretends that care was taken to avoid a buffer + overflow, but the nature of strncpy() was misunderstood by the + original code author. The size parameter is supposed to specify the + buffer size, not the input string size. By passing the input string + size, the null terminator is omitted, which is only mitigated by the + fact that the replacement string has the same size as the original + string, so the null terminator is already there. + + So let's stop pretending, and do what we were really doing all the + time. + + + * [dc01e5a27590f3539871e8699c86f7b844b524fc] + vnsiclient: use std::string in processRECORDINGS_Rename() + + For exception-safety. This also fixes a buffer overflow bug due to + use of unsafe string functions. + + + * [6935d3e46c231e369621c7eb343d71dfc0613a0d] + vnsiclient: allocate cIndexFile on the stack + + + + * [43d68ccb1f21c10bdb616a837a5eb37e93b5a8ef] + vnsiclient: use std::auto_ptr to be exception-safe + + I'd prefer to use std::unique_ptr, but I was asked not to use C++11 + features in this project. + + + * [1da5ca12c51a14c05bda9a6e6ad375fcaae158a3] + vnsiclient: fix two memory leaks + + A VNSI client can cause memory leaks on the server process by sending + "OSD_Connect" or "ChannelStream_Open" packets repeatedly. + + + * [1b3b46a1b465eb4346c974cc2de53ac1e0830732] + vnsiclient: remove nullptr checks before "delete" + + "delete nullptr" is legal in C++. + + + * [ae2c53f180bfcc0a063af0d98db8060bf90a9cb3] + requestpacket, vnsiclient: allocate data with new[] + + * [15515fd257e91bd4786ae34bd9bdcadba30a5f0f] + status: use clear() instead of erase(begin, end) + + * [9685cbed2ff31566ff00d56438ba136d6bb7e003] + vnsi: allocate cDvbVsniDeviceProbe statically + + * [f4e8f11671e7449e856fc8df0698beae228f28e9] + vnsi: move cDvbVsniDeviceProbe, no forward declaration + + * [bac1534e38e4ed8af636a0bba7ca6a387fc4a290] + videobuffer: remove NULL check before free() + + * [4a2334cba53ac6bc92ee11f6ea77ed00a31c870b] + videobuffer: allocate cRingBufferLinear statically + + * [3ea53c524afecf9b530d8712bed698432926ddce] + parser, parser_MPEGAudio: fix memory leak during realloc() + + If realloc() fails, the buffer pointer is cleared, but not freed. + + + * [6167cd81aeee290cd862ff6b8c4c8205ffdd3d11] + parser, parser_MPEGAudio: remove NULL check before free() + + + * [07a687cdd62fe836921c4104af83245a9c028e02] + parser_MPEGAudio: use free() instead of delete + + The buffer was allocated with malloc(), and it's illegal to use + delete. + + + * [d2112ca4cae9b8fabf90c593e8027cdbe742ca39] + channelscancontrol: remove NULL checks before free() + + free(NULL) is legal. Remove the freeAndNull() macro because we never + need to assign NULL in the destructor. Remove the deleteAndNull() + macro because it's unused. + + + * [8f8d56a5712c60de785e63b8e2fe8e1c039e29c9] + recplayer: allocate cIndexFile statically + + Fixes a memory leak, because the cIndexFile instance was never freed. + + + * [0a762dbf2c6bc42a0b79accdcc7e87119f6a9433] + recplayer: use std::string instead of manual string allocation + + * [4860712f3b428fb9cd06197936d049208feea188] + recplayer: m_segments stores instances, not pointers + + Less overhead. + + + * [7f3d9b2e6cf94be27270b0ee589e2888235a0429] + recplayer: use std::vector instead of cVector + + cVector is a badly designed class: it has virtual methods (overhead!), + and it requires its storage type to have a constructor taking an + integer. + + + * [e70a91ac20950ad0bf1cf27b91c87c891491aa9b] + recplayer: use C++ initializers in constructor + + * [1f377a9b78c44abf16968e0c04e14a88e7d3c6df] + vnsiclient: convert m_req to parameter + + This must be a parameter, because it belongs to one protocol request, + not to the object. + + + * [b9a44cefaba74d843dec1acc70317d00edf67737] + vnsiclient: allocate cRequestPacket on the stack + + Guaranteed automatic deallocation. + + + * [fdebdf6f7b7f4816deada6ecb4e3c379470f36f8] + vnsiclient: add more local cResponsePacket variables + + Create instances where they are needed. This makes the code more + robust, because the lifetime of all instances is clear and managed by + the C++ compiler. + + + * [bbdcbd349e256bc005f4dd4e68f1bb6fcace7498] + vnsiclient, streamer: allocate cResponsePacket on the stack + + Less overhead and better exception-safety. + + + * [32b3f8424654bf6873144d6998d81154faa2d03b] + vnsiosd: make the cResponsePacket variable local + + * [6f1ccbd8eb7498052f031400e9babae9f6ab0468] + requestpacket: init*() returns void + + None of the implementations has an error condition. This change + allows us to remove lots of unnecessary error handlers in callers. + + + * [40f5618791dc14b8e27a451a1224bd6c2d7df3a5] + include cleanup + + + * [4fd100eeb4cf0705b3ef73ad60369eb5fbc6d136] + requestpacket: use size_t instead of uint32_t for memory sizes + + * [409119bbf73ae3b864635c5bfb0cfce880371017] + requestpacket: make read-only methods "const" + + * [108e077fc6dcdead148db1748488a2d9d9910546] + requestpacket: remove method serverError() + + As described in my commit message of 120fb57, the method serverError() + was used in a way that was never going to work as designed. Let's + remove this. + + + * [8698e18487d879cb04081e3b2804b67000cba2b4] + requestpacket: do not transfer ownership in getData() + + This is a fragile thing to do, and cumbersome for callers to + implement. This change is pretty safe because there's no caller. + + + * [56c40e4e232188f7e9fc8490f2e0c7a294bdc9cb] + requestpacket: extract_String() returns pointer into userData buffer + + Since userData contains a null-terminated string, there's no reason to + allocate and copy the buffer; let's just return a pointer into the + existing buffer. + + As a side effect, this fixes a few memory leaks that occur because + some extract_String() callers do not care for freeing the return + value. + + + * [120fb57371c29ecae7d753286cec2e8779a85fa6] + requestpacket: add range checks to fix buffer overflow + + Calling strlen() on a buffer without knowing if there's a null + terminator is easy to crash. The strlen() function will simply run + across the buffer end, until it happens to find a null byte in the + following (undefined) data section, or until it gets killed by the + kernel. + + Another problem is that the method serverError() does not work. It + works only if nobody has moved the packetPos yet - which is a wrong + assumption to make. + + + * [fbddc69b7af2a02311925a51d131e2e8032a60e3] + fix RAM timeshift stream corruption + + + * [e994084621c1c10c1adef8d3ee019bc1cd3436a6] + fix c/p in status timers + + + * [53f37803343d919c0c3f3584745bd839b06fb124] + fix compilation for < 2.3.1 + + * [f766ec2d68cfe97d9f9d81640eed9786d11cda2d] + fixes after 2.3.1 adaption + + + * [24299b4d82f0f00c7d1236f149a9665f4d329aaf] + adapt to vdr 2.3.1 + + + * [7c6ff3035231f84884d4d92cf122ff504cd9f160] + bump version to 1.3.1 + + + * [8da5f80e90c9c2e1c30f68e52ec0df0512fe0bab] + fix div by zero - credits to MichaelAnders + + + * [e0fd85313ac6a75a31d2382927af45cf72b5bbf6] + fix duration for h264 frames in case of timestamps jumping back + + + * [eab5d83d07987858f1d7bf606897f6fa9b8f8fe3] + fix incorrect date of recordings + + + * [b0588983938dcbe409728d2299f675a45c0d3ef8] + revert 3bfed6c030388c9df64997fd02b7629b63d72003, nnow that aduio and video sync seperately it is not needed anymore + + + * [1c6888adcfa3ca4a05910f6806562fc718e485ab] + fix initial timout for AvoidEPGScan - scan may have engaged though parameter was set to avoid + + + * [65b0e9d385123e98dc93f1314ee6a51ffb9ace5d] + make avoid EPG scan while streaming default + + + * [1c63a8a6723a0ddaa7e7f9a06ce84aedc46e529c] + fix memleak caused by duplicate new of osd provider + + + * [28ebda158f20f43dd14aafe92dc7bf18b352d87a] + do net set channel on device, fix unwanted epg scan + + + * [a7b0670d5af265bea20055c18ed5c89a4fd5ca90] + handle cams for streams with MINPRIORITY + + + * [ed4942da3e8db12ac970007713e2df5ac48a5afd] + fix potential deadlock on re-tune channel + + + * [694c3fdcf618b66a57abc1dbd64c64437968e274] + fix segfault when entering OSD if vnsi was started without option d + + + * [1772c924e4d803b30eac53c68b4049f35186c108] + Merge pull request #27 from FernetMenta/device + + only active decoder for device in osd mode, required by femon + + * [017c1b0871f780c3fda946e54c12effda9cf39c5] + fix picon hash for western satellite positions + + + * [5f0b7478a6a3befd403520b0f94e80a8923a3c42] + only active decoder for device in osd mode, required by femon + + + * [cba5889a02bb97fdf4235600b6128701d3091cb5] + Improve .gitignore to not add patches or kdev build files + + + * [62d0b67634aea1fb31cabdbbdb0c19e52960b7d6] + Remove no more needed wirbelscan patch + + + * [be4d72aba71d73b555dc8c4a652d92e5e11f09b5] + Fix possible seq fault in void cRecPlayer::reScan() + + + * [d964bd391db66bfce102cb4a326dd9442086c86b] + Improve cVNSIClient class creation + + + * [2a694330d824f53142b1aa2a14a0f6fb3f102b74] + Rework all Licences and change to KODI + + + * [895fb2a8a272145568378b7e10da7d51603c87aa] + Add help description for newer VDR versions + + + * [e580f2dc4a74358ce8c60592f5cc95252f509d88] + Update channel scan to newest wirbelscan plugin interface + + + * [7977868767bf194da8b66e78138c0fd5c78dccca] + keep trying to open video input after retune request + + + * [d4761a0633e3551558424fb3088e696552d6b07f] + identify channels with Rid == 1 as radio channels + + + * [36e2b619006bad67687952d4f02d1751e253cc71] + Merge pull request #19 from AlwinEsch/rename-field + + Fix particular timestamp and rename fields Ext to side + + * [ba91efab4f2644b07585a35a4aaaf73b21c60e91] + Set PmtTimeout to 0 by default + + + * [145e2e8a4d2f3d6b7d84692cdd996d8a5dbcd3b5] + Fix particular timestamp and rename fields Ext to side + + + * [5997a1b44e69460cc19d031a43d68fd0939f2e68] + Added lithuanian translation file + + + * [a0cfb0b18dd97ec74dfda73350c8f716d3154a2e] + fix compile errors after c59100c922b996ae7574bc3caedd9afc359f7e2d + + + * [eee47762bbb19b9cce5c24f92c88610712f4b070] + Update HISTORY with RDS support + + + * [596089323f22fbbb0b322a2466f88a2b7031c9ca] + Add backword compatibility without RDS + + + * [80c105707b69004f637087bf0309cdbbbb348cdb] + Add RDS stream support + + + * [c59100c922b996ae7574bc3caedd9afc359f7e2d] + Add support of deleted and reproducable recordings + + + * [b887bc889ee7434ea0deece75bc7167de4426636] + bump version to 1.2.1 + + + * [ec20069b190bdac567fdc0fa7aa24f31dbe437ec] + changelog for 1.2.1 + + + * [3181f7de0fd406eb8b661eac18a5556b65a4a6cf] + add cmd parameter for setting port https://github.com/FernetMenta/vdr-plugin-vnsiserver/issues/12 + + + * [57aa73ddc36bbccb1d72ba829728eb9929168167] + stop triggering epg updates if client does not fetch epg + + + * [a48edf135fa7422570290c84a59213b58f457c95] + fix potential segfault on stop streaming + + + * [3ef54f37460caba81cfb96ed8f80ac715b4133a3] + fix conversion warning + + + * [5de5f011d5ab1070f0c1a535032b8ddf70247749] + fix command line parameter -d + + + * [ef61e89b0d2486dc9dd4796aa9e8c0161ae43486] + Add usage of test stream over command line arguments + + + * [97ebdbaea749bad1f51cabec41e70e82fc2a7764] + bump version to 1.2.0 + + + * [c081f79540287f2a67cda4a98af8225c26ff6eff] + add parameter to avoid epgscan while streaming + + + * [3f11c8e92d72f43177ce143d4bd79ddbe5778c74] + make vnsi device optional by cmd line parameter + + + * [dccf71e0a0bc89efcf03a2368ae9308c4b61d2bb] + have vnsi create a device, makes femon work + + + * [c113b4fc6857659e356a2513582414a7e9d58648] + Fixed Devision by zero error + + + * [7d4aa813cc54431151e9120f2080f00251e9cf48] + bump version to 1.1.0 + + + * [ed16a04299ef1e40de343a61a7b6b101ea195d14] + add setup paramter to select if current recording should start when tuning to a channel + + + * [a6f98bb7b0fea1c7de8557a98390b046d2e2e914] + only detect aac muxmode if environment variable VNSI_AAC_MUXMODE is set + + + * [3070d607bb19958b5e6f000da9c45e532352f65e] + bump max timeshift buffer for ram to 8 gig + + + * [cbf0ced29aaaacd0155fd9e482eccd4b4ce5bcff] + add picon reference for channels, ported from xvdr + + + * [96fac38ed6e8dcb5d780a25102c866e57243daa7] + Unified license text and removed incorrect FSF address. + + Licensecheck (which is part of the fedora review process) complains + about a number of files using the old and incorrect FSF address in its + license: ./xxx.c: GPL (v2 or later) (with incorrect FSF address) + + All files use GPLv2 which I certainly did not change. There were + basically 2 different ways in which the last paragraph of this license + was used. One contained the old address, therefore I decided to use + the other form. This is now used in all license files. + + Signed-off-by: Dr. Tilmann Bubeck + + + * [031f69bd8844af38dac78f403c197bcb96c9a43a] + do not trigger re-tune channel on pmt change event + + + * [e8312579ee8022d18b239e21fdde45d19b071b93] + cut undefined data at beginning of a video stream + + + * [77c74a4a01cdf2e2a19fbb452ab5725344d5691d] + use pts for dts if dts is not available in header + + + * [89920d4fa66e6e25875a4967c156c37e111baae6] + fix updating epg too frequently + + + * [78652d99418353dea6b18f8f2e2be74d299a11df] + h264: continuously calculate duration + + + * [a3f7ac569ad9cbbbe42cbdb3f13ce1b31f2dc407] + bump version to 1.0.0 + + + * [6ff29b7149a1a522804c0cd1877f1d2b5148d4d2] + remove protocol suffix from plugin name + + + * [77dcc4ed05a5104651c853fb8c0ced52c076642c] + update readme and history + + + * [b9c312b1e644f1cfda2f0c3dcf6af452865a6e06] + add gitignore + + + * [6102c51a26b80f93f4d0016028e056255adc1c94] + vdr-plugin-vnsiserver: fix thread priorities + + + * [9694b4092e6f8c501a060a20c074fc051c6cb0f0] + vdr-plugin-vnsiserver: correct flag for GetDevice, credits to manio + + + * [663eeed30f112ebdb605583b09d8212f08534fb6] + vdr-plugin-vnsiserver: implement status msg channelchange + + + * [fc56dae58189063336b9ea65233989cd59b17106] + vdr-plugin-vnsiserver: fix compile error after vdr 2.1.4 + + + * [2e5a1b73a17d810171c24406581858a45874b420] + vdr-plugin-vnsiserver: drop old debug logging + + + * [c322c868f44902c7dfcec391be10f5f443a17153] + vdr-plugin-vnsiserver: bump version to 0.9.4 + + + * [e10d6d2d165990c080a2653526cfae6ae79aa101] + vdr-plugin-vnsiserver: update length of recording + + + * [82213ce26a802b93d24d2aaa1eff359a7a6a8440] + vdr-plugin-vnsiserver: detect latm and adts by parsing + + + * [5d63799da37eaf6fdbd31e67dc6002b61b60dba8] + vdr-plugin-vnsiserver: fix incorrect language on audio and subs + + + * [7d1ab6d85f34e91bb0cffa1e72618e126dab3004] + vdr-plugin-vnsiserver: fix latm, wrong codec name + + + * [6c03c0f7f19455b26d69aa51ad43b7d78c1cd6f2] + vdr-plugin-vnsiserver: check and reset modified flag for channels instead of looking at file + + + * [92b301bd413bdbd646ec115195aaf6a18626dedd] + vdr-plugin-vnsiserver: update change log + + + * [975d5af9f5a6d6c1bf59807eadad3e107c05afa1] + vdr-plugin-vnsiserver: fix a bug in epg auto update + + + * [36491f34e6ed10d01c63009f72ffb8d7c716fdc6] + vdr-plugin-vnsiserver: raise nice level for vnsi threads + + + * [11d683b09d733513694d4e81e2b77faa8b8f43ed] + vdr-plugin-vnsiserver: do not set pts for dts on video streams + + + * [d80a4ace29020882a61e92346fb7bf55d9bd8deb] + vdr-plugin-vnsiserver: add channel filter + + + * [bdab088675a9929adfe549549ece3c8e040e1c3b] + vdr-plugin-vnsiserver: bump version to 0.9.3 + + + * [b0df7c45b2f276cbe7f20e68872241836f76c912] + vdr-plugin-vnsiserver: bump protocol version to 5 + + + * [f5d1c547142ee4a0537f9877fa2e945a478e9691] + vdr-plugin-vnsiserver: add edl support + + + * [64bdc733e04094c45f276aa3adf56def7c788374] + vdr-plugin-vnsiserver: send buffer times for timeshift + + + * [b7a196fe7a2cddbfcb6974a6a243899481aae618] + vdr 2.1.2 buildfix + + + * [638ddfcd71d5796200f6b9cda3e37f9544eb1498] + vdr-plugin-vnsiserver: fix seeking, only consider audio and video streams for searching + + + * [987f4fb4c5c3945804c24657ef0e30f26c0b6b81] + vdr-plugin-vnsiserver: FreeBSD patches, credits to Juergen Lock + + + * [9a84b0ef483e9c26001dbec42d902d409947ed65] + vdr-plugin-vnsiserver: check all timers for active recordings when opening a channel + + + * [67ef684804dbc1c1f2f0599e5fd193edce4962f6] + vdr-plugin-vnsiserver: do not assume a pes header right after pusi for video streams + + + * [03b913fb52f88ef65a0d4cf5e8a782441ae1517d] + vdr-plugin-vnsiserver: h264 parser - reset stream data on error + + + * [8f580cc83d18464da28a4da1a9231e5295578b2d] + vdr-plugin-vnsiserver: allow timeshift buffer in RAM to larger than 2 GB, change size_t to off_t + + + * [084f052c53111e9323c6dd1677e9dd0ad7d74b7e] + vdr-plugin-vnsiserver: silence compiler warning + + + * [0573539b4f99947b201df31334b75ba17711427e] + vdr-plugin-vnsiserver: fix layer for mpeg audio + + + * [7accc9baea6960934d8cd2ddbbabe694db2ca725] + vdr-plugin-vnsiserver: squash to specific errors + + + * [91353fc4da2122a7dc3060e8e869b25d24ae001f] + vdr-plugin-vnsiserver: present specific parser errors to user + + + * [c181d196043b60c36c48bddad9d8318427b459b3] + vdr-plugin-vnsiserver: fix potential segfault when reading incorrent pes header size + + + * [09257e5b486ea1151d50dce7e07b23ba896b9ce0] + vdr-plugin-vnsiserver: recplayer, drop NOATIME flag on open + + + * [b43609ca1da3920a1157c3ab66163dfa1861dcf8] + vdr-plugin-vnsiserver: increase max buffer size for pes packets + + + * [dcd27d1317df216c56a9ad913856ddbae597786d] + vdr-plugin-vnsiserver: atsc does not suppport mpeg2 audio, interpret pmt accordingly + + + * [21768ded668c9ccc2ddd86ce423b98a6242d1ed6] + vdr-plugin-vnsiserver: fix segfault when feeded with scrambled packets + + + * [df254e2ed4cba7725a44d5293c31d2f712fb8bf2] + vdr-plugin-vnsiserver: fix occasional incorrect timestamps after 505336e0b99306f95199d00f65bd7ef7ec2a9371 + + + * [555902d7c89bd9219d264fca00076de20dc01db6] + vdr-plugin-vnsiserver: fix getting stuck by reading eof at end of segment + + + * [4e6586626afa330214421080f96e600d961cb235] + vdr-plugin-vnsiserver: rework and fixes on video parsers + + + * [89329e8111fd338430a0f79929518046a550bef8] + vdr-plugin-vnsiserver: fix test harness + + + * [da0b51917a1d0d6a04c4315a83b72cf67e051cb3] + vdr-plugin-vnsiserver: only observe pts wraps on audio and video streams + + + * [e8c8d85bb15d19aac640b73afac4a6dcd898ba21] + vdr-plugin-vnsiserver: cleanup and fixes in pes parser + + + * [3bfed6c030388c9df64997fd02b7629b63d72003] + vdr-plugin-vnsiserver: do not transmit packates older than first frame, avoids large disconts on start of playback + + + * [d33f1db4fe409492cf8aebd050eb5782be924a73] + vdr-plugin-vnsiserver: fix compile error for loder vdr versions + + + * [1e14fa56233caae5eb401fd186900ee3319e04e2] + vdr-plugin-vnsiserver: update headers + + + * [8d5ae1b26dbdfd21680589f9025d83e70869880d] + vdr-plugin-vnsiserver: raise max value for timeshift buffers + + + * [cfce57b75994545413d2670e5dfdb28e5c715d57] + vdr-plugin-vnsiserver: add config option for timeshift buffer directory + + + * [9eb8c7cc076ffe54d17935fe71cd5fefdf59f087] + vdr-plugin-vnsiserver: optimize recplayer + + + * [ebd4fa4cec1ea1b3c1031718b83dd47bd7eee40c] + vdr-plugin-vnsiserver: add buffer status message + + + * [9f73277c49e33abc65a46f4af9ed8a02dd53bbdb] + vdr-plugin-vnsiserver: optimize file buffer method for timeshift + + + * [ec50d877a692900a2fff9357a9980f6231825054] + vdr-plugin-vnsiserver: increase read cache + + + * [85cc343733d080fc86ced9d081202e2bc3675e60] + vdr-plugin-vnsiserver: fix subtitle errors in xbmc log + + + * [d6e0ed10ff63116d0417775bf45ba6a17bd887ad] + vdr-plugin-vnsiserver: limit rescan for recording in progress + + + * [9d000e7d861ea9c70bf4a0df0f36144738d6557c] + vdr-plugin-vnsiserver: set priority for livetv, allow interrupt by rocording + + + * [aa1241501ddad9b6e4852796d3e1aa5f7e89f1b7] + vdr-plugin-vnsiserver: replay recording in progress + + + * [bbb1fadbbd10458d1d9ad31b7fbf476deb149d2f] + vdr-plugin-vnsiserver: add file buffer for timeshift + + + * [a6f294c07ee408b55a934bae302e94909942bd6d] + vdr-plugin-vnsiserver: parse setup parameter before saving + + + * [71130eb75c2b36dbccdd6cb479a7077637b76ec2] + vdr-plugin-vnsiserver: bump version to 0.9.2 + + + * [d10b281d222b59ffe0cf9cf6a26642cd226c711f] + vdr-plugin-vnsiserver: tag mux packet with a serial + + + * [5fb48be70cc548f77631f5e206d6e8ff1d660c0f] + vnsi: bump protocol version to 4 + + + * [0f376a017126a0a632c0534f48c59bcead0c9189] + vdr-plugin-vnsiserver: timeshift + + + * [d3314f3e2468c99b7785335eaf8aad7aa0eef2ad] + vdr-plugin-vnsiserver: bump version + + + * [23530fb0c204f4bfc8be1baffaf1e64fa30c2aa2] + vdr-vnsiserver Makefile vdr-1.7.36 + + + * [8da4ba1f6337ff87af0cf2475b294c8270bee33b] + vdr-plugin-vnsiserver: redesign for timeshift, revised parsers + + + * [ac50facbb337a5eb595db353aa4464d09fd67832] + vdr-plugin-vnsiserver: revised socket + + + * [d40df0114156a6ecc2f81a998c45d21e67847c7d] + vdr-plugin-vnsiserver: osd - increase memory + + + * [e283830e20ac920d4c74ed6a4057e6b09ccbcbef] + vdr-plugin-vnsiserver: trigger epg update + + + * [1431e065e9af887f289ad89b6fd6d824cff569ab] + vdr-plugin-vnsiserver: vdr osd + + + * [a1cb727b166d052a1335fd31f4be123515efd846] + vdr-plugin-vnsiserver: update GPLv2 license text + + + * [2b3775793aee88a662d5a9cf21c85aecfdcf8be9] + vdr-plugin-vnsiserver: adust makefile for better packaging + + + * [2fa4a0e48e821d876ddb4eb76a2ed52a03de17a0] + vdr-plugin-vnsiserver: adjust makefile to vdr 1.7.34 + + + * [479627933ac1d6a939cd86fed45053c923386f35] + vdr-plugin-vnsiserver: send audio config for AAC after ffmpeg was fixed + + + * [907061b5d13382fd4c23d9b560a91addd77f2c51] + vdr-pllugin-vnsiserver: drop ancient debug log + + + * [3719b071e592ec4df16c12f32b1b2fb957f62f5d] + vdr-plugin-vnsiserver: set default timeout for pmt fallback to 5 + + + * [d7a25afe09da8284a26075dbe9856fa1ad75485c] + vdr-plugin-vnsiserver: fix incorrectly named setup parameter + + + * [e678bc9847eba7d04b0803ca59788cdc7b72d112] + vdr-plugin-vnsiserver: fix h264 parser, signed golomb adjust sps to spec + + + * [778dd9c00abf682868e1b3c24a9a090163f11168] + Revert "vdr-plugin-vnsiserver: drop useless buffering of packets before i-frame" + + This reverts commit 283e55dc282792f09d0f482c9ea14b432671998f. + + + * [08f739bd88a96eda5ee1d7e3498f0ff6702b4c87] + vdr-plugin-vnsiserver: drop useless buffering of packets before i-frame + + + * [1a3dd5c08b29479f4f67f0b5b6e0636189cdd7b8] + vdr-plugin-vnsiserver: fix hang on h264 streams if first frame is no i-frame + + + * [a49fa57de595ea0c6a4fbe70f8e240c800197d48] + vdr-plugin-vnsiserver: fix borked time stamps for ac3 + + + * [d2ef8cf12f3c03124b99834d33ff23799b72afb1] + Fix server plugin compilation against vdr-1.7.33 + + + * [a53a9e5a8953d752ff2ca543cd4681b0810f112d] + vdr-plugin-vnsiserver: fix compile error for vdr versions lower 1.7.28 + + + * [1e642d72d802958f3e9c6564741a912ac2bdc7d8] + vdr-plugin-vnsiserver: fix eac3 + + + * [7f8f257d9f8d36b92ada37e86226a2e0f466ea19] + vnsi: use latm codec, the server no longer encapsulates latm into adts + + + * [3a85d7dfae78f908950ea81cffe386abb007df7e] + vdr-plugin-vnsiserver: make pmt timeout a setup parameter + + + * [8b04b144844a289ea433c22b3d6ec18f4ebfb7ef] + vdr-plugin-vnsiserver: keep pat/pmt in sync with buffer + + + * [cfd1be265154a6ef86dea3418f61ac6836898471] + vdr-plugin-vnsiserver: fix aac latm, use latm codec instead of repacking into adts + + + * [c9a5e94e317eb904229402d81d4fda23cd9a2e56] + vdr-plugin-vnsiserver: distinguish aac adst from latm, implement parsing for adst + + + * [fcaf4340f2af34db60373b6f6b4701fa7f4af246] + vdr-plugin-vnsiserver: add debug switch to makefile + + + * [2e3757603b0f92353421cc8ecac06ca0896122cb] + vdr-plugin-vnsiserver: align pmt filter with method in vdr + + + * [0d6aed831c2638a712a91b15e94a203763936acc] + vdr-plugin-vnsiserver: open demuxer for EAC3 + + + * [099c1691a6baf251b9fa9ef5158b31a67d049bbb] + vdr-plugin-vnsiserver: adopt AAC patch from tvheadend: https://github.com/tvheadend/tvheadend/commit/3e3a197fa55e6e2850375822fb6e8a1dcbf96385 + + + * [dc5132328340d821511b6b1fec3ad5e52846a703] + vdr-plugin-vnsiserver: drop incomplete and needless lookup table for pmt stream types + + + * [028f07d068a5dc5199320bb717b8955960a37775] + vdr-plugin-vnsiserver: update readme, set correct path to source + + + * [85772ce02158920ededf557582632ebb2a9c7041] + vdr-plugin-vnsiserver: attach receiver before having seen pmt, use channels conf for demuxers if not pmt has been seen + + + * [2429f7ab7a7b0ea3a8bee20dc565264fb75f97d0] + vdr-plugin-vnsiserver: remove dead code + + + * [b587eb4eb8f26df6af460ca113289f348fe1589a] + vdr-plugin-vnsiserver: send all stream props on with stream change, update language of audio streams + + + * [80b5d4005110a8d179618a8eafc8ace00baad45f] + vdr-plugin-vnsiserver: do not log read/write error if socket was closed gracefully + + + * [4fd8fee1b2a60239dda6a4d34eed834c6bc73ae3] + vdr-plugin-vnsiserver: rework handling of streams + + + * [d11d5fa50b9efa9ab523fb7306cdcb2c55c1e614] + vdr-pllugin-vnsiserver: bump version, drop backwards compatibility for now + + + * [c8dcbd50a18478bd997c3da26c9ec8bac3d9055d] + vdr-plugin-vnsiserver: take correct action in case of demuxer returns error + + + * [af9a1ad6b2e08a730b0634e81753d4f15c201b3f] + vdr-plugin-vnsiserver: fix freeze of streaming, thanks to manio who tracked this down for xvdr + + + * [f6a6f78a287b64f262fa1bd1db68f2120cd23f02] + vdr-plugin-vnsiserver: explicitly request streams we have demuxers for + + + * [3783b9082e5e72ad2bd36ece93df7d67d5919ec6] + vdr-plugin-vnsiserver: make network interface portable, consider byte alignment and padding + + + * [f08890ae398a64a8c02de0a3e313a2e99ad748da] + vdr-plugin-vnsiserver: silence compiler warnings + + + * [73bea642d850f4d0038e3e7e204458e69d19eb89] + vdr-plugin-vnsiserver: align makefile to current version of vdr + + + * [cc077a6d3e083a68b313fd98fe346411a4da497e] + vdr-plugin-vnsi: delay attaching streamer until PAT filter has all streams + + + * [dbc18443574c8d846ac6134c1d04056f1d25a182] + vnsi: missed makefile for server plugin + + + * [5611af4430bc320b35868f69d4e05769debbb4c3] + vnsi: add server plugin + - -- Tobias Grimm Sat, 23 Jan 2016 21:54:30 +0100 - -vdr-plugin-vnsiserver (1:1.3.1-1) unstable; urgency=medium - - * Fixed Vcs-Git to point to anonscm.debian.org - * Added upstream patch to fix issue with RAM time shift - - -- Tobias Grimm Sun, 01 Nov 2015 20:04:57 +0100 - -vdr-plugin-vnsiserver (1:1.2.1-1) unstable; urgency=medium - - * New upstream release - * Removed upstream bug fix patches - * Added vdr-plugin-vnsiserver-dbg for debugging symbols - * Added Tobias Grimm to uploaders - * Added more details to debian/copyright - * Updated upstream homepage in debian/copyright - * Improved package description - - -- Tobias Grimm Tue, 22 Sep 2015 01:10:34 +0200 - -vdr-plugin-vnsiserver (1:1.2.0-1) unstable; urgency=low - - * Initial release based on xbmc-pvr-addons - 13.0+git20140512+g91cc731+dfsg1-1 (Closes: #748288) - * Use links control file instead of postinst/postrm - * Import 4 upstream bug fix patches - - -- Balint Reczey Fri, 02 Jan 2015 01:45:33 +0100 + -- Andrey Pavlenko Thu, 07 Apr 2016 02:08:34 +0300 diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/compat vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/compat --- vdr-plugin-vnsiserver-1.3.1/debian/compat 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/compat 2016-04-06 23:08:34.000000000 +0000 @@ -1 +1 @@ -9 +7 diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/control vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/control --- vdr-plugin-vnsiserver-1.3.1/debian/control 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/control 2016-04-06 23:08:35.000000000 +0000 @@ -1,35 +1,16 @@ Source: vdr-plugin-vnsiserver Section: video Priority: extra -Maintainer: Debian Multimedia Maintainers -Uploaders: Balint Reczey , Tobias Grimm -Build-Depends: debhelper (>= 9), pkg-config, vdr-dev (>= 2.2.0) -Standards-Version: 3.9.6 -Homepage: https://github.com/FernetMenta/vdr-plugin-vnsiserver -Vcs-Git: git://anonscm.debian.org/pkg-multimedia/vdr-plugin-vnsiserver.git -Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-multimedia/vdr-plugin-vnsiserver.git +Maintainer: Andrey Pavlenko +Build-Depends: debhelper (>= 8.0.0), vdr-dev (>= 2.3.1), pkg-config, + gettext +Standards-Version: 3.9.3 +Homepage: https://github.com/opdenkamp/xbmc-pvr-addons/tree/master/addons/pvr.vdr.vnsi/vdr-plugin-vnsiserver +Vcs-Git: https://github.com/opdenkamp/xbmc-pvr-addons.git +Vcs-Browser: https://github.com/opdenkamp/xbmc-pvr-addons/tree/master/addons/pvr.vdr.vnsi/vdr-plugin-vnsiserver Package: vdr-plugin-vnsiserver Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, ${vdr:Depends} -Suggests: xbmc (>= 2:12) -Description: VDR plugin to provide PVR backend services for Kodi - The vdr-plugin-vnsiserver provides PVR backend services for Kodi - clients using the kodi-pvr-vdr-vnsi addon. Via VNSI - (VDR-Network-Streaming-Interface) Kodi connects to this plugin and - can access various VDR functions like timers, channels, - live-TV-streaming and recordings. - -Package: vdr-plugin-vnsiserver-dbg -Architecture: any -Section: debug -Priority: extra -Depends: vdr-plugin-vnsiserver (= ${binary:Version}), ${misc:Depends} -Description: VDR plugin to provide PVR backend services for Kodi - The vdr-plugin-vnsiserver provides PVR backend services for Kodi - clients using the kodi-pvr-vdr-vnsi addon. Via VNSI - (VDR-Network-Streaming-Interface) Kodi connects to this plugin and - can access various VDR functions like timers, channels, - live-TV-streaming and recordings. - . - This package contains the debugging symbols. +Depends: ${shlibs:Depends}, vdr (>= 2.3.1) +Description: VDR-Network-Streaming-Interface + VDR-Network-Streaming-Interface \ No newline at end of file diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/copyright vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/copyright --- vdr-plugin-vnsiserver-1.3.1/debian/copyright 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/copyright 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: vdr-plugin-vnsiserver -Source: https://github.com/FernetMenta/vdr-plugin-vnsiserver - -Files: * -Copyright: 2005-2014 Team XBMC (http://www.xbmc.org) - 2011 Alexander Pipelka - 2010 Alwin Esch (Team XBMC) -License: GPL-2+ - -Files: hash.* -Copyright: 1986 Gary S. Brown - 2011 Alexander Pipelka -Comment: CRC32 code -License: GPL-2+ - -Files: requestpacket.* responsepacket.* recplayer.* -Copyright: 2004, 2005, 2007 Chris Tallon - 2010 Alwin Esch - 2010, 2011 Alexander Pipelka -Comment: Based on the code from the VOMP for VDR plugin -License: GPL-2+ - -Files: csocket.* -Copyright: 2003 - 2006 Petri Hintukainen - 2010 Alwin Esch (Team XBMC) - 2011 Alexander Pipelka -Comment: Based on the code form the Xinelibouput VDR plugin -License: GPL-2+ - -Files: debian/* -Copyright: 2012 wsnipex - 2015 Balint Reczey - 2015 Tobias Grimm -License: GPL-2+ - -License: GPL-2+ - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see - . - On Debian systems, the complete text of the GNU General - Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/docs vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/docs --- vdr-plugin-vnsiserver-1.3.1/debian/docs 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/docs 2016-04-06 23:08:34.000000000 +0000 @@ -1 +1 @@ -README +README* diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/install vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/install --- vdr-plugin-vnsiserver-1.3.1/debian/install 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/install 2016-04-06 23:08:34.000000000 +0000 @@ -0,0 +1,2 @@ +etc/vdr/plugins +usr/lib/vdr/plugins \ No newline at end of file diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/links vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/links --- vdr-plugin-vnsiserver-1.3.1/debian/links 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/links 2016-04-06 23:08:34.000000000 +0000 @@ -0,0 +1 @@ +etc/vdr/allowed_hosts.conf etc/vdr/plugins/vnsiserver/allowed_hosts.conf diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/patches/fix-RAM-timeshift-stream-corruption.patch vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/patches/fix-RAM-timeshift-stream-corruption.patch --- vdr-plugin-vnsiserver-1.3.1/debian/patches/fix-RAM-timeshift-stream-corruption.patch 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/patches/fix-RAM-timeshift-stream-corruption.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -Description: fix RAM timeshift stream corruption -Author: glenvt18 -Origin: upstream -Applied-Upstream: fbddc69b7af2a02311925a51d131e2e8032a60e3 ---- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ -diff --git a/videobuffer.c b/videobuffer.c -index 885799c..c1da958 100644 ---- a/videobuffer.c -+++ b/videobuffer.c -@@ -303,7 +303,7 @@ int cVideoBufferRAM::ReadBlock(uint8_t **buf, unsigned int size, time_t &endTime - if (m_ReadPtr > (m_BufferSize - m_Margin)) - { - int bytesToCopy = m_BufferSize - m_ReadPtr; -- memmove(m_Buffer + (m_Margin - bytesToCopy), m_Buffer + m_ReadPtr, bytesToCopy); -+ memmove(m_Buffer + (m_Margin - bytesToCopy), m_BufferPtr + m_ReadPtr, bytesToCopy); - *buf = m_Buffer + (m_Margin - bytesToCopy); - } - else --- -2.5.3 - diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/patches/gcc6-fixes.patch vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/patches/gcc6-fixes.patch --- vdr-plugin-vnsiserver-1.3.1/debian/patches/gcc6-fixes.patch 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/patches/gcc6-fixes.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -Description: GCC 6 related fixes -Author: Tobias Grimm -Bug: https://github.com/FernetMenta/vdr-plugin-vnsiserver/pull/38 ---- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- a/config.h -+++ b/config.h -@@ -34,19 +34,19 @@ - // log output configuration - - #ifdef CONSOLEDEBUG --#define DEBUGLOG(x...) printf("VNSI: "x) -+#define DEBUGLOG(x...) printf("VNSI: " x) - #elif defined DEBUG --#define DEBUGLOG(x...) dsyslog("VNSI: "x) -+#define DEBUGLOG(x...) dsyslog("VNSI: " x) - #else - #define DEBUGLOG(x...) - #endif - - #ifdef CONSOLEDEBUG --#define INFOLOG(x...) printf("VNSI: "x) --#define ERRORLOG(x...) printf("VNSI-Error: "x) -+#define INFOLOG(x...) printf("VNSI: " x ) -+#define ERRORLOG(x...) printf("VNSI-Error: " x) - #else --#define INFOLOG(x...) isyslog("VNSI: "x) --#define ERRORLOG(x...) esyslog("VNSI-Error: "x) -+#define INFOLOG(x...) isyslog("VNSI: " x) -+#define ERRORLOG(x...) esyslog("VNSI-Error: " x) - #endif - - // default settings diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/patches/series vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/patches/series --- vdr-plugin-vnsiserver-1.3.1/debian/patches/series 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -fix-RAM-timeshift-stream-corruption.patch -gcc6-fixes.patch diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/plugin.vnsiserver.conf vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/plugin.vnsiserver.conf --- vdr-plugin-vnsiserver-1.3.1/debian/plugin.vnsiserver.conf 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/plugin.vnsiserver.conf 2016-04-06 23:08:34.000000000 +0000 @@ -0,0 +1 @@ +-t 10 diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/rules vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/rules --- vdr-plugin-vnsiserver-1.3.1/debian/rules 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/rules 2016-04-06 23:08:34.000000000 +0000 @@ -1,19 +1,15 @@ #!/usr/bin/make -f -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -# This has to be exported to make some magic below work. -export DH_OPTIONS - -PLG_PACKAGE = $(filter-out %-dbg, $(shell dh_listpackages)) -DBG_PACKAGE = $(filter %-dbg, $(shell dh_listpackages)) +DIR := $(CURDIR) +DESTDIR := $(DIR)/debian/tmp %: - dh $@ --parallel --with vdrplugin + dh $@ -override_dh_strip: - dh_strip --dbg-package=$(DBG_PACKAGE) +override_dh_auto_build: + $(MAKE) DESTDIR="$(DESTDIR)" override_dh_auto_install: - dh_auto_install --destdir=debian/$(PLG_PACKAGE) + $(MAKE) install DESTDIR="$(DESTDIR)" + [ -d "$(DESTDIR)/etc/vdr/plugins" ] || mkdir -p "$(DESTDIR)/etc/vdr/plugins" + cp "$(DIR)/debian/plugin.vnsiserver.conf" "$(DESTDIR)/etc/vdr/plugins/" diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/source/options vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/source/options --- vdr-plugin-vnsiserver-1.3.1/debian/source/options 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/source/options 2016-04-06 23:08:34.000000000 +0000 @@ -0,0 +1 @@ +compression = "bzip2" \ No newline at end of file diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/vdr-plugin-vnsiserver.install vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/vdr-plugin-vnsiserver.install --- vdr-plugin-vnsiserver-1.3.1/debian/vdr-plugin-vnsiserver.install 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/vdr-plugin-vnsiserver.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -vnsiserver/allowed_hosts.conf etc/vdr/plugins/vnsiserver -debian/vnsiserver.conf etc/vdr/conf.avail/ diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/vdr-plugin-vnsiserver.links vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/vdr-plugin-vnsiserver.links --- vdr-plugin-vnsiserver-1.3.1/debian/vdr-plugin-vnsiserver.links 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/vdr-plugin-vnsiserver.links 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -etc/vdr/plugins/vnsiserver/allowed_hosts.conf var/lib/vdr/plugins/vnsiserver/allowed_hosts.conf diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/vnsiserver.conf vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/vnsiserver.conf --- vdr-plugin-vnsiserver-1.3.1/debian/vnsiserver.conf 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/vnsiserver.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -# -# VNSI-Server VDR plugin arguments -# - -[vnsiserver] - --t 10 diff -Nru vdr-plugin-vnsiserver-1.3.1/debian/watch vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/watch --- vdr-plugin-vnsiserver-1.3.1/debian/watch 2016-01-23 20:54:39.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/debian/watch 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -version=3 -opts=uversionmangle=s/_/./g,dversionmangle=s/.dfsg[0-9]*// \ -https://github.com/FernetMenta/vdr-plugin-vnsiserver/tags .*/v(\d[\d\.]+)\.tar\.gz diff -Nru vdr-plugin-vnsiserver-1.3.1/hash.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/hash.c --- vdr-plugin-vnsiserver-1.3.1/hash.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/hash.c 2016-04-06 23:08:27.000000000 +0000 @@ -23,11 +23,11 @@ * */ +#include "hash.h" + #include #include -#include "hash.h" - static uint32_t crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, @@ -98,9 +98,21 @@ } const cChannel* FindChannelByUID(uint32_t channelUID) { - cChannel* result = NULL; + const cChannel* result = NULL; +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + // maybe we need to use a lookup table + for (const cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel)) { + cString channelid = channel->GetChannelID().ToString(); + if(channelUID == CreateStringHash(channelid)) { + result = channel; + break; + } + } +#else // maybe we need to use a lookup table + Channels.Lock(false); for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) { cString channelid = channel->GetChannelID().ToString(); if(channelUID == CreateStringHash(channelid)) { @@ -108,6 +120,8 @@ break; } } + Channels.Unlock(); +#endif return result; } diff -Nru vdr-plugin-vnsiserver-1.3.1/parser_AAC.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_AAC.c --- vdr-plugin-vnsiserver-1.3.1/parser_AAC.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_AAC.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,11 +22,11 @@ * */ -#include -#include +#include "parser_AAC.h" #include "config.h" -#include "parser_AAC.h" +#include +#include static int aac_sample_rates[16] = { diff -Nru vdr-plugin-vnsiserver-1.3.1/parser_AC3.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_AC3.c --- vdr-plugin-vnsiserver-1.3.1/parser_AC3.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_AC3.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,12 +22,12 @@ * */ -#include -#include -#include "config.h" - #include "parser_AC3.h" #include "bitstream.h" +#include "config.h" + +#include +#include #define AC3_HEADER_SIZE 7 diff -Nru vdr-plugin-vnsiserver-1.3.1/parser.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser.c --- vdr-plugin-vnsiserver-1.3.1/parser.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser.c 2016-04-06 23:08:27.000000000 +0000 @@ -58,8 +58,7 @@ cParser::~cParser() { - if (m_PesBuffer) - free(m_PesBuffer); + free(m_PesBuffer); } void cParser::Reset() @@ -370,13 +369,15 @@ return false; } m_PesBufferSize += m_PesBufferInitialSize / 10; - m_PesBuffer = (uint8_t*)realloc(m_PesBuffer, m_PesBufferSize); - if (m_PesBuffer == NULL) + uint8_t *new_buffer = (uint8_t*)realloc(m_PesBuffer, m_PesBufferSize); + if (new_buffer == NULL) { ERRORLOG("cParser::AddPESPacket - realloc failed"); Reset(); return false; } + + m_PesBuffer = new_buffer; } // copy first packet of new frame to front diff -Nru vdr-plugin-vnsiserver-1.3.1/parser_DTS.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_DTS.c --- vdr-plugin-vnsiserver-1.3.1/parser_DTS.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_DTS.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,12 +22,12 @@ * */ -#include -#include -#include "config.h" - #include "parser_DTS.h" #include "bitstream.h" +#include "config.h" + +#include +#include cParserDTS::cParserDTS(int pID, cTSStream *stream, sPtsWrap *ptsWrap, bool observePtsWraps) : cParser(pID, stream, ptsWrap, observePtsWraps) diff -Nru vdr-plugin-vnsiserver-1.3.1/parser_h264.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_h264.c --- vdr-plugin-vnsiserver-1.3.1/parser_h264.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_h264.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,12 +22,12 @@ * */ -#include -#include -#include "config.h" +#include "parser_h264.h" #include "bitstream.h" +#include "config.h" -#include "parser_h264.h" +#include +#include static const int h264_lev2cpbsize[][2] = { diff -Nru vdr-plugin-vnsiserver-1.3.1/parser_MPEGAudio.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_MPEGAudio.c --- vdr-plugin-vnsiserver-1.3.1/parser_MPEGAudio.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_MPEGAudio.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,12 +22,12 @@ * */ -#include -#include -#include "config.h" - #include "parser_MPEGAudio.h" #include "bitstream.h" +#include "config.h" + +#include +#include #define MAX_RDS_BUFFER_SIZE 100000 @@ -65,11 +65,7 @@ cParserMPEG2Audio::~cParserMPEG2Audio() { - if (m_RDSBuffer) - { - delete m_RDSBuffer; - m_RDSBuffer = NULL; - } + free(m_RDSBuffer); } void cParserMPEG2Audio::Parse(sStreamPacket *pkt, sStreamPacket *pkt_side_data) @@ -140,14 +136,16 @@ return; } m_RDSBufferSize += m_RDSBufferInitialSize / 10; - m_RDSBuffer = (uint8_t*)realloc(m_RDSBuffer, m_RDSBufferSize); - if (m_RDSBuffer == NULL) + uint8_t *new_buffer = (uint8_t *)realloc(m_RDSBuffer, m_RDSBufferSize); + if (new_buffer == NULL) { ERRORLOG("PVR Parser MPEG2-Audio - %s - realloc for RDS data failed", __FUNCTION__); m_RDSEnabled = false; return; } - } + + m_RDSBuffer = new_buffer; + } int pes_buffer_ptr = 0; for (int i = m_FrameSize-3; i > m_FrameSize-3-rdsl; i--) // <-- data reverse, from end to start diff -Nru vdr-plugin-vnsiserver-1.3.1/parser_MPEGVideo.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_MPEGVideo.c --- vdr-plugin-vnsiserver-1.3.1/parser_MPEGVideo.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_MPEGVideo.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,12 +22,12 @@ * */ -#include -#include -#include "config.h" +#include "parser_MPEGVideo.h" #include "bitstream.h" +#include "config.h" -#include "parser_MPEGVideo.h" +#include +#include using namespace std; diff -Nru vdr-plugin-vnsiserver-1.3.1/parser_Subtitle.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_Subtitle.c --- vdr-plugin-vnsiserver-1.3.1/parser_Subtitle.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_Subtitle.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,11 +22,11 @@ * */ -#include -#include +#include "parser_Subtitle.h" #include "config.h" -#include "parser_Subtitle.h" +#include +#include cParserSubtitle::cParserSubtitle(int pID, cTSStream *stream, sPtsWrap *ptsWrap, bool observePtsWraps) : cParser(pID, stream, ptsWrap, observePtsWraps) diff -Nru vdr-plugin-vnsiserver-1.3.1/parser_Teletext.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_Teletext.c --- vdr-plugin-vnsiserver-1.3.1/parser_Teletext.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/parser_Teletext.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,10 +22,10 @@ * */ -#include +#include "parser_Teletext.h" #include "config.h" -#include "parser_Teletext.h" +#include cParserTeletext::cParserTeletext(int pID, cTSStream *stream, sPtsWrap *ptsWrap, bool observePtsWraps) : cParser(pID, stream, ptsWrap, observePtsWraps) diff -Nru vdr-plugin-vnsiserver-1.3.1/recordingscache.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/recordingscache.c --- vdr-plugin-vnsiserver-1.3.1/recordingscache.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/recordingscache.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,8 +22,8 @@ * */ -#include "config.h" #include "recordingscache.h" +#include "config.h" #include "vnsiclient.h" #include "hash.h" @@ -38,7 +38,7 @@ return singleton; } -uint32_t cRecordingsCache::Register(cRecording* recording, bool deleted) { +uint32_t cRecordingsCache::Register(const cRecording* recording, bool deleted) { cString filename = recording->FileName(); uint32_t uid = CreateStringHash(filename); @@ -54,7 +54,7 @@ return uid; } -cRecording* cRecordingsCache::Lookup(uint32_t uid) { +const cRecording* cRecordingsCache::Lookup(uint32_t uid) { DEBUGLOG("%s - lookup uid: %08x", __FUNCTION__, uid); if(m_recordings.find(uid) == m_recordings.end()) { @@ -66,11 +66,65 @@ cString filename = m_recordings[uid].filename; DEBUGLOG("%s - filename: %s", __FUNCTION__, (const char*)filename); + const cRecording* r; + if (!m_recordings[uid].isDeleted) + { +#if VDRVERSNUM >= 20301 + LOCK_RECORDINGS_READ; + r = Recordings->GetByName(filename); +#else + r = Recordings.GetByName(filename); +#endif + } + else + { +#if VDRVERSNUM >= 20301 + LOCK_DELETEDRECORDINGS_READ; + r = DeletedRecordings->GetByName(filename); +#else + r = DeletedRecordings.GetByName(filename); +#endif + } + + DEBUGLOG("%s - recording %s", __FUNCTION__, (r == NULL) ? "not found !" : "found"); + m_mutex.Unlock(); + + return r; +} + +cRecording* cRecordingsCache::LookupWrite(uint32_t uid) +{ + DEBUGLOG("%s - lookup uid: %08x", __FUNCTION__, uid); + + if(m_recordings.find(uid) == m_recordings.end()) + { + DEBUGLOG("%s - not found !", __FUNCTION__); + return NULL; + } + + m_mutex.Lock(); + cString filename = m_recordings[uid].filename; + DEBUGLOG("%s - filename: %s", __FUNCTION__, (const char*)filename); + cRecording* r; if (!m_recordings[uid].isDeleted) + { +#if VDRVERSNUM >= 20301 + LOCK_RECORDINGS_WRITE; + r = Recordings->GetByName(filename); +#else r = Recordings.GetByName(filename); +#endif + } else + { +#if VDRVERSNUM >= 20301 + LOCK_DELETEDRECORDINGS_WRITE; + r = DeletedRecordings->GetByName(filename); +#else r = DeletedRecordings.GetByName(filename); +#endif + } DEBUGLOG("%s - recording %s", __FUNCTION__, (r == NULL) ? "not found !" : "found"); m_mutex.Unlock(); diff -Nru vdr-plugin-vnsiserver-1.3.1/recordingscache.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/recordingscache.h --- vdr-plugin-vnsiserver-1.3.1/recordingscache.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/recordingscache.h 2016-04-06 23:08:27.000000000 +0000 @@ -43,9 +43,10 @@ static cRecordingsCache& GetInstance(); - uint32_t Register(cRecording* recording, bool deleted = false); + uint32_t Register(const cRecording* recording, bool deleted = false); - cRecording* Lookup(uint32_t uid); + const cRecording* Lookup(uint32_t uid); + cRecording* LookupWrite(uint32_t uid); private: struct RecordingsInfo diff -Nru vdr-plugin-vnsiserver-1.3.1/recplayer.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/recplayer.c --- vdr-plugin-vnsiserver-1.3.1/recplayer.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/recplayer.c 2016-04-06 23:08:27.000000000 +0000 @@ -38,31 +38,28 @@ #define O_NOATIME 0 #endif -cRecPlayer::cRecPlayer(cRecording* rec, bool inProgress) -{ - m_file = -1; - m_fileOpen = -1; - m_recordingFilename = strdup(rec->FileName()); - m_inProgress = inProgress; - - // FIXME find out max file path / name lengths +cRecPlayer::cRecPlayer(const cRecording* rec, bool inProgress) + :m_inProgress(inProgress), + m_recordingFilename(rec->FileName()), #if VDRVERSNUM < 10703 - m_pesrecording = true; - m_indexFile = new cIndexFile(m_recordingFilename, false); + m_pesrecording(true), + m_indexFile(m_recordingFilename.c_str(), false), #else - m_pesrecording = rec->IsPesRecording(); - if(m_pesrecording) INFOLOG("recording '%s' is a PES recording", m_recordingFilename); - m_indexFile = new cIndexFile(m_recordingFilename, false, m_pesrecording); + m_pesrecording(rec->IsPesRecording()), + m_indexFile(m_recordingFilename.c_str(), false, m_pesrecording), +#endif + m_file(-1), m_fileOpen(-1) +{ + // FIXME find out max file path / name lengths +#if VDRVERSNUM >= 10703 + if(m_pesrecording) INFOLOG("recording '%s' is a PES recording", m_recordingFilename.c_str()); #endif scan(); } void cRecPlayer::cleanup() { - for(int i = 0; i != m_segments.Size(); i++) { - delete m_segments[i]; - } - m_segments.Clear(); + m_segments.clear(); } void cRecPlayer::scan() @@ -85,17 +82,17 @@ break; } - cSegment* segment = new cSegment(); - segment->start = m_totalLength; - segment->end = segment->start + s.st_size; + cSegment segment; + segment.start = m_totalLength; + segment.end = segment.start + s.st_size; - m_segments.Append(segment); + m_segments.push_back(segment); m_totalLength += s.st_size; INFOLOG("File %i found, size: %lu, totalLength now %lu", i, s.st_size, m_totalLength); } - m_totalFrames = m_indexFile->Last(); + m_totalFrames = m_indexFile.Last(); INFOLOG("total frames: %u", m_totalFrames); } @@ -114,21 +111,21 @@ } cSegment* segment; - if (m_segments.Size() < i+1) + if (m_segments.size() < i+1) { - segment = new cSegment(); - m_segments.Append(segment); + m_segments.push_back(cSegment()); + segment = &m_segments.back(); segment->start = m_totalLength; } else - segment = m_segments[i]; + segment = &m_segments[i]; segment->end = segment->start + s.st_size; m_totalLength += s.st_size; } - m_totalFrames = m_indexFile->Last(); + m_totalFrames = m_indexFile.Last(); } @@ -136,14 +133,13 @@ { cleanup(); closeFile(); - free(m_recordingFilename); } char* cRecPlayer::fileNameFromIndex(int index) { if (m_pesrecording) - snprintf(m_fileName, sizeof(m_fileName), "%s/%03i.vdr", m_recordingFilename, index+1); + snprintf(m_fileName, sizeof(m_fileName), "%s/%03i.vdr", m_recordingFilename.c_str(), index+1); else - snprintf(m_fileName, sizeof(m_fileName), "%s/%05i.ts", m_recordingFilename, index+1); + snprintf(m_fileName, sizeof(m_fileName), "%s/%05i.ts", m_recordingFilename.c_str(), index+1); return m_fileName; } @@ -212,25 +208,25 @@ amount = m_totalLength - position; // work out what block "position" is in - int segmentNumber = -1; - for(int i = 0; i < m_segments.Size(); i++) - { - if ((position >= m_segments[i]->start) && (position < m_segments[i]->end)) { - segmentNumber = i; + std::vector::iterator begin = m_segments.begin(), + end = m_segments.end(), segmentIterator = end; + for (std::vector::iterator i = begin; i != end; ++i) { + if ((position >= i->start) && (position < i->end)) { + segmentIterator = i; break; } } // segment not found / invalid position - if (segmentNumber == -1) + if (segmentIterator == end) return 0; // open file (if not already open) - if (!openFile(segmentNumber)) + if (!openFile(std::distance(begin, segmentIterator))) return 0; // work out position in current file - uint64_t filePosition = position - m_segments[segmentNumber]->start; + uint64_t filePosition = position - segmentIterator->start; // seek to position if(lseek(m_file, filePosition, SEEK_SET) == -1) @@ -264,8 +260,6 @@ uint64_t cRecPlayer::positionFromFrameNumber(uint32_t frameNumber) { - if (!m_indexFile) - return 0; #if VDRVERSNUM < 10703 unsigned char retFileNumber; int retFileOffset; @@ -278,41 +272,39 @@ int retLength; - if (!m_indexFile->Get((int)frameNumber, &retFileNumber, &retFileOffset, &retPicType, &retLength)) + if (!m_indexFile.Get((int)frameNumber, &retFileNumber, &retFileOffset, &retPicType, &retLength)) return 0; - if (retFileNumber >= m_segments.Size()) + if (retFileNumber >= m_segments.size()) return 0; - uint64_t position = m_segments[retFileNumber]->start + retFileOffset; + uint64_t position = m_segments[retFileNumber].start + retFileOffset; return position; } uint32_t cRecPlayer::frameNumberFromPosition(uint64_t position) { - if (!m_indexFile) return 0; - if (position >= m_totalLength) { DEBUGLOG("Client asked for data starting past end of recording!"); return m_totalFrames; } - int segmentNumber = -1; - for(int i = 0; i < m_segments.Size(); i++) - { - if ((position >= m_segments[i]->start) && (position < m_segments[i]->end)) { - segmentNumber = i; + std::vector::iterator begin = m_segments.begin(), + end = m_segments.end(), segmentIterator = end; + for (std::vector::iterator i = begin; i != end; ++i) { + if ((position >= i->start) && (position < i->end)) { + segmentIterator = i; break; } } - if(segmentNumber == -1) { + if (segmentIterator == end) return m_totalFrames; - } - uint32_t askposition = position - m_segments[segmentNumber]->start; - return m_indexFile->Get((int)segmentNumber, askposition); + uint32_t askposition = position - segmentIterator->start; + int segmentNumber = std::distance(begin, segmentIterator); + return m_indexFile.Get((int)segmentNumber, askposition); } @@ -321,8 +313,6 @@ // 0 = backwards // 1 = forwards - if (!m_indexFile) return false; - #if VDRVERSNUM < 10703 unsigned char waste1; int waste2; @@ -334,7 +324,7 @@ int iframeLength; int indexReturnFrameNumber; - indexReturnFrameNumber = (uint32_t)m_indexFile->GetNextIFrame(frameNumber, (direction==1 ? true : false), &waste1, &waste2, &iframeLength); + indexReturnFrameNumber = (uint32_t)m_indexFile.GetNextIFrame(frameNumber, (direction==1 ? true : false), &waste1, &waste2, &iframeLength); DEBUGLOG("GNIF input framenumber:%u, direction=%u, output:framenumber=%i, framelength=%i", frameNumber, direction, indexReturnFrameNumber, iframeLength); if (indexReturnFrameNumber == -1) return false; diff -Nru vdr-plugin-vnsiserver-1.3.1/recplayer.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/recplayer.h --- vdr-plugin-vnsiserver-1.3.1/recplayer.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/recplayer.h 2016-04-06 23:08:27.000000000 +0000 @@ -33,10 +33,12 @@ #include #include -#include #include "config.h" +#include +#include + class cSegment { public: @@ -47,7 +49,7 @@ class cRecPlayer { public: - cRecPlayer(cRecording* rec, bool inProgress = false); + cRecPlayer(const cRecording* rec, bool inProgress = false); ~cRecPlayer(); uint64_t getLengthBytes(); uint32_t getLengthFrames(); @@ -67,16 +69,16 @@ char* fileNameFromIndex(int index); void checkBufferSize(int s); + const bool m_inProgress; + const bool m_pesrecording; char m_fileName[512]; - cIndexFile *m_indexFile; + const std::string m_recordingFilename; + cIndexFile m_indexFile; int m_file; int m_fileOpen; - cVector m_segments; + std::vector m_segments; uint64_t m_totalLength; uint32_t m_totalFrames; - char *m_recordingFilename; - bool m_pesrecording; - bool m_inProgress; }; #endif // VNSI_RECPLAYER_H diff -Nru vdr-plugin-vnsiserver-1.3.1/requestpacket.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/requestpacket.c --- vdr-plugin-vnsiserver-1.3.1/requestpacket.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/requestpacket.c 2016-04-06 23:08:27.000000000 +0000 @@ -24,8 +24,11 @@ * */ +#include "requestpacket.h" +#include "vnsicommand.h" +#include "config.h" + #include -#include #include #ifndef __FreeBSD__ @@ -36,15 +39,10 @@ #define __cpu_to_be64 htobe64 #endif -#include "config.h" -#include "requestpacket.h" -#include "vnsicommand.h" - -cRequestPacket::cRequestPacket(uint32_t requestID, uint32_t opcode, uint8_t* data, uint32_t dataLength) +cRequestPacket::cRequestPacket(uint32_t requestID, uint32_t opcode, uint8_t* data, size_t dataLength) : userData(data), userDataLength(dataLength), opCode(opcode), requestID(requestID) { packetPos = 0; - ownBlock = true; channelID = 0; streamID = 0; flag = 0; @@ -52,37 +50,31 @@ cRequestPacket::~cRequestPacket() { - if (!ownBlock) return; // don't free if it's a getblock - - if (userData) free(userData); + delete[] userData; } -bool cRequestPacket::end() +bool cRequestPacket::end() const { return (packetPos >= userDataLength); } -int cRequestPacket::serverError() -{ - if ((packetPos == 0) && (userDataLength == 4) && !ntohl(*(uint32_t*)userData)) return 1; - else return 0; -} - char* cRequestPacket::extract_String() { - if (serverError()) return NULL; + char *p = (char *)&userData[packetPos]; + const char *end = (const char *)memchr(p, '\0', userDataLength - packetPos); + if (end == NULL) + /* string is not terminated - fail */ + throw MalformedVNSIPacket(); - int length = strlen((char*)&userData[packetPos]); - if ((packetPos + length) > userDataLength) return NULL; - char* str = new char[length + 1]; - strcpy(str, (char*)&userData[packetPos]); + int length = end - p; packetPos += length + 1; - return str; + return p; } uint8_t cRequestPacket::extract_U8() { - if ((packetPos + sizeof(uint8_t)) > userDataLength) return 0; + if ((packetPos + sizeof(uint8_t)) > userDataLength) + throw MalformedVNSIPacket(); uint8_t uc = userData[packetPos]; packetPos += sizeof(uint8_t); return uc; @@ -90,7 +82,8 @@ uint32_t cRequestPacket::extract_U32() { - if ((packetPos + sizeof(uint32_t)) > userDataLength) return 0; + if ((packetPos + sizeof(uint32_t)) > userDataLength) + throw MalformedVNSIPacket(); uint32_t ul; memcpy(&ul, &userData[packetPos], sizeof(uint32_t)); ul = ntohl(ul); @@ -100,7 +93,8 @@ uint64_t cRequestPacket::extract_U64() { - if ((packetPos + sizeof(uint64_t)) > userDataLength) return 0; + if ((packetPos + sizeof(uint64_t)) > userDataLength) + throw MalformedVNSIPacket(); uint64_t ull; memcpy(&ull, &userData[packetPos], sizeof(uint64_t)); ull = __be64_to_cpu(ull); @@ -110,7 +104,8 @@ int64_t cRequestPacket::extract_S64() { - if ((packetPos + sizeof(int64_t)) > userDataLength) return 0; + if ((packetPos + sizeof(int64_t)) > userDataLength) + throw MalformedVNSIPacket(); int64_t ll; memcpy(&ll, &userData[packetPos], sizeof(int64_t)); ll = __be64_to_cpu(ll); @@ -120,7 +115,8 @@ double cRequestPacket::extract_Double() { - if ((packetPos + sizeof(uint64_t)) > userDataLength) return 0; + if ((packetPos + sizeof(uint64_t)) > userDataLength) + throw MalformedVNSIPacket(); uint64_t ull; memcpy(&ull, &userData[packetPos], sizeof(uint64_t)); ull = __be64_to_cpu(ull); @@ -132,7 +128,8 @@ int32_t cRequestPacket::extract_S32() { - if ((packetPos + sizeof(int32_t)) > userDataLength) return 0; + if ((packetPos + sizeof(int32_t)) > userDataLength) + throw MalformedVNSIPacket(); int32_t l; memcpy(&l, &userData[packetPos], sizeof(int32_t)); l = ntohl(l); @@ -142,6 +139,5 @@ uint8_t* cRequestPacket::getData() { - ownBlock = false; return userData; } diff -Nru vdr-plugin-vnsiserver-1.3.1/requestpacket.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/requestpacket.h --- vdr-plugin-vnsiserver-1.3.1/requestpacket.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/requestpacket.h 2016-04-06 23:08:27.000000000 +0000 @@ -27,20 +27,29 @@ #ifndef VNSI_REQUESTPACKET_H #define VNSI_REQUESTPACKET_H +#include +#include + +#include + +class MalformedVNSIPacket : public std::runtime_error { +public: + MalformedVNSIPacket() + :std::runtime_error("Malformed VNSI packet") {} +}; + class cRequestPacket { public: - cRequestPacket(uint32_t requestID, uint32_t opcode, uint8_t* data, uint32_t dataLength); + cRequestPacket(uint32_t requestID, uint32_t opcode, uint8_t* data, size_t dataLength); ~cRequestPacket(); - int serverError(); - - uint32_t getDataLength() { return userDataLength; } - uint32_t getChannelID() { return channelID; } - uint32_t getRequestID() { return requestID; } - uint32_t getStreamID() { return streamID; } - uint32_t getFlag() { return flag; } - uint32_t getOpCode() { return opCode; } + size_t getDataLength() const { return userDataLength; } + uint32_t getChannelID() const { return channelID; } + uint32_t getRequestID() const { return requestID; } + uint32_t getStreamID() const { return streamID; } + uint32_t getFlag() const { return flag; } + uint32_t getOpCode() const { return opCode; } char* extract_String(); uint8_t extract_U8(); @@ -50,15 +59,15 @@ int32_t extract_S32(); double extract_Double(); - bool end(); + bool end() const; // If you call this, the memory becomes yours. Free with free() uint8_t* getData(); private: uint8_t* userData; - uint32_t userDataLength; - uint32_t packetPos; + size_t userDataLength; + size_t packetPos; uint32_t opCode; uint32_t channelID; @@ -67,8 +76,6 @@ uint32_t streamID; uint32_t flag; // stream only - - bool ownBlock; }; #endif // VNSI_REQUESTPACKET_H diff -Nru vdr-plugin-vnsiserver-1.3.1/responsepacket.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/responsepacket.c --- vdr-plugin-vnsiserver-1.3.1/responsepacket.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/responsepacket.c 2016-04-06 23:08:27.000000000 +0000 @@ -28,10 +28,13 @@ * This code is taken from VOMP for VDR plugin. */ +#include "responsepacket.h" +#include "vnsicommand.h" +#include "config.h" + #include #include #include -#include #ifndef __FreeBSD__ #include @@ -41,10 +44,6 @@ #define __cpu_to_be64 htobe64 #endif -#include "responsepacket.h" -#include "vnsicommand.h" -#include "config.h" - /* Packet format for an RR channel response: 4 bytes = channel ID = 1 (request/response channel) @@ -73,7 +72,7 @@ } } -bool cResponsePacket::init(uint32_t requestID) +void cResponsePacket::init(uint32_t requestID) { initBuffers(); @@ -87,11 +86,9 @@ memcpy(&buffer[userDataLenPos], &ul, sizeof(uint32_t)); bufUsed = headerLength; - - return true; } -bool cResponsePacket::initScan(uint32_t opCode) +void cResponsePacket::initScan(uint32_t opCode) { initBuffers(); @@ -105,11 +102,9 @@ memcpy(&buffer[userDataLenPos], &ul, sizeof(uint32_t)); bufUsed = headerLength; - - return true; } -bool cResponsePacket::initStatus(uint32_t opCode) +void cResponsePacket::initStatus(uint32_t opCode) { initBuffers(); @@ -123,11 +118,9 @@ memcpy(&buffer[userDataLenPos], &ul, sizeof(uint32_t)); bufUsed = headerLength; - - return true; } -bool cResponsePacket::initStream(uint32_t opCode, uint32_t streamID, uint32_t duration, int64_t pts, int64_t dts, uint32_t serial) +void cResponsePacket::initStream(uint32_t opCode, uint32_t streamID, uint32_t duration, int64_t pts, int64_t dts, uint32_t serial) { initBuffers(); @@ -152,11 +145,9 @@ memcpy(&buffer[userDataLenPosStream], &ul, sizeof(uint32_t)); bufUsed = headerLengthStream; - - return true; } -bool cResponsePacket::initOsd(uint32_t opCode, int32_t wnd, int32_t color, int32_t x0, int32_t y0, int32_t x1, int32_t y1) +void cResponsePacket::initOsd(uint32_t opCode, int32_t wnd, int32_t color, int32_t x0, int32_t y0, int32_t x1, int32_t y1) { initBuffers(); @@ -183,8 +174,6 @@ memcpy(&buffer[userDataLenPosOSD], &ul, sizeof(uint32_t)); bufUsed = headerLengthOSD; - - return true; } void cResponsePacket::finalise() diff -Nru vdr-plugin-vnsiserver-1.3.1/responsepacket.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/responsepacket.h --- vdr-plugin-vnsiserver-1.3.1/responsepacket.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/responsepacket.h 2016-04-06 23:08:27.000000000 +0000 @@ -31,17 +31,19 @@ #ifndef VNSI_RESPONSEPACKET_H #define VNSI_RESPONSEPACKET_H +#include + class cResponsePacket { public: cResponsePacket(); ~cResponsePacket(); - bool init(uint32_t requestID); - bool initScan(uint32_t opCode); - bool initStatus(uint32_t opCode); - bool initStream(uint32_t opCode, uint32_t streamID, uint32_t duration, int64_t pts, int64_t dts, uint32_t serial); - bool initOsd(uint32_t opCode, int32_t wnd, int32_t color, int32_t x0, int32_t y0, int32_t x1, int32_t y1); + void init(uint32_t requestID); + void initScan(uint32_t opCode); + void initStatus(uint32_t opCode); + void initStream(uint32_t opCode, uint32_t streamID, uint32_t duration, int64_t pts, int64_t dts, uint32_t serial); + void initOsd(uint32_t opCode, int32_t wnd, int32_t color, int32_t x0, int32_t y0, int32_t x1, int32_t y1); void finalise(); void finaliseStream(); void finaliseOSD(); diff -Nru vdr-plugin-vnsiserver-1.3.1/status.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/status.c --- vdr-plugin-vnsiserver-1.3.1/status.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/status.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,9 +22,10 @@ * */ -#include "vnsi.h" #include "status.h" +#include "vnsi.h" #include "vnsiclient.h" + #include #include #include @@ -43,7 +44,7 @@ { delete (*i); } - m_clients.erase(m_clients.begin(), m_clients.end()); + m_clients.clear(); } void cVNSIStatus::AddClient(cVNSIClient* client) @@ -55,17 +56,43 @@ void cVNSIStatus::Action(void) { cTimeMs chanTimer(0); + cTimeMs epgTimer(0); + + // get initial state of the recordings +#if VDRVERSNUM >= 20301 + cStateKey chanState; + const cChannels *channels = cChannels::GetChannelsRead(chanState); + chanState.Remove(); +#endif // get initial state of the recordings +#if VDRVERSNUM >= 20301 + cStateKey recState; + const cRecordings *recordings = cRecordings::GetRecordingsRead(recState); + recState.Remove(); +#else int recState = -1; Recordings.StateChanged(recState); +#endif // get initial state of the timers +#if VDRVERSNUM >= 20301 + cStateKey timerState; + const cTimers *timers = cTimers::GetTimersRead(timerState); + timerState.Remove(); +#else int timerState = -1; Timers.Modified(timerState); +#endif // last update of epg +#if VDRVERSNUM >= 20301 + cStateKey epgState; + const cSchedules *epg = cSchedules::GetSchedulesRead(epgState); + epgState.Remove(); +#else time_t epgUpdate = cSchedules::Modified(); +#endif // delete old timeshift file cString cmd; @@ -85,7 +112,7 @@ cmd = cString::sprintf("rm -f %s/*.vnsi", VideoDirectory); #endif } - int ret = system(cmd); + system(cmd); // set thread priority SetPriority(1); @@ -112,11 +139,24 @@ * Don't to updates during running channel scan, KODI's PVR manager becomes * restarted of finished scan. */ - if (!cVNSIClient::InhibidDataUpdates()) + if (!cVNSIClient::InhibidDataUpdates() && m_clients.size() > 0) { + // reset inactivity timeout as long as there are clients connected + ShutdownHandler.SetUserInactiveTimeout(); + // trigger clients to reload the modified channel list - if(m_clients.size() > 0 && chanTimer.TimedOut()) + if(chanTimer.TimedOut()) { +#if VDRVERSNUM >= 20301 + if (channels->Lock(chanState)) + { + chanState.Remove(); + INFOLOG("Requesting clients to reload channel list"); + for (ClientList::iterator i = m_clients.begin(); i != m_clients.end(); i++) + (*i)->ChannelsChange(); + chanTimer.Set(5000); + } +#else int modified = Channels.Modified(); if (modified) { @@ -126,14 +166,45 @@ (*i)->ChannelsChange(); } chanTimer.Set(5000); +#endif } - // reset inactivity timeout as long as there are clients connected - if(m_clients.size() > 0) + +#if VDRVERSNUM >= 20301 + if (recordings->Lock(recState)) { - ShutdownHandler.SetUserInactiveTimeout(); + recState.Remove(); + INFOLOG("Requesting clients to reload recordings list"); + for (ClientList::iterator i = m_clients.begin(); i != m_clients.end(); i++) + { + (*i)->RecordingsChange(); + } } + if (timers->Lock(timerState)) + { + timerState.Remove(); + INFOLOG("Requesting clients to reload timers"); + for (ClientList::iterator i = m_clients.begin(); i != m_clients.end(); i++) + { + (*i)->TimerChange(); + } + } + + if (epgTimer.TimedOut()) + { + if (epg->Lock(epgState)) + { + epgState.Remove(); + INFOLOG("Requesting clients to load epg"); + for (ClientList::iterator i = m_clients.begin(); i != m_clients.end(); i++) + { + (*i)->EpgChange(); + } + epgTimer.Set(5000); + } + } +#else // update recordings if(Recordings.StateChanged(recState)) { @@ -163,6 +234,7 @@ } epgUpdate = time(NULL); } +#endif } m_mutex.Unlock(); diff -Nru vdr-plugin-vnsiserver-1.3.1/status.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/status.h --- vdr-plugin-vnsiserver-1.3.1/status.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/status.h 2016-04-06 23:08:27.000000000 +0000 @@ -34,6 +34,7 @@ class cVNSIStatus : public cThread { public: + cVNSIStatus() : cThread("VNSI Status") {}; virtual ~cVNSIStatus(); void Shutdown(); void AddClient(cVNSIClient* client); diff -Nru vdr-plugin-vnsiserver-1.3.1/streamer.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/streamer.c --- vdr-plugin-vnsiserver-1.3.1/streamer.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/streamer.c 2016-04-06 23:08:27.000000000 +0000 @@ -97,12 +97,30 @@ } else if (PlayRecording && serial == -1) { +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_READ; + for (const cTimer *timer = Timers->First(); timer; timer = Timers->Next(timer)) +#else for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) +#endif { if (timer && timer->Recording() && timer->Channel() == m_Channel) { +#if VDRVERSNUM >= 20301 + LOCK_RECORDINGS_READ; + cTimer t(*timer); + cRecording matchRec(&t, t.Event()); + const cRecording *rec; + { + rec = Recordings->GetByName(matchRec.FileName()); + if (!rec) + { + return false; + } + } +#else Recordings.Load(); cRecording matchRec(timer, timer->Event()); cRecording *rec; @@ -114,6 +132,7 @@ return false; } } +#endif m_VideoBuffer = cVideoBuffer::Create(rec); recording = true; break; @@ -331,11 +350,7 @@ if(pkt->size == 0) return; - if (!m_streamHeader.initStream(VNSI_STREAM_MUXPKT, pkt->id, pkt->duration, pkt->pts, pkt->dts, pkt->serial)) - { - ERRORLOG("stream response packet init fail"); - return; - } + m_streamHeader.initStream(VNSI_STREAM_MUXPKT, pkt->id, pkt->duration, pkt->pts, pkt->dts, pkt->serial); m_streamHeader.setLen(m_streamHeader.getStreamHeaderLength() + pkt->size); m_streamHeader.finaliseStream(); @@ -350,136 +365,130 @@ void cLiveStreamer::sendStreamChange() { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStream(VNSI_STREAM_CHANGE, 0, 0, 0, 0, 0)) - { - ERRORLOG("stream response packet init fail"); - delete resp; - return; - } + cResponsePacket resp; + resp.initStream(VNSI_STREAM_CHANGE, 0, 0, 0, 0, 0); uint32_t FpsScale, FpsRate, Height, Width; double Aspect; uint32_t Channels, SampleRate, BitRate, BitsPerSample, BlockAlign; for (cTSStream* stream = m_Demuxer.GetFirstStream(); stream; stream = m_Demuxer.GetNextStream()) { - resp->add_U32(stream->GetPID()); + resp.add_U32(stream->GetPID()); if (stream->Type() == stMPEG2AUDIO) { stream->GetAudioInformation(Channels, SampleRate, BitRate, BitsPerSample, BlockAlign); - resp->add_String("MPEG2AUDIO"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(Channels); - resp->add_U32(SampleRate); - resp->add_U32(BlockAlign); - resp->add_U32(BitRate); - resp->add_U32(BitsPerSample); + resp.add_String("MPEG2AUDIO"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(Channels); + resp.add_U32(SampleRate); + resp.add_U32(BlockAlign); + resp.add_U32(BitRate); + resp.add_U32(BitsPerSample); for (unsigned int i = 0; i < stream->GetSideDataTypes()->size(); i++) { - resp->add_U32(stream->GetSideDataTypes()->at(i).first); + resp.add_U32(stream->GetSideDataTypes()->at(i).first); if (stream->GetSideDataTypes()->at(i).second == scRDS) { - resp->add_String("RDS"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(stream->GetPID()); + resp.add_String("RDS"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(stream->GetPID()); } } } else if (stream->Type() == stMPEG2VIDEO) { stream->GetVideoInformation(FpsScale, FpsRate, Height, Width, Aspect); - resp->add_String("MPEG2VIDEO"); - resp->add_U32(FpsScale); - resp->add_U32(FpsRate); - resp->add_U32(Height); - resp->add_U32(Width); - resp->add_double(Aspect); + resp.add_String("MPEG2VIDEO"); + resp.add_U32(FpsScale); + resp.add_U32(FpsRate); + resp.add_U32(Height); + resp.add_U32(Width); + resp.add_double(Aspect); } else if (stream->Type() == stAC3) { stream->GetAudioInformation(Channels, SampleRate, BitRate, BitsPerSample, BlockAlign); - resp->add_String("AC3"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(Channels); - resp->add_U32(SampleRate); - resp->add_U32(BlockAlign); - resp->add_U32(BitRate); - resp->add_U32(BitsPerSample); + resp.add_String("AC3"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(Channels); + resp.add_U32(SampleRate); + resp.add_U32(BlockAlign); + resp.add_U32(BitRate); + resp.add_U32(BitsPerSample); } else if (stream->Type() == stH264) { stream->GetVideoInformation(FpsScale, FpsRate, Height, Width, Aspect); - resp->add_String("H264"); - resp->add_U32(FpsScale); - resp->add_U32(FpsRate); - resp->add_U32(Height); - resp->add_U32(Width); - resp->add_double(Aspect); + resp.add_String("H264"); + resp.add_U32(FpsScale); + resp.add_U32(FpsRate); + resp.add_U32(Height); + resp.add_U32(Width); + resp.add_double(Aspect); } else if (stream->Type() == stDVBSUB) { - resp->add_String("DVBSUB"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(stream->CompositionPageId()); - resp->add_U32(stream->AncillaryPageId()); + resp.add_String("DVBSUB"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(stream->CompositionPageId()); + resp.add_U32(stream->AncillaryPageId()); } else if (stream->Type() == stTELETEXT) { - resp->add_String("TELETEXT"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(stream->CompositionPageId()); - resp->add_U32(stream->AncillaryPageId()); + resp.add_String("TELETEXT"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(stream->CompositionPageId()); + resp.add_U32(stream->AncillaryPageId()); } else if (stream->Type() == stAACADTS) { stream->GetAudioInformation(Channels, SampleRate, BitRate, BitsPerSample, BlockAlign); - resp->add_String("AAC"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(Channels); - resp->add_U32(SampleRate); - resp->add_U32(BlockAlign); - resp->add_U32(BitRate); - resp->add_U32(BitsPerSample); + resp.add_String("AAC"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(Channels); + resp.add_U32(SampleRate); + resp.add_U32(BlockAlign); + resp.add_U32(BitRate); + resp.add_U32(BitsPerSample); } else if (stream->Type() == stAACLATM) { stream->GetAudioInformation(Channels, SampleRate, BitRate, BitsPerSample, BlockAlign); - resp->add_String("AAC_LATM"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(Channels); - resp->add_U32(SampleRate); - resp->add_U32(BlockAlign); - resp->add_U32(BitRate); - resp->add_U32(BitsPerSample); + resp.add_String("AAC_LATM"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(Channels); + resp.add_U32(SampleRate); + resp.add_U32(BlockAlign); + resp.add_U32(BitRate); + resp.add_U32(BitsPerSample); } else if (stream->Type() == stEAC3) { stream->GetAudioInformation(Channels, SampleRate, BitRate, BitsPerSample, BlockAlign); - resp->add_String("EAC3"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(Channels); - resp->add_U32(SampleRate); - resp->add_U32(BlockAlign); - resp->add_U32(BitRate); - resp->add_U32(BitsPerSample); + resp.add_String("EAC3"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(Channels); + resp.add_U32(SampleRate); + resp.add_U32(BlockAlign); + resp.add_U32(BitRate); + resp.add_U32(BitsPerSample); } else if (stream->Type() == stDTS) { stream->GetAudioInformation(Channels, SampleRate, BitRate, BitsPerSample, BlockAlign); - resp->add_String("DTS"); - resp->add_String(stream->GetLanguage()); - resp->add_U32(Channels); - resp->add_U32(SampleRate); - resp->add_U32(BlockAlign); - resp->add_U32(BitRate); - resp->add_U32(BitsPerSample); + resp.add_String("DTS"); + resp.add_String(stream->GetLanguage()); + resp.add_U32(Channels); + resp.add_U32(SampleRate); + resp.add_U32(BlockAlign); + resp.add_U32(BitRate); + resp.add_U32(BitsPerSample); } } - resp->finaliseStream(); - m_Socket->write(resp->getPtr(), resp->getLen()); - delete resp; + resp.finaliseStream(); + m_Socket->write(resp.getPtr(), resp.getLen()); } void cLiveStreamer::sendSignalInfo() @@ -488,24 +497,17 @@ return a empty signalinfo package */ if (m_Frontend == -2) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStream(VNSI_STREAM_SIGNALINFO, 0, 0, 0, 0, 0)) - { - ERRORLOG("stream response packet init fail"); - delete resp; - return; - } - - resp->add_String(*cString::sprintf("Unknown")); - resp->add_String(*cString::sprintf("Unknown")); - resp->add_U32(0); - resp->add_U32(0); - resp->add_U32(0); - resp->add_U32(0); - - resp->finaliseStream(); - m_Socket->write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initStream(VNSI_STREAM_SIGNALINFO, 0, 0, 0, 0, 0); + resp.add_String(*cString::sprintf("Unknown")); + resp.add_String(*cString::sprintf("Unknown")); + resp.add_U32(0); + resp.add_U32(0); + resp.add_U32(0); + resp.add_U32(0); + + resp.finaliseStream(); + m_Socket->write(resp.getPtr(), resp.getLen()); return; } @@ -536,23 +538,17 @@ if (m_Frontend >= 0) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStream(VNSI_STREAM_SIGNALINFO, 0, 0, 0, 0, 0)) - { - ERRORLOG("stream response packet init fail"); - delete resp; - return; - } - resp->add_String(*cString::sprintf("Analog #%s - %s (%s)", *m_DeviceString, (char *) m_vcap.card, m_vcap.driver)); - resp->add_String(""); - resp->add_U32(0); - resp->add_U32(0); - resp->add_U32(0); - resp->add_U32(0); - - resp->finaliseStream(); - m_Socket->write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initStream(VNSI_STREAM_SIGNALINFO, 0, 0, 0, 0, 0); + resp.add_String(*cString::sprintf("Analog #%s - %s (%s)", *m_DeviceString, (char *) m_vcap.card, m_vcap.driver)); + resp.add_String(""); + resp.add_U32(0); + resp.add_U32(0); + resp.add_U32(0); + resp.add_U32(0); + + resp.finaliseStream(); + m_Socket->write(resp.getPtr(), resp.getLen()); } } else @@ -576,13 +572,8 @@ if (m_Frontend >= 0) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStream(VNSI_STREAM_SIGNALINFO, 0, 0, 0, 0, 0)) - { - ERRORLOG("stream response packet init fail"); - delete resp; - return; - } + cResponsePacket resp; + resp.initStream(VNSI_STREAM_SIGNALINFO, 0, 0, 0, 0, 0); fe_status_t status; uint16_t fe_snr; @@ -605,82 +596,69 @@ switch (m_Channel->Source() & cSource::st_Mask) { case cSource::stSat: - resp->add_String(*cString::sprintf("DVB-S%s #%d - %s", (m_FrontendInfo.caps & 0x10000000) ? "2" : "", cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); + resp.add_String(*cString::sprintf("DVB-S%s #%d - %s", (m_FrontendInfo.caps & 0x10000000) ? "2" : "", cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); break; case cSource::stCable: - resp->add_String(*cString::sprintf("DVB-C #%d - %s", cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); + resp.add_String(*cString::sprintf("DVB-C #%d - %s", cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); break; case cSource::stTerr: - resp->add_String(*cString::sprintf("DVB-T #%d - %s", cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); + resp.add_String(*cString::sprintf("DVB-T #%d - %s", cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); break; } - resp->add_String(*cString::sprintf("%s:%s:%s:%s:%s", (status & FE_HAS_LOCK) ? "LOCKED" : "-", (status & FE_HAS_SIGNAL) ? "SIGNAL" : "-", (status & FE_HAS_CARRIER) ? "CARRIER" : "-", (status & FE_HAS_VITERBI) ? "VITERBI" : "-", (status & FE_HAS_SYNC) ? "SYNC" : "-")); - resp->add_U32(fe_snr); - resp->add_U32(fe_signal); - resp->add_U32(fe_ber); - resp->add_U32(fe_unc); - - resp->finaliseStream(); - m_Socket->write(resp->getPtr(), resp->getLen()); - delete resp; + resp.add_String(*cString::sprintf("%s:%s:%s:%s:%s", (status & FE_HAS_LOCK) ? "LOCKED" : "-", (status & FE_HAS_SIGNAL) ? "SIGNAL" : "-", (status & FE_HAS_CARRIER) ? "CARRIER" : "-", (status & FE_HAS_VITERBI) ? "VITERBI" : "-", (status & FE_HAS_SYNC) ? "SYNC" : "-")); + resp.add_U32(fe_snr); + resp.add_U32(fe_signal); + resp.add_U32(fe_ber); + resp.add_U32(fe_unc); + + resp.finaliseStream(); + m_Socket->write(resp.getPtr(), resp.getLen()); } } } void cLiveStreamer::sendStreamStatus() { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStream(VNSI_STREAM_STATUS, 0, 0, 0, 0, 0)) - { - ERRORLOG("stream response packet init fail"); - delete resp; - return; - } + cResponsePacket resp; + resp.initStream(VNSI_STREAM_STATUS, 0, 0, 0, 0, 0); uint16_t error = m_Demuxer.GetError(); if (error & ERROR_PES_SCRAMBLE) { INFOLOG("Channel: scrambled %d", error); - resp->add_String(cString::sprintf("Channel: scrambled (%d)", error)); + resp.add_String(cString::sprintf("Channel: scrambled (%d)", error)); } else if (error & ERROR_PES_STARTCODE) { INFOLOG("Channel: startcode %d", error); - resp->add_String(cString::sprintf("Channel: encrypted? (%d)", error)); + resp.add_String(cString::sprintf("Channel: encrypted? (%d)", error)); } else if (error & ERROR_DEMUX_NODATA) { INFOLOG("Channel: no data %d", error); - resp->add_String(cString::sprintf("Channel: no data")); + resp.add_String(cString::sprintf("Channel: no data")); } else { INFOLOG("Channel: unknown error %d", error); - resp->add_String(cString::sprintf("Channel: unknown error (%d)", error)); + resp.add_String(cString::sprintf("Channel: unknown error (%d)", error)); } - resp->finaliseStream(); - m_Socket->write(resp->getPtr(), resp->getLen()); - delete resp; + resp.finaliseStream(); + m_Socket->write(resp.getPtr(), resp.getLen()); } void cLiveStreamer::sendBufferStatus() { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStream(VNSI_STREAM_BUFFERSTATS, 0, 0, 0, 0, 0)) - { - ERRORLOG("stream response packet init fail"); - delete resp; - return; - } + cResponsePacket resp; + resp.initStream(VNSI_STREAM_BUFFERSTATS, 0, 0, 0, 0, 0); uint32_t start, end; bool timeshift; m_Demuxer.BufferStatus(timeshift, start, end); - resp->add_U8(timeshift); - resp->add_U32(start); - resp->add_U32(end); - resp->finaliseStream(); - m_Socket->write(resp->getPtr(), resp->getLen()); - delete resp; + resp.add_U8(timeshift); + resp.add_U32(start); + resp.add_U32(end); + resp.finaliseStream(); + m_Socket->write(resp.getPtr(), resp.getLen()); } void cLiveStreamer::sendRefTime(sStreamPacket *pkt) @@ -688,19 +666,12 @@ if(pkt == NULL) return; - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStream(VNSI_STREAM_REFTIME, 0, 0, 0, 0, 0)) - { - ERRORLOG("stream response packet init fail"); - delete resp; - return; - } - - resp->add_U32(pkt->reftime); - resp->add_U64(pkt->pts); - resp->finaliseStream(); - m_Socket->write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initStream(VNSI_STREAM_REFTIME, 0, 0, 0, 0, 0); + resp.add_U32(pkt->reftime); + resp.add_U64(pkt->pts); + resp.finaliseStream(); + m_Socket->write(resp.getPtr(), resp.getLen()); } bool cLiveStreamer::SeekTime(int64_t time, uint32_t &serial) diff -Nru vdr-plugin-vnsiserver-1.3.1/videobuffer.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/videobuffer.c --- vdr-plugin-vnsiserver-1.3.1/videobuffer.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/videobuffer.c 2016-04-06 23:08:27.000000000 +0000 @@ -40,32 +40,25 @@ { friend class cVideoBuffer; public: - virtual void Put(uint8_t *buf, unsigned int size); + virtual void Put(const uint8_t *buf, unsigned int size); virtual int ReadBlock(uint8_t **buf, unsigned int size, time_t &endTime, time_t &wrapTime); protected: cVideoBufferSimple(); - virtual ~cVideoBufferSimple(); - cRingBufferLinear *m_Buffer; + cRingBufferLinear m_Buffer; int m_BytesConsumed; }; cVideoBufferSimple::cVideoBufferSimple() + :m_Buffer(MEGABYTE(3), TS_SIZE * 2, false) { - m_Buffer = new cRingBufferLinear(MEGABYTE(3), TS_SIZE * 2, false); - m_Buffer->SetTimeouts(0, 100); + m_Buffer.SetTimeouts(0, 100); m_BytesConsumed = 0; } -cVideoBufferSimple::~cVideoBufferSimple() +void cVideoBufferSimple::Put(const uint8_t *buf, unsigned int size) { - if (m_Buffer) - delete m_Buffer; -} - -void cVideoBufferSimple::Put(uint8_t *buf, unsigned int size) -{ - m_Buffer->Put(buf, size); + m_Buffer.Put(buf, size); } int cVideoBufferSimple::ReadBlock(uint8_t **buf, unsigned int size, time_t &endTime, time_t &wrapTime) @@ -73,10 +66,10 @@ int readBytes; if (m_BytesConsumed) { - m_Buffer->Del(m_BytesConsumed); + m_Buffer.Del(m_BytesConsumed); } m_BytesConsumed = 0; - *buf = m_Buffer->Get(readBytes); + *buf = m_Buffer.Get(readBytes); if (!(*buf) || readBytes < TS_SIZE) { usleep(100); @@ -94,7 +87,7 @@ if ((*buf)[0] != TS_SYNC_BYTE) { - m_Buffer->Del(m_BytesConsumed); + m_Buffer.Del(m_BytesConsumed); m_BytesConsumed = 0; return 0; } @@ -198,7 +191,7 @@ { friend class cVideoBuffer; public: - virtual void Put(uint8_t *buf, unsigned int size); + virtual void Put(const uint8_t *buf, unsigned int size); virtual int ReadBlock(uint8_t **buf, unsigned int size, time_t &endTime, time_t &wrapTime); virtual void SetPos(off_t pos); @@ -217,8 +210,7 @@ cVideoBufferRAM::~cVideoBufferRAM() { - if (m_Buffer) - free(m_Buffer); + free(m_Buffer); } bool cVideoBufferRAM::Init() @@ -243,7 +235,7 @@ m_BytesConsumed = 0; } -void cVideoBufferRAM::Put(uint8_t *buf, unsigned int size) +void cVideoBufferRAM::Put(const uint8_t *buf, unsigned int size) { if (Available() + MARGIN >= m_BufferSize) { @@ -303,7 +295,7 @@ if (m_ReadPtr > (m_BufferSize - m_Margin)) { int bytesToCopy = m_BufferSize - m_ReadPtr; - memmove(m_Buffer + (m_Margin - bytesToCopy), m_Buffer + m_ReadPtr, bytesToCopy); + memmove(m_Buffer + (m_Margin - bytesToCopy), m_BufferPtr + m_ReadPtr, bytesToCopy); *buf = m_Buffer + (m_Margin - bytesToCopy); } else @@ -335,7 +327,7 @@ friend class cVideoBuffer; public: virtual off_t GetPosMax(); - virtual void Put(uint8_t *buf, unsigned int size); + virtual void Put(const uint8_t *buf, unsigned int size); virtual int ReadBlock(uint8_t **buf, unsigned int size, time_t &endTime, time_t &wrapTime); virtual void SetPos(off_t pos); @@ -451,7 +443,7 @@ return posMax; } -void cVideoBufferFile::Put(uint8_t *buf, unsigned int size) +void cVideoBufferFile::Put(const uint8_t *buf, unsigned int size) { if (Available() + MARGIN >= m_BufferSize) { @@ -626,22 +618,22 @@ friend class cVideoBuffer; public: virtual off_t GetPosMax(); - virtual void Put(uint8_t *buf, unsigned int size); + virtual void Put(const uint8_t *buf, unsigned int size); virtual int ReadBlock(uint8_t **buf, unsigned int size, time_t &endTime, time_t &wrapTime); virtual time_t GetRefTime(); protected: - cVideoBufferRecording(cRecording *rec); + cVideoBufferRecording(const cRecording *rec); virtual ~cVideoBufferRecording(); virtual bool Init(); virtual off_t Available(); off_t GetPosEnd(); cRecPlayer *m_RecPlayer; - cRecording *m_Recording; + const cRecording *m_Recording; cTimeMs m_ScanTimer; }; -cVideoBufferRecording::cVideoBufferRecording(cRecording *rec) +cVideoBufferRecording::cVideoBufferRecording(const cRecording *rec) { m_Recording = rec; m_ReadCacheSize = 0; @@ -662,7 +654,7 @@ return cVideoBufferFile::GetPosMax(); } -void cVideoBufferRecording::Put(uint8_t *buf, unsigned int size) +void cVideoBufferRecording::Put(const uint8_t *buf, unsigned int size) { } @@ -778,7 +770,7 @@ friend class cVideoBuffer; public: virtual off_t GetPosMax(); - virtual void Put(uint8_t *buf, unsigned int size); + virtual void Put(const uint8_t *buf, unsigned int size); protected: cVideoBufferTest(cString filename); @@ -818,7 +810,7 @@ return end; } -void cVideoBufferTest::Put(uint8_t *buf, unsigned int size) +void cVideoBufferTest::Put(const uint8_t *buf, unsigned int size) { } @@ -915,7 +907,7 @@ return buffer; } -cVideoBuffer* cVideoBuffer::Create(cRecording *rec) +cVideoBuffer* cVideoBuffer::Create(const cRecording *rec) { INFOLOG("Open recording: %s", rec->FileName()); cVideoBufferRecording *buffer = new cVideoBufferRecording(rec); diff -Nru vdr-plugin-vnsiserver-1.3.1/videobuffer.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/videobuffer.h --- vdr-plugin-vnsiserver-1.3.1/videobuffer.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/videobuffer.h 2016-04-06 23:08:27.000000000 +0000 @@ -36,8 +36,8 @@ virtual ~cVideoBuffer(); static cVideoBuffer* Create(int clientID, uint8_t timeshift); static cVideoBuffer* Create(cString filename); - static cVideoBuffer* Create(cRecording *rec); - virtual void Put(uint8_t *buf, unsigned int size) = 0; + static cVideoBuffer* Create(const cRecording *rec); + virtual void Put(const uint8_t *buf, unsigned int size) = 0; virtual int ReadBlock(uint8_t **buf, unsigned int size, time_t &endTime, time_t &wrapTime) = 0; virtual off_t GetPosMin() { return 0; }; virtual off_t GetPosMax() { return 0; }; diff -Nru vdr-plugin-vnsiserver-1.3.1/videoinput.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/videoinput.c --- vdr-plugin-vnsiserver-1.3.1/videoinput.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/videoinput.c 2016-04-06 23:08:27.000000000 +0000 @@ -48,7 +48,11 @@ protected: virtual void Activate(bool On); +#if VDRVERSNUM >= 20301 + virtual void Receive(const uchar *Data, int Length); +#else virtual void Receive(uchar *Data, int Length); +#endif cVideoInput *m_VideoInput; }; @@ -66,7 +70,11 @@ } //void cLiveReceiver +#if VDRVERSNUM >= 20301 +void cLiveReceiver::Receive(const uchar *Data, int Length) +#else void cLiveReceiver::Receive(uchar *Data, int Length) +#endif { m_VideoInput->Receive(Data, Length); } @@ -122,7 +130,12 @@ { if (!assoc.isNITPid()) { +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + const cChannel *Channel = Channels->GetByServiceID(Source(), Transponder(), assoc.getServiceId()); +#else const cChannel *Channel = Channels.GetByServiceID(Source(), Transponder(), assoc.getServiceId()); +#endif if (Channel && (Channel == m_Channel)) { int prevPmtPid = m_pmtPid; @@ -160,7 +173,12 @@ } m_pmtVersion = pmt.getVersionNumber(); +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + const cChannel *Channel = Channels->GetByServiceID(Source(), Transponder(), pmt.getServiceId()); +#else cChannel *Channel = Channels.GetByServiceID(Source(), Transponder(), pmt.getServiceId()); +#endif if (Channel) { // Scan the stream-specific loop: SI::PMT::Stream stream; @@ -549,7 +567,7 @@ } } -inline void cVideoInput::Receive(uchar *data, int length) +inline void cVideoInput::Receive(const uchar *data, int length) { if (m_PmtChange) { diff -Nru vdr-plugin-vnsiserver-1.3.1/videoinput.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/videoinput.h --- vdr-plugin-vnsiserver-1.3.1/videoinput.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/videoinput.h 2016-04-06 23:08:27.000000000 +0000 @@ -47,7 +47,7 @@ virtual void Action(void); void PmtChange(int pidChange); cChannel *PmtChannel(); - void Receive(uchar *data, int length); + void Receive(const uchar *data, int length); void Retune(); cDevice *m_Device; cLivePatFilter *m_PatFilter; diff -Nru vdr-plugin-vnsiserver-1.3.1/vnsi.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsi.c --- vdr-plugin-vnsiserver-1.3.1/vnsi.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsi.c 2016-04-06 23:08:27.000000000 +0000 @@ -23,25 +23,19 @@ * */ -#include -#include #include "vnsi.h" #include "vnsicommand.h" #include "setup.h" +#include +#include + cPluginVNSIServer* cPluginVNSIServer::VNSIServer = NULL; cPluginVNSIServer::cPluginVNSIServer(void) { Server = NULL; VNSIServer = NULL; - probe = new cDvbVsniDeviceProbe(); -} - -cPluginVNSIServer::~cPluginVNSIServer() -{ - // Clean up after yourself! - delete probe; } const char *cPluginVNSIServer::CommandLineHelp(void) diff -Nru vdr-plugin-vnsiserver-1.3.1/vnsiclient.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiclient.c --- vdr-plugin-vnsiserver-1.3.1/vnsiclient.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiclient.c 2016-04-06 23:08:27.000000000 +0000 @@ -23,23 +23,11 @@ * */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - +#include "vnsiclient.h" #include "vnsi.h" #include "config.h" #include "vnsicommand.h" #include "recordingscache.h" -#include "vnsiclient.h" #include "streamer.h" #include "vnsiserver.h" #include "recplayer.h" @@ -50,6 +38,19 @@ #include "channelfilter.h" #include "channelscancontrol.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + cMutex cVNSIClient::m_timerLock; bool cVNSIClient::m_inhibidDataUpdates = false; @@ -62,12 +63,11 @@ m_bSupportRDS(false), m_ClientAddress(ClientAdr), m_RecPlayer(NULL), - m_req(NULL), - m_resp(NULL), m_Osd(NULL), m_ChannelScanControl(this) { m_socket.SetHandle(fd); + SetDescription("VNSI Client %u->%s", id, ClientAdr); Start(); } @@ -77,8 +77,9 @@ DEBUGLOG("%s", __FUNCTION__); StopChannelStreaming(); m_ChannelScanControl.StopScan(); - m_socket.close(); // force closing connection + m_socket.Shutdown(); Cancel(10); + m_socket.close(); DEBUGLOG("done"); } @@ -113,9 +114,9 @@ if (dataLength) { - data = (uint8_t*)malloc(dataLength); - if (!data) - { + try { + data = new uint8_t[dataLength]; + } catch (const std::bad_alloc &) { ERRORLOG("Extra data buffer malloc error"); break; } @@ -141,9 +142,13 @@ break; } - cRequestPacket* req = new cRequestPacket(requestID, opcode, data, dataLength); - - processRequest(req); + try { + cRequestPacket req(requestID, opcode, data, dataLength); + processRequest(req); + } catch (const std::exception &e) { + ERRORLOG("%s", e.what()); + break; + } } else { @@ -158,28 +163,23 @@ m_ChannelScanControl.StopScan(); // Shutdown OSD - if (m_Osd) - { - delete m_Osd; - m_Osd = NULL; - } + delete m_Osd; + m_Osd = NULL; } -bool cVNSIClient::StartChannelStreaming(const cChannel *channel, int32_t priority, uint8_t timeshift, uint32_t timeout) +bool cVNSIClient::StartChannelStreaming(cResponsePacket &resp, const cChannel *channel, int32_t priority, uint8_t timeshift, uint32_t timeout) { + delete m_Streamer; m_Streamer = new cLiveStreamer(m_Id, m_bSupportRDS, timeshift, timeout); - m_isStreaming = m_Streamer->StreamChannel(channel, priority, &m_socket, m_resp); + m_isStreaming = m_Streamer->StreamChannel(channel, priority, &m_socket, &resp); return m_isStreaming; } void cVNSIClient::StopChannelStreaming() { m_isStreaming = false; - if (m_Streamer) - { - delete m_Streamer; - m_Streamer = NULL; - } + delete m_Streamer; + m_Streamer = NULL; } void cVNSIClient::TimerChange(const cTimer *Timer, eTimerChange Change) @@ -193,16 +193,10 @@ if (m_StatusInterfaceEnabled) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStatus(VNSI_STATUS_TIMERCHANGE)) - { - delete resp; - return; - } - - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initStatus(VNSI_STATUS_TIMERCHANGE); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } } @@ -213,16 +207,10 @@ if (!m_StatusInterfaceEnabled) return; - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStatus(VNSI_STATUS_CHANNELCHANGE)) - { - delete resp; - return; - } - - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initStatus(VNSI_STATUS_CHANNELCHANGE); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } void cVNSIClient::RecordingsChange() @@ -232,16 +220,10 @@ if (!m_StatusInterfaceEnabled) return; - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStatus(VNSI_STATUS_RECORDINGSCHANGE)) - { - delete resp; - return; - } - - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initStatus(VNSI_STATUS_RECORDINGSCHANGE); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } void cVNSIClient::EpgChange() @@ -251,21 +233,35 @@ if (!m_StatusInterfaceEnabled) return; +#if VDRVERSNUM >= 20301 + cStateKey SchedulesStateKey(true); + const cSchedules *schedules = cSchedules::GetSchedulesRead(SchedulesStateKey); + if (!schedules) + { + return; + } +#else cSchedulesLock MutexLock; const cSchedules *schedules = cSchedules::Schedules(MutexLock); if (!schedules) return; +#endif std::map::iterator it; for (const cSchedule *schedule = schedules->First(); schedule; schedule = schedules->Next(schedule)) { - cEvent *lastEvent = schedule->Events()->Last(); + const cEvent *lastEvent = schedule->Events()->Last(); if (!lastEvent) continue; +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + const cChannel *channel = Channels->GetByChannelID(schedule->ChannelID()); +#else Channels.Lock(false); const cChannel *channel = Channels.GetByChannelID(schedule->ChannelID()); Channels.Unlock(); +#endif if (!channel) continue; @@ -288,17 +284,15 @@ INFOLOG("Trigger EPG update for channel %s, id: %d", channel->Name(), channelId); - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStatus(VNSI_STATUS_EPGCHANGE)) - { - delete resp; - return; - } - resp->add_U32(channelId); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initStatus(VNSI_STATUS_EPGCHANGE); + resp.add_U32(channelId); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } +#if VDRVERSNUM >= 20301 + SchedulesStateKey.Remove(); +#endif } void cVNSIClient::Recording(const cDevice *Device, const char *Name, const char *FileName, bool On) @@ -307,28 +301,22 @@ if (m_StatusInterfaceEnabled) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStatus(VNSI_STATUS_RECORDING)) - { - delete resp; - return; - } - - resp->add_U32(Device->CardIndex()); - resp->add_U32(On); + cResponsePacket resp; + resp.initStatus(VNSI_STATUS_RECORDING); + resp.add_U32(Device->CardIndex()); + resp.add_U32(On); if (Name) - resp->add_String(Name); + resp.add_String(Name); else - resp->add_String(""); + resp.add_String(""); if (FileName) - resp->add_String(FileName); + resp.add_String(FileName); else - resp->add_String(""); + resp.add_String(""); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } } @@ -359,19 +347,14 @@ else if (strcasecmp(Message, trVDR("Cancel editing?")) == 0) return; else if (strcasecmp(Message, trVDR("Cutter already running - Add to cutting queue?")) == 0) return; else if (strcasecmp(Message, trVDR("No index-file found. Creating may take minutes. Create one?")) == 0) return; + else if (strncmp(Message, trVDR("VDR will shut down in"), 21) == 0) return; - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initStatus(VNSI_STATUS_MESSAGE)) - { - delete resp; - return; - } - - resp->add_U32(0); - resp->add_String(Message); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initStatus(VNSI_STATUS_MESSAGE); + resp.add_U32(0); + resp.add_String(Message); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } } @@ -384,220 +367,211 @@ } } -bool cVNSIClient::processRequest(cRequestPacket* req) +bool cVNSIClient::processRequest(cRequestPacket &req) { cMutexLock lock(&m_msgLock); - m_req = req; - m_resp = new cResponsePacket(); - if (!m_resp->init(m_req->getRequestID())) - { - ERRORLOG("Response packet init fail"); - delete m_resp; - delete m_req; - m_resp = NULL; - m_req = NULL; - return false; - } - bool result = false; - switch(m_req->getOpCode()) + switch(req.getOpCode()) { /** OPCODE 1 - 19: VNSI network functions for general purpose */ case VNSI_LOGIN: - result = process_Login(); + result = process_Login(req); break; case VNSI_GETTIME: - result = process_GetTime(); + result = process_GetTime(req); break; case VNSI_ENABLESTATUSINTERFACE: - result = process_EnableStatusInterface(); + result = process_EnableStatusInterface(req); break; case VNSI_PING: - result = process_Ping(); + result = process_Ping(req); break; case VNSI_GETSETUP: - result = process_GetSetup(); + result = process_GetSetup(req); break; case VNSI_STORESETUP: - result = process_StoreSetup(); + result = process_StoreSetup(req); break; /** OPCODE 20 - 39: VNSI network functions for live streaming */ case VNSI_CHANNELSTREAM_OPEN: - result = processChannelStream_Open(); + result = processChannelStream_Open(req); break; case VNSI_CHANNELSTREAM_CLOSE: - result = processChannelStream_Close(); + result = processChannelStream_Close(req); break; case VNSI_CHANNELSTREAM_SEEK: - result = processChannelStream_Seek(); + result = processChannelStream_Seek(req); break; /** OPCODE 40 - 59: VNSI network functions for recording streaming */ case VNSI_RECSTREAM_OPEN: - result = processRecStream_Open(); + result = processRecStream_Open(req); break; case VNSI_RECSTREAM_CLOSE: - result = processRecStream_Close(); + result = processRecStream_Close(req); break; case VNSI_RECSTREAM_GETBLOCK: - result = processRecStream_GetBlock(); + result = processRecStream_GetBlock(req); break; case VNSI_RECSTREAM_POSTOFRAME: - result = processRecStream_PositionFromFrameNumber(); + result = processRecStream_PositionFromFrameNumber(req); break; case VNSI_RECSTREAM_FRAMETOPOS: - result = processRecStream_FrameNumberFromPosition(); + result = processRecStream_FrameNumberFromPosition(req); break; case VNSI_RECSTREAM_GETIFRAME: - result = processRecStream_GetIFrame(); + result = processRecStream_GetIFrame(req); break; case VNSI_RECSTREAM_GETLENGTH: - result = processRecStream_GetLength(); + result = processRecStream_GetLength(req); break; /** OPCODE 60 - 79: VNSI network functions for channel access */ case VNSI_CHANNELS_GETCOUNT: - result = processCHANNELS_ChannelsCount(); + result = processCHANNELS_ChannelsCount(req); break; case VNSI_CHANNELS_GETCHANNELS: - result = processCHANNELS_GetChannels(); + result = processCHANNELS_GetChannels(req); break; case VNSI_CHANNELGROUP_GETCOUNT: - result = processCHANNELS_GroupsCount(); + result = processCHANNELS_GroupsCount(req); break; case VNSI_CHANNELGROUP_LIST: - result = processCHANNELS_GroupList(); + result = processCHANNELS_GroupList(req); break; case VNSI_CHANNELGROUP_MEMBERS: - result = processCHANNELS_GetGroupMembers(); + result = processCHANNELS_GetGroupMembers(req); break; case VNSI_CHANNELS_GETCAIDS: - result = processCHANNELS_GetCaids(); + result = processCHANNELS_GetCaids(req); break; case VNSI_CHANNELS_GETWHITELIST: - result = processCHANNELS_GetWhitelist(); + result = processCHANNELS_GetWhitelist(req); break; case VNSI_CHANNELS_GETBLACKLIST: - result = processCHANNELS_GetBlacklist(); + result = processCHANNELS_GetBlacklist(req); break; case VNSI_CHANNELS_SETWHITELIST: - result = processCHANNELS_SetWhitelist(); + result = processCHANNELS_SetWhitelist(req); break; case VNSI_CHANNELS_SETBLACKLIST: - result = processCHANNELS_SetBlacklist(); + result = processCHANNELS_SetBlacklist(req); break; /** OPCODE 80 - 99: VNSI network functions for timer access */ case VNSI_TIMER_GETCOUNT: - result = processTIMER_GetCount(); + result = processTIMER_GetCount(req); break; case VNSI_TIMER_GET: - result = processTIMER_Get(); + result = processTIMER_Get(req); break; case VNSI_TIMER_GETLIST: - result = processTIMER_GetList(); + result = processTIMER_GetList(req); break; case VNSI_TIMER_ADD: - result = processTIMER_Add(); + result = processTIMER_Add(req); break; case VNSI_TIMER_DELETE: - result = processTIMER_Delete(); + result = processTIMER_Delete(req); break; case VNSI_TIMER_UPDATE: - result = processTIMER_Update(); + result = processTIMER_Update(req); break; + case VNSI_TIMER_GETTYPES: + result = processTIMER_GetTypes(req); + break; /** OPCODE 100 - 119: VNSI network functions for recording access */ case VNSI_RECORDINGS_DISKSIZE: - result = processRECORDINGS_GetDiskSpace(); + result = processRECORDINGS_GetDiskSpace(req); break; case VNSI_RECORDINGS_GETCOUNT: - result = processRECORDINGS_GetCount(); + result = processRECORDINGS_GetCount(req); break; case VNSI_RECORDINGS_GETLIST: - result = processRECORDINGS_GetList(); + result = processRECORDINGS_GetList(req); break; case VNSI_RECORDINGS_RENAME: - result = processRECORDINGS_Rename(); + result = processRECORDINGS_Rename(req); break; case VNSI_RECORDINGS_DELETE: - result = processRECORDINGS_Delete(); + result = processRECORDINGS_Delete(req); break; case VNSI_RECORDINGS_GETEDL: - result = processRECORDINGS_GetEdl(); + result = processRECORDINGS_GetEdl(req); break; /** OPCODE 120 - 139: VNSI network functions for epg access and manipulating */ case VNSI_EPG_GETFORCHANNEL: - result = processEPG_GetForChannel(); + result = processEPG_GetForChannel(req); break; /** OPCODE 140 - 159: VNSI network functions for channel scanning */ case VNSI_SCAN_SUPPORTED: - result = processSCAN_ScanSupported(); + result = processSCAN_ScanSupported(req); break; case VNSI_SCAN_GETCOUNTRIES: - result = processSCAN_GetCountries(); + result = processSCAN_GetCountries(req); break; case VNSI_SCAN_GETSATELLITES: - result = processSCAN_GetSatellites(); + result = processSCAN_GetSatellites(req); break; case VNSI_SCAN_START: - result = processSCAN_Start(); + result = processSCAN_Start(req); break; case VNSI_SCAN_STOP: - result = processSCAN_Stop(); + result = processSCAN_Stop(req); break; case VNSI_SCAN_SUPPORTED_TYPES: - result = processSCAN_GetSupportedTypes(); + result = processSCAN_GetSupportedTypes(req); break; /** OPCODE 160 - 179: VNSI network functions for OSD */ case VNSI_OSD_CONNECT: - result = processOSD_Connect(); + result = processOSD_Connect(req); break; case VNSI_OSD_DISCONNECT: @@ -605,55 +579,49 @@ break; case VNSI_OSD_HITKEY: - result = processOSD_Hitkey(); + result = processOSD_Hitkey(req); break; /** OPCODE 180 - 189: VNSI network functions for deleted recording access */ case VNSI_RECORDINGS_DELETED_ACCESS_SUPPORTED: - result = processRECORDINGS_DELETED_Supported(); + result = processRECORDINGS_DELETED_Supported(req); break; case VNSI_RECORDINGS_DELETED_GETCOUNT: - result = processRECORDINGS_DELETED_GetCount(); + result = processRECORDINGS_DELETED_GetCount(req); break; case VNSI_RECORDINGS_DELETED_GETLIST: - result = processRECORDINGS_DELETED_GetList(); + result = processRECORDINGS_DELETED_GetList(req); break; case VNSI_RECORDINGS_DELETED_DELETE: - result = processRECORDINGS_DELETED_Delete(); + result = processRECORDINGS_DELETED_Delete(req); break; case VNSI_RECORDINGS_DELETED_UNDELETE: - result = processRECORDINGS_DELETED_Undelete(); + result = processRECORDINGS_DELETED_Undelete(req); break; case VNSI_RECORDINGS_DELETED_DELETE_ALL: - result = processRECORDINGS_DELETED_DeleteAll(); + result = processRECORDINGS_DELETED_DeleteAll(req); break; } - delete m_resp; - m_resp = NULL; - - delete m_req; - m_req = NULL; - return result; } /** OPCODE 1 - 19: VNSI network functions for general purpose */ -bool cVNSIClient::process_Login() /* OPCODE 1 */ +bool cVNSIClient::process_Login(cRequestPacket &req) /* OPCODE 1 */ { - if (m_req->getDataLength() <= 4) return false; + if (req.getDataLength() <= 4) return false; - m_protocolVersion = m_req->extract_U32(); - m_req->extract_U8(); - const char *clientName = m_req->extract_String(); + m_protocolVersion = req.extract_U32(); + req.extract_U8(); + const char *clientName = req.extract_String(); INFOLOG("Welcome client '%s' with protocol version '%u'", clientName, m_protocolVersion); @@ -662,12 +630,14 @@ struct tm* timeStruct = localtime(&timeNow); int timeOffset = timeStruct->tm_gmtoff; - m_resp->add_U32(VNSI_PROTOCOLVERSION); - m_resp->add_U32(timeNow); - m_resp->add_S32(timeOffset); - m_resp->add_String("VDR-Network-Streaming-Interface (VNSI) Server"); - m_resp->add_String(VNSI_SERVER_VERSION); - m_resp->finalise(); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(VNSI_PROTOCOLVERSION); + resp.add_U32(timeNow); + resp.add_S32(timeOffset); + resp.add_String("VDR-Network-Streaming-Interface (VNSI) Server"); + resp.add_String(VNSI_SERVER_VERSION); + resp.finalise(); if (m_protocolVersion < VNSI_MIN_PROTOCOLVERSION) ERRORLOG("Client '%s' have a not allowed protocol version '%u', terminating client", clientName, m_protocolVersion); @@ -684,133 +654,145 @@ m_bSupportRDS = true; } - m_socket.write(m_resp->getPtr(), m_resp->getLen()); - - delete[] clientName; + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::process_GetTime() /* OPCODE 2 */ +bool cVNSIClient::process_GetTime(cRequestPacket &req) /* OPCODE 2 */ { time_t timeNow = time(NULL); struct tm* timeStruct = localtime(&timeNow); int timeOffset = timeStruct->tm_gmtoff; - m_resp->add_U32(timeNow); - m_resp->add_S32(timeOffset); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(timeNow); + resp.add_S32(timeOffset); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::process_EnableStatusInterface() +bool cVNSIClient::process_EnableStatusInterface(cRequestPacket &req) { - bool enabled = m_req->extract_U8(); + bool enabled = req.extract_U8(); SetStatusInterface(enabled); SetPriority(1); - m_resp->add_U32(VNSI_RET_OK); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(VNSI_RET_OK); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::process_Ping() /* OPCODE 7 */ +bool cVNSIClient::process_Ping(cRequestPacket &req) /* OPCODE 7 */ { - m_resp->add_U32(1); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(1); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::process_GetSetup() /* OPCODE 8 */ +bool cVNSIClient::process_GetSetup(cRequestPacket &req) /* OPCODE 8 */ { - char* name = m_req->extract_String(); + cResponsePacket resp; + resp.init(req.getRequestID()); + char* name = req.extract_String(); if (!strcasecmp(name, CONFNAME_PMTTIMEOUT)) - m_resp->add_U32(PmtTimeout); + resp.add_U32(PmtTimeout); else if (!strcasecmp(name, CONFNAME_TIMESHIFT)) - m_resp->add_U32(TimeshiftMode); + resp.add_U32(TimeshiftMode); else if (!strcasecmp(name, CONFNAME_TIMESHIFTBUFFERSIZE)) - m_resp->add_U32(TimeshiftBufferSize); + resp.add_U32(TimeshiftBufferSize); else if (!strcasecmp(name, CONFNAME_TIMESHIFTBUFFERFILESIZE)) - m_resp->add_U32(TimeshiftBufferFileSize); + resp.add_U32(TimeshiftBufferFileSize); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::process_StoreSetup() /* OPCODE 9 */ +bool cVNSIClient::process_StoreSetup(cRequestPacket &req) /* OPCODE 9 */ { - char* name = m_req->extract_String(); + char* name = req.extract_String(); if (!strcasecmp(name, CONFNAME_PMTTIMEOUT)) { - int value = m_req->extract_U32(); + int value = req.extract_U32(); cPluginVNSIServer::StoreSetup(CONFNAME_PMTTIMEOUT, value); } else if (!strcasecmp(name, CONFNAME_TIMESHIFT)) { - int value = m_req->extract_U32(); + int value = req.extract_U32(); cPluginVNSIServer::StoreSetup(CONFNAME_TIMESHIFT, value); } else if (!strcasecmp(name, CONFNAME_TIMESHIFTBUFFERSIZE)) { - int value = m_req->extract_U32(); + int value = req.extract_U32(); cPluginVNSIServer::StoreSetup(CONFNAME_TIMESHIFTBUFFERSIZE, value); } else if (!strcasecmp(name, CONFNAME_TIMESHIFTBUFFERFILESIZE)) { - int value = m_req->extract_U32(); + int value = req.extract_U32(); cPluginVNSIServer::StoreSetup(CONFNAME_TIMESHIFTBUFFERFILESIZE, value); } else if (!strcasecmp(name, CONFNAME_PLAYRECORDING)) { - int value = m_req->extract_U32(); + int value = req.extract_U32(); cPluginVNSIServer::StoreSetup(CONFNAME_PLAYRECORDING, value); } - m_resp->add_U32(VNSI_RET_OK); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(VNSI_RET_OK); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } /** OPCODE 20 - 39: VNSI network functions for live streaming */ -bool cVNSIClient::processChannelStream_Open() /* OPCODE 20 */ +bool cVNSIClient::processChannelStream_Open(cRequestPacket &req) /* OPCODE 20 */ { - uint32_t uid = m_req->extract_U32(); - int32_t priority = m_req->extract_S32(); - uint8_t timeshift = m_req->extract_U8(); - uint32_t timeout = m_req->extract_U32(); - - if(timeout == 0) - timeout = VNSIServerConfig.stream_timeout; + uint32_t uid = req.extract_U32(); + int32_t priority = req.extract_S32(); + uint8_t timeshift = req.extract_U8(); + uint32_t timeout = req.end() + ? VNSIServerConfig.stream_timeout + : req.extract_U32(); if (m_isStreaming) StopChannelStreaming(); - Channels.Lock(false); - const cChannel *channel = NULL; - - // try to find channel by uid first - channel = FindChannelByUID(uid); - Channels.Unlock(); + const cChannel *channel = FindChannelByUID(uid); // try channelnumber if (channel == NULL) + { +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + channel = Channels->GetByNumber(uid); +#else channel = Channels.GetByNumber(uid); +#endif + } + + cResponsePacket resp; + resp.init(req.getRequestID()); if (channel == NULL) { ERRORLOG("Can't find channel %08x", uid); - m_resp->add_U32(VNSI_RET_DATAINVALID); + resp.add_U32(VNSI_RET_DATAINVALID); } else { - if (StartChannelStreaming(channel, priority, timeshift, timeout)) + if (StartChannelStreaming(resp, channel, priority, timeshift, timeout)) { INFOLOG("Started streaming of channel %s (timeout %i seconds)", channel->Name(), timeout); // return here without sending the response @@ -819,93 +801,103 @@ } DEBUGLOG("Can't stream channel %s", channel->Name()); - m_resp->add_U32(VNSI_RET_DATALOCKED); + resp.add_U32(VNSI_RET_DATALOCKED); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return false; } -bool cVNSIClient::processChannelStream_Close() /* OPCODE 21 */ +bool cVNSIClient::processChannelStream_Close(cRequestPacket &req) /* OPCODE 21 */ { if (m_isStreaming) StopChannelStreaming(); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); + return true; } -bool cVNSIClient::processChannelStream_Seek() /* OPCODE 22 */ +bool cVNSIClient::processChannelStream_Seek(cRequestPacket &req) /* OPCODE 22 */ { + cResponsePacket resp; + resp.init(req.getRequestID()); + uint32_t serial = 0; if (m_isStreaming && m_Streamer) { - int64_t time = m_req->extract_S64(); + int64_t time = req.extract_S64(); if (m_Streamer->SeekTime(time, serial)) - m_resp->add_U32(VNSI_RET_OK); + resp.add_U32(VNSI_RET_OK); else - m_resp->add_U32(VNSI_RET_ERROR); + resp.add_U32(VNSI_RET_ERROR); } else - m_resp->add_U32(VNSI_RET_ERROR); + resp.add_U32(VNSI_RET_ERROR); - m_resp->add_U32(serial); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.add_U32(serial); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } /** OPCODE 40 - 59: VNSI network functions for recording streaming */ -bool cVNSIClient::processRecStream_Open() /* OPCODE 40 */ +bool cVNSIClient::processRecStream_Open(cRequestPacket &req) /* OPCODE 40 */ { - cRecording *recording = NULL; + const cRecording *recording = NULL; - uint32_t uid = m_req->extract_U32(); + uint32_t uid = req.extract_U32(); recording = cRecordingsCache::GetInstance().Lookup(uid); + cResponsePacket resp; + resp.init(req.getRequestID()); + if (recording && m_RecPlayer == NULL) { m_RecPlayer = new cRecPlayer(recording); - m_resp->add_U32(VNSI_RET_OK); - m_resp->add_U32(m_RecPlayer->getLengthFrames()); - m_resp->add_U64(m_RecPlayer->getLengthBytes()); + resp.add_U32(VNSI_RET_OK); + resp.add_U32(m_RecPlayer->getLengthFrames()); + resp.add_U64(m_RecPlayer->getLengthBytes()); #if VDRVERSNUM < 10703 - m_resp->add_U8(true);//added for TS + resp.add_U8(true);//added for TS #else - m_resp->add_U8(recording->IsPesRecording());//added for TS + resp.add_U8(recording->IsPesRecording());//added for TS #endif } else { - m_resp->add_U32(VNSI_RET_DATAUNKNOWN); + resp.add_U32(VNSI_RET_DATAUNKNOWN); ERRORLOG("%s - unable to start recording !", __FUNCTION__); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRecStream_Close() /* OPCODE 41 */ +bool cVNSIClient::processRecStream_Close(cRequestPacket &req) /* OPCODE 41 */ { - if (m_RecPlayer) - { - delete m_RecPlayer; - m_RecPlayer = NULL; - } + delete m_RecPlayer; + m_RecPlayer = NULL; - m_resp->add_U32(VNSI_RET_OK); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(VNSI_RET_OK); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRecStream_GetBlock() /* OPCODE 42 */ +bool cVNSIClient::processRecStream_GetBlock(cRequestPacket &req) /* OPCODE 42 */ { if (m_isStreaming) { @@ -919,62 +911,69 @@ return false; } - uint64_t position = m_req->extract_U64(); - uint32_t amount = m_req->extract_U32(); + uint64_t position = req.extract_U64(); + uint32_t amount = req.extract_U32(); + + cResponsePacket resp; + resp.init(req.getRequestID()); - uint8_t* p = m_resp->reserve(amount); + uint8_t* p = resp.reserve(amount); uint32_t amountReceived = m_RecPlayer->getBlock(p, position, amount); - if(amount > amountReceived) m_resp->unreserve(amount - amountReceived); + if(amount > amountReceived) resp.unreserve(amount - amountReceived); if (!amountReceived) { - m_resp->add_U32(0); + resp.add_U32(0); DEBUGLOG("written 4(0) as getblock got 0"); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRecStream_PositionFromFrameNumber() /* OPCODE 43 */ +bool cVNSIClient::processRecStream_PositionFromFrameNumber(cRequestPacket &req) /* OPCODE 43 */ { uint64_t retval = 0; - uint32_t frameNumber = m_req->extract_U32(); + uint32_t frameNumber = req.extract_U32(); if (m_RecPlayer) retval = m_RecPlayer->positionFromFrameNumber(frameNumber); - m_resp->add_U64(retval); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U64(retval); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); DEBUGLOG("Wrote posFromFrameNum reply to client"); return true; } -bool cVNSIClient::processRecStream_FrameNumberFromPosition() /* OPCODE 44 */ +bool cVNSIClient::processRecStream_FrameNumberFromPosition(cRequestPacket &req) /* OPCODE 44 */ { uint32_t retval = 0; - uint64_t position = m_req->extract_U64(); + uint64_t position = req.extract_U64(); if (m_RecPlayer) retval = m_RecPlayer->frameNumberFromPosition(position); - m_resp->add_U32(retval); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(retval); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); DEBUGLOG("Wrote frameNumFromPos reply to client"); return true; } -bool cVNSIClient::processRecStream_GetIFrame() /* OPCODE 45 */ +bool cVNSIClient::processRecStream_GetIFrame(cRequestPacket &req) /* OPCODE 45 */ { bool success = false; - uint32_t frameNumber = m_req->extract_U32(); - uint32_t direction = m_req->extract_U32(); + uint32_t frameNumber = req.extract_U32(); + uint32_t direction = req.extract_U32(); uint64_t rfilePosition = 0; uint32_t rframeNumber = 0; uint32_t rframeLength = 0; @@ -982,26 +981,29 @@ if (m_RecPlayer) success = m_RecPlayer->getNextIFrame(frameNumber, direction, &rfilePosition, &rframeNumber, &rframeLength); + cResponsePacket resp; + resp.init(req.getRequestID()); + // returns file position, frame number, length if (success) { - m_resp->add_U64(rfilePosition); - m_resp->add_U32(rframeNumber); - m_resp->add_U32(rframeLength); + resp.add_U64(rfilePosition); + resp.add_U32(rframeNumber); + resp.add_U32(rframeLength); } else { - m_resp->add_U32(0); + resp.add_U32(0); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); DEBUGLOG("Wrote GNIF reply to client %lu %u %u", rfilePosition, rframeNumber, rframeLength); return true; } -bool cVNSIClient::processRecStream_GetLength() /* OPCODE 46 */ +bool cVNSIClient::processRecStream_GetLength(cRequestPacket &req) /* OPCODE 46 */ { uint64_t length = 0; @@ -1011,42 +1013,66 @@ length = m_RecPlayer->getLengthBytes(); } - m_resp->add_U64(length); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U64(length); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } /** OPCODE 60 - 79: VNSI network functions for channel access */ -bool cVNSIClient::processCHANNELS_ChannelsCount() /* OPCODE 61 */ +bool cVNSIClient::processCHANNELS_ChannelsCount(cRequestPacket &req) /* OPCODE 61 */ { + int count = 0; +#if VDRVERSNUM >= 20301 + { + LOCK_CHANNELS_READ; + count = Channels->MaxNumber(); + } +#else Channels.Lock(false); - int count = Channels.MaxNumber(); + count = Channels.MaxNumber(); Channels.Unlock(); +#endif - m_resp->add_U32(count); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(count); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_GetChannels() /* OPCODE 63 */ +bool cVNSIClient::processCHANNELS_GetChannels(cRequestPacket &req) /* OPCODE 63 */ { - if (m_req->getDataLength() != 5) return false; + if (req.getDataLength() != 5) return false; - bool radio = m_req->extract_U32(); - bool filter = m_req->extract_U8(); + bool radio = req.extract_U32(); + bool filter = req.extract_U8(); +#if VDRVERSNUM >= 20301 + cStateKey ChannelsKey(true); + const cChannels *Channels = cChannels::GetChannelsRead(ChannelsKey); +#else Channels.Lock(false); +#endif + + cResponsePacket resp; + resp.init(req.getRequestID()); cString caids; int caid; int caid_idx; +#if VDRVERSNUM >= 20301 + for (const cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel)) +#else for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) +#endif { if (radio != cVNSIChannelFilter::IsRadio(channel)) continue; @@ -1060,11 +1086,11 @@ continue; uint32_t uuid = CreateChannelUID(channel); - m_resp->add_U32(channel->Number()); - m_resp->add_String(m_toUTF8.Convert(channel->Name())); - m_resp->add_String(m_toUTF8.Convert(channel->Provider())); - m_resp->add_U32(uuid); - m_resp->add_U32(channel->Ca(0)); + resp.add_U32(channel->Number()); + resp.add_String(m_toUTF8.Convert(channel->Name())); + resp.add_String(m_toUTF8.Convert(channel->Provider())); + resp.add_U32(uuid); + resp.add_U32(channel->Ca(0)); caid_idx = 0; caids = "caids:"; while((caid = channel->Ca(caid_idx)) != 0) @@ -1072,10 +1098,10 @@ caids = cString::sprintf("%s%d;", (const char*)caids, caid); caid_idx++; } - m_resp->add_String((const char*)caids); + resp.add_String((const char*)caids); if (m_protocolVersion >= 6) { - m_resp->add_String(CreatePiconRef(channel)); + resp.add_String(CreatePiconRef(channel)); } // create entry in EPG map on first query @@ -1088,19 +1114,21 @@ } } +#if VDRVERSNUM >= 20301 + ChannelsKey.Remove(); +#else Channels.Unlock(); +#endif - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_GroupsCount() +bool cVNSIClient::processCHANNELS_GroupsCount(cRequestPacket &req) { - uint32_t type = m_req->extract_U32(); - - Channels.Lock(false); + uint32_t type = req.extract_U32(); m_channelgroups[0].clear(); m_channelgroups[1].clear(); @@ -1118,54 +1146,64 @@ break; } - Channels.Unlock(); - uint32_t count = m_channelgroups[0].size() + m_channelgroups[1].size(); - m_resp->add_U32(count); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(count); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_GroupList() +bool cVNSIClient::processCHANNELS_GroupList(cRequestPacket &req) { - uint32_t radio = m_req->extract_U8(); + uint32_t radio = req.extract_U8(); std::map::iterator i; + cResponsePacket resp; + resp.init(req.getRequestID()); + for(i = m_channelgroups[radio].begin(); i != m_channelgroups[radio].end(); i++) { - m_resp->add_String(i->second.name.c_str()); - m_resp->add_U8(i->second.radio); + resp.add_String(i->second.name.c_str()); + resp.add_U8(i->second.radio); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_GetGroupMembers() +bool cVNSIClient::processCHANNELS_GetGroupMembers(cRequestPacket &req) { - char* groupname = m_req->extract_String(); - uint32_t radio = m_req->extract_U8(); - bool filter = m_req->extract_U8(); + char* groupname = req.extract_String(); + uint32_t radio = req.extract_U8(); + bool filter = req.extract_U8(); int index = 0; + cResponsePacket resp; + resp.init(req.getRequestID()); + // unknown group if(m_channelgroups[radio].find(groupname) == m_channelgroups[radio].end()) { - delete[] groupname; - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } bool automatic = m_channelgroups[radio][groupname].automatic; std::string name; +#if VDRVERSNUM >= 20301 + cStateKey ChannelsKey(true); + const cChannels *Channels = cChannels::GetChannelsRead(ChannelsKey); + for (const cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel)) +#else Channels.Lock(false); - for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) +#endif { if(automatic && !channel->GroupSep()) @@ -1191,27 +1229,30 @@ if(name == groupname) { - m_resp->add_U32(CreateChannelUID(channel)); - m_resp->add_U32(++index); + resp.add_U32(CreateChannelUID(channel)); + resp.add_U32(++index); } } +#if VDRVERSNUM >= 20301 + ChannelsKey.Remove(); +#else Channels.Unlock(); +#endif - delete[] groupname; - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_GetCaids() +bool cVNSIClient::processCHANNELS_GetCaids(cRequestPacket &req) { - uint32_t uid = m_req->extract_U32(); + uint32_t uid = req.extract_U32(); - Channels.Lock(false); - const cChannel *channel = NULL; - channel = FindChannelByUID(uid); - Channels.Unlock(); + const cChannel *channel = FindChannelByUID(uid); + + cResponsePacket resp; + resp.init(req.getRequestID()); if (channel != NULL) { @@ -1219,20 +1260,20 @@ int idx = 0; while((caid = channel->Ca(idx)) != 0) { - m_resp->add_U32(caid); + resp.add_U32(caid); idx++; } } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_GetWhitelist() +bool cVNSIClient::processCHANNELS_GetWhitelist(cRequestPacket &req) { - bool radio = m_req->extract_U8(); + bool radio = req.extract_U8(); std::vector *providers; if(radio) @@ -1240,22 +1281,25 @@ else providers = &VNSIChannelFilter.m_providersVideo; + cResponsePacket resp; + resp.init(req.getRequestID()); + VNSIChannelFilter.m_Mutex.Lock(); for(unsigned int i=0; isize(); i++) { - m_resp->add_String((*providers)[i].m_name.c_str()); - m_resp->add_U32((*providers)[i].m_caid); + resp.add_String((*providers)[i].m_name.c_str()); + resp.add_U32((*providers)[i].m_caid); } VNSIChannelFilter.m_Mutex.Unlock(); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_GetBlacklist() +bool cVNSIClient::processCHANNELS_GetBlacklist(cRequestPacket &req) { - bool radio = m_req->extract_U8(); + bool radio = req.extract_U8(); std::vector *channels; if(radio) @@ -1263,21 +1307,24 @@ else channels = &VNSIChannelFilter.m_channelsVideo; + cResponsePacket resp; + resp.init(req.getRequestID()); + VNSIChannelFilter.m_Mutex.Lock(); for(unsigned int i=0; isize(); i++) { - m_resp->add_U32((*channels)[i]); + resp.add_U32((*channels)[i]); } VNSIChannelFilter.m_Mutex.Unlock(); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_SetWhitelist() +bool cVNSIClient::processCHANNELS_SetWhitelist(cRequestPacket &req) { - bool radio = m_req->extract_U8(); + bool radio = req.extract_U8(); cVNSIProvider provider; std::vector *providers; @@ -1289,25 +1336,26 @@ VNSIChannelFilter.m_Mutex.Lock(); providers->clear(); - while(!m_req->end()) + while(!req.end()) { - char *str = m_req->extract_String(); + char *str = req.extract_String(); provider.m_name = str; - provider.m_caid = m_req->extract_U32(); - delete [] str; + provider.m_caid = req.extract_U32(); providers->push_back(provider); } VNSIChannelFilter.StoreWhitelist(radio); VNSIChannelFilter.m_Mutex.Unlock(); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processCHANNELS_SetBlacklist() +bool cVNSIClient::processCHANNELS_SetBlacklist(cRequestPacket &req) { - bool radio = m_req->extract_U8(); + bool radio = req.extract_U8(); cVNSIProvider provider; std::vector *channels; @@ -1320,16 +1368,18 @@ channels->clear(); int id; - while(!m_req->end()) + while(!req.end()) { - id = m_req->extract_U32(); + id = req.extract_U32(); channels->push_back(id); } VNSIChannelFilter.StoreBlacklist(radio); VNSIChannelFilter.m_Mutex.Unlock(); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } @@ -1337,7 +1387,13 @@ { std::string groupname; +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + for (const cChannel *channel = Channels->First(); channel; channel = Channels->Next(channel)) +#else + Channels.Lock(false); for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) +#endif { bool isRadio = cVNSIChannelFilter::IsRadio(channel); @@ -1358,111 +1414,177 @@ m_channelgroups[isRadio][groupname] = group; } } + +#if VDRVERSNUM < 20301 + Channels.Unlock(); +#endif } /** OPCODE 80 - 99: VNSI network functions for timer access */ -bool cVNSIClient::processTIMER_GetCount() /* OPCODE 80 */ +bool cVNSIClient::processTIMER_GetCount(cRequestPacket &req) /* OPCODE 80 */ { cMutexLock lock(&m_timerLock); +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_READ; + int count = Timers->Count(); +#else int count = Timers.Count(); +#endif - m_resp->add_U32(count); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(count); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processTIMER_Get() /* OPCODE 81 */ +bool cVNSIClient::processTIMER_Get(cRequestPacket &req) /* OPCODE 81 */ { cMutexLock lock(&m_timerLock); - uint32_t number = m_req->extract_U32(); + uint32_t number = req.extract_U32(); - int numTimers = Timers.Count(); + cResponsePacket resp; + resp.init(req.getRequestID()); + +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_READ; + int numTimers = Timers->Count(); if (numTimers > 0) { - cTimer *timer = Timers.Get(number-1); - if (timer) + const cTimer *timer = Timers->Get(number-1); +#else + int numTimers = Timers.Count(); + if (numTimers > 0) { - m_resp->add_U32(VNSI_RET_OK); + cTimer *timer = Timers.Get(number-1); +#endif + if (timer) + { + resp.add_U32(VNSI_RET_OK); - m_resp->add_U32(timer->Index()+1); - m_resp->add_U32(timer->HasFlags(tfActive)); - m_resp->add_U32(timer->Recording()); - m_resp->add_U32(timer->Pending()); - m_resp->add_U32(timer->Priority()); - m_resp->add_U32(timer->Lifetime()); - m_resp->add_U32(timer->Channel()->Number()); - m_resp->add_U32(CreateChannelUID(timer->Channel())); - m_resp->add_U32(timer->StartTime()); - m_resp->add_U32(timer->StopTime()); - m_resp->add_U32(timer->Day()); - m_resp->add_U32(timer->WeekDays()); - m_resp->add_String(m_toUTF8.Convert(timer->File())); + if (m_protocolVersion >= 9) + { + uint32_t type; + if (timer->HasFlags(tfVps)) + type = VNSI_TIMER_TYPE_VPS; + else + type = VNSI_TIMER_TYPE_MAN; + resp.add_U32(type); + } + resp.add_U32(timer->Index()+1); + resp.add_U32(timer->HasFlags(tfActive)); + resp.add_U32(timer->Recording()); + resp.add_U32(timer->Pending()); + resp.add_U32(timer->Priority()); + resp.add_U32(timer->Lifetime()); + resp.add_U32(timer->Channel()->Number()); + resp.add_U32(CreateChannelUID(timer->Channel())); + resp.add_U32(timer->StartTime()); + resp.add_U32(timer->StopTime()); + resp.add_U32(timer->Day()); + resp.add_U32(timer->WeekDays()); + resp.add_String(m_toUTF8.Convert(timer->File())); + if (m_protocolVersion >= 9) + { + resp.add_String(""); + } + } + else + resp.add_U32(VNSI_RET_DATAUNKNOWN); } else - m_resp->add_U32(VNSI_RET_DATAUNKNOWN); - } - else - m_resp->add_U32(VNSI_RET_DATAUNKNOWN); + resp.add_U32(VNSI_RET_DATAUNKNOWN); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processTIMER_GetList() /* OPCODE 82 */ +bool cVNSIClient::processTIMER_GetList(cRequestPacket &req) /* OPCODE 82 */ { + cResponsePacket resp; + resp.init(req.getRequestID()); + cMutexLock lock(&m_timerLock); - cTimer *timer; +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_READ; + int numTimers = Timers->Count(); + resp.add_U32(numTimers); + for (int i = 0; i < numTimers; i++) + { + const cTimer *timer = Timers->Get(i); +#else int numTimers = Timers.Count(); - - m_resp->add_U32(numTimers); - + resp.add_U32(numTimers); for (int i = 0; i < numTimers; i++) { - timer = Timers.Get(i); + cTimer *timer = Timers.Get(i); +#endif if (!timer) continue; - m_resp->add_U32(timer->Index()+1); - m_resp->add_U32(timer->HasFlags(tfActive)); - m_resp->add_U32(timer->Recording()); - m_resp->add_U32(timer->Pending()); - m_resp->add_U32(timer->Priority()); - m_resp->add_U32(timer->Lifetime()); - m_resp->add_U32(timer->Channel()->Number()); - m_resp->add_U32(CreateChannelUID(timer->Channel())); - m_resp->add_U32(timer->StartTime()); - m_resp->add_U32(timer->StopTime()); - m_resp->add_U32(timer->Day()); - m_resp->add_U32(timer->WeekDays()); - m_resp->add_String(m_toUTF8.Convert(timer->File())); + if (m_protocolVersion >= 9) + { + uint32_t type; + if (timer->HasFlags(tfVps)) + type = VNSI_TIMER_TYPE_VPS; + else + type = VNSI_TIMER_TYPE_MAN; + resp.add_U32(type); + } + resp.add_U32(timer->Index()+1); + resp.add_U32(timer->HasFlags(tfActive)); + resp.add_U32(timer->Recording()); + resp.add_U32(timer->Pending()); + resp.add_U32(timer->Priority()); + resp.add_U32(timer->Lifetime()); + resp.add_U32(timer->Channel()->Number()); + resp.add_U32(CreateChannelUID(timer->Channel())); + resp.add_U32(timer->StartTime()); + resp.add_U32(timer->StopTime()); + resp.add_U32(timer->Day()); + resp.add_U32(timer->WeekDays()); + resp.add_String(m_toUTF8.Convert(timer->File())); + if (m_protocolVersion >= 9) + { + resp.add_String(""); + } } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processTIMER_Add() /* OPCODE 83 */ +bool cVNSIClient::processTIMER_Add(cRequestPacket &req) /* OPCODE 83 */ { cMutexLock lock(&m_timerLock); - uint32_t flags = m_req->extract_U32() > 0 ? tfActive : tfNone; - uint32_t priority = m_req->extract_U32(); - uint32_t lifetime = m_req->extract_U32(); - uint32_t channelid = m_req->extract_U32(); - time_t startTime = m_req->extract_U32(); - time_t stopTime = m_req->extract_U32(); - time_t day = m_req->extract_U32(); - uint32_t weekdays = m_req->extract_U32(); - const char *file = m_req->extract_String(); - const char *aux = m_req->extract_String(); + bool vps = false; + if (m_protocolVersion >= 9) + { + uint32_t type = req.extract_U32(); + if (type == VNSI_TIMER_TYPE_VPS) + vps = true; + } + uint32_t flags = req.extract_U32() > 0 ? tfActive : tfNone; + uint32_t priority = req.extract_U32(); + uint32_t lifetime = req.extract_U32(); + uint32_t channelid = req.extract_U32(); + time_t startTime = req.extract_U32(); + time_t stopTime = req.extract_U32(); + time_t day = req.extract_U32(); + uint32_t weekdays = req.extract_U32(); + const char *file = req.extract_String(); + const char *aux = req.extract_String(); + if (m_protocolVersion >= 9) + const char *search = req.extract_String(); // handle instant timers if(startTime == -1 || startTime == 0) @@ -1478,6 +1600,9 @@ time = localtime_r(&stopTime, &tm_r); int stop = time->tm_hour * 100 + time->tm_min; + if (vps) + flags |= tfVps; + cString buffer; const cChannel* channel = FindChannelByUID(channelid); if(channel != NULL) @@ -1485,56 +1610,107 @@ buffer = cString::sprintf("%u:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, (const char*)channel->GetChannelID().ToString(), *cTimer::PrintDay(day, weekdays, true), start, stop, priority, lifetime, file, aux); } - delete[] file; - delete[] aux; + cResponsePacket resp; + resp.init(req.getRequestID()); - cTimer *timer = new cTimer; + std::auto_ptr timer(new cTimer); if (timer->Parse(buffer)) { - cTimer *t = Timers.GetTimer(timer); +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_WRITE; + const cTimer *t = Timers->GetTimer(timer.get()); + if (!t) + { + INFOLOG("Timer %s added", *timer->ToDescr()); + Timers->Add(timer.release()); + Timers->SetModified(); + resp.add_U32(VNSI_RET_OK); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); + return true; + } +#else + cTimer *t = Timers.GetTimer(timer.get()); if (!t) { - Timers.Add(timer); - Timers.SetModified(); INFOLOG("Timer %s added", *timer->ToDescr()); - m_resp->add_U32(VNSI_RET_OK); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + Timers.Add(timer.release()); + Timers.SetModified(); + resp.add_U32(VNSI_RET_OK); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } +#endif else { ERRORLOG("Timer already defined: %d %s", t->Index() + 1, *t->ToText()); - m_resp->add_U32(VNSI_RET_DATALOCKED); + resp.add_U32(VNSI_RET_DATALOCKED); } } else { ERRORLOG("Error in timer settings"); - m_resp->add_U32(VNSI_RET_DATAINVALID); + resp.add_U32(VNSI_RET_DATAINVALID); } - delete timer; - - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processTIMER_Delete() /* OPCODE 84 */ +bool cVNSIClient::processTIMER_Delete(cRequestPacket &req) /* OPCODE 84 */ { cMutexLock lock(&m_timerLock); - uint32_t number = m_req->extract_U32(); - bool force = m_req->extract_U32(); +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_WRITE; + int timersCount = Timers->Count(); +#else + int timersCount = Timers.Count(); +#endif + + uint32_t number = req.extract_U32(); + bool force = req.extract_U32(); - if (number <= 0 || number > (uint32_t)Timers.Count()) + cResponsePacket resp; + resp.init(req.getRequestID()); + + if (number <= 0 || number > (uint32_t)timersCount) { ERRORLOG("Unable to delete timer - invalid timer identifier"); - m_resp->add_U32(VNSI_RET_DATAINVALID); + resp.add_U32(VNSI_RET_DATAINVALID); } else { +#if VDRVERSNUM >= 20301 + cTimer *timer = Timers->Get(number-1); + if (timer) + { + Timers->SetExplicitModify(); + { + if (timer->Recording()) + { + if (force) + { + timer->Skip(); + cRecordControls::Process(Timers, time(NULL)); + } + else + { + ERRORLOG("Timer \"%i\" is recording and can be deleted (use force=1 to stop it)", number); + resp.add_U32(VNSI_RET_RECRUNNING); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); + return true; + } + } + INFOLOG("Deleting timer %s", *timer->ToDescr()); + Timers->Del(timer); + Timers->SetModified(); + resp.add_U32(VNSI_RET_OK); + } +#else cTimer *timer = Timers.Get(number-1); if (timer) { @@ -1550,49 +1726,66 @@ else { ERRORLOG("Timer \"%i\" is recording and can be deleted (use force=1 to stop it)", number); - m_resp->add_U32(VNSI_RET_RECRUNNING); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.add_U32(VNSI_RET_RECRUNNING); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } } INFOLOG("Deleting timer %s", *timer->ToDescr()); Timers.Del(timer); Timers.SetModified(); - m_resp->add_U32(VNSI_RET_OK); + resp.add_U32(VNSI_RET_OK); } else { ERRORLOG("Unable to delete timer - timers being edited at VDR"); - m_resp->add_U32(VNSI_RET_DATALOCKED); + resp.add_U32(VNSI_RET_DATALOCKED); } +#endif } else { ERRORLOG("Unable to delete timer - invalid timer identifier"); - m_resp->add_U32(VNSI_RET_DATAINVALID); + resp.add_U32(VNSI_RET_DATAINVALID); } } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processTIMER_Update() /* OPCODE 85 */ +bool cVNSIClient::processTIMER_Update(cRequestPacket &req) /* OPCODE 85 */ { cMutexLock lock(&m_timerLock); - int length = m_req->getDataLength(); - uint32_t index = m_req->extract_U32(); - bool active = m_req->extract_U32(); - + bool vps = false; + int length = req.getDataLength(); + uint32_t index = req.extract_U32(); + if (m_protocolVersion >= 9) + { + uint32_t type = req.extract_U32(); + if (type == VNSI_TIMER_TYPE_VPS) + vps = true; + } + bool active = req.extract_U32(); + +#if VDRVERSNUM >= 20301 + LOCK_TIMERS_WRITE; + cTimer *timer = Timers->Get(index - 1); +#else cTimer *timer = Timers.Get(index - 1); +#endif + + cResponsePacket resp; + resp.init(req.getRequestID()); + if (!timer) { ERRORLOG("Timer \"%u\" not defined", index); - m_resp->add_U32(VNSI_RET_DATAUNKNOWN); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.add_U32(VNSI_RET_DATAUNKNOWN); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } @@ -1608,15 +1801,17 @@ else { uint32_t flags = active ? tfActive : tfNone; - uint32_t priority = m_req->extract_U32(); - uint32_t lifetime = m_req->extract_U32(); - uint32_t channelid = m_req->extract_U32(); - time_t startTime = m_req->extract_U32(); - time_t stopTime = m_req->extract_U32(); - time_t day = m_req->extract_U32(); - uint32_t weekdays = m_req->extract_U32(); - const char *file = m_req->extract_String(); - const char *aux = m_req->extract_String(); + uint32_t priority = req.extract_U32(); + uint32_t lifetime = req.extract_U32(); + uint32_t channelid = req.extract_U32(); + time_t startTime = req.extract_U32(); + time_t stopTime = req.extract_U32(); + time_t day = req.extract_U32(); + uint32_t weekdays = req.extract_U32(); + const char *file = req.extract_String(); + const char *aux = req.extract_String(); + if (m_protocolVersion >= 9) + const char *search = req.extract_String(); struct tm tm_r; struct tm *time = localtime_r(&startTime, &tm_r); @@ -1626,6 +1821,9 @@ time = localtime_r(&stopTime, &tm_r); int stop = time->tm_hour * 100 + time->tm_min; + if (vps) + flags |= tfVps; + cString buffer; const cChannel* channel = FindChannelByUID(channelid); if(channel != NULL) @@ -1633,32 +1831,42 @@ buffer = cString::sprintf("%u:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, (const char*)channel->GetChannelID().ToString(), *cTimer::PrintDay(day, weekdays, true), start, stop, priority, lifetime, file, aux); } - delete[] file; - delete[] aux; - if (!t.Parse(buffer)) { ERRORLOG("Error in timer settings"); - m_resp->add_U32(VNSI_RET_DATAINVALID); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.add_U32(VNSI_RET_DATAINVALID); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } } *timer = t; +#if VDRVERSNUM >= 20301 + Timers->SetModified(); +#else Timers.SetModified(); +#endif - m_resp->add_U32(VNSI_RET_OK); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.add_U32(VNSI_RET_OK); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } +bool cVNSIClient::processTIMER_GetTypes(cRequestPacket &req) /* OPCODE 80 */ +{ + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(0); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); + return true; +} /** OPCODE 100 - 119: VNSI network functions for recording access */ -bool cVNSIClient::processRECORDINGS_GetDiskSpace() /* OPCODE 100 */ +bool cVNSIClient::processRECORDINGS_GetDiskSpace(cRequestPacket &req) /* OPCODE 100 */ { int FreeMB; int UsedMB; @@ -1669,30 +1877,52 @@ #endif int Total = FreeMB + UsedMB; - m_resp->add_U32(Total); - m_resp->add_U32(FreeMB); - m_resp->add_U32(Percent); + cResponsePacket resp; + resp.init(req.getRequestID()); + + resp.add_U32(Total); + resp.add_U32(FreeMB); + resp.add_U32(Percent); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_GetCount() /* OPCODE 101 */ +bool cVNSIClient::processRECORDINGS_GetCount(cRequestPacket &req) /* OPCODE 101 */ { - m_resp->add_U32(Recordings.Count()); + cResponsePacket resp; + resp.init(req.getRequestID()); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); +#if VDRVERSNUM >= 20301 + LOCK_RECORDINGS_READ; + resp.add_U32(Recordings->Count()); +#else + resp.add_U32(Recordings.Count()); +#endif + + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_GetList() /* OPCODE 102 */ +bool cVNSIClient::processRECORDINGS_GetList(cRequestPacket &req) /* OPCODE 102 */ { cMutexLock lock(&m_timerLock); +#if VDRVERSNUM >= 20301 + LOCK_RECORDINGS_READ; +#else cThreadLock RecordingsLock(&Recordings); +#endif + cResponsePacket resp; + resp.init(req.getRequestID()); + +#if VDRVERSNUM >= 20301 + for (const cRecording *recording = Recordings->First(); recording; recording = Recordings->Next(recording)) +#else for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) +#endif { #if APIVERSNUM >= 10705 const cEvent *event = recording->Info()->GetEvent(); @@ -1727,58 +1957,83 @@ DEBUGLOG("GRI: RC: recordingStart=%lu recordingDuration=%i", recordingStart, recordingDuration); // recording_time - m_resp->add_U32(recordingStart); + resp.add_U32(recordingStart); // duration - m_resp->add_U32(recordingDuration); + resp.add_U32(recordingDuration); // priority #if APIVERSNUM >= 10727 - m_resp->add_U32(recording->Priority()); + resp.add_U32(recording->Priority()); #else - m_resp->add_U32(recording->priority); + resp.add_U32(recording->priority); #endif // lifetime #if APIVERSNUM >= 10727 - m_resp->add_U32(recording->Lifetime()); + resp.add_U32(recording->Lifetime()); #else - m_resp->add_U32(recording->lifetime); + resp.add_U32(recording->lifetime); #endif // channel_name - m_resp->add_String(recording->Info()->ChannelName() ? m_toUTF8.Convert(recording->Info()->ChannelName()) : ""); + resp.add_String(recording->Info()->ChannelName() ? m_toUTF8.Convert(recording->Info()->ChannelName()) : ""); + if (m_protocolVersion >= 9) + { + // channel uuid +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + const cChannel *channel = Channels->GetByChannelID(recording->Info()->ChannelID()); +#else + Channels.Lock(false); + const cChannel *channel = Channels.GetByChannelID(recording->Info()->ChannelID()); + Channels.Unlock(); +#endif + if (channel) + { + resp.add_U32(CreateChannelUID(channel)); + resp.add_U8(cVNSIChannelFilter::IsRadio(channel) ? 1 : 2); + } + else + { + resp.add_U32(0); + resp.add_U8(0); + } + } char* fullname = strdup(recording->Name()); char* recname = strrchr(fullname, FOLDERDELIMCHAR); char* directory = NULL; - if(recname == NULL) { + if(recname == NULL) + { recname = fullname; } - else { + else + { *recname = 0; recname++; directory = fullname; } // title - m_resp->add_String(m_toUTF8.Convert(recname)); + resp.add_String(m_toUTF8.Convert(recname)); // subtitle if (!isempty(recording->Info()->ShortText())) - m_resp->add_String(m_toUTF8.Convert(recording->Info()->ShortText())); + resp.add_String(m_toUTF8.Convert(recording->Info()->ShortText())); else - m_resp->add_String(""); + resp.add_String(""); // description if (!isempty(recording->Info()->Description())) - m_resp->add_String(m_toUTF8.Convert(recording->Info()->Description())); + resp.add_String(m_toUTF8.Convert(recording->Info()->Description())); else - m_resp->add_String(""); + resp.add_String(""); // directory - if(directory != NULL) { + if(directory != NULL) + { char* p = directory; while(*p != 0) { if(*p == FOLDERDELIMCHAR) *p = '/'; @@ -1788,68 +2043,77 @@ while(*directory == '/') directory++; } - m_resp->add_String((isempty(directory)) ? "" : m_toUTF8.Convert(directory)); + resp.add_String((isempty(directory)) ? "" : m_toUTF8.Convert(directory)); // filename / uid of recording uint32_t uid = cRecordingsCache::GetInstance().Register(recording, false); - m_resp->add_U32(uid); + resp.add_U32(uid); free(fullname); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_Rename() /* OPCODE 103 */ +bool cVNSIClient::processRECORDINGS_Rename(cRequestPacket &req) /* OPCODE 103 */ { - uint32_t uid = m_req->extract_U32(); - char* newtitle = m_req->extract_String(); - cRecording* recording = cRecordingsCache::GetInstance().Lookup(uid); - int r = VNSI_RET_DATAINVALID; + uint32_t uid = req.extract_U32(); + char* newtitle = req.extract_String(); + int r = VNSI_RET_DATAINVALID; + +#if VDRVERSNUM >= 20301 + LOCK_RECORDINGS_WRITE; +#endif + + const cRecording* recording = cRecordingsCache::GetInstance().Lookup(uid); if(recording != NULL) { // get filename and remove last part (recording time) - char* filename_old = strdup((const char*)recording->FileName()); - char* sep = strrchr(filename_old, '/'); - if(sep != NULL) { - *sep = 0; - } + std::string filename_old(recording->FileName()); + std::string::size_type i = filename_old.rfind('/'); + if (i != filename_old.npos) + filename_old.erase(i); // replace spaces in newtitle strreplace(newtitle, ' ', '_'); - char* filename_new = new char[1024]; - strncpy(filename_new, filename_old, 512); - sep = strrchr(filename_new, '/'); - if(sep != NULL) { - sep++; - *sep = 0; - } - strncat(filename_new, newtitle, 512); + std::string filename_new(filename_old); + i = filename_new.rfind('/'); + if (i != filename_new.npos) + filename_new.erase(i + 1); - INFOLOG("renaming recording '%s' to '%s'", filename_old, filename_new); - r = rename(filename_old, filename_new); - Recordings.Update(); + filename_new += newtitle; - free(filename_old); - delete[] filename_new; + INFOLOG("renaming recording '%s' to '%s'", filename_old.c_str(), filename_new.c_str()); + r = rename(filename_old.c_str(), filename_new.c_str()); + +#if VDRVERSNUM >= 20301 + Recordings->Update(); +#else + Recordings.Update(); +#endif } - m_resp->add_U32(r); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(r); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_Delete() /* OPCODE 104 */ +bool cVNSIClient::processRECORDINGS_Delete(cRequestPacket &req) /* OPCODE 104 */ { cString recName; cRecording* recording = NULL; - uint32_t uid = m_req->extract_U32(); - recording = cRecordingsCache::GetInstance().Lookup(uid); + uint32_t uid = req.extract_U32(); + recording = cRecordingsCache::GetInstance().LookupWrite(uid); + + cResponsePacket resp; + resp.init(req.getRequestID()); if (recording) { @@ -1861,42 +2125,50 @@ if (recording->Delete()) { // Copy svdrdeveldevelp's way of doing this, see if it works +#if VDRVERSNUM >= 20301 + LOCK_RECORDINGS_WRITE; + Recordings->DelByName(recording->FileName()); +#else Recordings.DelByName(recording->FileName()); +#endif INFOLOG("Recording \"%s\" deleted", recording->FileName()); - m_resp->add_U32(VNSI_RET_OK); + resp.add_U32(VNSI_RET_OK); } else { ERRORLOG("Error while deleting recording!"); - m_resp->add_U32(VNSI_RET_ERROR); + resp.add_U32(VNSI_RET_ERROR); } } else { ERRORLOG("Recording \"%s\" is in use by timer %d", recording->Name(), rc->Timer()->Index() + 1); - m_resp->add_U32(VNSI_RET_DATALOCKED); + resp.add_U32(VNSI_RET_DATALOCKED); } } else { ERRORLOG("Error in recording name \"%s\"", (const char*)recName); - m_resp->add_U32(VNSI_RET_DATAUNKNOWN); + resp.add_U32(VNSI_RET_DATAUNKNOWN); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_GetEdl() /* OPCODE 105 */ +bool cVNSIClient::processRECORDINGS_GetEdl(cRequestPacket &req) /* OPCODE 105 */ { cString recName; - cRecording* recording = NULL; + const cRecording* recording = NULL; - uint32_t uid = m_req->extract_U32(); + uint32_t uid = req.extract_U32(); recording = cRecordingsCache::GetInstance().Lookup(uid); + cResponsePacket resp; + resp.init(req.getRequestID()); + if (recording) { cMarks marks; @@ -1907,15 +2179,15 @@ double fps = recording->FramesPerSecond(); while((mark = marks.GetNextBegin(mark)) != NULL) { - m_resp->add_U64(mark->Position() *1000 / fps); - m_resp->add_U64(mark->Position() *1000 / fps); - m_resp->add_S32(2); + resp.add_U64(mark->Position() *1000 / fps); + resp.add_U64(mark->Position() *1000 / fps); + resp.add_S32(2); } #endif } } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } @@ -1923,16 +2195,21 @@ /** OPCODE 120 - 139: VNSI network functions for epg access and manipulating */ -bool cVNSIClient::processEPG_GetForChannel() /* OPCODE 120 */ +bool cVNSIClient::processEPG_GetForChannel(cRequestPacket &req) /* OPCODE 120 */ { uint32_t channelUID = 0; - channelUID = m_req->extract_U32(); + channelUID = req.extract_U32(); - uint32_t startTime = m_req->extract_U32(); - uint32_t duration = m_req->extract_U32(); + uint32_t startTime = req.extract_U32(); + uint32_t duration = req.extract_U32(); +#if VDRVERSNUM >= 20301 + LOCK_CHANNELS_READ; + LOCK_SCHEDULES_READ; +#else Channels.Lock(false); +#endif const cChannel* channel = NULL; @@ -1942,37 +2219,50 @@ DEBUGLOG("get schedule called for channel '%s'", (const char*)channel->GetChannelID().ToString()); } + cResponsePacket resp; + resp.init(req.getRequestID()); + if (!channel) { - m_resp->add_U32(0); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.add_U32(0); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); +#if VDRVERSNUM < 20301 Channels.Unlock(); +#endif ERRORLOG("written 0 because channel = NULL"); return true; } +#if VDRVERSNUM < 20301 cSchedulesLock MutexLock; const cSchedules *Schedules = cSchedules::Schedules(MutexLock); if (!Schedules) { - m_resp->add_U32(0); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.add_U32(0); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); Channels.Unlock(); DEBUGLOG("written 0 because Schedule!s! = NULL"); return true; } +#endif +#if VDRVERSNUM >= 20301 const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); +#else + const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); +#endif if (!Schedule) { - m_resp->add_U32(0); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.add_U32(0); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); +#if VDRVERSNUM < 20301 Channels.Unlock(); +#endif DEBUGLOG("written 0 because Schedule = NULL"); return true; @@ -2021,32 +2311,35 @@ if (!thisEventSubTitle) thisEventSubTitle = ""; if (!thisEventDescription) thisEventDescription = ""; - m_resp->add_U32(thisEventID); - m_resp->add_U32(thisEventTime); - m_resp->add_U32(thisEventDuration); - m_resp->add_U32(thisEventContent); - m_resp->add_U32(thisEventRating); - - m_resp->add_String(m_toUTF8.Convert(thisEventTitle)); - m_resp->add_String(m_toUTF8.Convert(thisEventSubTitle)); - m_resp->add_String(m_toUTF8.Convert(thisEventDescription)); + resp.add_U32(thisEventID); + resp.add_U32(thisEventTime); + resp.add_U32(thisEventDuration); + resp.add_U32(thisEventContent); + resp.add_U32(thisEventRating); + + resp.add_String(m_toUTF8.Convert(thisEventTitle)); + resp.add_String(m_toUTF8.Convert(thisEventSubTitle)); + resp.add_String(m_toUTF8.Convert(thisEventDescription)); atLeastOneEvent = true; } +#if VDRVERSNUM < 20301 Channels.Unlock(); +#endif + DEBUGLOG("Got all event data"); if (!atLeastOneEvent) { - m_resp->add_U32(0); + resp.add_U32(0); DEBUGLOG("Written 0 because no data"); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); - cEvent *lastEvent = Schedule->Events()->Last(); + const cEvent *lastEvent = Schedule->Events()->Last(); if (lastEvent) { m_epgUpdate[channelUID].lastEvent = lastEvent->StartTime(); @@ -2063,19 +2356,21 @@ * VNSI network functions for channel scanning */ -bool cVNSIClient::processSCAN_ScanSupported() /* OPCODE 140 */ +bool cVNSIClient::processSCAN_ScanSupported(cRequestPacket &req) /* OPCODE 140 */ { uint32_t retValue = VNSI_RET_NOTSUPPORTED; if (!m_inhibidDataUpdates && m_ChannelScanControl.IsSupported()) retValue = VNSI_RET_OK; - m_resp->add_U32(retValue); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(retValue); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processSCAN_GetSupportedTypes() +bool cVNSIClient::processSCAN_GetSupportedTypes(cRequestPacket &req) { uint32_t retValue = 0; if (m_ChannelScanControl.IsSupported()) @@ -2088,241 +2383,221 @@ retValue |= m_ChannelScanControl.SupportsATSC() ? VNSI_SCAN_SUPPORT_ATSC : 0; } - m_resp->add_U32(retValue); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(retValue); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processSCAN_GetCountries() /* OPCODE 141 */ +bool cVNSIClient::processSCAN_GetCountries(cRequestPacket &req) /* OPCODE 141 */ { + cResponsePacket resp; + resp.init(req.getRequestID()); + scannerEntryList list; if (m_ChannelScanControl.GetCountries(list)) { - m_resp->add_U32(VNSI_RET_OK); + resp.add_U32(VNSI_RET_OK); for (scannerEntryList::const_iterator it = list.begin(); it != list.end(); ++it) { - m_resp->add_U32(it->index); - m_resp->add_String(it->name); - m_resp->add_String(it->longName); + resp.add_U32(it->index); + resp.add_String(it->name); + resp.add_String(it->longName); } } else { - m_resp->add_U32(VNSI_RET_NOTSUPPORTED); + resp.add_U32(VNSI_RET_NOTSUPPORTED); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processSCAN_GetSatellites() /* OPCODE 142 */ +bool cVNSIClient::processSCAN_GetSatellites(cRequestPacket &req) /* OPCODE 142 */ { + cResponsePacket resp; + resp.init(req.getRequestID()); + scannerEntryList list; if (m_ChannelScanControl.GetSatellites(list)) { - m_resp->add_U32(VNSI_RET_OK); + resp.add_U32(VNSI_RET_OK); for (scannerEntryList::const_iterator it = list.begin(); it != list.end(); ++it) { - m_resp->add_U32(it->index); - m_resp->add_String(it->name); - m_resp->add_String(it->longName); + resp.add_U32(it->index); + resp.add_String(it->name); + resp.add_String(it->longName); } } else { - m_resp->add_U32(VNSI_RET_NOTSUPPORTED); + resp.add_U32(VNSI_RET_NOTSUPPORTED); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processSCAN_Start() /* OPCODE 143 */ +bool cVNSIClient::processSCAN_Start(cRequestPacket &req) /* OPCODE 143 */ { sScanServiceData svc; - svc.type = (int)m_req->extract_U32(); - svc.scan_tv = (bool)m_req->extract_U8(); - svc.scan_radio = (bool)m_req->extract_U8(); - svc.scan_fta = (bool)m_req->extract_U8(); - svc.scan_scrambled = (bool)m_req->extract_U8(); - svc.scan_hd = (bool)m_req->extract_U8(); - svc.CountryIndex = (int)m_req->extract_U32(); - svc.DVBC_Inversion = (int)m_req->extract_U32(); - svc.DVBC_Symbolrate = (int)m_req->extract_U32(); - svc.DVBC_QAM = (int)m_req->extract_U32(); - svc.DVBT_Inversion = (int)m_req->extract_U32(); - svc.SatIndex = (int)m_req->extract_U32(); - svc.ATSC_Type = (int)m_req->extract_U32(); + svc.type = (int)req.extract_U32(); + svc.scan_tv = (bool)req.extract_U8(); + svc.scan_radio = (bool)req.extract_U8(); + svc.scan_fta = (bool)req.extract_U8(); + svc.scan_scrambled = (bool)req.extract_U8(); + svc.scan_hd = (bool)req.extract_U8(); + svc.CountryIndex = (int)req.extract_U32(); + svc.DVBC_Inversion = (int)req.extract_U32(); + svc.DVBC_Symbolrate = (int)req.extract_U32(); + svc.DVBC_QAM = (int)req.extract_U32(); + svc.DVBT_Inversion = (int)req.extract_U32(); + svc.SatIndex = (int)req.extract_U32(); + svc.ATSC_Type = (int)req.extract_U32(); + + cResponsePacket resp; + resp.init(req.getRequestID()); if (!m_inhibidDataUpdates && m_ChannelScanControl.IsSupported()) { if (m_ChannelScanControl.StartScan(svc)) { - m_resp->add_U32(VNSI_RET_OK); + resp.add_U32(VNSI_RET_OK); m_inhibidDataUpdates = true; } else - m_resp->add_U32(VNSI_RET_ERROR); + resp.add_U32(VNSI_RET_ERROR); } else - m_resp->add_U32(VNSI_RET_NOTSUPPORTED); + resp.add_U32(VNSI_RET_NOTSUPPORTED); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processSCAN_Stop() /* OPCODE 144 */ +bool cVNSIClient::processSCAN_Stop(cRequestPacket &req) /* OPCODE 144 */ { m_inhibidDataUpdates = false; + cResponsePacket resp; + resp.init(req.getRequestID()); + if (m_ChannelScanControl.IsSupported()) { if (m_ChannelScanControl.StopScan()) - m_resp->add_U32(VNSI_RET_OK); + resp.add_U32(VNSI_RET_OK); else - m_resp->add_U32(VNSI_RET_ERROR); + resp.add_U32(VNSI_RET_ERROR); } else - m_resp->add_U32(VNSI_RET_NOTSUPPORTED); + resp.add_U32(VNSI_RET_NOTSUPPORTED); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } void cVNSIClient::processSCAN_SetPercentage(int percent) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initScan(VNSI_SCANNER_PERCENTAGE)) - { - delete resp; - return; - } - resp->add_U32(percent); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initScan(VNSI_SCANNER_PERCENTAGE); + resp.add_U32(percent); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } void cVNSIClient::processSCAN_SetSignalStrength(int strength, bool locked) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initScan(VNSI_SCANNER_SIGNAL)) - { - delete resp; - return; - } - resp->add_U32(strength); - resp->add_U32(locked); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initScan(VNSI_SCANNER_SIGNAL); + resp.add_U32(strength); + resp.add_U32(locked); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } void cVNSIClient::processSCAN_SetDeviceInfo(const char *Info) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initScan(VNSI_SCANNER_DEVICE)) - { - delete resp; - return; - } - resp->add_String(Info); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initScan(VNSI_SCANNER_DEVICE); + resp.add_String(Info); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } void cVNSIClient::processSCAN_SetTransponder(const char *Info) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initScan(VNSI_SCANNER_TRANSPONDER)) - { - delete resp; - return; - } - resp->add_String(Info); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initScan(VNSI_SCANNER_TRANSPONDER); + resp.add_String(Info); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } void cVNSIClient::processSCAN_NewChannel(const char *Name, bool isRadio, bool isEncrypted, bool isHD) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initScan(VNSI_SCANNER_NEWCHANNEL)) - { - delete resp; - return; - } - resp->add_U32(isRadio); - resp->add_U32(isEncrypted); - resp->add_U32(isHD); - resp->add_String(Name); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initScan(VNSI_SCANNER_NEWCHANNEL); + resp.add_U32(isRadio); + resp.add_U32(isEncrypted); + resp.add_U32(isHD); + resp.add_String(Name); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } void cVNSIClient::processSCAN_IsFinished() { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initScan(VNSI_SCANNER_FINISHED)) - { - delete resp; - return; - } - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initScan(VNSI_SCANNER_FINISHED); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } void cVNSIClient::processSCAN_SetStatus(int status) { - cResponsePacket *resp = new cResponsePacket(); - if (!resp->initScan(VNSI_SCANNER_STATUS)) - { - delete resp; - return; - } - resp->add_U32(status); - resp->finalise(); - m_socket.write(resp->getPtr(), resp->getLen()); - delete resp; + cResponsePacket resp; + resp.initScan(VNSI_SCANNER_STATUS); + resp.add_U32(status); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); } -bool cVNSIClient::processOSD_Connect() /* OPCODE 160 */ +bool cVNSIClient::processOSD_Connect(cRequestPacket &req) /* OPCODE 160 */ { + delete m_Osd; m_Osd = new cVnsiOsdProvider(&m_socket); int osdWidth, osdHeight; double aspect; cDevice::PrimaryDevice()->GetOsdSize(osdWidth, osdHeight, aspect); - m_resp->add_U32(osdWidth); - m_resp->add_U32(osdHeight); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(osdWidth); + resp.add_U32(osdHeight); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } bool cVNSIClient::processOSD_Disconnect() /* OPCODE 161 */ { - if (m_Osd) - { - delete m_Osd; - m_Osd = NULL; - } + delete m_Osd; + m_Osd = NULL; return true; } -bool cVNSIClient::processOSD_Hitkey() /* OPCODE 162 */ +bool cVNSIClient::processOSD_Hitkey(cRequestPacket &req) /* OPCODE 162 */ { if (m_Osd) { - unsigned int key = m_req->extract_U32(); + unsigned int key = req.extract_U32(); cVnsiOsdProvider::SendKey(key); } return true; @@ -2330,29 +2605,45 @@ /** OPCODE 180 - 189: VNSI network functions for deleted recording access */ -bool cVNSIClient::processRECORDINGS_DELETED_Supported() /* OPCODE 180 */ +bool cVNSIClient::processRECORDINGS_DELETED_Supported(cRequestPacket &req) /* OPCODE 180 */ { - m_resp->add_U32(VNSI_RET_OK); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(VNSI_RET_OK); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_DELETED_GetCount() /* OPCODE 181 */ +bool cVNSIClient::processRECORDINGS_DELETED_GetCount(cRequestPacket &req) /* OPCODE 181 */ { - DeletedRecordings.Load(); - m_resp->add_U32(DeletedRecordings.Count()); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); +#if VDRVERSNUM >= 20301 + LOCK_DELETEDRECORDINGS_READ; + resp.add_U32(DeletedRecordings->Count()); +#else + resp.add_U32(DeletedRecordings.Count()); +#endif + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_DELETED_GetList() /* OPCODE 182 */ +bool cVNSIClient::processRECORDINGS_DELETED_GetList(cRequestPacket &req) /* OPCODE 182 */ { + cResponsePacket resp; + resp.init(req.getRequestID()); + cMutexLock lock(&m_timerLock); - cThreadLock RecordingsLock(&Recordings); +#if VDRVERSNUM >= 20301 + LOCK_DELETEDRECORDINGS_READ; + for (const cRecording *recording = DeletedRecordings->First(); recording; recording = DeletedRecordings->Next(recording)) +#else + cThreadLock RecordingsLock(&Recordings); for (cRecording *recording = DeletedRecordings.First(); recording; recording = DeletedRecordings.Next(recording)) +#endif { #if APIVERSNUM >= 10705 const cEvent *event = recording->Info()->GetEvent(); @@ -2387,27 +2678,27 @@ DEBUGLOG("GRI: RC: recordingStart=%lu recordingDuration=%i", recordingStart, recordingDuration); // recording_time - m_resp->add_U32(recordingStart); + resp.add_U32(recordingStart); // duration - m_resp->add_U32(recordingDuration); + resp.add_U32(recordingDuration); // priority #if APIVERSNUM >= 10727 - m_resp->add_U32(recording->Priority()); + resp.add_U32(recording->Priority()); #else - m_resp->add_U32(recording->priority); + resp.add_U32(recording->priority); #endif // lifetime #if APIVERSNUM >= 10727 - m_resp->add_U32(recording->Lifetime()); + resp.add_U32(recording->Lifetime()); #else - m_resp->add_U32(recording->lifetime); + resp.add_U32(recording->lifetime); #endif // channel_name - m_resp->add_String(recording->Info()->ChannelName() ? m_toUTF8.Convert(recording->Info()->ChannelName()) : ""); + resp.add_String(recording->Info()->ChannelName() ? m_toUTF8.Convert(recording->Info()->ChannelName()) : ""); char* fullname = strdup(recording->Name()); char* recname = strrchr(fullname, FOLDERDELIMCHAR); @@ -2423,19 +2714,19 @@ } // title - m_resp->add_String(m_toUTF8.Convert(recname)); + resp.add_String(m_toUTF8.Convert(recname)); // subtitle if (!isempty(recording->Info()->ShortText())) - m_resp->add_String(m_toUTF8.Convert(recording->Info()->ShortText())); + resp.add_String(m_toUTF8.Convert(recording->Info()->ShortText())); else - m_resp->add_String(""); + resp.add_String(""); // description if (!isempty(recording->Info()->Description())) - m_resp->add_String(m_toUTF8.Convert(recording->Info()->Description())); + resp.add_String(m_toUTF8.Convert(recording->Info()->Description())); else - m_resp->add_String(""); + resp.add_String(""); // directory if(directory != NULL) { @@ -2448,22 +2739,25 @@ while(*directory == '/') directory++; } - m_resp->add_String((isempty(directory)) ? "" : m_toUTF8.Convert(directory)); + resp.add_String((isempty(directory)) ? "" : m_toUTF8.Convert(directory)); // filename / uid of recording uint32_t uid = cRecordingsCache::GetInstance().Register(recording, false); - m_resp->add_U32(uid); + resp.add_U32(uid); free(fullname); } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_DELETED_Delete() /* OPCODE 183 */ +bool cVNSIClient::processRECORDINGS_DELETED_Delete(cRequestPacket &req) /* OPCODE 183 */ { + cResponsePacket resp; + resp.init(req.getRequestID()); + cString recName; cRecording* recording = NULL; @@ -2474,11 +2768,15 @@ #endif if (LockFile.Lock()) { - uint32_t uid = m_req->extract_U32(); + uint32_t uid = req.extract_U32(); +#if VDRVERSNUM >= 20301 + LOCK_DELETEDRECORDINGS_WRITE; + for (recording = DeletedRecordings->First(); recording; recording = DeletedRecordings->Next(recording)) +#else cThreadLock DeletedRecordingsLock(&DeletedRecordings); - for (recording = DeletedRecordings.First(); recording; recording = DeletedRecordings.Next(recording)) +#endif { if (uid == CreateStringHash(recording->FileName())) { @@ -2489,22 +2787,27 @@ #endif { ERRORLOG("Error while remove deleted recording (%s)", recording->FileName()); - m_resp->add_U32(VNSI_RET_ERROR); + resp.add_U32(VNSI_RET_ERROR); } else { +#if VDRVERSNUM >= 20301 + DeletedRecordings->Del(recording); + DeletedRecordings->Update(); +#else DeletedRecordings.Del(recording); DeletedRecordings.Update(); +#endif INFOLOG("Recording \"%s\" permanent deleted", recording->FileName()); - m_resp->add_U32(VNSI_RET_OK); + resp.add_U32(VNSI_RET_OK); } break; } } } - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } @@ -2517,7 +2820,7 @@ char *ext = strrchr(NewName, '.'); if (ext && strcmp(ext, ".del") == 0) { - strncpy(ext, ".rec", strlen(ext)); + strcpy(ext, ".rec"); if (!access(NewName, F_OK)) { ERRORLOG("Recording with the same name exists (%s)", NewName); @@ -2536,14 +2839,13 @@ ERRORLOG("Error while rename deleted recording (%s) to (%s)", recording->FileName(), NewName); } - cIndexFile *index = new cIndexFile(NewName, false, recording->IsPesRecording()); - int LastFrame = index->Last() - 1; + cIndexFile index(NewName, false, recording->IsPesRecording()); + int LastFrame = index.Last() - 1; if (LastFrame > 0) { uint16_t FileNumber = 0; off_t FileOffset = 0; - index->Get(LastFrame, &FileNumber, &FileOffset); - delete index; + index.Get(LastFrame, &FileNumber, &FileOffset); if (FileNumber == 0) { ERRORLOG("while read last filenumber (%s)", NewName); @@ -2564,14 +2866,21 @@ } else { - delete index; ERRORLOG("accessing indexfile (%s)", NewName); OsdStatusMessage(*cString::sprintf("%s (%s)", tr("Error while accessing indexfile"), NewName)); } +#if VDRVERSNUM >= 20301 + LOCK_RECORDINGS_WRITE; + LOCK_DELETEDRECORDINGS_WRITE; + DeletedRecordings->Del(recording); + Recordings->Update(); + DeletedRecordings->Update(); +#else DeletedRecordings.Del(recording); Recordings.Update(); DeletedRecordings.Update(); +#endif } else { @@ -2584,7 +2893,7 @@ return true; } -bool cVNSIClient::processRECORDINGS_DELETED_Undelete() /* OPCODE 184 */ +bool cVNSIClient::processRECORDINGS_DELETED_Undelete(cRequestPacket &req) /* OPCODE 184 */ { int ret = VNSI_RET_DATAUNKNOWN; @@ -2595,11 +2904,15 @@ #endif if (LockFile.Lock()) { - uint32_t uid = m_req->extract_U32(); + uint32_t uid = req.extract_U32(); +#if VDRVERSNUM >= 20301 + LOCK_DELETEDRECORDINGS_WRITE; + for (cRecording* recording = DeletedRecordings->First(); recording; recording = DeletedRecordings->Next(recording)) +#else cThreadLock DeletedRecordingsLock(&DeletedRecordings); - for (cRecording* recording = DeletedRecordings.First(); recording; recording = DeletedRecordings.Next(recording)) +#endif { if (uid == CreateStringHash(recording->FileName())) { @@ -2615,13 +2928,15 @@ } } - m_resp->add_U32(ret); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(ret); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } -bool cVNSIClient::processRECORDINGS_DELETED_DeleteAll() /* OPCODE 185 */ +bool cVNSIClient::processRECORDINGS_DELETED_DeleteAll(cRequestPacket &req) /* OPCODE 185 */ { int ret = VNSI_RET_OK; @@ -2633,11 +2948,19 @@ if (LockFile.Lock()) { +#if VDRVERSNUM >= 20301 + LOCK_DELETEDRECORDINGS_WRITE; + for (cRecording *recording = DeletedRecordings->First(); recording; ) +#else cThreadLock DeletedRecordingsLock(&DeletedRecordings); - for (cRecording *recording = DeletedRecordings.First(); recording; ) +#endif { +#if VDRVERSNUM >= 20301 + cRecording *next = DeletedRecordings->Next(recording); +#else cRecording *next = DeletedRecordings.Next(recording); +#endif #if VDRVERSNUM >= 20102 if (!cVideoDirectory::RemoveVideoFile(recording->FileName())) #else @@ -2652,19 +2975,26 @@ INFOLOG("Recording \"%s\" permanent deleted", recording->FileName()); recording = next; } +#if VDRVERSNUM >= 20301 + DeletedRecordings->Clear(); + DeletedRecordings->Update(); +#else DeletedRecordings.Clear(); DeletedRecordings.Update(); +#endif } - m_resp->add_U32(ret); - m_resp->finalise(); - m_socket.write(m_resp->getPtr(), m_resp->getLen()); + cResponsePacket resp; + resp.init(req.getRequestID()); + resp.add_U32(ret); + resp.finalise(); + m_socket.write(resp.getPtr(), resp.getLen()); return true; } // part of this method is taken from XVDR -cString cVNSIClient::CreatePiconRef(cChannel* channel) +cString cVNSIClient::CreatePiconRef(const cChannel* channel) { int hash = 0; diff -Nru vdr-plugin-vnsiserver-1.3.1/vnsiclient.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiclient.h --- vdr-plugin-vnsiserver-1.3.1/vnsiclient.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiclient.h 2016-04-06 23:08:27.000000000 +0000 @@ -61,8 +61,6 @@ bool m_bSupportRDS; cString m_ClientAddress; cRecPlayer *m_RecPlayer; - cRequestPacket *m_req; - cResponsePacket *m_resp; cCharSetConv m_toUTF8; uint32_t m_protocolVersion; cMutex m_msgLock; @@ -79,7 +77,7 @@ protected: - bool processRequest(cRequestPacket* req); + bool processRequest(cRequestPacket &req); virtual void Action(void); @@ -105,7 +103,7 @@ void SetLoggedIn(bool yesNo) { m_loggedIn = yesNo; } void SetStatusInterface(bool yesNo) { m_StatusInterfaceEnabled = yesNo; } - bool StartChannelStreaming(const cChannel *channel, int32_t priority, uint8_t timeshift, uint32_t timeout); + bool StartChannelStreaming(cResponsePacket &resp, const cChannel *channel, int32_t priority, uint8_t timeshift, uint32_t timeout); void StopChannelStreaming(); private: @@ -118,76 +116,77 @@ std::map m_channelgroups[2]; - bool process_Login(); - bool process_GetTime(); - bool process_EnableStatusInterface(); - bool process_Ping(); - bool process_GetSetup(); - bool process_StoreSetup(); - - bool processChannelStream_Open(); - bool processChannelStream_Close(); - bool processChannelStream_Seek(); - - bool processRecStream_Open(); - bool processRecStream_Close(); - bool processRecStream_GetBlock(); - bool processRecStream_PositionFromFrameNumber(); - bool processRecStream_FrameNumberFromPosition(); - bool processRecStream_GetIFrame(); - bool processRecStream_GetLength(); - - bool processCHANNELS_GroupsCount(); - bool processCHANNELS_ChannelsCount(); - bool processCHANNELS_GroupList(); - bool processCHANNELS_GetChannels(); - bool processCHANNELS_GetGroupMembers(); - bool processCHANNELS_GetCaids(); - bool processCHANNELS_GetWhitelist(); - bool processCHANNELS_GetBlacklist(); - bool processCHANNELS_SetWhitelist(); - bool processCHANNELS_SetBlacklist(); + bool process_Login(cRequestPacket &r); + bool process_GetTime(cRequestPacket &r); + bool process_EnableStatusInterface(cRequestPacket &r); + bool process_Ping(cRequestPacket &r); + bool process_GetSetup(cRequestPacket &r); + bool process_StoreSetup(cRequestPacket &r); + + bool processChannelStream_Open(cRequestPacket &r); + bool processChannelStream_Close(cRequestPacket &req); + bool processChannelStream_Seek(cRequestPacket &r); + + bool processRecStream_Open(cRequestPacket &r); + bool processRecStream_Close(cRequestPacket &r); + bool processRecStream_GetBlock(cRequestPacket &r); + bool processRecStream_PositionFromFrameNumber(cRequestPacket &r); + bool processRecStream_FrameNumberFromPosition(cRequestPacket &r); + bool processRecStream_GetIFrame(cRequestPacket &r); + bool processRecStream_GetLength(cRequestPacket &r); + + bool processCHANNELS_GroupsCount(cRequestPacket &r); + bool processCHANNELS_ChannelsCount(cRequestPacket &r); + bool processCHANNELS_GroupList(cRequestPacket &r); + bool processCHANNELS_GetChannels(cRequestPacket &r); + bool processCHANNELS_GetGroupMembers(cRequestPacket &r); + bool processCHANNELS_GetCaids(cRequestPacket &r); + bool processCHANNELS_GetWhitelist(cRequestPacket &r); + bool processCHANNELS_GetBlacklist(cRequestPacket &r); + bool processCHANNELS_SetWhitelist(cRequestPacket &r); + bool processCHANNELS_SetBlacklist(cRequestPacket &r); void CreateChannelGroups(bool automatic); - bool processTIMER_GetCount(); - bool processTIMER_Get(); - bool processTIMER_GetList(); - bool processTIMER_Add(); - bool processTIMER_Delete(); - bool processTIMER_Update(); - - bool processRECORDINGS_GetDiskSpace(); - bool processRECORDINGS_GetCount(); - bool processRECORDINGS_GetList(); - bool processRECORDINGS_GetInfo(); - bool processRECORDINGS_Rename(); - bool processRECORDINGS_Delete(); - bool processRECORDINGS_Move(); - bool processRECORDINGS_GetEdl(); - bool processRECORDINGS_DELETED_Supported(); - bool processRECORDINGS_DELETED_GetCount(); - bool processRECORDINGS_DELETED_GetList(); - bool processRECORDINGS_DELETED_Delete(); - bool processRECORDINGS_DELETED_Undelete(); - bool processRECORDINGS_DELETED_DeleteAll(); - - bool processEPG_GetForChannel(); - - bool processSCAN_ScanSupported(); - bool processSCAN_GetSupportedTypes(); - bool processSCAN_GetCountries(); - bool processSCAN_GetSatellites(); - bool processSCAN_Start(); - bool processSCAN_Stop(); + bool processTIMER_GetCount(cRequestPacket &r); + bool processTIMER_Get(cRequestPacket &r); + bool processTIMER_GetList(cRequestPacket &r); + bool processTIMER_Add(cRequestPacket &r); + bool processTIMER_Delete(cRequestPacket &r); + bool processTIMER_Update(cRequestPacket &r); + bool processTIMER_GetTypes(cRequestPacket &r); + + bool processRECORDINGS_GetDiskSpace(cRequestPacket &r); + bool processRECORDINGS_GetCount(cRequestPacket &r); + bool processRECORDINGS_GetList(cRequestPacket &r); + bool processRECORDINGS_GetInfo(cRequestPacket &r); + bool processRECORDINGS_Rename(cRequestPacket &r); + bool processRECORDINGS_Delete(cRequestPacket &r); + bool processRECORDINGS_Move(cRequestPacket &r); + bool processRECORDINGS_GetEdl(cRequestPacket &r); + bool processRECORDINGS_DELETED_Supported(cRequestPacket &r); + bool processRECORDINGS_DELETED_GetCount(cRequestPacket &r); + bool processRECORDINGS_DELETED_GetList(cRequestPacket &r); + bool processRECORDINGS_DELETED_Delete(cRequestPacket &r); + bool processRECORDINGS_DELETED_Undelete(cRequestPacket &r); + bool processRECORDINGS_DELETED_DeleteAll(cRequestPacket &r); + + bool processEPG_GetForChannel(cRequestPacket &r); + + bool processSCAN_ScanSupported(cRequestPacket &r); + bool processSCAN_GetSupportedTypes(cRequestPacket &r); + bool processSCAN_GetCountries(cRequestPacket &r); + bool processSCAN_GetSatellites(cRequestPacket &r); + bool processSCAN_Start(cRequestPacket &r); + bool processSCAN_Stop(cRequestPacket &r); bool Undelete(cRecording* recording); - bool processOSD_Connect(); + bool processOSD_Connect(cRequestPacket &req); bool processOSD_Disconnect(); - bool processOSD_Hitkey(); + bool processOSD_Hitkey(cRequestPacket &req); - cString CreatePiconRef(cChannel* channel); + cString CreatePiconRef(const cChannel* channel); private: /** Static callback functions to interact with wirbelscan plugin over diff -Nru vdr-plugin-vnsiserver-1.3.1/vnsicommand.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsicommand.h --- vdr-plugin-vnsiserver-1.3.1/vnsicommand.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsicommand.h 2016-04-06 23:08:27.000000000 +0000 @@ -27,7 +27,7 @@ #define VNSI_COMMAND_H /** Current VNSI Protocol Version number */ -#define VNSI_PROTOCOLVERSION 8 +#define VNSI_PROTOCOLVERSION 9 /** Start of RDS support protocol Version */ #define VNSI_RDS_PROTOCOLVERSION 8 @@ -95,6 +95,7 @@ #define VNSI_TIMER_ADD 83 #define VNSI_TIMER_DELETE 84 #define VNSI_TIMER_UPDATE 85 +#define VNSI_TIMER_GETTYPES 86 /* OPCODE 100 - 119: VNSI network functions for recording access */ #define VNSI_RECORDINGS_DISKSIZE 100 @@ -171,6 +172,13 @@ #define VNSI_SCAN_SUPPORT_ANALOG_RADIO 0x10 #define VNSI_SCAN_SUPPORT_ATSC 0x20 +/** Timer */ +#define VNSI_TIMER_TYPE_MAN 1 +#define VNSI_TIMER_TYPE_MAN_REPEAT 2 +#define VNSI_TIMER_TYPE_EPG 3 +#define VNSI_TIMER_TYPE_VPS 4 +#define VNSI_TIMER_TYPE_EPG_SEARCH 5 + /** Packet return codes */ #define VNSI_RET_OK 0 #define VNSI_RET_RECRUNNING 1 diff -Nru vdr-plugin-vnsiserver-1.3.1/vnsi.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsi.h --- vdr-plugin-vnsiserver-1.3.1/vnsi.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsi.h 2016-04-06 23:08:27.000000000 +0000 @@ -39,17 +39,20 @@ extern int PlayRecording; extern int AvoidEPGScan; -class cDvbVsniDeviceProbe; +class cDvbVsniDeviceProbe : public cDvbDeviceProbe +{ +public: + virtual bool Probe(int Adapter, int Frontend); +}; class cPluginVNSIServer : public cPlugin { private: cVNSIServer *Server; static cPluginVNSIServer *VNSIServer; - cDvbVsniDeviceProbe *probe; + cDvbVsniDeviceProbe probe; public: cPluginVNSIServer(void); - virtual ~cPluginVNSIServer(); virtual const char *Version(void) { return VERSION; } virtual const char *Description(void) { return DESCRIPTION; } virtual const char *CommandLineHelp(void); @@ -72,12 +75,6 @@ static void StoreSetup(const char *Name, int Value); }; -class cDvbVsniDeviceProbe : public cDvbDeviceProbe -{ -public: - virtual bool Probe(int Adapter, int Frontend); -}; - class cDvbVnsiDevice : public cDvbDevice { public: diff -Nru vdr-plugin-vnsiserver-1.3.1/vnsiosd.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiosd.c --- vdr-plugin-vnsiserver-1.3.1/vnsiosd.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiosd.c 2016-04-06 23:08:27.000000000 +0000 @@ -22,8 +22,8 @@ * */ -#include "config.h" #include "vnsiosd.h" +#include "config.h" #include "vnsicommand.h" #include "responsepacket.h" #include "vnsi.h" @@ -210,7 +210,6 @@ // --- cVnsiOsdProvider ------------------------------------------------------- -cResponsePacket cVnsiOsdProvider::m_OsdPacket; cxSocket *cVnsiOsdProvider::m_Socket; cMutex cVnsiOsdProvider::m_Mutex; bool cVnsiOsdProvider::m_RequestFull; @@ -245,11 +244,8 @@ if (!m_Socket) return; - if (!m_OsdPacket.initOsd(cmd, wnd, color, x0, y0, x1, y1)) - { - ERRORLOG("OSD response packet init fail"); - return; - } + cResponsePacket m_OsdPacket; + m_OsdPacket.initOsd(cmd, wnd, color, x0, y0, x1, y1); m_OsdPacket.setLen(m_OsdPacket.getOSDHeaderLength() + size); m_OsdPacket.finaliseOSD(); diff -Nru vdr-plugin-vnsiserver-1.3.1/vnsiosd.h vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiosd.h --- vdr-plugin-vnsiserver-1.3.1/vnsiosd.h 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiosd.h 2016-04-06 23:08:27.000000000 +0000 @@ -23,7 +23,6 @@ */ #include -#include "responsepacket.h" class cxSocket; @@ -37,7 +36,6 @@ static bool IsRequestFull(); static void SendKey(unsigned int key); private: - static cResponsePacket m_OsdPacket; static cxSocket *m_Socket; static cMutex m_Mutex; static bool m_RequestFull; diff -Nru vdr-plugin-vnsiserver-1.3.1/vnsiserver.c vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiserver.c --- vdr-plugin-vnsiserver-1.3.1/vnsiserver.c 2015-09-18 13:14:08.000000000 +0000 +++ vdr-plugin-vnsiserver-1.3.1-901~c63d8e8/vnsiserver.c 2016-04-06 23:08:27.000000000 +0000 @@ -23,6 +23,11 @@ * */ +#include "vnsiserver.h" +#include "vnsiclient.h" +#include "vnsi.h" +#include "channelfilter.h" + #include #include #include @@ -40,11 +45,6 @@ #include -#include "vnsi.h" -#include "vnsiserver.h" -#include "vnsiclient.h" -#include "channelfilter.h" - unsigned int cVNSIServer::m_IdCnt = 0; class cAllowedHosts : public cSVDRPhosts @@ -69,7 +69,7 @@ } }; -cVNSIServer::cVNSIServer(int listenPort) : cThread("VDR VNSI Server") +cVNSIServer::cVNSIServer(int listenPort) : cThread("VNSI Server") { m_ServerPort = listenPort; @@ -82,8 +82,8 @@ cVNSIServer::~cVNSIServer() { - m_Status.Shutdown(); Cancel(); + m_Status.Shutdown(); INFOLOG("VNSI Server stopped"); }