Silicondust / libhdhomerun

Silicondust library and cli utility for controlling HDHomeRun tuners
GNU Lesser General Public License v2.1
102 stars 43 forks source link

libhdhomerun versioning #4

Closed garybuhrmaster closed 4 years ago

garybuhrmaster commented 8 years ago

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);
garybuhrmaster commented 4 years ago

I believe at this point time (and the code) has moved on sufficiently that this issue is appropriately closed as "wontfix"