diff --git a/data/locale/english.locale b/data/locale/english.locale index 3d1a154cd..22d5a9ed5 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1302,6 +1302,15 @@ satsetup.diseqc_uncom_com Uncommited/Commited satsetup.comm_input Commited input satsetup.use_usals Use usals satsetup.usals_repeat USALS command repeat +satsetup.fastscan_head Fast scan (Astra 1, 19.2E, 12.515Mhz) +satsetup.fastscan_type Scan type +satsetup.fastscan_sd SD only +satsetup.fastscan_hd HD only +satsetup.fastscan_all SD and HD +satsetup.fastscan_prov Provider +satsetup.fastscan_prov_cd CanalDigitaal +satsetup.fastscan_prov_tvv TV Vlaanderen +satsetup.fastscan_prov_telesat TéléSAT motorcontrol.user_menu User menu motorcontrol.install_menu Install menu motorcontrol.step_west Step/Drive Motor West (b,c) diff --git a/src/gui/bouquetlist.cpp b/src/gui/bouquetlist.cpp index da1b9ad65..edc610d04 100644 --- a/src/gui/bouquetlist.cpp +++ b/src/gui/bouquetlist.cpp @@ -385,8 +385,16 @@ int CBouquetList::show(bool bShowChannelList) step = ((int) msg == g_settings.key_channelList_pageup) ? listmaxshow : 1; // browse or step 1 selected -= step; +#if 0 if((prev_selected-step) < 0) // because of uint selected = Bouquets.size()-1; +#endif + if((prev_selected-step) < 0) { + if(prev_selected != 0 && step != 1) + selected = 0; + else + selected = Bouquets.size() - 1; + } paintItem(prev_selected - liststart); unsigned int oldliststart = liststart; @@ -399,17 +407,27 @@ int CBouquetList::show(bool bShowChannelList) else if (msg == CRCInput::RC_down || (int) msg == g_settings.key_channelList_pagedown) { unsigned int step = 0; - int prev_selected = selected; + unsigned int prev_selected = selected; step = ((int) msg == g_settings.key_channelList_pagedown) ? listmaxshow : 1; // browse or step 1 selected += step; - +#if 0 if(selected >= Bouquets.size()) { if (((Bouquets.size() / listmaxshow) + 1) * listmaxshow == Bouquets.size() + listmaxshow) // last page has full entries selected = 0; else selected = ((step == listmaxshow) && (selected < (((Bouquets.size() / listmaxshow) + 1) * listmaxshow))) ? (Bouquets.size() - 1) : 0; } +#endif + if(selected >= Bouquets.size()) { + if((Bouquets.size() - listmaxshow -1 < prev_selected) && (prev_selected != (Bouquets.size() - 1)) && (step != 1)) + selected = Bouquets.size() - 1; + else if (((Bouquets.size() / listmaxshow) + 1) * listmaxshow == Bouquets.size() + listmaxshow) // last page has full entries + selected = 0; + else + selected = ((step == listmaxshow) && (selected < (((Bouquets.size() / listmaxshow)+1) * listmaxshow))) ? (Bouquets.size() - 1) : 0; + } + paintItem(prev_selected - liststart); unsigned int oldliststart = liststart; liststart = (selected/listmaxshow)*listmaxshow; diff --git a/src/gui/scan.cpp b/src/gui/scan.cpp index 479940281..0dbd1724a 100644 --- a/src/gui/scan.cpp +++ b/src/gui/scan.cpp @@ -83,6 +83,8 @@ CScanTs::CScanTs() extern int scan_pids; extern int scan_fta_flag;//in zapit descriptors definiert +extern int start_fast_scan(int scan_mode, int opid); + #define get_set CNeutrinoApp::getInstance()->getScanSettings() int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) { @@ -97,6 +99,8 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) bool scan_all = actionKey == "all"; bool test = actionKey == "test"; bool manual = (actionKey == "manual") || test; + bool fast = (actionKey == "fast"); + CZapitClient::ScanSatelliteList satList; CZapitClient::commandSetScanSatelliteList sat; int _scan_pids = scan_pids; @@ -146,7 +150,9 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) //printf("[neutrino] freq %d rate %d fec %d pol %d\n", TP.feparams.frequency, TP.feparams.u.qpsk.symbol_rate, TP.feparams.u.qpsk.fec_inner, TP.polarization); } satList.clear(); - if(manual || !scan_all) { + if(fast) { + } + else if(manual || !scan_all) { for(sit = satellitePositions.begin(); sit != satellitePositions.end(); sit++) { if(!strcmp(sit->second.name.c_str(),get_set.satNameNoDiseqc)) { sat.position = sit->first; @@ -181,7 +187,8 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) g_Zapit->setScanBouquetMode( (CZapitClient::bouquetMode)CNeutrinoApp::getInstance()->getScanSettings().bouquetMode); /* send satellite list to zapit */ - g_Zapit->setScanSatelliteList( satList); + if(satList.size()) + g_Zapit->setScanSatelliteList( satList); /* send scantype to zapit */ g_Zapit->setScanType((CZapitClient::scanType) CNeutrinoApp::getInstance()->getScanSettings().scanType ); @@ -204,11 +211,12 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) success = g_Zapit->tune_TP(TP); } else if(manual) success = g_Zapit->scan_TP(TP); + else if(fast) { + success = !start_fast_scan(get_set.fast_type, get_set.fast_op); + } else success = g_Zapit->startScan(scan_mode); - //paint(); - /* poll for messages */ istheend = !success; while (!istheend) { diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 6879b0424..41146fa9b 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -3930,9 +3930,6 @@ void CNeutrinoApp::standbyMode( bool bOnOff ) //printf("********* CNeutrinoApp::standbyMode, was_record %d bOnOff %d\n", was_record, bOnOff); //printf( ( bOnOff ) ? "mode: standby on\n" : "mode: standby off\n" ); if( bOnOff ) { - puts("[neutrino.cpp] executing " NEUTRINO_ENTER_STANDBY_SCRIPT "."); - if (system(NEUTRINO_ENTER_STANDBY_SCRIPT) != 0) - perror(NEUTRINO_ENTER_STANDBY_SCRIPT " failed"); if(autoshift) { stopAutoRecord(); @@ -3967,6 +3964,10 @@ void CNeutrinoApp::standbyMode( bool bOnOff ) InfoClock->StopClock(); + puts("[neutrino.cpp] executing " NEUTRINO_ENTER_STANDBY_SCRIPT "."); + if (system(NEUTRINO_ENTER_STANDBY_SCRIPT) != 0) + perror(NEUTRINO_ENTER_STANDBY_SCRIPT " failed"); + lastMode = mode; mode = mode_standby; int fspeed = 1; @@ -3985,6 +3986,7 @@ void CNeutrinoApp::standbyMode( bool bOnOff ) frameBuffer->setActive(true); funNotifier->changeNotify(NONEXISTANT_LOCALE, (void*) &g_settings.fan_speed); + puts("[neutrino.cpp] executing " NEUTRINO_LEAVE_STANDBY_SCRIPT "."); if (system(NEUTRINO_LEAVE_STANDBY_SCRIPT) != 0) perror(NEUTRINO_LEAVE_STANDBY_SCRIPT " failed"); diff --git a/src/neutrino_menue.cpp b/src/neutrino_menue.cpp index 1e02709a6..85dc6fa91 100644 --- a/src/neutrino_menue.cpp +++ b/src/neutrino_menue.cpp @@ -135,6 +135,7 @@ #include #include +#include //#define TEST_MENU @@ -1003,6 +1004,23 @@ int CTPSelectHandler::exec(CMenuTarget* parent, const std::string &/*actionkey*/ } extern int scan_pids; + +#define FAST_SCAN_OPTIONS_COUNT 3 +const CMenuOptionChooser::keyval FAST_SCAN_OPTIONS[FAST_SCAN_OPTIONS_COUNT] = +{ + { FAST_SCAN_SD, LOCALE_SATSETUP_FASTSCAN_SD }, + { FAST_SCAN_HD, LOCALE_SATSETUP_FASTSCAN_HD }, + { FAST_SCAN_ALL, LOCALE_SATSETUP_FASTSCAN_ALL } +}; + +#define FAST_SCAN_PROV_OPTIONS_COUNT 3 +const CMenuOptionChooser::keyval FAST_SCAN_PROV_OPTIONS[FAST_SCAN_PROV_OPTIONS_COUNT] = +{ + { OPERATOR_CD, LOCALE_SATSETUP_FASTSCAN_PROV_CD }, + { OPERATOR_TVV, LOCALE_SATSETUP_FASTSCAN_PROV_TVV }, + { OPERATOR_TELESAT, LOCALE_SATSETUP_FASTSCAN_PROV_TELESAT } +}; + void CNeutrinoApp::InitScanSettings(CMenuWidget &settings) { dprintf(DEBUG_DEBUG, "init scansettings\n"); @@ -1019,7 +1037,9 @@ void CNeutrinoApp::InitScanSettings(CMenuWidget &settings) CMenuOptionChooser* useNit = new CMenuOptionChooser(LOCALE_SATSETUP_USE_NIT, (int *)&scanSettings.scan_mode, OPTIONS_OFF1_ON0_OPTIONS, OPTIONS_OFF1_ON0_OPTION_COUNT, true, NULL, CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN); CMenuOptionChooser* scanPids = new CMenuOptionChooser(LOCALE_EXTRA_ZAPIT_SCANPIDS, &scan_pids, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, NULL, CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW); - CMenuOptionChooser* ftaFlag = new CMenuOptionChooser(LOCALE_SATSETUP_USE_FTA_FLAG, (int *)&scanSettings.scan_fta_flag, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF1_ON0_OPTION_COUNT, true, NULL, CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE); + // Please lets keep shortcuts which used for a long time - unchanged. -- focus + //CMenuOptionChooser* ftaFlag = new CMenuOptionChooser(LOCALE_SATSETUP_USE_FTA_FLAG, (int *)&scanSettings.scan_fta_flag, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF1_ON0_OPTION_COUNT, true, NULL, CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE); + CMenuOptionChooser* ftaFlag = new CMenuOptionChooser(LOCALE_SATSETUP_USE_FTA_FLAG, (int *)&scanSettings.scan_fta_flag, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF1_ON0_OPTION_COUNT, true, NULL, CRCInput::convertDigitToKey(0)); CMenuWidget* satSetup = new CMenuWidget(LOCALE_SATSETUP_SAT_SETUP, NEUTRINO_ICON_SETTINGS); satSetup->addItem(GenericMenuSeparator); @@ -1096,6 +1116,7 @@ void CNeutrinoApp::InitScanSettings(CMenuWidget &settings) } } satfindMenu->addItem(satSelect); + satfindMenu->addItem(new CMenuForwarder(LOCALE_SCANTS_SELECT_TP, true, NULL, tpSelect, "test")); int freq_length = (g_info.delivery_system == DVB_S) ? 8 : 6; @@ -1169,7 +1190,7 @@ void CNeutrinoApp::InitScanSettings(CMenuWidget &settings) manualScan->addItem(ftaFlag); manualScan->addItem(GenericMenuSeparatorLine); manualScan->addItem(new CMenuForwarder(LOCALE_SCANTS_TEST, true, NULL, scanTs, "test", CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW)); - manualScan->addItem(new CMenuForwarder(LOCALE_SCANTS_STARTNOW, true, NULL, scanTs, "manual", CRCInput::convertDigitToKey(0))); + manualScan->addItem(new CMenuForwarder(LOCALE_SCANTS_STARTNOW, true, NULL, scanTs, "manual", CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE)); CMenuWidget* autoScan = new CMenuWidget(LOCALE_SATSETUP_AUTO_SCAN, NEUTRINO_ICON_SETTINGS); addMenueIntroItems(*autoScan); @@ -1177,7 +1198,7 @@ void CNeutrinoApp::InitScanSettings(CMenuWidget &settings) autoScan->addItem(useNit); autoScan->addItem(scanPids); autoScan->addItem(ftaFlag); - autoScan->addItem(new CMenuForwarder(LOCALE_SCANTS_STARTNOW, true, NULL, scanTs, "auto", CRCInput::convertDigitToKey(0))); + autoScan->addItem(new CMenuForwarder(LOCALE_SCANTS_STARTNOW, true, NULL, scanTs, "auto", CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE)); CMenuOptionChooser* ojDiseqc = NULL; CMenuOptionNumberChooser * ojDiseqcRepeats = NULL; @@ -1206,7 +1227,7 @@ void CNeutrinoApp::InitScanSettings(CMenuWidget &settings) autoScanAll->addItem(useNit); autoScanAll->addItem(scanPids); autoScanAll->addItem(ftaFlag); - autoScanAll->addItem(new CMenuForwarder(LOCALE_SCANTS_STARTNOW, true, NULL, scanTs, "all", CRCInput::convertDigitToKey(0))); + autoScanAll->addItem(new CMenuForwarder(LOCALE_SCANTS_STARTNOW, true, NULL, scanTs, "all", CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE)); } settings.addItem(GenericMenuSeparator); @@ -1229,6 +1250,17 @@ void CNeutrinoApp::InitScanSettings(CMenuWidget &settings) if (g_info.delivery_system == DVB_S) { settings.addItem(fautoScanAll); + + CMenuWidget* fastScanMenu = new CMenuWidget(LOCALE_SATSETUP_FASTSCAN_HEAD, NEUTRINO_ICON_SETTINGS); + addMenueIntroItems(*fastScanMenu); + + CMenuOptionChooser* fastProv = new CMenuOptionChooser(LOCALE_SATSETUP_FASTSCAN_PROV, (int *)&scanSettings.fast_op, FAST_SCAN_PROV_OPTIONS, FAST_SCAN_PROV_OPTIONS_COUNT, true, NULL, CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED, true); + CMenuOptionChooser* fastType = new CMenuOptionChooser(LOCALE_SATSETUP_FASTSCAN_TYPE, (int *)&scanSettings.fast_type, FAST_SCAN_OPTIONS, FAST_SCAN_OPTIONS_COUNT, true, NULL, CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN, true); + + fastScanMenu->addItem(fastProv); + fastScanMenu->addItem(fastType); + fastScanMenu->addItem(new CMenuForwarder(LOCALE_SCANTS_STARTNOW, true, NULL, scanTs, "fast", CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE)); + settings.addItem(new CMenuForwarder(LOCALE_SATSETUP_FASTSCAN_HEAD, true, NULL, fastScanMenu, "", CRCInput::convertDigitToKey(0))); } } diff --git a/src/system/locals.h b/src/system/locals.h index 83ca21e54..bba03929c 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -945,6 +945,15 @@ typedef enum { LOCALE_SATSETUP_USE_NIT, LOCALE_SATSETUP_USE_USALS, LOCALE_SATSETUP_USALS_REPEAT, + LOCALE_SATSETUP_FASTSCAN_HEAD, + LOCALE_SATSETUP_FASTSCAN_TYPE, + LOCALE_SATSETUP_FASTSCAN_SD, + LOCALE_SATSETUP_FASTSCAN_HD, + LOCALE_SATSETUP_FASTSCAN_ALL, + LOCALE_SATSETUP_FASTSCAN_PROV, + LOCALE_SATSETUP_FASTSCAN_PROV_CD, + LOCALE_SATSETUP_FASTSCAN_PROV_TVV, + LOCALE_SATSETUP_FASTSCAN_PROV_TELESAT, LOCALE_SCANTS_ABORT_BODY, LOCALE_SCANTS_ABORT_HEADER, LOCALE_SCANTS_ACTCABLE, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index fed42835f..e5568d57e 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -945,6 +945,15 @@ const char *locale_real_names[] = { "satsetup.use_nit", "satsetup.use_usals", "satsetup.usals_repeat", + "satsetup.fastscan_head", + "satsetup.fastscan_type", + "satsetup.fastscan_sd", + "satsetup.fastscan_hd", + "satsetup.fastscan_all", + "satsetup.fastscan_prov", + "satsetup.fastscan_prov_cd", + "satsetup.fastscan_prov_tvv", + "satsetup.fastscan_prov_telesat", "scants.abort_body", "scants.abort_header", "scants.actcable", diff --git a/src/system/settings.cpp b/src/system/settings.cpp index ab735719c..3f777a26b 100644 --- a/src/system/settings.cpp +++ b/src/system/settings.cpp @@ -162,7 +162,7 @@ bool CScanSettings::loadSettings(const char * const fileName, const delivery_sys scanType=(CZapitClient::scanType) configfile.getInt32("scanType", scanType); strcpy(satNameNoDiseqc, configfile.getString("satNameNoDiseqc", satNameNoDiseqc).c_str()); - scan_fta_flag = configfile.getInt32("scan_fta_flag", 0); + scan_fta_flag = configfile.getInt32("scan_fta_flag", 0); scan_mode = configfile.getInt32("scan_mode", 1); // NIT (0) or fast (1) TP_fec = configfile.getInt32("TP_fec", 1); TP_pol = configfile.getInt32("TP_pol", 0); @@ -173,6 +173,9 @@ bool CScanSettings::loadSettings(const char * const fileName, const delivery_sys if(TP_fec == 4) TP_fec = 5; #endif scanSectionsd = configfile.getInt32("scanSectionsd", 0); + fast_type = configfile.getInt32("fast_type", 1); + fast_op = configfile.getInt32("fast_op", 0); + return true; } @@ -185,7 +188,7 @@ bool CScanSettings::saveSettings(const char * const fileName) configfile.setInt32( "scanType", scanType ); configfile.setString( "satNameNoDiseqc", satNameNoDiseqc ); - configfile.setInt32("scan_fta_flag", scan_fta_flag); + configfile.setInt32("scan_fta_flag", scan_fta_flag); configfile.setInt32("scan_mode", scan_mode); configfile.setInt32("TP_fec", TP_fec); configfile.setInt32("TP_pol", TP_pol); @@ -193,6 +196,8 @@ bool CScanSettings::saveSettings(const char * const fileName) configfile.setString("TP_freq", TP_freq); configfile.setString("TP_rate", TP_rate); configfile.setInt32("scanSectionsd", scanSectionsd ); + configfile.setInt32("fast_type", fast_type); + configfile.setInt32("fast_op", fast_op); if(configfile.getModifiedFlag()) configfile.saveConfig(fileName); diff --git a/src/system/settings.h b/src/system/settings.h index 70894835c..fd204b977 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -531,12 +531,14 @@ public: delivery_system_t delivery_system; int scanSectionsd; int scan_mode; - int scan_fta_flag; + int scan_fta_flag; int TP_fec; int TP_pol; int TP_mod; char TP_freq[10]; char TP_rate[9]; + int fast_type; + int fast_op; CScanSettings(); diff --git a/src/zapit/include/zapit/fastscan.h b/src/zapit/include/zapit/fastscan.h new file mode 100644 index 000000000..7261b8d81 --- /dev/null +++ b/src/zapit/include/zapit/fastscan.h @@ -0,0 +1,38 @@ +#ifndef _FASTSCAN_H_ +#define _FASTSCAN_H_ + +int parse_fnt(unsigned short pid, unsigned short operator_id); +int parse_fst(unsigned short pid, unsigned short operator_id); + +void * start_fast_scan(void * arg); + +typedef enum fs_operator { + OPERATOR_CD, + OPERATOR_TVV, + OPERATOR_TELESAT, + OPERATOR_MAX +} fs_operator_t; + +#define CD_OPERATOR_ID (106) +#define TVV_OPERATOR_ID (108) +#define TELESAT_OPERATOR_ID (109) + +#define FAST_SCAN_SD 1 +#define FAST_SCAN_HD 2 +#define FAST_SCAN_ALL 3 + +typedef struct fast_scan_operator { + int id; + unsigned short sd_pid; + unsigned short hd_pid; + char * name; +} fast_scan_operator_t; + +typedef struct fast_scan_type { + fs_operator_t op; + int type; +} fast_scan_type_t; + +extern fast_scan_operator_t fast_scan_operators [OPERATOR_MAX]; + +#endif diff --git a/src/zapit/src/Makefile.am b/src/zapit/src/Makefile.am index 52bd43bda..9a8994402 100644 --- a/src/zapit/src/Makefile.am +++ b/src/zapit/src/Makefile.am @@ -15,7 +15,7 @@ noinst_LIBRARIES = libzapit.a libzapit_a_SOURCES = \ bouquets.cpp channel.cpp dvbstring.cpp getservices.cpp \ scan.cpp zapit.cpp cam.cpp ci.cpp frontend.cpp \ - descriptors.cpp nit.cpp pat.cpp pmt.cpp sdt.cpp + descriptors.cpp nit.cpp pat.cpp pmt.cpp sdt.cpp fastscan.cpp bin_PROGRAMS = pzapit sbin_PROGRAMS = udpstreampes diff --git a/src/zapit/src/fastscan.cpp b/src/zapit/src/fastscan.cpp new file mode 100644 index 000000000..7391c9773 --- /dev/null +++ b/src/zapit/src/fastscan.cpp @@ -0,0 +1,578 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEC_SIZE 4096 + +fast_scan_operator_t fast_scan_operators [OPERATOR_MAX] = { + { CD_OPERATOR_ID, 900, 901, (char *) "CanalDigitaal" }, + { TVV_OPERATOR_ID, 910, 911, (char *) "TV Vlaanderen" }, + { TELESAT_OPERATOR_ID, 920, 921 , (char *) "TéléSAT" } +}; + +extern bool tuneFrequency(FrontendParameters *feparams, uint8_t polarization, t_satellite_position satellitePosition); +extern void stop_scan(const bool success); +extern CEventServer *eventServer; + +extern CFrontend *frontend; +extern CBouquetManager *g_bouquetManager; +extern CBouquetManager* scanBouquetManager; +extern CZapitClient::bouquetMode bouquetMode; +extern transponder_list_t transponders; // defined in zapit.cpp +extern tallchans allchans; // defined in zapit.cpp +extern int found_transponders; +extern int found_channels; +extern uint32_t found_tv_chans; +extern uint32_t found_radio_chans; +extern uint32_t found_data_chans; +extern int zapit(const t_channel_id channel_id, bool in_nvod, bool forupdate = 0, bool nowait = 0); +extern t_channel_id live_channel_id; + +int process_satellite_delivery_system_descriptor(const unsigned char * const buffer, FrontendParameters * feparams, uint8_t * polarization, t_satellite_position * satellitePosition); +void process_service_list_descriptor(const unsigned char * const buffer, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq); + +std::map fast_services_sat; +std::map fast_services_freq; + +void * start_fast_scan(void * arg) +{ + fast_scan_type_t * scan = (fast_scan_type_t *) arg; + fast_scan_operator_t * op; + fs_operator_t num = scan->op; + int type = scan->type; + uint8_t polarization; + FrontendParameters feparams; + int res; + + if(num >= OPERATOR_MAX) { + printf("[fast scan] invalid operator %d\n", num); + goto _err; + } + found_transponders = 0; + found_channels = 0; + found_tv_chans = 0; + found_data_chans = 0; + found_radio_chans = 0; + + op = &fast_scan_operators[num]; + + printf("[fast scan] scaning operator %d for %s channels\n", op->id, type == FAST_SCAN_SD ? "SD" : type == FAST_SCAN_HD ? "HD" : "All"); + + feparams.frequency = 12515000; + feparams.u.qpsk.symbol_rate = 22000000; + feparams.u.qpsk.fec_inner = FEC_5_6; + polarization = 0; + + eventServer->sendEvent(CZapitClient::EVT_SCAN_SATELLITE, CEventServer::INITID_ZAPIT, op->name, strlen(op->name)+1); + if(!tuneFrequency(&feparams, polarization, 192)) { + printf("[fast scan] tune failed\n"); + goto _err; + } + + scanBouquetManager = new CBouquetManager(); + + fast_services_sat.clear(); + fast_services_freq.clear(); + + if(type & FAST_SCAN_SD) { + res = parse_fnt(op->sd_pid, op->id); + if(res == 0) + parse_fst(op->sd_pid, op->id); + + printf("[fast scan] pid %d (SD) scan done, found %d transponders and %d services\n", op->sd_pid, found_transponders, found_channels); + } + if(type & FAST_SCAN_HD) { + res = parse_fnt(op->hd_pid, op->id); + if(res == 0) + res = parse_fst(op->hd_pid, op->id); + + printf("[fast scan] pid %d (HD) scan done, found %d transponders and %d services\n", op->hd_pid, found_transponders, found_channels); + } + + if(found_channels) { + CZapitClient myZapitClient; + SaveServices(true); + scanBouquetManager->saveBouquets(bouquetMode, ""); + g_bouquetManager->saveBouquets(); + g_bouquetManager->clearAll(); + g_bouquetManager->loadBouquets(); + stop_scan(true); + myZapitClient.reloadCurrentServices(); + } else { + stop_scan(false); + frontend->setTsidOnid(0); + //zapit(live_channel_id, 0); + } + fast_services_sat.clear(); + fast_services_freq.clear(); + + printf("[fast scan] fast scan done, found %d transponders and %d services\n", found_transponders, found_channels); + return NULL; +_err: + stop_scan(false); + return NULL; +} + +int parse_fst(unsigned short pid, unsigned short operator_id) +{ + int secdone[255]; + int sectotal = -1; + + memset(secdone, 0, 255); + + cDemux * dmx = new cDemux(); + dmx->Open(DMX_PSI_CHANNEL); + + unsigned char buffer[SEC_SIZE]; + + /* position in buffer */ + unsigned short pos; + unsigned short pos2; + + /* service_description_section elements */ + unsigned short section_length; + unsigned short transport_stream_id = 0; + unsigned short original_network_id = 0; + unsigned short operator_network_id = 0; + + unsigned short service_id; + unsigned short descriptors_loop_length; + unsigned short video_pid, audio_pid, pcr_pid; + + unsigned char filter[DMX_FILTER_SIZE]; + unsigned char mask[DMX_FILTER_SIZE]; + + memset(filter, 0x00, DMX_FILTER_SIZE); + memset(mask, 0x00, DMX_FILTER_SIZE); + + filter[0] = 0xBD; + filter[1] = (operator_id >> 8) & 0xff; + filter[2] = operator_id & 0xff; + mask[0] = mask[1] = mask[2] = 0xFF; + + printf("[FST] scaning pid %d operator %d\n", pid, operator_id); + + if (dmx->sectionFilter(pid, filter, mask, 3) < 0) { + delete dmx; + return -1; + } + do { + if (dmx->Read(buffer, SEC_SIZE) < 0) { + delete dmx; + return -1; + } + if(buffer[0] != 0xBD) + printf("[FST] ******************************************* Bogus section received: 0x%x\n", buffer[0]); + + + section_length = ((buffer[1] & 0x0F) << 8) | buffer[2]; + operator_network_id = (buffer[3] << 8) | buffer[4]; + + unsigned char secnum = buffer[6]; + printf("[FST] section %X last %X operator 0x%x -> %s\n", buffer[6], buffer[7], operator_network_id, secdone[secnum] ? "skip" : "use"); + + if(secdone[secnum]) + continue; + + secdone[secnum] = 1; + sectotal++; + + for (pos = 8; pos < section_length - 1; pos += descriptors_loop_length + 18) { + original_network_id = (buffer[pos] << 8) | buffer[pos+1]; + transport_stream_id = (buffer[pos+2] << 8) | buffer[pos+3]; + service_id = (buffer[pos+4] << 8) | buffer[pos+5]; + video_pid = (buffer[pos+6] << 8) | buffer[pos+7]; + audio_pid = (buffer[pos+8] << 8) | buffer[pos+9]; + pcr_pid = (buffer[pos+14] << 8) | buffer[pos+15]; + + //printf("[FST] onid %x tid %x sid %x vpid %x apid %x pcr %x\n", original_network_id, transport_stream_id, service_id, video_pid, audio_pid, pcr_pid); + descriptors_loop_length = ((buffer[pos + 16] & 0x0F) << 8) | buffer[pos + 17]; + + for (pos2 = pos + 18; pos2 < pos + descriptors_loop_length + 18; pos2 += buffer[pos2 + 1] + 2) { + switch (buffer[pos2]) { + case 0x48: + { + unsigned char * dbuf = &buffer[pos2]; + uint8_t service_type = dbuf[2]; + uint8_t service_provider_name_length = dbuf[3]; + /*uint8_t service_name_length = dbuf[service_provider_name_length + 4];*/ + int service_name_length = (2 + dbuf[1]) - (4 + service_provider_name_length + 1); + + t_satellite_position satellitePosition = 0; + freq_id_t freq = 0; + + t_channel_id channel_id = CREATE_CHANNEL_ID64; + + std::map ::iterator sIt = fast_services_sat.find(channel_id); + if(sIt != fast_services_sat.end()) + satellitePosition = sIt->second; + + std::map ::iterator fIt = fast_services_freq.find(channel_id); + if(fIt != fast_services_freq.end()) + freq = fIt->second; + + //std::string providerName = CDVBString((const char*)&(dbuf[4]), service_provider_name_length).getContent(); + //std::string serviceName = CDVBString((const char*)&(dbuf[4 + service_provider_name_length + 1]), (2 + dbuf[1]) - (4 + service_provider_name_length + 1)).getContent(); + + std::string providerName = convertDVBUTF8((const char*)&(dbuf[4]), service_provider_name_length, 1, 1); + std::string serviceName = convertDVBUTF8((const char*)&(dbuf[4 + service_provider_name_length + 1]), service_name_length, 1, 1); + + eventServer->sendEvent(CZapitClient::EVT_SCAN_PROVIDER, CEventServer::INITID_ZAPIT, (void *) providerName.c_str(), providerName.length() + 1); +#ifdef SCAN_DEBUG + printf("[FST] sat %04d onid %04x tid %04x sid %04x vpid %04x apid %04x pcr %04x freq %05d type %d prov [%s] name [%s]\n", satellitePosition, original_network_id, transport_stream_id, service_id, video_pid, audio_pid, pcr_pid, freq, service_type, providerName.c_str(), serviceName.c_str()); +#endif + found_channels ++; + eventServer->sendEvent ( CZapitClient::EVT_SCAN_NUM_CHANNELS, CEventServer::INITID_ZAPIT, &found_channels, sizeof(found_channels)); + switch (service_type) { + case ST_DIGITAL_TELEVISION_SERVICE: + found_tv_chans++; + eventServer->sendEvent(CZapitClient::EVT_SCAN_FOUND_TV_CHAN, CEventServer::INITID_ZAPIT, &found_tv_chans, sizeof(found_tv_chans)); + break; + case ST_DIGITAL_RADIO_SOUND_SERVICE: + found_radio_chans++; + eventServer->sendEvent(CZapitClient::EVT_SCAN_FOUND_RADIO_CHAN, CEventServer::INITID_ZAPIT, &found_radio_chans, sizeof(found_radio_chans)); + break; + case ST_NVOD_REFERENCE_SERVICE: + case ST_NVOD_TIME_SHIFTED_SERVICE: + case ST_DATA_BROADCAST_SERVICE: + case ST_RCS_MAP: + case ST_RCS_FLS: + default: + found_data_chans++; + eventServer->sendEvent(CZapitClient::EVT_SCAN_FOUND_DATA_CHAN, CEventServer::INITID_ZAPIT, &found_data_chans, sizeof(found_data_chans)); + break; + } + eventServer->sendEvent(CZapitClient::EVT_SCAN_SERVICENAME, CEventServer::INITID_ZAPIT, (void *) serviceName.c_str(), serviceName.length() + 1); + //service_descriptor(buffer + pos2, service_id, transport_stream_id, original_network_id, satellitePosition, freq, free_CA_mode); + channel_id = CREATE_CHANNEL_ID64; + + CZapitChannel * channel; + + tallchans_iterator I = allchans.find(channel_id); + if (I != allchans.end()) { + channel = &I->second; + + } else { + pair::iterator,bool> ret; + ret = allchans.insert ( + std::pair ( + channel_id, + CZapitChannel ( + serviceName, + service_id, + transport_stream_id, + original_network_id, + service_type, + satellitePosition, + freq + ) + ) + ); + channel = &ret.first->second; + } + channel->setName(serviceName); + channel->setServiceType(service_type); + channel->setVideoPid(video_pid); + channel->setAudioPid(audio_pid); + channel->setPcrPid(pcr_pid); + channel->setPidsFlag(); + + CZapitBouquet* bouquet; + int bouquetId; + char pname[100]; + if (frontend->getInfo()->type == FE_QPSK) + snprintf(pname, 100, "[%c%03d.%d] %s", satellitePosition > 0? 'E' : 'W', abs(satellitePosition)/10, abs(satellitePosition)%10, providerName.c_str()); + else + snprintf(pname, 100, "%s", providerName.c_str()); + + bouquetId = scanBouquetManager->existsBouquet(pname); + + if (bouquetId == -1) + bouquet = scanBouquetManager->addBouquet(std::string(pname), false); + else + bouquet = scanBouquetManager->Bouquets[bouquetId]; + bouquet->addService(channel); + if(channel->getServiceType() == 1) + live_channel_id = channel->getChannelID(); + + } + break; + default: + printf("[FST] descriptor_tag: %02x\n", buffer[pos2]); + break; + } + } + } + } while(sectotal < buffer[7]); + delete dmx; + + printf("[FST] done\n\n"); + return 0; +} + +int parse_fnt(unsigned short pid, unsigned short operator_id) +{ + int ret = 0; + int secdone[255]; + int sectotal = -1; + + for(int i = 0; i < 255; i++) + secdone[i] = 0; + + cDemux * dmx = new cDemux();; + dmx->Open(DMX_PSI_CHANNEL); + + unsigned char buffer[SEC_SIZE]; + + /* position in buffer */ + unsigned short pos; + unsigned short pos2; + + /* network_information_section elements */ + unsigned short section_length; + unsigned short network_descriptors_length; + unsigned short transport_descriptors_length; + unsigned short transport_stream_loop_length; + t_transport_stream_id transport_stream_id; + t_original_network_id original_network_id; + unsigned short network_id; + + unsigned char filter[DMX_FILTER_SIZE]; + unsigned char mask[DMX_FILTER_SIZE]; + + memset(filter, 0x00, DMX_FILTER_SIZE); + memset(mask, 0x00, DMX_FILTER_SIZE); + + filter[0] = 0xBC; + filter[1] = (operator_id >> 8) & 0xff; + filter[2] = operator_id & 0xff; + + mask[0] = mask[1] = mask[2] = 0xFF; + + printf("[FNT] scaning pid %d operator %d\n", pid, operator_id); + if (dmx->sectionFilter(pid, filter, mask, 3) < 0) { + delete dmx; + return -1; + } + do { + if (dmx->Read(buffer, SEC_SIZE) < 0) { + delete dmx; + return -1; + } + if(buffer[0] != 0xBC) + printf("[FNT] ******************************************* Bogus section received: 0x%x\n", buffer[0]); + + section_length = ((buffer[1] & 0x0F) << 8) + buffer[2]; + network_id = ((buffer[3] << 8)| buffer [4]); + network_descriptors_length = ((buffer[8] & 0x0F) << 8) | buffer[9]; + + unsigned char secnum = buffer[6]; + printf("[FNT] section %X last %X network_id 0x%x -> %s\n", secnum, buffer[7], network_id, secdone[secnum] ? "skip" : "use"); + if(secdone[secnum]) // mark sec XX done + continue; + secdone[secnum] = 1; + sectotal++; + + for (pos = 10; pos < network_descriptors_length + 10; pos += buffer[pos + 1] + 2) + { + switch (buffer[pos]) + { + case 0x40: +#ifdef SCAN_DEBUG + { + unsigned char len = buffer[pos+1]; + char name[255]; + int i; + + for(i = 0; i < len; i++) + name[i] = buffer[pos+2+i]; + name[i] = 0; + printf("[FNT] network name: %s (%d)\n", name, len); + + //printf("[FNT] network name descriptor\n"); + //network_name_descriptor(buffer + pos); + } +#endif + break; + default: + printf("[FNT] descriptor_tag: %02x\n", buffer[pos]); + break; + } + } + + transport_stream_loop_length = ((buffer[pos] & 0x0F) << 8) | buffer[pos + 1]; + + if (!transport_stream_loop_length) + continue; + + for (pos += 2; pos < section_length - 3; pos += transport_descriptors_length + 6) + { + transport_stream_id = (buffer[pos] << 8) | buffer[pos + 1]; + original_network_id = (buffer[pos + 2] << 8) | buffer[pos + 3]; + transport_descriptors_length = ((buffer[pos + 4] & 0x0F) << 8) | buffer[pos + 5]; + FrontendParameters feparams; + uint8_t polarization; + t_satellite_position satellitePosition = 0; + freq_id_t freq; + + for (pos2 = pos + 6; pos2 < pos + transport_descriptors_length + 6; pos2 += buffer[pos2 + 1] + 2) + { + //printf("[FNT] second_descriptor_tag: %02x\n", buffer[pos2]); + switch (buffer[pos2]) + { + case 0x43: + { + transponder_id_t TsidOnid; + stiterator stI; + + process_satellite_delivery_system_descriptor(buffer + pos2, &feparams, &polarization, &satellitePosition); + freq = feparams.frequency / 1000; + TsidOnid = CREATE_TRANSPONDER_ID_FROM_SATELLITEPOSITION_ORIGINALNETWORK_TRANSPORTSTREAM_ID(freq, satellitePosition, original_network_id, transport_stream_id); + stI = transponders.find(TsidOnid); + if(stI == transponders.end()) { + transponders.insert ( + std::pair ( + TsidOnid, + transponder ( + transport_stream_id, + feparams, + polarization, + original_network_id + ) + ) + ); + } + found_transponders++; + //eventServer->sendEvent(CZapitClient::EVT_SCAN_NUM_TRANSPONDERS, CEventServer::INITID_ZAPIT, + // &found_transponders, sizeof(found_transponders)); + uint32_t actual_freq = freq; + eventServer->sendEvent(CZapitClient::EVT_SCAN_REPORT_FREQUENCY,CEventServer::INITID_ZAPIT, + &actual_freq, sizeof(actual_freq)); + //satellite_delivery_system_descriptor(buffer + pos2, transport_stream_id, original_network_id, satellitePosition, freq); + } + break; + case 0x41: + process_service_list_descriptor(buffer + pos2, transport_stream_id, original_network_id, 0, 0); + break; + case 0x83: // logical_service_desciptor + break; + case 0x44: + //cable_delivery_system_descriptor(buffer + pos2, transport_stream_id, original_network_id, satellitePosition, freq); + break; + default: + printf("[FNT] second_descriptor_tag: %02x\n", buffer[pos2]); + break; + } + } + std::map ::iterator sIt = fast_services_sat.begin(); + for(; sIt != fast_services_sat.end(); sIt++) + if(sIt->second == 0) + sIt->second = satellitePosition; + + std::map ::iterator fIt = fast_services_freq.begin(); + for(; fIt != fast_services_freq.end(); fIt++) + if(fIt->second == 0) + fIt->second = freq; + } + eventServer->sendEvent(CZapitClient::EVT_SCAN_NUM_TRANSPONDERS, CEventServer::INITID_ZAPIT, + &found_transponders, sizeof(found_transponders)); + } while(sectotal < buffer[7]); + + dmx->Stop(); + delete dmx; + printf("[FNT] done\n\n"); + return ret; +} + +void process_service_list_descriptor(const unsigned char * const buffer, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq) +{ + for (int i = 0; i < buffer[1]; i += 3) { + t_service_id service_id = buffer[i + 2] << 8 | buffer[i + 3]; + t_channel_id channel_id = CREATE_CHANNEL_ID64; +#ifdef SCAN_DEBUG + std::map ::iterator sIt = fast_services_sat.find(channel_id); + if(sIt != fast_services_sat.end()) + printf("[FNT] dup channel %llx\n", channel_id); +#endif + fast_services_sat[channel_id] = satellitePosition; + fast_services_freq[channel_id] = freq; + } +} + +int process_satellite_delivery_system_descriptor(const unsigned char * const buffer, FrontendParameters * feparams, uint8_t * polarization, t_satellite_position * satellitePosition) +{ + stiterator tI; + int modulationSystem, modulationType, rollOff, fec_inner; + + feparams->frequency = ( + ((buffer[2] >> 4) * 100000000) + + ((buffer[2] & 0x0F) * 10000000) + + ((buffer[3] >> 4) * 1000000) + + ((buffer[3] & 0x0F) * 100000) + + ((buffer[4] >> 4) * 10000) + + ((buffer[4] & 0x0F) * 1000) + + ((buffer[5] >> 4) * 100) + + ((buffer[5] & 0x0F) * 10) + ); + + * satellitePosition = ( + ((buffer[6] >> 4) * 1000) + + ((buffer[6] & 0x0F) * 100) + + ((buffer[7] >> 4) * 10) + + ((buffer[7] & 0x0F) * 1) + ); + feparams->inversion = INVERSION_AUTO; + + rollOff = (buffer[8] >> 4) & 0x03; //alpha_0_35, alpha_0_25, alpha_0_20, alpha_auto + modulationSystem = (buffer[8] >> 2) & 0x01; // 1= DVB_S2 + modulationType = (buffer[8]) & 0x03; // 1=QPSK, 2=M8PSK + + feparams->u.qpsk.symbol_rate = ( + ((buffer[9] >> 4) * 100000000) + + ((buffer[9] & 0x0F) * 10000000) + + ((buffer[10] >> 4) * 1000000) + + ((buffer[10] & 0x0F) * 100000) + + ((buffer[11] >> 4) * 10000) + + ((buffer[11] & 0x0F) * 1000) + + ((buffer[12] >> 4) * 100) + ); + + fec_inner = CFrontend::getCodeRate(buffer[12] & 0x0F, modulationSystem); + if(modulationType == 2) + fec_inner += 9; + + feparams->u.qpsk.fec_inner = (fe_code_rate_t) fec_inner; + + * polarization = (buffer[8] >> 5) & 0x03; + + /* workarounds for braindead broadcasters (e.g. on Telstar 12 at 15.0W) */ + if (feparams->frequency >= 100000000) + feparams->frequency /= 10; + if (feparams->u.qpsk.symbol_rate >= 50000000) + feparams->u.qpsk.symbol_rate /= 10; + + feparams->frequency = (int) 1000 * (int) round ((double) feparams->frequency / (double) 1000); + +#ifdef SCAN_DEBUG + printf("[FNT] new TP: sat %d freq %d SR %d fec %d pol %d\n", *satellitePosition, feparams->frequency, feparams->u.qpsk.symbol_rate, fec_inner, * polarization); +#endif + + return 0; +} diff --git a/src/zapit/src/getservices.cpp b/src/zapit/src/getservices.cpp index c4da72240..e8cc7828f 100644 --- a/src/zapit/src/getservices.cpp +++ b/src/zapit/src/getservices.cpp @@ -29,7 +29,7 @@ #include #include #include - +#include extern xmlDocPtr scanInputParser; extern transponder_list_t transponders; extern tallchans allchans; diff --git a/src/zapit/src/zapit.cpp b/src/zapit/src/zapit.cpp index a14724322..9ba716198 100644 --- a/src/zapit/src/zapit.cpp +++ b/src/zapit/src/zapit.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -730,6 +731,26 @@ int start_scan(int scan_mode) return 0; } +int start_fast_scan(int scan_mode, int opid) +{ + fast_scan_type_t scant; + + scant.type = scan_mode; + scant.op = (fs_operator_t) opid; + + scan_runs = 1; + stopPlayBack(true); + pmt_stop_update_filter(&pmt_update_fd); + + found_transponders = 0; + found_channels = 0; + if (pthread_create(&scan_thread, 0, start_fast_scan, (void*)&scant)) { + ERROR("pthread_create"); + scan_runs = 0; + return -1; + } + return 0; +} bool zapit_parse_command(CBasicMessage::Header &rmsg, int connfd) {