summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--p2pvr/scanner/Jamfile.jam7
-rw-r--r--p2pvr/scanner/crc32.cpp61
-rw-r--r--p2pvr/scanner/dvbSiReaderHelper.cpp130
-rw-r--r--p2pvr/scanner/dvbSiReaderHelper.h34
-rw-r--r--p2pvr/scanner/dvb_info_tables.c284
-rw-r--r--p2pvr/scanner/eitRows.cpp (renamed from p2pvr/scanner/p2scan.cpp)296
-rw-r--r--p2pvr/scanner/eitRows.h42
-rw-r--r--p2pvr/scanner/lookup.cpp52
-rw-r--r--p2pvr/scanner/tv_grab_dvb.h32
9 files changed, 282 insertions, 656 deletions
diff --git a/p2pvr/scanner/Jamfile.jam b/p2pvr/scanner/Jamfile.jam
index d784eeb..7288b23 100644
--- a/p2pvr/scanner/Jamfile.jam
+++ b/p2pvr/scanner/Jamfile.jam
@@ -3,14 +3,11 @@ project
<variant>debug:<linkflags>-Wl,-z,defs <cflags>"-W -Wall -Werror -Wwrite-strings"
;
-# Scanner base - the common part lifted from tv_grab_dvb
-lib p2pvr-scan-base : crc32.cpp dvb_info_tables.c lookup.cpp ;
-
# Scanner - the common part implementing the ICE interface
-lib p2pvr-scan-ice : icescan.cpp scanner.ice : <library>p2pvr-scan-base ;
+lib p2pvr-scan-ice : icescan.cpp scanner.ice : <library>p2pvr-scan-p2 ;
# Scanner - t
-lib p2pvr-scan-p2 : p2scan.cpp : <library>p2pvr-scan-base <library>../../project2//p2common ;
+lib p2pvr-scan-p2 : eitRows.cpp dvbSiReaderHelper.cpp : <library>../../project2//p2common ;
# ScannerICE - the ICE test app
#exe scanice : ice_scan.cpp : <library>p2pvr-scan ;
diff --git a/p2pvr/scanner/crc32.cpp b/p2pvr/scanner/crc32.cpp
deleted file mode 100644
index 3dec763..0000000
--- a/p2pvr/scanner/crc32.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/* crc32.c: CRC32 routine
- */
-#include <stdio.h>
-#include <stdint.h>
-
-static const uint32_t crc_table[256] = {
- 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
- 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
- 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
- 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
- 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
- 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
- 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
- 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
- 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
- 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
- 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
- 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
- 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
- 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
- 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
- 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
- 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
- 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
- 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
- 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
- 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
- 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
- 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
- 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
- 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
- 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
- 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
- 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
- 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
- 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
- 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
- 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
- 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
- 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
- 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
- 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
- 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
- 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
- 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
- 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
- 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
- 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
- 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
-};
-
-uint32_t _dvb_crc32(const uint8_t *data, size_t len)
-{
- size_t i;
- uint32_t crc = 0xffffffff;
-
- for (i = 0; i < len; i++)
- crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff];
-
- return crc;
-}
diff --git a/p2pvr/scanner/dvbSiReaderHelper.cpp b/p2pvr/scanner/dvbSiReaderHelper.cpp
new file mode 100644
index 0000000..015a60c
--- /dev/null
+++ b/p2pvr/scanner/dvbSiReaderHelper.cpp
@@ -0,0 +1,130 @@
+#include "dvbSiReaderHelper.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <glibmm.h>
+#include <sys/poll.h>
+#include "si_tables.h"
+#include <boost/crc.hpp>
+
+SimpleMessageException(ErrorReadingData);
+SimpleMessageException(TimeoutReadingData);
+SimpleMessageException(DemuxOpenFailure);
+
+const std::string DvbSiReaderHelper::ISO10646("ISO-10646");
+const std::string DvbSiReaderHelper::EitEncoding("ISO6937");
+const std::string DvbSiReaderHelper::UTF8("UTF8");
+
+DvbSiReaderHelper::DvbSiReaderHelper(const xmlpp::Element * p) :
+ demux(p, "demux", false, "/dev/dvb/adapter0/demux0"),
+ timeout(p, "timeout", false, 10000),
+ fd_epg(0)
+{
+}
+
+DvbSiReaderHelper::~DvbSiReaderHelper()
+{
+ closeInput();
+}
+
+void
+DvbSiReaderHelper::openInput() const
+{
+ if ((fd_epg = open(demux(), O_RDWR)) < 0) {
+ throw DemuxOpenFailure(strerror(errno));
+ }
+ filterInput(fd_epg);
+}
+
+void
+DvbSiReaderHelper::closeInput() const
+{
+ if (fd_epg) {
+ close(fd_epg);
+ fd_epg = 0;
+ }
+}
+
+VariableType
+DvbSiReaderHelper::convert(const char * txt, size_t len)
+{
+ char enc[20];
+ switch (*txt) {
+ default:
+ EitEncoding.copy(enc, EitEncoding.length());
+ enc[EitEncoding.length()] = '\0';
+ break;
+ case 0x01 ... 0x05:
+ snprintf(enc, sizeof(enc), "ISO-8859-%d\n", txt[0] + 4);
+ txt += 1;
+ len -= 1;
+ break;
+ case 0x10:
+ snprintf(enc, sizeof(enc), "ISO-8859-%02x%02x\n", txt[1], txt[2]);
+ txt += 3;
+ len -= 3;
+ break;
+ case 0x11:
+ ISO10646.copy(enc, ISO10646.length());
+ enc[ISO10646.length()] = '\0';
+ break;
+ case 0x1F:
+ // Values for the first byte of "0x00", "0x06" to "0x0F", and "0x12" to "0x1F" are reserved for future use.
+ //fprintf(stderr, "Reserved encoding: %02x\n", txt[0]);
+ //fprintf(stderr, "%d: %.*s\n", txt[1], len - 2, txt + 2);
+ case 0x06 ... 0x0F:
+ case 0x12 ... 0x1E:
+ case 0x00: // empty string
+ return boost::shared_ptr<Glib::ustring>(new Glib::ustring());
+ }
+ size_t used = 0, newlen = 0;
+ GError * err = NULL;
+ boost::shared_ptr<gchar> utf8 = boost::shared_ptr<gchar>(g_convert(txt, len, "utf-8", enc, &used, &newlen, &err), g_free);
+ if (err) {
+ throw Glib::ConvertError(err);
+ }
+ return boost::shared_ptr<Glib::ustring>(new Glib::ustring(utf8.get()));
+}
+
+bool
+_dvb_crc32(void * buf, size_t len)
+{
+ boost::crc_optimal<32, 0x0, 0xFFFFFFFF, 0x0, true, false> crc;
+ crc.process_bytes(buf, len);
+ return crc.checksum() == 0;
+}
+
+void
+DvbSiReaderHelper::readTables(const RowProcessor * rp) const
+{
+ u_char buf[1<<12];
+ struct pollfd ufd;
+ memset(&ufd, 0, sizeof(pollfd));
+ ufd.fd = fd_epg;
+ ufd.events = POLLIN;
+ size_t n;
+ int prtn = 0;
+ time_t lastuseful = time(NULL);
+ while (((prtn = poll(&ufd, 1, timeout())) == 1) && (n = read(fd_epg, buf, sizeof(buf)))) {
+ if (n < sizeof(struct si_tab))
+ throw ErrorReadingData("Smaller that si_tab");
+ struct si_tab *tab = (struct si_tab *)buf;
+ size_t l = sizeof(struct si_tab) + GetSectionLength(tab);
+ if (n < l)
+ throw ErrorReadingData("Smaller that section length");
+ if (_dvb_crc32(buf, l)) {
+ if (parseSIT(buf, l, rp)) {
+ time(&lastuseful);
+ }
+ else {
+ if (lastuseful < time(NULL) - 5) {
+ break;
+ }
+ }
+ }
+ }
+ if (prtn < 1) {
+ throw TimeoutReadingData("Tuned to a multiplex?");
+ }
+}
diff --git a/p2pvr/scanner/dvbSiReaderHelper.h b/p2pvr/scanner/dvbSiReaderHelper.h
new file mode 100644
index 0000000..325bc66
--- /dev/null
+++ b/p2pvr/scanner/dvbSiReaderHelper.h
@@ -0,0 +1,34 @@
+#ifndef DVBSIREADERHELPER_H
+#define DVBSIREADERHELPER_H
+
+#include "xmlObjectLoader.h"
+#include "variables.h"
+
+class RowProcessor;
+
+class DvbSiReaderHelper {
+ public:
+ DvbSiReaderHelper(const xmlpp::Element * p);
+ ~DvbSiReaderHelper();
+
+ const Variable demux;
+ const Variable timeout;
+
+ protected:
+ void openInput() const;
+ virtual void filterInput(int fd) const = 0;
+ void readTables(const RowProcessor *) const;
+ virtual bool parseSIT(const u_char *data, size_t len, const RowProcessor *) const = 0;
+ void closeInput() const;
+
+ static VariableType convert(const char * txt, size_t len);
+ static const std::string ISO10646;
+ static const std::string EitEncoding;
+ static const std::string UTF8;
+
+ private:
+ mutable int fd_epg;
+};
+
+#endif
+
diff --git a/p2pvr/scanner/dvb_info_tables.c b/p2pvr/scanner/dvb_info_tables.c
deleted file mode 100644
index 10a687a..0000000
--- a/p2pvr/scanner/dvb_info_tables.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * tv_grab_dvb - (c) Mark Bryars 2004
- * God bless vim and macros, this would have taken forever to format otherwise.
- */
-#include "tv_grab_dvb.h"
-
-const struct lookup_table description_table[] = {
- { {0x00}, "\0UNDEFINED CONTENT"},
- { {0x01}, "\0UNDEFINED CONTENT"},
- { {0x02}, "\0UNDEFINED CONTENT"},
- { {0x03}, "\0UNDEFINED CONTENT"},
- { {0x04}, "\0UNDEFINED CONTENT"},
- { {0x05}, "\0UNDEFINED CONTENT"},
- { {0x06}, "\0UNDEFINED CONTENT"},
- { {0x07}, "\0UNDEFINED CONTENT"},
- { {0x08}, "\0UNDEFINED CONTENT"},
- { {0x09}, "\0UNDEFINED CONTENT"},
- { {0x0A}, "\0UNDEFINED CONTENT"},
- { {0x0B}, "\0UNDEFINED CONTENT"},
- { {0x0C}, "\0UNDEFINED CONTENT"},
- { {0x0D}, "\0UNDEFINED CONTENT"},
- { {0x0E}, "\0UNDEFINED CONTENT"},
- { {0x0F}, "\0UNDEFINED CONTENT"},
-
- { {0x10}, "Movie / Drama" },
- { {0x11}, "Movie - detective/thriller" },
- { {0x12}, "Movie - adventure/western/war" },
- { {0x13}, "Movie - science fiction/fantasy/horror" },
- { {0x14}, "Movie - comedy" },
- { {0x15}, "Movie - soap/melodrama/folkloric" },
- { {0x16}, "Movie - romance" },
- { {0x17}, "Movie - serious/classical/religious/historical movie/drama" },
- { {0x18}, "Movie - adult movie/drama" },
- { {0x19}, "\0Movie - RESERVED" },
- { {0x1A}, "\0Movie - RESERVED" },
- { {0x1B}, "\0Movie - RESERVED" },
- { {0x1C}, "\0Movie - RESERVED" },
- { {0x1D}, "\0Movie - RESERVED" },
- { {0x1E}, "\0Movie - RESERVED" },
- { {0x1F}, NULL },
-
- { {0x20}, "News / Current Affairs" },
- { {0x21}, "New - news/weather report" },
- { {0x22}, "New - news magazine" },
- { {0x23}, "New - documentary" },
- { {0x24}, "New - discussion/interview/debate" },
- { {0x25}, "\0News - RESERVED" },
- { {0x26}, "\0News - RESERVED" },
- { {0x27}, "\0News - RESERVED" },
- { {0x28}, "\0News - RESERVED" },
- { {0x29}, "\0News - RESERVED" },
- { {0x2A}, "\0News - RESERVED" },
- { {0x2B}, "\0News - RESERVED" },
- { {0x2C}, "\0News - RESERVED" },
- { {0x2D}, "\0News - RESERVED" },
- { {0x2E}, "\0News - RESERVED" },
- { {0x2E}, NULL },
-
- { {0x30}, "Show / Game Show" },
- { {0x31}, "Show - game show/quiz/contest" },
- { {0x32}, "Show - variety show" },
- { {0x33}, "Show - talk show" },
- { {0x34}, "\0Show - RESERVED" },
- { {0x35}, "\0Show - RESERVED" },
- { {0x36}, "\0Show - RESERVED" },
- { {0x37}, "\0Show - RESERVED" },
- { {0x38}, "\0Show - RESERVED" },
- { {0x39}, "\0Show - RESERVED" },
- { {0x3A}, "\0Show - RESERVED" },
- { {0x3B}, "\0Show - RESERVED" },
- { {0x3C}, "\0Show - RESERVED" },
- { {0x3D}, "\0Show - RESERVED" },
- { {0x3E}, "\0Show - RESERVED" },
- { {0x3F}, NULL },
-
- { {0x40}, "Sports" },
- { {0x41}, "Sports - special events (Olympic Games, World Cup etc.)" },
- { {0x42}, "Sports - sports magazines" },
- { {0x43}, "Sports - football/soccer" },
- { {0x44}, "Sports - tennis/squash" },
- { {0x45}, "Sports - team sports (excluding football)" },
- { {0x46}, "Sports - athletics" },
- { {0x47}, "Sports - motor sport" },
- { {0x48}, "Sports - water sport" },
- { {0x49}, "Sports - winter sports" },
- { {0x4A}, "Sports - equestrian" },
- { {0x4B}, "Sports - martial sports" },
- { {0x4C}, "\0Sports - RESERVED" },
- { {0x4D}, "\0Sports - RESERVED" },
- { {0x4E}, "\0Sports - RESERVED" },
- { {0x4F}, NULL },
-
- { {0x50}, "Childrens / Youth" },
- { {0x51}, "Children - pre-school children's programmes" },
- { {0x52}, "Children - entertainment programmes for 6 to 14" },
- { {0x53}, "Children - entertainment programmes for 10 to 16" },
- { {0x54}, "Children - informational/educational/school programmes" },
- { {0x55}, "Children - cartoons/puppets" },
- { {0x56}, "\0Children - RESERVED" },
- { {0x57}, "\0Children - RESERVED" },
- { {0x58}, "\0Children - RESERVED" },
- { {0x59}, "\0Children - RESERVED" },
- { {0x5A}, "\0Children - RESERVED" },
- { {0x5B}, "\0Children - RESERVED" },
- { {0x5C}, "\0Children - RESERVED" },
- { {0x5D}, "\0Children - RESERVED" },
- { {0x5E}, "\0Children - RESERVED" },
- { {0x5F}, NULL },
-
- { {0x60}, "Music / Ballet / Dance" },
- { {0x61}, "Music - rock/pop" },
- { {0x62}, "Music - serious music/classical music" },
- { {0x63}, "Music - folk/traditional music" },
- { {0x64}, "Music - jazz" },
- { {0x65}, "Music - musical/opera" },
- { {0x66}, "Music - ballet" },
- { {0x67}, "\0Music - RESERVED" },
- { {0x68}, "\0Music - RESERVED" },
- { {0x69}, "\0Music - RESERVED" },
- { {0x6A}, "\0Music - RESERVED" },
- { {0x6B}, "\0Music - RESERVED" },
- { {0x6C}, "\0Music - RESERVED" },
- { {0x6D}, "\0Music - RESERVED" },
- { {0x6E}, "\0Music - RESERVED" },
- { {0x6F}, NULL },
-
- { {0x70}, "Arts / Culture" },
- { {0x71}, "Arts - performing arts" },
- { {0x72}, "Arts - fine arts" },
- { {0x73}, "Arts - religion" },
- { {0x74}, "Arts - popular culture/traditional arts" },
- { {0x75}, "Arts - literature" },
- { {0x76}, "Arts - film/cinema" },
- { {0x77}, "Arts - experimental film/video" },
- { {0x78}, "Arts - broadcasting/press" },
- { {0x79}, "Arts - new media" },
- { {0x7A}, "Arts - arts/culture magazines" },
- { {0x7B}, "Arts - fashion" },
- { {0x7C}, "\0Arts - RESERVED" },
- { {0x7D}, "\0Arts - RESERVED" },
- { {0x7E}, "\0Arts - RESERVED" },
- { {0x7F}, NULL },
-
- { {0x80}, "Social / Policical / Economics" },
- { {0x81}, "Social - magazines/reports/documentary" },
- { {0x82}, "Social - economics/social advisory" },
- { {0x83}, "Social - remarkable people" },
- { {0x84}, "\0Social - RESERVED" },
- { {0x85}, "\0Social - RESERVED" },
- { {0x86}, "\0Social - RESERVED" },
- { {0x87}, "\0Social - RESERVED" },
- { {0x88}, "\0Social - RESERVED" },
- { {0x89}, "\0Social - RESERVED" },
- { {0x8A}, "\0Social - RESERVED" },
- { {0x8b}, "\0Social - RESERVED" },
- { {0x8C}, "\0Social - RESERVED" },
- { {0x8D}, "\0Social - RESERVED" },
- { {0x8E}, "\0Social - RESERVED" },
- { {0x8F}, NULL },
-
- { {0x90}, "Education / Science / Factual" },
- { {0x91}, "Education - nature/animals/environment" },
- { {0x92}, "Education - technology/natural sciences" },
- { {0x93}, "Education - medicine/physiology/psychology" },
- { {0x94}, "Education - foreign countries/expeditions" },
- { {0x95}, "Education - social/spiritual sciences" },
- { {0x96}, "Education - further education" },
- { {0x97}, "Education - languages" },
- { {0x98}, "\0Education - RESERVED" },
- { {0x99}, "\0Education - RESERVED" },
- { {0x9A}, "\0Education - RESERVED" },
- { {0x9B}, "\0Education - RESERVED" },
- { {0x9C}, "\0Education - RESERVED" },
- { {0x9D}, "\0Education - RESERVED" },
- { {0x9E}, "\0Education - RESERVED" },
- { {0x9F}, NULL },
-
- { {0xA0}, "Leisure / Hobbies" },
- { {0xA1}, "Leisure - tourism/travel" },
- { {0xA2}, "Leisure - handicraft" },
- { {0xA3}, "Leisure - motoring" },
- { {0xA4}, "Leisure - fitness &amp; health" },
- { {0xA5}, "Leisure - cooking" },
- { {0xA6}, "Leisure - advertizement/shopping" },
- { {0xA7}, "Leisure - gardening" },
- { {0xA8}, "\0Leisure - RESERVED" },
- { {0xA9}, "\0Leisure - RESERVED" },
- { {0xAA}, "\0Leisure - RESERVED" },
- { {0xAB}, "\0Leisure - RESERVED" },
- { {0xAC}, "\0Leisure - RESERVED" },
- { {0xAD}, "\0Leisure - RESERVED" },
- { {0xAE}, "\0Leisure - RESERVED" },
- { {0xAF}, NULL },
-
- // Special
- { {0xB0}, "Original Language" },
- { {0xB1}, "black &amp; white" },
- { {0xB2}, "unpublished" },
- { {0xB3}, "live broadcast" },
- { {0xB4}, "\0Characteristics - RESERVED" },
- { {0xB5}, "\0Characteristics - RESERVED" },
- { {0xB6}, "\0Characteristics - RESERVED" },
- { {0xB7}, "\0Characteristics - RESERVED" },
- { {0xB8}, "\0Characteristics - RESERVED" },
- { {0xB9}, "\0Characteristics - RESERVED" },
- { {0xBA}, "\0Characteristics - RESERVED" },
- { {0xBB}, "\0Characteristics - RESERVED" },
- { {0xBC}, "\0Characteristics - RESERVED" },
- { {0xBD}, "\0Characteristics - RESERVED" },
- { {0xBE}, "\0Characteristics - RESERVED" },
- { {0xBF}, NULL },
-
- { {0xC0}, "\0RESERVED" },
- { {0xC1}, "\0RESERVED" },
- { {0xC2}, "\0RESERVED" },
- { {0xC3}, "\0RESERVED" },
- { {0xC4}, "\0RESERVED" },
- { {0xC5}, "\0RESERVED" },
- { {0xC6}, "\0RESERVED" },
- { {0xC7}, "\0RESERVED" },
- { {0xC8}, "\0RESERVED" },
- { {0xC9}, "\0RESERVED" },
- { {0xCA}, "\0RESERVED" },
- { {0xCB}, "\0RESERVED" },
- { {0xCC}, "\0RESERVED" },
- { {0xCD}, "\0RESERVED" },
- { {0xCE}, "\0RESERVED" },
- { {0xCF}, "\0RESERVED" },
-
- { {0xD0}, "\0RESERVED" },
- { {0xD1}, "\0RESERVED" },
- { {0xD2}, "\0RESERVED" },
- { {0xD3}, "\0RESERVED" },
- { {0xD4}, "\0RESERVED" },
- { {0xD5}, "\0RESERVED" },
- { {0xD6}, "\0RESERVED" },
- { {0xD7}, "\0RESERVED" },
- { {0xD8}, "\0RESERVED" },
- { {0xD9}, "\0RESERVED" },
- { {0xDA}, "\0RESERVED" },
- { {0xDB}, "\0RESERVED" },
- { {0xDC}, "\0RESERVED" },
- { {0xDD}, "\0RESERVED" },
- { {0xDE}, "\0RESERVED" },
- { {0xDF}, "\0RESERVED" },
-
- { {0xE0}, "\0RESERVED" },
- { {0xE1}, "\0RESERVED" },
- { {0xE2}, "\0RESERVED" },
- { {0xE3}, "\0RESERVED" },
- { {0xE4}, "\0RESERVED" },
- { {0xE5}, "\0RESERVED" },
- { {0xE6}, "\0RESERVED" },
- { {0xE7}, "\0RESERVED" },
- { {0xE8}, "\0RESERVED" },
- { {0xE9}, "\0RESERVED" },
- { {0xEA}, "\0RESERVED" },
- { {0xEB}, "\0RESERVED" },
- { {0xEC}, "\0RESERVED" },
- { {0xED}, "\0RESERVED" },
- { {0xEE}, "\0RESERVED" },
- { {0xEF}, "\0RESERVED" },
-
- // UK Freeview custom id
- { {0xF0}, "Drama" },
- { {0xF1}, NULL },
- { {0xF2}, NULL },
- { {0xF3}, NULL },
- { {0xF4}, NULL },
- { {0xF5}, NULL },
- { {0xF6}, NULL },
- { {0xF7}, NULL },
- { {0xF8}, NULL },
- { {0xF9}, NULL },
- { {0xFA}, NULL },
- { {0xFB}, NULL },
- { {0xFC}, NULL },
- { {0xFD}, NULL },
- { {0xFE}, NULL },
- { {0xFF}, NULL },
-
- { {-1}, NULL }
-};
-
diff --git a/p2pvr/scanner/p2scan.cpp b/p2pvr/scanner/eitRows.cpp
index 8fe3578..aea639f 100644
--- a/p2pvr/scanner/p2scan.cpp
+++ b/p2pvr/scanner/eitRows.cpp
@@ -27,29 +27,18 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <sys/ioctl.h>
-#include <sys/poll.h>
#include <errno.h>
-#include <getopt.h>
-#include <stdarg.h>
#include <stdint.h>
-#include <signal.h>
#include <time.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <glibmm.h>
#include <boost/bind.hpp>
#include <boost/date_time/gregorian_calendar.hpp>
#include <linux/dvb/dmx.h>
#include "si_tables.h"
-#include "tv_grab_dvb.h"
-#include "variables.h"
#include "rowProcessor.h"
+#include "eitRows.h"
struct EitProgram {
VariableType serviceID;
@@ -77,195 +66,99 @@ struct EitProgram {
};
Glib::ustring title("title");
-#include "xmlObjectLoader.h"
-#include "rowSet.h"
template <class C, class M>
const M &
getMember(M C::*t, C * p) {
return p->*t;
}
SimpleMessageException(NoSuchAttribute);
-class EitRows : public RowSet {
- public:
- EitRows(const xmlpp::Element * p);
- ~EitRows();
- void execute(const RowProcessor *) const;
- void loadComplete(const CommonObjects *) {
- }
- void setFilter(const Glib::ustring &) {
- }
- unsigned int columnCount() const {
- return 1;
- }
- const Glib::ustring & getColumnName(unsigned int) const {
- return title;
- }
- VariableType getCurrentValue(const Glib::ustring &) const {
- return current->title;
- }
- VariableType getCurrentValue(unsigned int) const {
- return current->title;
- }
- bool isNull(unsigned int ) const {
- return false;
- }
- bool isNull(const Glib::ustring & ) const {
- return false;
- }
+
+void
+EitRows::loadComplete(const CommonObjects *)
+{
+}
+
+void
+EitRows::setFilter(const Glib::ustring &)
+{
+}
+
+unsigned int
+EitRows::columnCount() const
+{
+ return 1;
+}
+
+const Glib::ustring &
+EitRows::getColumnName(unsigned int) const {
+ return title;
+}
+
+VariableType
+EitRows::getCurrentValue(const Glib::ustring &) const {
+ return current->title;
+}
+
+VariableType
+EitRows::getCurrentValue(unsigned int) const {
+ return current->title;
+}
+
+bool
+EitRows::isNull(unsigned int ) const {
+ return false;
+}
+
+bool
+EitRows::isNull(const Glib::ustring & ) const {
+ return false;
+}
+
#define returnAttr(name) if (attrName == #name) return boost::bind(getMember<EitProgram, VariableType>, &EitProgram::name, boost::ref(current))
- RowAttribute resolveAttr(const Glib::ustring & attrName) const {
- returnAttr(serviceID);
- returnAttr(eventID);
- returnAttr(title);
- returnAttr(titleLang);
- returnAttr(subtitle);
- returnAttr(descLang);
- returnAttr(desc1);
- returnAttr(desc2);
- returnAttr(desc3);
- returnAttr(videoAspect);
- returnAttr(videoFrameRate);
- returnAttr(videoHD);
- returnAttr(audioChannels);
- returnAttr(language);
- returnAttr(teletextSubtitleLang);
- returnAttr(category);
- returnAttr(dvbRating);
- returnAttr(contentItemID);
- returnAttr(contentSeriesID);
- returnAttr(contentRecommendation);
- returnAttr(startTime);
- returnAttr(stopTime);
- throw NoSuchAttribute(attrName);
- }
- private:
- Variable demux;
- Variable timeout;
- void openInput() const;
- void closeInput() const;
- void readEventTables(const RowProcessor *) const;
- bool parseEIT(const u_char *data, size_t len, const RowProcessor *) const;
- void parseEventDescription(const u_char *data) const;
- void parseLongEventDescription(const u_char *data) const;
- void parseComponentDescription(const u_char *data) const;
- void parseContentDescription(const u_char *data) const;
- void parseRatingDescription(const u_char *data) const;
- void parseContentIdentifierDescription(const u_char *data) const;
- void parseDescription(const u_char * data, size_t len) const;
-
- VariableType convert(const char * txt, size_t len) const;
-
- mutable int fd_epg;
- mutable EitProgram * current;
-
- static const std::string ISO10646;
- static const std::string EitEncoding;
- static const std::string UTF8;
-};
+RowSet::RowAttribute
+EitRows::resolveAttr(const Glib::ustring & attrName) const {
+ returnAttr(serviceID);
+ returnAttr(eventID);
+ returnAttr(title);
+ returnAttr(titleLang);
+ returnAttr(subtitle);
+ returnAttr(descLang);
+ returnAttr(desc1);
+ returnAttr(desc2);
+ returnAttr(desc3);
+ returnAttr(videoAspect);
+ returnAttr(videoFrameRate);
+ returnAttr(videoHD);
+ returnAttr(audioChannels);
+ returnAttr(language);
+ returnAttr(teletextSubtitleLang);
+ returnAttr(category);
+ returnAttr(dvbRating);
+ returnAttr(contentItemID);
+ returnAttr(contentSeriesID);
+ returnAttr(contentRecommendation);
+ returnAttr(startTime);
+ returnAttr(stopTime);
+ throw NoSuchAttribute(attrName);
+}
DECLARE_LOADER("eitrows", EitRows);
-const std::string EitRows::ISO10646("ISO-10646");
-const std::string EitRows::EitEncoding("ISO6937");
-const std::string EitRows::UTF8("UTF8");
-
EitRows::EitRows(const xmlpp::Element * p) :
RowSet(p),
- demux(p, "demux", false, "/dev/dvb/adapter0/demux0"),
- timeout(p, "timeout", false, 10000),
- fd_epg(0),
+ DvbSiReaderHelper(p),
current(NULL)
{
}
EitRows::~EitRows()
{
- closeInput();
-}
-void
-EitRows::closeInput() const
-{
- if (fd_epg) {
- close(fd_epg);
- fd_epg = 0;
- }
}
static int time_offset = 0;
static int chan_filter = 0;
static int chan_filter_mask = 0;
-/* Parse command line arguments. {{{ */
-int do_options(int arg_count, char **arg_strings) {
- static const struct option Long_Options[] = {
- {"help", 0, 0, 'h'},
- {"chanidents", 1, 0, 'c'},
- {0, 0, 0, 0}
- };
- int Option_Index = 0;
-
- while (1) {
- int c = getopt_long(arg_count, arg_strings, "udscmpnht:o:f:i:e:", Long_Options, &Option_Index);
- switch (c) {
- case 'n':
- chan_filter = 0x4e;
- chan_filter_mask = 0xfe;
- break;
- case 'm':
- chan_filter = 0x4e;
- chan_filter_mask = 0xff;
- break;
- case 'p':
- chan_filter = 0x4f;
- chan_filter_mask = 0xff;
- break;
- }
- }
- return 0;
-} /*}}}*/
-
-
-VariableType
-EitRows::convert(const char * txt, size_t len) const
-{
- char enc[20];
- switch (*txt) {
- default:
- EitEncoding.copy(enc, EitEncoding.length());
- enc[EitEncoding.length()] = '\0';
- break;
- case 0x01 ... 0x05:
- snprintf(enc, sizeof(enc), "ISO-8859-%d\n", txt[0] + 4);
- txt += 1;
- len -= 1;
- break;
- case 0x10:
- snprintf(enc, sizeof(enc), "ISO-8859-%02x%02x\n", txt[1], txt[2]);
- txt += 3;
- len -= 3;
- break;
- case 0x11:
- ISO10646.copy(enc, ISO10646.length());
- enc[ISO10646.length()] = '\0';
- break;
- case 0x1F:
- // Values for the first byte of "0x00", "0x06" to "0x0F", and "0x12" to "0x1F" are reserved for future use.
- //fprintf(stderr, "Reserved encoding: %02x\n", txt[0]);
- //fprintf(stderr, "%d: %.*s\n", txt[1], len - 2, txt + 2);
- case 0x06 ... 0x0F:
- case 0x12 ... 0x1E:
- case 0x00: // empty string
- return boost::shared_ptr<Glib::ustring>(new Glib::ustring());
- }
- size_t used = 0, newlen = 0;
- GError * err = NULL;
- boost::shared_ptr<gchar> utf8 = boost::shared_ptr<gchar>(g_convert(txt, len, "utf-8", enc, &used, &newlen, &err), g_free);
- if (err) {
- throw Glib::ConvertError(err);
- }
- return boost::shared_ptr<Glib::ustring>(new Glib::ustring(utf8.get()));
-}
-
void
EitRows::parseEventDescription(const u_char *data) const {
assert(GetDescriptorTag(data) == 0x4D);
@@ -521,7 +414,7 @@ SeenProgram::operator<(const SeenProgram & o) const
typedef std::set<SeenProgram> SeenPrograms;
SeenPrograms seenPrograms;
bool
-EitRows::parseEIT(const u_char *data, size_t len, const RowProcessor * rp) const {
+EitRows::parseSIT(const u_char *data, size_t len, const RowProcessor * rp) const {
const struct eit *e = reinterpret_cast<const struct eit *>(data);
len -= 4; //remove CRC
@@ -572,52 +465,11 @@ EitRows::parseEIT(const u_char *data, size_t len, const RowProcessor * rp) const
return found;
}
-SimpleMessageException(ErrorReadingData);
-SimpleMessageException(TimeoutReadingData);
-void
-EitRows::readEventTables(const RowProcessor * rp) const
-{
- u_char buf[1<<12];
- struct pollfd ufd;
- memset(&ufd, 0, sizeof(pollfd));
- ufd.fd = fd_epg;
- ufd.events = POLLIN;
- size_t n;
- int prtn = 0;
- time_t lastuseful = time(NULL);
- while (((prtn = poll(&ufd, 1, timeout())) == 1) && (n = read(fd_epg, buf, sizeof(buf)))) {
- if (n < sizeof(struct si_tab))
- throw ErrorReadingData("Smaller that si_tab");
- struct si_tab *tab = (struct si_tab *)buf;
- size_t l = sizeof(struct si_tab) + GetSectionLength(tab);
- if (n < l)
- throw ErrorReadingData("Smaller that section length");
- if (_dvb_crc32(buf, l) == 0) {
- if (parseEIT(buf, l, rp)) {
- time(&lastuseful);
- }
- else {
- if (lastuseful < time(NULL) - 5) {
- break;
- }
- }
- }
- }
- if (prtn < 1) {
- throw TimeoutReadingData("Tuned to a multiplex?");
- }
-}
-
-SimpleMessageException(DemuxOpenFailure);
SimpleMessageException(DemuxSetFilterFailure);
void
-EitRows::openInput() const
+EitRows::filterInput(int fd) const
{
- if ((fd_epg = open(demux(), O_RDWR)) < 0) {
- throw DemuxOpenFailure(strerror(errno));
- }
-
struct dmx_sct_filter_params sctFilterParams;
memset(&sctFilterParams, 0, sizeof(dmx_sct_filter_params));
sctFilterParams.pid = 18; // EIT data
@@ -626,7 +478,7 @@ EitRows::openInput() const
sctFilterParams.filter.filter[0] = chan_filter; // 4e is now/next this multiplex, 4f others
sctFilterParams.filter.mask[0] = chan_filter_mask;
- if (ioctl(fd_epg, DMX_SET_FILTER, &sctFilterParams) < 0) {
+ if (ioctl(fd, DMX_SET_FILTER, &sctFilterParams) < 0) {
throw DemuxSetFilterFailure(strerror(errno));
}
}
@@ -635,7 +487,7 @@ void
EitRows::execute(const RowProcessor * rp) const
{
openInput();
- readEventTables(rp);
+ readTables(rp);
closeInput();
}
diff --git a/p2pvr/scanner/eitRows.h b/p2pvr/scanner/eitRows.h
new file mode 100644
index 0000000..9078b53
--- /dev/null
+++ b/p2pvr/scanner/eitRows.h
@@ -0,0 +1,42 @@
+#ifndef P2SCAN_H
+#define P2SCAN_H
+
+#include "xmlObjectLoader.h"
+#include "rowSet.h"
+#include "variables.h"
+#include "dvbSiReaderHelper.h"
+
+class EitProgram;
+
+class EitRows : public RowSet, DvbSiReaderHelper {
+ public:
+ EitRows(const xmlpp::Element * p);
+ ~EitRows();
+
+ void execute(const RowProcessor *) const;
+ void loadComplete(const CommonObjects *);
+ void setFilter(const Glib::ustring &);
+ unsigned int columnCount() const;
+ const Glib::ustring & getColumnName(unsigned int) const;
+ VariableType getCurrentValue(const Glib::ustring &) const;
+ VariableType getCurrentValue(unsigned int) const;
+ bool isNull(unsigned int ) const;
+ bool isNull(const Glib::ustring & ) const;
+ RowAttribute resolveAttr(const Glib::ustring & attrName) const;
+
+ private:
+ void filterInput(int fd) const;
+ bool parseSIT(const u_char *data, size_t len, const RowProcessor *) const;
+ void parseEventDescription(const u_char *data) const;
+ void parseLongEventDescription(const u_char *data) const;
+ void parseComponentDescription(const u_char *data) const;
+ void parseContentDescription(const u_char *data) const;
+ void parseRatingDescription(const u_char *data) const;
+ void parseContentIdentifierDescription(const u_char *data) const;
+ void parseDescription(const u_char * data, size_t len) const;
+
+ mutable EitProgram * current;
+};
+
+#endif
+
diff --git a/p2pvr/scanner/lookup.cpp b/p2pvr/scanner/lookup.cpp
deleted file mode 100644
index 6d2a0b6..0000000
--- a/p2pvr/scanner/lookup.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-#include "tv_grab_dvb.h"
-
-const char *lookup(const struct lookup_table *l, int id) {
-// printf("Looked up %x", id);
- while ((l->u.i != id) && (l->u.i != -1))
- l++;
- return l->desc;
-}
-
-/* Read lookup_table from file into newly allocated table.
- * The table is a single allocation consisting of two parts:
- * first the array of structs, followed by a char-array of strings. */
-int load_lookup(struct lookup_table **l, const char *file) {
- int name;
- char value[256];
- int n = 1, size = sizeof(struct lookup_table);
-
- if (file == NULL)
- return -1;
-
- FILE *fd = fopen(file, "r");
- if (!fd)
- return -1;
-
- // 1st: determine size needed
- while (fscanf(fd, "%d %255s", &name, value) == 2) {
- n++;
- size += sizeof(struct lookup_table);
- size += strlen(value) + 1;
- }
- struct lookup_table *p = *l = static_cast<struct lookup_table *>(malloc(size));
- if (p == NULL)
- return -1;
-
- // 2nd: read data
- rewind(fd);
- char *c = (char *)(p + n);
- while (fscanf(fd, "%d %255s", &p->u.i, c) == 2) {
- p->desc = c;
- c += strlen(c) + 1;
- p++;
- }
- p->u.i = -1;
- p->desc = NULL;
-
- fclose(fd);
- return 0;
-}
-
diff --git a/p2pvr/scanner/tv_grab_dvb.h b/p2pvr/scanner/tv_grab_dvb.h
deleted file mode 100644
index 460b7f6..0000000
--- a/p2pvr/scanner/tv_grab_dvb.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __tv_grab_dvd
-#define __tv_grab_dvd
-
-#include <stdint.h>
-#include <stdlib.h>
-
-/* lookup.c */
-union lookup_key {
- int i;
- char c[4];
-};
-struct lookup_table {
- union lookup_key u;
- const char *desc;
-};
-
-extern const char *lookup(const struct lookup_table *l, int id);
-extern int load_lookup(struct lookup_table **l, const char *file);
-
-/* dvb_info_tables.c */
-extern const struct lookup_table description_table[];
-extern const struct lookup_table aspect_table[];
-extern const struct lookup_table audio_table[];
-extern const struct lookup_table crid_type_table[];
-
-/* langidents.c */
-extern const struct lookup_table languageid_table[];
-
-/* crc32.c */
-extern uint32_t _dvb_crc32(const uint8_t *data, size_t len);
-
-#endif