diff --git a/mythtv/libs/libmythhdhomerun/hdhomerun_device.c b/mythtv/libs/libmythhdhomerun/hdhomerun_device.c index 6d8da3594c8..9217e41ec11 100644 --- a/mythtv/libs/libmythhdhomerun/hdhomerun_device.c +++ b/mythtv/libs/libmythhdhomerun/hdhomerun_device.c @@ -543,6 +543,18 @@ int hdhomerun_device_get_tuner_channel(struct hdhomerun_device_t *hd, char **pch return hdhomerun_control_get(hd->cs, name, pchannel, NULL); } +int hdhomerun_device_get_tuner_vchannel(struct hdhomerun_device_t *hd, char **pvchannel) +{ + if (!hd->cs) { + hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_get_tuner_vchannel: device not set\n"); + return -1; + } + + char name[32]; + sprintf(name, "/tuner%u/vchannel", hd->tuner); + return hdhomerun_control_get(hd->cs, name, pvchannel, NULL); +} + int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap) { if (!hd->cs) { @@ -752,6 +764,18 @@ int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char return hdhomerun_control_set_with_lockkey(hd->cs, name, channel, hd->lockkey, NULL, NULL); } +int hdhomerun_device_set_tuner_vchannel(struct hdhomerun_device_t *hd, const char *vchannel) +{ + if (!hd->cs) { + hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_tuner_vchannel: device not set\n"); + return -1; + } + + char name[32]; + sprintf(name, "/tuner%u/vchannel", hd->tuner); + return hdhomerun_control_set_with_lockkey(hd->cs, name, vchannel, hd->lockkey, NULL, NULL); +} + int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap) { if (!hd->cs) { diff --git a/mythtv/libs/libmythhdhomerun/hdhomerun_device.h b/mythtv/libs/libmythhdhomerun/hdhomerun_device.h index 7fb0f51a09b..7975ef2c334 100644 --- a/mythtv/libs/libmythhdhomerun/hdhomerun_device.h +++ b/mythtv/libs/libmythhdhomerun/hdhomerun_device.h @@ -116,6 +116,7 @@ extern LIBTYPE uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun 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_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); @@ -143,6 +144,7 @@ extern LIBTYPE const char *hdhomerun_device_get_model_str(struct hdhomerun_devic * 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]); diff --git a/mythtv/libs/libmythhdhomerun/hdhomerun_sock_posix.c b/mythtv/libs/libmythhdhomerun/hdhomerun_sock_posix.c index 28b050840c9..150d8890be0 100644 --- a/mythtv/libs/libmythhdhomerun/hdhomerun_sock_posix.c +++ b/mythtv/libs/libmythhdhomerun/hdhomerun_sock_posix.c @@ -65,24 +65,42 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int } struct ifconf ifc; - uint8_t buf[8192]; - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = (char *)buf; + struct ifreq ifreq_dummy; + size_t ifreq_size = _SIZEOF_ADDR_IFREQ(ifreq_dummy); + size_t ifreq_buffer_size = ifreq_size * 16; - memset(buf, 0, sizeof(buf)); + while (1) { + ifc.ifc_len = ifreq_buffer_size; + ifc.ifc_buf = (char *)malloc(ifreq_buffer_size); + if (!ifc.ifc_buf) { + close(sock); + return -1; + } - if (ioctl(sock, SIOCGIFCONF, &ifc) != 0) { - close(sock); - return -1; + memset(ifc.ifc_buf, 0, ifreq_buffer_size); + + if (ioctl(sock, SIOCGIFCONF, &ifc) != 0) { + free(ifc.ifc_buf); + close(sock); + return -1; + } + + if (ifc.ifc_len >= ifreq_buffer_size) { + free(ifc.ifc_buf); + ifreq_buffer_size += ifreq_size * 16; + continue; + } + + break; } - uint8_t *ptr = (uint8_t *)ifc.ifc_req; - uint8_t *end = (uint8_t *)&ifc.ifc_buf[ifc.ifc_len]; + char *ptr = ifc.ifc_buf; + char *end = ifc.ifc_buf + ifc.ifc_len; int count = 0; while (ptr <= end) { struct ifreq *ifr = (struct ifreq *)ptr; - ptr += _SIZEOF_ADDR_IFREQ(*ifr); + ptr += ifreq_size; if (ioctl(sock, SIOCGIFADDR, ifr) != 0) { continue; @@ -110,6 +128,7 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int } } + free(ifc.ifc_buf); close(sock); return count; } @@ -200,12 +219,6 @@ uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock) return ntohl(sock_addr.sin_addr.s_addr); } -#if defined(__CYGWIN__) -uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name) -{ - return 0; -} -#else uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name) { struct addrinfo hints; @@ -225,7 +238,6 @@ uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name freeaddrinfo(sock_info); return addr; } -#endif bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port) { diff --git a/mythtv/libs/libmythhdhomerun/hdhomerun_sock_windows.c b/mythtv/libs/libmythhdhomerun/hdhomerun_sock_windows.c index 0ffe4a11ed1..7fea65dbeda 100644 --- a/mythtv/libs/libmythhdhomerun/hdhomerun_sock_windows.c +++ b/mythtv/libs/libmythhdhomerun/hdhomerun_sock_windows.c @@ -51,33 +51,43 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count) { - PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); - ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); + PIP_ADAPTER_INFO AdapterInfo; + ULONG AdapterInfoLength = sizeof(IP_ADAPTER_INFO) * 16; + + while (1) { + AdapterInfo = (IP_ADAPTER_INFO *)malloc(AdapterInfoLength); + if (!AdapterInfo) { + return -1; + } + + ULONG LengthNeeded = AdapterInfoLength; + DWORD Ret = GetAdaptersInfo(AdapterInfo, &LengthNeeded); + if (Ret == NO_ERROR) { + break; + } + + free(AdapterInfo); - DWORD Ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); - if (Ret != NO_ERROR) { - free(pAdapterInfo); if (Ret != ERROR_BUFFER_OVERFLOW) { return -1; } - pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); - Ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); - if (Ret != NO_ERROR) { - free(pAdapterInfo); + if (AdapterInfoLength >= LengthNeeded) { return -1; } + + AdapterInfoLength = LengthNeeded; } int count = 0; - PIP_ADAPTER_INFO pAdapter = pAdapterInfo; - while (pAdapter) { - IP_ADDR_STRING *pIPAddr = &pAdapter->IpAddressList; - while (pIPAddr) { - uint32_t ip_addr = ntohl(inet_addr(pIPAddr->IpAddress.String)); - uint32_t subnet_mask = ntohl(inet_addr(pIPAddr->IpMask.String)); + PIP_ADAPTER_INFO Adapter = AdapterInfo; + while (Adapter) { + IP_ADDR_STRING *IPAddr = &Adapter->IpAddressList; + while (IPAddr) { + uint32_t ip_addr = ntohl(inet_addr(IPAddr->IpAddress.String)); + uint32_t subnet_mask = ntohl(inet_addr(IPAddr->IpMask.String)); if (ip_addr == 0) { - pIPAddr = pIPAddr->Next; + IPAddr = IPAddr->Next; continue; } @@ -89,17 +99,17 @@ int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int break; } - pIPAddr = pIPAddr->Next; + IPAddr = IPAddr->Next; } if (count >= max_count) { break; } - pAdapter = pAdapter->Next; + Adapter = Adapter->Next; } - free(pAdapterInfo); + free(AdapterInfo); return count; }