essp/
protocol.rs

1use rand::{Rng, OsRng};
2use byteorder::{LittleEndian, WriteBytesExt, ReadBytesExt};
3use std::io::Cursor;
4use std::iter;
5use std::convert;
6use std::string::FromUtf8Error;
7use std::fmt;
8use crypto::{aessafe, blockmodes};
9use crypto::symmetriccipher::{Encryptor, Decryptor, SymmetricCipherError};
10use crypto::buffer::{RefReadBuffer, RefWriteBuffer, BufferResult};
11
12const STX: u8 = 0x7Fu8;
13const STEX: u8 = 0x7Eu8;
14const MAX_SLAVE_ID: u8 = 0x7Du8;
15
16pub type SlaveID = u8;
17pub type Data = Vec<u8>;
18pub type DataSlice = [u8];
19pub type CRC = [u8; 2];
20pub type ECount = u32;
21pub type Generator = u64;
22pub type Modulus = u64;
23pub type InterKey = u64;
24pub type Key = [u8; 16];
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27#[allow(dead_code)]
28pub enum Command {
29    // Generic Commands
30    Reset,
31    HostProtocolVersion,
32    GetSerialNumber,
33    Sync,
34    Disable,
35    Enable,
36    GetFirmwareVersion,
37    GetDatasetVersion,
38    // Smart Hopper Commands
39    PayoutAmount,
40    GetDenominationLevel,
41    HaltPayout,
42    GetDenominationRoute,
43    GetMinimumPayout,
44    SetCoinMechInhibits,
45    PayoutByDenomination,
46    SetGenerator,
47    RequestKeyExchange,
48    GetBuildRevision,
49    GetHopperOptions,
50    CashboxPayoutOperationData,
51    EventAck,
52    SetFixedEncryptionKey,
53    SetupRequest,
54    Poll,
55    GetAllLevels,
56    SetDenominationLevel,
57    CommunicationPassThrough,
58    SetDenominatinoRoute,
59    FloatAmount,
60    EmptyAll,
61    FloatByDenomination,
62    SetCoinMechGlobalInhibit,
63    SetModulus,
64    SetBaudRate,
65    SetHopperOptions,
66    SmartEmpty,
67    PollWithAck,
68    CoinMechOptions,
69    ResetFixedEncryptionKey,
70    SetCashboxPayoutLimit,
71    // NV9 USB bill validator commands
72    SetInhibits,
73    DisplayOn,
74    DisplayOff,
75    Reject,
76    UintData,
77    ChannelValueData,
78    ChannelSecurityData,
79    LastRejectCode,
80    Hold,
81    GetCounters,
82    ResetCounters,
83    Unknown(u8),
84}
85
86impl Command {
87    #[allow(dead_code)]
88    pub fn from_u8(n: u8) -> Command {
89        match n {
90            0x01 => Command::Reset,
91            0x06 => Command::HostProtocolVersion,
92            0x0C => Command::GetSerialNumber,
93            0x11 => Command::Sync,
94            0x09 => Command::Disable,
95            0x0A => Command::Enable,
96            0x20 => Command::GetFirmwareVersion,
97            0x21 => Command::GetDatasetVersion,
98            0x33 => Command::PayoutAmount,
99            0x35 => Command::GetDenominationLevel,
100            0x38 => Command::HaltPayout,
101            0x3C => Command::GetDenominationRoute,
102            0x3E => Command::GetMinimumPayout,
103            0x40 => Command::SetCoinMechInhibits,
104            0x46 => Command::PayoutByDenomination,
105            0x4A => Command::SetGenerator,
106            0x4C => Command::RequestKeyExchange,
107            0x4F => Command::GetBuildRevision,
108            0x51 => Command::GetHopperOptions,
109            0x53 => Command::CashboxPayoutOperationData,
110            0x57 => Command::EventAck,
111            0x60 => Command::SetFixedEncryptionKey,
112            0x05 => Command::SetupRequest,
113            0x07 => Command::Poll,
114            0x22 => Command::GetAllLevels,
115            0x34 => Command::SetDenominationLevel,
116            0x37 => Command::CommunicationPassThrough,
117            0x3B => Command::SetDenominatinoRoute,
118            0x3D => Command::FloatAmount,
119            0x3F => Command::EmptyAll,
120            0x44 => Command::FloatByDenomination,
121            0x49 => Command::SetCoinMechGlobalInhibit,
122            0x4B => Command::SetModulus,
123            0x4D => Command::SetBaudRate,
124            0x50 => Command::SetHopperOptions,
125            0x52 => Command::SmartEmpty,
126            0x56 => Command::PollWithAck,
127            0x5A => Command::CoinMechOptions,
128            0x61 => Command::ResetFixedEncryptionKey,
129            0x4E => Command::SetCashboxPayoutLimit,
130            0x02 => Command::SetInhibits,
131            0x03 => Command::DisplayOn,
132            0x04 => Command::DisplayOff,
133            0x08 => Command::Reject,
134            0x0D => Command::UintData,
135            0x0E => Command::ChannelValueData,
136            0x0F => Command::ChannelSecurityData,
137            0x17 => Command::LastRejectCode,
138            0x18 => Command::Hold,
139            0x58 => Command::GetCounters,
140            0x59 => Command::ResetCounters,
141            _ => Command::Unknown(n),
142        }
143    }
144
145    #[allow(dead_code)]
146    pub fn to_u8(&self) -> u8 {
147        match *self {
148            Command::Reset => 0x01,
149            Command::HostProtocolVersion => 0x06,
150            Command::GetSerialNumber => 0x0C,
151            Command::Sync => 0x11,
152            Command::Disable => 0x09,
153            Command::Enable => 0x0A,
154            Command::GetFirmwareVersion => 0x20,
155            Command::GetDatasetVersion => 0x21,
156            Command::PayoutAmount => 0x33,
157            Command::GetDenominationLevel => 0x35,
158            Command::HaltPayout => 0x38,
159            Command::GetDenominationRoute => 0x3C,
160            Command::GetMinimumPayout => 0x3E,
161            Command::SetCoinMechInhibits => 0x40,
162            Command::PayoutByDenomination => 0x46,
163            Command::SetGenerator => 0x4A,
164            Command::RequestKeyExchange => 0x4C,
165            Command::GetBuildRevision => 0x4F,
166            Command::GetHopperOptions => 0x51,
167            Command::CashboxPayoutOperationData => 0x53,
168            Command::EventAck => 0x57,
169            Command::SetFixedEncryptionKey => 0x60,
170            Command::SetupRequest => 0x05,
171            Command::Poll => 0x07,
172            Command::GetAllLevels => 0x22,
173            Command::SetDenominationLevel => 0x34,
174            Command::CommunicationPassThrough => 0x37,
175            Command::SetDenominatinoRoute => 0x3B,
176            Command::FloatAmount => 0x3D,
177            Command::EmptyAll => 0x3F,
178            Command::FloatByDenomination => 0x44,
179            Command::SetCoinMechGlobalInhibit => 0x49,
180            Command::SetModulus => 0x4B,
181            Command::SetBaudRate => 0x4D,
182            Command::SetHopperOptions => 0x50,
183            Command::SmartEmpty => 0x52,
184            Command::PollWithAck => 0x56,
185            Command::CoinMechOptions => 0x5A,
186            Command::ResetFixedEncryptionKey => 0x61,
187            Command::SetCashboxPayoutLimit => 0x4E,
188            Command::SetInhibits => 0x02,
189            Command::DisplayOn => 0x03,
190            Command::DisplayOff => 0x04,
191            Command::Reject => 0x08,
192            Command::UintData => 0x0D,
193            Command::ChannelValueData => 0x0E,
194            Command::ChannelSecurityData => 0x0F,
195            Command::LastRejectCode => 0x17,
196            Command::Hold => 0x18,
197            Command::GetCounters => 0x58,
198            Command::ResetCounters => 0x59,
199            Command::Unknown(n) => n,
200        }
201    }
202}
203
204#[derive(Debug, Clone, Copy, PartialEq, Eq)]
205#[allow(dead_code)]
206pub enum Response {
207    Ok,
208    CommandNotKnown,
209    WrongNumberOfParameters,
210    ParameterOutOfRange,
211    CommandCannotBeProcessed,
212    SoftwareError,
213    Fail,
214    KeyNotSet,
215    Unknown(u8),
216}
217
218impl Response {
219    #[allow(dead_code)]
220    pub fn from_u8(n: u8) -> Response {
221        match n {
222            0xF0 => Response::Ok,
223            0xF2 => Response::CommandNotKnown,
224            0xF3 => Response::WrongNumberOfParameters,
225            0xF4 => Response::ParameterOutOfRange,
226            0xF5 => Response::CommandCannotBeProcessed,
227            0xF6 => Response::SoftwareError,
228            0xF8 => Response::Fail,
229            0xFA => Response::KeyNotSet,
230            _ => Response::Unknown(n),
231        }
232    }
233
234    #[allow(dead_code)]
235    pub fn to_u8(&self) -> u8 {
236        match *self {
237            Response::Ok => 0xF0,
238            Response::CommandNotKnown => 0xF2,
239            Response::WrongNumberOfParameters => 0xF3,
240            Response::ParameterOutOfRange => 0xF4,
241            Response::CommandCannotBeProcessed => 0xF5,
242            Response::SoftwareError => 0xF6,
243            Response::Fail => 0xF8,
244            Response::KeyNotSet => 0xFA,
245            Response::Unknown(n) => n,
246        }
247    }
248}
249
250
251#[derive(Debug, Clone)]
252#[allow(dead_code)]
253pub enum ErrorType {
254    NotAResponse,
255    PartialMessage,
256    CRCError,
257    EncryptedCRCError,
258    SlaveIdError,
259    NoResponse,
260    UnknownResponse,
261    KeyNotSet,
262    UTF8Error,
263    KeyExchangeError,
264    CryptoError(SymmetricCipherError),
265    EncryptionCounterError,
266    NotOkResponse(Payload),
267    ParseError,
268}
269
270impl convert::From<SymmetricCipherError> for ErrorType {
271    fn from(e: SymmetricCipherError) -> ErrorType {
272        ErrorType::CryptoError(e)
273    }
274}
275
276impl convert::From<FromUtf8Error> for ErrorType {
277    fn from(_: FromUtf8Error) -> ErrorType {
278        ErrorType::UTF8Error
279    }
280}
281
282#[derive(Debug, Clone, Copy, PartialEq, Eq)]
283#[allow(dead_code)]
284pub enum Code {
285    CommandCode(Command),
286    ResponseCode(Response),
287}
288
289#[derive(Debug, Clone, PartialEq, Eq)]
290#[allow(dead_code)]
291pub struct CoinValue {
292    pub value: u32,
293    pub country_code: String,
294}
295
296impl CoinValue {
297    pub fn decode(data: &mut Vec<u8>) -> Result<CoinValue, ErrorType> {
298        let value_vec: Vec<u8> = data.drain(0..4 as usize).collect();
299        let country_code_vec: Vec<u8> = data.drain(0..3 as usize).collect();
300
301        let country_code = String::from_utf8(country_code_vec)?;
302
303        let val = vec_to_u32(&value_vec)?;
304
305        Ok(CoinValue {
306               value: val,
307               country_code: country_code,
308           })
309    }
310
311    pub fn decode_list(data: &mut Vec<u8>) -> Result<Vec<CoinValue>, ErrorType> {
312        let num = data.remove(0);
313        let mut coin_values = Vec::<CoinValue>::new();
314        for _ in 0..num {
315            coin_values.push(CoinValue::decode(data)?);
316        }
317        Ok(coin_values)
318    }
319
320    pub fn encode(&self) -> Vec<u8> {
321        let mut data = vec![];
322        let mut value_vec = u32_to_vec(self.value);
323        data.append(&mut value_vec);
324        data.extend_from_slice(self.country_code.as_bytes());
325
326        data
327    }
328
329    pub fn encode_list(list: &Vec<CoinValue>) -> Vec<u8> {
330        let mut data = vec![list.len() as u8];
331
332        for elem in list {
333            let mut elem_data = elem.encode();
334            data.append(&mut elem_data);
335        }
336        data
337    }
338}
339
340impl fmt::Display for CoinValue {
341    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
342        write!(f, "{} {}", self.value, self.country_code)
343    }
344}
345
346#[derive(Debug, Clone, PartialEq, Eq)]
347#[allow(dead_code)]
348pub struct CoinNumValue {
349    pub num: u16,
350    pub value: u32,
351    pub country_code: String,
352}
353
354impl CoinNumValue {
355    pub fn decode(data: &mut Vec<u8>) -> Result<CoinNumValue, ErrorType> {
356        let num_vec: Vec<u8> = data.drain(0..2 as usize).collect();
357        let value_vec: Vec<u8> = data.drain(0..4 as usize).collect();
358        let country_code_vec: Vec<u8> = data.drain(0..3 as usize).collect();
359
360        let country_code = String::from_utf8(country_code_vec)?;
361
362        let num = vec_to_u16(&num_vec)?;
363        let val = vec_to_u32(&value_vec)?;
364
365        Ok(CoinNumValue {
366               num: num,
367               value: val,
368               country_code: country_code,
369           })
370    }
371
372    pub fn decode_list(data: &mut Vec<u8>) -> Result<Vec<CoinNumValue>, ErrorType> {
373        let num = data.remove(0);
374        let mut coin_num_values = Vec::<CoinNumValue>::new();
375        for _ in 0..num {
376            coin_num_values.push(CoinNumValue::decode(data)?);
377        }
378        Ok(coin_num_values)
379    }
380
381    pub fn encode(&self) -> Vec<u8> {
382        let mut data = vec![];
383        let mut num_vec = u16_to_vec(self.num);
384        data.append(&mut num_vec);
385        let mut value_vec = u32_to_vec(self.value);
386        data.append(&mut value_vec);
387        data.extend_from_slice(self.country_code.as_bytes());
388
389        data
390    }
391
392    pub fn encode_list(list: &Vec<CoinNumValue>) -> Vec<u8> {
393        let mut data = vec![list.len() as u8];
394
395        for elem in list {
396            let mut elem_data = elem.encode();
397            data.append(&mut elem_data);
398        }
399        data
400    }
401}
402
403impl fmt::Display for CoinNumValue {
404    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
405        write!(f, "{} {}: {}", self.value, self.country_code, self.num)
406    }
407}
408
409#[derive(Debug, Clone, PartialEq, Eq)]
410#[allow(dead_code)]
411pub struct IncompleteCoinValue {
412    pub value: u32,
413    pub value_requested: u32,
414    pub country_code: String,
415}
416
417impl IncompleteCoinValue {
418    pub fn decode(data: &mut Vec<u8>) -> Result<IncompleteCoinValue, ErrorType> {
419        let value_vec: Vec<u8> = data.drain(0..4 as usize).collect();
420        let value_requested_vec: Vec<u8> = data.drain(0..4 as usize).collect();
421        let country_code_vec: Vec<u8> = data.drain(0..3 as usize).collect();
422
423        let country_code = String::from_utf8(country_code_vec)?;
424
425        let val = vec_to_u32(&value_vec)?;
426        let val_req = vec_to_u32(&value_requested_vec)?;
427
428        Ok(IncompleteCoinValue {
429               value: val,
430               value_requested: val_req,
431               country_code: country_code,
432           })
433    }
434
435    pub fn decode_list(data: &mut Vec<u8>) -> Result<Vec<IncompleteCoinValue>, ErrorType> {
436        let num = data.remove(0);
437        let mut coin_values = Vec::<IncompleteCoinValue>::new();
438        for _ in 0..num {
439            coin_values.push(IncompleteCoinValue::decode(data)?);
440        }
441        Ok(coin_values)
442    }
443
444    pub fn encode(&self) -> Vec<u8> {
445        let mut data = vec![];
446        let mut value_vec = u32_to_vec(self.value);
447        data.append(&mut value_vec);
448        let mut value_vec_req = u32_to_vec(self.value_requested);
449        data.append(&mut value_vec_req);
450        data.extend_from_slice(self.country_code.as_bytes());
451
452        data
453    }
454
455    pub fn encode_list(list: &Vec<IncompleteCoinValue>) -> Vec<u8> {
456        let mut data = vec![list.len() as u8];
457
458        for elem in list {
459            let mut elem_data = elem.encode();
460            data.append(&mut elem_data);
461        }
462        data
463    }
464}
465
466
467
468#[derive(Debug, Clone, PartialEq, Eq)]
469#[allow(dead_code)]
470pub struct CashboxPayoutData {
471    pub known: Vec<CoinNumValue>,
472    pub unknown: u32,
473}
474
475impl CashboxPayoutData {
476    pub fn decode(data: &mut Vec<u8>) -> Result<CashboxPayoutData, ErrorType> {
477        let known = CoinNumValue::decode_list(data)?;
478        let unknown_vec: Vec<u8> = data.drain(0..4 as usize).collect();
479        let unknown = vec_to_u32(&unknown_vec)?;
480
481        Ok(CashboxPayoutData {
482               known: known,
483               unknown: unknown,
484           })
485    }
486
487    pub fn encode(&self) -> Vec<u8> {
488        let mut data = vec![];
489        let mut known = CoinNumValue::encode_list(&self.known);
490        data.append(&mut known);
491
492        let mut unknown_vec = u32_to_vec(self.unknown);
493        data.append(&mut unknown_vec);
494
495        data
496    }
497}
498
499
500
501#[derive(Debug)]
502#[derive(Clone)]
503#[allow(dead_code)]
504pub enum DeviceType {
505    BillValidator,
506    SmartHopper,
507}
508
509#[derive(Debug, Clone, PartialEq, Eq)]
510#[allow(dead_code)]
511pub enum FraudAttemptData {
512    BillValidatorData { channel: u8 },
513    SmartHopperData { dispensed: Vec<CoinValue> },
514}
515
516#[derive(Debug, Clone, PartialEq, Eq)]
517#[allow(dead_code)]
518pub enum PollEvent {
519    SlaveReset,
520    Disabled,
521    FraudAttempt { data: FraudAttemptData },
522    Initialising,
523    Dispensing { dispensed: Vec<CoinValue> },
524    Dispensed { dispensed: Vec<CoinValue> },
525    CoinsLow,
526    HopperJammed { dispensed: Vec<CoinValue> },
527    Halted { dispensed: Vec<CoinValue> },
528    Floating { floated: Vec<CoinValue> },
529    Floated { floated: Vec<CoinValue> },
530    Timeout { dispensed: Vec<CoinValue> },
531    IncompletePayout { dispensed: Vec<IncompleteCoinValue> },
532    IncompleteFloat { floated: Vec<IncompleteCoinValue> },
533    CashboxPaid { dispensed: Vec<CoinValue> },
534    CoinCredit { credit: CoinValue },
535    CoinMechJammed,
536    CoinMechReturnActive,
537    Emptying,
538    Emptied,
539    SmartEmptying { dispensed: Vec<CoinValue> },
540    SmartEmptied { dispensed: Vec<CoinValue> },
541    CalibrationFailed { error_code: u8 },
542    CoinMechError { error_code: u8 },
543    AttachedCoinMechDisabled,
544    AttachedCoinMechEnabled,
545    Read { channel: u8 },
546    NoteCredit { channel: u8 },
547    Rejecting,
548    Rejected,
549    Stacking,
550    Stacked,
551    SafeJam,
552    UnsafeJam,
553    StackerFull,
554    NoteClearedFromFront { channel: u8 },
555    NoteClearedIntoCashbox { channel: u8 },
556    ChannelDisable,
557    TicketInBezel,
558    PrintedToCashbox,
559    Unknown(u8),
560}
561
562impl PollEvent {
563    #[allow(dead_code)]
564    pub fn parse_first(data: &mut Vec<u8>, device_type: &DeviceType) -> Result<Option<PollEvent>, ErrorType> {
565
566        // Note: it's parsing poll response as ESSP ver6
567
568        if data.len() == 0 {
569            return Ok(None);
570        }
571        let code = data.remove(0);
572        match code {
573            0xF1 => Ok(Some(PollEvent::SlaveReset)),
574            0xE8 => Ok(Some(PollEvent::Disabled)),
575            0xE6 => {
576                match device_type {
577                    &DeviceType::BillValidator => {
578                        let channel = data.remove(0);
579                        Ok(Some(PollEvent::FraudAttempt { data: FraudAttemptData::BillValidatorData { channel: channel } }))
580                    }
581                    &DeviceType::SmartHopper => {
582                        let coin_values = CoinValue::decode_list(data)?;
583                        Ok(Some(PollEvent::FraudAttempt { data: FraudAttemptData::SmartHopperData { dispensed: coin_values } }))
584                    }
585                }
586            }
587            0xB6 => Ok(Some(PollEvent::Initialising)),
588            0xDA => {
589                let coin_values = CoinValue::decode_list(data)?;
590                Ok(Some(PollEvent::Dispensing { dispensed: coin_values }))
591            }
592            0xD2 => {
593                let coin_values = CoinValue::decode_list(data)?;
594                Ok(Some(PollEvent::Dispensed { dispensed: coin_values }))
595            }
596            0xD3 => Ok(Some(PollEvent::CoinsLow)),
597            0xD5 => {
598                let coin_values = CoinValue::decode_list(data)?;
599                Ok(Some(PollEvent::HopperJammed { dispensed: coin_values }))
600            }
601            0xD6 => {
602                let coin_values = CoinValue::decode_list(data)?;
603                Ok(Some(PollEvent::Halted { dispensed: coin_values }))
604            }
605            0xD7 => {
606                let coin_values = CoinValue::decode_list(data)?;
607                Ok(Some(PollEvent::Floating { floated: coin_values }))
608            }
609            0xD8 => {
610                let coin_values = CoinValue::decode_list(data)?;
611                Ok(Some(PollEvent::Floated { floated: coin_values }))
612            }
613            0xD9 => {
614                let coin_values = CoinValue::decode_list(data)?;
615                Ok(Some(PollEvent::Timeout { dispensed: coin_values }))
616            }
617            0xDC => {
618                let coin_values = IncompleteCoinValue::decode_list(data)?;
619                Ok(Some(PollEvent::IncompletePayout { dispensed: coin_values }))
620            }
621            0xDD => {
622                let coin_values = IncompleteCoinValue::decode_list(data)?;
623                Ok(Some(PollEvent::IncompleteFloat { floated: coin_values }))
624            }
625            0xDE => {
626                let coin_values = CoinValue::decode_list(data)?;
627                Ok(Some(PollEvent::CashboxPaid { dispensed: coin_values }))
628            }
629            0xDF => {
630                let coin_value = CoinValue::decode(data)?;
631                Ok(Some(PollEvent::CoinCredit { credit: coin_value }))
632            }
633            0xC4 => Ok(Some(PollEvent::CoinMechJammed)),
634            0xC5 => Ok(Some(PollEvent::CoinMechReturnActive)),
635            0xC2 => Ok(Some(PollEvent::Emptying)),
636            0xC3 => Ok(Some(PollEvent::Emptied)),
637            0xB3 => {
638                let coin_values = CoinValue::decode_list(data)?;
639                Ok(Some(PollEvent::SmartEmptying { dispensed: coin_values }))
640            }
641            0xB4 => {
642                let coin_values = CoinValue::decode_list(data)?;
643                Ok(Some(PollEvent::SmartEmptied { dispensed: coin_values }))
644            }
645            0x83 => {
646                let error_code = data.remove(0);
647                Ok(Some(PollEvent::CalibrationFailed { error_code: error_code }))
648            }
649            0xB7 => {
650                let error_code = data.remove(0);
651                Ok(Some(PollEvent::CoinMechError { error_code: error_code }))
652            }
653            0xBD => Ok(Some(PollEvent::AttachedCoinMechDisabled)),
654            0xBE => Ok(Some(PollEvent::AttachedCoinMechEnabled)),
655            0xEF => {
656                let channel = data.remove(0);
657                Ok(Some(PollEvent::Read { channel: channel }))
658            }
659            0xEE => {
660                let channel = data.remove(0);
661                Ok(Some(PollEvent::NoteCredit { channel: channel }))
662            }
663            0xED => Ok(Some(PollEvent::Rejecting)),
664            0xEC => Ok(Some(PollEvent::Rejected)),
665            0xCC => Ok(Some(PollEvent::Stacking)),
666            0xEB => Ok(Some(PollEvent::Stacked)),
667            0xEA => Ok(Some(PollEvent::SafeJam)),
668            0xE9 => Ok(Some(PollEvent::UnsafeJam)),
669            0xE7 => Ok(Some(PollEvent::StackerFull)),
670            0xE1 => {
671                let channel = data.remove(0);
672                Ok(Some(PollEvent::NoteClearedFromFront { channel: channel }))
673            }
674            0xE2 => {
675                let channel = data.remove(0);
676                Ok(Some(PollEvent::NoteClearedIntoCashbox { channel: channel }))
677            }
678            0xB5 => Ok(Some(PollEvent::ChannelDisable)),
679            0xAD => Ok(Some(PollEvent::TicketInBezel)),
680            0xAF => Ok(Some(PollEvent::PrintedToCashbox)),
681            _ => Ok(Some(PollEvent::Unknown(code))),
682        }
683    }
684
685    pub fn encode(&self) -> Vec<u8> {
686        match self {
687            &PollEvent::SlaveReset => vec![0xF1],
688            &PollEvent::Disabled => vec![0xE8],
689            &PollEvent::FraudAttempt { ref data } => {
690                match data {
691                    &FraudAttemptData::BillValidatorData { channel } => vec![0xE6, channel],
692                    &FraudAttemptData::SmartHopperData { dispensed: ref coin_values } => {
693                        let mut res = vec![0xE6];
694                        let mut encoded = CoinValue::encode_list(coin_values);
695                        res.append(&mut encoded);
696                        res
697                    }
698                }
699            }
700            &PollEvent::Initialising => vec![0xB6],
701            &PollEvent::Dispensing { dispensed: ref coin_values } => {
702                let mut res = vec![0xDA];
703                let mut encoded = CoinValue::encode_list(coin_values);
704                res.append(&mut encoded);
705                res
706            }
707            &PollEvent::Dispensed { dispensed: ref coin_values } => {
708                let mut res = vec![0xD2];
709                let mut encoded = CoinValue::encode_list(coin_values);
710                res.append(&mut encoded);
711                res
712            }
713            &PollEvent::CoinsLow => vec![0xD3],
714            &PollEvent::HopperJammed { dispensed: ref coin_values } => {
715                let mut res = vec![0xD5];
716                let mut encoded = CoinValue::encode_list(coin_values);
717                res.append(&mut encoded);
718                res
719            }
720            &PollEvent::Halted { dispensed: ref coin_values } => {
721                let mut res = vec![0xD6];
722                let mut encoded = CoinValue::encode_list(coin_values);
723                res.append(&mut encoded);
724                res
725            }
726            &PollEvent::Floating { floated: ref coin_values } => {
727                let mut res = vec![0xD7];
728                let mut encoded = CoinValue::encode_list(coin_values);
729                res.append(&mut encoded);
730                res
731            }
732            &PollEvent::Floated { floated: ref coin_values } => {
733                let mut res = vec![0xD8];
734                let mut encoded = CoinValue::encode_list(coin_values);
735                res.append(&mut encoded);
736                res
737            }
738            &PollEvent::Timeout { dispensed: ref coin_values } => {
739                let mut res = vec![0xD9];
740                let mut encoded = CoinValue::encode_list(coin_values);
741                res.append(&mut encoded);
742                res
743            }
744            &PollEvent::IncompletePayout { dispensed: ref coin_values } => {
745                let mut res = vec![0xDC];
746                let mut encoded = IncompleteCoinValue::encode_list(coin_values);
747                res.append(&mut encoded);
748                res
749            }
750            &PollEvent::IncompleteFloat { floated: ref coin_values } => {
751                let mut res = vec![0xDD];
752                let mut encoded = IncompleteCoinValue::encode_list(coin_values);
753                res.append(&mut encoded);
754                res
755            }
756            &PollEvent::CashboxPaid { dispensed: ref coin_values } => {
757                let mut res = vec![0xDE];
758                let mut encoded = CoinValue::encode_list(coin_values);
759                res.append(&mut encoded);
760                res
761            }
762            &PollEvent::CoinCredit { credit: ref coin_value } => {
763                let mut res = vec![0xDF];
764                let mut encoded = coin_value.encode();
765                res.append(&mut encoded);
766                res
767            }
768            &PollEvent::CoinMechJammed => vec![0xC4],
769            &PollEvent::CoinMechReturnActive => vec![0xC5],
770            &PollEvent::Emptying => vec![0xC2],
771            &PollEvent::Emptied => vec![0xC3],
772            &PollEvent::SmartEmptying { dispensed: ref coin_values } => {
773                let mut res = vec![0xB3];
774                let mut encoded = CoinValue::encode_list(coin_values);
775                res.append(&mut encoded);
776                res
777            }
778            &PollEvent::SmartEmptied { dispensed: ref coin_values } => {
779                let mut res = vec![0xB4];
780                let mut encoded = CoinValue::encode_list(coin_values);
781                res.append(&mut encoded);
782                res
783            }
784            &PollEvent::CalibrationFailed { error_code } => vec![0x83, error_code],
785            &PollEvent::CoinMechError { error_code } => vec![0xB7, error_code],
786            &PollEvent::AttachedCoinMechDisabled => vec![0xBD],
787            &PollEvent::AttachedCoinMechEnabled => vec![0xBE],
788            &PollEvent::Read { channel } => vec![0xEF, channel],
789            &PollEvent::NoteCredit { channel } => vec![0xEE, channel],
790            &PollEvent::Rejecting => vec![0xED],
791            &PollEvent::Rejected => vec![0xEC],
792            &PollEvent::Stacking => vec![0xCC],
793            &PollEvent::Stacked => vec![0xEB],
794            &PollEvent::SafeJam => vec![0xEA],
795            &PollEvent::UnsafeJam => vec![0xE9],
796            &PollEvent::StackerFull => vec![0xE7],
797            &PollEvent::NoteClearedFromFront { channel } => vec![0xE1, channel],
798            &PollEvent::NoteClearedIntoCashbox { channel } => vec![0xE2, channel],
799            &PollEvent::ChannelDisable => vec![0xB5],
800            &PollEvent::TicketInBezel => vec![0xAD],
801            &PollEvent::PrintedToCashbox => vec![0xAF],
802            &PollEvent::Unknown(val) => vec![val],
803        }
804    }
805}
806
807#[derive(Debug)]
808#[derive(Clone)]
809#[allow(dead_code)]
810pub enum PayoutError {
811    NotEnoughValue,
812    CannotPayExactAmount,
813    DeviceBusy,
814    DeviceDisabled,
815    Unknown(u8),
816}
817
818impl PayoutError {
819    fn from_u8(n: u8) -> PayoutError {
820        match n {
821            1 => PayoutError::NotEnoughValue,
822            2 => PayoutError::CannotPayExactAmount,
823            3 => PayoutError::DeviceBusy,
824            4 => PayoutError::DeviceDisabled,
825            _ => PayoutError::Unknown(n),
826        }
827    }
828}
829
830pub fn calc_crc(data: &Vec<u8>) -> CRC {
831    let poly = 0x8005;
832    let mut crc = 0xFFFFu16;
833
834    for byte in data {
835        crc ^= (*byte as u16) << 8;
836        for _ in 0..8 {
837            if (crc & 0x8000) != 0 {
838                crc = ((crc << 1) & 0xffff) ^ poly;
839            } else {
840                crc <<= 1;
841            }
842        }
843    }
844    [(crc & 0xff) as u8, (crc >> 8 & 0xff) as u8]
845}
846
847pub fn vec_to_u16(vector: &Vec<u8>) -> Result<u16, ErrorType> {
848    let mut rdr = Cursor::new(vector);
849    match rdr.read_u16::<LittleEndian>() {
850        Ok(data) => Ok(data),
851        Err(_) => Err(ErrorType::ParseError),
852    }
853}
854
855#[allow(dead_code)]
856pub fn u16_to_vec(num: u16) -> Vec<u8> {
857    let mut data = vec![];
858    data.write_u16::<LittleEndian>(num).unwrap();
859    data
860}
861
862pub fn vec_to_u32(vector: &Vec<u8>) -> Result<u32, ErrorType> {
863    let mut rdr = Cursor::new(vector);
864    match rdr.read_u32::<LittleEndian>() {
865        Ok(data) => Ok(data),
866        Err(_) => Err(ErrorType::ParseError),
867    }
868}
869
870pub fn u32_to_vec(num: u32) -> Vec<u8> {
871    let mut data = vec![];
872    data.write_u32::<LittleEndian>(num).unwrap();
873    data
874}
875
876pub fn vec_to_u64(vector: &Vec<u8>) -> Result<u64, ErrorType> {
877    let mut rdr = Cursor::new(vector);
878    match rdr.read_u64::<LittleEndian>() {
879        Ok(data) => Ok(data),
880        Err(_) => Err(ErrorType::ParseError),
881    }
882}
883
884pub fn u64_to_vec(num: u64) -> Vec<u8> {
885    let mut data = vec![];
886    data.write_u64::<LittleEndian>(num).unwrap();
887    data
888}
889
890
891#[derive(Debug, Clone, PartialEq, Eq)]
892#[allow(dead_code)]
893pub struct Payload {
894    pub code: Code,
895    pub data: Data,
896    pub encrypted: bool,
897}
898
899
900impl Payload {
901    pub fn new_u64(code: Code, data_u64: u64, encrypted: bool) -> Payload {
902        Payload {
903            code: code,
904            data: u64_to_vec(data_u64),
905            encrypted: encrypted,
906        }
907    }
908
909    pub fn encode(&self, ecount: ECount, key: Option<Key>) -> Result<Vec<u8>, ErrorType> {
910        let mut temp = Vec::<u8>::new();
911        let code_byte = match &self.code {
912            &Code::CommandCode(ref cmd) => cmd.to_u8(),
913            &Code::ResponseCode(ref resp) => resp.to_u8(),
914        };
915        temp.push(code_byte);
916        temp.append(&mut self.data.clone());
917
918        match self.encrypted {
919            true => {
920                if let None = key {
921                    Err(ErrorType::KeyNotSet)
922                } else {
923                    Payload::encrypt(&temp, ecount, key.unwrap())
924                }
925            }
926            false => Ok(temp),
927        }
928    }
929
930    pub fn decode(raw: &Vec<u8>, ecount: ECount, key: Option<Key>) -> Result<Payload, ErrorType> {
931        let encrypted = raw[0] == STEX;
932        let mut data = match encrypted {
933            true => {
934                if let None = key {
935                    return Err(ErrorType::KeyNotSet);
936                } else {
937                    Payload::decrypt(raw, ecount, key.unwrap())?
938                }
939            }
940            false => raw.clone(),
941        };
942        let code_byte = data.remove(0);
943
944        // decode always assumes that it's decoding a response, so it will interpret the first byte as response code
945        Ok(Payload {
946               code: Code::ResponseCode(Response::from_u8(code_byte)),
947               data: data,
948               encrypted: encrypted,
949           })
950    }
951
952    fn encrypt(raw_payload: &Vec<u8>, ecount: ECount, key: Key) -> Result<Vec<u8>, ErrorType> {
953        let mut to_encode = Vec::<u8>::new();
954        to_encode.push(raw_payload.len() as u8);
955
956        let mut ecount_vec = u32_to_vec(ecount);
957        to_encode.append(&mut ecount_vec);
958
959        to_encode.extend_from_slice(raw_payload);
960        // add packing to make length mod 16
961        let packing_len = 16 - ((to_encode.len() + 2) % 16);
962        to_encode.extend(iter::repeat(0u8).take(packing_len));
963
964        // CRC of the encrypted part
965        let ecrc = calc_crc(&to_encode);
966        to_encode.extend_from_slice(&ecrc);
967
968        let enc_len = to_encode.len();
969
970        let aes_enc = aessafe::AesSafe128Encryptor::new(&key[..]);
971        let mut encryptor = blockmodes::EcbEncryptor::new(aes_enc, blockmodes::NoPadding);
972
973        let mut out = Vec::<u8>::with_capacity(enc_len);
974        out.resize(enc_len, 0u8);
975
976        {
977            let mut buff_in = RefReadBuffer::new(&to_encode);
978            let mut buff_out = RefWriteBuffer::new(&mut out);
979
980            match encryptor.encrypt(&mut buff_in, &mut buff_out, true) {
981                Ok(BufferResult::BufferUnderflow) => {}
982                Ok(BufferResult::BufferOverflow) => {
983                    panic!("ESSP Encryption buffer overflow"); // this should not happend with ECB encryption mode
984                }
985                Err(err) => return Err(ErrorType::CryptoError(err)),
986            }
987        }
988        // debug!("Ciphertext: {:?}", out);
989
990        // put STEX in after encryption
991        out.insert(0, STEX);
992
993        Ok(out)
994    }
995
996    fn decrypt(raw: &Vec<u8>, ecount: ECount, key: Key) -> Result<Vec<u8>, ErrorType> {
997        let mut to_decode = raw.clone();
998
999        // removeing STEX
1000        to_decode.remove(0);
1001
1002        // debug!("To decode: {:?}", &to_decode);
1003        let dec_len = to_decode.len();
1004
1005        let aes_dec = aessafe::AesSafe128Decryptor::new(&key[..]);
1006        let mut decryptor = blockmodes::EcbDecryptor::new(aes_dec, blockmodes::NoPadding);
1007
1008        let mut out = Vec::<u8>::with_capacity(dec_len);
1009        out.resize(dec_len, 0u8);
1010
1011        {
1012            let mut buff_in = RefReadBuffer::new(&to_decode);
1013            let mut buff_out = RefWriteBuffer::new(&mut out);
1014
1015            match decryptor.decrypt(&mut buff_in, &mut buff_out, true) {
1016                Ok(BufferResult::BufferUnderflow) => {}
1017                Ok(BufferResult::BufferOverflow) => {
1018                    panic!("ESSP Decryption buffer overflow!"); // This should not happend with ECB encryption
1019                }
1020                Err(err) => return Err(ErrorType::CryptoError(err)),
1021            }
1022        }
1023        // debug!("Decoded: {:?}", out);
1024
1025        let crc_2 = out.pop().unwrap();
1026        let crc_1 = out.pop().unwrap();
1027
1028        let received_crc: CRC = [crc_1, crc_2];
1029        let expected_crc = calc_crc(&out);
1030        if received_crc != expected_crc {
1031            return Err(ErrorType::EncryptedCRCError);
1032        }
1033
1034        let payload_len = out.remove(0);
1035        // TODO check len
1036        // debug!("payload len: {:?}", payload_len);
1037
1038        // cut the counter
1039        let mut payload = out.split_off(4);
1040        let received_ecount = vec_to_u32(&out)?;
1041
1042        // check ecount
1043        if received_ecount != ecount {
1044            return Err(ErrorType::EncryptionCounterError);
1045        }
1046
1047        // cut the packing and crc
1048        let _ = payload.split_off(payload_len as usize);
1049
1050        // debug!("payload after decryption: {:?}", payload);
1051
1052        Ok(payload)
1053    }
1054
1055    pub fn parse_as_u64(&self) -> Result<u64, ErrorType> {
1056        vec_to_u64(&self.data)
1057    }
1058
1059    pub fn parse_as_u32(&self) -> Result<u32, ErrorType> {
1060        vec_to_u32(&self.data)
1061    }
1062
1063    pub fn parse_as_payout_error(&self) -> PayoutError {
1064        PayoutError::from_u8(self.data[0])
1065    }
1066
1067    pub fn parse_as_poll_response(&self, device_type: &DeviceType) -> Result<Vec<PollEvent>, ErrorType> {
1068        let mut event_data = self.data.clone();
1069        let mut events = Vec::<PollEvent>::new();
1070        while event_data.len() > 0 {
1071            let event = PollEvent::parse_first(&mut event_data, &device_type)?;
1072            if let Some(event) = event {
1073                events.push(event);
1074            }
1075        }
1076        Ok(events)
1077    }
1078
1079    pub fn parse_as_coin_values(&self) -> Result<Vec<CoinNumValue>, ErrorType> {
1080        CoinNumValue::decode_list(&mut self.data.clone())
1081    }
1082
1083    pub fn parse_as_cashbox_payout_data(&self) -> Result<CashboxPayoutData, ErrorType> {
1084        CashboxPayoutData::decode(&mut self.data.clone())
1085    }
1086}
1087
1088#[derive(Debug, Clone, PartialEq, Eq)]
1089#[allow(dead_code)]
1090pub struct Message {
1091    pub slave_id: SlaveID,
1092    pub payload: Payload,
1093}
1094
1095impl Message {
1096    // should be called after CRC is calculated
1097    fn byte_stuff(data: &Data) -> Data {
1098        // if data has STX, insert another STX
1099        let mut temp = Vec::<u8>::new();
1100        temp.push(data[0]);
1101
1102        // we ignore the first byte, it should not be stuffed
1103        for byte in data[1..].iter() {
1104            if *byte == STX {
1105                temp.push(STX);
1106            }
1107            temp.push(*byte);
1108        }
1109
1110        temp
1111    }
1112
1113    fn byte_destuff(data: &DataSlice) -> Data {
1114        let mut res = vec![];
1115
1116        let mut previous_byte = 0u8;
1117        for i in 0..data.len() {
1118            if previous_byte == STX && data[i] == STX {
1119                previous_byte = 0u8;
1120            } else {
1121                previous_byte = data[i];
1122                res.push(previous_byte);
1123            }
1124        }
1125
1126        res
1127    }
1128
1129    pub fn encode(&self, seq: bool, ecount: ECount, key: Option<Key>) -> Result<Vec<u8>, ErrorType> {
1130        let mut temp = Vec::<u8>::new();
1131        if seq {
1132            temp.push(self.slave_id + 128u8);
1133        } else {
1134            temp.push(self.slave_id);
1135        }
1136
1137        let mut encoded_payload = self.payload.encode(ecount, key)?;
1138        temp.push(encoded_payload.len() as u8);
1139        temp.append(&mut encoded_payload);
1140
1141        // CRC is calculated with every byte except STX
1142        let crc = calc_crc(&temp);
1143        temp.extend_from_slice(&crc);
1144
1145        // put STX at the beginning
1146        temp.insert(0, STX);
1147
1148        // returning the byte stuffed version of the message
1149        Ok(Message::byte_stuff(&temp))
1150    }
1151
1152    pub fn decode(buffer: &mut Vec<u8>, seq: bool, ecount: ECount, key: Option<Key>) -> Result<Message, ErrorType> {
1153        if buffer.len() < 3 {
1154            return Err(ErrorType::PartialMessage);
1155        }
1156
1157        while buffer[0] != STX || buffer[1] == STX {
1158            warn!("Message alignment error, clearing buffer until next STX! Bad buffer: {:?}", buffer);
1159
1160            let mut invalid_message: Vec<u8> = vec![];
1161            invalid_message.push(buffer.remove(0));
1162
1163            let stx_pos = buffer.iter().position(|&r| r == STX);
1164            match stx_pos {
1165                Some(pos) => {
1166                    invalid_message.extend(buffer.drain(0..pos as usize));
1167                    warn!("Clearing {} bytes from buffer: {:?}, remaining buffer: {:?}", pos + 1, invalid_message, buffer);
1168                }
1169                None => {
1170                    invalid_message.append(buffer);
1171                    buffer.clear();
1172                    warn!("Clearing from buffer: {:?}, buffer is empty", invalid_message);
1173                }
1174            }
1175
1176            if buffer.len() < 3 {
1177                return Err(ErrorType::PartialMessage);
1178            }
1179        }
1180
1181        trace!("Result buffer: {:?}", buffer);
1182
1183        let buffer_size: usize = buffer.len();
1184        if buffer_size < 3 {
1185            return Err(ErrorType::PartialMessage);
1186        }
1187
1188        let mut slave_id = buffer[1];
1189        let received_seq;
1190        if slave_id >= 128 {
1191            received_seq = true;
1192            slave_id -= 128;
1193        } else {
1194            received_seq = false;
1195        }
1196
1197        if slave_id > MAX_SLAVE_ID {
1198            debug!("Invalid slave ID received: {:?}", slave_id);
1199            buffer.drain(0..2);
1200            return Err(ErrorType::SlaveIdError);
1201        }
1202
1203        trace!("Decoding buffer: {:?}", buffer);
1204
1205        let payload_size = buffer[2] as usize;
1206        let expected_msg_size = payload_size + 5;
1207
1208        let mut to_read: usize = 0;
1209        let mut destuffed: Vec<u8> = vec![];
1210        let mut destuffed_size = 0;
1211
1212        trace!("Guessing message size: {}", expected_msg_size);
1213
1214        while destuffed_size != expected_msg_size {
1215            to_read = to_read + expected_msg_size - destuffed_size;
1216
1217            if buffer_size < to_read {
1218                trace!("Partial message: {:?} - size: {}, expected: {}", buffer, buffer_size, to_read);
1219                return Err(ErrorType::PartialMessage);
1220            };
1221
1222            trace!("Message to destuff: {:?}", &buffer[0..to_read]);
1223
1224            destuffed = Message::byte_destuff(&buffer[0..to_read]);
1225            destuffed_size = destuffed.len();
1226
1227            let removed = to_read - destuffed_size;
1228            trace!("Byte stuffing removed, got: {:?} - diff: {}", destuffed, removed);
1229        }
1230
1231        // if success, really drain the message
1232        buffer.drain(0..to_read);
1233        // don't touch buffer after this, it may have the next message
1234
1235        if received_seq == seq {
1236            // Why is this not working omg???
1237            //debug!("SEQ error in ESSP message: {:?}", raw_msg);
1238            //return Err(ErrorType::NotAResponse);
1239        }
1240
1241        if !Message::validate_crc(&destuffed) {
1242            error!("CRC error on ESSP message: {:?}", destuffed);
1243            return Err(ErrorType::CRCError);
1244        }
1245
1246        trace!("Received valid ESSP message for slaveID: {:?}, seq {:?} - raw message {:?}", slave_id, received_seq, destuffed);
1247
1248        // cut the payload part
1249        let raw_payload = destuffed.drain(3..(payload_size + 3)).collect();
1250
1251        let decoded_payload = Payload::decode(&raw_payload, ecount, key)?;
1252
1253        trace!("Decoded: {:?}", decoded_payload);
1254
1255        Ok(Message {
1256               slave_id: slave_id,
1257               payload: decoded_payload,
1258           })
1259    }
1260
1261    pub fn validate_crc(raw: &Vec<u8>) -> bool {
1262        if raw.is_empty() {
1263            error!("Validate CRC called on empty ESSP message!");
1264            return false;
1265        }
1266
1267        let mut data = raw.clone();
1268        // remove STX
1269        data.remove(0);
1270
1271        let crc2 = data.pop().unwrap();
1272        let crc1 = data.pop().unwrap();
1273
1274        [crc1, crc2] == calc_crc(&data)
1275    }
1276}
1277
1278fn mod_pow(num: u64, pow: u64, modulo: u64) -> u64 {
1279    let mut num = num;
1280    let mut pow = pow;
1281    let mut ret = 1;
1282    while pow > 0 {
1283        if pow & 1 == 1 {
1284            ret = (ret * num) % modulo;
1285        }
1286        pow >>= 1;
1287        num = (num * num) % modulo;
1288    }
1289    ret
1290}
1291
1292pub fn calc_inter_key(generator: Generator, modulus: Modulus) -> (InterKey, InterKey) {
1293    let mut os_rng = OsRng::new().unwrap();
1294    let host_rnd = os_rng.next_u64();
1295
1296    let inter_key: InterKey = mod_pow(generator, host_rnd, modulus);
1297
1298    (inter_key, host_rnd)
1299}
1300
1301pub fn calc_key(slave_inter_key: InterKey, host_rnd: InterKey, modulus: Modulus, fix_key: InterKey) -> [u8; 16] {
1302    let negotiated_key = mod_pow(slave_inter_key, host_rnd, modulus);
1303    let mut negotiated_key_vec = u64_to_vec(negotiated_key);
1304    let mut fix_key_vec = u64_to_vec(fix_key);
1305    let mut key_calc = vec![];
1306
1307    // negotiated is first?
1308    key_calc.append(&mut fix_key_vec);
1309    key_calc.append(&mut negotiated_key_vec);
1310
1311    let mut array = [0u8; 16];
1312    for (&x, p) in key_calc.iter().zip(array.iter_mut()) {
1313        *p = x;
1314    }
1315    array
1316}
1317
1318
1319#[cfg(test)]
1320mod tests {
1321    use super::*;
1322
1323    #[test]
1324    fn essp_crc() {
1325        let data = vec![128, 1, 240];
1326        assert_eq!(calc_crc(&data), [35, 128]);
1327    }
1328
1329    #[test]
1330    fn essp_destuff_payload() {
1331        let buffer_original = vec![127, 16, 17, 126, 3, 4, 138, 40, 34, 127, 127, 49, 153, 193, 182, 35, 94, 11, 49, 201, 112];
1332        let buffer_expected = vec![127, 16, 17, 126, 3, 4, 138, 40, 34, 127, 49, 153, 193, 182, 35, 94, 11, 49, 201, 112];
1333        let res = Message::byte_destuff(&buffer_original);
1334        assert_eq!(res, buffer_expected);
1335    }
1336
1337    #[test]
1338    fn essp_destuff_crc1() {
1339        let buffer_original = vec![127, 16, 17, 126, 202, 137, 148, 122, 207, 20, 164, 91, 71, 249, 182, 87, 229, 42, 127, 127, 220];
1340        let buffer_expected = vec![127, 16, 17, 126, 202, 137, 148, 122, 207, 20, 164, 91, 71, 249, 182, 87, 229, 42, 127, 220];
1341        let res = Message::byte_destuff(&buffer_original);
1342        assert_eq!(res, buffer_expected);
1343    }
1344
1345    #[test]
1346    fn essp_destuff_crc2() {
1347        let buffer_original = vec![127, 168, 17, 126, 147, 14, 209, 35, 122, 97, 150, 16, 194, 114, 247, 10, 162, 95, 197, 47, 131, 127, 127];
1348        let buffer_expected = vec![127, 168, 17, 126, 147, 14, 209, 35, 122, 97, 150, 16, 194, 114, 247, 10, 162, 95, 197, 47, 131, 127];
1349        let res = Message::byte_destuff(&buffer_original);
1350        assert_eq!(res, buffer_expected);
1351    }
1352
1353    #[test]
1354    fn essp_double_destuff() {
1355        let buffer_original = vec![127, 16, 18, 126, 3, 4, 138, 40, 34, 127, 127, 127, 127, 49, 153, 193, 182, 35, 94, 11, 49, 201, 112];
1356        let buffer_expected = vec![127, 16, 18, 126, 3, 4, 138, 40, 34, 127, 127, 49, 153, 193, 182, 35, 94, 11, 49, 201, 112];
1357        let res = Message::byte_destuff(&buffer_original);
1358        assert_eq!(res, buffer_expected);
1359    }
1360
1361    #[test]
1362    fn essp_decode_partial() {
1363        let mut buffer = vec![127, 168, 2, 240, 127, 127, 49, 129, 127, 16, 17, 126, 3, 4, 138, 40, 34, 127, 127, 49, 153, 193, 182, 35, 94, 11, 49];
1364
1365        let res = Message::decode(&mut buffer, false, 0, None);
1366        let expected = Message {
1367            slave_id: 40,
1368            payload: Payload {
1369                code: Code::ResponseCode(Response::Ok),
1370                data: vec![127],
1371                encrypted: false,
1372            },
1373        };
1374        assert_eq!(res.unwrap(), expected);
1375
1376        let res = Message::decode(&mut buffer, false, 0, None);
1377        assert!(res.is_err());
1378        match res.unwrap_err() {
1379            ErrorType::PartialMessage => {}
1380            other => panic!("Expected PartialMessage, got: {:?}", other),
1381        }
1382        assert_eq!(buffer.len(), 19);
1383    }
1384
1385    #[test]
1386    fn essp_decode_double_stuffed() {
1387        let mut buffer = vec![127, 168, 2, 240, 127, 127, 49, 129, 127, 168, 5, 240, 100, 127, 127, 127, 127, 200, 174, 30];
1388
1389        // decode first
1390        let mut res = Message::decode(&mut buffer, false, 0, None);
1391        let expected1 = Message {
1392            slave_id: 40,
1393            payload: Payload {
1394                code: Code::ResponseCode(Response::Ok),
1395                data: vec![127],
1396                encrypted: false,
1397            },
1398        };
1399        assert_eq!(res.unwrap(), expected1);
1400
1401        // decode second, should not be byte de-stuffed twice!
1402        res = Message::decode(&mut buffer, false, 0, None);
1403        let expected2 = Message {
1404            slave_id: 40,
1405            payload: Payload {
1406                code: Code::ResponseCode(Response::Ok),
1407                data: vec![100, 127, 127, 200],
1408                encrypted: false,
1409            },
1410        };
1411        assert_eq!(res.unwrap(), expected2);
1412        assert!(buffer.is_empty());
1413    }
1414
1415    /*#[test]
1416    fn essp_decode_encrypted() {
1417        // TODO
1418    }*/
1419
1420    #[test]
1421    fn essp_decode_unencrypted() {
1422        let mut buffer = vec![127, 168, 9, 240, 199, 63, 16, 0, 0, 0, 0, 0, 254, 238];
1423        let res = Message::decode(&mut buffer, false, 0, None);
1424        assert!(res.is_ok());
1425        let expected = Message {
1426            slave_id: 40,
1427            payload: Payload {
1428                code: Code::ResponseCode(Response::Ok),
1429                data: vec![199, 63, 16, 0, 0, 0, 0, 0],
1430                encrypted: false,
1431            },
1432        };
1433        assert_eq!(res.unwrap(), expected);
1434        assert!(buffer.is_empty());
1435    }
1436
1437    #[test]
1438    fn essp_message_alignment_self_heal() {
1439        let expected = Message {
1440            slave_id: 0,
1441            payload: Payload {
1442                code: Code::ResponseCode(Response::Ok),
1443                data: vec![],
1444                encrypted: false,
1445            },
1446        };
1447
1448        let mut buffer = vec![9, 240, 199, 127, 127, 127, 127, 127, 128, 1, 240, 35, 128];
1449        let mut res = Message::decode(&mut buffer, false, 0, None);
1450        assert_eq!(res.unwrap(), expected);
1451        assert!(buffer.is_empty());
1452
1453        buffer = vec![199, 127, 127, 127, 127, 127, 128, 1, 240, 35, 128];
1454        res = Message::decode(&mut buffer, false, 0, None);
1455        assert_eq!(res.unwrap(), expected);
1456        assert!(buffer.is_empty());
1457
1458        let mut buffer = vec![127, 127, 127, 127, 127, 128, 1, 240, 35, 128];
1459        let res = Message::decode(&mut buffer, false, 0, None);
1460        assert_eq!(res.unwrap(), expected);
1461        assert!(buffer.is_empty());
1462
1463        let mut buffer = vec![127, 127, 127, 127, 128, 1, 240, 35, 128];
1464        let res = Message::decode(&mut buffer, false, 0, None);
1465        assert_eq!(res.unwrap(), expected);
1466        assert!(buffer.is_empty());
1467
1468        let mut buffer = vec![127, 127, 127, 128, 1, 240, 35, 128];
1469        let res = Message::decode(&mut buffer, false, 0, None);
1470        assert_eq!(res.unwrap(), expected);
1471        assert!(buffer.is_empty());
1472
1473        let mut buffer = vec![127, 128, 1, 240, 35, 128];
1474        let res = Message::decode(&mut buffer, false, 0, None);
1475        assert_eq!(res.unwrap(), expected);
1476        assert!(buffer.is_empty());
1477
1478        let mut buffer = vec![127, 128, 1, 240, 35, 128];
1479        let res = Message::decode(&mut buffer, false, 0, None);
1480        assert_eq!(res.unwrap(), expected);
1481        assert!(buffer.is_empty());
1482    }
1483
1484}