cf7acde6130bafb186ed9be3efd0567ebb776196
[enigma2.git] / lib / dvb_ci / dvbci.cpp
1 #include <fcntl.h>
2 #include <sys/ioctl.h>
3
4 #include <lib/base/init.h>
5 #include <lib/base/init_num.h>
6 #include <lib/base/ebase.h>
7
8 #include <lib/base/eerror.h>
9 #include <lib/dvb_ci/dvbci.h>
10 #include <lib/dvb_ci/dvbci_session.h>
11
12 #include <lib/dvb_ci/dvbci_ui.h>
13 #include <lib/dvb_ci/dvbci_appmgr.h>
14 #include <lib/dvb_ci/dvbci_mmi.h>
15
16 eDVBCIInterfaces *eDVBCIInterfaces::instance = 0;
17
18 eDVBCIInterfaces::eDVBCIInterfaces()
19 {
20         int num_ci = 0;
21         
22         instance = this;
23         
24         eDebug("scanning for common interfaces..");
25
26         while (1)
27         {
28                 struct stat s;
29                 char filename[128];
30                 sprintf(filename, "/dev/ci%d", num_ci);
31
32                 if (stat(filename, &s))
33                         break;
34
35                 ePtr<eDVBCISlot> cislot;
36
37                 cislot = new eDVBCISlot(eApp, num_ci);
38                 m_slots.push_back(cislot);
39
40                 ++num_ci;
41         }
42
43         eDebug("done, found %d common interface slots", num_ci);
44 }
45
46 eDVBCIInterfaces::~eDVBCIInterfaces()
47 {
48 }
49
50 eDVBCIInterfaces *eDVBCIInterfaces::getInstance()
51 {
52         return instance;
53 }
54
55 eDVBCISlot *eDVBCIInterfaces::getSlot(int slotid)
56 {
57         for(eSmartPtrList<eDVBCISlot>::iterator i(m_slots.begin()); i != m_slots.end(); ++i)
58                 if(i->getSlotID() == slotid)
59                         return i;
60
61         printf("FIXME: request for unknown slot\n");
62                         
63         return 0;
64 }
65
66 int eDVBCIInterfaces::reset(int slotid)
67 {
68         eDVBCISlot *slot;
69
70         if( (slot = getSlot(slotid)) == 0 )
71                 return -1;
72         
73         return slot->reset();
74 }
75
76 int eDVBCIInterfaces::initialize(int slotid)
77 {
78         eDVBCISlot *slot;
79
80         if( (slot = getSlot(slotid)) == 0 )
81                 return -1;
82         
83         return slot->initialize();
84 }
85
86 int eDVBCIInterfaces::startMMI(int slotid)
87 {
88         eDVBCISlot *slot;
89
90         if( (slot = getSlot(slotid)) == 0 )
91                 return -1;
92         
93         return slot->startMMI();
94 }
95
96 int eDVBCIInterfaces::stopMMI(int slotid)
97 {
98         eDVBCISlot *slot;
99
100         if( (slot = getSlot(slotid)) == 0 )
101                 return -1;
102         
103         return slot->stopMMI();
104 }
105
106 int eDVBCIInterfaces::answerText(int slotid, int answer)
107 {
108         eDVBCISlot *slot;
109
110         if( (slot = getSlot(slotid)) == 0 )
111                 return -1;
112         
113         return slot->answerText(answer);
114 }
115
116 int eDVBCIInterfaces::answerEnq(int slotid, int answer, char *value)
117 {
118         eDVBCISlot *slot;
119
120         if( (slot = getSlot(slotid)) == 0 )
121                 return -1;
122         
123         return slot->answerEnq(answer, value);
124 }
125
126 int eDVBCISlot::send(const unsigned char *data, size_t len)
127 {
128         int res;
129         //int i;
130         //printf("< ");
131         //for(i=0;i<len;i++)
132         //      printf("%02x ",data[i]);
133         //printf("\n");
134
135         res = ::write(fd, data, len);
136
137         //printf("write() %d\n",res);
138
139         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority | eSocketNotifier::Write);
140
141         return res;
142 }
143
144 void eDVBCISlot::data(int what)
145 {
146         if(what == eSocketNotifier::Priority) {
147                 if(state != stateRemoved) {
148                         state = stateRemoved;
149                         printf("ci removed\n");
150                         notifier->setRequested(eSocketNotifier::Read);
151                         //HACK
152                         eDVBCI_UI::getInstance()->setState(0,0);
153                 }
154                 return;
155         }
156
157         __u8 data[4096];
158         int r;
159         r = ::read(fd, data, 4096);
160
161         if(state != stateInserted) {
162                 state = stateInserted;
163                 eDebug("ci inserted");
164
165                 //HACK
166                 eDVBCI_UI::getInstance()->setState(0,1);
167
168                 /* enable PRI to detect removal or errors */
169                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
170         }
171
172         if(r > 0) {
173                 //int i;
174                 //printf("> ");
175                 //for(i=0;i<r;i++)
176                 //      printf("%02x ",data[i]);
177                 //printf("\n");
178                 eDVBCISession::receiveData(this, data, r);
179                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
180                 return;
181         }
182
183         if(what == eSocketNotifier::Write) {
184                 if(eDVBCISession::pollAll() == 0) {
185                         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority);
186                 }
187         }
188 }
189
190 DEFINE_REF(eDVBCISlot);
191
192 eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
193 {
194         char filename[128];
195
196         application_manager = 0;
197         mmi_session = 0;
198         
199         slotid = nr;
200
201         sprintf(filename, "/dev/ci%d", nr);
202
203         fd = ::open(filename, O_RDWR | O_NONBLOCK);
204
205         eDebug("eDVBCISlot has fd %d", fd);
206         
207         state = stateInserted;
208
209         if (fd >= 0)
210         {
211                 notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Priority);
212                 CONNECT(notifier->activated, eDVBCISlot::data);
213         } else
214         {
215                 perror(filename);
216         }
217 }
218
219 eDVBCISlot::~eDVBCISlot()
220 {
221 }
222
223 int eDVBCISlot::getSlotID()
224 {
225         return slotid;
226 }
227
228 int eDVBCISlot::reset()
229 {
230         printf("edvbcislot: reset requested\n");
231
232         ioctl(fd, 0);
233
234         return 0;
235 }
236
237 int eDVBCISlot::initialize()
238 {
239         printf("edvbcislot: initialize()\n");
240         return 0;
241 }
242
243 int eDVBCISlot::startMMI()
244 {
245         printf("edvbcislot: startMMI()\n");
246         
247         if(application_manager)
248                 application_manager->startMMI();
249         
250         return 0;
251 }
252
253 int eDVBCISlot::stopMMI()
254 {
255         printf("edvbcislot: stopMMI()\n");
256
257         if(mmi_session)
258                 mmi_session->stopMMI();
259         
260         return 0;
261 }
262
263 int eDVBCISlot::answerText(int answer)
264 {
265         printf("edvbcislot: answerText(%d)\n", answer);
266
267         if(mmi_session)
268                 mmi_session->answerText(answer);
269
270         return 0;
271 }
272
273 int eDVBCISlot::answerEnq(int answer, char *value)
274 {
275         printf("edvbcislot: answerMMI(%d,%s)\n", answer, value);
276         return 0;
277 }
278
279 eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");