Comments (3)
I would think that you could have the modbus server return an error response, by returning from call() like so:
. . .
let fncode = tokio_modbus::coderc::req_to_fn_code(&req);
return std::future::ready(Err(tokio_modbus::frame::ExceptionResponse {
function: fncode,
exception: tokio_modbus::frame::Exception::IllegalFunction, // Or any other kind of Modbus exception
}));
. . .
Like mentioned before, for this to work, the following needs to be published:
- frame::ExceptionResponse
- frame::Exception
- codec::req_to_fn_code()
The first 2 could be included in the prelude, like Request and Response are.
The last 1 I am not sure about.
If you return with another kind of error than an ExceptionResponse, like std::io::Error, the application compiles just fine, but the connection is forcibly closed by the server when the error is returned.
The workaround from @justinyhuang (clever!) works fine:
return std::future::ready(error_response(&req, Exception::IllegalFunction));
Copy the following functions and enum to make this work:
fn error_response(req: &Request, exc: Exception) -> std::io::Result<Response> {
Ok(Response::Custom(req2functioncode(&req) | 0x80, vec![exc as u8]))
}
fn req2functioncode(req: &Request) -> FunctionCode {
match *req {
Request::ReadCoils(_, _) => 0x01,
Request::ReadDiscreteInputs(_, _) => 0x02,
Request::WriteSingleCoil(_, _) => 0x05,
Request::WriteMultipleCoils(_, _) => 0x0F,
Request::ReadInputRegisters(_, _) => 0x04,
Request::ReadHoldingRegisters(_, _) => 0x03,
Request::WriteSingleRegister(_, _) => 0x06,
Request::WriteMultipleRegisters(_, _) => 0x10,
Request::ReadWriteMultipleRegisters(_, _, _, _) => 0x17,
Request::Custom(code, _) => code,
_ => 0x00,
}
}
#[repr(u8)]
enum Exception {
IllegalFunction = 0x01,
IllegalDataAddress = 0x02,
IllegalDataValue = 0x03,
ServerDeviceFailure = 0x04,
Acknowledge = 0x05,
ServerDeviceBusy = 0x06,
MemoryParityError = 0x08,
GatewayPathUnavailable = 0x0A,
GatewayTargetDevice = 0x0B,
}
from tokio-modbus.
Any response to this question? it appears to me that the exception definitions are in frame
which is private.
How could a server implementation produce an appropriate exception response in this case?
For what is worth, below is my workaround:
the client side appears to be taken care of so if you are only interested in building a client the current implementation would work just fine.
the server side however does not get support from this crate at the moment, the way I get it working is to overload the custom
response type to send back the exception response. though it is not clean and could be confusing, but it works for now.
from tokio-modbus.
I wanted to match on
Custom { kind: Other, error: ExceptionResponse { function: 3, exception: GatewayTargetDevice } } => {
}
but you are right frame is private where I find myself needing a few things from it.
In the end I converted the error to a string and did a match (yuck)
from tokio-modbus.
Related Issues (20)
- Flow control when using RS-485 HOT 2
- No timeout in the RTU client async implementation HOT 2
- Infinite retry loop with heavy CPU load HOT 5
- "Device or resource busy" in RTU server example HOT 3
- Generalize impl around `Service` usage HOT 5
- Tokio module 'runtime' is private HOT 12
- Asyncronous responses / Multiplexing HOT 2
- How to convert tokio_modbus::Request to bytes? HOT 5
- TCP server example - shared data hashmap HOT 5
- TCP Sync Client HOT 6
- write_multiple_registers taking array as a param HOT 3
- Can not disconnect slave, need help HOT 3
- Although disconnect the context, the SerialStream reopen error HOT 1
- Patterns/best practice for reconnect-after-failure? HOT 1
- How to turn 'tokio_serial::SerialStream' into global static to save it for reuse
- is_connected()? HOT 1
- Modbus RTU - Serial Direction Pin HOT 6
- Dev Dependencies: Upgrade rustls-pemfile and tokio-rustls HOT 4
- Return Modbus exception codes for client and server.
- Use `async-trait` in `Service` trait ? HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tokio-modbus.