ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-DVB/DVB.xs
Revision: 1.4
Committed: Tue Apr 5 03:42:21 2005 UTC (19 years, 1 month ago) by root
Branch: MAIN
CVS Tags: rel-0_3, rel-0_4
Changes since 1.3: +293 -119 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <string.h>
6
7 #include <linux/dvb/frontend.h>
8 #include <linux/dvb/dmx.h>
9
10 #define CONST(name) { #name, name }
11
12 enum {
13 SCT_PAT = 0x00,
14 SCT_CAT = 0x01,
15 SCT_PMT = 0x02,
16 SCT_TSDT = 0x03,
17 SCT_NIT = 0x40,//TODO
18 SCT_NIT_OTHER = 0x41,
19 SCT_SDT = 0x42,
20 SCT_SDT_OTHER = 0x46,
21 SCT_BAT = 0x4a,//TODO
22 SCT_EIT_PRESENT = 0x4e,
23 SCT_EIT_PRESENT_OTHER = 0x4f,
24 SCT_EIT_SCHEDULE0 = 0x50,
25 SCT_EIT_SCHEDULE15 = 0x5f,
26 SCT_EIT_SCHEDULE_OTHER0 = 0x60,
27 SCT_EIT_SCHEDULE_OTHER15 = 0x6f,
28 SCT_TDT = 0x70,
29 SCT_RST = 0x71,
30 SCT_ST = 0x72,
31 SCT_TOT = 0x73,
32 SCT_RNT = 0x74,
33 SCT_CST = 0x75,
34 SCT_RCT = 0x76,
35 SCT_CIT = 0x77,
36 SCT_MPE = 0x78,
37 SCT_DIT = 0x7e,
38 SCT_SIT = 0x7f,
39 };
40
41 enum {
42 DT_network_name = 0x40,
43 DT_service_list = 0x41,
44 DT_satellite_delivery_system = 0x43,
45 DT_cable_delivery_system = 0x44,
46 DT_service = 0x48,
47 DT_country_availability = 0x49,
48 DT_linkage = 0x4a,
49 DT_short_event = 0x4d,
50 DT_extended_event = 0x4e, //NYI
51 DT_component = 0x50,
52 DT_content = 0x54,
53 DT_terrestrial_delivery_system = 0x5A,
54 DT_private_data_specifier = 0x5f,
55 DT_short_smoothing_buffer = 0x61, //NYI
56 DT_scrambling_indicator = 0x65, //NYI
57 DT_PDC = 0x69,
58 };
59
60 static const struct consts {
61 const char *name;
62 const long value;
63 } consts [] = {
64 CONST (FE_QPSK),
65 CONST (FE_QAM),
66 CONST (FE_OFDM),
67
68 CONST (FE_IS_STUPID),
69 CONST (FE_CAN_INVERSION_AUTO),
70 CONST (FE_CAN_FEC_1_2),
71 CONST (FE_CAN_FEC_2_3),
72 CONST (FE_CAN_FEC_3_4),
73 CONST (FE_CAN_FEC_4_5),
74 CONST (FE_CAN_FEC_5_6),
75 CONST (FE_CAN_FEC_6_7),
76 CONST (FE_CAN_FEC_7_8),
77 CONST (FE_CAN_FEC_8_9),
78 CONST (FE_CAN_FEC_AUTO),
79 CONST (FE_CAN_QPSK),
80 CONST (FE_CAN_QAM_16),
81 CONST (FE_CAN_QAM_32),
82 CONST (FE_CAN_QAM_64),
83 CONST (FE_CAN_QAM_128),
84 CONST (FE_CAN_QAM_256),
85 CONST (FE_CAN_QAM_AUTO),
86 CONST (FE_CAN_TRANSMISSION_MODE_AUTO),
87 CONST (FE_CAN_BANDWIDTH_AUTO),
88 CONST (FE_CAN_GUARD_INTERVAL_AUTO),
89 CONST (FE_CAN_HIERARCHY_AUTO),
90 CONST (FE_NEEDS_BENDING),
91 CONST (FE_CAN_RECOVER),
92 CONST (FE_CAN_MUTE_TS),
93
94 CONST (FE_HAS_SIGNAL),
95 CONST (FE_HAS_CARRIER),
96 CONST (FE_HAS_VITERBI),
97 CONST (FE_HAS_SYNC),
98 CONST (FE_HAS_LOCK),
99 CONST (FE_TIMEDOUT),
100 CONST (FE_REINIT),
101
102 CONST (INVERSION_OFF),
103 CONST (INVERSION_ON),
104 CONST (INVERSION_AUTO),
105
106 CONST (FEC_NONE),
107 CONST (FEC_1_2),
108 CONST (FEC_2_3),
109 CONST (FEC_3_4),
110 CONST (FEC_4_5),
111 CONST (FEC_5_6),
112 CONST (FEC_6_7),
113 CONST (FEC_7_8),
114 CONST (FEC_8_9),
115 CONST (FEC_AUTO),
116
117 CONST (QPSK),
118 CONST (QAM_16),
119 CONST (QAM_32),
120 CONST (QAM_64),
121 CONST (QAM_128),
122 CONST (QAM_256),
123 CONST (QAM_AUTO),
124
125 CONST (TRANSMISSION_MODE_2K),
126 CONST (TRANSMISSION_MODE_8K),
127 CONST (TRANSMISSION_MODE_AUTO),
128
129 CONST (BANDWIDTH_8_MHZ),
130 CONST (BANDWIDTH_7_MHZ),
131 CONST (BANDWIDTH_6_MHZ),
132 CONST (BANDWIDTH_AUTO),
133
134 CONST (GUARD_INTERVAL_1_32),
135 CONST (GUARD_INTERVAL_1_16),
136 CONST (GUARD_INTERVAL_1_8),
137 CONST (GUARD_INTERVAL_1_4),
138 CONST (GUARD_INTERVAL_AUTO),
139
140 CONST (HIERARCHY_NONE),
141 CONST (HIERARCHY_1),
142 CONST (HIERARCHY_2),
143 CONST (HIERARCHY_4),
144 CONST (HIERARCHY_AUTO),
145
146 CONST (DMX_OUT_DECODER),
147 CONST (DMX_OUT_TAP),
148 CONST (DMX_OUT_TS_TAP),
149
150 CONST (DMX_IN_FRONTEND),
151 CONST (DMX_IN_DVR),
152
153 CONST (DMX_PES_AUDIO0),
154 CONST (DMX_PES_VIDEO0),
155 CONST (DMX_PES_TELETEXT0),
156 CONST (DMX_PES_SUBTITLE0),
157 CONST (DMX_PES_PCR0),
158
159 CONST (DMX_PES_AUDIO1),
160 CONST (DMX_PES_VIDEO1),
161 CONST (DMX_PES_TELETEXT1),
162 CONST (DMX_PES_SUBTITLE1),
163 CONST (DMX_PES_PCR1),
164
165 CONST (DMX_PES_AUDIO2),
166 CONST (DMX_PES_VIDEO2),
167 CONST (DMX_PES_TELETEXT2),
168 CONST (DMX_PES_SUBTITLE2),
169 CONST (DMX_PES_PCR2),
170
171 CONST (DMX_PES_AUDIO3),
172 CONST (DMX_PES_VIDEO3),
173 CONST (DMX_PES_TELETEXT3),
174 CONST (DMX_PES_SUBTITLE3),
175 CONST (DMX_PES_PCR3),
176
177 CONST (DMX_PES_OTHER),
178
179 CONST (DMX_PES_AUDIO),
180 CONST (DMX_PES_VIDEO),
181 CONST (DMX_PES_TELETEXT),
182 CONST (DMX_PES_SUBTITLE),
183 CONST (DMX_PES_PCR),
184
185 CONST (DMX_SCRAMBLING_EV),
186 CONST (DMX_FRONTEND_EV),
187
188 CONST (DMX_CHECK_CRC),
189 CONST (DMX_ONESHOT),
190 CONST (DMX_IMMEDIATE_START),
191 CONST (DMX_KERNEL_CLIENT),
192
193 CONST (DMX_SOURCE_FRONT0),
194 CONST (DMX_SOURCE_FRONT1),
195 CONST (DMX_SOURCE_FRONT2),
196 CONST (DMX_SOURCE_FRONT3),
197
198 CONST (DMX_SOURCE_DVR0),
199 CONST (DMX_SOURCE_DVR1),
200 CONST (DMX_SOURCE_DVR2),
201 CONST (DMX_SOURCE_DVR3),
202
203 CONST (DMX_SCRAMBLING_OFF),
204 CONST (DMX_SCRAMBLING_ON),
205
206 // constants defined by this file
207 CONST (SCT_PAT),
208 CONST (SCT_CAT),
209 CONST (SCT_PMT),
210 CONST (SCT_TSDT),
211 CONST (SCT_NIT),
212 CONST (SCT_NIT_OTHER),
213 CONST (SCT_SDT),
214 CONST (SCT_SDT_OTHER),
215 CONST (SCT_BAT),
216 CONST (SCT_EIT_PRESENT),
217 CONST (SCT_EIT_PRESENT_OTHER),
218 CONST (SCT_EIT_SCHEDULE0),
219 CONST (SCT_EIT_SCHEDULE15),
220 CONST (SCT_EIT_SCHEDULE_OTHER0),
221 CONST (SCT_EIT_SCHEDULE_OTHER15),
222 CONST (SCT_TDT),
223 CONST (SCT_RST),
224 CONST (SCT_ST),
225 CONST (SCT_TOT),
226 CONST (SCT_RNT),
227 CONST (SCT_CST),
228 CONST (SCT_RCT),
229 CONST (SCT_CIT),
230 CONST (SCT_MPE),
231 CONST (SCT_DIT),
232 CONST (SCT_SIT),
233
234 CONST (DT_network_name),
235 CONST (DT_service_list),
236 CONST (DT_satellite_delivery_system),
237 CONST (DT_cable_delivery_system),
238 CONST (DT_service),
239 CONST (DT_country_availability),
240 CONST (DT_linkage),
241 CONST (DT_short_event),
242 CONST (DT_extended_event),
243 CONST (DT_component),
244 CONST (DT_content),
245 CONST (DT_terrestrial_delivery_system),
246 CONST (DT_private_data_specifier),
247 CONST (DT_short_smoothing_buffer),
248 CONST (DT_scrambling_indicator),
249 CONST (DT_PDC),
250 };
251
252 #define HVS_S(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSVpv (struct.member, 0), 0)
253 #define HVS_I(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSViv (struct.member), 0)
254 #define HVS(hv,name,sv) hv_store (hv, #name, sizeof (#name) - 1, (sv), 0)
255
256 static void
257 get_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type)
258 {
259 HVS_I (hv, (*p), frequency);
260 HVS_I (hv, (*p), inversion);
261
262 switch (type)
263 {
264 case FE_QPSK:
265 HVS_I (hv, (*p).u.qpsk, symbol_rate);
266 HVS_I (hv, (*p).u.qpsk, fec_inner);
267 break;
268
269 case FE_QAM:
270 HVS_I (hv, (*p).u.qam, symbol_rate);
271 HVS_I (hv, (*p).u.qam, fec_inner);
272 HVS_I (hv, (*p).u.qam, modulation);
273 break;
274
275 case FE_OFDM:
276 HVS_I (hv, (*p).u.ofdm, bandwidth);
277 HVS_I (hv, (*p).u.ofdm, code_rate_HP);
278 HVS_I (hv, (*p).u.ofdm, code_rate_LP);
279 HVS_I (hv, (*p).u.ofdm, constellation);
280 HVS_I (hv, (*p).u.ofdm, transmission_mode);
281 break;
282 }
283 }
284
285 #define HVF_I(hv,struct,member) \
286 if (v = hv_fetch (hv, #member, sizeof (#member) - 1, 0)) \
287 struct.member = SvIV (*v); \
288 else \
289 croak ("required hash key '%s' not specified", #member);
290
291 static void
292 set_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type)
293 {
294 SV **v;
295
296 HVF_I (hv, (*p), frequency);
297 HVF_I (hv, (*p), inversion);
298
299 switch (type)
300 {
301 case FE_QPSK:
302 HVF_I (hv, (*p).u.qpsk, symbol_rate);
303 HVF_I (hv, (*p).u.qpsk, fec_inner);
304 break;
305
306 case FE_QAM:
307 HVF_I (hv, (*p).u.qam, symbol_rate);
308 HVF_I (hv, (*p).u.qam, fec_inner);
309 HVF_I (hv, (*p).u.qam, modulation);
310 break;
311
312 case FE_OFDM:
313 HVF_I (hv, (*p).u.ofdm, bandwidth);
314 HVF_I (hv, (*p).u.ofdm, code_rate_HP);
315 HVF_I (hv, (*p).u.ofdm, code_rate_LP);
316 HVF_I (hv, (*p).u.ofdm, constellation);
317 HVF_I (hv, (*p).u.ofdm, transmission_mode);
318 break;
319 }
320 }
321
322 typedef unsigned char u8;
323
324 static SV *dec_sv;
325 static u8 *dec_data;
326 static long dec_ofs, dec_len8;
327 static U32 dec_field;
328 STRLEN dec_len;
329
330 #define decode_overflow (dec_ofs > dec_len8)
331
332 static void
333 decode_set (SV *data)
334 {
335 if (dec_sv)
336 SvREFCNT_dec (dec_sv);
337
338 dec_sv = newSVsv (data);
339 dec_data = SvPVbyte (dec_sv, dec_len);
340 dec_ofs = 0;
341 dec_len8 = dec_len << 3;
342 }
343
344 static U32
345 decode_field (int bits)
346 {
347 u8 *p = dec_data + (dec_ofs >> 3);
348 int frac = 8 - (dec_ofs & 7);
349 dec_ofs += bits;
350
351 if (decode_overflow)
352 return dec_field = 0;
353
354 U32 r = *p++;
355
356 r &= (1UL << frac) - 1;
357
358 if (bits < frac)
359 r >>= (frac - bits);
360 else
361 {
362 bits -= frac;
363
364 while (bits >= 8)
365 {
366 r = (r << 8) | *p++;
367 bits -= 8;
368 }
369
370 if (bits > 0)
371 r = (r << bits) | (*p >> (8 - bits));
372 }
373
374 return dec_field = r;
375 }
376
377 U32
378 clamp (U32 len)
379 {
380 return len < 4096
381 && len <= dec_len8 - (dec_ofs >> 3) + 1 /* +1 to detect overflows */
382 ? len : 0;
383 }
384
385 /* works on SvPOK strings ONLY */
386 void
387 safe_sv_chop (SV *sv, STRLEN count)
388 {
389 if ((U32)count >= (U32)SvCUR (sv))
390 SvCUR_set (sv, 0);
391 else
392 sv_chop (sv, SvPVX (sv) + count);
393 }
394
395 U32
396 bcd_to_int (U32 bcd_number)
397 {
398 U32 result = 0;
399 U32 multiplicator = 1;
400
401 while (bcd_number != 0)
402 {
403 result += (bcd_number & 0x0f) * multiplicator;
404 bcd_number >>= 4;
405 multiplicator *= 10;
406 }
407
408 return result;
409 }
410
411 static SV *
412 text2sv (u8 *data, U32 len)
413 {
414 dSP;
415 SV *sv = newSVpvn (data, clamp (len));
416
417 PUSHMARK (SP);
418 XPUSHs (sv);
419 PUTBACK;
420 call_pv ("Linux::DVB::Decode::text", G_VOID);
421
422 return sv;
423 }
424
425 #define DEC_I(hv, bits, name) HVS (hv, name, newSViv (decode_field (bits)))
426 #define DEC_T(hv, bytes, name) HVS (hv, name, text2sv (dec_data + (dec_ofs >> 3), clamp (bytes))), dec_ofs += clamp (bytes) << 3
427 #define DEC_S(hv, bytes, name) HVS (hv, name, newSVpvn (dec_data + (dec_ofs >> 3), clamp (bytes))), dec_ofs += clamp (bytes) << 3
428
429 static AV *
430 decode_descriptors (long end)
431 {
432 AV *av = newAV ();
433
434 while (dec_ofs < end)
435 {
436 HV *hv = newHV ();
437 U8 type, len, len2;
438 AV *av2;
439 long end, end2;
440
441 av_push (av, newRV_noinc ((SV *)hv));
442
443 DEC_I (hv, 8, type);
444 type = dec_field;
445 len = decode_field (8);
446 end = dec_ofs + (len << 3);
447
448 if (end > dec_len8)
449 return av;
450
451 switch (type)
452 {
453 case DT_network_name:
454 DEC_T (hv, (end - dec_ofs) >> 3, network_name);
455 break;
456
457 case DT_service_list:
458 {
459 AV *services = newAV ();
460 HVS (hv, services, newRV_noinc ((SV *)services));
461
462 while (dec_ofs < end)
463 {
464 HV *sv = newHV ();
465 av_push (services, newRV_noinc ((SV *)sv));
466
467 DEC_I (sv, 16, service_id);
468 DEC_I (sv, 8, service_type);
469
470 }
471 }
472
473 break;
474
475 case DT_satellite_delivery_system:
476 HVS (hv, frequency, newSVuv (bcd_to_int (decode_field (32))));
477 HVS (hv, orbital_position, newSVnv (bcd_to_int (decode_field (32)) / 10));
478 DEC_I (hv, 1, west_east_flag);
479 DEC_I (hv, 2, polarization);
480 DEC_I (hv, 5, modulation);
481 HVS (hv, symbol_rate, newSVuv (bcd_to_int (decode_field (28))));
482 DEC_I (hv, 4, fec_inner);
483 break;
484
485 case DT_cable_delivery_system:
486 {
487 I16 qam_modulation = -1;
488
489 HVS (hv, frequency, newSVuv (bcd_to_int (decode_field (32))));
490 decode_field (12); // reserved
491 DEC_I (hv, 4, fec_outer);
492
493 DEC_I (hv, 8, modulation);
494
495 if (dec_field >= 1 && dec_field <= 5)
496 qam_modulation = 1 << dec_field + 3;
497
498 HVS (hv, modulation_qam, newSViv (qam_modulation));
499
500 HVS (hv, symbol_rate, newSVuv (bcd_to_int (decode_field (28))));
501 DEC_I (hv, 4, fec_inner);
502
503 break;
504 }
505
506 case DT_service:
507 DEC_I (hv, 8, service_type);
508 len2 = decode_field (8); DEC_T (hv, len2, service_provider_name);
509 len2 = decode_field (8); DEC_T (hv, len2, service_name);
510 break;
511
512 case DT_country_availability:
513 DEC_I (hv, 1, country_availability_flag);
514 decode_field (7);
515
516 DEC_S (hv, (end - dec_ofs) >> 3, private_data);
517 //while (dec_ofs + 24 <= end)
518 // av_push (av,
519 break;
520
521 case DT_linkage:
522 DEC_I (hv, 16, transport_stream_id);
523 DEC_I (hv, 16, original_network_id);
524 DEC_I (hv, 16, service_id);
525 DEC_I (hv, 8, linkage_type);
526
527 if (dec_field == 8)
528 {
529 U32 hot, org;
530
531 DEC_I (hv, 8, hand_over_type); hot = dec_field;
532 decode_field (3);
533 DEC_I (hv, 1, origin_type); org = dec_field;
534
535 if (hot > 0x00 && hot < 0x04)
536 DEC_I (hv, 16, network_id);
537
538 if (org == 0)
539 DEC_I (hv, 16, initial_service_id);
540 }
541
542 DEC_S (hv, (end - dec_ofs) >> 3, private_data);
543 break;
544
545 case DT_PDC:
546 decode_field (4);
547 DEC_I (hv, 20, programme_identification_label);
548 break;
549
550 case DT_component:
551 decode_field (4);
552 DEC_I (hv, 4, stream_content);
553 DEC_I (hv, 8, component_type);
554 DEC_I (hv, 8, component_tag);
555 DEC_S (hv, 3, ISO_639_language_code);
556 DEC_T (hv, (end - dec_ofs) >> 3, text);
557 break;
558
559 case DT_short_event:
560 DEC_S (hv, 3, ISO_639_language_code);
561 len2 = decode_field (8); DEC_T (hv, len2, event_name);
562 len2 = decode_field (8); DEC_T (hv, len2, text);
563 break;
564
565 case DT_extended_event:
566 DEC_I (hv, 4, descriptor_number);
567 DEC_I (hv, 4, last_descriptor_number);
568 DEC_S (hv, 3, ISO_639_language_code);
569
570 len2 = decode_field (8); end2 = dec_ofs + (len2 << 3);
571 av2 = newAV ();
572 HVS (hv, items, newRV_noinc ((SV *)av2));
573
574 while (dec_ofs < end2)
575 {
576 AV *av3 = newAV ();
577 len2 = decode_field (8); av_push (av3, text2sv (dec_data + (dec_ofs >> 3), len2)), dec_ofs += len << 3;
578 len2 = decode_field (8); av_push (av3, text2sv (dec_data + (dec_ofs >> 3), len2)), dec_ofs += len << 3;
579
580 av_push (av2, newRV_noinc ((SV *)av3));
581 }
582
583 len2 = decode_field (8); DEC_T (hv, len2, text);
584 break;
585
586 case DT_content:
587 av2 = newAV ();
588 HVS (hv, items, newRV_noinc ((SV *)av2));
589
590 while (dec_ofs < end)
591 {
592 HV *ev = newHV ();
593
594 DEC_I (ev, 4, content_nibble_level_1);
595 DEC_I (ev, 4, content_nibble_level_2);
596 DEC_I (ev, 4, user_nibble_1);
597 DEC_I (ev, 4, user_nibble_2);
598
599 av_push (av2, newRV_noinc ((SV *)ev));
600 }
601
602 break;
603
604 case DT_terrestrial_delivery_system:
605 {
606 I8 bandwidth_mhz = -1;
607
608 HVS (hv, centre_frequency, newSVuv (decode_field (32) * 10));
609
610 DEC_I (hv, 3, bandwidth);
611
612 if (dec_field <= 3)
613 bandwidth_mhz = 8 - dec_field;
614
615 HVS (hv, bandwidth_mhz, newSViv (bandwidth_mhz));
616
617 DEC_I (hv, 1, priority);
618 DEC_I (hv, 1, time_slicing_indicator);
619 DEC_I (hv, 1, mpe_fec_indicator);
620 decode_field (2); // reserved
621 DEC_I (hv, 2, constellation);
622 DEC_I (hv, 3, hierarchy_information);
623 DEC_I (hv, 3, code_rate_hp_stream);
624 DEC_I (hv, 3, code_rate_lp_stream);
625 DEC_I (hv, 2, guard_interval);
626 DEC_I (hv, 2, transmission_mode);
627 DEC_I (hv, 1, other_frequency_use);
628 decode_field (32);
629 }
630 break;
631
632 case DT_private_data_specifier:
633 DEC_I (hv, 32, private_data_specifier);
634 break;
635
636 default:
637 //fprintf (stderr, "UNKXXX %x\n", type);//D
638
639 case 0:
640 case 0x80:
641 case 0x81:
642 case 0x82:
643 case 0x83:
644 case 0x84:
645 case 0x85:
646 case 0x8d:
647 case 0x8e:
648 case 0xb2:
649 DEC_S (hv, len, raw_data);
650 break;
651 }
652
653 dec_ofs = end; // re-sync, in case of problems
654 }
655
656 return av;
657 }
658
659 MODULE = Linux::DVB PACKAGE = Linux::DVB
660
661 PROTOTYPES: DISABLE
662
663 void
664 _consts ()
665 PPCODE:
666 const struct consts *c;
667 for (c = consts;
668 c < consts + sizeof (consts) / sizeof (consts[0]);
669 c++)
670 {
671 XPUSHs (sv_2mortal (newSVpv (c->name, 0)));
672 XPUSHs (sv_2mortal (newSViv (c->value)));
673 }
674
675 MODULE = Linux::DVB PACKAGE = Linux::DVB::Frontend
676
677 SV *
678 _frontend_info (int fd)
679 CODE:
680 struct dvb_frontend_info fi;
681 HV *hv;
682
683 if (ioctl (fd, FE_GET_INFO, &fi) < 0)
684 XSRETURN_UNDEF;
685
686 hv = newHV ();
687 HVS_S (hv, fi, name);
688 HVS_I (hv, fi, type);
689 HVS_I (hv, fi, type);
690 HVS_I (hv, fi, frequency_min);
691 HVS_I (hv, fi, frequency_max);
692 HVS_I (hv, fi, frequency_stepsize);
693 HVS_I (hv, fi, frequency_tolerance);
694 HVS_I (hv, fi, symbol_rate_min);
695 HVS_I (hv, fi, symbol_rate_max);
696 HVS_I (hv, fi, symbol_rate_tolerance);
697 HVS_I (hv, fi, notifier_delay);
698 HVS_I (hv, fi, caps);
699
700 RETVAL = (SV *)newRV_noinc ((SV *)hv);
701 OUTPUT:
702 RETVAL
703
704 long
705 _read_status (int fd)
706 CODE:
707 fe_status_t st;
708
709 if (ioctl (fd, FE_READ_STATUS, &st) < 0)
710 XSRETURN_UNDEF;
711
712 RETVAL = st;
713 OUTPUT:
714 RETVAL
715
716 U32
717 _read_ber (int fd)
718 CODE:
719 uint32_t ber;
720 if (ioctl (fd, FE_READ_BER, &ber) < 0)
721 XSRETURN_UNDEF;
722
723 RETVAL = ber;
724 OUTPUT:
725 RETVAL
726
727 U32
728 _read_snr (int fd)
729 CODE:
730 uint32_t ber;
731 if (ioctl (fd, FE_READ_SNR, &ber) < 0)
732 XSRETURN_UNDEF;
733
734 RETVAL = ber;
735 OUTPUT:
736 RETVAL
737
738
739 I16
740 _signal_strength (int fd)
741 CODE:
742 int16_t st;
743 if (ioctl (fd, FE_READ_SIGNAL_STRENGTH, &st) < 0)
744 XSRETURN_UNDEF;
745
746 RETVAL = st;
747 OUTPUT:
748 RETVAL
749
750
751 U32
752 _uncorrected_blocks (int fd)
753 CODE:
754 uint32_t ubl;
755 if (ioctl (fd, FE_READ_UNCORRECTED_BLOCKS, &ubl) < 0)
756 XSRETURN_UNDEF;
757
758 RETVAL = ubl;
759 OUTPUT:
760 RETVAL
761
762 int
763 _set (int fd, SV *parameters, int type)
764 CODE:
765 struct dvb_frontend_parameters p;
766
767 if (!SvROK (parameters) || SvTYPE (SvRV (parameters)) != SVt_PVHV)
768 croak ("Linux::DVB::Frontend::set requires a hash as argument");
769
770 set_parameters ((HV *)SvRV (parameters), &p, type);
771
772 if (ioctl (fd, FE_SET_FRONTEND, &p) < 0)
773 XSRETURN_UNDEF;
774
775 RETVAL = 1;
776 OUTPUT:
777 RETVAL
778
779 SV *
780 _get (int fd, int type)
781 CODE:
782 struct dvb_frontend_parameters p;
783 HV *hv;
784
785 if (ioctl (fd, FE_GET_FRONTEND, &p) < 0)
786 XSRETURN_UNDEF;
787
788 hv = newHV ();
789 get_parameters (hv, &p, type);
790 RETVAL = (SV *)newRV_noinc ((SV *)hv);
791 OUTPUT:
792 RETVAL
793
794 SV *
795 _event (int fd, int type)
796 CODE:
797 struct dvb_frontend_event e;
798 HV *hv;
799
800 if (ioctl (fd, FE_GET_EVENT, &e) < 0)
801 XSRETURN_UNDEF;
802
803 hv = newHV ();
804 HVS_I (hv, e, status);
805 get_parameters (hv, &e.parameters, type);
806 RETVAL = (SV *)newRV_noinc ((SV *)hv);
807 OUTPUT:
808 RETVAL
809
810 MODULE = Linux::DVB PACKAGE = Linux::DVB::Demux
811
812 int
813 _start (int fd)
814 ALIAS:
815 _stop = 1
816 CODE:
817 if (ioctl (fd, ix ? DMX_STOP : DMX_START, 0) < 0)
818 XSRETURN_UNDEF;
819
820 RETVAL = 1;
821 OUTPUT:
822 RETVAL
823
824 int
825 _filter (int fd, U16 pid, SV *filter, SV *mask, U32 timeout = 0, U32 flags = DMX_CHECK_CRC)
826 CODE:
827 struct dmx_sct_filter_params p;
828 STRLEN l;
829 char *s;
830
831 memset (&p.filter, 0, sizeof (p.filter));
832
833 p.pid = pid;
834 s = SvPVbyte (filter, l); if (l > DMX_FILTER_SIZE) l = DMX_FILTER_SIZE; memcpy (p.filter.filter, s, l);
835 s = SvPVbyte (mask , l); if (l > DMX_FILTER_SIZE) l = DMX_FILTER_SIZE; memcpy (p.filter.mask , s, l);
836 p.timeout = timeout;
837 p.flags = flags;
838 if (ioctl (fd, DMX_SET_FILTER, &p) < 0)
839 XSRETURN_UNDEF;
840
841 RETVAL = 1;
842 OUTPUT:
843 RETVAL
844
845 int
846 _pes_filter (int fd, U16 pid, long input, long output, long type, U32 flags = 0)
847 CODE:
848 struct dmx_pes_filter_params p;
849
850 p.pid = pid;
851 p.input = input;
852 p.output = output;
853 p.pes_type = type;
854 p.flags = flags;
855 if (ioctl (fd, DMX_SET_PES_FILTER, &p) < 0)
856 XSRETURN_UNDEF;
857
858 RETVAL = 1;
859 OUTPUT:
860 RETVAL
861
862 int
863 _buffer (int fd, unsigned long size)
864 CODE:
865
866 if (ioctl (fd, DMX_SET_BUFFER_SIZE, size) < 0)
867 XSRETURN_UNDEF;
868
869 RETVAL = 1;
870 OUTPUT:
871 RETVAL
872
873 MODULE = Linux::DVB PACKAGE = Linux::DVB::Decode PREFIX = decode_
874
875 void
876 set (SV *data)
877 CODE:
878
879 int
880 len ()
881 CODE:
882 RETVAL = (dec_ofs + 7) >> 3;
883 OUTPUT:
884 RETVAL
885
886 U32
887 field (int bits)
888
889 SV *
890 si (SV *stream)
891 CODE:
892 HV *hv = newHV ();
893
894 int syntax_indicator;
895 U8 table_id;
896 U16 length;
897 long end;
898
899 decode_set (stream);
900
901 do {
902 DEC_I (hv, 8, table_id);
903 table_id = dec_field;
904 } while (table_id == 0xff);
905
906 syntax_indicator = decode_field (1);
907 HVS (hv, section_syntax_indicator, newSViv (syntax_indicator));
908
909 decode_field (1);
910 decode_field (2);
911
912 length = decode_field (12);
913 end = dec_ofs + (length << 3);
914
915 if (syntax_indicator)
916 {
917 switch (table_id)
918 {
919 case SCT_NIT:
920 {
921 U16 descriptor_end_offset;
922
923 DEC_I (hv, 16, network_id);
924 decode_field (2); // reserved
925 DEC_I (hv, 5, version_number);
926 DEC_I (hv, 1, current_next_indicator);
927 DEC_I (hv, 8, section_number);
928 DEC_I (hv, 8, last_section_number);
929 decode_field (4); // reserved
930
931 AV *desc;
932 descriptor_end_offset = dec_ofs + (decode_field (12) << 3);
933 desc = decode_descriptors (descriptor_end_offset);
934 HVS (hv,network_descriptors, newRV_noinc ((SV *)desc));
935
936 decode_field (4); //reserved
937 decode_field (12); // Skip length, we read until the end
938
939 AV *events = newAV ();
940 HVS (hv, events, newRV_noinc ((SV *)events));
941 while (end - dec_ofs > 32)
942 {
943 long dll;
944 HV *ev = newHV ();
945 av_push (events, newRV_noinc ((SV *)ev));
946
947 DEC_I (ev, 16, transport_stream_id);
948 DEC_I (ev, 16, original_network_id);
949 decode_field (4);
950
951 dll = dec_ofs + (decode_field (12) << 3);
952 desc = decode_descriptors (dll);
953 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
954 }
955
956 decode_field (32); // skip CRC
957 }
958
959 break;
960
961 case SCT_EIT_PRESENT:
962 case SCT_EIT_PRESENT_OTHER:
963 case SCT_EIT_SCHEDULE0...SCT_EIT_SCHEDULE15: //GCC
964 case SCT_EIT_SCHEDULE_OTHER0...SCT_EIT_SCHEDULE_OTHER15: //GCC
965 DEC_I (hv, 16, service_id);
966 decode_field (2);
967 DEC_I (hv, 5, version_number);
968 DEC_I (hv, 1, current_next_indicator);
969 DEC_I (hv, 8, section_number);
970 DEC_I (hv, 8, last_section_number);
971 DEC_I (hv, 16, transport_stream_id);
972 DEC_I (hv, 16, original_network_id);
973 DEC_I (hv, 8, segment_last_section_number);
974 DEC_I (hv, 8, last_table_id);
975
976 AV *events = newAV ();
977 HVS (hv, events, newRV_noinc ((SV *)events));
978
979 while (end - dec_ofs > 32)
980 {
981 long dll;
982 AV *desc;
983 HV *ev = newHV ();
984 av_push (events, newRV_noinc ((SV *)ev));
985
986 DEC_I (ev, 16, event_id);
987 DEC_I (ev, 16, start_time_mjd);
988 DEC_I (ev, 24, start_time_hms);
989 DEC_I (ev, 24, duration);
990 DEC_I (ev, 3, running_status);
991 DEC_I (ev, 1, free_CA_mode);
992
993 dll = dec_ofs + (decode_field (12) << 3);
994
995 desc = decode_descriptors (dll);
996 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
997 }
998
999 decode_field (32); // skip CRC
1000
1001 break;
1002
1003 case SCT_SDT:
1004 case SCT_SDT_OTHER:
1005 DEC_I (hv, 16, transport_stream_id);
1006 decode_field (2);
1007 DEC_I (hv, 5, version_number);
1008 DEC_I (hv, 1, current_next_indicator);
1009 DEC_I (hv, 8, section_number);
1010 DEC_I (hv, 8, last_section_number);
1011 DEC_I (hv, 16, original_network_id);
1012 decode_field (8);
1013
1014 AV *services = newAV ();
1015 HVS (hv, services, newRV_noinc ((SV *)services));
1016
1017 while (end - dec_ofs > 32)
1018 {
1019 HV *ev = newHV ();
1020 U32 dll;
1021 AV *desc;
1022 av_push (services, newRV_noinc ((SV *)ev));
1023
1024 DEC_I (ev, 16, service_id);
1025 decode_field (6);
1026 DEC_I (ev, 1, EIT_schedule_flags);
1027 DEC_I (ev, 1, EIT_present_following_flag);
1028 DEC_I (ev, 3, running_status);
1029 DEC_I (ev, 1, free_CA_mode);
1030
1031 dll = dec_ofs + (decode_field (12) << 3);
1032
1033 desc = decode_descriptors (dll);
1034 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
1035 }
1036
1037 decode_field (32); // skip CRC
1038 break;
1039
1040 default:
1041 DEC_S (hv, length, raw_data);
1042 break;
1043 }
1044
1045 if (decode_overflow)
1046 {
1047 SvREFCNT_dec (hv);
1048 safe_sv_chop (stream, (end + 7) >> 3);
1049 XSRETURN_UNDEF;
1050 }
1051
1052 safe_sv_chop (stream, (dec_ofs + 7) >> 3);
1053 }
1054 else
1055 {
1056 SvREFCNT_dec (hv);
1057 safe_sv_chop (stream, (end + 7) >> 3);
1058 XSRETURN_UNDEF;
1059 }
1060
1061 RETVAL = (SV *)newRV_noinc ((SV *)hv);
1062 OUTPUT:
1063 RETVAL
1064