1use byteorder::{BigEndian, ReadBytesExt};
2use std::io::Cursor;
3
4use crate::application::domain::{
5 AnyValue, GetListResponseBody, GetOpenResponseBody, SmlListEntry, SmlMessageEnvelope,
6 SmlMessages,
7};
8
9#[non_exhaustive]
10#[derive(Debug)]
11pub enum ParseError {
12 Unknown,
13}
14
15pub type ParseResult<T> = Result<T, ParseError>;
16
17pub fn parse_body(input: &[u8]) -> ParseResult<SmlMessages> {
19 sml_parser::sml_body(input).map_err(|_| ParseError::Unknown)
20}
21
22pub fn parse_message(input: &[u8]) -> ParseResult<SmlMessages> {
24 sml_parser::sml_messages(input).map_err(|_| ParseError::Unknown)
25}
26
27peg::parser! {
28 grammar sml_parser<'a>() for [u8] {
29
30 pub (crate) rule sml_body() -> SmlMessages =
31 a: (sml_message_envelope())*
32 {
33 SmlMessages {
34 messages: a
35 }
36 }
37
38 pub (crate) rule sml_messages() -> SmlMessages =
39 header()
40 a: (sml_message_envelope())*
41 footer()
42 {
43 SmlMessages {
44 messages: a
45 }
46 }
47
48 rule header() -> () =
49 [0x1b] [0x1b] [0x1b] [0x1b] [0x01] [0x01] [0x01] [0x01]
50
51 rule footer() -> () =
52 [0x1b] [0x1b] [0x1b] [0x1b] [0x1a] [0..=255]*<3>
53
54 rule sml_message_envelope() -> SmlMessageEnvelope =
55 [0x76]
56 transaction_id()
57 group_no()
58 abort_on_error()
59 a:sml_message_body()
60 crc()
61 end_of_message()
62 { a }
63
64 rule crc() = [0x63] any_number() any_number()
65
66 rule end_of_message() = [0x00]+
68
69 rule sml_message_body() -> SmlMessageEnvelope =
70 get_open_response() /
71 get_list_response() /
72 get_close_response() rule get_open_response() -> SmlMessageEnvelope =
75 [0x72] [0x63] [0x01] [0x01]
76 a: get_open_response_content()
77 {
78 SmlMessageEnvelope::GetOpenResponse(a)
79 }
80
81 rule get_open_response_content() -> GetOpenResponseBody =
82 [0x76]
83 ([0x01] / string())
84 ([0x01] / string())
85 req_file_id: string()
86 server_id: string()
87 optional_sml_time()
88 optional_unsigned()
89 {
90 GetOpenResponseBody {
91 server_id,
92 req_file_id
93 }
94 }
95
96 rule optional_sml_time() = ([0x01]) / (sml_time())
97
98 rule sml_time() =
99 [0x72]
100 ([0x62] [0x01] unsigned()) /
101 ([0x62] [0x02] unsigned()) /
102 ([0x62] [0x03] sml_timestamp_local())
103
104 rule sml_timestamp_local() =
105 [0x73]
106 unsigned()
107 signed()
108 signed()
109
110 rule get_close_response() -> SmlMessageEnvelope =
111 [0x72] [0x63] [0x02] [0x01] [0x71]
112 get_close_response_content()
113 {
114 SmlMessageEnvelope::GetCloseResponse
115 }
116
117 rule get_close_response_content() = [0x01] / string()
118
119 rule get_list_response() -> SmlMessageEnvelope =
120 [0x72] [0x63] [0x07] [0x01] [0x77]
121 a: get_list_response_content()
122 {
123 SmlMessageEnvelope::GetListResponse(a)
124 }
125
126 rule list_signature() = [0x01] / string()
127
128 rule act_gateway_time() = ([0x01]*<0,1>) / (sml_time())
130
131 rule get_list_response_content() -> GetListResponseBody =
132 string()
134 server_id: string()
135 list_name: string()
136 ([0x01] / sml_time())
137 value_list: list_sml_value() list_signature() act_gateway_time()
138 {
139 GetListResponseBody {
140 server_id,
141 list_name,
142 value_list
143 }
144 }
145
146 rule obscure_prefix_in_get_list_response() =
147 [0x72] [0x62] [0..=255] [0x65] [0..=255] [0..=255] [0..=255] [0..=255]
148
149 rule list_sml_value() -> Vec<SmlListEntry> =
150 prefix: [0x71..=0x7f]
151 value: single_sml_value() * <{
152 let length = prefix - 0x70;
153 length as usize
154 }>
155 { value }
156
157 rule single_sml_value() -> SmlListEntry =
158 [0x77]
159 object_name: string()
160 status: optional_unsigned()
161 value_time: string()
162 unit: optional_unsigned()
163 scaler: scaler()
164 value: value() sml_value_signature()
165 {
166 SmlListEntry {
167 object_name, status, value_time, unit, scaler, value
168 }
169 }
170
171 rule scaler() -> Option<isize> = optional_signed()
172
173 rule value() -> AnyValue = arbitrary()
174
175 rule sml_value_signature() = [0x01] / string()
176
177 rule arbitrary() -> AnyValue =
178 (v:string() { AnyValue::String(v) }) /
179 (v:signed() { AnyValue::Signed(v as isize) }) /
180 (v:unsigned() { AnyValue::Unsigned(v as usize) })
181
182 pub (crate) rule unsigned() -> usize =
183 prefix: [0x62|0x63|0x64|0x65|0x66|0x67|0x68|0x69]
184 value: (any_number()) * <{
185 let length = prefix - 0x60;
186 length as usize - 1
187 }>
188 {
189 let left_padding = 8+1-(prefix - 0x60) as usize;
190 let mut m = vec![0u8;left_padding];
191 m.append(&mut value.to_vec());
192 let mut rdr = Cursor::new(m);
193 rdr.read_u64::<BigEndian>().unwrap() as usize
194 }
195
196 pub (crate) rule signed() -> isize =
197 prefix: [0x52|0x53|0x54|0x55|0x56|0x57|0x58|0x59]
198 value: (any_number()) * <{
199 let length = prefix - 0x50;
200 length as usize - 1
201 }>
202 {
203 let left_padding = 8+1-(prefix - 0x50) as usize;
204 let pad_byte = if value[0]>=128 { 0xFF } else { 0x00 };
205 let mut m = vec![pad_byte;left_padding];
206 m.append(&mut (value).to_vec());
207 let mut rdr = Cursor::new(m);
208 rdr.read_i64::<BigEndian>().unwrap() as isize
209 }
210
211 rule transaction_id() -> Vec<u8> =
212 string()
213
214 rule group_no() =
215 [0x62] any_number()
216
217 rule abort_on_error() =
218 [0x62] [0x00]
219
220 rule message_checksum() =
221 any_number() any_number() any_number()
222
223 rule any_number() -> u8 =
224 [0..=255]
225
226 rule optional_signed() -> Option<isize> =
227 (v:signed() { Some(v) }) / ([0x01] { None })
228
229 rule optional_unsigned() -> Option<usize> =
230 (v:unsigned() { Some(v) }) / ([0x01] { None })
231
232 rule string() -> Vec<u8> =
233 short_string() / long_string()
234
235 rule short_string() -> Vec<u8> =
236 prefix: [0x01..=0x0f]
237 value: (any_number()) * <{
238 let length = prefix - 0x01;
239 length as usize
240 }>
241 { value }
242
243 rule long_string() -> Vec<u8> =
244 prefix_1: [0x81..=0x83]
245 prefix_2: [0x00..=0x0f]
246 value: any_number() * <{
247 let length = match prefix_1 {
248 0x81 => 14 + prefix_2,
249 0x82 => 30 + prefix_2,
250 0x83 => 46 + prefix_2,
251 _ => unreachable!()
252 };
253 length as usize
254 }>
255 { value }
256 }
257}
258
259#[cfg(test)]
260mod test {
261 use super::*;
262 #[test]
263 pub fn open() {
264 let example_open = vec![
266 0x1b, 0x1b, 0x1b, 0x1b, 0x01, 0x01, 0x01, 0x01, 0x76, 0x05, 0x03, 0x2b, 0x18, 0x0f, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x05, 0x04, 0x03, 0x02, 0x01, 0x0b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
278 0x0a, 0x01, 0x01, 0x63, 0x49, 0x00, 0x00, 0x1b, 0x1b, 0x1b, 0x1b, 0x1a, 0x00, 0x70, 0xb2, ];
287
288 let result = sml_parser::sml_messages(&example_open);
289
290 assert_eq!(
291 result,
292 Ok(SmlMessages {
293 messages: vec![SmlMessageEnvelope::GetOpenResponse(GetOpenResponseBody {
294 server_id: vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a],
295 req_file_id: vec![0x04, 0x03, 0x02, 0x01]
296 })]
297 })
298 )
299 }
300
301 #[test]
302 pub fn get_list_response_body() {
303 let example_list = vec![
305 0x76, 0x05, 0x01, 0xD3, 0xD7, 0xBB, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77, 0x01, 0x0B, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
314 0x0a, 0x07, 0x01, 0x00, 0x62, 0x0A, 0xFF, 0xFF, 0x72, 0x62, 0x01, 0x65, 0x01, 0x8A, 0x4D, 0x15, 0x72, 0x77, 0x07, 0x81, 0x81, 0xC7, 0x82, 0x03,
322 0xFF, 0x01, 0x01, 0x01, 0x01, 0x04, 0x49, 0x53,
328 0x4B, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x00,
332 0xFF, 0x65, 0x00, 0x00, 0x01, 0x82, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x01, 0x01, 0x01, 0x63, 0xC6, 0x12, 0x00, ];
345
346 let result = sml_parser::sml_body(&example_list);
347
348 assert_eq!(
349 result,
350 Ok(SmlMessages {
351 messages: vec![SmlMessageEnvelope::GetListResponse(GetListResponseBody {
352 server_id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
353 list_name: vec![1, 0, 98, 10, 255, 255],
354 value_list: vec![
355 SmlListEntry {
356 object_name: vec![129, 129, 199, 130, 3, 255],
357 status: None,
358 value_time: vec![],
359 unit: None,
360 scaler: None,
361 value: AnyValue::String(vec![73, 83, 75])
362 },
363 SmlListEntry {
364 object_name: vec![1, 0, 1, 8, 0, 255],
365 status: Some(386),
366 value_time: vec![],
367 unit: Some(30),
368 scaler: Some(-1),
369 value: AnyValue::Signed(0)
370 }
371 ]
372 })]
373 })
374 )
375 }
376
377 #[test]
378 pub fn get_close_response() {
379 let example_close = vec![
380 0x1b, 0x1b, 0x1b, 0x1b, 0x01, 0x01, 0x01, 0x01, 0x76, 0x05, 0x03, 0x2b, 0x18, 0x11, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x02, 0x01, 0x71, 0x01, 0x63, 0xfa, 0x36, 0x00, 0x1b, 0x1b, 0x1b, 0x1b, 0x1a, 0x00, 0x70, 0xb2, ];
395 let result = sml_parser::sml_messages(&example_close);
396
397 assert_eq!(
398 result,
399 Ok(SmlMessages {
400 messages: vec![SmlMessageEnvelope::GetCloseResponse]
401 })
402 )
403 }
404
405 #[test]
406 pub fn example_with_exotic_number_types() {
407 let bytes = vec![
408 0x1b, 0x1b, 0x1b, 0x1b, 0x01, 0x01, 0x01, 0x01, 0x76, 0x07, 0x00, 0x11, 0x06, 0x33,
409 0x10, 0x11, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x07,
410 0x00, 0x11, 0x04, 0x5d, 0x05, 0x5b, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x93, 0xa2, 0xc7, 0x01, 0x01, 0x63, 0xc0, 0xd3, 0x00, 0x76, 0x07, 0x00, 0x11, 0x06,
412 0x33, 0x10, 0x12, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77, 0x01, 0x0b,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xa2, 0xc7, 0x07, 0x01, 0x00, 0x62,
414 0x0a, 0xff, 0xff, 0x72, 0x62, 0x01, 0x65, 0x04, 0x5d, 0x00, 0xd1, 0x79, 0x77, 0x07,
415 0x81, 0x81, 0xc7, 0x82, 0x03, 0xff, 0x01, 0x01, 0x01, 0x01, 0x04, 0x45, 0x4d, 0x48,
416 0x01, 0x77, 0x07, 0x01, 0x00, 0x00, 0x00, 0x09, 0xff, 0x01, 0x01, 0x01, 0x01, 0x0b,
417 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xa2, 0xc7, 0x01, 0x77, 0x07, 0x01,
418 0x00, 0x01, 0x08, 0x00, 0xff, 0x64, 0x01, 0x02, 0x82, 0x01, 0x62, 0x1e, 0x52, 0x03,
419 0x56, 0x00, 0x00, 0x00, 0x0e, 0x0d, 0x01, 0x77, 0x07, 0x01, 0x00, 0x02, 0x08, 0x00,
420 0xff, 0x64, 0x01, 0x02, 0x82, 0x01, 0x62, 0x1e, 0x52, 0x03, 0x56, 0x00, 0x00, 0x00,
421 0x14, 0xc1, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x01, 0xff, 0x01, 0x01, 0x62,
422 0x1e, 0x52, 0x03, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x77, 0x07, 0x01, 0x00,
423 0x02, 0x08, 0x01, 0xff, 0x01, 0x01, 0x62, 0x1e, 0x52, 0x03, 0x56, 0x00, 0x00, 0x00,
424 0x14, 0xc1, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x02, 0xff, 0x01, 0x01, 0x62,
425 0x1e, 0x52, 0x03, 0x56, 0x00, 0x00, 0x00, 0x0e, 0x0d, 0x01, 0x77, 0x07, 0x01, 0x00,
426 0x02, 0x08, 0x02, 0xff, 0x01, 0x01, 0x62, 0x1e, 0x52, 0x03, 0x56, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x01, 0x77, 0x07, 0x81, 0x81, 0xc7, 0x82, 0x05, 0xff, 0x01, 0x01, 0x01,
428 0x01, 0x83, 0x02, 0x65, 0xdc, 0xe7, 0x5e, 0xa7, 0x7a, 0xdf, 0x65, 0x1c, 0xc3, 0xc3,
429 0xde, 0x43, 0xe2, 0xf6, 0xb2, 0x72, 0x0d, 0x78, 0x0b, 0xd2, 0xf0, 0x54, 0xa4, 0xc7,
430 0x8c, 0xc3, 0x8c, 0xfc, 0x42, 0xb0, 0x6e, 0xa5, 0x27, 0xbf, 0xe0, 0xfc, 0x51, 0x4a,
431 0xb8, 0x6f, 0x83, 0x03, 0x0f, 0x54, 0x1b, 0x4f, 0x87, 0x01, 0x01, 0x01, 0x63, 0xaa,
432 0x28, 0x00, 0x76, 0x07, 0x00, 0x11, 0x06, 0x33, 0x10, 0x15, 0x62, 0x00, 0x62, 0x00,
433 0x72, 0x63, 0x02, 0x01, 0x71, 0x01, 0x63, 0x0b, 0x74, 0x00, 0x1b, 0x1b, 0x1b, 0x1b,
434 0x1a, 0x00, 0x0b, 0xc6,
435 ];
436 let result = sml_parser::sml_messages(&bytes);
437
438 assert_eq!(result.is_ok(), true)
439 }
440
441 #[test]
442 pub fn reads_8_bit_signed() {
443 let bytes = vec![0x52, 0x02];
444
445 let result = sml_parser::signed(&bytes);
446 assert_eq!(result, Ok(2isize));
447 }
448
449 #[test]
450 pub fn reads_negative_8_bit_signed() {
451 let bytes = vec![0x52, 0xFE];
452
453 let result = sml_parser::signed(&bytes);
454 assert_eq!(result, Ok(-2isize));
455 }
456
457 #[test]
458 pub fn reads_32_bit_signed() {
459 let bytes = vec![0x55, 0x00, 0x00, 0x00, 0x01];
460
461 let result = sml_parser::signed(&bytes);
462 assert_eq!(result, Ok(1isize));
463 }
464
465 #[test]
466 pub fn reads_negative_32_bit_signed() {
467 let bytes = vec![0x55, 0xFF, 0xFF, 0xFF, 0xFF];
468
469 let result = sml_parser::signed(&bytes);
470 assert_eq!(result, Ok(-1isize));
471 }
472
473 #[test]
474 pub fn reads_positive_56_bit_unsigned() {
475 let bytes = vec![0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01];
476
477 let result = sml_parser::unsigned(&bytes);
478 assert_eq!(result, Ok(1usize));
479 }
480
481 #[test]
482 pub fn reads_positive_56_bit_signed() {
483 let bytes = vec![0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01];
484
485 let result = sml_parser::signed(&bytes);
486 assert_eq!(result, Ok(1isize));
487 }
488
489 #[test]
490
491 pub fn reads_negative_56_bit_signed() {
492 let bytes = vec![0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
493
494 let result = sml_parser::signed(&bytes);
495 assert_eq!(result, Ok(-1isize));
496 }
497
498 #[test]
499 pub fn iskra_mt631() {
500 let bytes = vec![
501 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01, 0x76, 0x05, 0x13, 0x31, 0xB4, 0xC4,
502 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x05, 0x06, 0x65,
503 0xE6, 0xEC, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x72,
504 0x62, 0x01, 0x65, 0x06, 0x65, 0xE8, 0xA5, 0x62, 0x01, 0x63, 0xEB, 0x95, 0x00, 0x76,
505 0x05, 0x13, 0x31, 0xB4, 0xC5, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77,
506 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x07, 0x01,
507 0x00, 0x62, 0x0A, 0xFF, 0xFF, 0x72, 0x62, 0x01, 0x65, 0x06, 0x65, 0xE8, 0xA5, 0x76,
508 0x77, 0x07, 0x01, 0x00, 0x60, 0x32, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x49,
509 0x53, 0x4B, 0x01, 0x77, 0x07, 0x01, 0x00, 0x60, 0x01, 0x00, 0xFF, 0x01, 0x01, 0x01,
510 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x01, 0x77,
511 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x1C, 0x00, 0x04, 0x01, 0x62,
512 0x1E, 0x52, 0xFF, 0x65, 0x0A, 0x07, 0x44, 0xF5, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01,
513 0x08, 0x01, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x63, 0xB3, 0x63, 0x01, 0x77,
514 0x07, 0x01, 0x00, 0x01, 0x08, 0x02, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x65,
515 0x0A, 0x06, 0x91, 0x92, 0x01, 0x77, 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01,
516 0x01, 0x62, 0x1B, 0x52, 0x00, 0x52, 0x00, 0x01, 0x01, 0x01, 0x63, 0xC5, 0x24, 0x00,
517 0x76, 0x05, 0x13, 0x31, 0xB4, 0xC6, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x02, 0x01,
518 0x71, 0x01, 0x63, 0x98, 0x98, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1A, 0x00, 0x1A, 0xB1,
519 ];
520
521 let bytes2 = vec![
522 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01, 0x76, 0x05, 0x13, 0x31, 0xB4, 0xC7,
523 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x05, 0x06, 0x65,
524 0xE6, 0xED, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x72,
525 0x62, 0x01, 0x65, 0x06, 0x65, 0xE8, 0xA6, 0x62, 0x01, 0x63, 0x9B, 0x24, 0x00, 0x76,
526 0x05, 0x13, 0x31, 0xB4, 0xC8, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77,
527 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x07, 0x01,
528 0x00, 0x62, 0x0A, 0xFF, 0xFF, 0x72, 0x62, 0x01, 0x65, 0x06, 0x65, 0xE8, 0xA6, 0x76,
529 0x77, 0x07, 0x01, 0x00, 0x60, 0x32, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x49,
530 0x53, 0x4B, 0x01, 0x77, 0x07, 0x01, 0x00, 0x60, 0x01, 0x00, 0xFF, 0x01, 0x01, 0x01,
531 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x01, 0x77,
532 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x1C, 0x00, 0x04, 0x01, 0x62,
533 0x1E, 0x52, 0xFF, 0x65, 0x0A, 0x07, 0x44, 0xF5, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01,
534 0x08, 0x01, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x63, 0xB3, 0x63, 0x01, 0x77,
535 0x07, 0x01, 0x00, 0x01, 0x08, 0x02, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x65,
536 0x0A, 0x06, 0x91, 0x92, 0x01, 0x77, 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01,
537 0x01, 0x62, 0x1B, 0x52, 0x00, 0x52, 0x00, 0x01, 0x01, 0x01, 0x63, 0x59, 0xD0, 0x00,
538 0x76, 0x05, 0x13, 0x31, 0xB4, 0xC9, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x02, 0x01,
539 0x71, 0x01, 0x63, 0xD4, 0x84, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1A, 0x00, 0x28, 0xCE,
540 ];
541
542 let bytes3 = vec![
543 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01, 0x76, 0x05, 0x13, 0x31, 0xB4, 0xCA,
544 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x05, 0x06, 0x65,
545 0xE6, 0xEE, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x72,
546 0x62, 0x01, 0x65, 0x06, 0x65, 0xE8, 0xA7, 0x62, 0x01, 0x63, 0x6E, 0xE2, 0x00, 0x76,
547 0x05, 0x13, 0x31, 0xB4, 0xCB, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77,
548 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x07, 0x01,
549 0x00, 0x62, 0x0A, 0xFF, 0xFF, 0x72, 0x62, 0x01, 0x65, 0x06, 0x65, 0xE8, 0xA7, 0x76,
550 0x77, 0x07, 0x01, 0x00, 0x60, 0x32, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x49,
551 0x53, 0x4B, 0x01, 0x77, 0x07, 0x01, 0x00, 0x60, 0x01, 0x00, 0xFF, 0x01, 0x01, 0x01,
552 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x01, 0x77,
553 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x1C, 0x00, 0x04, 0x01, 0x62,
554 0x1E, 0x52, 0xFF, 0x65, 0x0A, 0x07, 0x44, 0xF5, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01,
555 0x08, 0x01, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x63, 0xB3, 0x63, 0x01, 0x77,
556 0x07, 0x01, 0x00, 0x01, 0x08, 0x02, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x65,
557 0x0A, 0x06, 0x91, 0x92, 0x01, 0x77, 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01,
558 0x01, 0x62, 0x1B, 0x52, 0x00, 0x52, 0x00, 0x01, 0x01, 0x01, 0x63, 0x38, 0x51, 0x00,
559 0x76, 0x05, 0x13, 0x31, 0xB4, 0xCC, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x02, 0x01,
560 0x71, 0x01, 0x63, 0x10, 0x8F, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1A, 0x00, 0x58, 0xD8,
561 ];
562
563 let bytes4 = vec![
564 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01, 0x76, 0x05, 0x13, 0x31, 0xB4, 0xCD,
565 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x05, 0x06, 0x65,
566 0xE6, 0xEF, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x72,
567 0x62, 0x01, 0x65, 0x06, 0x65, 0xE8, 0xA8, 0x62, 0x01, 0x63, 0xBF, 0x4D, 0x00, 0x76,
568 0x05, 0x13, 0x31, 0xB4, 0xCE, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77,
569 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x07, 0x01,
570 0x00, 0x62, 0x0A, 0xFF, 0xFF, 0x72, 0x62, 0x01, 0x65, 0x06, 0x65, 0xE8, 0xA8, 0x76,
571 0x77, 0x07, 0x01, 0x00, 0x60, 0x32, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x49,
572 0x53, 0x4B, 0x01, 0x77, 0x07, 0x01, 0x00, 0x60, 0x01, 0x00, 0xFF, 0x01, 0x01, 0x01,
573 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x01, 0x77,
574 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x1C, 0x00, 0x04, 0x01, 0x62,
575 0x1E, 0x52, 0xFF, 0x65, 0x0A, 0x07, 0x44, 0xF5, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01,
576 0x08, 0x01, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x63, 0xB3, 0x63, 0x01, 0x77,
577 0x07, 0x01, 0x00, 0x01, 0x08, 0x02, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x65,
578 0x0A, 0x06, 0x91, 0x92, 0x01, 0x77, 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01,
579 0x01, 0x62, 0x1B, 0x52, 0x00, 0x52, 0x00, 0x01, 0x01, 0x01, 0x63, 0xAB, 0x25, 0x00,
580 0x76, 0x05, 0x13, 0x31, 0xB4, 0xCF, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x02, 0x01,
581 0x71, 0x01, 0x63, 0xA3, 0x71, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1A, 0x00, 0x1B, 0xC4,
582 ];
583
584 let result = sml_parser::sml_messages(&bytes);
585 let result2 = sml_parser::sml_messages(&bytes2);
586 let result3 = sml_parser::sml_messages(&bytes3);
587 let result4 = sml_parser::sml_messages(&bytes4);
588
589 assert!(result.is_ok());
590 assert!(result2.is_ok());
591 assert!(result3.is_ok());
592 assert!(result4.is_ok());
593 }
594
595 #[test]
596 pub fn iskra_mt631_without_pin() {
597 let bytes = vec![
598 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01, 0x76, 0x05, 0x13, 0x00, 0x88, 0x91,
599 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x05, 0x06, 0x55,
600 0x82, 0xDB, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x72,
601 0x62, 0x01, 0x65, 0x06, 0x55, 0x84, 0x8E, 0x62, 0x01, 0x63, 0xA4, 0xFF, 0x00, 0x76,
602 0x05, 0x13, 0x00, 0x88, 0x92, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77,
603 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x07, 0x01,
604 0x00, 0x62, 0x0A, 0xFF, 0xFF, 0x72, 0x62, 0x01, 0x65, 0x06, 0x55, 0x84, 0x8E, 0x75,
605 0x77, 0x07, 0x01, 0x00, 0x60, 0x32, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x49,
606 0x53, 0x4B, 0x01, 0x77, 0x07, 0x01, 0x00, 0x60, 0x01, 0x00, 0xFF, 0x01, 0x01, 0x01,
607 0x01, 0x0B, 0x0A, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x54, 0xA9, 0x5F, 0x01, 0x77,
608 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x1C, 0x00, 0x04, 0x01, 0x62,
609 0x1E, 0x52, 0x03, 0x63, 0x41, 0x92, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x01,
610 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0x03, 0x62, 0x04, 0x01, 0x77, 0x07, 0x01, 0x00,
611 0x01, 0x08, 0x02, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0x03, 0x63, 0x41, 0x8E, 0x01,
612 0x01, 0x01, 0x63, 0x52, 0x4D, 0x00, 0x76, 0x05, 0x13, 0x00, 0x88, 0x93, 0x62, 0x00,
613 0x62, 0x00, 0x72, 0x63, 0x02, 0x01, 0x71, 0x01, 0x63, 0x33, 0xF4, 0x00, 0x00, 0x00,
614 0x1B, 0x1B, 0x1B, 0x1B, 0x1A, 0x02, 0x40, 0x0D,
615 ];
616 let result = sml_parser::sml_messages(&bytes);
617 assert!(result.is_ok());
618 }
619}