3 #include <lib/dvb/db.h>
4 #include <lib/dvb/dvb.h>
5 #include <lib/dvb/frontend.h>
6 #include <lib/dvb/epgcache.h>
7 #include <lib/base/cfile.h>
8 #include <lib/base/eenv.h>
9 #include <lib/base/eerror.h>
10 #include <lib/base/estring.h>
11 #include <lib/base/nconfig.h>
12 #include <xmlccwrap/xmlccwrap.h>
13 #include <dvbsi++/service_description_section.h>
14 #include <dvbsi++/descriptor_tag.h>
15 #include <dvbsi++/service_descriptor.h>
16 #include <dvbsi++/satellite_delivery_system_descriptor.h>
19 DEFINE_REF(eDVBService);
21 RESULT eBouquet::addService(const eServiceReference &ref, eServiceReference before)
24 std::find(m_services.begin(), m_services.end(), ref);
25 if ( it != m_services.end() )
29 it = std::find(m_services.begin(), m_services.end(), before);
30 m_services.insert(it, ref);
33 m_services.push_back(ref);
34 eDVBDB::getInstance()->renumberBouquet();
38 RESULT eBouquet::removeService(const eServiceReference &ref, bool renameBouquet)
41 std::find(m_services.begin(), m_services.end(), ref);
42 if ( it == m_services.end() )
44 if (renameBouquet && (ref.flags & eServiceReference::canDescent))
46 std::string filename = ref.toString();
47 size_t pos = filename.find("FROM BOUQUET ");
48 if(pos != std::string::npos)
50 char endchr = filename[pos+13];
53 char *beg = &filename[pos+14];
54 char *end = strchr(beg, endchr);
55 filename.assign(beg, end - beg);
56 filename = eEnv::resolve("${sysconfdir}/enigma2/" + filename);
57 std::string newfilename(filename);
58 newfilename.append(".del");
59 eDebug("[eBouquet] Rename bouquet file %s to %s", filename.c_str(), newfilename.c_str());
60 rename(filename.c_str(), newfilename.c_str());
65 eDVBDB::getInstance()->renumberBouquet();
69 RESULT eBouquet::moveService(const eServiceReference &ref, unsigned int pos)
71 if ( pos < 0 || pos >= m_services.size() )
74 list::iterator source=m_services.end();
75 list::iterator dest=m_services.end();
77 for (list::iterator it(m_services.begin()); it != m_services.end(); ++it)
79 if (dest == m_services.end() && !--pos)
86 if (dest != m_services.end() && source != m_services.end())
89 if (dest == m_services.end() || source == m_services.end() || source == dest)
91 while (source != dest)
94 std::iter_swap(source++, source);
96 std::iter_swap(source--, source);
98 eDVBDB::getInstance()->renumberBouquet();
102 RESULT eBouquet::flushChanges()
104 std::string filename = eEnv::resolve("${sysconfdir}/enigma2/" + m_filename);
106 CFile f((filename + ".writing").c_str(), "w");
109 if ( fprintf(f, "#NAME %s\r\n", m_bouquet_name.c_str()) < 0 )
111 for (list::iterator i(m_services.begin()); i != m_services.end(); ++i)
113 eServiceReference tmp = *i;
114 std::string str = tmp.path;
115 if ( fprintf(f, "#SERVICE %s\r\n", tmp.toString().c_str()) < 0 )
117 if ( i->name.length() )
118 if ( fprintf(f, "#DESCRIPTION %s\r\n", i->name.c_str()) < 0 )
123 rename((filename + ".writing").c_str(), filename.c_str());
126 eDebug("[eBouquet] couldn't write file %s", m_filename.c_str());
130 RESULT eBouquet::setListName(const std::string &name)
132 m_bouquet_name = name;
136 eDVBService::eDVBService()
137 :m_cache(0), m_flags(0)
141 eDVBService::~eDVBService()
146 eDVBService &eDVBService::operator=(const eDVBService &s)
148 m_service_name = s.m_service_name;
149 m_service_name_sort = s.m_service_name_sort;
150 m_provider_name = s.m_provider_name;
153 copyCache(s.m_cache);
157 void eDVBService::genSortName()
159 size_t start = m_service_name.find_first_not_of(' ');
160 if (start != std::string::npos)
162 /* strip leading spaces */
163 m_service_name_sort = m_service_name.substr(start);
165 m_service_name_sort = removeDVBChars(m_service_name_sort);
166 /* convert to uppercase */
167 makeUpper(m_service_name_sort);
170 if (m_service_name_sort.empty())
172 /* put unnamed services at the end, not at the beginning. */
173 m_service_name_sort = "\xFF";
177 RESULT eDVBService::getName(const eServiceReference &ref, std::string &name)
179 if (!ref.name.empty())
180 name = ref.name; // use renamed service name..
181 else if (!m_service_name.empty())
182 name = m_service_name;
188 RESULT eDVBService::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time)
190 return eEPGCache::getInstance()->lookupEventTime(ref, start_time, ptr);
193 bool eDVBService::isCrypted()
195 return m_ca.size() > 0;
198 int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
200 ePtr<eDVBResourceManager> res_mgr;
201 bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false);
203 if (eDVBResourceManager::getInstance(res_mgr))
204 eDebug("[eDVBService] isPlayble... no res manager!!");
207 eDVBChannelID chid, chid_ignore;
210 ((const eServiceReferenceDVB&)ref).getChannelID(chid);
211 ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
213 if (res_mgr->canAllocateChannel(chid, chid_ignore, system, simulate))
216 if (remote_fallback_enabled)
223 int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query)
226 switch (query.m_type)
228 case eDVBChannelQuery::tName:
230 res = m_service_name_sort == query.m_string;
233 case eDVBChannelQuery::tProvider:
235 if (query.m_string == "Unknown" && m_provider_name.empty())
238 res = m_provider_name == query.m_string;
241 case eDVBChannelQuery::tType:
243 int service_type = ref.getServiceType();
244 if (query.m_int == 1) // TV Service
246 // Hack for dish network
247 int onid = ref.getOriginalNetworkID().get();
248 if (onid >= 0x1001 && onid <= 0x100b)
250 static int dish_tv_types[] = { 128, 133, 137, 140, 144, 145, 150, 154, 163, 164, 165, 166, 167, 168, 173, 174 };
251 static size_t dish_tv_num_types = sizeof(dish_tv_types) / sizeof(int);
252 if (std::binary_search(dish_tv_types, dish_tv_types + dish_tv_num_types, service_type))
256 res = service_type == query.m_int;
259 case eDVBChannelQuery::tBouquet:
264 case eDVBChannelQuery::tSatellitePosition:
266 res = ((unsigned int)ref.getDVBNamespace().get())>>16 == (unsigned int)query.m_int;
269 case eDVBChannelQuery::tFlags:
271 res = (m_flags & query.m_int) == query.m_int;
274 case eDVBChannelQuery::tChannelID:
277 ref.getChannelID(chid);
278 res = chid == query.m_channelid;
281 case eDVBChannelQuery::tAND:
283 res = checkFilter(ref, *query.m_p1) && checkFilter(ref, *query.m_p2);
286 case eDVBChannelQuery::tOR:
288 res = checkFilter(ref, *query.m_p1) || checkFilter(ref, *query.m_p2);
291 case eDVBChannelQuery::tAny:
304 bool eDVBService::cacheEmpty()
307 for (int i=0; i < cacheMax; ++i)
308 if (m_cache[i] != -1)
313 void eDVBService::initCache()
315 m_cache = new int[cacheMax];
316 memset(m_cache, -1, sizeof(int) * cacheMax);
319 void eDVBService::copyCache(int *source)
324 m_cache = new int[cacheMax];
325 memcpy(m_cache, source, cacheMax * sizeof(int));
334 int eDVBService::getCacheEntry(cacheID id)
336 if (id >= cacheMax || !m_cache)
341 void eDVBService::setCacheEntry(cacheID id, int pid)
351 void eDVBDB::reloadServicelist()
353 loadServicelist(eEnv::resolve("${sysconfdir}/enigma2/lamedb").c_str());
356 void eDVBDB::parseServiceData(ePtr<eDVBService> s, std::string str)
358 while ((!str.empty()) && str[1]==':') // new: p:, f:, c:%02d...
360 size_t c=str.find(',');
363 if (c == std::string::npos)
369 v=str.substr(2, c-2);
372 // eDebug("[eDVBDB] %c ... %s", p, v.c_str());
374 s->m_provider_name=v;
377 sscanf(v.c_str(), "%x", &s->m_flags);
381 sscanf(v.c_str(), "%02d%x", &cid, &val);
382 s->setCacheEntry((eDVBService::cacheID)cid,val);
386 sscanf(v.c_str(), "%04x", &val);
387 s->m_ca.push_back((uint16_t)val);
392 static ePtr<eDVBFrontendParameters> parseFrontendData(const char* line, int version)
398 eDVBFrontendParametersSatellite sat;
399 int frequency, symbol_rate, polarisation, fec, orbital_position, inversion,
401 system=eDVBFrontendParametersSatellite::System_DVB_S,
402 modulation=eDVBFrontendParametersSatellite::Modulation_QPSK,
403 rolloff=eDVBFrontendParametersSatellite::RollOff_alpha_0_35,
404 pilot=eDVBFrontendParametersSatellite::Pilot_Unknown;
406 sscanf(line+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
407 &frequency, &symbol_rate, &polarisation, &fec, &orbital_position,
408 &inversion, &system, &modulation, &rolloff, &pilot);
410 sscanf(line+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
411 &frequency, &symbol_rate, &polarisation, &fec, &orbital_position,
412 &inversion, &flags, &system, &modulation, &rolloff, &pilot);
413 sat.frequency = frequency;
414 sat.symbol_rate = symbol_rate;
415 sat.polarisation = polarisation;
417 sat.orbital_position = orbital_position < 0 ? orbital_position + 3600 : orbital_position;
418 sat.inversion = inversion;
420 sat.modulation = modulation;
421 sat.rolloff = rolloff;
423 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
424 feparm->setDVBS(sat);
425 feparm->setFlags(flags);
430 eDVBFrontendParametersTerrestrial ter;
431 int frequency, bandwidth, code_rate_HP, code_rate_LP, modulation, transmission_mode,
432 guard_interval, hierarchy, inversion, flags = 0, plpid = 0;
433 int system = eDVBFrontendParametersTerrestrial::System_DVB_T;
434 sscanf(line+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
435 &frequency, &bandwidth, &code_rate_HP, &code_rate_LP, &modulation,
436 &transmission_mode, &guard_interval, &hierarchy, &inversion, &flags, &system, &plpid);
437 ter.frequency = frequency;
440 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: ter.bandwidth = 8000000; break;
441 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: ter.bandwidth = 7000000; break;
442 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: ter.bandwidth = 6000000; break;
444 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: ter.bandwidth = 0; break;
445 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: ter.bandwidth = 5000000; break;
446 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: ter.bandwidth = 1712000; break;
447 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: ter.bandwidth = 10000000; break;
449 ter.code_rate_HP = code_rate_HP;
450 ter.code_rate_LP = code_rate_LP;
451 ter.modulation = modulation;
452 ter.transmission_mode = transmission_mode;
453 ter.guard_interval = guard_interval;
454 ter.hierarchy = hierarchy;
455 ter.inversion = inversion;
458 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
459 feparm->setDVBT(ter);
460 feparm->setFlags(flags);
465 eDVBFrontendParametersCable cab;
466 int frequency, symbol_rate,
467 inversion=eDVBFrontendParametersCable::Inversion_Unknown,
468 modulation=eDVBFrontendParametersCable::Modulation_Auto,
469 fec_inner=eDVBFrontendParametersCable::FEC_Auto,
470 system = eDVBFrontendParametersCable::System_DVB_C_ANNEX_A,
472 sscanf(line+2, "%d:%d:%d:%d:%d:%d:%d",
473 &frequency, &symbol_rate, &inversion, &modulation, &fec_inner, &flags, &system);
474 cab.frequency = frequency;
475 cab.fec_inner = fec_inner;
476 cab.inversion = inversion;
477 cab.symbol_rate = symbol_rate;
478 cab.modulation = modulation;
480 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
481 feparm->setDVBC(cab);
482 feparm->setFlags(flags);
490 static eDVBChannelID parseChannelData(const char * line)
492 int dvb_namespace = -1, transport_stream_id = -1, original_network_id = -1;
493 sscanf(line, "%x:%x:%x", &dvb_namespace, &transport_stream_id, &original_network_id);
494 if (original_network_id == -1)
495 return eDVBChannelID();
496 return eDVBChannelID(
497 eDVBNamespace(dvb_namespace),
498 eTransportStreamID(transport_stream_id),
499 eOriginalNetworkID(original_network_id));
502 static eServiceReferenceDVB parseServiceRefData(const char *line)
504 int service_id = -1, dvb_namespace, transport_stream_id = -1, original_network_id = -1,
505 service_type = -1, service_number = -1;
506 sscanf(line, "%x:%x:%x:%x:%d:%d", &service_id, &dvb_namespace, &transport_stream_id,
507 &original_network_id, &service_type, &service_number);
508 if (service_number == -1)
509 return eServiceReferenceDVB();
510 return eServiceReferenceDVB(
511 eDVBNamespace(dvb_namespace),
512 eTransportStreamID(transport_stream_id),
513 eOriginalNetworkID(original_network_id),
514 eServiceID(service_id),
518 void eDVBDB::loadServicelist(const char *file)
520 eDebug("[eDVBDB] ---- opening lame channel db");
523 eDebug("[eDVBDB] can't open %s: %m", file);
529 if ((!fgets(line, sizeof(line), f)) || sscanf(line, "eDVB services /%d/", &version) != 1)
531 eDebug("[eDVBDB] not a valid servicefile");
534 eDebug("[eDVBDB] reading services (version %d)", version);
536 if ((!fgets(line, sizeof(line), f)) || strcmp(line, "transponders\n"))
538 eDebug("[eDVBDB] services invalid, no transponders");
541 // clear all transponders
545 if (!fgets(line, sizeof(line), f) || !strcmp(line, "end\n"))
548 eDVBChannelID channelid = parseChannelData(line);
552 if (!fgets(line, sizeof(line), f))
554 ePtr<eDVBFrontendParameters> feparm = parseFrontendData(line + 1, version);
556 addChannelToList(channelid, feparm);
559 if (!fgets(line, sizeof(line), f) || strcmp(line, "/\n"))
563 if ((!fgets(line, sizeof(line), f)) || strcmp(line, "services\n"))
565 eDebug("[eDVBDB] services invalid, no services");
568 // clear all services
573 if (!fgets(line, sizeof(line), f) || !strcmp(line, "end\n"))
576 eServiceReferenceDVB ref = parseServiceRefData(line);
579 if (!fgets(line, sizeof(line), f))
581 len = strlen(line); /* strip newline */
582 if (len > 0 && line[len - 1 ] == '\n')
583 line[len - 1] = '\0';
584 ePtr<eDVBService> s = new eDVBService;
585 s->m_service_name = line;
588 if (!fgets(line, sizeof(line), f))
590 len = strlen(line); /* strip newline */
591 if (len > 0 && line[len - 1 ] == '\n')
592 line[len - 1] = '\0';
593 if (line[1] != ':') // old ... (only service_provider)
594 s->m_provider_name = line;
596 parseServiceData(s, line);
601 eDebug("[eDVBDB] loaded %d channels/transponders and %d services", tcount, scount);
604 void eDVBDB::saveServicelist(const char *file)
606 eDebug("[eDVBDB] ---- saving lame channel db");
607 std::string filename = file;
609 CFile f((filename + ".writing").c_str(), "w");
610 int channels=0, services=0;
612 eFatal("[eDVBDB] couldn't save lame channel db!");
613 fprintf(f, "eDVB services /4/\n");
614 fprintf(f, "transponders\n");
615 for (std::map<eDVBChannelID, channel>::const_iterator i(m_channels.begin());
616 i != m_channels.end(); ++i)
618 const eDVBChannelID &chid = i->first;
619 const channel &ch = i->second;
621 fprintf(f, "%08x:%04x:%04x\n", chid.dvbnamespace.get(),
622 chid.transport_stream_id.get(), chid.original_network_id.get());
623 eDVBFrontendParametersSatellite sat;
624 eDVBFrontendParametersTerrestrial ter;
625 eDVBFrontendParametersCable cab;
626 unsigned int flags; // flagOnlyFree yet..
627 ch.m_frontendParameters->getFlags(flags);
628 if (!ch.m_frontendParameters->getDVBS(sat))
630 if (sat.system == eDVBFrontendParametersSatellite::System_DVB_S2)
632 fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
633 sat.frequency, sat.symbol_rate,
634 sat.polarisation, sat.fec,
635 sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
645 fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d\n",
646 sat.frequency, sat.symbol_rate,
647 sat.polarisation, sat.fec,
648 sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
649 sat.inversion, flags);
652 else if (!ch.m_frontendParameters->getDVBT(ter))
655 switch (ter.bandwidth)
657 case 8000000: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
658 case 7000000: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
659 case 6000000: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
661 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
662 case 5000000: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
663 case 1712000: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
664 case 10000000: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
666 if (ter.system == eDVBFrontendParametersTerrestrial::System_DVB_T_T2)
669 * System_DVB_T_T2 (T with fallback to T2) is used only when 'system' is not (yet) specified.
670 * When storing a transponder with 'system' still equalling System_DVB_T_T2,
671 * there has been no fallback to T2 (in which case 'system' would have been set to
673 * So we are dealing with a T transponder, store it with System_DVB_T.
674 * (fallback to T2 is only used while scanning, System_DVB_T_T2 should never be used for actual
675 * transponders in the lamedb)
677 ter.system = eDVBFrontendParametersTerrestrial::System_DVB_T;
679 fprintf(f, "\tt %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
680 ter.frequency, bandwidth, ter.code_rate_HP,
681 ter.code_rate_LP, ter.modulation, ter.transmission_mode,
682 ter.guard_interval, ter.hierarchy, ter.inversion, flags, ter.system, ter.plpid);
684 else if (!ch.m_frontendParameters->getDVBC(cab))
686 fprintf(f, "\tc %d:%d:%d:%d:%d:%d:%d\n",
687 cab.frequency, cab.symbol_rate, cab.inversion, cab.modulation, cab.fec_inner, flags, cab.system);
692 fprintf(f, "end\nservices\n");
694 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator i(m_services.begin());
695 i != m_services.end(); ++i)
697 const eServiceReferenceDVB &s = i->first;
698 fprintf(f, "%04x:%08x:%04x:%04x:%d:%d\n",
699 s.getServiceID().get(), s.getDVBNamespace().get(),
700 s.getTransportStreamID().get(),s.getOriginalNetworkID().get(),
704 fprintf(f, "%s\n", i->second->m_service_name.c_str());
706 fprintf(f, "p:%s", i->second->m_provider_name.c_str());
709 for (int x=0; x < eDVBService::cacheMax; ++x)
711 int entry = i->second->getCacheEntry((eDVBService::cacheID)x);
713 fprintf(f, ",c:%02d%04x", x, entry);
716 // write cached ca pids
717 for (CAID_LIST::const_iterator ca(i->second->m_ca.begin());
718 ca != i->second->m_ca.end(); ++ca)
719 fprintf(f, ",C:%04x", *ca);
721 if (i->second->m_flags)
722 fprintf(f, ",f:%x", i->second->m_flags);
727 fprintf(f, "end\nHave a lot of bugs!\n");
728 eDebug("[eDVBDB] saved %d channels and %d services!", channels, services);
731 rename((filename + ".writing").c_str(), filename.c_str());
734 void eDVBDB::saveServicelist()
736 saveServicelist(eEnv::resolve("${sysconfdir}/enigma2/lamedb").c_str());
739 void eDVBDB::loadBouquet(const char *path)
741 std::vector<std::string> userbouquetsfiles;
742 std::string extension;
743 if (!strcmp(path, "bouquets.tv"))
745 if (!strcmp(path, "bouquets.radio"))
746 extension = ".radio";
747 if (extension.length())
749 std::string p = eEnv::resolve("${sysconfdir}/enigma2/");
750 DIR *dir = opendir(p.c_str());
753 eDebug("[eDVBDB] Cannot open directory where the userbouquets should be expected..");
757 while((entry = readdir(dir)) != NULL)
758 if (entry->d_type == DT_REG)
760 std::string filename = entry->d_name;
761 if (filename.find("userbouquet") != std::string::npos && filename.find(extension, (filename.length() - extension.size())) != std::string::npos)
762 userbouquetsfiles.push_back(filename);
766 std::string bouquet_name = path;
767 if (!bouquet_name.length())
769 eDebug("[eDVBDB] Bouquet load failed.. no path given..");
772 size_t pos = bouquet_name.rfind('/');
773 if ( pos != std::string::npos )
774 bouquet_name.erase(0, pos+1);
775 if (bouquet_name.empty())
777 eDebug("[eDVBDB] Bouquet load failed.. no filename given..");
780 eBouquet &bouquet = m_bouquets[bouquet_name];
781 bouquet.m_filename = bouquet_name;
782 std::list<eServiceReference> &list = bouquet.m_services;
786 std::string enigma_conf = eEnv::resolve("${sysconfdir}/enigma2/");
787 std::string file_path;
790 static const char *const searchpath[] = { "alternatives", "bouquets", "", 0 };
792 for(int index = 0; searchpath[index]; index++)
794 file_path = enigma_conf + searchpath[index] + "/" + path;
796 if (!access(file_path.c_str(), R_OK))
805 eDebug("[eDVBDB] can't open %s: %m", (enigma_conf + ".../" + path).c_str());
806 if (!strcmp(path, "bouquets.tv"))
808 file_path = enigma_conf + path;
810 eDebug("[eDVBDB] recreate bouquets.tv");
811 bouquet.m_bouquet_name="Bouquets (TV)";
812 bouquet.flushChanges();
816 if (!strcmp(path, "bouquets.radio"))
818 file_path = enigma_conf + path;
820 eDebug("[eDVBDB] recreate bouquets.radio");
821 bouquet.m_bouquet_name="Bouquets (Radio)";
822 bouquet.flushChanges();
829 eDebug("[eDVBDB] loading bouquet... %s", file_path.c_str());
830 CFile fp(file_path, "rt");
834 size_t linesize = 256;
835 char *line = (char*)malloc(linesize);
836 bool read_descr=false;
837 eServiceReference *e = NULL;
841 if ((len = getline(&line, &linesize, fp)) < 2) break;
844 /* strip carriage return (when found) */
845 if (line[len - 1] == '\r') line[--len] = 0;
846 if (!strncmp(line, "#SERVICE", 8))
848 int offs = line[8] == ':' ? 10 : 9;
849 eServiceReference tmp(line+offs);
850 if ( tmp.flags&eServiceReference::canDescent )
852 size_t pos = tmp.path.rfind('/');
854 std::string path = tmp.path;
855 if ( pos != std::string::npos )
856 path.erase(0, pos+1);
859 eDebug("[eDVBDB] Bouquet load failed.. no filename given..");
862 pos = path.find("FROM BOUQUET ");
863 if (pos != std::string::npos)
865 char endchr = path[pos+13];
868 eDebug("[eDVBDB] ignore invalid bouquet '%s' (only \" are allowed)",
869 tmp.toString().c_str());
872 char *beg = &path[pos+14];
873 char *end = strchr(beg, endchr);
874 path.assign(beg, end - beg);
878 snprintf(buf, sizeof(buf), "FROM BOUQUET \"%s\" ORDER BY bouquet", path.c_str());
881 for(unsigned int i=0; i<userbouquetsfiles.size(); ++i)
883 if (userbouquetsfiles[i].compare(path.c_str()) == 0)
885 userbouquetsfiles.erase(userbouquetsfiles.begin() + i);
889 loadBouquet(path.c_str());
896 else if (read_descr && !strncmp(line, "#DESCRIPTION", 12))
898 int offs = line[12] == ':' ? 14 : 13;
902 else if (!strncmp(line, "#NAME ", 6))
903 bouquet.m_bouquet_name=line+6;
908 if (userbouquetsfiles.size())
910 for(unsigned int i=0; i<userbouquetsfiles.size(); ++i)
912 if (m_load_unlinked_userbouquets)
914 eDebug("[eDVBDB] Adding additional userbouquet %s", userbouquetsfiles[i].c_str());
916 if (!strcmp(path, "bouquets.tv"))
917 snprintf(buf, sizeof(buf), "1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"%s\" ORDER BY bouquet", userbouquetsfiles[i].c_str());
919 snprintf(buf, sizeof(buf), "1:7:2:0:0:0:0:0:0:0:FROM BOUQUET \"%s\" ORDER BY bouquet", userbouquetsfiles[i].c_str());
920 eServiceReference tmp(buf);
921 loadBouquet(userbouquetsfiles[i].c_str());
922 if (!strcmp(userbouquetsfiles[i].c_str(), "userbouquet.LastScanned.tv"))
925 list.push_front(tmp);
930 std::string filename = eEnv::resolve("${sysconfdir}/enigma2/" + userbouquetsfiles[i]);
931 std::string newfilename(filename);
932 newfilename.append(".del");
933 eDebug("[eDVBDB] Rename unlinked bouquet file %s to %s", filename.c_str(), newfilename.c_str());
934 rename(filename.c_str(), newfilename.c_str());
937 bouquet.flushChanges();
939 eDebug("[eDVBDB] %d entries in Bouquet %s", entries, bouquet_name.c_str());
942 void eDVBDB::reloadBouquets()
945 loadBouquet("bouquets.tv");
946 loadBouquet("bouquets.radio");
947 // create default bouquets when missing
948 if ( m_bouquets.find("userbouquet.favourites.tv") == m_bouquets.end() )
950 eBouquet &b = m_bouquets["userbouquet.favourites.tv"];
951 b.m_filename = "userbouquet.favourites.tv";
952 b.m_bouquet_name = "Favourites (TV)";
954 eServiceReference ref;
958 ref.path="FROM BOUQUET \"userbouquet.favourites.tv\" ORDER BY bouquet";
959 eBouquet &parent = m_bouquets["bouquets.tv"];
960 parent.m_services.push_back(ref);
961 parent.flushChanges();
963 if ( m_bouquets.find("userbouquet.favourites.radio") == m_bouquets.end() )
965 eBouquet &b = m_bouquets["userbouquet.favourites.radio"];
966 b.m_filename = "userbouquet.favourites.radio";
967 b.m_bouquet_name = "Favourites (Radio)";
969 eServiceReference ref;
973 ref.path="FROM BOUQUET \"userbouquet.favourites.radio\" ORDER BY bouquet";
974 eBouquet &parent = m_bouquets["bouquets.radio"];
975 parent.m_services.push_back(ref);
976 parent.flushChanges();
981 void eDVBDB::renumberBouquet()
983 eDebug("[eDVBDB] Renumbering...");
984 renumberBouquet( m_bouquets["bouquets.tv"] );
985 renumberBouquet( m_bouquets["bouquets.radio"] );
988 void eDVBDB::setNumberingMode(bool numberingMode)
990 if (m_numbering_mode != numberingMode)
992 m_numbering_mode = numberingMode;
997 int eDVBDB::renumberBouquet(eBouquet &bouquet, int startChannelNum)
999 std::list<eServiceReference> &list = bouquet.m_services;
1000 for (std::list<eServiceReference>::iterator it = list.begin(); it != list.end(); ++it)
1002 eServiceReference &ref = *it;
1003 if (ref.flags & eServiceReference::canDescent)
1005 std::string filename = ref.toString();
1006 size_t pos = filename.find("FROM BOUQUET ");
1007 if(pos != std::string::npos)
1009 char endchr = filename[pos+13];
1012 char *beg = &filename[pos+14];
1013 char *end = strchr(beg, endchr);
1014 filename.assign(beg, end - beg);
1015 eBouquet &subBouquet = m_bouquets[filename];
1016 if (m_numbering_mode || filename.find("alternatives.") == 0)
1017 renumberBouquet(subBouquet);
1019 startChannelNum = renumberBouquet(subBouquet, startChannelNum);
1023 if( !(ref.flags & (eServiceReference::isMarker|eServiceReference::isDirectory)) ||
1024 (ref.flags & eServiceReference::isNumberedMarker) )
1025 ref.number = startChannelNum++;
1028 return startChannelNum;
1031 eDVBDB *eDVBDB::instance;
1033 using namespace xmlcc;
1036 : m_numbering_mode(false), m_load_unlinked_userbouquets(true)
1039 reloadServicelist();
1042 PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObject tp_dict)
1044 if (!PyDict_Check(tp_dict)) {
1045 PyErr_SetString(PyExc_StandardError,
1047 eDebug("[eDVBDB] readSatellites arg 2 is not a python dict");
1050 else if (!PyDict_Check(sat_dict))
1052 PyErr_SetString(PyExc_StandardError,
1054 eDebug("[eDVBDB] readSatellites arg 1 is not a python dict");
1057 else if (!PyList_Check(sat_list))
1059 PyErr_SetString(PyExc_StandardError,
1061 eDebug("[eDVBDB] readSatellites arg 0 is not a python list");
1065 const char* satellitesFilename = "/etc/enigma2/satellites.xml";
1066 if (::access(satellitesFilename, R_OK) < 0)
1068 satellitesFilename = "/etc/tuxbox/satellites.xml";
1070 tree.setFilename(satellitesFilename);
1072 Element *root = tree.getRoot();
1075 eDebug("[eDVBDB] couldn't open /etc/tuxbox/satellites.xml!!");
1076 Py_INCREF(Py_False);
1079 int tmp, *dest = NULL,
1080 modulation, system, freq, sr, pol, fec, inv, pilot, rolloff, tsid, onid;
1082 const Attribute *at;
1084 const ElementList &root_elements = root->getElementList();
1085 for (ElementConstIterator it(root_elements.begin()); it != root_elements.end(); ++it)
1087 // eDebug("[eDVBDB] element: %s", (*it)->name().c_str());
1088 const Element *el = *it;
1089 const ElementList &sat_elements = el->getElementList();
1090 const AttributeList &sat_attributes = el->getAttributeList();
1093 ePyObject sat_flags;
1094 for (AttributeConstIterator it(sat_attributes.begin()); it != sat_attributes.end(); ++it)
1096 // eDebug("[eDVBDB] \tattr: %s", at->name().c_str());
1100 sat_name = PyString_FromString(at->value().c_str());
1101 else if (name == "flags")
1103 tmp = strtol(at->value().c_str(), &end_ptr, 10);
1105 sat_flags = PyInt_FromLong(tmp);
1107 else if (name == "position")
1109 tmp = strtol(at->value().c_str(), &end_ptr, 10);
1114 sat_pos = PyInt_FromLong(tmp);
1118 if (sat_pos && sat_name)
1120 ePyObject tplist = PyList_New(0);
1121 ePyObject tuple = PyTuple_New(3);
1123 sat_flags = PyInt_FromLong(0);
1124 PyTuple_SET_ITEM(tuple, 0, sat_pos);
1125 PyTuple_SET_ITEM(tuple, 1, sat_name);
1126 PyTuple_SET_ITEM(tuple, 2, sat_flags);
1127 PyList_Append(sat_list, tuple);
1129 PyDict_SetItem(sat_dict, sat_pos, sat_name);
1130 PyDict_SetItem(tp_dict, sat_pos, tplist);
1131 for (ElementConstIterator it(sat_elements.begin()); it != sat_elements.end(); ++it)
1133 //eDebug("[eDVBDB] \telement: %s", (*it)->name().c_str());
1134 const AttributeList &tp_attributes = (*it)->getAttributeList();
1135 AttributeConstIterator end = tp_attributes.end();
1136 modulation = eDVBFrontendParametersSatellite::Modulation_QPSK;
1137 system = eDVBFrontendParametersSatellite::System_DVB_S;
1141 fec = eDVBFrontendParametersSatellite::FEC_Auto;
1142 inv = eDVBFrontendParametersSatellite::Inversion_Unknown;
1143 pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
1144 rolloff = eDVBFrontendParametersSatellite::RollOff_alpha_0_35;
1148 for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
1151 //eDebug("[eDVBDB] \t\tattr: %s", at->name().c_str());
1153 if (name == "modulation") dest = &modulation;
1154 else if (name == "system") dest = &system;
1155 else if (name == "frequency") dest = &freq;
1156 else if (name == "symbol_rate") dest = &sr;
1157 else if (name == "polarization") dest = &pol;
1158 else if (name == "fec_inner") dest = &fec;
1159 else if (name == "inversion") dest = &inv;
1160 else if (name == "rolloff") dest = &rolloff;
1161 else if (name == "pilot") dest = &pilot;
1162 else if (name == "tsid") dest = &tsid;
1163 else if (name == "onid") dest = &onid;
1167 //eDebug("[eDVBDB] \t\t\tvalue: %s", at->value().c_str());
1168 tmp = strtol(at->value().c_str(), &end_ptr, 10);
1173 if (freq && sr && pol != -1)
1175 tuple = PyTuple_New(12);
1176 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
1177 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq));
1178 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(sr));
1179 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(pol));
1180 PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong(fec));
1181 PyTuple_SET_ITEM(tuple, 5, PyInt_FromLong(system));
1182 PyTuple_SET_ITEM(tuple, 6, PyInt_FromLong(modulation));
1183 PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong(inv));
1184 PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong(rolloff));
1185 PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong(pilot));
1186 PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(tsid));
1187 PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(onid));
1188 PyList_Append(tplist, tuple);
1199 Py_DECREF(sat_name);
1201 Py_DECREF(sat_flags);
1208 PyObject *eDVBDB::readCables(ePyObject cab_list, ePyObject tp_dict)
1210 if (!PyDict_Check(tp_dict)) {
1211 PyErr_SetString(PyExc_StandardError,
1213 eDebug("[eDVBDB] readCables arg 1 is not a python dict");
1216 else if (!PyList_Check(cab_list))
1218 PyErr_SetString(PyExc_StandardError,
1220 eDebug("[eDVBDB] readCables arg 0 is not a python list");
1224 tree.setFilename("/etc/tuxbox/cables.xml");
1226 Element *root = tree.getRoot();
1229 eDebug("[eDVBDB] couldn't open /etc/tuxbox/cables.xml!!");
1230 Py_INCREF(Py_False);
1233 const Attribute *at;
1235 modulation, fec, freq, sr, inversion, system;
1238 const ElementList &root_elements = root->getElementList();
1239 for (ElementConstIterator it(root_elements.begin()); it != root_elements.end(); ++it)
1241 // eDebug("[eDVBDB] element: %s", el->name().c_str());
1242 const Element *el = *it;
1243 const ElementList &cab_elements = el->getElementList();
1244 const AttributeList &cab_attributes = el->getAttributeList();
1246 ePyObject cab_flags;
1247 for (AttributeConstIterator it(cab_attributes.begin()); it != cab_attributes.end(); ++it)
1249 // eDebug("[eDVBDB]\tattr: %s", at->name().c_str());
1253 cab_name = PyString_FromString(at->value().c_str());
1254 else if (name == "flags")
1256 tmp = strtol(at->value().c_str(), &end_ptr, 10);
1258 cab_flags = PyInt_FromLong(tmp);
1263 ePyObject tplist = PyList_New(0);
1264 ePyObject tuple = PyTuple_New(2);
1266 cab_flags = PyInt_FromLong(0);
1267 PyTuple_SET_ITEM(tuple, 0, cab_name);
1268 PyTuple_SET_ITEM(tuple, 1, cab_flags);
1269 PyList_Append(cab_list, tuple);
1271 PyDict_SetItem(tp_dict, cab_name, tplist);
1272 for (ElementConstIterator it(cab_elements.begin()); it != cab_elements.end(); ++it)
1274 // eDebug("[eDVBDB]\telement: %s", (*it)->name().c_str());
1275 const AttributeList &tp_attributes = (*it)->getAttributeList();
1276 AttributeConstIterator end = tp_attributes.end();
1277 modulation = eDVBFrontendParametersCable::Modulation_QAM64;
1278 fec = eDVBFrontendParametersCable::FEC_Auto;
1279 system = eDVBFrontendParametersCable::System_DVB_C_ANNEX_A;
1280 inversion = eDVBFrontendParametersCable::Inversion_Unknown;
1283 for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
1285 // eDebug("[eDVBDB]\t\tattr: %s", at->name().c_str());
1289 if (name == "modulation") dest = &modulation;
1290 else if (name == "frequency") dest = &freq;
1291 else if (name == "symbol_rate") dest = &sr;
1292 else if (name == "fec_inner") dest = &fec;
1293 else if (name == "inversion") dest = &inversion;
1294 else if (name == "system") dest = &system;
1298 tmp = strtol(at->value().c_str(), &end_ptr, 10);
1305 while (freq > 999999)
1307 tuple = PyTuple_New(7);
1308 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
1309 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq));
1310 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(sr));
1311 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(modulation));
1312 PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong(fec));
1313 PyTuple_SET_ITEM(tuple, 5, PyInt_FromLong(inversion));
1314 PyTuple_SET_ITEM(tuple, 6, PyInt_FromLong(system));
1315 PyList_Append(tplist, tuple);
1322 Py_DECREF(cab_flags);
1328 PyObject *eDVBDB::readTerrestrials(ePyObject ter_list, ePyObject tp_dict)
1330 if (!PyDict_Check(tp_dict)) {
1331 PyErr_SetString(PyExc_StandardError,
1333 eDebug("[eDVBDB] readTerrestrials arg 1 is not a python dict");
1336 else if (!PyList_Check(ter_list))
1338 PyErr_SetString(PyExc_StandardError,
1340 eDebug("[eDVBDB] readTerrestrials arg 0 is not a python list");
1344 tree.setFilename("/etc/tuxbox/terrestrial.xml");
1346 Element *root = tree.getRoot();
1349 eDebug("[eDVBDB] couldn't open /etc/tuxbox/terrestrial.xml!!");
1350 Py_INCREF(Py_False);
1353 const Attribute *at;
1356 freq, bw, constellation, crh, crl, guard, transm, hierarchy, inv, system, plpid;
1358 const ElementList &root_elements = root->getElementList();
1359 for (ElementConstIterator it(root_elements.begin()); it != root_elements.end(); ++it)
1361 // eDebug("[eDVBDB] element: %s", el->name().c_str());
1362 const Element *el = *it;
1363 const ElementList &ter_elements = el->getElementList();
1364 const AttributeList &ter_attributes = el->getAttributeList();
1366 ePyObject ter_flags;
1367 for (AttributeConstIterator it(ter_attributes.begin()); it != ter_attributes.end(); ++it)
1369 // eDebug("[eDVBDB]\tattr: %s", at->name().c_str());
1373 ter_name = PyString_FromString(at->value().c_str());
1374 else if (name == "flags")
1376 tmp = strtol(at->value().c_str(), &end_ptr, 10);
1378 ter_flags = PyInt_FromLong(tmp);
1383 ePyObject tplist = PyList_New(0);
1384 ePyObject tuple = PyTuple_New(2);
1386 ter_flags = PyInt_FromLong(0);
1387 PyTuple_SET_ITEM(tuple, 0, ter_name);
1388 PyTuple_SET_ITEM(tuple, 1, ter_flags);
1389 PyList_Append(ter_list, tuple);
1391 PyDict_SetItem(tp_dict, ter_name, tplist);
1392 for (ElementConstIterator it(ter_elements.begin()); it != ter_elements.end(); ++it)
1394 // eDebug("[eDVBDB]\telement: %s", (*it)->name().c_str());
1395 const AttributeList &tp_attributes = (*it)->getAttributeList();
1396 AttributeConstIterator end = tp_attributes.end();
1398 bw = eDVBFrontendParametersTerrestrial::Bandwidth_Auto;
1399 constellation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
1400 crh = eDVBFrontendParametersTerrestrial::FEC_Auto;
1401 crl = eDVBFrontendParametersTerrestrial::FEC_Auto;
1402 guard = eDVBFrontendParametersTerrestrial::GuardInterval_Auto;
1403 transm = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto;
1404 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
1405 inv = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
1406 system = eDVBFrontendParametersTerrestrial::System_DVB_T_T2;
1408 for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
1410 // eDebug("[eDVBDB]\t\tattr: %s", at->name().c_str());
1414 if (name == "centre_frequency") dest = &freq;
1415 else if (name == "bandwidth") dest = &bw;
1416 else if (name == "constellation") dest = &constellation;
1417 else if (name == "code_rate_hp") dest = &crh;
1418 else if (name == "code_rate_lp") dest = &crl;
1419 else if (name == "guard_interval") dest = &guard;
1420 else if (name == "transmission_mode") dest = &transm;
1421 else if (name == "hierarchy_information") dest = &hierarchy;
1422 else if (name == "inversion") dest = &inv;
1423 else if (name == "system") dest = &system;
1424 else if (name == "plp_id") dest = &plpid;
1428 tmp = strtol(at->value().c_str(), &end_ptr, 10);
1437 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bw = 8000000; break;
1438 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bw = 7000000; break;
1439 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bw = 6000000; break;
1441 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bw = 0; break;
1442 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bw = 5000000; break;
1443 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bw = 1712000; break;
1444 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bw = 10000000; break;
1446 if (crh > eDVBFrontendParametersTerrestrial::FEC_8_9)
1447 crh = eDVBFrontendParametersTerrestrial::FEC_Auto;
1448 if (crl > eDVBFrontendParametersTerrestrial::FEC_8_9)
1449 crl = eDVBFrontendParametersTerrestrial::FEC_Auto;
1450 tuple = PyTuple_New(12);
1451 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(2));
1452 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq));
1453 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(bw));
1454 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(constellation));
1455 PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong(crh));
1456 PyTuple_SET_ITEM(tuple, 5, PyInt_FromLong(crl));
1457 PyTuple_SET_ITEM(tuple, 6, PyInt_FromLong(guard));
1458 PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong(transm));
1459 PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong(hierarchy));
1460 PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong(inv));
1461 PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(system));
1462 PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(plpid));
1463 PyList_Append(tplist, tuple);
1470 Py_DECREF(ter_flags);
1481 RESULT eDVBDB::removeService(const eServiceReference &ref)
1483 if (ref.type == eServiceReference::idDVB)
1485 eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
1486 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(service));
1487 if (it != m_services.end())
1489 m_services.erase(it);
1496 RESULT eDVBDB::removeServices(int dvb_namespace, int tsid, int onid, unsigned int orb_pos)
1498 return removeServices(eDVBChannelID(eDVBNamespace(dvb_namespace), eTransportStreamID(tsid), eOriginalNetworkID(onid)), orb_pos);
1501 RESULT eDVBDB::removeServices(eDVBChannelID chid, unsigned int orbpos)
1505 eTransportStreamID eTsid;
1506 eOriginalNetworkID eOnid;
1507 std::map<eDVBChannelID, channel>::iterator it(m_channels.begin());
1508 std::set<eDVBChannelID> removed_chids;
1509 while (it != m_channels.end())
1511 const eDVBChannelID &ch = it->first;
1514 it->second.m_frontendParameters->getSystem(system);
1515 if ( system == iDVBFrontend::feSatellite )
1517 eDVBFrontendParametersSatellite sat;
1518 it->second.m_frontendParameters->getDVBS(sat);
1519 if ((unsigned int)sat.orbital_position != orbpos)
1522 if ( remove && chid.dvbnamespace != eNs ) // namespace given?
1524 if ( system == iDVBFrontend::feCable && chid.dvbnamespace.get() == (int)0xFFFF0000 )
1526 else if ( system == iDVBFrontend::feTerrestrial && chid.dvbnamespace.get() == (int)0xEEEE0000 )
1528 else if ( chid.dvbnamespace != ch.dvbnamespace )
1531 else if ( system == iDVBFrontend::feCable || system == iDVBFrontend::feTerrestrial )
1533 if ( remove && chid.original_network_id != eOnid && chid.original_network_id != ch.original_network_id )
1535 if ( remove && chid.transport_stream_id != eTsid && chid.transport_stream_id != ch.transport_stream_id )
1539 eDebug("[eDVBDB] remove %08x %04x %04x",
1540 ch.dvbnamespace.get(),
1541 ch.original_network_id.get(),
1542 ch.transport_stream_id.get());
1543 removed_chids.insert(it->first);
1544 m_channels.erase(it++);
1549 if (!removed_chids.empty())
1551 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator service(m_services.begin());
1552 while(service != m_services.end())
1555 service->first.getChannelID(chid);
1556 std::set<eDVBChannelID>::iterator it(removed_chids.find(chid));
1557 if (it != removed_chids.end())
1558 m_services.erase(service++);
1567 RESULT eDVBDB::removeServices(iDVBFrontendParameters *feparm)
1570 std::set<eDVBChannelID> removed_chids;
1571 std::map<eDVBChannelID, channel>::iterator it(m_channels.begin());
1572 while (it != m_channels.end())
1575 if (!feparm->calculateDifference(&(*it->second.m_frontendParameters), diff, false))
1579 removed_chids.insert(it->first);
1580 m_channels.erase(it++);
1588 if (!removed_chids.empty())
1590 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator service(m_services.begin());
1591 while(service != m_services.end())
1594 service->first.getChannelID(chid);
1595 std::set<eDVBChannelID>::iterator it(removed_chids.find(chid));
1596 if (it != removed_chids.end())
1597 m_services.erase(service++);
1606 PyObject *eDVBDB::getFlag(const eServiceReference &ref)
1608 if (ref.type == eServiceReference::idDVB)
1610 eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
1611 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(service));
1612 if (it != m_services.end())
1613 return PyInt_FromLong(it->second->m_flags);
1615 return PyInt_FromLong(0);
1618 RESULT eDVBDB::addFlag(const eServiceReference &ref, unsigned int flagmask)
1620 if (ref.type == eServiceReference::idDVB)
1622 eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
1623 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(service));
1624 if (it != m_services.end())
1625 it->second->m_flags |= flagmask;
1631 RESULT eDVBDB::removeFlag(const eServiceReference &ref, unsigned int flagmask)
1633 if (ref.type == eServiceReference::idDVB)
1635 eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
1636 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(service));
1637 if (it != m_services.end())
1638 it->second->m_flags &= ~flagmask;
1644 RESULT eDVBDB::removeFlags(unsigned int flagmask, int dvb_namespace, int tsid, int onid, unsigned int orb_pos)
1646 return removeFlags(flagmask, eDVBChannelID(eDVBNamespace(dvb_namespace), eTransportStreamID(tsid), eOriginalNetworkID(onid)), orb_pos);
1649 RESULT eDVBDB::removeFlags(unsigned int flagmask, eDVBChannelID chid, unsigned int orbpos)
1652 eTransportStreamID eTsid;
1653 eOriginalNetworkID eOnid;
1654 std::map<eDVBChannelID, channel>::iterator it(m_channels.begin());
1655 std::set<eDVBChannelID> removed_chids;
1656 while (it != m_channels.end())
1658 const eDVBChannelID &ch = it->first;
1661 it->second.m_frontendParameters->getSystem(system);
1662 if ( orbpos != 0xFFFFFFFF && system == iDVBFrontend::feSatellite )
1664 eDVBFrontendParametersSatellite sat;
1665 it->second.m_frontendParameters->getDVBS(sat);
1666 if ((unsigned int)sat.orbital_position != orbpos)
1669 if ( remove && chid.dvbnamespace != eNs )
1671 if (system == iDVBFrontend::feCable && chid.dvbnamespace.get() == (int)0xFFFF0000)
1673 else if (system == iDVBFrontend::feTerrestrial && chid.dvbnamespace.get() == (int)0xEEEE0000)
1675 else if ( chid.dvbnamespace != ch.dvbnamespace )
1678 if ( remove && chid.original_network_id != eOnid && chid.original_network_id != ch.original_network_id )
1680 if ( remove && chid.transport_stream_id != eTsid && chid.transport_stream_id != ch.transport_stream_id )
1683 removed_chids.insert(it->first);
1686 if (!removed_chids.empty())
1688 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator service(m_services.begin());
1689 while(service != m_services.end())
1692 service->first.getChannelID(chid);
1693 std::set<eDVBChannelID>::iterator it(removed_chids.find(chid));
1694 if (it != removed_chids.end())
1695 service->second->m_flags &= ~flagmask;
1702 RESULT eDVBDB::addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm)
1705 std::map<eDVBChannelID, channel>::iterator it = m_channels.find(id);
1707 ch.m_frontendParameters = feparm;
1708 if (it != m_channels.end())
1711 m_channels.insert(std::pair<eDVBChannelID, channel>(id, ch));
1715 RESULT eDVBDB::removeChannel(const eDVBChannelID &id)
1717 m_channels.erase(id);
1721 RESULT eDVBDB::getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm)
1723 std::map<eDVBChannelID, channel>::iterator i = m_channels.find(id);
1724 if (i == m_channels.end())
1729 parm = i->second.m_frontendParameters;
1733 RESULT eDVBDB::addService(const eServiceReferenceDVB &serviceref, eDVBService *service)
1735 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(serviceref));
1736 if (it == m_services.end())
1737 m_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(serviceref, service));
1741 RESULT eDVBDB::getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service)
1743 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator i;
1744 i = m_services.find(reference);
1745 if (i == m_services.end())
1750 service = i->second;
1754 RESULT eDVBDB::flush()
1760 RESULT eDVBDB::getBouquet(const eServiceReference &ref, eBouquet* &bouquet)
1762 std::string str = ref.path;
1765 eDebug("[eDVBDB] getBouquet failed.. no path given!");
1768 size_t pos = str.find("FROM BOUQUET \"");
1769 if ( pos != std::string::npos )
1771 str.erase(0, pos+14);
1772 pos = str.find('"');
1773 if ( pos != std::string::npos )
1780 eDebug("[eDVBDB] getBouquet failed.. couldn't parse bouquet name");
1783 std::map<std::string, eBouquet>::iterator i =
1784 m_bouquets.find(str);
1785 if (i == m_bouquets.end())
1790 bouquet = &i->second;
1794 RESULT eDVBDB::startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *q, const eServiceReference &source)
1796 if ( source.path.find("FROM") != std::string::npos )
1798 if ( source.path.find("BOUQUET") != std::string::npos )
1799 query = new eDVBDBBouquetQuery(this, source, q);
1800 else if ( source.path.find("SATELLITES") != std::string::npos )
1801 query = new eDVBDBSatellitesQuery(this, source, q);
1802 else if ( source.path.find("PROVIDERS") != std::string::npos )
1803 query = new eDVBDBProvidersQuery(this, source, q);
1805 eFatal("[eDVBDB] invalid query %s", source.toString().c_str());
1808 query = new eDVBDBQuery(this, source, q);
1812 eServiceReference eDVBDB::searchReference(int tsid, int onid, int sid)
1814 eServiceID Sid(sid);
1815 eTransportStreamID Tsid(tsid);
1816 eOriginalNetworkID Onid(onid);
1817 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator sit(m_services.begin());
1818 sit != m_services.end(); ++sit)
1820 if (sit->first.getTransportStreamID() == Tsid &&
1821 sit->first.getOriginalNetworkID() == Onid &&
1822 sit->first.getServiceID() == Sid)
1825 return eServiceReference();
1828 void eDVBDB::searchAllReferences(std::vector<eServiceReference> &result, int tsid, int onid, int sid)
1830 eServiceID Sid(sid);
1831 eTransportStreamID Tsid(tsid);
1832 eOriginalNetworkID Onid(onid);
1833 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator sit(m_services.begin());
1834 sit != m_services.end(); ++sit)
1836 if (sit->first.getTransportStreamID() == Tsid &&
1837 sit->first.getOriginalNetworkID() == Onid &&
1838 sit->first.getServiceID() == Sid)
1839 result.push_back(sit->first);
1843 DEFINE_REF(eDVBDBQueryBase);
1845 eDVBDBQueryBase::eDVBDBQueryBase(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
1846 :m_db(db), m_query(query), m_source(source)
1850 int eDVBDBQueryBase::compareLessEqual(const eServiceReferenceDVB &a, const eServiceReferenceDVB &b)
1852 ePtr<eDVBService> a_service, b_service;
1853 int sortmode = m_query ? m_query->m_sort : eDVBChannelQuery::tName;
1855 if ((sortmode == eDVBChannelQuery::tName) || (sortmode == eDVBChannelQuery::tProvider))
1857 if (a.name.empty() && m_db->getService(a, a_service))
1859 if (b.name.empty() && m_db->getService(b, b_service))
1865 case eDVBChannelQuery::tName:
1869 return a_service->m_service_name_sort < b_service->m_service_name_sort;
1872 std::string str = b.name;
1874 return a_service->m_service_name_sort < str;
1879 std::string str = a.name;
1881 return str < b_service->m_service_name_sort;
1885 std::string aa = a.name, bb = b.name;
1890 case eDVBChannelQuery::tProvider:
1891 return a_service->m_provider_name < b_service->m_provider_name;
1892 case eDVBChannelQuery::tType:
1893 return a.getServiceType() < b.getServiceType();
1894 case eDVBChannelQuery::tBouquet:
1896 case eDVBChannelQuery::tSatellitePosition:
1897 return (a.getDVBNamespace().get() >> 16) < (b.getDVBNamespace().get() >> 16);
1904 eDVBDBQuery::eDVBDBQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
1905 :eDVBDBQueryBase(db, source, query)
1907 m_cursor = m_db->m_services.begin();
1910 RESULT eDVBDBQuery::getNextResult(eServiceReferenceDVB &ref)
1912 while (m_cursor != m_db->m_services.end())
1914 ePtr<eDVBService> service = m_cursor->second;
1915 if (service->isHidden())
1919 ref = m_cursor->first;
1921 int res = (!m_query) || service->checkFilter(ref, *m_query);
1930 ref.type = eServiceReference::idInvalid;
1935 eDVBDBBouquetQuery::eDVBDBBouquetQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
1936 :eDVBDBQueryBase(db, source, query), m_cursor(db->m_bouquets[query->m_bouquet_name].m_services.begin())
1940 RESULT eDVBDBBouquetQuery::getNextResult(eServiceReferenceDVB &ref)
1942 eBouquet &bouquet = m_db->m_bouquets[m_query->m_bouquet_name];
1943 std::list<eServiceReference> &list = bouquet.m_services;
1944 while (m_cursor != list.end())
1946 ref = *((eServiceReferenceDVB*)&(*m_cursor));
1948 std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it =
1949 m_db->m_services.find(ref);
1951 int res = (!m_query) || it == m_db->m_services.end() || !(it->second->isHidden() && it->second->checkFilter(ref, *m_query));
1959 ref.type = eServiceReference::idInvalid;
1964 eDVBDBListQuery::eDVBDBListQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
1965 :eDVBDBQueryBase(db, source, query), m_cursor(m_list.end())
1969 RESULT eDVBDBListQuery::getNextResult(eServiceReferenceDVB &ref)
1971 if (m_cursor != m_list.end())
1976 ref.type = eServiceReference::idInvalid;
1980 int eDVBDBListQuery::compareLessEqual(const eServiceReferenceDVB &a, const eServiceReferenceDVB &b)
1982 if ( m_query->m_sort == eDVBChannelQuery::tSatellitePosition )
1984 int x = (a.getDVBNamespace().get() >> 16);
1985 int y = (b.getDVBNamespace().get() >> 16);
1992 std::string aa = a.name, bb = b.name;
1998 eDVBDBSatellitesQuery::eDVBDBSatellitesQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
1999 :eDVBDBListQuery(db, source, query)
2001 std::set<unsigned int> found;
2002 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_db->m_services.begin());
2003 it != m_db->m_services.end(); ++it)
2005 int res = !it->second->isHidden() && it->second->checkFilter(it->first, *query);
2008 unsigned int dvbnamespace = it->first.getDVBNamespace().get()&0xFFFF0000;
2009 if (found.find(dvbnamespace) == found.end())
2011 found.insert(dvbnamespace);
2012 eServiceReferenceDVB ref;
2013 ref.setDVBNamespace(dvbnamespace);
2014 ref.flags=eServiceReference::flagDirectory;
2016 snprintf(buf, sizeof(buf), "(satellitePosition == %d) && ", dvbnamespace>>16);
2018 ref.path=buf+source.path;
2019 unsigned int pos=ref.path.find("FROM");
2020 ref.path.erase(pos);
2021 ref.path+="ORDER BY name";
2022 // eDebug("[eDVBDB] ref.path now %s", ref.path.c_str());
2023 m_list.push_back(ref);
2025 ref.path=buf+source.path;
2026 pos=ref.path.find("FROM");
2027 ref.path.erase(pos+5);
2028 ref.path+="PROVIDERS ORDER BY name";
2029 // eDebug("[eDVBDB] ref.path now %s", ref.path.c_str());
2030 m_list.push_back(ref);
2032 snprintf(buf, sizeof(buf), "(satellitePosition == %d) && (flags == %d) && ", dvbnamespace>>16, eDVBService::dxNewFound);
2033 ref.path=buf+source.path;
2034 pos=ref.path.find("FROM");
2035 ref.path.erase(pos);
2036 ref.path+="ORDER BY name";
2037 // eDebug("[eDVBDB] ref.path now %s", ref.path.c_str());
2038 m_list.push_back(ref);
2042 m_cursor=m_list.begin();
2045 eDVBDBProvidersQuery::eDVBDBProvidersQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
2046 :eDVBDBListQuery(db, source, query)
2048 std::set<std::string> found;
2049 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_db->m_services.begin());
2050 it != m_db->m_services.end(); ++it)
2052 int res = !it->second->isHidden() && it->second->checkFilter(it->first, *query);
2055 const char *provider_name = it->second->m_provider_name.length() ?
2056 it->second->m_provider_name.c_str() :
2058 if (found.find(std::string(provider_name)) == found.end())
2060 found.insert(std::string(provider_name));
2061 eServiceReferenceDVB ref;
2063 ref.name=provider_name;
2064 snprintf(buf, sizeof(buf), "(provider == \"%s\") && ", provider_name);
2065 ref.path=buf+source.path;
2066 unsigned int pos = ref.path.find("FROM");
2067 ref.flags=eServiceReference::flagDirectory;
2068 ref.path.erase(pos);
2069 ref.path+="ORDER BY name";
2070 // eDebug("[eDVBDB] ref.path now %s", ref.path.c_str());
2071 m_list.push_back(ref);
2075 m_cursor=m_list.begin();
2078 /* (<name|provider|type|bouquet|satpos|chid> <==|...> <"string"|int>)[||,&& (..)] */
2080 static int decodeType(const std::string &type)
2083 return eDVBChannelQuery::tName;
2084 else if (type == "provider")
2085 return eDVBChannelQuery::tProvider;
2086 else if (type == "type")
2087 return eDVBChannelQuery::tType;
2088 else if (type == "bouquet")
2089 return eDVBChannelQuery::tBouquet;
2090 else if (type == "satellitePosition")
2091 return eDVBChannelQuery::tSatellitePosition;
2092 else if (type == "channelID")
2093 return eDVBChannelQuery::tChannelID;
2094 else if (type == "flags")
2095 return eDVBChannelQuery::tFlags;
2100 /* never, NEVER write a parser in C++! */
2101 RESULT parseExpression(ePtr<eDVBChannelQuery> &res, std::list<std::string>::const_iterator begin, std::list<std::string>::const_iterator end)
2103 std::list<std::string>::const_iterator end_of_exp;
2111 while (end_of_exp != end)
2112 if (*end_of_exp == ")")
2117 if (end_of_exp == end)
2119 eDebug("[parseExpression] end of expression while searching for closing brace");
2124 // begin..end_of_exp
2125 int r = parseExpression(res, begin, end_of_exp);
2130 /* we had only one sub expression */
2131 if (end_of_exp == end)
2133 // eDebug("[parseExpression] only one sub expression");
2137 /* otherwise we have an operator here.. */
2139 ePtr<eDVBChannelQuery> r2 = res;
2140 res = new eDVBChannelQuery();
2146 if (*end_of_exp == "||")
2147 res->m_type = eDVBChannelQuery::tOR;
2148 else if (*end_of_exp == "&&")
2149 res->m_type = eDVBChannelQuery::tAND;
2152 eDebug("[parseExpression] found operator %s, but only && and || are allowed!", end_of_exp->c_str());
2159 return parseExpression(res->m_p2, end_of_exp, end);
2162 // "begin" <op> "end"
2163 std::string type, op, val;
2165 res = new eDVBChannelQuery();
2169 while (begin != end)
2183 eDebug("[parseExpression] malformed query: got '%s', but expected only <type> <op> <val>", begin->c_str());
2192 eDebug("[parseExpression] malformed query: missing stuff");
2197 res->m_type = decodeType(type);
2199 if (res->m_type == -1)
2201 eDebug("[parseExpression] malformed query: invalid type %s", type.c_str());
2208 else if (op == "!=")
2212 eDebug("[parseExpression] invalid operator %s", op.c_str());
2217 res->m_string = val;
2219 if (res->m_type == eDVBChannelQuery::tChannelID)
2222 if (sscanf(val.c_str(), "%08x%04x%04x", &ns, &tsid, &onid) == 3)
2223 res->m_channelid = eDVBChannelID(eDVBNamespace(ns), eTransportStreamID(tsid), eOriginalNetworkID(onid));
2225 eDebug("[parseExpression] couldn't parse channelid !! format should be hex NNNNNNNNTTTTOOOO (namespace, tsid, onid)");
2228 res->m_int = atoi(val.c_str());
2233 RESULT eDVBChannelQuery::compile(ePtr<eDVBChannelQuery> &res, std::string query)
2235 std::list<std::string> tokens;
2237 std::string current_token;
2238 std::string bouquet_name;
2240 // eDebug("[eDVBChannelQuery] splitting %s....", query.c_str());
2242 const char *splitchars="()";
2243 int quotemode = 0, lastsplit = 0, lastalnum = 0;
2244 while (i <= query.size())
2246 int c = (i < query.size()) ? query[i] : ' ';
2249 int issplit = !!strchr(splitchars, c);
2250 int isaln = isalnum(c);
2251 int iswhite = c == ' ';
2252 int isquot = c == '\"';
2256 iswhite = issplit = 0;
2260 if (issplit || iswhite || isquot || lastsplit || (lastalnum != isaln))
2262 if (current_token.size())
2263 tokens.push_back(current_token);
2264 current_token.clear();
2267 if (!(iswhite || isquot))
2271 quotemode = !quotemode;
2272 lastsplit = issplit;
2276 // for (std::list<std::string>::const_iterator a(tokens.begin()); a != tokens.end(); ++a)
2278 // printf("%s\n", a->c_str());
2281 int sort = eDVBChannelQuery::tName;
2282 /* check for "ORDER BY ..." */
2284 std::list<std::string>::iterator it = tokens.begin();
2285 while (it != tokens.end())
2290 if (it != tokens.end() && *it == "BY")
2293 sort = decodeType(*it);
2298 else if (*it == "FROM")
2301 if (it != tokens.end() && *it == "BOUQUET")
2307 else if (it != tokens.end() && *it == "SATELLITES")
2309 else if (it != tokens.end() && *it == "PROVIDERS")
2313 eDebug("[eDVBChannelQuery] FROM unknown %s", (*it).c_str());
2323 eWarning("[eDVBChannelQuery] ORDER BY .. string invalid.");
2328 // eDebug("[eDVBChannelQuery] sort by %d", sort);
2330 /* now we recursivly parse that. */
2331 int r = parseExpression(res, tokens.begin(), tokens.end());
2333 /* we have an empty (but valid!) expression */
2336 res = new eDVBChannelQuery();
2338 res->m_type = eDVBChannelQuery::tAny;
2344 res->m_bouquet_name = bouquet_name;
2347 // eDebug("[eDVBChannelQuery] return: %d", r);
2351 DEFINE_REF(eDVBChannelQuery);