From bc207f273cee362d20696c6245b54942ece1619d Mon Sep 17 00:00:00 2001 From: nickkelsey Date: Fri, 28 Apr 2023 10:50:23 -0700 Subject: [PATCH 1/3] 20230428 --- README.md | 2 +- hdhomerun_discover.c | 2 +- hdhomerun_os_posix.c | 44 ++++++++++++++++++++++++++++-------------- hdhomerun_os_posix.h | 3 +++ hdhomerun_os_windows.c | 27 ++++++++++++++++++++++++-- hdhomerun_os_windows.h | 3 +++ 6 files changed, 63 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 1f3a6dd..8b83d53 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Copyright © 2005-2022 Silicondust USA Inc. . +Copyright © 2005-2023 Silicondust USA Inc. . This library implements the libhdhomerun protocol for use with Silicondust HDHomeRun TV tuners. diff --git a/hdhomerun_discover.c b/hdhomerun_discover.c index 6a375d6..8dae716 100644 --- a/hdhomerun_discover.c +++ b/hdhomerun_discover.c @@ -863,7 +863,7 @@ static void hdhomerun_discover_recv_internal_auth_bin(char **poutput, struct hdh int i; for (i = 0; i < 24; i += 4) { - static char hdhomerun_discover_recv_base64_encode_table[64 + 1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + static const char hdhomerun_discover_recv_base64_encode_table[64 + 1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; uint32_t raw24; raw24 = (uint32_t)hdhomerun_pkt_read_u8(rx_pkt) << 16; diff --git a/hdhomerun_os_posix.c b/hdhomerun_os_posix.c index 3191edf..90b38a0 100644 --- a/hdhomerun_os_posix.c +++ b/hdhomerun_os_posix.c @@ -65,27 +65,31 @@ static inline void clock_realtime_timespec(struct timespec *ts) #endif -static pthread_once_t random_get32_once = PTHREAD_ONCE_INIT; -static FILE *random_get32_fp = NULL; +static pthread_once_t random_getbytes_once = PTHREAD_ONCE_INIT; +static FILE *random_getbytes_fp = NULL; -static void random_get32_init(void) +static void random_getbytes_init(void) { - random_get32_fp = fopen("/dev/urandom", "rb"); + random_getbytes_fp = fopen("/dev/urandom", "rb"); +} + +void random_getbytes(uint8_t *out, size_t length) +{ + pthread_once(&random_getbytes_once, random_getbytes_init); + + if (!random_getbytes_fp) { + exit(1); + } + + if (fread(out, 1, length, random_getbytes_fp) != length) { + exit(1); + } } uint32_t random_get32(void) { - pthread_once(&random_get32_once, random_get32_init); - - if (!random_get32_fp) { - return (uint32_t)getcurrenttime(); - } - uint32_t Result; - if (fread(&Result, 4, 1, random_get32_fp) != 1) { - return (uint32_t)getcurrenttime(); - } - + random_getbytes((uint8_t *)&Result, 4); return Result; } @@ -96,6 +100,18 @@ uint64_t getcurrenttime(void) return ((uint64_t)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); } +uint64_t timer_get_hires_ticks(void) +{ + struct timespec ts; + clock_monotonic_timespec(&ts); + return ((uint64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); +} + +uint64_t timer_get_hires_frequency(void) +{ + return 1000000; +} + void msleep_approx(uint64_t ms) { uint64_t delay_s = ms / 1000; diff --git a/hdhomerun_os_posix.h b/hdhomerun_os_posix.h index 8643b64..319efec 100644 --- a/hdhomerun_os_posix.h +++ b/hdhomerun_os_posix.h @@ -63,8 +63,11 @@ typedef struct { extern "C" { #endif +extern LIBHDHOMERUN_API void random_getbytes(uint8_t *out, size_t length); extern LIBHDHOMERUN_API uint32_t random_get32(void); extern LIBHDHOMERUN_API uint64_t getcurrenttime(void); +extern LIBHDHOMERUN_API uint64_t timer_get_hires_ticks(void); +extern LIBHDHOMERUN_API uint64_t timer_get_hires_frequency(void); extern LIBHDHOMERUN_API void msleep_approx(uint64_t ms); extern LIBHDHOMERUN_API void msleep_minimum(uint64_t ms); diff --git a/hdhomerun_os_windows.c b/hdhomerun_os_windows.c index 42fc741..70d814c 100644 --- a/hdhomerun_os_windows.c +++ b/hdhomerun_os_windows.c @@ -20,10 +20,15 @@ #include "hdhomerun.h" +void random_getbytes(uint8_t *out, size_t length) +{ + BCryptGenRandom(NULL, out, (ULONG)length, BCRYPT_USE_SYSTEM_PREFERRED_RNG); +} + uint32_t random_get32(void) { - uint32_t Result = 0; - BCryptGenRandom(NULL, (uint8_t *)&Result, 4, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + uint32_t Result; + random_getbytes((uint8_t *)&Result, 4); return Result; } @@ -32,6 +37,24 @@ uint64_t getcurrenttime(void) return GetTickCount64(); } +uint64_t timer_get_hires_ticks(void) +{ + LARGE_INTEGER count; + if (!QueryPerformanceCounter(&count)) { + return 0; + } + return count.QuadPart; +} + +uint64_t timer_get_hires_frequency(void) +{ + LARGE_INTEGER count; + if (!QueryPerformanceFrequency(&count)) { + return 0; + } + return count.QuadPart; +} + void msleep_approx(uint64_t ms) { Sleep((DWORD)ms); diff --git a/hdhomerun_os_windows.h b/hdhomerun_os_windows.h index fecc60f..d1fab53 100644 --- a/hdhomerun_os_windows.h +++ b/hdhomerun_os_windows.h @@ -87,8 +87,11 @@ typedef HANDLE thread_cond_t; extern "C" { #endif +extern LIBHDHOMERUN_API void random_getbytes(uint8_t *out, size_t length); extern LIBHDHOMERUN_API uint32_t random_get32(void); extern LIBHDHOMERUN_API uint64_t getcurrenttime(void); +extern LIBHDHOMERUN_API uint64_t timer_get_hires_ticks(void); +extern LIBHDHOMERUN_API uint64_t timer_get_hires_frequency(void); extern LIBHDHOMERUN_API void msleep_approx(uint64_t ms); extern LIBHDHOMERUN_API void msleep_minimum(uint64_t ms); From b3153544aa5ff74f727b8bdd30fa7d3228db1261 Mon Sep 17 00:00:00 2001 From: nickkelsey Date: Fri, 20 Oct 2023 10:58:09 -0700 Subject: [PATCH 2/3] 20231020 --- hdhomerun_sock_windows.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hdhomerun_sock_windows.c b/hdhomerun_sock_windows.c index 41c0719..f7d72ab 100644 --- a/hdhomerun_sock_windows.c +++ b/hdhomerun_sock_windows.c @@ -27,6 +27,7 @@ struct hdhomerun_sock_t { long events_selected; int af; uint8_t ttl_set; + bool shutdown; }; bool hdhomerun_local_ip_info2(int af, hdhomerun_local_ip_info2_callback_t callback, void *callback_arg) @@ -181,7 +182,9 @@ void hdhomerun_sock_destroy(struct hdhomerun_sock_t *sock) void hdhomerun_sock_stop(struct hdhomerun_sock_t *sock) { + sock->shutdown = true; shutdown(sock->sock, SD_BOTH); + SetEvent(sock->event); } void hdhomerun_sock_set_send_buffer_size(struct hdhomerun_sock_t *sock, size_t size) @@ -373,6 +376,11 @@ static bool hdhomerun_sock_event_select(struct hdhomerun_sock_t *sock, long even } ResetEvent(sock->event); + + if (sock->shutdown) { + return false; + } + return true; } From e8f29fd4e071580ffb583cbeb9cf720c96a4e75f Mon Sep 17 00:00:00 2001 From: nickkelsey Date: Thu, 9 Nov 2023 10:32:29 -0700 Subject: [PATCH 3/3] 20231109 --- Makefile | 5 ++ hdhomerun_discover_example.c | 106 +++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 hdhomerun_discover_example.c diff --git a/Makefile b/Makefile index c22bc98..1d8fb9f 100644 --- a/Makefile +++ b/Makefile @@ -80,9 +80,14 @@ libhdhomerun$(LIBEXT) : $(LIBSRCS) endif +hdhomerun_discover_example$(BINEXT): hdhomerun_discover_example.c $(LIBSRCS) + $(CC) $(CFLAGS) $+ $(LDFLAGS) -o $@ + $(STRIP) $@ + clean : -rm -f hdhomerun_config$(BINEXT) -rm -f libhdhomerun$(LIBEXT) + -rm -f hdhomerun_discover_example$(BINEXT) distclean : clean diff --git a/hdhomerun_discover_example.c b/hdhomerun_discover_example.c new file mode 100644 index 0000000..0d0824b --- /dev/null +++ b/hdhomerun_discover_example.c @@ -0,0 +1,106 @@ +/* + * hdhomerun_discover_example.c + * + * Copyright © 2023 Silicondust USA Inc. . + * + * 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 + */ + +#include "hdhomerun.h" + +int main(int argc, char *argv[]) +{ +#if defined(_WIN32) + WORD wVersionRequested = MAKEWORD(2, 0); + WSADATA wsaData; + (void)WSAStartup(wVersionRequested, &wsaData); +#endif + + /* + * Create discover object + */ + struct hdhomerun_discover_t *ds = hdhomerun_discover_create(NULL); + if (!ds) { + fprintf(stderr, "hdhomerun_discover_create failed\n"); + return 1; + } + + /* + * Execute discover + * + * Remove HDHOMERUN_DISCOVER_FLAGS_IPV4_LOCALHOST and HDHOMERUN_DISCOVER_FLAGS_IPV6_LOCALHOST if the app platform cannot have the record engine installed. + * Remove HDHOMERUN_DISCOVER_FLAGS_IPV6_LINKLOCAL if the app does not support ipv6 scope_id required for all link-local network operations. + */ + uint32_t flags = HDHOMERUN_DISCOVER_FLAGS_IPV4_GENERAL | HDHOMERUN_DISCOVER_FLAGS_IPV4_LOCALHOST | HDHOMERUN_DISCOVER_FLAGS_IPV6_GENERAL | HDHOMERUN_DISCOVER_FLAGS_IPV6_LINKLOCAL | HDHOMERUN_DISCOVER_FLAGS_IPV6_LOCALHOST; + + uint32_t device_types[2]; + device_types[0] = HDHOMERUN_DEVICE_TYPE_TUNER; + device_types[1] = HDHOMERUN_DEVICE_TYPE_STORAGE; + + if (hdhomerun_discover2_find_devices_broadcast(ds, flags, device_types, 2) < 0) { + fprintf(stderr, "hdhomerun_discover2_find_devices_broadcast failed\n"); + return 1; + } + + /* + * Print results + */ + struct hdhomerun_discover2_device_t *device = hdhomerun_discover2_iter_device_first(ds); + while (device) { + uint32_t device_id = hdhomerun_discover2_device_get_device_id(device); + const char *storage_id = hdhomerun_discover2_device_get_storage_id(device); + const char *device_auth = hdhomerun_discover2_device_get_device_auth(device); + bool is_tuner = hdhomerun_discover2_device_is_type(device, HDHOMERUN_DEVICE_TYPE_TUNER); + bool is_storage = hdhomerun_discover2_device_is_type(device, HDHOMERUN_DEVICE_TYPE_STORAGE); + bool is_legacy = hdhomerun_discover2_device_is_legacy(device); + uint8_t tuner_count = hdhomerun_discover2_device_get_tuner_count(device); + + struct hdhomerun_discover2_device_if_t *device_if = hdhomerun_discover2_iter_device_if_first(device); + + struct sockaddr_storage ip_address; + hdhomerun_discover2_device_if_get_ip_addr(device_if, &ip_address); + char ip_address_str[64]; + hdhomerun_sock_sockaddr_to_ip_str(ip_address_str, (struct sockaddr *)&ip_address, true); + + const char *base_url = hdhomerun_discover2_device_if_get_base_url(device_if); + const char *lineup_url = hdhomerun_discover2_device_if_get_lineup_url(device_if); + const char *storage_url = hdhomerun_discover2_device_if_get_storage_url(device_if); + + printf("found:\n"); + + printf("\tip_address: %s\n", ip_address_str); + printf("\tbase_url: %s\n", base_url); + printf("\tlineup_url: %s\n", lineup_url); + printf("\tstorage_url: %s\n", storage_url); + + printf("\tdevice_id: %08X\n", device_id); + printf("\tstorage_id: %s\n", storage_id); + printf("\tdevice_auth: %s\n", device_auth); + printf("\tis_tuner: %u\n", is_tuner); + printf("\tis_storage: %u\n", is_storage); + printf("\tis_legacy: %u\n", is_legacy); + printf("\ttuner_count: %u\n", tuner_count); + + printf("\n"); + + device = hdhomerun_discover2_iter_device_next(device); + } + + /* + * Free discover object + */ + hdhomerun_discover_destroy(ds); + return 0; +}