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#[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#[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#[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#[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#[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#[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#[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#[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#[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 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 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; 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 len + 8
671 }
672}
673
674#[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#[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 ]; 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 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 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 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 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 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; let expected_len: usize = 66;
1355 assert_eq!(&len, &expected_len, "Wrong number of bytes");
1356
1357 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 66, 0, 0, 0,
1376 2, 0, 0, 0,
1378 210, 2, 150, 73, 0, 0, 0, 0,
1380 2, 0, 0, 0,
1382 10, 0, 0, 0,
1384 4, 0, 0, 0,
1386 232, 3, 0, 0,
1388 20, 0, 0, 0,
1390 2, 0, 0, 0,
1392 208, 7,
1394 210, 2, 150, 73, 0, 0, 0, 0,
1396 1, 0, 0, 0,
1398 30, 0, 0, 0,
1400 8, 0, 0, 0,
1402 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}