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 104 105 106 107 108 109 110 111 112
use failure::Error; use libmodbus_sys as ffi; use modbus::Modbus; use std::ffi::CString; /// The TCP backend implements a Modbus variant used for communications over TCP/IPv4 networks. /// It does not require a checksum calculation as lower layer takes care of the same. /// /// * Create a Modbus TCP context /// - [`new_tcp()`](struct.Modbus.html#method.new_tcp) /// pub trait ModbusTCP { fn new_tcp(ip: &str, port: i32) -> Result<Modbus, Error>; fn tcp_accept(&mut self, socket: &mut i32) -> Result<i32, Error>; fn tcp_listen(&mut self, num_connection: i32) -> Result<i32, Error>; } impl ModbusTCP for Modbus { /// `new_tcp` - create a libmodbus context for TCP/IPv4 /// /// The [`new_tcp()`](#method.new_tcp) function shall allocate and initialize a modbus_t structure /// to communicate with a Modbus TCP IPv4 server. /// The **ip** argument specifies the IP address of the server to which the client wants to /// establish a connection. A empty string `""` value can be used to listen any addresses in server mode. /// The **port** argument is the TCP port to use. Set the port to `MODBUS_TCP_DEFAULT_PORT` /// to use the default one (502). It’s convenient to use a port number greater than or /// equal to 1024 because it’s not necessary to have administrator privileges. /// /// # Examples /// /// ``` /// use libmodbus_rs::{Modbus, ModbusTCP}; /// /// let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); /// let modbus = Modbus::new_tcp("127.0.0.1", Modbus::TCP_DEFAULT_PORT as i32).unwrap(); /// /// match modbus.connect() { /// Ok(_) => { } /// Err(e) => println!("Error: {}", e), /// } /// ``` fn new_tcp(ip: &str, port: i32) -> Result<Modbus, Error> { unsafe { let ip = CString::new(ip).unwrap(); let ctx = ffi::modbus_new_tcp(ip.as_ptr(), port); if ctx.is_null() { bail!(::std::io::Error::last_os_error()) } else { Ok(Modbus { ctx: ctx }) } } } /// `tcp_accept` - accept a new connection on a TCP Modbus socket (IPv4) /// /// The [`tcp_accept()`](#method.tcp_accept) function shall extract the first connection on the /// queue of pending connections and create a new socket given as argument. /// /// # Parameters /// /// * `socket` - Socket /// /// # Examples /// /// ```rust,no_run /// use libmodbus_rs::{Modbus, ModbusTCP}; /// /// let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); /// let mut socket = modbus.tcp_listen(1).unwrap(); /// /// modbus.tcp_accept(&mut socket); /// ``` fn tcp_accept(&mut self, socket: &mut i32) -> Result<i32, Error> { unsafe { match ffi::modbus_tcp_accept(self.ctx, socket) { -1 => bail!(::std::io::Error::last_os_error()), socket => Ok(socket), } } } /// `tcp_listen` - create and listen a TCP Modbus socket (IPv4) /// /// The [`tcp_listen()`](#method.tcp_listen) function shall create a socket and listen to maximum /// `num_connection` incoming connections on the specified IP address. /// If IP address is set to NULL or '0.0.0.0', any addresses will be listen. /// /// # Parameters /// /// * `num_connection` - maximum number of incoming connections on the specified IP address /// /// # Examples /// /// ```rust,no_run /// use libmodbus_rs::{Modbus, ModbusTCP}; /// /// let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); /// /// let socket = modbus.tcp_listen(1); /// ``` fn tcp_listen(&mut self, num_connection: i32) -> Result<i32, Error> { unsafe { match ffi::modbus_tcp_listen(self.ctx, num_connection) { -1 => bail!(::std::io::Error::last_os_error()), socket => Ok(socket), } } } }