Closed Sympatron closed 11 months ago
I got both to communicate with a custom in memory channel:
use libosdp::{
channel::{Channel, OsdpChannel},
commands::OsdpCommandBuzzer,
cp::ControlPanel,
events::OsdpEventCardRead,
pd::PeripheralDevice,
OsdpError, OsdpFlag, PdCapEntity, PdCapability, PdId, PdInfo,
};
use ringbuf::HeapRb;
use std::{
io::{Read, Write},
result::Result,
sync::Arc,
thread,
time::Duration,
};
const SCBK: [u8; 16] = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
];
fn main() -> Result<(), Box<dyn std::any::Any + Send>> {
env_logger::builder()
.filter_level(log::LevelFilter::Trace)
.format_target(false)
.format_timestamp(None)
.init();
let (channel1, channel2) = MemoryChannel::new();
let cp = thread::spawn(move || {
cp(channel1).ok();
});
thread::sleep(Duration::from_millis(150));
let pd = thread::spawn(move || {
pd(channel2).ok();
});
pd.join()?;
cp.join()
}
fn cp(stream: MemoryChannel) -> Result<(), OsdpError> {
// let stream = UnixChannel::new("conn-1")?;
let pd_info = vec![PdInfo::for_cp(
"PD 101",
1,
115200,
OsdpFlag::EnforceSecure,
OsdpChannel::new::<MemoryChannel>(Box::new(stream)),
SCBK,
)];
let mut cp = ControlPanel::new(pd_info)?;
let mut i = 0;
loop {
cp.refresh();
thread::sleep(Duration::from_millis(5));
i += 5;
if i % 1600 == 0 {
let _ = cp.send_command(
1,
libosdp::commands::OsdpCommand::Buzzer(OsdpCommandBuzzer {
reader: 0,
control_code: 2,
on_count: 1,
off_count: 0,
rep_count: 1,
}),
);
}
}
}
fn pd(stream: MemoryChannel) -> Result<(), OsdpError> {
// let stream = UnixChannel::connect("conn-1")?;
let pd_info = PdInfo::for_pd(
"PD 101",
1,
115200,
OsdpFlag::EnforceSecure,
PdId::from_number(101),
vec![PdCapability::CommunicationSecurity(PdCapEntity::new(1, 1))],
OsdpChannel::new::<MemoryChannel>(Box::new(stream)),
SCBK,
);
let mut pd = PeripheralDevice::new(pd_info)?;
pd.set_command_callback(|_| {
println!("Received command!");
0
});
let mut i = 0;
loop {
pd.refresh();
thread::sleep(Duration::from_millis(5));
i += 5;
if i % 2000 == 0 {
let _ = pd.notify_event(libosdp::events::OsdpEvent::CardRead(
OsdpEventCardRead::new(libosdp::events::OsdpCardFormats::Weigand, vec![0x55, 0x33]),
));
}
}
}
struct MemoryChannel {
id: i32,
sender: ringbuf::Producer<u8, Arc<HeapRb<u8>>>,
receiver: ringbuf::Consumer<u8, Arc<HeapRb<u8>>>,
}
impl MemoryChannel {
pub fn new() -> (Self, Self) {
let rb1 = HeapRb::<u8>::new(1024);
let (prod1, cons1) = rb1.split();
let rb2 = HeapRb::<u8>::new(1024);
let (prod2, cons2) = rb2.split();
(
Self {
id: 0,
sender: prod1,
receiver: cons2,
},
Self {
id: 1,
sender: prod2,
receiver: cons1,
},
)
}
}
impl Write for MemoryChannel {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.sender.write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
impl Read for MemoryChannel {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.receiver.read(buf)
}
}
impl Channel for MemoryChannel {
fn get_id(&self) -> i32 {
self.id
}
}
Dependencies:
[dependencies]
env_logger = "0.10.1"
libosdp = "0.1.5"
log = "0.4.20"
ringbuf = "0.3.3"
Now send_command
gives me: [INFO ] Invalid PD number 101
And notify_event
gives me this every time:
[ERROR] Failed to decode reply RAW(50) for command POLL(60)
[INFO ] PD SC session timeout!
[ERROR] CMD: POLL(60) not allowed due to ENFORCE_SECURE
[WARN ] PD replied with NAK(6) for CMD(60)
[DEBUG] CMD: ID(61) REPLY: PDID(45)
[DEBUG] CMD: ID(61) REPLY: PDID(45)
[DEBUG] CMD: CAP(62) REPLY: PDCAP(46)
[DEBUG] Reports capability 'CheckCharacter' (1/0)
[DEBUG] Reports capability 'CommunicationSecurity' (1/0)
[DEBUG] Reports capability 'ReceiveBufferSize' (0/1)
[DEBUG] CMD: CAP(62) REPLY: PDCAP(46)
[DEBUG] CMD: CHLNG(76) REPLY: CCRYPT(76)
[DEBUG] CMD: CHLNG(76) REPLY: CCRYPT(76)
[DEBUG] CMD: SCRYPT(77) REPLY: RMAC_I(78)
[INFO ] SC Active
[DEBUG] CMD: SCRYPT(77) REPLY: RMAC_I(78)
[INFO ] SC Active
[ERROR] Failed to decode reply RAW(50) for command POLL(60)
[INFO ] PD SC session timeout!
[ERROR] CMD: POLL(60) not allowed due to ENFORCE_SECURE
[WARN ] PD replied with NAK(6) for CMD(60)
[DEBUG] CMD: ID(61) REPLY: PDID(45)
[DEBUG] CMD: ID(61) REPLY: PDID(45)
[DEBUG] CMD: CAP(62) REPLY: PDCAP(46)
[DEBUG] Reports capability 'CheckCharacter' (1/0)
[DEBUG] Reports capability 'CommunicationSecurity' (1/0)
[DEBUG] Reports capability 'ReceiveBufferSize' (0/1)
[DEBUG] CMD: CAP(62) REPLY: PDCAP(46)
[DEBUG] CMD: CHLNG(76) REPLY: CCRYPT(76)
[DEBUG] CMD: CHLNG(76) REPLY: CCRYPT(76)
[DEBUG] CMD: SCRYPT(77) REPLY: RMAC_I(78)
[INFO ] SC Active
[DEBUG] CMD: SCRYPT(77) REPLY: RMAC_I(78)
[INFO ] SC Active
[ERROR] Failed to decode reply RAW(50) for command POLL(60)
[INFO ] PD SC session timeout!
I am running this in WSL so maybe that's the problem. Can somebody confirm this?
If you are you using WSL2 it should just work. Not sure what is going wrong.
I got both to communicate with a custom in memory channel
Nice, please feel free to send a PR alongside the UnixChannel :)
Now send_command gives me: [INFO ] Invalid PD number 101
Not sure how you got 101
there (maybe this output is from a different run?) but the issue arrises due to the PD number in command; it has to be offsets of the PD in the pd info vector of the CP. In your case, the PD has to be addressed with offset number 0. So the code becomes:
let _ = cp.send_command(0, ...),
And notify_event gives me this every time
This was a bug; the card data length should be in bits for Weigand. Should be addressed in the latest master.
Closing this as no-action needed. Feel free to re-open if needed.
Connection could not be established in Rust project. I tried running the CP and a PD in the same program in different threads. But the two could not communicate successfully. I am running this in WSL so maybe that's the problem. Can somebody confirm this?
main.rs
:Logs: