OSDN Git Service

add bit parser
[rec10/rec10-git.git] / epgdump / epgdump.c
index 38dc1e1..0c0141b 100755 (executable)
@@ -7,9 +7,14 @@
 #include <time.h>
 
 #include "ts.h"
+#include "psi.h"
 #include "sdt.h"
+#include "sdtt.h"
 #include "eit.h"
+#include "tot.h"
+#include "dsmcc.h"
 #include "ts_ctl.h"
+#include "util.h"
 
 typedef                struct  _ContentTYPE{
        char    *japanese ;
@@ -18,134 +23,78 @@ typedef            struct  _ContentTYPE{
 
 #define                CAT_COUNT               16
 static  CONTENT_TYPE   ContentCatList[CAT_COUNT] = {
-       { "¥Ë¥å¡¼¥¹¡¦ÊóÆ»", "news" },
-       { "¥¹¥Ý¡¼¥Ä", "sports" },
-       { "¾ðÊó", "information" },
-       { "¥É¥é¥Þ", "drama" },
-       { "²»³Ú", "music" },
-       { "¥Ð¥é¥¨¥Æ¥£", "variety" },
-       { "±Ç²è", "cinema" },
-       { "¥¢¥Ë¥á¡¦Æû£", "anime" },
-       { "¥É¥­¥å¥á¥ó¥¿¥ê¡¼¡¦¶µÍÜ", "documentary" },
-       { "±é·à", "stage" },
-       { "¼ñÌ£¡¦¼ÂÍÑ", "hobby" },
-       { "Ê¡»ã", "etc" },                      //Ê¡»ã
-       { "ͽÈ÷", "etc" }, //ͽÈ÷
-       { "ͽÈ÷", "etc" }, //ͽÈ÷
-       { "ͽÈ÷", "etc" }, //ͽÈ÷
-       { "¤½¤Î¾", "etc" } //¤½¤Î¾
-};
-typedef struct _TAG_STATION
-{
-       char    *name;
-       char    *ontv;
-       int             tsId;           // OriginalNetworkID
-       int             onId;           // TransportStreamID
-       int             svId;           // ServiceID
-} STATION;
-
-static STATION bsSta[] = {
-       { "NHK BS1", "3001.ontvjapan.com", 16625, 4, 101},
-       { "NHK BS2", "3002.ontvjapan.com", 16625, 4, 102},
-       { "NHK BSh", "3003.ontvjapan.com", 16626, 4, 103},
-       { "BSÆü¥Æ¥ì", "3004.ontvjapan.com", 16592, 4, 141},
-       { "BSÄ«Æü", "3005.ontvjapan.com", 16400, 4, 151},
-       { "BS-i", "3006.ontvjapan.com", 16401, 4, 161},
-       { "BS¥¸¥ã¥Ñ¥ó", "3007.ontvjapan.com", 16433, 4, 171},
-       { "BS¥Õ¥¸", "3008.ontvjapan.com", 16593, 4, 181},
-       { "WOWOW", "3009.ontvjapan.com", 16432, 4, 191},
-       { "WOWOW2", "3010.ontvjapan.com", 16432, 4, 192},
-       { "WOWOW3", "3011.ontvjapan.com", 16432, 4, 193},
-       { "BS11", "3013.ontvjapan.com", 16528, 4, 211},
-       { "TwellV", "3014.ontvjapan.com", 16530, 4, 222},
+       { "ニュース・報道", "news" },
+       { "スポーツ", "sports" },
+       { "情報", "information" },
+       { "ドラマ", "drama" },
+       { "音楽", "music" },
+       { "バラエティ", "variety" },
+       { "映画", "cinema" },
+       { "アニメ・特撮", "anime" },
+       { "ドキュメンタリー・教養", "documentary" },
+       { "演劇", "stage" },
+       { "趣味・実用", "hobby" },
+       { "福祉", "welfare" },
+       { "予備", "etc" },
+       { "予備", "etc" },
+       { "予備", "etc" },
+       { "その他", "etc" }
 };
 
-static int bsStaCount = sizeof(bsSta) / sizeof (STATION);
-
-
-
-static STATION csSta[] = {
-       { "¥¹¥¿¡¼£ã£è¥×¥é¥¹", "1002.ontvjapan.com", 24608, 6, 237},
-       { "ÆüËܱDzèÀìÌç£ã£è£È£Ä", "1086.ontvjapan.com", 24608, 6, 239},
-       { "¥Õ¥¸¥Æ¥ì¥Ó£Ã£Ó£È£Ä", "306ch.epgdata.ontvjapan", 24608, 6, 306},
-       { "¥·¥ç¥Ã¥×¥Á¥ã¥ó¥Í¥ë", "1059.ontvjapan.com", 24704, 6, 55},
-       { "¥­¥Ã¥º¥¹¥Æ¡¼¥·¥ç¥ó£È£Ä", "335ch.ontvjapan.com", 24704, 6, 335},
-       { "¥¶¡¦¥·¥Í¥Þ", "1217.ontvjapan.com", 24736, 6, 228},
-       { "¥¹¥«¥Á¥ã¥ó£È£Ä£¸£°£°", "800ch.epgdata.ontvjapan", 24736, 6, 800},
-       { "¥¹¥«¥Á¥ã¥ó£¸£°£±", "801ch.epgdata.ontvjapan", 24736, 6, 801},
-       { "¥¹¥«¥Á¥ã¥ó£¸£°£²", "802ch.epgdata.ontvjapan", 24736, 6, 802},
-       { "£å£²¥×¥í¥â", "100ch.epgdata.ontvjapan", 28736, 7, 100},
-       { "¥¤¥ó¥¿¡¼¥í¡¼¥«¥ë£Ô£Ö", "194ch.epgdata.ontvjapan", 28736, 7, 194},
-       { "£Ê¥¹¥Ý¡¼¥Ä¡¡£Å£Ó£Ð£Î", "1025.ontvjapan.com", 28736, 7, 256},
-       { "£Æ£Ï£Ø", "1016.ontvjapan.com", 28736, 7, 312},
-       { "¥¹¥Ú¡¼¥¹¥·¥ã¥ï¡¼£Ô£Ö", "1018.ontvjapan.com", 28736, 7, 322},
-       { "¥«¡¼¥È¥¥¡¼¥ó¡¡¥Í¥Ã¥È", "1046.ontvjapan.com", 28736, 7, 331},
-       { "¥È¥¥¡¼¥ó¡¦¥Ç¥£¥º¥Ë¡¼", "1213.ontvjapan.com", 28736, 7, 334},
-       { "Åì±Ç¥Á¥ã¥ó¥Í¥ë", "1010.ontvjapan.com", 28768, 7, 221},
-       { "±ÒÀ±·à¾ì", "1005.ontvjapan.com", 28768, 7, 222},
-       { "¥Á¥ã¥ó¥Í¥ë£Î£Å£Ã£Ï", "1008.ontvjapan.com", 28768, 7, 223},
-       { "Íβè¡ú¥·¥Í¥Õ¥£¥ë", "1009.ontvjapan.com", 28768, 7, 224},
-       { "¥¹¥¿¡¼¡¦¥¯¥é¥·¥Ã¥¯", "1003.ontvjapan.com", 28768, 7, 238},
-       { "»þÂå·àÀìÌç¥Á¥ã¥ó¥Í¥ë", "1133.ontvjapan.com", 28768, 7, 292},
-       { "¥¹¡¼¥Ñ¡¼¥É¥é¥Þ", "1006.ontvjapan.com", 28768, 7, 310},
-       { "£Á£Ø£Î", "1014.ontvjapan.com", 28768, 7, 311},
-       { "¥Ê¥·¥ç¥¸¥ª¥Á¥ã¥ó¥Í¥ë", "1204.ontvjapan.com", 28768, 7, 343},
-       { "¥ï¥ó¥Æ¥ó¥Ý¡¼¥¿¥ë", "110ch.epgdata.ontvjapan", 28864, 7, 110},
-       { "¥´¥ë¥Õ¥Á¥ã¥ó¥Í¥ë", "1028.ontvjapan.com", 28864, 7, 260},
-       { "¥Æ¥ìÄ«¥Á¥ã¥ó¥Í¥ë", "1092.ontvjapan.com", 28864, 7, 303},
-       { "£Í£Ô£Ö", "1019.ontvjapan.com", 28864, 7, 323},
-       { "¥ß¥å¡¼¥¸¥Ã¥¯¡¦¥¨¥¢", "1024.ontvjapan.com", 28864, 7, 324},
-       { "Ä«Æü¥Ë¥å¡¼¥¹¥¿¡¼", "1067.ontvjapan.com", 28864, 7, 352},
-       { "£Â£Â£Ã¥ï¡¼¥ë¥É", "1070.ontvjapan.com", 28864, 7, 353},
-       { "£Ã£Î£Î£ê", "1069.ontvjapan.com", 28864, 7, 354},
-       { "¥¸¥ã¥¹¥È¡¦¥¢¥¤", "361ch.epgdata.ontvjapan", 28864, 7, 361},
-       { "£Ê¥¹¥Ý¡¼¥Ä¡¡£±", "1041.ontvjapan.com", 28896, 7, 251},
-       { "£Ê¥¹¥Ý¡¼¥Ä¡¡£²", "1042.ontvjapan.com", 28896, 7, 252},
-       { "£Ê¥¹¥Ý¡¼¥Ä£Ð£ì£õ£ó£È", "1043.ontvjapan.com", 28896, 7, 253},
-       { "£Ç£Á£Ï£Ò£Á", "1026.ontvjapan.com", 28896, 7, 254},
-       { "£ó£ë£ù¡¦£Á¥¹¥Ý¡¼¥Ä¡Ü", "1040.ontvjapan.com", 28896, 7, 255},
-       { "ÊõÄÍ¥×¥í¥â¥Á¥ã¥ó¥Í¥ë", "101ch.epgdata.ontvjapan", 28928, 7, 101},
-       { "£Ó£Ë£Ù¡¦£Ó£Ô£Á£Ç£Å", "1207.ontvjapan.com", 28928, 7, 290},
-       { "¥Á¥ã¥ó¥Í¥ë¶ä²Ï", "305ch.epgdata.ontvjapan", 28928, 7, 305},
-       { "£Á£Ô-£Ø", "1201.ontvjapan.com", 28928, 7, 333},
-       { "¥Ò¥¹¥È¥ê¡¼¥Á¥ã¥ó¥Í¥ë", "1050.ontvjapan.com", 28928, 7, 342},
-       { "¥¹¥«¥Á¥ã¥ó£¸£°£³", "803ch.epgdata.ontvjapan", 28928, 7, 803},
-       { "¥¹¥«¥Á¥ã¥ó£¸£°£´", "804ch.epgdata.ontvjapan", 28928, 7, 804},
-       { "¥à¡¼¥Ó¡¼¥×¥é¥¹£È£Ä", "1007.ontvjapan.com", 28960, 7, 240},
-       { "¥´¥ë¥Õ¥Í¥Ã¥È¥ï¡¼¥¯", "1027.ontvjapan.com", 28960, 7, 262},
-       { "£Ì£á£Ì£á¡¡£È£Ä", "1074.ontvjapan.com", 28960, 7, 314},
-       { "¥Õ¥¸¥Æ¥ì¥Ó£Ï£Î£Å", "1073.ontvjapan.com", 28992, 7, 307},
-       { "¥Õ¥¸¥Æ¥ì¥Ó£Ô£×£Ï", "1072.ontvjapan.com", 28992, 7, 308},
-       { "¥¢¥Ë¥Þ¥Ã¥¯¥¹", "1047.ontvjapan.com", 28992, 7, 332},
-       { "¥Ç¥£¥¹¥«¥Ð¥ê¡¼", "1062.ontvjapan.com", 28992, 7, 340},
-       { "¥¢¥Ë¥Þ¥ë¥×¥é¥Í¥Ã¥È", "1193.ontvjapan.com", 28992, 7, 341},
-       { "£Ã-£Ô£Â£Ó¥¦¥¨¥ë¥«¥à", "160ch.epgdata.ontvjapan", 29024, 7, 160},
-       { "£Ñ£Ö£Ã", "1120.ontvjapan.com", 29024, 7, 161},
-       { "¥×¥é¥¤¥à£³£¶£µ¡¥£Ô£Ö", "185ch.epgdata.ontvjapan", 29024, 7, 185},
-       { "¥Õ¥¡¥ß¥ê¡¼·à¾ì", "1015.ontvjapan.com", 29024, 7, 293},
-       { "£Ô£Â£Ó¥Á¥ã¥ó¥Í¥ë", "3201.ontvjapan.com", 29024, 7, 301},
-       { "¥Ç¥£¥º¥Ë¡¼¥Á¥ã¥ó¥Í¥ë", "1090.ontvjapan.com", 29024, 7, 304},
-       { "MUSIC ON! TV", "1022.ontvjapan.com", 29024, 7, 325},
-       { "¥­¥Ã¥º¥¹¥Æ¡¼¥·¥ç¥ó", "1045.ontvjapan.com", 29024, 7, 330},
-       { "£Ô£Â£Ó¥Ë¥å¡¼¥¹¥Ð¡¼¥É", "1076.ontvjapan.com", 29024, 7, 351},
-       { "£Ã£ÓÆüËÜÈÖÁÈ¥¬¥¤¥É", "147ch.epgdata.ontvjapan", 29056, 7, 147},
-       { "Æü¥Æ¥ì£Ç¡Ü", "1068.ontvjapan.com", 29056, 7, 257},
-       { "fashion TV", "5004.ontvjapan.com", 29056, 7, 291},
-       { "Æü¥Æ¥ì¥×¥é¥¹", "300ch.epgdata.ontvjapan", 29056, 7, 300},
-       { "¥¨¥³¥ß¥å¡¼¥¸¥Ã¥¯£Ô£Ö", "1023.ontvjapan.com", 29056, 7, 320},
-       { "Music Japan TV", "1208.ontvjapan.com", 29056, 7, 321},
-       { "Æü¥Æ¥ì£Î£Å£×£Ó£²£´", "2002.ontvjapan.com", 29056, 7, 350},
-};
 
-static int csStaCount = sizeof(csSta) / sizeof (STATION);
 SVT_CONTROL    *svttop = NULL;
-#define                SECCOUNT        4
-char   title[1024];
-char   subtitle[1024];
-char   desc[102400] = {0};
-char   Category[1024];
-char   ServiceName[1024];
-iconv_t        cd ;
+DSM_CONTROL    dsmctl[1024];
+#define                SECCOUNT        64
+static unsigned char *base64 = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static void base64_char(unsigned long bb, int srclen, unsigned char *dest, int j)
+{
+       int x, i, base;
+
+       /* 最終位置の計算 */
+       for ( i = srclen; i < 2; i++ ) 
+               bb <<= 8;
+
+       /* BASE64変換 */
+       for ( base = 18, x = 0; x < srclen + 2; x++, base -= 6) {
+               dest[j++] = base64[ (unsigned long)((bb>>base) & 0x3F) ];
+       }
+
+       /* 端数の判断 */
+       for ( i = x; i < 4; i++ ) {
+               dest[j++] = (unsigned char)'=';         /* 端数 */
+       }
+       
+}
+
+static void base64_encode(unsigned char *dest, const unsigned char *src, int len)
+{
+       unsigned char *p = src;
+       unsigned long bb = (unsigned long)0;
+       int i = 0, j = 0;
+
+       while (len--)
+       {
+               bb <<= 8;
+               bb |= (unsigned long)*p;
+
+               /* 24bit単位に編集 */
+               if (i == 2) {
+                       base64_char(bb, i, dest, j);
+
+                       j = j + 4;
+                       i = 0;
+                       bb = 0;
+               } else
+                       i++;
+
+               p++;
+       }
+
+       /* 24bitに満たない場合 */
+       if (i) base64_char(bb, i - 1, dest, j);
+
+}
 
 void   xmlspecialchars(char *str)
 {
@@ -158,27 +107,72 @@ void      xmlspecialchars(char *str)
 
 
 
-void   GetSDT(FILE *infile, SVT_CONTROL *svttop, SECcache *secs, int count)
+void   GetSDT(FILE *infile, SVT_CONTROL *svttop, SECcache *secs, 
+       int count, STATION **station, int * station_count, char *header, int is_logo)
 {
        SECcache  *bsecs;
+       int pmtpids[SECCOUNT];
+       memset(pmtpids, 0, sizeof(pmtpids));
+       int dsmccpids[SECCOUNT];
+       memset(dsmccpids, 0, sizeof(dsmccpids));
+       int i = 0 , downloadDataId = 0;
 
        while((bsecs = readTS(infile, secs, count)) != NULL) {
                /* SDT */
                if((bsecs->pid & 0xFF) == 0x11) {
-                       dumpSDT(bsecs->buf, svttop);
+                       dumpSDT(bsecs->buf, svttop, station, station_count, header);
+               }
+               /* TOT */
+               else if((bsecs->pid & 0xFF) == 0x14) {
+                       dumpTOT(bsecs->buf);
+               }
+               /* SDTT */
+               //else if((bsecs->pid & 0xFF) == 0x23) {
+               //      dumpSDTT(bsecs->buf, *station, *station_count);
+               //}
+               /* BIT */
+               else if((bsecs->pid & 0xFF) == 0x24) {
+                       dumpBIT(bsecs->buf);
+               }
+               /* CDT */
+               else if((bsecs->pid & 0xFF) == 0x29) {
+                       dumpCDT(bsecs->buf, *station, *station_count);
+               }
+               else if ( is_logo ) {
+                       /* PAT */
+                       if((bsecs->pid & 0xFF) == 0x00) {
+                               dumpPAT(bsecs->buf, secs, count, pmtpids);
+                       }
+                       /* PMT */
+                       for ( i = 1; i < SECCOUNT; i++ ) {
+                               if ( pmtpids[i] == 0 ) {
+                                       break;
+                               }
+                               /* PMT specified by PAT */
+                               if ( bsecs->pid == pmtpids[i] ) {
+                                       dumpPMT(bsecs->buf, secs, count, dsmccpids);
+                               }
+                       }
+                       /* DSM-CC */
+                       for ( i = 0; i < SECCOUNT; i++ ) {
+                               if ( dsmccpids[i] == 0 ) {
+                                       break;
+                               }
+                               /* DSM-CC specified by PMT */
+                               if ( bsecs->pid == dsmccpids[i] ) {
+                                       dumpDSMCC(bsecs->buf, &downloadDataId, &dsmctl);
+                               }
+                       }
                }
        }
 }
-void   GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs, int count)
+
+void   GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs)
 {
        SECcache  *bsecs;
        EIT_CONTROL     *eitcur ;
        EIT_CONTROL     *eitnext ;
        EIT_CONTROL     *eittop = NULL;
-       char    *outptr ;
-       char    *inptr ;
-       size_t  ilen;
-       size_t  olen;
        time_t  l_time ;
        time_t  end_time ;
        struct  tm      tl ;
@@ -186,6 +180,18 @@ void       GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs, int coun
        char    cendtime[32];
        char    cstarttime[32];
 
+       char    title[1024];
+       char    subtitle[1024];
+       char    desc[102400] = {0};
+       char    Category[1024];
+       char    VideoType[1024];
+       char    AudioType[1024];
+
+       memset(secs, 0,  sizeof(SECcache) * SECCOUNT);
+       secs[0].pid = 0x12; /* EIT  */
+       secs[1].pid = 0x26; /* EIT  */
+       secs[2].pid = 0x27; /* EIT  */
+
        eittop = calloc(1, sizeof(EIT_CONTROL));
        eitcur = eittop ;
        fseek(infile, 0, SEEK_SET);
@@ -208,40 +214,32 @@ void      GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs, int coun
                if(eitcur->content_type > CAT_COUNT){
                        eitcur->content_type = CAT_COUNT -1 ;
                }
-               outptr = title ;
                memset(title, '\0', sizeof(title));
-               ilen = strlen(eitcur->title);
-               olen = sizeof(title);
-               inptr = eitcur->title;
-               iconv(cd, &inptr, &ilen, &outptr, &olen);
+               strcpy(title, eitcur->title);
                xmlspecialchars(title);
 
                memset(subtitle, '\0', sizeof(subtitle));
-               ilen = strlen(eitcur->subtitle);
-               olen = sizeof(subtitle);
-               outptr = subtitle ;
-               inptr = eitcur->subtitle;
-               iconv(cd, &inptr, &ilen, &outptr, &olen);
+               strcpy(subtitle, eitcur->subtitle);
                xmlspecialchars(subtitle);
 
                memset(desc, '\0', sizeof(desc));
                if ( eitcur->desc ) {
-                       ilen = strlen(eitcur->desc);
-                       olen = sizeof(desc);
-                       outptr = desc ;
-                       inptr = eitcur->desc;
-                       iconv(cd, &inptr, &ilen, &outptr, &olen);
+                       strcpy(desc, eitcur->desc);
                        xmlspecialchars(desc);
                }
 
                memset(Category, '\0', sizeof(Category));
-               ilen = strlen(ContentCatList[eitcur->content_type].japanese);
-               olen = sizeof(Category);
-               outptr = Category ;
-               inptr = ContentCatList[eitcur->content_type].japanese;
-               iconv(cd, &inptr, &ilen, &outptr, &olen);
+               strcpy(Category, ContentCatList[eitcur->content_type].japanese);
                xmlspecialchars(Category);
 
+               memset(VideoType, '\0', sizeof(VideoType));
+               strcpy(VideoType, parseComponentDescType(eitcur->video_type));
+               xmlspecialchars(VideoType);
+
+               memset(AudioType, '\0', sizeof(AudioType));
+               strcpy(AudioType, parseAudioComponentDescType(eitcur->audio_type));
+               xmlspecialchars(AudioType);
+
                tl.tm_sec = eitcur->ss ;
                tl.tm_min = eitcur->hm ;
                tl.tm_hour = eitcur->hh ;
@@ -254,7 +252,7 @@ void        GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs, int coun
                l_time = mktime(&tl);
                if((eitcur->ehh == 0) && (eitcur->emm == 0) && (eitcur->ess == 0)){
                        (void)time(&l_time);
-                       end_time = l_time + (60 * 5);           // £µÊ¬¸å¤ËÀßÄê
+                       end_time = l_time + (60 * 5);           // 5分後に設定
                endtl = localtime(&end_time);
                }else{
                        end_time = l_time + eitcur->ehh * 3600 + eitcur->emm * 60 + eitcur->ess;
@@ -264,24 +262,25 @@ void      GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs, int coun
                memset(cstarttime, '\0', sizeof(cstarttime));
                strftime(cendtime, (sizeof(cendtime) - 1), "%Y%m%d%H%M%S", endtl);
                strftime(cstarttime, (sizeof(cstarttime) - 1), "%Y%m%d%H%M%S", &tl);
-#if 1
-               fprintf(outfile, "  <programme start=\"%s +0900\" stop=\"%s +0900\" channel=\"%s\">\n", 
-                               cstarttime, cendtime, psta->ontv);
+
+               fprintf(outfile, "  <programme start=\"%s +0900\" stop=\"%s +0900\" channel=\"%s\" event=\"%d\">\n",    
+                               cstarttime, cendtime, psta->ontv, eitcur->event_id);
                fprintf(outfile, "    <title lang=\"ja_JP\">%s</title>\n", title);
                fprintf(outfile, "    <desc lang=\"ja_JP\">%s</desc>\n", subtitle);
                fprintf(outfile, "    <longdesc lang=\"ja_JP\">%s</longdesc>\n", desc);
                fprintf(outfile, "    <category lang=\"ja_JP\">%s</category>\n", Category);
-//             fprintf(outfile, "    <category lang=\"en\">%s</category>\n", ContentCatList[eitcur->content_type].english);
+               fprintf(outfile, "    <video type=\"%d\">%s</video>\n", eitcur->video_type, VideoType);
+               fprintf(outfile, "    <audio type=\"%d\" multi=\"%d\">%s</audio>\n", eitcur->audio_type, eitcur->multi_type, AudioType);
+               //fprintf(outfile, "    <category lang=\"en\">%s</category>\n", ContentCatList[eitcur->content_type].english);
                fprintf(outfile, "  </programme>\n");
-#else
+#if 0
                fprintf(outfile, "(%x:%x:%x)%s,%s,%s,%s,%s,%s\n",
                                        eitcur->servid, eitcur->table_id, eitcur->event_id,
                                        cstarttime, cendtime,
                                        title, subtitle,
                                        Category,
                                        ContentCatList[eitcur->content_type].english);
-#endif
-#if 0
+
                fprintf(outfile, "(%x:%x)%04d/%02d/%02d,%02d:%02d:%02d,%02d:%02d:%02d,%s,%s,%s,%s\n",
                                        eitcur->table_id, eitcur->event_id,
                                        eitcur->yy, eitcur->mm, eitcur->dd,
@@ -300,75 +299,170 @@ void     GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs, int coun
        free(eittop);
        eittop = NULL;
 }
+
+void checkSta(STATION **station,int *stalength){
+       STATION *statmp;
+       int chl[90];
+       int chlt = 0;
+       int stal = 0;
+       STATION * statin = *station;
+       statmp = malloc( sizeof(STATION) * 2 );
+       for (int i = 0 ; i < *stalength ; i++){
+               int noidinchl = 1;
+               for (int j = 0 ; j < chlt ; j++){
+                       if ( chl[j] == statin[i].svId ) {
+                               noidinchl = 0;
+                       }
+               }
+               if ( noidinchl == 1 ) {
+                       statmp = realloc(statmp, (stal+1) * sizeof(STATION));
+                       statmp[stal] = statin[i];
+                       chl[chlt] = statin[i].svId;
+                       chlt++;
+                       stal++;
+               }
+       }
+       *station = statmp;
+       *stalength = stal;//ここいらが怪しい
+       //memcpy(statin,statmp,chlt*sizeof(STATION));
+       //free(statmp);
+       return;
+}
+
 int main(int argc, char *argv[])
 {
 
        FILE *infile = stdin;
        FILE *outfile = stdout;
-       int             arg_maxcount = 1 ;
        char    *arg_onTV ;
-       int   mode = 1;
        int             staCount ;
-       int   eitcnt;
-       char *file;
        int   inclose = 0;
        int   outclose = 0;
-       int             flag = 0 ;
        SVT_CONTROL     *svtcur ;
        SVT_CONTROL     *svtsave ;
-       char    *outptr ;
-       char    *inptr ;
-       size_t  ilen;
-       size_t  olen;
        SECcache   secs[SECCOUNT];
-       int rtn;
        int             lp ;
        STATION *pStas ;
-       int             act ;
+       int             act = 0;
+       int             i , j, k ;
+       int             is_logo = 0;
+       SDTTdata  sdtd;
+       SDTTdataLoop *loop;
+       SDTTdataService *service;
 
-       /* ¶½Ì£¤Î¤¢¤ëpid¤ò»ØÄê */
-       memset(secs, 0,  sizeof(SECcache) * SECCOUNT);
-       secs[0].pid = 0x11;
-       secs[1].pid = 0x12;
-       secs[2].pid = 0x26;
-       secs[3].pid = 0x27;
+       memset(dsmctl, 0,  sizeof(dsmctl));
 
+       if(argc == 5 && strcmp(argv[1], "/LOGO") == 0){
+               argc--;
+               argv[1] = argv[2];
+               argv[2] = argv[3];
+               argv[3] = argv[4];
+               is_logo = 1;
+       }
        if(argc == 4){
                arg_onTV = argv[1];
-               file = argv[2];
-               if(strcmp(file, "-")) {
-                       infile = fopen(file, "r");
+               if(strcmp(argv[2], "-")) {
+                       infile = fopen(argv[2], "r");
+                       if ( !infile) {
+                         printf( "tsFile not found (Can't open file: %s)\n", argv[2] );
+                         exit( -1 );
+                       }
                        inclose = 1;
                }
+               else {
+                       infile = stdin;
+               }
                if(strcmp(argv[3], "-")) {
                        outfile = fopen(argv[3], "w+");
+                       if ( !outfile) {
+                         printf( "xmlFile not found (Can't open file: %s)\n", argv[3] );
+                         exit( -1 );
+                       }
                        outclose = 1;
                }
+               else {
+                       outfile = stdout;
+               }
        }else{
-               fprintf(stdout, "Usage : %s /BS <tsFile> <outfile>\n", argv[0]);
-               fprintf(stdout, "Usage : %s <ontvcode> <tsFile> <outfile>\n", argv[0]);
-               fprintf(stdout, "ontvcode ¥Á¥ã¥ó¥Í¥ë¼±Ê̻ҡ£****.ontvjapan.com ¤Ê¤É\n");
-               fprintf(stdout, "/BS      BS¥â¡¼¥É¡£°ì¤Ä¤ÎTS¤«¤éBSÁ´¶É¤Î¥Ç¡¼¥¿¤òÆɤ߹þ¤ß¤Þ¤¹¡£\n");
-               fprintf(stdout, "/CS      CS¥â¡¼¥É¡£°ì¤Ä¤ÎTS¤«¤éÊ£¿ô¶É¤Î¥Ç¡¼¥¿¤òÆɤ߹þ¤ß¤Þ¤¹¡£\n");
+               fprintf(stdout, "Usage : %s (/LOGO) {/BS|/CS|<id>} <tsFile> <outfile>\n", argv[0]);
+               fprintf(stdout, "\n");
+               fprintf(stdout, "/LOGO    ロゴ取得モード。独立して指定し、番組表の出力を行ないません。\n");
+               fprintf(stdout, "         必要なTSの長さ 地上波は10分 BS/CSは20分です。\n");
+               fprintf(stdout, "id       チャンネル識別子。地上波の物理チャンネルを与えます。\n");
+               fprintf(stdout, "/BS      BSモード。一つのTSからBS全局のデータを読み込みます。\n");
+               fprintf(stdout, "/CS      CSモード。一つのTSから複数局のデータを読み込みます。\n");
+               fprintf(stdout, "/TIME    時刻合わせモード。TSからTOT(Time Offset Table)を読み込みます。\n");
+               fprintf(stdout, "         recpt1 <任意> 10(秒以上) - | epgdump /TIME - <任意>の形で使用してください。\n");
+               fprintf(stdout, "         TOTは5秒に1回しか来ないため、recpt1に与える時間をある程度長くしてください。\n");
+/*
+               fprintf(stdout, "  ontvcode   Channel identifier (ex. ****.ontvjapan.com)\n");
+               fprintf(stdout, "  /BS        BS mode\n");
+               fprintf(stdout, "               This mode reads the data of all BS TV stations\n");
+               fprintf(stdout, "               from one TS data.\n");
+               fprintf(stdout, "  /CS        CS mode\n");
+               fprintf(stdout, "               This mode reads the data of two or more CS TV stations\n");
+               fprintf(stdout, "               from one TS data.\n");
+*/
                return 0;
        }
 
-       if(strcmp(arg_onTV, "/BS") == 0){
-               pStas = bsSta;
-               staCount = bsStaCount;
-               act = 0 ;
+       pStas = NULL;
+       staCount = 0;
+       svttop = calloc(1, sizeof(SVT_CONTROL));
+       act = 0 ;
+
+       /* 興味のあるpidを指定 */
+       if ( is_logo ) {
+               memset(secs, 0,  sizeof(SECcache) * SECCOUNT);
+               secs[0].pid = 0x00; /* PAT  */
+               secs[1].pid = 0x11; /* SDT  */
+               secs[2].pid = 0x29; /* CDT  */
+       }
+       else {
+               memset(secs, 0,  sizeof(SECcache) * SECCOUNT);
+               secs[0].pid = 0x00; /* PAT  */
+               secs[1].pid = 0x11; /* SDT  */
+               secs[2].pid = 0x12; /* EIT  */
+               secs[3].pid = 0x23; /* SDTT */
+               secs[4].pid = 0x26; /* EIT  */
+               secs[5].pid = 0x27; /* EIT  */
+               secs[6].pid = 0x29; /* CDT  */
+       }
+
+       if(strcmp(arg_onTV, "/TIME") == 0){
+               printf("TSに載っている時刻データは2秒ほど早めてあるのかもしれません。\n");
+               memset(secs, 0,  sizeof(SECcache) * SECCOUNT);
+               secs[0].pid = 0x14; /* TOT  */
+
+               GetSDT(infile, NULL, secs, SECCOUNT,NULL, NULL,NULL, 0);
+
+               goto cleanup;
+       }else if(strcmp(arg_onTV, "/BS") == 0){
+               char *head = "BS";
+               GetSDT(infile, svttop, secs, SECCOUNT, &pStas, &staCount, head, is_logo);
        }else if(strcmp(arg_onTV, "/CS") == 0){
-               pStas = csSta;
-               staCount = csStaCount;
-               act = 0 ;
+               char *head = "CS";
+               GetSDT(infile, svttop, secs, SECCOUNT, &pStas, &staCount, head, is_logo);
+       }else if(strcmp(arg_onTV, "/TEST") == 0){
+               memset(secs, 0,  sizeof(SECcache) * SECCOUNT);
+               secs[0].pid = 0x24; /* BIT  */
+
+               char *head = "TEST";
+               GetSDT(infile, svttop, secs, SECCOUNT, &pStas, &staCount, head, 0);
+               //if (sta_count) 
+               //      printf("Station count: %d\n1st ontv=%s,name=%s\n",staCount, pStas[0].ontv, pStas[0].name);
        }else{
+               GetSDT(infile, svttop, secs, SECCOUNT, &pStas, &staCount, arg_onTV, 0);
+
+               // 地上波のマルチチャンネル対応のためコメントアウト
+               /*
                act = 1 ;
                svttop = calloc(1, sizeof(SVT_CONTROL));
                GetSDT(infile, svttop, secs, SECCOUNT);
-               svtcur = svttop->next ; //ÀèƬ
+               svtcur = svttop->next ; //先頭
                if(svtcur == NULL){
                        free(svttop);
-                       return ;
+                       return 1;
                }
 
                pStas = calloc(1, sizeof(STATION));
@@ -378,41 +472,120 @@ int main(int argc, char *argv[])
                pStas->ontv = arg_onTV ;
                pStas->name = svtcur->servicename ;
                staCount = 1;
+               */
        }
+       checkSta(&pStas, &staCount);
 
        fprintf(outfile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        fprintf(outfile, "<!DOCTYPE tv SYSTEM \"xmltv.dtd\">\n\n");
        fprintf(outfile, "<tv generator-info-name=\"tsEPG2xml\" generator-info-url=\"http://localhost/\">\n");
 
-       cd = iconv_open("UTF-8", "EUC-JP");
+       char    ServiceName[1024];
+       char    Logo[8192];
+
+       if ( is_logo ) {
+               memset(Logo, '\0', sizeof(Logo));
+               for(lp = 0 ; lp < staCount ; lp++){
+                       for ( i = 0 ; i < 6 ; i++) {
+                               if (pStas[lp].logo_array[i].logo) {
+                                       base64_encode(Logo, pStas[lp].logo_array[i].logo, pStas[lp].logo_array[i].logo_size);
+                                       xmlspecialchars(Logo);
+                                       fprintf(outfile, "    <logo ts=\"%d\" on=\"%d\" sv=\"%d\" type=\"%d\">%s</logo>\n", 
+                                               pStas[lp].tsId, 
+                                               pStas[lp].onId, 
+                                               pStas[lp].svId, 
+                                               i, 
+                                               Logo);
+                               }
+                       }
+               }
+
+               for ( i = 0; i < 1024; i++) {
+                       if ( dsmctl[i].isUsed == 0 ) break;
+                       parseSDTTdata(dsmctl[i].blockData, &sdtd);
+
+                       for (j = 0; j < sdtd.number_of_loop; j++) {
+                               loop = sdtd.loop + sizeof(SDTTdataLoop) * j;
+
+                               for ( k = 0; k < loop->number_of_services; k++) {
+                                       service = loop->services + sizeof(SDTTdataService) * k;
+
+                                       /*
+                                       for(lp = 0 ; lp < staCount ; lp++){
+                                               if ( 
+                                                       pStas[lp].tsId == service->transport_stream_id && 
+                                                       pStas[lp].onId == service->original_network_id && 
+                                                       pStas[lp].svId == service->service_id
+                                               ) {
+                                                       clt2png(loop->data, 
+                                                               &pStas[lp].logo_array[sdtd.logo_type].logo, 
+                                                               &pStas[lp].logo_array[sdtd.logo_type].logo_size);
+                                               }
+                                       }
+                                       */
+
+                                       #if 0
+                                       printf( "SDTTdataLoop (%d:%d) %d:%d[%d:%d:%d]%d\n", 
+                                               i, j, 
+                                               sdtd.logo_type, 
+                                               loop->logo_id, 
+                                               service->transport_stream_id, 
+                                               service->original_network_id, 
+                                               service->service_id, 
+                                               loop->data_size
+                                       );
+                                       #endif
+
+                               
+                                       void* logo = NULL;
+                                       int logo_size = 0;
+
+                                       clt2png(loop->data, &logo, &logo_size);
+                                       memset(Logo, '\0', sizeof(Logo));
+                                       base64_encode(Logo, logo, logo_size);
+                                       xmlspecialchars(Logo);
+
+                                       fprintf(outfile, "  <logo ts=\"%d\" on=\"%d\" sv=\"%d\" type=\"%d\" dlid=\"%d\">%s</logo>\n", 
+                                               service->transport_stream_id, 
+                                               service->original_network_id, 
+                                               service->service_id, 
+                                               sdtd.logo_type, 
+                                               loop->logo_id, 
+                                               Logo);
+                               }
+
+                       }
+               }
+       }
        for(lp = 0 ; lp < staCount ; lp++){
                memset(ServiceName, '\0', sizeof(ServiceName));
-               ilen = strlen(pStas[lp].name);
-               olen = sizeof(ServiceName);
-               outptr = ServiceName ;
-               inptr = pStas[lp].name ;
-               iconv(cd, &inptr, &ilen, &outptr, &olen);
+               strcpy(ServiceName, pStas[lp].name);
                xmlspecialchars(ServiceName);
 
                fprintf(outfile, "  <channel id=\"%s\">\n", pStas[lp].ontv);
                fprintf(outfile, "    <display-name lang=\"ja_JP\">%s</display-name>\n", ServiceName);
+               fprintf(outfile, "    <id ts=\"%d\" on=\"%d\" sv=\"%d\"/>\n", pStas[lp].tsId, pStas[lp].onId, pStas[lp].svId);
+
                fprintf(outfile, "  </channel>\n");
        }
+       if ( is_logo ) {
+               fprintf(outfile, "</tv>\n");
+               goto cleanup;
+       }
        for(lp = 0 ; lp < staCount ; lp++){
-               GetEIT(infile, outfile, &pStas[lp], secs, SECCOUNT);
+               GetEIT(infile, outfile, &pStas[lp], secs);
        }
        fprintf(outfile, "</tv>\n");
+cleanup: 
        if(inclose) {
                fclose(infile);
        }
-
        if(outclose) {
                fclose(outfile);
        }
-       iconv_close(cd);
        if(act){
                free(pStas);
-               svtcur = svttop ;       //ÀèƬ
+               svtcur = svttop ;       //先頭
                while(svtcur != NULL){
                        svtsave = svtcur->next ;
                        free(svtcur);
@@ -422,3 +595,4 @@ int main(int argc, char *argv[])
 
        return 0;
 }
+