zapit: split audio pids saving to SaveAudioMap;

remove global cam_ci;
add CFEManager API to save/load per frontend settings;
use new  pat/pmt classes;
use CFEManager API to close, open, get frontend;
set CI clock at startup;
cleanup unused code;
This commit is contained in:
[CST] Focus
2012-01-13 16:14:02 +04:00
parent 985a14dfc0
commit 73a2f85e35
2 changed files with 264 additions and 250 deletions

View File

@@ -16,7 +16,7 @@
#include <zapit/channel.h>
#include <zapit/bouquets.h>
#include <zapit/frontend_c.h>
#include <zapit/femanager.h>
#define PAL 0
#define NTSC 1
@@ -80,6 +80,8 @@ class CZapit : public OpenThreads::Thread
CZapitChannel * current_channel;
t_channel_id live_channel_id;
CFrontend * live_fe;
audio_map_t audio_map;
bool current_is_nvod;
bool standby;
@@ -89,12 +91,13 @@ class CZapit : public OpenThreads::Thread
int pmt_update_fd;
void LoadAudioMap();
void SaveSettings(bool write_conf, bool write_audio);
void SaveAudioMap();
void SaveSettings(bool write);
void SaveChannelPids(CZapitChannel* channel);
void RestoreChannelPids(CZapitChannel* channel);
void ConfigFrontend();
bool TuneChannel(CZapitChannel * channel, bool &transponder_change);
bool TuneChannel(CFrontend *frontend, CZapitChannel * channel, bool &transponder_change);
bool ParsePatPmt(CZapitChannel * channel);
bool send_data_count(int connfd, int data_count);
@@ -161,5 +164,7 @@ class CZapit : public OpenThreads::Thread
CZapitChannel * GetCurrentChannel() { return current_channel; };
t_channel_id GetCurrentChannelID() { return live_channel_id; };
void SetCurrentChannelID(const t_channel_id channel_id) { live_channel_id = channel_id; };
void SetLiveFrontend(CFrontend * fe) { if(fe) live_fe = fe; }
CFrontend * GetLiveFrontend() { return live_fe; };
};
#endif /* __zapit_h__ */

View File

