2.10. ioctls CEC_G_MODE 和 CEC_S_MODE

CEC_G_MODE, CEC_S_MODE - 获取或设置 CEC 适配器的独占使用权

2.10.1. 概要

CEC_G_MODE

int ioctl(int fd, CEC_G_MODE, __u32 *argp)

CEC_S_MODE

int ioctl(int fd, CEC_S_MODE, __u32 *argp)

2.10.2. 参数

fd

open() 返回的文件描述符。

argp

指向 CEC 模式的指针。

2.10.3. 描述

默认情况下,任何文件句柄都可以使用 ioctls CEC_RECEIVE 和 CEC_TRANSMIT,但是为了防止应用程序互相干扰,必须能够获得对 CEC 适配器的独占访问权。此 ioctl 将文件句柄设置为发起者和/或跟随者模式,该模式可以根据所选模式进行独占。发起者是用于启动消息的文件句柄,即它命令其他 CEC 设备。跟随者是接收发送到 CEC 适配器并处理它们的消息的文件句柄。同一个文件句柄可以既是发起者又是跟随者,或者此角色可以由两个不同的文件句柄承担。

当收到 CEC 消息时,CEC 框架将决定如何处理它。如果该消息是对先前发送的消息的回复,则该回复将发送回正在等待它的文件句柄。此外,CEC 框架将对其进行处理。

如果该消息不是回复,则 CEC 框架将首先对其进行处理。如果没有跟随者,则该消息将被丢弃,并且如果框架无法处理该消息,则会向发起者发送一个功能中止。如果有跟随者,则该消息将传递给跟随者,后者将使用 ioctl CEC_RECEIVE 来取消新消息的排队。框架期望跟随者做出正确的决定。

除非跟随者另有要求,否则 CEC 框架将处理核心消息。跟随者可以启用直通模式。在这种情况下,CEC 框架将传递大多数核心消息而不进行处理,并且跟随者将必须实现这些消息。有些消息核心将始终处理,而不管直通模式如何。有关详细信息,请参见 核心消息处理

如果没有发起者,则任何 CEC 文件句柄都可以使用 ioctl CEC_TRANSMIT。如果存在独占发起者,则只有该发起者可以调用 ioctls CEC_RECEIVE 和 CEC_TRANSMIT。当然,跟随者始终可以调用 ioctl CEC_TRANSMIT

可用的发起者模式为

发起者模式

CEC_MODE_NO_INITIATOR

0x0

这不是发起者,即它无法发送 CEC 消息或对 CEC 适配器进行任何其他更改。

CEC_MODE_INITIATOR

0x1

这是发起者(打开设备时的默认值),它可以发送 CEC 消息并更改 CEC 适配器,除非存在独占发起者。

CEC_MODE_EXCL_INITIATOR

0x2

这是一个独占发起者,并且此文件描述符是唯一可以发送 CEC 消息并更改 CEC 适配器的描述符。如果其他人已经是独占发起者,则尝试成为独占发起者将返回 EBUSY 错误代码错误。

可用的跟随者模式为

跟随者模式

CEC_MODE_NO_FOLLOWER

0x00

这不是跟随者(打开设备时的默认值)。

CEC_MODE_FOLLOWER

0x10

这是一个跟随者,它将接收 CEC 消息,除非存在独占跟随者。如果未设置 CEC_CAP_TRANSMIT 或指定了 CEC_MODE_NO_INITIATOR,则不能成为跟随者,在这种情况下将返回 EINVAL 错误代码。

CEC_MODE_EXCL_FOLLOWER

0x20

这是一个独占跟随者,只有此文件描述符将接收 CEC 消息进行处理。如果其他人已经是独占跟随者,则尝试成为独占跟随者将返回 EBUSY 错误代码。如果未设置 CEC_CAP_TRANSMIT 或指定了 CEC_MODE_NO_INITIATOR,则不能成为跟随者,在这种情况下将返回 EINVAL 错误代码。

CEC_MODE_EXCL_FOLLOWER_PASSTHRU

0x30

这是一个独占跟随者,只有此文件描述符将接收 CEC 消息进行处理。此外,它会将 CEC 设备置于直通模式,从而允许独占跟随者处理大多数核心消息,而不是依赖 CEC 框架。如果其他人已经是独占跟随者,则尝试成为独占跟随者将返回 EBUSY 错误代码。如果未设置 CEC_CAP_TRANSMIT 或指定了 CEC_MODE_NO_INITIATOR,则不能成为跟随者,在这种情况下将返回 EINVAL 错误代码。

