X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/652d872f2cfba15d561090e3fa27f3614e0e8f2d..6347d817582886ab7c7535b44601538749d06d5b:/lib/dvb/db.cpp diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 8f418dac..1c332033 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -151,7 +151,7 @@ RESULT eDVBService::getEvent(const eServiceReference &ref, ePtr & return eEPGCache::getInstance()->lookupEventTime(ref, start_time, ptr); } -int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore) +int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { ePtr res_mgr; if ( eDVBResourceManager::getInstance( res_mgr ) ) @@ -161,7 +161,7 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc eDVBChannelID chid, chid_ignore; ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - return res_mgr->canAllocateChannel(chid, chid_ignore); + return res_mgr->canAllocateChannel(chid, chid_ignore, simulate); } return 0; } @@ -260,12 +260,17 @@ void eDVBService::setCacheEntry(cacheID id, int pid) DEFINE_REF(eDVBDB); - /* THIS CODE IS BAD. it should be replaced by somethine better. */ void eDVBDB::reloadServicelist() +{ + loadServicelist(CONFIGDIR"/enigma2/lamedb"); +} + + /* THIS CODE IS BAD. it should be replaced by somethine better. */ +void eDVBDB::loadServicelist(const char *file) { eDebug("---- opening lame channel db"); - FILE *f=fopen(CONFIGDIR"/enigma2/lamedb", "rt"); - if (!f) + FILE *f=fopen(file, "rt"); + if (!f && strcmp(file, CONFIGDIR"/enigma2/lamedb") == 0) { struct stat s; if ( !stat("lamedb", &s) ) @@ -279,13 +284,14 @@ void eDVBDB::reloadServicelist() return; } char line[256]; - if ((!fgets(line, 256, f)) || strncmp(line, "eDVB services", 13)) + int version=3; + if ((!fgets(line, 256, f)) || sscanf(line, "eDVB services /%d/", &version) != 1) { - eDebug("not a servicefile"); + eDebug("not a valid servicefile"); fclose(f); return; } - eDebug("reading services"); + eDebug("reading services (version %d)", version); if ((!fgets(line, 256, f)) || strcmp(line, "transponders\n")) { eDebug("services invalid, no transponders"); @@ -320,10 +326,15 @@ void eDVBDB::reloadServicelist() { eDVBFrontendParametersSatellite sat; int frequency, symbol_rate, polarisation, fec, orbital_position, inversion, + flags=0, system=eDVBFrontendParametersSatellite::System::DVB_S, modulation=eDVBFrontendParametersSatellite::Modulation::QPSK, - rolloff=eDVBFrontendParametersSatellite::RollOff::alpha_auto; - sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &system, &modulation, &rolloff); + rolloff=eDVBFrontendParametersSatellite::RollOff::alpha_0_35, + pilot=eDVBFrontendParametersSatellite::Pilot::Unknown; + if (version == 3) + sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &system, &modulation, &rolloff, &pilot); + else + sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &flags, &system, &modulation, &rolloff, &pilot); sat.frequency = frequency; sat.symbol_rate = symbol_rate; sat.polarisation = polarisation; @@ -333,13 +344,15 @@ void eDVBDB::reloadServicelist() sat.inversion = inversion; sat.system = system; sat.modulation = modulation; - sat.roll_off = rolloff; + sat.rolloff = rolloff; + sat.pilot = pilot; feparm->setDVBS(sat); + feparm->setFlags(flags); } else if (line[1]=='t') { eDVBFrontendParametersTerrestrial ter; - int frequency, bandwidth, code_rate_HP, code_rate_LP, modulation, transmission_mode, guard_interval, hierarchy, inversion; - sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &bandwidth, &code_rate_HP, &code_rate_LP, &modulation, &transmission_mode, &guard_interval, &hierarchy, &inversion); + int frequency, bandwidth, code_rate_HP, code_rate_LP, modulation, transmission_mode, guard_interval, hierarchy, inversion, flags=0; + sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &bandwidth, &code_rate_HP, &code_rate_LP, &modulation, &transmission_mode, &guard_interval, &hierarchy, &inversion, &flags); ter.frequency = frequency; ter.bandwidth = bandwidth; ter.code_rate_HP = code_rate_HP; @@ -350,20 +363,23 @@ void eDVBDB::reloadServicelist() ter.hierarchy = hierarchy; ter.inversion = inversion; feparm->setDVBT(ter); + feparm->setFlags(flags); } else if (line[1]=='c') { eDVBFrontendParametersCable cab; int frequency, symbol_rate, inversion=eDVBFrontendParametersCable::Inversion::Unknown, modulation=eDVBFrontendParametersCable::Modulation::Auto, - fec_inner=eDVBFrontendParametersCable::FEC::fAuto; - sscanf(line+3, "%d:%d:%d:%d:%d", &frequency, &symbol_rate, &inversion, &modulation, &fec_inner); + fec_inner=eDVBFrontendParametersCable::FEC::fAuto, + flags=0; + sscanf(line+3, "%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &inversion, &modulation, &fec_inner, &flags); cab.frequency = frequency; cab.fec_inner = fec_inner; cab.inversion = inversion; cab.symbol_rate = symbol_rate; cab.modulation = modulation; feparm->setDVBC(cab); + feparm->setFlags(flags); } } addChannelToList(channelid, feparm); @@ -417,7 +433,7 @@ void eDVBDB::reloadServicelist() } else while ((!str.empty()) && str[1]==':') // new: p:, f:, c:%02d... { - unsigned int c=str.find(','); + size_t c=str.find(','); char p=str[0]; std::string v; if (c == std::string::npos) @@ -455,14 +471,14 @@ void eDVBDB::reloadServicelist() fclose(f); } -void eDVBDB::saveServicelist() +void eDVBDB::saveServicelist(const char *file) { eDebug("---- saving lame channel db"); - FILE *f=fopen(CONFIGDIR"/enigma2/lamedb", "w"); + FILE *f=fopen(file, "w"); int channels=0, services=0; if (!f) eFatal("couldn't save lame channel db!"); - fprintf(f, "eDVB services /3/\n"); + fprintf(f, "eDVB services /4/\n"); fprintf(f, "transponders\n"); for (std::map::const_iterator i(m_channels.begin()); i != m_channels.end(); ++i) @@ -475,39 +491,43 @@ void eDVBDB::saveServicelist() eDVBFrontendParametersSatellite sat; eDVBFrontendParametersTerrestrial ter; eDVBFrontendParametersCable cab; + unsigned int flags; // flagOnlyFree yet.. + ch.m_frontendParameters->getFlags(flags); if (!ch.m_frontendParameters->getDVBS(sat)) { if (sat.system == eDVBFrontendParametersSatellite::System::DVB_S2) { - fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d\n", + fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", sat.frequency, sat.symbol_rate, sat.polarisation, sat.fec, sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position, sat.inversion, + flags, sat.system, sat.modulation, - sat.roll_off); + sat.rolloff, + sat.pilot); } else { - fprintf(f, "\ts %d:%d:%d:%d:%d:%d\n", + fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d\n", sat.frequency, sat.symbol_rate, sat.polarisation, sat.fec, sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position, - sat.inversion); + sat.inversion, flags); } } else if (!ch.m_frontendParameters->getDVBT(ter)) { - fprintf(f, "\tt %d:%d:%d:%d:%d:%d:%d:%d:%d\n", + fprintf(f, "\tt %d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n", ter.frequency, ter.bandwidth, ter.code_rate_HP, ter.code_rate_LP, ter.modulation, ter.transmission_mode, - ter.guard_interval, ter.hierarchy, ter.inversion); + ter.guard_interval, ter.hierarchy, ter.inversion, flags); } else if (!ch.m_frontendParameters->getDVBC(cab)) { - fprintf(f, "\tc %d:%d:%d:%d:%d\n", - cab.frequency, cab.symbol_rate, cab.inversion, cab.modulation, cab.fec_inner); + fprintf(f, "\tc %d:%d:%d:%d:%d:%d\n", + cab.frequency, cab.symbol_rate, cab.inversion, cab.modulation, cab.fec_inner, flags); } fprintf(f, "/\n"); channels++; @@ -552,6 +572,11 @@ void eDVBDB::saveServicelist() fclose(f); } +void eDVBDB::saveServicelist() +{ + saveServicelist(CONFIGDIR"/enigma2/lamedb"); +} + void eDVBDB::loadBouquet(const char *path) { std::string bouquet_name = path; @@ -560,7 +585,7 @@ void eDVBDB::loadBouquet(const char *path) eDebug("Bouquet load failed.. no path given.."); return; } - unsigned int pos = bouquet_name.rfind('/'); + size_t pos = bouquet_name.rfind('/'); if ( pos != std::string::npos ) bouquet_name.erase(0, pos+1); if (bouquet_name.empty()) @@ -627,7 +652,7 @@ void eDVBDB::loadBouquet(const char *path) } if ( tmp.flags&eServiceReference::canDescent ) { - unsigned int pos = tmp.path.rfind('/'); + size_t pos = tmp.path.rfind('/'); char buf[256]; std::string path = tmp.path; if ( pos != std::string::npos ) @@ -760,8 +785,8 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje Py_INCREF(Py_False); return Py_False; } - int tmp, *dest, - modulation, system, freq, sr, pol, fec; + int tmp, *dest = NULL, + modulation, system, freq, sr, pol, fec, inv, pilot, rolloff; char *end_ptr; const Attribute *at; std::string name; @@ -823,6 +848,9 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje sr = 0; pol = -1; fec = 0; // AUTO default + inv = 2; // AUTO default + pilot = 2; // AUTO default + rolloff = 0; // alpha 0.35 for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it) { // eDebug("\t\tattr: %s", at->name().c_str()); @@ -834,6 +862,9 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje else if (name == "symbol_rate") dest = &sr; else if (name == "polarization") dest = &pol; else if (name == "fec_inner") dest = &fec; + else if (name == "inversion") dest = &inv; + else if (name == "rolloff") dest = &rolloff; + else if (name == "pilot") dest = &pilot; if (dest) { tmp = strtol(at->value().c_str(), &end_ptr, 10); @@ -843,7 +874,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje } if (freq && sr && pol != -1) { - tuple = PyTuple_New(7); + tuple = PyTuple_New(10); PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq)); PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(sr)); @@ -851,6 +882,9 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong(fec)); PyTuple_SET_ITEM(tuple, 5, PyInt_FromLong(system)); PyTuple_SET_ITEM(tuple, 6, PyInt_FromLong(modulation)); + PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong(inv)); + PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong(rolloff)); + PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong(pilot)); PyList_Append(tplist, tuple); Py_DECREF(tuple); } @@ -863,6 +897,8 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje Py_DECREF(sat_pos); if (sat_name) Py_DECREF(sat_name); + if (sat_flags) + Py_DECREF(sat_flags); } } Py_INCREF(Py_True); @@ -1158,10 +1194,15 @@ RESULT eDVBDB::removeServices(eDVBChannelID chid, unsigned int orbpos) if ((unsigned int)sat.orbital_position != orbpos) remove=false; } - else if (orbpos != 0xFFFFFFFF) // do not remove -C or -T transponders when a orbital position is given.. - remove=false; - if ( remove && chid.dvbnamespace != eNs && chid.dvbnamespace != ch.dvbnamespace ) - remove=false; + if ( remove && chid.dvbnamespace != eNs ) + { + if (system == iDVBFrontend::feCable && chid.dvbnamespace.get() == (int)0xFFFF0000) + ; + else if (system == iDVBFrontend::feTerrestrial && chid.dvbnamespace.get() == (int)0xEEEE0000) + ; + else if ( chid.dvbnamespace != ch.dvbnamespace ) + remove=false; + } if ( remove && chid.original_network_id != eOnid && chid.original_network_id != ch.original_network_id ) remove=false; if ( remove && chid.transport_stream_id != eTsid && chid.transport_stream_id != ch.transport_stream_id ) @@ -1196,6 +1237,45 @@ RESULT eDVBDB::removeServices(eDVBChannelID chid, unsigned int orbpos) return ret; } +RESULT eDVBDB::removeServices(iDVBFrontendParameters *feparm) +{ + int ret = -1; + std::set removed_chids; + std::map::iterator it(m_channels.begin()); + while (it != m_channels.end()) + { + int diff; + if (!feparm->calculateDifference(&(*it->second.m_frontendParameters), diff, false)) + { + if (diff < 4000) + { + removed_chids.insert(it->first); + m_channels.erase(it++); + } + else + ++it; + } + else + ++it; + } + if (!removed_chids.empty()) + { + std::map >::iterator service(m_services.begin()); + while(service != m_services.end()) + { + eDVBChannelID chid; + service->first.getChannelID(chid); + std::set::iterator it(removed_chids.find(chid)); + if (it != removed_chids.end()) + m_services.erase(service++); + else + ++service; + } + ret = 0; + } + return ret; +} + RESULT eDVBDB::addFlag(const eServiceReference &ref, unsigned int flagmask) { if (ref.type == eServiceReference::idDVB) @@ -1247,8 +1327,15 @@ RESULT eDVBDB::removeFlags(unsigned int flagmask, eDVBChannelID chid, unsigned i if ((unsigned int)sat.orbital_position != orbpos) remove=false; } - if ( remove && chid.dvbnamespace != eNs && chid.dvbnamespace != ch.dvbnamespace ) - remove=false; + if ( remove && chid.dvbnamespace != eNs ) + { + if (system == iDVBFrontend::feCable && chid.dvbnamespace.get() == (int)0xFFFF0000) + ; + else if (system == iDVBFrontend::feTerrestrial && chid.dvbnamespace.get() == (int)0xEEEE0000) + ; + else if ( chid.dvbnamespace != ch.dvbnamespace ) + remove=false; + } if ( remove && chid.original_network_id != eOnid && chid.original_network_id != ch.original_network_id ) remove=false; if ( remove && chid.transport_stream_id != eTsid && chid.transport_stream_id != ch.transport_stream_id ) @@ -1276,9 +1363,13 @@ RESULT eDVBDB::removeFlags(unsigned int flagmask, eDVBChannelID chid, unsigned i RESULT eDVBDB::addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm) { channel ch; + std::map::iterator it = m_channels.find(id); assert(feparm); ch.m_frontendParameters = feparm; - m_channels.insert(std::pair(id, ch)); + if (it != m_channels.end()) + it->second = ch; + else + m_channels.insert(std::pair(id, ch)); return 0; } @@ -1335,7 +1426,7 @@ RESULT eDVBDB::getBouquet(const eServiceReference &ref, eBouquet* &bouquet) eDebug("getBouquet failed.. no path given!"); return -1; } - unsigned int pos = str.find("FROM BOUQUET \""); + size_t pos = str.find("FROM BOUQUET \""); if ( pos != std::string::npos ) { str.erase(0, pos+14); @@ -1466,14 +1557,20 @@ RESULT eDVBDBQuery::getNextResult(eServiceReferenceDVB &ref) { while (m_cursor != m_db->m_services.end()) { - ref = m_cursor->first; + ePtr service = m_cursor->second; + if (service->isHidden()) + ++m_cursor; + else + { + ref = m_cursor->first; - int res = (!m_query) || m_cursor->second->checkFilter(ref, *m_query); + int res = (!m_query) || service->checkFilter(ref, *m_query); - ++m_cursor; + ++m_cursor; - if (res) - return 0; + if (res) + return 0; + } } ref.type = eServiceReference::idInvalid; @@ -1497,7 +1594,7 @@ RESULT eDVBDBBouquetQuery::getNextResult(eServiceReferenceDVB &ref) std::map >::iterator it = m_db->m_services.find(ref); - int res = (!m_query) || it == m_db->m_services.end() || it->second->checkFilter(ref, *m_query); + int res = (!m_query) || it == m_db->m_services.end() || !(it->second->isHidden() && it->second->checkFilter(ref, *m_query)); ++m_cursor; @@ -1551,7 +1648,7 @@ eDVBDBSatellitesQuery::eDVBDBSatellitesQuery(eDVBDB *db, const eServiceReference for (std::map >::iterator it(m_db->m_services.begin()); it != m_db->m_services.end(); ++it) { - int res = it->second->checkFilter(it->first, *query); + int res = !it->second->isHidden() && it->second->checkFilter(it->first, *query); if (res) { unsigned int dvbnamespace = it->first.getDVBNamespace().get()&0xFFFF0000; @@ -1598,7 +1695,7 @@ eDVBDBProvidersQuery::eDVBDBProvidersQuery(eDVBDB *db, const eServiceReference & for (std::map >::iterator it(m_db->m_services.begin()); it != m_db->m_services.end(); ++it) { - int res = it->second->checkFilter(it->first, *query); + int res = !it->second->isHidden() && it->second->checkFilter(it->first, *query); if (res) { const char *provider_name = it->second->m_provider_name.length() ?