Update EPG Cache(thanks to open source community)
[vuplus_dvbapp] / lib / dvb / db.cpp
index 110cedd..dadca4d 100644 (file)
@@ -3,6 +3,7 @@
 #include <lib/dvb/dvb.h>
 #include <lib/dvb/frontend.h>
 #include <lib/dvb/epgcache.h>
+#include <lib/base/eenv.h>
 #include <lib/base/eerror.h>
 #include <lib/base/estring.h>
 #include <xmlccwrap/xmlccwrap.h>
@@ -73,7 +74,7 @@ RESULT eBouquet::moveService(const eServiceReference &ref, unsigned int pos)
 
 RESULT eBouquet::flushChanges()
 {
-       FILE *f=fopen((CONFIGDIR"/enigma2/"+m_filename).c_str(), "w");
+       FILE *f=fopen(eEnv::resolve("${sysconfdir}/enigma2/" + m_filename).c_str(), "w");
        if (!f)
                return -1;
        if ( fprintf(f, "#NAME %s\r\n", m_bouquet_name.c_str()) < 0 )
@@ -159,9 +160,10 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc
        else
        {
                eDVBChannelID chid, chid_ignore;
+               int system;
                ((const eServiceReferenceDVB&)ref).getChannelID(chid);
                ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
-               return res_mgr->canAllocateChannel(chid, chid_ignore, simulate);
+               return res_mgr->canAllocateChannel(chid, chid_ignore, system, simulate);
        }
        return 0;
 }
@@ -172,14 +174,32 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ
        switch (query.m_type)
        {
        case eDVBChannelQuery::tName:
-               res = m_service_name_sort.find(query.m_string) != std::string::npos;
+               res = m_service_name_sort == query.m_string;
                break;
        case eDVBChannelQuery::tProvider:
-               res = m_provider_name.find(query.m_string) != std::string::npos;
+               if (query.m_string == "Unknown" && m_provider_name.empty())
+                       res = 1;
+               else
+                       res = m_provider_name == query.m_string;
                break;
        case eDVBChannelQuery::tType:
-               res = ref.getServiceType() == query.m_int;
+       {
+               int service_type = ref.getServiceType();
+               if (query.m_int == 1) // TV Service
+               {
+                       // Hack for dish network
+                       int onid = ref.getOriginalNetworkID().get();
+                       if (onid >= 0x1001 && onid <= 0x100b)
+                       {
+                               static int dish_tv_types[] = { 128, 133, 137, 140, 144, 145, 150, 154, 160, 163, 164, 165, 166, 167, 168, 173, 174 };
+                               static size_t dish_tv_num_types = sizeof(dish_tv_types) / sizeof(int);
+                               if (std::binary_search(dish_tv_types, dish_tv_types + dish_tv_num_types, service_type))
+                                       return true;
+                       }
+               }
+               res = service_type == query.m_int;
                break;
+       }
        case eDVBChannelQuery::tBouquet:
                res = 0;
                break;
@@ -262,7 +282,43 @@ DEFINE_REF(eDVBDB);
 
 void eDVBDB::reloadServicelist()
 {
-       loadServicelist(CONFIGDIR"/enigma2/lamedb");
+       loadServicelist(eEnv::resolve("${sysconfdir}/enigma2/lamedb").c_str());
+}
+
+void eDVBDB::parseServiceData(ePtr<eDVBService> s, std::string str)
+{
+       while ((!str.empty()) && str[1]==':') // new: p:, f:, c:%02d...
+       {
+               size_t c=str.find(',');
+               char p=str[0];
+               std::string v;
+               if (c == std::string::npos)
+               {
+                       v=str.substr(2);
+                       str="";
+               } else
+               {
+                       v=str.substr(2, c-2);
+                       str=str.substr(c+1);
+               }
+//             eDebug("%c ... %s", p, v.c_str());
+               if (p == 'p')
+                       s->m_provider_name=v;
+               else if (p == 'f')
+               {
+                       sscanf(v.c_str(), "%x", &s->m_flags);
+               } else if (p == 'c')
+               {
+                       int cid, val;
+                       sscanf(v.c_str(), "%02d%x", &cid, &val);
+                       s->setCacheEntry((eDVBService::cacheID)cid,val);
+               } else if (p == 'C')
+               {
+                       int val;
+                       sscanf(v.c_str(), "%04x", &val);
+                       s->m_ca.push_front((uint16_t)val);
+               }
+       }
 }
 
        /* THIS CODE IS BAD. it should be replaced by somethine better. */
@@ -270,19 +326,11 @@ void eDVBDB::loadServicelist(const char *file)
 {
        eDebug("---- opening lame channel db");
        FILE *f=fopen(file, "rt");
-       if (!f && strcmp(file, CONFIGDIR"/enigma2/lamedb") == 0)
-       {
-               struct stat s;
-               if ( !stat("lamedb", &s) )
-               {
-                       if ( !stat(CONFIGDIR"/enigma2", &s) )
-                       {
-                               rename("lamedb", CONFIGDIR"/enigma2/lamedb" );
-                               reloadServicelist();
-                       }
-               }
+       if (!f) {
+               eDebug("can't open %s: %m", file);
                return;
        }
+
        char line[256];
        int version=3;
        if ((!fgets(line, 256, f)) || sscanf(line, "eDVB services /%d/", &version) != 1)
@@ -330,11 +378,17 @@ void eDVBDB::loadServicelist(const char *file)
                                        system=eDVBFrontendParametersSatellite::System_DVB_S,
                                        modulation=eDVBFrontendParametersSatellite::Modulation_QPSK,
                                        rolloff=eDVBFrontendParametersSatellite::RollOff_alpha_0_35,
-                                       pilot=eDVBFrontendParametersSatellite::Pilot_Unknown;
+                                       pilot=eDVBFrontendParametersSatellite::Pilot_Unknown,
+                                       is_id = NO_STREAM_ID_FILTER,
+                                       pls_code = 0,
+                                       pls_mode = eDVBFrontendParametersSatellite::PLS_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);
+                                       sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+                                               &frequency, &symbol_rate, &polarisation, &fec, &orbital_position,
+                                               &inversion, &flags, &system, &modulation, &rolloff, &pilot,
+                                               &is_id, &pls_code, &pls_mode);
                                sat.frequency = frequency;
                                sat.symbol_rate = symbol_rate;
                                sat.polarisation = polarisation;
@@ -346,13 +400,17 @@ void eDVBDB::loadServicelist(const char *file)
                                sat.modulation = modulation;
                                sat.rolloff = rolloff;
                                sat.pilot = pilot;
+                               sat.is_id = is_id;
+                               sat.pls_mode = pls_mode & 3;
+                               sat.pls_code = pls_code & 0x3FFFF;
                                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, 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);
