everything else
[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::answerMMI(int slotid, int answer, char *value)
107 {
108         eDVBCISlot *slot;
109
110         if( (slot = getSlot(slotid)) == 0 )
111                 return -1;
112         
113         return slot->answerMMI(answer, value);
114 }
115
116 int eDVBCISlot::send(const unsigned char *data, size_t len)
117 {
118         int res;
119         //int i;
120         //printf("< ");
121         //for(i=0;i<len;i++)
122         //      printf("%02x ",data[i]);
123         //printf("\n");
124
125         res = ::write(fd, data, len);
126
127         //printf("write() %d\n",res);
128
129         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority | eSocketNotifier::Write);
130
131         return res;
132 }
133
134 void eDVBCISlot::data(int what)
135 {
136         if(what == eSocketNotifier::Priority) {
137                 if(state != stateRemoved) {
138                         state = stateRemoved;
139                         printf("ci removed\n");
140                         notifier->setRequested(eSocketNotifier::Read);
141                         //HACK
142                         eDVBCI_UI::getInstance()->setState(0,0);
143                         //FIXME; do in deconstructor of the appmgr class                        
144                         application_manager = 0;
145                         mmi_session = 0;
146                 }
147                 return;
148         }
149
150         __u8 data[4096];
151         int r;
152         r = ::read(fd, data, 4096);
153
154         if(state != stateInserted) {
155                 state = stateInserted;
156                 eDebug("ci inserted");
157
158                 //HACK
159                 eDVBCI_UI::getInstance()->setState(0,1);
160
161                 /* enable PRI to detect removal or errors */
162                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
163         }
164
165         if(r > 0) {
166                 //int i;
167                 //printf("> ");
168                 //for(i=0;i<r;i++)
169                 //      printf("%02x ",data[i]);
170                 //printf("\n");
171                 eDVBCISession::receiveData(this, data, r);
172                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
173                 return;
174         }
175
176         if(what == eSocketNotifier::Write) {
177                 if(eDVBCISession::pollAll() == 0) {
178                         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority);
179                 }
180         }
181 }
182
183 DEFINE_REF(eDVBCISlot);
184
185 eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
186 {
187         char filename[128];
188         
189         application_manager = 0;
190         mmi_session = 0;
191
192         slotid = nr;
193
194         sprintf(filename, "/dev/ci%d", nr);
195
196         fd = ::open(filename, O_RDWR | O_NONBLOCK);
197
198         eDebug("eDVBCISlot has fd %d", fd);
199         
200         state = stateInserted;
201
202         if (fd >= 0)
203         {
204                 notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Priority);
205                 CONNECT(notifier->activated, eDVBCISlot::data);
206         } else
207         {
208                 perror(filename);
209         }
210 }
211
212 eDVBCISlot::~eDVBCISlot()
213 {
214 }
215
216 int eDVBCISlot::getSlotID()
217 {
218         return slotid;
219 }
220
221 int eDVBCISlot::reset()
222 {
223         printf("edvbcislot: reset requested\n");
224
225         ioctl(fd, 0);
226
227         return 0;
228 }
229
230 int eDVBCISlot::initialize()
231 {
232         printf("edvbcislot: initialize()\n");
233         return 0;
234 }
235
236 int eDVBCISlot::startMMI()
237 {
238         printf("edvbcislot: startMMI()\n");
239         
240         if(application_manager)
241                 application_manager->startMMI();
242         
243         return 0;
244 }
245
246 int eDVBCISlot::stopMMI()
247 {
248         printf("edvbcislot: stopMMI()\n");
249
250         if(mmi_session)
251                 mmi_session->stopMMI();
252         
253         return 0;
254 }
255
256 int eDVBCISlot::answerMMI(int answer, char *value)
257 {
258         printf("edvbcislot: answerMMI()\n");
259         return 0;
260 }
261
262 eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");