change session handling
[enigma2.git] / lib / dvb_ci / dvbci.cpp
1 #include <fcntl.h>
2
3 #include <lib/base/eerror.h>
4 #include <lib/dvb_ci/dvbci.h>
5 #include <lib/dvb_ci/dvbci_session.h>
6
7 eDVBCIInterfaces::eDVBCIInterfaces()
8 {
9         int num_ci = 0;
10
11         eDebug("scanning for common interfaces..");
12         while (1)
13         {
14                 struct stat s;
15                 char filename[128];
16                 sprintf(filename, "/dev/ci%d", num_ci);
17
18                 if (stat(filename, &s))
19                         break;
20
21                 ePtr<eDVBCISlot> cislot;
22
23                 cislot = new eDVBCISlot(eApp, num_ci);
24                 m_slots.push_back(cislot);
25
26                 ++num_ci;
27         }
28
29         eDebug("done, found %d common interfaces");
30 }
31
32 int eDVBCISlot::write(const unsigned char *data, size_t len)
33 {
34         return ::write(fd, data, len);
35 }
36
37 void eDVBCISlot::data(int)
38 {
39         eDebug("ci talks to us");
40
41         __u8 data[4096];
42         int r;
43         r = ::read(fd, data, 4096);
44         if(r < 0)
45                 eWarning("ERROR reading from CI - %m\n");
46
47         if(state != stateInserted) {
48                 state = stateInserted;
49                 eDebug("ci inserted");
50
51                 /* enable HUP to detect removal or errors */
52                 notifier_event->start();
53         }
54
55         if(r > 0)
56                 eDVBCISession::receiveData(this, data, r);
57 }
58
59 void eDVBCISlot::event(int)
60 {
61         state = stateRemoved;
62
63         eDebug("CI removed");
64         
65         /* kill the TransportConnection */
66         
67         /* we know about and disable HUP */
68         notifier_event->stop();
69 }
70
71 eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
72 {
73         char filename[128];
74
75         sprintf(filename, "/dev/ci%d", nr);
76
77         fd = ::open(filename, O_RDWR | O_NONBLOCK);
78
79         eDebug("eDVBCISlot has fd %d", fd);
80
81         if (fd >= 0)
82         {
83                 //read callback
84                 notifier_data = new eSocketNotifier(context, fd, eSocketNotifier::Read);
85                 CONNECT(notifier_data->activated, eDVBCISlot::data);
86                 //remove callback
87                 notifier_event = new eSocketNotifier(context, fd, eSocketNotifier::Hungup);
88                 CONNECT(notifier_event->activated, eDVBCISlot::event);
89         } else
90         {
91                 perror(filename);
92         }
93 }
94