+                               int frequency, bandwidth, code_rate_HP, code_rate_LP, modulation, transmission_mode, guard_interval, hierarchy, inversion, flags = 0, plpid = 0;
+                               int system=eDVBFrontendParametersTerrestrial::System_DVB_T;
+                               sscanf(line+3, "%d:%d:%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, &system, &plpid);
                                ter.frequency = frequency;
                                ter.bandwidth = bandwidth;
                                ter.code_rate_HP = code_rate_HP;
@@ -362,6 +420,8 @@ void eDVBDB::loadServicelist(const char *file)
                                ter.guard_interval = guard_interval;
                                ter.hierarchy = hierarchy;
                                ter.inversion = inversion;
+                               ter.system = system;
+                               ter.plpid = plpid;
                                feparm->setDVBT(ter);
                                feparm->setFlags(flags);
                        } else if (line[1]=='c')
@@ -425,44 +485,10 @@ void eDVBDB::loadServicelist(const char *file)
                fgets(line, 256, f);
                if (strlen(line))
                        line[strlen(line)-1]=0;
-               std::string str=line;
-
-               if (str[1]!=':')        // old ... (only service_provider)
-               {
+               if (line[1]!=':')       // old ... (only service_provider)
                        s->m_provider_name=line;
-               } else
-                       while ((!str.empty()) && str[1]==':') // new: p:, f:, c:%02d...
-                       {
-                               size_t c=str.find(',');
-                               char p=str[0];
-                               std::string v;
-                               if (c == std::string::npos)
-                               {
-                                       v=str.substr(2);
-                                       str="";
-                               } else
-                               {
-                                       v=str.substr(2, c-2);
-                                       str=str.substr(c+1);
-                               }
-//                             eDebug("%c ... %s", p, v.c_str());
-                               if (p == 'p')
-                                       s->m_provider_name=v;
-                               else if (p == 'f')
-                               {
-                                       sscanf(v.c_str(), "%x", &s->m_flags);
-                               } else if (p == 'c')
-                               {
-                                       int cid, val;
-                                       sscanf(v.c_str(), "%02d%x", &cid, &val);
-                                       s->setCacheEntry((eDVBService::cacheID)cid,val);
-                               } else if (p == 'C')
-                               {
-                                       int val;
-                                       sscanf(v.c_str(), "%04x", &val);
-                                       s->m_ca.push_front((uint16_t)val);
-                               }
-                       }
+               else
+                       parseServiceData(s, line);
                addService(ref, s);
        }
 
