cleverdog/protocol/
scan.rs

1use core::{convert::TryFrom, str};
2use std::net::SocketAddr;
3
4use crate::{mac::MacAddr, protocol::version::Version};
5
6#[derive(Debug, Clone, Copy)]
7pub struct ScanInfo {
8    /// Camera MAC address.
9    mac: MacAddr,
10    /// Firmware version.
11    version: Version,
12}
13
14impl TryFrom<&[u8]> for ScanInfo {
15    type Error = &'static str;
16
17    fn try_from(v: &[u8]) -> Result<Self, Self::Error> {
18        let mut it = v.split(|&ch| ch == b'\0');
19
20        let mac = match it.next() {
21            Some(mac) => match str::from_utf8(mac.into()) {
22                Ok(mac) => match MacAddr::from_str(mac) {
23                    Ok(mac) => mac,
24                    Err(..) => return Err("MAC address is invalid"),
25                },
26                Err(..) => return Err("MAC address contains invalid UTF-8 sequence"),
27            },
28            None => return Err("missing MAC address"),
29        };
30
31        let version = match it.next() {
32            Some(version) => match str::from_utf8(version.into()) {
33                Ok(version) => match Version::from_str(version) {
34                    Ok(version) => version,
35                    Err(..) => return Err("version is invalid"),
36                },
37                Err(..) => return Err("version contains invalid UTF-8 sequence"),
38            },
39            None => return Err("missing version"),
40        };
41
42        let v = Self { mac, version };
43
44        Ok(v)
45    }
46}
47
48#[derive(Debug, Clone, Copy)]
49pub struct LookupInfo {
50    /// Camera endpoint.
51    addr: SocketAddr,
52    /// Camera ID.
53    cid: [u8; 16],
54    /// Scan info.
55    info: ScanInfo,
56}
57
58impl LookupInfo {
59    pub fn new(addr: SocketAddr, cid: [u8; 16], info: ScanInfo) -> Self {
60        Self { addr, cid, info }
61    }
62
63    /// Returns socket address where the camera is bound.
64    #[inline]
65    pub fn addr(&self) -> SocketAddr {
66        self.addr
67    }
68
69    /// Returns camera's client id.
70    #[inline]
71    pub fn cid(&self) -> &[u8] {
72        &self.cid[..]
73    }
74
75    /// Returns camera's MAC address.
76    #[inline]
77    pub fn mac(&self) -> &MacAddr {
78        &self.info.mac
79    }
80
81    /// Returns camera's firmware version.
82    #[inline]
83    pub fn version(&self) -> &Version {
84        &self.info.version
85    }
86}