@@ -4,6 +4,7 @@
* zapit - d-box2 linux project
*
* (C) 2001, 2002 by Philipp Leusmann <faralla@berlios.de>
* Copyright (C) 2011 CoolStream International Ltd
*
* 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
@@ -51,7 +52,7 @@
#include <ca_cs.h>
#include <zapit/satconfig.h>
#include <zapit/frontend_c.h>
#include <zapit/femanager.h>
#include <dmx.h>
#if HAVE_COOL_HARDWARE
#include <record_cs.h>
@@ -70,13 +71,12 @@
#include "libtuxtxt/teletext.h"
/* globals */
int sig_delay = 2; // seconds between signal check
/* the bouquet manager */
CBouquetManager *g_bouquetManager = NULL;
int cam_ci = 2; // CA_INIT_SC 0 or CA_INIT_CI 1 or CA_INIT_BOTH 2
//int cam_ci = 2; // CA_INIT_SC 0 or CA_INIT_CI 1 or CA_INIT_BOTH 2
cCA *ca = NULL;
extern cDemux * pmtDemux;
extern cVideo *videoDecoder;
@@ -140,12 +140,13 @@ void CZapit::SendEvent(const unsigned int eventID, const void* eventbody, const
eventServer->sendEvent(eventID, CEventServer::INITID_ZAPIT, eventbody, eventbodysize);
}
void CZapit::SaveSettings(bool write, bool write_a)
void CZapit::SaveSettings(bool write)
{
if (current_channel) {
// now save the lowest channel number with the current channel_id
int c = ((currentMode & RADIO_MODE) ? g_bouquetManager->radioChannelsBegin() : g_bouquetManager->tvChannelsBegin()).getLowestChannelNumberWithChannelID(current_channel->getChannelID());
//printf("LAST CHAN %d !!!!!!!!!!!\n\n\n", c);
//FIXME save last TV/RADIO channel id, always ?
if (c >= 0) {
if ((currentMode & RADIO_MODE))
lastChannelRadio = c;
@@ -162,81 +163,88 @@ void CZapit::SaveSettings(bool write, bool write_a)
configfile.setInt32("lastChannelTV", lastChannelTV);
configfile.setInt64("lastChannel", live_channel_id);
}
configfile.setInt32("lastSatellitePosition", CFrontend::getInstance()->getCurrentSatellitePosition());
configfile.setInt32("diseqcRepeats", CFrontend::getInstance()->getDiseqcRepeats());
configfile.setInt32("diseqcType", CFrontend::getInstance()->getDiseqcType());
configfile.setInt32("motorRotationSpeed", config.motorRotationSpeed);
configfile.setBool("writeChannelsNames", config.writeChannelsNames);
configfile.setBool("makeRemainingChannelsBouquet", config.makeRemainingChannelsBouquet);
configfile.setInt32("feTimeout", config.feTimeout);
configfile.setInt32("rezapTimeout", config.rezapTimeout);
configfile.setBool("scanPids", config.scanPids);
configfile.setBool("highVoltage", config.highVoltage);
configfile.setInt32("scanSDT", config.scanSDT);
configfile.setInt32("cam_ci", config.cam_ci);
#if 0 // unused
configfile.setBool("fastZap", config.fastZap);
configfile.setBool("sortNames", config.sortNames);
#endif
/* FIXME FE global */
char tempd[12];
sprintf(tempd, "%3.6f", config.gotoXXLatitude);
configfile.setString("gotoXXLatitude", tempd);
sprintf(tempd, "%3.6f", config.gotoXXLongitude);
configfile.setString("gotoXXLongitude", tempd);
configfile.setInt32("gotoXXLaDirection", config.gotoXXLaDirection);
configfile.setInt32("gotoXXLoDirection", config.gotoXXLoDirection);
configfile.setInt32("repeatUsals", config.repeatUsals);
configfile.setInt32("scanSDT", config.scanSDT);
#if 1
/* FIXME FE specific */
configfile.setBool("highVoltage", config.highVoltage);
configfile.setInt32("lastSatellitePosition", live_fe->getCurrentSatellitePosition());
configfile.setInt32("diseqcRepeats", live_fe->getDiseqcRepeats());
configfile.setInt32("diseqcType", live_fe->getDiseqcType());
configfile.setInt32("motorRotationSpeed", config.motorRotationSpeed);
configfile.setInt32("uni_scr", config.uni_scr);
configfile.setInt32("uni_qrg", config.uni_qrg);
configfile.setInt32("cam_ci", cam_ci);
#if 0 // unused
configfile.setBool("fastZap", config.fastZap);
configfile.setBool("sortNames", config.sortNames);
#endif
if (configfile.getModifiedFlag())
configfile.saveConfig(CONFIGFILE);
}
if (write_a) {
FILE *audio_config_file = fopen(AUDIO_CONFIG_FILE, "w");
if (audio_config_file) {
for (audio_map_iterator_t audio_map_it = audio_map.begin(); audio_map_it != audio_map.end(); audio_map_it++) {
fprintf(audio_config_file, "%llx %d %d %d %d %d %d\n", (uint64_t) audio_map_it->first,
(int) audio_map_it->second.apid, (int) audio_map_it->second.mode, (int) audio_map_it->second.volume,
(int) audio_map_it->second.subpid, (int) audio_map_it->second.ttxpid, (int) audio_map_it->second.ttxpage);
}
fdatasync(fileno(audio_config_file));
fclose(audio_config_file);
} else
perror(AUDIO_CONFIG_FILE);
}
}
void CZapit::LoadAudioMap()
{
FILE *audio_config_file = fopen(AUDIO_CONFIG_FILE, "r");
audio_map.clear();
if (audio_config_file) {
t_channel_id chan;
int apid = 0, subpid = 0, ttxpid = 0, ttxpage = 0;
int mode = 0;
int volume = 0;
char s[1000];
while (fgets(s, 1000, audio_config_file)) {
sscanf(s, "%llx %d %d %d %d %d %d", &chan, &apid, &mode, &volume, &subpid, &ttxpid, &ttxpage);
audio_map[chan].apid = apid;
audio_map[chan].subpid = subpid;
audio_map[chan].mode = mode;
audio_map[chan].volume = volume;
audio_map[chan].ttxpid = ttxpid;
audio_map[chan].ttxpage = ttxpage;
}
fclose(audio_config_file);
} else
if (!audio_config_file) {
perror(AUDIO_CONFIG_FILE);
return;
}
t_channel_id chan;
int apid = 0, subpid = 0, ttxpid = 0, ttxpage = 0;
int mode = 0;
int volume = 0;
char s[1000];
while (fgets(s, 1000, audio_config_file)) {
sscanf(s, "%llx %d %d %d %d %d %d", &chan, &apid, &mode, &volume, &subpid, &ttxpid, &ttxpage);
audio_map[chan].apid = apid;
audio_map[chan].subpid = subpid;
audio_map[chan].mode = mode;
audio_map[chan].volume = volume;
audio_map[chan].ttxpid = ttxpid;
audio_map[chan].ttxpage = ttxpage;
}
fclose(audio_config_file);
}
void CZapit::SaveAudioMap()
{
FILE *audio_config_file = fopen(AUDIO_CONFIG_FILE, "w");
if (!audio_config_file) {
perror(AUDIO_CONFIG_FILE);
return;
}
for (audio_map_iterator_t audio_map_it = audio_map.begin(); audio_map_it != audio_map.end(); audio_map_it++) {
fprintf(audio_config_file, "%llx %d %d %d %d %d %d\n", (uint64_t) audio_map_it->first,
(int) audio_map_it->second.apid, (int) audio_map_it->second.mode, (int) audio_map_it->second.volume,
(int) audio_map_it->second.subpid, (int) audio_map_it->second.ttxpid, (int) audio_map_it->second.ttxpage);
}
fdatasync(fileno(audio_config_file));
fclose(audio_config_file);
}
void CZapit::LoadSettings()
{
if (!configfile.loadConfig(CONFIGFILE))
@@ -252,11 +260,16 @@ void CZapit::LoadSettings()
voltageOff = configfile.getBool("voltageOff", 0);
#endif
config.saveLastChannel = configfile.getBool("saveLastChannel", true);
config.rezapTimeout = configfile.getInt32("rezapTimeout", 1);
config.feTimeout = configfile.getInt32("feTimeout", 40);
/* FIXME Channels renum should be done for all channels atm. TODO*/
//config.makeRemainingChannelsBouquet = configfile.getBool("makeRemainingChannelsBouquet", 1);
config.makeRemainingChannelsBouquet = 1;
config.scanPids = configfile.getBool("scanPids", 0);
config.scanSDT = configfile.getInt32("scanSDT", 0);
config.cam_ci = configfile.getInt32("cam_ci", 2);
config.rezapTimeout = configfile.getInt32("rezapTimeout", 1);
config.feTimeout = configfile.getInt32("feTimeout", 40);
config.highVoltage = configfile.getBool("highVoltage", 0);
config.makeRemainingChannelsBouquet = configfile.getBool("makeRemainingChannelsBouquet", 1);
config.gotoXXLatitude = strtod(configfile.getString("gotoXXLatitude", "0.0").c_str(), NULL);
config.gotoXXLongitude = strtod(configfile.getString("gotoXXLongitude", "0.0").c_str(), NULL);
@@ -264,42 +277,42 @@ void CZapit::LoadSettings()
config.gotoXXLoDirection = configfile.getInt32("gotoXXLoDirection", 0);
config.repeatUsals = configfile.getInt32("repeatUsals", 0);
config.scanSDT = configfile.getInt32("scanSDT", 0);
/* FIXME FE specific, to be removed */
diseqcType = (diseqc_t)configfile.getInt32("diseqcType", NO_DISEQC);
config.motorRotationSpeed = configfile.getInt32("motorRotationSpeed", 18); // default: 1.8 degrees per second
config.uni_scr = configfile.getInt32("uni_scr", -1);
config.uni_qrg = configfile.getInt32("uni_qrg", 0);
cam_ci = configfile.getInt32("cam_ci", 2);
diseqcType = (diseqc_t)configfile.getInt32("diseqcType", NO_DISEQC);
config.motorRotationSpeed = configfile.getInt32("motorRotationSpeed", 18); // default: 1.8 degrees per second
CFrontend::getInstance()->setDiseqcRepeats(configfile.getInt32("diseqcRepeats", 0));
CFrontend::getInstance()->setCurrentSatellitePosition(configfile.getInt32("lastSatellitePosition", 0));
CFrontend::getInstance()->setDiseqcType(diseqcType);
//FIXME globals !
#if 0
motorRotationSpeed = config.motorRotationSpeed;
highVoltage = config.highVoltage;
feTimeout = config.feTimeout;
gotoXXLaDirection = config.gotoXXLaDirection;
gotoXXLoDirection = config.gotoXXLoDirection;
gotoXXLatitude = config.gotoXXLatitude;
gotoXXLongitude = config.gotoXXLongitude;
repeatUsals = config.repeatUsals;
#endif
printf("[zapit.cpp] diseqc type = %d\n", diseqcType);
CFEManager::getInstance()->loadSettings();
/**/
LoadAudioMap();
}
void CZapit::ConfigFrontend()
{
CFrontend::getInstance()->setTimeout(config.feTimeout);
CFrontend::getInstance()->configUsals(config.gotoXXLatitude, config.gotoXXLongitude,
config.gotoXXLaDirection, config.gotoXXLoDirection, config.repeatUsals);
CFrontend::getInstance()->configRotor(config.motorRotationSpeed, config.highVoltage);
CFrontend::getInstance()->configUnicable(config.uni_scr, config.uni_qrg);
int count = CFEManager::getInstance()->getFrontendCount();
for(int i = 0; i < count; i++) {
CFrontend * fe = CFEManager::getInstance()->getFE(i);
if(!fe)
continue;
fe->setTimeout(config.feTimeout);
fe->configUsals(config.gotoXXLatitude, config.gotoXXLongitude,
config.gotoXXLaDirection, config.gotoXXLoDirection, config.repeatUsals);
if(!CFEManager::getInstance()->configExist()) {
INFO("New frontend config not exist");
fe->configRotor(config.motorRotationSpeed, config.highVoltage);
fe->configUnicable(config.uni_scr, config.uni_qrg);
fe->setDiseqcType(diseqcType);
fe->setDiseqcRepeats(configfile.getInt32("diseqcRepeats", 0));
fe->setCurrentSatellitePosition(configfile.getInt32("lastSatellitePosition", 0));
fe->setSatellites(CServiceManager::getInstance()->SatelliteList());
}
}
}
void CZapit::SendPMT(bool forupdate)
@@ -386,13 +399,21 @@ audio_map_set_t * CZapit::GetSavedPids(const t_channel_id channel_id)
return NULL;
}
bool CZapit::TuneChannel(CZapitChannel * channel, bool &transponder_change)
bool CZapit::TuneChannel(CFrontend * frontend, CZapitChannel * channel, bool &transponder_change)
{
//CFrontend * frontend = CFEManager::getInstance()->allocateFE(channel);
if(frontend == NULL) {
ERROR("Cannot get frontend\n");
return false;
}
transponder_change = false;
if (!(currentMode & RECORD_MODE)) {
transponder_change = CFrontend::getInstance()->setInput(channel, current_is_nvod);
#if 0
if (!(currentMode & RECORD_MODE))
#endif
{
transponder_change = frontend->setInput(channel, current_is_nvod);
if(transponder_change && !current_is_nvod) {
int waitForMotor = CFrontend::getInstance()->driveToSatellitePosition(channel->getSatellitePosition());
int waitForMotor = frontend->driveToSatellitePosition(channel->getSatellitePosition());
if(waitForMotor > 0) {
printf("[zapit] waiting %d seconds for motor to turn satellite dish.\n", waitForMotor);
SendEvent(CZapitClient::EVT_ZAP_MOTOR, &waitForMotor, sizeof(waitForMotor));
@@ -408,40 +429,33 @@ bool CZapit::TuneChannel(CZapitChannel * channel, bool &transponder_change)
/* if channel's transponder does not match frontend's tuned transponder ... */
if (transponder_change || current_is_nvod) {
if (CFrontend::getInstance()->tuneChannel(channel, current_is_nvod) == false) {
if (frontend->tuneChannel(channel, current_is_nvod) == false) {
return false;
}
}
} else if(!SAME_TRANSPONDER(channel->getChannelID(), live_channel_id))
}
#if 0
else if(!SAME_TRANSPONDER(channel->getChannelID(), live_channel_id))
return false;
#endif
return true;
}
bool CZapit::ParsePatPmt(CZapitChannel * channel)
{
CPat pat(channel->getRecordDemux());
CPmt pmt(channel->getRecordDemux());
DBG("looking up pids for channel_id " PRINTF_CHANNEL_ID_TYPE "\n", channel->getChannelID());
/* get program map table pid from program association table */
if (channel->getPmtPid() == 0) {
printf("[zapit] no pmt pid, going to parse pat\n");
if (parse_pat(channel) < 0) {
printf("[zapit] pat parsing failed\n");
return false;
}
if(!pat.Parse(channel)) {
printf("[zapit] pat parsing failed\n");
return false;
}
if (!pmt.parse_pmt(channel)) {
printf("[zapit] pmt parsing failed\n");
return false;
}
/* parse program map table and store pids */
if (parse_pmt(channel) < 0) {
printf("[zapit] pmt parsing failed\n");
if (parse_pat(channel) < 0) {
printf("pat parsing failed\n");
return false;
}
else if (parse_pmt(channel) < 0) {
printf("[zapit] pmt parsing failed\n");
return false;
}
}
return true;
}
@@ -459,6 +473,16 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay
return false;
}
printf("[zapit] zap to %s (%llx tp %llx)\n", newchannel->getName().c_str(), newchannel->getChannelID(), newchannel->getTransponderId());
CFrontend * fe = CFEManager::getInstance()->allocateFE(newchannel);
if(fe == NULL) {
ERROR("Cannot get frontend\n");
return false;
}
live_fe = fe;
CFEManager::getInstance()->setLiveFE(live_fe);
sig_delay = 2;
if (!firstzap && current_channel)
SaveChannelPids(current_channel);
@@ -477,30 +501,16 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay
current_channel = newchannel;
live_channel_id = current_channel->getChannelID();
SaveSettings(false, false);
SaveSettings(false);
printf("[zapit] zap to %s (%llx)\n", current_channel->getName().c_str(), live_channel_id);
if(!TuneChannel(newchannel, transponder_change))
if(!TuneChannel(live_fe, newchannel, transponder_change))
return false;
if (current_channel->getServiceType() == ST_NVOD_REFERENCE_SERVICE) {
current_is_nvod = true;
return true;
}
#if 0 //FIXME improve or remove ? this is to start playback before pmt
//bool we_playing = channel->getPidsFlag();//FIXME: this starts playback before pmt
bool we_playing = 0;
if (we_playing) {
printf("[zapit] channel have pids: vpid %X apid %X pcr %X\n", current_channel->getVideoPid(), current_channel->getPreAudioPid(), current_channel->getPcrPid());fflush(stdout);
if((current_channel->getAudioChannelCount() <= 0) && current_channel->getPreAudioPid() > 0) {
std::string desc = "Preset";
current_channel->addAudioChannel(current_channel->getPreAudioPid(), CZapitAudioChannel::MPEG, desc, 0xFF);
}
StartPlayBack(current_channel);
}
#endif
failed = !ParsePatPmt(current_channel);
@@ -547,7 +557,13 @@ bool CZapit::ZapForRecord(const t_channel_id channel_id)
return false;
}
printf("%s: %s (%llx)\n", __FUNCTION__, newchannel->getName().c_str(), channel_id);
if(!TuneChannel(newchannel, transponder_change))
CFrontend * frontend = CFEManager::getInstance()->allocateFE(newchannel);
if(frontend == NULL) {
ERROR("Cannot get frontend\n");
return false;
}
if(!TuneChannel(frontend, newchannel, transponder_change))
return false;
if(!ParsePatPmt(newchannel))
@@ -777,7 +793,7 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd)
}
case CZapitMessages::CMD_GET_CURRENT_SATELLITE_POSITION: {
int32_t currentSatellitePosition = current_channel ? current_channel->getSatellitePosition() : CFrontend::getInstance()->getCurrentSatellitePosition();
int32_t currentSatellitePosition = current_channel ? current_channel->getSatellitePosition() : live_fe->getCurrentSatellitePosition();
CBasicServer::send_data(connfd, &currentSatellitePosition, sizeof(currentSatellitePosition));
break;
}
@@ -826,16 +842,16 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd)
msgCurrentServiceInfo.pmtpid = current_channel->getPmtPid();
msgCurrentServiceInfo.pmt_version = (current_channel->getCaPmt() != NULL) ? current_channel->getCaPmt()->version_number : 0xff;
msgCurrentServiceInfo.pcrpid = current_channel->getPcrPid();
msgCurrentServiceInfo.tsfrequency = CFrontend::getInstance()->getFrequency();
msgCurrentServiceInfo.rate = CFrontend::getInstance()->getRate();
msgCurrentServiceInfo.fec = CFrontend::getInstance()->getCFEC();
msgCurrentServiceInfo.tsfrequency = live_fe->getFrequency();
msgCurrentServiceInfo.rate = live_fe->getRate();
msgCurrentServiceInfo.fec = live_fe->getCFEC();
msgCurrentServiceInfo.vtype = current_channel->type;
//msgCurrentServiceInfo.diseqc = current_channel->getDiSEqC();
}
if(!msgCurrentServiceInfo.fec)
msgCurrentServiceInfo.fec = (fe_code_rate)3;
if (CFrontend::getInstance()->getInfo()->type == FE_QPSK)
msgCurrentServiceInfo.polarisation = CFrontend::getInstance()->getPolarization();
if (live_fe->getInfo()->type == FE_QPSK)
msgCurrentServiceInfo.polarisation = live_fe->getPolarization();
else
msgCurrentServiceInfo.polarisation = 2;
CBasicServer::send_data(connfd, &msgCurrentServiceInfo, sizeof(msgCurrentServiceInfo));
@@ -844,7 +860,7 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd)
case CZapitMessages::CMD_GET_DELIVERY_SYSTEM: {
CZapitMessages::responseDeliverySystem _response;
switch (CFrontend::getInstance()->getInfo()->type) {
switch (live_fe->getInfo()->type) {
case FE_QAM:
_response.system = DVB_C;
break;
@@ -855,7 +871,7 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd)
_response.system = DVB_T;
break;
default:
WARN("Unknown type %d", CFrontend::getInstance()->getInfo()->type);
WARN("Unknown type %d", live_fe->getInfo()->type);
return false;
}
@@ -961,7 +977,7 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd)
CBasicServer::send_data(connfd, &response, sizeof(response));
#endif
DBG("[zapit] sending EVT_SERVICES_CHANGED\n");
CFrontend::getInstance()->setTsidOnid(0);
live_fe->setTsidOnid(0);
ZapIt(live_channel_id, current_is_nvod);
SendEvent(CZapitClient::EVT_SERVICES_CHANGED);
//SendEvent(CZapitClient::EVT_BOUQUETS_CHANGED);
@@ -1002,23 +1018,24 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd)
TP.feparams.inversion = INVERSION_AUTO;
const char *name = scanProviders.size() > 0 ? scanProviders.begin()->second.c_str() : "unknown";
switch (CFrontend::getInstance()->getInfo()->type) {
switch (live_fe->getInfo()->type) {
case FE_QPSK:
case FE_OFDM: {
//FIXME check scanProviders.size() !
t_satellite_position satellitePosition = scanProviders.begin()->first;
printf("[zapit] tune to sat %s freq %d rate %d fec %d pol %d\n", name, TP.feparams.frequency, TP.feparams.u.qpsk.symbol_rate, TP.feparams.u.qpsk.fec_inner, TP.polarization);
CFrontend::getInstance()->setInput(satellitePosition, TP.feparams.frequency, TP.polarization);
CFrontend::getInstance()->driveToSatellitePosition(satellitePosition);
live_fe->setInput(satellitePosition, TP.feparams.frequency, TP.polarization);
live_fe->driveToSatellitePosition(satellitePosition);
break;
}
case FE_QAM:
printf("[zapit] tune to cable %s freq %d rate %d fec %d\n", name, TP.feparams.frequency, TP.feparams.u.qam.symbol_rate, TP.feparams.u.qam.fec_inner);
break;
default:
WARN("Unknown type %d", CFrontend::getInstance()->getInfo()->type);
WARN("Unknown type %d", live_fe->getInfo()->type);
return false;
}
CFrontend::getInstance()->tuneFrequency(&TP.feparams, TP.polarization, true);
live_fe->tuneFrequency(&TP.feparams, TP.polarization, true);
}
break;
case CZapitMessages::CMD_SCAN_TP: {
@@ -1027,10 +1044,11 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd)
#if 0
printf("[zapit] TP_id %d freq %d rate %d fec %d pol %d\n", TP.TP_id, TP.feparams.frequency, TP.feparams.u.qpsk.symbol_rate, TP.feparams.u.qpsk.fec_inner, TP.polarization);
#endif
//FIXME not used ? to scan current channel's TP. manual scan menu updated with current params
if(!(TP.feparams.frequency > 0) && current_channel) {
transponder_list_t::iterator transponder = transponders.find(current_channel->getTransponderId());
TP.feparams.frequency = transponder->second.feparams.frequency;
switch (CFrontend::getInstance()->getInfo()->type) {
switch (live_fe->getInfo()->type) {
case FE_QPSK:
case FE_OFDM:
TP.feparams.u.qpsk.symbol_rate = transponder->second.feparams.u.qpsk.symbol_rate;
@@ -1043,20 +1061,14 @@ printf("[zapit] TP_id %d freq %d rate %d fec %d pol %d\n", TP.TP_id, TP.feparams
TP.feparams.u.qam.modulation = transponder->second.feparams.u.qam.modulation;
break;
default:
WARN("Unknown type %d", CFrontend::getInstance()->getInfo()->type);
WARN("Unknown type %d", live_fe->getInfo()->type);
return false;
}
if(scanProviders.size() > 0)
scanProviders.clear();
#if 0
std::map<string, t_satellite_position>::iterator spos_it;
for (spos_it = satellitePositions.begin(); spos_it != satellitePositions.end(); spos_it++)
if(spos_it->second == current_channel->getSatellitePosition())
scanProviders[transponder->second.DiSEqC] = spos_it->first.c_str();
#endif
//FIXME not ready
//if(satellitePositions.find(current_channel->getSatellitePosition()) != satellitePositions.end())
scanProviders.clear();
scanProviders[current_channel->getSatellitePosition()] =
CServiceManager::getInstance()->GetSatelliteName(current_channel->getSatellitePosition());
current_channel = 0;
}
PrepareScan();
@@ -1082,8 +1094,8 @@ printf("[zapit] TP_id %d freq %d rate %d fec %d pol %d\n", TP.TP_id, TP.feparams
CZapitClient::responseGetSatelliteList sat;
satlength = sizeof(sat);
sat_iterator_t sit;
for(sit = satellitePositions.begin(); sit != satellitePositions.end(); sit++) {
satellite_map_t satmap = CServiceManager::getInstance()->SatelliteList();
for(sat_iterator_t sit = satmap.begin(); sit != satmap.end(); sit++) {
strncpy(sat.satName, sit->second.name.c_str(), 50);
sat.satName[49] = 0;
sat.satPosition = sit->first;
@@ -1097,33 +1109,45 @@ printf("[zapit] TP_id %d freq %d rate %d fec %d pol %d\n", TP.TP_id, TP.feparams
}
case CZapitMessages::CMD_SCANSETSCANSATLIST: {
bool setfe = true;
CZapitClient::commandSetScanSatelliteList sat;
scanProviders.clear();
while (CBasicServer::receive_data(connfd, &sat, sizeof(sat))) {
printf("[zapit] adding to scan %s (position %d)\n", sat.satName, sat.position);
scanProviders[sat.position] = sat.satName;
if(setfe) {
/* for test signal */
CServiceScan::getInstance()->SetFrontend(sat.position);
live_fe = CServiceScan::getInstance()->GetFrontend();
setfe = false;
}
}
break;
}
case CZapitMessages::CMD_SCANSETSCANMOTORPOSLIST: {
// absolute
ERROR("CZapitMessages::CMD_SCANSETSCANMOTORPOSLIST: depreciated command\n");
break;
}
case CZapitMessages::CMD_SCANSETDISEQCTYPE: {
//diseqcType is global
//FIXME diseqcType is global
#if 0
CBasicServer::receive_data(connfd, &diseqcType, sizeof(diseqcType));
CFrontend::getInstance()->setDiseqcType(diseqcType);
DBG("set diseqc type %d", diseqcType);
live_fe->setDiseqcType(diseqcType);
#endif
ERROR("CZapitMessages::CMD_SCANSETDISEQCTYPE: depreciated command\n");
break;
}
case CZapitMessages::CMD_SCANSETDISEQCREPEAT: {
#if 0
uint32_t repeats;
CBasicServer::receive_data(connfd, &repeats, sizeof(repeats));
CFrontend::getInstance()->setDiseqcRepeats(repeats);
DBG("set diseqc repeats to %d", repeats);
live_fe->setDiseqcRepeats(repeats);
#endif
ERROR("CZapitMessages::CMD_SCANSETDISEQCREPEAT: depreciated command\n");
break;
}
@@ -1422,12 +1446,11 @@ printf("[zapit] TP_id %d freq %d rate %d fec %d pol %d\n", TP.TP_id, TP.feparams
case CZapitMessages::CMD_GET_FE_SIGNAL: {
CZapitClient::responseFESignal response_FEsig;
response_FEsig.sig = CFrontend::getInstance()->getSignalStrength();
response_FEsig.snr = CFrontend::getInstance()->getSignalNoiseRatio();
response_FEsig.ber = CFrontend::getInstance()->getBitErrorRate();
response_FEsig.sig = live_fe->getSignalStrength();
response_FEsig.snr = live_fe->getSignalNoiseRatio();
response_FEsig.ber = live_fe->getBitErrorRate();
CBasicServer::send_data(connfd, &response_FEsig, sizeof(CZapitClient::responseFESignal));
ERROR("CZapitMessages::CMD_GET_FE_SIGNAL: depreciated command\n");
break;
}
@@ -1537,10 +1560,10 @@ printf("[zapit] TP_id %d freq %d rate %d fec %d pol %d\n", TP.TP_id, TP.feparams
CBasicServer::receive_data(connfd, &msgMotor, sizeof(msgMotor));
printf("[zapit] received motor command: %x %x %x %x %x %x\n", msgMotor.cmdtype, msgMotor.address, msgMotor.cmd, msgMotor.num_parameters, msgMotor.param1, msgMotor.param2);
if(msgMotor.cmdtype > 0x20)
CFrontend::getInstance()->sendMotorCommand(msgMotor.cmdtype, msgMotor.address, msgMotor.cmd, msgMotor.num_parameters, msgMotor.param1, msgMotor.param2);
live_fe->sendMotorCommand(msgMotor.cmdtype, msgMotor.address, msgMotor.cmd, msgMotor.num_parameters, msgMotor.param1, msgMotor.param2);
// TODO !!
//else if(current_channel)
// CFrontend::getInstance()->satFind(msgMotor.cmdtype, current_channel);
// live_fe->satFind(msgMotor.cmdtype, current_channel);
break;
}
@@ -1606,22 +1629,10 @@ void CZapit::sendAPIDs(int connfd)
void CZapit::internalSendChannels(int connfd, ZapitChannelList* channels, const unsigned int first_channel_nr, bool nonames)
{
int data_count = channels->size();
#if RECORD_RESEND // old, before tv/radio resend
if (currentMode & RECORD_MODE) {
for (uint32_t i = 0; i < channels->size(); i++)
if ((*channels)[i]->getTransponderId() != channel->getTransponderId())
data_count--;
}
#endif
if (!send_data_count(connfd, data_count))
return;
for (uint32_t i = 0; i < channels->size();i++) {
#if RECORD_RESEND // old, before tv/radio resend
if ((currentMode & RECORD_MODE) && ((*channels)[i]->getTransponderId() != CFrontend::getInstance()->getTsidOnid()))
continue;
#endif
if(nonames) {
CZapitClient::responseGetBouquetNChannels response;
response.nr = first_channel_nr + i;
@@ -1637,14 +1648,14 @@ void CZapit::internalSendChannels(int connfd, ZapitChannelList* channels, const
CZapitClient::responseGetBouquetChannels response;
strncpy(response.name, ((*channels)[i]->getName()).c_str(), CHANNEL_NAME_SIZE);
response.name[CHANNEL_NAME_SIZE-1] = 0;
//printf("internalSendChannels: name %s\n", response.name);
//printf("internalSendChannels: name %s\n", response.name);
response.satellitePosition = (*channels)[i]->getSatellitePosition();
response.channel_id = (*channels)[i]->getChannelID();
response.nr = first_channel_nr + i;
if (CBasicServer::send_data(connfd, &response, sizeof(response)) == false) {
ERROR("could not send any return");
DBG("current: %d name %s total %d\n", i, response.name, data_count);
DBG("current: %d name %s total %d\n", i, response.name, data_count);
if (CBasicServer::send_data(connfd, &response, sizeof(response)) == false) {
ERROR("could not send any return, stop");
return;
@@ -1675,25 +1686,16 @@ void CZapit::sendBouquets(int connfd, const bool emptyBouquetsToo, CZapitClient:
if (emptyBouquetsToo || (!g_bouquetManager->Bouquets[i]->bHidden && g_bouquetManager->Bouquets[i]->bUser)
|| ((!g_bouquetManager->Bouquets[i]->bHidden)
&& (((curMode & RADIO_MODE) && !g_bouquetManager->Bouquets[i]->radioChannels.empty()) ||
((curMode & TV_MODE) && !g_bouquetManager->Bouquets[i]->tvChannels.empty())))
)
((curMode & TV_MODE) && !g_bouquetManager->Bouquets[i]->tvChannels.empty()))))
{
// ATTENTION: in RECORD_MODE empty bouquets are not send!
#if RECORD_RESEND // old, before tv/radio resend
if ((!(currentMode & RECORD_MODE)) || ((CFrontend::getInstance() != NULL) &&
(((currentMode & RADIO_MODE) && (g_bouquetManager->Bouquets[i]->recModeRadioSize(CFrontend::getInstance()->getTsidOnid()) > 0)) ||
((currentMode & TV_MODE) && (g_bouquetManager->Bouquets[i]->recModeTVSize (CFrontend::getInstance()->getTsidOnid()) > 0)))))
#endif
{
msgBouquet.bouquet_nr = i;
strncpy(msgBouquet.name, g_bouquetManager->Bouquets[i]->Name.c_str(), 30);
msgBouquet.name[29] = 0;
msgBouquet.locked = g_bouquetManager->Bouquets[i]->bLocked;
msgBouquet.hidden = g_bouquetManager->Bouquets[i]->bHidden;
if (CBasicServer::send_data(connfd, &msgBouquet, sizeof(msgBouquet)) == false) {
ERROR("could not send any return");
return;
}
msgBouquet.bouquet_nr = i;
strncpy(msgBouquet.name, g_bouquetManager->Bouquets[i]->Name.c_str(), 30);
msgBouquet.name[29] = 0;
msgBouquet.locked = g_bouquetManager->Bouquets[i]->bLocked;
msgBouquet.hidden = g_bouquetManager->Bouquets[i]->bHidden;
if (CBasicServer::send_data(connfd, &msgBouquet, sizeof(msgBouquet)) == false) {
ERROR("could not send any return");
return;
}
}
}
@@ -1747,17 +1749,19 @@ bool CZapit::StartPlayBack(CZapitChannel *thisChannel)
bool have_video = false;
bool have_teletext = false;
INFO("standby %d playing %d forced %d", standby, playing, playbackStopForced);
if(!thisChannel)
thisChannel = current_channel;
if ((playbackStopForced == true) || (!thisChannel) || playing)
return false;
printf("[zapit] vpid %X apid %X pcr %X\n", thisChannel->getVideoPid(), thisChannel->getAudioPid(), thisChannel->getPcrPid());
if(standby) {
CFrontend::getInstance()->Open();
CFEManager::getInstance()->Open();
return true;
}
printf("[zapit] vpid %X apid %X pcr %X\n", thisChannel->getVideoPid(), thisChannel->getAudioPid(), thisChannel->getPcrPid());
if (thisChannel->getPcrPid() != 0)
have_pcr = true;
if (thisChannel->getAudioPid() != 0)
@@ -1824,12 +1828,18 @@ bool CZapit::StartPlayBack(CZapitChannel *thisChannel)
bool CZapit::StopPlayBack(bool send_pmt)
{
#if 1
if(send_pmt) {
CCamManager::getInstance()->Stop(live_channel_id, CCamManager::PLAY);
ca->SendPMT(0, (unsigned char*) "", 0, CA_SLOT_TYPE_SMARTCARD);
}
printf("StopPlayBack: standby %d forced %d\n", standby, playbackStopForced);
#endif
#if 0
if (send_pmt && !(currentMode & RECORD_MODE))
ca->SendPMT(0, (unsigned char*) "", 0, CA_SLOT_TYPE_SMARTCARD);
CCamManager::getInstance()->Stop(live_channel_id, CCamManager::PLAY);
#endif
INFO("standby %d playing %d forced %d", standby, playing, playbackStopForced);
if (!playing)
return true;
@@ -1860,34 +1870,31 @@ bool CZapit::StopPlayBack(bool send_pmt)
void CZapit::enterStandby(void)
{
INFO("standby %d", standby);
if (standby)
return;
standby = true;
SaveSettings(true, true);
SaveSettings(true);
SaveAudioMap();
StopPlayBack(true);
if(!(currentMode & RECORD_MODE)) {
CFrontend::getInstance()->Close();
CFEManager::getInstance()->Close();
}
}
void CZapit::leaveStandby(void)
{
INFO("standby %d", standby);
if(!standby)
return;
printf("[zapit] diseqc type = %d\n", diseqcType);
CFrontend::getInstance()->setDiseqcRepeats(configfile.getInt32("diseqcRepeats", 0));
CFrontend::getInstance()->setCurrentSatellitePosition(configfile.getInt32("lastSatellitePosition", 0));
CFrontend::getInstance()->setDiseqcType(diseqcType);
if(!(currentMode & RECORD_MODE)) {
CFrontend::getInstance()->Open();
CFrontend::getInstance()->setTsidOnid(0);
CFrontend::getInstance()->setDiseqcType(diseqcType);
CFEManager::getInstance()->Open();
}
standby = false;
if (current_channel)
@@ -1959,6 +1966,8 @@ bool CZapit::Start(Z_start_arg *ZapStart_arg)
if(started)
return false;
CFEManager::getInstance()->Init();
live_fe = CFEManager::getInstance()->getFE(0);
/* load configuration or set defaults if no configuration file exists */
video_mode = ZapStart_arg->video_mode;
@@ -1982,11 +1991,23 @@ bool CZapit::Start(Z_start_arg *ZapStart_arg)
#endif
ca = cCA::GetInstance();
LoadSettings();
ConfigFrontend();
//LoadSettings();
//LoadAudioMap();
/* create bouquet manager */
g_bouquetManager = new CBouquetManager();
if (!PrepareChannels())
WARN("error parsing services");
else
INFO("channels have been loaded succesfully");
/* FIXME to transit from old satconfig.conf to new frontend.conf,
* ConfigFrontend called after PrepareChannels, as it copy satellitePositions to every fe */
LoadSettings();
ConfigFrontend();
if(!CFEManager::getInstance()->configExist())
CFEManager::getInstance()->saveSettings(true);
if (configfile.getInt32("lastChannelMode", 0))
SetRadioMode();
@@ -2000,7 +2021,7 @@ bool CZapit::Start(Z_start_arg *ZapStart_arg)
}
/* CA_INIT_CI or CA_INIT_SC or CA_INIT_BOTH */
switch(cam_ci){
switch(config.cam_ci){
case 2:
ca->SetInitMask(CA_INIT_BOTH);
break;
@@ -2014,15 +2035,13 @@ bool CZapit::Start(Z_start_arg *ZapStart_arg)
ca->SetInitMask(CA_INIT_BOTH);
break;
}
// set ci clock to ZapStart_arg->ci_clock
ca->SetTSClock(ZapStart_arg->ci_clock * 1000000);
ca->Start();
eventServer = new CEventServer;
if (!PrepareChannels())
WARN("error parsing services");
else
INFO("channels have been loaded succesfully");
current_channel = CServiceManager::getInstance()->FindChannel(live_channel_id);
// some older? hw needs this sleep. e.g. my hd-1c.
@@ -2072,23 +2091,24 @@ void CZapit::run()
if (pmt_update_fd != -1) {
unsigned char buf[4096];
int ret = pmtDemux->Read(buf, 4095, 10);
if (ret > 0) {
pmt_stop_update_filter(&pmt_update_fd);
printf("[zapit] pmt updated, sid 0x%x new version 0x%x\n", (buf[3] << 8) + buf[4], (buf[5] >> 1) & 0x1F);
if(current_channel) {
t_channel_id channel_id = current_channel->getChannelID();
int vpid = current_channel->getVideoPid();
parse_pmt(current_channel);
if(vpid != current_channel->getVideoPid()) {
ZapIt(current_channel->getChannelID(), true);
} else {
SendPMT(true);
pmt_set_update_filter(current_channel, &pmt_update_fd);
}
SendEvent(CZapitClient::EVT_PMT_CHANGED, &channel_id, sizeof(channel_id));
if (ret > 0) {
pmt_stop_update_filter(&pmt_update_fd);
printf("[zapit] pmt updated, sid 0x%x new version 0x%x\n", (buf[3] << 8) + buf[4], (buf[5] >> 1) & 0x1F);
if(current_channel) {
t_channel_id channel_id = current_channel->getChannelID();
int vpid = current_channel->getVideoPid();
CPmt pmt;
pmt.parse_pmt(current_channel);
if(vpid != current_channel->getVideoPid()) {
ZapIt(current_channel->getChannelID(), true);
} else {
SendPMT(true);
pmt_set_update_filter(current_channel, &pmt_update_fd);
}
SendEvent(CZapitClient::EVT_PMT_CHANGED, &channel_id, sizeof(channel_id));
}
}
}
/* yuck, don't waste that much cpu time :) */
usleep(0);
#if 0
@@ -2096,11 +2116,11 @@ void CZapit::run()
curtime = time(0);
if(sig_delay && (curtime - stime) > sig_delay) {
stime = curtime;
uint16_t sig = CFrontend::getInstance()->getSignalStrength();
uint16_t sig = live_fe->getSignalStrength();
//if(sig < 8000)
if(sig < 28000) {
printf("[monitor] signal %d, trying to re-tune...\n", sig);
CFrontend::getInstance()->retuneChannel();
live_fe->retuneChannel();
}
}
}
@@ -2108,8 +2128,10 @@ void CZapit::run()
}
SaveChannelPids(current_channel);
SaveSettings(true, true);
SaveSettings(true);
SaveAudioMap();
StopPlayBack(true);
CFEManager::getInstance()->saveSettings(true);
CServiceManager::getInstance()->SaveMotorPositions();
@@ -2127,10 +2149,8 @@ void CZapit::run()
INFO("demuxes/decoders deleted");
CFrontend::getInstance()->Close();
delete CFrontend::getInstance();
INFO("frontend deleted");
delete CFEManager::getInstance();
INFO("frontend(s) deleted");
if (ca) {
INFO("stopping CA");
ca->Stop();
@@ -2146,18 +2166,7 @@ void CZapit::SetConfig(Zapit_config * Cfg)
config = *Cfg;
//FIXME globals!
#if 0
motorRotationSpeed = config.motorRotationSpeed;
highVoltage = config.highVoltage;
feTimeout = config.feTimeout;
gotoXXLaDirection = config.gotoXXLaDirection;
gotoXXLoDirection = config.gotoXXLoDirection;
gotoXXLatitude = config.gotoXXLatitude;
gotoXXLongitude = config.gotoXXLongitude;
repeatUsals = config.repeatUsals;
#endif
SaveSettings(true, false);
SaveSettings(true);
ConfigFrontend();
}