#include <lib/dvb/db.h>
#include <lib/dvb/frontend.h>
#include <lib/base/eerror.h>
-#include <lib/dvb_si/sdt.h>
-#include <lib/dvb_si/descriptor_tag.h>
-#include <lib/dvb_si/service_descriptor.h>
-#include <lib/dvb_si/satellite_delivery_system_descriptor.h>
+#include <lib/base/estring.h>
+#include <dvbsi++/service_description_section.h>
+#include <dvbsi++/descriptor_tag.h>
+#include <dvbsi++/service_descriptor.h>
+#include <dvbsi++/satellite_delivery_system_descriptor.h>
DEFINE_REF(eDVBService);
RESULT eDVBService::getName(const eServiceReference &ref, std::string &name)
{
- name = m_service_name;
+ name = convertDVBUTF8(m_service_name);
+ return 0;
+}
+
+int eDVBService::getLength(const eServiceReference &ref)
+{
+ return -1;
}
int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query)
return res;
}
+int eDVBService::getCachePID(cacheID id)
+{
+ std::map<int, int>::iterator it = m_cache.find(id);
+ if ( it != m_cache.end() )
+ return it->second;
+ return -1;
+}
+
+void eDVBService::setCachePID(cacheID id, int pid)
+{
+ m_cache[id] = pid;
+}
+
DEFINE_REF(eDVBDB);
-eDVBDB::eDVBDB()
+ /* THIS CODE IS BAD. it should be replaced by somethine better. */
+void eDVBDB::load()
{
eDebug("---- opening lame channel db");
FILE *f=fopen("lamedb", "rt");
fclose(f);
return;
}
-
+
// clear all transponders
while (!feof(f))
if (original_network_id == -1)
continue;
eDVBChannelID channelid = eDVBChannelID(
- eDVBNamespace(dvb_namespace),
- eTransportStreamID(transport_stream_id),
+ eDVBNamespace(dvb_namespace),
+ eTransportStreamID(transport_stream_id),
eOriginalNetworkID(original_network_id));
-
+
ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
while (!feof(f))
{
// ...
// t.setSatellite(frequency, symbol_rate, polarisation, fec, sat, inversion);
feparm->setDVBS(sat);
- }
- if (line[1]=='c')
+ } else if (line[1]=='t')
+ {
+ eDVBFrontendParametersTerrestrial ter;
+ int frequency, bandwidth, code_rate_HP, code_rate_LP, modulation, transmission_mode, guard_interval, hierarchy, inversion;
+ sscanf(line+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &bandwidth, &code_rate_HP, &code_rate_LP, &modulation, &transmission_mode, &guard_interval, &hierarchy, &inversion);
+ ter.frequency = frequency;
+ ter.bandwidth = bandwidth;
+ ter.code_rate_HP = code_rate_HP;
+ ter.code_rate_LP = code_rate_LP;
+ ter.modulation = modulation;
+ ter.transmission_mode = transmission_mode;
+ 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);
eDebug("services invalid, no services");
return;
}
-
+
// clear all services
-
+
int count=0;
while (!feof(f))
if (service_number == -1)
continue;
ePtr<eDVBService> s = new eDVBService;
- eServiceReferenceDVB ref =
+ eServiceReferenceDVB ref =
eServiceReferenceDVB(
eDVBNamespace(dvb_namespace),
eTransportStreamID(transport_stream_id),
}
eDebug("loaded %d services", count);
-
+
fclose(f);
-
}
-eDVBDB::~eDVBDB()
+void eDVBDB::save()
{
eDebug("---- saving lame channel db");
FILE *f=fopen("lamedb", "wt");
int channels=0, services=0;
if (!f)
- eFatal("couldn't save lame channel db!");
+ eFatal("couldn't save lame channel db!");
fprintf(f, "eDVB services /3/\n");
fprintf(f, "transponders\n");
for (std::map<eDVBChannelID, channel>::const_iterator i(m_channels.begin());
{
const eDVBChannelID &chid = i->first;
const channel &ch = i->second;
-
+
fprintf(f, "%08x:%04x:%04x\n", chid.dvbnamespace.get(),
chid.transport_stream_id.get(), chid.original_network_id.get());
eDVBFrontendParametersSatellite sat;
+ eDVBFrontendParametersTerrestrial ter;
if (!ch.m_frontendParameters->getDVBS(sat))
{
- fprintf(f, "\ts %d:%d:%d:%d:%d:%d\n",
+ fprintf(f, "\ts %d:%d:%d:%d:%d:%d\n",
sat.frequency, sat.symbol_rate,
sat.polarisation, sat.fec, sat.inversion,
sat.orbital_position);
}
+ if (!ch.m_frontendParameters->getDVBT(ter))
+ {
+ fprintf(f, "\tt %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);
+ }
fprintf(f, "/\n");
channels++;
}
fprintf(f, "end\nservices\n");
-
+
for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator i(m_services.begin());
i != m_services.end(); ++i)
{
const eServiceReferenceDVB &s = i->first;
- fprintf(f, "%04x:%08x:%04x:%04x:%d:%d\n",
- s.getServiceID().get(), s.getDVBNamespace().get(),
- s.getTransportStreamID().get(),s.getOriginalNetworkID().get(),
+ fprintf(f, "%04x:%08x:%04x:%04x:%d:%d\n",
+ s.getServiceID().get(), s.getDVBNamespace().get(),
+ s.getTransportStreamID().get(),s.getOriginalNetworkID().get(),
s.getServiceType(),
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<int,int>::const_iterator ca(i->second->m_cache.begin());
+ ca != i->second->m_cache.end(); ++ca)
+ fprintf(f, ",c:%02d%04x", ca->first, ca->second);
+
+ // write cached ca pids
for (std::set<int>::const_iterator ca(i->second->m_ca.begin());
ca != i->second->m_ca.end(); ++ca)
fprintf(f, ",C:%04x", *ca);
+
fprintf(f, "\n");
services++;
}
fclose(f);
}
+eDVBDB::eDVBDB()
+{
+ load();
+}
+
+eDVBDB::~eDVBDB()
+{
+// save();
+}
+
RESULT eDVBDB::addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm)
{
channel ch;
RESULT eDVBDB::startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *q)
{
- query = new eDVBDBQuery(this, q);
+ query = new eDVBDBQuery(this, eServiceReference(), q);
return 0;
}
DEFINE_REF(eDVBDBQuery);
-eDVBDBQuery::eDVBDBQuery(eDVBDB *db, eDVBChannelQuery *query): m_db(db), m_query(query)
+eDVBDBQuery::eDVBDBQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query): m_db(db), m_query(query)
{
+ // TODO: use SOURCE ...
m_cursor = m_db->m_services.begin();
}
return 1;
}
+/* (<name|provider|type|bouquet|satpos|chid> <==|...> <"string"|int>)[AND (..)] */
+
+ /* never, NEVER write a parser in C++! */
+RESULT parseExpression(ePtr<eDVBChannelQuery> &res, std::list<std::string>::const_iterator begin, std::list<std::string>::const_iterator end)
+{
+ std::list<std::string>::const_iterator end_of_exp;
+ if (*begin == "(")
+ {
+ end_of_exp = begin;
+ while (end_of_exp != end)
+ if (*end_of_exp == ")")
+ break;
+ else
+ ++end_of_exp;
+
+ if (end_of_exp == end)
+ {
+ eDebug("expression parse: end of expression while searching for closing brace");
+ return -1;
+ }
+
+ ++begin;
+ // begin..end_of_exp
+ int r = parseExpression(res, begin, end_of_exp);
+ if (r)
+ return r;
+ ++end_of_exp;
+
+ /* we had only one sub expression */
+ if (end_of_exp == end)
+ return 1;
+
+ /* otherwise we have an operator here.. */
+
+ ePtr<eDVBChannelQuery> r2 = res;
+ res = new eDVBChannelQuery();
+ res->m_p1 = r2;
+ res->m_inverse = 0;
+ r2 = 0;
+
+ if (*end_of_exp == "||")
+ res->m_type = eDVBChannelQuery::tOR;
+ else if (*end_of_exp == "&&")
+ res->m_type = eDVBChannelQuery::tAND;
+ else
+ {
+ eDebug("found operator %s, but only && and || are allowed!", end_of_exp->c_str());
+ res = 0;
+ return 1;
+ }
+
+ ++end_of_exp;
+
+ return parseExpression(res->m_p2, end_of_exp, end);
+ }
+
+ // "begin" <op> "end"
+ std::string type, op, val;
+
+ res = new eDVBChannelQuery();
+
+ int cnt = 0;
+ while (begin != end)
+ {
+ switch (cnt)
+ {
+ case 0:
+ type = *begin;
+ break;
+ case 1:
+ op = *begin;
+ break;
+ case 2:
+ val = *begin;
+ break;
+ case 3:
+ eDebug("malformed query: got '%s', but expected only <type> <op> <val>", begin->c_str());
+ return 1;
+ }
+ ++begin;
+ ++cnt;
+ }
+
+ if (cnt != 3)
+ {
+ eDebug("malformed query: missing stuff");
+ res = 0;
+ return 1;
+ }
+
+ if (type == "name")
+ res->m_type = eDVBChannelQuery::tName;
+ else if (type == "provider")
+ res->m_type = eDVBChannelQuery::tProvider;
+ else if (type == "type")
+ res->m_type = eDVBChannelQuery::tType;
+ else if (type == "bouquet")
+ res->m_type = eDVBChannelQuery::tBouquet;
+ else if (type == "satellitePosition")
+ res->m_type = eDVBChannelQuery::tSatellitePosition;
+ else if (type == "channelID")
+ res->m_type = eDVBChannelQuery::tChannelID;
+ else
+ {
+ eDebug("malformed query: invalid type %s", type.c_str());
+ res = 0;
+ return 1;
+ }
+
+ eDebug("type is %d, nice!", res->m_type);
+
+ if (op == "==")
+ res->m_inverse = 0;
+ else if (op == "!=")
+ res->m_inverse = 1;
+ else
+ {
+ eDebug("invalid operator %s", op.c_str());
+ res = 0;
+ return 1;
+ }
+
+ res->m_string = val;
+ res->m_int = atoi(val.c_str());
+// res->m_channelid = eDVBChannelID(val);
+
+ return 0;
+}
+
RESULT eDVBChannelQuery::compile(ePtr<eDVBChannelQuery> &res, std::string query)
{
+ std::list<std::string> tokens;
+
+ std::string current_token;
+
+// eDebug("splitting %s....", query.c_str());
+ unsigned int i = 0;
+ const char *splitchars="()";
+ int quotemode = 0, lastsplit = 0, lastalnum = 0;
+ while (i <= query.size())
+ {
+ int c = (i < query.size()) ? query[i] : ' ';
+ ++i;
+
+ int issplit = !!strchr(splitchars, c);
+ int isaln = isalnum(c);
+ int iswhite = c == ' ';
+ int isquot = c == '\"';
+
+ if (quotemode)
+ {
+ iswhite = issplit = 0;
+ isaln = lastalnum;
+ }
+
+ if (issplit || iswhite || isquot || lastsplit || (lastalnum != isaln))
+ {
+ if (current_token.size())
+ tokens.push_back(current_token);
+ current_token.clear();
+ }
+
+ if (!(iswhite || isquot))
+ current_token += c;
+
+ if (isquot)
+ quotemode = !quotemode;
+ lastsplit = issplit;
+ lastalnum = isaln;
+ }
+
+// for (std::list<std::string>::const_iterator a(tokens.begin()); a != tokens.end(); ++a)
+// {
+// printf("%s\n", a->c_str());
+// }
+
+ /* now we recursivly parse that. */
+ return parseExpression(res, tokens.begin(), tokens.end());
+/*
res = new eDVBChannelQuery();
res->m_type = eDVBChannelQuery::tName;
res->m_inverse = 0;
res->m_string = query;
- return 0;
+ return 0; */
}
DEFINE_REF(eDVBChannelQuery);