74fa66c794afc8eb879f1c90625d611ee09f0435
[vuplus_dvbapp] / 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::startMMI(int slotid)
75 {
76         eDVBCISlot *slot;
77
78         if( (slot = getSlot(slotid)) == 0 )
79                 return -1;
80         
81         return slot->startMMI();
82 }
83
84 int eDVBCISlot::send(const unsigned char *data, size_t len)
85 {
86         int res;
87         //int i;
88         //printf("< ");
89         //for(i=0;i<len;i++)
90         //      printf("%02x ",data[i]);
91         //printf("\n");
92
93         res = ::write(fd, data, len);
94
95         //printf("write() %d\n",res);
96
97         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority | eSocketNotifier::Write);
98
99         return res;
100 }
101
102 void eDVBCISlot::data(int what)
103 {
104         if(what == eSocketNotifier::Priority) {
105                 if(state != stateRemoved) {
106                         state = stateRemoved;
107                         printf("ci removed\n");
108                         notifier->setRequested(eSocketNotifier::Read);
109                         //HACK
110                         eDVBCI_UI::getInstance()->setState(0,0);
111                 }
112                 return;
113         }
114
115         __u8 data[4096];
116         int r;
117         r = ::read(fd, data, 4096);
118
119         if(state != stateInserted) {
120                 state = stateInserted;
121                 eDebug("ci inserted");
122
123                 //HACK
124                 eDVBCI_UI::getInstance()->setState(0,1);
125
126                 /* enable PRI to detect removal or errors */
127                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
128         }
129
130         if(r > 0) {
131                 //int i;
132                 //printf("> ");
133                 //for(i=0;i<r;i++)
134                 //      printf("%02x ",data[i]);
135                 //printf("\n");
136                 eDVBCISession::receiveData(this, data, r);
137                 notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
138                 return;
139         }
140
141         if(what == eSocketNotifier::Write) {
142                 if(eDVBCISession::pollAll() == 0) {
143                         notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority);
144                 }
145         }
146 }
147
148 DEFINE_REF(eDVBCISlot);
149
150 eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
151 {
152         char filename[128];
153
154         slotid = nr;
155
156         sprintf(filename, "/dev/ci%d", nr);
157
158         fd = ::open(filename, O_RDWR | O_NONBLOCK);
159
160         eDebug("eDVBCISlot has fd %d", fd);
161         
162         state = stateInserted;
163
164         if (fd >= 0)
165         {
166                 notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Priority);
167                 CONNECT(notifier->activated, eDVBCISlot::data);
168         } else
169         {
170                 perror(filename);
171         }
172 }
173
174 eDVBCISlot::~eDVBCISlot()
175 {
176 }
177
178 int eDVBCISlot::getSlotID()
179 {
180         return slotid;
181 }
182
183 int eDVBCISlot::reset()
184 {
185         printf("edvbcislot: reset requested\n");
186
187         ioctl(fd, 0);
188
189         return 0;
190 }
191
192 int eDVBCISlot::startMMI()
193 {
194         printf("edvbcislot: startMMI()\n");
195         return 0;
196 }
197
198 eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");