Version 1.4.1-4

- Fixed converting the port number in the "connect from..." log message of SVDRP
  (thanks to Ville Skyttä).
- Made the cCiSession members sessionId and resourceId uint16_t and uint32_t,
  respectively, to match their types in the CI session data (thanks to Ville Skyttä
  for reporting that there are places where ntohs() is assigned to different types).
- Changed the way a device is selected for receiving in order to keep devices with
  CAMs better available, even if this means recording on the primary device (reported
  by Jörn Reder; thanks to Anssi Hannula for improving handling Transfer Mode devices
  in this).
- No longer stopping removing empty directories if an error occurs (thanks to
  Oliver Endriss).
- Added a log error message to cPlugin::ConfigDirectory() in case a plugin calls it
  from a separate thread (reported by Udo Richter).
This commit is contained in:
Klaus Schmidinger 2006-08-13 18:00:00 +02:00
parent 33f1491b18
commit f5ad8fc5d7
9 changed files with 81 additions and 53 deletions

View File

@ -639,6 +639,7 @@ Oliver Endriss <o.endriss@gmx.de>
against invalid data
for reporting a problem in extracting APIVERSION with older versions of 'sed'
for fixing broken APIVERSION extraction line in 'newplugin'
for making VDR no longer stop removing empty directories if an error occurs
Reinhard Walter Buchner <rw.buchner@freenet.de>
for adding some satellites to 'sources.conf'
@ -1460,6 +1461,8 @@ Udo Richter <udo_richter@gmx.de>
for reporting that the shutdown message "Recording in ... minutes, shut down anyway?"
may have been given with a negative number of minutes
for fixing getting the next active timer when shutting down
for reporting a problem with cPlugin::ConfigDirectory() in case a plugin calls it
from a separate thread
Sven Kreiensen <svenk@kammer.uni-hannover.de>
for his help in keeping 'channels.conf.terr' up to date
@ -1621,6 +1624,8 @@ Ville Skytt
for fixing several spelling errors
for reporting that the call to pthread_setschedparam(childTid, SCHED_RR, 0) in
thread.c caused a compiler warning with g++ 4.1.1
for fixing converting the port number in the "connect from..." log message of SVDRP
for reporting that there are places where ntohs() is assigned to different types
Steffen Beyer <cpunk@reactor.de>
for fixing setting the colored button help after deleting a recording in case the next
@ -1953,6 +1958,7 @@ Anssi Hannula <anssi.hannula@gmail.com>
for a patch that was used to implement processing the "frequency list descriptor"
for suggesting that cDevice::GetDevice() should prefer any device that's already
receiving and doesn't require detatching receivers
for improving handling Transfer Mode devices when selecting a device to receive
Antti Hartikainen <ami+vdr@ah.fi>
for updating 'S13E' in 'sources.conf'
@ -1970,3 +1976,7 @@ Norbert Wentz <norbert.wentz@online.de>
Frank Schmirler <vdr@schmirler.de>
for fixing handling client side termination of SVDRP connections
for fixing assigning schedules to channels in case there is no initial EPG information
Jörn Reder <joern@zyn.de>
for reporting that a recording may unnecessarily block a device with a CAM, while
it could record on the primary device as well

16
HISTORY
View File

@ -4858,3 +4858,19 @@ Video Disk Recorder Revision History
a negative number of minutes (reported by Udo Richter).
- Fixed getting the next active timer when shutting down (thanks to Udo Richter).
- Modified the cSVDRP::Close() function to avoid code duplication.
2006-08-13: Version 1.4.1-4
- Fixed converting the port number in the "connect from..." log message of SVDRP
(thanks to Ville Skyttä).
- Made the cCiSession members sessionId and resourceId uint16_t and uint32_t,
respectively, to match their types in the CI session data (thanks to Ville Skyttä
for reporting that there are places where ntohs() is assigned to different types).
- Changed the way a device is selected for receiving in order to keep devices with
CAMs better available, even if this means recording on the primary device (reported
by Jörn Reder; thanks to Anssi Hannula for improving handling Transfer Mode devices
in this).
- No longer stopping removing empty directories if an error occurs (thanks to
Oliver Endriss).
- Added a log error message to cPlugin::ConfigDirectory() in case a plugin calls it
from a separate thread (reported by Udo Richter).

