Project

General

Profile

RE: Graceperiod expired with TBS6984 ยป test.c

Test program - John Smith, 2013-03-09 15:28

 
1
#include <stdio.h>
2
#include <fcntl.h>
3
#include <memory.h>
4
#include <time.h>
5
#include <stdint.h>
6
#include <sys/ioctl.h>
7
#include <linux/dvb/frontend.h>
8
#include <linux/dvb/dmx.h>
9

    
10
#define LOWVAL 9750000
11
#define HIGHVAL 10600000
12
#define SWITCHVAL 11700000
13

    
14
#define BUFSIZE 4096
15

    
16
struct adapter_struct {
17
	const char *fe_name;
18
	const char *dvr_name;
19
	const char *dmx_name;
20
	int fe_fd;
21
	int dvr_fd;
22
	int dmx_fd;
23
	unsigned char buffer[BUFSIZE];
24
	unsigned long byte_counter;
25
};
26

    
27
struct adapter_struct adapter[2] = {
28
	{
29
		.fe_name = "/dev/dvb/adapter0/frontend0",
30
		.dvr_name = "/dev/dvb/adapter0/dvr0",
31
		.dmx_name = "/dev/dvb/adapter0/demux0"
32
	},
33
	{
34
		.fe_name = "/dev/dvb/adapter1/frontend0",
35
		.dvr_name = "/dev/dvb/adapter1/dvr0",
36
		.dmx_name = "/dev/dvb/adapter1/demux0"
37
	}
38
};
39

    
40
struct channel_struct {
41
	const unsigned int frontend;
42
	const unsigned int demux;
43
	const unsigned int sat_no;
44
	const unsigned int freq;
45
	const unsigned int pol;
46
	const unsigned int sr;
47
	const unsigned int vpid;
48
	const unsigned int apid;
49
	const int sid;
50
	const unsigned int delivery;
51
	const int modulation;
52
	const int fec;
53
	const int rolloff;
54
};
55

    
56
const struct channel_struct svt1_hd = {
57
	.frontend = 0,
58
	.demux = 0,
59
	.sat_no = 1,
60
	.freq = 10903000,
61
	.pol = 1,
62
	.sr = 25000000,
63
	.vpid = 512,
64
	.apid = 640,
65
	.sid = 1406,
66
	.delivery = 6,
67
	.modulation = 0,
68
	.fec = 9,
69
	.rolloff = 0,
70
};
71

    
72
const struct channel_struct viasat_hockey = {
73
	.frontend = 0,
74
	.demux = 0,
75
	.sat_no = 0,
76
	.freq = 11977000,
77
	.pol = 1,
78
	.sr = 27500000,
79
	.vpid = 2141,
80
	.apid = 2142,
81
	.sid = 2140,
82
	.delivery = 5,
83
	.modulation = 0,
84
	.fec = 9,
85
	.rolloff = 0,
86
};
87

    
88
const struct channel_struct *channel[3] = {
89
	&svt1_hd,
90
	&viasat_hockey
91
};
92

    
93
struct diseqc_cmd {
94
	struct dvb_diseqc_master_cmd cmd;
95
	uint32_t wait;
96
};
97

    
98
void diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
99
		     fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
100
{
101
	if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) == -1)
102
		perror("FE_SET_TONE failed");
103
	if (ioctl(fd, FE_SET_VOLTAGE, v) == -1)
104
		perror("FE_SET_VOLTAGE failed");
105
		usleep(15 * 1000);
106
	if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd) == -1)
107
		perror("FE_DISEQC_SEND_MASTER_CMD failed");
108
		usleep(cmd->wait * 1000);
109
		usleep(15 * 1000);
110
	if (ioctl(fd, FE_DISEQC_SEND_BURST, b) == -1)
111
		perror("FE_DISEQC_SEND_BURST failed");
112
		usleep(15 * 1000);
113
	if (ioctl(fd, FE_SET_TONE, t) == -1)
114
		perror("FE_SET_TONE failed");
115
}
116

    
117
/* digital satellite equipment control,
118
 * specification is available from http://www.eutelsat.com/
119
 */
