static bool_t hdhomerun_device_selector_choose_test(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *test_hd) { const char *name = hdhomerun_device_get_name(test_hd); /* * Attempt to aquire lock. */ char *error; int ret = hdhomerun_device_tuner_lockkey_request(test_hd, &error); if (ret > 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s chosen\n", name); return TRUE; } if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } /* * In use - check target. */ char *target; ret = hdhomerun_device_get_tuner_target(test_hd, &target); if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } if (ret == 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to read target\n", name); return FALSE; } char *ptr = strstr(target, "//"); if (ptr) { target = ptr + 2; } ptr = strchr(target, ' '); if (ptr) { *ptr = 0; } unsigned long a[4]; unsigned long target_port; if (sscanf(target, "%lu.%lu.%lu.%lu:%lu", &a[0], &a[1], &a[2], &a[3], &target_port) != 5) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, no target set (%s)\n", name, target); return FALSE; } uint32_t target_ip = (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0)); uint32_t local_ip = hdhomerun_device_get_local_machine_addr(test_hd); if (target_ip != local_ip) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by %s\n", name, target); return FALSE; } /* * Test local port. */ hdhomerun_sock_t test_sock = hdhomerun_sock_create_udp(); if (test_sock == HDHOMERUN_SOCK_INVALID) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to create test sock\n", name); return FALSE; } bool_t inuse = (hdhomerun_sock_bind(test_sock, INADDR_ANY, (uint16_t)target_port, FALSE) == FALSE); hdhomerun_sock_destroy(test_sock); if (inuse) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine\n", name); return FALSE; } /* * Dead local target, force clear lock. */ ret = hdhomerun_device_tuner_lockkey_force(test_hd); if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } if (ret == 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine, dead target, failed to force release lockkey\n", name); return FALSE; } hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine, dead target, lockkey force successful\n", name); /* * Attempt to aquire lock. */ ret = hdhomerun_device_tuner_lockkey_request(test_hd, &error); if (ret > 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s chosen\n", name); return TRUE; } if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s still in use after lockkey force (%s)\n", name, error); return FALSE; }
static bool_t hdhomerun_device_selector_choose_test(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *test_hd) { const char *name = hdhomerun_device_get_name(test_hd); /* * Attempt to aquire lock. */ char *error = NULL; int ret = hdhomerun_device_tuner_lockkey_request(test_hd, &error); if (ret > 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s chosen\n", name); return TRUE; } if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } /* * In use - check target. */ char *target; ret = hdhomerun_device_get_tuner_target(test_hd, &target); if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } if (ret == 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to read target\n", name); return FALSE; } if (strcmp(target, "none") == 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, no target set\n", name); return FALSE; } if ((strncmp(target, "udp://", 6) != 0) && (strncmp(target, "rtp://", 6) != 0)) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by %s\n", name, target); return FALSE; } unsigned int a[4]; unsigned int target_port; if (sscanf(target + 6, "%u.%u.%u.%u:%u", &a[0], &a[1], &a[2], &a[3], &target_port) != 5) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, unexpected target set (%s)\n", name, target); return FALSE; } uint32_t target_ip = (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0)); uint32_t local_ip = hdhomerun_device_get_local_machine_addr(test_hd); if (target_ip != local_ip) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by %s\n", name, target); return FALSE; } /* * Test local port. */ 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; } bool_t inuse = (hdhomerun_sock_bind(test_sock, INADDR_ANY, (uint16_t)target_port, FALSE) == FALSE); hdhomerun_sock_destroy(test_sock); if (inuse) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine\n", name); return FALSE; } /* * Dead local target, force clear lock. */ ret = hdhomerun_device_tuner_lockkey_force(test_hd); if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } if (ret == 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine, dead target, failed to force release lockkey\n", name); return FALSE; } hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine, dead target, lockkey force successful\n", name); /* * Attempt to aquire lock. */ ret = hdhomerun_device_tuner_lockkey_request(test_hd, &error); if (ret > 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s chosen\n", name); return TRUE; } if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s still in use after lockkey force (%s)\n", name, error); return FALSE; }
static bool_t hdhomerun_device_selector_choose_test(struct hdhomerun_device_selector_t *hds, struct hdhomerun_device_t *test_hd) { const char *name = hdhomerun_device_get_name(test_hd); /* * Attempt to aquire lock. */ char *error; int ret = hdhomerun_device_tuner_lockkey_request(test_hd, &error); if (ret > 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s chosen\n", name); return TRUE; } if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } /* * In use - check target. */ char *target; ret = hdhomerun_device_get_tuner_target(test_hd, &target); if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } if (ret == 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to read target\n", name); return FALSE; } char *ptr = strstr(target, "//"); if (ptr) { target = ptr + 2; } ptr = strchr(target, ' '); if (ptr) { *ptr = 0; } unsigned long a[4]; unsigned long target_port; if (sscanf(target, "%lu.%lu.%lu.%lu:%lu", &a[0], &a[1], &a[2], &a[3], &target_port) != 5) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, no target set (%s)\n", name, target); return FALSE; } uint32_t target_ip = (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0)); uint32_t local_ip = hdhomerun_device_get_local_machine_addr(test_hd); if (target_ip != local_ip) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by %s\n", name, target); return FALSE; } /* * Test local port. */ int test_sock = (int)socket(AF_INET, SOCK_DGRAM, 0); if (test_sock == -1) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use, failed to create test sock\n", name); 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(INADDR_ANY); sock_addr.sin_port = htons((uint16_t)target_port); ret = bind(test_sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)); close(test_sock); if (ret != 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine\n", name); return FALSE; } /* * Dead local target, force clear lock. */ ret = hdhomerun_device_tuner_lockkey_force(test_hd); if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } if (ret == 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine, dead target, failed to force release lockkey\n", name); return FALSE; } hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s in use by local machine, dead target, lockkey force successful\n", name); /* * Attempt to aquire lock. */ ret = hdhomerun_device_tuner_lockkey_request(test_hd, &error); if (ret > 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s chosen\n", name); return TRUE; } if (ret < 0) { hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s communication error\n", name); return FALSE; } hdhomerun_debug_printf(hds->dbg, "hdhomerun_device_selector_choose_test: device %s still in use after lockkey force (%s)\n", name, error); return FALSE; }