STRUCT CEC_MSG(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’Œ struct cec_msg β€” CEC message structure ✨

okay so bestie, we're in the Kernel API Manual today and the main character is struct cec_msg πŸ’… this is the CEC message structure itself, no cap. CEC = the thing your TV remote talks over HDMI, and this struct is literally the whole text message. let's get into it 🫢


🌸 NAME 🌸

struct cec_msg β€” CEC message structure, fr fr. that's the whole vibe.


✨ SYNOPSIS ✨

struct cec_msg {
    __u64 tx_ts;
    __u64 rx_ts;
    __u32 len;
    __u32 timeout;
    __u32 sequence;
    __u32 flags;
    __u8 msg[CEC_MAX_MSG_SIZE];
    __u8 reply;
    __u8 rx_status;
    __u8 tx_status;
    __u8 tx_arb_lost_cnt;
    __u8 tx_nack_cnt;
    __u8 tx_low_drive_cnt;
    __u8 tx_error_cnt;
 };

like, copy that exactly, don't be cute with it πŸŽ€


πŸ’– Members πŸ’–

okay field-by-field, group chat style, but every single fact stays:

  • tx_ts β€” timestamp in nanoseconds using CLOCK_MONOTONIC. the driver sets this when the message transmission has finished πŸ•
  • rx_ts β€” timestamp in nanoseconds using CLOCK_MONOTONIC. driver sets this when the message was received πŸ“₯
  • len β€” length in bytes of the message. that's it, that's the whole field ✨
  • timeout β€” the timeout (in ms) used to timeout CEC_RECEIVE. set it to 0 if you literally want to wait forever 😭 this timeout can also be used with CEC_TRANSMIT as the timeout for waiting for a reply. but heads up: if it's 0, then it uses a 1 second timeout instead of waiting forever, which is not what CEC_RECEIVE does. the way these two behave differently… πŸ’€
  • sequence β€” the framework assigns a sequence number to messages that are sent. use it to track replies to messages you sent earlier πŸ‘‘
  • flags β€” set to 0. that's the assignment. slay πŸŽ€
  • msg β€” the message payload πŸ’Œ
  • reply β€” okay this one's the big one, sit down. this field is ignored with CEC_RECEIVE and is only used by CEC_TRANSMIT. if non-zero, then wait for a reply with this opcode. set it to CEC_MSG_FEATURE_ABORT if you want to wait for a possible ABORT reply. if there was an error when sending the msg or FeatureAbort was returned, then reply is set to 0. if reply is non-zero upon return, then len/msg are set to the received message. if reply is zero upon return and status has the CEC_TX_STATUS_FEATURE_ABORT bit set, then len/msg are set to the received feature abort message. if reply is zero upon return and status has the CEC_TX_STATUS_MAX_RETRIES bit set, then no reply was seen at all πŸ˜” if reply is non-zero for CEC_TRANSMIT and the message is a broadcast, then -EINVAL is returned. if reply is non-zero, then timeout is set to 1000 (the required maximum response time). phew. iconic field, frankly πŸ‘‘
  • rx_status β€” the message receive status bits. set by the driver πŸ¦‹
  • tx_status β€” the message transmit status bits. set by the driver πŸ¦‹
  • tx_arb_lost_cnt β€” the number of 'Arbitration Lost' events. set by the driver 😀
  • tx_nack_cnt β€” the number of 'Not Acknowledged' events. set by the driver πŸ™ˆ
  • tx_low_drive_cnt β€” the number of 'Low Drive Detected' events. set by the driver πŸ’€
  • tx_error_cnt β€” the number of 'Error' events. set by the driver πŸ”₯
ngl bestie, notice the pattern: almost everything here is set by the driver. you're reading these, not writing them. respect the driver's main character energy 🌈

πŸ‘€ SEE ALSO πŸ‘€

kernel file ./include/uapi/linux/cec.h, plus the whole friend group:

go read them, iykyk πŸ“š


and that's the page!! πŸ’œ this one lives at ./include/uapi/linux, dated October 2026, and it's filed under struct cec_msg(9) in the Kernel API Manual β€” mwah, bye bestie, go send some CEC messages πŸ’…βœ¨

πŸ“¦ where this page comes from