120
int diseqc(int secfd, int sat_no, int pol_vert, int hi_band)
121
{
122
	struct diseqc_cmd cmd =
123
		{ {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
124

    
125
	/**
126
	 * param: high nibble: reset bits, low nibble set bits,
127
	 * bits are: option, position, polarizaion, band
128
	 */
129
	cmd.cmd.msg[3] =
130
		0xf0 | (((sat_no * 4) & 0x0f) | (hi_band ? 1 : 0) | (pol_vert ? 0 : 2));
131

    
132
	diseqc_send_msg(secfd, pol_vert ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18,
133
			&cmd, hi_band ? SEC_TONE_ON : SEC_TONE_OFF,
134
			(sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A);
135

    
136
	return 1;	//TRUE
137
}
138

    
139
int do_tune(int fefd, unsigned int ifreq, unsigned int sr, enum fe_delivery_system delsys,
140
		   int modulation, int fec, int rolloff)
141
{
142
	struct dvb_frontend_event ev;
143
	struct dtv_property p[] = {
144
		{ .cmd = DTV_DELIVERY_SYSTEM,	.u.data = delsys },
145
		{ .cmd = DTV_FREQUENCY,		.u.data = ifreq },
146
		{ .cmd = DTV_MODULATION,	.u.data = modulation },
147
		{ .cmd = DTV_SYMBOL_RATE,	.u.data = sr },
148
		{ .cmd = DTV_INNER_FEC,		.u.data = fec },
149
		{ .cmd = DTV_INVERSION,		.u.data = INVERSION_AUTO },
150
		{ .cmd = DTV_ROLLOFF,		.u.data = rolloff },
151
		{ .cmd = DTV_PILOT,		.u.data = PILOT_AUTO },
152
		{ .cmd = DTV_TUNE },
153
	};
154
	struct dtv_properties cmdseq = {
155
		.num = 9,
156
		.props = p
157
	};
158

    
159
	/* discard stale QPSK events */
160
	while (1) {
161
		if (ioctl(fefd, FE_GET_EVENT, &ev) == -1)
162
		break;
163
	}
164

    
165
	if ((ioctl(fefd, FE_SET_PROPERTY, &cmdseq)) == -1) {
166
		perror("FE_SET_PROPERTY failed");
167
		return 0;	//FALSE
168
	}
169

    
170
	return 1;	//TRUE
171
}
172

    
173
void print_frontend_status(struct adapter_struct *a)
174
{
175
	fe_status_t status;
176
	uint16_t snr, signal;
177
	uint32_t ber, uncorrected_blocks;
178
	int timeout = 0;
179

    
180
	if (ioctl(a->fe_fd, FE_READ_STATUS, &status) == -1)
181
		perror("FE_READ_STATUS failed");
182
	if (ioctl(a->fe_fd, FE_READ_SIGNAL_STRENGTH, &signal) == -1)
183
		signal = -2;
184
	if (ioctl(a->fe_fd, FE_READ_SNR, &snr) == -1)
185
		snr = -2;
186
	if (ioctl(a->fe_fd, FE_READ_BER, &ber) == -1)
187
		ber = -2;
188
	if (ioctl(a->fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks) == -1)
189
		uncorrected_blocks = -2;
190

    
191
	printf ("%02x | %3u%% | %3u%% | %5d | %4d",
192
		status, (signal * 100) / 0xffff, (snr * 100) / 0xffff, ber, uncorrected_blocks);
193
}
194

    
195
void print_status()
196
{
197
	printf("%12ld | ", adapter[0].byte_counter);
198
	print_frontend_status(&adapter[0]);
199
	printf("   |||   ");
200
	printf("%12ld | ", adapter[1].byte_counter);
201
	print_frontend_status(&adapter[1]);
202
	printf("\n");
203
}
204

    
205
void open_adapter_devices(struct adapter_struct *a)
206
{
207
	a->fe_fd = open(a->fe_name, O_RDWR | O_NONBLOCK, 0);
208
	a->dvr_fd = open(a->dvr_name, O_RDONLY | O_NONBLOCK, 0);
209
	a->dmx_fd = open(a->dmx_name, O_RDWR, 0);
210
	if (a->fe_fd < 0 || a->dvr_fd < 0 || a->dmx_fd < 0)
211
		printf("Error opening adapter device.\n");
212
}
213

    
214
void close_adapter_devices(const struct adapter_struct *a)
215
{
216
	close(a->fe_fd);
217
	close(a->dvr_fd);
218
	close(a->dmx_fd);
219
}
220

    
221
void setup_diseqc_switch(const struct adapter_struct *a, const struct channel_struct *ch)
222
{
223
	int hiband = 0;
224
	if (ch->freq >= SWITCHVAL) hiband = 1;
225
	diseqc(a->fe_fd, ch->sat_no, ch->pol, hiband);
226
}
227

    
228
void tune(const struct adapter_struct *a, const struct channel_struct *ch)
229
{
230
	struct dtv_property p[] = {
231
		{ .cmd = DTV_CLEAR },
232
	};
233

    
234
	struct dtv_properties cmdseq = {
235
		.num = 1,
236
		.props = p
237
	};
238

    
239
	int hiband = 0;
240
	uint32_t ifreq;
241

    
242
	if (ch->freq >= SWITCHVAL) hiband = 1;
243
	if (hiband)
244
		ifreq = ch->freq - HIGHVAL;
245
	else {
246
		if (ch->freq < LOWVAL)
247
			ifreq = LOWVAL - ch->freq;
248
		else
249
			ifreq = ch->freq - LOWVAL;
250
	}
251
	/* Tune */
252
	if (ioctl(a->fe_fd, FE_SET_PROPERTY, &cmdseq) == -1)
253
		perror("FE_SET_PROPERTY failed");
254
	do_tune(a->fe_fd, ifreq, ch->sr, ch->delivery, ch->modulation, ch->fec, ch->rolloff);
255
}	
256

    
257
void configure_demuxer(const struct adapter_struct *a)
258
{
259
	struct dmx_pes_filter_params dmx_param;
260

    
261
	memset(&dmx_param, 0, sizeof(dmx_param));
262
  dmx_param.pid = 0x2000;
263
  dmx_param.input = DMX_IN_FRONTEND;
264
  dmx_param.output = DMX_OUT_TS_TAP;
265
  dmx_param.pes_type = DMX_PES_OTHER;
266
  dmx_param.flags = DMX_IMMEDIATE_START;
267

    
268
	if (ioctl(a->dmx_fd, DMX_SET_PES_FILTER, &dmx_param) == -1)
269
		perror("DMX_SET_PES_FILTER failed");
270
}
271

    
272
void test_loop_5s(void)
273
{
274
	int t, last_t, c;
275
  time_t start_time;
276

    
277
	start_time = time(NULL);
278
	last_t = -1;
279
	
280
 	adapter[0].byte_counter = 0;	
281
 	adapter[1].byte_counter = 0;	
282

    
283
	while((t = (time(NULL) - start_time)) < 5) {
284
	  c = read(adapter[0].dvr_fd, adapter[0].buffer, BUFSIZE);
285
    if (c > 0)
286
     	adapter[0].byte_counter += c;	
287

    
288
	  c = read(adapter[1].dvr_fd, adapter[1].buffer, BUFSIZE);
289
    if (c > 0)
290
     	adapter[1].byte_counter += c;	
291

    
292
		if (t > last_t) {
293
			print_status();
294
			last_t = t;			
295
		}
296
  }
297
  
298
  printf("adapter0: ");
299
  if (adapter[0].byte_counter == 0)
300
  	printf("FAIL    ");
301
  else
302
  	printf("OK      ");
303
  printf("adapter1: ");
304
  if (adapter[1].byte_counter == 0)
305
  	printf("FAIL    ");
306
  else
307
  	printf("OK      ");
308
  printf("\n");
309
}
310

    
311
int main()
312
{
313
	int i, s;
314
	
315
	for (i = 0; i < 6; i++) {
316
		s = i % 2;
317
		printf("Iteration: %d, sleep(%d)\n", i, s);
318

    
319
		open_adapter_devices(&adapter[0]);	
320
		sleep(s);	// Apparently sleep is required here
321
		open_adapter_devices(&adapter[1]);	
322
		
323
		/* First adapter  */
324
		setup_diseqc_switch(&adapter[0], channel[0]);
325
		tune(&adapter[0], channel[0]);
326
		configure_demuxer(&adapter[0]);
327
	
328
		/* Second adapter  */
329
		setup_diseqc_switch(&adapter[1], channel[1]);
330
		tune(&adapter[1], channel[1]);
331
		configure_demuxer(&adapter[1]);
332
	
333
		test_loop_5s();
334
		
335
		close_adapter_devices(&adapter[0]);
336
		close_adapter_devices(&adapter[1]);
337
	}
338
	return 0;	
339
}
    (1-1/1)