--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "eit.h"
+
+char *subtitle_cnv_str[] = {
+// "¡¡Âè",
+// "¡¼Âè",
+// "-Âè",
+// " Âè",
+// "¡¡¡Ö",
+// "¡¡¡ô",
+// "¡Ê",
+// "¡Ö",
+ NULL
+};
+static void timecmp(int *,int *,int *,
+ int, int, int);
+
+int parseEIThead(unsigned char *data, EIThead *h) {
+ int boff = 0;
+
+ memset(h, 0, sizeof(EIThead));
+
+ h->table_id = getBit(data, &boff, 8);
+ h->section_syntax_indicator = getBit(data, &boff, 1);
+ h->reserved_future_use = getBit(data, &boff, 1);
+ h->reserved1 = getBit(data, &boff, 2);
+ h->section_length =getBit(data, &boff,12);
+ h->service_id = getBit(data, &boff, 16);
+ h->reserved2 = getBit(data, &boff, 2);
+ h->version_number = getBit(data, &boff, 5);
+ h->current_next_indicator = getBit(data, &boff, 1);
+ h->section_number = getBit(data, &boff, 8);
+ h->last_section_number = getBit(data, &boff, 8);
+ h->transport_stream_id = getBit(data, &boff, 16);
+ h->original_network_id = getBit(data, &boff, 16);
+ h->segment_last_section_number = getBit(data, &boff, 8);
+ h->last_table_id = getBit(data, &boff, 8);
+
+ return 14;
+}
+
+int parseEITbody(unsigned char *data, EITbody *b)
+{
+ int boff = 0;
+ int tnum;
+ char buf[4];
+
+ memset(b, 0, sizeof(EITbody));
+
+ b->event_id = getBit(data, &boff, 16);
+
+ memcpy(b->start_time, data + boff / 8, 5);
+ /* b->start_time = getBit(data, &boff, 40); */
+ boff += 40;
+ memcpy(b->duration, data + boff / 8, 3);
+ /* b->duration = getBit(data, &boff, 24); */
+ boff += 24;
+ b->running_status = getBit(data, &boff, 3);
+ b->free_CA_mode = getBit(data, &boff, 1);
+ b->descriptors_loop_length = getBit(data, &boff, 12);
+
+ /* ÆüÉÕÊÑ´¹ */
+ tnum = (b->start_time[0] & 0xFF) << 8 | (b->start_time[1] & 0xFF);
+
+ b->yy = (tnum - 15078.2) / 365.25;
+ b->mm = ((tnum - 14956.1) - (int)(b->yy * 365.25)) / 30.6001;
+ b->dd = (tnum - 14956) - (int)(b->yy * 365.25) - (int)(b->mm * 30.6001);
+
+ if(b->dd == 0) {
+ printf("aa");
+ }
+
+ if(b->mm == 14 || b->mm == 15) {
+ b->yy += 1;
+ b->mm = b->mm - 1 - (1 * 12);
+ } else {
+ b->mm = b->mm - 1;
+ }
+
+ b->yy += 1900;
+
+ memset(buf, '\0', sizeof(buf));
+ sprintf(buf, "%x", b->start_time[2]);
+ b->hh = atoi(buf);
+ memset(buf, '\0', sizeof(buf));
+ sprintf(buf, "%x", b->start_time[3]);
+ b->hm = atoi(buf);
+ memset(buf, '\0', sizeof(buf));
+ sprintf(buf, "%x", b->start_time[4]);
+ b->ss = atoi(buf);
+
+ if((b->duration[0] == 0xFF) && (b->duration[1] == 0xFF) && (b->duration[2] == 0xFF)){
+ b->dhh = b->dhm = b->dss = 0;
+ }else{
+ memset(buf, '\0', sizeof(buf));
+ sprintf(buf, "%x", b->duration[0]);
+ b->dhh = atoi(buf);
+ memset(buf, '\0', sizeof(buf));
+ sprintf(buf, "%x", b->duration[1]);
+ b->dhm = atoi(buf);
+ memset(buf, '\0', sizeof(buf));
+ sprintf(buf, "%x", b->duration[2]);
+ b->dss = atoi(buf);
+ }
+ return 12;
+}
+
+int parseSEVTdesc(unsigned char *data, SEVTdesc *desc) {
+ int boff = 0;
+
+ memset(desc, 0, sizeof(SEVTdesc));
+
+ desc->descriptor_tag = getBit(data, &boff, 8);
+ if((desc->descriptor_tag & 0xFF) != 0x4D) {
+ return -1;
+ }
+ desc->descriptor_length = getBit(data, &boff, 8);
+ memcpy(desc->ISO_639_language_code, data + boff / 8, 3);
+ /* desc->ISO_639_language_code = getBit(data, &boff, 24); */
+ boff += 24;
+ desc->event_name_length = getBit(data, &boff, 8);
+ getStr(desc->event_name, data, &boff, desc->event_name_length);
+ desc->text_length = getBit(data, &boff, 8);
+ getStr(desc->text, data, &boff, desc->text_length);
+
+ return desc->descriptor_length + 2;
+}
+
+int parseContentDesc(unsigned char *data, ContentDesc *desc) {
+ int boff = 0;
+
+ memset(desc, 0, sizeof(ContentDesc));
+
+ desc->descriptor_tag = getBit(data, &boff, 8);
+ if((desc->descriptor_tag & 0xFF) != 0x54) {
+ return -1;
+ }
+ desc->descriptor_length = getBit(data, &boff, 8);
+ memcpy(desc->content, data+(boff/8), desc->descriptor_length);
+ //getStr(desc->content, data, &boff, desc->descriptor_length);
+ return desc->descriptor_length + 2;
+}
+
+int parseSeriesDesc(unsigned char *data, SeriesDesc *desc) {
+ int boff = 0;
+
+ memset(desc, 0, sizeof(SeriesDesc));
+
+ desc->descriptor_tag = getBit(data, &boff, 8);
+ if((desc->descriptor_tag & 0xFF) != 0xD5) {
+ return -1;
+ }
+ desc->descriptor_length = getBit(data, &boff, 8);
+ desc->series_id = getBit(data, &boff, 16);
+ desc->repeat_label = getBit(data, &boff, 4);
+ desc->program_pattern = getBit(data, &boff, 3);
+ desc->expire_date_valid_flag = getBit(data, &boff, 1);
+
+ desc->expire_date = getBit(data, &boff, 16);
+ //memcpy(desc->expire_date, data + boff / 8, 2);
+ //boff += 16;
+
+ desc->episode_number = getBit(data, &boff, 12);
+ desc->last_episode_number = getBit(data, &boff, 12);
+
+ getStr(desc->series_name_char, data, &boff, desc->descriptor_length - 8);
+ return desc->descriptor_length + 2;
+}
+
+int parseEEVTDhead(unsigned char *data, EEVTDhead *desc) {
+ int boff = 0;
+
+ memset(desc, 0, sizeof(EEVTDhead));
+
+ desc->descriptor_tag = getBit(data, &boff, 8);
+ if((desc->descriptor_tag & 0xFF) != 0x4E) {
+ return -1;
+ }
+ desc->descriptor_length = getBit(data, &boff, 8);
+ desc->descriptor_number = getBit(data, &boff, 4);
+ desc->last_descriptor_number = getBit(data, &boff, 4);
+ memcpy(desc->ISO_639_language_code, data + boff / 8, 3);
+ /* desc->ISO_639_language_code = getBit(data, &boff, 24); */
+ boff += 24;
+
+ desc->length_of_items = getBit(data, &boff, 8);
+
+ return 7;
+}
+
+int parseEEVTDitem(unsigned char *data, EEVTDitem *desc) {
+ int boff = 0;
+
+ memset(desc, 0, sizeof(EEVTDitem));
+
+ desc->item_description_length = getBit(data, &boff, 8);
+ getStr(desc->item_description, data, &boff, desc->item_description_length);
+
+ desc->item_length = getBit(data, &boff, 8);
+// memcpy(desc->item, data + (boff / 8), desc->item_length);
+ getStr(desc->item, data, &boff, desc->item_length);
+
+ return desc->item_description_length + desc->item_length + 2;
+}
+
+int parseEEVTDtail(unsigned char *data, EEVTDtail *desc) {
+ int boff = 0;
+
+ memset(desc, 0, sizeof(EEVTDtail));
+
+ desc->text_length = getBit(data, &boff, 8);
+ getStr(desc->text, data, &boff, desc->text_length);
+
+ return desc->text_length + 1;
+}
+
+int checkEEVTDitem(EEVTDitem *save, EEVTDitem *new, int descriptor_number) {
+
+ EEVTDitem swap;
+ int boff = 0;
+ if(new == NULL) {
+ if(save->item_length != 0) {
+ swap = *save;
+ getStr(save->item, (unsigned char*)swap.item, &boff, swap.item_length);
+
+
+ //save->descriptor_number = descriptor_number;
+ //*new = swap;
+ //*save = swap;
+ if (swap.descriptor_number==1){
+// printf("descriptor_num %d typeB\n",swap.descriptor_number);
+ }
+
+ return 1;
+ } else {
+
+
+ //printf("descriptor_num %d typeC\n",swap.descriptor_number);
+
+
+
+ return 0;
+ }
+ }
+
+ if(new->item_description_length == 0) {
+ /* ³¤ Êݸ */
+ memcpy(save->item + save->item_length, new->item, new->item_length);
+ save->item_length += new->item_length;
+
+
+ if (swap.descriptor_number==1){
+ printf("descriptor_num %d typeD\n",swap.descriptor_number);
+ }
+
+
+ return 0;
+ } else {
+ /* ¥Ö¥ì¡¼¥¯¡£save¤ò°õºþÂоݤˤ¹¤ë¡£save¤ò¥¯¥ê¥¢? */
+ if(save->item_length != 0) {
+ /* ÂàÈòºÑ¤ß¤¬¤¢¤ê */
+ swap = *save;
+ getStr(save->item, (unsigned char*)swap.item, &boff, swap.item_length);
+ swap = *new;
+ *new = *save;
+ *save = swap;
+ save->descriptor_number = descriptor_number;
+
+
+
+
+ if (swap.descriptor_number==1){
+ printf("descriptor_num %d typeE\n",swap.descriptor_number);
+ }
+
+
+ } else {
+ *save = *new;
+ save->descriptor_number = descriptor_number;
+
+ if (swap.descriptor_number==1){
+ printf("descriptor_num %d typeF\n",swap.descriptor_number);
+ }
+
+
+ return 0;
+ }
+ }
+
+ return 1;
+}
+EIT_CONTROL *searcheit(EIT_CONTROL *top, int servid, int eventid)
+{
+ EIT_CONTROL *cur ;
+ cur = top ;
+
+ while(cur != NULL){
+ if((cur->event_id == eventid) && (cur->servid == servid)){
+ return cur ;
+ }
+
+ cur = cur->next ;
+ }
+ return NULL ;
+}
+void conv_title_subtitle(EIT_CONTROL *eitptr)
+{
+ int lp = 0 ;
+ size_t addsize ;
+ char *ptr ;
+ char *newsubtitle ;
+
+ for(lp = 0 ; subtitle_cnv_str[lp] != NULL ; lp++){
+ ptr = strstr(eitptr->title, subtitle_cnv_str[lp]);
+ if(ptr == NULL){
+ continue ;
+ }
+ // ¥¿¥¤¥È¥ë¤¬¤Ê¤¯¤Ê¤é¤Ê¤¤¤è¤¦¤Ë
+ if(ptr == eitptr->title){
+ continue ;
+ }
+ newsubtitle = calloc(1, ((strlen(ptr) + 1) + (strlen(eitptr->subtitle) + 1)));
+ memcpy(newsubtitle, ptr, strlen(ptr));
+ newsubtitle[strlen(ptr)] = ' ';
+ *ptr = NULL ;
+ strcat(newsubtitle, eitptr->subtitle);
+ free(eitptr->subtitle);
+ eitptr->subtitle = newsubtitle ;
+ return ;
+ }
+}
+void enqueue(EIT_CONTROL *top, EIT_CONTROL *eitptr)
+{
+ EIT_CONTROL *cur ;
+ cur = top ;
+ int rc ;
+
+ if(top->next == NULL){
+ top->next = eitptr ;
+ eitptr->prev = top ;
+ return ;
+ }
+ cur = top->next ;
+ while(cur != NULL){
+ rc = memcmp(&cur->yy, &eitptr->yy, (sizeof(int) * 3));
+ if(rc == 0){
+ rc = memcmp(&cur->hh, &eitptr->hh, (sizeof(int) * 3));
+ if(rc == 0){
+ free(eitptr->title);
+ free(eitptr->subtitle);
+ free(eitptr);
+ return ;
+ }
+ if(rc > 0){
+ if(cur->prev != 0){
+ cur->prev->next = eitptr ;
+ eitptr->prev = cur->prev ;
+ }
+ cur->prev = eitptr ;
+ eitptr->next = cur ;
+ conv_title_subtitle(eitptr);
+ return ;
+ }
+ }
+ if(rc > 0){
+ if(cur->prev != 0){
+ cur->prev->next = eitptr ;
+ eitptr->prev = cur->prev ;
+ }
+ cur->prev = eitptr ;
+ eitptr->next = cur ;
+ conv_title_subtitle(eitptr);
+ return ;
+ }
+ if(cur->next == NULL){
+ cur->next = eitptr ;
+ eitptr->prev = cur ;
+ conv_title_subtitle(eitptr);
+ return ;
+ }
+ cur = cur->next ;
+ }
+ return ;
+
+}
+
+void dumpEIT(unsigned char *ptr, int serv_id, int original_network_id, int transport_stream_id, EIT_CONTROL *eittop)
+{
+
+ EIThead eith;
+ EITbody eitb;
+ SEVTdesc sevtd;
+
+ EEVTDhead eevthead;
+ EEVTDitem eevtitem;
+ EEVTDtail eevttail;
+
+ EEVTDitem save_eevtitem;
+
+ EIT_CONTROL *cur ;
+ EIT_CONTROL *curtmp ;
+
+ int len = 0;
+ int loop_len = 0;
+ int loop_blen = 0;
+ int loop_elen = 0;
+ int str_alen = 0;
+
+ int ehh, emm, ess;
+
+ /* EIT */
+ len = parseEIThead(ptr, &eith);
+
+ ptr += len;
+ loop_len = eith.section_length - (len - 3 + 4); // 3¤Ï¶¦Ḁ̈إåÀĹ 4¤ÏCRC
+ while(loop_len > 0) {
+ /* Ϣ³¤¹¤ë³ÈÄ¥¥¤¥Ù¥ó¥È¤Ï¡¢´Á»ú¥³¡¼¥É¤¬µã¤Ê̤줷¤Æ
+ ʬ³ä¤µ¤ì¤ë¤è¤¦¤À¡£Ï¢Â³¤«¤É¤¦¤«¤Ï¡¢item_description_length¤¬
+ ÀßÄꤵ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤ÇȽÃǤǤ¤ë¤è¤¦¤À¡£ */
+ memset(&save_eevtitem, 0, sizeof(EEVTDitem));
+
+ len = parseEITbody(ptr, &eitb);
+ ptr += len;
+ loop_len -= len;
+
+ /* printf("evtid:%d\n", eitb.event_id); */
+
+ loop_blen = eitb.descriptors_loop_length;
+ loop_len -= loop_blen;
+ while(loop_blen > 0) {
+
+/*yukikaze-test*/
+ //printf("desc_tag");
+ //int itt=getBit(*ptr,0,8);
+ //printf("%x",itt);
+
+ len = parseSEVTdesc(ptr, &sevtd);
+ if(len > 0) {
+
+ /*
+ if(eith.service_id == 19304 &&
+ eitb.event_id == 46564) {
+ printf("aa");
+ }
+ */
+
+ ehh = eitb.hh;
+ emm = eitb.hm;
+ ess = eitb.ss;
+ if(eith.service_id != serv_id){
+ ptr += len;
+ loop_blen -= len;
+ continue ;
+ }
+
+ timecmp(&ehh, &emm, &ess,
+ eitb.dhh, eitb.dhm, eitb.dss);
+ cur = searcheit(eittop, eith.service_id, eitb.event_id);
+ if(cur == NULL){
+ curtmp = NULL;
+ cur = calloc(1, sizeof(EIT_CONTROL));
+ }
+ else {
+ curtmp = cur;
+ }
+ cur->event_id = eitb.event_id ;
+ cur->servid = eith.service_id ;
+ cur->title = calloc(1, (strlen(sevtd.event_name) + 1));
+
+ memcpy(cur->title, sevtd.event_name, strlen(sevtd.event_name));
+ cur->subtitle = calloc(1, (strlen(sevtd.text) + 1));
+ memcpy(cur->subtitle, sevtd.text, strlen(sevtd.text));
+ cur->yy = eitb.yy;
+ cur->mm = eitb.mm;
+ cur->dd = eitb.dd;
+ cur->hh = eitb.hh;
+ cur->hm = eitb.hm;
+ cur->ss = eitb.ss;
+ cur->ehh = eitb.dhh;
+ cur->emm = eitb.dhm;
+ cur->ess = eitb.dss ;
+ cur->table_id = eith.table_id ;
+ if ( !curtmp ) enqueue(eittop, cur);
+ } else {
+ len = parseEEVTDhead(ptr, &eevthead);
+
+ /*
+ if(eith.service_id == 19304 &&
+ eitb.event_id == 46564) {
+ printf("aa");
+ }
+ */
+
+ if(len > 0) {
+ ptr += len;
+ loop_blen -= len;
+
+ loop_elen = eevthead.length_of_items;
+ loop_len -= loop_elen;
+ while(loop_elen > 0) {
+ len = parseEEVTDitem(ptr, &eevtitem);
+
+ ptr += len;
+ loop_elen -= len;
+ loop_blen -= len;
+
+ if (1||checkEEVTDitem(&save_eevtitem, &eevtitem,
+ eevthead.descriptor_number)) {
+#if 0
+ {
+ if (eevtitem.descriptor_number>0){
+ //printf("descriptor_num %d\n",eevtitem.descriptor_number);
+ }
+
+ /* long format */
+ //printf("descriptor_num %d\n",eevtitem.descriptor_number);
+#if 1
+ printf("EEVT,%d,%d,%d,%s,%s\n",
+ eith.service_id,
+ eitb.event_id,
+ eevtitem.descriptor_number, // ÂàÈò¹àÌÜ
+ eevtitem.item_description,
+ eevtitem.item);
+#endif
+
+ }
+#endif
+ cur = searcheit(eittop, eith.service_id, eitb.event_id);
+ if(cur == NULL){
+ curtmp = NULL;
+ cur = calloc(1, sizeof(EIT_CONTROL));
+ }
+ else {
+ curtmp = cur;
+ }
+
+#if 1
+ if ( cur->desc ) {
+ str_alen = strlen( cur->desc );
+ }
+ else {
+ str_alen = 0;
+ }
+ eevtitem.item_description_length = strlen(eevtitem.item_description);
+ eevtitem.item_length = strlen(eevtitem.item);
+ cur->desc = realloc(cur->desc, str_alen + eevtitem.item_description_length + eevtitem.item_length + 1000);
+ if ( !str_alen ) *cur->desc = '\0';
+
+ if ( eevtitem.item_description_length && !strstr(cur->desc, eevtitem.item_description) ) {
+ strcat(cur->desc, eevtitem.item_description);
+ strcat(cur->desc, "\t");
+ }
+
+ if ( eevtitem.item_length && !strstr(cur->desc, eevtitem.item) ) {
+ strcat(cur->desc, eevtitem.item);
+ strcat(cur->desc, "\\n");
+ }
+#endif
+ if ( !curtmp ) enqueue(eittop, cur);
+ }
+ }
+
+ len = parseEEVTDtail(ptr, &eevttail);
+#if 0
+ { /* long format */
+ printf("EEVTt,%d,%d,%d,%s\n",
+ eith.service_id,
+ eitb.event_id,
+ eevthead.descriptor_number,
+ eevttail.text);
+ }
+#endif
+ } else {
+ ContentDesc contentDesc;
+ len = parseContentDesc(ptr, &contentDesc);
+ if (len > 0) {
+ int header_printed = 0;
+ for (int i = 0; i < contentDesc.descriptor_length - 1; i+=2) {
+ /*
+ if (0xff == (unsigned char)contentDesc.content[i])
+ continue;
+ */
+#if 0
+ if (!header_printed) {
+ fprintf(out, "Content,%d,%d",
+ eith.service_id,
+ eitb.event_id);
+ header_printed = 1;
+ }
+#endif
+
+#if 0
+ fprintf(out, ",%02x%02x", (unsigned char)contentDesc.content[i], (unsigned char)contentDesc.content[i+1]);
+#endif
+ }
+ if((eith.original_network_id == original_network_id) && (eith.transport_stream_id == transport_stream_id)){
+ cur = searcheit(eittop, eith.service_id, eitb.event_id);
+ if(cur != NULL){
+ cur->content_type = (unsigned char)(contentDesc.content[0] >> 4);
+#if 0
+ fprintf(stdout, "%s:", cur->title);
+ fprintf(stdout, ",%02x%02x", (unsigned char)contentDesc.content[0], (unsigned char)contentDesc.content[1]);
+ fprintf(stdout, ",%02x%02x\n", (unsigned char)contentDesc.content[2], (unsigned char)contentDesc.content[3]);
+#endif
+
+ }
+#if 0
+ if (header_printed) {
+ fprintf(out, "\n");
+ }
+#endif
+ }
+ } else {
+ SeriesDesc seriesDesc;
+ len = parseSeriesDesc(ptr, &seriesDesc);
+ if (len > 0) {
+#if 0
+ printf("Series,%d,%d,series=%d,repeat=%01x,pattern=%d,expire_valid=%d,expire=%04x,epinum=%d,lastepinum=%d,%s\n",
+ eith.service_id,
+ eitb.event_id,
+ seriesDesc.series_id,
+ seriesDesc.repeat_label,
+ seriesDesc.program_pattern,
+ seriesDesc.expire_date_valid_flag,
+ seriesDesc.expire_date,
+ seriesDesc.episode_number,
+ seriesDesc.last_episode_number,
+ seriesDesc.series_name_char);
+#endif
+ } else {
+ len = parseOTHERdesc(ptr);
+ }
+ }
+ }
+ }
+ ptr += len;
+ loop_blen -= len;
+ }
+ /* ºÇ¸å¤Î¥Ö¥ì¡¼¥¯¥Á¥§¥Ã¥¯ */
+
+ if(checkEEVTDitem(&save_eevtitem, NULL, 0)) {
+#if 0
+ if(mode == 1) { /* long format */
+ fprintf(out, "EEVT,%d,%d,%d,%s,%s\n",
+ eith.service_id,
+ eitb.event_id,
+ save_eevtitem.descriptor_number,
+ save_eevtitem.item_description,
+ save_eevtitem.item);
+ }
+#endif
+ }
+ }
+
+ return;
+}
+
+void timecmp(int *thh, int *tmm, int *tss,
+ int dhh, int dmm, int dss) {
+
+ int ama;
+
+ *tss += dss;
+ ama = *tss % 60;
+ *tmm += (*tss / 60);
+ *tss = ama;
+
+ *tmm += dmm;
+ ama = *tmm % 60;
+ *thh += (*tmm / 60);
+ *tmm = ama;
+
+ *thh += dhh;
+
+}