CServiceManager class to hold all service-related code.

git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-beta@1644 e54a6e83-5905-42d5-8d5c-058d10e6a962
This commit is contained in:
focus
2011-09-01 12:08:52 +00:00
parent 3f9447410a
commit b4d309b375
2 changed files with 502 additions and 164 deletions

View File

@@ -30,21 +30,14 @@
#include "descriptors.h" #include "descriptors.h"
#include "sdt.h" #include "sdt.h"
#include "types.h" #include "types.h"
#include "xmlinterface.h" #include <xmltree/xmlinterface.h>
#include <zapit/channel.h>
#include <zapit/bouquets.h>
#include <zapit/satconfig.h>
#include <map> #include <map>
#define zapped_chan_is_nvod 0x80 #define zapped_chan_is_nvod 0x80
//#define NONE 0x0000
//#define INVALID 0x1FFF
void ParseTransponders(xmlNodePtr xmltransponder, t_satellite_position satellitePosition);
void ParseChannels (xmlNodePtr node, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq);
void FindTransponder (xmlNodePtr root);
int LoadServices (fe_type_t FrontendType, diseqc_t, bool only_current);
void SaveServices(bool tocopy);
void SaveMotorPositions();
struct transponder struct transponder
{ {
t_transport_stream_id transport_stream_id; t_transport_stream_id transport_stream_id;
@@ -80,10 +73,81 @@ struct transponder
updated = 0; updated = 0;
} }
}; };
typedef std::map <transponder_id_t, transponder> transponder_list_t; typedef std::map <transponder_id_t, transponder> transponder_list_t;
typedef std::map <transponder_id_t, transponder>::iterator stiterator; typedef std::map <transponder_id_t, transponder>::iterator stiterator;
typedef std::map<transponder_id_t, time_t> sdt_tp_t;
extern transponder_list_t scantransponders; extern transponder_list_t scantransponders;
extern transponder_list_t transponders; extern transponder_list_t transponders;
typedef map<t_channel_id, CZapitChannel> channel_map_t;
typedef channel_map_t::iterator channel_map_iterator_t;
typedef std::pair<t_channel_id, CZapitChannel> channel_pair_t;
typedef std::pair<channel_map_iterator_t,bool> channel_insert_res_t;
class CServiceManager
{
private:
xmlDocPtr scanInputParser;
int service_count;
int tp_count;
uint32_t fake_tid;
uint32_t fake_nid;
int newfound;
tallchans allchans;
tallchans curchans;
tallchans nvodchannels;
bool ParseScanXml();
void ParseTransponders(xmlNodePtr node, t_satellite_position satellitePosition, bool cable);
void ParseChannels(xmlNodePtr node, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq);
void FindTransponder(xmlNodePtr search);
void ParseSatTransponders(fe_type_t frontendType, xmlNodePtr search, t_satellite_position satellitePosition);
int LoadMotorPositions(void);
void WriteSatHeader(FILE * fd, sat_config_t &config);
void WriteTransponderHeader(FILE * fd, struct transponder &tp);
void WriteCurrentService(FILE * fd, bool &satfound, bool &tpdone,
bool &updated, char * satstr, struct transponder &tp, CZapitChannel &channel, const char * action);
static CServiceManager * manager;
CServiceManager();
public:
~CServiceManager();
static CServiceManager * getInstance();
static void CopyFile(char * from, char * to);
void InitSatPosition(t_satellite_position position);
bool LoadServices(bool only_current);
void SaveServices(bool tocopy);
void SaveMotorPositions();
bool SaveCurrentServices(transponder_id_t tpid);
bool AddChannel(CZapitChannel * &channel);
bool AddCurrentChannel(CZapitChannel * &channel);
bool AddNVODChannel(CZapitChannel * &channel);
void ResetChannelNumbers();
void RemoveChannel(const t_channel_id channel_id);
void RemoveAllChannels();
void RemoveCurrentChannels();
void RemoveNVODChannels();
CZapitChannel* FindChannel(const t_channel_id channel_id, bool * current_is_nvod = NULL);
CZapitChannel* FindChannelByName(std::string name);
CZapitChannel* FindCurrentChannel(const t_channel_id channel_id);
std::string GetServiceName(t_channel_id channel_id);
bool GetAllRadioChannels(ZapitChannelList &list);
bool GetAllTvChannels(ZapitChannelList &list);
bool GetAllHDChannels(ZapitChannelList &list);
bool GetAllSatelliteChannels(ZapitChannelList &list, t_satellite_position position);
bool GetAllUnusedChannels(ZapitChannelList &list);
xmlDocPtr ScanXml();
};
#endif /* __getservices_h__ */ #endif /* __getservices_h__ */

