ads_client/
ads_write_control.rs1use bytes::{Bytes, BytesMut};
2use log::info;
3use crate::{Client, Result, AdsCommand, AdsError, AdsErrorCode, StateInfo, HEADER_SIZE, LEN_WR_CTRL_MIN, misc::HandleData};
4
5impl Client {
6
7 fn pre_write_ctrl(&self, state : &StateInfo, data : Option<&[u8]>, invoke_id : u32) -> Bytes {
8 let mut data_length : u32 = 0;
9
10 if let Some(v) = data {
11 data_length = v.len() as u32;
12 }
13
14 let ams_header = self.c_init_ams_header(invoke_id, Some(LEN_WR_CTRL_MIN as u32 + data_length), AdsCommand::WriteControl);
15 let mut wr_ctrl_header : [u8; LEN_WR_CTRL_MIN] = [0; LEN_WR_CTRL_MIN];
16
17 wr_ctrl_header[0..2].copy_from_slice(&(state.ads_state as u16).to_ne_bytes());
18 wr_ctrl_header[2..4].copy_from_slice(&state.device_state.to_ne_bytes());
19 wr_ctrl_header[4..8].copy_from_slice(&data_length.to_ne_bytes());
20
21 let iter_ams_header = ams_header.into_iter();
22 let iter_wrt_ctrl = wr_ctrl_header.into_iter();
23
24 let mut _wr_ctrl_request = BytesMut::with_capacity(HEADER_SIZE + LEN_WR_CTRL_MIN + data_length as usize);
25
26 match data {
27 Some(data) => _wr_ctrl_request = iter_ams_header.chain(iter_wrt_ctrl.chain(data.iter().cloned())).collect(),
28 None => _wr_ctrl_request = iter_ams_header.chain(iter_wrt_ctrl).collect()
29 }
30
31 _wr_ctrl_request.freeze()
32 }
33
34 fn post_write_ctrl(wr_ctrl_response : HandleData) -> Result<()>{
35 Client::eval_ams_error(wr_ctrl_response.ams_err)?;
36
37 wr_ctrl_response.payload
38 .map(|p| Client::eval_return_code(p.as_ref()))
39 .ok_or_else(|| AdsError{n_error : AdsErrorCode::ADSERR_DEVICE_INVALIDDATA.into(), s_msg : String::from("Invalid data values")})??;
40
41 Ok(())
42 }
43
44 pub async fn write_control(&self, state : &StateInfo, data: Option<&[u8]>) -> Result<()>{
45 let invoke_id = self.create_invoke_id();
47 let _wr_ctr_request = self.pre_write_ctrl(state, data, invoke_id);
48
49 info!("Submit Write Control Request: Invoke ID: {}", invoke_id);
50
51 self.register_command_handle(invoke_id, AdsCommand::WriteControl);
53
54 let cmd_man_future = self.create_cmd_man_future(invoke_id);
56
57 let socket_future = self.socket_write(&_wr_ctr_request);
59
60 tokio::try_join!(cmd_man_future, socket_future).and_then( | (wr_ctr_response, _) | Client::post_write_ctrl(wr_ctr_response))
61 }
62}