@@ -495,34 +521,30 @@ void eDVBDB::saveServicelist(const char *file)
                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:%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,
-                                       flags,
-                                       sat.system,
-                                       sat.modulation,
-                                       sat.rolloff,
-                                       sat.pilot);
-                       }
-                       else
+                       fprintf(f, "\ts %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);
+
+                       if ((sat.system == eDVBFrontendParametersSatellite::System_DVB_S2) || (sat.system == eDVBFrontendParametersSatellite::System_DVB_S2X))
                        {
-                               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, flags);
+                               fprintf(f, ":%d:%d:%d:%d", sat.system, sat.modulation, sat.rolloff, sat.pilot);
+
+                               if (static_cast<unsigned int>(sat.is_id) != NO_STREAM_ID_FILTER ||
+                                       (sat.pls_code & 0x3FFFF) != 0 ||
+                                       (sat.pls_mode & 3) != eDVBFrontendParametersSatellite::PLS_Unknown)
+                               {
+                                       fprintf(f, ":%d:%d:%d", sat.is_id, sat.pls_code & 0x3FFFF, sat.pls_mode & 3);
+                               }
                        }
+                       fprintf(f, "\n");
                }
                else if (!ch.m_frontendParameters->getDVBT(ter))
                {
-                       fprintf(f, "\tt %d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+                       fprintf(f, "\tt %d:%d:%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, flags);
+                               ter.guard_interval, ter.hierarchy, ter.inversion, flags, ter.system, ter.plpid);
                }
                else if (!ch.m_frontendParameters->getDVBC(cab))
                {
@@ -574,7 +596,7 @@ void eDVBDB::saveServicelist(const char *file)
 
 void eDVBDB::saveServicelist()
 {
-       saveServicelist(CONFIGDIR"/enigma2/lamedb");
+       saveServicelist(eEnv::resolve("${sysconfdir}/enigma2/lamedb").c_str());
 }
 
 void eDVBDB::loadBouquet(const char *path)
@@ -598,28 +620,20 @@ void eDVBDB::loadBouquet(const char *path)
        std::list<eServiceReference> &list = bouquet.m_services;
        list.clear();
 
-       std::string p = CONFIGDIR"/enigma2/";
+       std::string p = eEnv::resolve("${sysconfdir}/enigma2/");
        p+=path;
        eDebug("loading bouquet... %s", p.c_str());
        FILE *fp=fopen(p.c_str(), "rt");
-       int entries=0;
        if (!fp)
        {
-               struct stat s;
-               if ( !stat(path, &s) )
-               {
-                       rename(path, p.c_str() );
-                       loadBouquet(path);
-                       return;
-               }
-               eDebug("failed to open.");
-               if ( strstr(path, "bouquets.tv") )
+               eDebug("can't open %s: %m", p.c_str());
+               if (!strcmp(path, "bouquets.tv"))
                {
                        eDebug("recreate bouquets.tv");
                        bouquet.m_bouquet_name="Bouquets (TV)";
                        bouquet.flushChanges();
                }
-               else if ( strstr(path, "bouquets.radio") )
+               else if (!strcmp(path, "bouquets.radio"))
                {
                        eDebug("recreate bouquets.radio");
                        bouquet.m_bouquet_name="Bouquets (Radio)";
@@ -627,29 +641,25 @@ void eDVBDB::loadBouquet(const char *path)
                }
                return;
        }
-       char line[256];
+       int entries=0;
+       size_t linesize = 256;
+       char *line = (char*)malloc(linesize);
        bool read_descr=false;
        eServiceReference *e = NULL;
        while (1)
        {
-               if (!fgets(line, 256, fp))
-                       break;
-               line[strlen(line)-1]=0;
-               if (strlen(line) && line[strlen(line)-1]=='\r')
-                       line[strlen(line)-1]=0;
-               if (!line[0])
-                       break;
+               int len;
+               if ((len = getline(&line, &linesize, fp)) < 2) break;
+               /* strip newline */
+               line[--len] = 0;
+               /* strip carriage return (when found) */
+               if (line[len - 1] == '\r') line[--len] = 0;
                if (line[0]=='#')
                {
                        if (!strncmp(line, "#SERVICE", 8))
                        {
                                int offs = line[8] == ':' ? 10 : 9;
                                eServiceReference tmp(line+offs);
-                               if (tmp.type != eServiceReference::idDVB)
-                               {
-                                       eDebug("only DVB Bouquets supported");
-                                       continue;
-                               }
                                if ( tmp.flags&eServiceReference::canDescent )
                                {
                                        size_t pos = tmp.path.rfind('/');
@@ -699,6 +709,7 @@ void eDVBDB::loadBouquet(const char *path)
                        continue;
                }
        }
+       free(line);
        fclose(fp);
        eDebug("%d entries in Bouquet %s", entries, bouquet_name.c_str());
 }
@@ -786,7 +797,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
                return Py_False;
        }
        int tmp, *dest = NULL,
-               modulation, system, freq, sr, pol, fec, inv, pilot, rolloff, tsid, onid;
+               modulation, system, freq, sr, pol, fec, inv, pilot, rolloff, is_id, pls_code, pls_mode, tsid, onid;
        char *end_ptr;
        const Attribute *at;
        std::string name;
@@ -839,7 +850,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
                        PyDict_SetItem(tp_dict, sat_pos, tplist);
                        for (ElementConstIterator it(sat_elements.begin()); it != sat_elements.end(); ++it)
                        {
-//                             eDebug("\telement: %s", (*it)->name().c_str());
+                               //eDebug("\telement: %s", (*it)->name().c_str());
                                const AttributeList &tp_attributes = (*it)->getAttributeList();
                                AttributeConstIterator end = tp_attributes.end();
                                modulation = eDVBFrontendParametersSatellite::Modulation_QPSK;
@@ -851,13 +862,16 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
                                inv = eDVBFrontendParametersSatellite::Inversion_Unknown;
                                pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
                                rolloff = eDVBFrontendParametersSatellite::RollOff_alpha_0_35;
+                               is_id = NO_STREAM_ID_FILTER;
+                               pls_code = 0;
+                               pls_mode = eDVBFrontendParametersSatellite::PLS_Unknown;
                                tsid = -1;
                                onid = -1;
 
                                for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
                                {
-                                       //eDebug("\t\tattr: %s", at->name().c_str());
                                        at = *it;
+                                       //eDebug("\t\tattr: %s", at->name().c_str());
                                        name = at->name();
                                        if (name == "modulation") dest = &modulation;
                                        else if (name == "system") dest = &system;
@@ -868,10 +882,15 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
                                        else if (name == "inversion") dest = &inv;
                                        else if (name == "rolloff") dest = &rolloff;
                                        else if (name == "pilot") dest = &pilot;
+                                       else if (name == "is_id") dest = &is_id;
+                                       else if (name == "pls_code") dest = &pls_code;
+                                       else if (name == "pls_mode") dest = &pls_mode;
                                        else if (name == "tsid") dest = &tsid;
                                        else if (name == "onid") dest = &onid;
+                                       else continue;
                                        if (dest)
                                        {
+                                               //eDebug("\t\t\tvalue: %s", at->value().c_str());
                                                tmp = strtol(at->value().c_str(), &end_ptr, 10);
                                                if (!*end_ptr)
                                                        *dest = tmp;
@@ -879,7 +898,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
                                }
                                if (freq && sr && pol != -1)
                                {
-                                       tuple = PyTuple_New(12);
+                                       tuple = PyTuple_New(15);
                                        PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
                                        PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq));
                                        PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(sr));
@@ -890,8 +909,11 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
                                        PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong(inv));
                                        PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong(rolloff));
                                        PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong(pilot));
