Skip to content

Commit

Permalink
feat(custom_server): add standard FC handling in the server implement…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
dkoehler-dev committed Mar 12, 2024
1 parent afbfbca commit 2d1ccab
Showing 1 changed file with 47 additions and 9 deletions.
56 changes: 47 additions & 9 deletions rodbus/examples/custom_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,46 +85,67 @@ impl RequestHandler for SimpleHandler {
if values.len() != 2 {
return Err(ExceptionCode::IllegalDataValue);
}

let start = *values.iter().next().unwrap();
let count = *values.iter().next().unwrap();

// read coils
Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![start, count]))
let coil_values = self.coils_as_mut().get(start as usize..start as usize + count as usize).unwrap().to_vec();
let result = coil_values.iter().map(|&val| val as u16).collect();

Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), result))
},
0x02 => {
if values.len() != 2 {
return Err(ExceptionCode::IllegalDataValue);
}

let start = *values.iter().next().unwrap();
let count = *values.iter().next().unwrap();

// read discrete inputs
Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![start, count]))
let discrete_input_values = self.discrete_inputs_as_mut().get(start as usize..start as usize + count as usize).unwrap().to_vec();
let result = discrete_input_values.iter().map(|&val| val as u16).collect();

Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), result))
},
0x03 => {
if values.len() != 2 {
return Err(ExceptionCode::IllegalDataValue);
}

let start = *values.iter().next().unwrap();
let count = *values.iter().next().unwrap();

// read holding registers
Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![start, count]))
let result = self.holding_registers_as_mut().get(start as usize..start as usize + count as usize).unwrap().to_vec();

Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), result))
},
0x04 => {
if values.len() != 2 {
return Err(ExceptionCode::IllegalDataValue);
}

let start = *values.iter().next().unwrap();
let count = *values.iter().next().unwrap();

// read input registers
Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![start, count]))
let result = self.input_registers_as_mut().get(start as usize..start as usize + count as usize).unwrap().to_vec();

Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), result))
},
0x05 => {
if values.len() != 2 {
return Err(ExceptionCode::IllegalDataValue);
}

let address = *values.iter().next().unwrap();
let value = *values.iter().next().unwrap() != 0;

// write single coil
let result = self.write_single_coil(Indexed::new(address, value));

match result {
Ok(_) => Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![address, value as u16])),
Err(exception) => Err(exception),
Expand All @@ -136,8 +157,10 @@ impl RequestHandler for SimpleHandler {
}
let address = *values.iter().next().unwrap();
let value = *values.iter().next().unwrap();

// write single register
let result = self.write_single_register(Indexed::new(address, value));

match result {
Ok(_) => Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![address, value])),
Err(exception) => Err(exception),
Expand All @@ -147,47 +170,62 @@ impl RequestHandler for SimpleHandler {
if values.len() < 5 {
return Err(ExceptionCode::IllegalDataValue);
}

let start = *values.iter().next().unwrap();
let count = *values.iter().next().unwrap();
let mut iterator = values.iter().skip(2);
let mut coils = vec![];
for _ in 0..count {
coils.push(*iterator.next().unwrap() != 0);
}

// write multiple coils
let result = self.write_multiple_coils(WriteCoils::new(AddressRange::try_from(start, count).unwrap(), coils.into_iter()));
/*
let range = AddressRange::try_from(start, count).unwrap();
let result = self.write_multiple_coils(WriteCoils::new(range, coils.into_iter()));
match result {
Ok(_) => Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![start, count])),
Err(exception) => Err(exception),
}
*/

Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![start, count]))
},
0x10 => {
if values.len() < 5 {
return Err(ExceptionCode::IllegalDataValue);
}

let start = *values.iter().next().unwrap();
let count = *values.iter().next().unwrap();
let mut iterator = values.iter().skip(2);
let mut registers = vec![];
for _ in 0..count {
registers.push(*iterator.next().unwrap());
}

// write multiple registers
let result = self.write_multiple_registers(WriteRegisters::new(AddressRange::try_from(start, count).unwrap(), registers.into_iter());
/*
let range = AddressRange::try_from(start, count).unwrap();
let result = self.write_multiple_registers(WriteRegisters::new(range, registers.into_iter()));
match result {
Ok(_) => Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![start, count])),
Err(exception) => Err(exception),
}
*/
Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), vec![start, count]))
},
0x69 => {
0x41 => {
// increment each CFC value by 1 and return the result
// Create a new vector to hold the incremented values
let incremented_data = values.iter().map(|&val| val + 1).collect();

// Return a new CustomFunctionCode with the incremented data
Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), incremented_data))
},
0x70 => {
0x42 => {
// add a new value to the buffer and return the result
// Create a new vector to hold the incremented values
let extended_data = {
Expand All @@ -199,7 +237,7 @@ impl RequestHandler for SimpleHandler {
// Return a new CustomFunctionCode with the incremented data
Ok(CustomFunctionCode::new(values.function_code(), values.byte_count_in(), values.byte_count_out(), extended_data))
},
0x71 => {
0x43 => {
// remove the first value from the buffer and return the result
// Create a new vector to hold the incremented values
let truncated_data = {
Expand Down

0 comments on commit 2d1ccab

Please sign in to comment.