1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*!
 * Simple example of Passthrough Mode.
 * 
 * This does what the core would do if not in Passthrough Mode.
 */

use cec_linux::*;

fn main() -> std::io::Result<()> {
    let cec = CecDevice::open("/dev/cec0")?;

    cec.set_mode(CecModeInitiator::Send, CecModeFollower::ExclusivePassthru)?;

    let physical_addr = cec.get_phys()?;

    loop {
        let msg = cec.rec()?;
        match msg.opcode() {
            Some(Ok(CecOpcode::ActiveSource)) | Some(Ok(CecOpcode::RoutingInformation)) | Some(Ok(CecOpcode::SetStreamPath))
                if msg.parameters() == physical_addr.to_be_bytes() =>
            {
                // this is not done by the core
                println!("THIS IS US {:?}", msg.opcode().unwrap().unwrap());
                cec.transmit_data(CecLogicalAddress::Playback2, CecLogicalAddress::UnregisteredBroadcast, CecOpcode::ActiveSource, &physical_addr.to_be_bytes())?;
            },
            Some(Ok(CecOpcode::ReportPhysicalAddr)) => {},//core is still taking care of that
            Some(Ok(opcode)) if msg.destination() == CecLogicalAddress::UnregisteredBroadcast => {
                //dont answer brodcasts
                println!("{:?}: {:?} {:x?}", msg.initiator(), opcode, msg.parameters());
            },
            Some(Ok(CecOpcode::GetCecVersion)) => {
                cec.transmit_data(
                    msg.destination(),
                    msg.initiator(),
                    CecOpcode::CecVersion,
                &[
                    Version::V1_3A.into()
                ])?;
            },
            Some(Ok(CecOpcode::GiveDeviceVendorId)) => {
                cec.transmit_data(
                    msg.destination(),
                    msg.initiator(),
                    CecOpcode::FeatureAbort,
                &[
                    CecOpcode::GiveDeviceVendorId.into(),
                    CecAbortReason::Unrecognized.into()
                ])?;/*
                cec.transmit_data(
                    msg.destination(),
                    msg.initiator(),
                    CecOpcode::DeviceVendorId,
                &[0,0,0])?;*/
            },
            Some(Ok(CecOpcode::Abort)) => {
                cec.transmit_data(
                    msg.destination(),
                    msg.initiator(),
                    CecOpcode::FeatureAbort,
                &[
                    CecOpcode::Abort.into(),
                    CecAbortReason::Other.into()
                ])?;
            },
            Some(Ok(CecOpcode::GivePhysicalAddr)) => {
                let l = cec.get_log()?;
                let mut addr = Vec::with_capacity(3);
                
                if l.num_log_addrs > 0 {
                    if let Some(log) = l.log_addr.first() {
                        addr.extend_from_slice(&physical_addr.to_be_bytes());
                        addr.push(*log);

                        cec.transmit_data(
                            msg.destination(),
                            msg.initiator(),
                            CecOpcode::ReportPhysicalAddr,
                        &addr)?;
                    }
                }//else no address yet?!?!?
            },
            Some(Ok(CecOpcode::GiveOsdName)) => {
                cec.transmit_data(
                    msg.destination(),
                    msg.initiator(),
                    CecOpcode::SetOsdName,
                b"pi4")?;
            },
            Some(Ok(CecOpcode::GiveDevicePowerStatus)) => {
                cec.transmit_data(
                    msg.destination(),
                    msg.initiator(),
                    CecOpcode::ReportPowerStatus,
                &[CecPowerStatus::On.into()])?;
            },
            Some(Ok(CecOpcode::GiveFeatures)) => {},
            Some(Ok(opcode)) => {
                println!("{:?} -> {:?} : {:?} {:x?}", msg.initiator(), msg.destination(), opcode, msg.parameters());
            },
            _ => {
                println!("{:?}", msg);
            }
        }
    }
}