config.iptv_tpool_count = 2;
config.date_mask = strdup("");
config.label_formatting = 0;
+ config.hdhomerun_ip = strdup("");
+ config.local_ip = strdup("");
+ config.local_port = 0;
idclass_register(&config_class);
free(config.picon_path);
free(config.cors_origin);
free(config.date_mask);
+ free(config.hdhomerun_ip);
+ free(config.local_ip);
file_unlock(config_lock, config_lock_fd);
}
.opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT,
.group = 1
},
+ {
+ .type = PT_STR,
+ .id = "hdhomerun_ip",
+ .name = N_("HDHomerun IP Address"),
+ .desc = N_("IP address of the HDHomerun device. This is needed if you "
+ "plan to run TVheadend in a container and you want to stream "
+ "from an HDHomerun without enabling host networking for "
+ "the container."),
+ .off = offsetof(config_t, hdhomerun_ip),
+ .opts = PO_HIDDEN | PO_EXPERT,
+ .group = 1
+ },
+ {
+ .type = PT_STR,
+ .id = "local_ip",
+ .name = N_("Local IP Address"),
+ .desc = N_("IP address of the HDHomerun device. This is needed if you "
+ "plan to run TVheadend in a container and you want to stream "
+ "from an HDHomerun without enabling host networking for "
+ "the container."),
+ .off = offsetof(config_t, local_ip),
+ .opts = PO_HIDDEN | PO_EXPERT,
+ .group = 1
+ },
+ {
+ .type = PT_INT,
+ .id = "local_port",
+ .name = N_("Local Socket Port Number"),
+ .desc = N_("Port number of the UDP listener. This listener listens "
+ "for traffic from the HDHomerun device. This is needed if "
+ "you plan to run TVheadend in a container and you want to "
+ "stream from an HDHomerun without enabling host networking "
+ "for the container."),
+ .off = offsetof(config_t, local_port),
+ .opts = PO_HIDDEN | PO_EXPERT,
+ .group = 1
+ },
{
.type = PT_STR,
.id = "language_ui",
char *date_mask;
int label_formatting;
uint32_t ticket_expires;
+ char *hdhomerun_ip;
+ char *local_ip;
+ int local_port;
} config_t;
extern const idclass_t config_class;
#include <arpa/inet.h>
#include <openssl/sha.h>
+#include "config.h"
+
#ifdef HDHOMERUN_TAG_DEVICE_AUTH_BIN
#define hdhomerun_discover_find_devices_custom \
hdhomerun_discover_find_devices_custom_v2
htsmsg_destroy(conf);
}
+static uint32_t
+tvhdhomerun_ip( void )
+{
+ static int homerun_ip_initialized = 0;
+ static uint32_t ip = 0;
+
+ if (!homerun_ip_initialized)
+ {
+ if ((*config.hdhomerun_ip != 0) && inet_pton(AF_INET, config.hdhomerun_ip, &ip))
+ {
+ tvhinfo(LS_TVHDHOMERUN, "HDHomerun IP set to %s", config.hdhomerun_ip);
+ ip = ntohl(ip);
+ }
+ homerun_ip_initialized = 1;
+ }
+ return ip;
+}
+
static void *
tvhdhomerun_device_discovery_thread( void *aux )
{
while (tvheadend_is_running()) {
numDevices =
- hdhomerun_discover_find_devices_custom(0,
+ hdhomerun_discover_find_devices_custom(tvhdhomerun_ip(),
HDHOMERUN_DEVICE_TYPE_TUNER,
HDHOMERUN_DEVICE_ID_WILDCARD,
result_list,
#include "tcp.h"
#include "tvhdhomerun_private.h"
+#include <arpa/inet.h>
+#include "config.h"
+
static int
tvhdhomerun_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight )
{
/* local IP */
/* TODO: this is nasty */
local_ip = hdhomerun_device_get_local_machine_addr(hfe->hf_hdhomerun_tuner);
+ if ((*config.local_ip != 0) && inet_pton(AF_INET, config.local_ip, &local_ip))
+ {
+ local_ip = ntohl(local_ip);
+ }
/* first setup a local socket for the device to stream to */
sockfd = tvh_socket(AF_INET, SOCK_DGRAM, 0);
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- sock_addr.sin_port = 0;
+ sock_addr.sin_port = config.local_port==0?0:htons(config.local_port);
if(bind(sockfd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) != 0) {
tvherror(LS_TVHDHOMERUN, "failed bind socket: %d", errno);
close(sockfd);