mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-09-02 18:31:12 +02:00
add bat parsing code
Origin commit data
------------------
Branch: ni/coolstream
Commit: 674507c4c3
Author: [CST] Focus <focus.cst@gmail.com>
Date: 2012-03-18 (Sun, 18 Mar 2012)
------------------
No further description and justification available within origin commit message!
------------------
This commit was generated by Migit
This commit is contained in:
62
src/zapit/include/zapit/scanbat.h
Normal file
62
src/zapit/include/zapit/scanbat.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Neutrino-GUI - DBoxII-Project
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 CoolStream International Ltd
|
||||||
|
*
|
||||||
|
* License: GPLv2
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation;
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zapit_scan_bat_h__
|
||||||
|
#define __zapit_scan_bat_h__
|
||||||
|
|
||||||
|
#include <OpenThreads/Thread>
|
||||||
|
#include <dmx.h>
|
||||||
|
#include <dvbsi++/bouquet_association_section.h>
|
||||||
|
#include <dvbsi++/service_list_descriptor.h>
|
||||||
|
#include <dvbsi++/logical_channel_descriptor.h>
|
||||||
|
|
||||||
|
#define BAT_SECTION_SIZE 4098
|
||||||
|
|
||||||
|
typedef std::map <t_channel_id, int> channel_number_map_t;
|
||||||
|
|
||||||
|
class CBat : public OpenThreads::Thread
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int dmxnum;
|
||||||
|
bool cable;
|
||||||
|
|
||||||
|
t_satellite_position satellitePosition;
|
||||||
|
freq_id_t freq_id;
|
||||||
|
channel_number_map_t logical_map;
|
||||||
|
|
||||||
|
BouquetAssociationSectionList sections;
|
||||||
|
|
||||||
|
void run();
|
||||||
|
bool Read();
|
||||||
|
bool ParseServiceList(ServiceListDescriptor * sd, BouquetAssociation * b);
|
||||||
|
bool ParseLogicalChannels(LogicalChannelDescriptor * ld, BouquetAssociation * b);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CBat(t_satellite_position spos, freq_id_t frq, int dnum = 0);
|
||||||
|
~CBat();
|
||||||
|
bool Start();
|
||||||
|
bool Stop();
|
||||||
|
bool Parse();
|
||||||
|
channel_number_map_t & getLogicalMap() { return logical_map; };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
270
src/zapit/src/scanbat.cpp
Normal file
270
src/zapit/src/scanbat.cpp
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 CoolStream International Ltd
|
||||||
|
*
|
||||||
|
* License: GPLv2
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation;
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zapit/debug.h>
|
||||||
|
#include <zapit/getservices.h>
|
||||||
|
#include <dmx.h>
|
||||||
|
#include <zapit/scanbat.h>
|
||||||
|
#include <zapit/scan.h>
|
||||||
|
#include <dvbsi++/descriptor_tag.h>
|
||||||
|
#include <dvbsi++/bouquet_name_descriptor.h>
|
||||||
|
#include <dvbsi++/linkage_descriptor.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <eitd/edvbstring.h>
|
||||||
|
|
||||||
|
#define DEBUG_BAT
|
||||||
|
#define DEBUG_BAT_UNUSED
|
||||||
|
|
||||||
|
CBat::CBat(t_satellite_position spos, freq_id_t frq, int dnum)
|
||||||
|
{
|
||||||
|
satellitePosition = spos;
|
||||||
|
freq_id = frq;
|
||||||
|
dmxnum = dnum;
|
||||||
|
cable = (CServiceScan::getInstance()->GetFrontend()->getInfo()->type == FE_QAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
CBat::~CBat()
|
||||||
|
{
|
||||||
|
BouquetAssociationSectionConstIterator sit;
|
||||||
|
for (sit = sections.begin(); sit != sections.end(); ++sit) {
|
||||||
|
delete *(sit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBat::Start()
|
||||||
|
{
|
||||||
|
int ret = start();
|
||||||
|
return (ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBat::Stop()
|
||||||
|
{
|
||||||
|
int ret = join();
|
||||||
|
return (ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBat::run()
|
||||||
|
{
|
||||||
|
if(Parse())
|
||||||
|
printf("[scan] BAT finished.\n");
|
||||||
|
else
|
||||||
|
printf("[scan] BAT failed !\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBat::Read()
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
int secdone[255];
|
||||||
|
int sectotal = -1;
|
||||||
|
|
||||||
|
memset(secdone, 0, 255);
|
||||||
|
|
||||||
|
cDemux * dmx = new cDemux(dmxnum);
|
||||||
|
dmx->Open(DMX_PSI_CHANNEL);
|
||||||
|
|
||||||
|
unsigned char buffer[BAT_SECTION_SIZE];
|
||||||
|
|
||||||
|
unsigned char filter[DMX_FILTER_SIZE];
|
||||||
|
unsigned char mask[DMX_FILTER_SIZE];
|
||||||
|
|
||||||
|
memset(filter, 0x00, DMX_FILTER_SIZE);
|
||||||
|
memset(mask, 0x00, DMX_FILTER_SIZE);
|
||||||
|
|
||||||
|
int flen = 1;
|
||||||
|
filter[0] = 0x4A;
|
||||||
|
mask[0] = 0xFF;
|
||||||
|
|
||||||
|
if (dmx->sectionFilter(0x11, filter, mask, flen) < 0) {
|
||||||
|
delete dmx;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (dmx->Read(buffer, BAT_SECTION_SIZE) < 0) {
|
||||||
|
delete dmx;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CServiceScan::getInstance()->Aborted()) {
|
||||||
|
ret = false;
|
||||||
|
goto _return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer[0] != 0x4A) {
|
||||||
|
printf("[BAT] ******************************************* Bogus section received: 0x%x\n", buffer[0]);
|
||||||
|
ret = false;
|
||||||
|
goto _return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char secnum = buffer[6];
|
||||||
|
#ifdef DEBUG_BAT
|
||||||
|
printf("[BAT] section %X last %X -> %s\n", secnum, buffer[7], secdone[secnum] ? "skip" : "use");
|
||||||
|
#endif
|
||||||
|
if(secdone[secnum])
|
||||||
|
continue;
|
||||||
|
secdone[secnum] = 1;
|
||||||
|
sectotal++;
|
||||||
|
|
||||||
|
BouquetAssociationSection * bat = new BouquetAssociationSection(buffer);
|
||||||
|
sections.push_back(bat);
|
||||||
|
|
||||||
|
} while(sectotal < buffer[7]);
|
||||||
|
_return:
|
||||||
|
dmx->Stop();
|
||||||
|
delete dmx;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBat::Parse()
|
||||||
|
{
|
||||||
|
printf("[scan] trying to parse BAT\n");
|
||||||
|
|
||||||
|
if(!Read())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BouquetAssociationSectionConstIterator sit;
|
||||||
|
for (sit = sections.begin(); sit != sections.end(); ++sit) {
|
||||||
|
BouquetAssociationSection * bat = *sit;
|
||||||
|
uint16_t bouquet_id = bat->getTableIdExtension();
|
||||||
|
|
||||||
|
if (CServiceScan::getInstance()->Aborted())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const DescriptorList * dlist = bat->getDescriptors();
|
||||||
|
DescriptorConstIterator dit;
|
||||||
|
#ifdef DEBUG_BAT
|
||||||
|
printf("BAT: section %d, %d descriptors\n", bat->getSectionNumber(), dlist->size());
|
||||||
|
#endif
|
||||||
|
for (dit = dlist->begin(); dit != dlist->end(); ++dit) {
|
||||||
|
Descriptor * d = *dit;
|
||||||
|
//printf("BAT: parse descriptor %02x len %d\n", d->getTag(), d->getLength());
|
||||||
|
switch(d->getTag()) {
|
||||||
|
case BOUQUET_NAME_DESCRIPTOR:
|
||||||
|
{
|
||||||
|
BouquetNameDescriptor * nd = (BouquetNameDescriptor *) d;
|
||||||
|
std::string bouquetName = stringDVBUTF8(nd->getBouquetName());
|
||||||
|
printf("BAT: bouquet name [%s]\n", bouquetName.c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LINKAGE_DESCRIPTOR:
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_BAT
|
||||||
|
LinkageDescriptor * ld = (LinkageDescriptor*) d;
|
||||||
|
printf("BAT: linkage, tsid %04x onid %04x sid %04x type %02x\n", ld->getTransportStreamId(),
|
||||||
|
ld->getOriginalNetworkId(), ld->getServiceId(), ld->getLinkageType());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COUNTRY_AVAILABILITY_DESCRIPTOR:
|
||||||
|
case PRIVATE_DATA_SPECIFIER_DESCRIPTOR:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_BAT_UNUSED
|
||||||
|
printf("BAT: descriptor %02x: ", d->getTag());
|
||||||
|
uint8_t len = 2+d->getLength();
|
||||||
|
uint8_t buf[len];
|
||||||
|
d->writeToBuffer(buf);
|
||||||
|
for(uint8_t i = 0; i < len; i++)
|
||||||
|
printf("%02x ", buf[i]);
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const BouquetAssociationList &blist = *bat->getBouquets();
|
||||||
|
BouquetAssociationConstIterator it;
|
||||||
|
for(it = blist.begin(); it != blist.end(); ++it) {
|
||||||
|
BouquetAssociation * b = *it;
|
||||||
|
dlist = b->getDescriptors();
|
||||||
|
#if 1
|
||||||
|
printf("BAT: bouquet_id %04x tsid %04x onid %04x %d descriptors\n", bouquet_id, b->getTransportStreamId(),
|
||||||
|
b->getOriginalNetworkId(), dlist->size());
|
||||||
|
#endif
|
||||||
|
for (dit = dlist->begin(); dit != dlist->end(); ++dit) {
|
||||||
|
Descriptor * d = *dit;
|
||||||
|
switch(d->getTag()) {
|
||||||
|
case SERVICE_LIST_DESCRIPTOR:
|
||||||
|
ParseServiceList((ServiceListDescriptor *) d, b);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOGICAL_CHANNEL_DESCRIPTOR:
|
||||||
|
ParseLogicalChannels((LogicalChannelDescriptor *) d, b);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_BAT_UNUSED
|
||||||
|
printf("BAT: descriptor %02x: ", d->getTag());
|
||||||
|
uint8_t len = 2+d->getLength();
|
||||||
|
uint8_t buf[len];
|
||||||
|
d->writeToBuffer(buf);
|
||||||
|
for(uint8_t i = 0; i < len; i++)
|
||||||
|
printf("%02x ", buf[i]);
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBat::ParseServiceList(ServiceListDescriptor * sd, BouquetAssociation * b)
|
||||||
|
{
|
||||||
|
const ServiceListItemList * slist = sd->getServiceList();
|
||||||
|
ServiceListItemConstIterator it;
|
||||||
|
for (it = slist->begin(); it != slist->end(); ++it) {
|
||||||
|
ServiceListItem * s = *it;
|
||||||
|
#if 0
|
||||||
|
t_channel_id channel_id = CZapitChannel::makeChannelId(satellitePosition,
|
||||||
|
freq_id, b->getTransportStreamId(), b->getOriginalNetworkId(), s->getServiceId());
|
||||||
|
CServiceScan::getInstance()->AddServiceType(channel_id, s->getServiceType());
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG_BAT
|
||||||
|
printf("BAT: service tsid %04x onid %04x sid %04x type %02x\n",
|
||||||
|
b->getTransportStreamId(), b->getOriginalNetworkId(), s->getServiceId(), s->getServiceType());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBat::ParseLogicalChannels(LogicalChannelDescriptor * ld, BouquetAssociation * b)
|
||||||
|
{
|
||||||
|
t_transport_stream_id transport_stream_id = b->getTransportStreamId();
|
||||||
|
t_original_network_id original_network_id = b->getOriginalNetworkId();
|
||||||
|
|
||||||
|
const LogicalChannelList &clist = *ld->getChannelList();
|
||||||
|
LogicalChannelListConstIterator it;
|
||||||
|
for (it = clist.begin(); it != clist.end(); ++it) {
|
||||||
|
t_service_id service_id = (*it)->getServiceId();
|
||||||
|
int lcn = (*it)->getLogicalChannelNumber();
|
||||||
|
/* FIXME dont use freq_id / satellitePosition ? */
|
||||||
|
t_channel_id channel_id = CZapitChannel::makeChannelId(satellitePosition,
|
||||||
|
freq_id, transport_stream_id, original_network_id, service_id);
|
||||||
|
/* (*it)->getVisibleServiceFlag(); */
|
||||||
|
logical_map[channel_id] = lcn;
|
||||||
|
#ifdef DEBUG_LCN
|
||||||
|
printf("BAT: logical channel tsid %04x onid %04x %llx -> %d\n", transport_stream_id, original_network_id, channel_id, lcn);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
Reference in New Issue
Block a user