app-manager takes care of its own instancepointer in slot
[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                 }
144                 return;
145         }
146
147         __u8 data[4096];
148         int r;
149         r = ::read(fd, data, 4096);
150
151         if(state != stateInserted) {
152                 state = stateInserted;
153                 eDebug("ci inserted");
154
155                 //HACK
156                 eDVBCI_UI::getInstance()->setState(0,1);
157
158                 /* enable PRI to detect removal or errors */
159                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
160         }
161
162         if(r > 0) {
163                 //int i;
164                 //printf("> ");
165                 //for(i=0;i<r;i++)
166                 //      printf("%02x ",data[i]);
167                 //printf("\n");
168                 eDVBCISession::receiveData(this, data, r);
169                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
170                 return;
171         }
172
173         if(what == eSocketNotifier::Write) {
174                 if(eDVBCISession::pollAll() == 0) {
175                         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority);
176                 }
177         }
178 }
179
180 DEFINE_REF(eDVBCISlot);
181
182 eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
183 {
184         char filename[128];
185
186         application_manager = 0;
187         mmi_session = 0;
188         
189         slotid = nr;
190
191         sprintf(filename, "/dev/ci%d", nr);
192
193         fd = ::open(filename, O_RDWR | O_NONBLOCK);
194
195         eDebug("eDVBCISlot has fd %d", fd);
196         
197         state = stateInserted;
198
199         if (fd >= 0)
200         {
201                 notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Priority);
202                 CONNECT(notifier->activated, eDVBCISlot::data);
203         } else
204         {
205                 perror(filename);
206         }
207 }
208
209 eDVBCISlot::~eDVBCISlot()
210 {
211 }
212
213 int eDVBCISlot::getSlotID()
214 {
215         return slotid;
216 }
217
218 int eDVBCISlot::reset()
219 {
220         printf("edvbcislot: reset requested\n");
221
222         ioctl(fd, 0);
223
224         return 0;
225 }
226
227 int eDVBCISlot::initialize()
228 {
229         printf("edvbcislot: initialize()\n");
230         return 0;
231 }
232
233 int eDVBCISlot::startMMI()
234 {
235         printf("edvbcislot: startMMI()\n");
236         
237         if(application_manager)
238                 application_manager->startMMI();
239         
240         return 0;
241 }
242
243 int eDVBCISlot::stopMMI()
244 {
245         printf("edvbcislot: stopMMI()\n");
246
247         if(mmi_session)
248                 mmi_session->stopMMI();
249         
250         return 0;
251 }
252
253 int eDVBCISlot::answerMMI(int answer, char *value)
254 {
255         printf("edvbcislot: answerMMI()\n");
256         return 0;
257 }
258
259 eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");