ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-DVB/DVB.xs
(Generate patch)

Comparing Linux-DVB/DVB.xs (file contents):
Revision 1.1 by root, Mon Sep 6 06:25:12 2004 UTC vs.
Revision 1.7 by root, Mon Feb 25 04:53:35 2008 UTC

7#include <linux/dvb/frontend.h> 7#include <linux/dvb/frontend.h>
8#include <linux/dvb/dmx.h> 8#include <linux/dvb/dmx.h>
9 9
10#define CONST(name) { #name, name } 10#define CONST(name) { #name, name }
11 11
12typedef int FE_fd;
13
12enum { 14enum {
13 SCT_PAT = 0x00, 15 SCT_PAT = 0x00,
14 SCT_CAT = 0x01, 16 SCT_CAT = 0x01,
15 SCT_PMT = 0x02, 17 SCT_PMT = 0x02,
16 SCT_TSDT = 0x03, 18 SCT_TSDT = 0x03,
17 SCT_NIT = 0x40, 19 SCT_NIT = 0x40,//TODO
18 SCT_NIT_OTHER = 0x41, 20 SCT_NIT_OTHER = 0x41,
19 SCT_SDT = 0x42, 21 SCT_SDT = 0x42,
20 SCT_SDT_OTHER = 0x46, 22 SCT_SDT_OTHER = 0x46,
21 SCT_BAT = 0x4a, 23 SCT_BAT = 0x4a,//TODO
22 SCT_EIT_PRESENT = 0x4e, 24 SCT_EIT_PRESENT = 0x4e,
23 SCT_EIT_PRESENT_OTHER = 0x4f, 25 SCT_EIT_PRESENT_OTHER = 0x4f,
24 SCT_EIT_SCHEDULE0 = 0x50, 26 SCT_EIT_SCHEDULE0 = 0x50,
25 SCT_EIT_SCHEDULE15 = 0x5f, 27 SCT_EIT_SCHEDULE15 = 0x5f,
26 SCT_EIT_SCHEDULE_OTHER0 = 0x60, 28 SCT_EIT_SCHEDULE_OTHER0 = 0x60,
27 SCT_EIT_SCHEDULE_OTHER15 = 0x6f, 29 SCT_EIT_SCHEDULE_OTHER15 = 0x6f,
28 SCT_TDT = 0x70, 30 SCT_TDT = 0x70,
29 SCT_RST = 0x71, 31 SCT_RST = 0x71,
30 SCT_ST = 0x72, 32 SCT_ST = 0x72,
31 SCT_TOT = 0x73, 33 SCT_TOT = 0x73,
32 SCT_RNT = 0x74, 34 SCT_RNT = 0x74,
33 SCT_CST = 0x75, 35 SCT_CST = 0x75,
34 SCT_RCT = 0x76, 36 SCT_RCT = 0x76,
35 SCT_CIT = 0x77, 37 SCT_CIT = 0x77,
36 SCT_MPE = 0x78, 38 SCT_MPE = 0x78,
37 SCT_DIT = 0x7e, 39 SCT_DIT = 0x7e,
38 SCT_SIT = 0x7f, 40 SCT_SIT = 0x7f,
39}; 41};
40 42
41enum { 43enum {
44 DT_network_name = 0x40,
45 DT_service_list = 0x41,
46 DT_satellite_delivery_system = 0x43,
47 DT_cable_delivery_system = 0x44,
48 DT_service = 0x48,
49 DT_country_availability = 0x49,
50 DT_linkage = 0x4a,
42 DT_short_event = 0x4d, 51 DT_short_event = 0x4d,
43 DT_extended_event = 0x4e, 52 DT_extended_event = 0x4e, //NYI
44 DT_component = 0x50, 53 DT_component = 0x50,
45 DT_content = 0x54, 54 DT_content = 0x54,
55 DT_terrestrial_delivery_system = 0x5A,
46 DT_private_data_specifier = 0x5f, 56 DT_private_data_specifier = 0x5f,
47 DT_short_smoothing_buffer = 0x61, //NYI 57 DT_short_smoothing_buffer = 0x61, //NYI
48 DT_scrambling_indicator = 0x65, //NYI 58 DT_scrambling_indicator = 0x65, //NYI
49 DT_PDC = 0x69, 59 DT_PDC = 0x69,
50}; 60};
51 61
52static const struct consts { 62static const struct consts {
53 const char *name; 63 const char *name;
54 const long value; 64 const long value;
172 CONST (DMX_PES_VIDEO), 182 CONST (DMX_PES_VIDEO),
173 CONST (DMX_PES_TELETEXT), 183 CONST (DMX_PES_TELETEXT),
174 CONST (DMX_PES_SUBTITLE), 184 CONST (DMX_PES_SUBTITLE),
175 CONST (DMX_PES_PCR), 185 CONST (DMX_PES_PCR),
176 186
177 CONST (DMX_SCRAMBLING_EV), 187 //CONST (DMX_SCRAMBLING_EV),
178 CONST (DMX_FRONTEND_EV), 188 //CONST (DMX_FRONTEND_EV),
179 189
180 CONST (DMX_CHECK_CRC), 190 CONST (DMX_CHECK_CRC),
181 CONST (DMX_ONESHOT), 191 CONST (DMX_ONESHOT),
182 CONST (DMX_IMMEDIATE_START), 192 CONST (DMX_IMMEDIATE_START),
183 CONST (DMX_KERNEL_CLIENT), 193 CONST (DMX_KERNEL_CLIENT),
190 CONST (DMX_SOURCE_DVR0), 200 CONST (DMX_SOURCE_DVR0),
191 CONST (DMX_SOURCE_DVR1), 201 CONST (DMX_SOURCE_DVR1),
192 CONST (DMX_SOURCE_DVR2), 202 CONST (DMX_SOURCE_DVR2),
193 CONST (DMX_SOURCE_DVR3), 203 CONST (DMX_SOURCE_DVR3),
194 204
195 CONST (DMX_SCRAMBLING_OFF), 205 //CONST (DMX_SCRAMBLING_OFF),
196 CONST (DMX_SCRAMBLING_ON), 206 //CONST (DMX_SCRAMBLING_ON),
197 207
198 // constants defined by this file 208 // constants defined by this file
199 CONST (SCT_PAT), 209 CONST (SCT_PAT),
200 CONST (SCT_CAT), 210 CONST (SCT_CAT),
201 CONST (SCT_PMT), 211 CONST (SCT_PMT),
220 CONST (SCT_RCT), 230 CONST (SCT_RCT),
221 CONST (SCT_CIT), 231 CONST (SCT_CIT),
222 CONST (SCT_MPE), 232 CONST (SCT_MPE),
223 CONST (SCT_DIT), 233 CONST (SCT_DIT),
224 CONST (SCT_SIT), 234 CONST (SCT_SIT),
235
236 CONST (DT_network_name),
237 CONST (DT_service_list),
238 CONST (DT_satellite_delivery_system),
239 CONST (DT_cable_delivery_system),
240 CONST (DT_service),
241 CONST (DT_country_availability),
242 CONST (DT_linkage),
243 CONST (DT_short_event),
244 CONST (DT_extended_event),
245 CONST (DT_component),
246 CONST (DT_content),
247 CONST (DT_terrestrial_delivery_system),
248 CONST (DT_private_data_specifier),
249 CONST (DT_short_smoothing_buffer),
250 CONST (DT_scrambling_indicator),
251 CONST (DT_PDC),
225}; 252};
226 253
227#define HVS_S(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSVpv (struct.member, 0), 0) 254#define HVS_S(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSVpv (struct.member, 0), 0)
228#define HVS_I(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSViv (struct.member), 0) 255#define HVS_I(hv,struct,member) hv_store (hv, #member, sizeof (#member) - 1, newSViv (struct.member), 0)
256#define HVS(hv,name,sv) hv_store (hv, #name, sizeof (#name) - 1, (sv), 0)
229 257
230static void 258static void
231set_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type) 259get_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type)
232{ 260{
233 HVS_I (hv, (*p), frequency); 261 HVS_I (hv, (*p), frequency);
234 HVS_I (hv, (*p), inversion); 262 HVS_I (hv, (*p), inversion);
235 263
236 switch (type) 264 switch (type)
254 HVS_I (hv, (*p).u.ofdm, transmission_mode); 282 HVS_I (hv, (*p).u.ofdm, transmission_mode);
255 break; 283 break;
256 } 284 }
257} 285}
258 286
287#define HVF_I(hv,struct,member) \
288 if (v = hv_fetch (hv, #member, sizeof (#member) - 1, 0)) \
289 struct.member = SvIV (*v); \
290 else \
291 croak ("required hash key '%s' not specified", #member);
292
293static void
294set_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type)
295{
296 SV **v;
297
298 HVF_I (hv, (*p), frequency);
299 HVF_I (hv, (*p), inversion);
300
301 switch (type)
302 {
303 case FE_QPSK:
304 HVF_I (hv, (*p).u.qpsk, symbol_rate);
305 HVF_I (hv, (*p).u.qpsk, fec_inner);
306 break;
307
308 case FE_QAM:
309 HVF_I (hv, (*p).u.qam, symbol_rate);
310 HVF_I (hv, (*p).u.qam, fec_inner);
311 HVF_I (hv, (*p).u.qam, modulation);
312 break;
313
314 case FE_OFDM:
315 HVF_I (hv, (*p).u.ofdm, bandwidth);
316 HVF_I (hv, (*p).u.ofdm, code_rate_HP);
317 HVF_I (hv, (*p).u.ofdm, code_rate_LP);
318 HVF_I (hv, (*p).u.ofdm, constellation);
319 HVF_I (hv, (*p).u.ofdm, transmission_mode);
320 break;
321 }
322}
323
259typedef unsigned char u8; 324typedef unsigned char u8;
260 325
261static SV *dec_sv; 326static SV *dec_sv;
262static u8 *dec_data; 327static u8 *dec_data;
263static long dec_ofs, dec_len8; 328static long dec_ofs, dec_len8;
271{ 336{
272 if (dec_sv) 337 if (dec_sv)
273 SvREFCNT_dec (dec_sv); 338 SvREFCNT_dec (dec_sv);
274 339
275 dec_sv = newSVsv (data); 340 dec_sv = newSVsv (data);
276 dec_data = SvPVbyte (dec_sv, dec_len); 341 dec_data = (u8 *)SvPVbyte (dec_sv, dec_len);
277 dec_ofs = 0; 342 dec_ofs = 0;
278 dec_len8 = dec_len << 3; 343 dec_len8 = dec_len << 3;
279} 344}
280 345
281static U32 346static U32
309 } 374 }
310 375
311 return dec_field = r; 376 return dec_field = r;
312} 377}
313 378
379U32
380clamp (U32 len)
381{
382 return len < 4096
383 && len <= dec_len8 - (dec_ofs >> 3) + 1 /* +1 to detect overflows */
384 ? len : 0;
385}
386
387/* works on SvPOK strings ONLY */
388void
389safe_sv_chop (SV *sv, STRLEN count)
390{
391 if ((U32)count >= (U32)SvCUR (sv))
392 SvCUR_set (sv, 0);
393 else
394 sv_chop (sv, SvPVX (sv) + count);
395}
396
397U32
398bcd_to_int (U32 bcd_number)
399{
400 U32 result = 0;
401 U32 multiplicator = 1;
402
403 while (bcd_number != 0)
404 {
405 result += (bcd_number & 0x0f) * multiplicator;
406 bcd_number >>= 4;
407 multiplicator *= 10;
408 }
409
410 return result;
411}
412
413static SV *
414text2sv (u8 *data, U32 len)
415{
416 dSP;
417 SV *sv = newSVpvn ((char *)data, clamp (len));
418
419 PUSHMARK (SP);
420 XPUSHs (sv);
421 PUTBACK;
422 call_pv ("Linux::DVB::Decode::text", G_VOID);
423
424 return sv;
425}
426
314#define DEC_I(hv, bits, name) hv_store (hv, #name, sizeof (#name) - 1, newSViv (decode_field (bits)), 0) 427#define DEC_I(hv, bits, name) HVS (hv, name, newSViv (decode_field (bits)))
428#define DEC_T(hv, bytes, name) HVS (hv, name, text2sv (dec_data + (dec_ofs >> 3), clamp (bytes))), dec_ofs += clamp (bytes) << 3
315#define DEC_S(hv, bytes, name) hv_store (hv, #name, sizeof (#name) - 1, newSVpvn (dec_data + (dec_ofs >> 3), (bytes)), 0), dec_ofs += (bytes) << 3 429#define DEC_S(hv, bytes, name) HVS (hv, name, newSVpvn ((char *)dec_data + (dec_ofs >> 3), clamp (bytes))), dec_ofs += clamp (bytes) << 3
316 430
317static AV * 431static AV *
318decode_descriptors (long end) 432decode_descriptors (long end)
319{ 433{
320 AV *av = newAV (); 434 AV *av = newAV ();
321 435
322 while (dec_ofs < end) 436 while (dec_ofs < end)
323 { 437 {
324 HV *hv = newHV (); 438 HV *hv = newHV ();
325 U8 type, len, a; 439 U8 type, len, len2;
440 AV *av2;
326 long end; 441 long end, end2;
327 442
328 av_push (av, newRV_noinc ((SV *)hv)); 443 av_push (av, newRV_noinc ((SV *)hv));
329 444
330 DEC_I (hv, 8, type); 445 DEC_I (hv, 8, type);
331 type = dec_field; 446 type = dec_field;
332 len = decode_field (8); 447 len = decode_field (8);
333
334 end = dec_ofs + (len << 3); 448 end = dec_ofs + (len << 3);
335 449
336 if (end > dec_len8) 450 if (end > dec_len8)
337 return av; 451 return av;
338 452
339 switch (type) 453 switch (type)
340 { 454 {
455 case DT_network_name:
456 DEC_T (hv, (end - dec_ofs) >> 3, network_name);
457 break;
458
459 case DT_service_list:
460 {
461 AV *services = newAV ();
462 HVS (hv, services, newRV_noinc ((SV *)services));
463
464 while (dec_ofs < end)
465 {
466 HV *sv = newHV ();
467 av_push (services, newRV_noinc ((SV *)sv));
468
469 DEC_I (sv, 16, service_id);
470 DEC_I (sv, 8, service_type);
471
472 }
473 }
474
475 break;
476
477 case DT_satellite_delivery_system:
478 HVS (hv, frequency, newSVuv (bcd_to_int (decode_field (32))));
479 HVS (hv, orbital_position, newSVnv (bcd_to_int (decode_field (32)) / 10));
480 DEC_I (hv, 1, west_east_flag);
481 DEC_I (hv, 2, polarization);
482 DEC_I (hv, 5, modulation);
483 HVS (hv, symbol_rate, newSVuv (bcd_to_int (decode_field (28))));
484 DEC_I (hv, 4, fec_inner);
485 break;
486
487 case DT_cable_delivery_system:
488 {
489 I16 qam_modulation = -1;
490
491 HVS (hv, frequency, newSVuv (bcd_to_int (decode_field (32))));
492 decode_field (12); // reserved
493 DEC_I (hv, 4, fec_outer);
494
495 DEC_I (hv, 8, modulation);
496
497 if (dec_field >= 1 && dec_field <= 5)
498 qam_modulation = 1 << dec_field + 3;
499
500 HVS (hv, modulation_qam, newSViv (qam_modulation));
501
502 HVS (hv, symbol_rate, newSVuv (bcd_to_int (decode_field (28))));
503 DEC_I (hv, 4, fec_inner);
504
505 break;
506 }
507
508 case DT_service:
509 DEC_I (hv, 8, service_type);
510 len2 = decode_field (8); DEC_T (hv, len2, service_provider_name);
511 len2 = decode_field (8); DEC_T (hv, len2, service_name);
512 break;
513
514 case DT_country_availability:
515 DEC_I (hv, 1, country_availability_flag);
516 decode_field (7);
517
518 DEC_S (hv, (end - dec_ofs) >> 3, private_data);
519 //while (dec_ofs + 24 <= end)
520 // av_push (av,
521 break;
522
523 case DT_linkage:
524 DEC_I (hv, 16, transport_stream_id);
525 DEC_I (hv, 16, original_network_id);
526 DEC_I (hv, 16, service_id);
527 DEC_I (hv, 8, linkage_type);
528
529 if (dec_field == 8)
530 {
531 U32 hot, org;
532
533 DEC_I (hv, 8, hand_over_type); hot = dec_field;
534 decode_field (3);
535 DEC_I (hv, 1, origin_type); org = dec_field;
536
537 if (hot > 0x00 && hot < 0x04)
538 DEC_I (hv, 16, network_id);
539
540 if (org == 0)
541 DEC_I (hv, 16, initial_service_id);
542 }
543
544 DEC_S (hv, (end - dec_ofs) >> 3, private_data);
545 break;
546
341 case DT_PDC: 547 case DT_PDC:
342 decode_field (4); 548 decode_field (4);
343 DEC_I (hv, 20, programme_identification_label); 549 DEC_I (hv, 20, programme_identification_label);
344 break; 550 break;
345 551
347 decode_field (4); 553 decode_field (4);
348 DEC_I (hv, 4, stream_content); 554 DEC_I (hv, 4, stream_content);
349 DEC_I (hv, 8, component_type); 555 DEC_I (hv, 8, component_type);
350 DEC_I (hv, 8, component_tag); 556 DEC_I (hv, 8, component_tag);
351 DEC_S (hv, 3, ISO_639_language_code); 557 DEC_S (hv, 3, ISO_639_language_code);
352 DEC_S (hv, (end - dec_ofs) >> 3, text); 558 DEC_T (hv, (end - dec_ofs) >> 3, text);
353 break; 559 break;
354 560
355 case DT_short_event: 561 case DT_short_event:
356 DEC_S (hv, 3, ISO_639_language_code); 562 DEC_S (hv, 3, ISO_639_language_code);
357 a = decode_field (8); DEC_S (hv, a, event_name); 563 len2 = decode_field (8); DEC_T (hv, len2, event_name);
358 a = decode_field (8); DEC_S (hv, a, text); 564 len2 = decode_field (8); DEC_T (hv, len2, text);
359 break; 565 break;
360 566
567 case DT_extended_event:
568 DEC_I (hv, 4, descriptor_number);
569 DEC_I (hv, 4, last_descriptor_number);
570 DEC_S (hv, 3, ISO_639_language_code);
571
572 len2 = decode_field (8); end2 = dec_ofs + (len2 << 3);
573 av2 = newAV ();
574 HVS (hv, items, newRV_noinc ((SV *)av2));
575
576 while (dec_ofs < end2)
577 {
578 AV *av3 = newAV ();
579 len2 = decode_field (8); av_push (av3, text2sv (dec_data + (dec_ofs >> 3), len2)), dec_ofs += len << 3;
580 len2 = decode_field (8); av_push (av3, text2sv (dec_data + (dec_ofs >> 3), len2)), dec_ofs += len << 3;
581
582 av_push (av2, newRV_noinc ((SV *)av3));
583 }
584
585 len2 = decode_field (8); DEC_T (hv, len2, text);
586 break;
587
361 case DT_content: 588 case DT_content:
362 DEC_S (hv, len, content); 589 av2 = newAV ();
590 HVS (hv, items, newRV_noinc ((SV *)av2));
591
592 while (dec_ofs < end)
593 {
594 HV *ev = newHV ();
595
596 DEC_I (ev, 4, content_nibble_level_1);
597 DEC_I (ev, 4, content_nibble_level_2);
598 DEC_I (ev, 4, user_nibble_1);
599 DEC_I (ev, 4, user_nibble_2);
600
601 av_push (av2, newRV_noinc ((SV *)ev));
602 }
603
363 break; 604 break;
605
606 case DT_terrestrial_delivery_system:
607 {
608 I8 bandwidth_mhz = -1;
609
610 HVS (hv, centre_frequency, newSVuv (decode_field (32) * 10));
611
612 DEC_I (hv, 3, bandwidth);
613
614 if (dec_field <= 3)
615 bandwidth_mhz = 8 - dec_field;
616
617 HVS (hv, bandwidth_mhz, newSViv (bandwidth_mhz));
618
619 DEC_I (hv, 1, priority);
620 DEC_I (hv, 1, time_slicing_indicator);
621 DEC_I (hv, 1, mpe_fec_indicator);
622 decode_field (2); // reserved
623 DEC_I (hv, 2, constellation);
624 DEC_I (hv, 3, hierarchy_information);
625 DEC_I (hv, 3, code_rate_hp_stream);
626 DEC_I (hv, 3, code_rate_lp_stream);
627 DEC_I (hv, 2, guard_interval);
628 DEC_I (hv, 2, transmission_mode);
629 DEC_I (hv, 1, other_frequency_use);
630 decode_field (32);
631 }
632 break;
364 633
365 case DT_private_data_specifier: 634 case DT_private_data_specifier:
366 DEC_I (hv, 32, private_data_specifier); 635 DEC_I (hv, 32, private_data_specifier);
367 break; 636 break;
368 637
369 default: 638 default:
370 fprintf (stderr, "UNKXXX %x\n", type);//D 639 //fprintf (stderr, "UNKXXX %x\n", type);//D
640
371 case 0: 641 case 0:
372 case DT_extended_event:
373 case 0x80: 642 case 0x80:
374 case 0x81: 643 case 0x81:
375 case 0x82: 644 case 0x82:
645 case 0x83:
376 case 0x84: 646 case 0x84:
377 case 0x85: 647 case 0x85:
648 case 0x8d:
649 case 0x8e:
650 case 0xb2:
378 DEC_S (hv, len, raw_data); 651 DEC_S (hv, len, raw_data);
379 break; 652 break;
380 } 653 }
381 654
382 dec_ofs = end; // re-sync, in case of problems 655 dec_ofs = end; // re-sync, in case of problems
402 } 675 }
403 676
404MODULE = Linux::DVB PACKAGE = Linux::DVB::Frontend 677MODULE = Linux::DVB PACKAGE = Linux::DVB::Frontend
405 678
406SV * 679SV *
407_frontend_info (int fd) 680frontend_info (FE_fd fd)
408 CODE: 681 CODE:
409 struct dvb_frontend_info fi; 682 struct dvb_frontend_info fi;
410 HV *hv; 683 HV *hv;
411 684
412 if (ioctl (fd, FE_GET_INFO, &fi) < 0) 685 if (ioctl (fd, FE_GET_INFO, &fi) < 0)
429 RETVAL = (SV *)newRV_noinc ((SV *)hv); 702 RETVAL = (SV *)newRV_noinc ((SV *)hv);
430 OUTPUT: 703 OUTPUT:
431 RETVAL 704 RETVAL
432 705
433long 706long
434_read_status (int fd) 707read_status (FE_fd fd)
435 CODE: 708 CODE:
436 fe_status_t st; 709 fe_status_t st;
437 710
438 if (ioctl (fd, FE_READ_STATUS, &st) < 0) 711 if (ioctl (fd, FE_READ_STATUS, &st) < 0)
439 XSRETURN_UNDEF; 712 XSRETURN_UNDEF;
441 RETVAL = st; 714 RETVAL = st;
442 OUTPUT: 715 OUTPUT:
443 RETVAL 716 RETVAL
444 717
445U32 718U32
446_read_ber (int fd) 719read_ber (FE_fd fd)
447 CODE: 720 CODE:
448 uint32_t ber; 721 uint32_t ber;
449 if (ioctl (fd, FE_READ_BER, &ber) < 0) 722 if (ioctl (fd, FE_READ_BER, &ber) < 0)
450 XSRETURN_UNDEF; 723 XSRETURN_UNDEF;
451 724
452 RETVAL = ber; 725 RETVAL = ber;
453 OUTPUT: 726 OUTPUT:
454 RETVAL 727 RETVAL
455 728
456U32 729U32
457_read_snr (int fd) 730read_snr (FE_fd fd)
458 CODE: 731 CODE:
459 uint32_t ber; 732 uint32_t ber;
460 if (ioctl (fd, FE_READ_SNR, &ber) < 0) 733 if (ioctl (fd, FE_READ_SNR, &ber) < 0)
461 XSRETURN_UNDEF; 734 XSRETURN_UNDEF;
462 735
464 OUTPUT: 737 OUTPUT:
465 RETVAL 738 RETVAL
466 739
467 740
468I16 741I16
469_signal_strength (int fd) 742signal_strength (FE_fd fd)
470 CODE: 743 CODE:
471 int16_t st; 744 int16_t st;
472 if (ioctl (fd, FE_READ_SIGNAL_STRENGTH, &st) < 0) 745 if (ioctl (fd, FE_READ_SIGNAL_STRENGTH, &st) < 0)
473 XSRETURN_UNDEF; 746 XSRETURN_UNDEF;
474 747
476 OUTPUT: 749 OUTPUT:
477 RETVAL 750 RETVAL
478 751
479 752
480U32 753U32
481_uncorrected_blocks (int fd) 754uncorrected_blocks (FE_fd fd)
482 CODE: 755 CODE:
483 uint32_t ubl; 756 uint32_t ubl;
484 if (ioctl (fd, FE_READ_UNCORRECTED_BLOCKS, &ubl) < 0) 757 if (ioctl (fd, FE_READ_UNCORRECTED_BLOCKS, &ubl) < 0)
485 XSRETURN_UNDEF; 758 XSRETURN_UNDEF;
486 759
487 RETVAL = ubl; 760 RETVAL = ubl;
488 OUTPUT: 761 OUTPUT:
489 RETVAL 762 RETVAL
490 763
764int
765_set (int fd, SV *parameters, int type)
766 CODE:
767 struct dvb_frontend_parameters p;
768
769 if (!SvROK (parameters) || SvTYPE (SvRV (parameters)) != SVt_PVHV)
770 croak ("Linux::DVB::Frontend::set requires a hash as argument");
771
772 set_parameters ((HV *)SvRV (parameters), &p, type);
773
774 if (ioctl (fd, FE_SET_FRONTEND, &p) < 0)
775 XSRETURN_UNDEF;
776
777 RETVAL = 1;
778 OUTPUT:
779 RETVAL
780
491SV * 781SV *
492_get (int fd, int type) 782_get (int fd, int type)
493 CODE: 783 CODE:
494 struct dvb_frontend_parameters p; 784 struct dvb_frontend_parameters p;
495 HV *hv; 785 HV *hv;
496 786
497 if (ioctl (fd, FE_GET_FRONTEND, &p) < 0) 787 if (ioctl (fd, FE_GET_FRONTEND, &p) < 0)
498 XSRETURN_UNDEF; 788 XSRETURN_UNDEF;
499 789
500 hv = newHV (); 790 hv = newHV ();
501 set_parameters (hv, &p, type); 791 get_parameters (hv, &p, type);
502 RETVAL = (SV *)newRV_noinc ((SV *)hv); 792 RETVAL = (SV *)newRV_noinc ((SV *)hv);
503 OUTPUT: 793 OUTPUT:
504 RETVAL 794 RETVAL
505 795
506SV * 796SV *
512 if (ioctl (fd, FE_GET_EVENT, &e) < 0) 802 if (ioctl (fd, FE_GET_EVENT, &e) < 0)
513 XSRETURN_UNDEF; 803 XSRETURN_UNDEF;
514 804
515 hv = newHV (); 805 hv = newHV ();
516 HVS_I (hv, e, status); 806 HVS_I (hv, e, status);
517 set_parameters (hv, &e.parameters, type); 807 get_parameters (hv, &e.parameters, type);
518 RETVAL = (SV *)newRV_noinc ((SV *)hv); 808 RETVAL = (SV *)newRV_noinc ((SV *)hv);
809 OUTPUT:
810 RETVAL
811
812int
813diseqc_reset_overload (FE_fd fd)
814 CODE:
815 RETVAL = !!ioctl (fd, FE_DISEQC_RESET_OVERLOAD);
816 OUTPUT:
817 RETVAL
818
819int
820diseqc_voltage (FE_fd fd, int volts)
821 CODE:
822 RETVAL = !!ioctl (fd, FE_SET_VOLTAGE, volts == 18
823 ? SEC_VOLTAGE_18
824 : SEC_VOLTAGE_13);
825 OUTPUT:
826 RETVAL
827
828int
829diseqc_tone (FE_fd fd, int on)
830 CODE:
831 RETVAL = !!ioctl (fd, FE_SET_TONE, on ? SEC_TONE_ON : SEC_TONE_OFF);
832 OUTPUT:
833 RETVAL
834
835int
836diseqc_send_burst (FE_fd fd, int type)
837 CODE:
838 RETVAL = !!ioctl (fd, FE_DISEQC_SEND_BURST, type ? SEC_MINI_B : SEC_MINI_A);
839 OUTPUT:
840 RETVAL
841
842int
843diseqc_cmd (FE_fd fd, SV *command_)
844 CODE:
845{
846 STRLEN len;
847 char *command = SvPVbyte (command_, len);
848 struct dvb_diseqc_master_cmd cmd;
849
850 memcpy (cmd.msg, command_, len);
851 cmd.msg_len = len;
852 RETVAL = !!ioctl (fd, FE_DISEQC_SEND_MASTER_CMD, &cmd);
853}
854 OUTPUT:
855 RETVAL
856
857SV *
858diseqc_reply (FE_fd fd, int timeout_ms)
859 CODE:
860{
861 struct dvb_diseqc_slave_reply rep;
862 rep.timeout = timeout_ms;
863
864 if (!!ioctl (fd, FE_DISEQC_RECV_SLAVE_REPLY, &rep))
865 RETVAL = newSVpvn ((char *)rep.msg, rep.msg_len);
866 else
867 RETVAL = &PL_sv_undef;
868}
519 OUTPUT: 869 OUTPUT:
520 RETVAL 870 RETVAL
521 871
522MODULE = Linux::DVB PACKAGE = Linux::DVB::Demux 872MODULE = Linux::DVB PACKAGE = Linux::DVB::Demux
523 873
583 RETVAL 933 RETVAL
584 934
585MODULE = Linux::DVB PACKAGE = Linux::DVB::Decode PREFIX = decode_ 935MODULE = Linux::DVB PACKAGE = Linux::DVB::Decode PREFIX = decode_
586 936
587void 937void
588set (SV *data) 938decode_set (SV *data)
589 CODE: 939 CODE:
590 940
591int 941int
592len () 942decode_len ()
593 CODE: 943 CODE:
594 RETVAL = (dec_ofs + 7) >> 3; 944 RETVAL = (dec_ofs + 7) >> 3;
595 OUTPUT: 945 OUTPUT:
596 RETVAL 946 RETVAL
597 947
598U32 948U32
599field (int bits) 949decode_field (int bits)
600 950
601SV * 951SV *
602si (SV *stream) 952decode_si (SV *stream)
603 CODE: 953 CODE:
604 HV *hv = newHV (); 954 HV *hv = newHV ();
605 955
956 int syntax_indicator;
606 U8 table_id; 957 U8 table_id;
607 U16 length; 958 U16 length;
608 long end; 959 long end;
609 960
610 decode_set (stream); 961 decode_set (stream);
612 do { 963 do {
613 DEC_I (hv, 8, table_id); 964 DEC_I (hv, 8, table_id);
614 table_id = dec_field; 965 table_id = dec_field;
615 } while (table_id == 0xff); 966 } while (table_id == 0xff);
616 967
617 DEC_I (hv, 1, section_syntax_indicator); 968 syntax_indicator = decode_field (1);
969 HVS (hv, section_syntax_indicator, newSViv (syntax_indicator));
970
618 decode_field (1); 971 decode_field (1);
619 decode_field (2); 972 decode_field (2);
620 973
621 length = decode_field (12); 974 length = decode_field (12);
622 end = dec_ofs + (length << 3); 975 end = dec_ofs + (length << 3);
623 976
977 if (syntax_indicator)
978 {
624 switch (table_id) 979 switch (table_id)
625 { 980 {
981 case SCT_NIT:
982 case SCT_NIT_OTHER:
983 {
984 U16 descriptor_end_offset;
985
986 DEC_I (hv, 16, network_id);
987 decode_field (2); // reserved
988 DEC_I (hv, 5, version_number);
989 DEC_I (hv, 1, current_next_indicator);
990 DEC_I (hv, 8, section_number);
991 DEC_I (hv, 8, last_section_number);
992 decode_field (4); // reserved
993
994 AV *desc;
995 descriptor_end_offset = dec_ofs + (decode_field (12) << 3);
996 desc = decode_descriptors (descriptor_end_offset);
997 HVS (hv,network_descriptors, newRV_noinc ((SV *)desc));
998
999 decode_field (4); //reserved
1000 decode_field (12); // Skip length, we read until the end
1001
1002 AV *events = newAV ();
1003 HVS (hv, events, newRV_noinc ((SV *)events));
1004 while (end - dec_ofs > 32)
1005 {
1006 long dll;
1007 HV *ev = newHV ();
1008 av_push (events, newRV_noinc ((SV *)ev));
1009
1010 DEC_I (ev, 16, transport_stream_id);
1011 DEC_I (ev, 16, original_network_id);
1012 decode_field (4);
1013
1014 dll = dec_ofs + (decode_field (12) << 3);
1015 desc = decode_descriptors (dll);
1016 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
1017 }
1018
1019 decode_field (32); // skip CRC
1020 }
1021
1022 break;
1023
626 case SCT_EIT_PRESENT: 1024 case SCT_EIT_PRESENT:
627 case SCT_EIT_PRESENT_OTHER: 1025 case SCT_EIT_PRESENT_OTHER:
628 case SCT_EIT_SCHEDULE0...SCT_EIT_SCHEDULE15: //GCC 1026 case SCT_EIT_SCHEDULE0...SCT_EIT_SCHEDULE15: //GCC
629 case SCT_EIT_SCHEDULE_OTHER0...SCT_EIT_SCHEDULE_OTHER15: //GCC 1027 case SCT_EIT_SCHEDULE_OTHER0...SCT_EIT_SCHEDULE_OTHER15: //GCC
630 DEC_I (hv, 16, service_id);
631 decode_field (2);
632 DEC_I (hv, 5, version_number);
633 DEC_I (hv, 1, current_next_indicator);
634 DEC_I (hv, 8, section_number);
635 DEC_I (hv, 8, last_section_number);
636 DEC_I (hv, 16, transport_stream_id);
637 DEC_I (hv, 16, original_network_id);
638 DEC_I (hv, 8, segment_last_section_number);
639 DEC_I (hv, 8, last_table_id);
640
641 AV *events = newAV ();
642 hv_store (hv, "events", 6, newRV_noinc ((SV *)events), 0);
643
644 while (end - dec_ofs > 32)
645 {
646 long dll;
647 AV *desc;
648 HV *ev = newHV ();
649 av_push (events, newRV_noinc ((SV *)ev));
650
651 DEC_I (ev, 16, event_id);
652 DEC_I (ev, 16, start_time_mjd);
653 DEC_I (ev, 24, start_time_hms);
654 DEC_I (ev, 24, duration);
655 DEC_I (ev, 3, running_status);
656 DEC_I (ev, 1, free_CA_mode);
657
658 dll = dec_ofs + (decode_field (12) << 3);
659
660 desc = decode_descriptors (dll);
661 hv_store (ev, "descriptors", 11, newRV_noinc ((SV *)desc), 0);
662 }
663
664 decode_field (32); // skip CRC
665
666 break;
667#if 0 // service desc table
668 case SCT_SDT:
669 case SCT_SDT_OTHER:
670
671 AV *events = newAV ();
672 hv_store (hv, "events", 0, newRV_noinc (events), 0);
673
674 while (end - dec_ofs > 32)
675 {
676 HV *ev = newHV ();
677 U32 dll;
678 av_push (events, newRV_noinc (ev));
679
680 DEC_I (ev, 16, service_id);
681 decode_field (6);
682 DEC_I (ev, 1, EIT_schedule_flags);
683 DEC_I (ev, 1, EIT_present_following_flag);
684 DEC_I (ev, 3, running_status);
685 DEC_I (ev, 1, free_CA_mode);
686
687 dll = decode_field (12);
688 1028 {
1029 DEC_I (hv, 16, service_id);
1030 decode_field (2);
1031 DEC_I (hv, 5, version_number);
1032 DEC_I (hv, 1, current_next_indicator);
1033 DEC_I (hv, 8, section_number);
1034 DEC_I (hv, 8, last_section_number);
1035 DEC_I (hv, 16, transport_stream_id);
1036 DEC_I (hv, 16, original_network_id);
1037 DEC_I (hv, 8, segment_last_section_number);
1038 DEC_I (hv, 8, last_table_id);
1039
1040 AV *events = newAV ();
1041 HVS (hv, events, newRV_noinc ((SV *)events));
1042
1043 while (end - dec_ofs > 32)
1044 {
1045 long dll;
1046 AV *desc;
1047 HV *ev = newHV ();
1048 av_push (events, newRV_noinc ((SV *)ev));
1049
1050 DEC_I (ev, 16, event_id);
1051 DEC_I (ev, 16, start_time_mjd);
1052 DEC_I (ev, 24, start_time_hms);
1053 DEC_I (ev, 24, duration);
1054 DEC_I (ev, 3, running_status);
1055 DEC_I (ev, 1, free_CA_mode);
1056
1057 dll = dec_ofs + (decode_field (12) << 3);
1058
1059 desc = decode_descriptors (dll);
1060 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
1061 }
1062
1063 decode_field (32); // skip CRC
1064 }
1065
1066 break;
1067
1068 case SCT_SDT:
1069 case SCT_SDT_OTHER:
1070 DEC_I (hv, 16, transport_stream_id);
1071 decode_field (2);
1072 DEC_I (hv, 5, version_number);
1073 DEC_I (hv, 1, current_next_indicator);
1074 DEC_I (hv, 8, section_number);
1075 DEC_I (hv, 8, last_section_number);
1076 DEC_I (hv, 16, original_network_id);
1077 decode_field (8);
1078
1079 AV *services = newAV ();
1080 HVS (hv, services, newRV_noinc ((SV *)services));
1081
1082 while (end - dec_ofs > 32)
1083 {
1084 HV *ev = newHV ();
1085 U32 dll;
1086 AV *desc;
1087 av_push (services, newRV_noinc ((SV *)ev));
1088
1089 DEC_I (ev, 16, service_id);
1090 decode_field (6);
1091 DEC_I (ev, 1, EIT_schedule_flags);
1092 DEC_I (ev, 1, EIT_present_following_flag);
1093 DEC_I (ev, 3, running_status);
689 DEC_I (ev, 1, free_CA_mode); 1094 DEC_I (ev, 1, free_CA_mode);
1095
1096 dll = dec_ofs + (decode_field (12) << 3);
1097
1098 desc = decode_descriptors (dll);
1099 HVS (ev, descriptors, newRV_noinc ((SV *)desc));
690 } 1100 }
691 1101
692 decode_field (32); // skip CRC 1102 decode_field (32); // skip CRC
693 //DEC_S (hv, length + 3 - (dec_ofs >> 3), raw_data);
694 break; 1103 break;
695#endif 1104
696 default: 1105 default:
697 DEC_S (hv, length, raw_data); 1106 DEC_S (hv, length, raw_data);
698 break; 1107 break;
1108 }
1109
1110 if (decode_overflow)
1111 {
1112 SvREFCNT_dec (hv);
1113 safe_sv_chop (stream, (end + 7) >> 3);
1114 XSRETURN_UNDEF;
1115 }
1116
1117 safe_sv_chop (stream, (dec_ofs + 7) >> 3);
699 } 1118 }
700 1119 else
701 if (decode_overflow)
702 { 1120 {
703 SvREFCNT_dec (hv); 1121 SvREFCNT_dec (hv);
1122 safe_sv_chop (stream, (end + 7) >> 3);
704 XSRETURN_UNDEF; 1123 XSRETURN_UNDEF;
705 } 1124 }
706 1125
707 sv_chop (stream, SvPVX (stream) + ((dec_ofs + 7) >> 3));
708
709 RETVAL = (SV *)newRV_noinc ((SV *)hv); 1126 RETVAL = (SV *)newRV_noinc ((SV *)hv);
710 OUTPUT: 1127 OUTPUT:
711 RETVAL 1128 RETVAL
712 1129

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines