ads_proto/proto/
response.rs

1use crate::error::{AdsError, TryIntoError};
2use crate::proto::ads_state::AdsState;
3use crate::proto::command_id::CommandID;
4use crate::proto::proto_traits::{Command, ReadFrom, WriteTo};
5use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
6use std::convert::TryInto;
7use std::io::{self, Read, Write};
8use std::string::FromUtf8Error;
9
10/// Each Response enum variant holds the struct with the data needed for a certain command.
11/// The created Response can then be supplied to an [AMS header](super::ams_header).
12/// ```
13/// use crate::ads_proto::proto::response::*;
14/// use crate::ads_proto::proto::proto_traits::{ReadFrom, WriteTo};
15/// use crate::ads_proto::error::AdsError;
16///
17/// let response = Response::ReadDeviceInfo(ReadDeviceInfoResponse::new(
18///     AdsError::ErrNoError,
19///     1,
20///     2,
21///     33,
22///     [1; 16],
23/// ));
24/// ```
25#[derive(Debug, PartialEq, Eq)]
26pub enum Response {
27    Invalid(InvalidResponse),
28    ReadDeviceInfo(ReadDeviceInfoResponse),
29    Read(ReadResponse),
30    Write(WriteResponse),
31    ReadState(ReadStateResponse),
32    WriteControl(WriteControlResponse),
33    AddDeviceNotification(AddDeviceNotificationResponse),
34    DeleteDeviceNotification(DeleteDeviceNotificationResponse),
35    DeviceNotification(AdsNotificationStream),
36    ReadWrite(ReadWriteResponse),
37}
38
39impl WriteTo for Response {
40    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
41        match self {
42            Response::Invalid(_) => Ok(()),
43            Response::ReadDeviceInfo(w) => w.write_to(&mut wtr),
44            Response::Read(w) => w.write_to(&mut wtr),
45            Response::Write(w) => w.write_to(&mut wtr),
46            Response::ReadState(w) => w.write_to(&mut wtr),
47            Response::WriteControl(w) => w.write_to(&mut wtr),
48            Response::AddDeviceNotification(w) => w.write_to(&mut wtr),
49            Response::DeleteDeviceNotification(w) => w.write_to(&mut wtr),
50            Response::DeviceNotification(w) => w.write_to(&mut wtr),
51            Response::ReadWrite(w) => w.write_to(&mut wtr),
52        }
53    }
54}
55
56impl Command for Response {
57    fn command_id(&self) -> CommandID {
58        match self {
59            Response::Invalid(r) => r.command_id,
60            Response::ReadDeviceInfo(r) => r.command_id,
61            Response::ReadState(r) => r.command_id,
62            Response::Read(r) => r.command_id,
63            Response::Write(r) => r.command_id,
64            Response::ReadWrite(r) => r.command_id,
65            Response::AddDeviceNotification(r) => r.command_id,
66            Response::WriteControl(r) => r.command_id,
67            Response::DeviceNotification(r) => r.command_id,
68            Response::DeleteDeviceNotification(r) => r.command_id,
69        }
70    }
71}
72
73impl From<InvalidResponse> for Response {
74    fn from(request: InvalidResponse) -> Self {
75        Response::Invalid(request)
76    }
77}
78
79impl TryInto<InvalidResponse> for Response {
80    type Error = TryIntoError;
81
82    fn try_into(self) -> Result<InvalidResponse, Self::Error> {
83        match self {
84            Response::Invalid(r) => Ok(r),
85            _ => Err(TryIntoError::TryIntoResponseFailed),
86        }
87    }
88}
89
90impl From<ReadDeviceInfoResponse> for Response {
91    fn from(response: ReadDeviceInfoResponse) -> Self {
92        Response::ReadDeviceInfo(response)
93    }
94}
95
96impl TryInto<ReadDeviceInfoResponse> for Response {
97    type Error = TryIntoError;
98
99    fn try_into(self) -> Result<ReadDeviceInfoResponse, Self::Error> {
100        match self {
101            Response::ReadDeviceInfo(r) => Ok(r),
102            _ => Err(TryIntoError::TryIntoResponseFailed),
103        }
104    }
105}
106
107impl From<WriteResponse> for Response {
108    fn from(response: WriteResponse) -> Self {
109        Response::Write(response)
110    }
111}
112
113impl TryInto<WriteResponse> for Response {
114    type Error = TryIntoError;
115
116    fn try_into(self) -> Result<WriteResponse, Self::Error> {
117        match self {
118            Response::Write(r) => Ok(r),
119            _ => Err(TryIntoError::TryIntoResponseFailed),
120        }
121    }
122}
123
124impl From<WriteControlResponse> for Response {
125    fn from(response: WriteControlResponse) -> Self {
126        Response::WriteControl(response)
127    }
128}
129
130impl TryInto<WriteControlResponse> for Response {
131    type Error = TryIntoError;
132
133    fn try_into(self) -> Result<WriteControlResponse, Self::Error> {
134        match self {
135            Response::WriteControl(r) => Ok(r),
136            _ => Err(TryIntoError::TryIntoResponseFailed),
137        }
138    }
139}
140
141impl From<ReadStateResponse> for Response {
142    fn from(response: ReadStateResponse) -> Self {
143        Response::ReadState(response)
144    }
145}
146
147impl TryInto<ReadStateResponse> for Response {
148    type Error = TryIntoError;
149
150    fn try_into(self) -> Result<ReadStateResponse, Self::Error> {
151        match self {
152            Response::ReadState(r) => Ok(r),
153            _ => Err(TryIntoError::TryIntoResponseFailed),
154        }
155    }
156}
157
158impl From<AddDeviceNotificationResponse> for Response {
159    fn from(response: AddDeviceNotificationResponse) -> Self {
160        Response::AddDeviceNotification(response)
161    }
162}
163
164impl TryInto<AddDeviceNotificationResponse> for Response {
165    type Error = TryIntoError;
166
167    fn try_into(self) -> Result<AddDeviceNotificationResponse, Self::Error> {
168        match self {
169            Response::AddDeviceNotification(r) => Ok(r),
170            _ => Err(TryIntoError::TryIntoResponseFailed),
171        }
172    }
173}
174
175impl From<DeleteDeviceNotificationResponse> for Response {
176    fn from(response: DeleteDeviceNotificationResponse) -> Self {
177        Response::DeleteDeviceNotification(response)
178    }
179}
180
181impl TryInto<DeleteDeviceNotificationResponse> for Response {
182    type Error = TryIntoError;
183
184    fn try_into(self) -> Result<DeleteDeviceNotificationResponse, Self::Error> {
185        match self {
186            Response::DeleteDeviceNotification(r) => Ok(r),
187            _ => Err(TryIntoError::TryIntoResponseFailed),
188        }
189    }
190}
191
192impl From<AdsNotificationStream> for Response {
193    fn from(response: AdsNotificationStream) -> Self {
194        Response::DeviceNotification(response)
195    }
196}
197
198impl TryInto<AdsNotificationStream> for Response {
199    type Error = TryIntoError;
200
201    fn try_into(self) -> Result<AdsNotificationStream, Self::Error> {
202        match self {
203            Response::DeviceNotification(r) => Ok(r),
204            _ => Err(TryIntoError::TryIntoResponseFailed),
205        }
206    }
207}
208
209impl From<ReadResponse> for Response {
210    fn from(response: ReadResponse) -> Self {
211        Response::Read(response)
212    }
213}
214
215impl TryInto<ReadResponse> for Response {
216    type Error = TryIntoError;
217
218    fn try_into(self) -> Result<ReadResponse, Self::Error> {
219        match self {
220            Response::Read(r) => Ok(r),
221            _ => Err(TryIntoError::TryIntoResponseFailed),
222        }
223    }
224}
225
226impl From<ReadWriteResponse> for Response {
227    fn from(response: ReadWriteResponse) -> Self {
228        Response::ReadWrite(response)
229    }
230}
231
232impl TryInto<ReadWriteResponse> for Response {
233    type Error = TryIntoError;
234
235    fn try_into(self) -> Result<ReadWriteResponse, Self::Error> {
236        match self {
237            Response::ReadWrite(r) => Ok(r),
238            _ => Err(TryIntoError::TryIntoResponseFailed),
239        }
240    }
241}
242
243/// ADS Invalid response
244#[derive(Debug, Clone, PartialEq, Eq)]
245pub struct InvalidResponse {
246    command_id: CommandID,
247}
248
249impl InvalidResponse {
250    pub fn new() -> Self {
251        InvalidResponse {
252            command_id: CommandID::Invalid,
253        }
254    }
255}
256
257impl Default for InvalidResponse {
258    fn default() -> Self {
259        Self::new()
260    }
261}
262
263/// ADS Read Device Info
264#[derive(Debug, PartialEq, Clone, Eq)]
265pub struct ReadDeviceInfoResponse {
266    pub result: AdsError,
267    pub major_version: u8,
268    pub minor_version: u8,
269    pub version_build: u16,
270    pub device_name: [u8; 16],
271    pub command_id: CommandID,
272}
273
274impl ReadFrom for ReadDeviceInfoResponse {
275    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
276        let result = AdsError::from(read.read_u32::<LittleEndian>()?);
277        let major_version = read.read_u8()?;
278        let minor_version = read.read_u8()?;
279        let version_build = read.read_u16::<LittleEndian>()?;
280        let mut device_name = [0; 16];
281        read.read_exact(&mut device_name)?;
282        Ok(Self {
283            result,
284            major_version,
285            minor_version,
286            version_build,
287            device_name,
288            command_id: CommandID::ReadDeviceInfo,
289        })
290    }
291}
292
293impl WriteTo for ReadDeviceInfoResponse {
294    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
295        wtr.write_u32::<LittleEndian>(self.result.as_u32())?;
296        wtr.write_u8(self.major_version)?;
297        wtr.write_u8(self.minor_version)?;
298        wtr.write_u16::<LittleEndian>(self.version_build)?;
299        wtr.write_all(&self.device_name)?;
300        Ok(())
301    }
302}
303
304impl ReadDeviceInfoResponse {
305    pub fn new(
306        result: AdsError,
307        major_version: u8,
308        minor_version: u8,
309        version_build: u16,
310        device_name: [u8; 16],
311    ) -> Self {
312        ReadDeviceInfoResponse {
313            result,
314            major_version,
315            minor_version,
316            version_build,
317            device_name,
318            command_id: CommandID::ReadDeviceInfo,
319        }
320    }
321
322    pub fn get_device_name(&self) -> Result<String, FromUtf8Error> {
323        let name_bytes = self
324            .device_name
325            .to_vec()
326            .iter()
327            .filter(|value| **value > 0)
328            .copied()
329            .collect();
330
331        String::from_utf8(name_bytes)
332    }
333
334    pub fn create_device_name_buf(device_name: &str) -> [u8; 16] {
335        let mut device_name_buffer: [u8; 16] = [0; 16];
336        for (n, b) in device_name.as_bytes().iter().enumerate() {
337            if n == device_name_buffer.len() {
338                break;
339            }
340            device_name_buffer[n] = *b;
341        }
342        device_name_buffer
343    }
344}
345
346///Ads Write
347#[derive(Debug, PartialEq, Clone, Eq)]
348pub struct WriteResponse {
349    pub result: AdsError,
350    pub command_id: CommandID,
351}
352
353impl ReadFrom for WriteResponse {
354    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
355        let result = AdsError::from(read.read_u32::<LittleEndian>()?);
356        Ok(Self {
357            result,
358            command_id: CommandID::Write,
359        })
360    }
361}
362
363impl WriteTo for WriteResponse {
364    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
365        wtr.write_u32::<LittleEndian>(self.result.as_u32())?;
366        Ok(())
367    }
368}
369
370impl WriteResponse {
371    pub fn new(result: AdsError) -> Self {
372        WriteResponse {
373            result,
374            command_id: CommandID::Write,
375        }
376    }
377}
378
379/// ADS Read State
380#[derive(Debug, PartialEq, Clone, Eq)]
381pub struct ReadStateResponse {
382    pub result: AdsError,
383    pub ads_state: AdsState,
384    pub device_state: u16,
385    pub command_id: CommandID,
386}
387
388impl ReadFrom for ReadStateResponse {
389    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
390        Ok(Self {
391            result: AdsError::from(read.read_u32::<LittleEndian>()?),
392            ads_state: AdsState::read_from(read)?,
393            device_state: read.read_u16::<LittleEndian>()?,
394            command_id: CommandID::ReadState,
395        })
396    }
397}
398
399impl WriteTo for ReadStateResponse {
400    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
401        wtr.write_u32::<LittleEndian>(self.result.as_u32())?;
402        self.ads_state.write_to(&mut wtr)?;
403        wtr.write_u16::<LittleEndian>(self.device_state)?;
404        Ok(())
405    }
406}
407
408impl ReadStateResponse {
409    pub fn new(result: AdsError, ads_state: AdsState, device_state: u16) -> Self {
410        ReadStateResponse {
411            result,
412            ads_state,
413            device_state,
414            command_id: CommandID::ReadState,
415        }
416    }
417}
418
419///Write control
420#[derive(Debug, PartialEq, Clone, Eq)]
421pub struct WriteControlResponse {
422    pub result: AdsError,
423    pub command_id: CommandID,
424}
425
426impl ReadFrom for WriteControlResponse {
427    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
428        Ok(Self {
429            result: AdsError::from(read.read_u32::<LittleEndian>()?),
430            command_id: CommandID::WriteControl,
431        })
432    }
433}
434
435impl WriteTo for WriteControlResponse {
436    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
437        wtr.write_u32::<LittleEndian>(self.result.as_u32())?;
438        Ok(())
439    }
440}
441
442impl WriteControlResponse {
443    pub fn new(result: AdsError) -> Self {
444        WriteControlResponse {
445            result,
446            command_id: CommandID::WriteControl,
447        }
448    }
449}
450
451/// ADS Add Device Notification
452#[derive(Debug, PartialEq, Clone, Eq)]
453pub struct AddDeviceNotificationResponse {
454    pub result: AdsError,
455    pub notification_handle: u32,
456    pub command_id: CommandID,
457}
458
459impl ReadFrom for AddDeviceNotificationResponse {
460    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
461        Ok(Self {
462            result: AdsError::from(read.read_u32::<LittleEndian>()?),
463            notification_handle: read.read_u32::<LittleEndian>()?,
464            command_id: CommandID::AddDeviceNotification,
465        })
466    }
467}
468
469impl WriteTo for AddDeviceNotificationResponse {
470    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
471        wtr.write_u32::<LittleEndian>(self.result.as_u32())?;
472        wtr.write_u32::<LittleEndian>(self.notification_handle)?;
473        Ok(())
474    }
475}
476
477impl AddDeviceNotificationResponse {
478    pub fn new(result: AdsError, notification_handle: u32) -> Self {
479        AddDeviceNotificationResponse {
480            result,
481            notification_handle,
482            command_id: CommandID::AddDeviceNotification,
483        }
484    }
485}
486
487/// ADS Delete Device Notification
488#[derive(Debug, PartialEq, Clone, Eq)]
489pub struct DeleteDeviceNotificationResponse {
490    pub result: AdsError,
491    pub command_id: CommandID,
492}
493
494impl ReadFrom for DeleteDeviceNotificationResponse {
495    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
496        Ok(Self {
497            result: AdsError::from(read.read_u32::<LittleEndian>()?),
498            command_id: CommandID::DeleteDeviceNotification,
499        })
500    }
501}
502
503impl WriteTo for DeleteDeviceNotificationResponse {
504    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
505        wtr.write_u32::<LittleEndian>(self.result.as_u32())?;
506        Ok(())
507    }
508}
509
510impl DeleteDeviceNotificationResponse {
511    pub fn new(result: AdsError) -> Self {
512        DeleteDeviceNotificationResponse {
513            result,
514            command_id: CommandID::DeleteDeviceNotification,
515        }
516    }
517}
518
519//ADS Device Notification Response
520#[derive(Debug, PartialEq, Clone, Eq)]
521pub struct AdsNotificationSample {
522    pub notification_handle: u32,
523    pub sample_size: u32,
524    pub data: Vec<u8>,
525}
526
527impl AdsNotificationSample {
528    pub fn new(notification_handle: u32, data: Vec<u8>) -> Self {
529        AdsNotificationSample {
530            notification_handle,
531            sample_size: data.len() as u32,
532            data,
533        }
534    }
535    pub fn sample_len(&self) -> usize {
536        //plus fixed byte length (notification_handle, sample_size)
537        self.data.len() + 8
538    }
539}
540
541#[derive(Debug, PartialEq, Clone, Eq)]
542pub struct AdsStampHeader {
543    pub time_stamp: u64,
544    pub samples: u32,
545    pub notification_samples: Vec<AdsNotificationSample>,
546}
547
548impl ReadFrom for AdsStampHeader {
549    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
550        let time_stamp = read.read_u64::<LittleEndian>()?;
551        let samples = read.read_u32::<LittleEndian>()?;
552        let mut notification_samples: Vec<AdsNotificationSample> =
553            Vec::with_capacity(samples as usize);
554
555        for _ in 0..samples {
556            let notification_handle = read.read_u32::<LittleEndian>()?;
557            let sample_size = read.read_u32::<LittleEndian>()?;
558            let mut data = vec![0; sample_size as usize];
559            read.read_exact(&mut data)?;
560            notification_samples.push(AdsNotificationSample {
561                notification_handle,
562                sample_size,
563                data,
564            });
565        }
566
567        Ok(Self {
568            time_stamp,
569            samples,
570            notification_samples,
571        })
572    }
573}
574
575impl WriteTo for AdsStampHeader {
576    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
577        wtr.write_u64::<LittleEndian>(self.time_stamp)?;
578        wtr.write_u32::<LittleEndian>(self.samples)?;
579
580        for sample in &self.notification_samples {
581            wtr.write_u32::<LittleEndian>(sample.notification_handle)?;
582            wtr.write_u32::<LittleEndian>(sample.sample_size)?;
583            wtr.write_all(sample.data.as_slice())?;
584        }
585        Ok(())
586    }
587}
588
589impl AdsStampHeader {
590    pub fn new(
591        time_stamp: u64,
592        samples: u32,
593        notification_samples: Vec<AdsNotificationSample>,
594    ) -> Self {
595        AdsStampHeader {
596            time_stamp,
597            samples,
598            notification_samples,
599        }
600    }
601
602    pub fn stamp_len(&self) -> usize {
603        let mut len: usize = 0;
604        for sample in &self.notification_samples {
605            len += sample.sample_len();
606        }
607        //plus fixed byte size (time_stamp, samples)
608        len + 12
609    }
610}
611
612#[derive(Debug, PartialEq, Clone, Eq)]
613pub struct AdsNotificationStream {
614    pub length: u32,
615    pub stamps: u32,
616    pub ads_stamp_headers: Vec<AdsStampHeader>,
617    pub command_id: CommandID,
618}
619
620impl ReadFrom for AdsNotificationStream {
621    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
622        let length = read.read_u32::<LittleEndian>()?;
623        let stamps = read.read_u32::<LittleEndian>()?;
624        let stamp_data_size = ((length - 4) / stamps) as u32; //-4 -> stamps is in length incl. but already read in previous line!
625        let mut ads_stamp_headers: Vec<AdsStampHeader> = Vec::with_capacity(stamps as usize);
626        let mut buffer: Vec<u8> = vec![0; (stamp_data_size) as usize];
627        for _ in 0..stamps {
628            read.read_exact(&mut buffer)?;
629            let stamp = AdsStampHeader::read_from(&mut buffer.as_slice())?;
630            ads_stamp_headers.push(stamp);
631        }
632
633        Ok(Self {
634            length,
635            stamps,
636            ads_stamp_headers,
637            command_id: CommandID::DeviceNotification,
638        })
639    }
640}
641
642impl WriteTo for AdsNotificationStream {
643    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
644        wtr.write_u32::<LittleEndian>(self.length)?;
645        wtr.write_u32::<LittleEndian>(self.stamps)?;
646
647        for stamp_header in &self.ads_stamp_headers {
648            stamp_header.write_to(&mut wtr)?;
649        }
650        Ok(())
651    }
652}
653
654impl AdsNotificationStream {
655    pub fn new(length: u32, stamps: u32, ads_stamp_headers: Vec<AdsStampHeader>) -> Self {
656        AdsNotificationStream {
657            length,
658            stamps,
659            ads_stamp_headers,
660            command_id: CommandID::DeviceNotification,
661        }
662    }
663
664    pub fn stream_len(&self) -> usize {
665        let mut len: usize = 0;
666        for stamp in &self.ads_stamp_headers {
667            len += stamp.stamp_len();
668        }
669        //plus fixed byte size (length, stamps)
670        len + 8
671    }
672}
673
674//Ads Read response
675#[derive(Debug, Clone, PartialEq, Eq)]
676pub struct ReadResponse {
677    pub result: AdsError,
678    pub length: u32,
679    pub data: Vec<u8>,
680    pub command_id: CommandID,
681}
682
683impl ReadFrom for ReadResponse {
684    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
685        let result = AdsError::from(read.read_u32::<LittleEndian>()?);
686        let length = read.read_u32::<LittleEndian>()?;
687        let mut data = Vec::with_capacity(length as usize);
688        read.read_to_end(&mut data)?;
689        Ok(Self {
690            result,
691            length,
692            data,
693            command_id: CommandID::Read,
694        })
695    }
696}
697
698impl WriteTo for ReadResponse {
699    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
700        wtr.write_u32::<LittleEndian>(self.result.as_u32())?;
701        wtr.write_u32::<LittleEndian>(self.length)?;
702        wtr.write_all(self.data.as_slice())?;
703        Ok(())
704    }
705}
706
707impl ReadResponse {
708    pub fn new(result: AdsError, data: Vec<u8>) -> Self {
709        ReadResponse {
710            result,
711            length: data.len() as u32,
712            data,
713            command_id: CommandID::Read,
714        }
715    }
716}
717
718//Ads ReadWrite response
719#[derive(Debug, Clone, PartialEq, Eq)]
720pub struct ReadWriteResponse {
721    pub result: AdsError,
722    pub length: u32,
723    pub data: Vec<u8>,
724    pub command_id: CommandID,
725}
726
727impl ReadFrom for ReadWriteResponse {
728    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
729        let result = AdsError::from(read.read_u32::<LittleEndian>()?);
730        let length = read.read_u32::<LittleEndian>()?;
731        let mut data = Vec::with_capacity(length as usize);
732        read.read_to_end(&mut data)?;
733        Ok(Self {
734            result,
735            length,
736            data,
737            command_id: CommandID::ReadWrite,
738        })
739    }
740}
741
742impl WriteTo for ReadWriteResponse {
743    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
744        wtr.write_u32::<LittleEndian>(self.result.as_u32())?;
745        wtr.write_u32::<LittleEndian>(self.length)?;
746        wtr.write_all(self.data.as_slice())?;
747        Ok(())
748    }
749}
750
751impl ReadWriteResponse {
752    pub fn new(result: AdsError, data: Vec<u8>) -> Self {
753        ReadWriteResponse {
754            result,
755            length: data.len() as u32,
756            data,
757            command_id: CommandID::ReadWrite,
758        }
759    }
760}
761
762#[cfg(test)]
763mod tests {
764    use super::*;
765
766    #[test]
767    fn response_from_read_device_info() {
768        let read_device_info_response =
769            ReadDeviceInfoResponse::new(AdsError::ErrNoError, 1, 2, 33, [1; 16]);
770
771        assert_eq!(
772            Response::ReadDeviceInfo(read_device_info_response.clone()),
773            Response::from(read_device_info_response)
774        );
775    }
776
777    #[test]
778    fn response_try_into_read_device_info() {
779        let read_device_info_response =
780            ReadDeviceInfoResponse::new(AdsError::ErrNoError, 1, 2, 33, [1; 16]);
781
782        let response = Response::ReadDeviceInfo(read_device_info_response.clone());
783        assert_eq!(CommandID::ReadDeviceInfo, response.command_id());
784
785        let test = response.try_into().unwrap();
786        assert_eq!(read_device_info_response, test);
787    }
788
789    #[test]
790    fn response_from_read() {
791        let read_response = ReadResponse::new(AdsError::ErrNoError, vec![66]);
792
793        assert_eq!(
794            Response::Read(read_response.clone()),
795            Response::from(read_response)
796        );
797    }
798
799    #[test]
800    fn response_try_into_read() {
801        let read_response = ReadResponse::new(AdsError::ErrNoError, vec![66]);
802
803        let response = Response::Read(read_response.clone());
804        assert_eq!(CommandID::Read, response.command_id());
805
806        let test = response.try_into().unwrap();
807        assert_eq!(read_response, test);
808    }
809
810    #[test]
811    fn response_from_write() {
812        let write_response = WriteResponse::new(AdsError::ErrNoError);
813
814        assert_eq!(
815            Response::Write(write_response.clone()),
816            Response::from(write_response)
817        );
818    }
819
820    #[test]
821    fn response_try_into_write() {
822        let write_response = WriteResponse::new(AdsError::ErrNoError);
823
824        let response = Response::Write(write_response.clone());
825        assert_eq!(CommandID::Write, response.command_id());
826
827        let test = response.try_into().unwrap();
828        assert_eq!(write_response, test);
829    }
830
831    #[test]
832    fn response_from_read_state() {
833        let read_state_response =
834            ReadStateResponse::new(AdsError::ErrNoError, AdsState::AdsStateConfig, 123);
835
836        assert_eq!(
837            Response::ReadState(read_state_response.clone()),
838            Response::from(read_state_response)
839        );
840    }
841
842    #[test]
843    fn response_try_into_read_state() {
844        let read_state_response =
845            ReadStateResponse::new(AdsError::ErrNoError, AdsState::AdsStateConfig, 123);
846
847        let response = Response::ReadState(read_state_response.clone());
848        assert_eq!(CommandID::ReadState, response.command_id());
849
850        let test = response.try_into().unwrap();
851        assert_eq!(read_state_response, test);
852    }
853
854    #[test]
855    fn response_from_write_control() {
856        let write_control_response = WriteControlResponse::new(AdsError::ErrNoError);
857
858        assert_eq!(
859            Response::WriteControl(write_control_response.clone()),
860            Response::from(write_control_response)
861        );
862    }
863
864    #[test]
865    fn response_try_into_write_control() {
866        let write_control_response = WriteControlResponse::new(AdsError::ErrNoError);
867
868        let response = Response::WriteControl(write_control_response.clone());
869        assert_eq!(CommandID::WriteControl, response.command_id());
870
871        let test = response.try_into().unwrap();
872        assert_eq!(write_control_response, test);
873    }
874
875    #[test]
876    fn response_from_add_device_notification() {
877        let add_device_notification_response =
878            AddDeviceNotificationResponse::new(AdsError::ErrNoError, 1);
879
880        assert_eq!(
881            CommandID::AddDeviceNotification,
882            Response::AddDeviceNotification(add_device_notification_response.clone()).command_id()
883        );
884
885        assert_eq!(
886            Response::AddDeviceNotification(add_device_notification_response.clone()),
887            Response::from(add_device_notification_response)
888        );
889    }
890
891    #[test]
892    fn response_try_into_add_device_notification() {
893        let add_device_notification_response =
894            AddDeviceNotificationResponse::new(AdsError::ErrNoError, 1);
895
896        let response = Response::AddDeviceNotification(add_device_notification_response.clone());
897        assert_eq!(CommandID::AddDeviceNotification, response.command_id());
898
899        let test = response.try_into().unwrap();
900        assert_eq!(add_device_notification_response, test);
901    }
902
903    #[test]
904    fn response_from_delete_device_notification() {
905        let delete_device_notification_response =
906            DeleteDeviceNotificationResponse::new(AdsError::ErrNoError);
907
908        assert_eq!(
909            Response::DeleteDeviceNotification(delete_device_notification_response.clone()),
910            Response::from(delete_device_notification_response)
911        );
912    }
913
914    #[test]
915    fn response_try_into_delete_device_notification() {
916        let delete_device_notification_response =
917            DeleteDeviceNotificationResponse::new(AdsError::ErrNoError);
918
919        let response =
920            Response::DeleteDeviceNotification(delete_device_notification_response.clone());
921        assert_eq!(CommandID::DeleteDeviceNotification, response.command_id());
922
923        let test = response.try_into().unwrap();
924        assert_eq!(delete_device_notification_response, test);
925    }
926
927    #[test]
928    fn response_from_device_notification() {
929        let notification_sample1: Vec<u8> = vec![4, 0, 0, 0, 2, 0, 0, 0, 6, 0];
930        let notification_sample2: Vec<u8> = vec![4, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0];
931
932        let mut stamp_header: Vec<u8> = vec![255, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0];
933        stamp_header.extend(notification_sample1);
934        stamp_header.extend(notification_sample2);
935
936        let mut notification_stream: Vec<u8> = vec![72, 0, 0, 0, 2, 0, 0, 0];
937        notification_stream.extend(stamp_header.clone());
938        notification_stream.extend(stamp_header);
939
940        let device_notification_response =
941            AdsNotificationStream::read_from(&mut notification_stream.as_slice()).unwrap();
942
943        assert_eq!(
944            Response::DeviceNotification(device_notification_response.clone()),
945            Response::from(device_notification_response)
946        );
947    }
948
949    #[test]
950    fn response_try_into_device_notification() {
951        let notification_sample1: Vec<u8> = vec![4, 0, 0, 0, 2, 0, 0, 0, 6, 0];
952        let notification_sample2: Vec<u8> = vec![4, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0];
953
954        let mut stamp_header: Vec<u8> = vec![255, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0];
955        stamp_header.extend(notification_sample1);
956        stamp_header.extend(notification_sample2);
957
958        let mut notification_stream: Vec<u8> = vec![72, 0, 0, 0, 2, 0, 0, 0];
959        notification_stream.extend(stamp_header.clone());
960        notification_stream.extend(stamp_header);
961
962        let device_notification_response =
963            AdsNotificationStream::read_from(&mut notification_stream.as_slice()).unwrap();
964
965        let response = Response::DeviceNotification(device_notification_response.clone());
966        assert_eq!(CommandID::DeviceNotification, response.command_id());
967
968        let test = response.try_into().unwrap();
969        assert_eq!(device_notification_response, test);
970    }
971
972    #[test]
973    fn response_from_read_write() {
974        let read_write_response = ReadWriteResponse::new(AdsError::ErrNoError, vec![66]);
975
976        assert_eq!(
977            CommandID::ReadWrite,
978            Response::ReadWrite(read_write_response.clone()).command_id()
979        );
980
981        assert_eq!(
982            Response::ReadWrite(read_write_response.clone()),
983            Response::from(read_write_response)
984        );
985    }
986
987    #[test]
988    fn response_try_into_read_write() {
989        let read_write_response = ReadWriteResponse::new(AdsError::ErrNoError, vec![66]);
990
991        let response = Response::ReadWrite(read_write_response.clone());
992        assert_eq!(CommandID::ReadWrite, response.command_id());
993
994        let test = response.try_into().unwrap();
995        assert_eq!(read_write_response, test);
996    }
997
998    #[test]
999    fn read_device_info_response_write_to_test() {
1000        let mut buffer: Vec<u8> = Vec::new();
1001        let mut device_name: [u8; 16] = [0; 16];
1002
1003        for (n, b) in "Device".as_bytes().iter().enumerate() {
1004            device_name[n] = *b;
1005        }
1006
1007        let device_info_response =
1008            ReadDeviceInfoResponse::new(AdsError::ErrAccessDenied, 1, 2, 10, device_name);
1009
1010        let response_data: Vec<u8> = vec![
1011            30, 0, 0, 0, 1, 2, 10, 0, 68, 101, 118, 105, 99, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1012        ];
1013
1014        device_info_response.write_to(&mut buffer).unwrap();
1015
1016        assert_eq!(buffer, response_data);
1017    }
1018
1019    #[test]
1020    fn read_device_info_response_test() {
1021        let response_data: Vec<u8> = vec![
1022            30, 0, 0, 0, 2, 14, 1, 1, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 0, 0,
1023            0, 0,
1024        ];
1025
1026        let read_device_info_response =
1027            ReadDeviceInfoResponse::read_from(&mut response_data.as_slice()).unwrap();
1028
1029        assert_eq!(read_device_info_response.result, AdsError::ErrAccessDenied);
1030        assert_eq!(read_device_info_response.major_version, 2);
1031        assert_eq!(read_device_info_response.minor_version, 14);
1032        assert_eq!(read_device_info_response.version_build, 257);
1033
1034        let expected_device_name: [u8; 16] = [
1035            72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 0, 0, 0, 0,
1036        ]; //Hello World
1037        assert_eq!(read_device_info_response.device_name, expected_device_name);
1038        let expected_device_name = "Hello World".to_string();
1039        assert_eq!(
1040            read_device_info_response.get_device_name().unwrap(),
1041            expected_device_name,
1042            "Parsing device name failed"
1043        );
1044    }
1045
1046    #[test]
1047    fn read_device_info_device_name_buf_test() {
1048        let device_name: [u8; 16] = ReadDeviceInfoResponse::create_device_name_buf("Device");
1049
1050        let device_info_response =
1051            ReadDeviceInfoResponse::new(AdsError::ErrAccessDenied, 1, 2, 10, device_name);
1052
1053        assert_eq!(device_info_response.get_device_name().unwrap(), "Device");
1054    }
1055
1056    #[test]
1057    fn read_device_info_device_name_buf_test2() {
1058        let device_name: [u8; 16] =
1059            ReadDeviceInfoResponse::create_device_name_buf("OverflowtestOverflowtest");
1060
1061        let device_info_response =
1062            ReadDeviceInfoResponse::new(AdsError::ErrAccessDenied, 1, 2, 10, device_name);
1063
1064        assert_eq!(
1065            device_info_response.get_device_name().unwrap(),
1066            "OverflowtestOver"
1067        );
1068    }
1069
1070    #[test]
1071    fn read_response_test() {
1072        let response_data: Vec<u8> = vec![4, 0, 0, 0, 2, 0, 0, 0, 255, 2];
1073
1074        let read_response = ReadResponse::read_from(&mut response_data.as_slice()).unwrap();
1075
1076        assert_eq!(read_response.result, AdsError::ErrInsertMailBox);
1077        assert_eq!(read_response.length, 2);
1078        assert_eq!(read_response.data, vec![255, 2]);
1079    }
1080
1081    #[test]
1082    fn read_response_write_to_test() {
1083        let mut buffer: Vec<u8> = Vec::new();
1084        let data: u32 = 90000;
1085        let read_response =
1086            ReadResponse::new(AdsError::ErrAccessDenied, data.to_le_bytes().to_vec());
1087        read_response.write_to(&mut buffer).unwrap();
1088        assert_eq!(buffer, [30, 0, 0, 0, 4, 0, 0, 0, 144, 95, 1, 0]);
1089    }
1090
1091    #[test]
1092    fn write_response_test() {
1093        let response_data: Vec<u8> = vec![4, 0, 0, 0];
1094
1095        let write_response = WriteResponse::read_from(&mut response_data.as_slice()).unwrap();
1096
1097        assert_eq!(write_response.result, AdsError::from(4));
1098    }
1099
1100    #[test]
1101    fn write_response_write_to_test() {
1102        let mut buffer: Vec<u8> = Vec::new();
1103        let write_response = WriteResponse::new(AdsError::ErrAccessDenied);
1104        write_response.write_to(&mut buffer).unwrap();
1105        assert_eq!(buffer, [30, 0, 0, 0]);
1106    }
1107
1108    #[test]
1109    fn read_state_response_test() {
1110        let response_data: Vec<u8> = vec![4, 0, 0, 0, 9, 0, 1, 1];
1111
1112        let read_state_response =
1113            ReadStateResponse::read_from(&mut response_data.as_slice()).unwrap();
1114
1115        assert_eq!(read_state_response.result, AdsError::ErrInsertMailBox);
1116        assert_eq!(
1117            read_state_response.ads_state,
1118            AdsState::AdsStatePowerFailure
1119        );
1120        assert_eq!(read_state_response.device_state, 257);
1121    }
1122
1123    #[test]
1124    fn read_state_response_write_to_test() {
1125        let mut buffer: Vec<u8> = Vec::new();
1126        let read_state_response =
1127            ReadStateResponse::new(AdsError::ErrAccessDenied, AdsState::AdsStateConfig, 4);
1128        read_state_response.write_to(&mut buffer).unwrap();
1129        assert_eq!(buffer, [30, 0, 0, 0, 15, 0, 4, 0]);
1130    }
1131
1132    #[test]
1133    fn write_control_response_test() {
1134        let response_data: Vec<u8> = vec![30, 0, 0, 0];
1135
1136        let write_control_response =
1137            WriteControlResponse::read_from(&mut response_data.as_slice()).unwrap();
1138
1139        assert_eq!(write_control_response.result, AdsError::ErrAccessDenied);
1140    }
1141
1142    #[test]
1143    fn write_control_response_write_to_test() {
1144        let mut buffer: Vec<u8> = Vec::new();
1145        let write_control_response = WriteControlResponse::new(AdsError::ErrAccessDenied);
1146        write_control_response.write_to(&mut buffer).unwrap();
1147        assert_eq!(buffer, [30, 0, 0, 0]);
1148    }
1149
1150    #[test]
1151    fn add_device_notification_response_test() {
1152        let response_data: Vec<u8> = vec![4, 0, 0, 0, 10, 0, 0, 0];
1153
1154        let add_device_notification_response =
1155            AddDeviceNotificationResponse::read_from(&mut response_data.as_slice()).unwrap();
1156
1157        assert_eq!(
1158            add_device_notification_response.result,
1159            AdsError::ErrInsertMailBox
1160        );
1161        assert_eq!(add_device_notification_response.notification_handle, 10);
1162    }
1163
1164    #[test]
1165    fn add_device_notification_response_write_to_test() {
1166        let mut buffer: Vec<u8> = Vec::new();
1167        let add_device_notification_response =
1168            AddDeviceNotificationResponse::new(AdsError::ErrInsertMailBox, 10);
1169        add_device_notification_response
1170            .write_to(&mut buffer)
1171            .unwrap();
1172        assert_eq!(buffer, [4, 0, 0, 0, 10, 0, 0, 0]);
1173    }
1174
1175    #[test]
1176    fn delete_device_notification_response_test() {
1177        let response_data: Vec<u8> = vec![4, 0, 0, 0];
1178
1179        let delete_device_notification_response =
1180            DeleteDeviceNotificationResponse::read_from(&mut response_data.as_slice()).unwrap();
1181
1182        assert_eq!(
1183            delete_device_notification_response.result,
1184            AdsError::ErrInsertMailBox
1185        );
1186    }
1187
1188    #[test]
1189    fn delete_device_notification_response_write_to_test() {
1190        let mut buffer: Vec<u8> = Vec::new();
1191        let delete_device_notification_response =
1192            DeleteDeviceNotificationResponse::new(AdsError::ErrAccessDenied);
1193        delete_device_notification_response
1194            .write_to(&mut buffer)
1195            .unwrap();
1196        assert_eq!(buffer, [30, 0, 0, 0]);
1197    }
1198
1199    #[test]
1200    fn ads_notification_stream_test() {
1201        let notification_sample1: Vec<u8> = vec![4, 0, 0, 0, 2, 0, 0, 0, 6, 0];
1202        let notification_sample2: Vec<u8> = vec![4, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0];
1203
1204        let mut stamp_header: Vec<u8> = vec![255, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0];
1205        stamp_header.extend(notification_sample1);
1206        stamp_header.extend(notification_sample2);
1207
1208        let mut notification_stream: Vec<u8> = vec![72, 0, 0, 0, 2, 0, 0, 0];
1209        notification_stream.extend(stamp_header.clone());
1210        notification_stream.extend(stamp_header);
1211
1212        let notification_data =
1213            AdsNotificationStream::read_from(&mut notification_stream.as_slice()).unwrap();
1214
1215        assert_eq!(notification_data.length, 72, "Wrong data stream length");
1216        assert_eq!(notification_data.stamps, 2, "Wrong data stream stamp count");
1217        assert_eq!(
1218            notification_data.ads_stamp_headers.len(),
1219            2,
1220            "Wrong stamp header vec length"
1221        );
1222        assert_eq!(
1223            notification_data.ads_stamp_headers[0]
1224                .notification_samples
1225                .len(),
1226            2,
1227            "Wrong notification sample vec len [0]"
1228        );
1229        assert_eq!(
1230            notification_data.ads_stamp_headers[0].samples, 2,
1231            "Wrong notification samples count [0]"
1232        );
1233        assert_eq!(
1234            notification_data.ads_stamp_headers[0].time_stamp, 255,
1235            "Wrong time stamp [0]"
1236        );
1237        assert_eq!(
1238            notification_data.ads_stamp_headers[0].notification_samples[0].notification_handle, 4,
1239            "Wrong notification handle [0][0]"
1240        );
1241        assert_eq!(
1242            notification_data.ads_stamp_headers[0].notification_samples[0].sample_size, 2,
1243            "Wrong sample size [0][0]"
1244        );
1245        assert_eq!(
1246            notification_data.ads_stamp_headers[0].notification_samples[0].data,
1247            vec![6, 0],
1248            "Wrong data [0][0]"
1249        );
1250        assert_eq!(
1251            notification_data.ads_stamp_headers[0].notification_samples[1].notification_handle, 4,
1252            "Wrong notification handle [0][1]"
1253        );
1254        assert_eq!(
1255            notification_data.ads_stamp_headers[0].notification_samples[1].sample_size, 4,
1256            "Wrong sample size [0][1]"
1257        );
1258        assert_eq!(
1259            notification_data.ads_stamp_headers[0].notification_samples[1].data,
1260            vec![9, 0, 0, 0],
1261            "Wrong data [0][1]"
1262        );
1263
1264        assert_eq!(
1265            notification_data.ads_stamp_headers[1]
1266                .notification_samples
1267                .len(),
1268            2,
1269            "Wrong notification sample vec len [1]"
1270        );
1271        assert_eq!(
1272            notification_data.ads_stamp_headers[1].samples, 2,
1273            "Wrong notification samples count [1]"
1274        );
1275        assert_eq!(
1276            notification_data.ads_stamp_headers[1].time_stamp, 255,
1277            "Wrong time stamp [1]"
1278        );
1279        assert_eq!(
1280            notification_data.ads_stamp_headers[1].notification_samples[0].notification_handle, 4,
1281            "Wrong notification handle [1][0]"
1282        );
1283        assert_eq!(
1284            notification_data.ads_stamp_headers[1].notification_samples[0].sample_size, 2,
1285            "Wrong sample size [1][0]"
1286        );
1287        assert_eq!(
1288            notification_data.ads_stamp_headers[1].notification_samples[0].data,
1289            vec![6, 0],
1290            "Wrong data [1][0]"
1291        );
1292        assert_eq!(
1293            notification_data.ads_stamp_headers[1].notification_samples[1].notification_handle, 4,
1294            "Wrong notification handle [1][1]"
1295        );
1296        assert_eq!(
1297            notification_data.ads_stamp_headers[1].notification_samples[1].sample_size, 4,
1298            "Wrong sample size [1][1]"
1299        );
1300        assert_eq!(
1301            notification_data.ads_stamp_headers[1].notification_samples[1].data,
1302            vec![9, 0, 0, 0],
1303            "Wrong data [1][1]"
1304        );
1305    }
1306
1307    #[test]
1308    fn ads_notification_stream_write_to_test() {
1309        //4+4+4=12byte
1310        let sample_data1: u32 = 1000;
1311        let notification_sample1 = AdsNotificationSample {
1312            notification_handle: 10,
1313            sample_size: 4,
1314            data: sample_data1.to_le_bytes().to_vec(),
1315        };
1316
1317        //4+4+2=10byte
1318        let sample_data2: u16 = 2000;
1319        let notification_sample2 = AdsNotificationSample {
1320            notification_handle: 20,
1321            sample_size: 2,
1322            data: sample_data2.to_le_bytes().to_vec(),
1323        };
1324
1325        //4+4+8=16byte
1326        let sample_data3: u64 = 3000;
1327        let notification_sample3 = AdsNotificationSample {
1328            notification_handle: 30,
1329            sample_size: 8,
1330            data: sample_data3.to_le_bytes().to_vec(),
1331        };
1332
1333        //8+4+12+10=34byte
1334        let mut notification_samples = Vec::new();
1335        notification_samples.push(notification_sample1);
1336        notification_samples.push(notification_sample2);
1337        let stamp_header1 = AdsStampHeader::new(1234567890, 2, notification_samples);
1338
1339        //8+4+16=28byte
1340        let mut notification_samples = Vec::new();
1341        notification_samples.push(notification_sample3);
1342        let stamp_header2 = AdsStampHeader::new(1234567890, 1, notification_samples);
1343
1344        let mut stamp_headers = Vec::new();
1345        stamp_headers.push(stamp_header1);
1346        stamp_headers.push(stamp_header2);
1347
1348        let mut len: usize = 0;
1349        for header in &stamp_headers {
1350            len += header.stamp_len();
1351        }
1352        len += 4; //4 byte for the u32 stamps var after length
1353
1354        let expected_len: usize = 66;
1355        assert_eq!(&len, &expected_len, "Wrong number of bytes");
1356
1357        //4+4+34+28=70byte
1358        let ads_notification_stream =
1359            AdsNotificationStream::new(len as u32, stamp_headers.len() as u32, stamp_headers);
1360
1361        let expected_len: usize = 70;
1362        assert_eq!(
1363            &ads_notification_stream.stream_len(),
1364            &expected_len,
1365            "Wrong number of bytes"
1366        );
1367
1368        let mut buffer: Vec<u8> = Vec::new();
1369
1370        ads_notification_stream.write_to(&mut buffer).unwrap();
1371
1372        #[rustfmt::skip]
1373        let expected_data = [
1374            //Notification stream Length
1375            66, 0, 0, 0,
1376            ////Notification stream number of stamps
1377            2, 0, 0, 0,
1378            //Stamp header1 time_stamp
1379            210, 2, 150, 73, 0, 0, 0, 0,
1380            //Stamp header1 number of samples
1381            2, 0, 0, 0,
1382            //Notification sample 1 notification handle
1383            10, 0, 0, 0,
1384            //Notification sample 1 sample size
1385            4, 0, 0, 0,
1386            //Notification sample 1 data
1387            232, 3, 0, 0,
1388            //Notification sample 2 notification handle
1389            20, 0, 0, 0,
1390            //Notification sample 2 sample size
1391            2, 0, 0, 0,
1392            //Notification sample 2 data
1393            208, 7,
1394            //Stamp header2 time_stamp
1395            210, 2, 150, 73, 0, 0, 0, 0,
1396            //Stamp header2 number of samples
1397            1, 0, 0, 0,
1398            //Notification sample 3 notification handle
1399            30, 0, 0, 0,
1400            //Notification sample 3 sample size
1401            8, 0, 0, 0,
1402            //Notification sample 3 data
1403            184, 11, 0, 0, 0, 0, 0, 0,
1404        ];
1405
1406        assert_eq!(buffer, expected_data, "Data in buffer is not as expected");
1407    }
1408}