mirror of
https://github.com/Silicondust/libhdhomerun
synced 2025-07-05 12:36:48 -07:00
libhdhomerun 20160130
This commit is contained in:
parent
a2475b9991
commit
8d861a8f0b
29 changed files with 916 additions and 725 deletions
27
README.md
27
README.md
|
@ -1,28 +1,11 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
Copyright © 2005-2016 Silicondust USA Inc. <www.silicondust.com>.
|
||||
|
||||
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:
|
||||
- pthread
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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_list_t;
|
||||
|
||||
extern LIBTYPE 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_from_country_source(const char *countrycode, const char *source, const char *supported);
|
||||
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 LIBTYPE 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 uint16_t hdhomerun_channel_entry_channel_number(struct hdhomerun_channel_entry_t *entry);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_entry_frequency(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 LIBTYPE void hdhomerun_channel_list_destroy(struct hdhomerun_channel_list_t *channel_list);
|
||||
extern LIBHDHOMERUN_API struct hdhomerun_channel_list_t *hdhomerun_channel_list_create(const char *channelmap);
|
||||
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 LIBTYPE 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 LIBTYPE 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 LIBTYPE uint32_t hdhomerun_channel_list_frequency_count(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 LIBHDHOMERUN_API 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_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_prev(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_list_total_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 LIBTYPE 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 LIBTYPE uint16_t hdhomerun_channel_frequency_to_number(struct hdhomerun_channel_list_t *channel_list, uint32_t frequency);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_frequency_round(uint32_t frequency, uint32_t resolution);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_frequency_round_normal(uint32_t frequency);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_channel_number_to_frequency(struct hdhomerun_channel_list_t *channel_list, uint16_t channel_number);
|
||||
extern LIBHDHOMERUN_API uint16_t hdhomerun_channel_frequency_to_number(struct hdhomerun_channel_list_t *channel_list, uint32_t frequency);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -29,12 +29,12 @@ extern "C" {
|
|||
|
||||
struct hdhomerun_channelscan_t;
|
||||
|
||||
extern LIBTYPE 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 struct hdhomerun_channelscan_t *channelscan_create(struct hdhomerun_device_t *hd, const char *channelmap);
|
||||
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 LIBTYPE 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 int channelscan_advance(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 LIBHDHOMERUN_API uint8_t channelscan_get_progress(struct hdhomerun_channelscan_t *scan);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -20,16 +20,6 @@
|
|||
|
||||
#include "hdhomerun.h"
|
||||
|
||||
/*
|
||||
* The console output format should be set to UTF-8, however in XP and Vista this breaks batch file processing.
|
||||
* Attempting to restore on exit fails to restore if the program is terminated by the user.
|
||||
* Solution - set the output format each printf.
|
||||
*/
|
||||
#if defined(__WINDOWS__)
|
||||
#define printf console_printf
|
||||
#define vprintf console_vprintf
|
||||
#endif
|
||||
|
||||
static const char *appname;
|
||||
|
||||
struct hdhomerun_device_t *hd;
|
||||
|
@ -413,7 +403,7 @@ static int cmd_save(const char *tuner_str, const char *filename)
|
|||
}
|
||||
|
||||
/* Windows - indicate activity to suppress auto sleep mode. */
|
||||
#if defined(__WINDOWS__)
|
||||
#if defined(_WIN32)
|
||||
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
|
||||
#endif
|
||||
|
||||
|
@ -625,7 +615,9 @@ static int main_cmd(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. */
|
||||
WORD wVersionRequested = MAKEWORD(2, 0);
|
||||
WSADATA wsaData;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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 actual_device_id;
|
||||
uint32_t actual_device_ip;
|
||||
hdhomerun_sock_t sock;
|
||||
struct hdhomerun_sock_t *sock;
|
||||
struct hdhomerun_debug_t *dbg;
|
||||
struct hdhomerun_pkt_t tx_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)
|
||||
{
|
||||
if (cs->sock == HDHOMERUN_SOCK_INVALID) {
|
||||
if (!cs->sock) {
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -65,7 +65,6 @@ struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, ui
|
|||
}
|
||||
|
||||
cs->dbg = dbg;
|
||||
cs->sock = HDHOMERUN_SOCK_INVALID;
|
||||
hdhomerun_control_set_device(cs, device_id, device_ip);
|
||||
|
||||
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)
|
||||
{
|
||||
if (cs->sock != HDHOMERUN_SOCK_INVALID) {
|
||||
if (cs->sock) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -103,7 +102,7 @@ static bool_t hdhomerun_control_connect_sock(struct hdhomerun_control_sock_t *cs
|
|||
|
||||
/* Create socket. */
|
||||
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());
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -216,7 +215,7 @@ static int hdhomerun_control_send_recv_internal(struct hdhomerun_control_sock_t
|
|||
|
||||
int i;
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (cs->sock == HDHOMERUN_SOCK_INVALID) {
|
||||
if (!cs->sock) {
|
||||
if (!hdhomerun_control_connect_sock(cs)) {
|
||||
hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: connect failed\n");
|
||||
return -1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
extern LIBTYPE struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, uint32_t device_ip, struct hdhomerun_debug_t *dbg);
|
||||
extern LIBTYPE void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs);
|
||||
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 LIBHDHOMERUN_API void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs);
|
||||
|
||||
/*
|
||||
* Get the actual device id or ip of the device.
|
||||
*
|
||||
* Returns 0 if the device id cannot be determined.
|
||||
*/
|
||||
extern LIBTYPE uint32_t hdhomerun_control_get_device_id(struct hdhomerun_control_sock_t *cs);
|
||||
extern LIBTYPE uint32_t hdhomerun_control_get_device_ip(struct hdhomerun_control_sock_t *cs);
|
||||
extern LIBTYPE uint32_t hdhomerun_control_get_device_id_requested(struct hdhomerun_control_sock_t *cs);
|
||||
extern LIBTYPE uint32_t hdhomerun_control_get_device_ip_requested(struct hdhomerun_control_sock_t *cs);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_control_get_device_id(struct hdhomerun_control_sock_t *cs);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_control_get_device_ip(struct hdhomerun_control_sock_t *cs);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_control_get_device_id_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.
|
||||
|
@ -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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
|
@ -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 -1 if a communication error occurs.
|
||||
*/
|
||||
extern LIBTYPE int hdhomerun_control_get(struct hdhomerun_control_sock_t *cs, const char *name, char **pvalue, char **perror);
|
||||
extern LIBTYPE int hdhomerun_control_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror);
|
||||
extern LIBTYPE int hdhomerun_control_set_with_lockkey(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, uint32_t lockkey, char **pvalue, char **perror);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_control_get(struct hdhomerun_control_sock_t *cs, const char *name, 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 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.
|
||||
|
@ -96,7 +96,7 @@ extern LIBTYPE int hdhomerun_control_set_with_lockkey(struct hdhomerun_control_s
|
|||
* Returns 0 if the upload was rejected.
|
||||
* Returns -1 if an error occurs.
|
||||
*/
|
||||
extern LIBTYPE int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -65,7 +65,7 @@ struct hdhomerun_debug_t
|
|||
|
||||
char *file_name;
|
||||
FILE *file_fp;
|
||||
hdhomerun_sock_t sock;
|
||||
struct hdhomerun_sock_t *sock;
|
||||
};
|
||||
|
||||
static THREAD_FUNC_PREFIX hdhomerun_debug_thread_execute(void *arg);
|
||||
|
@ -77,8 +77,6 @@ struct hdhomerun_debug_t *hdhomerun_debug_create(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
dbg->sock = HDHOMERUN_SOCK_INVALID;
|
||||
|
||||
pthread_mutex_init(&dbg->print_lock, NULL);
|
||||
pthread_mutex_init(&dbg->queue_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) {
|
||||
fclose(dbg->file_fp);
|
||||
}
|
||||
if (dbg->sock != HDHOMERUN_SOCK_INVALID) {
|
||||
if (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;
|
||||
}
|
||||
|
||||
if (dbg->sock != HDHOMERUN_SOCK_INVALID) {
|
||||
if (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 */
|
||||
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();
|
||||
if (current_time < dbg->connect_delay) {
|
||||
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->sock = hdhomerun_sock_create_tcp();
|
||||
if (dbg->sock == HDHOMERUN_SOCK_INVALID) {
|
||||
if (!dbg->sock) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -32,20 +32,20 @@ extern "C" {
|
|||
|
||||
struct hdhomerun_debug_t;
|
||||
|
||||
extern LIBTYPE struct hdhomerun_debug_t *hdhomerun_debug_create(void);
|
||||
extern LIBTYPE void hdhomerun_debug_destroy(struct hdhomerun_debug_t *dbg);
|
||||
extern LIBHDHOMERUN_API struct hdhomerun_debug_t *hdhomerun_debug_create(void);
|
||||
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 LIBTYPE 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 LIBTYPE void hdhomerun_debug_disable(struct hdhomerun_debug_t *dbg);
|
||||
extern LIBTYPE bool_t hdhomerun_debug_enabled(struct hdhomerun_debug_t *dbg);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_debug_set_prefix(struct hdhomerun_debug_t *dbg, const char *prefix);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_debug_set_filename(struct hdhomerun_debug_t *dbg, const char *filename);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_debug_enable(struct hdhomerun_debug_t *dbg);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_debug_disable(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 LIBTYPE void hdhomerun_debug_close(struct hdhomerun_debug_t *dbg, uint64_t timeout);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_debug_flush(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 LIBTYPE void hdhomerun_debug_vprintf(struct hdhomerun_debug_t *dbg, const char *fmt, va_list args);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_debug_printf(struct hdhomerun_debug_t *dbg, const char *fmt, ...);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_debug_vprintf(struct hdhomerun_debug_t *dbg, const char *fmt, va_list args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -63,25 +63,25 @@ extern "C" {
|
|||
* <tuner index>
|
||||
* /tuner<tuner index>
|
||||
*/
|
||||
extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner, struct hdhomerun_debug_t *dbg);
|
||||
extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_create_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 LIBTYPE void hdhomerun_device_destroy(struct hdhomerun_device_t *hd);
|
||||
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 LIBHDHOMERUN_API 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_from_str(const char *device_str, struct hdhomerun_debug_t *dbg);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_device_destroy(struct hdhomerun_device_t *hd);
|
||||
|
||||
/*
|
||||
* Get the device id, ip, or tuner of the device instance.
|
||||
*/
|
||||
extern LIBTYPE const char *hdhomerun_device_get_name(struct hdhomerun_device_t *hd);
|
||||
extern LIBTYPE uint32_t hdhomerun_device_get_device_id(struct hdhomerun_device_t *hd);
|
||||
extern LIBTYPE uint32_t hdhomerun_device_get_device_ip(struct hdhomerun_device_t *hd);
|
||||
extern LIBTYPE uint32_t hdhomerun_device_get_device_id_requested(struct hdhomerun_device_t *hd);
|
||||
extern LIBTYPE uint32_t hdhomerun_device_get_device_ip_requested(struct hdhomerun_device_t *hd);
|
||||
extern LIBTYPE unsigned int hdhomerun_device_get_tuner(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API const char *hdhomerun_device_get_name(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_device_get_device_id(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_device_get_device_ip(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_device_get_device_id_requested(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_device_get_device_ip_requested(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 LIBTYPE 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 LIBTYPE int hdhomerun_device_set_tuner_from_str(struct hdhomerun_device_t *hd, const char *tuner_str);
|
||||
extern LIBHDHOMERUN_API 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_multicast(struct hdhomerun_device_t *hd, uint32_t multicast_ip, uint16_t multicast_port);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner);
|
||||
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.
|
||||
|
@ -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.
|
||||
*/
|
||||
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.
|
||||
|
@ -103,29 +103,29 @@ extern LIBTYPE uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun
|
|||
* Returns 0 if the operation was rejected.
|
||||
* Returns -1 if a communication error occurred.
|
||||
*/
|
||||
extern LIBTYPE int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, char **pstatus_str, struct hdhomerun_tuner_status_t *status);
|
||||
extern LIBTYPE int hdhomerun_device_get_tuner_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 LIBTYPE 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 LIBTYPE int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap);
|
||||
extern LIBTYPE int hdhomerun_device_get_tuner_filter(struct hdhomerun_device_t *hd, char **pfilter);
|
||||
extern LIBTYPE int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, char **pprogram);
|
||||
extern LIBTYPE int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget);
|
||||
extern LIBTYPE int hdhomerun_device_get_tuner_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount);
|
||||
extern LIBTYPE int hdhomerun_device_get_tuner_lockkey_owner(struct hdhomerun_device_t *hd, char **powner);
|
||||
extern LIBTYPE int hdhomerun_device_get_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 LIBTYPE 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 LIBTYPE int hdhomerun_device_get_supported(struct hdhomerun_device_t *hd, char *prefix, char **pstr);
|
||||
extern LIBHDHOMERUN_API 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_vstatus(struct hdhomerun_device_t *hd, char **pvstatus_str, struct hdhomerun_tuner_vstatus_t *vstatus);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_streaminfo(struct hdhomerun_device_t *hd, char **pstreaminfo);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_channel(struct hdhomerun_device_t *hd, char **pchannel);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_vchannel(struct hdhomerun_device_t *hd, char **pvchannel);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_filter(struct hdhomerun_device_t *hd, char **pfilter);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, char **pprogram);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget);
|
||||
extern LIBHDHOMERUN_API 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_lockkey_owner(struct hdhomerun_device_t *hd, char **powner);
|
||||
extern LIBHDHOMERUN_API 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_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num);
|
||||
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 LIBTYPE uint32_t hdhomerun_device_get_tuner_status_snq_color(struct hdhomerun_tuner_status_t *status);
|
||||
extern LIBTYPE uint32_t hdhomerun_device_get_tuner_status_seq_color(struct hdhomerun_tuner_status_t *status);
|
||||
extern LIBHDHOMERUN_API 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_snq_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 LIBTYPE const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API const char *hdhomerun_device_get_hw_model_str(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd);
|
||||
|
||||
/*
|
||||
* 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 -1 if a communication error occurred.
|
||||
*/
|
||||
extern LIBTYPE int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char *channel);
|
||||
extern LIBTYPE int hdhomerun_device_set_tuner_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 LIBTYPE int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter);
|
||||
extern LIBTYPE int hdhomerun_device_set_tuner_filter_by_array(struct hdhomerun_device_t *hd, unsigned char filter_array[0x2000]);
|
||||
extern LIBTYPE int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, const char *program);
|
||||
extern LIBTYPE int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, const char *target);
|
||||
extern LIBTYPE int hdhomerun_device_set_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_tuner_channel(struct hdhomerun_device_t *hd, const char *channel);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_set_tuner_vchannel(struct hdhomerun_device_t *hd, const char *vchannel);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter);
|
||||
extern LIBHDHOMERUN_API 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_program(struct hdhomerun_device_t *hd, const char *program);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_set_tuner_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 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.
|
||||
|
@ -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 -1 if a communication error occurs.
|
||||
*/
|
||||
extern LIBTYPE int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, char **pvalue, char **perror);
|
||||
extern LIBTYPE int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const char *name, const char *value, char **pvalue, char **perror);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, 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.
|
||||
|
@ -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
|
||||
* before destroying the hdhomerun_device object.
|
||||
*/
|
||||
extern LIBTYPE int hdhomerun_device_tuner_lockkey_request(struct hdhomerun_device_t *hd, char **perror);
|
||||
extern LIBTYPE int hdhomerun_device_tuner_lockkey_release(struct hdhomerun_device_t *hd);
|
||||
extern LIBTYPE int hdhomerun_device_tuner_lockkey_force(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_tuner_lockkey_request(struct hdhomerun_device_t *hd, char **perror);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_tuner_lockkey_release(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.
|
||||
*/
|
||||
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.
|
||||
|
@ -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.
|
||||
* 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.
|
||||
|
@ -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.
|
||||
*/
|
||||
extern LIBTYPE 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 LIBTYPE 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 int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_device_stream_flush(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd);
|
||||
|
||||
/*
|
||||
* Channel scan API.
|
||||
*/
|
||||
extern LIBTYPE int hdhomerun_device_channelscan_init(struct hdhomerun_device_t *hd, const char *channelmap);
|
||||
extern LIBTYPE int hdhomerun_device_channelscan_advance(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result);
|
||||
extern LIBTYPE int hdhomerun_device_channelscan_detect(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result);
|
||||
extern LIBTYPE uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_channelscan_init(struct hdhomerun_device_t *hd, const char *channelmap);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_device_channelscan_advance(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 LIBHDHOMERUN_API uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd);
|
||||
|
||||
/*
|
||||
* 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 -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.
|
||||
*/
|
||||
extern LIBTYPE struct hdhomerun_control_sock_t *hdhomerun_device_get_control_sock(struct hdhomerun_device_t *hd);
|
||||
extern LIBTYPE struct hdhomerun_video_sock_t *hdhomerun_device_get_video_sock(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API struct hdhomerun_control_sock_t *hdhomerun_device_get_control_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.
|
||||
*/
|
||||
extern LIBTYPE void hdhomerun_device_debug_print_video_stats(struct hdhomerun_device_t *hd);
|
||||
extern LIBTYPE void hdhomerun_device_get_video_stats(struct hdhomerun_device_t *hd, struct hdhomerun_video_stats_t *stats);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_device_debug_print_video_stats(struct hdhomerun_device_t *hd);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_device_get_video_stats(struct hdhomerun_device_t *hd, struct hdhomerun_video_stats_t *stats);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ int hdhomerun_device_selector_load_from_file(struct hdhomerun_device_selector_t
|
|||
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)
|
||||
{
|
||||
HKEY tuners_key;
|
||||
|
@ -374,8 +374,8 @@ static bool_t hdhomerun_device_selector_choose_test(struct hdhomerun_device_sele
|
|||
/*
|
||||
* Test local port.
|
||||
*/
|
||||
hdhomerun_sock_t test_sock = hdhomerun_sock_create_udp();
|
||||
if (test_sock == HDHOMERUN_SOCK_INVALID) {
|
||||
struct hdhomerun_sock_t *test_sock = hdhomerun_sock_create_udp();
|
||||
if (!test_sock) {
|
||||
hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to create test sock\n", name);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.
|
||||
* The dbg parameter may be null.
|
||||
*/
|
||||
extern LIBTYPE 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 struct hdhomerun_device_selector_t *hdhomerun_device_selector_create(struct hdhomerun_debug_t *dbg);
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
* 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 LIBTYPE 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);
|
||||
extern LIBHDHOMERUN_API 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_file(struct hdhomerun_device_selector_t *hds, char *filename);
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
* 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 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_add_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.
|
||||
*/
|
||||
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.
|
||||
|
@ -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
|
||||
* 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
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define HDHOMERUN_DISOCVER_MAX_SOCK_COUNT 16
|
||||
|
||||
struct hdhomerun_discover_sock_t {
|
||||
hdhomerun_sock_t sock;
|
||||
struct hdhomerun_sock_t *sock;
|
||||
bool_t detected;
|
||||
uint32_t local_ip;
|
||||
uint32_t subnet_mask;
|
||||
|
@ -54,8 +54,9 @@ static bool_t hdhomerun_discover_sock_add(struct hdhomerun_discover_t *ds, uint3
|
|||
}
|
||||
|
||||
/* Create socket. */
|
||||
hdhomerun_sock_t sock = hdhomerun_sock_create_udp();
|
||||
if (sock == HDHOMERUN_SOCK_INVALID) {
|
||||
struct hdhomerun_sock_t *sock = hdhomerun_sock_create_udp();
|
||||
if (!sock) {
|
||||
hdhomerun_debug_printf(ds->dbg, "discover: failed to allocate socket (%d)\n", hdhomerun_sock_getlasterror());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,14 +45,14 @@ struct hdhomerun_discover_device_t {
|
|||
* Returns the number of devices found.
|
||||
* 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.
|
||||
*/
|
||||
extern LIBTYPE struct hdhomerun_discover_t *hdhomerun_discover_create(struct hdhomerun_debug_t *dbg);
|
||||
extern LIBTYPE 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 struct hdhomerun_discover_t *hdhomerun_discover_create(struct hdhomerun_debug_t *dbg);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_discover_find_devices_v2(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count);
|
||||
|
||||
/*
|
||||
* 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 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.
|
||||
|
@ -71,7 +71,7 @@ extern LIBTYPE bool_t hdhomerun_discover_validate_device_id(uint32_t device_id);
|
|||
* Returns TRUE if multicast.
|
||||
* 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
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#if defined(_WIN32)
|
||||
#include "hdhomerun_os_windows.h"
|
||||
#else
|
||||
#include "hdhomerun_os_posix.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -21,8 +21,48 @@
|
|||
#include "hdhomerun_os.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
#include <mach/clock.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
|
||||
|
||||
static pthread_once_t random_get32_once = PTHREAD_ONCE_INIT;
|
||||
|
@ -51,22 +91,9 @@ uint32_t random_get32(void)
|
|||
|
||||
uint64_t getcurrenttime(void)
|
||||
{
|
||||
#if defined(CLOCK_MONOTONIC)
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
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
|
||||
struct timespec ts;
|
||||
clock_monotonic_timespec(&ts);
|
||||
return ((uint64_t)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (buffer >= end) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -38,25 +38,35 @@
|
|||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef int bool_t;
|
||||
typedef uint8_t bool_t;
|
||||
typedef void (*sig_t)(int);
|
||||
|
||||
#define LIBTYPE
|
||||
#define console_vprintf vprintf
|
||||
#define console_printf printf
|
||||
typedef struct {
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t cond;
|
||||
} thread_cond_t;
|
||||
|
||||
#define LIBHDHOMERUN_API
|
||||
#define THREAD_FUNC_PREFIX void *
|
||||
#define THREAD_FUNC_RESULT NULL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern LIBTYPE uint32_t random_get32(void);
|
||||
extern LIBTYPE uint64_t getcurrenttime(void);
|
||||
extern LIBTYPE void msleep_approx(uint64_t ms);
|
||||
extern LIBTYPE void msleep_minimum(uint64_t ms);
|
||||
extern LIBHDHOMERUN_API uint32_t random_get32(void);
|
||||
extern LIBHDHOMERUN_API uint64_t getcurrenttime(void);
|
||||
extern LIBHDHOMERUN_API void msleep_approx(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 LIBTYPE bool_t hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...);
|
||||
extern LIBHDHOMERUN_API void thread_cond_init(thread_cond_t *cond);
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "hdhomerun_os.h"
|
||||
|
||||
static DWORD random_get32_context_tls = TlsAlloc();
|
||||
#include "hdhomerun.h"
|
||||
|
||||
#if defined(_WINRT)
|
||||
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);
|
||||
if (!phProv) {
|
||||
phProv = (HCRYPTPROV *)calloc(1, sizeof(HCRYPTPROV));
|
||||
|
@ -38,6 +47,7 @@ uint32_t random_get32(void)
|
|||
|
||||
return Result;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint64_t getcurrenttime(void)
|
||||
{
|
||||
|
@ -100,6 +110,31 @@ void pthread_mutex_unlock(pthread_mutex_t *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)
|
||||
{
|
||||
if (buffer >= end) {
|
||||
|
@ -129,24 +164,3 @@ bool_t hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...)
|
|||
va_end(ap);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define _WINSOCKAPI_
|
||||
#include <windows.h>
|
||||
#ifdef _WINRT
|
||||
#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 <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
#if defined(DLL_IMPORT)
|
||||
#define LIBTYPE __declspec( dllexport )
|
||||
#elif defined(DLL_EXPORT)
|
||||
#define LIBTYPE __declspec( dllimport )
|
||||
#else
|
||||
#define LIBTYPE
|
||||
#ifdef LIBHDHOMERUN_DLLEXPORT
|
||||
#define LIBHDHOMERUN_API __declspec(dllexport)
|
||||
#endif
|
||||
#ifdef LIBHDHOMERUN_DLLIMPORT
|
||||
#define LIBHDHOMERUN_API __declspec(dllimport)
|
||||
#endif
|
||||
#ifndef LIBHDHOMERUN_API
|
||||
#define LIBHDHOMERUN_API
|
||||
#endif
|
||||
|
||||
typedef int 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 uint8_t bool_t;
|
||||
typedef void (*sig_t)(int);
|
||||
typedef HANDLE pthread_t;
|
||||
typedef HANDLE pthread_mutex_t;
|
||||
typedef HANDLE thread_cond_t;
|
||||
|
||||
#if !defined(va_copy)
|
||||
#define va_copy(x, y) x = y
|
||||
|
@ -60,35 +69,35 @@ typedef HANDLE pthread_mutex_t;
|
|||
#define atoll _atoi64
|
||||
#define strdup _strdup
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#define fseeko _fseeki64
|
||||
#define ftello _ftelli64
|
||||
#define THREAD_FUNC_PREFIX DWORD WINAPI
|
||||
#define THREAD_FUNC_RESULT 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern LIBTYPE uint32_t random_get32(void);
|
||||
extern LIBTYPE uint64_t getcurrenttime(void);
|
||||
extern LIBTYPE void msleep_approx(uint64_t ms);
|
||||
extern LIBTYPE void msleep_minimum(uint64_t ms);
|
||||
extern LIBHDHOMERUN_API uint32_t random_get32(void);
|
||||
extern LIBHDHOMERUN_API uint64_t getcurrenttime(void);
|
||||
extern LIBHDHOMERUN_API void msleep_approx(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 LIBTYPE int pthread_join(pthread_t tid, void **value_ptr);
|
||||
extern LIBTYPE void pthread_mutex_init(pthread_mutex_t *mutex, void *attr);
|
||||
extern LIBTYPE void pthread_mutex_lock(pthread_mutex_t *mutex);
|
||||
extern LIBTYPE void pthread_mutex_unlock(pthread_mutex_t *mutex);
|
||||
extern LIBHDHOMERUN_API int pthread_create(pthread_t *tid, void *attr, LPTHREAD_START_ROUTINE start, void *arg);
|
||||
extern LIBHDHOMERUN_API int pthread_join(pthread_t tid, void **value_ptr);
|
||||
extern LIBHDHOMERUN_API void pthread_mutex_init(pthread_mutex_t *mutex, void *attr);
|
||||
extern LIBHDHOMERUN_API void pthread_mutex_lock(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 LIBTYPE bool_t hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...);
|
||||
extern LIBHDHOMERUN_API void thread_cond_init(thread_cond_t *cond);
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
extern LIBTYPE void console_vprintf(const char *fmt, va_list ap);
|
||||
extern LIBTYPE void console_printf(const char *fmt, ...);
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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_TUNER 0x00000001
|
||||
#define HDHOMERUN_DEVICE_TYPE_STORAGE 0x00000005
|
||||
#define HDHOMERUN_DEVICE_ID_WILDCARD 0xFFFFFFFF
|
||||
|
||||
#define HDHOMERUN_MIN_PEEK_LENGTH 4
|
||||
|
@ -145,25 +146,25 @@ struct hdhomerun_pkt_t {
|
|||
uint8_t buffer[3074];
|
||||
};
|
||||
|
||||
extern LIBTYPE struct hdhomerun_pkt_t *hdhomerun_pkt_create(void);
|
||||
extern LIBTYPE void hdhomerun_pkt_destroy(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBTYPE void hdhomerun_pkt_reset(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBHDHOMERUN_API struct hdhomerun_pkt_t *hdhomerun_pkt_create(void);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_pkt_destroy(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 LIBTYPE uint16_t hdhomerun_pkt_read_u16(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBTYPE uint32_t hdhomerun_pkt_read_u32(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBTYPE size_t hdhomerun_pkt_read_var_length(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBTYPE uint8_t *hdhomerun_pkt_read_tlv(struct hdhomerun_pkt_t *pkt, uint8_t *ptag, size_t *plength);
|
||||
extern LIBTYPE void hdhomerun_pkt_read_mem(struct hdhomerun_pkt_t *pkt, void *mem, size_t length);
|
||||
extern LIBHDHOMERUN_API uint8_t hdhomerun_pkt_read_u8(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBHDHOMERUN_API uint16_t hdhomerun_pkt_read_u16(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_pkt_read_u32(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBHDHOMERUN_API size_t hdhomerun_pkt_read_var_length(struct hdhomerun_pkt_t *pkt);
|
||||
extern LIBHDHOMERUN_API uint8_t *hdhomerun_pkt_read_tlv(struct hdhomerun_pkt_t *pkt, uint8_t *ptag, size_t *plength);
|
||||
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 LIBTYPE void hdhomerun_pkt_write_u16(struct hdhomerun_pkt_t *pkt, uint16_t v);
|
||||
extern LIBTYPE void hdhomerun_pkt_write_u32(struct hdhomerun_pkt_t *pkt, uint32_t v);
|
||||
extern LIBTYPE void hdhomerun_pkt_write_var_length(struct hdhomerun_pkt_t *pkt, size_t v);
|
||||
extern LIBTYPE void hdhomerun_pkt_write_mem(struct hdhomerun_pkt_t *pkt, const void *mem, size_t length);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_u8(struct hdhomerun_pkt_t *pkt, uint8_t v);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_u16(struct hdhomerun_pkt_t *pkt, uint16_t v);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_u32(struct hdhomerun_pkt_t *pkt, uint32_t v);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_pkt_write_var_length(struct hdhomerun_pkt_t *pkt, size_t v);
|
||||
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 LIBTYPE void hdhomerun_pkt_seal_frame(struct hdhomerun_pkt_t *pkt, uint16_t frame_type);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_pkt_open_frame(struct hdhomerun_pkt_t *pkt, uint16_t *ptype);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_pkt_seal_frame(struct hdhomerun_pkt_t *pkt, uint16_t frame_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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;
|
||||
};
|
||||
|
||||
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 LIBTYPE hdhomerun_sock_t hdhomerun_sock_create_tcp(void);
|
||||
extern LIBTYPE void hdhomerun_sock_destroy(hdhomerun_sock_t sock);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_sock_set_send_buffer_size(struct hdhomerun_sock_t *sock, size_t size);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_sock_set_recv_buffer_size(struct hdhomerun_sock_t *sock, size_t size);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_sock_set_allow_reuse(struct hdhomerun_sock_t *sock);
|
||||
|
||||
extern LIBTYPE int hdhomerun_sock_getlasterror(void);
|
||||
extern LIBTYPE uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock);
|
||||
extern LIBTYPE uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock);
|
||||
extern LIBTYPE uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock);
|
||||
extern LIBTYPE uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name);
|
||||
extern LIBHDHOMERUN_API int hdhomerun_sock_getlasterror(void);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_sock_getsockname_addr(struct hdhomerun_sock_t *sock);
|
||||
extern LIBHDHOMERUN_API uint16_t hdhomerun_sock_getsockname_port(struct hdhomerun_sock_t *sock);
|
||||
extern LIBHDHOMERUN_API uint32_t hdhomerun_sock_getpeername_addr(struct hdhomerun_sock_t *sock);
|
||||
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 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_join_multicast_group(struct 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 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_bind(struct hdhomerun_sock_t *sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse);
|
||||
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 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_send(struct hdhomerun_sock_t *sock, 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 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_recv(struct hdhomerun_sock_t *sock, 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
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <net/if.h>
|
||||
|
@ -51,10 +35,14 @@
|
|||
#define MSG_NOSIGNAL 0
|
||||
#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 sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock == HDHOMERUN_SOCK_INVALID) {
|
||||
if (sock == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -77,7 +65,7 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (ifc.ifc_len < ifreq_buffer_size) {
|
||||
if (ifc.ifc_len < (int)ifreq_buffer_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -139,49 +127,83 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int
|
|||
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. */
|
||||
hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock == -1) {
|
||||
return HDHOMERUN_SOCK_INVALID;
|
||||
sock->sock = socket(AF_INET, protocol, 0);
|
||||
if (sock->sock == -1) {
|
||||
free(sock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set non-blocking */
|
||||
if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) {
|
||||
close(sock);
|
||||
return HDHOMERUN_SOCK_INVALID;
|
||||
if (fcntl(sock->sock, F_SETFL, O_NONBLOCK) != 0) {
|
||||
hdhomerun_sock_destroy(sock);
|
||||
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. */
|
||||
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. */
|
||||
return sock;
|
||||
}
|
||||
|
||||
hdhomerun_sock_t hdhomerun_sock_create_tcp(void)
|
||||
struct hdhomerun_sock_t *hdhomerun_sock_create_tcp(void)
|
||||
{
|
||||
/* Create socket. */
|
||||
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;
|
||||
return hdhomerun_sock_create_internal(SOCK_STREAM);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -189,43 +211,43 @@ int hdhomerun_sock_getlasterror(void)
|
|||
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;
|
||||
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 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;
|
||||
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 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;
|
||||
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 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;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
@ -245,38 +267,38 @@ uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name
|
|||
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;
|
||||
memset(&imr, 0, sizeof(imr));
|
||||
imr.imr_multiaddr.s_addr = htonl(multicast_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 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;
|
||||
memset(&imr, 0, sizeof(imr));
|
||||
imr.imr_multiaddr.s_addr = htonl(multicast_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 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;
|
||||
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;
|
||||
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_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 TRUE;
|
||||
}
|
||||
|
||||
static bool_t hdhomerun_sock_wait_for_event(hdhomerun_sock_t sock, short event_type, uint64_t stop_time)
|
||||
{
|
||||
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)
|
||||
bool_t hdhomerun_sock_connect(struct hdhomerun_sock_t *sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout)
|
||||
{
|
||||
struct sockaddr_in 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_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)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t stop_time = getcurrenttime() + timeout;
|
||||
return hdhomerun_sock_wait_for_event(sock, POLLOUT, stop_time);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
while (1) {
|
||||
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;
|
||||
}
|
||||
|
||||
int ret = send(sock->sock, ptr, length, MSG_NOSIGNAL);
|
||||
if (ret >= length) {
|
||||
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 = (const 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, 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;
|
||||
if ((ret < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
ptr += ret;
|
||||
length -= ret;
|
||||
}
|
||||
}
|
||||
|
||||
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, data, *length, 0);
|
||||
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;
|
||||
}
|
||||
struct pollfd poll_event;
|
||||
poll_event.fd = sock->sock;
|
||||
poll_event.events = POLLOUT;
|
||||
poll_event.revents = 0;
|
||||
|
||||
if (ret == 0) {
|
||||
if (poll(&poll_event, 1, (int)timeout) <= 0) {
|
||||
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;
|
||||
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;
|
||||
|
||||
while (1) {
|
||||
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;
|
||||
}
|
||||
struct sockaddr_in sock_addr;
|
||||
memset(&sock_addr, 0, sizeof(sock_addr));
|
||||
socklen_t sockaddr_size = sizeof(sock_addr);
|
||||
|
||||
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_port = ntohs(sock_addr.sin_port);
|
||||
*length = ret;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <windows.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)
|
||||
{
|
||||
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);
|
||||
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. */
|
||||
hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock == -1) {
|
||||
return HDHOMERUN_SOCK_INVALID;
|
||||
sock->sock = socket(AF_INET, protocol, 0);
|
||||
if (sock->sock == INVALID_SOCKET) {
|
||||
free(sock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set non-blocking */
|
||||
unsigned long mode = 1;
|
||||
if (ioctlsocket(sock, FIONBIO, &mode) != 0) {
|
||||
closesocket(sock);
|
||||
return HDHOMERUN_SOCK_INVALID;
|
||||
if (ioctlsocket(sock->sock, FIONBIO, &mode) != 0) {
|
||||
hdhomerun_sock_destroy(sock);
|
||||
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. */
|
||||
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. */
|
||||
return sock;
|
||||
}
|
||||
|
||||
hdhomerun_sock_t hdhomerun_sock_create_tcp(void)
|
||||
struct hdhomerun_sock_t *hdhomerun_sock_create_tcp(void)
|
||||
{
|
||||
/* Create socket. */
|
||||
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;
|
||||
return hdhomerun_sock_create_internal(SOCK_STREAM);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -152,43 +182,43 @@ int hdhomerun_sock_getlasterror(void)
|
|||
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;
|
||||
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 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;
|
||||
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 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;
|
||||
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 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;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
@ -208,38 +238,38 @@ uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name
|
|||
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;
|
||||
memset(&imr, 0, sizeof(imr));
|
||||
imr.imr_multiaddr.s_addr = htonl(multicast_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 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;
|
||||
memset(&imr, 0, sizeof(imr));
|
||||
imr.imr_multiaddr.s_addr = htonl(multicast_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 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;
|
||||
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;
|
||||
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_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 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;
|
||||
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);
|
||||
|
||||
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) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for connect to complete (both success and failure will signal). */
|
||||
WSAEVENT wsa_event = WSACreateEvent();
|
||||
if (wsa_event == WSA_INVALID_EVENT) {
|
||||
DWORD wait_ret = WaitForSingleObjectEx(sock->event, (DWORD)timeout, FALSE);
|
||||
if (wait_ret != WAIT_OBJECT_0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (WSAEventSelect(sock, wsa_event, FD_WRITE | FD_CLOSE) == SOCKET_ERROR) {
|
||||
WSACloseEvent(wsa_event);
|
||||
WSANETWORKEVENTS network_events;
|
||||
if (WSAEnumNetworkEvents(sock->sock, sock->event, &network_events) == SOCKET_ERROR) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD ret = WaitForSingleObjectEx(wsa_event, (DWORD)timeout, FALSE);
|
||||
WSACloseEvent(wsa_event);
|
||||
if (ret != WAIT_OBJECT_0) {
|
||||
if ((network_events.lNetworkEvents & FD_WRITE) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
if (network_events.lNetworkEvents & FD_CLOSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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 (current_time >= stop_time) {
|
||||
if (!hdhomerun_sock_event_select(sock, FD_WRITE | FD_CLOSE)) {
|
||||
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;
|
||||
const uint8_t *ptr = (uint8_t *)data;
|
||||
|
||||
while (1) {
|
||||
int ret = send(sock, (char *)ptr, (int)length, 0);
|
||||
if (ret <= 0) {
|
||||
if (WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) {
|
||||
return FALSE;
|
||||
}
|
||||
continue;
|
||||
int ret = send(sock->sock, (char *)ptr, (int)length, 0);
|
||||
if (ret >= (int)length) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (ret < (int)length) {
|
||||
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) {
|
||||
if ((ret == SOCKET_ERROR) && (WSAGetLastError() != WSAEWOULDBLOCK)) {
|
||||
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;
|
||||
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;
|
||||
memset(&sock_addr, 0, 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;
|
||||
}
|
||||
struct sockaddr_in sock_addr;
|
||||
memset(&sock_addr, 0, sizeof(sock_addr));
|
||||
int sockaddr_size = sizeof(sock_addr);
|
||||
|
||||
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_port = ntohs(sock_addr.sin_port);
|
||||
*length = ret;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,7 +23,7 @@
|
|||
struct hdhomerun_video_sock_t {
|
||||
pthread_mutex_t lock;
|
||||
struct hdhomerun_debug_t *dbg;
|
||||
hdhomerun_sock_t sock;
|
||||
struct hdhomerun_sock_t *sock;
|
||||
|
||||
volatile size_t head;
|
||||
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->sock = HDHOMERUN_SOCK_INVALID;
|
||||
pthread_mutex_init(&vs->lock, NULL);
|
||||
|
||||
/* Reset sequence tracking. */
|
||||
|
@ -79,14 +78,13 @@ struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, bool
|
|||
|
||||
/* Create socket. */
|
||||
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");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Expand socket buffer size. */
|
||||
int rx_size = 1024 * 1024;
|
||||
setsockopt(vs->sock, SOL_SOCKET, SO_RCVBUF, (char *)&rx_size, sizeof(rx_size));
|
||||
hdhomerun_sock_set_recv_buffer_size(vs->sock, 1024 * 1024);
|
||||
|
||||
/* Bind socket. */
|
||||
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;
|
||||
|
||||
error:
|
||||
if (vs->sock != HDHOMERUN_SOCK_INVALID) {
|
||||
if (vs->sock) {
|
||||
hdhomerun_sock_destroy(vs->sock);
|
||||
}
|
||||
if (vs->buffer) {
|
||||
|
@ -125,7 +123,7 @@ void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *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;
|
||||
}
|
||||
|
@ -281,7 +279,7 @@ static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg)
|
|||
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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
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 LIBTYPE void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs);
|
||||
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 LIBHDHOMERUN_API void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs);
|
||||
|
||||
/*
|
||||
* Get the port the socket is listening on.
|
||||
*
|
||||
* Returns 16-bit port with native endianness, or 0 on error.
|
||||
*/
|
||||
extern LIBTYPE uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs);
|
||||
extern LIBHDHOMERUN_API uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs);
|
||||
|
||||
/*
|
||||
* 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 LIBTYPE void hdhomerun_video_leave_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 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.
|
||||
|
@ -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
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
extern LIBTYPE void hdhomerun_video_debug_print_stats(struct hdhomerun_video_sock_t *vs);
|
||||
extern LIBTYPE void hdhomerun_video_get_stats(struct hdhomerun_video_sock_t *vs, struct hdhomerun_video_stats_t *stats);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_video_debug_print_stats(struct hdhomerun_video_sock_t *vs);
|
||||
extern LIBHDHOMERUN_API void hdhomerun_video_get_stats(struct hdhomerun_video_sock_t *vs, struct hdhomerun_video_stats_t *stats);
|
||||
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue