示例#1
0
PyObject *py_device_tuner_lockkey_request(py_device_object *self) {
    char *ret_error = "the device rejected the lock request";
    int success;

    success = hdhomerun_device_tuner_lockkey_request(self->hd, &ret_error);

    if(success == -1) {
        PyErr_SetString(PyExc_IOError, DEVICE_ERR_COMMUNICATION);
        return NULL;
    } else if(success == 0) {
        PyErr_SetString(hdhomerun_device_error, ret_error);
        return NULL;
    } else if(success == 1) {
        self->locked = 1;
    } else {
        PyErr_SetString(hdhomerun_device_error, DEVICE_ERR_UNDOCUMENTED);
        return NULL;
    }
    Py_RETURN_NONE;
}
示例#2
0
static int cmd_scan(const char *tuner_str, const char *filename)
{
	if (hdhomerun_device_set_tuner_from_str(hd, tuner_str) <= 0) {
		fprintf(stderr, "invalid tuner number\n");
		return -1;
	}

	char *ret_error;
	if (hdhomerun_device_tuner_lockkey_request(hd, &ret_error) <= 0) {
		fprintf(stderr, "failed to lock tuner\n");
		if (ret_error) {
			fprintf(stderr, "%s\n", ret_error);
		}
		return -1;
	}

	hdhomerun_device_set_tuner_target(hd, "none");

	char *channelmap;
	if (hdhomerun_device_get_tuner_channelmap(hd, &channelmap) <= 0) {
		fprintf(stderr, "failed to query channelmap from device\n");
		return -1;
	}

	const char *channelmap_scan_group = hdhomerun_channelmap_get_channelmap_scan_group(channelmap);
	if (!channelmap_scan_group) {
		fprintf(stderr, "unknown channelmap '%s'\n", channelmap);
		return -1;
	}

	if (hdhomerun_device_channelscan_init(hd, channelmap_scan_group) <= 0) {
		fprintf(stderr, "failed to initialize channel scan\n");
		return -1;
	}

	FILE *fp = NULL;
	if (filename) {
		fp = fopen(filename, "w");
		if (!fp) {
			fprintf(stderr, "unable to create file: %s\n", filename);
			return -1;
		}
	}

	register_signal_handlers(sigabort_handler, sigabort_handler, siginfo_handler);

	int ret = 0;
	while (!sigabort_flag) {
		struct hdhomerun_channelscan_result_t result;
		ret = hdhomerun_device_channelscan_advance(hd, &result);
		if (ret <= 0) {
			break;
		}

		cmd_scan_printf(fp, "SCANNING: %lu (%s)\n",
			(unsigned long)result.frequency, result.channel_str
		);

		ret = hdhomerun_device_channelscan_detect(hd, &result);
		if (ret <= 0) {
			break;
		}

		cmd_scan_printf(fp, "LOCK: %s (ss=%u snq=%u seq=%u)\n",
			result.status.lock_str, result.status.signal_strength,
			result.status.signal_to_noise_quality, result.status.symbol_error_quality
		);

		if (result.transport_stream_id_detected) {
			cmd_scan_printf(fp, "TSID: 0x%04X\n", result.transport_stream_id);
		}

		int i;
		for (i = 0; i < result.program_count; i++) {
			struct hdhomerun_channelscan_program_t *program = &result.programs[i];
			cmd_scan_printf(fp, "PROGRAM %s\n", program->program_str);
		}
	}

	hdhomerun_device_tuner_lockkey_release(hd);

	if (fp) {
		fclose(fp);
	}
	if (ret < 0) {
		fprintf(stderr, "communication error sending request to hdhomerun device\n");
	}
	return ret;
}
示例#3
0
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;
}