Skip to content

Commit

Permalink
osdpctl: More WIP changes; CP and PD services work
Browse files Browse the repository at this point in the history
Signed-off-by: Siddharth Chandrasekaran <[email protected]>
  • Loading branch information
sidcha committed Feb 13, 2024
1 parent 3a4df4d commit a0f8968
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 91 deletions.
1 change: 1 addition & 0 deletions osdpctl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ dirs = "5.0.1"
libosdp = { version = "0.1.2", path = "../rust" }
log = "0.4.20"
log4rs = "1.2.0"
nix = { version = "0.27.1", features = ["signal"] }
rand = "0.8.5"
toml = "0.8.8"
62 changes: 50 additions & 12 deletions osdpctl/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use anyhow::bail;
use anyhow::Context;
use configparser::ini::Ini;
use libosdp::{
channel::{UnixChannel, OsdpChannel},
channel::{OsdpChannel, UnixChannel},
OsdpFlag, PdCapability, PdId, PdInfo,
};
use rand::Rng;
use std::{
fmt::Write,
path::{Path, PathBuf},
str::FromStr,
};
use rand::Rng;

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

Expand Down Expand Up @@ -85,7 +86,7 @@ pub struct PdData {
}

pub struct CpConfig {
runtime_dir: PathBuf,
pub runtime_dir: PathBuf,
pub name: String,
pd_data: Vec<PdData>,
pub log_level: log::LevelFilter,
Expand All @@ -97,7 +98,6 @@ impl CpConfig {
let name = config.get("default", "name").unwrap();
let mut runtime_dir = runtime_dir.to_owned();
runtime_dir.push(&name);
std::fs::create_dir_all(&runtime_dir)?;
let mut pd_data = Vec::new();
for pd in 0..num_pd {
let section = format!("pd-{pd}");
Expand Down Expand Up @@ -127,15 +127,18 @@ impl CpConfig {
}

pub fn pd_info(&self) -> Result<Vec<PdInfo>> {
let mut runtime_dir = self.runtime_dir.clone();
runtime_dir.pop();
self.pd_data
.iter()
.map(|d| {
let parts: Vec<&str> = d.channel.split("::").collect();
if parts[0] != "unix" {
bail!("Only unix channel is supported for now")
}
let path = self.runtime_dir.join(format!("{}/{}.sock", d.name, parts[1]).as_str());
let stream = UnixChannel::connect(&path)?;
let path = runtime_dir.join(format!("{}/{}.sock", d.name, parts[1]).as_str());
let stream = UnixChannel::connect(&path)
.context("Unable to connect to PD channel")?;
Ok(PdInfo::for_cp(
&self.name,
d.address,
Expand All @@ -150,7 +153,7 @@ impl CpConfig {
}

pub struct PdConfig {
runtime_dir: PathBuf,
pub runtime_dir: PathBuf,
pub name: String,
channel: String,
address: i32,
Expand All @@ -165,13 +168,24 @@ impl PdConfig {
pub fn new(config: &Ini, runtime_dir: &Path) -> Result<Self> {
let vendor_code = config.getuint("pd_id", "vendor_code").unwrap().unwrap() as u32;
let serial_number = config.getuint("pd_id", "serial_number").unwrap().unwrap() as u32;
let firmware_version = config.getuint("pd_id", "firmware_version").unwrap().unwrap() as u32;
let firmware_version = config
.getuint("pd_id", "firmware_version")
.unwrap()
.unwrap() as u32;
let pd_id = PdId {
version: config.getuint("pd_id", "version").unwrap().unwrap() as i32,
model: config.getuint("pd_id", "model").unwrap().unwrap() as i32,
vendor_code: (vendor_code as u8, (vendor_code >> 8) as u8, (vendor_code >> 16) as u8),
vendor_code: (
vendor_code as u8,
(vendor_code >> 8) as u8,
(vendor_code >> 16) as u8,
),
serial_number: serial_number.to_le_bytes(),
firmware_version: (firmware_version as u8, (firmware_version >> 8) as u8, (firmware_version >> 16) as u8),
firmware_version: (
firmware_version as u8,
(firmware_version >> 8) as u8,
(firmware_version >> 16) as u8,
),
};
let mut flags = OsdpFlag::empty();
if let Some(val) = config.get("default", "flags") {
Expand All @@ -197,10 +211,9 @@ impl PdConfig {
_ => log::LevelFilter::Off,
};
let key = &config.get("default", "scbk").unwrap();
let name = config.get("default", "name").unwrap();
let name = config.get("default", "name").unwrap();
let mut runtime_dir = runtime_dir.to_owned();
runtime_dir.push(&name);
std::fs::create_dir_all(&runtime_dir)?;
let key_store = KeyStore::create(runtime_dir.join("key.store"), key)?;
Ok(Self {
name,
Expand Down Expand Up @@ -240,9 +253,34 @@ pub enum DeviceConfig {
PdConfig(PdConfig),
}

fn read_pid_from_file(file: PathBuf) -> Result<i32> {
let pid = std::fs::read_to_string(file)?;
let pid = pid.trim();
let pid = pid.parse::<i32>()?;
Ok(pid)
}

impl DeviceConfig {
pub fn get_pid(&self) -> Result<i32> {
match self {
DeviceConfig::CpConfig(dev) => {
let pid_file = dev.runtime_dir.join(format!("dev-{}.pid", dev.name));
read_pid_from_file(pid_file)
}
DeviceConfig::PdConfig(dev) => {
let pid_file = dev.runtime_dir.join(format!("dev-{}.pid", dev.name));
read_pid_from_file(pid_file)
}
}
}
}

impl DeviceConfig {
pub fn new(cfg: &Path, runtime_dir: &Path) -> Result<Self> {
let mut config = Ini::new_cs();
if !cfg.exists() {
bail!("Config {} does not exist!", cfg.display())
}
config.load(cfg).unwrap();
let config = match config.get("default", "num_pd") {
Some(_) => DeviceConfig::CpConfig(CpConfig::new(&config, runtime_dir)?),
Expand Down
28 changes: 25 additions & 3 deletions osdpctl/src/cp.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
use std::{thread, time::Duration};

use crate::config::CpConfig;
use anyhow::Context;
use libosdp::{OsdpEvent, ControlPanel};
use libosdp::{ControlPanel, OsdpEvent};
use std::io::Write;

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

pub fn create_cp(dev: &CpConfig) -> Result<ControlPanel> {
fn setup(dev: &CpConfig, daemonize: bool) -> Result<()> {
if dev.runtime_dir.exists() {
std::fs::remove_dir_all(&dev.runtime_dir)?;
}
std::fs::create_dir_all(&dev.runtime_dir)?;
if daemonize {
crate::daemonize::daemonize(&dev.runtime_dir, &dev.name)?;
} else {
let pid_file = dev.runtime_dir.join(format!("dev-{}.pid", dev.name));
let mut pid_file = std::fs::File::create(pid_file)?;
write!(pid_file, "{}", std::process::id())?;
}
Ok(())
}

pub fn main(dev: CpConfig, daemonize: bool) -> Result<()> {
setup(&dev, daemonize)?;
let pd_info = dev.pd_info()
.context("Failed to create PD info list")?;
let mut cp = ControlPanel::new(pd_info)?;
Expand All @@ -25,5 +44,8 @@ pub fn create_cp(dev: &CpConfig) -> Result<ControlPanel> {
}
0
});
Ok(cp)
loop {
cp.refresh();
thread::sleep(Duration::from_millis(50));
}
}
20 changes: 20 additions & 0 deletions osdpctl/src/daemonize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use anyhow::Context;
use daemonize::Daemonize;
use std::path::Path;

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

pub fn daemonize(runtime_dir: &Path, name: &str) -> Result<()> {
let stdout = std::fs::File::create(runtime_dir.join(format!("dev-{}.out.log", name).as_str()))
.context("Failed to create stdout for daemon")?;
let stderr = std::fs::File::create(runtime_dir.join(format!("dev-{}.err.log", name).as_str()))
.context("Failed to create stderr for daemon")?;
let daemon = Daemonize::new()
.pid_file(runtime_dir.join(format!("dev-{}.pid", name)))
.chown_pid_file(true)
.working_directory(runtime_dir)
.stdout(stdout)
.stderr(stderr);
daemon.start().context("Failed to start daemon process")?;
Ok(())
}
Loading

0 comments on commit a0f8968

Please sign in to comment.