X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=tstools%2Fepgdump%2Fdsmcc.c;fp=tstools%2Fepgdump%2Fdsmcc.c;h=792493519028e14d1a96278a082f977920c2e6be;hb=0d75d6d668b483567fa7cf86c3107ee41d06e831;hp=0000000000000000000000000000000000000000;hpb=930d3dbdc17ad4179a9b512f4e787a896a544943;p=rec10%2Frec10-git.git diff --git a/tstools/epgdump/dsmcc.c b/tstools/epgdump/dsmcc.c new file mode 100644 index 0000000..7924935 --- /dev/null +++ b/tstools/epgdump/dsmcc.c @@ -0,0 +1,258 @@ +// -*- tab-width:4 -*- + +#include +#include +#include + +#include "dsmcc.h" +#include "ts_ctl.h" +#include "clt2png.h" + +// STD-B21 p130 (144) +// a_90-with-att.pdf p24 (29/99) +int parseDSMCChead(unsigned char *data, DSMCChead *dsmh) { + int boff = 0; + + memset(dsmh, 0, sizeof(DSMCChead)); + + dsmh->table_id = getBit(data, &boff, 8); + dsmh->section_syntax_indicator = getBit(data, &boff, 1); + dsmh->complement_indicator = getBit(data, &boff,1); + dsmh->reserved1 = getBit(data, &boff, 2); + dsmh->section_length = getBit(data, &boff, 12); + dsmh->table_id_extension = getBit(data, &boff, 16); + dsmh->reserved2 = getBit(data, &boff, 2); + dsmh->version_number = getBit(data, &boff, 5); + dsmh->current_next_indicator = getBit(data, &boff, 1); + dsmh->section_number = getBit(data, &boff, 8); + dsmh->last_section_number = getBit(data, &boff, 8); + + return 8; +} + +// a_90-with-att.pdf p29 (34/99) +// 2-STD-B24v5_4-3p3.pdf p16 (30/125) +int parseDSMCCbodyDII(unsigned char *data, DSMCCbodyDII *dsmbdii) { + int boff = 0, i; + DSMCCbodyDIIModule *module; + + memset(dsmbdii, 0, sizeof(DSMCCbodyDII)); + + // header + dsmbdii->protocolDiscriminator = getBit(data, &boff, 8); + dsmbdii->dsmccType = getBit(data, &boff, 8); + dsmbdii->messageId = getBit(data, &boff, 16); + dsmbdii->transaction_id = getBit(data, &boff, 32); + dsmbdii->reserved = getBit(data, &boff, 8); + dsmbdii->adaptationLength = getBit(data, &boff, 8); + dsmbdii->messageLength = getBit(data, &boff, 16); + if ( dsmbdii->adaptationLength > 0 ) { + dsmbdii->dsmccAdaptationHeader = allocCopy(data, &boff, dsmbdii->adaptationLength); + } + + // body + dsmbdii->downloadId = getBit(data, &boff, 32); + dsmbdii->blockSize = getBit(data, &boff, 16); + dsmbdii->windowSize = getBit(data, &boff, 8); + dsmbdii->ackPeriod = getBit(data, &boff, 8); + dsmbdii->tCDownloadWindow = getBit(data, &boff, 32); + dsmbdii->tCDownloadScenario = getBit(data, &boff, 32); + dsmbdii->compatibilityDescriptor = getBit(data, &boff, 16); +/* + see http://www.atsc.org/cms/standards/a_90-with-att.pdf + + compatibilityDescriptorLength 16 + descriptorCount 16 + for(i=0;icompatibilityDescriptor * 8; + dsmbdii->numberOfModules = getBit(data, &boff, 16); + + if ( dsmbdii->numberOfModules > 0 ) { + dsmbdii->modules = calloc(1, sizeof(DSMCCbodyDIIModule) * dsmbdii->numberOfModules + 1000); + + for (i=0; inumberOfModules; i++) { + module = dsmbdii->modules + sizeof(DSMCCbodyDIIModule) * i; + module->moduleId = getBit(data, &boff, 16); + module->moduleSize = getBit(data, &boff, 32); + module->moduleVersion = getBit(data, &boff, 8); + module->moduleInfoLength = getBit(data, &boff, 8); + + if ( *(data + boff / 8) == 0x01 ) { + /* Type 記述子 モジュールの型(MIME 形式等) */ + module->descriptor_tag = getBit(data, &boff, 8); + module->descriptor_length = getBit(data, &boff, 8); + module->Type = allocCopy(data, &boff, module->descriptor_length + 1); + module->Type[module->descriptor_length] = '\0'; + // +1 byte for null-terminated + } + else if ( *(data + boff / 8) == 0x02 ) { + /* Name 記述子 モジュール名(ファイル名) */ + module->descriptor_tag = getBit(data, &boff, 8); + module->descriptor_length = getBit(data, &boff, 8); + module->Name = allocCopy(data, &boff, module->descriptor_length + 1); + module->Name[module->descriptor_length] = '\0'; + } + else if ( *(data + boff / 8) == 0x03 ) { + /* Info 記述子 モジュール情報(文字型) */ + module->descriptor_tag = getBit(data, &boff, 8); + module->descriptor_length = getBit(data, &boff, 8); + boff += 24; // ISO_639_language_code + module->Info = allocCopy(data, &boff, module->descriptor_length - 3 + 1); + module->Info[module->descriptor_length] = '\0'; + } + else { + module->moduleInfo = allocCopy(data, &boff, module->moduleInfoLength); + } + } + } + + dsmbdii->privateDataLength = getBit(data, &boff, 8); + dsmbdii->privateData = allocCopy(data, &boff, dsmbdii->privateDataLength); + + return boff / 8; +} + +// a_90-with-att.pdf p35 (40/99) +int parseDSMCCbodyDDB(unsigned char *data, DSMCCbodyDDB *dsmbddb) { + int boff = 0; + + memset(dsmbddb, 0, sizeof(DSMCCbodyDDB)); + + // header + dsmbddb->protocolDiscriminator = getBit(data, &boff, 8); + dsmbddb->dsmccType = getBit(data, &boff, 8); + dsmbddb->messageId = getBit(data, &boff, 16); + dsmbddb->downloadId = getBit(data, &boff, 32); + dsmbddb->reserved1 = getBit(data, &boff, 8); + dsmbddb->adaptationLength = getBit(data, &boff, 8); + dsmbddb->messageLength = getBit(data, &boff, 16); + if ( dsmbddb->adaptationLength > 0 ) { + dsmbddb->dsmccAdaptationHeader = allocCopy(data, &boff, dsmbddb->adaptationLength); + } + + // body + dsmbddb->moduleId = getBit(data, &boff, 16); + dsmbddb->moduleVersion = getBit(data, &boff, 8); + dsmbddb->reserved2 = getBit(data, &boff, 8); + dsmbddb->blockNumber = getBit(data, &boff, 16); + dsmbddb->blockData = allocCopy(data, &boff, dsmbddb->messageLength); + + return boff / 8; +} + +void dumpDSMCC(unsigned char *ptr, int * downloadDataId, DSM_CONTROL *dsmctl) +{ + DSMCChead dsmh; + DSMCCbodyDII dsmbdii; + DSMCCbodyDDB dsmbddb; + DSMCCbodyDIIModule *module; + + int len = 0; + int i = 0; + + /* DSMCC */ + len = parseDSMCChead(ptr, &dsmh); + ptr += len; + //loop_len = dsmh.section_length - (len - 3 + 4); // 3は共通ヘッダ長 4はCRC +/* + printf("DSMCChead=(%d:%d:%d:%d)\n", + dsmh.table_id, dsmh.section_length, + dsmh.table_id_extension, dsmh.section_number); +*/ + if ( dsmh.table_id == 0x3B ) { + len = parseDSMCCbodyDII(ptr, &dsmbdii); +#if 0 + printf("DSMCCbDII=(%d:%d:%d:%d:%d:%d) (%d:%d:%d:%d)\n", + dsmbdii.protocolDiscriminator, dsmbdii.dsmccType, + dsmbdii.messageId, dsmbdii.transaction_id, + dsmbdii.adaptationLength, dsmbdii.messageLength, + + dsmbdii.downloadId , dsmbdii.blockSize , dsmbdii.compatibilityDescriptor , + dsmbdii.numberOfModules); +#endif + for (i=0; idescriptor_tag == 0x01 ) { + //printf("1 %s\n", module->Type); + } + else if ( module->descriptor_tag == 0x02 ) { + //printf("2 %s\n", module->Name); + // is_bs_cs == 1 && + if ( !strncmp( module->Name, "LOGO", 4 ) ) { + //printf("%s(%d) : id = %d\n", module->Name, is_bs_cs, dsmbdii.downloadId); + *downloadDataId = dsmbdii.downloadId; + } + // なぜかBSにCSのロゴも載ってるため + // is_bs_cs == 2 && + else if ( !strncmp( module->Name, "CS_LOGO", 7 ) ) { + //printf("%s(%d) : id = %d\n", module->Name, is_bs_cs, dsmbdii.downloadId); + *downloadDataId = dsmbdii.downloadId; + } + } + else if ( module->descriptor_tag == 0x03 ) { + //printf("3 %s\n", module->Info); + } + } + } + else if ( dsmh.table_id == 0x3C ) { + len = parseDSMCCbodyDDB(ptr, &dsmbddb); + if ( *downloadDataId == dsmbddb.downloadId ) { +// if ( 33882368 == dsmbddb.downloadId ) { +// { +#if 0 + printf("DSMCCbDDB=(%d:%d:%d:%d:%d:%d) (%d:%d:%d)\n", + dsmbddb.protocolDiscriminator, dsmbddb.dsmccType, + dsmbddb.messageId, dsmbddb.downloadId, + dsmbddb.adaptationLength, dsmbddb.messageLength, + + dsmbddb.moduleId , dsmbddb.moduleVersion , dsmbddb.blockNumber); +#endif + + for (i = 0; i < 1024; i++) { + if ( dsmctl[i].isUsed == 0 ) { + // リストの終端まで来たので + //printf("moduleId=%d as dsmctl[%d]\n", dsmbddb.moduleId, i); + dsmctl[i].moduleId = dsmbddb.moduleId; + dsmctl[i].lastBlockNumber = -1; + dsmctl[i].isUsed = 1; + } + if ( dsmctl[i].moduleId == dsmbddb.moduleId ) { + if ( dsmctl[i].lastBlockNumber + 1 == dsmbddb.blockNumber ) { + dsmbddb.messageLength -= 6; // length of moduleId, moduleVersion, reserved, blockNumber + //printf("moduleId=%d as dsmctl[%d] size %d += %d\n", dsmbddb.moduleId, i, dsmctl[i].blockSize, dsmbddb.messageLength); + dsmctl[i].blockData = realloc( dsmctl[i].blockData, dsmctl[i].blockSize + dsmbddb.messageLength ); + memcpy( dsmctl[i].blockData + dsmctl[i].blockSize, dsmbddb.blockData, dsmbddb.messageLength ); + dsmctl[i].blockSize += dsmbddb.messageLength; + dsmctl[i].lastBlockNumber++; + } + else { + //printf("ignoring %d(max %d)\n", dsmbddb.blockNumber, dsmctl[i].lastBlockNumber); + } + break; + } + } + } + } + + return; +} +