libhdhomerun 20160130

This commit is contained in:
Nick Kelsey 2016-01-30 11:51:36 -08:00
parent a2475b9991
commit 8d861a8f0b
29 changed files with 916 additions and 725 deletions

View file

@ -1,28 +1,11 @@
/* Copyright © 2005-2016 Silicondust USA Inc. <www.silicondust.com>.
* README
*
* Copyright © 2005-2009 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
* 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
*/
Top level include file: hdhomerun.h This library implements the libhdhomerun protocol for use with Silicondust HDHomeRun TV tuners.
Top level API: hdhomerun_device. See hdhomerun_device.h for documentation. 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 hdhomerun_device API should be used rather than the low level control and video APIs required with previous versions. The top level API is hdhomerun_device - see hdhomerun_device.h for documentation.
Additional libraries required: Additional libraries required:
- pthread - pthread

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_channels.c * hdhomerun_channels.c
* *
* Copyright © 2007-2008 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2007-2014 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_channels.h * hdhomerun_channels.h
* *
* Copyright © 2007-2008 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2007-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -25,27 +25,27 @@ extern "C" {
struct hdhomerun_channel_entry_t; struct hdhomerun_channel_entry_t;
struct hdhomerun_channel_list_t; struct hdhomerun_channel_list_t;
extern LIBTYPE const char *hdhomerun_channelmap_get_channelmap_from_country_source(const char *countrycode, const char *source, const char *supported); extern LIBHDHOMERUN_API const char *hdhomerun_channelmap_get_channelmap_from_country_source(const char *countrycode, const char *source, const char *supported);
extern LIBTYPE const char *hdhomerun_channelmap_get_channelmap_scan_group(const char *channelmap); extern LIBHDHOMERUN_API const char *hdhomerun_channelmap_get_channelmap_scan_group(const char *channelmap);
extern LIBTYPE uint16_t hdhomerun_channel_entry_channel_number(struct hdhomerun_channel_entry_t *entry); extern LIBHDHOMERUN_API uint16_t hdhomerun_channel_entry_channel_number(struct hdhomerun_channel_entry_t *entry);
extern LIBTYPE uint32_t hdhomerun_channel_entry_frequency(struct hdhomerun_channel_entry_t *entry); extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_entry_frequency(struct hdhomerun_channel_entry_t *entry);
extern LIBTYPE const char *hdhomerun_channel_entry_name(struct hdhomerun_channel_entry_t *entry); extern LIBHDHOMERUN_API const char *hdhomerun_channel_entry_name(struct hdhomerun_channel_entry_t *entry);
extern LIBTYPE struct hdhomerun_channel_list_t *hdhomerun_channel_list_create(const char *channelmap); extern LIBHDHOMERUN_API struct hdhomerun_channel_list_t *hdhomerun_channel_list_create(const char *channelmap);
extern LIBTYPE void hdhomerun_channel_list_destroy(struct hdhomerun_channel_list_t *channel_list); extern LIBHDHOMERUN_API void hdhomerun_channel_list_destroy(struct hdhomerun_channel_list_t *channel_list);
extern LIBTYPE struct hdhomerun_channel_entry_t *hdhomerun_channel_list_first(struct hdhomerun_channel_list_t *channel_list); extern LIBHDHOMERUN_API struct hdhomerun_channel_entry_t *hdhomerun_channel_list_first(struct hdhomerun_channel_list_t *channel_list);
extern LIBTYPE struct hdhomerun_channel_entry_t *hdhomerun_channel_list_last(struct hdhomerun_channel_list_t *channel_list); extern LIBHDHOMERUN_API struct hdhomerun_channel_entry_t *hdhomerun_channel_list_last(struct hdhomerun_channel_list_t *channel_list);
extern LIBTYPE struct hdhomerun_channel_entry_t *hdhomerun_channel_list_next(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry); extern LIBHDHOMERUN_API struct hdhomerun_channel_entry_t *hdhomerun_channel_list_next(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry);
extern LIBTYPE struct hdhomerun_channel_entry_t *hdhomerun_channel_list_prev(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry); extern LIBHDHOMERUN_API struct hdhomerun_channel_entry_t *hdhomerun_channel_list_prev(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry);
extern LIBTYPE uint32_t hdhomerun_channel_list_total_count(struct hdhomerun_channel_list_t *channel_list); extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_list_total_count(struct hdhomerun_channel_list_t *channel_list);
extern LIBTYPE uint32_t hdhomerun_channel_list_frequency_count(struct hdhomerun_channel_list_t *channel_list); extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_list_frequency_count(struct hdhomerun_channel_list_t *channel_list);
extern LIBTYPE uint32_t hdhomerun_channel_frequency_round(uint32_t frequency, uint32_t resolution); extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_frequency_round(uint32_t frequency, uint32_t resolution);
extern LIBTYPE uint32_t hdhomerun_channel_frequency_round_normal(uint32_t frequency); extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_frequency_round_normal(uint32_t frequency);
extern LIBTYPE uint32_t hdhomerun_channel_number_to_frequency(struct hdhomerun_channel_list_t *channel_list, uint16_t channel_number); extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_number_to_frequency(struct hdhomerun_channel_list_t *channel_list, uint16_t channel_number);
extern LIBTYPE uint16_t hdhomerun_channel_frequency_to_number(struct hdhomerun_channel_list_t *channel_list, uint32_t frequency); extern LIBHDHOMERUN_API uint16_t hdhomerun_channel_frequency_to_number(struct hdhomerun_channel_list_t *channel_list, uint32_t frequency);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_channelscan.c * hdhomerun_channelscan.c
* *
* Copyright © 2007-2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2007-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_channelscan.h * hdhomerun_channelscan.h
* *
* Copyright © 2007-2008 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2007-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -29,12 +29,12 @@ extern "C" {
struct hdhomerun_channelscan_t; struct hdhomerun_channelscan_t;
extern LIBTYPE struct hdhomerun_channelscan_t *channelscan_create(struct hdhomerun_device_t *hd, const char *channelmap); extern LIBHDHOMERUN_API struct hdhomerun_channelscan_t *channelscan_create(struct hdhomerun_device_t *hd, const char *channelmap);
extern LIBTYPE void channelscan_destroy(struct hdhomerun_channelscan_t *scan); extern LIBHDHOMERUN_API void channelscan_destroy(struct hdhomerun_channelscan_t *scan);
extern LIBTYPE int channelscan_advance(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result); extern LIBHDHOMERUN_API int channelscan_advance(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result);
extern LIBTYPE int channelscan_detect(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result); extern LIBHDHOMERUN_API int channelscan_detect(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result);
extern LIBTYPE uint8_t channelscan_get_progress(struct hdhomerun_channelscan_t *scan); extern LIBHDHOMERUN_API uint8_t channelscan_get_progress(struct hdhomerun_channelscan_t *scan);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_config.c * hdhomerun_config.c
* *
* Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -20,16 +20,6 @@
#include "hdhomerun.h" #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; static const char *appname;
struct hdhomerun_device_t *hd; struct hdhomerun_device_t *hd;
@ -413,7 +403,7 @@ static int cmd_save(const char *tuner_str, const char *filename)
} }
/* Windows - indicate activity to suppress auto sleep mode. */ /* Windows - indicate activity to suppress auto sleep mode. */
#if defined(__WINDOWS__) #if defined(_WIN32)
SetThreadExecutionState(ES_SYSTEM_REQUIRED); SetThreadExecutionState(ES_SYSTEM_REQUIRED);
#endif #endif
@ -625,7 +615,9 @@ static int main_cmd(int argc, char *argv[])
static int main_internal(int argc, char *argv[]) static int main_internal(int argc, char *argv[])
{ {
#if defined(__WINDOWS__) #if defined(_WIN32)
/* Configure console for UTF-8. */
SetConsoleOutputCP(CP_UTF8);
/* Initialize network socket support. */ /* Initialize network socket support. */
WORD wVersionRequested = MAKEWORD(2, 0); WORD wVersionRequested = MAKEWORD(2, 0);
WSADATA wsaData; WSADATA wsaData;

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_control.c * hdhomerun_control.c
* *
* Copyright © 2006-2010 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -30,7 +30,7 @@ struct hdhomerun_control_sock_t {
uint32_t desired_device_ip; uint32_t desired_device_ip;
uint32_t actual_device_id; uint32_t actual_device_id;
uint32_t actual_device_ip; uint32_t actual_device_ip;
hdhomerun_sock_t sock; struct hdhomerun_sock_t *sock;
struct hdhomerun_debug_t *dbg; struct hdhomerun_debug_t *dbg;
struct hdhomerun_pkt_t tx_pkt; struct hdhomerun_pkt_t tx_pkt;
struct hdhomerun_pkt_t rx_pkt; struct hdhomerun_pkt_t rx_pkt;
@ -38,12 +38,12 @@ struct hdhomerun_control_sock_t {
static void hdhomerun_control_close_sock(struct hdhomerun_control_sock_t *cs) static void hdhomerun_control_close_sock(struct hdhomerun_control_sock_t *cs)
{ {
if (cs->sock == HDHOMERUN_SOCK_INVALID) { if (!cs->sock) {
return; return;
} }
hdhomerun_sock_destroy(cs->sock); hdhomerun_sock_destroy(cs->sock);
cs->sock = HDHOMERUN_SOCK_INVALID; cs->sock = NULL;
} }
void hdhomerun_control_set_device(struct hdhomerun_control_sock_t *cs, uint32_t device_id, uint32_t device_ip) void hdhomerun_control_set_device(struct hdhomerun_control_sock_t *cs, uint32_t device_id, uint32_t device_ip)
@ -65,7 +65,6 @@ struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, ui
} }
cs->dbg = dbg; cs->dbg = dbg;
cs->sock = HDHOMERUN_SOCK_INVALID;
hdhomerun_control_set_device(cs, device_id, device_ip); hdhomerun_control_set_device(cs, device_id, device_ip);
return cs; return cs;
@ -79,7 +78,7 @@ void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs)
static bool_t hdhomerun_control_connect_sock(struct hdhomerun_control_sock_t *cs) static bool_t hdhomerun_control_connect_sock(struct hdhomerun_control_sock_t *cs)
{ {
if (cs->sock != HDHOMERUN_SOCK_INVALID) { if (cs->sock) {
return TRUE; return TRUE;
} }
@ -103,7 +102,7 @@ static bool_t hdhomerun_control_connect_sock(struct hdhomerun_control_sock_t *cs
/* Create socket. */ /* Create socket. */
cs->sock = hdhomerun_sock_create_tcp(); cs->sock = hdhomerun_sock_create_tcp();
if (cs->sock == HDHOMERUN_SOCK_INVALID) { if (!cs->sock) {
hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to create socket (%d)\n", hdhomerun_sock_getlasterror()); hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to create socket (%d)\n", hdhomerun_sock_getlasterror());
return FALSE; return FALSE;
} }
@ -216,7 +215,7 @@ static int hdhomerun_control_send_recv_internal(struct hdhomerun_control_sock_t
int i; int i;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (cs->sock == HDHOMERUN_SOCK_INVALID) { if (!cs->sock) {
if (!hdhomerun_control_connect_sock(cs)) { if (!hdhomerun_control_connect_sock(cs)) {
hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: connect failed\n"); hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: connect failed\n");
return -1; return -1;

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_control.h * hdhomerun_control.h
* *
* Copyright © 2006 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -37,20 +37,20 @@ struct hdhomerun_control_sock_t;
* *
* When no longer needed, the socket should be destroyed by calling hdhomerun_control_destroy. * 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 LIBHDHOMERUN_API 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); extern LIBHDHOMERUN_API void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs);
/* /*
* Get the actual device id or ip of the device. * Get the actual device id or ip of the device.
* *
* Returns 0 if the device id cannot be determined. * 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API void hdhomerun_control_set_device(struct hdhomerun_control_sock_t *cs, uint32_t device_id, uint32_t device_ip);
/* /*
* Get the local machine IP address used when communicating with the device. * Get the local machine IP address used when communicating with the device.
@ -59,12 +59,12 @@ extern LIBTYPE void hdhomerun_control_set_device(struct hdhomerun_control_sock_t
* *
* Returns 32-bit IP address with native endianness, or 0 on error. * 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); extern LIBHDHOMERUN_API uint32_t hdhomerun_control_get_local_addr(struct hdhomerun_control_sock_t *cs);
/* /*
* Low-level communication. * 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 LIBHDHOMERUN_API 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);
/* /*
* Get/set a control variable on the device. * Get/set a control variable on the device.
@ -83,9 +83,9 @@ extern LIBTYPE int hdhomerun_control_send_recv(struct hdhomerun_control_sock_t *
* Returns 0 if the operation was rejected (pvalue NULL, perror set). * Returns 0 if the operation was rejected (pvalue NULL, perror set).
* Returns -1 if a communication error occurs. * 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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);
/* /*
* Upload new firmware to the device. * Upload new firmware to the device.
@ -96,7 +96,7 @@ extern LIBTYPE int hdhomerun_control_set_with_lockkey(struct hdhomerun_control_s
* Returns 0 if the upload was rejected. * Returns 0 if the upload was rejected.
* Returns -1 if an error occurs. * Returns -1 if an error occurs.
*/ */
extern LIBTYPE int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file); extern LIBHDHOMERUN_API int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_debug.c * hdhomerun_debug.c
* *
* Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2007-2016 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -65,7 +65,7 @@ struct hdhomerun_debug_t
char *file_name; char *file_name;
FILE *file_fp; FILE *file_fp;
hdhomerun_sock_t sock; struct hdhomerun_sock_t *sock;
}; };
static THREAD_FUNC_PREFIX hdhomerun_debug_thread_execute(void *arg); static THREAD_FUNC_PREFIX hdhomerun_debug_thread_execute(void *arg);
@ -77,8 +77,6 @@ struct hdhomerun_debug_t *hdhomerun_debug_create(void)
return NULL; return NULL;
} }
dbg->sock = HDHOMERUN_SOCK_INVALID;
pthread_mutex_init(&dbg->print_lock, NULL); pthread_mutex_init(&dbg->print_lock, NULL);
pthread_mutex_init(&dbg->queue_lock, NULL); pthread_mutex_init(&dbg->queue_lock, NULL);
pthread_mutex_init(&dbg->send_lock, NULL); pthread_mutex_init(&dbg->send_lock, NULL);
@ -109,7 +107,7 @@ void hdhomerun_debug_destroy(struct hdhomerun_debug_t *dbg)
if (dbg->file_fp) { if (dbg->file_fp) {
fclose(dbg->file_fp); fclose(dbg->file_fp);
} }
if (dbg->sock != HDHOMERUN_SOCK_INVALID) { if (dbg->sock) {
hdhomerun_sock_destroy(dbg->sock); hdhomerun_sock_destroy(dbg->sock);
} }
@ -124,9 +122,9 @@ static void hdhomerun_debug_close_internal(struct hdhomerun_debug_t *dbg)
dbg->file_fp = NULL; dbg->file_fp = NULL;
} }
if (dbg->sock != HDHOMERUN_SOCK_INVALID) { if (dbg->sock) {
hdhomerun_sock_destroy(dbg->sock); hdhomerun_sock_destroy(dbg->sock);
dbg->sock = HDHOMERUN_SOCK_INVALID; dbg->sock = NULL;
} }
} }
@ -350,7 +348,7 @@ static bool_t hdhomerun_debug_output_message_file(struct hdhomerun_debug_t *dbg,
/* Send lock held by caller */ /* Send lock held by caller */
static bool_t hdhomerun_debug_output_message_sock(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message) static bool_t hdhomerun_debug_output_message_sock(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message)
{ {
if (dbg->sock == HDHOMERUN_SOCK_INVALID) { if (!dbg->sock) {
uint64_t current_time = getcurrenttime(); uint64_t current_time = getcurrenttime();
if (current_time < dbg->connect_delay) { if (current_time < dbg->connect_delay) {
return FALSE; return FALSE;
@ -358,7 +356,7 @@ static bool_t hdhomerun_debug_output_message_sock(struct hdhomerun_debug_t *dbg,
dbg->connect_delay = current_time + HDHOMERUN_DEBUG_CONNECT_RETRY_TIME; dbg->connect_delay = current_time + HDHOMERUN_DEBUG_CONNECT_RETRY_TIME;
dbg->sock = hdhomerun_sock_create_tcp(); dbg->sock = hdhomerun_sock_create_tcp();
if (dbg->sock == HDHOMERUN_SOCK_INVALID) { if (!dbg->sock) {
return FALSE; return FALSE;
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_debug.h * hdhomerun_debug.h
* *
* Copyright © 2006 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2007-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -32,20 +32,20 @@ extern "C" {
struct hdhomerun_debug_t; struct hdhomerun_debug_t;
extern LIBTYPE struct hdhomerun_debug_t *hdhomerun_debug_create(void); extern LIBHDHOMERUN_API struct hdhomerun_debug_t *hdhomerun_debug_create(void);
extern LIBTYPE void hdhomerun_debug_destroy(struct hdhomerun_debug_t *dbg); extern LIBHDHOMERUN_API void hdhomerun_debug_destroy(struct hdhomerun_debug_t *dbg);
extern LIBTYPE void hdhomerun_debug_set_prefix(struct hdhomerun_debug_t *dbg, const char *prefix); extern LIBHDHOMERUN_API void hdhomerun_debug_set_prefix(struct hdhomerun_debug_t *dbg, const char *prefix);
extern LIBTYPE void hdhomerun_debug_set_filename(struct hdhomerun_debug_t *dbg, const char *filename); extern LIBHDHOMERUN_API void hdhomerun_debug_set_filename(struct hdhomerun_debug_t *dbg, const char *filename);
extern LIBTYPE void hdhomerun_debug_enable(struct hdhomerun_debug_t *dbg); extern LIBHDHOMERUN_API void hdhomerun_debug_enable(struct hdhomerun_debug_t *dbg);
extern LIBTYPE void hdhomerun_debug_disable(struct hdhomerun_debug_t *dbg); extern LIBHDHOMERUN_API void hdhomerun_debug_disable(struct hdhomerun_debug_t *dbg);
extern LIBTYPE bool_t hdhomerun_debug_enabled(struct hdhomerun_debug_t *dbg); extern LIBHDHOMERUN_API bool_t hdhomerun_debug_enabled(struct hdhomerun_debug_t *dbg);
extern LIBTYPE void hdhomerun_debug_flush(struct hdhomerun_debug_t *dbg, uint64_t timeout); extern LIBHDHOMERUN_API void hdhomerun_debug_flush(struct hdhomerun_debug_t *dbg, uint64_t timeout);
extern LIBTYPE void hdhomerun_debug_close(struct hdhomerun_debug_t *dbg, uint64_t timeout); extern LIBHDHOMERUN_API void hdhomerun_debug_close(struct hdhomerun_debug_t *dbg, uint64_t timeout);
extern LIBTYPE void hdhomerun_debug_printf(struct hdhomerun_debug_t *dbg, const char *fmt, ...); extern LIBHDHOMERUN_API void hdhomerun_debug_printf(struct hdhomerun_debug_t *dbg, const char *fmt, ...);
extern LIBTYPE void hdhomerun_debug_vprintf(struct hdhomerun_debug_t *dbg, const char *fmt, va_list args); extern LIBHDHOMERUN_API void hdhomerun_debug_vprintf(struct hdhomerun_debug_t *dbg, const char *fmt, va_list args);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_device.c * hdhomerun_device.c
* *
* Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_device.h * hdhomerun_device.h
* *
* Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -63,25 +63,25 @@ extern "C" {
* <tuner index> * <tuner index>
* /tuner<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 LIBHDHOMERUN_API 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_multicast(uint32_t multicast_ip, uint16_t multicast_port, struct hdhomerun_debug_t *dbg); extern LIBHDHOMERUN_API struct hdhomerun_device_t *hdhomerun_device_create_multicast(uint32_t multicast_ip, uint16_t multicast_port, 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 LIBHDHOMERUN_API 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); extern LIBHDHOMERUN_API void hdhomerun_device_destroy(struct hdhomerun_device_t *hd);
/* /*
* Get the device id, ip, or tuner of the device instance. * 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API unsigned int hdhomerun_device_get_tuner(struct hdhomerun_device_t *hd);
extern LIBTYPE int hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip); extern LIBHDHOMERUN_API int hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip);
extern LIBTYPE int hdhomerun_device_set_multicast(struct hdhomerun_device_t *hd, uint32_t multicast_ip, uint16_t multicast_port); extern LIBHDHOMERUN_API int hdhomerun_device_set_multicast(struct hdhomerun_device_t *hd, uint32_t multicast_ip, uint16_t multicast_port);
extern LIBTYPE int hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner); extern LIBHDHOMERUN_API int 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 LIBHDHOMERUN_API int hdhomerun_device_set_tuner_from_str(struct hdhomerun_device_t *hd, const char *tuner_str);
/* /*
* Get the local machine IP address used when communicating with the device. * Get the local machine IP address used when communicating with the device.
@ -90,7 +90,7 @@ extern LIBTYPE int hdhomerun_device_set_tuner_from_str(struct hdhomerun_device_t
* *
* Returns 32-bit IP address with native endianness, or 0 on error. * 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 LIBHDHOMERUN_API uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun_device_t *hd);
/* /*
* Get operations. * Get operations.
@ -103,29 +103,29 @@ extern LIBTYPE uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun
* Returns 0 if the operation was rejected. * Returns 0 if the operation was rejected.
* Returns -1 if a communication error occurred. * 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 LIBHDHOMERUN_API 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_vstatus(struct hdhomerun_device_t *hd, char **pvstatus_str, struct hdhomerun_tuner_vstatus_t *vstatus); extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_vstatus(struct hdhomerun_device_t *hd, char **pvstatus_str, struct hdhomerun_tuner_vstatus_t *vstatus);
extern LIBTYPE int hdhomerun_device_get_tuner_streaminfo(struct hdhomerun_device_t *hd, char **pstreaminfo); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API int hdhomerun_device_get_tuner_channel(struct hdhomerun_device_t *hd, char **pchannel);
extern LIBTYPE int hdhomerun_device_get_tuner_vchannel(struct hdhomerun_device_t *hd, char **pvchannel); extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_vchannel(struct hdhomerun_device_t *hd, char **pvchannel);
extern LIBTYPE int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API int hdhomerun_device_get_tuner_lockkey_owner(struct hdhomerun_device_t *hd, char **powner);
extern LIBTYPE int hdhomerun_device_get_oob_status(struct hdhomerun_device_t *hd, char **pstatus_str, struct hdhomerun_tuner_status_t *status); extern LIBHDHOMERUN_API int hdhomerun_device_get_oob_status(struct hdhomerun_device_t *hd, char **pstatus_str, struct hdhomerun_tuner_status_t *status);
extern LIBTYPE int hdhomerun_device_get_oob_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount); extern LIBHDHOMERUN_API int hdhomerun_device_get_oob_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount);
extern LIBTYPE int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget); extern LIBHDHOMERUN_API int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget);
extern LIBTYPE int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num); extern LIBHDHOMERUN_API int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num);
extern LIBTYPE int hdhomerun_device_get_supported(struct hdhomerun_device_t *hd, char *prefix, char **pstr); extern LIBHDHOMERUN_API int hdhomerun_device_get_supported(struct hdhomerun_device_t *hd, char *prefix, char **pstr);
extern LIBTYPE uint32_t hdhomerun_device_get_tuner_status_ss_color(struct hdhomerun_tuner_status_t *status); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API uint32_t hdhomerun_device_get_tuner_status_seq_color(struct hdhomerun_tuner_status_t *status);
extern LIBTYPE const char *hdhomerun_device_get_hw_model_str(struct hdhomerun_device_t *hd); extern LIBHDHOMERUN_API const char *hdhomerun_device_get_hw_model_str(struct hdhomerun_device_t *hd);
extern LIBTYPE const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd); extern LIBHDHOMERUN_API const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd);
/* /*
* Set operations. * Set operations.
@ -136,15 +136,15 @@ extern LIBTYPE const char *hdhomerun_device_get_model_str(struct hdhomerun_devic
* Returns 0 if the operation was rejected. * Returns 0 if the operation was rejected.
* Returns -1 if a communication error occurred. * Returns -1 if a communication error occurred.
*/ */
extern LIBTYPE int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char *channel); extern LIBHDHOMERUN_API int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char *channel);
extern LIBTYPE int hdhomerun_device_set_tuner_vchannel(struct hdhomerun_device_t *hd, const char *vchannel); extern LIBHDHOMERUN_API int hdhomerun_device_set_tuner_vchannel(struct hdhomerun_device_t *hd, const char *vchannel);
extern LIBTYPE int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, const char *target);
extern LIBTYPE int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target); extern LIBHDHOMERUN_API int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target);
extern LIBTYPE int hdhomerun_device_set_sys_dvbc_modulation(struct hdhomerun_device_t *hd, const char *modulation_list); extern LIBHDHOMERUN_API int hdhomerun_device_set_sys_dvbc_modulation(struct hdhomerun_device_t *hd, const char *modulation_list);
/* /*
* Get/set a named control variable on the device. * Get/set a named control variable on the device.
@ -163,8 +163,8 @@ extern LIBTYPE int hdhomerun_device_set_sys_dvbc_modulation(struct hdhomerun_dev
* Returns 0 if the operation was rejected (pvalue NULL, perror set). * Returns 0 if the operation was rejected (pvalue NULL, perror set).
* Returns -1 if a communication error occurs. * 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 LIBHDHOMERUN_API 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); extern LIBHDHOMERUN_API int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const char *name, const char *value, char **pvalue, char **perror);
/* /*
* Tuner locking. * Tuner locking.
@ -179,14 +179,14 @@ extern LIBTYPE int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const
* previously held lock. If locking is used then this function must be called * previously held lock. If locking is used then this function must be called
* before destroying the hdhomerun_device object. * before destroying the hdhomerun_device object.
*/ */
extern LIBTYPE int hdhomerun_device_tuner_lockkey_request(struct hdhomerun_device_t *hd, char **perror); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API int hdhomerun_device_tuner_lockkey_release(struct hdhomerun_device_t *hd);
extern LIBTYPE int hdhomerun_device_tuner_lockkey_force(struct hdhomerun_device_t *hd); extern LIBHDHOMERUN_API int hdhomerun_device_tuner_lockkey_force(struct hdhomerun_device_t *hd);
/* /*
* Intended only for non persistent connections; eg, hdhomerun_config. * 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); extern LIBHDHOMERUN_API void hdhomerun_device_tuner_lockkey_use_value(struct hdhomerun_device_t *hd, uint32_t lockkey);
/* /*
* Wait for tuner lock after channel change. * Wait for tuner lock after channel change.
@ -198,7 +198,7 @@ extern LIBTYPE void hdhomerun_device_tuner_lockkey_use_value(struct hdhomerun_de
* It will return quickly if there is no signal detected. * 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. * 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 LIBHDHOMERUN_API int hdhomerun_device_wait_for_lock(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status);
/* /*
* Stream a filtered program or the unfiltered stream. * Stream a filtered program or the unfiltered stream.
@ -216,18 +216,18 @@ extern LIBTYPE int hdhomerun_device_wait_for_lock(struct hdhomerun_device_t *hd,
* *
* The hdhomerun_device_stream_stop function tells the device to stop streaming data. * 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 LIBHDHOMERUN_API int hdhomerun_device_stream_start(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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API void hdhomerun_device_stream_flush(struct hdhomerun_device_t *hd);
extern LIBTYPE void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd); extern LIBHDHOMERUN_API void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd);
/* /*
* Channel scan API. * Channel scan API.
*/ */
extern LIBTYPE int hdhomerun_device_channelscan_init(struct hdhomerun_device_t *hd, const char *channelmap); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd);
/* /*
* Upload new firmware to the device. * Upload new firmware to the device.
@ -238,19 +238,19 @@ extern LIBTYPE uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomeru
* Returns 0 if the upload was rejected. * Returns 0 if the upload was rejected.
* Returns -1 if an error occurs. * Returns -1 if an error occurs.
*/ */
extern LIBTYPE int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file); extern LIBHDHOMERUN_API int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file);
/* /*
* Low level accessor functions. * Low level accessor functions.
*/ */
extern LIBTYPE struct hdhomerun_control_sock_t *hdhomerun_device_get_control_sock(struct hdhomerun_device_t *hd); extern LIBHDHOMERUN_API 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); extern LIBHDHOMERUN_API struct hdhomerun_video_sock_t *hdhomerun_device_get_video_sock(struct hdhomerun_device_t *hd);
/* /*
* Debug print internal stats. * Debug print internal stats.
*/ */
extern LIBTYPE void hdhomerun_device_debug_print_video_stats(struct hdhomerun_device_t *hd); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API void hdhomerun_device_get_video_stats(struct hdhomerun_device_t *hd, struct hdhomerun_video_stats_t *stats);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_device_selector.c * hdhomerun_device_selector.c
* *
* Copyright © 2009-2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2009-2016 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -56,7 +56,7 @@ void hdhomerun_device_selector_destroy(struct hdhomerun_device_selector_t *hds,
free(hds); free(hds);
} }
LIBTYPE int hdhomerun_device_selector_get_device_count(struct hdhomerun_device_selector_t *hds) int hdhomerun_device_selector_get_device_count(struct hdhomerun_device_selector_t *hds)
{ {
return (int)hds->hd_count; return (int)hds->hd_count;
} }
@ -263,7 +263,7 @@ int hdhomerun_device_selector_load_from_file(struct hdhomerun_device_selector_t
return count; return count;
} }
#if defined(__WINDOWS__) #if defined(_WIN32) && !defined(_WINRT)
int hdhomerun_device_selector_load_from_windows_registry(struct hdhomerun_device_selector_t *hds, wchar_t *wsource) int hdhomerun_device_selector_load_from_windows_registry(struct hdhomerun_device_selector_t *hds, wchar_t *wsource)
{ {
HKEY tuners_key; HKEY tuners_key;
@ -374,8 +374,8 @@ static bool_t hdhomerun_device_selector_choose_test(struct hdhomerun_device_sele
/* /*
* Test local port. * Test local port.
*/ */
hdhomerun_sock_t test_sock = hdhomerun_sock_create_udp(); struct hdhomerun_sock_t *test_sock = hdhomerun_sock_create_udp();
if (test_sock == HDHOMERUN_SOCK_INVALID) { if (!test_sock) {
hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to create test sock\n", name); hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to create test sock\n", name);
return FALSE; return FALSE;
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_device_selector.h * hdhomerun_device_selector.h
* *
* Copyright © 2009 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2009-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -27,34 +27,35 @@ extern "C" {
* All tuners registered with a specific device selector instance must have the same signal source. * All tuners registered with a specific device selector instance must have the same signal source.
* The dbg parameter may be null. * The dbg parameter may be null.
*/ */
extern LIBTYPE struct hdhomerun_device_selector_t *hdhomerun_device_selector_create(struct hdhomerun_debug_t *dbg); extern LIBHDHOMERUN_API struct hdhomerun_device_selector_t *hdhomerun_device_selector_create(struct hdhomerun_debug_t *dbg);
extern LIBTYPE void hdhomerun_device_selector_destroy(struct hdhomerun_device_selector_t *hds, bool_t destroy_devices); extern LIBHDHOMERUN_API void hdhomerun_device_selector_destroy(struct hdhomerun_device_selector_t *hds, bool_t destroy_devices);
/* /*
* Get the number of devices in the list. * Get the number of devices in the list.
*/ */
extern LIBTYPE int hdhomerun_device_selector_get_device_count(struct hdhomerun_device_selector_t *hds); extern LIBHDHOMERUN_API int hdhomerun_device_selector_get_device_count(struct hdhomerun_device_selector_t *hds);
/* /*
* Populate device selector with devices from given source. * Populate device selector with devices from given source.
* Returns the number of devices populated. * Returns the number of devices populated.
*/ */
extern LIBTYPE int hdhomerun_device_selector_load_from_str(struct hdhomerun_device_selector_t *hds, char *device_str); extern LIBHDHOMERUN_API int hdhomerun_device_selector_load_from_str(struct hdhomerun_device_selector_t *hds, char *device_str);
extern LIBTYPE int hdhomerun_device_selector_load_from_file(struct hdhomerun_device_selector_t *hds, char *filename); extern LIBHDHOMERUN_API int hdhomerun_device_selector_load_from_file(struct hdhomerun_device_selector_t *hds, char *filename);
#if defined(__WINDOWS__)
extern LIBTYPE int hdhomerun_device_selector_load_from_windows_registry(struct hdhomerun_device_selector_t *hds, wchar_t *wsource); #if defined(_WIN32) && !defined(_WINRT)
extern LIBHDHOMERUN_API int hdhomerun_device_selector_load_from_windows_registry(struct hdhomerun_device_selector_t *hds, wchar_t *wsource);
#endif #endif
/* /*
* Add/remove a device from the selector list. * Add/remove a device from the selector list.
*/ */
extern LIBTYPE void hdhomerun_device_selector_add_device(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *hd); extern LIBHDHOMERUN_API void hdhomerun_device_selector_add_device(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *hd);
extern LIBTYPE void hdhomerun_device_selector_remove_device(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *hd); extern LIBHDHOMERUN_API void hdhomerun_device_selector_remove_device(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *hd);
/* /*
* Find a device in the selector list. * Find a device in the selector list.
*/ */
extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_selector_find_device(struct hdhomerun_device_selector_t *hds, uint32_t device_id, unsigned int tuner_index); extern LIBHDHOMERUN_API struct hdhomerun_device_t *hdhomerun_device_selector_find_device(struct hdhomerun_device_selector_t *hds, uint32_t device_id, unsigned int tuner_index);
/* /*
* Select and lock an available device. * Select and lock an available device.
@ -79,7 +80,7 @@ extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_selector_find_device(
* to refresh the lock. If this function succeeds then the same device can be used. If this fucntion fails * to refresh the lock. If this function succeeds then the same device can be used. If this fucntion fails
* then call hdhomerun_device_selector_choose_and_lock() to choose and lock an available tuner. * then call hdhomerun_device_selector_choose_and_lock() to choose and lock an available tuner.
*/ */
extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_selector_choose_and_lock(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *prefered); extern LIBHDHOMERUN_API struct hdhomerun_device_t *hdhomerun_device_selector_choose_and_lock(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *prefered);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -23,7 +23,7 @@
#define HDHOMERUN_DISOCVER_MAX_SOCK_COUNT 16 #define HDHOMERUN_DISOCVER_MAX_SOCK_COUNT 16
struct hdhomerun_discover_sock_t { struct hdhomerun_discover_sock_t {
hdhomerun_sock_t sock; struct hdhomerun_sock_t *sock;
bool_t detected; bool_t detected;
uint32_t local_ip; uint32_t local_ip;
uint32_t subnet_mask; uint32_t subnet_mask;
@ -54,8 +54,9 @@ static bool_t hdhomerun_discover_sock_add(struct hdhomerun_discover_t *ds, uint3
} }
/* Create socket. */ /* Create socket. */
hdhomerun_sock_t sock = hdhomerun_sock_create_udp(); struct hdhomerun_sock_t *sock = hdhomerun_sock_create_udp();
if (sock == HDHOMERUN_SOCK_INVALID) { if (!sock) {
hdhomerun_debug_printf(ds->dbg, "discover: failed to allocate socket (%d)\n", hdhomerun_sock_getlasterror());
return FALSE; return FALSE;
} }

View file

@ -45,14 +45,14 @@ struct hdhomerun_discover_device_t {
* Returns the number of devices found. * Returns the number of devices found.
* Retruns -1 on error. * Retruns -1 on error.
*/ */
extern LIBTYPE 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_t result_list[], int max_count);
/* /*
* Optional: persistent discover instance available for discover polling use. * Optional: persistent discover instance available for discover polling use.
*/ */
extern LIBTYPE struct hdhomerun_discover_t *hdhomerun_discover_create(struct hdhomerun_debug_t *dbg); extern LIBHDHOMERUN_API struct hdhomerun_discover_t *hdhomerun_discover_create(struct hdhomerun_debug_t *dbg);
extern LIBTYPE void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds); extern LIBHDHOMERUN_API void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds);
extern LIBTYPE 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_t result_list[], int max_count);
/* /*
* Verify that the device ID given is valid. * Verify that the device ID given is valid.
@ -63,7 +63,7 @@ extern LIBTYPE int hdhomerun_discover_find_devices_v2(struct hdhomerun_discover_
* Returns TRUE if valid. * Returns TRUE if valid.
* Returns FALSE if not valid. * Returns FALSE if not valid.
*/ */
extern LIBTYPE bool_t hdhomerun_discover_validate_device_id(uint32_t device_id); extern LIBHDHOMERUN_API bool_t hdhomerun_discover_validate_device_id(uint32_t device_id);
/* /*
* Detect if an IP address is multicast. * Detect if an IP address is multicast.
@ -71,7 +71,7 @@ extern LIBTYPE bool_t hdhomerun_discover_validate_device_id(uint32_t device_id);
* Returns TRUE if multicast. * Returns TRUE if multicast.
* Returns FALSE if zero, unicast, expermental, or broadcast. * Returns FALSE if zero, unicast, expermental, or broadcast.
*/ */
extern LIBTYPE bool_t hdhomerun_discover_is_ip_multicast(uint32_t ip_addr); extern LIBHDHOMERUN_API bool_t hdhomerun_discover_is_ip_multicast(uint32_t ip_addr);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_os.h * hdhomerun_os.h
* *
* Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -18,11 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32)
#define __WINDOWS__
#endif
#if defined(__WINDOWS__)
#include "hdhomerun_os_windows.h" #include "hdhomerun_os_windows.h"
#else #else
#include "hdhomerun_os_posix.h" #include "hdhomerun_os_posix.h"

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_os_posix.c * hdhomerun_os_posix.c
* *
* Copyright © 2006-2010 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -21,8 +21,48 @@
#include "hdhomerun_os.h" #include "hdhomerun_os.h"
#if defined(__APPLE__) #if defined(__APPLE__)
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/mach.h> #include <mach/mach.h>
static pthread_once_t clock_monotonic_once = PTHREAD_ONCE_INIT;
static clock_serv_t clock_monotonic_clock_serv;
static void clock_monotonic_init(void)
{
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &clock_monotonic_clock_serv);
}
static inline void clock_monotonic_timespec(struct timespec *ts)
{
pthread_once(&clock_monotonic_once, clock_monotonic_init);
struct mach_timespec mt;
clock_get_time(clock_monotonic_clock_serv, &mt);
ts->tv_nsec = mt.tv_nsec;
ts->tv_sec = mt.tv_sec;
}
static inline void clock_realtime_timespec(struct timespec *ts)
{
struct timeval tv;
gettimeofday(&tv, NULL);
ts->tv_nsec = tv.tv_usec * 1000;
ts->tv_sec = tv.tv_sec;
}
#else
static inline void clock_monotonic_timespec(struct timespec *ts)
{
clock_gettime(CLOCK_MONOTONIC, ts);
}
static inline void clock_realtime_timespec(struct timespec *ts)
{
clock_gettime(CLOCK_REALTIME, ts);
}
#endif #endif
static pthread_once_t random_get32_once = PTHREAD_ONCE_INIT; static pthread_once_t random_get32_once = PTHREAD_ONCE_INIT;
@ -51,22 +91,9 @@ uint32_t random_get32(void)
uint64_t getcurrenttime(void) uint64_t getcurrenttime(void)
{ {
#if defined(CLOCK_MONOTONIC) struct timespec ts;
struct timespec t; clock_monotonic_timespec(&ts);
clock_gettime(CLOCK_MONOTONIC, &t); return ((uint64_t)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
return ((uint64_t)t.tv_sec * 1000) + (t.tv_nsec / 1000000);
#elif defined(__APPLE__)
clock_serv_t clock_serv;
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &clock_serv);
struct mach_timespec t;
clock_get_time(clock_serv, &t);
mach_port_deallocate(mach_task_self(), clock_serv);
return ((uint64_t)t.tv_sec * 1000) + (t.tv_nsec / 1000000);
#else
#error no clock source for getcurrenttime()
#endif
} }
void msleep_approx(uint64_t ms) void msleep_approx(uint64_t ms)
@ -97,6 +124,44 @@ void msleep_minimum(uint64_t ms)
} }
} }
void thread_cond_init(thread_cond_t *cond)
{
pthread_mutex_init(&cond->lock, NULL);
pthread_cond_init(&cond->cond, NULL);
}
void thread_cond_dispose(thread_cond_t *cond)
{
}
void thread_cond_signal(thread_cond_t *cond)
{
pthread_mutex_lock(&cond->lock);
pthread_cond_signal(&cond->cond);
pthread_mutex_unlock(&cond->lock);
}
void thread_cond_wait(thread_cond_t *cond)
{
pthread_mutex_lock(&cond->lock);
pthread_cond_wait(&cond->cond, &cond->lock);
pthread_mutex_unlock(&cond->lock);
}
void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time)
{
struct timespec ts;
clock_realtime_timespec(&ts);
uint64_t tv_nsec = (uint64_t)ts.tv_nsec + (max_wait_time * 1000000);
ts.tv_nsec = (long)(tv_nsec % 1000000000);
ts.tv_sec += (time_t)(tv_nsec / 1000000000);
pthread_mutex_lock(&cond->lock);
pthread_cond_timedwait(&cond->cond, &cond->lock, &ts);
pthread_mutex_unlock(&cond->lock);
}
bool_t hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap) bool_t hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap)
{ {
if (buffer >= end) { if (buffer >= end) {

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_os_posix.h * hdhomerun_os_posix.h
* *
* Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -38,25 +38,35 @@
#include <netdb.h> #include <netdb.h>
#include <pthread.h> #include <pthread.h>
typedef int bool_t; typedef uint8_t bool_t;
typedef void (*sig_t)(int); typedef void (*sig_t)(int);
#define LIBTYPE typedef struct {
#define console_vprintf vprintf pthread_mutex_t lock;
#define console_printf printf pthread_cond_t cond;
} thread_cond_t;
#define LIBHDHOMERUN_API
#define THREAD_FUNC_PREFIX void * #define THREAD_FUNC_PREFIX void *
#define THREAD_FUNC_RESULT NULL
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern LIBTYPE uint32_t random_get32(void); extern LIBHDHOMERUN_API uint32_t random_get32(void);
extern LIBTYPE uint64_t getcurrenttime(void); extern LIBHDHOMERUN_API uint64_t getcurrenttime(void);
extern LIBTYPE void msleep_approx(uint64_t ms); extern LIBHDHOMERUN_API void msleep_approx(uint64_t ms);
extern LIBTYPE void msleep_minimum(uint64_t ms); extern LIBHDHOMERUN_API void msleep_minimum(uint64_t ms);
extern LIBTYPE bool_t hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap); extern LIBHDHOMERUN_API void thread_cond_init(thread_cond_t *cond);
extern LIBTYPE bool_t hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...); extern LIBHDHOMERUN_API void thread_cond_dispose(thread_cond_t *cond);
extern LIBHDHOMERUN_API void thread_cond_signal(thread_cond_t *cond);
extern LIBHDHOMERUN_API void thread_cond_wait(thread_cond_t *cond);
extern LIBHDHOMERUN_API void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time);
extern LIBHDHOMERUN_API bool_t hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap);
extern LIBHDHOMERUN_API bool_t hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_os_windows.c * hdhomerun_os_windows.c
* *
* Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -18,12 +18,21 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "hdhomerun_os.h" #include "hdhomerun.h"
static DWORD random_get32_context_tls = TlsAlloc();
#if defined(_WINRT)
uint32_t random_get32(void) uint32_t random_get32(void)
{ {
return (uint32_t)getcurrenttime();
}
#else
uint32_t random_get32(void)
{
static DWORD random_get32_context_tls = 0xFFFFFFFF;
if (random_get32_context_tls == 0xFFFFFFFF) {
random_get32_context_tls = TlsAlloc();
}
HCRYPTPROV *phProv = (HCRYPTPROV *)TlsGetValue(random_get32_context_tls); HCRYPTPROV *phProv = (HCRYPTPROV *)TlsGetValue(random_get32_context_tls);
if (!phProv) { if (!phProv) {
phProv = (HCRYPTPROV *)calloc(1, sizeof(HCRYPTPROV)); phProv = (HCRYPTPROV *)calloc(1, sizeof(HCRYPTPROV));
@ -38,6 +47,7 @@ uint32_t random_get32(void)
return Result; return Result;
} }
#endif
uint64_t getcurrenttime(void) uint64_t getcurrenttime(void)
{ {
@ -100,6 +110,31 @@ void pthread_mutex_unlock(pthread_mutex_t *mutex)
ReleaseMutex(*mutex); ReleaseMutex(*mutex);
} }
void thread_cond_init(thread_cond_t *cond)
{
*cond = CreateEvent(NULL, FALSE, FALSE, NULL);
}
void thread_cond_dispose(thread_cond_t *cond)
{
CloseHandle(*cond);
}
void thread_cond_signal(thread_cond_t *cond)
{
SetEvent(*cond);
}
void thread_cond_wait(thread_cond_t *cond)
{
WaitForSingleObject(*cond, INFINITE);
}
void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time)
{
WaitForSingleObject(*cond, (DWORD)max_wait_time);
}
bool_t hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap) bool_t hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap)
{ {
if (buffer >= end) { if (buffer >= end) {
@ -129,24 +164,3 @@ bool_t hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...)
va_end(ap); va_end(ap);
return result; return result;
} }
/*
* 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.
*/
void console_vprintf(const char *fmt, va_list ap)
{
UINT cp = GetConsoleOutputCP();
SetConsoleOutputCP(CP_UTF8);
vprintf(fmt, ap);
SetConsoleOutputCP(cp);
}
void console_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
console_vprintf(fmt, ap);
va_end(ap);
}

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_os_windows.h * hdhomerun_os_windows.h
* *
* Copyright © 2006-2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -18,40 +18,49 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#define _WINSOCKAPI_ #ifdef _WINRT
#include <windows.h> #include <SDKDDKVer.h>
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#endif
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#endif
#include <winsock2.h> #include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <wspiapi.h> #include <wspiapi.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#if defined(DLL_IMPORT) #ifdef LIBHDHOMERUN_DLLEXPORT
#define LIBTYPE __declspec( dllexport ) #define LIBHDHOMERUN_API __declspec(dllexport)
#elif defined(DLL_EXPORT) #endif
#define LIBTYPE __declspec( dllimport ) #ifdef LIBHDHOMERUN_DLLIMPORT
#else #define LIBHDHOMERUN_API __declspec(dllimport)
#define LIBTYPE #endif
#ifndef LIBHDHOMERUN_API
#define LIBHDHOMERUN_API
#endif #endif
typedef int bool_t; typedef uint8_t bool_t;
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef signed __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef void (*sig_t)(int); typedef void (*sig_t)(int);
typedef HANDLE pthread_t; typedef HANDLE pthread_t;
typedef HANDLE pthread_mutex_t; typedef HANDLE pthread_mutex_t;
typedef HANDLE thread_cond_t;
#if !defined(va_copy) #if !defined(va_copy)
#define va_copy(x, y) x = y #define va_copy(x, y) x = y
@ -60,35 +69,35 @@ typedef HANDLE pthread_mutex_t;
#define atoll _atoi64 #define atoll _atoi64
#define strdup _strdup #define strdup _strdup
#define strcasecmp _stricmp #define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define fseeko _fseeki64 #define fseeko _fseeki64
#define ftello _ftelli64 #define ftello _ftelli64
#define THREAD_FUNC_PREFIX DWORD WINAPI #define THREAD_FUNC_PREFIX DWORD WINAPI
#define THREAD_FUNC_RESULT 0
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern LIBTYPE uint32_t random_get32(void); extern LIBHDHOMERUN_API uint32_t random_get32(void);
extern LIBTYPE uint64_t getcurrenttime(void); extern LIBHDHOMERUN_API uint64_t getcurrenttime(void);
extern LIBTYPE void msleep_approx(uint64_t ms); extern LIBHDHOMERUN_API void msleep_approx(uint64_t ms);
extern LIBTYPE void msleep_minimum(uint64_t ms); extern LIBHDHOMERUN_API void msleep_minimum(uint64_t ms);
extern LIBTYPE int pthread_create(pthread_t *tid, void *attr, LPTHREAD_START_ROUTINE start, void *arg); extern LIBHDHOMERUN_API int pthread_create(pthread_t *tid, void *attr, LPTHREAD_START_ROUTINE start, void *arg);
extern LIBTYPE int pthread_join(pthread_t tid, void **value_ptr); extern LIBHDHOMERUN_API int pthread_join(pthread_t tid, void **value_ptr);
extern LIBTYPE void pthread_mutex_init(pthread_mutex_t *mutex, void *attr); extern LIBHDHOMERUN_API void pthread_mutex_init(pthread_mutex_t *mutex, void *attr);
extern LIBTYPE void pthread_mutex_lock(pthread_mutex_t *mutex); extern LIBHDHOMERUN_API void pthread_mutex_lock(pthread_mutex_t *mutex);
extern LIBTYPE void pthread_mutex_unlock(pthread_mutex_t *mutex); extern LIBHDHOMERUN_API void pthread_mutex_unlock(pthread_mutex_t *mutex);
extern LIBTYPE bool_t hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap); extern LIBHDHOMERUN_API void thread_cond_init(thread_cond_t *cond);
extern LIBTYPE bool_t hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...); extern LIBHDHOMERUN_API void thread_cond_dispose(thread_cond_t *cond);
extern LIBHDHOMERUN_API void thread_cond_signal(thread_cond_t *cond);
extern LIBHDHOMERUN_API void thread_cond_wait(thread_cond_t *cond);
extern LIBHDHOMERUN_API void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time);
/* extern LIBHDHOMERUN_API bool_t hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap);
* The console output format should be set to UTF-8, however in XP and Vista this breaks batch file processing. extern LIBHDHOMERUN_API bool_t hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...);
* Attempting to restore on exit fails to restore if the program is terminated by the user.
* Solution - set the output format each printf.
*/
extern LIBTYPE void console_vprintf(const char *fmt, va_list ap);
extern LIBTYPE void console_printf(const char *fmt, ...);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_pkt.c * hdhomerun_pkt.c
* *
* Copyright © 2005-2006 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2014 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_pkt.h * hdhomerun_pkt.h
* *
* Copyright © 2005-2006 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2006-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -133,6 +133,7 @@ extern "C" {
#define HDHOMERUN_DEVICE_TYPE_WILDCARD 0xFFFFFFFF #define HDHOMERUN_DEVICE_TYPE_WILDCARD 0xFFFFFFFF
#define HDHOMERUN_DEVICE_TYPE_TUNER 0x00000001 #define HDHOMERUN_DEVICE_TYPE_TUNER 0x00000001
#define HDHOMERUN_DEVICE_TYPE_STORAGE 0x00000005
#define HDHOMERUN_DEVICE_ID_WILDCARD 0xFFFFFFFF #define HDHOMERUN_DEVICE_ID_WILDCARD 0xFFFFFFFF
#define HDHOMERUN_MIN_PEEK_LENGTH 4 #define HDHOMERUN_MIN_PEEK_LENGTH 4
@ -145,25 +146,25 @@ struct hdhomerun_pkt_t {
uint8_t buffer[3074]; uint8_t buffer[3074];
}; };
extern LIBTYPE struct hdhomerun_pkt_t *hdhomerun_pkt_create(void); extern LIBHDHOMERUN_API struct hdhomerun_pkt_t *hdhomerun_pkt_create(void);
extern LIBTYPE void hdhomerun_pkt_destroy(struct hdhomerun_pkt_t *pkt); extern LIBHDHOMERUN_API void hdhomerun_pkt_destroy(struct hdhomerun_pkt_t *pkt);
extern LIBTYPE void hdhomerun_pkt_reset(struct hdhomerun_pkt_t *pkt); extern LIBHDHOMERUN_API void hdhomerun_pkt_reset(struct hdhomerun_pkt_t *pkt);
extern LIBTYPE uint8_t hdhomerun_pkt_read_u8(struct hdhomerun_pkt_t *pkt); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API uint8_t *hdhomerun_pkt_read_tlv(struct hdhomerun_pkt_t *pkt, uint8_t *ptag, size_t *plength);
extern LIBTYPE void hdhomerun_pkt_read_mem(struct hdhomerun_pkt_t *pkt, void *mem, size_t length); extern LIBHDHOMERUN_API void hdhomerun_pkt_read_mem(struct hdhomerun_pkt_t *pkt, void *mem, size_t length);
extern LIBTYPE void hdhomerun_pkt_write_u8(struct hdhomerun_pkt_t *pkt, uint8_t v); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API 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 LIBHDHOMERUN_API int 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 LIBHDHOMERUN_API void hdhomerun_pkt_seal_frame(struct hdhomerun_pkt_t *pkt, uint16_t frame_type);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_sock.h * hdhomerun_sock.h
* *
* Copyright © 2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2010-2016 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -26,33 +26,36 @@ struct hdhomerun_local_ip_info_t {
uint32_t subnet_mask; uint32_t subnet_mask;
}; };
extern LIBTYPE int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count); extern LIBHDHOMERUN_API int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count);
#define HDHOMERUN_SOCK_INVALID -1 struct hdhomerun_sock_t;
typedef int hdhomerun_sock_t; extern LIBHDHOMERUN_API struct hdhomerun_sock_t *hdhomerun_sock_create_udp(void);
extern LIBHDHOMERUN_API struct hdhomerun_sock_t *hdhomerun_sock_create_tcp(void);
extern LIBHDHOMERUN_API void hdhomerun_sock_stop(struct hdhomerun_sock_t *sock);
extern LIBHDHOMERUN_API void hdhomerun_sock_destroy(struct hdhomerun_sock_t *sock);
extern LIBTYPE hdhomerun_sock_t hdhomerun_sock_create_udp(void); extern LIBHDHOMERUN_API void hdhomerun_sock_set_send_buffer_size(struct hdhomerun_sock_t *sock, size_t size);
extern LIBTYPE hdhomerun_sock_t hdhomerun_sock_create_tcp(void); extern LIBHDHOMERUN_API void hdhomerun_sock_set_recv_buffer_size(struct hdhomerun_sock_t *sock, size_t size);
extern LIBTYPE void hdhomerun_sock_destroy(hdhomerun_sock_t sock); extern LIBHDHOMERUN_API void hdhomerun_sock_set_allow_reuse(struct hdhomerun_sock_t *sock);
extern LIBTYPE int hdhomerun_sock_getlasterror(void); extern LIBHDHOMERUN_API int hdhomerun_sock_getlasterror(void);
extern LIBTYPE uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock); extern LIBHDHOMERUN_API uint32_t hdhomerun_sock_getsockname_addr(struct hdhomerun_sock_t *sock);
extern LIBTYPE uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock); extern LIBHDHOMERUN_API uint16_t hdhomerun_sock_getsockname_port(struct hdhomerun_sock_t *sock);
extern LIBTYPE uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock); extern LIBHDHOMERUN_API uint32_t hdhomerun_sock_getpeername_addr(struct hdhomerun_sock_t *sock);
extern LIBTYPE uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name); extern LIBHDHOMERUN_API uint32_t hdhomerun_sock_getaddrinfo_addr(struct hdhomerun_sock_t *sock, const char *name);
extern LIBTYPE bool_t hdhomerun_sock_join_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip); extern LIBHDHOMERUN_API bool_t hdhomerun_sock_join_multicast_group(struct hdhomerun_sock_t *sock, uint32_t multicast_ip, uint32_t local_ip);
extern LIBTYPE bool_t hdhomerun_sock_leave_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip); extern LIBHDHOMERUN_API bool_t hdhomerun_sock_leave_multicast_group(struct hdhomerun_sock_t *sock, uint32_t multicast_ip, uint32_t local_ip);
extern LIBTYPE bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse); extern LIBHDHOMERUN_API bool_t hdhomerun_sock_bind(struct hdhomerun_sock_t *sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse);
extern LIBTYPE bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout); extern LIBHDHOMERUN_API bool_t hdhomerun_sock_connect(struct hdhomerun_sock_t *sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout);
extern LIBTYPE bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout); extern LIBHDHOMERUN_API bool_t hdhomerun_sock_send(struct hdhomerun_sock_t *sock, const void *data, size_t length, uint64_t timeout);
extern LIBTYPE bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout); extern LIBHDHOMERUN_API bool_t hdhomerun_sock_sendto(struct hdhomerun_sock_t *sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout);
extern LIBTYPE bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout); extern LIBHDHOMERUN_API bool_t hdhomerun_sock_recv(struct hdhomerun_sock_t *sock, void *data, size_t *length, uint64_t timeout);
extern LIBTYPE bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout); extern LIBHDHOMERUN_API bool_t hdhomerun_sock_recvfrom(struct hdhomerun_sock_t *sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_sock_posix.c * hdhomerun_sock_posix.c
* *
* Copyright © 2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2010-2016 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -18,22 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/*
* Implementation notes:
*
* API specifies timeout for each operation (or zero for non-blocking).
*
* It is not possible to rely on the OS socket timeout as this will fail to
* detect the command-response situation where data is sent successfully and
* the other end chooses not to send a response (other than the TCP ack).
*
* The select() cannot be used with high socket numbers (typically max 1024)
* so the code works as follows:
* - Use non-blocking sockets to allow operation without select.
* - Use select where safe (low socket numbers).
* - Poll with short sleep when select cannot be used safely.
*/
#include "hdhomerun.h" #include "hdhomerun.h"
#include <net/if.h> #include <net/if.h>
@ -51,10 +35,14 @@
#define MSG_NOSIGNAL 0 #define MSG_NOSIGNAL 0
#endif #endif
struct hdhomerun_sock_t {
int sock;
};
int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count) int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count)
{ {
int sock = socket(AF_INET, SOCK_DGRAM, 0); int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == HDHOMERUN_SOCK_INVALID) { if (sock == -1) {
return -1; return -1;
} }
@ -77,7 +65,7 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int
return -1; return -1;
} }
if (ifc.ifc_len < ifreq_buffer_size) { if (ifc.ifc_len < (int)ifreq_buffer_size) {
break; break;
} }
@ -139,49 +127,83 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int
return count; return count;
} }
hdhomerun_sock_t hdhomerun_sock_create_udp(void) static struct hdhomerun_sock_t *hdhomerun_sock_create_internal(int protocol)
{ {
struct hdhomerun_sock_t *sock = (struct hdhomerun_sock_t *)calloc(1, sizeof(struct hdhomerun_sock_t));
if (!sock) {
return NULL;
}
/* Create socket. */ /* Create socket. */
hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_DGRAM, 0); sock->sock = socket(AF_INET, protocol, 0);
if (sock == -1) { if (sock->sock == -1) {
return HDHOMERUN_SOCK_INVALID; free(sock);
return NULL;
} }
/* Set non-blocking */ /* Set non-blocking */
if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) { if (fcntl(sock->sock, F_SETFL, O_NONBLOCK) != 0) {
close(sock); hdhomerun_sock_destroy(sock);
return HDHOMERUN_SOCK_INVALID; return NULL;
}
/* Configure socket not to generate pipe-error signal (BSD/OSX). */
#if defined(SO_NOSIGPIPE)
int set = 1;
setsockopt(sock->sock, SOL_SOCKET, SO_NOSIGPIPE, (char *)&set, sizeof(set));
#endif
/* Success. */
return sock;
}
struct hdhomerun_sock_t *hdhomerun_sock_create_udp(void)
{
struct hdhomerun_sock_t *sock = hdhomerun_sock_create_internal(SOCK_DGRAM);
if (!sock) {
return NULL;
} }
/* Allow broadcast. */ /* Allow broadcast. */
int sock_opt = 1; int sock_opt = 1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt)); setsockopt(sock->sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));
/* Success. */ /* Success. */
return sock; return sock;
} }
hdhomerun_sock_t hdhomerun_sock_create_tcp(void) struct hdhomerun_sock_t *hdhomerun_sock_create_tcp(void)
{ {
/* Create socket. */ return hdhomerun_sock_create_internal(SOCK_STREAM);
hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
return HDHOMERUN_SOCK_INVALID;
}
/* Set non-blocking */
if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) {
close(sock);
return HDHOMERUN_SOCK_INVALID;
}
/* Success. */
return sock;
} }
void hdhomerun_sock_destroy(hdhomerun_sock_t sock) void hdhomerun_sock_destroy(struct hdhomerun_sock_t *sock)
{ {
close(sock); close(sock->sock);
free(sock);
}
void hdhomerun_sock_stop(struct hdhomerun_sock_t *sock)
{
shutdown(sock->sock, SHUT_RDWR);
}
void hdhomerun_sock_set_send_buffer_size(struct hdhomerun_sock_t *sock, size_t size)
{
int size_opt = (int)size;
setsockopt(sock->sock, SOL_SOCKET, SO_SNDBUF, (char *)&size_opt, sizeof(size_opt));
}
void hdhomerun_sock_set_recv_buffer_size(struct hdhomerun_sock_t *sock, size_t size)
{
int size_opt = (int)size;
setsockopt(sock->sock, SOL_SOCKET, SO_RCVBUF, (char *)&size_opt, sizeof(size_opt));
}
void hdhomerun_sock_set_allow_reuse(struct hdhomerun_sock_t *sock)
{
int sock_opt = 1;
setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt));
} }
int hdhomerun_sock_getlasterror(void) int hdhomerun_sock_getlasterror(void)
@ -189,43 +211,43 @@ int hdhomerun_sock_getlasterror(void)
return errno; return errno;
} }
uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock) uint32_t hdhomerun_sock_getsockname_addr(struct hdhomerun_sock_t *sock)
{ {
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
socklen_t sockaddr_size = sizeof(sock_addr); socklen_t sockaddr_size = sizeof(sock_addr);
if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) { if (getsockname(sock->sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
return 0; return 0;
} }
return ntohl(sock_addr.sin_addr.s_addr); return ntohl(sock_addr.sin_addr.s_addr);
} }
uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock) uint16_t hdhomerun_sock_getsockname_port(struct hdhomerun_sock_t *sock)
{ {
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
socklen_t sockaddr_size = sizeof(sock_addr); socklen_t sockaddr_size = sizeof(sock_addr);
if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) { if (getsockname(sock->sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
return 0; return 0;
} }
return ntohs(sock_addr.sin_port); return ntohs(sock_addr.sin_port);
} }
uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock) uint32_t hdhomerun_sock_getpeername_addr(struct hdhomerun_sock_t *sock)
{ {
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
socklen_t sockaddr_size = sizeof(sock_addr); socklen_t sockaddr_size = sizeof(sock_addr);
if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) { if (getpeername(sock->sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
return 0; return 0;
} }
return ntohl(sock_addr.sin_addr.s_addr); return ntohl(sock_addr.sin_addr.s_addr);
} }
uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name) uint32_t hdhomerun_sock_getaddrinfo_addr(struct hdhomerun_sock_t *sock, const char *name)
{ {
struct addrinfo hints; struct addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
@ -245,38 +267,38 @@ uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name
return addr; return addr;
} }
bool_t hdhomerun_sock_join_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip) bool_t hdhomerun_sock_join_multicast_group(struct hdhomerun_sock_t *sock, uint32_t multicast_ip, uint32_t local_ip)
{ {
struct ip_mreq imr; struct ip_mreq imr;
memset(&imr, 0, sizeof(imr)); memset(&imr, 0, sizeof(imr));
imr.imr_multiaddr.s_addr = htonl(multicast_ip); imr.imr_multiaddr.s_addr = htonl(multicast_ip);
imr.imr_interface.s_addr = htonl(local_ip); imr.imr_interface.s_addr = htonl(local_ip);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) { if (setsockopt(sock->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
bool_t hdhomerun_sock_leave_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip) bool_t hdhomerun_sock_leave_multicast_group(struct hdhomerun_sock_t *sock, uint32_t multicast_ip, uint32_t local_ip)
{ {
struct ip_mreq imr; struct ip_mreq imr;
memset(&imr, 0, sizeof(imr)); memset(&imr, 0, sizeof(imr));
imr.imr_multiaddr.s_addr = htonl(multicast_ip); imr.imr_multiaddr.s_addr = htonl(multicast_ip);
imr.imr_interface.s_addr = htonl(local_ip); imr.imr_interface.s_addr = htonl(local_ip);
if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) { if (setsockopt(sock->sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse) bool_t hdhomerun_sock_bind(struct hdhomerun_sock_t *sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse)
{ {
int sock_opt = allow_reuse; int sock_opt = allow_reuse;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt)); setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt));
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr)); memset(&sock_addr, 0, sizeof(sock_addr));
@ -284,39 +306,14 @@ bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t
sock_addr.sin_addr.s_addr = htonl(local_addr); sock_addr.sin_addr.s_addr = htonl(local_addr);
sock_addr.sin_port = htons(local_port); sock_addr.sin_port = htons(local_port);
if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { if (bind(sock->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static bool_t hdhomerun_sock_wait_for_event(hdhomerun_sock_t sock, short event_type, uint64_t stop_time) bool_t hdhomerun_sock_connect(struct hdhomerun_sock_t *sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout)
{
uint64_t current_time = getcurrenttime();
if (current_time >= stop_time) {
return FALSE;
}
struct pollfd poll_event;
poll_event.fd = sock;
poll_event.events = event_type;
poll_event.revents = 0;
uint64_t timeout = stop_time - current_time;
if (poll(&poll_event, 1, (int)timeout) <= 0) {
return FALSE;
}
if ((poll_event.revents & event_type) == 0) {
return FALSE;
}
return TRUE;
}
bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout)
{ {
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr)); memset(&sock_addr, 0, sizeof(sock_addr));
@ -324,128 +321,224 @@ bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint1
sock_addr.sin_addr.s_addr = htonl(remote_addr); sock_addr.sin_addr.s_addr = htonl(remote_addr);
sock_addr.sin_port = htons(remote_port); sock_addr.sin_port = htons(remote_port);
if (connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { if (connect(sock->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) { if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE; return FALSE;
} }
} }
uint64_t stop_time = getcurrenttime() + timeout; struct pollfd poll_event;
return hdhomerun_sock_wait_for_event(sock, POLLOUT, stop_time); poll_event.fd = sock->sock;
poll_event.events = POLLOUT;
poll_event.revents = 0;
if (poll(&poll_event, 1, (int)timeout) <= 0) {
return FALSE;
}
if ((poll_event.revents & POLLOUT) == 0) {
return FALSE;
}
return TRUE;
} }
bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout) bool_t hdhomerun_sock_send(struct hdhomerun_sock_t *sock, const void *data, size_t length, uint64_t timeout)
{ {
uint64_t stop_time = getcurrenttime() + timeout;
const uint8_t *ptr = (const uint8_t *)data; const uint8_t *ptr = (const uint8_t *)data;
int ret = send(sock->sock, ptr, length, MSG_NOSIGNAL);
while (1) { if (ret >= length) {
int ret = send(sock, ptr, length, MSG_NOSIGNAL);
if (ret <= 0) {
if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE;
}
if (!hdhomerun_sock_wait_for_event(sock, POLLOUT, stop_time)) {
return FALSE;
}
continue;
}
if (ret < (int)length) {
ptr += ret;
length -= ret;
continue;
}
return TRUE; return TRUE;
} }
}
bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout) if ((ret < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
{ return FALSE;
uint64_t stop_time = getcurrenttime() + timeout; }
const uint8_t *ptr = (const uint8_t *)data;
if (ret > 0) {
while (1) { ptr += ret;
struct sockaddr_in sock_addr; length -= ret;
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = htonl(remote_addr);
sock_addr.sin_port = htons(remote_port);
int ret = sendto(sock, ptr, length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (ret <= 0) {
if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE;
}
if (!hdhomerun_sock_wait_for_event(sock, POLLOUT, stop_time)) {
return FALSE;
}
continue;
}
if (ret < (int)length) {
ptr += ret;
length -= ret;
continue;
}
return TRUE;
} }
}
bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout)
{
uint64_t stop_time = getcurrenttime() + timeout; uint64_t stop_time = getcurrenttime() + timeout;
while (1) { while (1) {
int ret = recv(sock, data, *length, 0); struct pollfd poll_event;
if (ret < 0) { poll_event.fd = sock->sock;
if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) { poll_event.events = POLLOUT;
return FALSE; poll_event.revents = 0;
}
if (!hdhomerun_sock_wait_for_event(sock, POLLIN, stop_time)) {
return FALSE;
}
continue;
}
if (ret == 0) { if (poll(&poll_event, 1, (int)timeout) <= 0) {
return FALSE; return FALSE;
} }
if ((poll_event.revents & POLLOUT) == 0) {
return FALSE;
}
ret = send(sock->sock, ptr, length, MSG_NOSIGNAL);
if (ret >= length) {
return TRUE;
}
if ((ret < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE;
}
if (ret > 0) {
ptr += ret;
length -= ret;
}
uint64_t current_time = getcurrenttime();
if (current_time >= stop_time) {
return FALSE;
}
timeout = stop_time - current_time;
}
}
bool_t hdhomerun_sock_sendto(struct hdhomerun_sock_t *sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout)
{
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(remote_addr);
sock_addr.sin_port = htons(remote_port);
const uint8_t *ptr = (const uint8_t *)data;
int ret = sendto(sock->sock, ptr, length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (ret >= length) {
return TRUE;
}
if ((ret < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE;
}
if (ret > 0) {
ptr += ret;
length -= ret;
}
uint64_t stop_time = getcurrenttime() + timeout;
while (1) {
struct pollfd poll_event;
poll_event.fd = sock->sock;
poll_event.events = POLLOUT;
poll_event.revents = 0;
if (poll(&poll_event, 1, (int)timeout) <= 0) {
return FALSE;
}
if ((poll_event.revents & POLLOUT) == 0) {
return FALSE;
}
ret = sendto(sock->sock, ptr, length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (ret >= length) {
return TRUE;
}
if ((ret < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE;
}
if (ret > 0) {
ptr += ret;
length -= ret;
}
uint64_t current_time = getcurrenttime();
if (current_time >= stop_time) {
return FALSE;
}
timeout = stop_time - current_time;
}
}
bool_t hdhomerun_sock_recv(struct hdhomerun_sock_t *sock, void *data, size_t *length, uint64_t timeout)
{
int ret = recv(sock->sock, data, *length, 0);
if (ret > 0) {
*length = ret; *length = ret;
return TRUE; return TRUE;
} }
if (ret == 0) {
return FALSE;
}
if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE;
}
struct pollfd poll_event;
poll_event.fd = sock->sock;
poll_event.events = POLLIN;
poll_event.revents = 0;
if (poll(&poll_event, 1, (int)timeout) <= 0) {
return FALSE;
}
if ((poll_event.revents & POLLIN) == 0) {
return FALSE;
}
ret = recv(sock->sock, data, *length, 0);
if (ret > 0) {
*length = ret;
return TRUE;
}
return FALSE;
} }
bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout) bool_t hdhomerun_sock_recvfrom(struct hdhomerun_sock_t *sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout)
{ {
uint64_t stop_time = getcurrenttime() + timeout; struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr));
while (1) { socklen_t sockaddr_size = sizeof(sock_addr);
struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr));
socklen_t sockaddr_size = sizeof(sock_addr);
int ret = recvfrom(sock, data, *length, 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
if (ret < 0) {
if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE;
}
if (!hdhomerun_sock_wait_for_event(sock, POLLIN, stop_time)) {
return FALSE;
}
continue;
}
if (ret == 0) {
return FALSE;
}
int ret = recvfrom(sock->sock, data, *length, 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
if (ret > 0) {
*remote_addr = ntohl(sock_addr.sin_addr.s_addr); *remote_addr = ntohl(sock_addr.sin_addr.s_addr);
*remote_port = ntohs(sock_addr.sin_port); *remote_port = ntohs(sock_addr.sin_port);
*length = ret; *length = ret;
return TRUE; return TRUE;
} }
if (ret == 0) {
return FALSE;
}
if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
return FALSE;
}
struct pollfd poll_event;
poll_event.fd = sock->sock;
poll_event.events = POLLIN;
poll_event.revents = 0;
if (poll(&poll_event, 1, (int)timeout) <= 0) {
return FALSE;
}
if ((poll_event.revents & POLLIN) == 0) {
return FALSE;
}
ret = recvfrom(sock->sock, data, *length, 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
if (ret > 0) {
*remote_addr = ntohl(sock_addr.sin_addr.s_addr);
*remote_port = ntohs(sock_addr.sin_port);
*length = ret;
return TRUE;
}
return FALSE;
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_sock_windows.c * hdhomerun_sock_windows.c
* *
* Copyright © 2010 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2010-2016 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public
@ -18,25 +18,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/*
* Implementation notes:
*
* API specifies timeout for each operation (or zero for non-blocking).
*
* It is not possible to rely on the OS socket timeout as this will fail to
* detect the command-response situation where data is sent successfully and
* the other end chooses not to send a response (other than the TCP ack).
*
* Windows supports select() however native WSA events are used to:
* - avoid problems with socket numbers above 1024.
* - wait without allowing other events handlers to run (important for use
* with win7 WMC).
*/
#include "hdhomerun.h" #include "hdhomerun.h"
#include <windows.h>
#include <iphlpapi.h> #include <iphlpapi.h>
struct hdhomerun_sock_t {
SOCKET sock;
HANDLE event;
long events_selected;
};
#if !defined(_WINRT)
int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count) int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count)
{ {
PIP_ADAPTER_INFO AdapterInfo; PIP_ADAPTER_INFO AdapterInfo;
@ -99,52 +90,91 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int
free(AdapterInfo); free(AdapterInfo);
return count; return count;
} }
#endif
hdhomerun_sock_t hdhomerun_sock_create_udp(void) static struct hdhomerun_sock_t *hdhomerun_sock_create_internal(int protocol)
{ {
struct hdhomerun_sock_t *sock = (struct hdhomerun_sock_t *)calloc(1, sizeof(struct hdhomerun_sock_t));
if (!sock) {
return NULL;
}
/* Create socket. */ /* Create socket. */
hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_DGRAM, 0); sock->sock = socket(AF_INET, protocol, 0);
if (sock == -1) { if (sock->sock == INVALID_SOCKET) {
return HDHOMERUN_SOCK_INVALID; free(sock);
return NULL;
} }
/* Set non-blocking */ /* Set non-blocking */
unsigned long mode = 1; unsigned long mode = 1;
if (ioctlsocket(sock, FIONBIO, &mode) != 0) { if (ioctlsocket(sock->sock, FIONBIO, &mode) != 0) {
closesocket(sock); hdhomerun_sock_destroy(sock);
return HDHOMERUN_SOCK_INVALID; return NULL;
}
/* Event */
sock->event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!sock->event) {
hdhomerun_sock_destroy(sock);
return NULL;
}
/* Success. */
return sock;
}
struct hdhomerun_sock_t *hdhomerun_sock_create_udp(void)
{
struct hdhomerun_sock_t *sock = hdhomerun_sock_create_internal(SOCK_DGRAM);
if (!sock) {
return NULL;
} }
/* Allow broadcast. */ /* Allow broadcast. */
int sock_opt = 1; int sock_opt = 1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt)); setsockopt(sock->sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));
/* Success. */ /* Success. */
return sock; return sock;
} }
hdhomerun_sock_t hdhomerun_sock_create_tcp(void) struct hdhomerun_sock_t *hdhomerun_sock_create_tcp(void)
{ {
/* Create socket. */ return hdhomerun_sock_create_internal(SOCK_STREAM);
hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
return HDHOMERUN_SOCK_INVALID;
}
/* Set non-blocking */
unsigned long mode = 1;
if (ioctlsocket(sock, FIONBIO, &mode) != 0) {
closesocket(sock);
return HDHOMERUN_SOCK_INVALID;
}
/* Success. */
return sock;
} }
void hdhomerun_sock_destroy(hdhomerun_sock_t sock) void hdhomerun_sock_destroy(struct hdhomerun_sock_t *sock)
{ {
closesocket(sock); if (sock->event) {
CloseHandle(sock->event);
}
closesocket(sock->sock);
free(sock);
}
void hdhomerun_sock_stop(struct hdhomerun_sock_t *sock)
{
shutdown(sock->sock, SD_BOTH);
}
void hdhomerun_sock_set_send_buffer_size(struct hdhomerun_sock_t *sock, size_t size)
{
int size_opt = (int)size;
setsockopt(sock->sock, SOL_SOCKET, SO_SNDBUF, (char *)&size_opt, sizeof(size_opt));
}
void hdhomerun_sock_set_recv_buffer_size(struct hdhomerun_sock_t *sock, size_t size)
{
int size_opt = (int)size;
setsockopt(sock->sock, SOL_SOCKET, SO_RCVBUF, (char *)&size_opt, sizeof(size_opt));
}
void hdhomerun_sock_set_allow_reuse(struct hdhomerun_sock_t *sock)
{
int sock_opt = 1;
setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt));
} }
int hdhomerun_sock_getlasterror(void) int hdhomerun_sock_getlasterror(void)
@ -152,43 +182,43 @@ int hdhomerun_sock_getlasterror(void)
return WSAGetLastError(); return WSAGetLastError();
} }
uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock) uint32_t hdhomerun_sock_getsockname_addr(struct hdhomerun_sock_t *sock)
{ {
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
int sockaddr_size = sizeof(sock_addr); int sockaddr_size = sizeof(sock_addr);
if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) { if (getsockname(sock->sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
return 0; return 0;
} }
return ntohl(sock_addr.sin_addr.s_addr); return ntohl(sock_addr.sin_addr.s_addr);
} }
uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock) uint16_t hdhomerun_sock_getsockname_port(struct hdhomerun_sock_t *sock)
{ {
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
int sockaddr_size = sizeof(sock_addr); int sockaddr_size = sizeof(sock_addr);
if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) { if (getsockname(sock->sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
return 0; return 0;
} }
return ntohs(sock_addr.sin_port); return ntohs(sock_addr.sin_port);
} }
uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock) uint32_t hdhomerun_sock_getpeername_addr(struct hdhomerun_sock_t *sock)
{ {
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
int sockaddr_size = sizeof(sock_addr); int sockaddr_size = sizeof(sock_addr);
if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) { if (getpeername(sock->sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
return 0; return 0;
} }
return ntohl(sock_addr.sin_addr.s_addr); return ntohl(sock_addr.sin_addr.s_addr);
} }
uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name) uint32_t hdhomerun_sock_getaddrinfo_addr(struct hdhomerun_sock_t *sock, const char *name)
{ {
struct addrinfo hints; struct addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
@ -208,38 +238,38 @@ uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name
return addr; return addr;
} }
bool_t hdhomerun_sock_join_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip) bool_t hdhomerun_sock_join_multicast_group(struct hdhomerun_sock_t *sock, uint32_t multicast_ip, uint32_t local_ip)
{ {
struct ip_mreq imr; struct ip_mreq imr;
memset(&imr, 0, sizeof(imr)); memset(&imr, 0, sizeof(imr));
imr.imr_multiaddr.s_addr = htonl(multicast_ip); imr.imr_multiaddr.s_addr = htonl(multicast_ip);
imr.imr_interface.s_addr = htonl(local_ip); imr.imr_interface.s_addr = htonl(local_ip);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) { if (setsockopt(sock->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
bool_t hdhomerun_sock_leave_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip) bool_t hdhomerun_sock_leave_multicast_group(struct hdhomerun_sock_t *sock, uint32_t multicast_ip, uint32_t local_ip)
{ {
struct ip_mreq imr; struct ip_mreq imr;
memset(&imr, 0, sizeof(imr)); memset(&imr, 0, sizeof(imr));
imr.imr_multiaddr.s_addr = htonl(multicast_ip); imr.imr_multiaddr.s_addr = htonl(multicast_ip);
imr.imr_interface.s_addr = htonl(local_ip); imr.imr_interface.s_addr = htonl(local_ip);
if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) { if (setsockopt(sock->sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse) bool_t hdhomerun_sock_bind(struct hdhomerun_sock_t *sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse)
{ {
int sock_opt = allow_reuse; int sock_opt = allow_reuse;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt)); setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt));
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr)); memset(&sock_addr, 0, sizeof(sock_addr));
@ -247,204 +277,202 @@ bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t
sock_addr.sin_addr.s_addr = htonl(local_addr); sock_addr.sin_addr.s_addr = htonl(local_addr);
sock_addr.sin_port = htons(local_port); sock_addr.sin_port = htons(local_port);
if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { if (bind(sock->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout) bool_t hdhomerun_sock_event_select(struct hdhomerun_sock_t *sock, long events)
{ {
/* Connect (non-blocking). */ if (sock->events_selected != events) {
if (WSAEventSelect(sock->sock, sock->event, events) == SOCKET_ERROR) {
return FALSE;
}
sock->events_selected = events;
}
ResetEvent(sock->event);
return TRUE;
}
bool_t hdhomerun_sock_connect(struct hdhomerun_sock_t *sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout)
{
if (!hdhomerun_sock_event_select(sock, FD_WRITE | FD_CLOSE)) {
return FALSE;
}
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr)); memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET; sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = htonl(remote_addr); sock_addr.sin_addr.s_addr = htonl(remote_addr);
sock_addr.sin_port = htons(remote_port); sock_addr.sin_port = htons(remote_port);
if (connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { if (connect(sock->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
if (WSAGetLastError() != WSAEWOULDBLOCK) { if (WSAGetLastError() != WSAEWOULDBLOCK) {
return FALSE; return FALSE;
} }
} }
/* Wait for connect to complete (both success and failure will signal). */ DWORD wait_ret = WaitForSingleObjectEx(sock->event, (DWORD)timeout, FALSE);
WSAEVENT wsa_event = WSACreateEvent(); if (wait_ret != WAIT_OBJECT_0) {
if (wsa_event == WSA_INVALID_EVENT) {
return FALSE; return FALSE;
} }
if (WSAEventSelect(sock, wsa_event, FD_WRITE | FD_CLOSE) == SOCKET_ERROR) { WSANETWORKEVENTS network_events;
WSACloseEvent(wsa_event); if (WSAEnumNetworkEvents(sock->sock, sock->event, &network_events) == SOCKET_ERROR) {
return FALSE; return FALSE;
} }
if ((network_events.lNetworkEvents & FD_WRITE) == 0) {
DWORD ret = WaitForSingleObjectEx(wsa_event, (DWORD)timeout, FALSE);
WSACloseEvent(wsa_event);
if (ret != WAIT_OBJECT_0) {
return FALSE; return FALSE;
} }
if (network_events.lNetworkEvents & FD_CLOSE) {
/* Detect success/failure. */
wsa_event = WSACreateEvent();
if (wsa_event == WSA_INVALID_EVENT) {
return FALSE;
}
if (WSAEventSelect(sock, wsa_event, FD_CLOSE) == SOCKET_ERROR) {
WSACloseEvent(wsa_event);
return FALSE;
}
ret = WaitForSingleObjectEx(wsa_event, 0, FALSE);
WSACloseEvent(wsa_event);
if (ret == WAIT_OBJECT_0) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static bool_t hdhomerun_sock_wait_for_event(hdhomerun_sock_t sock, long event_type, uint64_t stop_time) bool_t hdhomerun_sock_send(struct hdhomerun_sock_t *sock, const void *data, size_t length, uint64_t timeout)
{ {
uint64_t current_time = getcurrenttime(); if (!hdhomerun_sock_event_select(sock, FD_WRITE | FD_CLOSE)) {
if (current_time >= stop_time) {
return FALSE; return FALSE;
} }
WSAEVENT wsa_event = WSACreateEvent();
if (wsa_event == WSA_INVALID_EVENT) {
return FALSE;
}
if (WSAEventSelect(sock, wsa_event, event_type) == SOCKET_ERROR) {
WSACloseEvent(wsa_event);
return FALSE;
}
DWORD ret = WaitForSingleObjectEx(wsa_event, (DWORD)(stop_time - current_time), FALSE);
WSACloseEvent(wsa_event);
if (ret != WAIT_OBJECT_0) {
return FALSE;
}
return TRUE;
}
bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout)
{
uint64_t stop_time = getcurrenttime() + timeout; uint64_t stop_time = getcurrenttime() + timeout;
const uint8_t *ptr = (uint8_t *)data; const uint8_t *ptr = (uint8_t *)data;
while (1) { while (1) {
int ret = send(sock, (char *)ptr, (int)length, 0); int ret = send(sock->sock, (char *)ptr, (int)length, 0);
if (ret <= 0) { if (ret >= (int)length) {
if (WSAGetLastError() != WSAEWOULDBLOCK) { return TRUE;
return FALSE;
}
if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) {
return FALSE;
}
continue;
} }
if (ret < (int)length) { if ((ret == SOCKET_ERROR) && (WSAGetLastError() != WSAEWOULDBLOCK)) {
ptr += ret;
length -= ret;
continue;
}
return TRUE;
}
}
bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout)
{
uint64_t stop_time = getcurrenttime() + timeout;
const uint8_t *ptr = (uint8_t *)data;
while (1) {
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(remote_addr);
sock_addr.sin_port = htons(remote_port);
int ret = sendto(sock, (char *)ptr, (int)length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (ret <= 0) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
return FALSE;
}
if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) {
return FALSE;
}
continue;
}
if (ret < (int)length) {
ptr += ret;
length -= ret;
continue;
}
return TRUE;
}
}
bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout)
{
uint64_t stop_time = getcurrenttime() + timeout;
while (1) {
int ret = recv(sock, (char *)data, (int)(*length), 0);
if (ret < 0) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
return FALSE;
}
if (!hdhomerun_sock_wait_for_event(sock, FD_READ | FD_CLOSE, stop_time)) {
return FALSE;
}
continue;
}
if (ret == 0) {
return FALSE; return FALSE;
} }
if (ret > 0) {
ptr += ret;
length -= ret;
}
uint64_t current_time = getcurrenttime();
if (current_time >= stop_time) {
return FALSE;
}
if (WaitForSingleObjectEx(sock->event, (DWORD)(stop_time - current_time), FALSE) != WAIT_OBJECT_0) {
return FALSE;
}
}
}
bool_t hdhomerun_sock_sendto(struct hdhomerun_sock_t *sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout)
{
if (!hdhomerun_sock_event_select(sock, FD_WRITE | FD_CLOSE)) {
return FALSE;
}
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(remote_addr);
sock_addr.sin_port = htons(remote_port);
int ret = sendto(sock->sock, (char *)data, (int)length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (ret >= (int)length) {
return TRUE;
}
if (ret >= 0) {
return FALSE;
}
if (WSAGetLastError() != WSAEWOULDBLOCK) {
return FALSE;
}
if (WaitForSingleObjectEx(sock->event, (DWORD)timeout, FALSE) != WAIT_OBJECT_0) {
return FALSE;
}
ret = sendto(sock->sock, (char *)data, (int)length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (ret >= (int)length) {
return TRUE;
}
return FALSE;
}
bool_t hdhomerun_sock_recv(struct hdhomerun_sock_t *sock, void *data, size_t *length, uint64_t timeout)
{
if (!hdhomerun_sock_event_select(sock, FD_READ | FD_CLOSE)) {
return FALSE;
}
int ret = recv(sock->sock, (char *)data, (int)(*length), 0);
if (ret > 0) {
*length = ret; *length = ret;
return TRUE; return TRUE;
} }
if (ret == 0) {
return FALSE;
}
if (WSAGetLastError() != WSAEWOULDBLOCK) {
return FALSE;
}
if (WaitForSingleObjectEx(sock->event, (DWORD)timeout, FALSE) != WAIT_OBJECT_0) {
return FALSE;
}
ret = recv(sock->sock, (char *)data, (int)(*length), 0);
if (ret > 0) {
*length = ret;
return TRUE;
}
return FALSE;
} }
bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout) bool_t hdhomerun_sock_recvfrom(struct hdhomerun_sock_t *sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout)
{ {
uint64_t stop_time = getcurrenttime() + timeout; if (!hdhomerun_sock_event_select(sock, FD_READ | FD_CLOSE)) {
return FALSE;
}
while (1) { struct sockaddr_in sock_addr;
struct sockaddr_in sock_addr; memset(&sock_addr, 0, sizeof(sock_addr));
memset(&sock_addr, 0, sizeof(sock_addr)); int sockaddr_size = sizeof(sock_addr);
int sockaddr_size = sizeof(sock_addr);
int ret = recvfrom(sock, (char *)data, (int)(*length), 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
if (ret < 0) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
return FALSE;
}
if (!hdhomerun_sock_wait_for_event(sock, FD_READ | FD_CLOSE, stop_time)) {
return FALSE;
}
continue;
}
if (ret == 0) {
return FALSE;
}
int ret = recvfrom(sock->sock, (char *)data, (int)(*length), 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
if (ret > 0) {
*remote_addr = ntohl(sock_addr.sin_addr.s_addr); *remote_addr = ntohl(sock_addr.sin_addr.s_addr);
*remote_port = ntohs(sock_addr.sin_port); *remote_port = ntohs(sock_addr.sin_port);
*length = ret; *length = ret;
return TRUE; return TRUE;
} }
if (ret == 0) {
return FALSE;
}
if (WSAGetLastError() != WSAEWOULDBLOCK) {
return FALSE;
}
if (WaitForSingleObjectEx(sock->event, (DWORD)timeout, FALSE) != WAIT_OBJECT_0) {
return FALSE;
}
ret = recvfrom(sock->sock, (char *)data, (int)(*length), 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
if (ret > 0) {
*remote_addr = ntohl(sock_addr.sin_addr.s_addr);
*remote_port = ntohs(sock_addr.sin_port);
*length = ret;
return TRUE;
}
return FALSE;
} }

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_types.h * hdhomerun_types.h
* *
* Copyright © 2008-2009 Silicondust USA Inc. <www.silicondust.com>. * Copyright © 2008-2015 Silicondust USA Inc. <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 * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_video.c * hdhomerun_video.c
* *
* Copyright © 2006-2010 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -23,7 +23,7 @@
struct hdhomerun_video_sock_t { struct hdhomerun_video_sock_t {
pthread_mutex_t lock; pthread_mutex_t lock;
struct hdhomerun_debug_t *dbg; struct hdhomerun_debug_t *dbg;
hdhomerun_sock_t sock; struct hdhomerun_sock_t *sock;
volatile size_t head; volatile size_t head;
volatile size_t tail; volatile size_t tail;
@ -56,7 +56,6 @@ struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, bool
} }
vs->dbg = dbg; vs->dbg = dbg;
vs->sock = HDHOMERUN_SOCK_INVALID;
pthread_mutex_init(&vs->lock, NULL); pthread_mutex_init(&vs->lock, NULL);
/* Reset sequence tracking. */ /* Reset sequence tracking. */
@ -79,14 +78,13 @@ struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, bool
/* Create socket. */ /* Create socket. */
vs->sock = hdhomerun_sock_create_udp(); vs->sock = hdhomerun_sock_create_udp();
if (vs->sock == HDHOMERUN_SOCK_INVALID) { if (!vs->sock) {
hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to allocate socket\n"); hdhomerun_debug_printf(dbg, "hdhomerun_video_create: failed to allocate socket\n");
goto error; goto error;
} }
/* Expand socket buffer size. */ /* Expand socket buffer size. */
int rx_size = 1024 * 1024; hdhomerun_sock_set_recv_buffer_size(vs->sock, 1024 * 1024);
setsockopt(vs->sock, SOL_SOCKET, SO_RCVBUF, (char *)&rx_size, sizeof(rx_size));
/* Bind socket. */ /* Bind socket. */
if (!hdhomerun_sock_bind(vs->sock, INADDR_ANY, listen_port, allow_port_reuse)) { if (!hdhomerun_sock_bind(vs->sock, INADDR_ANY, listen_port, allow_port_reuse)) {
@ -104,7 +102,7 @@ struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, bool
return vs; return vs;
error: error:
if (vs->sock != HDHOMERUN_SOCK_INVALID) { if (vs->sock) {
hdhomerun_sock_destroy(vs->sock); hdhomerun_sock_destroy(vs->sock);
} }
if (vs->buffer) { if (vs->buffer) {
@ -125,7 +123,7 @@ void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs)
free(vs); free(vs);
} }
hdhomerun_sock_t hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs) struct hdhomerun_sock_t *hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs)
{ {
return vs->sock; return vs->sock;
} }
@ -281,7 +279,7 @@ static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg)
pthread_mutex_unlock(&vs->lock); pthread_mutex_unlock(&vs->lock);
} }
return NULL; return THREAD_FUNC_RESULT;
} }
uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size) uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size)