-                                       PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(tsid));
-                                       PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(onid));
+                                       PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(is_id));
+                                       PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(pls_mode & 3));
+                                       PyTuple_SET_ITEM(tuple, 12, PyInt_FromLong(pls_code & 0x3FFFF));
+                                       PyTuple_SET_ITEM(tuple, 13, PyInt_FromLong(tsid));
+                                       PyTuple_SET_ITEM(tuple, 14, PyInt_FromLong(onid));
                                        PyList_Append(tplist, tuple);
                                        Py_DECREF(tuple);
                                }
@@ -995,6 +1017,7 @@ PyObject *eDVBDB::readCables(ePyObject cab_list, ePyObject tp_dict)
                                        else if (name == "frequency") dest = &freq;
                                        else if (name == "symbol_rate") dest = &sr;
                                        else if (name == "fec_inner") dest = &fec;
+                                       else continue;
                                        if (dest)
                                        {
                                                tmp = strtol(at->value().c_str(), &end_ptr, 10);
@@ -1053,7 +1076,8 @@ PyObject *eDVBDB::readTerrestrials(ePyObject ter_list, ePyObject tp_dict)
        const Attribute *at;
        std::string name;
        int tmp, *dest,
-               freq, bw, constellation, crh = 5, crl = 5, guard = 4, transm, hierarchy, inv = 2;
+//             freq, bw, constellation, crh = 5, crl = 5, guard = 4, transm, hierarchy, inv = 2;
+               freq, bw, constellation, crh, crl, guard, transm, hierarchy, inv, system, plpid;
        char *end_ptr;
        const ElementList &root_elements = root->getElementList();
        for (ElementConstIterator it(root_elements.begin()); it != root_elements.end(); ++it)
@@ -1103,6 +1127,8 @@ PyObject *eDVBDB::readTerrestrials(ePyObject ter_list, ePyObject tp_dict)
                                transm = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto;
                                hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
                                inv = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
+                               system = eDVBFrontendParametersTerrestrial::System_DVB_T;
+                               plpid = 0;
                                for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
                                {
 //                                     eDebug("\t\tattr: %s", at->name().c_str());
@@ -1118,6 +1144,9 @@ PyObject *eDVBDB::readTerrestrials(ePyObject ter_list, ePyObject tp_dict)
                                        else if (name == "transmission_mode") dest = &transm;
                                        else if (name == "hierarchy_information") dest = &hierarchy;
                                        else if (name == "inversion") dest = &inv;
+                                       else if (name == "system") dest = &system;
+                                       else if (name == "plp_id") dest = &plpid;
+                                       else continue;
                                        if (dest)
                                        {
                                                tmp = strtol(at->value().c_str(), &end_ptr, 10);
@@ -1127,11 +1156,11 @@ PyObject *eDVBDB::readTerrestrials(ePyObject ter_list, ePyObject tp_dict)
                                }
                                if (freq)
                                {
-                                       if (crh > 5) // our terrestrial.xml is buggy... 6 for AUTO
-                                               crh = 5;
-                                       if (crl > 5) // our terrestrial.xml is buggy... 6 for AUTO
-                                               crl = 5;
-                                       tuple = PyTuple_New(10);
+                                       if (crh > eDVBFrontendParametersTerrestrial::FEC_8_9)
+                                               crh = eDVBFrontendParametersTerrestrial::FEC_Auto;
+                                       if (crl > eDVBFrontendParametersTerrestrial::FEC_8_9)
+                                               crl = eDVBFrontendParametersTerrestrial::FEC_Auto;
+                                       tuple = PyTuple_New(12);
                                        PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(2));
                                        PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq));
                                        PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(bw));
