static int standby_resume_standby_toggle(struct node *node, unsigned me, unsigned la, bool interactive)
{
	if (!node->remote[la].in_standby)
		return NOTAPPLICABLE;

	struct cec_msg msg = {};
	unsigned unresponsive_time = 0;
	__u8 new_status;

	node->remote[la].in_standby = false;

	/* Send Standby again to test that it is not acting like a toggle */
	announce("Sending Standby message.");
	cec_msg_init(&msg, me, la);
	cec_msg_standby(&msg);
	int res = doioctl(node, CEC_TRANSMIT, &msg);
	fail_on_test(res && res != ENONET);
	fail_on_test(cec_msg_status_is_abort(&msg));
	fail_on_test(wait_changing_power_status(node, me, la, new_status, unresponsive_time));
	fail_on_test(new_status != CEC_OP_POWER_STATUS_STANDBY);
	fail_on_test(interactive && !question("Is the device still in standby?"));
	node->remote[la].in_standby = true;
	if (unresponsive_time > 0)
		warn("The device went correctly into standby, but became unresponsive for %d s during the transition.\n",
		     unresponsive_time);

	return 0;
}
static int standby_resume_active_source_nowake(struct node *node, unsigned me, unsigned la, bool interactive)
{
	if (!node->remote[la].in_standby)
		return NOTAPPLICABLE;

	struct cec_msg msg = {};
	unsigned unresponsive_time = 0;
	__u8 new_status;

	node->remote[la].in_standby = false;

	/* In CEC 2.0 it is specified that a device shall not go out of standby
	   if an Active Source message is received. */
	announce("Sending Active Source message.");
	cec_msg_init(&msg, me, la);
	cec_msg_active_source(&msg, node->phys_addr);
	int res = doioctl(node, CEC_TRANSMIT, &msg);
	fail_on_test(res && res != ENONET);
	fail_on_test(wait_changing_power_status(node, me, la, new_status, unresponsive_time));
	fail_on_test_v2_warn(node->remote[la].cec_version, new_status != CEC_OP_POWER_STATUS_STANDBY);
	node->remote[la].in_standby = true;
	if (unresponsive_time > 0)
		warn("The device stayed correctly in standby, but became unresponsive for %d s.\n",
		     unresponsive_time);

	return 0;
}
static int standby_resume_standby(struct node *node, unsigned me, unsigned la, bool interactive)
{
	if (!node->remote[la].has_power_status)
		return NOTAPPLICABLE;

	struct cec_msg msg = {};
	unsigned unresponsive_time = 0;

	fail_on_test(!util_interactive_ensure_power_state(node, me, la, interactive, CEC_OP_POWER_STATUS_ON));

	announce("Sending Standby message.");
	cec_msg_init(&msg, me, la);
	cec_msg_standby(&msg);
	fail_on_test(!transmit_timeout(node, &msg));
	fail_on_test(cec_msg_status_is_abort(&msg));
	fail_on_test(!poll_stable_power_status(node, me, la, CEC_OP_POWER_STATUS_STANDBY, unresponsive_time));
	fail_on_test(interactive && !question("Is the device in standby?"));
	node->remote[la].in_standby = true;

	if (unresponsive_time > 0)
		warn("The device went correctly into standby, but became unresponsive for %d s during the transition.\n",
		     unresponsive_time);

	return 0;
}
static int one_touch_play_req_active_source(struct node *node, unsigned me, unsigned la, bool interactive)
{
	struct cec_msg msg = {};

	cec_msg_init(&msg, me, la);
	cec_msg_active_source(&msg, node->phys_addr);
	fail_on_test(!transmit_timeout(node, &msg));

	/* We have now said that we are active source, so receiving a reply to
	   Request Active Source should fail the test. */
	cec_msg_init(&msg, me, la);
	cec_msg_request_active_source(&msg, true);
	fail_on_test(!transmit_timeout(node, &msg));
	fail_on_test(!timed_out(&msg));

	return 0;
}
static int wakeup_source(struct node *node, unsigned me, unsigned la)
{
	struct cec_msg msg = {};

	cec_msg_init(&msg, me, la);
	cec_msg_set_stream_path(&msg, node->remote[la].phys_addr);
	fail_on_test(!transmit_timeout(node, &msg));
	if (!cec_msg_status_is_abort(&msg))
		return 0;

	return wakeup_rc(node, me, la);
}
Exemple #6
0
static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
{
	struct vivid_dev *dev = adap->priv;
	struct cec_msg reply;
	u8 dest = cec_msg_destination(msg);
	u16 pa;
	u8 disp_ctl;
	char osd[14];

	if (cec_msg_is_broadcast(msg))
		dest = adap->log_addrs.log_addr[0];
	cec_msg_init(&reply, dest, cec_msg_initiator(msg));

	switch (cec_msg_opcode(msg)) {
	case CEC_MSG_SET_STREAM_PATH:
		if (cec_is_sink(adap))
			return -ENOMSG;
		cec_ops_set_stream_path(msg, &pa);
		if (pa != adap->phys_addr)
			return -ENOMSG;
		cec_msg_active_source(&reply, adap->phys_addr);
		cec_transmit_msg(adap, &reply, false);
		break;
	case CEC_MSG_SET_OSD_STRING:
		if (!cec_is_sink(adap))
			return -ENOMSG;
		cec_ops_set_osd_string(msg, &disp_ctl, osd);
		switch (disp_ctl) {
		case CEC_OP_DISP_CTL_DEFAULT:
			strcpy(dev->osd, osd);
			dev->osd_jiffies = jiffies;
			break;
		case CEC_OP_DISP_CTL_UNTIL_CLEARED:
			strcpy(dev->osd, osd);
			dev->osd_jiffies = 0;
			break;
		case CEC_OP_DISP_CTL_CLEAR:
			dev->osd[0] = 0;
			dev->osd_jiffies = 0;
			break;
		default:
			cec_msg_feature_abort(&reply, cec_msg_opcode(msg),
					      CEC_OP_ABORT_INVALID_OP);
			cec_transmit_msg(adap, &reply, false);
			break;
		}
		break;
	default:
		return -ENOMSG;
	}
	return 0;
}
static int wakeup_rc(struct node *node, unsigned me, unsigned la)
{
	struct cec_msg msg = {};
	struct cec_op_ui_command rc_press = {};

	/* Todo: A release should be sent after this */
	cec_msg_init(&msg, me, la);
	rc_press.ui_cmd = 0x6D;  /* Power On Function */
	cec_msg_user_control_pressed(&msg, &rc_press);
	fail_on_test(!transmit_timeout(node, &msg));
	fail_on_test(cec_msg_status_is_abort(&msg));

	return 0;
}
static int power_status_report(struct node *node, unsigned me, unsigned la, bool interactive)
{
	struct cec_msg msg = {};

	cec_msg_init(&msg, me, la);
	cec_msg_report_power_status(&msg, CEC_OP_POWER_STATUS_ON);
	fail_on_test(!transmit_timeout(node, &msg));
	if (unrecognized_op(&msg))
		return NOTSUPPORTED;
	if (refused(&msg))
		return REFUSED;

	return PRESUMED_OK;
}
static int wakeup_tv(struct node *node, unsigned me, unsigned la)
{
	struct cec_msg msg = {};

	cec_msg_init(&msg, me, la);
	cec_msg_image_view_on(&msg);
	msg.timeout = 2000;
	int res = doioctl(node, CEC_TRANSMIT, &msg);
	if (res == ENONET && la == CEC_LOG_ADDR_TV) {
		msg.msg[0] = (CEC_LOG_ADDR_UNREGISTERED << 4) | la;
		res = doioctl(node, CEC_TRANSMIT, &msg);
	}
	fail_on_test(res || !(msg.tx_status & CEC_TX_STATUS_OK));
	if (!cec_msg_status_is_abort(&msg))
		return 0;

	cec_msg_init(&msg, me, la);
	cec_msg_text_view_on(&msg);
	fail_on_test(!transmit_timeout(node, &msg));
	if (!cec_msg_status_is_abort(&msg))
		return 0;

	return wakeup_rc(node, me, la);
}
Exemple #10
0
static bool get_power_status(struct node *node, unsigned me, unsigned la, __u8 &power_status)
{
	struct cec_msg msg = {};

	cec_msg_init(&msg, me, la);
	cec_msg_give_device_power_status(&msg, true);
	msg.timeout = 2000;
	int res = doioctl(node, CEC_TRANSMIT, &msg);
	if (res == ENONET) {
		power_status = CEC_OP_POWER_STATUS_STANDBY;
		return true;
	}
	if (res || timed_out_or_abort(&msg))
		return false;
	cec_ops_report_power_status(&msg, &power_status);
	return true;
}
Exemple #11
0
static int power_status_give(struct node *node, unsigned me, unsigned la, bool interactive)
{
	struct cec_msg msg = { };

	cec_msg_init(&msg, me, la);
	cec_msg_give_device_power_status(&msg, true);
	fail_on_test(!transmit_timeout(node, &msg));
	fail_on_test(timed_out(&msg));
	fail_on_test(unrecognized_op(&msg));
	if (refused(&msg))
		return REFUSED;
	if (cec_msg_status_is_abort(&msg))
		return PRESUMED_OK;

	__u8 power_status;
	cec_ops_report_power_status(&msg, &power_status);
	fail_on_test(power_status >= 4);

	return 0;
}
Exemple #12
0
static int one_touch_play_view_on_change(struct node *node, unsigned me, unsigned la, bool interactive,
					 __u8 opcode)
{
	struct cec_msg msg = {};
	int ret;

	fail_on_test(!util_interactive_ensure_power_state(node, me, la, interactive, CEC_OP_POWER_STATUS_ON));

	interactive_info(true, "Please switch the TV to another source.");
	ret = one_touch_play_view_on(node, me, la, interactive, opcode);
	if (ret && ret != PRESUMED_OK)
		return ret;
	cec_msg_init(&msg, me, la);
	cec_msg_active_source(&msg, node->phys_addr);
	fail_on_test(!transmit_timeout(node, &msg));
	fail_on_test(interactive && !question("Did the TV switch to this source?"));

	if (interactive)
		return 0;
	else
		return PRESUMED_OK;
}
Exemple #13
0
static int one_touch_play_view_on(struct node *node, unsigned me, unsigned la, bool interactive,
				  __u8 opcode)
{
	struct cec_msg msg = {};

	cec_msg_init(&msg, me, la);
	if (opcode == CEC_MSG_IMAGE_VIEW_ON)
		cec_msg_image_view_on(&msg);
	else if (opcode == CEC_MSG_TEXT_VIEW_ON)
		cec_msg_text_view_on(&msg);
	fail_on_test(!transmit_timeout(node, &msg));
	fail_on_test(is_tv(la, node->remote[la].prim_type) && unrecognized_op(&msg));
	if (refused(&msg))
		return REFUSED;
	if (cec_msg_status_is_abort(&msg))
		return PRESUMED_OK;
	if (opcode == CEC_MSG_IMAGE_VIEW_ON)
		node->remote[la].has_image_view_on = true;
	else if (opcode == CEC_MSG_TEXT_VIEW_ON)
		node->remote[la].has_text_view_on = true;

	return 0;
}