diff options
-rw-r--r-- | abs/core-testing/mythtv/stable/mythtv/PKGBUILD | 21 | ||||
-rw-r--r-- | abs/core-testing/mythtv/stable/mythtv/changeset-20877.patch | 5910 |
2 files changed, 8 insertions, 5923 deletions
diff --git a/abs/core-testing/mythtv/stable/mythtv/PKGBUILD b/abs/core-testing/mythtv/stable/mythtv/PKGBUILD index 3d7a7ad..3c11345 100644 --- a/abs/core-testing/mythtv/stable/mythtv/PKGBUILD +++ b/abs/core-testing/mythtv/stable/mythtv/PKGBUILD @@ -1,18 +1,16 @@ pkgname=mythtv pkgver=0.21 -pkgrel=78 +pkgrel=79 pkgdesc="A Homebrew PVR project" arch=('i686' 'x86_64') -depends=('bash' 'mysql-clients>=5.0' 'qt3' 'lame' 'lirc-utils' 'ffmpeg' \ - 'libxvmc' 'libavc1394' 'libdc1394' 'libiec61883' 'perl-net-upnp' 'perl-time-format') +depends=('bash' 'mysql-clients>=5.0' 'qt3' 'lame' 'lirc-utils' 'ffmpeg' + 'libxvmc' 'libavc1394' 'libdc1394' 'libiec61883' 'perl-net-upnp' + 'perl-time-format') backup=(etc/mythtv/mythbackend.conf etc/mythtv/mysql.txt usr/share/mythtv/is.xmlusr/share/mythtv/media_settings.xml ) -source=(ftp://ftp.knoppmyth.net/R6/sources/${pkgname}-${pkgver}-fixes.tar.bz2 \ - mythbackend myththemedmenu.cpp.patch myththemedmenu.h.patch smolt_jump.patch pretty gnome_screensaver.patch mpegpspatch mythbackend.lr mythfrontend.lr - changeset-20877.patch) - - -#md5sums=('e316ed18d7ac837cf8c4af54b1478793' '7ef6de58240e7aad389a0b13d91b1cf6'\ -# 'a0ecb7f476cb71c0c1ac90d349fc7695') +source=(ftp://ftp.knoppmyth.net/R6/sources/${pkgname}-${pkgver}-fixes.tar.bz2 + mythbackend myththemedmenu.cpp.patch myththemedmenu.h.patch + smolt_jump.patch pretty gnome_screensaver.patch mpegpspatch + mythbackend.lr mythfrontend.lr) license=('GPL2') makedepends=(libgl subversion python perl) @@ -36,9 +34,6 @@ build() { # patch -p0 < $startdir/src/mpegpspatch # cd - -# Remove the hdhomerun changeset 20877 that prevents things from compiling. -# patch -p3 < ../changeset-20877.patch - . /etc/profile.d/qt3.sh # use QT3 qmake diff --git a/abs/core-testing/mythtv/stable/mythtv/changeset-20877.patch b/abs/core-testing/mythtv/stable/mythtv/changeset-20877.patch deleted file mode 100644 index b92f0c1..0000000 --- a/abs/core-testing/mythtv/stable/mythtv/changeset-20877.patch +++ /dev/null @@ -1,5910 +0,0 @@ -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/Makefile src/mythtv-0.21/libs/libmythtv/hdhomerun/Makefile ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/Makefile 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/Makefile 2009-01-09 13:14:56.000000000 +1030 -@@ -1,52 +1,21 @@ --LIBSRCS += hdhomerun_pkt.c --LIBSRCS += hdhomerun_debug.c --LIBSRCS += hdhomerun_discover.c --LIBSRCS += hdhomerun_channels.c --LIBSRCS += hdhomerun_channelscan.c --LIBSRCS += hdhomerun_control.c --LIBSRCS += hdhomerun_video.c --LIBSRCS += hdhomerun_device.c --LIBSRCS += hdhomerun_device_selector.c - --CC := $(CROSS_COMPILE)gcc --STRIP := $(CROSS_COMPILE)strip -+SRCS += hdhomerun_pkt.c -+SRCS += hdhomerun_discover.c -+SRCS += hdhomerun_control.c -+SRCS += hdhomerun_video.c -+SRCS += hdhomerun_device.c -+SRCS += hdhomerun_config.c - - CFLAGS += -Wall -O2 -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith --LDFLAGS += -lpthread --SHARED = -shared -Wl,-soname,libhdhomerun$(LIBEXT) - --ifeq ($(OS),Windows_NT) -- BINEXT := .exe -- LIBEXT := .dll -- LDFLAGS += -liphlpapi --else -- LIBEXT := .so -- ifneq ($(findstring solaris,$(shell echo $$OSTYPE)),) -- LDFLAGS += -lns -lsocket -- endif -- ifneq ($(findstring darwin,$(shell echo $$OSTYPE)),) -- CFLAGS += -arch i386 -arch ppc -- LIBEXT := .dylib -- SHARED := -dynamiclib -install_name libhdhomerun$(LIBEXT) -- endif --endif -- --all : hdhomerun_config$(BINEXT) libhdhomerun$(LIBEXT) -- --hdhomerun_config$(BINEXT) : hdhomerun_config.c $(LIBSRCS) -- $(CC) $(CFLAGS) $+ $(LDFLAGS) -o $@ -- $(STRIP) $@ -- --libhdhomerun$(LIBEXT) : $(LIBSRCS) -- $(CC) $(CFLAGS) -fPIC -DDLL_EXPORT $(SHARED) $+ $(LDFLAGS) -o $@ -+hdhomerun_config : $(SRCS) -+ gcc $(CFLAGS) $(SRCS) -lpthread -o $@ -+ strip $@ -+ -+hdhomerun_config.exe : $(SRCS) -+ gcc $(CFLAGS) $(SRCS) -lpthread -liphlpapi -o $@ -+ strip $@ - - clean : -- -rm -f hdhomerun_config$(BINEXT) -- -rm -f libhdhomerun$(LIBEXT) -- --distclean : clean -- --%: -- @echo "(ignoring request to make $@)" -- --.PHONY: all list clean distclean -+ rm -f hdhomerun_config -+ rm -f hdhomerun_config.exe -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun.h src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun.h ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun.h 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun.h 2009-01-09 13:14:56.000000000 +1030 -@@ -1,14 +1,12 @@ --#ifndef __HDHOMERUN_INCLUDES__ --#define __HDHOMERUN_INCLUDES__ - /* -- * hdhomerun.h -+ * hdhomerun_device.h - * -- * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -16,33 +14,13 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - #include "hdhomerun_os.h" --#include "hdhomerun_types.h" - #include "hdhomerun_pkt.h" --#include "hdhomerun_debug.h" - #include "hdhomerun_discover.h" - #include "hdhomerun_control.h" - #include "hdhomerun_video.h" --#include "hdhomerun_channels.h" --#include "hdhomerun_channelscan.h" - #include "hdhomerun_device.h" --#include "hdhomerun_device_selector.h" -- --#endif /* __HDHOMERUN_INCLUDES__ */ -- -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_channels.c -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_channels.h -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_channelscan.c -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_channelscan.h -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_config.c src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_config.c ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_config.c 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_config.c 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_config.c - * -- * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,34 +14,12 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - #include "hdhomerun.h" - --/* -- * The console output format should be set to UTF-8, however in XP and Vista this breaks batch file processing. -- * Attempting to restore on exit fails to restore if the program is terminated by the user. -- * Solution - set the output format each printf. -- */ --#if defined(__WINDOWS__) --#define printf console_printf --#define vprintf console_vprintf --#endif -- - static const char *appname; - - struct hdhomerun_device_t *hd; -@@ -53,8 +31,7 @@ - printf("\t%s <id> get help\n", appname); - printf("\t%s <id> get <item>\n", appname); - printf("\t%s <id> set <item> <value>\n", appname); -- printf("\t%s <id> scan <tuner> [<filename>]\n", appname); -- printf("\t%s <id> save <tuner> <filename>\n", appname); -+ printf("\t%s <id> scan <tuner> <starting channel>\n", appname); - printf("\t%s <id> upgrade <filename>\n", appname); - return -1; - } -@@ -91,29 +68,10 @@ - return FALSE; - } - --static uint32_t parse_ip_addr(const char *str) --{ -- unsigned long a[4]; -- if (sscanf(str, "%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], &a[3]) != 4) { -- return 0; -- } -- -- return (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0)); --} -- --static int discover_print(char *target_ip_str) -+static int discover_print(void) - { -- uint32_t target_ip = 0; -- if (target_ip_str) { -- target_ip = parse_ip_addr(target_ip_str); -- if (target_ip == 0) { -- fprintf(stderr, "invalid ip address: %s\n", target_ip_str); -- return -1; -- } -- } -- - struct hdhomerun_discover_device_t result_list[64]; -- int count = hdhomerun_discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, 64); -+ int count = hdhomerun_discover_find_devices(HDHOMERUN_DEVICE_TYPE_TUNER, result_list, 64); - if (count < 0) { - fprintf(stderr, "error sending discover request\n"); - return -1; -@@ -136,6 +94,32 @@ - return count; - } - -+static bool_t parse_device_id_str(const char *s, uint32_t *pdevice_id, uint32_t *pdevice_ip) -+{ -+ unsigned long a[4]; -+ if (sscanf(s, "%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], &a[3]) == 4) { -+ *pdevice_id = HDHOMERUN_DEVICE_ID_WILDCARD; -+ *pdevice_ip = (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0)); -+ return TRUE; -+ } -+ -+ unsigned long device_id_raw; -+ if (sscanf(s, "%lx", &device_id_raw) != 1) { -+ fprintf(stderr, "invalid device id: %s\n", s); -+ return FALSE; -+ } -+ -+ uint32_t device_id = (uint32_t)device_id_raw; -+ if (!hdhomerun_discover_validate_device_id(device_id)) { -+ fprintf(stderr, "invalid device id: %s\n", s); -+ return FALSE; -+ } -+ -+ *pdevice_id = device_id; -+ *pdevice_ip = 0; -+ return TRUE; -+} -+ - static int cmd_get(const char *item) - { - char *ret_value; -@@ -154,7 +138,7 @@ - return 1; - } - --static int cmd_set_internal(const char *item, const char *value) -+static int cmd_set(const char *item, const char *value) - { - char *ret_error; - if (hdhomerun_device_set_var(hd, item, value, NULL, &ret_error) < 0) { -@@ -170,260 +154,118 @@ - return 1; - } - --static int cmd_set(const char *item, const char *value) -+static int cmd_streaminfo(const char *tuner_str) - { -- if (strcmp(value, "-") == 0) { -- char *buffer = NULL; -- size_t pos = 0; -- -- while (1) { -- buffer = (char *)realloc(buffer, pos + 1024); -- if (!buffer) { -- fprintf(stderr, "out of memory\n"); -- return -1; -- } -- -- size_t size = fread(buffer + pos, 1, 1024, stdin); -- pos += size; -- -- if (size < 1024) { -- break; -- } -- } -- -- buffer[pos] = 0; -- -- int ret = cmd_set_internal(item, buffer); -- -- free(buffer); -- return ret; -- } -- -- return cmd_set_internal(item, value); --} -- --static bool_t sigabort = FALSE; -- --static void signal_abort(int arg) --{ -- sigabort = TRUE; --} -- --static void cmd_scan_printf(FILE *fp, const char *fmt, ...) --{ -- va_list ap; -- va_start(ap, fmt); -- -- if (fp) { -- va_list apc; -- va_copy(apc, ap); -- -- vfprintf(fp, fmt, apc); -- fflush(fp); -- -- va_end(apc); -- } -- -- vprintf(fmt, ap); -- fflush(stdout); -- -- va_end(ap); -+ fprintf(stderr, "streaminfo: use \"get /tuner<n>/streaminfo\"\n"); -+ return -1; - } - --static int cmd_scan(const char *tuner_str, const char *filename) -+static int cmd_scan(const char *tuner_str, const char *start_value) - { -- if (hdhomerun_device_set_tuner_from_str(hd, tuner_str) <= 0) { -+ unsigned int tuner; -+ if (sscanf(tuner_str, "%u", &tuner) != 1) { - fprintf(stderr, "invalid tuner number\n"); - return -1; - } - -- char *ret_error; -- if (hdhomerun_device_tuner_lockkey_request(hd, &ret_error) <= 0) { -- fprintf(stderr, "failed to lock tuner\n"); -- if (ret_error) { -- fprintf(stderr, "%s\n", ret_error); -- } -- return -1; -- } -+ hdhomerun_device_set_tuner(hd, tuner); - -- hdhomerun_device_set_tuner_target(hd, "none"); -- -- char *channelmap; -- if (hdhomerun_device_get_tuner_channelmap(hd, &channelmap) <= 0) { -- fprintf(stderr, "failed to query channelmap from device\n"); -- return -1; -+ char channel_str[64]; -+ strncpy(channel_str, start_value, sizeof(channel_str)); -+ channel_str[sizeof(channel_str) - 8] = 0; -+ -+ char *channel_number_ptr = strrchr(channel_str, ':'); -+ if (!channel_number_ptr) { -+ channel_number_ptr = channel_str; -+ } else { -+ channel_number_ptr++; - } - -- const char *channelmap_scan_group = hdhomerun_channelmap_get_channelmap_scan_group(channelmap); -- if (!channelmap_scan_group) { -- fprintf(stderr, "unknown channelmap '%s'\n", channelmap); -+ unsigned int channel_number = atol(channel_number_ptr); -+ if (channel_number == 0) { -+ fprintf(stderr, "invalid starting channel\n"); - return -1; - } - -- if (hdhomerun_device_channelscan_init(hd, channelmap_scan_group) <= 0) { -- fprintf(stderr, "failed to initialize channel scan\n"); -+ /* Test starting channel. */ -+ int ret = hdhomerun_device_set_tuner_channel(hd, channel_str); -+ if (ret < 0) { -+ fprintf(stderr, "communication error sending request to hdhomerun device\n"); - return -1; - } -- -- FILE *fp = NULL; -- if (filename) { -- fp = fopen(filename, "w"); -- if (!fp) { -- fprintf(stderr, "unable to create file: %s\n", filename); -- return -1; -- } -+ if (ret == 0) { -+ fprintf(stderr, "invalid starting channel\n"); -+ return -1; - } - -- signal(SIGINT, signal_abort); -- signal(SIGPIPE, signal_abort); -+ while (1) { -+ /* Update channel value */ -+ sprintf(channel_number_ptr, "%u", channel_number); - -- int ret = 0; -- while (!sigabort) { -- struct hdhomerun_channelscan_result_t result; -- ret = hdhomerun_device_channelscan_advance(hd, &result); -- if (ret <= 0) { -- break; -+ /* Set channel. */ -+ ret = hdhomerun_device_set_tuner_channel(hd, channel_str); -+ if (ret < 0) { -+ fprintf(stderr, "communication error sending request to hdhomerun device\n"); -+ return -1; - } -- -- cmd_scan_printf(fp, "SCANNING: %lu (%s)\n", -- result.frequency, result.channel_str -- ); -- -- ret = hdhomerun_device_channelscan_detect(hd, &result); -- if (ret <= 0) { -- break; -+ if (ret == 0) { -+ return 0; - } - -- cmd_scan_printf(fp, "LOCK: %s (ss=%u snq=%u seq=%u)\n", -- result.status.lock_str, result.status.signal_strength, -- result.status.signal_to_noise_quality, result.status.symbol_error_quality -- ); -+ /* Wait 1.5s for lock (qam auto is the slowest to lock). */ -+ usleep(HDHOMERUN_DEVICE_MAX_TUNE_TO_LOCK_TIME * 1000); - -- if (result.transport_stream_id_detected) { -- cmd_scan_printf(fp, "TSID: 0x%04X\n", result.transport_stream_id); -+ /* Get status to check for signal. Quality numbers will not be valid yet. */ -+ struct hdhomerun_tuner_status_t status; -+ if (hdhomerun_device_get_tuner_status(hd, &status) < 0) { -+ fprintf(stderr, "communication error sending request to hdhomerun device\n"); -+ return -1; - } - -- int i; -- for (i = 0; i < result.program_count; i++) { -- struct hdhomerun_channelscan_program_t *program = &result.programs[i]; -- cmd_scan_printf(fp, "PROGRAM %s\n", program->program_str); -+ /* If no signal then advance to next channel. */ -+ if (status.signal_strength == 0) { -+ printf("%s: no signal\n", channel_str); -+ channel_number++; -+ continue; - } -- } -- -- hdhomerun_device_tuner_lockkey_release(hd); - -- if (fp) { -- fclose(fp); -- } -- if (ret < 0) { -- fprintf(stderr, "communication error sending request to hdhomerun device\n"); -- } -- return ret; --} -- --static int cmd_save(const char *tuner_str, const char *filename) --{ -- if (hdhomerun_device_set_tuner_from_str(hd, tuner_str) <= 0) { -- fprintf(stderr, "invalid tuner number\n"); -- return -1; -- } -+ /* Wait for 2s. */ -+ usleep(HDHOMERUN_DEVICE_MAX_LOCK_TO_DATA_TIME * 1000); - -- FILE *fp; -- if (strcmp(filename, "null") == 0) { -- fp = NULL; -- } else if (strcmp(filename, "-") == 0) { -- fp = stdout; -- } else { -- fp = fopen(filename, "wb"); -- if (!fp) { -- fprintf(stderr, "unable to create file %s\n", filename); -+ /* Get status to check quality numbers. */ -+ if (hdhomerun_device_get_tuner_status(hd, &status) < 0) { -+ fprintf(stderr, "communication error sending request to hdhomerun device\n"); - return -1; - } -- } -- -- int ret = hdhomerun_device_stream_start(hd); -- if (ret <= 0) { -- fprintf(stderr, "unable to start stream\n"); -- if (fp && fp != stdout) { -- fclose(fp); -- } -- return ret; -- } -- -- signal(SIGINT, signal_abort); -- signal(SIGPIPE, signal_abort); -- -- struct hdhomerun_video_stats_t stats_old, stats_cur; -- hdhomerun_device_get_video_stats(hd, &stats_old); -- -- uint64_t next_progress = getcurrenttime() + 1000; -- -- while (!sigabort) { -- uint64_t loop_start_time = getcurrenttime(); -- -- size_t actual_size; -- uint8_t *ptr = hdhomerun_device_stream_recv(hd, VIDEO_DATA_BUFFER_SIZE_1S, &actual_size); -- if (!ptr) { -- msleep(64); -+ if (status.signal_strength == 0) { -+ printf("%s: no signal\n", channel_str); -+ channel_number++; - continue; - } -+ printf("%s: ss=%u snq=%u seq=%u\n", channel_str, status.signal_strength, status.signal_to_noise_quality, status.symbol_error_quality); - -- if (fp) { -- if (fwrite(ptr, 1, actual_size, fp) != actual_size) { -- fprintf(stderr, "error writing output\n"); -- return -1; -- } -+ /* Detect sub channels. */ -+ usleep(4 * 1000000); -+ char *streaminfo; -+ if (hdhomerun_device_get_tuner_streaminfo(hd, &streaminfo) <= 0) { -+ channel_number++; -+ continue; - } -- -- if (loop_start_time >= next_progress) { -- next_progress += 1000; -- if (loop_start_time >= next_progress) { -- next_progress = loop_start_time + 1000; -- } -- -- hdhomerun_device_get_video_stats(hd, &stats_cur); -- -- if (stats_cur.overflow_error_count > stats_old.overflow_error_count) { -- fprintf(stderr, "o"); -- } else if (stats_cur.network_error_count > stats_old.network_error_count) { -- fprintf(stderr, "n"); -- } else if (stats_cur.transport_error_count > stats_old.transport_error_count) { -- fprintf(stderr, "t"); -- } else if (stats_cur.sequence_error_count > stats_old.sequence_error_count) { -- fprintf(stderr, "s"); -- } else { -- fprintf(stderr, "."); -+ while (1) { -+ char *end = strchr(streaminfo, '\n'); -+ if (!end) { -+ break; - } - -- stats_old = stats_cur; -- fflush(stderr); -- } -+ *end++ = 0; -+ printf("program %s\n", streaminfo); - -- int32_t delay = 64 - (int32_t)(getcurrenttime() - loop_start_time); -- if (delay <= 0) { -- continue; -+ streaminfo = end; - } - -- msleep(delay); -- } -- -- if (fp) { -- fclose(fp); -+ /* Advance to next channel. */ -+ channel_number++; - } -- -- hdhomerun_device_stream_stop(hd); -- hdhomerun_device_get_video_stats(hd, &stats_cur); -- -- fprintf(stderr, "\n"); -- fprintf(stderr, "-- Video statistics --\n"); -- fprintf(stderr, "%u packets received, %u overflow errors, %u network errors, %u transport errors, %u sequence errors\n", -- (unsigned int)stats_cur.packet_count, -- (unsigned int)stats_cur.overflow_error_count, -- (unsigned int)stats_cur.network_error_count, -- (unsigned int)stats_cur.transport_error_count, -- (unsigned int)stats_cur.sequence_error_count); -- -- return 0; - } - - static int cmd_upgrade(const char *filename) -@@ -434,98 +276,16 @@ - return -1; - } - -- printf("uploading firmware...\n"); - if (hdhomerun_device_upgrade(hd, fp) <= 0) { - fprintf(stderr, "error sending upgrade file to hdhomerun device\n"); - fclose(fp); - return -1; - } -- sleep(2); -- -- printf("upgrading firmware...\n"); -- sleep(8); -- -- printf("rebooting...\n"); -- int count = 0; -- char *version_str; -- while (1) { -- if (hdhomerun_device_get_version(hd, &version_str, NULL) >= 0) { -- break; -- } -- -- count++; -- if (count > 30) { -- fprintf(stderr, "error finding device after firmware upgrade\n"); -- fclose(fp); -- return -1; -- } - -- sleep(1); -- } -- -- printf("upgrade complete - now running firmware %s\n", version_str); -+ printf("upgrade complete\n"); - return 0; - } - --static int cmd_execute(void) --{ -- char *ret_value; -- char *ret_error; -- if (hdhomerun_device_get_var(hd, "/sys/boot", &ret_value, &ret_error) < 0) { -- fprintf(stderr, "communication error sending request to hdhomerun device\n"); -- return -1; -- } -- -- if (ret_error) { -- printf("%s\n", ret_error); -- return 0; -- } -- -- char *end = ret_value + strlen(ret_value); -- char *pos = ret_value; -- -- while (1) { -- if (pos >= end) { -- break; -- } -- -- char *eol_r = strchr(pos, '\r'); -- if (!eol_r) { -- eol_r = end; -- } -- -- char *eol_n = strchr(pos, '\n'); -- if (!eol_n) { -- eol_n = end; -- } -- -- char *eol = eol_r; -- if (eol_n < eol) { -- eol = eol_n; -- } -- -- char *sep = strchr(pos, ' '); -- if (!sep || sep > eol) { -- pos = eol + 1; -- continue; -- } -- -- *sep = 0; -- *eol = 0; -- -- char *item = pos; -- char *value = sep + 1; -- -- printf("set %s \"%s\"\n", item, value); -- -- cmd_set_internal(item, value); -- -- pos = eol + 1; -- } -- -- return 1; --} -- - static int main_cmd(int argc, char *argv[]) - { - if (argc < 1) { -@@ -534,17 +294,6 @@ - - char *cmd = *argv++; argc--; - -- if (contains(cmd, "key")) { -- if (argc < 2) { -- return help(); -- } -- uint32_t lockkey = strtoul(argv[0], NULL, 0); -- hdhomerun_device_tuner_lockkey_use_value(hd, lockkey); -- -- cmd = argv[1]; -- argv+=2; argc-=2; -- } -- - if (contains(cmd, "get")) { - if (argc < 1) { - return help(); -@@ -559,22 +308,18 @@ - return cmd_set(argv[0], argv[1]); - } - -- if (contains(cmd, "scan")) { -+ if (contains(cmd, "streaminfo")) { - if (argc < 1) { - return help(); - } -- if (argc < 2) { -- return cmd_scan(argv[0], NULL); -- } else { -- return cmd_scan(argv[0], argv[1]); -- } -+ return cmd_streaminfo(argv[0]); - } - -- if (contains(cmd, "save")) { -+ if (contains(cmd, "scan")) { - if (argc < 2) { - return help(); - } -- return cmd_save(argv[0], argv[1]); -+ return cmd_scan(argv[0], argv[1]); - } - - if (contains(cmd, "upgrade")) { -@@ -584,17 +329,16 @@ - return cmd_upgrade(argv[0]); - } - -- if (contains(cmd, "execute")) { -- return cmd_execute(); -- } -- - return help(); - } - - static int main_internal(int argc, char *argv[]) - { - #if defined(__WINDOWS__) -- /* Initialize network socket support. */ -+ //Start pthreads -+ pthread_win32_process_attach_np(); -+ -+ // Start WinSock - WORD wVersionRequested = MAKEWORD(2, 0); - WSADATA wsaData; - WSAStartup(wVersionRequested, &wsaData); -@@ -613,36 +357,35 @@ - return help(); - } - if (contains(id_str, "discover")) { -- if (argc < 1) { -- return discover_print(NULL); -- } else { -- return discover_print(argv[0]); -- } -+ return discover_print(); - } - -- /* Device object. */ -- hd = hdhomerun_device_create_from_str(id_str, NULL); -- if (!hd) { -- fprintf(stderr, "invalid device id: %s\n", id_str); -+ /* Device ID. */ -+ uint32_t device_id, device_ip; -+ if (!parse_device_id_str(id_str, &device_id, &device_ip)) { - return -1; - } - -- /* Device ID check. */ -- uint32_t device_id_requested = hdhomerun_device_get_device_id_requested(hd); -- if (!hdhomerun_discover_validate_device_id(device_id_requested)) { -- fprintf(stderr, "invalid device id: %08lX\n", (unsigned long)device_id_requested); -+ /* Device object. */ -+ hd = hdhomerun_device_create(device_id, device_ip, 0); -+ if (!hd) { -+ fprintf(stderr, "unable to create device\n"); -+ return -1; - } - -- /* Connect to device and check model. */ -- const char *model = hdhomerun_device_get_model_str(hd); -- if (!model) { -+ /* Connect to device and check firmware version. */ -+ int ret = hdhomerun_device_firmware_version_check(hd, 0); -+ if (ret < 0) { - fprintf(stderr, "unable to connect to device\n"); - hdhomerun_device_destroy(hd); - return -1; - } -+ if (ret == 0) { -+ fprintf(stderr, "WARNING: firmware upgrade needed for all operations to function\n"); -+ } - - /* Command. */ -- int ret = main_cmd(argc, argv); -+ ret = main_cmd(argc, argv); - - /* Cleanup. */ - hdhomerun_device_destroy(hd); -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.c src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_control.c ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.c 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_control.c 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_control.c - * -- * Copyright © 2006 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,119 +14,83 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - --#include "hdhomerun.h" -- --#define HDHOMERUN_CONTROL_SEND_TIMEOUT 5000 --#define HDHOMERUN_CONTROL_RECV_TIMEOUT 5000 --#define HDHOMERUN_CONTROL_UPGRADE_TIMEOUT 20000 -+#include "hdhomerun_os.h" -+#include "hdhomerun_pkt.h" -+#include "hdhomerun_discover.h" -+#include "hdhomerun_control.h" - - struct hdhomerun_control_sock_t { -- uint32_t desired_device_id; -- uint32_t desired_device_ip; -- uint32_t actual_device_id; -- uint32_t actual_device_ip; -+ uint32_t device_id; -+ uint32_t device_ip; - int sock; -- struct hdhomerun_debug_t *dbg; -- struct hdhomerun_pkt_t tx_pkt; -- struct hdhomerun_pkt_t rx_pkt; -+ uint8_t buffer[16384]; - }; - --static void hdhomerun_control_close_sock(struct hdhomerun_control_sock_t *cs) --{ -- if (cs->sock == -1) { -- return; -- } -- -- close(cs->sock); -- cs->sock = -1; --} -- --void hdhomerun_control_set_device(struct hdhomerun_control_sock_t *cs, uint32_t device_id, uint32_t device_ip) --{ -- hdhomerun_control_close_sock(cs); -- -- cs->desired_device_id = device_id; -- cs->desired_device_ip = device_ip; -- cs->actual_device_id = 0; -- cs->actual_device_ip = 0; --} -- --struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, uint32_t device_ip, struct hdhomerun_debug_t *dbg) -+struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, uint32_t device_ip) - { -- struct hdhomerun_control_sock_t *cs = (struct hdhomerun_control_sock_t *)calloc(1, sizeof(struct hdhomerun_control_sock_t)); -+ struct hdhomerun_control_sock_t *cs = (struct hdhomerun_control_sock_t *)malloc(sizeof(struct hdhomerun_control_sock_t)); - if (!cs) { -- hdhomerun_debug_printf(dbg, "hdhomerun_control_create: failed to allocate control object\n"); - return NULL; - } -- -- cs->dbg = dbg; -+ -+ cs->device_id = device_id; -+ cs->device_ip = device_ip; - cs->sock = -1; -- hdhomerun_control_set_device(cs, device_id, device_ip); - - return cs; - } - - void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs) - { -- hdhomerun_control_close_sock(cs); -+ if (cs->sock != -1) { -+ close(cs->sock); -+ } - free(cs); - } - -+static void hdhomerun_control_close_sock(struct hdhomerun_control_sock_t *cs) -+{ -+ close(cs->sock); -+ cs->sock = -1; -+} -+ - static bool_t hdhomerun_control_connect_sock(struct hdhomerun_control_sock_t *cs) - { - if (cs->sock != -1) { - return TRUE; - } - -- if ((cs->desired_device_id == 0) && (cs->desired_device_ip == 0)) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: no device specified\n"); -- return FALSE; -- } -- -- /* Find device. */ -- struct hdhomerun_discover_device_t result; -- if (hdhomerun_discover_find_devices_custom(cs->desired_device_ip, HDHOMERUN_DEVICE_TYPE_WILDCARD, cs->desired_device_id, &result, 1) <= 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: device not found\n"); -- return FALSE; -+ /* Find ip address. */ -+ uint32_t device_ip = cs->device_ip; -+ if (device_ip == 0) { -+ struct hdhomerun_discover_device_t result; -+ if (hdhomerun_discover_find_device(cs->device_id, &result) <= 0) { -+ return FALSE; -+ } -+ device_ip = result.ip_addr; - } -- cs->actual_device_ip = result.ip_addr; -- cs->actual_device_id = result.device_id; - - /* Create socket. */ - cs->sock = (int)socket(AF_INET, SOCK_STREAM, 0); - if (cs->sock == -1) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to create socket (%d)\n", sock_getlasterror); - return FALSE; - } - - /* Set timeouts. */ -- setsocktimeout(cs->sock, SOL_SOCKET, SO_SNDTIMEO, HDHOMERUN_CONTROL_SEND_TIMEOUT); -- setsocktimeout(cs->sock, SOL_SOCKET, SO_RCVTIMEO, HDHOMERUN_CONTROL_RECV_TIMEOUT); -+ setsocktimeout(cs->sock, SOL_SOCKET, SO_SNDTIMEO, 1000); -+ setsocktimeout(cs->sock, SOL_SOCKET, SO_RCVTIMEO, 1000); - - /* Initiate connection. */ - struct sockaddr_in sock_addr; - memset(&sock_addr, 0, sizeof(sock_addr)); - sock_addr.sin_family = AF_INET; -- sock_addr.sin_addr.s_addr = htonl(cs->actual_device_ip); -+ sock_addr.sin_addr.s_addr = htonl(device_ip); - sock_addr.sin_port = htons(HDHOMERUN_CONTROL_TCP_PORT); - if (connect(cs->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to connect (%d)\n", sock_getlasterror); - hdhomerun_control_close_sock(cs); - return FALSE; - } -@@ -135,215 +99,125 @@ - return TRUE; - } - --uint32_t hdhomerun_control_get_device_id(struct hdhomerun_control_sock_t *cs) --{ -- if (!hdhomerun_control_connect_sock(cs)) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_device_id: connect failed\n"); -- return 0; -- } -- -- return cs->actual_device_id; --} -- --uint32_t hdhomerun_control_get_device_ip(struct hdhomerun_control_sock_t *cs) --{ -- if (!hdhomerun_control_connect_sock(cs)) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_device_ip: connect failed\n"); -- return 0; -- } -- -- return cs->actual_device_ip; --} -- --uint32_t hdhomerun_control_get_device_id_requested(struct hdhomerun_control_sock_t *cs) --{ -- return cs->desired_device_id; --} -- --uint32_t hdhomerun_control_get_device_ip_requested(struct hdhomerun_control_sock_t *cs) --{ -- return cs->desired_device_ip; --} -- - uint32_t hdhomerun_control_get_local_addr(struct hdhomerun_control_sock_t *cs) - { - if (!hdhomerun_control_connect_sock(cs)) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_local_addr: connect failed\n"); - return 0; - } - - struct sockaddr_in sock_addr; - socklen_t sockaddr_size = sizeof(sock_addr); - if (getsockname(cs->sock, (struct sockaddr*)&sock_addr, &sockaddr_size) != 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_local_addr: getsockname failed (%d)\n", sock_getlasterror); - return 0; - } - - return ntohl(sock_addr.sin_addr.s_addr); - } - --static int hdhomerun_control_send_sock(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt) -+static int hdhomerun_control_send(struct hdhomerun_control_sock_t *cs, uint8_t *start, uint8_t *end) - { -- int length = (int)(tx_pkt->end - tx_pkt->start); -- if (send(cs->sock, (char *)tx_pkt->start, (int)length, 0) != length) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_sock: send failed (%d)\n", sock_getlasterror); -- hdhomerun_control_close_sock(cs); -+ int length = (int)(end - start); -+ if (send(cs->sock, (char *)start, (int)length, 0) != length) { - return -1; - } - -- return 1; -+ return length; - } - --static int hdhomerun_control_recv_sock(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *rx_pkt, uint16_t *ptype, uint64_t recv_timeout) -+static int hdhomerun_control_recv_sock(struct hdhomerun_control_sock_t *cs, uint8_t *buffer, uint8_t *limit) - { -- uint64_t stop_time = getcurrenttime() + recv_timeout; -- hdhomerun_pkt_reset(rx_pkt); -+ struct timeval t; -+ t.tv_sec = 0; -+ t.tv_usec = 250000; - -- while (getcurrenttime() < stop_time) { -- struct timeval t; -- t.tv_sec = 0; -- t.tv_usec = 250000; -- -- fd_set readfds; -- FD_ZERO(&readfds); -- FD_SET(cs->sock, &readfds); -- -- if (select(cs->sock+1, &readfds, NULL, NULL, &t) < 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: select failed (%d)\n", sock_getlasterror); -- hdhomerun_control_close_sock(cs); -- return -1; -- } -- -- if (!FD_ISSET(cs->sock, &readfds)) { -- continue; -- } -- -- int rx_length = recv(cs->sock, (char *)rx_pkt->end, (int)(rx_pkt->limit - rx_pkt->end), 0); -- if (rx_length <= 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: recv failed (%d)\n", sock_getlasterror); -- hdhomerun_control_close_sock(cs); -- return -1; -- } -- rx_pkt->end += rx_length; -+ fd_set readfds; -+ FD_ZERO(&readfds); -+ FD_SET(cs->sock, &readfds); - -- int ret = hdhomerun_pkt_open_frame(rx_pkt, ptype); -- if (ret < 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: frame error\n"); -- hdhomerun_control_close_sock(cs); -- return -1; -- } -- if (ret == 0) { -- continue; -- } -+ if (select(cs->sock+1, &readfds, NULL, NULL, &t) < 0) { -+ return -1; -+ } - -- return 1; -+ if (!FD_ISSET(cs->sock, &readfds)) { -+ return 0; - } - -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: timeout\n"); -- hdhomerun_control_close_sock(cs); -- return -1; -+ int length = recv(cs->sock, (char *)buffer, (int)(limit - buffer), 0); -+ if (length <= 0) { -+ return -1; -+ } -+ -+ return length; - } - --static int hdhomerun_control_send_recv_internal(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt, struct hdhomerun_pkt_t *rx_pkt, uint16_t type, uint64_t recv_timeout) -+static int hdhomerun_control_recv(struct hdhomerun_control_sock_t *cs, uint8_t *buffer, uint8_t *limit) - { -- hdhomerun_pkt_seal_frame(tx_pkt, type); -+ uint64_t timeout = getcurrenttime() + 1000; -+ uint8_t *ptr = buffer; - -- int i; -- for (i = 0; i < 2; i++) { -- if (cs->sock == -1) { -- if (!hdhomerun_control_connect_sock(cs)) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: connect failed\n"); -- return -1; -- } -+ while (getcurrenttime() < timeout) { -+ int length = hdhomerun_control_recv_sock(cs, ptr, limit); -+ if (length < 0) { -+ return -1; - } -- -- if (hdhomerun_control_send_sock(cs, tx_pkt) < 0) { -+ if (length == 0) { - continue; - } -- if (!rx_pkt) { -- return 1; -- } -+ ptr += length; - -- uint16_t rsp_type; -- if (hdhomerun_control_recv_sock(cs, rx_pkt, &rsp_type, recv_timeout) < 0) { -+ if (buffer + HDHOMERUN_MIN_PEEK_LENGTH > limit) { - continue; - } -- if (rsp_type != type + 1) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: unexpected frame type\n"); -- hdhomerun_control_close_sock(cs); -+ -+ length = (int)hdhomerun_peek_packet_length(buffer); -+ if (buffer + length > limit) { - continue; - } - -- return 1; -+ return length; - } - -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: failed\n"); - return -1; - } - --int hdhomerun_control_send_recv(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt, struct hdhomerun_pkt_t *rx_pkt, uint16_t type) -+static int hdhomerun_control_get_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror) - { -- return hdhomerun_control_send_recv_internal(cs, tx_pkt, rx_pkt, type, HDHOMERUN_CONTROL_RECV_TIMEOUT); --} -- --static int hdhomerun_control_get_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, uint32_t lockkey, char **pvalue, char **perror) --{ -- struct hdhomerun_pkt_t *tx_pkt = &cs->tx_pkt; -- struct hdhomerun_pkt_t *rx_pkt = &cs->rx_pkt; -- -- /* Request. */ -- hdhomerun_pkt_reset(tx_pkt); -- -- int name_len = (int)strlen(name) + 1; -- if (tx_pkt->end + 3 + name_len > tx_pkt->limit) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_set: request too long\n"); -+ /* Send request. */ -+ uint8_t *ptr = cs->buffer; -+ hdhomerun_write_get_set_request(&ptr, name, value); -+ if (hdhomerun_control_send(cs, cs->buffer, ptr) < 0) { - return -1; - } -- hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_GETSET_NAME); -- hdhomerun_pkt_write_var_length(tx_pkt, name_len); -- hdhomerun_pkt_write_mem(tx_pkt, (void *)name, name_len); - -- if (value) { -- int value_len = (int)strlen(value) + 1; -- if (tx_pkt->end + 3 + value_len > tx_pkt->limit) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_set: request too long\n"); -- return -1; -- } -- hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_GETSET_VALUE); -- hdhomerun_pkt_write_var_length(tx_pkt, value_len); -- hdhomerun_pkt_write_mem(tx_pkt, (void *)value, value_len); -+ /* Receive response. */ -+ int length = hdhomerun_control_recv(cs, cs->buffer, cs->buffer + sizeof(cs->buffer)); -+ if (length <= 0) { -+ return -1; - } - -- if (lockkey != 0) { -- if (tx_pkt->end + 6 > tx_pkt->limit) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_set: request too long\n"); -- return -1; -- } -- hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_GETSET_LOCKKEY); -- hdhomerun_pkt_write_var_length(tx_pkt, 4); -- hdhomerun_pkt_write_u32(tx_pkt, lockkey); -+ /* Parse response. */ -+ ptr = cs->buffer; -+ uint8_t *end = ptr + length; -+ int type = hdhomerun_process_packet(&ptr, &end); -+ if (type < 0) { -+ return -1; - } -- -- /* Send/Recv. */ -- if (hdhomerun_control_send_recv_internal(cs, tx_pkt, rx_pkt, HDHOMERUN_TYPE_GETSET_REQ, HDHOMERUN_CONTROL_RECV_TIMEOUT) < 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_set: send/recv error\n"); -+ if (type != HDHOMERUN_TYPE_GETSET_RPY) { - return -1; - } - -- /* Response. */ -- while (1) { -+ while (ptr < end) { - uint8_t tag; - size_t len; -- uint8_t *next = hdhomerun_pkt_read_tlv(rx_pkt, &tag, &len); -- if (!next) { -+ uint8_t *val; -+ if (hdhomerun_read_tlv(&ptr, end, &tag, &len, &val) < 0) { - break; - } -- - switch (tag) { - case HDHOMERUN_TAG_GETSET_VALUE: - if (pvalue) { -- *pvalue = (char *)rx_pkt->pos; -- rx_pkt->pos[len] = 0; -+ *pvalue = (char *)val; -+ val[len] = 0; - } - if (perror) { - *perror = NULL; -@@ -351,48 +225,59 @@ - return 1; - - case HDHOMERUN_TAG_ERROR_MESSAGE: -- rx_pkt->pos[len] = 0; -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_set: %s\n", rx_pkt->pos); -- - if (pvalue) { - *pvalue = NULL; - } - if (perror) { -- *perror = (char *)rx_pkt->pos; -+ *perror = (char *)val; -+ val[len] = 0; - } -- - return 0; - } -- -- rx_pkt->pos = next; - } - -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_set: missing response tags\n"); - return -1; - } - - int hdhomerun_control_get(struct hdhomerun_control_sock_t *cs, const char *name, char **pvalue, char **perror) - { -- return hdhomerun_control_get_set(cs, name, NULL, 0, pvalue, perror); -+ if (!hdhomerun_control_connect_sock(cs)) { -+ return -1; -+ } -+ -+ int ret = hdhomerun_control_get_set(cs, name, NULL, pvalue, perror); -+ if (ret < 0) { -+ hdhomerun_control_close_sock(cs); -+ return -1; -+ } -+ -+ return ret; - } - - int hdhomerun_control_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror) - { -- return hdhomerun_control_get_set(cs, name, value, 0, pvalue, perror); --} -+ if (!hdhomerun_control_connect_sock(cs)) { -+ return -1; -+ } - --int hdhomerun_control_set_with_lockkey(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, uint32_t lockkey, char **pvalue, char **perror) --{ -- return hdhomerun_control_get_set(cs, name, value, lockkey, pvalue, perror); -+ int ret = hdhomerun_control_get_set(cs, name, value, pvalue, perror); -+ if (ret < 0) { -+ hdhomerun_control_close_sock(cs); -+ return -1; -+ } -+ -+ return ret; - } - - int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file) - { -- struct hdhomerun_pkt_t *tx_pkt = &cs->tx_pkt; -- struct hdhomerun_pkt_t *rx_pkt = &cs->rx_pkt; -+ if (!hdhomerun_control_connect_sock(cs)) { -+ return -1; -+ } -+ - uint32_t sequence = 0; -+ uint8_t *ptr; - -- /* Upload. */ - while (1) { - uint8_t data[256]; - size_t length = fread(data, 1, 256, upgrade_file); -@@ -400,12 +285,10 @@ - break; - } - -- hdhomerun_pkt_reset(tx_pkt); -- hdhomerun_pkt_write_u32(tx_pkt, sequence); -- hdhomerun_pkt_write_mem(tx_pkt, data, length); -- -- if (hdhomerun_control_send_recv_internal(cs, tx_pkt, NULL, HDHOMERUN_TYPE_UPGRADE_REQ, 0) < 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_upgrade: send/recv failed\n"); -+ ptr = cs->buffer; -+ hdhomerun_write_upgrade_request(&ptr, sequence, data, length); -+ if (hdhomerun_control_send(cs, cs->buffer, ptr) < 0) { -+ hdhomerun_control_close_sock(cs); - return -1; - } - -@@ -414,40 +297,15 @@ - - if (sequence == 0) { - /* No data in file. Error, but no need to close connection. */ -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_upgrade: zero length file\n"); - return 0; - } - -- /* Execute upgrade. */ -- hdhomerun_pkt_reset(tx_pkt); -- hdhomerun_pkt_write_u32(tx_pkt, 0xFFFFFFFF); -- -- if (hdhomerun_control_send_recv_internal(cs, tx_pkt, rx_pkt, HDHOMERUN_TYPE_UPGRADE_REQ, HDHOMERUN_CONTROL_UPGRADE_TIMEOUT) < 0) { -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_upgrade: send/recv failed\n"); -+ ptr = cs->buffer; -+ hdhomerun_write_upgrade_request(&ptr, 0xFFFFFFFF, NULL, 0); -+ if (hdhomerun_control_send(cs, cs->buffer, ptr) < 0) { -+ hdhomerun_control_close_sock(cs); - return -1; - } - -- /* Check response. */ -- while (1) { -- uint8_t tag; -- size_t len; -- uint8_t *next = hdhomerun_pkt_read_tlv(rx_pkt, &tag, &len); -- if (!next) { -- break; -- } -- -- switch (tag) { -- case HDHOMERUN_TAG_ERROR_MESSAGE: -- rx_pkt->pos[len] = 0; -- hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_upgrade: %s\n", (char *)rx_pkt->pos); -- return 0; -- -- default: -- break; -- } -- -- rx_pkt->pos = next; -- } -- - return 1; - } -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.h src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_control.h ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.h 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_control.h 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_control.h - * -- * Copyright © 2006 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,20 +14,8 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - #ifdef __cplusplus - extern "C" { -@@ -43,26 +31,13 @@ - * - * uint32_t device_id = 32-bit device id of device. Set to HDHOMERUN_DEVICE_ID_WILDCARD to match any device ID. - * uint32_t device_ip = IP address of device. Set to 0 to auto-detect. -- * struct hdhomerun_debug_t *dbg: Pointer to debug logging object. May be NULL. - * - * Returns a pointer to the newly created control socket. - * - * When no longer needed, the socket should be destroyed by calling hdhomerun_control_destroy. - */ --extern LIBTYPE struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, uint32_t device_ip, struct hdhomerun_debug_t *dbg); --extern LIBTYPE void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs); -- --/* -- * Get the actual device id or ip of the device. -- * -- * Returns 0 if the device id cannot be determined. -- */ --extern LIBTYPE uint32_t hdhomerun_control_get_device_id(struct hdhomerun_control_sock_t *cs); --extern LIBTYPE uint32_t hdhomerun_control_get_device_ip(struct hdhomerun_control_sock_t *cs); --extern LIBTYPE uint32_t hdhomerun_control_get_device_id_requested(struct hdhomerun_control_sock_t *cs); --extern LIBTYPE uint32_t hdhomerun_control_get_device_ip_requested(struct hdhomerun_control_sock_t *cs); -- --extern LIBTYPE void hdhomerun_control_set_device(struct hdhomerun_control_sock_t *cs, uint32_t device_id, uint32_t device_ip); -+extern struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, uint32_t device_ip); -+extern void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs); - - /* - * Get the local machine IP address used when communicating with the device. -@@ -71,12 +46,7 @@ - * - * Returns 32-bit IP address with native endianness, or 0 on error. - */ --extern LIBTYPE uint32_t hdhomerun_control_get_local_addr(struct hdhomerun_control_sock_t *cs); -- --/* -- * Low-level communication. -- */ --extern LIBTYPE int hdhomerun_control_send_recv(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt, struct hdhomerun_pkt_t *rx_pkt, uint16_t type); -+extern uint32_t hdhomerun_control_get_local_addr(struct hdhomerun_control_sock_t *cs); - - /* - * Get/set a control variable on the device. -@@ -95,9 +65,8 @@ - * Returns 0 if the operation was rejected (pvalue NULL, perror set). - * Returns -1 if a communication error occurs. - */ --extern LIBTYPE int hdhomerun_control_get(struct hdhomerun_control_sock_t *cs, const char *name, char **pvalue, char **perror); --extern LIBTYPE int hdhomerun_control_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror); --extern LIBTYPE int hdhomerun_control_set_with_lockkey(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, uint32_t lockkey, char **pvalue, char **perror); -+extern int hdhomerun_control_get(struct hdhomerun_control_sock_t *cs, const char *name, char **pvalue, char **perror); -+extern int hdhomerun_control_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror); - - /* - * Upload new firmware to the device. -@@ -108,7 +77,7 @@ - * Returns 0 if the upload was rejected. - * Returns -1 if an error occurs. - */ --extern LIBTYPE int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file); -+extern int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file); - - #ifdef __cplusplus - } -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_debug.c -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_debug.h -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.c src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_device.c ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.c 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_device.c 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* -- * hdhomerun_device.c -+ * hdhomerun_record.c - * -- * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,92 +14,43 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - --#include "hdhomerun.h" -+#include "hdhomerun_os.h" -+#include "hdhomerun_pkt.h" -+#include "hdhomerun_control.h" -+#include "hdhomerun_video.h" -+#include "hdhomerun_device.h" - - struct hdhomerun_device_t { - struct hdhomerun_control_sock_t *cs; - struct hdhomerun_video_sock_t *vs; -- struct hdhomerun_debug_t *dbg; -- struct hdhomerun_channelscan_t *scan; -- uint32_t device_id; - unsigned int tuner; -- uint32_t lockkey; -- char name[32]; -- char model[32]; -+ char result_buffer[1024]; - }; - --static void hdhomerun_device_set_update(struct hdhomerun_device_t *hd) --{ -- /* Clear cached information. */ -- *hd->model = 0; -- -- /* New name. */ -- sprintf(hd->name, "%08lX-%u", (unsigned long)hd->device_id, hd->tuner); --} -- --void hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip) --{ -- hdhomerun_control_set_device(hd->cs, device_id, device_ip); -- -- if ((device_id == 0) || (device_id == HDHOMERUN_DEVICE_ID_WILDCARD)) { -- device_id = hdhomerun_control_get_device_id(hd->cs); -- } -- -- hd->device_id = device_id; -- hdhomerun_device_set_update(hd); --} -- --void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner) --{ -- hd->tuner = tuner; -- hdhomerun_device_set_update(hd); --} -- --struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner, struct hdhomerun_debug_t *dbg) -+struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner) - { - struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)calloc(1, sizeof(struct hdhomerun_device_t)); - if (!hd) { -- hdhomerun_debug_printf(dbg, "hdhomerun_device_create: failed to allocate device object\n"); - return NULL; - } - -- hd->dbg = dbg; -+ hd->tuner = tuner; - -- hd->cs = hdhomerun_control_create(0, 0, hd->dbg); -+ hd->cs = hdhomerun_control_create(device_id, device_ip); - if (!hd->cs) { -- hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_create: failed to create control object\n"); - free(hd); - return NULL; - } - -- hdhomerun_device_set_device(hd, device_id, device_ip); -- hdhomerun_device_set_tuner(hd, tuner); -- - return hd; - } - - void hdhomerun_device_destroy(struct hdhomerun_device_t *hd) - { -- if (hd->scan) { -- channelscan_destroy(hd->scan); -- } -- - if (hd->vs) { - hdhomerun_video_destroy(hd->vs); - } -@@ -109,152 +60,9 @@ - free(hd); - } - --static bool_t is_hex_char(char c) --{ -- if ((c >= '0') && (c <= '9')) { -- return TRUE; -- } -- if ((c >= 'A') && (c <= 'F')) { -- return TRUE; -- } -- if ((c >= 'a') && (c <= 'f')) { -- return TRUE; -- } -- return FALSE; --} -- --static struct hdhomerun_device_t *hdhomerun_device_create_from_str_device_id(const char *device_str, struct hdhomerun_debug_t *dbg) --{ -- int i; -- const char *ptr = device_str; -- for (i = 0; i < 8; i++) { -- if (!is_hex_char(*ptr++)) { -- return NULL; -- } -- } -- -- if (*ptr == 0) { -- unsigned long device_id; -- if (sscanf(device_str, "%lx", &device_id) != 1) { -- return NULL; -- } -- return hdhomerun_device_create((uint32_t)device_id, 0, 0, dbg); -- } -- -- if (*ptr == '-') { -- unsigned long device_id; -- unsigned int tuner; -- if (sscanf(device_str, "%lx-%u", &device_id, &tuner) != 2) { -- return NULL; -- } -- return hdhomerun_device_create((uint32_t)device_id, 0, tuner, dbg); -- } -- -- return NULL; --} -- --static struct hdhomerun_device_t *hdhomerun_device_create_from_str_ip(const char *device_str, struct hdhomerun_debug_t *dbg) --{ -- unsigned long a[4]; -- if (sscanf(device_str, "%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], &a[3]) != 4) { -- return NULL; -- } -- -- unsigned long device_ip = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0); -- return hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, (uint32_t)device_ip, 0, dbg); --} -- --static struct hdhomerun_device_t *hdhomerun_device_create_from_str_dns(const char *device_str, struct hdhomerun_debug_t *dbg) --{ --#if defined(__CYGWIN__) -- return NULL; --#else -- struct addrinfo hints; -- memset(&hints, 0, sizeof(hints)); -- hints.ai_family = AF_INET; -- hints.ai_socktype = SOCK_STREAM; -- hints.ai_protocol = IPPROTO_TCP; -- -- struct addrinfo *sock_info; -- if (getaddrinfo(device_str, "65001", &hints, &sock_info) != 0) { -- return NULL; -- } -- -- struct sockaddr_in *sock_addr = (struct sockaddr_in *)sock_info->ai_addr; -- uint32_t device_ip = ntohl(sock_addr->sin_addr.s_addr); -- freeaddrinfo(sock_info); -- -- if (device_ip == 0) { -- return NULL; -- } -- -- return hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, (uint32_t)device_ip, 0, dbg); --#endif --} -- --struct hdhomerun_device_t *hdhomerun_device_create_from_str(const char *device_str, struct hdhomerun_debug_t *dbg) --{ -- struct hdhomerun_device_t *device = hdhomerun_device_create_from_str_device_id(device_str, dbg); -- if (device) { -- return device; -- } -- -- device = hdhomerun_device_create_from_str_ip(device_str, dbg); -- if (device) { -- return device; -- } -- -- device = hdhomerun_device_create_from_str_dns(device_str, dbg); -- if (device) { -- return device; -- } -- -- return NULL; --} -- --int hdhomerun_device_set_tuner_from_str(struct hdhomerun_device_t *hd, const char *tuner_str) --{ -- unsigned int tuner; -- if (sscanf(tuner_str, "%u", &tuner) == 1) { -- hdhomerun_device_set_tuner(hd, tuner); -- return 1; -- } -- if (sscanf(tuner_str, "/tuner%u", &tuner) == 1) { -- hdhomerun_device_set_tuner(hd, tuner); -- return 1; -- } -- -- return -1; --} -- --const char *hdhomerun_device_get_name(struct hdhomerun_device_t *hd) --{ -- return hd->name; --} -- --uint32_t hdhomerun_device_get_device_id(struct hdhomerun_device_t *hd) --{ -- return hdhomerun_control_get_device_id(hd->cs); --} -- --uint32_t hdhomerun_device_get_device_ip(struct hdhomerun_device_t *hd) --{ -- return hdhomerun_control_get_device_ip(hd->cs); --} -- --uint32_t hdhomerun_device_get_device_id_requested(struct hdhomerun_device_t *hd) --{ -- return hdhomerun_control_get_device_id_requested(hd->cs); --} -- --uint32_t hdhomerun_device_get_device_ip_requested(struct hdhomerun_device_t *hd) --{ -- return hdhomerun_control_get_device_ip_requested(hd->cs); --} -- --unsigned int hdhomerun_device_get_tuner(struct hdhomerun_device_t *hd) -+void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner) - { -- return hd->tuner; -+ hd->tuner = tuner; - } - - struct hdhomerun_control_sock_t *hdhomerun_device_get_control_sock(struct hdhomerun_device_t *hd) -@@ -264,16 +72,9 @@ - - struct hdhomerun_video_sock_t *hdhomerun_device_get_video_sock(struct hdhomerun_device_t *hd) - { -- if (hd->vs) { -- return hd->vs; -- } -- -- hd->vs = hdhomerun_video_create(0, VIDEO_DATA_BUFFER_SIZE_1S * 2, hd->dbg); - if (!hd->vs) { -- hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_video_sock: failed to create video object\n"); -- return NULL; -+ hd->vs = hdhomerun_video_create(0, VIDEO_DATA_BUFFER_SIZE_1S); - } -- - return hd->vs; - } - -@@ -295,73 +96,7 @@ - return (uint32_t)value; - } - --static bool_t hdhomerun_device_get_tuner_status_lock_is_bcast(struct hdhomerun_tuner_status_t *status) --{ -- if (strcmp(status->lock_str, "8vsb") == 0) { -- return TRUE; -- } -- if (strncmp(status->lock_str, "t8", 2) == 0) { -- return TRUE; -- } -- if (strncmp(status->lock_str, "t7", 2) == 0) { -- return TRUE; -- } -- if (strncmp(status->lock_str, "t6", 2) == 0) { -- return TRUE; -- } -- -- return FALSE; --} -- --uint32_t hdhomerun_device_get_tuner_status_ss_color(struct hdhomerun_tuner_status_t *status) --{ -- unsigned int ss_yellow_min; -- unsigned int ss_green_min; -- -- if (!status->lock_supported) { -- return HDHOMERUN_STATUS_COLOR_NEUTRAL; -- } -- -- if (hdhomerun_device_get_tuner_status_lock_is_bcast(status)) { -- ss_yellow_min = 50; /* -30dBmV */ -- ss_green_min = 75; /* -15dBmV */ -- } else { -- ss_yellow_min = 80; /* -12dBmV */ -- ss_green_min = 90; /* -6dBmV */ -- } -- -- if (status->signal_strength >= ss_green_min) { -- return HDHOMERUN_STATUS_COLOR_GREEN; -- } -- if (status->signal_strength >= ss_yellow_min) { -- return HDHOMERUN_STATUS_COLOR_YELLOW; -- } -- -- return HDHOMERUN_STATUS_COLOR_RED; --} -- --uint32_t hdhomerun_device_get_tuner_status_snq_color(struct hdhomerun_tuner_status_t *status) --{ -- if (status->signal_to_noise_quality >= 70) { -- return HDHOMERUN_STATUS_COLOR_GREEN; -- } -- if (status->signal_to_noise_quality >= 50) { -- return HDHOMERUN_STATUS_COLOR_YELLOW; -- } -- -- return HDHOMERUN_STATUS_COLOR_RED; --} -- --uint32_t hdhomerun_device_get_tuner_status_seq_color(struct hdhomerun_tuner_status_t *status) --{ -- if (status->symbol_error_quality >= 100) { -- return HDHOMERUN_STATUS_COLOR_GREEN; -- } -- -- return HDHOMERUN_STATUS_COLOR_RED; --} -- --int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, char **pstatus_str, struct hdhomerun_tuner_status_t *status) -+int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status) - { - memset(status, 0, sizeof(struct hdhomerun_tuner_status_t)); - -@@ -374,18 +109,9 @@ - return ret; - } - -- if (pstatus_str) { -- *pstatus_str = status_str; -- } -- - char *channel = strstr(status_str, "ch="); - if (channel) { -- sscanf(channel + 3, "%31s", status->channel); -- } -- -- char *lock = strstr(status_str, "lock="); -- if (lock) { -- sscanf(lock + 5, "%31s", status->lock_str); -+ sscanf(channel + 3, "%s", status->channel); - } - - status->signal_strength = (unsigned int)hdhomerun_device_get_status_parse(status_str, "ss="); -@@ -394,16 +120,6 @@ - status->raw_bits_per_second = hdhomerun_device_get_status_parse(status_str, "bps="); - status->packets_per_second = hdhomerun_device_get_status_parse(status_str, "pps="); - -- status->signal_present = status->signal_strength >= 45; -- -- if (strcmp(status->lock_str, "none") != 0) { -- if (status->lock_str[0] == '(') { -- status->lock_unsupported = TRUE; -- } else { -- status->lock_supported = TRUE; -- } -- } -- - return 1; - } - -@@ -435,74 +151,26 @@ - return hdhomerun_control_get(hd->cs, name, pfilter, NULL); - } - --int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, char **pprogram) -+int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, uint16_t *pprogram_number) - { - char name[32]; - sprintf(name, "/tuner%u/program", hd->tuner); -- return hdhomerun_control_get(hd->cs, name, pprogram, NULL); --} -- --int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget) --{ -- char name[32]; -- sprintf(name, "/tuner%u/target", hd->tuner); -- return hdhomerun_control_get(hd->cs, name, ptarget, NULL); --} -- --int hdhomerun_device_get_tuner_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount) --{ -- char name[32]; -- sprintf(name, "/tuner%u/plotsample", hd->tuner); - -- char *result; -- int ret = hdhomerun_control_get(hd->cs, name, &result, NULL); -+ char *program_str; -+ int ret = hdhomerun_control_get(hd->cs, name, &program_str, NULL); - if (ret <= 0) { - return ret; - } - -- struct hdhomerun_plotsample_t *samples = (struct hdhomerun_plotsample_t *)result; -- *psamples = samples; -- size_t count = 0; -- -- while (1) { -- char *ptr = strchr(result, ' '); -- if (!ptr) { -- break; -- } -- *ptr++ = 0; -- -- unsigned long raw; -- if (sscanf(result, "%lx", &raw) != 1) { -- break; -- } -- -- uint16_t real = (raw >> 12) & 0x0FFF; -- if (real & 0x0800) { -- real |= 0xF000; -- } -- -- uint16_t imag = (raw >> 0) & 0x0FFF; -- if (imag & 0x0800) { -- imag |= 0xF000; -- } -- -- samples->real = (int16_t)real; -- samples->imag = (int16_t)imag; -- samples++; -- count++; -- -- result = ptr; -- } -- -- *pcount = count; -+ *pprogram_number = (uint16_t)atol(program_str); - return 1; - } - --int hdhomerun_device_get_tuner_lockkey_owner(struct hdhomerun_device_t *hd, char **powner) -+int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget) - { - char name[32]; -- sprintf(name, "/tuner%u/lockkey", hd->tuner); -- return hdhomerun_control_get(hd->cs, name, powner, NULL); -+ sprintf(name, "/tuner%u/target", hd->tuner); -+ return hdhomerun_control_get(hd->cs, name, ptarget, NULL); - } - - int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget) -@@ -510,11 +178,6 @@ - return hdhomerun_control_get(hd->cs, "/ir/target", ptarget, NULL); - } - --int hdhomerun_device_get_lineup_location(struct hdhomerun_device_t *hd, char **plocation) --{ -- return hdhomerun_control_get(hd->cs, "/lineup/location", plocation, NULL); --} -- - int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num) - { - char *version_str; -@@ -543,119 +206,44 @@ - { - char name[32]; - sprintf(name, "/tuner%u/channel", hd->tuner); -- return hdhomerun_control_set_with_lockkey(hd->cs, name, channel, hd->lockkey, NULL, NULL); -+ return hdhomerun_control_set(hd->cs, name, channel, NULL, NULL); - } - - int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap) - { - char name[32]; - sprintf(name, "/tuner%u/channelmap", hd->tuner); -- return hdhomerun_control_set_with_lockkey(hd->cs, name, channelmap, hd->lockkey, NULL, NULL); -+ return hdhomerun_control_set(hd->cs, name, channelmap, NULL, NULL); - } - - int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter) - { - char name[32]; - sprintf(name, "/tuner%u/filter", hd->tuner); -- return hdhomerun_control_set_with_lockkey(hd->cs, name, filter, hd->lockkey, NULL, NULL); --} -- --static int hdhomerun_device_set_tuner_filter_by_array_append(char **pptr, char *end, uint16_t range_begin, uint16_t range_end) --{ -- char *ptr = *pptr; -- -- size_t available = end - ptr; -- size_t required; -- -- if (range_begin == range_end) { -- required = snprintf(ptr, available, "0x%04x ", range_begin) + 1; -- } else { -- required = snprintf(ptr, available, "0x%04x-0x%04x ", range_begin, range_end) + 1; -- } -- -- if (required > available) { -- return FALSE; -- } -- -- *pptr = strchr(ptr, 0); -- return TRUE; --} -- --int hdhomerun_device_set_tuner_filter_by_array(struct hdhomerun_device_t *hd, unsigned char filter_array[0x2000]) --{ -- char filter[1024]; -- char *ptr = filter; -- char *end = filter + sizeof(filter); -- -- uint16_t range_begin = 0xFFFF; -- uint16_t range_end = 0xFFFF; -- -- uint16_t i; -- for (i = 0; i <= 0x1FFF; i++) { -- if (!filter_array[i]) { -- if (range_begin == 0xFFFF) { -- continue; -- } -- if (!hdhomerun_device_set_tuner_filter_by_array_append(&ptr, end, range_begin, range_end)) { -- return 0; -- } -- range_begin = 0xFFFF; -- range_end = 0xFFFF; -- continue; -- } -- -- if (range_begin == 0xFFFF) { -- range_begin = i; -- range_end = i; -- continue; -- } -- -- range_end = i; -- } -- -- if (range_begin != 0xFFFF) { -- if (!hdhomerun_device_set_tuner_filter_by_array_append(&ptr, end, range_begin, range_end)) { -- return 0; -- } -- } -- -- /* Remove trailing space. */ -- if (ptr > filter) { -- ptr--; -- } -- *ptr = 0; -- -- return hdhomerun_device_set_tuner_filter(hd, filter); -+ return hdhomerun_control_set(hd->cs, name, filter, NULL, NULL); - } - --int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, const char *program) -+int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, uint16_t program_number) - { -- char name[32]; -+ char name[32], value[32]; - sprintf(name, "/tuner%u/program", hd->tuner); -- return hdhomerun_control_set_with_lockkey(hd->cs, name, program, hd->lockkey, NULL, NULL); -+ sprintf(value, "%u", program_number); -+ return hdhomerun_control_set(hd->cs, name, value, NULL, NULL); - } - --int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, const char *target) -+int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, char *target) - { - char name[32]; - sprintf(name, "/tuner%u/target", hd->tuner); -- return hdhomerun_control_set_with_lockkey(hd->cs, name, target, hd->lockkey, NULL, NULL); -+ return hdhomerun_control_set(hd->cs, name, target, NULL, NULL); - } - --int hdhomerun_device_set_tuner_target_to_local_protocol(struct hdhomerun_device_t *hd, const char *protocol) -+static int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd) - { -- /* Create video socket. */ -- hdhomerun_device_get_video_sock(hd); -- if (!hd->vs) { -- return -1; -- } -- -- /* Set target. */ - char target[64]; - uint32_t local_ip = hdhomerun_control_get_local_addr(hd->cs); - uint16_t local_port = hdhomerun_video_get_local_port(hd->vs); -- sprintf(target, "%s://%u.%u.%u.%u:%u", -- protocol, -+ sprintf(target, "%u.%u.%u.%u:%u", - (unsigned int)(local_ip >> 24) & 0xFF, (unsigned int)(local_ip >> 16) & 0xFF, - (unsigned int)(local_ip >> 8) & 0xFF, (unsigned int)(local_ip >> 0) & 0xFF, - (unsigned int)local_port -@@ -664,21 +252,11 @@ - return hdhomerun_device_set_tuner_target(hd, target); - } - --int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd) --{ -- return hdhomerun_device_set_tuner_target_to_local_protocol(hd, HDHOMERUN_TARGET_PROTOCOL_UDP); --} -- - int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target) - { - return hdhomerun_control_set(hd->cs, "/ir/target", target, NULL, NULL); - } - --int hdhomerun_device_set_lineup_location(struct hdhomerun_device_t *hd, const char *location) --{ -- return hdhomerun_control_set(hd->cs, "/lineup/location", location, NULL, NULL); --} -- - int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, char **pvalue, char **perror) - { - return hdhomerun_control_get(hd->cs, name, pvalue, perror); -@@ -686,183 +264,41 @@ - - int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const char *name, const char *value, char **pvalue, char **perror) - { -- return hdhomerun_control_set_with_lockkey(hd->cs, name, value, hd->lockkey, pvalue, perror); --} -- --int hdhomerun_device_tuner_lockkey_request(struct hdhomerun_device_t *hd, char **perror) --{ -- uint32_t new_lockkey = (uint32_t)getcurrenttime(); -- -- char name[32]; -- sprintf(name, "/tuner%u/lockkey", hd->tuner); -- -- char new_lockkey_str[64]; -- sprintf(new_lockkey_str, "%u", (unsigned int)new_lockkey); -- -- int ret = hdhomerun_control_set_with_lockkey(hd->cs, name, new_lockkey_str, hd->lockkey, NULL, perror); -- if (ret <= 0) { -- hd->lockkey = 0; -- return ret; -- } -- -- hd->lockkey = new_lockkey; -- return ret; --} -- --int hdhomerun_device_tuner_lockkey_release(struct hdhomerun_device_t *hd) --{ -- if (hd->lockkey == 0) { -- return 1; -- } -- -- char name[32]; -- sprintf(name, "/tuner%u/lockkey", hd->tuner); -- int ret = hdhomerun_control_set_with_lockkey(hd->cs, name, "none", hd->lockkey, NULL, NULL); -- -- hd->lockkey = 0; -- return ret; --} -- --int hdhomerun_device_tuner_lockkey_force(struct hdhomerun_device_t *hd) --{ -- char name[32]; -- sprintf(name, "/tuner%u/lockkey", hd->tuner); -- int ret = hdhomerun_control_set(hd->cs, name, "force", NULL, NULL); -- -- hd->lockkey = 0; -- return ret; --} -- --void hdhomerun_device_tuner_lockkey_use_value(struct hdhomerun_device_t *hd, uint32_t lockkey) --{ -- hd->lockkey = lockkey; -+ return hdhomerun_control_set(hd->cs, name, value, pvalue, perror); - } - --int hdhomerun_device_wait_for_lock(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status) -+int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd) - { -- /* Delay for SS reading to be valid (signal present). */ -- msleep(250); -- -- /* Wait for up to 2.5 seconds for lock. */ -- uint64_t timeout = getcurrenttime() + 2500; -- while (1) { -- /* Get status to check for lock. Quality numbers will not be valid yet. */ -- int ret = hdhomerun_device_get_tuner_status(hd, NULL, status); -- if (ret <= 0) { -- return ret; -- } -- -- if (!status->signal_present) { -- return 1; -- } -- if (status->lock_supported || status->lock_unsupported) { -- return 1; -- } -- -- if (getcurrenttime() >= timeout) { -- return 1; -- } -- -- msleep(250); -+ /* Create video socket. */ -+ hdhomerun_device_get_video_sock(hd); -+ if (!hd->vs) { -+ return -1; - } --} - --int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd) --{ - /* Set target. */ -- int ret = hdhomerun_device_stream_refresh_target(hd); -+ int ret = hdhomerun_device_set_tuner_target_to_local(hd); - if (ret <= 0) { - return ret; - } - - /* Flush video buffer. */ -- msleep(64); -+ usleep(64000); - hdhomerun_video_flush(hd->vs); - - /* Success. */ - return 1; - } - --int hdhomerun_device_stream_refresh_target(struct hdhomerun_device_t *hd) --{ -- int ret = hdhomerun_device_set_tuner_target_to_local_protocol(hd, HDHOMERUN_TARGET_PROTOCOL_RTP); -- if (ret == 0) { -- ret = hdhomerun_device_set_tuner_target_to_local_protocol(hd, HDHOMERUN_TARGET_PROTOCOL_UDP); -- } -- return ret; --} -- - uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size) - { -- if (!hd->vs) { -- return NULL; -- } - return hdhomerun_video_recv(hd->vs, max_size, pactual_size); - } - --void hdhomerun_device_stream_flush(struct hdhomerun_device_t *hd) --{ -- hdhomerun_video_flush(hd->vs); --} -- - void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd) - { - hdhomerun_device_set_tuner_target(hd, "none"); - } - --int hdhomerun_device_channelscan_init(struct hdhomerun_device_t *hd, const char *channelmap) --{ -- if (hd->scan) { -- channelscan_destroy(hd->scan); -- } -- -- hd->scan = channelscan_create(hd, channelmap); -- if (!hd->scan) { -- return -1; -- } -- -- return 1; --} -- --int hdhomerun_device_channelscan_advance(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result) --{ -- if (!hd->scan) { -- return 0; -- } -- -- int ret = channelscan_advance(hd->scan, result); -- if (ret <= 0) { -- channelscan_destroy(hd->scan); -- hd->scan = NULL; -- } -- -- return ret; --} -- --int hdhomerun_device_channelscan_detect(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result) --{ -- if (!hd->scan) { -- return 0; -- } -- -- int ret = channelscan_detect(hd->scan, result); -- if (ret <= 0) { -- channelscan_destroy(hd->scan); -- hd->scan = NULL; -- } -- -- return ret; --} -- --uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd) --{ -- if (!hd->scan) { -- return 0; -- } -- -- return channelscan_get_progress(hd->scan); --} -- - int hdhomerun_device_firmware_version_check(struct hdhomerun_device_t *hd, uint32_t features) - { - uint32_t version; -@@ -870,74 +306,16 @@ - return -1; - } - -- if (version < 20070219) { -- return 0; -+ if (version >= 20061213) { -+ return 1; - } - -- return 1; --} -- --const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd) --{ -- if (*hd->model) { -- return hd->model; -- } -- -- char *model_str; -- int ret = hdhomerun_control_get(hd->cs, "/sys/model", &model_str, NULL); -- if (ret < 0) { -- return NULL; -- } -- if (ret == 0) { -- model_str = "hdhomerun_atsc"; -- } -- -- strncpy(hd->model, model_str, sizeof(hd->model) - 1); -- hd->model[sizeof(hd->model) - 1] = 0; -- -- return hd->model; -+ return 0; - } - - int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file) - { -- hdhomerun_control_set(hd->cs, "/tuner0/lockkey", "force", NULL, NULL); - hdhomerun_control_set(hd->cs, "/tuner0/channel", "none", NULL, NULL); -- -- hdhomerun_control_set(hd->cs, "/tuner1/lockkey", "force", NULL, NULL); - hdhomerun_control_set(hd->cs, "/tuner1/channel", "none", NULL, NULL); -- - return hdhomerun_control_upgrade(hd->cs, upgrade_file); - } -- --void hdhomerun_device_debug_print_video_stats(struct hdhomerun_device_t *hd) --{ -- if (!hdhomerun_debug_enabled(hd->dbg)) { -- return; -- } -- -- char name[32]; -- sprintf(name, "/tuner%u/debug", hd->tuner); -- -- char *debug_str; -- char *error_str; -- int ret = hdhomerun_control_get(hd->cs, name, &debug_str, &error_str); -- if (ret < 0) { -- hdhomerun_debug_printf(hd->dbg, "video dev: communication error getting debug stats\n"); -- return; -- } -- -- if (error_str) { -- hdhomerun_debug_printf(hd->dbg, "video dev: %s\n", error_str); -- } else { -- hdhomerun_debug_printf(hd->dbg, "video dev: %s\n", debug_str); -- } -- -- if (hd->vs) { -- hdhomerun_video_debug_print_stats(hd->vs); -- } --} -- --void hdhomerun_device_get_video_stats(struct hdhomerun_device_t *hd, struct hdhomerun_video_stats_t *stats) --{ -- hdhomerun_video_get_stats(hd->vs, stats); --} -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.h src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_device.h ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.h 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_device.h 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_device.h - * -- * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,20 +14,8 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - #ifdef __cplusplus -@@ -38,8 +26,16 @@ - #define HDHOMERUN_DEVICE_MAX_LOCK_TO_DATA_TIME 2000 - #define HDHOMERUN_DEVICE_MAX_TUNE_TO_DATA_TIME (HDHOMERUN_DEVICE_MAX_TUNE_TO_LOCK_TIME + HDHOMERUN_DEVICE_MAX_LOCK_TO_DATA_TIME) - --#define HDHOMERUN_TARGET_PROTOCOL_UDP "udp" --#define HDHOMERUN_TARGET_PROTOCOL_RTP "rtp" -+struct hdhomerun_device_t; -+ -+struct hdhomerun_tuner_status_t { -+ char channel[32]; -+ unsigned int signal_strength; -+ unsigned int signal_to_noise_quality; -+ unsigned int symbol_error_quality; -+ uint32_t raw_bits_per_second; -+ uint32_t packets_per_second; -+}; - - /* - * Create a device object. -@@ -49,49 +45,22 @@ - * - * For example, a threaded application that streams video from 4 tuners (2 HDHomeRun devices) and has - * GUI feedback to the user of the selected tuner might use 5 device objects: 4 for streaming video -- * (one per thread) and one for the GUI display that can switch between tuners. -+ * (one per thread) and one for the GUI display that can just between tuners. - * -- * This function will not attempt to connect to the device. The connection will be established when first used. -+ * This function will not attempt to connect to the device. -+ * The connection will be established when first used. - * - * uint32_t device_id = 32-bit device id of device. Set to HDHOMERUN_DEVICE_ID_WILDCARD to match any device ID. - * uint32_t device_ip = IP address of device. Set to 0 to auto-detect. - * unsigned int tuner = tuner index (0 or 1). Can be changed later by calling hdhomerun_device_set_tuner. -- * struct hdhomerun_debug_t *dbg: Pointer to debug logging object. May be NULL. - * - * Returns a pointer to the newly created device object. - * - * When no longer needed, the socket should be destroyed by calling hdhomerun_device_destroy. -- * -- * The hdhomerun_device_create_from_str function creates a device object from the given device_str. -- * The device_str parameter can be any of the following forms: -- * <device id> -- * <device id>-<tuner index> -- * <ip address> -- * If the tuner index is not included in the device_str then it is set to zero. Use hdhomerun_device_set_tuner -- * or hdhomerun_device_set_tuner_from_str to set the tuner. -- * -- * The hdhomerun_device_set_tuner_from_str function sets the tuner from the given tuner_str. -- * The tuner_str parameter can be any of the following forms: -- * <tuner index> -- * /tuner<tuner index> - */ --extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner, struct hdhomerun_debug_t *dbg); --extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_create_from_str(const char *device_str, struct hdhomerun_debug_t *dbg); --extern LIBTYPE void hdhomerun_device_destroy(struct hdhomerun_device_t *hd); -- --/* -- * Get the device id, ip, or tuner of the device instance. -- */ --extern LIBTYPE const char *hdhomerun_device_get_name(struct hdhomerun_device_t *hd); --extern LIBTYPE uint32_t hdhomerun_device_get_device_id(struct hdhomerun_device_t *hd); --extern LIBTYPE uint32_t hdhomerun_device_get_device_ip(struct hdhomerun_device_t *hd); --extern LIBTYPE uint32_t hdhomerun_device_get_device_id_requested(struct hdhomerun_device_t *hd); --extern LIBTYPE uint32_t hdhomerun_device_get_device_ip_requested(struct hdhomerun_device_t *hd); --extern LIBTYPE unsigned int hdhomerun_device_get_tuner(struct hdhomerun_device_t *hd); -- --extern LIBTYPE void hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip); --extern LIBTYPE void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner); --extern LIBTYPE int hdhomerun_device_set_tuner_from_str(struct hdhomerun_device_t *hd, const char *tuner_str); -+extern struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner); -+extern void hdhomerun_device_destroy(struct hdhomerun_device_t *hd); -+extern void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner); - - /* - * Get the local machine IP address used when communicating with the device. -@@ -100,7 +69,7 @@ - * - * Returns 32-bit IP address with native endianness, or 0 on error. - */ --extern LIBTYPE uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun_device_t *hd); -+extern uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun_device_t *hd); - - /* - * Get operations. -@@ -113,24 +82,15 @@ - * Returns 0 if the operation was rejected. - * Returns -1 if a communication error occurred. - */ --extern LIBTYPE int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, char **pstatus_str, struct hdhomerun_tuner_status_t *status); --extern LIBTYPE int hdhomerun_device_get_tuner_streaminfo(struct hdhomerun_device_t *hd, char **pstreaminfo); --extern LIBTYPE int hdhomerun_device_get_tuner_channel(struct hdhomerun_device_t *hd, char **pchannel); --extern LIBTYPE int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap); --extern LIBTYPE int hdhomerun_device_get_tuner_filter(struct hdhomerun_device_t *hd, char **pfilter); --extern LIBTYPE int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, char **pprogram); --extern LIBTYPE int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget); --extern LIBTYPE int hdhomerun_device_get_tuner_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount); --extern LIBTYPE int hdhomerun_device_get_tuner_lockkey_owner(struct hdhomerun_device_t *hd, char **powner); --extern LIBTYPE int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget); --extern LIBTYPE int hdhomerun_device_get_lineup_location(struct hdhomerun_device_t *hd, char **plocation); --extern LIBTYPE int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num); -- --extern LIBTYPE uint32_t hdhomerun_device_get_tuner_status_ss_color(struct hdhomerun_tuner_status_t *status); --extern LIBTYPE uint32_t hdhomerun_device_get_tuner_status_snq_color(struct hdhomerun_tuner_status_t *status); --extern LIBTYPE uint32_t hdhomerun_device_get_tuner_status_seq_color(struct hdhomerun_tuner_status_t *status); -- --extern LIBTYPE const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd); -+extern int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status); -+extern int hdhomerun_device_get_tuner_streaminfo(struct hdhomerun_device_t *hd, char **pstreaminfo); -+extern int hdhomerun_device_get_tuner_channel(struct hdhomerun_device_t *hd, char **pchannel); -+extern int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap); -+extern int hdhomerun_device_get_tuner_filter(struct hdhomerun_device_t *hd, char **pfilter); -+extern int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, uint16_t *pprogram_number); -+extern int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget); -+extern int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget); -+extern int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num); - - /* - * Set operations. -@@ -141,16 +101,12 @@ - * Returns 0 if the operation was rejected. - * Returns -1 if a communication error occurred. - */ --extern LIBTYPE int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char *channel); --extern LIBTYPE int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap); --extern LIBTYPE int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter); --extern LIBTYPE int hdhomerun_device_set_tuner_filter_by_array(struct hdhomerun_device_t *hd, unsigned char filter_array[0x2000]); --extern LIBTYPE int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, const char *program); --extern LIBTYPE int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, const char *target); --extern LIBTYPE int hdhomerun_device_set_tuner_target_to_local_protocol(struct hdhomerun_device_t *hd, const char *protocol); --extern LIBTYPE int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd); --extern LIBTYPE int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target); --extern LIBTYPE int hdhomerun_device_set_lineup_location(struct hdhomerun_device_t *hd, const char *location); -+extern int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char *channel); -+extern int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap); -+extern int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter); -+extern int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, uint16_t program_number); -+extern int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, char *target); -+extern int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target); - - /* - * Get/set a named control variable on the device. -@@ -169,42 +125,8 @@ - * Returns 0 if the operation was rejected (pvalue NULL, perror set). - * Returns -1 if a communication error occurs. - */ --extern LIBTYPE int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, char **pvalue, char **perror); --extern LIBTYPE int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const char *name, const char *value, char **pvalue, char **perror); -- --/* -- * Tuner locking. -- * -- * The hdhomerun_device_tuner_lockkey_request function is used to obtain a lock -- * or to verify that the hdhomerun_device object still holds the lock. -- * Returns 1 if the lock request was successful and the lock was obtained. -- * Returns 0 if the lock request was rejected. -- * Returns -1 if a communication error occurs. -- * -- * The hdhomerun_device_tuner_lockkey_release function is used to release a -- * previously held lock. If locking is used then this function must be called -- * before destroying the hdhomerun_device object. -- */ --extern LIBTYPE int hdhomerun_device_tuner_lockkey_request(struct hdhomerun_device_t *hd, char **perror); --extern LIBTYPE int hdhomerun_device_tuner_lockkey_release(struct hdhomerun_device_t *hd); --extern LIBTYPE int hdhomerun_device_tuner_lockkey_force(struct hdhomerun_device_t *hd); -- --/* -- * Intended only for non persistent connections; eg, hdhomerun_config. -- */ --extern LIBTYPE void hdhomerun_device_tuner_lockkey_use_value(struct hdhomerun_device_t *hd, uint32_t lockkey); -- --/* -- * Wait for tuner lock after channel change. -- * -- * The hdhomerun_device_wait_for_lock function is used to detect/wait for a lock vs no lock indication -- * after a channel change. -- * -- * It will return quickly if a lock is aquired. -- * It will return quickly if there is no signal detected. -- * Worst case it will time out after 1.5 seconds - the case where there is signal but no lock. -- */ --extern LIBTYPE int hdhomerun_device_wait_for_lock(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status); -+extern int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, char **pvalue, char **perror); -+extern int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const char *name, const char *value, char **pvalue, char **perror); - - /* - * Stream a filtered program or the unfiltered stream. -@@ -222,19 +144,9 @@ - * - * The hdhomerun_device_stream_stop function tells the device to stop streaming data. - */ --extern LIBTYPE int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd); --extern LIBTYPE int hdhomerun_device_stream_refresh_target(struct hdhomerun_device_t *hd); --extern LIBTYPE uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size); --extern LIBTYPE void hdhomerun_device_stream_flush(struct hdhomerun_device_t *hd); --extern LIBTYPE void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd); -- --/* -- * Channel scan API. -- */ --extern LIBTYPE int hdhomerun_device_channelscan_init(struct hdhomerun_device_t *hd, const char *channelmap); --extern LIBTYPE int hdhomerun_device_channelscan_advance(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result); --extern LIBTYPE int hdhomerun_device_channelscan_detect(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result); --extern LIBTYPE uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd); -+extern int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd); -+extern uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size); -+extern void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd); - - /* - * Check that the device is running the recommended firmware. -@@ -245,7 +157,7 @@ - * Returns 0 if th firmware does not meet the minimum requriements for all operations. - * Returns -1 if an error occurs. - */ --extern LIBTYPE int hdhomerun_device_firmware_version_check(struct hdhomerun_device_t *hd, uint32_t features); -+extern int hdhomerun_device_firmware_version_check(struct hdhomerun_device_t *hd, uint32_t features); - - /* - * Upload new firmware to the device. -@@ -256,19 +168,13 @@ - * Returns 0 if the upload was rejected. - * Returns -1 if an error occurs. - */ --extern LIBTYPE int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file); -+extern int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file); - - /* - * Low level accessor functions. - */ --extern LIBTYPE struct hdhomerun_control_sock_t *hdhomerun_device_get_control_sock(struct hdhomerun_device_t *hd); --extern LIBTYPE struct hdhomerun_video_sock_t *hdhomerun_device_get_video_sock(struct hdhomerun_device_t *hd); -- --/* -- * Debug print internal stats. -- */ --extern LIBTYPE void hdhomerun_device_debug_print_video_stats(struct hdhomerun_device_t *hd); --extern LIBTYPE void hdhomerun_device_get_video_stats(struct hdhomerun_device_t *hd, struct hdhomerun_video_stats_t *stats); -+extern struct hdhomerun_control_sock_t *hdhomerun_device_get_control_sock(struct hdhomerun_device_t *hd); -+extern struct hdhomerun_video_sock_t *hdhomerun_device_get_video_sock(struct hdhomerun_device_t *hd); - - #ifdef __cplusplus - } -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_device_selector.c -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_device_selector.h -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_dhcp.c -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_dhcp.h -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.c src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_discover.c ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.c 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_discover.c 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_discover.c - * -- * Copyright © 2006-2007 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,93 +14,206 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - --#include "hdhomerun.h" -+#include "hdhomerun_os.h" -+#include "hdhomerun_pkt.h" -+#include "hdhomerun_discover.h" - - #if defined(__CYGWIN__) || defined(__WINDOWS__) - #include <windows.h> -+#include <iptypes.h> - #include <iphlpapi.h> --#define USE_IPHLPAPI 1 --#else --#include <net/if.h> --#include <sys/ioctl.h> --#ifndef _SIZEOF_ADDR_IFREQ --#define _SIZEOF_ADDR_IFREQ(x) sizeof(x) --#endif - #endif - --#define HDHOMERUN_DISOCVER_MAX_SOCK_COUNT 16 -+// for OSX -+#include <unistd.h> // execl, pipe, sysconf -+#include <sys/types.h> // waitpid -+#include <sys/wait.h> // waitpid - - struct hdhomerun_discover_sock_t { - int sock; -- uint32_t local_ip; -- uint32_t subnet_mask; - }; - --struct hdhomerun_discover_t { -- struct hdhomerun_discover_sock_t socks[HDHOMERUN_DISOCVER_MAX_SOCK_COUNT]; -- unsigned int sock_count; -- struct hdhomerun_pkt_t tx_pkt; -- struct hdhomerun_pkt_t rx_pkt; --}; -- --static bool_t hdhomerun_discover_sock_create(struct hdhomerun_discover_t *ds, uint32_t local_ip, uint32_t subnet_mask) -+static struct hdhomerun_discover_sock_t *hdhomerun_discover_create(void) - { -- if (ds->sock_count >= HDHOMERUN_DISOCVER_MAX_SOCK_COUNT) { -- return FALSE; -+ struct hdhomerun_discover_sock_t *ds = (struct hdhomerun_discover_sock_t *)malloc(sizeof(struct hdhomerun_discover_sock_t)); -+ if (!ds) { -+ return NULL; - } -- -+ - /* Create socket. */ -- int sock = (int)socket(AF_INET, SOCK_DGRAM, 0); -- if (sock == -1) { -- return FALSE; -+ ds->sock = (int)socket(AF_INET, SOCK_DGRAM, 0); -+ if (ds->sock == -1) { -+ free(ds); -+ return NULL; - } - - /* Set timeouts. */ -- setsocktimeout(sock, SOL_SOCKET, SO_SNDTIMEO, 1000); -- setsocktimeout(sock, SOL_SOCKET, SO_RCVTIMEO, 1000); -+ setsocktimeout(ds->sock, SOL_SOCKET, SO_SNDTIMEO, 1000); -+ setsocktimeout(ds->sock, SOL_SOCKET, SO_RCVTIMEO, 1000); - - /* Allow broadcast. */ - int sock_opt = 1; -- setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt)); -+ setsockopt(ds->sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt)); - - /* Bind socket. */ - struct sockaddr_in sock_addr; - memset(&sock_addr, 0, sizeof(sock_addr)); - sock_addr.sin_family = AF_INET; -- sock_addr.sin_addr.s_addr = htonl(local_ip); -+ sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); - sock_addr.sin_port = htons(0); -- if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { -- close(sock); -- return FALSE; -+ if (bind(ds->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { -+ close(ds->sock); -+ free(ds); -+ return NULL; - } - -- /* Write sock entry. */ -- struct hdhomerun_discover_sock_t *dss = &ds->socks[ds->sock_count++]; -- dss->sock = sock; -- dss->local_ip = local_ip; -- dss->subnet_mask = subnet_mask; -+ /* Success. */ -+ return ds; -+} - -- return TRUE; -+static void hdhomerun_discover_destroy(struct hdhomerun_discover_sock_t *ds) -+{ -+ close(ds->sock); -+ free(ds); - } - --#if defined(USE_IPHLPAPI) --static void hdhomerun_discover_sock_detect(struct hdhomerun_discover_t *ds) -+static int hdhomerun_discover_send_packet(struct hdhomerun_discover_sock_t *ds, uint32_t ip_addr, uint32_t device_type, uint32_t device_id) -+{ -+ uint8_t buffer[1024]; -+ uint8_t *ptr = buffer; -+ hdhomerun_write_discover_request(&ptr, device_type, device_id); -+ -+ struct sockaddr_in sock_addr; -+ memset(&sock_addr, 0, sizeof(sock_addr)); -+ sock_addr.sin_family = AF_INET; -+ sock_addr.sin_addr.s_addr = htonl(ip_addr); -+ sock_addr.sin_port = htons(HDHOMERUN_DISCOVER_UDP_PORT); -+ -+ int length = (int)(ptr - buffer); -+ if (sendto(ds->sock, (char *)buffer, (int)length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != length) { -+ return -1; -+ } -+ -+ return 0; -+} -+ -+#if defined(__APPLE__) -+static int hdhomerun_discover_send_internal(struct hdhomerun_discover_sock_t *ds, unsigned long device_type, unsigned long device_id) -+{ -+ /* printf("Looking for 0x%lx with id 0x%lx\n", device_type, device_id); */ -+ int fds[2]; -+ if (pipe(fds) < 0) -+ { -+ printf("Pipe Failed\n"); -+ return -1; -+ } -+ -+ pid_t child = fork(); -+ if (child < 0) -+ { -+ printf("Fork Failed\n"); -+ return -1; -+ } -+ else if (child == 0) -+ { -+ /* Child */ -+ int i = 0; -+ -+ /* Attach stdout to pipe */ -+ close(1); -+ dup2(fds[1], 1); -+ -+ /* Close all open file descriptors except stdout/stderr */ -+ for (i = sysconf(_SC_OPEN_MAX) - 1; i > 2; i--) -+ close(i); -+ -+ /* Run command */ -+ execl("/bin/sh", "sh", "-c", "ifconfig", NULL); -+ -+ /* Failed to exec */ -+ _exit(1); /* this exit is ok */ -+ } -+ else -+ { -+ /* Parent */ -+ int send_count = 0; -+ int status; -+ FILE *fp; -+ char line[1024]; -+ char adaptor[1024]; -+ -+ close(fds[1]); -+ -+ if (waitpid(child, &status, 0) < 0) -+ return -1; -+ -+ if (WEXITSTATUS(status)) -+ return -1; -+ -+ fp = fdopen(fds[0], "r"); -+ while (1) -+ { -+ char *ptr = NULL; -+ int netmask, broadcast; -+ int a,b,c,d; -+ -+ if (!fgets(line, sizeof(line) - 1, fp)) -+ { -+ break; -+ } -+ -+ line[1023] = 0; -+ -+ /* find ": flags" */ -+ ptr = strnstr(line, ": flags", 1024 - 1); -+ if (ptr >= line) -+ { -+ /* grab adaptor before that */ -+ strncpy(adaptor, line, ptr-line); -+ adaptor[ptr-line] = 0; -+ } -+ -+ /* find "netmask " */ -+ ptr = strnstr(line, "netmask ", 1024 - 1); -+ if (ptr <= line) -+ continue; -+ ptr += strlen("netmask "); -+ sscanf(ptr, "%x", &netmask); -+ -+ /* find "broadcast " */ -+ ptr = strnstr(ptr, "broadcast ", 1024 - 1); -+ if (ptr <= line) -+ continue; -+ ptr += strlen("broadcast "); -+ sscanf(ptr, "%i.%i.%i.%i", &a, &b, &c, &d); -+ broadcast = a<<24 | b<<16 | c<<8 | d; -+ /* -+ printf("Adaptor: '%s' 0x%08x %i.%i.%i.%i\n", -+ adaptor, broadcast, a,b,c,d); -+ */ -+ -+ /* send discover packet this adaptor */ -+ if (hdhomerun_discover_send_packet( -+ ds, broadcast, device_type, device_id) >= 0) -+ { -+ send_count++; -+ } -+ } -+ -+ fclose(fp); /* this closes fds[0] as well */ -+ -+ /* printf("send_count: %i\n\n", send_count); */ -+ return (send_count == 0) ? -1 : 0; -+ } -+} -+ -+#elif defined(__CYGWIN__) || defined(__WINDOWS__) -+ -+static int hdhomerun_discover_send_internal(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id) - { - PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); - ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); -@@ -109,29 +222,37 @@ - if (Ret != NO_ERROR) { - free(pAdapterInfo); - if (Ret != ERROR_BUFFER_OVERFLOW) { -- return; -+ return -1; - } - pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); - Ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); - if (Ret != NO_ERROR) { - free(pAdapterInfo); -- return; -+ return -1; - } - } - -+ unsigned int send_count = 0; - PIP_ADAPTER_INFO pAdapter = pAdapterInfo; - while (pAdapter) { - IP_ADDR_STRING *pIPAddr = &pAdapter->IpAddressList; - while (pIPAddr) { -- uint32_t local_ip = ntohl(inet_addr(pIPAddr->IpAddress.String)); -+ uint32_t addr = ntohl(inet_addr(pIPAddr->IpAddress.String)); - uint32_t mask = ntohl(inet_addr(pIPAddr->IpMask.String)); -+ -+ uint32_t broadcast = addr | ~mask; -+ if ((broadcast == 0x00000000) || (broadcast == 0xFFFFFFFF)) { -+ pIPAddr = pIPAddr->Next; -+ continue; -+ } - -- if (local_ip == 0) { -+ if (hdhomerun_discover_send_packet(ds, broadcast, device_type, device_id) < 0) { - pIPAddr = pIPAddr->Next; - continue; - } - -- hdhomerun_discover_sock_create(ds, local_ip, mask); -+ send_count++; -+ - pIPAddr = pIPAddr->Next; - } - -@@ -139,198 +260,111 @@ - } - - free(pAdapterInfo); --} -- --#else - --static void hdhomerun_discover_sock_detect(struct hdhomerun_discover_t *ds) --{ -- int fd = socket(AF_INET, SOCK_DGRAM, 0); -- if (fd == -1) { -- return; -+ if (send_count == 0) { -+ return -1; - } -+ return 0; -+} - -- struct ifconf ifc; -- uint8_t buf[8192]; -- ifc.ifc_len = sizeof(buf); -- ifc.ifc_buf = (char *)buf; -- -- memset(buf, 0, sizeof(buf)); -+#elif defined(__linux__) - -- if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { -- close(fd); -- return; -+static int hdhomerun_discover_send_internal(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id) -+{ -+ FILE *fp = fopen("/proc/net/route", "r"); -+ if (!fp) { -+ return -1; - } - -- uint8_t *ptr = (uint8_t *)ifc.ifc_req; -- uint8_t *end = (uint8_t *)&ifc.ifc_buf[ifc.ifc_len]; -- -- while (ptr <= end) { -- struct ifreq *ifr = (struct ifreq *)ptr; -- ptr += _SIZEOF_ADDR_IFREQ(*ifr); -+ unsigned int send_count = 0; -+ while (1) { -+ char line[256]; -+ if (!fgets(line, sizeof(line), fp)) { -+ break; -+ } -+ line[255] = 0; - -- if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { -+ uint32_t dest; -+ uint32_t mask; -+ if (sscanf(line, "%*s %x %*x %*x %*d %*d %*d %x", &dest, &mask) != 2) { - continue; - } -- struct sockaddr_in *addr_in = (struct sockaddr_in *)&(ifr->ifr_addr); -- uint32_t local_ip = ntohl(addr_in->sin_addr.s_addr); -- if (local_ip == 0) { -+ dest = ntohl(dest); -+ mask = ntohl(mask); -+ -+ uint32_t broadcast = dest | ~mask; -+ -+ if ((broadcast == 0x00000000) || (broadcast == 0xFFFFFFFF)) { - continue; - } - -- if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { -+ if (hdhomerun_discover_send_packet(ds, broadcast, device_type, device_id) < 0) { - continue; - } -- struct sockaddr_in *mask_in = (struct sockaddr_in *)&(ifr->ifr_addr); -- uint32_t mask = ntohl(mask_in->sin_addr.s_addr); - -- hdhomerun_discover_sock_create(ds, local_ip, mask); -+ send_count++; - } --} --#endif - --static struct hdhomerun_discover_t *hdhomerun_discover_create(void) --{ -- struct hdhomerun_discover_t *ds = (struct hdhomerun_discover_t *)calloc(1, sizeof(struct hdhomerun_discover_t)); -- if (!ds) { -- return NULL; -- } -- -- /* Create a routable socket. */ -- if (!hdhomerun_discover_sock_create(ds, 0, 0)) { -- free(ds); -- return NULL; -+ fclose(fp); -+ if (send_count == 0) { -+ return -1; - } -- -- /* Detect & create local sockets. */ -- hdhomerun_discover_sock_detect(ds); -- -- /* Success. */ -- return ds; -+ return 0; - } - --static void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds) --{ -- unsigned int i; -- for (i = 0; i < ds->sock_count; i++) { -- struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; -- close(dss->sock); -- } -- -- free(ds); --} -+#else - --static bool_t hdhomerun_discover_send_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, uint32_t target_ip, uint32_t device_type, uint32_t device_id) -+static int hdhomerun_discover_send_internal(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id) - { -- struct hdhomerun_pkt_t *tx_pkt = &ds->tx_pkt; -- hdhomerun_pkt_reset(tx_pkt); -- -- hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_DEVICE_TYPE); -- hdhomerun_pkt_write_var_length(tx_pkt, 4); -- hdhomerun_pkt_write_u32(tx_pkt, device_type); -- hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_DEVICE_ID); -- hdhomerun_pkt_write_var_length(tx_pkt, 4); -- hdhomerun_pkt_write_u32(tx_pkt, device_id); -- hdhomerun_pkt_seal_frame(tx_pkt, HDHOMERUN_TYPE_DISCOVER_REQ); -- -- struct sockaddr_in sock_addr; -- memset(&sock_addr, 0, sizeof(sock_addr)); -- sock_addr.sin_family = AF_INET; -- sock_addr.sin_addr.s_addr = htonl(target_ip); -- sock_addr.sin_port = htons(HDHOMERUN_DISCOVER_UDP_PORT); -- -- int length = (int)(tx_pkt->end - tx_pkt->start); -- if (sendto(dss->sock, (char *)tx_pkt->start, length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != length) { -- return FALSE; -- } -- -- return TRUE; -+ return -1; - } -+#endif - --static bool_t hdhomerun_discover_send_wildcard_ip(struct hdhomerun_discover_t *ds, uint32_t device_type, uint32_t device_id) -+static int hdhomerun_discover_send(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id) - { -- bool_t result = FALSE; -- -- /* -- * Send subnet broadcast using each local ip socket. -- * This will work with multiple separate 169.254.x.x interfaces. -- */ -- unsigned int i; -- for (i = 1; i < ds->sock_count; i++) { -- struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; -- uint32_t target_ip = dss->local_ip | ~dss->subnet_mask; -- result |= hdhomerun_discover_send_internal(ds, dss, target_ip, device_type, device_id); -- } -- -- /* -- * If no local ip sockets then fall back to sending a global broadcast letting the OS choose the interface. -- */ -- if (!result) { -- struct hdhomerun_discover_sock_t *dss = &ds->socks[0]; -- result = hdhomerun_discover_send_internal(ds, dss, 0xFFFFFFFF, device_type, device_id); -+ if (hdhomerun_discover_send_internal(ds, device_type, device_id) < 0) { -+ return hdhomerun_discover_send_packet(ds, 0xFFFFFFFF, device_type, device_id); - } -- -- return result; -+ return 0; - } - --static bool_t hdhomerun_discover_send_target_ip(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id) -+static int hdhomerun_discover_recv(struct hdhomerun_discover_sock_t *ds, struct hdhomerun_discover_device_t *result) - { -- bool_t result = FALSE; -- -- /* -- * Send targeted packet from any local ip that is in the same subnet. -- * This will work with multiple separate 169.254.x.x interfaces. -- */ -- unsigned int i; -- for (i = 1; i < ds->sock_count; i++) { -- struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; -- if ((target_ip & dss->subnet_mask) != (dss->local_ip & dss->subnet_mask)) { -- continue; -- } -+ struct timeval t; -+ t.tv_sec = 0; -+ t.tv_usec = 250000; - -- result |= hdhomerun_discover_send_internal(ds, dss, target_ip, device_type, device_id); -- } -+ fd_set readfds; -+ FD_ZERO(&readfds); -+ FD_SET(ds->sock, &readfds); - -- /* -- * If target IP does not match a local subnet then fall back to letting the OS choose the gateway interface. -- */ -- if (!result) { -- struct hdhomerun_discover_sock_t *dss = &ds->socks[0]; -- result = hdhomerun_discover_send_internal(ds, dss, target_ip, device_type, device_id); -+ if (select(ds->sock+1, &readfds, NULL, NULL, &t) < 0) { -+ return -1; - } -- -- return result; --} -- --static bool_t hdhomerun_discover_send(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id) --{ -- if (target_ip != 0) { -- return hdhomerun_discover_send_target_ip(ds, target_ip, device_type, device_id); -+ if (!FD_ISSET(ds->sock, &readfds)) { -+ return 0; - } - -- return hdhomerun_discover_send_wildcard_ip(ds, device_type, device_id); --} -- --static int hdhomerun_discover_recv_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, struct hdhomerun_discover_device_t *result) --{ -- struct hdhomerun_pkt_t *rx_pkt = &ds->rx_pkt; -- hdhomerun_pkt_reset(rx_pkt); -- -+ uint8_t buffer[1024]; - struct sockaddr_in sock_addr; -- memset(&sock_addr, 0, sizeof(sock_addr)); - socklen_t sockaddr_size = sizeof(sock_addr); -- -- int rx_length = recvfrom(dss->sock, (char *)rx_pkt->end, (int)(rx_pkt->limit - rx_pkt->end), 0, (struct sockaddr *)&sock_addr, &sockaddr_size); -+ int rx_length = recvfrom(ds->sock, (char *)buffer, sizeof(buffer), 0, (struct sockaddr *)&sock_addr, &sockaddr_size); - if (rx_length <= 0) { - /* Don't return error - windows machine on VPN can sometimes cause a sock error here but otherwise works. */ - return 0; - } -- rx_pkt->end += rx_length; -+ if (rx_length < HDHOMERUN_MIN_PEEK_LENGTH) { -+ return 0; -+ } - -- uint16_t type; -- if (hdhomerun_pkt_open_frame(rx_pkt, &type) <= 0) { -+ size_t length = hdhomerun_peek_packet_length(buffer); -+ if (length > (size_t)rx_length) { - return 0; - } -+ -+ uint8_t *ptr = buffer; -+ uint8_t *end = buffer + length; -+ int type = hdhomerun_process_packet(&ptr, &end); - if (type != HDHOMERUN_TYPE_DISCOVER_RPY) { - return 0; - } -@@ -338,12 +372,11 @@ - result->ip_addr = ntohl(sock_addr.sin_addr.s_addr); - result->device_type = 0; - result->device_id = 0; -- - while (1) { - uint8_t tag; - size_t len; -- uint8_t *next = hdhomerun_pkt_read_tlv(rx_pkt, &tag, &len); -- if (!next) { -+ uint8_t *value; -+ if (hdhomerun_read_tlv(&ptr, end, &tag, &len, &value) < 0) { - break; - } - -@@ -352,71 +385,28 @@ - if (len != 4) { - break; - } -- result->device_type = hdhomerun_pkt_read_u32(rx_pkt); -+ result->device_type = hdhomerun_read_u32(&value); - break; -- - case HDHOMERUN_TAG_DEVICE_ID: - if (len != 4) { - break; - } -- result->device_id = hdhomerun_pkt_read_u32(rx_pkt); -+ result->device_id = hdhomerun_read_u32(&value); - break; -- - default: - break; - } -- -- rx_pkt->pos = next; - } - - return 1; - } - --static int hdhomerun_discover_recv(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_device_t *result) --{ -- struct timeval t; -- t.tv_sec = 0; -- t.tv_usec = 250000; -- -- fd_set readfds; -- FD_ZERO(&readfds); -- int max_sock = -1; -- -- unsigned int i; -- for (i = 0; i < ds->sock_count; i++) { -- struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; -- FD_SET(dss->sock, &readfds); -- if (dss->sock > max_sock) { -- max_sock = dss->sock; -- } -- } -- -- if (select(max_sock+1, &readfds, NULL, NULL, &t) < 0) { -- return -1; -- } -- -- for (i = 0; i < ds->sock_count; i++) { -- struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; -- if (!FD_ISSET(dss->sock, &readfds)) { -- continue; -- } -- -- if (hdhomerun_discover_recv_internal(ds, dss, result) <= 0) { -- continue; -- } -- -- return 1; -- } -- -- return 0; --} -- --static struct hdhomerun_discover_device_t *hdhomerun_discover_find_in_list(struct hdhomerun_discover_device_t result_list[], int count, uint32_t ip_addr) -+static struct hdhomerun_discover_device_t *hdhomerun_discover_find_in_list(struct hdhomerun_discover_device_t result_list[], int count, uint32_t device_id) - { - int index; - for (index = 0; index < count; index++) { - struct hdhomerun_discover_device_t *result = &result_list[index]; -- if (result->ip_addr == ip_addr) { -+ if (result->device_id == device_id) { - return result; - } - } -@@ -424,12 +414,13 @@ - return NULL; - } - --static int hdhomerun_discover_find_devices_internal(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count) -+static int hdhomerun_discover_find_devices_internal(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count) - { - int count = 0; -+ - int attempt; - for (attempt = 0; attempt < 4; attempt++) { -- if (!hdhomerun_discover_send(ds, target_ip, device_type, device_id)) { -+ if (hdhomerun_discover_send(ds, device_type, device_id) < 0) { - return -1; - } - -@@ -442,7 +433,7 @@ - return -1; - } - if (ret == 0) { -- continue; -+ break; - } - - /* Filter. */ -@@ -458,7 +449,7 @@ - } - - /* Ensure not already in list. */ -- if (hdhomerun_discover_find_in_list(result_list, count, result->ip_addr)) { -+ if (hdhomerun_discover_find_in_list(result_list, count, result->device_id)) { - continue; - } - -@@ -473,14 +464,27 @@ - return count; - } - --int hdhomerun_discover_find_devices_custom(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count) -+int hdhomerun_discover_find_device(uint32_t device_id, struct hdhomerun_discover_device_t *result) -+{ -+ struct hdhomerun_discover_sock_t *ds = hdhomerun_discover_create(); -+ if (!ds) { -+ return -1; -+ } -+ -+ int ret = hdhomerun_discover_find_devices_internal(ds, HDHOMERUN_DEVICE_TYPE_WILDCARD, device_id, result, 1); -+ -+ hdhomerun_discover_destroy(ds); -+ return ret; -+} -+ -+int hdhomerun_discover_find_devices(uint32_t device_type, struct hdhomerun_discover_device_t result_list[], int max_count) - { -- struct hdhomerun_discover_t *ds = hdhomerun_discover_create(); -+ struct hdhomerun_discover_sock_t *ds = hdhomerun_discover_create(); - if (!ds) { - return -1; - } - -- int ret = hdhomerun_discover_find_devices_internal(ds, target_ip, device_type, device_id, result_list, max_count); -+ int ret = hdhomerun_discover_find_devices_internal(ds, device_type, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, max_count); - - hdhomerun_discover_destroy(ds); - return ret; -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.h src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_discover.h ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.h 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_discover.h 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_discover.h - * -- * Copyright © 2006-2007 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,20 +14,8 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - #ifdef __cplusplus - extern "C" { -@@ -40,18 +28,29 @@ - }; - - /* -- * Find devices. -+ * Find a device by device ID. -+ * -+ * The device information is stored in caller-supplied hdhomerun_discover_device_t var. -+ * Multiple attempts are made to find the device. -+ * Worst-case execution time is 1 second. -+ * -+ * Returns 1 on success. -+ * Returns 0 if not found. -+ * Retruns -1 on error. -+ */ -+extern int hdhomerun_discover_find_device(uint32_t device_id, struct hdhomerun_discover_device_t *result); -+ -+/* -+ * Find all devices of a given type. - * - * The device information is stored in caller-supplied array of hdhomerun_discover_device_t vars. - * Multiple attempts are made to find devices. - * Execution time is 1 second. - * -- * Set target_ip to zero to auto-detect IP address. -- * - * Returns the number of devices found. - * Retruns -1 on error. - */ --extern LIBTYPE int hdhomerun_discover_find_devices_custom(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count); -+extern int hdhomerun_discover_find_devices(uint32_t device_type, struct hdhomerun_discover_device_t result_list[], int max_count); - - /* - * Verify that the device ID given is valid. -@@ -62,7 +61,7 @@ - * Returns TRUE if valid. - * Returns FALSE if not valid. - */ --extern LIBTYPE bool_t hdhomerun_discover_validate_device_id(uint32_t device_id); -+extern bool_t hdhomerun_discover_validate_device_id(uint32_t device_id); - - #ifdef __cplusplus - } -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_os.h src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_os.h ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_os.h 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_os.h 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_os.h - * -- * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,36 +14,97 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - --#if defined(_WIN32) || defined(_WIN64) -+#include <stdlib.h> -+#include <stdio.h> -+#include <string.h> -+ -+#if defined(WIN32) - #define __WINDOWS__ - #endif - - #if defined(__WINDOWS__) --#include "hdhomerun_os_windows.h" -+#include <windows.h> -+#include <sys/types.h> -+#include <sys/timeb.h> - #else --#include "hdhomerun_os_posix.h" -+#include <unistd.h> -+#include <errno.h> -+#include <sys/types.h> -+#include <sys/socket.h> -+#include <netinet/in.h> -+#include <arpa/inet.h> -+#include <netdb.h> -+#include <sys/time.h> -+#include <sys/timeb.h> -+#include <fcntl.h> - #endif - -+#include <pthread.h> -+ - #if !defined(TRUE) - #define TRUE 1 - #endif -- - #if !defined(FALSE) - #define FALSE 0 - #endif -+ -+#if defined(__WINDOWS__) -+ -+typedef int bool_t; -+typedef unsigned __int8 uint8_t; -+typedef unsigned __int16 uint16_t; -+typedef unsigned __int32 uint32_t; -+typedef unsigned __int64 uint64_t; -+ -+#define socklen_t int -+#define close closesocket -+#define sock_getlasterror WSAGetLastError() -+#define sock_getlasterror_socktimeout (WSAGetLastError() == WSAETIMEDOUT) -+#define atoll _atoi64 -+#define strcasecmp _stricmp -+#define fseeko _fseeki64 -+#define ftello _ftelli64 -+#define usleep(us) Sleep((us)/1000) -+#define sleep(sec) Sleep((sec)*1000) -+ -+static inline uint64_t getcurrenttime(void) -+{ -+ struct timeb tb; -+ ftime(&tb); -+ return ((uint64_t)tb.time * 1000) + tb.millitm; -+} -+ -+static inline int setsocktimeout(int s, int level, int optname, uint64_t timeout) -+{ -+ int t = (int)timeout; -+ return setsockopt(s, level, optname, (char *)&t, sizeof(t)); -+} -+ -+#else -+ -+typedef int bool_t; -+ -+#define sock_getlasterror errno -+#define sock_getlasterror_socktimeout (errno == EAGAIN) -+ -+static inline uint64_t getcurrenttime(void) -+{ -+ struct timeval t; -+ gettimeofday(&t, NULL); -+ return ((uint64_t)t.tv_sec * 1000) + (t.tv_usec / 1000); -+} -+ -+static inline int setsocktimeout(int s, int level, int optname, uint64_t timeout) -+{ -+ struct timeval t; -+ t.tv_sec = timeout / 1000; -+ t.tv_usec = (timeout % 1000) * 1000; -+ return setsockopt(s, level, optname, (char *)&t, sizeof(t)); -+} -+ -+#endif -+ -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_os_posix.h -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_os_windows.h -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.c src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_pkt.c ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.c 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_pkt.c 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_pkt.c - * -- * Copyright © 2005-2006 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2005-2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,232 +14,255 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - --#include "hdhomerun.h" -+#include "hdhomerun_os.h" -+#include "hdhomerun_pkt.h" - --struct hdhomerun_pkt_t *hdhomerun_pkt_create(void) -+uint8_t hdhomerun_read_u8(uint8_t **pptr) - { -- struct hdhomerun_pkt_t *pkt = (struct hdhomerun_pkt_t *)calloc(1, sizeof(struct hdhomerun_pkt_t)); -- if (!pkt) { -- return NULL; -- } -- -- hdhomerun_pkt_reset(pkt); -- -- return pkt; --} -- --void hdhomerun_pkt_destroy(struct hdhomerun_pkt_t *pkt) --{ -- free(pkt); --} -- --void hdhomerun_pkt_reset(struct hdhomerun_pkt_t *pkt) --{ -- pkt->limit = pkt->buffer + sizeof(pkt->buffer) - 4; -- pkt->start = pkt->buffer + 1024; -- pkt->end = pkt->start; -- pkt->pos = pkt->start; --} -- --static uint32_t hdhomerun_pkt_calc_crc(uint8_t *start, uint8_t *end) --{ -- uint8_t *pos = start; -- uint32_t crc = 0xFFFFFFFF; -- while (pos < end) { -- uint8_t x = (uint8_t)(crc) ^ *pos++; -- crc >>= 8; -- if (x & 0x01) crc ^= 0x77073096; -- if (x & 0x02) crc ^= 0xEE0E612C; -- if (x & 0x04) crc ^= 0x076DC419; -- if (x & 0x08) crc ^= 0x0EDB8832; -- if (x & 0x10) crc ^= 0x1DB71064; -- if (x & 0x20) crc ^= 0x3B6E20C8; -- if (x & 0x40) crc ^= 0x76DC4190; -- if (x & 0x80) crc ^= 0xEDB88320; -- } -- return crc ^ 0xFFFFFFFF; --} -- --uint8_t hdhomerun_pkt_read_u8(struct hdhomerun_pkt_t *pkt) --{ -- uint8_t v = *pkt->pos++; -+ uint8_t *ptr = *pptr; -+ uint8_t v = *ptr++; -+ *pptr = ptr; - return v; - } - --uint16_t hdhomerun_pkt_read_u16(struct hdhomerun_pkt_t *pkt) -+uint16_t hdhomerun_read_u16(uint8_t **pptr) - { -+ uint8_t *ptr = *pptr; - uint16_t v; -- v = (uint16_t)*pkt->pos++ << 8; -- v |= (uint16_t)*pkt->pos++ << 0; -+ v = (uint16_t)*ptr++ << 8; -+ v |= (uint16_t)*ptr++ << 0; -+ *pptr = ptr; - return v; - } - --uint32_t hdhomerun_pkt_read_u32(struct hdhomerun_pkt_t *pkt) -+uint32_t hdhomerun_read_u32(uint8_t **pptr) - { -+ uint8_t *ptr = *pptr; - uint32_t v; -- v = (uint32_t)*pkt->pos++ << 24; -- v |= (uint32_t)*pkt->pos++ << 16; -- v |= (uint32_t)*pkt->pos++ << 8; -- v |= (uint32_t)*pkt->pos++ << 0; -+ v = (uint32_t)*ptr++ << 24; -+ v |= (uint32_t)*ptr++ << 16; -+ v |= (uint32_t)*ptr++ << 8; -+ v |= (uint32_t)*ptr++ << 0; -+ *pptr = ptr; - return v; - } - --size_t hdhomerun_pkt_read_var_length(struct hdhomerun_pkt_t *pkt) -+size_t hdhomerun_read_var_length(uint8_t **pptr, uint8_t *end) - { -+ uint8_t *ptr = *pptr; - size_t length; - -- if (pkt->pos + 1 > pkt->end) { -- return (size_t)-1; -+ if (ptr + 1 > end) { -+ return -1; - } - -- length = (size_t)*pkt->pos++; -+ length = (size_t)*ptr++; - if (length & 0x0080) { -- if (pkt->pos + 1 > pkt->end) { -- return (size_t)-1; -+ if (ptr + 1 > end) { -+ return -1; - } - - length &= 0x007F; -- length |= (size_t)*pkt->pos++ << 7; -+ length |= (size_t)*ptr++ << 7; - } - -+ *pptr = ptr; - return length; - } - --uint8_t *hdhomerun_pkt_read_tlv(struct hdhomerun_pkt_t *pkt, uint8_t *ptag, size_t *plength) -+int hdhomerun_read_tlv(uint8_t **pptr, uint8_t *end, uint8_t *ptag, size_t *plength, uint8_t **pvalue) - { -- if (pkt->pos + 2 > pkt->end) { -- return NULL; -+ if (end - *pptr < 2) { -+ return -1; - } - -- *ptag = hdhomerun_pkt_read_u8(pkt); -- *plength = hdhomerun_pkt_read_var_length(pkt); -- -- if (pkt->pos + *plength > pkt->end) { -- return NULL; -+ *ptag = hdhomerun_read_u8(pptr); -+ *plength = hdhomerun_read_var_length(pptr, end); -+ *pvalue = *pptr; -+ -+ if ((size_t)(end - *pptr) < *plength) { -+ return -1; - } - -- return pkt->pos + *plength; -+ *pptr += *plength; -+ return 0; - } - --void hdhomerun_pkt_write_u8(struct hdhomerun_pkt_t *pkt, uint8_t v) -+void hdhomerun_write_u8(uint8_t **pptr, uint8_t v) - { -- *pkt->pos++ = v; -+ uint8_t *ptr = *pptr; -+ *ptr++ = v; -+ *pptr = ptr; -+} - -- if (pkt->pos > pkt->end) { -- pkt->end = pkt->pos; -- } -+void hdhomerun_write_u16(uint8_t **pptr, uint16_t v) -+{ -+ uint8_t *ptr = *pptr; -+ *ptr++ = (uint8_t)(v >> 8); -+ *ptr++ = (uint8_t)(v >> 0); -+ *pptr = ptr; - } - --void hdhomerun_pkt_write_u16(struct hdhomerun_pkt_t *pkt, uint16_t v) -+void hdhomerun_write_u32(uint8_t **pptr, uint32_t v) - { -- *pkt->pos++ = (uint8_t)(v >> 8); -- *pkt->pos++ = (uint8_t)(v >> 0); -+ uint8_t *ptr = *pptr; -+ *ptr++ = (uint8_t)(v >> 24); -+ *ptr++ = (uint8_t)(v >> 16); -+ *ptr++ = (uint8_t)(v >> 8); -+ *ptr++ = (uint8_t)(v >> 0); -+ *pptr = ptr; -+} - -- if (pkt->pos > pkt->end) { -- pkt->end = pkt->pos; -+void hdhomerun_write_var_length(uint8_t **pptr, size_t v) -+{ -+ uint8_t *ptr = *pptr; -+ if (v <= 127) { -+ *ptr++ = (uint8_t)v; -+ } else { -+ *ptr++ = (uint8_t)(v | 0x80); -+ *ptr++ = (uint8_t)(v >> 7); - } -+ *pptr = ptr; - } - --void hdhomerun_pkt_write_u32(struct hdhomerun_pkt_t *pkt, uint32_t v) -+static void hdhomerun_write_mem(uint8_t **pptr, void *mem, size_t length) - { -- *pkt->pos++ = (uint8_t)(v >> 24); -- *pkt->pos++ = (uint8_t)(v >> 16); -- *pkt->pos++ = (uint8_t)(v >> 8); -- *pkt->pos++ = (uint8_t)(v >> 0); -+ uint8_t *ptr = *pptr; -+ memcpy(ptr, mem, length); -+ ptr += length; -+ *pptr = ptr; -+} - -- if (pkt->pos > pkt->end) { -- pkt->end = pkt->pos; -+static uint32_t hdhomerun_calc_crc(uint8_t *start, uint8_t *end) -+{ -+ uint8_t *ptr = start; -+ uint32_t crc = 0xFFFFFFFF; -+ while (ptr < end) { -+ uint8_t x = (uint8_t)(crc) ^ *ptr++; -+ crc >>= 8; -+ if (x & 0x01) crc ^= 0x77073096; -+ if (x & 0x02) crc ^= 0xEE0E612C; -+ if (x & 0x04) crc ^= 0x076DC419; -+ if (x & 0x08) crc ^= 0x0EDB8832; -+ if (x & 0x10) crc ^= 0x1DB71064; -+ if (x & 0x20) crc ^= 0x3B6E20C8; -+ if (x & 0x40) crc ^= 0x76DC4190; -+ if (x & 0x80) crc ^= 0xEDB88320; - } -+ return crc ^ 0xFFFFFFFF; - } - --void hdhomerun_pkt_write_var_length(struct hdhomerun_pkt_t *pkt, size_t v) -+static int hdhomerun_check_crc(uint8_t *start, uint8_t *end) - { -- if (v <= 127) { -- *pkt->pos++ = (uint8_t)v; -- } else { -- *pkt->pos++ = (uint8_t)(v | 0x80); -- *pkt->pos++ = (uint8_t)(v >> 7); -+ if (end - start < 8) { -+ return -1; - } -- -- if (pkt->pos > pkt->end) { -- pkt->end = pkt->pos; -+ uint8_t *ptr = end -= 4; -+ uint32_t actual_crc = hdhomerun_calc_crc(start, ptr); -+ uint32_t packet_crc; -+ packet_crc = (uint32_t)*ptr++ << 0; -+ packet_crc |= (uint32_t)*ptr++ << 8; -+ packet_crc |= (uint32_t)*ptr++ << 16; -+ packet_crc |= (uint32_t)*ptr++ << 24; -+ if (actual_crc != packet_crc) { -+ return -1; - } -+ return 0; - } - --void hdhomerun_pkt_write_mem(struct hdhomerun_pkt_t *pkt, const void *mem, size_t length) -+static void hdhomerun_write_header_length(uint8_t *ptr, size_t length) - { -- memcpy(pkt->pos, mem, length); -- pkt->pos += length; -+ hdhomerun_write_u16(&ptr, (uint16_t)length); -+} - -- if (pkt->pos > pkt->end) { -- pkt->end = pkt->pos; -- } -+void hdhomerun_write_crc(uint8_t **pptr, uint8_t *start) -+{ -+ uint8_t *ptr = *pptr; -+ uint32_t crc = hdhomerun_calc_crc(start, ptr); -+ *ptr++ = (uint8_t)(crc >> 0); -+ *ptr++ = (uint8_t)(crc >> 8); -+ *ptr++ = (uint8_t)(crc >> 16); -+ *ptr++ = (uint8_t)(crc >> 24); -+ *pptr = ptr; - } - --int hdhomerun_pkt_open_frame(struct hdhomerun_pkt_t *pkt, uint16_t *ptype) -+void hdhomerun_write_discover_request(uint8_t **pptr, uint32_t device_type, uint32_t device_id) - { -- pkt->pos = pkt->start; -+ uint8_t *start = *pptr; -+ hdhomerun_write_u16(pptr, HDHOMERUN_TYPE_DISCOVER_REQ); -+ hdhomerun_write_u16(pptr, 0); - -- if (pkt->pos + 4 > pkt->end) { -- return 0; -- } -+ hdhomerun_write_u8(pptr, HDHOMERUN_TAG_DEVICE_TYPE); -+ hdhomerun_write_var_length(pptr, 4); -+ hdhomerun_write_u32(pptr, device_type); -+ hdhomerun_write_u8(pptr, HDHOMERUN_TAG_DEVICE_ID); -+ hdhomerun_write_var_length(pptr, 4); -+ hdhomerun_write_u32(pptr, device_id); - -- *ptype = hdhomerun_pkt_read_u16(pkt); -- size_t length = hdhomerun_pkt_read_u16(pkt); -- pkt->pos += length; -+ hdhomerun_write_header_length(start + 2, (int)(*pptr - start - 4)); -+ hdhomerun_write_crc(pptr, start); -+} - -- if (pkt->pos + 4 > pkt->end) { -- pkt->pos = pkt->start; -- return 0; -- } -+void hdhomerun_write_get_set_request(uint8_t **pptr, const char *name, const char *value) -+{ -+ uint8_t *start = *pptr; -+ hdhomerun_write_u16(pptr, HDHOMERUN_TYPE_GETSET_REQ); -+ hdhomerun_write_u16(pptr, 0); - -- uint32_t calc_crc = hdhomerun_pkt_calc_crc(pkt->start, pkt->pos); -+ int name_len = (int)strlen(name) + 1; -+ hdhomerun_write_u8(pptr, HDHOMERUN_TAG_GETSET_NAME); -+ hdhomerun_write_var_length(pptr, name_len); -+ hdhomerun_write_mem(pptr, (void *)name, name_len); - -- uint32_t packet_crc; -- packet_crc = (uint32_t)*pkt->pos++ << 0; -- packet_crc |= (uint32_t)*pkt->pos++ << 8; -- packet_crc |= (uint32_t)*pkt->pos++ << 16; -- packet_crc |= (uint32_t)*pkt->pos++ << 24; -- if (calc_crc != packet_crc) { -- return -1; -+ if (value) { -+ int value_len = (int)strlen(value) + 1; -+ hdhomerun_write_u8(pptr, HDHOMERUN_TAG_GETSET_VALUE); -+ hdhomerun_write_var_length(pptr, value_len); -+ hdhomerun_write_mem(pptr, (void *)value, value_len); - } - -- pkt->start += 4; -- pkt->end = pkt->start + length; -- pkt->pos = pkt->start; -- return 1; -+ hdhomerun_write_header_length(start + 2, (int)(*pptr - start - 4)); -+ hdhomerun_write_crc(pptr, start); - } - --void hdhomerun_pkt_seal_frame(struct hdhomerun_pkt_t *pkt, uint16_t frame_type) -+void hdhomerun_write_upgrade_request(uint8_t **pptr, uint32_t sequence, void *data, size_t length) - { -- size_t length = pkt->end - pkt->start; -+ uint8_t *start = *pptr; -+ hdhomerun_write_u16(pptr, HDHOMERUN_TYPE_UPGRADE_REQ); -+ hdhomerun_write_u16(pptr, 0); - -- pkt->start -= 4; -- pkt->pos = pkt->start; -- hdhomerun_pkt_write_u16(pkt, frame_type); -- hdhomerun_pkt_write_u16(pkt, (uint16_t)length); -+ hdhomerun_write_u32(pptr, sequence); -+ if (length > 0) { -+ hdhomerun_write_mem(pptr, data, length); -+ } - -- uint32_t crc = hdhomerun_pkt_calc_crc(pkt->start, pkt->end); -- *pkt->end++ = (uint8_t)(crc >> 0); -- *pkt->end++ = (uint8_t)(crc >> 8); -- *pkt->end++ = (uint8_t)(crc >> 16); -- *pkt->end++ = (uint8_t)(crc >> 24); -+ hdhomerun_write_header_length(start + 2, *pptr - start - 4); -+ hdhomerun_write_crc(pptr, start); -+} - -- pkt->pos = pkt->start; -+size_t hdhomerun_peek_packet_length(uint8_t *ptr) -+{ -+ ptr += 2; -+ return (size_t)hdhomerun_read_u16(&ptr) + 8; - } -+ -+int hdhomerun_process_packet(uint8_t **pptr, uint8_t **pend) -+{ -+ if (hdhomerun_check_crc(*pptr, *pend) < 0) { -+ return -1; -+ } -+ *pend -= 4; -+ -+ uint16_t type = hdhomerun_read_u16(pptr); -+ uint16_t length = hdhomerun_read_u16(pptr); -+ if ((*pend - *pptr) < length) { -+ return -1; -+ } -+ *pend = *pptr + length; -+ return (int)type; -+} -+ -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.h src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_pkt.h ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.h 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_pkt.h 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_pkt.h - * -- * Copyright © 2005-2006 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2005-2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,20 +14,8 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - #ifdef __cplusplus - extern "C" { -@@ -122,9 +110,6 @@ - #define HDHOMERUN_DISCOVER_UDP_PORT 65001 - #define HDHOMERUN_CONTROL_TCP_PORT 65001 - --#define HDHOMERUN_MAX_PACKET_SIZE 1460 --#define HDHOMERUN_MAX_PAYLOAD_SIZE 1452 -- - #define HDHOMERUN_TYPE_DISCOVER_REQ 0x0002 - #define HDHOMERUN_TYPE_DISCOVER_RPY 0x0003 - #define HDHOMERUN_TYPE_GETSET_REQ 0x0004 -@@ -136,7 +121,6 @@ - #define HDHOMERUN_TAG_DEVICE_ID 0x02 - #define HDHOMERUN_TAG_GETSET_NAME 0x03 - #define HDHOMERUN_TAG_GETSET_VALUE 0x04 --#define HDHOMERUN_TAG_GETSET_LOCKKEY 0x15 - #define HDHOMERUN_TAG_ERROR_MESSAGE 0x05 - - #define HDHOMERUN_DEVICE_TYPE_WILDCARD 0xFFFFFFFF -@@ -145,33 +129,25 @@ - - #define HDHOMERUN_MIN_PEEK_LENGTH 4 - --struct hdhomerun_pkt_t { -- uint8_t *pos; -- uint8_t *start; -- uint8_t *end; -- uint8_t *limit; -- uint8_t buffer[3074]; --}; -- --extern LIBTYPE struct hdhomerun_pkt_t *hdhomerun_pkt_create(void); --extern LIBTYPE void hdhomerun_pkt_destroy(struct hdhomerun_pkt_t *pkt); --extern LIBTYPE void hdhomerun_pkt_reset(struct hdhomerun_pkt_t *pkt); -- --extern LIBTYPE uint8_t hdhomerun_pkt_read_u8(struct hdhomerun_pkt_t *pkt); --extern LIBTYPE uint16_t hdhomerun_pkt_read_u16(struct hdhomerun_pkt_t *pkt); --extern LIBTYPE uint32_t hdhomerun_pkt_read_u32(struct hdhomerun_pkt_t *pkt); --extern LIBTYPE size_t hdhomerun_pkt_read_var_length(struct hdhomerun_pkt_t *pkt); --extern LIBTYPE uint8_t *hdhomerun_pkt_read_tlv(struct hdhomerun_pkt_t *pkt, uint8_t *ptag, size_t *plength); -- --extern LIBTYPE void hdhomerun_pkt_write_u8(struct hdhomerun_pkt_t *pkt, uint8_t v); --extern LIBTYPE void hdhomerun_pkt_write_u16(struct hdhomerun_pkt_t *pkt, uint16_t v); --extern LIBTYPE void hdhomerun_pkt_write_u32(struct hdhomerun_pkt_t *pkt, uint32_t v); --extern LIBTYPE void hdhomerun_pkt_write_var_length(struct hdhomerun_pkt_t *pkt, size_t v); --extern LIBTYPE void hdhomerun_pkt_write_mem(struct hdhomerun_pkt_t *pkt, const void *mem, size_t length); -- --extern LIBTYPE bool_t hdhomerun_pkt_open_frame(struct hdhomerun_pkt_t *pkt, uint16_t *ptype); --extern LIBTYPE void hdhomerun_pkt_seal_frame(struct hdhomerun_pkt_t *pkt, uint16_t frame_type); -+extern uint8_t hdhomerun_read_u8(uint8_t **pptr); -+extern uint16_t hdhomerun_read_u16(uint8_t **pptr); -+extern uint32_t hdhomerun_read_u32(uint8_t **pptr); -+extern size_t hdhomerun_read_var_length(uint8_t **pptr, uint8_t *end); -+extern void hdhomerun_write_u8(uint8_t **pptr, uint8_t v); -+extern void hdhomerun_write_u16(uint8_t **pptr, uint16_t v); -+extern void hdhomerun_write_u32(uint8_t **pptr, uint32_t v); -+extern void hdhomerun_write_var_length(uint8_t **pptr, size_t v); -+extern void hdhomerun_write_crc(uint8_t **pptr, uint8_t *start); -+ -+extern size_t hdhomerun_peek_packet_length(uint8_t *ptr); -+extern int hdhomerun_process_packet(uint8_t **pptr, uint8_t **pend); -+extern int hdhomerun_read_tlv(uint8_t **pptr, uint8_t *end, uint8_t *ptag, size_t *plength, uint8_t **pvalue); -+ -+extern void hdhomerun_write_discover_request(uint8_t **pptr, uint32_t device_type, uint32_t device_id); -+extern void hdhomerun_write_get_set_request(uint8_t **pptr, const char *name, const char *value); -+extern void hdhomerun_write_upgrade_request(uint8_t **pptr, uint32_t sequence, void *data, size_t length); - - #ifdef __cplusplus - } - #endif -+ -Only in branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun: hdhomerun_types.h -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.c src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_video.c ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.c 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_video.c 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_video.c - * -- * Copyright © 2006 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,82 +14,93 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - --#include "hdhomerun.h" -+#include "hdhomerun_os.h" -+#include "hdhomerun_pkt.h" -+#include "hdhomerun_video.h" - - struct hdhomerun_video_sock_t { -- pthread_mutex_t lock; - uint8_t *buffer; - size_t buffer_size; - volatile size_t head; - volatile size_t tail; - size_t advance; -+ volatile bool_t running; - volatile bool_t terminate; - pthread_t thread; - int sock; -- uint32_t rtp_sequence; -- struct hdhomerun_debug_t *dbg; -- volatile uint32_t packet_count; -- volatile uint32_t transport_error_count; -- volatile uint32_t network_error_count; -- volatile uint32_t sequence_error_count; -- volatile uint32_t overflow_error_count; -- volatile uint8_t sequence[0x2000]; - }; - --static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg); -+static void *hdhomerun_video_thread(void *arg); - --struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, size_t buffer_size, struct hdhomerun_debug_t *dbg) -+static bool_t hdhomerun_video_bind_sock_internal(struct hdhomerun_video_sock_t *vs, uint16_t listen_port) -+{ -+ struct sockaddr_in sock_addr; -+ memset(&sock_addr, 0, sizeof(sock_addr)); -+ sock_addr.sin_family = AF_INET; -+ sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); -+ sock_addr.sin_port = htons(listen_port); -+ if (bind(vs->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+static bool_t hdhomerun_video_bind_sock(struct hdhomerun_video_sock_t *vs, uint16_t listen_port) -+{ -+ if (listen_port != 0) { -+ return hdhomerun_video_bind_sock_internal(vs, listen_port); -+ } -+ -+#if defined(__CYGWIN__) || defined(__WINDOWS__) -+ /* Windows firewall silently blocks a listening port if the port number is not explicitly given. */ -+ /* Workaround - pick a random port number. The port may already be in use to try multiple port numbers. */ -+ srand((int)getcurrenttime()); -+ int retry; -+ for (retry = 8; retry > 0; retry--) { -+ uint16_t listen_port = (uint16_t)((rand() % 32768) + 32768); -+ if (hdhomerun_video_bind_sock_internal(vs, listen_port)) { -+ return TRUE; -+ } -+ } -+ return FALSE; -+#else -+ return hdhomerun_video_bind_sock_internal(vs, listen_port); -+#endif -+} -+ -+struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, size_t buffer_size) - { - /* Create object. */ - struct hdhomerun_video_sock_t *vs = (struct hdhomerun_video_sock_t *)calloc(1, sizeof(struct hdhomerun_video_sock_t)); - if (!vs) { -- hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to allocate video object\n"); - return NULL; - } - -- vs->dbg = dbg; -- vs->sock = -1; -- pthread_mutex_init(&vs->lock, NULL); -- -- /* Reset sequence tracking. */ -- hdhomerun_video_flush(vs); -- - /* Buffer size. */ - vs->buffer_size = (buffer_size / VIDEO_DATA_PACKET_SIZE) * VIDEO_DATA_PACKET_SIZE; - if (vs->buffer_size == 0) { -- hdhomerun_debug_printf(dbg, "hdhomerun_video_create: invalid buffer size (%lu bytes)\n", (unsigned long)buffer_size); -- goto error; -+ free(vs); -+ return NULL; - } - vs->buffer_size += VIDEO_DATA_PACKET_SIZE; - - /* Create buffer. */ - vs->buffer = (uint8_t *)malloc(vs->buffer_size); - if (!vs->buffer) { -- hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to allocate buffer (%lu bytes)\n", (unsigned long)vs->buffer_size); -- goto error; -+ free(vs); -+ return NULL; - } - - /* Create socket. */ - vs->sock = (int)socket(AF_INET, SOCK_DGRAM, 0); - if (vs->sock == -1) { -- hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to allocate socket\n"); -- goto error; -+ free(vs->buffer); -+ free(vs); -+ return NULL; - } - - /* Expand socket buffer size. */ -@@ -101,44 +112,30 @@ - setsocktimeout(vs->sock, SOL_SOCKET, SO_RCVTIMEO, 1000); - - /* Bind socket. */ -- struct sockaddr_in sock_addr; -- memset(&sock_addr, 0, sizeof(sock_addr)); -- sock_addr.sin_family = AF_INET; -- sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); -- sock_addr.sin_port = htons(listen_port); -- if (bind(vs->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { -- hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to bind socket (port %u)\n", listen_port); -- goto error; -+ if (!hdhomerun_video_bind_sock(vs, listen_port)) { -+ hdhomerun_video_destroy(vs); -+ return NULL; - } - - /* Start thread. */ -- if (pthread_create(&vs->thread, NULL, &hdhomerun_video_thread_execute, vs) != 0) { -- hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to start thread\n"); -- goto error; -+ if (pthread_create(&vs->thread, NULL, &hdhomerun_video_thread, vs) != 0) { -+ hdhomerun_video_destroy(vs); -+ return NULL; - } -+ vs->running = 1; - - /* Success. */ - return vs; -- --error: -- if (vs->sock != -1) { -- close(vs->sock); -- } -- if (vs->buffer) { -- free(vs->buffer); -- } -- free(vs); -- return NULL; - } - - void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs) - { -- vs->terminate = TRUE; -- pthread_join(vs->thread, NULL); -- -+ if (vs->running) { -+ vs->terminate = 1; -+ pthread_join(vs->thread, NULL); -+ } - close(vs->sock); - free(vs->buffer); -- - free(vs); - } - -@@ -147,85 +144,25 @@ - struct sockaddr_in sock_addr; - socklen_t sockaddr_size = sizeof(sock_addr); - if (getsockname(vs->sock, (struct sockaddr*)&sock_addr, &sockaddr_size) != 0) { -- hdhomerun_debug_printf(vs->dbg, "hdhomerun_video_get_local_port: getsockname failed (%d)\n", sock_getlasterror); - return 0; - } -- - return ntohs(sock_addr.sin_port); - } - --static void hdhomerun_video_stats_ts_pkt(struct hdhomerun_video_sock_t *vs, uint8_t *ptr) --{ -- uint16_t packet_identifier = ((uint16_t)(ptr[1] & 0x1F) << 8) | (uint16_t)ptr[2]; -- if (packet_identifier == 0x1FFF) { -- return; -- } -- -- bool_t transport_error = ptr[1] >> 7; -- if (transport_error) { -- vs->transport_error_count++; -- vs->sequence[packet_identifier] = 0xFF; -- return; -- } -- -- uint8_t continuity_counter = ptr[3] & 0x0F; -- uint8_t previous_sequence = vs->sequence[packet_identifier]; -- -- if (continuity_counter == ((previous_sequence + 1) & 0x0F)) { -- vs->sequence[packet_identifier] = continuity_counter; -- return; -- } -- if (previous_sequence == 0xFF) { -- vs->sequence[packet_identifier] = continuity_counter; -- return; -- } -- if (continuity_counter == previous_sequence) { -- return; -- } -- -- vs->sequence_error_count++; -- vs->sequence[packet_identifier] = continuity_counter; --} -- --static void hdhomerun_video_parse_rtp(struct hdhomerun_video_sock_t *vs, struct hdhomerun_pkt_t *pkt) -+int hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs) - { -- pkt->pos += 2; -- uint32_t rtp_sequence = hdhomerun_pkt_read_u16(pkt); -- pkt->pos += 8; -- -- if (rtp_sequence != ((vs->rtp_sequence + 1) & 0xFFFF)) { -- if (vs->rtp_sequence != 0xFFFFFFFF) { -- vs->network_error_count++; -- -- /* restart pid sequence check */ -- /* can't use memset bcs sequence is volatile */ -- int i; -- for (i = 0; i < sizeof(vs->sequence) / sizeof(uint8_t) ; i++) -- vs->sequence[i] = 0xFF; -- } -- } -- -- vs->rtp_sequence = rtp_sequence; -+ return vs->sock; - } - --static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg) -+static void *hdhomerun_video_thread(void *arg) - { - struct hdhomerun_video_sock_t *vs = (struct hdhomerun_video_sock_t *)arg; -- struct hdhomerun_pkt_t pkt_inst; - - while (!vs->terminate) { -- struct hdhomerun_pkt_t *pkt = &pkt_inst; -- hdhomerun_pkt_reset(pkt); -+ size_t head = vs->head; - - /* Receive. */ -- int length = recv(vs->sock, (char *)pkt->end, VIDEO_RTP_DATA_PACKET_SIZE, 0); -- pkt->end += length; -- -- if (length == VIDEO_RTP_DATA_PACKET_SIZE) { -- hdhomerun_video_parse_rtp(vs, pkt); -- length = (int)(pkt->end - pkt->pos); -- } -- -+ int length = recv(vs->sock, (char *)vs->buffer + head, VIDEO_DATA_PACKET_SIZE, 0); - if (length != VIDEO_DATA_PACKET_SIZE) { - if (length > 0) { - /* Data received but not valid - ignore. */ -@@ -235,27 +172,10 @@ - /* Wait for more data. */ - continue; - } -- vs->terminate = TRUE; -+ vs->terminate = 1; - return NULL; - } - -- pthread_mutex_lock(&vs->lock); -- -- /* Store in ring buffer. */ -- size_t head = vs->head; -- uint8_t *ptr = vs->buffer + head; -- memcpy(ptr, pkt->pos, length); -- -- /* Stats. */ -- vs->packet_count++; -- hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 0); -- hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 1); -- hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 2); -- hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 3); -- hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 4); -- hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 5); -- hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 6); -- - /* Calculate new head. */ - head += length; - if (head >= vs->buffer_size) { -@@ -264,15 +184,11 @@ - - /* Check for buffer overflow. */ - if (head == vs->tail) { -- vs->overflow_error_count++; -- pthread_mutex_unlock(&vs->lock); - continue; - } - - /* Atomic update. */ - vs->head = head; -- -- pthread_mutex_unlock(&vs->lock); - } - - return NULL; -@@ -280,8 +196,6 @@ - - uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size) - { -- pthread_mutex_lock(&vs->lock); -- - size_t head = vs->head; - size_t tail = vs->tail; - -@@ -298,7 +212,6 @@ - if (head == tail) { - vs->advance = 0; - *pactual_size = 0; -- pthread_mutex_unlock(&vs->lock); - return NULL; - } - -@@ -306,7 +219,6 @@ - if (size == 0) { - vs->advance = 0; - *pactual_size = 0; -- pthread_mutex_unlock(&vs->lock); - return NULL; - } - -@@ -321,58 +233,13 @@ - } - vs->advance = size; - *pactual_size = size; -- uint8_t *result = vs->buffer + tail; -- -- pthread_mutex_unlock(&vs->lock); -- return result; -+ return vs->buffer + tail; - } - - void hdhomerun_video_flush(struct hdhomerun_video_sock_t *vs) - { -- pthread_mutex_lock(&vs->lock); -- -+ /* Atomic update of tail. */ - vs->tail = vs->head; - vs->advance = 0; -- -- /* can't use memset bcs sequence is volatile */ -- int i; -- for (i = 0; i < sizeof(vs->sequence) / sizeof(uint8_t) ; i++) -- vs->sequence[i] = 0xFF; -- -- vs->rtp_sequence = 0xFFFFFFFF; -- -- vs->packet_count = 0; -- vs->transport_error_count = 0; -- vs->network_error_count = 0; -- vs->sequence_error_count = 0; -- vs->overflow_error_count = 0; -- -- pthread_mutex_unlock(&vs->lock); - } - --void hdhomerun_video_debug_print_stats(struct hdhomerun_video_sock_t *vs) --{ -- struct hdhomerun_video_stats_t stats; -- hdhomerun_video_get_stats(vs, &stats); -- -- hdhomerun_debug_printf(vs->dbg, "video sock: pkt=%ld net=%ld te=%ld miss=%ld drop=%ld\n", -- stats.packet_count, stats.network_error_count, -- stats.transport_error_count, stats.sequence_error_count, -- stats.overflow_error_count -- ); --} -- --void hdhomerun_video_get_stats(struct hdhomerun_video_sock_t *vs, struct hdhomerun_video_stats_t *stats) --{ -- memset(stats, 0, sizeof(struct hdhomerun_video_stats_t)); -- -- pthread_mutex_lock(&vs->lock); -- -- stats->packet_count = vs->packet_count; -- stats->network_error_count = vs->network_error_count; -- stats->transport_error_count = vs->transport_error_count; -- stats->sequence_error_count = vs->sequence_error_count; -- stats->overflow_error_count = vs->overflow_error_count; -- -- pthread_mutex_unlock(&vs->lock); --} -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.h src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_video.h ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.h 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/hdhomerun_video.h 2009-01-09 13:14:56.000000000 +1030 -@@ -1,12 +1,12 @@ - /* - * hdhomerun_video.h - * -- * Copyright © 2006 Silicondust USA Inc. <www.silicondust.com>. -+ * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. - * -- * This library is free software; you can redistribute it and/or -+ * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either -- * version 3 of the License, or (at your option) any later version. -+ * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of -@@ -14,20 +14,8 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public -- * License along with this library. If not, see <http://www.gnu.org/licenses/>. -- * -- * As a special exception to the GNU Lesser General Public License, -- * you may link, statically or dynamically, an application with a -- * publicly distributed version of the Library to produce an -- * executable file containing portions of the Library, and -- * distribute that executable file under terms of your choice, -- * without any of the additional requirements listed in clause 4 of -- * the GNU Lesser General Public License. -- * -- * By "a publicly distributed version of the Library", we mean -- * either the unmodified Library as distributed by Silicondust, or a -- * modified version of the Library that is distributed under the -- * conditions defined in the GNU Lesser General Public License. -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - #ifdef __cplusplus - extern "C" { -@@ -35,40 +23,34 @@ - - struct hdhomerun_video_sock_t; - --struct hdhomerun_video_stats_t { -- uint32_t packet_count; -- uint32_t network_error_count; -- uint32_t transport_error_count; -- uint32_t sequence_error_count; -- uint32_t overflow_error_count; --}; -- - #define TS_PACKET_SIZE 188 - #define VIDEO_DATA_PACKET_SIZE (188 * 7) - #define VIDEO_DATA_BUFFER_SIZE_1S (20000000 / 8) - --#define VIDEO_RTP_DATA_PACKET_SIZE ((188 * 7) + 12) -- - /* - * Create a video/data socket. - * - * uint16_t listen_port: Port number to listen on. Set to 0 to auto-select. - * size_t buffer_size: Size of receive buffer. For 1 second of buffer use VIDEO_DATA_BUFFER_SIZE_1S. -- * struct hdhomerun_debug_t *dbg: Pointer to debug logging object. May be NULL. - * - * Returns a pointer to the newly created control socket. - * - * When no longer needed, the socket should be destroyed by calling hdhomerun_control_destroy. - */ --extern LIBTYPE struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, size_t buffer_size, struct hdhomerun_debug_t *dbg); --extern LIBTYPE void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs); -+extern struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, size_t buffer_size); -+extern void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs); - - /* - * Get the port the socket is listening on. - * - * Returns 16-bit port with native endianness, or 0 on error. - */ --extern LIBTYPE uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs); -+extern uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs); -+ -+/* -+ * Get the low-level socket handle. -+ */ -+extern int hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs); - - /* - * Read data from buffer. -@@ -87,18 +69,12 @@ - * The buffer is implemented as a ring buffer. It is possible for this function to return a small - * amount of data when more is available due to the wrap-around case. - */ --extern LIBTYPE uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size); -+extern uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size); - - /* - * Flush the buffer. - */ --extern LIBTYPE void hdhomerun_video_flush(struct hdhomerun_video_sock_t *vs); -- --/* -- * Debug print internal stats. -- */ --extern LIBTYPE void hdhomerun_video_debug_print_stats(struct hdhomerun_video_sock_t *vs); --extern LIBTYPE void hdhomerun_video_get_stats(struct hdhomerun_video_sock_t *vs, struct hdhomerun_video_stats_t *stats); -+extern void hdhomerun_video_flush(struct hdhomerun_video_sock_t *vs); - - #ifdef __cplusplus - } -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/lgpl.txt src/mythtv-0.21/libs/libmythtv/hdhomerun/lgpl.txt ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhomerun/lgpl.txt 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhomerun/lgpl.txt 2009-01-09 13:14:56.000000000 +1030 -@@ -1,165 +1,504 @@ -- GNU LESSER GENERAL PUBLIC LICENSE -- Version 3, 29 June 2007 -+ GNU LESSER GENERAL PUBLIC LICENSE -+ Version 2.1, February 1999 - -- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> -+ Copyright (C) 1991, 1999 Free Software Foundation, Inc. -+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -- -- This version of the GNU Lesser General Public License incorporates --the terms and conditions of version 3 of the GNU General Public --License, supplemented by the additional permissions listed below. -- -- 0. Additional Definitions. -- -- As used herein, "this License" refers to version 3 of the GNU Lesser --General Public License, and the "GNU GPL" refers to version 3 of the GNU --General Public License. -- -- "The Library" refers to a covered work governed by this License, --other than an Application or a Combined Work as defined below. -- -- An "Application" is any work that makes use of an interface provided --by the Library, but which is not otherwise based on the Library. --Defining a subclass of a class defined by the Library is deemed a mode --of using an interface provided by the Library. -- -- A "Combined Work" is a work produced by combining or linking an --Application with the Library. The particular version of the Library --with which the Combined Work was made is also called the "Linked --Version". -- -- The "Minimal Corresponding Source" for a Combined Work means the --Corresponding Source for the Combined Work, excluding any source code --for portions of the Combined Work that, considered in isolation, are --based on the Application, and not on the Linked Version. -- -- The "Corresponding Application Code" for a Combined Work means the --object code and/or source code for the Application, including any data --and utility programs needed for reproducing the Combined Work from the --Application, but excluding the System Libraries of the Combined Work. -- -- 1. Exception to Section 3 of the GNU GPL. -- -- You may convey a covered work under sections 3 and 4 of this License --without being bound by section 3 of the GNU GPL. -- -- 2. Conveying Modified Versions. -- -- If you modify a copy of the Library, and, in your modifications, a --facility refers to a function or data to be supplied by an Application --that uses the facility (other than as an argument passed when the --facility is invoked), then you may convey a copy of the modified --version: -- -- a) under this License, provided that you make a good faith effort to -- ensure that, in the event an Application does not supply the -- function or data, the facility still operates, and performs -- whatever part of its purpose remains meaningful, or -- -- b) under the GNU GPL, with none of the additional permissions of -- this License applicable to that copy. -- -- 3. Object Code Incorporating Material from Library Header Files. -- -- The object code form of an Application may incorporate material from --a header file that is part of the Library. You may convey such object --code under terms of your choice, provided that, if the incorporated --material is not limited to numerical parameters, data structure --layouts and accessors, or small macros, inline functions and templates --(ten or fewer lines in length), you do both of the following: -- -- a) Give prominent notice with each copy of the object code that the -- Library is used in it and that the Library and its use are -- covered by this License. -- -- b) Accompany the object code with a copy of the GNU GPL and this license -- document. -- -- 4. Combined Works. -- -- You may convey a Combined Work under terms of your choice that, --taken together, effectively do not restrict modification of the --portions of the Library contained in the Combined Work and reverse --engineering for debugging such modifications, if you also do each of --the following: -- -- a) Give prominent notice with each copy of the Combined Work that -- the Library is used in it and that the Library and its use are -- covered by this License. -- -- b) Accompany the Combined Work with a copy of the GNU GPL and this license -- document. -- -- c) For a Combined Work that displays copyright notices during -- execution, include the copyright notice for the Library among -- these notices, as well as a reference directing the user to the -- copies of the GNU GPL and this license document. -- -- d) Do one of the following: -- -- 0) Convey the Minimal Corresponding Source under the terms of this -- License, and the Corresponding Application Code in a form -- suitable for, and under terms that permit, the user to -- recombine or relink the Application with a modified version of -- the Linked Version to produce a modified Combined Work, in the -- manner specified by section 6 of the GNU GPL for conveying -- Corresponding Source. -- -- 1) Use a suitable shared library mechanism for linking with the -- Library. A suitable mechanism is one that (a) uses at run time -- a copy of the Library already present on the user's computer -- system, and (b) will operate properly with a modified version -- of the Library that is interface-compatible with the Linked -- Version. -- -- e) Provide Installation Information, but only if you would otherwise -- be required to provide such information under section 6 of the -- GNU GPL, and only to the extent that such information is -- necessary to install and execute a modified version of the -- Combined Work produced by recombining or relinking the -- Application with a modified version of the Linked Version. (If -- you use option 4d0, the Installation Information must accompany -- the Minimal Corresponding Source and Corresponding Application -- Code. If you use option 4d1, you must provide the Installation -- Information in the manner specified by section 6 of the GNU GPL -- for conveying Corresponding Source.) -- -- 5. Combined Libraries. -- -- You may place library facilities that are a work based on the --Library side by side in a single library together with other library --facilities that are not Applications and are not covered by this --License, and convey such a combined library under terms of your --choice, if you do both of the following: -- -- a) Accompany the combined library with a copy of the same work based -- on the Library, uncombined with any other library facilities, -- conveyed under the terms of this License. -- -- b) Give prominent notice with the combined library that part of it -- is a work based on the Library, and explaining where to find the -- accompanying uncombined form of the same work. -- -- 6. Revised Versions of the GNU Lesser General Public License. -- -- The Free Software Foundation may publish revised and/or new versions --of the GNU Lesser General Public License from time to time. Such new --versions will be similar in spirit to the present version, but may --differ in detail to address new problems or concerns. -- -- Each version is given a distinguishing version number. If the --Library as you received it specifies that a certain numbered version --of the GNU Lesser General Public License "or any later version" --applies to it, you have the option of following the terms and --conditions either of that published version or of any later version --published by the Free Software Foundation. If the Library as you --received it does not specify a version number of the GNU Lesser --General Public License, you may choose any version of the GNU Lesser --General Public License ever published by the Free Software Foundation. -- -- If the Library as you received it specifies that a proxy can decide --whether future versions of the GNU Lesser General Public License shall --apply, that proxy's public statement of acceptance of any version is --permanent authorization for you to choose that version for the -+[This is the first released version of the Lesser GPL. It also counts -+ as the successor of the GNU Library Public License, version 2, hence -+ the version number 2.1.] -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+Licenses are intended to guarantee your freedom to share and change -+free software--to make sure the software is free for all its users. -+ -+ This license, the Lesser General Public License, applies to some -+specially designated software packages--typically libraries--of the -+Free Software Foundation and other authors who decide to use it. You -+can use it too, but we suggest you first think carefully about whether -+this license or the ordinary General Public License is the better -+strategy to use in any particular case, based on the explanations below. -+ -+ When we speak of free software, we are referring to freedom of use, -+not price. Our General Public Licenses are designed to make sure that -+you have the freedom to distribute copies of free software (and charge -+for this service if you wish); that you receive source code or can get -+it if you want it; that you can change the software and use pieces of -+it in new free programs; and that you are informed that you can do -+these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+distributors to deny you these rights or to ask you to surrender these -+rights. These restrictions translate to certain responsibilities for -+you if you distribute copies of the library or if you modify it. -+ -+ For example, if you distribute copies of the library, whether gratis -+or for a fee, you must give the recipients all the rights that we gave -+you. You must make sure that they, too, receive or can get the source -+code. If you link other code with the library, you must provide -+complete object files to the recipients, so that they can relink them -+with the library after making changes to the library and recompiling -+it. And you must show them these terms so they know their rights. -+ -+ We protect your rights with a two-step method: (1) we copyright the -+library, and (2) we offer you this license, which gives you legal -+permission to copy, distribute and/or modify the library. -+ -+ To protect each distributor, we want to make it very clear that -+there is no warranty for the free library. Also, if the library is -+modified by someone else and passed on, the recipients should know -+that what they have is not the original version, so that the original -+author's reputation will not be affected by problems that might be -+introduced by others. -+ -+ Finally, software patents pose a constant threat to the existence of -+any free program. We wish to make sure that a company cannot -+effectively restrict the users of a free program by obtaining a -+restrictive license from a patent holder. Therefore, we insist that -+any patent license obtained for a version of the library must be -+consistent with the full freedom of use specified in this license. -+ -+ Most GNU software, including some libraries, is covered by the -+ordinary GNU General Public License. This license, the GNU Lesser -+General Public License, applies to certain designated libraries, and -+is quite different from the ordinary General Public License. We use -+this license for certain libraries in order to permit linking those -+libraries into non-free programs. -+ -+ When a program is linked with a library, whether statically or using -+a shared library, the combination of the two is legally speaking a -+combined work, a derivative of the original library. The ordinary -+General Public License therefore permits such linking only if the -+entire combination fits its criteria of freedom. The Lesser General -+Public License permits more lax criteria for linking other code with -+the library. -+ -+ We call this license the "Lesser" General Public License because it -+does Less to protect the user's freedom than the ordinary General -+Public License. It also provides other free software developers Less -+of an advantage over competing non-free programs. These disadvantages -+are the reason we use the ordinary General Public License for many -+libraries. However, the Lesser license provides advantages in certain -+special circumstances. -+ -+ For example, on rare occasions, there may be a special need to -+encourage the widest possible use of a certain library, so that it becomes -+a de-facto standard. To achieve this, non-free programs must be -+allowed to use the library. A more frequent case is that a free -+library does the same job as widely used non-free libraries. In this -+case, there is little to gain by limiting the free library to free -+software only, so we use the Lesser General Public License. -+ -+ In other cases, permission to use a particular library in non-free -+programs enables a greater number of people to use a large body of -+free software. For example, permission to use the GNU C Library in -+non-free programs enables many more people to use the whole GNU -+operating system, as well as its variant, the GNU/Linux operating -+system. -+ -+ Although the Lesser General Public License is Less protective of the -+users' freedom, it does ensure that the user of a program that is -+linked with the Library has the freedom and the wherewithal to run -+that program using a modified version of the Library. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. Pay close attention to the difference between a -+"work based on the library" and a "work that uses the library". The -+former contains code derived from the library, whereas the latter must -+be combined with the library in order to run. -+ -+ GNU LESSER GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License Agreement applies to any software library or other -+program which contains a notice placed by the copyright holder or -+other authorized party saying it may be distributed under the terms of -+this Lesser General Public License (also called "this License"). -+Each licensee is addressed as "you". -+ -+ A "library" means a collection of software functions and/or data -+prepared so as to be conveniently linked with application programs -+(which use some of those functions and data) to form executables. -+ -+ The "Library", below, refers to any such software library or work -+which has been distributed under these terms. A "work based on the -+Library" means either the Library or any derivative work under -+copyright law: that is to say, a work containing the Library or a -+portion of it, either verbatim or with modifications and/or translated -+straightforwardly into another language. (Hereinafter, translation is -+included without limitation in the term "modification".) -+ -+ "Source code" for a work means the preferred form of the work for -+making modifications to it. For a library, complete source code means -+all the source code for all modules it contains, plus any associated -+interface definition files, plus the scripts used to control compilation -+and installation of the library. -+ -+ Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running a program using the Library is not restricted, and output from -+such a program is covered only if its contents constitute a work based -+on the Library (independent of the use of the Library in a tool for -+writing it). Whether that is true depends on what the Library does -+and what the program that uses the Library does. -+ -+ 1. You may copy and distribute verbatim copies of the Library's -+complete source code as you receive it, in any medium, provided that -+you conspicuously and appropriately publish on each copy an -+appropriate copyright notice and disclaimer of warranty; keep intact -+all the notices that refer to this License and to the absence of any -+warranty; and distribute a copy of this License along with the - Library. -+ -+ You may charge a fee for the physical act of transferring a copy, -+and you may at your option offer warranty protection in exchange for a -+fee. -+ -+ 2. You may modify your copy or copies of the Library or any portion -+of it, thus forming a work based on the Library, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) The modified work must itself be a software library. -+ -+ b) You must cause the files modified to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ c) You must cause the whole of the work to be licensed at no -+ charge to all third parties under the terms of this License. -+ -+ d) If a facility in the modified Library refers to a function or a -+ table of data to be supplied by an application program that uses -+ the facility, other than as an argument passed when the facility -+ is invoked, then you must make a good faith effort to ensure that, -+ in the event an application does not supply such function or -+ table, the facility still operates, and performs whatever part of -+ its purpose remains meaningful. -+ -+ (For example, a function in a library to compute square roots has -+ a purpose that is entirely well-defined independent of the -+ application. Therefore, Subsection 2d requires that any -+ application-supplied function or table used by this function must -+ be optional: if the application does not supply it, the square -+ root function must still compute square roots.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Library, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Library, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote -+it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Library. -+ -+In addition, mere aggregation of another work not based on the Library -+with the Library (or with a work based on the Library) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may opt to apply the terms of the ordinary GNU General Public -+License instead of this License to a given copy of the Library. To do -+this, you must alter all the notices that refer to this License, so -+that they refer to the ordinary GNU General Public License, version 2, -+instead of to this License. (If a newer version than version 2 of the -+ordinary GNU General Public License has appeared, then you can specify -+that version instead if you wish.) Do not make any other change in -+these notices. -+ -+ Once this change is made in a given copy, it is irreversible for -+that copy, so the ordinary GNU General Public License applies to all -+subsequent copies and derivative works made from that copy. -+ -+ This option is useful when you wish to copy part of the code of -+the Library into a program that is not a library. -+ -+ 4. You may copy and distribute the Library (or a portion or -+derivative of it, under Section 2) in object code or executable form -+under the terms of Sections 1 and 2 above provided that you accompany -+it with the complete corresponding machine-readable source code, which -+must be distributed under the terms of Sections 1 and 2 above on a -+medium customarily used for software interchange. -+ -+ If distribution of object code is made by offering access to copy -+from a designated place, then offering equivalent access to copy the -+source code from the same place satisfies the requirement to -+distribute the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 5. A program that contains no derivative of any portion of the -+Library, but is designed to work with the Library by being compiled or -+linked with it, is called a "work that uses the Library". Such a -+work, in isolation, is not a derivative work of the Library, and -+therefore falls outside the scope of this License. -+ -+ However, linking a "work that uses the Library" with the Library -+creates an executable that is a derivative of the Library (because it -+contains portions of the Library), rather than a "work that uses the -+library". The executable is therefore covered by this License. -+Section 6 states terms for distribution of such executables. -+ -+ When a "work that uses the Library" uses material from a header file -+that is part of the Library, the object code for the work may be a -+derivative work of the Library even though the source code is not. -+Whether this is true is especially significant if the work can be -+linked without the Library, or if the work is itself a library. The -+threshold for this to be true is not precisely defined by law. -+ -+ If such an object file uses only numerical parameters, data -+structure layouts and accessors, and small macros and small inline -+functions (ten lines or less in length), then the use of the object -+file is unrestricted, regardless of whether it is legally a derivative -+work. (Executables containing this object code plus portions of the -+Library will still fall under Section 6.) -+ -+ Otherwise, if the work is a derivative of the Library, you may -+distribute the object code for the work under the terms of Section 6. -+Any executables containing that work also fall under Section 6, -+whether or not they are linked directly with the Library itself. -+ -+ 6. As an exception to the Sections above, you may also combine or -+link a "work that uses the Library" with the Library to produce a -+work containing portions of the Library, and distribute that work -+under terms of your choice, provided that the terms permit -+modification of the work for the customer's own use and reverse -+engineering for debugging such modifications. -+ -+ You must give prominent notice with each copy of the work that the -+Library is used in it and that the Library and its use are covered by -+this License. You must supply a copy of this License. If the work -+during execution displays copyright notices, you must include the -+copyright notice for the Library among them, as well as a reference -+directing the user to the copy of this License. Also, you must do one -+of these things: -+ -+ a) Accompany the work with the complete corresponding -+ machine-readable source code for the Library including whatever -+ changes were used in the work (which must be distributed under -+ Sections 1 and 2 above); and, if the work is an executable linked -+ with the Library, with the complete machine-readable "work that -+ uses the Library", as object code and/or source code, so that the -+ user can modify the Library and then relink to produce a modified -+ executable containing the modified Library. (It is understood -+ that the user who changes the contents of definitions files in the -+ Library will not necessarily be able to recompile the application -+ to use the modified definitions.) -+ -+ b) Use a suitable shared library mechanism for linking with the -+ Library. A suitable mechanism is one that (1) uses at run time a -+ copy of the library already present on the user's computer system, -+ rather than copying library functions into the executable, and (2) -+ will operate properly with a modified version of the library, if -+ the user installs one, as long as the modified version is -+ interface-compatible with the version that the work was made with. -+ -+ c) Accompany the work with a written offer, valid for at -+ least three years, to give the same user the materials -+ specified in Subsection 6a, above, for a charge no more -+ than the cost of performing this distribution. -+ -+ d) If distribution of the work is made by offering access to copy -+ from a designated place, offer equivalent access to copy the above -+ specified materials from the same place. -+ -+ e) Verify that the user has already received a copy of these -+ materials or that you have already sent this user a copy. -+ -+ For an executable, the required form of the "work that uses the -+Library" must include any data and utility programs needed for -+reproducing the executable from it. However, as a special exception, -+the materials to be distributed need not include anything that is -+normally distributed (in either source or binary form) with the major -+components (compiler, kernel, and so on) of the operating system on -+which the executable runs, unless that component itself accompanies -+the executable. -+ -+ It may happen that this requirement contradicts the license -+restrictions of other proprietary libraries that do not normally -+accompany the operating system. Such a contradiction means you cannot -+use both them and the Library together in an executable that you -+distribute. -+ -+ 7. You may place library facilities that are a work based on the -+Library side-by-side in a single library together with other library -+facilities not covered by this License, and distribute such a combined -+library, provided that the separate distribution of the work based on -+the Library and of the other library facilities is otherwise -+permitted, and provided that you do these two things: -+ -+ a) Accompany the combined library with a copy of the same work -+ based on the Library, uncombined with any other library -+ facilities. This must be distributed under the terms of the -+ Sections above. -+ -+ b) Give prominent notice with the combined library of the fact -+ that part of it is a work based on the Library, and explaining -+ where to find the accompanying uncombined form of the same work. -+ -+ 8. You may not copy, modify, sublicense, link with, or distribute -+the Library except as expressly provided under this License. Any -+attempt otherwise to copy, modify, sublicense, link with, or -+distribute the Library is void, and will automatically terminate your -+rights under this License. However, parties who have received copies, -+or rights, from you under this License will not have their licenses -+terminated so long as such parties remain in full compliance. -+ -+ 9. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Library or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Library (or any work based on the -+Library), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Library or works based on it. -+ -+ 10. Each time you redistribute the Library (or any work based on the -+Library), the recipient automatically receives a license from the -+original licensor to copy, distribute, link with or modify the Library -+subject to these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties with -+this License. -+ -+ 11. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Library at all. For example, if a patent -+license would not permit royalty-free redistribution of the Library by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Library. -+ -+If any portion of this section is held invalid or unenforceable under any -+particular circumstance, the balance of the section is intended to apply, -+and the section as a whole is intended to apply in other circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 12. If the distribution and/or use of the Library is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Library under this License may add -+an explicit geographical distribution limitation excluding those countries, -+so that distribution is permitted only in or among countries not thus -+excluded. In such case, this License incorporates the limitation as if -+written in the body of this License. -+ -+ 13. The Free Software Foundation may publish revised and/or new -+versions of the Lesser General Public License from time to time. -+Such new versions will be similar in spirit to the present version, -+but may differ in detail to address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Library -+specifies a version number of this License which applies to it and -+"any later version", you have the option of following the terms and -+conditions either of that version or of any later version published by -+the Free Software Foundation. If the Library does not specify a -+license version number, you may choose any version ever published by -+the Free Software Foundation. -+ -+ 14. If you wish to incorporate parts of the Library into other free -+programs whose distribution conditions are incompatible with these, -+write to the author to ask for permission. For software which is -+copyrighted by the Free Software Foundation, write to the Free -+Software Foundation; we sometimes make exceptions for this. Our -+decision will be guided by the two goals of preserving the free status -+of all derivatives of our free software and of promoting the sharing -+and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. -+ -+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -+DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ How to Apply These Terms to Your New Libraries -+ -+ If you develop a new library, and you want it to be of the greatest -+possible use to the public, we recommend making it free software that -+everyone can redistribute and change. You can do so by permitting -+redistribution under these terms (or, alternatively, under the terms of the -+ordinary General Public License). -+ -+ To apply these terms, attach the following notices to the library. It is -+safest to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least the -+"copyright" line and a pointer to where the full notice is found. -+ -+ <one line to give the library's name and a brief idea of what it does.> -+ Copyright (C) <year> <name of author> -+ -+ This library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ This library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with this library; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the library, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the -+ library `Frob' (a library for tweaking knobs) written by James Random Hacker. -+ -+ <signature of Ty Coon>, 1 April 1990 -+ Ty Coon, President of Vice -+ -+That's all there is to it! -+ -+ -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhrchannel.cpp src/mythtv-0.21/libs/libmythtv/hdhrchannel.cpp ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhrchannel.cpp 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhrchannel.cpp 2009-01-09 13:14:58.000000000 +1030 -@@ -1,6 +1,6 @@ - /** -- * HDHRChannel -- * Copyright (c) 2006-2009 by Silicondust Engineering Ltd. -+ * DBox2Channel -+ * Copyright (c) 2006 by Silicondust Engineering Ltd. - * Distributed as part of MythTV under GPL v2 and later. - */ - -@@ -24,6 +24,7 @@ - #include "hdhrchannel.h" - #include "videosource.h" - #include "channelutil.h" -+#include "frequencytables.h" - - #define DEBUG_PID_FILTERS - -@@ -31,7 +32,7 @@ - #define LOC_ERR QString("HDHRChan(%1), Error: ").arg(GetDevice()) - - HDHRChannel::HDHRChannel(TVRec *parent, const QString &device, uint tuner) -- : DTVChannel(parent), _hdhomerun_device(NULL), -+ : DTVChannel(parent), _control_socket(NULL), - _device_id(0), _device_ip(0), - _tuner(tuner), _lock(true) - { -@@ -41,8 +42,6 @@ - if (valid && hdhomerun_discover_validate_device_id(_device_id)) - return; - -- _device_id = HDHOMERUN_DEVICE_ID_WILDCARD; -- - /* Otherwise, is it a valid IP address? */ - struct in_addr address; - if (inet_aton(device, &address)) -@@ -55,6 +54,7 @@ - VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Invalid DeviceID '%1'") - .arg(device)); - -+ _device_id = HDHOMERUN_DEVICE_ID_WILDCARD; - } - - HDHRChannel::~HDHRChannel(void) -@@ -67,38 +67,77 @@ - if (IsOpen()) - return true; - -+ if (!FindDevice()) -+ return false; -+ - if (!InitializeInputs()) - return false; - -- return Connect(); -+ return (_device_ip != 0) && Connect(); - } - - void HDHRChannel::Close(void) - { -- if (_hdhomerun_device) -+ if (_control_socket) - { -- hdhomerun_device_destroy(_hdhomerun_device); -- _hdhomerun_device = NULL; -+ hdhomerun_control_destroy(_control_socket); -+ _control_socket = NULL; - } - } - - bool HDHRChannel::EnterPowerSavingMode(void) - { -- return hdhomerun_device_set_tuner_channel(_hdhomerun_device, "none") > 0; -+ return QString::null != TunerSet("channel", "none", false); -+} -+ -+bool HDHRChannel::FindDevice(void) -+{ -+ if (!_device_id) -+ return _device_ip; -+ -+ _device_ip = 0; -+ -+ /* Discover. */ -+ struct hdhomerun_discover_device_t result; -+ int ret = hdhomerun_discover_find_device(_device_id, &result); -+ if (ret < 0) -+ { -+ VERBOSE(VB_IMPORTANT, LOC_ERR + "Unable to send discovery request" + ENO); -+ return false; -+ } -+ if (ret == 0) -+ { -+ VERBOSE(VB_IMPORTANT, LOC_ERR + QString("device not found")); -+ return false; -+ } -+ -+ /* Found. */ -+ _device_ip = result.ip_addr; -+ -+ VERBOSE(VB_IMPORTANT, LOC + -+ QString("device found at address %1.%2.%3.%4") -+ .arg((_device_ip>>24) & 0xFF).arg((_device_ip>>16) & 0xFF) -+ .arg((_device_ip>> 8) & 0xFF).arg((_device_ip>> 0) & 0xFF)); -+ -+ return true; - } - - bool HDHRChannel::Connect(void) - { -- _hdhomerun_device = hdhomerun_device_create( -- _device_id, _device_ip, _tuner, NULL); -+ _control_socket = hdhomerun_control_create(_device_id, _device_ip); -+ if (!_control_socket) -+ { -+ VERBOSE(VB_IMPORTANT, LOC_ERR + "Unable to create control socket"); -+ return false; -+ } - -- if (!_hdhomerun_device) -+ if (hdhomerun_control_get_local_addr(_control_socket) == 0) - { -- VERBOSE(VB_IMPORTANT, -- LOC_ERR + "Unable to create hdhomerun device object"); -+ VERBOSE(VB_IMPORTANT, LOC_ERR + "Unable to connect to device"); - return false; - } - -+ VERBOSE(VB_CHANNEL, LOC + "Successfully connected to device"); - return true; - } - -@@ -106,7 +145,7 @@ - { - QMutexLocker locker(&_lock); - -- if (!_hdhomerun_device) -+ if (!_control_socket) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + "Get request failed (not connected)"); - return QString::null; -@@ -114,7 +153,7 @@ - - char *value = NULL; - char *error = NULL; -- if (hdhomerun_device_get_var(_hdhomerun_device, name, &value, &error) < 0) -+ if (hdhomerun_control_get(_control_socket, name, &value, &error) < 0) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + "Get request failed" + ENO); - return QString::null; -@@ -136,7 +175,7 @@ - { - QMutexLocker locker(&_lock); - -- if (!_hdhomerun_device) -+ if (!_control_socket) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + "Set request failed (not connected)"); - return QString::null; -@@ -144,8 +183,7 @@ - - char *value = NULL; - char *error = NULL; -- if (hdhomerun_device_set_var( -- _hdhomerun_device, name, val, &value, &error) < 0) -+ if (hdhomerun_control_set(_control_socket, name, val, &value, &error) < 0) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + "Set request failed" + ENO); - -@@ -163,11 +201,6 @@ - return QString(value); - } - --struct hdhomerun_device_t *HDHRChannel::GetHDHRDevice(void) --{ -- return _hdhomerun_device; --} -- - QString HDHRChannel::TunerGet(const QString &name, bool report_error_return) - { - return DeviceGet(QString("/tuner%1/%2").arg(_tuner).arg(name), -@@ -188,8 +221,7 @@ - return false; - } - -- unsigned long localIP = hdhomerun_device_get_local_machine_addr( -- _hdhomerun_device); -+ unsigned long localIP = hdhomerun_control_get_local_addr(_control_socket); - if (localIP == 0) - { - return false; -@@ -200,7 +232,7 @@ - .arg((localIP >> 8) & 0xFF).arg((localIP >> 0) & 0xFF) - .arg(localPort); - -- if (hdhomerun_device_set_tuner_target(_hdhomerun_device, configValue) <= 0) -+ if (!TunerSet("target", configValue)) - { - return false; - } -@@ -208,9 +240,9 @@ - return true; - } - --bool HDHRChannel::DeviceClearTarget(void) -+bool HDHRChannel::DeviceClearTarget() - { -- return hdhomerun_device_set_tuner_target(_hdhomerun_device, "none") > 0; -+ return TunerSet("target", "0.0.0.0:0"); - } - - bool HDHRChannel::SetChannelByString(const QString &channum) -@@ -316,8 +348,7 @@ - if (mpeg_prog_num && (GetTuningMode() == "mpeg")) - { - QString pnum = QString::number(mpeg_prog_num); -- _ignore_filters = (hdhomerun_device_set_tuner_program( -- _hdhomerun_device, pnum) > 0); -+ _ignore_filters = QString::null != TunerSet("program", pnum, false); - } - - return true; -@@ -360,27 +391,22 @@ - bool HDHRChannel::Tune(uint frequency, QString /*input*/, - QString modulation, QString si_std) - { -- // Convert dtv_multiplex.modulation strings to something the HDHR can use: -- modulation.replace("qam_", "qam"); // e.g. qam_256 -> qam256 --#if 0 -- if (modulation == "qamauto") -- modulation = "qam"; // "auto" works just as well? --#endif -- -- if (modulation.isEmpty()) -- modulation = "auto"; -+ bool ok = false; - -- QString chan = modulation + ':' + QString::number(frequency); -+ VERBOSE(VB_CHANNEL, LOC + -+ QString("TuneTo(%1,%2)").arg(frequency).arg(modulation)); - -- VERBOSE(VB_CHANNEL, LOC + "Tune()ing to " + chan); -+ if (modulation == "8vsb") -+ ok = TunerSet("channel", QString("8vsb:%1").arg(frequency)); -+ else if (modulation == "qam_64") -+ ok = TunerSet("channel", QString("qam64:%1").arg(frequency)); -+ else if (modulation == "qam_256") -+ ok = TunerSet("channel", QString("qam256:%1").arg(frequency)); - -- if (hdhomerun_device_set_tuner_channel(_hdhomerun_device, chan) > 0) -- { -+ if (ok) - SetSIStandard(si_std); -- return true; -- } - -- return false; -+ return ok; - } - - bool HDHRChannel::AddPID(uint pid, bool do_update) -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhrchannel.h src/mythtv-0.21/libs/libmythtv/hdhrchannel.h ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhrchannel.h 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhrchannel.h 2009-01-09 13:14:58.000000000 +1030 -@@ -39,7 +39,7 @@ - bool SetChannelByString(const QString &chan); - - // Gets -- bool IsOpen(void) const { return (_hdhomerun_device != NULL); } -+ bool IsOpen(void) const { return (_control_socket != NULL); } - QString GetDevice(void) const - { return QString("%1/%2").arg(_device_id, 8, 16).arg(_tuner); } - vector<uint> GetPIDs(void) const -@@ -57,13 +57,11 @@ - bool Tune(const DTVMultiplex &tuning, QString inputname); - - private: -+ bool FindDevice(void); - bool Connect(void); - bool Tune(uint frequency, QString inputname, - QString modulation, QString si_std); - -- -- struct hdhomerun_device_t *GetHDHRDevice(void); -- - bool DeviceSetTarget(unsigned short localPort); - bool DeviceClearTarget(void); - -@@ -76,7 +74,7 @@ - bool report_error_return = true); - - private: -- struct hdhomerun_device_t *_hdhomerun_device; -+ hdhr_socket_t *_control_socket; - uint _device_id; - uint _device_ip; - uint _tuner; -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhrrecorder.cpp src/mythtv-0.21/libs/libmythtv/hdhrrecorder.cpp ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhrrecorder.cpp 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhrrecorder.cpp 2009-01-22 18:52:43.000000000 +1030 -@@ -1,6 +1,6 @@ - /** -*- Mode: c++ -*- - * HDHRRecorder -- * Copyright (c) 2006-2009 by Silicondust Engineering Ltd, and -+ * Copyright (c) 2006 by Silicondust Engineering Ltd, and - * Daniel Thor Kristjansson - * Distributed as part of MythTV under GPL v2 and later. - */ -@@ -27,7 +27,6 @@ - #include "hdhrrecorder.h" - #include "atsctables.h" - #include "atscstreamdata.h" --#include "dvbstreamdata.h" - #include "eithelper.h" - #include "tv_rec.h" - -@@ -110,7 +109,7 @@ - buffersize = max(49 * TSPacket::SIZE * 128, buffersize); - - /* Create TS socket. */ -- _video_socket = hdhomerun_video_create(0, buffersize, NULL); -+ _video_socket = hdhomerun_video_create(0, buffersize); - if (!_video_socket) - { - VERBOSE(VB_IMPORTANT, LOC + "Open() failed to open socket"); -@@ -177,13 +176,10 @@ - data->AddMPEGListener(this); - - ATSCStreamData *atsc = dynamic_cast<ATSCStreamData*>(data); -- DVBStreamData *dvb = dynamic_cast<DVBStreamData*>(data); - - if (atsc && atsc->DesiredMinorChannel()) - atsc->SetDesiredChannel(atsc->DesiredMajorChannel(), - atsc->DesiredMinorChannel()); -- else if (dvb) -- dvb->AddDVBMainListener(this); - else if (data->DesiredProgram() >= 0) - data->SetDesiredProgram(data->DesiredProgram()); - } -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhrsignalmonitor.cpp src/mythtv-0.21/libs/libmythtv/hdhrsignalmonitor.cpp ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/hdhrsignalmonitor.cpp 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/hdhrsignalmonitor.cpp 2009-01-09 13:14:58.000000000 +1030 -@@ -139,17 +139,19 @@ - { - dtvMonitorRunning = true; - -- HDHRChannel *hdrc = dynamic_cast<HDHRChannel*>(channel); -- struct hdhomerun_device_t *_hdhomerun_device = hdrc->GetHDHRDevice(); -- -- if (!_hdhomerun_device) -+ struct hdhomerun_video_sock_t *_video_socket; -+ _video_socket = hdhomerun_video_create(0, VIDEO_DATA_BUFFER_SIZE_1S); -+ if (!_video_socket) - { -- VERBOSE(VB_IMPORTANT, "Failed to get HDHomeRun device handle"); -+ VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to get video socket"); - return; - } - -- if (!hdhomerun_device_stream_start(_hdhomerun_device)) -+ HDHRChannel *hdrc = dynamic_cast<HDHRChannel*>(channel); -+ uint localPort = hdhomerun_video_get_local_port(_video_socket); -+ if (!hdrc->DeviceSetTarget(localPort)) - { -+ hdhomerun_video_destroy(_video_socket); - VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to set target"); - return; - } -@@ -164,7 +166,7 @@ - - size_t data_length; - unsigned char *data_buffer = -- hdhomerun_device_stream_recv(_hdhomerun_device, -+ hdhomerun_video_recv(_video_socket, - VIDEO_DATA_BUFFER_SIZE_1S / 5, - &data_length); - -@@ -177,7 +179,8 @@ - usleep(2500); - } - -- hdhomerun_device_stream_stop(_hdhomerun_device); -+ hdrc->DeviceClearTarget(); -+ hdhomerun_video_destroy(_video_socket); - - VERBOSE(VB_CHANNEL, LOC + "RunTableMonitor(): -- shutdown"); - -@@ -212,15 +215,16 @@ - return; - } - -- HDHRChannel *hdrc = dynamic_cast<HDHRChannel*>(channel); -- struct hdhomerun_device_t *_hdhomerun_device = hdrc->GetHDHRDevice(); -- struct hdhomerun_tuner_status_t status; -- hdhomerun_device_get_tuner_status(_hdhomerun_device, NULL, &status); -- -- uint sig = status.signal_strength; -- uint snq = status.signal_to_noise_quality; -- uint seq = status.symbol_error_quality; -- -+ QString msg = ((HDHRChannel*)channel)->TunerGet("status"); -+ //ss = signal strength, [0,100] -+ //snq = signal to noise quality [0,100] -+ //seq = signal error quality [0,100] -+ int loc_sig = msg.find("ss="), loc_snq = msg.find("snq="); -+ int loc_seq = msg.find("seq="), loc_end = msg.length(); -+ bool ok0, ok1, ok2; -+ uint sig = msg.mid(loc_sig + 3, loc_snq - loc_sig - 4).toUInt(&ok0); -+ uint snq = msg.mid(loc_snq + 4, loc_seq - loc_snq - 5).toUInt(&ok1); -+ uint seq = msg.mid(loc_seq + 4, loc_end - loc_seq - 4).toUInt(&ok2); - (void) snq; // TODO should convert to S/N - (void) seq; // TODO should report this... - -@@ -232,8 +236,9 @@ - bool isLocked = false; - { - QMutexLocker locker(&statusLock); -- signalStrength.SetValue(sig); -- signalLock.SetValue(status.lock_supported); -+ if (loc_sig > 0 && loc_snq > 0 && ok0) -+ signalStrength.SetValue(sig); -+ signalLock.SetValue(signalStrength.IsGood() ? 1 : 0); - isLocked = signalLock.IsGood(); - } - -diff -aur branches/release-0-21-fixes/mythtv/libs/libmythtv/libmythtv.pro src/mythtv-0.21/libs/libmythtv/libmythtv.pro ---- branches/release-0-21-fixes/mythtv/libs/libmythtv/libmythtv.pro 2009-07-13 15:44:12.000000000 +0930 -+++ src/mythtv-0.21/libs/libmythtv/libmythtv.pro 2009-01-09 13:14:58.000000000 +1030 -@@ -459,28 +459,12 @@ - DEFINES += USING_HDHOMERUN - - # HDHomeRun library -- HEADERS += hdhomerun/hdhomerun.h -+ HEADERS += hdhomerun/hdhomerun_pkt.h hdhomerun/hdhomerun_discover.h -+ HEADERS += hdhomerun/hdhomerun_video.h hdhomerun/hdhomerun_control.h - HEADERS += hdhomerun/hdhomerun_os.h -- HEADERS += hdhomerun/hdhomerun_os_posix.h -- HEADERS += hdhomerun/hdhomerun_os_windows.h -- HEADERS += hdhomerun/hdhomerun_channelscan.h -- HEADERS += hdhomerun/hdhomerun_channels.h -- HEADERS += hdhomerun/hdhomerun_control.h -- HEADERS += hdhomerun/hdhomerun_debug.h -- HEADERS += hdhomerun/hdhomerun_pkt.h -- HEADERS += hdhomerun/hdhomerun_device.h -- HEADERS += hdhomerun/hdhomerun_types.h -- HEADERS += hdhomerun/hdhomerun_discover.h -- HEADERS += hdhomerun/hdhomerun_video.h -- -- SOURCES += hdhomerun/hdhomerun_pkt.c -- SOURCES += hdhomerun/hdhomerun_debug.c -- SOURCES += hdhomerun/hdhomerun_discover.c -- SOURCES += hdhomerun/hdhomerun_channels.c -- SOURCES += hdhomerun/hdhomerun_channelscan.c -- SOURCES += hdhomerun/hdhomerun_control.c -- SOURCES += hdhomerun/hdhomerun_video.c -- SOURCES += hdhomerun/hdhomerun_device.c -+ -+ SOURCES += hdhomerun/hdhomerun_pkt.c hdhomerun/hdhomerun_discover.c -+ SOURCES += hdhomerun/hdhomerun_video.c hdhomerun/hdhomerun_control.c - } - - # Support for PVR-150/250/350/500, etc. on Linux |