vdr  2.2.0
dvbci.c
Go to the documentation of this file.
1 /*
2  * dvbci.h: Common Interface for DVB devices
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: dvbci.c 3.1 2015/01/14 11:13:49 kls Exp $
8  */
9 
10 #include "dvbci.h"
11 #include <linux/dvb/ca.h>
12 #include <sys/ioctl.h>
13 #include "dvbdevice.h"
14 
15 // --- cDvbCiAdapter ---------------------------------------------------------
16 
17 cDvbCiAdapter::cDvbCiAdapter(cDevice *Device, int Fd, int Adapter, int Frontend)
18 {
19  device = Device;
20  SetDescription("device %d CI adapter", device->DeviceNumber());
21  fd = Fd;
22  adapter = Adapter;
23  frontend = Frontend;
24  idle = false;
25  ca_caps_t Caps;
26  if (ioctl(fd, CA_GET_CAP, &Caps) == 0) {
27  if ((Caps.slot_type & CA_CI_LINK) != 0) {
28  int NumSlots = Caps.slot_num;
29  if (NumSlots > 0) {
30  for (int i = 0; i < NumSlots; i++)
31  new cCamSlot(this);
32  Start();
33  }
34  else
35  esyslog("ERROR: no CAM slots found on device %d", device->DeviceNumber());
36  }
37  else
38  isyslog("device %d doesn't support CI link layer interface", device->DeviceNumber());
39  }
40  else
41  esyslog("ERROR: can't get CA capabilities on device %d", device->DeviceNumber());
42 }
43 
45 {
46  Cancel(3);
48  CloseCa();
49 }
50 
52 {
53  if (fd >= 0)
54  return true;
56  return (fd >= 0);
57 }
58 
60 {
61  if (fd < 0)
62  return;
63  close(fd);
64  fd = -1;
65 }
66 
67 bool cDvbCiAdapter::SetIdle(bool Idle, bool TestOnly)
68 {
69  if ((adapter < 0) || (frontend < 0))
70  return false;
71  if (TestOnly || (idle == Idle))
72  return true;
73  if (Idle)
74  CloseCa();
75  else
76  OpenCa();
77  idle = Idle;
78  return true;
79 }
80 
81 int cDvbCiAdapter::Read(uint8_t *Buffer, int MaxLength)
82 {
83  if (idle || (fd < 0))
84  return 0;
85  if (Buffer && MaxLength > 0) {
86  struct pollfd pfd[1];
87  pfd[0].fd = fd;
88  pfd[0].events = POLLIN;
89  if (poll(pfd, 1, CAM_READ_TIMEOUT) > 0 && (pfd[0].revents & POLLIN)) {
90  int n = safe_read(fd, Buffer, MaxLength);
91  if (n >= 0)
92  return n;
93  esyslog("ERROR: can't read from CI adapter on device %d: %m", device->DeviceNumber());
94  }
95  }
96  return 0;
97 }
98 
99 void cDvbCiAdapter::Write(const uint8_t *Buffer, int Length)
100 {
101  if (idle || (fd < 0))
102  return;
103  if (Buffer && Length > 0) {
104  if (safe_write(fd, Buffer, Length) != Length)
105  esyslog("ERROR: can't write to CI adapter on device %d: %m", device->DeviceNumber());
106  }
107 }
108 
109 bool cDvbCiAdapter::Reset(int Slot)
110 {
111  if (idle || (fd < 0))
112  return false;
113  if (ioctl(fd, CA_RESET, 1 << Slot) != -1)
114  return true;
115  else
116  esyslog("ERROR: can't reset CAM slot %d on device %d: %m", Slot, device->DeviceNumber());
117  return false;
118 }
119 
121 {
122  if (idle || (fd < 0))
123  return msNone;
124  ca_slot_info_t sinfo;
125  sinfo.num = Slot;
126  if (ioctl(fd, CA_GET_SLOT_INFO, &sinfo) != -1) {
127  if ((sinfo.flags & CA_CI_MODULE_READY) != 0)
128  return msReady;
129  else if ((sinfo.flags & CA_CI_MODULE_PRESENT) != 0)
130  return msPresent;
131  }
132  else
133  esyslog("ERROR: can't get info of CAM slot %d on device %d: %m", Slot, device->DeviceNumber());
134  return msNone;
135 }
136 
137 bool cDvbCiAdapter::Assign(cDevice *Device, bool Query)
138 {
139  // The CI is hardwired to its device, so there's not really much to do here
140  if (Device)
141  return Device == device;
142  return true;
143 }
144 
145 cDvbCiAdapter *cDvbCiAdapter::CreateCiAdapter(cDevice *Device, int Fd, int Adapter, int Frontend)
146 {
147  // TODO check whether a CI is actually present?
148  if (Device)
149  return new cDvbCiAdapter(Device, Fd, Adapter, Frontend);
150  return NULL;
151 }
Definition: ci.h:77
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
Definition: device.c:197
void SetDescription(const char *Description,...) __attribute__((format(printf
Definition: thread.c:236
virtual bool Reset(int Slot)
Resets the CAM in the given Slot.
Definition: dvbci.c:109
virtual void Write(const uint8_t *Buffer, int Length)
Writes Length bytes of the given Buffer.
Definition: dvbci.c:99
#define esyslog(a...)
Definition: tools.h:34
void CloseCa(void)
Definition: dvbci.c:59
Definition: ci.h:77
cDvbCiAdapter(cDevice *Device, int Fd, int Adapter=-1, int Frontend=-1)
Definition: dvbci.c:17
cDevice * device
Definition: dvbci.h:17
int adapter
Definition: dvbci.h:19
virtual bool SetIdle(bool Idle, bool TestOnly)
Definition: dvbci.c:67
ssize_t safe_write(int filedes, const void *buffer, size_t size)
Definition: tools.c:65
bool idle
Definition: dvbci.h:21
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
Definition: thread.c:273
#define DEV_DVB_CA
Definition: dvbdevice.h:81
#define CAM_READ_TIMEOUT
Definition: ci.h:21
bool HasSubDevice(void) const
Definition: device.h:837
static cDvbCiAdapter * CreateCiAdapter(cDevice *Device, int Fd, int Adapter=-1, int Frontend=-1)
Definition: dvbci.c:145
bool OpenCa(void)
Definition: dvbci.c:51
friend class cCamSlot
Definition: ci.h:80
int fd
Definition: dvbci.h:18
virtual bool Assign(cDevice *Device, bool Query=false)
Assigns this adapter to the given Device, if this is possible.
Definition: dvbci.c:137
virtual int Read(uint8_t *Buffer, int MaxLength)
Reads one chunk of data into the given Buffer, up to MaxLength bytes.
Definition: dvbci.c:81
bool IsSubDevice(void) const
Definition: device.h:836
#define isyslog(a...)
Definition: tools.h:35
virtual ~cDvbCiAdapter()
Definition: dvbci.c:44
ssize_t safe_read(int filedes, void *buffer, size_t size)
Definition: tools.c:53
virtual eModuleStatus ModuleStatus(int Slot)
Returns the status of the CAM in the given Slot.
Definition: dvbci.c:120
eModuleStatus
Definition: ci.h:77
Definition: ci.h:77
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
Definition: thread.c:323
The cDevice class is the base from which actual devices can be derived.
Definition: device.h:109
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError=false)
Definition: dvbdevice.c:1195
int frontend
Definition: dvbci.h:20