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
use failure::Error; use libmodbus_sys as ffi; use modbus_mapping::ModbusMapping; use modbus::Modbus; /// The server is waiting for request from clients and must answer when it is concerned by the request. The libmodbus /// offers the following functions to handle requests: /// /// * Receive /// - [`receive()`](struct.Modbus.html#method.receive) /// * Reply /// - [`reply()`](struct.Modbus.html#method.reply), [`reply_exception()`](struct.Modbus.html#method.reply_exception) /// pub trait ModbusServer { fn receive(&self, request: &mut [u8]) -> Result<i32, Error>; fn reply(&self, request: &[u8], request_len: i32, modbus_mapping: &ModbusMapping) -> Result<i32, Error>; } impl ModbusServer for Modbus { /// `receive` - receive an indication request /// /// The [`receive()`](#method.receive) function shall receive an indication request from the socket of the context /// ctx. /// This function is used by Modbus slave/server to receive and analyze indication request sent by the /// masters/clients. /// /// If you need to use another socket or file descriptor than the one defined in the context ctx, see the function /// [`set_socket()`](struct.Modbus.html#method.set_socket). /// /// # Examples /// /// ```rust,no_run /// use libmodbus_rs::{Modbus, ModbusServer, ModbusTCP}; /// let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); /// let mut query = vec![0; Modbus::MAX_ADU_LENGTH as usize]; /// /// assert!(modbus.receive(&mut query).is_ok()); /// ``` fn receive(&self, request: &mut [u8]) -> Result<i32, Error> { assert!(request.len() <= Modbus::MAX_ADU_LENGTH as usize); unsafe { let len = ffi::modbus_receive(self.ctx, request.as_mut_ptr()); match len { -1 => bail!(::std::io::Error::last_os_error()), len => Ok(len), } } } /// `modbus_reply` - send a reponse to the received request /// /// The [`reply()`](#method.reply) function shall send a response to received request. The request req given in /// argument is analyzed, a response is then built and sent by using the information of the modbus context ctx. /// If the request indicates to read or write a value the operation will done in the modbus mapping mb_mapping /// according to the type of the manipulated data. /// If an error occurs, an exception response will be sent. /// /// This function is designed for Modbus server. /// /// # Examples /// /// ```rust,no_run /// use libmodbus_rs::{Modbus, ModbusServer, ModbusTCP}; /// /// let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); /// let mut query = vec![0; Modbus::MAX_ADU_LENGTH as usize]; /// /// assert!(modbus.receive(&mut query).is_ok()); /// ``` fn reply(&self, request: &[u8], request_len: i32, modbus_mapping: &ModbusMapping) -> Result<i32, Error> { unsafe { let len = ffi::modbus_reply(self.ctx, request.as_ptr(), request_len, modbus_mapping.modbus_mapping); match len { -1 => bail!(::std::io::Error::last_os_error()), len => Ok(len), } } } }