1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use crate::iso8583::iso_spec::{Spec, IsoMsg};
use crate::iso8583::IsoError;
use std::net::{TcpStream, Shutdown};
use crate::iso8583::mli::{MLI, MLIType, MLI2E, MLI2I, MLI4E, MLI4I};
use std::io::{Write, Read};
use crate::iso8583::server::get_hexdump;
pub struct ISOTcpClient {
server_addr: String,
mli: Box<dyn MLI>,
spec: &'static Spec,
_tcp_stream: Option<TcpStream>,
}
impl ISOTcpClient {
pub fn new(server_addr: &str, spec: &'static Spec, mli_type: MLIType) -> ISOTcpClient {
let mli: Box<dyn MLI>;
match mli_type {
MLIType::MLI2E => mli = Box::new(MLI2E {}),
MLIType::MLI2I => mli = Box::new(MLI2I {}),
MLIType::MLI4E => mli = Box::new(MLI4E {}),
MLIType::MLI4I => mli = Box::new(MLI4I {})
}
ISOTcpClient {
server_addr: server_addr.to_string(),
spec,
mli,
_tcp_stream: None,
}
}
pub fn send(&mut self, iso_msg: &IsoMsg) -> Result<IsoMsg, IsoError> {
match iso_msg.assemble() {
Ok(data) => {
let mut buf = self.mli.create(&data.len()).unwrap();
buf.extend(data);
self.send_recv(&buf)
}
Err(e) => {
Err(IsoError { msg: format!("Failed to assemble request message: {}", e.msg) })
}
}
}
fn send_recv(&mut self, raw_msg: &Vec<u8>) -> Result<IsoMsg, IsoError> {
println!("raw iso msg = {}", hex::encode(raw_msg.as_slice()));
if self._tcp_stream.is_none() {
self._tcp_stream = match TcpStream::connect(&self.server_addr) {
Err(e) => return Err(IsoError { msg: e.to_string() }),
Ok(c) => {
println!("connected to server @ {:?}", c.local_addr());
Option::Some(c)
}
}
}
let client = self._tcp_stream.as_mut().unwrap();
client.write_all(raw_msg.as_slice()).unwrap();
client.flush().unwrap();
let len: u32;
match self.mli.parse(client) {
Ok(n) => len = n,
Err(e) => return Err(e)
};
let mut out_buf = vec![0; len as usize];
match client.read_exact(&mut out_buf[..]) {
Ok(()) => {
println!("received response: with {} bytes. \n {}\n", len, get_hexdump(&out_buf));
match self.spec.parse(&mut out_buf) {
Ok(resp_iso_msg) => {
Ok(resp_iso_msg)
}
Err(e) => {
Err(IsoError { msg: e.msg })
}
}
}
Err(e) => {
Err(IsoError { msg: e.to_string() })
}
}
}
pub fn close(&mut self) {
self._tcp_stream.as_ref().unwrap().shutdown(Shutdown::Both).unwrap();
}
}