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); }
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); }
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; }
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; }
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; }
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; }