Skip to content

Commit

Permalink
osdpctl: start using PdInfoBuilder for PdIno creation
Browse files Browse the repository at this point in the history
Signed-off-by: Siddharth Chandrasekaran <sidcha.dev@gmail.com>
  • Loading branch information
sidcha committed Mar 24, 2024
1 parent 517d687 commit 174c57e
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 25 deletions.
2 changes: 1 addition & 1 deletion osdpctl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ clap = "4.4.7"
configparser = "3.0.2"
daemonize = "0.5.0"
dirs = "5.0.1"
libosdp = { version = "0.1.8" }
libosdp = { path = "../libosdp" }
log = "0.4.20"
log4rs = "1.2.0"
nix = { version = "0.28.0", features = ["signal"] }
Expand Down
50 changes: 26 additions & 24 deletions osdpctl/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
use anyhow::bail;
use anyhow::Context;
use configparser::ini::Ini;
use libosdp::{
channel::{OsdpChannel, UnixChannel},
OsdpFlag, PdCapability, PdId, PdInfo,
};
use libosdp::PdInfoBuilder;
use libosdp::{OsdpFlag, PdCapability, PdId, PdInfo};
use rand::Rng;
use std::{
fmt::Write,
path::{Path, PathBuf},
str::FromStr,
};

use crate::unix_channel::UnixChannel;

type Result<T> = anyhow::Result<T, anyhow::Error>;

fn vec_to_array<T, const N: usize>(v: Vec<T>) -> [T; N] {
Expand Down Expand Up @@ -142,16 +142,17 @@ impl CpConfig {
bail!("Only unix channel is supported for now")
}
let path = runtime_dir.join(format!("{}/{}.sock", d.name, parts[1]).as_str());
let stream =
let channel =
UnixChannel::connect(&path).context("Unable to connect to PD channel")?;
Ok(PdInfo::for_cp(
&self.name,
d.address,
9600,
d.flags,
OsdpChannel::new::<UnixChannel>(Box::new(stream)),
d.key_store.load()?,
))
let pd_info = PdInfoBuilder::new()
.name(&self.name)?
.address(d.address)?
.baud_rate(115200)?
.flag(d.flags)
.channel(Box::new(channel))
.secure_channel_key(d.key_store.load()?)
.build();
Ok(pd_info)
})
.collect()
}
Expand Down Expand Up @@ -239,17 +240,18 @@ impl PdConfig {
bail!("Only unix channel is supported for now")
}
let path = self.runtime_dir.join(format!("{}.sock", parts[1]).as_str());
let stream = UnixChannel::new(&path)?;
Ok(PdInfo::for_pd(
&self.name,
self.address,
9600,
self.flags,
self.pd_id.clone(),
self.pd_cap.clone(),
OsdpChannel::new::<UnixChannel>(Box::new(stream)),
self.key_store.load()?,
))
let channel = UnixChannel::new(&path)?;
let pd_info = PdInfoBuilder::new()
.name(&self.name)?
.address(self.address)?
.baud_rate(115200)?
.flag(self.flags)
.capabilities(&self.pd_cap)
.id(&self.pd_id)
.channel(Box::new(channel))
.secure_channel_key(self.key_store.load()?)
.build();
Ok(pd_info)
}
}

Expand Down
1 change: 1 addition & 0 deletions osdpctl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod config;
mod cp;
mod daemonize;
mod pd;
mod unix_channel;

use anyhow::{bail, Context};
use clap::{arg, Command};
Expand Down
89 changes: 89 additions & 0 deletions osdpctl/src/unix_channel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//
// Copyright (c) 2023-2024 Siddharth Chandrasekaran <sidcha.dev@gmail.com>
//
// SPDX-License-Identifier: Apache-2.0

//! OSDP unix channel

use core::time::Duration;
use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
io::{Read, Write},
os::unix::net::{UnixListener, UnixStream},
path::{Path, PathBuf},
str::FromStr,
thread,
};

use libosdp::ChannelError;

type Result<T> = std::result::Result<T, libosdp::OsdpError>;

/// A reference OSDP channel implementation for unix domain socket.
#[derive(Debug)]
pub struct UnixChannel {
id: i32,
stream: UnixStream,
}

pub fn str_to_channel_id(key: &str) -> i32 {
let mut hasher = DefaultHasher::new();
key.hash(&mut hasher);
let mut id: u64 = hasher.finish();
id = (id >> 32) ^ id & 0xffffffff;
id as i32
}

impl UnixChannel {
/// Connect to a channel identified by `name`.
pub fn connect(path: &Path) -> Result<Self> {
let id = 0;
let stream = UnixStream::connect(&path)?;
Ok(Self { id, stream })
}

/// Listen on a channel identified by `name`.
pub fn new(path: &Path) -> Result<Self> {
let id = str_to_channel_id(path.as_os_str().try_into().unwrap());
if path.exists() {
std::fs::remove_file(&path)?;
}
let listener = UnixListener::bind(&path)?;
println!("Waiting for connection to unix::{}", path.display());
let (stream, _) = listener.accept()?;
Ok(Self { id, stream })
}

/// Create a bi-directional channel pair. Returns Result<(server, client)>
pub fn _pair(name: &str) -> Result<(Self, Self)> {
let path = PathBuf::from_str(format!("/tmp/osdp-{name}.sock").as_str())?;
let path_clone = path.clone();
let h = thread::spawn(move || {
let path = path_clone;
UnixChannel::new(&path)
});
thread::sleep(Duration::from_secs(1));
let client = UnixChannel::connect(&path)?;
let server = h.join().unwrap()?;
Ok((server, client))
}
}

impl libosdp::Channel for UnixChannel {
fn get_id(&self) -> i32 {
self.id
}

fn read(&mut self, buf: &mut [u8]) -> std::prelude::v1::Result<usize, libosdp::ChannelError> {
self.stream.read(buf).map_err(ChannelError::from)
}

fn write(&mut self, buf: &[u8]) -> std::prelude::v1::Result<usize, libosdp::ChannelError> {
self.stream.write(buf).map_err(ChannelError::from)
}

fn flush(&mut self) -> std::prelude::v1::Result<(), libosdp::ChannelError> {
self.stream.flush().map_err(ChannelError::from)
}
}

0 comments on commit 174c57e

Please sign in to comment.