static int main_internal(int argc, char *argv[]) { #if defined(__WINDOWS__) /* Initialize network socket support. */ WORD wVersionRequested = MAKEWORD(2, 0); WSADATA wsaData; WSAStartup(wVersionRequested, &wsaData); #endif extract_appname(argv[0]); argv++; argc--; if (argc == 0) { return help(); } char *id_str = *argv++; argc--; if (contains(id_str, "help")) { return help(); } if (contains(id_str, "discover")) { if (argc < 1) { return discover_print(NULL); } else { return discover_print(argv[0]); } } /* Device object. */ hd = hdhomerun_device_create_from_str(id_str, NULL); if (!hd) { fprintf(stderr, "invalid device id: %s\n", id_str); return -1; } /* Device ID check. */ uint32_t device_id_requested = hdhomerun_device_get_device_id_requested(hd); if (!hdhomerun_discover_validate_device_id(device_id_requested)) { fprintf(stderr, "invalid device id: %08lX\n", (unsigned long)device_id_requested); } /* Connect to device and check model. */ const char *model = hdhomerun_device_get_model_str(hd); if (!model) { fprintf(stderr, "unable to connect to device\n"); hdhomerun_device_destroy(hd); return -1; } /* Command. */ int ret = main_cmd(argc, argv); /* Cleanup. */ hdhomerun_device_destroy(hd); /* Complete. */ return ret; }
bool HDHRDevice::validate() { if(mDeviceInfo.device_id != 0) { struct hdhomerun_discover_device_t deviceInfo; bool valid = hdhomerun_discover_validate_device_id(mDeviceInfo.device_id); bool done = false; // if validation fails, give it a few seconds to come back // putting the system to sleep on Mac OS X seems to cause a problem if(valid) { int result, iter = 5; do { // -1 = error, 0 = none found, else number of devices found (max 1 here) result = hdhomerun_discover_find_devices_custom_v2(0, HDHOMERUN_DEVICE_TYPE_TUNER, mDeviceInfo.device_id, &deviceInfo, 1); // flog( "Native.log", "hdhomerun_discover_find_device(%08lx) returned %d\r\n", mDeviceInfo.device_id, result); if(result == -1) return false; if(result != 1) { if(--iter == 0) { done = true; } else { sleep(1); } } else done = true; } while(!done); if(result == 1) { // update cached info if we didn't get an error if((deviceInfo.device_type != mDeviceInfo.device_type) || (deviceInfo.ip_addr != mDeviceInfo.ip_addr)) { memcpy(&mDeviceInfo, &deviceInfo, sizeof(struct hdhomerun_discover_device_t)); } return true; } } else { // clear an invalid entry (id is invalid) // FIXME: threading issues? mDeviceInfo.ip_addr = 0; mDeviceInfo.device_type = 0; // mDeviceInfo.device_id = 0; flog( "Native.log", "I have an invalid device ID!!! (%08lx)\r\n", (unsigned long)mDeviceInfo.device_id); } } return false; }
int hdhomerun_device_selector_load_from_str(struct hdhomerun_device_selector_t *hds, char *device_str) { /* * IP address based device_str. */ unsigned int a[4]; if (sscanf(device_str, "%u.%u.%u.%u", &a[0], &a[1], &a[2], &a[3]) == 4) { uint32_t ip_addr = (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0)); /* * Multicast IP address. */ unsigned int port; if (sscanf(device_str, "%u.%u.%u.%u:%u", &a[0], &a[1], &a[2], &a[3], &port) == 5) { struct hdhomerun_device_t *hd = hdhomerun_device_create_multicast(ip_addr, port, hds->dbg); if (!hd) { return 0; } hdhomerun_device_selector_add_device(hds, hd); return 1; } /* * IP address + tuner number. */ unsigned int tuner; if (sscanf(device_str, "%u.%u.%u.%u-%u", &a[0], &a[1], &a[2], &a[3], &tuner) == 5) { struct hdhomerun_device_t *hd = hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, ip_addr, tuner, hds->dbg); if (!hd) { return 0; } hdhomerun_device_selector_add_device(hds, hd); return 1; } /* * IP address only - discover and add tuners. */ return hdhomerun_device_selector_load_from_str_discover(hds, ip_addr, HDHOMERUN_DEVICE_ID_WILDCARD); } /* * Device ID based device_str. */ char *end; uint32_t device_id = (uint32_t)strtoul(device_str, &end, 16); if ((end == device_str + 8) && hdhomerun_discover_validate_device_id(device_id)) { /* * IP address + tuner number. */ if (*end == '-') { unsigned int tuner = (unsigned int)strtoul(end + 1, NULL, 10); struct hdhomerun_device_t *hd = hdhomerun_device_create(device_id, 0, tuner, hds->dbg); if (!hd) { return 0; } hdhomerun_device_selector_add_device(hds, hd); return 1; } /* * Device ID only - discover and add tuners. */ return hdhomerun_device_selector_load_from_str_discover(hds, 0, device_id); } /* * DNS based device_str. */ struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; struct addrinfo *sock_info; if (getaddrinfo(device_str, "65001", &hints, &sock_info) != 0) { return 0; } struct sockaddr_in *sock_addr = (struct sockaddr_in *)sock_info->ai_addr; uint32_t ip_addr = (uint32_t)ntohl(sock_addr->sin_addr.s_addr); freeaddrinfo(sock_info); if (ip_addr == 0) { return 0; } return hdhomerun_device_selector_load_from_str_discover(hds, ip_addr, HDHOMERUN_DEVICE_ID_WILDCARD); }