68
ci.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: ci.c 1.43 2006/07/22 13:40:30 kls Exp $
* $Id: ci.c 1.44 2006/08/12 10:14:27 kls Exp $
*/
#include "ci.h"
@ -630,24 +630,24 @@ cCiTransportConnection *cCiTransportLayer::Process(int Slot)
class cCiSession {
private:
int sessionId;
int resourceId;
uint16_t sessionId;
uint32_t resourceId;
cCiTransportConnection *tc;
protected:
int GetTag(int &Length, const uint8_t **Data);
const uint8_t *GetData(const uint8_t *Data, int &Length);
int SendData(int Tag, int Length = 0, const uint8_t *Data = NULL);
public:
cCiSession(int SessionId, int ResourceId, cCiTransportConnection *Tc);
cCiSession(uint16_t SessionId, uint32_t ResourceId, cCiTransportConnection *Tc);
virtual ~cCiSession();
const cCiTransportConnection *Tc(void) { return tc; }
int SessionId(void) { return sessionId; }
int ResourceId(void) { return resourceId; }
uint16_t SessionId(void) { return sessionId; }
uint32_t ResourceId(void) { return resourceId; }
virtual bool HasUserIO(void) { return false; }
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
};
cCiSession::cCiSession(int SessionId, int ResourceId, cCiTransportConnection *Tc)
cCiSession::cCiSession(uint16_t SessionId, uint32_t ResourceId, cCiTransportConnection *Tc)
{
sessionId = SessionId;
resourceId = ResourceId;
@ -711,11 +711,11 @@ class cCiResourceManager : public cCiSession {
private:
int state;
public:
cCiResourceManager(int SessionId, cCiTransportConnection *Tc);
cCiResourceManager(uint16_t SessionId, cCiTransportConnection *Tc);
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
};
cCiResourceManager::cCiResourceManager(int SessionId, cCiTransportConnection *Tc)
cCiResourceManager::cCiResourceManager(uint16_t SessionId, cCiTransportConnection *Tc)
:cCiSession(SessionId, RI_RESOURCE_MANAGER, Tc)
{
dbgprotocol("New Resource Manager (session id %d)\n", SessionId);
@ -729,12 +729,12 @@ bool cCiResourceManager::Process(int Length, const uint8_t *Data)
switch (Tag) {
case AOT_PROFILE_ENQ: {
dbgprotocol("%d: <== Profile Enquiry\n", SessionId());
int resources[] = { htonl(RI_RESOURCE_MANAGER),
htonl(RI_APPLICATION_INFORMATION),
htonl(RI_CONDITIONAL_ACCESS_SUPPORT),
htonl(RI_DATE_TIME),
htonl(RI_MMI)
};
uint32_t resources[] = { htonl(RI_RESOURCE_MANAGER),
htonl(RI_APPLICATION_INFORMATION),
htonl(RI_CONDITIONAL_ACCESS_SUPPORT),
htonl(RI_DATE_TIME),
htonl(RI_MMI)
};
dbgprotocol("%d: ==> Profile\n", SessionId());
SendData(AOT_PROFILE, sizeof(resources), (uint8_t*)resources);
state = 3;
@ -779,14 +779,14 @@ private:
uint16_t manufacturerCode;
char *menuString;
public:
cCiApplicationInformation(int SessionId, cCiTransportConnection *Tc);
cCiApplicationInformation(uint16_t SessionId, cCiTransportConnection *Tc);
virtual ~cCiApplicationInformation();
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
bool EnterMenu(void);
const char *GetMenuString(void) { return menuString; }
};
cCiApplicationInformation::cCiApplicationInformation(int SessionId, cCiTransportConnection *Tc)
cCiApplicationInformation::cCiApplicationInformation(uint16_t SessionId, cCiTransportConnection *Tc)
:cCiSession(SessionId, RI_APPLICATION_INFORMATION, Tc)
{
dbgprotocol("New Application Information (session id %d)\n", SessionId);
@ -963,14 +963,14 @@ private:
int numCaSystemIds;
unsigned short caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated!
public:
cCiConditionalAccessSupport(int SessionId, cCiTransportConnection *Tc);
cCiConditionalAccessSupport(uint16_t SessionId, cCiTransportConnection *Tc);
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
const unsigned short *GetCaSystemIds(void) { return caSystemIds; }
bool SendPMT(cCiCaPmt *CaPmt);
bool ReceivedReply(bool CanDescramble = false);
};
cCiConditionalAccessSupport::cCiConditionalAccessSupport(int SessionId, cCiTransportConnection *Tc)
cCiConditionalAccessSupport::cCiConditionalAccessSupport(uint16_t SessionId, cCiTransportConnection *Tc)
:cCiSession(SessionId, RI_CONDITIONAL_ACCESS_SUPPORT, Tc)
{
dbgprotocol("New Conditional Access Support (session id %d)\n", SessionId);
@ -1090,11 +1090,11 @@ private:
time_t lastTime;
bool SendDateTime(void);
public:
cCiDateTime(int SessionId, cCiTransportConnection *Tc);
cCiDateTime(uint16_t SessionId, cCiTransportConnection *Tc);
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
};
cCiDateTime::cCiDateTime(int SessionId, cCiTransportConnection *Tc)
cCiDateTime::cCiDateTime(uint16_t SessionId, cCiTransportConnection *Tc)
:cCiSession(SessionId, RI_DATE_TIME, Tc)
{
interval = 0;
@ -1193,7 +1193,7 @@ private:
cCiMenu *menu, *fetchedMenu;
cCiEnquiry *enquiry, *fetchedEnquiry;
public:
cCiMMI(int SessionId, cCiTransportConnection *Tc);
cCiMMI(uint16_t SessionId, cCiTransportConnection *Tc);
virtual ~cCiMMI();
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
virtual bool HasUserIO(void) { return menu || enquiry; }
@ -1204,7 +1204,7 @@ public:
bool SendCloseMMI(void);
};
cCiMMI::cCiMMI(int SessionId, cCiTransportConnection *Tc)
cCiMMI::cCiMMI(uint16_t SessionId, cCiTransportConnection *Tc)
:cCiSession(SessionId, RI_MMI, Tc)
{
dbgprotocol("New MMI (session id %d)\n", SessionId);
@ -1524,12 +1524,12 @@ cCiHandler *cCiHandler::CreateCiHandler(const char *FileName)
return NULL;
}
int cCiHandler::ResourceIdToInt(const uint8_t *Data)
uint32_t cCiHandler::ResourceIdToInt(const uint8_t *Data)
{
return (ntohl(get_unaligned((int32_t *)Data)));
return (ntohl(get_unaligned((uint32_t *)Data)));
}
bool cCiHandler::Send(uint8_t Tag, int SessionId, int ResourceId, int Status)
bool cCiHandler::Send(uint8_t Tag, uint16_t SessionId, uint32_t ResourceId, int Status)
{
uint8_t buffer[16];
uint8_t *p = buffer;
@ -1538,7 +1538,7 @@ bool cCiHandler::Send(uint8_t Tag, int SessionId, int ResourceId, int Status)
if (Status >= 0)
*p++ = Status;
if (ResourceId) {
put_unaligned(htonl(ResourceId), (int32_t *)p);
put_unaligned(htonl(ResourceId), (uint32_t *)p);
p += 4;
}
put_unaligned(htons(SessionId), (uint16_t *)p);
@ -1547,7 +1547,7 @@ bool cCiHandler::Send(uint8_t Tag, int SessionId, int ResourceId, int Status)
return tc && tc->SendData(p - buffer, buffer) == OK;
}
cCiSession *cCiHandler::GetSessionBySessionId(int SessionId)
cCiSession *cCiHandler::GetSessionBySessionId(uint16_t SessionId)
{
for (int i = 0; i < MAX_CI_SESSION; i++) {
if (sessions[i] && sessions[i]->SessionId() == SessionId)
@ -1556,7 +1556,7 @@ cCiSession *cCiHandler::GetSessionBySessionId(int SessionId)
return NULL;
}
cCiSession *cCiHandler::GetSessionByResourceId(int ResourceId, int Slot)
cCiSession *cCiHandler::GetSessionByResourceId(uint32_t ResourceId, int Slot)
{
for (int i = 0; i < MAX_CI_SESSION; i++) {
if (sessions[i] && sessions[i]->Tc()->Slot() == Slot && sessions[i]->ResourceId() == ResourceId)
@ -1565,7 +1565,7 @@ cCiSession *cCiHandler::GetSessionByResourceId(int ResourceId, int Slot)
return NULL;
}
cCiSession *cCiHandler::CreateSession(int ResourceId)
cCiSession *cCiHandler::CreateSession(uint32_t ResourceId)
{
if (!GetSessionByResourceId(ResourceId, tc->Slot())) {
for (int i = 0; i < MAX_CI_SESSION; i++) {
@ -1588,7 +1588,7 @@ cCiSession *cCiHandler::CreateSession(int ResourceId)
bool cCiHandler::OpenSession(int Length, const uint8_t *Data)
{
if (Length == 6 && *(Data + 1) == 0x04) {
int ResourceId = ResourceIdToInt(Data + 2);
uint32_t ResourceId = ResourceIdToInt(Data + 2);
dbgprotocol("OpenSession %08X\n", ResourceId);
switch (ResourceId) {
case RI_RESOURCE_MANAGER:
@ -1611,9 +1611,9 @@ bool cCiHandler::OpenSession(int Length, const uint8_t *Data)
return false;
}
bool cCiHandler::CloseSession(int SessionId)
bool cCiHandler::CloseSession(uint16_t SessionId)
{
dbgprotocol("CloseSession %08X\n", SessionId);
dbgprotocol("CloseSession %d\n", SessionId);
cCiSession *Session = GetSessionBySessionId(SessionId);
if (Session && sessions[SessionId - 1] == Session) {
delete Session;
@ -1675,7 +1675,7 @@ bool cCiHandler::Process(int Slot)
if (Data && Length > 1) {
switch (*Data) {
case ST_SESSION_NUMBER: if (Length > 4) {
int SessionId = ntohs(get_unaligned((uint16_t *)&Data[2]));
uint16_t SessionId = ntohs(get_unaligned((uint16_t *)&Data[2]));
cCiSession *Session = GetSessionBySessionId(SessionId);
if (Session)
Session->Process(Length - 4, Data + 4);

14
ci.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: ci.h 1.21 2006/01/07 15:03:05 kls Exp $
* $Id: ci.h 1.22 2006/08/12 09:43:31 kls Exp $
*/
#ifndef __CI_H
@ -110,14 +110,14 @@ private:
int source;
int transponder;
cList<cCiCaProgramData> caProgramList;
int ResourceIdToInt(const uint8_t *Data);
bool Send(uint8_t Tag, int SessionId, int ResourceId = 0, int Status = -1);
uint32_t ResourceIdToInt(const uint8_t *Data);
bool Send(uint8_t Tag, uint16_t SessionId, uint32_t ResourceId = 0, int Status = -1);
const unsigned short *GetCaSystemIds(int Slot);
cCiSession *GetSessionBySessionId(int SessionId);
cCiSession *GetSessionByResourceId(int ResourceId, int Slot);
cCiSession *CreateSession(int ResourceId);
cCiSession *GetSessionBySessionId(uint16_t SessionId);
cCiSession *GetSessionByResourceId(uint32_t ResourceId, int Slot);
cCiSession *CreateSession(uint32_t ResourceId);
bool OpenSession(int Length, const uint8_t *Data);
bool CloseSession(int SessionId);
bool CloseSession(uint16_t SessionId);
int CloseAllSessions(int Slot);
cCiHandler(int Fd, int NumSlots);
void SendCaPmt(void);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.h 1.264 2006/07/29 09:56:04 kls Exp $
* $Id: config.h 1.265 2006/08/12 09:10:11 kls Exp $
*/
#ifndef __CONFIG_H
@ -21,7 +21,7 @@
// VDR's own version number:
#define VDRVERSION "1.4.1-3"
#define VDRVERSION "1.4.1-4"
#define VDRVERSNUM 10401 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number:

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.c 1.134 2006/07/29 10:03:56 kls Exp $
* $Id: device.c 1.135 2006/08/12 11:33:34 kls Exp $
*/
#include "device.h"
@ -294,11 +294,11 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool *NeedsDe
uint imp = 0;
imp <<= 1; imp |= !device[i]->Receiving(true) || ndr; // use receiving devices if we don't need to detach existing receivers
imp <<= 1; imp |= device[i]->Receiving(); // avoid devices that are receiving
imp <<= 1; imp |= device[i] == ActualDevice(); // avoid the actual device (in case of Transfer Mode)
imp <<= 1; imp |= device[i]->IsPrimaryDevice(); // avoid the primary device
imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards
imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device
imp <<= 8; imp |= min(max(device[i]->Priority() + MAXPRIORITY, 0), 0xFF); // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used)
imp <<= 8; imp |= min(max(device[i]->ProvidesCa(Channel), 0), 0xFF); // use the device that provides the lowest number of conditional access methods
imp <<= 1; imp |= device[i]->IsPrimaryDevice(); // avoid the primary device
imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards
if (imp < Impact) {
// This device has less impact than any previous one, so we take it.
Impact = imp;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: plugin.c 1.22 2006/04/17 09:20:05 kls Exp $
* $Id: plugin.c 1.23 2006/08/13 08:51:44 kls Exp $
*/
#include "plugin.h"
@ -15,6 +15,7 @@
#include <time.h>
#include "config.h"
#include "interface.h"
#include "thread.h"
#define LIBVDR_PREFIX "libvdr-"
#define SO_INDICATOR ".so."
@ -137,6 +138,8 @@ void cPlugin::SetConfigDirectory(const char *Dir)
const char *cPlugin::ConfigDirectory(const char *PluginName)
{
static char *buffer = NULL;
if (!cThread::IsMainThread())
esyslog("ERROR: plugin '%s' called cPlugin::ConfigDirectory(), which is not thread safe!", PluginName ? PluginName : "<no name given>");
free(buffer);
asprintf(&buffer, "%s/plugins%s%s", configDirectory, PluginName ? "/" : "", PluginName ? PluginName : "");
return MakeDirs(buffer, true) ? buffer : NULL;

View File

@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
* $Id: svdrp.c 1.99 2006/08/06 09:17:58 kls Exp $
* $Id: svdrp.c 1.100 2006/08/12 09:09:55 kls Exp $
*/
#include "svdrp.h"
@ -120,7 +120,7 @@ int cSocket::Accept(void)
close(newsock);
newsock = -1;
}
isyslog("connect from %s, port %hd - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED");
isyslog("connect from %s, port %hu - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED");
}
else if (errno != EINTR && errno != EAGAIN)
LOG_ERROR;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.c 1.119 2006/06/17 09:45:32 kls Exp $
* $Id: tools.c 1.120 2006/08/12 13:30:07 kls Exp $
*/
#include "tools.h"
@ -422,8 +422,7 @@ bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis)
}
else {
LOG_ERROR_STR(buffer);
free(buffer);
return false;
empty = false;
}
free(buffer);
}