Skip to content

Commit

Permalink
libosdp: Update to latest version and rework channel API
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 9, 2024
1 parent 4268007 commit 671eaaa
Show file tree
Hide file tree
Showing 21 changed files with 353 additions and 403 deletions.
11 changes: 4 additions & 7 deletions libosdp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,17 @@ categories = ["development-tools", "embedded"]

[dependencies]
bitflags = "2.4.0"
embedded-io = "0.6.1"
libosdp-sys = "0.1.5"
libosdp-sys = "3.0.2"
log = "0.4.20"
multiqueue = "0.3.2"
once_cell = "1.18.0"
parking_lot = { version = "0.12.1", optional = true }
ringbuf = "0.3.3"
serde = { version = "1.0.192", features = ["derive"] }
spin = "0.9.8"
thiserror = { version = "1.0.50", optional = true }

[dev-dependencies]
env_logger = "0.10.0"
multiqueue = "0.3.2"
ringbuf = "0.3.3"

[features]
default = ["std"]
std = ["thiserror", "parking_lot"]
std = ["thiserror"]
45 changes: 38 additions & 7 deletions libosdp/examples/cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,62 @@
// SPDX-License-Identifier: Apache-2.0

use libosdp::{
channel::{OsdpChannel, UnixChannel},
ControlPanel, OsdpError, OsdpFlag, PdInfo,
OsdpError, OsdpFlag, PdInfo, Channel, ChannelError,
};
use std::{result::Result, thread, time::Duration, path::PathBuf, str::FromStr};
use std::{env, thread, time::Duration};

struct OsdpChannel;

impl OsdpChannel {
fn new(_path: &str) -> Self {
// setup device
Self {
}
}
}

/// Read documentation for each member in [libosdp::Channel].
impl Channel for OsdpChannel {
fn get_id(&self) -> i32 {
0
}

fn read(&mut self, _buf: &mut [u8]) -> Result<usize, ChannelError> {
// TODO: Read from device
Ok(0)
}

fn write(&mut self, buf: &[u8]) -> Result<usize, ChannelError> {
// TODO: Write from device
Ok(buf.len())
}

fn flush(&mut self) -> Result<(), ChannelError> {
// TODO: flush device
Ok(())
}
}

fn main() -> Result<(), OsdpError> {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.format_target(false)
.format_timestamp(None)
.init();
let path = PathBuf::from_str("/tmp/conn-1")?;
let stream = UnixChannel::connect(&path)?;
let args: Vec<String> = env::args().collect();
let channel = OsdpChannel::new(&args[1]);
let pd_info = vec![PdInfo::for_cp(
"PD 101",
101,
115200,
OsdpFlag::EnforceSecure,
OsdpChannel::new::<UnixChannel>(Box::new(stream)),
Box::new(channel),
[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f,
],
)];
let mut cp = ControlPanel::new(pd_info)?;
let mut cp = libosdp::ControlPanel::new(pd_info)?;
loop {
cp.refresh();
thread::sleep(Duration::from_millis(50));
Expand Down
45 changes: 38 additions & 7 deletions libosdp/examples/pd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,64 @@
// SPDX-License-Identifier: Apache-2.0

use libosdp::{
channel::{OsdpChannel, UnixChannel},
OsdpError, OsdpFlag, PdCapEntity, PdCapability, PdId, PdInfo, PeripheralDevice,
Channel, ChannelError, OsdpError, OsdpFlag, PdCapEntity, PdCapability, PdId, PdInfo,
};
use std::{result::Result, thread, time::Duration, path::PathBuf, str::FromStr};
use std::{thread, time::Duration};

struct OsdpChannel;

impl OsdpChannel {
pub fn new(_path: &str) -> Self {
// setup device
Self {
}
}
}

/// Read documentation for each member in [libosdp::Channel].
impl Channel for OsdpChannel {
fn get_id(&self) -> i32 {
0
}

fn read(&mut self, _buf: &mut [u8]) -> Result<usize, ChannelError> {
// TODO: Read from device
Ok(0)
}

fn write(&mut self, buf: &[u8]) -> Result<usize, ChannelError> {
// TODO: Write from device
Ok(buf.len())
}

fn flush(&mut self) -> Result<(), ChannelError> {
// TODO: flush device
Ok(())
}
}

fn main() -> Result<(), OsdpError> {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.format_target(false)
.format_timestamp(None)
.init();
let path = PathBuf::from_str("/tmp/conn-1")?;
let stream = UnixChannel::new(&path)?;
let args: Vec<String> = std::env::args().collect();
let channel = OsdpChannel::new(&args[1]);
let pd_info = PdInfo::for_pd(
"PD 101",
101,
115200,
OsdpFlag::EnforceSecure,
PdId::from_number(101),
vec![PdCapability::CommunicationSecurity(PdCapEntity::new(1, 1))],
OsdpChannel::new::<UnixChannel>(Box::new(stream)),
Box::new(channel),
[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f,
],
);
let mut pd = PeripheralDevice::new(pd_info)?;
let mut pd = libosdp::PeripheralDevice::new(pd_info)?;
pd.set_command_callback(|_| {
println!("Received command!");
0
Expand Down
67 changes: 67 additions & 0 deletions libosdp/src/channel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// Copyright (c) 2023-2024 Siddharth Chandrasekaran <sidcha.dev@gmail.com>
//
// SPDX-License-Identifier: Apache-2.0

//! The OSDP specification defines that communication between OSDP devices
//! happen over an RS-485 connection. For testing and development purpose this
//! can be limiting so LibOSDP defines a notion called "Channel" which is a
//! software representation (abstraction) of the physical transport medium.
//!
//! Since RS-485 is stream based protocol, we can think of it to be something
//! that we can read from and write to (which in turn is Read and Write traits
//! in rust). This allows us to run OSDP devices over many IPC schemes such as
//! Unix socket and message queues.
//!
//! This module provides a way to define an OSDP channel and export it to
//! LibOSDP.

/// OSDP channel errors
#[derive(Clone, Debug)]
pub enum ChannelError {
/// Channel is temporarily unavailable (could have blocked until it was
/// ready but LibOSDP required channel to be non-blocking so return "I would
/// have blocked" instead)
WouldBlock,
/// Channel failed irrecoverably.
TransportError,
}

impl From<std::io::Error> for ChannelError {
fn from(value: std::io::Error) -> Self {
match value.kind() {
std::io::ErrorKind::WouldBlock => ChannelError::WouldBlock,
_ => ChannelError::TransportError,
}
}
}

/// The Channel trait acts as an interface for all channel implementors. See
/// module description for the definition of a "channel" in LibOSDP.
pub trait Channel: Send + Sync {
/// Since OSDP channels can be multi-drop (more than one PD can talk to a
/// CP on the same channel) and LibOSDP supports mixing multi-drop
/// connections among PDs it needs a way to identify each unique channel by
/// a channel ID. Implementors of this trait must also provide a method
/// which returns a unique i32 per channel.
fn get_id(&self) -> i32;

/// Pull as many bytes into buffer as possible; returns the number of bytes
/// were read.
fn read(&mut self, buf: &mut [u8]) -> Result<usize, ChannelError>;

/// Write a buffer into this writer, returning how many bytes were written.
fn write(&mut self, buf: &[u8]) -> Result<usize, ChannelError>;

/// Flush this output stream, ensuring that all intermediately buffered
/// contents reach their destination.
fn flush(&mut self) -> Result<(), ChannelError>;
}

impl core::fmt::Debug for dyn Channel {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Channel")
.field("id", &self.get_id())
.finish()
}
}
Loading

0 comments on commit 671eaaa

Please sign in to comment.