e6e3237d50e418a4b57d5411a8d644e447b95ba0
[enigma2.git] / lib / dvb_ci / dvbci.cpp
1 #include <fcntl.h>
2
3 #include <lib/base/init.h>
4 #include <lib/base/init_num.h>
5
6 #include <lib/base/eerror.h>
7 #include <lib/dvb_ci/dvbci.h>
8 #include <lib/dvb_ci/dvbci_session.h>
9
10 eDVBCIInterfaces::eDVBCIInterfaces()
11 {
12         int num_ci = 0;
13
14         eDebug("scanning for common interfaces..");
15
16         while (1)
17         {
18                 struct stat s;
19                 char filename[128];
20                 sprintf(filename, "/dev/ci%d", num_ci);
21
22                 if (stat(filename, &s))
23                         break;
24
25                 ePtr<eDVBCISlot> cislot;
26
27                 cislot = new eDVBCISlot(eApp, num_ci);
28                 m_slots.push_back(cislot);
29
30                 ++num_ci;
31         }
32
33         eDebug("done, found %d common interface slots");
34 }
35
36 eDVBCIInterfaces::~eDVBCIInterfaces()
37 {
38 }
39
40 int eDVBCISlot::send(const unsigned char *data, size_t len)
41 {
42         int res;
43         //int i;
44         //printf("< ");
45         //for(i=0;i<len;i++)
46         //      printf("%02x ",data[i]);
47         //printf("\n");
48
49         res = ::write(fd, data, len);
50
51         //printf("write() %d\n",res);
52
53         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority | eSocketNotifier::Write);
54
55         return res;
56 }
57
58 void eDVBCISlot::data(int what)
59 {
60         if(what == eSocketNotifier::Priority) {
61                 if(state != stateRemoved) {
62                         state = stateRemoved;
63                         printf("ci removed\n");
64                         notifier->setRequested(eSocketNotifier::Read);
65                 }
66                 return;
67         }
68
69
70         __u8 data[4096];
71         int r;
72         r = ::read(fd, data, 4096);
73
74         if(state != stateInserted) {
75                 state = stateInserted;
76                 eDebug("ci inserted");
77                 /* enable PRI to detect removal or errors */
78                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
79         }
80
81         if(r > 0) {
82                 //int i;
83                 //printf("> ");
84                 //for(i=0;i<r;i++)
85                 //      printf("%02x ",data[i]);
86                 //printf("\n");
87                 eDVBCISession::receiveData(this, data, r);
88                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
89                 return;
90         }
91
92         if(what == eSocketNotifier::Write) {
93                 if(eDVBCISession::pollAll() == 0) {
94                         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority);
95                 }
96         }
97 }
98
99 DEFINE_REF(eDVBCISlot);
100
101 eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
102 {
103         char filename[128];
104
105         sprintf(filename, "/dev/ci%d", nr);
106
107         fd = ::open(filename, O_RDWR | O_NONBLOCK);
108
109         eDebug("eDVBCISlot has fd %d", fd);
110
111         if (fd >= 0)
112         {
113                 notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Priority);
114                 CONNECT(notifier->activated, eDVBCISlot::data);
115         } else
116         {
117                 perror(filename);
118         }
119 }
120
121 eDVBCISlot::~eDVBCISlot()
122 {
123 }
124
125 eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");