Commit a0c759a9 authored by Christophe Massiot's avatar Christophe Massiot

* dvb/si.h: Add handling of service list, linkage and private data specifier...

* dvb/si.h: Add handling of service list, linkage and private data specifier descriptors, as well as EICTA's LCN and HD_SIMULCAST_LCN. * dvb/si_print.h: Store the last private data specifier and use it to call the private print functions.
parent 2e37c440
...@@ -358,6 +358,58 @@ static inline void desc40_print(const uint8_t *p_desc, ...@@ -358,6 +358,58 @@ static inline void desc40_print(const uint8_t *p_desc,
free(psz_network_name); free(psz_network_name);
} }
/*****************************************************************************
* Descriptor 0x41: Service list descriptor
*****************************************************************************/
#define DESC41_HEADER_SIZE DESC_HEADER_SIZE
#define DESC41_SERVICE_SIZE 3
static inline uint8_t *desc41_get_service(uint8_t *p_desc, uint8_t n)
{
uint8_t *p_desc_n = p_desc + DESC41_HEADER_SIZE + n * DESC41_SERVICE_SIZE;
if (p_desc_n + DESC41_SERVICE_SIZE - p_desc
> desc_get_length(p_desc) + DESC41_HEADER_SIZE)
return NULL;
return p_desc_n;
}
static inline uint16_t desc41n_get_sid(const uint8_t *p_desc_n)
{
return (p_desc_n[0] << 8) | p_desc_n[1];
}
static inline uint8_t desc41n_get_type(const uint8_t *p_desc_n)
{
return p_desc_n[2];
}
static inline bool desc41_validate(const uint8_t *p_desc)
{
return !(desc_get_length(p_desc) % DESC41_SERVICE_SIZE);
}
static inline void desc41_print(uint8_t *p_desc, f_print pf_print,
void *opaque, print_type_t i_print_type)
{
uint8_t j = 0;
uint8_t *p_desc_n;
while ((p_desc_n = desc41_get_service(p_desc, j)) != NULL) {
j++;
switch (i_print_type) {
case PRINT_XML:
pf_print(opaque,
"<SERVICE_LIST_DESC sid=\"%hu\" type=\"%hhu\" />",
desc41n_get_sid(p_desc_n), desc41n_get_type(p_desc_n));
break;
default:
pf_print(opaque,
" - desc 41 service_list sid=%hu type=%hhu",
desc41n_get_sid(p_desc_n), desc41n_get_type(p_desc_n));
}
}
}
/***************************************************************************** /*****************************************************************************
* Descriptor 0x43: Satellite delivery system descriptor * Descriptor 0x43: Satellite delivery system descriptor
*****************************************************************************/ *****************************************************************************/
...@@ -736,6 +788,54 @@ static inline void desc48_print(const uint8_t *p_desc, ...@@ -736,6 +788,54 @@ static inline void desc48_print(const uint8_t *p_desc,
free(psz_service); free(psz_service);
} }
/*****************************************************************************
* Descriptor 0x4a: Linkage descriptor (partially implemented)
*****************************************************************************/
#define DESC4A_HEADER_SIZE (DESC_HEADER_SIZE + 7)
static inline uint16_t desc4a_get_tsid(const uint8_t *p_desc)
{
return (p_desc[2] << 8) | p_desc[3];
}
static inline uint16_t desc4a_get_onid(const uint8_t *p_desc)
{
return (p_desc[4] << 8) | p_desc[5];
}
static inline uint16_t desc4a_get_sid(const uint8_t *p_desc)
{
return (p_desc[6] << 8) | p_desc[7];
}
static inline uint8_t desc4a_get_linkage(const uint8_t *p_desc)
{
return p_desc[8];
}
static inline bool desc4a_validate(const uint8_t *p_desc)
{
return desc_get_length(p_desc) >= DESC4A_HEADER_SIZE - DESC_HEADER_SIZE;
}
static inline void desc4a_print(const uint8_t *p_desc, f_print pf_print,
void *opaque, print_type_t i_print_type)
{
switch (i_print_type) {
case PRINT_XML:
pf_print(opaque,
"<LINKAGE_DESC tsid=\"%hu\" onid=\"%hu\" sid=\"%hu\" linkage=\"%hhu\" />",
desc4a_get_tsid(p_desc), desc4a_get_onid(p_desc),
desc4a_get_sid(p_desc), desc4a_get_linkage(p_desc));
break;
default:
pf_print(opaque,
" - desc 4a linkage tsid=%hu onid=%hu sid=%hu linkage=%hhu",
desc4a_get_tsid(p_desc), desc4a_get_onid(p_desc),
desc4a_get_sid(p_desc), desc4a_get_linkage(p_desc));
}
}
/***************************************************************************** /*****************************************************************************
* Descriptor 0x56: Teletext descriptor * Descriptor 0x56: Teletext descriptor
*****************************************************************************/ *****************************************************************************/
...@@ -1003,10 +1103,45 @@ static inline void desc5a_print(const uint8_t *p_desc, f_print pf_print, ...@@ -1003,10 +1103,45 @@ static inline void desc5a_print(const uint8_t *p_desc, f_print pf_print,
} }
} }
/*****************************************************************************
* Descriptor 0x5f: Private data specifier descriptor
*****************************************************************************/
#define DESC5F_HEADER_SIZE (DESC_HEADER_SIZE + 4)
static inline void desc5f_init(uint8_t *p_desc)
{
desc_set_tag(p_desc, 0x5f);
}
static inline uint32_t desc5f_get_specifier(const uint8_t *p_desc)
{
return (p_desc[2] << 24) | (p_desc[3] << 16) |
(p_desc[4] << 8) | p_desc[5];
}
static inline bool desc5f_validate(const uint8_t *p_desc)
{
return desc_get_length(p_desc) >= DESC5F_HEADER_SIZE - DESC_HEADER_SIZE;
}
static inline void desc5f_print(const uint8_t *p_desc, f_print pf_print,
void *opaque, print_type_t i_print_type)
{
switch (i_print_type) {
case PRINT_XML:
pf_print(opaque, "<PRIVATE_DATA_SPECIFIER_DESC specifier=\"%u\" />",
desc5f_get_specifier(p_desc));
break;
default:
pf_print(opaque, " - desc 5f private data specifier=%u",
desc5f_get_specifier(p_desc));
}
}
/***************************************************************************** /*****************************************************************************
* Descriptor 0x6a: AC-3 descriptor * Descriptor 0x6a: AC-3 descriptor
*****************************************************************************/ *****************************************************************************/
#define DESC6A_HEADER_SIZE 3 #define DESC6A_HEADER_SIZE (DESC_HEADER_SIZE + 1)
static inline void desc6a_init(uint8_t *p_desc) static inline void desc6a_init(uint8_t *p_desc)
{ {
...@@ -1035,6 +1170,94 @@ static inline void desc6a_print(const uint8_t *p_desc, f_print pf_print, ...@@ -1035,6 +1170,94 @@ static inline void desc6a_print(const uint8_t *p_desc, f_print pf_print,
} }
} }
/*****************************************************************************
* Descriptor 0x83: Logical channel descriptor (IEC/CENELEC 62 216)
* Only valid if a private data specifier descriptor 28 is present before.
*****************************************************************************/
#define DESC83P28_HEADER_SIZE DESC_HEADER_SIZE
#define DESC83P28_SERVICE_SIZE 4
static inline void desc83p28_init(uint8_t *p_desc)
{
desc_set_tag(p_desc, 0x83);
}
static inline uint8_t *desc83p28_get_service(uint8_t *p_desc, uint8_t n)
{
uint8_t *p_desc_n = p_desc + DESC83P28_HEADER_SIZE
+ n * DESC83P28_SERVICE_SIZE;
if (p_desc_n + DESC83P28_SERVICE_SIZE - p_desc
> desc_get_length(p_desc) + DESC83P28_HEADER_SIZE)
return NULL;
return p_desc_n;
}
static inline uint16_t desc83p28n_get_sid(const uint8_t *p_desc_n)
{
return (p_desc_n[0] << 8) | p_desc_n[1];
}
static inline bool desc83p28n_get_visible(const uint8_t *p_desc_n)
{
return !!(p_desc_n[2] & 0x80);
}
static inline uint16_t desc83p28n_get_lcn(const uint8_t *p_desc_n)
{
return ((p_desc_n[2] & 0x3) << 8) | p_desc_n[3];
}
static inline bool desc83p28_validate(const uint8_t *p_desc)
{
return !(desc_get_length(p_desc) % DESC83P28_SERVICE_SIZE);
}
static inline void desc83p28_print(uint8_t *p_desc, f_print pf_print,
void *opaque, print_type_t i_print_type)
{
uint8_t j = 0;
uint8_t *p_desc_n;
while ((p_desc_n = desc83p28_get_service(p_desc, j)) != NULL) {
j++;
switch (i_print_type) {
case PRINT_XML:
pf_print(opaque,
"<%s sid=\"%hu\" visible=\"%d\" lcn=\"%hu\" />",
desc_get_tag(p_desc) == 0x88 ? "HD_SIMULCAST_LCN_DESC" : "LCN_DESC",
desc83p28n_get_sid(p_desc_n),
desc83p28n_get_visible(p_desc_n) ? 1 : 0,
desc83p28n_get_lcn(p_desc_n));
break;
default:
pf_print(opaque,
" - desc %hhu lcn sid=%hu%s lcn=%hu", desc_get_tag(p_desc),
desc83p28n_get_sid(p_desc_n),
desc83p28n_get_visible(p_desc_n) ? " visible" : "",
desc83p28n_get_lcn(p_desc_n));
}
}
}
/*****************************************************************************
* Descriptor 0x88: HD simulcast logical channel descriptor (IEC/CENELEC 62 216)
* Only valid if a private data specifier descriptor 28 is present before.
*****************************************************************************/
#define DESC88P28_HEADER_SIZE DESC83P28_HEADER_SIZE
#define DESC88P28_SERVICE_SIZE DESC83P28_SERVICE_SIZE
static inline void desc88p28_init(uint8_t *p_desc)
{
desc_set_tag(p_desc, 0x88);
}
#define desc88p28_get_service desc83p28_get_service
#define desc88p28_get_sid desc83p28_get_sid
#define desc88p28_get_visible desc83p28_get_visible
#define desc88p28_get_lcn desc83p28_get_lcn
#define desc88p28_validate desc83p28_validate
#define desc88p28_print desc83p28_print
/***************************************************************************** /*****************************************************************************
* Network Information Table * Network Information Table
*****************************************************************************/ *****************************************************************************/
......
...@@ -39,6 +39,7 @@ static inline void descs_print(uint8_t *p_descs, ...@@ -39,6 +39,7 @@ static inline void descs_print(uint8_t *p_descs,
{ {
uint16_t j = 0; uint16_t j = 0;
uint8_t *p_desc; uint8_t *p_desc;
uint32_t i_private_data_specifier = 0;
while ((p_desc = descs_get_desc(p_descs, j)) != NULL) { while ((p_desc = descs_get_desc(p_descs, j)) != NULL) {
uint8_t i_tag = desc_get_tag(p_desc); uint8_t i_tag = desc_get_tag(p_desc);
...@@ -46,6 +47,29 @@ static inline void descs_print(uint8_t *p_descs, ...@@ -46,6 +47,29 @@ static inline void descs_print(uint8_t *p_descs,
desc_print_begin(p_desc, pf_print, print_opaque, i_print_type); desc_print_begin(p_desc, pf_print, print_opaque, i_print_type);
if (i_private_data_specifier == 0x28) {
/* EICTA */
switch (i_tag) {
#define CASE_DESC(id) \
case 0x##id: \
if (desc##id##p28_validate(p_desc)) \
desc##id##p28_print(p_desc, pf_print, print_opaque, \
i_print_type); \
else \
desc_print_error(p_desc, pf_print, print_opaque, \
i_print_type); \
goto print_end;
CASE_DESC(83)
CASE_DESC(88)
#undef CASE_DESC
default:
break;
}
}
switch (i_tag) { switch (i_tag) {
#define CASE_DESC(id) \ #define CASE_DESC(id) \
case 0x##id: \ case 0x##id: \
...@@ -71,20 +95,34 @@ static inline void descs_print(uint8_t *p_descs, ...@@ -71,20 +95,34 @@ static inline void descs_print(uint8_t *p_descs,
CASE_DESC(09) CASE_DESC(09)
CASE_DESC(0a) CASE_DESC(0a)
CASE_DESC_ICONV(40) CASE_DESC_ICONV(40)
CASE_DESC(41)
CASE_DESC(43) CASE_DESC(43)
CASE_DESC(44) CASE_DESC(44)
CASE_DESC(46) CASE_DESC(46)
CASE_DESC_ICONV(48) CASE_DESC_ICONV(48)
CASE_DESC(4a)
CASE_DESC(56) CASE_DESC(56)
CASE_DESC(59) CASE_DESC(59)
CASE_DESC(5a) CASE_DESC(5a)
CASE_DESC(6a) CASE_DESC(6a)
#undef CASE_DESC
#undef CASE_DESC_ICONV
case 0x5f:
if (desc5f_validate(p_desc)) {
desc5f_print(p_desc, pf_print, print_opaque, i_print_type);
i_private_data_specifier = desc5f_get_specifier(p_desc);
} else
desc_print_error(p_desc, pf_print, print_opaque, i_print_type);
break;
default: default:
desc_print(p_desc, pf_print, print_opaque, i_print_type); desc_print(p_desc, pf_print, print_opaque, i_print_type);
break; break;
} }
print_end:
desc_print_end(p_desc, pf_print, print_opaque, i_print_type); desc_print_end(p_desc, pf_print, print_opaque, i_print_type);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment