Giter Club home page Giter Club logo

libhdhomerun's Introduction

Copyright © 2005-2023 Silicondust USA Inc. <www.silicondust.com>.

This library implements the libhdhomerun protocol for use with Silicondust HDHomeRun TV tuners.

To compile simply "make" - this will compile both the library and the hdhomerun_config command line utility suitable for sending commands or scripting control of a HDHomeRun.

The top level API is hdhomerun_device - see hdhomerun_device.h for documentation.

Additional libraries required:

  • pthread (osx, linux, bsd)
  • iphlpapi (windows)

libhdhomerun's People

Contributors

nickkelsey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libhdhomerun's Issues

IP address selection misbehaviour

I usually tunnel all packets (even thus destined to the local subnet) via a separate gateway. This is done so all packets leaving this device get encrypted. The only packets that leave this device without being routed through this gateway are those packets that get the tunnel to the gateway working.

With this setup the library will insist on using the IP address of the untunneld interface. But packets get routed through the tunnel interface (like intended and according to the routing table and routing policies i have set up) but they will be silently dropped because the address is not allowed as source on this interface. If the interface through which i connect to the gateway is not on the same subnet as the device i want to connect to it just works like it should.

I don't know why this is the case but i suggest not trying to be too smart about the IP address selection and let the TCP/IP stack do its job of selecting an appropriate IP address while considering the local routing table and routing policies. If you really need to be explicit about the IP address selection it would be nice to consider the routing table or at least let users override the otherwise automatically selected IP address.

If there might be a reason this doesn't work as intended with regards to my setup i would be happy to get any hint on how to fix this. For now i setup a IP masquerading rule via iptables to rewrite the IP address to that of the outgoing interface but i would rather like to not do that.

libhdhomerun versioning

Request for enhanced libhdhomerun versioning

I understand if this will be closed without implementation, but I figured I would ask.

WIth the incompatible changes to the hdhomerun_discover_device_t struct and the new (v2) discover functions, there can be a challenge with shared library versioning on some platforms, and I will note that the make file does not create a versioned library, just a libhdhomerun.so file (and this can lead to the equivalent of "dll hell") if one has both newer and older programs trying to use a shared library. And while there are ways to address these issues, I would like to request that you re-consider providing in the libraries themselves the (now legacy) functions that an old program can continue to access to receive the old discover results, and rename the new structure to something like hdhomerun_discover_device_v2_t for the new functions (yes, this adds work for your existing new internal codes for a one time structure name change). And, for compilers that support such capability, add in the appropriate deprecated attribute on the (now legacy) old functions such that any use will get a warning (to upgrade). The old functions can be provided via the new functions. The intent is to provide some backwards compatibility for a limited period when using a shared (as opposed to internal static) library.

(mostly) untested source diff follows (it compiled on linux!).

Thank you for your consideration

diff -ru libhdhomerun-master/hdhomerun_config.c libhdhomerun-master.new/hdhomerun_config.c
--- libhdhomerun-master/hdhomerun_config.c  2016-02-09 00:48:59.000000000 +0000
+++ libhdhomerun-master.new/hdhomerun_config.c  2016-04-30 17:03:26.763075046 +0000
@@ -90,7 +90,7 @@
        }
    }

