1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use alloc::vec;
use core::convert::TryInto;

use crate::convert_packet::{ConvertPacket, ConvertPacketError};
use crate::event::event_code::*;
use crate::event::EventError;
use crate::packet::Packet;

#[derive(Debug, PartialEq)]
pub struct BootloaderHelloEvent {
    pub programmer_address: u16,
    pub bootloader_address: u16,
}

impl ConvertPacket<BootloaderHelloEvent> for BootloaderHelloEvent {
    fn try_from_packet(packet: &Packet) -> Result<Self, ConvertPacketError> {
        if packet.data.len() != 4 {
            return Err(ConvertPacketError::WrongSize);
        }

        if packet.is_error {
            return Err(ConvertPacketError::WrongType);
        }

        if u16::from_be_bytes(packet.data[0..=1].try_into().unwrap()) != BOOTLOADER_HELLO_EVENT_CODE
        {
            return Err(ConvertPacketError::Event(EventError::WrongEventType));
        }

        let programmer_address = packet.device_address;
        let bootloader_address = u16::from_be_bytes(packet.data[2..=3].try_into().unwrap());

        Ok(BootloaderHelloEvent {
            programmer_address,
            bootloader_address,
        })
    }

    fn to_packet(&self) -> Packet {
        let mut data = vec![];

        for byte in u16::to_be_bytes(BOOTLOADER_HELLO_EVENT_CODE).iter() {
            data.push(*byte);
        }

        for byte in u16::to_be_bytes(self.bootloader_address).iter() {
            data.push(*byte);
        }

        Packet {
            is_error: false,
            device_address: self.programmer_address,
            data,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    const EVENT_PACKET: Packet = Packet {
        is_error: false,
        device_address: 0xabab,
        data: vec![],
    };

    #[test]
    fn try_from_packet_test() {
        let mut packet = EVENT_PACKET;
        packet.data = vec![
            ((BOOTLOADER_HELLO_EVENT_CODE >> 8) & 0xff) as u8, // event code
            ((BOOTLOADER_HELLO_EVENT_CODE >> 0) & 0xff) as u8, // event code
            0x01,                                              // bootloader address
            0x23,                                              // bootloader address
        ];

        let event = BootloaderHelloEvent::try_from_packet(&packet).unwrap();

        assert_eq!(event.programmer_address, 0xabab);
        assert_eq!(event.bootloader_address, 0x0123);
    }

    #[test]
    #[should_panic]
    fn try_from_packet_wrong_size_test() {
        let mut packet = EVENT_PACKET;
        packet.data = vec![
            ((BOOTLOADER_HELLO_EVENT_CODE >> 8) & 0xff) as u8, // event code
            ((BOOTLOADER_HELLO_EVENT_CODE >> 0) & 0xff) as u8, // event code
            0x01,                                              // bootloader address
            0x23,                                              // bootloader address
            0x00,                                              // extra byte
        ];

        BootloaderHelloEvent::try_from_packet(&packet).unwrap();
    }

    #[test]
    #[should_panic]
    fn try_from_packet_wrong_type_test() {
        let mut packet = EVENT_PACKET;
        packet.data = vec![
            ((BOOTLOADER_HELLO_EVENT_CODE >> 8) & 0xff) as u8, // event code
            ((BOOTLOADER_HELLO_EVENT_CODE >> 0) & 0xff) as u8, // event code
            0x01,                                              // bootloader address
            0x23,                                              // bootloader address
        ];
        packet.is_error = true;

        BootloaderHelloEvent::try_from_packet(&packet).unwrap();
    }

    #[test]
    #[should_panic]
    fn try_from_packet_wrong_event_type_test() {
        let mut packet = EVENT_PACKET;
        packet.data = vec![
            ((PROGRAMMER_HELLO_EVENT_CODE >> 8) & 0xff) as u8, // event code
            ((PROGRAMMER_HELLO_EVENT_CODE >> 0) & 0xff) as u8, // event code
            0xab,                                              // programmer address
            0xab,                                              // programmer address
        ];

        BootloaderHelloEvent::try_from_packet(&packet).unwrap();
    }

    #[test]
    fn to_packet_test() {
        let event = BootloaderHelloEvent {
            programmer_address: 0xabab,
            bootloader_address: 0x0123,
        };

        let mut packet = EVENT_PACKET;
        packet.data = vec![
            ((BOOTLOADER_HELLO_EVENT_CODE >> 8) & 0xff) as u8, // event code
            ((BOOTLOADER_HELLO_EVENT_CODE >> 0) & 0xff) as u8, // event code
            0x01,                                              // bootloader address
            0x23,                                              // bootloader address
        ];

        assert_eq!(event.to_packet(), packet);
    }
}