linux_media/
media_device_info.rs1use std::ffi::CStr;
2use std::fmt;
3use std::fs::OpenOptions;
4use std::os::fd::{AsFd, AsRawFd, OwnedFd};
5use std::os::unix::fs::OpenOptionsExt;
6use std::path::Path;
7
8use linux_media_sys as media;
9use serde::{Deserialize, Serialize};
10
11use crate::error;
12use crate::ioctl;
13use crate::version::*;
14
15#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
16pub struct MediaDeviceInfo {
17 pub driver: String,
18 pub model: String,
19 pub serial: String,
20 pub bus_info: String,
21 pub media_version: Version,
22 pub hw_revision: u32,
23 pub driver_version: Version,
24}
25
26impl fmt::Debug for MediaDeviceInfo {
27 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28 write!(
29 f,
30 "MediaDeviceInfo {{ driver: \"{}\", model: \"{}\", serial: \"{}\", bus_info: \"{}\", media_version: {}, hw_revision: 0x{:02X}, driver_version: {} }}",
31 self.driver,
32 self.model,
33 self.serial,
34 self.bus_info,
35 self.media_version,
36 self.hw_revision,
37 self.driver_version,
38 )
39 }
40}
41
42impl MediaDeviceInfo {
43 pub fn from_path<P>(path: P) -> error::Result<(OwnedFd, Self)>
44 where
45 P: AsRef<Path>,
46 {
47 let path = path.as_ref();
48 let fd: OwnedFd = OpenOptions::new()
49 .read(true)
50 .write(true)
51 .custom_flags(libc::O_CLOEXEC)
52 .open(path)
53 .map_err(|err| error::trap_io_error(err, path.to_path_buf()))?
54 .into();
55 let info = Self::from_fd(fd.as_fd())?;
56 Ok((fd, info))
57 }
58
59 pub fn from_fd<F>(fd: F) -> error::Result<Self>
60 where
61 F: AsFd,
62 {
63 let info = unsafe {
64 let mut info: media::media_device_info = std::mem::zeroed();
65 ioctl!(fd.as_fd(), media::MEDIA_IOC_DEVICE_INFO, &mut info)?;
66 info
67 };
68 Ok(info.into())
69 }
70
71 pub fn driver(&self) -> &str {
72 &self.driver
73 }
74
75 pub fn model(&self) -> &str {
76 &self.model
77 }
78
79 pub fn serial(&self) -> &str {
80 &self.serial
81 }
82
83 pub fn bus_info(&self) -> &str {
84 &self.bus_info
85 }
86
87 pub fn media_version(&self) -> Version {
88 self.media_version.clone()
89 }
90
91 pub fn hw_revision(&self) -> u32 {
92 self.hw_revision
93 }
94
95 pub fn driver_version(&self) -> Version {
96 self.driver_version.clone()
97 }
98}
99
100impl From<media::media_device_info> for MediaDeviceInfo {
101 fn from(info: media::media_device_info) -> Self {
102 let driver = unsafe { CStr::from_ptr(info.driver.as_ptr()) }
103 .to_string_lossy()
104 .to_string();
105 let model = unsafe { CStr::from_ptr(info.model.as_ptr()) }
106 .to_string_lossy()
107 .to_string();
108 let serial = unsafe { CStr::from_ptr(info.serial.as_ptr()) }
109 .to_string_lossy()
110 .to_string();
111 let bus_info = unsafe { CStr::from_ptr(info.bus_info.as_ptr()) }
112 .to_string_lossy()
113 .to_string();
114 let media_version = info.media_version.into();
115 let hw_revision = info.hw_revision;
116 let driver_version = info.driver_version.into();
117 Self {
118 driver,
119 model,
120 serial,
121 bus_info,
122 media_version,
123 hw_revision,
124 driver_version,
125 }
126 }
127}