aboutsummaryrefslogtreecommitdiff
path: root/lib/dvb_ci/dvbci.cpp
blob: 315d2ae53dcd146ecf9b348c70c1e36d1932415b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <fcntl.h>

#include <lib/base/init.h>
#include <lib/base/init_num.h>

#include <lib/base/eerror.h>
#include <lib/dvb_ci/dvbci.h>
#include <lib/dvb_ci/dvbci_session.h>

eDVBCIInterfaces::eDVBCIInterfaces()
{
	int num_ci = 0;

	eDebug("scanning for common interfaces..");

	while (1)
	{
		struct stat s;
		char filename[128];
		sprintf(filename, "/dev/ci%d", num_ci);

		if (stat(filename, &s))
			break;

		ePtr<eDVBCISlot> cislot;

		cislot = new eDVBCISlot(eApp, num_ci);
		m_slots.push_back(cislot);

		++num_ci;
	}

	eDebug("done, found %d common interface slots", num_ci);
}

eDVBCIInterfaces::~eDVBCIInterfaces()
{
}

int eDVBCISlot::send(const unsigned char *data, size_t len)
{
	int res;
	//int i;
	//printf("< ");
	//for(i=0;i<len;i++)
	//	printf("%02x ",data[i]);
	//printf("\n");

	res = ::write(fd, data, len);

	//printf("write() %d\n",res);

	notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority | eSocketNotifier::Write);

	return res;
}

void eDVBCISlot::data(int what)
{
	if(what == eSocketNotifier::Priority) {
		if(state != stateRemoved) {
			state = stateRemoved;
			printf("ci removed\n");
			notifier->setRequested(eSocketNotifier::Read);
		}
		return;
	}


	__u8 data[4096];
	int r;
	r = ::read(fd, data, 4096);

	if(state != stateInserted) {
		state = stateInserted;
		eDebug("ci inserted");
		/* enable PRI to detect removal or errors */
		notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
	}

	if(r > 0) {
		//int i;
		//printf("> ");
		//for(i=0;i<r;i++)
		//	printf("%02x ",data[i]);
		//printf("\n");
		eDVBCISession::receiveData(this, data, r);
		notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Write);
		return;
	}

	if(what == eSocketNotifier::Write) {
		if(eDVBCISession::pollAll() == 0) {
			notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Priority);
		}
	}
}

DEFINE_REF(eDVBCISlot);

eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
{
	char filename[128];

	sprintf(filename, "/dev/ci%d", nr);

	fd = ::open(filename, O_RDWR | O_NONBLOCK);

	eDebug("eDVBCISlot has fd %d", fd);

	if (fd >= 0)
	{
		notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Priority);
		CONNECT(notifier->activated, eDVBCISlot::data);
	} else
	{
		perror(filename);
	}
}

eDVBCISlot::~eDVBCISlot()
{
}

eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");