dvb: redo sdt parser to make it more robust

Fixes some problems reported in #hts regarding missing services
(cherry picked from commit 13fad234d5)

Conflicts:

	src/dvb/dvb_tables.c
This commit is contained in:
Adam Sutton 2013-04-09 14:59:22 +01:00
parent 29e3555d61
commit 4280b7c932

View file

@ -334,6 +334,7 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
uint8_t running_status;
#endif
int l;
uint8_t *dlptr, *dptr;
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
@ -356,6 +357,7 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
if (!tdmi) return -1;
}
TRACE("sdt", "onid %04X tsid %04X", onid, tsid);
//hexdump("sdt", ptr, len);
// version = ptr[2] >> 1 & 0x1f;
// section_number = ptr[3];
@ -370,7 +372,6 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
len -= 8;
ptr += 8;
while(len >= 5) {
int save = 0;
service_id = ptr[0] << 8 | ptr[1];
@ -380,13 +381,13 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
#endif
free_ca_mode = (ptr[3] >> 4) & 0x1;
dllen = ((ptr[3] & 0x0f) << 8) | ptr[4];
dlptr = ptr + 5;
TRACE("sdt", " sid %04X running %d free_ca %d",
service_id, running_status, free_ca_mode);
len -= 5;
ptr += 5;
if(dllen > len)
ptr += (5 + dllen);
len -= (5 + dllen);
if (len < 0)
break;
stype = 0;
@ -394,16 +395,18 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
*crid = 0;
while(dllen > 2) {
dtag = ptr[0];
dlen = ptr[1];
dtag = dlptr[0];
dlen = dlptr[1];
dptr = dlptr + 2;
len -= 2; ptr += 2; dllen -= 2;
dlptr += (2 + dlen);
dllen -= (2 + dlen);
if(dlen > len) break;
if(dllen < 0) break;
switch(dtag) {
case DVB_DESC_SERVICE:
if(dvb_desc_service(ptr, dlen, &stype,
if(dvb_desc_service(dptr, dlen, &stype,
provider, sizeof(provider),
chname0, sizeof(chname0)) == 0) {
TRACE("sdt", " stype = %d, provider = %s, name = %s",
@ -427,10 +430,9 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
}
break;
case DVB_DESC_DEF_AUTHORITY:
dvb_desc_def_authority(ptr, dlen, crid, sizeof(crid));
dvb_desc_def_authority(dptr, dlen, crid, sizeof(crid));
break;
}
len -= dlen; ptr += dlen; dllen -= dlen;
}
if (!servicetype_is_tv(stype) &&