-   struct hdhomerun_discover_device_t result_list[64];
+   struct hdhomerun_discover_device_v2_t result_list[64];
    int count = hdhomerun_discover_find_devices_custom_v2(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, 64);
    if (count < 0) {
        fprintf(stderr, "error sending discover request\n");
@@ -103,7 +103,7 @@

    int index;
    for (index = 0; index < count; index++) {
-       struct hdhomerun_discover_device_t *result = &result_list[index];
+       struct hdhomerun_discover_device_v2_t *result = &result_list[index];
        printf("hdhomerun device %08X found at %u.%u.%u.%u\n",
            (unsigned int)result->device_id,
            (unsigned int)(result->ip_addr >> 24) & 0x0FF, (unsigned int)(result->ip_addr >> 16) & 0x0FF,
diff -ru libhdhomerun-master/hdhomerun_control.c libhdhomerun-master.new/hdhomerun_control.c
--- libhdhomerun-master/hdhomerun_control.c 2016-02-09 00:48:59.000000000 +0000
+++ libhdhomerun-master.new/hdhomerun_control.c 2016-04-30 17:03:05.708079467 +0000
@@ -92,7 +92,7 @@
    }

    /* Find device. */
-   struct hdhomerun_discover_device_t result;
+   struct hdhomerun_discover_device_v2_t result;
    if (hdhomerun_discover_find_devices_custom_v2(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;
diff -ru libhdhomerun-master/hdhomerun_device_selector.c libhdhomerun-master.new/hdhomerun_device_selector.c
--- libhdhomerun-master/hdhomerun_device_selector.c 2016-02-09 00:48:59.000000000 +0000
+++ libhdhomerun-master.new/hdhomerun_device_selector.c 2016-04-30 17:00:06.789132691 +0000
@@ -124,12 +124,12 @@

 static int hdhomerun_device_selector_load_from_str_discover(struct hdhomerun_device_selector_t *hds, uint32_t target_ip, uint32_t device_id)
 {
-   struct hdhomerun_discover_device_t result_list[64];
+   struct hdhomerun_discover_device_v2_t result_list[64];
    int discover_count = hdhomerun_discover_find_devices_custom_v2(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, device_id, result_list, 64);

    int count = 0;
    int result_index;
-   struct hdhomerun_discover_device_t *result = result_list;
+   struct hdhomerun_discover_device_v2_t *result = result_list;
    for (result_index = 0; result_index < discover_count; result_index++) {
        unsigned int tuner_index;
        for (tuner_index = 0; tuner_index < result->tuner_count; tuner_index++) {
diff -ru libhdhomerun-master/hdhomerun_discover.c libhdhomerun-master.new/hdhomerun_discover.c
--- libhdhomerun-master/hdhomerun_discover.c    2016-02-09 00:48:59.000000000 +0000
+++ libhdhomerun-master.new/hdhomerun_discover.c    2016-04-30 17:32:21.959254988 +0000
@@ -254,7 +254,7 @@
    }
 }

-static bool_t hdhomerun_discover_recv_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, struct hdhomerun_discover_device_t *result)
+static bool_t hdhomerun_discover_recv_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, struct hdhomerun_discover_device_v2_t *result)
 {
    static char hdhomerun_discover_recv_base64_encode_table[64 + 1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    struct hdhomerun_pkt_t *rx_pkt = &ds->rx_pkt;
@@ -277,7 +277,7 @@
        return FALSE;
    }

-   memset(result, 0, sizeof(struct hdhomerun_discover_device_t));
+   memset(result, 0, sizeof(struct hdhomerun_discover_device_v2_t));
    result->ip_addr = remote_addr;

    hdhomerun_sprintf(result->base_url, result->base_url + sizeof(result->base_url), "http://%u.%u.%u.%u:80",
@@ -377,7 +377,7 @@
    return TRUE;
 }

-static bool_t hdhomerun_discover_recv(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_device_t *result)
+static bool_t hdhomerun_discover_recv(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_device_v2_t *result)
 {
    unsigned int i;
    for (i = 0; i < ds->sock_count; i++) {
@@ -391,12 +391,12 @@
    return FALSE;
 }

-static struct hdhomerun_discover_device_t *hdhomerun_discover_find_in_list(struct hdhomerun_discover_device_t result_list[], int count, struct hdhomerun_discover_device_t *lookup)
+static struct hdhomerun_discover_device_v2_t *hdhomerun_discover_find_in_list(struct hdhomerun_discover_device_v2_t result_list[], int count, struct hdhomerun_discover_device_v2_t *lookup)
 {
    int index;
    for (index = 0; index < count; index++) {
-       struct hdhomerun_discover_device_t *entry = &result_list[index];
-       if (memcmp(lookup, entry, sizeof(struct hdhomerun_discover_device_t)) == 0) {
+       struct hdhomerun_discover_device_v2_t *entry = &result_list[index];
+       if (memcmp(lookup, entry, sizeof(struct hdhomerun_discover_device_v2_t)) == 0) {
            return entry;
        }
    }
@@ -404,7 +404,26 @@
    return NULL;
 }

-int hdhomerun_discover_find_devices_v2(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)
+int hdhomerun_discover_find_devices(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t legacy_result_list[], int max_count)
+{
+    struct hdhomerun_discover_device_v2_t *result_list = (struct hdhomerun_discover_device_v2_t *)calloc(max_count, sizeof(struct hdhomerun_discover_device_v2_t));
+    if (!result_list) {
+        return -1;
+    }
+    int count = hdhomerun_discover_find_devices_v2(ds, target_ip, device_type, device_id, result_list, max_count);
+    for (int i = 0; i < count; i++) {
+        legacy_result_list[i].ip_addr     = result_list[i].ip_addr;
+        legacy_result_list[i].device_type = result_list[i].device_type;
+        legacy_result_list[i].device_id   = result_list[i].device_id;
+        legacy_result_list[i].tuner_count = result_list[i].tuner_count;
+    }
+    
+    free(result_list);
+
+    return(count);
+}
+
+int hdhomerun_discover_find_devices_v2(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_v2_t result_list[], int max_count)
 {
    hdhomerun_discover_sock_detect(ds);

@@ -417,8 +436,8 @@

        uint64_t timeout = getcurrenttime() + 200;
        while (1) {
-           struct hdhomerun_discover_device_t *result = &result_list[count];
-           memset(result, 0, sizeof(struct hdhomerun_discover_device_t));
+           struct hdhomerun_discover_device_v2_t *result = &result_list[count];
+           memset(result, 0, sizeof(struct hdhomerun_discover_device_v2_t));

            if (!hdhomerun_discover_recv(ds, result)) {
                if (getcurrenttime() >= timeout) {
@@ -456,7 +475,26 @@
    return count;
 }

-int hdhomerun_discover_find_devices_custom_v2(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_devices_custom(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t legacy_result_list[], int max_count)
+{
+    struct hdhomerun_discover_device_v2_t *result_list = (struct hdhomerun_discover_device_v2_t *)calloc(max_count, sizeof(struct hdhomerun_discover_device_v2_t));
+    if (!result_list) {
+        return -1;
+    }
+    int count = hdhomerun_discover_find_devices_custom_v2(target_ip, device_type, device_id, result_list, max_count);
+    for (int i = 0; i < count; i++) {
+        legacy_result_list[i].ip_addr     = result_list[i].ip_addr;
+        legacy_result_list[i].device_type = result_list[i].device_type;
+        legacy_result_list[i].device_id   = result_list[i].device_id;
+        legacy_result_list[i].tuner_count = result_list[i].tuner_count;
+    }
+
+    free(result_list);
+
+    return(count);
+}
+
+int hdhomerun_discover_find_devices_custom_v2(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_v2_t result_list[], int max_count)
 {
    if (hdhomerun_discover_is_ip_multicast(target_ip)) {
        return 0;
diff -ru libhdhomerun-master/hdhomerun_discover.h libhdhomerun-master.new/hdhomerun_discover.h
--- libhdhomerun-master/hdhomerun_discover.h    2016-02-09 00:48:59.000000000 +0000
+++ libhdhomerun-master.new/hdhomerun_discover.h    2016-04-30 18:22:17.943405747 +0000
@@ -21,7 +21,7 @@
 extern "C" {
 #endif

-struct hdhomerun_discover_device_t {
+struct hdhomerun_discover_device_v2_t {
    uint32_t ip_addr;
    uint32_t device_type;
    uint32_t device_id;
@@ -34,7 +34,7 @@
 /*
  * Find devices.
  *
- * The device information is stored in caller-supplied array of hdhomerun_discover_device_t vars.
+ * The device information is stored in caller-supplied array of hdhomerun_discover_device_v2_t vars.
  * Multiple attempts are made to find devices.
  * Execution time is typically 400ms if max_count is not reached.
  *
@@ -45,14 +45,14 @@
  * Returns the number of devices found.
  * Retruns -1 on error.
  */
-extern LIBHDHOMERUN_API int hdhomerun_discover_find_devices_custom_v2(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count);
+extern LIBHDHOMERUN_API int hdhomerun_discover_find_devices_custom_v2(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_v2_t result_list[], int max_count);

 /*
  * Optional: persistent discover instance available for discover polling use.
  */
 extern LIBHDHOMERUN_API struct hdhomerun_discover_t *hdhomerun_discover_create(struct hdhomerun_debug_t *dbg);
 extern LIBHDHOMERUN_API void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds);
-extern LIBHDHOMERUN_API int hdhomerun_discover_find_devices_v2(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);
+extern LIBHDHOMERUN_API int hdhomerun_discover_find_devices_v2(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_v2_t result_list[], int max_count);

 /*
  * Verify that the device ID given is valid.
@@ -73,6 +73,20 @@
  */
 extern LIBHDHOMERUN_API bool_t hdhomerun_discover_is_ip_multicast(uint32_t ip_addr);

+/*
+ * Legacy APIs - Convert new code to the v2 versions
+ */
+
+struct hdhomerun_discover_device_t {
+    uint32_t ip_addr;
+    uint32_t device_type;
+    uint32_t device_id;
+    uint8_t tuner_count;
+};
+
+LIBHDHOMERUN_DEPRECATED extern LIBHDHOMERUN_API int hdhomerun_discover_find_devices_custom(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t legacy_result_list[], int max_count);
+LIBHDHOMERUN_DEPRECATED extern LIBHDHOMERUN_API int hdhomerun_discover_find_devices(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t legacy_result_list[], int max_count);
+
 #ifdef __cplusplus
 }
 #endif
diff -ru libhdhomerun-master/hdhomerun_os_posix.h libhdhomerun-master.new/hdhomerun_os_posix.h
--- libhdhomerun-master/hdhomerun_os_posix.h    2016-02-09 00:48:59.000000000 +0000
+++ libhdhomerun-master.new/hdhomerun_os_posix.h    2016-04-30 17:07:56.041043835 +0000
@@ -47,6 +47,7 @@
 } thread_cond_t;

 #define LIBHDHOMERUN_API
+#define LIBHDHOMERUN_DEPRECATED __attribute__((deprecated))
 #define THREAD_FUNC_PREFIX void *
 #define THREAD_FUNC_RESULT NULL

diff -ru libhdhomerun-master/hdhomerun_os_windows.h libhdhomerun-master.new/hdhomerun_os_windows.h
--- libhdhomerun-master/hdhomerun_os_windows.h  2016-02-09 00:48:59.000000000 +0000
+++ libhdhomerun-master.new/hdhomerun_os_windows.h  2016-04-30 16:48:23.290178770 +0000
@@ -55,6 +55,7 @@
 #ifndef LIBHDHOMERUN_API
 #define LIBHDHOMERUN_API
 #endif
+#define LIBHDHOMERUN_DEPRECATED __declspec(deprecated)

 typedef uint8_t bool_t;
 typedef void (*sig_t)(int);

Android build

Please add instructions or .sh script how to build the lidhdhomerun.so binary for the Android platform (armeabi-v7a and arm64-v8a) Thank you!

Discover packet reply from tuner includes tag 0x27

It would appear that there is a tag (0x27) returned as part of the discover packet that appears to be the LineupURL. Is this a sanctioned tag that is intended to be continued, or is it destined to be removed in preference to using the BaseURL tag?

Even if deprecated, should hdhomerun_pkt.h include the definition something like the form:

#define HDHOMERUN_TAG_LINEUP_URL 0x27

Copyright 2006-206 should be 2006-2016 in file hdhomerun_config.c?

Looks like a typo in the copyright year in file hdhomerun_config.c. Proposed patch follows...

diff --git a/hdhomerun_config.c b/hdhomerun_config.c
index 8fb37e1..e398f47 100644
--- a/hdhomerun_config.c
+++ b/hdhomerun_config.c
@@ -1,7 +1,7 @@
 /*
  * hdhomerun_config.c
  *
- * Copyright © 2006-206 Silicondust USA Inc. <www.silicondust.com>.
+ * Copyright © 2006-2016 Silicondust USA Inc. <www.silicondust.com>.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public

Communication error

All my devices on firesticks are working except my firecube with the hd homerun device it keeps saying communication error

gcc compiler warning with cross compile for windows

When attempting to cross compile libhdhomerun for windows, I received the following warning:

hdhomerun_sock_windows.c:338:6: warning: no previous prototype for 'hdhomerun_sock_event_select' [-Wmissing-prototypes]
bool hdhomerun_sock_event_select(struct hdhomerun_sock_t *sock, long events)

Proposed patch (the function appears local to this source file, so just make it static)

diff --git a/hdhomerun_sock_windows.c b/hdhomerun_sock_windows.c
index 810c0bc..ea5d232 100644
--- a/hdhomerun_sock_windows.c
+++ b/hdhomerun_sock_windows.c
@@ -335,7 +335,7 @@ bool hdhomerun_sock_bind(struct hdhomerun_sock_t *sock, uint32_t local_addr, uin
        return true;
 }
 
-bool hdhomerun_sock_event_select(struct hdhomerun_sock_t *sock, long events)
+static bool hdhomerun_sock_event_select(struct hdhomerun_sock_t *sock, long events)
 {
        if (sock->events_selected != events) {
                if (WSAEventSelect(sock->sock, sock->event, events) == SOCKET_ERROR) {

Inconsistent versioning between github and silicondust download for "latest".

On the SiliconDust website, the latest linux download is tagged with the date 20190621, but the last commit on github indicates the latest release is 20190625. There are some source differences (for FreeBSD broadcast handling) on the github repo. Should the distribution on the SD website be updated? And for that matter, there is no release commit on github for 20190621 (and, as others have stated, no release tags that could make automated rebuilds a bit easier).

Unable to use hdhomerun_config on releases after 2022-03-02

Using the 2022-03-02 release I am able to use the hdhomerun_config util without problems

$ hdhomerun_config discover
hdhomerun device 1052XXXX found at 192.168.1.32
hdhomerun device 1052XXXX found at 192.168.1.31

On any newer release I end up with the following errors, even though the build was successful

$ hdhomerun_config discover
Illegal instruction (core dumped)

Build environment:

github actions ubuntu22/20230129.2/images/linux/Ubuntu2204

My build repo is here

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.