NIT: replacement code for nit.cpp

Origin commit data
------------------
Branch: ni/coolstream
Commit: 26f87c561c
Author: [CST] Focus <focus.cst@gmail.com>
Date: 2012-01-20 (Fri, 20 Jan 2012)


------------------
No further description and justification available within origin commit message!

------------------
This commit was generated by Migit
This commit is contained in:
[CST] Focus
2012-01-20 19:31:52 +04:00
parent 8a5deca888
commit 92c7923983
2 changed files with 349 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
/*
* 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_nit_h__
#define __zapit_scan_nit_h__
#include <OpenThreads/Thread>
#include <dmx.h>
#include <dvbsi++/network_information_section.h>
#include <dvbsi++/satellite_delivery_system_descriptor.h>
#include <dvbsi++/cable_delivery_system_descriptor.h>
#include <dvbsi++/service_list_descriptor.h>
#define NIT_SECTION_SIZE 1024
class CNit : public OpenThreads::Thread
{
private:
int dmxnum;
bool cable;
t_satellite_position satellitePosition;
freq_id_t freq_id;
unsigned short nid;
NetworkInformationSectionList sections;
void run();
bool Read();
bool ParseSatelliteDescriptor(SatelliteDeliverySystemDescriptor * sd, TransportStreamInfo * ts);
bool ParseCableDescriptor(CableDeliverySystemDescriptor * sd, TransportStreamInfo * ts);
bool ParseServiceList(ServiceListDescriptor * sd, TransportStreamInfo * ts);
public:
CNit(t_satellite_position spos, freq_id_t frq, unsigned short pnid, int dnum = 0);
~CNit();
bool Start();
bool Stop();
bool Parse();
};
#endif

288
src/zapit/src/scannit.cpp Normal file
View File

@@ -0,0 +1,288 @@
/*
* 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/scannit.h>
#include <zapit/scan.h>
#include <dvbsi++/descriptor_tag.h>
#include <math.h>
#define DEBUG_NIT
CNit::CNit(t_satellite_position spos, freq_id_t frq, unsigned short pnid, int dnum)
{
satellitePosition = spos;
freq_id = frq;
nid = pnid;
dmxnum = dnum;
cable = (CServiceScan::getInstance()->GetFrontend()->getInfo()->type == FE_QAM);
}
CNit::~CNit()
{
NetworkInformationSectionIterator sit;
for (sit = sections.begin(); sit != sections.end(); ++sit) {
delete *(sit);
}
}
bool CNit::Start()
{
int ret = start();
return (ret == 0);
}
bool CNit::Stop()
{
int ret = join();
return (ret == 0);
}
void CNit::run()
{
if(Parse())
printf("[scan] NIT finished.\n");
else
printf("[scan] NIT failed !\n");
}
bool CNit::Read()
{
bool ret = true;
int secdone[2][255];
int sectotal[2] = { -1, -1 };
int nit_index = 0;
for(int i = 0; i < 2; i++) {
for (int j = 0; j < 255; j++)
secdone[i][j] = 0;
}
cDemux * dmx = new cDemux(dmxnum);
dmx->Open(DMX_PSI_CHANNEL);
unsigned char buffer[NIT_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] = 0x40;
mask[0] = (nid != 0) ? 0xFE : 0xFF; // in case we have network ID we also want the 'other' tables
if (nid) { // filter for the network ID
filter[1] = (nid >> 8) & 0xff;
filter[2] = (nid >> 0) & 0xff;
mask[1] = 0xff;
mask[2] = 0xff;
flen = 3;
}
if (dmx->sectionFilter(0x10, filter, mask, flen) < 0) {
delete dmx;
return false;
}
do {
if (dmx->Read(buffer, NIT_SECTION_SIZE) < 0) {
delete dmx;
return false;
}
if (CServiceScan::getInstance()->Aborted()) {
ret = false;
goto _return;
}
if ((buffer[0] != 0x40) && ((nid > 0) && (buffer[0] != 0x41))) {
// NIT actual or NIT other
printf("[NIT] ******************************************* Bogus section received: 0x%x\n", buffer[0]);
ret = false;
goto _return;
}
nit_index = buffer[0] & 1;
unsigned char secnum = buffer[6];
#ifdef DEBUG_NIT
printf("[NIT] section %X last %X -> %s\n", secnum, buffer[7], secdone[nit_index][secnum] ? "skip" : "use");
#endif
if(secdone[nit_index][secnum]) // mark sec XX done
continue;
secdone[nit_index][secnum] = 1;
sectotal[nit_index]++;
NetworkInformationSection * nit = new NetworkInformationSection(buffer);
sections.push_back(nit);
} while(sectotal[nit_index] < buffer[7]);
_return:
dmx->Stop();
delete dmx;
return ret;
}
bool CNit::Parse()
{
printf("[scan] trying to parse NIT\n");
if(!Read())
return false;
NetworkInformationSectionIterator sit;
#ifdef DEBUG_NIT
printf("NIT: %d sections\n", sections.size());
#endif
for (sit = sections.begin(); sit != sections.end(); ++sit) {
NetworkInformationSection * nit = *sit;
const TransportStreamInfoList *tslist = nit->getTsInfo();
#ifdef DEBUG_NIT
printf("NIT: %d TransportStreamInfos\n", tslist->size());
#endif
if (CServiceScan::getInstance()->Aborted())
return false;
for(TransportStreamInfoConstIterator tit = tslist->begin(); tit != tslist->end(); ++tit) {
TransportStreamInfo * tsinfo = *tit;
const DescriptorList * dlist = tsinfo->getDescriptors();
#if 0 //ifdef DEBUG_NIT
printf("NIT: tsid %04x onid %04x %d descriptors\n", tsinfo->getTransportStreamId(),
tsinfo->getOriginalNetworkId(), dlist->size());
#endif
DescriptorConstIterator dit;
for (dit = dlist->begin(); dit != dlist->end(); ++dit) {
Descriptor * d = *dit;
switch(d->getTag()) {
case SATELLITE_DELIVERY_SYSTEM_DESCRIPTOR:
ParseSatelliteDescriptor((SatelliteDeliverySystemDescriptor *)d, tsinfo);
break;
case CABLE_DELIVERY_SYSTEM_DESCRIPTOR:
ParseCableDescriptor((CableDeliverySystemDescriptor *)d, tsinfo);
break;
case SERVICE_LIST_DESCRIPTOR:
ParseServiceList((ServiceListDescriptor *) d, tsinfo);
break;
default:
{
#ifdef DEBUG_NIT
printf("NIT: 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 CNit::ParseSatelliteDescriptor(SatelliteDeliverySystemDescriptor * sd, TransportStreamInfo * tsinfo)
{
if (cable)
return false;
t_satellite_position newSat;
newSat = ((sd->getOrbitalPosition() >> 12) & 0xF) * 1000;
newSat += ((sd->getOrbitalPosition() >> 8) & 0xF) * 100;
newSat += ((sd->getOrbitalPosition() >> 4) & 0xF) * 10;
newSat += ((sd->getOrbitalPosition()) & 0xF);
if (newSat && (!sd->getWestEastFlag()))
newSat = 3600 - newSat;
if(satellitePosition != newSat) {
printf("NIT: different satellite position: our %d nit %d\n",
satellitePosition, sd->getOrbitalPosition());
}
uint8_t polarization = sd->getPolarization();
FrontendParameters feparams;
feparams.inversion = INVERSION_AUTO;
feparams.frequency = sd->getFrequency() * 10;
feparams.u.qpsk.symbol_rate = sd->getSymbolRate() * 100;
int fec_inner = CFrontend::getCodeRate(sd->getFecInner(), sd->getModulationSystem());
if(sd->getModulation() == 2)
fec_inner += 9;
feparams.u.qpsk.fec_inner = (fe_code_rate_t) fec_inner;
feparams.frequency = (int) 1000 * (int) round ((double) feparams.frequency / (double) 1000);
freq_id_t freq = feparams.frequency / 1000;
transponder_id_t TsidOnid = CREATE_TRANSPONDER_ID_FROM_SATELLITEPOSITION_ORIGINALNETWORK_TRANSPORTSTREAM_ID(
freq, satellitePosition, tsinfo->getTransportStreamId(), tsinfo->getOriginalNetworkId());
CServiceScan::getInstance()->AddTransponder(TsidOnid, &feparams, polarization, true);
return true;
}
bool CNit::ParseCableDescriptor(CableDeliverySystemDescriptor * sd, TransportStreamInfo * tsinfo)
{
if (!cable)
return false;
FrontendParameters feparams;
feparams.inversion = INVERSION_AUTO;
feparams.frequency = sd->getFrequency() * 100;
feparams.u.qam.symbol_rate = sd->getSymbolRate() * 100;
feparams.u.qam.fec_inner = CFrontend::getCodeRate(sd->getFecInner());
feparams.u.qam.modulation = CFrontend::getModulation(sd->getModulation());
if(feparams.frequency > 1000*1000)
feparams.frequency /= 1000;
freq_id_t freq = feparams.frequency / 1000;
transponder_id_t TsidOnid = CREATE_TRANSPONDER_ID_FROM_SATELLITEPOSITION_ORIGINALNETWORK_TRANSPORTSTREAM_ID(
freq, satellitePosition, tsinfo->getTransportStreamId(), tsinfo->getOriginalNetworkId());
CServiceScan::getInstance()->AddTransponder(TsidOnid, &feparams, 0, true);
return true;
}
bool CNit::ParseServiceList(ServiceListDescriptor * sd, TransportStreamInfo * tsinfo)
{
const ServiceListItemList * slist = sd->getServiceList();
ServiceListItemConstIterator it;
for (it = slist->begin(); it != slist->end(); ++it) {
ServiceListItem * s = *it;
t_channel_id channel_id = CZapitChannel::makeChannelId(satellitePosition,
freq_id, tsinfo->getTransportStreamId(), tsinfo->getOriginalNetworkId(), s->getServiceId());
CServiceScan::getInstance()->AddServiceType(channel_id, s->getServiceType());
}
return true;
}