View File

@@ -19,9 +19,8 @@
* *
*/ */
#include <zapit/bouquets.h>
#include <zapit/channel.h>
#include <zapit/debug.h> #include <zapit/debug.h>
#include <zapit/zapit.h>
#include <zapit/frontend_c.h> #include <zapit/frontend_c.h>
#include <zapit/getservices.h> #include <zapit/getservices.h>
#include <zapit/settings.h> #include <zapit/settings.h>
@@ -29,41 +28,235 @@
#include <xmlinterface.h> #include <xmlinterface.h>
#include <math.h> #include <math.h>
#include <sys/time.h> #include <sys/time.h>
#include <set>
extern xmlDocPtr scanInputParser; //#define SAVE_DEBUG
extern transponder_list_t transponders; extern transponder_list_t transponders;
extern tallchans allchans;
extern int scanSDT;
static int newfound;
satellite_map_t satellitePositions; satellite_map_t satellitePositions;
std::map<transponder_id_t, transponder> select_transponders; std::map<transponder_id_t, transponder> select_transponders;
int newtpid;
int tcnt = 0;
int scnt = 0;
extern int zapit_debug; extern int zapit_debug;
extern map<t_channel_id, audio_map_set_t> audio_map;
void save_services(bool tocopy);
#define TIMER_START() \ CServiceManager * CServiceManager::manager = NULL;
static struct timeval tv, tv2; \
static unsigned int msec; \
gettimeofday(&tv, NULL)
#define TIMER_STOP(label) \ CServiceManager::CServiceManager()
gettimeofday(&tv2, NULL); \ {
msec = ((tv2.tv_sec - tv.tv_sec) * 1000) + ((tv2.tv_usec - tv.tv_usec) / 1000); \ scanInputParser = NULL;
printf("%s: %u msec\n", label, msec) service_count = 0;
}
void ParseTransponders(xmlNodePtr node, t_satellite_position satellitePosition, bool cable) CServiceManager::~CServiceManager()
{
delete scanInputParser;
}
CServiceManager * CServiceManager::getInstance()
{
if(manager == NULL)
manager = new CServiceManager();
return manager;
}
bool CServiceManager::ParseScanXml(void)
{
if(scanInputParser) {
delete scanInputParser;
scanInputParser = NULL;
}
switch (CFrontend::getInstance()->getInfo()->type) {
case FE_QPSK:
scanInputParser = parseXmlFile(SATELLITES_XML);
break;
case FE_QAM:
scanInputParser = parseXmlFile(CABLES_XML);
break;
default:
WARN("Unknown type %d", CFrontend::getInstance()->getInfo()->type);
return false;
}
return (scanInputParser != NULL);
}
xmlDocPtr CServiceManager::ScanXml()
{
if(!scanInputParser)
ParseScanXml();
return scanInputParser;
}
bool CServiceManager::AddChannel(CZapitChannel * &channel)
{
channel_insert_res_t ret = allchans.insert (
channel_pair_t (channel->getChannelID(), *channel));
delete channel;
channel = &ret.first->second;
return ret.second;
}
bool CServiceManager::AddCurrentChannel(CZapitChannel * &channel)
{
channel_insert_res_t ret = curchans.insert (
channel_pair_t (channel->getChannelID(), *channel));
delete channel;
channel = &ret.first->second;
return ret.second;
}
bool CServiceManager::AddNVODChannel(CZapitChannel * &channel)
{
t_service_id service_id = channel->getServiceId();
t_original_network_id original_network_id = channel->getOriginalNetworkId();
t_transport_stream_id transport_stream_id = channel->getTransportStreamId();
t_satellite_position satellitePosition = channel->getSatellitePosition();
t_channel_id sub_channel_id =
((uint64_t) ( satellitePosition >= 0 ? satellitePosition : (uint64_t)(0xF000+ abs(satellitePosition))) << 48) |
(uint64_t) CREATE_CHANNEL_ID_FROM_SERVICE_ORIGINALNETWORK_TRANSPORTSTREAM_ID(service_id, original_network_id, transport_stream_id);
channel_insert_res_t ret = nvodchannels.insert (
channel_pair_t (sub_channel_id, *channel));
delete channel;
channel = &ret.first->second;
return ret.second;
}
void CServiceManager::ResetChannelNumbers()
{
for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); it++) {
it->second.number = 0;
it->second.has_bouquet = 0;
}
}
void CServiceManager::RemoveChannel(const t_channel_id channel_id)
{
allchans.erase(channel_id);
}
void CServiceManager::RemoveAllChannels()
{
allchans.clear();
}
void CServiceManager::RemoveNVODChannels()
{
nvodchannels.clear();
}
void CServiceManager::RemoveCurrentChannels()
{
curchans.clear();
}
CZapitChannel * CServiceManager::FindChannel(const t_channel_id channel_id, bool * current_is_nvod)
{
if(current_is_nvod)
*current_is_nvod = false;
channel_map_iterator_t cit = nvodchannels.find(channel_id);
if (cit == nvodchannels.end()) {
cit = allchans.find(channel_id);
if (cit == allchans.end()) {
printf("%s: channel %llx not found\n", __FUNCTION__, channel_id);
return NULL;
}
} else if(current_is_nvod)
*current_is_nvod = true;
return &cit->second;
}
CZapitChannel * CServiceManager::FindChannelByName(std::string name)
{
for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); it++) {
if(it->second.getName().length() == name.length() &&
!strcasecmp(it->second.getName().c_str(), name.c_str())) {
return &it->second;
}
}
return NULL;
}
CZapitChannel * CServiceManager::FindCurrentChannel(const t_channel_id channel_id)
{
channel_map_iterator_t cit = curchans.find(channel_id);
if(cit != curchans.end())
return &cit->second;
return NULL;
}
bool CServiceManager::GetAllRadioChannels(ZapitChannelList &list)
{
list.clear();
for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); it++) {
if (it->second.getServiceType() == ST_DIGITAL_RADIO_SOUND_SERVICE)
list.push_back(&(it->second));
}
return (list.size() != 0);
}
bool CServiceManager::GetAllTvChannels(ZapitChannelList &list)
{
list.clear();
for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); it++) {
if (it->second.getServiceType() != ST_DIGITAL_RADIO_SOUND_SERVICE)
list.push_back(&(it->second));
}
return (list.size() != 0);
}
bool CServiceManager::GetAllHDChannels(ZapitChannelList &list)
{
list.clear();
for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); it++) {
if (it->second.isHD())
list.push_back(&(it->second));
}
return (list.size() != 0);
}
bool CServiceManager::GetAllUnusedChannels(ZapitChannelList &list)
{
list.clear();
for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); it++) {
if (it->second.has_bouquet == false)
list.push_back(&(it->second));
}
return (list.size() != 0);
}
bool CServiceManager::GetAllSatelliteChannels(ZapitChannelList &list, t_satellite_position position)
{
list.clear();
for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); it++) {
if(it->second.getSatellitePosition() == position)
list.push_back(&(it->second));
}
return (list.size() != 0);
}
std::string CServiceManager::GetServiceName(t_channel_id channel_id)
{
channel_map_iterator_t it = allchans.find(channel_id);
if (it != allchans.end())
return it->second.getName();
else
return "";
}
void CServiceManager::ParseTransponders(xmlNodePtr node, t_satellite_position satellitePosition, bool cable)
{ {
t_transport_stream_id transport_stream_id; t_transport_stream_id transport_stream_id;
t_original_network_id original_network_id; t_original_network_id original_network_id;
FrontendParameters feparams; FrontendParameters feparams;
uint8_t polarization = 0; uint8_t polarization = 0;
uint16_t freq; uint16_t freq;
tcnt =0; tp_count = 0;
memset(&feparams, 0, sizeof(FrontendParameters)); memset(&feparams, 0, sizeof(FrontendParameters));
@@ -122,7 +315,7 @@ void ParseTransponders(xmlNodePtr node, t_satellite_position satellitePosition,
return; return;
} }
void ParseChannels(xmlNodePtr node, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq) void CServiceManager::ParseChannels(xmlNodePtr node, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq)
{ {
t_service_id service_id; t_service_id service_id;
std::string name; std::string name;
@@ -164,69 +357,46 @@ void ParseChannels(xmlNodePtr node, const t_transport_stream_id transport_stream
node = node->xmlNextNode; node = node->xmlNextNode;
continue; continue;
} }
#if 0 audio_map_set_t * pidmap = CZapit::getInstance()->GetSavedPids(chid);
switch (service_type) { if(pidmap)
case ST_DIGITAL_TELEVISION_SERVICE: apid = pidmap->apid;
case ST_NVOD_REFERENCE_SERVICE:
case ST_NVOD_TIME_SHIFTED_SERVICE:
case ST_DIGITAL_RADIO_SOUND_SERVICE:
#endif
{
map<t_channel_id, audio_map_set_t>::iterator audio_map_it;
audio_map_it = audio_map.find(chid);
if((audio_map_it != audio_map.end()) && (audio_map_it->second.apid != 0)) {
apid = audio_map_it->second.apid;
}
pair<map<t_channel_id, CZapitChannel>::iterator,bool> ret; CZapitChannel * channel = new CZapitChannel ( name, service_id,
ret = allchans.insert ( transport_stream_id,
std::pair <t_channel_id, CZapitChannel> (chid, original_network_id,
CZapitChannel ( name, service_id, service_type,
transport_stream_id, satellitePosition,
original_network_id, freq);
service_type,
satellitePosition,
freq
)
)
);
//printf("INS CHANNEL %s %x\n", name.c_str(), (int) &ret.first->second);
if(ret.second == false) {
printf("[zapit] duplicate channel %s id %llx freq %d (old %s at %d)\n",
name.c_str(), chid, freq, ret.first->second.getName().c_str(), ret.first->second.getFreqId());
} else {
scnt++;
tallchans_iterator cit1 = ret.first;
cit1->second.scrambled = scrambled;
service_type = cit1->second.getServiceType();
if(pmtpid != 0 && (((service_type == 2) && (apid > 0)) || ( (service_type == 1) && (vpid > 0) && (apid > 0))) ) {
DBG("[getserv] preset chan %s vpid %X sid %X tpid %X onid %X\n", name.c_str(), vpid, service_id, transport_stream_id, transport_stream_id);
cit1->second.setVideoPid(vpid);
cit1->second.setAudioPid(apid);
cit1->second.setPcrPid(pcrpid);
cit1->second.setPmtPid(pmtpid);
cit1->second.setTeletextPid(txpid);
cit1->second.setPidsFlag();
cit1->second.type = vtype;
}
}
}
#if 0
break;
default: bool ret = AddChannel(channel);
break;
//printf("INS CHANNEL %s %x\n", name.c_str(), (int) &ret.first->second);
if(ret == false) {
printf("[zapit] duplicate channel %s id %llx freq %d (old %s at %d)\n",
name.c_str(), chid, freq, channel->getName().c_str(), channel->getFreqId());
} else {
service_count++;
channel->scrambled = scrambled;
service_type = channel->getServiceType();
if(pmtpid != 0 && (((service_type == 2) && (apid > 0)) || ( (service_type == 1) && (vpid > 0) && (apid > 0))) ) {
DBG("[getserv] preset chan %s vpid %X sid %X tpid %X onid %X\n", name.c_str(), vpid, service_id, transport_stream_id, transport_stream_id);
channel->setVideoPid(vpid);
channel->setAudioPid(apid);
channel->setPcrPid(pcrpid);
channel->setPmtPid(pmtpid);
channel->setTeletextPid(txpid);
channel->setPidsFlag();
channel->type = vtype;
}
} }
#endif
node = node->xmlNextNode; node = node->xmlNextNode;
} }
return; return;
} }
void FindTransponder(xmlNodePtr search) void CServiceManager::FindTransponder(xmlNodePtr search)
{ {
t_satellite_position satellitePosition = 0; t_satellite_position satellitePosition = 0;
newtpid = 0xC000;
while (search) { while (search) {
bool cable = false; bool cable = false;
@@ -245,8 +415,7 @@ void FindTransponder(xmlNodePtr search)
} }
} }
static uint32_t fake_tid, fake_nid; void CServiceManager::ParseSatTransponders(fe_type_t frontendType, xmlNodePtr search, t_satellite_position satellitePosition)
void ParseSatTransponders(fe_type_t frontendType, xmlNodePtr search, t_satellite_position satellitePosition)
{ {
uint8_t polarization = 0; uint8_t polarization = 0;
uint8_t system = 0, modulation = 1; uint8_t system = 0, modulation = 1;
@@ -309,7 +478,7 @@ void ParseSatTransponders(fe_type_t frontendType, xmlNodePtr search, t_satellite
} }
} }
int LoadMotorPositions(void) int CServiceManager::LoadMotorPositions(void)
{ {
FILE *fd = NULL; FILE *fd = NULL;
char buffer[256] = ""; char buffer[256] = "";
@@ -337,6 +506,7 @@ int LoadMotorPositions(void)
sit->second.use_in_scan = inuse; sit->second.use_in_scan = inuse;
sit->second.use_usals = usals; sit->second.use_usals = usals;
sit->second.input = input; sit->second.input = input;
sit->second.position = satellitePosition;
} }
fgets(buffer, 255, fd); fgets(buffer, 255, fd);
} }
@@ -348,7 +518,7 @@ int LoadMotorPositions(void)
return 0; return 0;
} }
void SaveMotorPositions() void CServiceManager::SaveMotorPositions()
{ {
FILE * fd; FILE * fd;
sat_iterator_t sit; sat_iterator_t sit;
@@ -369,7 +539,7 @@ void SaveMotorPositions()
fclose(fd); fclose(fd);
} }
void init_sat(t_satellite_position position) void CServiceManager::InitSatPosition(t_satellite_position position)
{ {
satellitePositions[position].position = 0; satellitePositions[position].position = 0;
satellitePositions[position].diseqc = -1; satellitePositions[position].diseqc = -1;
@@ -385,29 +555,25 @@ void init_sat(t_satellite_position position)
satellitePositions[position].input = 0; satellitePositions[position].input = 0;
} }
int LoadServices(fe_type_t frontendType, diseqc_t /*diseqcType*/, bool only_current) bool CServiceManager::LoadServices(bool only_current)
{ {
xmlDocPtr parser; xmlDocPtr parser;
static bool satcleared = 0;//clear only once, because menu is static static bool satcleared = 0;//clear only once, because menu is static
scnt = 0; service_count = 0;
printf("[zapit] Loading services, channel size %d ..\n", sizeof(CZapitChannel)); printf("[zapit] Loading services, channel size %d ..\n", sizeof(CZapitChannel));
fe_type_t frontendType = CFrontend::getInstance()->getInfo()->type;
if(only_current) if(only_current)
goto do_current; goto do_current;
TIMER_START(); TIMER_START();
allchans.clear();
transponders.clear();
select_transponders.clear(); select_transponders.clear();
fake_tid = fake_nid = 0; fake_tid = fake_nid = 0;
if(!scanInputParser) { if (ParseScanXml()) {
if(frontendType == FE_QPSK) {
scanInputParser = parseXmlFile(SATELLITES_XML);
} else if(frontendType == FE_QAM) {
scanInputParser = parseXmlFile(CABLES_XML);
}
}
if (scanInputParser != NULL) {
t_satellite_position position = 0; t_satellite_position position = 0;
if(!satcleared) if(!satcleared)
satellitePositions.clear(); satellitePositions.clear();
@@ -418,15 +584,15 @@ int LoadServices(fe_type_t frontendType, diseqc_t /*diseqcType*/, bool only_curr
if (!(strcmp(xmlGetName(search), "sat"))) { if (!(strcmp(xmlGetName(search), "sat"))) {
position = xmlGetSignedNumericAttribute(search, "position", 10); position = xmlGetSignedNumericAttribute(search, "position", 10);
char * name = xmlGetAttribute(search, "name"); char * name = xmlGetAttribute(search, "name");
/* FIXME reuse this */
if(satellitePositions.find(position) == satellitePositions.end()) { if(satellitePositions.find(position) == satellitePositions.end()) {
init_sat(position); InitSatPosition(position);
} }
satellitePositions[position].name = name; satellitePositions[position].name = name;
} else if(!(strcmp(xmlGetName(search), "cable"))) { } else if(!(strcmp(xmlGetName(search), "cable"))) {
char * name = xmlGetAttribute(search, "name"); char * name = xmlGetAttribute(search, "name");
if(satellitePositions.find(position) == satellitePositions.end()) { if(satellitePositions.find(position) == satellitePositions.end()) {
init_sat(position); InitSatPosition(position);
} }
satellitePositions[position].name = name; satellitePositions[position].name = name;
} }
@@ -444,7 +610,7 @@ int LoadServices(fe_type_t frontendType, diseqc_t /*diseqcType*/, bool only_curr
t_satellite_position position = xmlGetSignedNumericAttribute(search, "position", 10); t_satellite_position position = xmlGetSignedNumericAttribute(search, "position", 10);
char * name = xmlGetAttribute(search, "name"); char * name = xmlGetAttribute(search, "name");
if(satellitePositions.find(position) == satellitePositions.end()) { if(satellitePositions.find(position) == satellitePositions.end()) {
init_sat(position); InitSatPosition(position);
satellitePositions[position].name = name; satellitePositions[position].name = name;
} }
} }
@@ -459,7 +625,7 @@ int LoadServices(fe_type_t frontendType, diseqc_t /*diseqcType*/, bool only_curr
LoadMotorPositions(); LoadMotorPositions();
} }
printf("[zapit] %d services loaded (%d)...\n", scnt, allchans.size()); printf("[zapit] %d services loaded (%d)...\n", service_count, allchans.size());
TIMER_STOP("[zapit] service loading took"); TIMER_STOP("[zapit] service loading took");
if(zapit_debug) {//FIXME if(zapit_debug) {//FIXME
@@ -469,7 +635,7 @@ int LoadServices(fe_type_t frontendType, diseqc_t /*diseqcType*/, bool only_curr
} }
do_current: do_current:
DBG("Loading current..\n"); DBG("Loading current..\n");
if (scanSDT && (parser = parseXmlFile(CURRENTSERVICES_XML))) { if (CZapit::getInstance()->scanSDT() && (parser = parseXmlFile(CURRENTSERVICES_XML))) {
newfound = 0; newfound = 0;
printf("[getservices] " CURRENTSERVICES_XML " found.\n"); printf("[getservices] " CURRENTSERVICES_XML " found.\n");
FindTransponder(xmlDocGetRootElement(parser)->xmlChildrenNode); FindTransponder(xmlDocGetRootElement(parser)->xmlChildrenNode);
@@ -487,11 +653,10 @@ do_current:
} }
} }
return 0; return true;
} }
//#define SAVE_DEBUG void CServiceManager::CopyFile(char * from, char * to)
void zapit_cp(char * from, char * to)
{ {
char cmd[256] = "cp -f "; char cmd[256] = "cp -f ";
strcat(cmd, from); strcat(cmd, from);
@@ -501,16 +666,54 @@ void zapit_cp(char * from, char * to)
sync(); sync();
} }
void SaveServices(bool tocopy) void CServiceManager::WriteSatHeader(FILE * fd, sat_config_t &config)
{
switch (CFrontend::getInstance()->getInfo()->type) {
case FE_QPSK: /* satellite */
fprintf(fd, "\t<sat name=\"%s\" position=\"%hd\" diseqc=\"%hd\" uncommited=\"%hd\">\n",
config.name.c_str(), config.position, config.diseqc, config.uncommited);
break;
case FE_QAM: /* cable */
fprintf(fd, "\t<cable name=\"%s\" position=\"%hd\">\n", config.name.c_str(), config.position);
break;
case FE_OFDM:
default:
break;
}
}
void CServiceManager::WriteTransponderHeader(FILE * fd, struct transponder &tp)
{
switch (CFrontend::getInstance()->getInfo()->type) {
case FE_QPSK: /* satellite */
fprintf(fd, "\t\t<TS id=\"%04x\" on=\"%04x\" frq=\"%u\" inv=\"%hu\" sr=\"%u\" fec=\"%hu\" pol=\"%hu\">\n",
tp.transport_stream_id, tp.original_network_id,
tp.feparams.frequency, tp.feparams.inversion,
tp.feparams.u.qpsk.symbol_rate, tp.feparams.u.qpsk.fec_inner,
tp.polarization);
break;
case FE_QAM: /* cable */
fprintf(fd, "\t\t<TS id=\"%04x\" on=\"%04x\" frq=\"%u\" inv=\"%hu\" sr=\"%u\" fec=\"%hu\" mod=\"%hu\">\n",
tp.transport_stream_id, tp.original_network_id,
tp.feparams.frequency, tp.feparams.inversion,
tp.feparams.u.qam.symbol_rate, tp.feparams.u.qam.fec_inner,
tp.feparams.u.qam.modulation);
break;
case FE_OFDM:
default:
break;
}
}
void CServiceManager::SaveServices(bool tocopy)
{ {
transponder_id_t tpid = 0; transponder_id_t tpid = 0;
FILE * fd = 0; FILE * fd = 0;
bool updated = 0; bool updated = 0;
tallchans_iterator ccI; channel_map_iterator_t ccI;
tallchans_iterator dI; channel_map_iterator_t dI;
transponder_list_t::iterator tI; transponder_list_t::iterator tI;
char tpstr[256];
bool tpdone = 0; bool tpdone = 0;
bool satdone = 0; bool satdone = 0;
int processed = 0; int processed = 0;
@@ -546,60 +749,19 @@ void SaveServices(bool tocopy)
#endif #endif
continue; continue;
} }
switch (CFrontend::getInstance()->getInfo()->type) {
case FE_QPSK: /* satellite */
sprintf(tpstr, "\t\t<TS id=\"%04x\" on=\"%04x\" frq=\"%u\" inv=\"%hu\" sr=\"%u\" fec=\"%hu\" pol=\"%hu\">\n",
tI->second.transport_stream_id, tI->second.original_network_id,
tI->second.feparams.frequency, tI->second.feparams.inversion,
tI->second.feparams.u.qpsk.symbol_rate, tI->second.feparams.u.qpsk.fec_inner,
tI->second.polarization);
break;
case FE_QAM: /* cable */
sprintf(tpstr, "\t\t<TS id=\"%04x\" on=\"%04x\" frq=\"%u\" inv=\"%hu\" sr=\"%u\" fec=\"%hu\" mod=\"%hu\">\n",
tI->second.transport_stream_id, tI->second.original_network_id,
tI->second.feparams.frequency, tI->second.feparams.inversion,
tI->second.feparams.u.qam.symbol_rate, tI->second.feparams.u.qam.fec_inner,
tI->second.feparams.u.qam.modulation);
break;
case FE_OFDM:
default:
break;
}
tpid = tI->first; tpid = tI->first;
for (ccI = allchans.begin(); ccI != allchans.end(); ccI++) { for (ccI = allchans.begin(); ccI != allchans.end(); ccI++) {
if(ccI->second.getTransponderId() == tpid) { if(ccI->second.getTransponderId() == tpid) {
if(!satdone) { if(!satdone) {
switch (CFrontend::getInstance()->getInfo()->type) { WriteSatHeader(fd, spos_it->second);
case FE_QPSK: /* satellite */
fprintf(fd, "\t<sat name=\"%s\" position=\"%hd\" diseqc=\"%hd\" uncommited=\"%hd\">\n",
spos_it->second.name.c_str(), spos_it->first, spos_it->second.diseqc, spos_it->second.uncommited);
break;
case FE_QAM: /* cable */
fprintf(fd, "\t<cable name=\"%s\" position=\"%hd\">\n", spos_it->second.name.c_str(), spos_it->first);
break;
case FE_OFDM:
default:
break;
}
satdone = 1; satdone = 1;
} }
if(!tpdone) { if(!tpdone) {
fprintf(fd, "%s", tpstr); WriteTransponderHeader(fd, tI->second);
tpdone = 1; tpdone = 1;
} }
if(ccI->second.getPidsFlag()) {
fprintf(fd, "\t\t\t<S i=\"%04x\" n=\"%s\" v=\"%x\" a=\"%x\" p=\"%x\" pmt=\"%x\" tx=\"%x\" t=\"%x\" vt=\"%d\" s=\"%d\"/>\n", ccI->second.dumpServiceXml(fd);
ccI->second.getServiceId(), convert_UTF8_To_UTF8_XML(ccI->second.getName().c_str()).c_str(),
ccI->second.getVideoPid(), ccI->second.getPreAudioPid(),
ccI->second.getPcrPid(), ccI->second.getPmtPid(), ccI->second.getTeletextPid(),
ccI->second.getServiceType(true), ccI->second.type, ccI->second.scrambled);
} else {
fprintf(fd, "\t\t\t<S i=\"%04x\" n=\"%s\" t=\"%x\" s=\"%d\"/>\n",
ccI->second.getServiceId(), convert_UTF8_To_UTF8_XML(ccI->second.getName().c_str()).c_str(),
ccI->second.getServiceType(true), ccI->second.scrambled);
}
processed++; processed++;
#ifdef SAVE_DEBUG #ifdef SAVE_DEBUG
chans_processed.insert(ccI->second.getChannelID()); chans_processed.insert(ccI->second.getChannelID());
@@ -624,16 +786,128 @@ void SaveServices(bool tocopy)
fprintf(fd, "</zapit>\n"); fprintf(fd, "</zapit>\n");
fclose(fd); fclose(fd);
if(tocopy) { if(tocopy) {
zapit_cp((char *) SERVICES_TMP, (char *) SERVICES_XML); CopyFile((char *) SERVICES_TMP, (char *) SERVICES_XML);
unlink(SERVICES_TMP); unlink(SERVICES_TMP);
} }
#ifdef SAVE_DEBUG #ifdef SAVE_DEBUG
printf("processed channels: %d\n", chans_processed.size()); printf("processed channels: %d\n", chans_processed.size());
int i = 0; int i = 0;
for (tallchans::iterator it = allchans.begin(); it != allchans.end(); it++) for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); it++)
if (chans_processed.find(it->first) == chans_processed.end()) if (chans_processed.find(it->first) == chans_processed.end())
printf("unused channel %d sat %d freq %d sid %04X: %s\n", ++i, it->second.getSatellitePosition(), it->second.getFreqId(), it->second.getServiceId(), it->second.getName().c_str()); printf("unused channel %d sat %d freq %d sid %04X: %s\n", ++i, it->second.getSatellitePosition(), it->second.getFreqId(), it->second.getServiceId(), it->second.getName().c_str());
chans_processed.clear(); chans_processed.clear();
#endif #endif
printf("processed channels: %d\n", processed); printf("processed channels: %d\n", processed);
} }
/* helper for reused code */
void CServiceManager::WriteCurrentService(FILE * fd, bool &satfound, bool &tpdone,
bool &updated, char * satstr, struct transponder &tp, CZapitChannel &channel, const char * action)
{
if(!tpdone) {
if(!satfound)
fprintf(fd, "%s", satstr);
WriteTransponderHeader(fd, tp);
tpdone = 1;
}
updated = 1;
channel.dumpServiceXml(fd, action);
}
bool CServiceManager::SaveCurrentServices(transponder_id_t tpid)
{
channel_map_iterator_t ccI;
channel_map_iterator_t dI;
transponder_list_t::iterator tI;
char satstr[256];
char buffer[256];
FILE * fd = 0;
FILE * fd1 = 0;
bool updated = 0;
bool tpdone = 0;
bool satfound = 0;
tI = transponders.find(tpid);
if(tI == transponders.end()) {
printf("[sdt monitor] tp not found ?!\n");
return false;
}
t_satellite_position satellitePosition = GET_SATELLITEPOSITION_FROM_TRANSPONDER_ID(tpid) & 0xFFF;
if(GET_SATELLITEPOSITION_FROM_TRANSPONDER_ID(tpid) & 0xF000)
satellitePosition = -satellitePosition;
fd = fopen(CURRENTSERVICES_TMP, "w");
if(!fd) {
printf("[sdt monitor] " CURRENTSERVICES_TMP ": cant open!\n");
return false;
}
sat_iterator_t spos_it = satellitePositions.find(satellitePosition);
if(spos_it == satellitePositions.end())
return false;
switch (CFrontend::getInstance()->getInfo()->type) {
case FE_QPSK: /* satellite */
sprintf(satstr, "\t<%s name=\"%s\" position=\"%hd\">\n", "sat", spos_it->second.name.c_str(), satellitePosition);
break;
case FE_QAM: /* cable */
sprintf(satstr, "\t<%s name=\"%s\"\n", "cable", spos_it->second.name.c_str());
break;
case FE_OFDM:
default:
break;
}
fd1 = fopen(CURRENTSERVICES_XML, "r");
if(!fd1) {
fprintf(fd, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<zapit>\n");
} else {
fgets(buffer, 255, fd1);
while(!feof(fd1) && !strstr(buffer, satfound ? "</sat>" : "</zapit>")) {
if(!satfound && !strcmp(buffer, satstr))
satfound = 1;
fputs(buffer, fd);
fgets(buffer, 255, fd1);
}
}
for (channel_map_iterator_t cI = curchans.begin(); cI != curchans.end(); cI++) {
ccI = allchans.find(cI->second.getChannelID());
if(ccI == allchans.end()) {
WriteCurrentService(fd, satfound, tpdone, updated, satstr, tI->second, cI->second, "add");
} else {
if(strcmp(cI->second.getName().c_str(), ccI->second.getName().c_str()) || cI->second.scrambled != ccI->second.scrambled) {
WriteCurrentService(fd, satfound, tpdone, updated, satstr, tI->second, cI->second, "replace");
}
}
}
for (ccI = allchans.begin(); ccI != allchans.end(); ccI++) {
if(ccI->second.getTransponderId() == tpid) {
dI = curchans.find(ccI->second.getChannelID());
if(dI == curchans.end())
WriteCurrentService(fd, satfound, tpdone, updated, satstr, tI->second, ccI->second, "remove");
}
}
if(tpdone) {
fprintf(fd, "\t\t</TS>\n");
fprintf(fd, "\t</sat>\n");
} else if(satfound)
fprintf(fd, "\t</sat>\n");
if(fd1) {
fgets(buffer, 255, fd1);
while(!feof(fd1)) {
fputs(buffer, fd);
fgets(buffer, 255, fd1);
}
if(!satfound) fprintf(fd, "</zapit>\n");
fclose(fd1);
} else
fprintf(fd, "</zapit>\n");
fclose(fd);
rename(CURRENTSERVICES_TMP, CURRENTSERVICES_XML);
return updated;
}