add some stuff
[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
14 eDVBCIInterfaces *eDVBCIInterfaces::instance = 0;
15
16 eDVBCIInterfaces::eDVBCIInterfaces()
17 {
18         int num_ci = 0;
19         
20         instance = this;
21         
22         eDebug("scanning for common interfaces..");
23
24         while (1)
25         {
26                 struct stat s;
27                 char filename[128];
28                 sprintf(filename, "/dev/ci%d", num_ci);
29
30                 if (stat(filename, &s))
31                         break;
32
33                 ePtr<eDVBCISlot> cislot;
34
35                 cislot = new eDVBCISlot(eApp, num_ci);
36                 m_slots.push_back(cislot);
37
38                 ++num_ci;
39         }
40
41         eDebug("done, found %d common interface slots", num_ci);
42 }
43
44 eDVBCIInterfaces::~eDVBCIInterfaces()
45 {
46 }
47
48 eDVBCIInterfaces *eDVBCIInterfaces::getInstance()
49 {
50         return instance;
51 }
52
53 eDVBCISlot *eDVBCIInterfaces::getSlot(int slotid)
54 {
55         for(eSmartPtrList<eDVBCISlot>::iterator i(m_slots.begin()); i != m_slots.end(); ++i)
56                 if(i->getSlotID() == slotid)
57                         return i;
58
59         printf("FIXME: request for unknown slot\n");
60                         
61         return 0;
62 }
63
64 int eDVBCIInterfaces::reset(int slotid)
65 {
66         eDVBCISlot *slot;
67
68         if( (slot = getSlot(slotid)) == 0 )
69                 return -1;
70         
71         return slot->reset();
72 }
73
74 int eDVBCIInterfaces::initialize(int slotid)
75 {
76         eDVBCISlot *slot;
77
78         if( (slot = getSlot(slotid)) == 0 )
79                 return -1;
80         
81         return slot->initialize();
82 }
83
84 int eDVBCIInterfaces::startMMI(int slotid)
85 {
86         eDVBCISlot *slot;
87
88         if( (slot = getSlot(slotid)) == 0 )
89                 return -1;
90         
91         return slot->startMMI();
92 }
93
94 int eDVBCIInterfaces::answerMMI(int slotid, int answer, char *value)
95 {
96         eDVBCISlot *slot;
97
98         if( (slot = getSlot(slotid)) == 0 )
99                 return -1;
100         
101         return slot->answerMMI(answer, value);
102 }
103
104 int eDVBCISlot::send(const unsigned char *data, size_t len)
105 {
106         int res;
107         //int i;
108         //printf("< ");
109         //for(i=0;i<len;i++)
110         //      printf("%02x ",data[i]);
111         //printf("\n");
112
113         res = ::write(fd, data, len);
114
115         //printf("write() %d\n",res);
116
117         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority | eSocketNotifier::Write);
118
119         return res;
120 }
121
122 void eDVBCISlot::data(int what)
123 {
124         if(what == eSocketNotifier::Priority) {
125                 if(state != stateRemoved) {
126                         state = stateRemoved;
127                         printf("ci removed\n");
128                         notifier->setRequested(eSocketNotifier::Read);
129                         //HACK
130                         eDVBCI_UI::getInstance()->setState(0,0);
131                 }
132                 return;
133         }
134
135         __u8 data[4096];
136         int r;
137         r = ::read(fd, data, 4096);
138
139         if(state != stateInserted) {
140                 state = stateInserted;
141                 eDebug("ci inserted");
142
143                 //HACK
144                 eDVBCI_UI::getInstance()->setState(0,1);
145
146                 /* enable PRI to detect removal or errors */
147                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
148         }
149
150         if(r > 0) {
151                 //int i;
152                 //printf("> ");
153                 //for(i=0;i<r;i++)
154                 //      printf("%02x ",data[i]);
155                 //printf("\n");
156                 eDVBCISession::receiveData(this, data, r);
157                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
158                 return;
159         }
160
161         if(what == eSocketNotifier::Write) {
162                 if(eDVBCISession::pollAll() == 0) {
163                         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority);
164                 }
165         }
166 }
167
168 DEFINE_REF(eDVBCISlot);
169
170 eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
171 {
172         char filename[128];
173
174         slotid = nr;
175
176         sprintf(filename, "/dev/ci%d", nr);
177
178         fd = ::open(filename, O_RDWR | O_NONBLOCK);
179
180         eDebug("eDVBCISlot has fd %d", fd);
181         
182         state = stateInserted;
183
184         if (fd >= 0)
185         {
186                 notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Priority);
187                 CONNECT(notifier->activated, eDVBCISlot::data);
188         } else
189         {
190                 perror(filename);
191         }
192 }
193
194 eDVBCISlot::~eDVBCISlot()
195 {
196 }
197
198 int eDVBCISlot::getSlotID()
199 {
200         return slotid;
201 }
202
203 int eDVBCISlot::reset()
204 {
205         printf("edvbcislot: reset requested\n");
206
207         ioctl(fd, 0);
208
209         return 0;
210 }
211
212 int eDVBCISlot::initialize()
213 {
214         printf("edvbcislot: initialize()\n");
215         return 0;
216 }
217
218 int eDVBCISlot::startMMI()
219 {
220         printf("edvbcislot: startMMI()\n");
221         return 0;
222 }
223
224 int eDVBCISlot::answerMMI(int answer, char *value)
225 {
226         printf("edvbcislot: answerMMI()\n");
227         return 0;
228 }
229
230 eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");