cb53334256d2d8dd99894df017ae97b12be5830d
[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 interfaces");
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         
45         printf("< ");
46         for(i=0;i<len;i++)
47                 printf("%02x ",data[i]);
48         printf("\n");
49
50         res = ::write(fd, data, len);
51
52         printf("write() %d\n",res);
53
54         notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Hungup|eSocketNotifier::Write);
55
56         return res;
57 }
58
59 void eDVBCISlot::data(int what)
60 {
61         if(what == eSocketNotifier::Hungup) {
62                 if(state != stateRemoved) {
63                         state = stateRemoved;
64                         printf("ci removed\n");
65                         notifier->setRequested(eSocketNotifier::Read);
66                 }
67                 return;
68         }
69
70
71         __u8 data[4096];
72         int r;
73         r = ::read(fd, data, 4096);
74         //if(r < 0)
75         //      eWarning("ERROR reading from CI - %m\n");
76
77         if(state != stateInserted) {
78                 state = stateInserted;
79                 eDebug("ci inserted");
80
81                 /* enable HUP to detect removal or errors */
82                 //notifier_event->start();
83                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Hungup|eSocketNotifier::Write);
84         }
85
86         if(r > 0) {
87                 int i;
88                 printf("> ");
89                 for(i=0;i<r;i++)
90                         printf("%02x ",data[i]);
91                 printf("\n");
92                 //eDebug("ci talks to us");
93                 eDVBCISession::receiveData(this, data, r);
94                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Hungup|eSocketNotifier::Write);
95                 return;
96         }
97
98         if(what == eSocketNotifier::Write) {
99                 printf("pollall\n");
100                 if(eDVBCISession::pollAll() == 0) {
101                         printf("disable pollout\n");
102                         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Hungup);
103                 }
104                 return;
105         }
106 }
107
108 DEFINE_REF(eDVBCISlot);
109
110 eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
111 {
112         char filename[128];
113
114         sprintf(filename, "/dev/ci%d", nr);
115
116         fd = ::open(filename, O_RDWR | O_NONBLOCK);
117
118         eDebug("eDVBCISlot has fd %d", fd);
119
120         if (fd >= 0)
121         {
122                 notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Hungup);
123                 CONNECT(notifier->activated, eDVBCISlot::data);
124         } else
125         {
126                 perror(filename);
127         }
128 }
129
130 eDVBCISlot::~eDVBCISlot()
131 {
132 }
133
134 eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");