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