View file

@ -1,7 +1,7 @@
/* /*
* hdhomerun_video.h * hdhomerun_video.h
* *
* Copyright © 2006 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -48,21 +48,21 @@ struct hdhomerun_video_stats_t {
* *
* When no longer needed, the socket should be destroyed by calling hdhomerun_control_destroy. * 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, bool_t allow_port_reuse, size_t buffer_size, struct hdhomerun_debug_t *dbg); extern LIBHDHOMERUN_API struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, bool_t allow_port_reuse, size_t buffer_size, struct hdhomerun_debug_t *dbg);
extern LIBTYPE void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs); extern LIBHDHOMERUN_API void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs);
/* /*
* Get the port the socket is listening on. * Get the port the socket is listening on.
* *
* Returns 16-bit port with native endianness, or 0 on error. * 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 LIBHDHOMERUN_API uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs);
/* /*
* Join/leave multicast group. * Join/leave multicast group.
*/ */
extern LIBTYPE int hdhomerun_video_join_multicast_group(struct hdhomerun_video_sock_t *vs, uint32_t multicast_ip, uint32_t local_ip); extern LIBHDHOMERUN_API int hdhomerun_video_join_multicast_group(struct hdhomerun_video_sock_t *vs, uint32_t multicast_ip, uint32_t local_ip);
extern LIBTYPE void hdhomerun_video_leave_multicast_group(struct hdhomerun_video_sock_t *vs, uint32_t multicast_ip, uint32_t local_ip); extern LIBHDHOMERUN_API void hdhomerun_video_leave_multicast_group(struct hdhomerun_video_sock_t *vs, uint32_t multicast_ip, uint32_t local_ip);
/* /*
* Read data from buffer. * Read data from buffer.
@ -81,23 +81,23 @@ extern LIBTYPE void hdhomerun_video_leave_multicast_group(struct hdhomerun_video
* The buffer is implemented as a ring buffer. It is possible for this function to return a small * 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. * 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 LIBHDHOMERUN_API uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size);
/* /*
* Flush the buffer. * Flush the buffer.
*/ */
extern LIBTYPE void hdhomerun_video_flush(struct hdhomerun_video_sock_t *vs); extern LIBHDHOMERUN_API void hdhomerun_video_flush(struct hdhomerun_video_sock_t *vs);
/* /*
* Debug print internal stats. * Debug print internal stats.
*/ */
extern LIBTYPE void hdhomerun_video_debug_print_stats(struct hdhomerun_video_sock_t *vs); extern LIBHDHOMERUN_API 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 LIBHDHOMERUN_API void hdhomerun_video_get_stats(struct hdhomerun_video_sock_t *vs, struct hdhomerun_video_stats_t *stats);
/* /*
* Internal use only. * Internal use only.
*/ */
extern LIBTYPE hdhomerun_sock_t hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs); extern LIBHDHOMERUN_API struct hdhomerun_sock_t *hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs);
#ifdef __cplusplus #ifdef __cplusplus
} }