CEC_MODE_MONITOR_PIN

0xd0

将文件描述符置于引脚监视模式。只能与 CEC_MODE_NO_INITIATOR 结合使用,否则将返回 EINVAL 错误代码。此模式要求设置 CEC_CAP_MONITOR_PIN 功能,否则将返回 EINVAL 错误代码。在引脚监视模式下,此文件描述符可以接收 CEC_EVENT_PIN_CEC_LOWCEC_EVENT_PIN_CEC_HIGH 事件以查看低级 CEC 引脚转换。这对于调试非常有用。仅当进程具有 CAP_NET_ADMIN 功能时,才允许使用此模式。如果未设置该功能,则返回 EPERM 错误代码。

CEC_MODE_MONITOR

0xe0

将文件描述符置于监视器模式。只能与 CEC_MODE_NO_INITIATOR 结合使用,否则将返回 EINVAL 错误代码。在监视器模式下,将报告此 CEC 设备发送的所有消息以及接收的所有消息(广播消息和定向到其逻辑地址之一的消息)。这对于调试非常有用。仅当进程具有 CAP_NET_ADMIN 功能时,才允许使用此模式。如果未设置该功能,则返回 EPERM 错误代码。

CEC_MODE_MONITOR_ALL

0xf0

将文件描述符设置为“监控所有”模式。只能与 CEC_MODE_NO_INITIATOR 结合使用,否则将返回 EINVAL 错误代码。在“监控所有”模式下,此 CEC 设备发送的所有消息以及接收的所有消息(包括针对其他 CEC 设备的定向消息)都将被报告。这对于调试非常有用,但并非所有设备都支持此功能。此模式要求设置 CEC_CAP_MONITOR_ALL 功能,否则将返回 EINVAL 错误代码。只有当进程具有 CAP_NET_ADMIN 功能时才允许这样做。如果未设置该功能,则返回 EPERM 错误代码。

核心消息处理细节

核心消息处理

CEC_MSG_GET_CEC_VERSION

核心将返回使用 ioctl CEC_ADAP_S_LOG_ADDRS 设置的 CEC 版本,除非处于直通模式。在直通模式下,核心不执行任何操作,此消息必须由跟随者处理。

CEC_MSG_GIVE_DEVICE_VENDOR_ID

核心将返回使用 ioctl CEC_ADAP_S_LOG_ADDRS 设置的供应商 ID,除非处于直通模式。在直通模式下,核心不执行任何操作,此消息必须由跟随者处理。

CEC_MSG_ABORT

核心将按照规范返回原因“拒绝功能”的功能中止消息,除非处于直通模式。在直通模式下,核心不执行任何操作,此消息必须由跟随者处理。

CEC_MSG_GIVE_PHYSICAL_ADDR

核心将报告当前的物理地址,除非处于直通模式。在直通模式下,核心不执行任何操作,此消息必须由跟随者处理。

CEC_MSG_GIVE_OSD_NAME

核心将报告使用 ioctl CEC_ADAP_S_LOG_ADDRS 设置的当前 OSD 名称,除非处于直通模式。在直通模式下,核心不执行任何操作,此消息必须由跟随者处理。

CEC_MSG_GIVE_FEATURES

如果 CEC 版本低于 2.0,则核心将不执行任何操作,否则它将报告使用 ioctl CEC_ADAP_S_LOG_ADDRS 设置的当前功能,除非处于直通模式。在直通模式下,核心不执行任何操作(对于任何 CEC 版本),此消息必须由跟随者处理。

CEC_MSG_USER_CONTROL_PRESSED

如果设置了 CEC_CAP_RC 且设置了 CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU,则生成遥控按键。此消息始终传递给跟随者。

CEC_MSG_USER_CONTROL_RELEASED

如果设置了 CEC_CAP_RC 且设置了 CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU,则生成遥控按键释放。此消息始终传递给跟随者。

CEC_MSG_REPORT_PHYSICAL_ADDR

CEC 框架将记录报告的物理地址,然后将消息传递给跟随者。

2.10.4. 返回值

成功时返回 0,失败时返回 -1,并且会相应地设置 errno 变量。通用错误代码在 通用错误代码 章节中描述。

ioctl CEC_S_MODE 可以返回以下错误代码

EINVAL

请求的模式无效。

EPERM

请求监控模式,但进程不具有 CAP_NET_ADMIN 功能。

EBUSY

其他人已经是独占跟随者或发起者。