slmp_client/
lib.rs

1mod dual_port_memory;
2mod enums;
3mod internal_memory;
4mod packing;
5mod remote_control;
6mod structs;
7
8pub use dual_port_memory::*;
9pub use enums::*;
10pub use internal_memory::*;
11pub use packing::*;
12pub use remote_control::*;
13pub use structs::*;
14
15/// デバイス読み書き時のデバイス指定32bit版
16///
17/// # 引数
18///
19/// * `d_type` - デバイスタイプ
20/// * `first_addr` - 先頭アドレス
21/// * `count` - 点数
22///
23/// # 返値
24///
25/// パックしたバイト列
26pub fn make_cmd_rw_devices32(d_type: SLMPDeviceCode, first_addr: u32, count: u16) -> Vec<u8> {
27    let mut buf = Vec::new();
28    let d_code = d_type as u16;
29    buf.push(d_code as u8);
30    buf.push((d_code >> 8) as u8);
31    buf.push(first_addr as u8);
32    buf.push((first_addr >> 8) as u8);
33    buf.push((first_addr >> 16) as u8);
34    buf.push((first_addr >> 24) as u8);
35    buf.push(count as u8);
36    buf.push((count >> 8) as u8);
37    buf
38}
39
40/// デバイス読み書き時のデバイス指定16bit版
41///
42/// # 引数
43///
44/// * `d_type` - デバイスタイプ
45/// * `first_addr` - 先頭アドレス
46/// * `count` - 点数
47///
48/// # 返値
49///
50/// パックしたバイト列
51pub fn make_cmd_rw_devices16(d_type: SLMPDeviceCode, first_addr: u16, count: u16) -> Vec<u8> {
52    let mut buf = Vec::new();
53    let d_code = d_type as u8;
54    buf.push(d_code);
55    buf.push(first_addr as u8);
56    buf.push((first_addr >> 8) as u8);
57    buf.push(0u8);
58    buf.push(count as u8);
59    buf.push((count >> 8) as u8);
60    buf
61}
62/// セルフチェック
63///
64/// # 引数
65///
66/// * `connection_info` - 接続情報
67/// * `timeout` - SLMPコマンドのタイムアウト
68/// * `data` - 折り返しチェックのための文字列データ、0-9もしくはA-Zのみが使用可能
69///
70/// # 返値
71///
72/// 送信時のシリアル
73pub fn send_self_test_cmd(
74    connection_info: &mut SLMPConnectionInfo,
75    timeout: u16,
76    data: &[u8],
77) -> Option<u16> {
78    let mut buf = Vec::new();
79    let length = data.len();
80    if length > 960 {
81        eprintln!("too long data");
82        return None;
83    }
84    buf.push(length as u8);
85    buf.push((length >> 8) as u8);
86    buf.extend_from_slice(data);
87    connection_info.send_cmd(timeout, SLMPCommand::SelfTest, 0, &buf)
88}
89/// セルフテストの応答を処理
90/// # 引数
91/// * `buf` - セルフテストの応答を含んだバッファ
92/// # 返値
93/// セルフテストで送信したデータ
94pub fn decode_self_test_response(buf: &[u8]) -> Vec<u8> {
95    let mut ret = Vec::new();
96    for d in buf[2..].iter() {
97        ret.push(*d);
98    }
99    ret
100}
101
102/// エラークリア
103/// # 引数
104/// * `connection_info` - SLMP接続情報
105/// * `timeout` - SLMPコマンドのタイムアウト, 250msec単位
106/// # 返値
107/// コマンド発行時のシリアル番号
108pub fn send_clear_error_cmd(connection_info: &mut SLMPConnectionInfo, timeout: u16) -> Option<u16> {
109    connection_info.send_cmd(timeout, SLMPCommand::ClearErrorCode, 0, &[])
110}
111/// 受信したオンデマンドデータの処理
112/// # 引数
113/// * `buf` - 受信したオンデマンドデータの入ったバッファ
114/// # 返値
115/// オンデマンドデータ
116pub fn decode_on_demand_data(buf: &[u8]) -> Option<Vec<u8>> {
117    if buf[0] != 1 || buf[1] != 0x21 || buf[2] != 0 || buf[3] != 0 {
118        None
119    } else {
120        let mut ret = Vec::new();
121        ret.copy_from_slice(&buf[3..]);
122        Some(ret)
123    }
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129    use std::net::{IpAddr, Ipv4Addr, SocketAddr};
130
131    #[test]
132    #[ignore]
133    pub fn test_udp_self_test() {
134        let mut connection_info = SLMPConnectionInfo::new_udp(SocketAddr::new(
135            IpAddr::V4(Ipv4Addr::new(192, 168, 1, 10)),
136            5000,
137        ));
138        let buf = [0x31, 0x32, 0x34];
139        let seq = send_self_test_cmd(&mut connection_info, 40, &buf);
140        let (seq_r, buf_r, end_code) = connection_info.recv_cmd();
141        assert_eq!(seq.unwrap(), seq_r);
142        assert_eq!(end_code, Some(SLMPEndCode::Success));
143        let ret = decode_self_test_response(&buf_r);
144        assert_eq!(ret.len(), 3);
145        assert_eq!(ret[0] as u8, buf[0] as u8);
146        assert_eq!(ret[1] as u8, buf[1] as u8);
147        assert_eq!(ret[2] as u8, buf[2] as u8);
148    }
149}