X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/0d34f9703fc13e99c4d76a0ee539d58d39dded2d..db7917f04df76583bb8949283b45e2c4f5c9d48b:/lib/dvb/db.cpp diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 65b42def..eb0721b6 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -107,12 +107,20 @@ err: return -1; } +RESULT eBouquet::setListName(const std::string &name) +{ + m_bouquet_name = name; + return 0; +} + eDVBService::eDVBService() + :m_cache(0), m_flags(0) { } eDVBService::~eDVBService() { + delete [] m_cache; } eDVBService &eDVBService::operator=(const eDVBService &s) @@ -122,7 +130,7 @@ eDVBService &eDVBService::operator=(const eDVBService &s) m_provider_name = s.m_provider_name; m_flags = s.m_flags; m_ca = s.m_ca; - m_cache = s.m_cache; + copyCache(s.m_cache); return *this; } @@ -187,7 +195,10 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ res = 0; break; case eDVBChannelQuery::tSatellitePosition: - res = (ref.getDVBNamespace().get() >> 16) == query.m_int; + res = ((unsigned int)ref.getDVBNamespace().get())>>16 == (unsigned int)query.m_int; + break; + case eDVBChannelQuery::tFlags: + res = (m_flags & query.m_int) == query.m_int; break; case eDVBChannelQuery::tChannelID: { @@ -202,6 +213,9 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ case eDVBChannelQuery::tOR: res = checkFilter(ref, *query.m_p1) || checkFilter(ref, *query.m_p2); break; + case eDVBChannelQuery::tAny: + res = 1; + break; } if (query.m_inverse) @@ -210,23 +224,55 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ return res; } -int eDVBService::getCachePID(cacheID id) +bool eDVBService::cacheEmpty() { - std::map::iterator it = m_cache.find(id); - if ( it != m_cache.end() ) - return it->second; - return -1; + if (m_cache) + for (int i=0; i < cacheMax; ++i) + if (m_cache[i] != -1) + return false; + return true; +} + +void eDVBService::initCache() +{ + m_cache = new int[cacheMax]; + memset(m_cache, -1, sizeof(int) * cacheMax); +} + +void eDVBService::copyCache(int *source) +{ + if (source) + { + if (!m_cache) + m_cache = new int[cacheMax]; + memcpy(m_cache, source, cacheMax * sizeof(int)); + } + else + { + delete [] m_cache; + m_cache = 0; + } +} + +int eDVBService::getCacheEntry(cacheID id) +{ + if (id >= cacheMax || !m_cache) + return -1; + return m_cache[id]; } -void eDVBService::setCachePID(cacheID id, int pid) +void eDVBService::setCacheEntry(cacheID id, int pid) { - m_cache[id] = pid; + if (!m_cache) + initCache(); + if (id < cacheMax) + m_cache[id] = pid; } DEFINE_REF(eDVBDB); /* THIS CODE IS BAD. it should be replaced by somethine better. */ -void eDVBDB::load() +void eDVBDB::reloadServicelist() { eDebug("---- opening lame channel db"); FILE *f=fopen(CONFIGDIR"/enigma2/lamedb", "rt"); @@ -235,8 +281,11 @@ void eDVBDB::load() struct stat s; if ( !stat("lamedb", &s) ) { - rename("lamedb", CONFIGDIR"/enigma2/lamedb" ); - load(); + if ( !stat(CONFIGDIR"/enigma2", &s) ) + { + rename("lamedb", CONFIGDIR"/enigma2/lamedb" ); + reloadServicelist(); + } } return; } @@ -281,8 +330,11 @@ void eDVBDB::load() if (line[1]=='s') { eDVBFrontendParametersSatellite sat; - int frequency, symbol_rate, polarisation, fec, orbital_position, inversion; - sscanf(line+2, "%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion); + int frequency, symbol_rate, polarisation, fec, orbital_position, inversion, + system=eDVBFrontendParametersSatellite::System::DVB_S, + modulation=eDVBFrontendParametersSatellite::Modulation::QPSK, + rolloff=eDVBFrontendParametersSatellite::RollOff::alpha_auto; + sscanf(line+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &system, &modulation, &rolloff); sat.frequency = frequency; sat.symbol_rate = symbol_rate; sat.polarisation = polarisation; @@ -290,6 +342,9 @@ void eDVBDB::load() sat.orbital_position = orbital_position < 0 ? orbital_position + 3600 : orbital_position; sat.inversion = inversion; + sat.system = system; + sat.modulation = modulation; + sat.roll_off = rolloff; feparm->setDVBS(sat); } else if (line[1]=='t') { @@ -305,13 +360,21 @@ void eDVBDB::load() ter.guard_interval = guard_interval; ter.hierarchy = hierarchy; ter.inversion = inversion; - feparm->setDVBT(ter); } else if (line[1]=='c') { - int frequency, symbol_rate, inversion=0, modulation=3; - sscanf(line+2, "%d:%d:%d:%d", &frequency, &symbol_rate, &inversion, &modulation); -// t.setCable(frequency, symbol_rate, inversion, modulation); + eDVBFrontendParametersCable cab; + int frequency, symbol_rate, + inversion=eDVBFrontendParametersCable::Inversion::Unknown, + modulation=eDVBFrontendParametersCable::Modulation::Auto, + fec_inner=eDVBFrontendParametersCable::FEC::fAuto; + sscanf(line+2, "%d:%d:%d:%d:%d", &frequency, &symbol_rate, &inversion, &modulation, &fec_inner); + cab.frequency = frequency; + cab.fec_inner = fec_inner; + cab.inversion = inversion; + cab.symbol_rate = symbol_rate; + cab.modulation = modulation; + feparm->setDVBC(cab); } } addChannelToList(channelid, feparm); @@ -357,7 +420,6 @@ void eDVBDB::load() fgets(line, 256, f); if (strlen(line)) line[strlen(line)-1]=0; - std::string str=line; if (str[1]!=':') // old ... (only service_provider) @@ -388,12 +450,12 @@ void eDVBDB::load() { int cid, val; sscanf(v.c_str(), "%02d%04x", &cid, &val); - s->m_cache[cid]=val; + s->setCacheEntry((eDVBService::cacheID)cid,val); } else if (p == 'C') { int val; sscanf(v.c_str(), "%04x", &val); - s->m_ca.insert(val); + s->m_ca.push_front((uint16_t)val); } } addService(ref, s); @@ -404,7 +466,7 @@ void eDVBDB::load() fclose(f); } -void eDVBDB::save() +void eDVBDB::saveServicelist() { eDebug("---- saving lame channel db"); FILE *f=fopen(CONFIGDIR"/enigma2/lamedb", "w"); @@ -423,13 +485,28 @@ void eDVBDB::save() chid.transport_stream_id.get(), chid.original_network_id.get()); eDVBFrontendParametersSatellite sat; eDVBFrontendParametersTerrestrial ter; + eDVBFrontendParametersCable cab; if (!ch.m_frontendParameters->getDVBS(sat)) { - fprintf(f, "\ts %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); + if (sat.system == eDVBFrontendParametersSatellite::System::DVB_S2) + { + fprintf(f, "\ts %d:%d:%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.system, + sat.modulation, + sat.roll_off); + } + else + { + fprintf(f, "\ts %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); + } } if (!ch.m_frontendParameters->getDVBT(ter)) { @@ -438,6 +515,11 @@ void eDVBDB::save() ter.code_rate_LP, ter.modulation, ter.transmission_mode, ter.guard_interval, ter.hierarchy, ter.inversion); } + 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, "/\n"); channels++; } @@ -454,18 +536,25 @@ void eDVBDB::save() 0); fprintf(f, "%s\n", i->second->m_service_name.c_str()); + fprintf(f, "p:%s", i->second->m_provider_name.c_str()); // write cached pids - for (std::map::const_iterator ca(i->second->m_cache.begin()); - ca != i->second->m_cache.end(); ++ca) - fprintf(f, ",c:%02d%04x", ca->first, ca->second); + for (int x=0; x < eDVBService::cacheMax; ++x) + { + int entry = i->second->getCacheEntry((eDVBService::cacheID)x); + if (entry != -1) + fprintf(f, ",c:%02d%04x", x, entry); + } // write cached ca pids - for (std::set::const_iterator ca(i->second->m_ca.begin()); + for (CAID_LIST::const_iterator ca(i->second->m_ca.begin()); ca != i->second->m_ca.end(); ++ca) fprintf(f, ",C:%04x", *ca); + if (i->second->m_flags) + fprintf(f, ",f:%x", i->second->m_flags); + fprintf(f, "\n"); services++; } @@ -581,8 +670,9 @@ void eDVBDB::loadBouquet(const char *path) eDebug("%d entries in Bouquet %s", entries, bouquet_name.c_str()); } -void eDVBDB::loadBouquets() +void eDVBDB::reloadBouquets() { + m_bouquets.clear(); loadBouquet("bouquets.tv"); loadBouquet("bouquets.radio"); // create default bouquets when missing @@ -612,7 +702,7 @@ void eDVBDB::loadBouquets() memset(ref.data, 0, sizeof(ref.data)); ref.type=1; ref.flags=7; - ref.data[0]=1; + ref.data[0]=2; ref.path="(type == 2) FROM BOUQUET \"userbouquet.favourites.radio\" ORDER BY bouquet"; eBouquet &parent = m_bouquets["bouquets.radio"]; parent.m_services.push_back(ref); @@ -620,15 +710,171 @@ void eDVBDB::loadBouquets() } } +eDVBDB *eDVBDB::instance; + eDVBDB::eDVBDB() { - load(); - loadBouquets(); + instance = this; + reloadServicelist(); } eDVBDB::~eDVBDB() { -// save(); + instance=NULL; +} + +RESULT eDVBDB::removeService(const eServiceReference &ref) +{ + if (ref.type == eServiceReference::idDVB) + { + eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref; + std::map >::iterator it(m_services.find(service)); + if (it != m_services.end()) + { + m_services.erase(it); + return 0; + } + } + return -1; +} + +RESULT eDVBDB::removeServices(int dvb_namespace, int tsid, int onid, unsigned int orb_pos) +{ + return removeServices(eDVBChannelID(eDVBNamespace(dvb_namespace), eTransportStreamID(tsid), eOriginalNetworkID(onid)), orb_pos); +} + +RESULT eDVBDB::removeServices(eDVBChannelID chid, unsigned int orbpos) +{ + RESULT ret=-1; + eDVBNamespace eNs; + eTransportStreamID eTsid; + eOriginalNetworkID eOnid; + std::map::iterator it(m_channels.begin()); + std::set removed_chids; + while (it != m_channels.end()) + { + const eDVBChannelID &ch = it->first; + bool remove=true; + int system; + it->second.m_frontendParameters->getSystem(system); + if ( orbpos != 0xFFFFFFFF && system == iDVBFrontend::feSatellite ) + { + eDVBFrontendParametersSatellite sat; + it->second.m_frontendParameters->getDVBS(sat); + if ((unsigned int)sat.orbital_position != orbpos) + remove=false; + } + if ( remove && chid.dvbnamespace != eNs && 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 ) + remove=false; + if ( remove ) + { + eDebug("remove %08x %04x %04x", + ch.dvbnamespace.get(), + ch.original_network_id.get(), + ch.transport_stream_id.get()); + removed_chids.insert(it->first); + m_channels.erase(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) + { + eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref; + std::map >::iterator it(m_services.find(service)); + if (it != m_services.end()) + it->second->m_flags |= ~flagmask; + return 0; + } + return -1; +} + +RESULT eDVBDB::removeFlag(const eServiceReference &ref, unsigned int flagmask) +{ + if (ref.type == eServiceReference::idDVB) + { + eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref; + std::map >::iterator it(m_services.find(service)); + if (it != m_services.end()) + it->second->m_flags &= ~flagmask; + return 0; + } + return -1; +} + +RESULT eDVBDB::removeFlags(unsigned int flagmask, int dvb_namespace, int tsid, int onid, unsigned int orb_pos) +{ + return removeFlags(flagmask, eDVBChannelID(eDVBNamespace(dvb_namespace), eTransportStreamID(tsid), eOriginalNetworkID(onid)), orb_pos); +} + +RESULT eDVBDB::removeFlags(unsigned int flagmask, eDVBChannelID chid, unsigned int orbpos) +{ + eDVBNamespace eNs; + eTransportStreamID eTsid; + eOriginalNetworkID eOnid; + std::map::iterator it(m_channels.begin()); + std::set removed_chids; + while (it != m_channels.end()) + { + const eDVBChannelID &ch = it->first; + bool remove=true; + int system; + it->second.m_frontendParameters->getSystem(system); + if ( orbpos != 0xFFFFFFFF && system == iDVBFrontend::feSatellite ) + { + eDVBFrontendParametersSatellite sat; + it->second.m_frontendParameters->getDVBS(sat); + if ((unsigned int)sat.orbital_position != orbpos) + remove=false; + } + if ( remove && chid.dvbnamespace != eNs && 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 ) + remove=false; + if ( remove ) + removed_chids.insert(it->first); + ++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()) + service->second->m_flags &= ~flagmask; + ++service; + } + } + return 0; } RESULT eDVBDB::addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm) @@ -660,7 +906,9 @@ RESULT eDVBDB::getChannelFrontendData(const eDVBChannelID &id, ePtr >(serviceref, service)); + std::map >::iterator it(m_services.find(serviceref)); + if (it == m_services.end()) + m_services.insert(std::pair >(serviceref, service)); return 0; } @@ -679,7 +927,7 @@ RESULT eDVBDB::getService(const eServiceReferenceDVB &reference, ePtr &query, eDVBChannelQuery *q return 0; } +eServiceReference eDVBDB::searchReference(int tsid, int onid, int sid) +{ + eServiceID Sid(sid); + eTransportStreamID Tsid(tsid); + eOriginalNetworkID Onid(onid); + for (std::map >::iterator sit(m_services.begin()); + sit != m_services.end(); ++sit) + { + if (sit->first.getTransportStreamID() == Tsid && + sit->first.getOriginalNetworkID() == Onid && + sit->first.getServiceID() == Sid) + return sit->first; + } + return eServiceReference(); +} + DEFINE_REF(eDVBDBQueryBase); eDVBDBQueryBase::eDVBDBQueryBase(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query) @@ -881,8 +1145,8 @@ eDVBDBSatellitesQuery::eDVBDBSatellitesQuery(eDVBDB *db, const eServiceReference eServiceReferenceDVB ref; ref.setDVBNamespace(dvbnamespace); ref.flags=eServiceReference::flagDirectory; - char buf[64]; - snprintf(buf, 64, "(satellitePosition == %d) && ", dvbnamespace>>16); + char buf[128]; + snprintf(buf, 128, "(satellitePosition == %d) && ", dvbnamespace>>16); ref.path=buf+source.path; unsigned int pos=ref.path.find("FROM"); @@ -895,6 +1159,14 @@ eDVBDBSatellitesQuery::eDVBDBSatellitesQuery(eDVBDB *db, const eServiceReference pos=ref.path.find("FROM"); ref.path.erase(pos+5); ref.path+="PROVIDERS ORDER BY name"; +// eDebug("ref.path now %s", ref.path.c_str()); + m_list.push_back(ref); + + snprintf(buf, 128, "(satellitePosition == %d) && (flags == %d) && ", dvbnamespace>>16, eDVBService::dxNewFound); + ref.path=buf+source.path; + pos=ref.path.find("FROM"); + ref.path.erase(pos); + ref.path+="ORDER BY name"; // eDebug("ref.path now %s", ref.path.c_str()); m_list.push_back(ref); } @@ -959,6 +1231,8 @@ static int decodeType(const std::string &type) return eDVBChannelQuery::tSatellitePosition; else if (type == "channelID") return eDVBChannelQuery::tChannelID; + else if (type == "flags") + return eDVBChannelQuery::tFlags; else return -1; } @@ -967,6 +1241,13 @@ static int decodeType(const std::string &type) RESULT parseExpression(ePtr &res, std::list::const_iterator begin, std::list::const_iterator end) { std::list::const_iterator end_of_exp; + + if (begin == end) + { + eDebug("empty expression!"); + return 0; + } + if (*begin == "(") { end_of_exp = begin; @@ -1183,6 +1464,14 @@ RESULT eDVBChannelQuery::compile(ePtr &res, std::string query) /* now we recursivly parse that. */ int r = parseExpression(res, tokens.begin(), tokens.end()); + /* we have an empty (but valid!) expression */ + if (!r && !res) + { + res = new eDVBChannelQuery(); + res->m_inverse = 0; + res->m_type = eDVBChannelQuery::tAny; + } + if (res) { res->m_sort = sort;