--- Linux-DVB/DVB.xs 2004/09/08 19:47:30 1.2 +++ Linux-DVB/DVB.xs 2005/04/03 02:16:05 1.3 @@ -244,7 +244,7 @@ #define HVS(hv,name,sv) hv_store (hv, #name, sizeof (#name) - 1, (sv), 0) static void -set_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type) +get_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type) { HVS_I (hv, (*p), frequency); HVS_I (hv, (*p), inversion); @@ -272,6 +272,43 @@ } } +#define HVF_I(hv,struct,member) \ + if (v = hv_fetch (hv, #member, sizeof (#member) - 1, 0)) \ + struct.member = SvIV (*v); \ + else \ + croak ("required hash key '%s' not specified", #member); + +static void +set_parameters (HV *hv, struct dvb_frontend_parameters *p, fe_type_t type) +{ + SV **v; + + HVF_I (hv, (*p), frequency); + HVF_I (hv, (*p), inversion); + + switch (type) + { + case FE_QPSK: + HVF_I (hv, (*p).u.qpsk, symbol_rate); + HVF_I (hv, (*p).u.qpsk, fec_inner); + break; + + case FE_QAM: + HVF_I (hv, (*p).u.qam, symbol_rate); + HVF_I (hv, (*p).u.qam, fec_inner); + HVF_I (hv, (*p).u.qam, modulation); + break; + + case FE_OFDM: + HVF_I (hv, (*p).u.ofdm, bandwidth); + HVF_I (hv, (*p).u.ofdm, code_rate_HP); + HVF_I (hv, (*p).u.ofdm, code_rate_LP); + HVF_I (hv, (*p).u.ofdm, constellation); + HVF_I (hv, (*p).u.ofdm, transmission_mode); + break; + } +} + typedef unsigned char u8; static SV *dec_sv; @@ -327,11 +364,17 @@ return dec_field = r; } +U32 +clamp (U32 len) +{ + return len < 4096 ? len : 0; +} + static SV * text2sv (u8 *data, U32 len) { dSP; - SV *sv = newSVpvn (data, len); + SV *sv = newSVpvn (data, clamp (len)); PUSHMARK (SP); XPUSHs (sv); @@ -342,8 +385,8 @@ } #define DEC_I(hv, bits, name) HVS (hv, name, newSViv (decode_field (bits))) -#define DEC_T(hv, bytes, name) HVS (hv, name, text2sv (dec_data + (dec_ofs >> 3), (bytes))), dec_ofs += (bytes) << 3 -#define DEC_S(hv, bytes, name) HVS (hv, name, newSVpvn (dec_data + (dec_ofs >> 3), (bytes))), dec_ofs += (bytes) << 3 +#define DEC_T(hv, bytes, name) HVS (hv, name, text2sv (dec_data + (dec_ofs >> 3), clamp (bytes))), dec_ofs += clamp (bytes) << 3 +#define DEC_S(hv, bytes, name) HVS (hv, name, newSVpvn (dec_data + (dec_ofs >> 3), clamp (bytes))), dec_ofs += clamp (bytes) << 3 static AV * decode_descriptors (long end) @@ -450,7 +493,21 @@ break; case DT_content: - DEC_S (hv, len, content); + av2 = newAV (); + HVS (hv, items, newRV_noinc ((SV *)av2)); + + while (dec_ofs < end) + { + HV *ev = newHV (); + + DEC_I (ev, 4, content_nibble_level_1); + DEC_I (ev, 4, content_nibble_level_2); + DEC_I (ev, 4, user_nibble_1); + DEC_I (ev, 4, user_nibble_2); + + av_push (av2, newRV_noinc ((SV *)ev)); + } + break; case DT_private_data_specifier: @@ -458,7 +515,8 @@ break; default: - fprintf (stderr, "UNKXXX %x\n", type);//D + //fprintf (stderr, "UNKXXX %x\n", type);//D + case 0: case 0x80: case 0x81: @@ -582,6 +640,23 @@ OUTPUT: RETVAL +int +_set (int fd, SV *parameters, int type) + CODE: + struct dvb_frontend_parameters p; + + if (!SvROK (parameters) || SvTYPE (SvRV (parameters)) != SVt_PVHV) + croak ("Linux::DVB::Frontend::set requires a hash as argument"); + + set_parameters ((HV *)SvRV (parameters), &p, type); + + if (ioctl (fd, FE_SET_FRONTEND, &p) < 0) + XSRETURN_UNDEF; + + RETVAL = 1; + OUTPUT: + RETVAL + SV * _get (int fd, int type) CODE: @@ -592,7 +667,7 @@ XSRETURN_UNDEF; hv = newHV (); - set_parameters (hv, &p, type); + get_parameters (hv, &p, type); RETVAL = (SV *)newRV_noinc ((SV *)hv); OUTPUT: RETVAL @@ -608,7 +683,7 @@ hv = newHV (); HVS_I (hv, e, status); - set_parameters (hv, &e.parameters, type); + get_parameters (hv, &e.parameters, type); RETVAL = (SV *)newRV_noinc ((SV *)hv); OUTPUT: RETVAL