@@ -1142,6 +1171,8 @@ PyObject *eDVBDB::readTerrestrials(ePyObject ter_list, ePyObject tp_dict)
                                        PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong(transm));
                                        PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong(hierarchy));
                                        PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong(inv));
+                                       PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(system));
+                                       PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(plpid));
                                        PyList_Append(tplist, tuple);
                                        Py_DECREF(tuple);
                                }
@@ -1373,7 +1404,7 @@ RESULT eDVBDB::addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters
 {
        channel ch;
        std::map<eDVBChannelID, channel>::iterator it = m_channels.find(id);
-       assert(feparm);
+       ASSERT(feparm);
        ch.m_frontendParameters = feparm;
        if (it != m_channels.end())
                it->second = ch;
@@ -1495,6 +1526,21 @@ eServiceReference eDVBDB::searchReference(int tsid, int onid, int sid)
        return eServiceReference();
 }
 
+void eDVBDB::searchAllReferences(std::vector<eServiceReference> &result, int tsid, int onid, int sid)
+{
+       eServiceID Sid(sid);
+       eTransportStreamID Tsid(tsid);
+       eOriginalNetworkID Onid(onid);
+       for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator sit(m_services.begin());
+               sit != m_services.end(); ++sit)
+       {
+               if (sit->first.getTransportStreamID() == Tsid &&
+                       sit->first.getOriginalNetworkID() == Onid &&
+                       sit->first.getServiceID() == Sid)
+                       result.push_back(sit->first);
+       }
+}
+
 DEFINE_REF(eDVBDBQueryBase);
 
 eDVBDBQueryBase::eDVBDBQueryBase(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)