diff --git a/src/epg.c b/src/epg.c index cbbd4314..50108762 100644 --- a/src/epg.c +++ b/src/epg.c @@ -1318,6 +1318,15 @@ epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, channel_t *ch ) return (epg_broadcast_t*)_epg_object_find_by_id(id); } +epg_broadcast_t *epg_broadcast_find_by_eid ( int eid, channel_t *ch ) +{ + epg_broadcast_t *e; + RB_FOREACH(e, &ch->ch_epg_schedule, sched_link) { + if (e->dvb_eid == eid) return e; + } + return NULL; +} + int epg_broadcast_set_episode ( epg_broadcast_t *broadcast, epg_episode_t *episode ) { diff --git a/src/epg.h b/src/epg.h index a5ea1367..defa092d 100644 --- a/src/epg.h +++ b/src/epg.h @@ -283,6 +283,7 @@ struct epg_broadcast { epg_object_t; ///< Parent object + int dvb_eid; ///< DVB Event ID time_t start; ///< Start time time_t stop; ///< End time @@ -312,6 +313,7 @@ struct epg_broadcast epg_broadcast_t *epg_broadcast_find_by_time ( struct channel *ch, time_t start, time_t stop, int create, int *save ); epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, struct channel *ch ); +epg_broadcast_t *epg_broadcast_find_by_eid ( int eid, struct channel *ch ); /* Mutators */ int epg_broadcast_set_episode ( epg_broadcast_t *b, epg_episode_t *e ) diff --git a/src/epggrab/opentv.c b/src/epggrab/opentv.c index be0c6017..71160ffb 100644 --- a/src/epggrab/opentv.c +++ b/src/epggrab/opentv.c @@ -168,21 +168,28 @@ static int _opentv_prov_load ( const char *key, htsmsg_t *m ) * Parser * ***********************************************************************/ +static epggrab_channel_t *_opentv_find_channel ( int cid, int create, int *save ) +{ + char chid[16]; + sprintf(chid, "opentv-%d", cid); + return epggrab_module_channel_find(&_opentv_mod, chid, create, save); +} + static char *_parse_string ( opentv_prov_t *prov, uint8_t *buf, int len ) { return huffman_decode(prov->dict->codes, buf, len, 0x20); } -static int _parse_record ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t eid ) +static int _parse_record ( opentv_prov_t *prov, uint8_t *buf, int len, epg_broadcast_t *ebc, int *save ) { + epg_episode_t *ee; char *str; uint8_t rtag = buf[0]; uint8_t rlen = buf[1]; - printf("_parse_record(): rtag=%02X, rlen=%d\n", rtag, rlen); if (rlen+2 > len) return rlen+2; switch (rtag) { - case 0xb5: #if 0 + case 0xb5: str = _parse_string(buf+2, rlen); if (str) { printf("EID: %d, TITLE: %s\n", eid, str); @@ -193,16 +200,17 @@ static int _parse_record ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t case 0xb9: str = _parse_string(prov, buf+2, rlen); if (str) { - printf("EID: %d, SUMMARY: %s\n", eid, str); + char *uri = md5sum(str); + ee = epg_episode_find_by_uri(uri, 1, save); + if (ee) *save |= epg_episode_set_summary(ee, str); + if (ee) *save |= epg_broadcast_set_episode(ebc, ee); free(str); + free(uri); } break; case 0xbb: - str = _parse_string(prov, buf+2, rlen); - if (str) { - printf("EID: %d, DESCRIPTION: %s\n", eid, str); - free(str); - } + //str = _parse_string(prov, buf+2, rlen); + // TODO break; case 0xc1: //_parse_series_link(buf+2, rlen); @@ -213,15 +221,16 @@ static int _parse_record ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t return rlen + 2; } -static int _parse_summary ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t cid ) +static int _parse_summary ( opentv_prov_t *prov, uint8_t *buf, int len, channel_t *ch, int *save ) { + epg_broadcast_t *ebc; uint16_t eid = ((uint16_t)buf[0] << 8) | buf[1]; int slen = ((int)buf[2] & 0xf << 8) | buf[3]; int i = 4; - printf("_parse_summary(): cid=%d, eid=%d, slen=%d\n", cid, eid, slen); + if (!(ebc = epg_broadcast_find_by_eid(eid, ch))) return slen+4; if (slen+4 > len) return slen+4; while (i < slen+4) { - i += _parse_record(prov, buf+i, len-i, eid); + i += _parse_record(prov, buf+i, len-i, ebc, save); } return slen+4; } @@ -229,21 +238,20 @@ static int _parse_summary ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t static int _opentv_summary_callback ( th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tid, void *p ) { - // TODO: currently this will only get summary tables! + int save = 0; int i = 0; - uint16_t cid, mjd; - //if (len < 20) return 0; + uint16_t cid;//, mjd; + epggrab_channel_t *ec; + if (len < 20) return 0; cid = ((uint16_t)buf[0] << 8) | buf[1]; - mjd = ((uint16_t)buf[5] << 8) | buf[6]; - printf("summary callback(): len=%d, cid=%d, mjd=%d\n", len, cid, mjd); - for ( i = 0; i < 100; i++ ) { - printf("0x%02x ", buf[i]); - } - printf("\n"); + if (!(ec = _opentv_find_channel(cid, 0, NULL))) return 0; + if (!ec->channel) return 0; + //mjd = ((uint16_t)buf[5] << 8) | buf[6]; i = 7; while (i < len) { - i += _parse_summary((opentv_prov_t*)p, buf+i, len-i, cid); + i += _parse_summary((opentv_prov_t*)p, buf+i, len-i, ec->channel, &save); } + if (save) epg_updated(); return 0; } @@ -268,20 +276,15 @@ static int _opentv_channel_callback ( th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tid, void *p ) { static epggrab_channel_t *ec; - int tsid, cid, cnum, bid; + int tsid, cid, cnum; uint16_t sid; int i, j, k, tdlen, dlen, dtag, tslen; - char chid[16]; channel_t *ch; if (tid != 0x4a) return 0; // TODO: bouqets - bid = ((int)buf[0] << 8) | buf[1]; - printf("BID: %d\n", bid); i = 7 + ((((int)buf[5] & 0xf) << 8) | buf[6]); tslen = (((int)buf[i] & 0xf) << 8) | buf[i+1]; - printf("TSLEN: %d\n", tslen); - // TODO: this isn't quite right (should use tslen) i += 2; while (tslen > 0) { tsid = ((int)buf[i] << 8) | buf[i+1]; @@ -296,7 +299,6 @@ static int _opentv_channel_callback k = j + 2; j += (dlen + 2); tdlen -= (dlen + 2); - printf("dtag = 0x%02x, dlen=%d\n", dtag, dlen); if (dtag == 0xb1) { k += 2; dlen -= 2; @@ -308,18 +310,13 @@ static int _opentv_channel_callback /* Find the channel */ ch = _find_channel(tsid, sid); if (ch) { - printf("FOUND tsid=%d, sid=%d, cid=%d, num=%d, ch=%s\n", - tsid, sid, cid, cnum, ch->ch_name); int save = 0; - sprintf(chid, "opentv-%u", cid); - ec = epggrab_module_channel_find(&_opentv_mod, chid, 1, &save); + ec = _opentv_find_channel(cid, 1, &save); if (save) { ec->channel = ch; // Note: could use set_sid() but not nec. epggrab_channel_set_number(ec, cnum); epggrab_channel_updated(ec); } - } else { - printf("NOT FOUND tsid=%d, cid=%d, cnum=%d\n", tsid, cid, cnum); } k += 9; dlen -= 9; @@ -334,16 +331,15 @@ static int _opentv_title_callback ( th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tid, void *p ) { int save = 0, save2 = 0; - char chid[16]; int cid, mjd, i, eid; time_t start, stop; //uint8_t cat; int l1, l2; char *title; + epggrab_channel_t *ec; channel_t *ch; opentv_prov_t *prov = (opentv_prov_t*)p; epg_broadcast_t *ebc; - epg_episode_t *ee; char *uri; if (len < 20) return 0; @@ -351,40 +347,36 @@ static int _opentv_title_callback /* Get channel/time */ cid = ((int)buf[0] << 8) | buf[1]; mjd = ((int)buf[5] << 8) | buf[6]; - sprintf(chid, "opentv-%d", cid); - epggrab_channel_t *ec = epggrab_module_channel_find(&_opentv_mod, chid, 0, NULL); - if (!ec || !ec->channel) { - printf("NOT FOUND cid=%d\n", cid); - return 0; - } + if (!(ec = _opentv_find_channel(cid, 0, NULL))) return 0; + if (!ec->channel) return 0; ch = ec->channel; - printf("opentv channel %s, len=%d\n", ch->ch_name, len); /* Process events */ i = 7; while ( i < len ) { eid = ((int)buf[i] << 8) | buf[i+1]; l1 = (((int)buf[i+2] & 0xf) << 8) | buf[i+3]; - printf("l1 = %d\n", l1); if (buf[i+4] != 0xb5) return 0; i += 4; l2 = buf[i+1] - 7; - printf("l2 = %d\n", l2); start = ((mjd - 40587) * 86400) + (((int)buf[i+2] << 9) | (buf[i+3] << 1)); stop = start + (((int)buf[i+4] << 9) | (buf[i+5] << 1)); title = huffman_decode(prov->dict->codes, buf+i+9, l2, 0x20); uri = md5sum(title); //cat = buf[i+6]; - printf("ch=%s, eid=%d, start=%lu, stop=%lu, title=%s\n", - ch->ch_name, eid, start, stop, title); i += l1; save = 0; ebc = epg_broadcast_find_by_time(ch, start, stop, 1, &save); + save2 |= save; if (ebc) { - ee = epg_episode_find_by_uri(uri, 1, &save); - save |= epg_episode_set_title(ee, title); - save |= epg_broadcast_set_episode(ebc, ee); - save2 = 1; + // TODO: if EIDs do not match? + if (ebc->dvb_eid != eid) { + ebc->dvb_eid = eid; + save2 = 1; + } + if (ebc->episode) { + save2 |= epg_episode_set_title(ebc->episode, title); + } } free(uri); free(title); @@ -411,7 +403,6 @@ static void _opentv_prov_add_tables fp->filter.filter[0] = 0x4a; fp->filter.mask[0] = 0xff; // TODO: what about 0x46 (service description) - printf("add filter pid=%d\n", *t); tdt_add(tdmi, fp, _opentv_channel_callback, prov, "opentv-c", TDT_CRC, *t++, NULL); }