1#![no_std]
137
138pub mod error;
139pub mod field;
140pub mod packet;
141pub mod payload;
142pub mod types;
143
144#[cfg(test)]
145mod tests {
146 use crate::{
147 packet::Packet,
148 payload::Repr,
149 types::{ClientId, MessageId, MessageType, RequestId, ReturnCode},
150 };
151
152 #[test]
153 fn test_deconstruct_without_payload() {
154 let raw_packet: [u8; 16] = [
155 0x12, 0x34, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, ];
163
164 let packet = Packet::new_checked(&raw_packet[..]).unwrap();
165 let repr = Repr::parse(&packet).unwrap();
166
167 assert_eq!(
168 repr.message_id,
169 MessageId {
170 service_id: 0x1234,
171 method_id: 0x0001,
172 }
173 );
174 assert_eq!(repr.length, 8); assert_eq!(
177 repr.request_id,
178 RequestId {
179 client_id: ClientId {
180 client_id_prefix: 0x01,
181 client_id: 0x02,
182 },
183 session_id: 0x0001,
184 }
185 );
186 assert_eq!(repr.protocol_version, 0x01);
187 assert_eq!(repr.interface_version, 0x01);
188 assert_eq!(repr.message_type, MessageType::Request);
189 assert_eq!(repr.return_code, ReturnCode::E_OK);
190 assert_eq!(repr.data, &[]);
191 }
192
193 #[test]
194 fn test_deconstruct_with_payload() {
195 let raw_packet: [u8; 20] = [
196 0x12, 0x34, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, ];
205
206 let packet = Packet::new_checked(&raw_packet[..]).unwrap();
207 let repr = Repr::parse(&packet).unwrap();
208
209 assert_eq!(
210 repr.message_id,
211 MessageId {
212 service_id: 0x1234,
213 method_id: 0x0001,
214 }
215 );
216 assert_eq!(repr.length, 12); assert_eq!(
219 repr.request_id,
220 RequestId {
221 client_id: ClientId {
222 client_id_prefix: 0x01,
223 client_id: 0x02,
224 },
225 session_id: 0x0001,
226 }
227 );
228 assert_eq!(repr.protocol_version, 0x01);
229 assert_eq!(repr.interface_version, 0x01);
230 assert_eq!(repr.message_type, MessageType::Request);
231 assert_eq!(repr.return_code, ReturnCode::E_OK);
232 assert_eq!(repr.data, &[0xDE, 0xAD, 0xBE, 0xEF]);
233 }
234
235 #[test]
236 fn test_repr_parse() {
237 let raw_packet: [u8; 16] = [
238 0x12, 0x34, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, ];
246
247 let packet = Packet::new_checked(&raw_packet[..]).unwrap();
248 let repr = Repr::parse(&packet).unwrap();
249
250 assert_eq!(
251 repr,
252 Repr::new(
253 MessageId {
254 service_id: 0x1234,
255 method_id: 0x0001,
256 },
257 RequestId {
258 client_id: ClientId {
259 client_id_prefix: 0x01,
260 client_id: 0x02,
261 },
262 session_id: 0x0001,
263 },
264 0x01,
265 0x01,
266 MessageType::Request,
267 ReturnCode::E_OK,
268 &[],
269 )
270 );
271 }
272
273 #[test]
274 fn test_repr_emit() {
275 let repr = Repr::new(
276 MessageId {
277 service_id: 0x1234,
278 method_id: 0x0001,
279 },
280 RequestId {
281 client_id: ClientId {
282 client_id_prefix: 0x01,
283 client_id: 0x02,
284 },
285 session_id: 0x0001,
286 },
287 0x01,
288 0x01,
289 MessageType::Request,
290 ReturnCode::E_OK,
291 &[0xDE, 0xAD, 0xBE, 0xEF],
292 );
293 let mut buffer = [0u8; 20];
294 let mut packet = Packet::new_unchecked(&mut buffer);
295 repr.emit(&mut packet);
296 let expected: [u8; 20] = [
297 0x12, 0x34, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, ];
306 assert_eq!(&buffer, &expected);
307 }
308
309 fn round_trip_test(repr: Repr) {
310 let mut buffer = [0u8; 1024];
311 {
312 let mut packet = Packet::new_unchecked(&mut buffer);
313 repr.emit(&mut packet);
314 }
315 let packet = Packet::new_checked(&buffer).unwrap();
316 let parsed_repr = Repr::parse(&packet).unwrap();
317 assert_eq!(parsed_repr, repr);
318 }
319
320 fn round_trip_test_with_bytes(repr: Repr, expected_bytes: &[u8]) {
321 let mut buffer = [0u8; 1024]; {
323 let mut packet = Packet::new_unchecked(&mut buffer[..expected_bytes.len()]);
324 repr.emit(&mut packet);
325 }
326
327 assert_eq!(&buffer[..expected_bytes.len()], expected_bytes);
328
329 let packet = Packet::new_checked(&buffer[..expected_bytes.len()]).unwrap();
330 let parsed_repr = Repr::parse(&packet).unwrap();
331 assert_eq!(repr, parsed_repr);
332 }
333
334 #[test]
335 fn test_repr_round_trip_request() {
336 let repr = Repr {
337 message_id: MessageId {
338 service_id: 0x1234,
339 method_id: 0x0001,
340 },
341 length: 12,
342 request_id: RequestId {
343 client_id: ClientId {
344 client_id_prefix: 0x01,
345 client_id: 0x02,
346 },
347 session_id: 0x0001,
348 },
349 protocol_version: 0x01,
350 interface_version: 0x01,
351 message_type: MessageType::Request,
352 return_code: ReturnCode::E_OK,
353 data: &[0xDE, 0xAD, 0xBE, 0xEF],
354 };
355 round_trip_test(repr);
356 round_trip_test_with_bytes(
357 repr,
358 &[
359 0x12, 0x34, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, ],
369 );
370 }
371
372 #[test]
373 fn test_repr_round_trip_request_no_return() {
374 let repr = Repr {
375 message_id: MessageId {
376 service_id: 0x1234,
377 method_id: 0x0001,
378 },
379 length: 10,
380 request_id: RequestId {
381 client_id: ClientId {
382 client_id_prefix: 0x01,
383 client_id: 0x02,
384 },
385 session_id: 0x0001,
386 },
387 protocol_version: 0x01,
388 interface_version: 0x01,
389 message_type: MessageType::RequestNoReturn,
390 return_code: ReturnCode::E_OK,
391 data: &[0xAA, 0xBB],
392 };
393 round_trip_test(repr);
394 }
395
396 #[test]
397 fn test_repr_round_trip_notification() {
398 let repr = Repr {
399 message_id: MessageId {
400 service_id: 0x5678,
401 method_id: 0x8001,
402 },
403 length: 0,
404 request_id: RequestId {
405 client_id: ClientId {
406 client_id_prefix: 0xFF,
407 client_id: 0xFF,
408 },
409 session_id: 0x0001,
410 },
411 protocol_version: 0x01,
412 interface_version: 0x01,
413 message_type: MessageType::Notification,
414 return_code: ReturnCode::E_OK,
415 data: &[],
416 };
417 round_trip_test(repr);
418 }
419
420 #[test]
421 fn test_repr_round_trip_response() {
422 let repr = Repr {
423 message_id: MessageId {
424 service_id: 0x1234,
425 method_id: 0x0001,
426 },
427 length: 16,
428 request_id: RequestId {
429 client_id: ClientId {
430 client_id_prefix: 0x01,
431 client_id: 0x02,
432 },
433 session_id: 0x0001,
434 },
435 protocol_version: 0x01,
436 interface_version: 0x01,
437 message_type: MessageType::Response,
438 return_code: ReturnCode::E_OK,
439 data: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77],
440 };
441 round_trip_test(repr);
442 }
443
444 #[test]
445 fn test_repr_round_trip_error() {
446 let repr = Repr {
447 message_id: MessageId {
448 service_id: 0x1234,
449 method_id: 0x0001,
450 },
451 length: 0,
452 request_id: RequestId {
453 client_id: ClientId {
454 client_id_prefix: 0x01,
455 client_id: 0x02,
456 },
457 session_id: 0x0001,
458 },
459 protocol_version: 0x01,
460 interface_version: 0x01,
461 message_type: MessageType::Error,
462 return_code: ReturnCode::E_NOT_OK,
463 data: &[],
464 };
465 round_trip_test(repr);
466 }
467
468 #[test]
469 fn test_repr_round_trip_tp_request() {
470 let repr = Repr {
471 message_id: MessageId {
472 service_id: 0xABCD,
473 method_id: 0x0042,
474 },
475 length: 9,
476 request_id: RequestId {
477 client_id: ClientId {
478 client_id_prefix: 0x10,
479 client_id: 0x20,
480 },
481 session_id: 0x1234,
482 },
483 protocol_version: 0x01,
484 interface_version: 0x02,
485 message_type: MessageType::TPRequest,
486 return_code: ReturnCode::E_OK,
487 data: &[0xFF],
488 };
489 round_trip_test(repr);
490 }
491
492 #[test]
493 fn test_repr_round_trip_tp_request_no_return() {
494 let repr = Repr {
495 message_id: MessageId {
496 service_id: 0x0001,
497 method_id: 0x0002,
498 },
499 length: 11,
500 request_id: RequestId {
501 client_id: ClientId {
502 client_id_prefix: 0x00,
503 client_id: 0x01,
504 },
505 session_id: 0x0002,
506 },
507 protocol_version: 0x01,
508 interface_version: 0x01,
509 message_type: MessageType::TPRequestNoReturn,
510 return_code: ReturnCode::E_OK,
511 data: &[0x01, 0x02, 0x03],
512 };
513 round_trip_test(repr);
514 }
515
516 #[test]
517 fn test_repr_round_trip_tp_notification() {
518 let repr = Repr {
519 message_id: MessageId {
520 service_id: 0x9999,
521 method_id: 0x8888,
522 },
523 length: 10,
524 request_id: RequestId {
525 client_id: ClientId {
526 client_id_prefix: 0x00,
527 client_id: 0x00,
528 },
529 session_id: 0x0000,
530 },
531 protocol_version: 0x01,
532 interface_version: 0x01,
533 message_type: MessageType::TPNotification,
534 return_code: ReturnCode::E_OK,
535 data: &[0xCA, 0xFE],
536 };
537 round_trip_test(repr);
538 }
539
540 #[test]
541 fn test_repr_round_trip_tp_response() {
542 let repr = Repr {
543 message_id: MessageId {
544 service_id: 0x4321,
545 method_id: 0x8765,
546 },
547 length: 13,
548 request_id: RequestId {
549 client_id: ClientId {
550 client_id_prefix: 0xAA,
551 client_id: 0xBB,
552 },
553 session_id: 0xCCDD,
554 },
555 protocol_version: 0x01,
556 interface_version: 0x05,
557 message_type: MessageType::TPResponse,
558 return_code: ReturnCode::E_OK,
559 data: &[0x10, 0x20, 0x30, 0x40, 0x50],
560 };
561 round_trip_test(repr);
562 }
563
564 #[test]
565 fn test_repr_round_trip_tp_error() {
566 let repr = Repr {
567 message_id: MessageId {
568 service_id: 0xFFFF,
569 method_id: 0xFFFF,
570 },
571 length: 0,
572 request_id: RequestId {
573 client_id: ClientId {
574 client_id_prefix: 0xFF,
575 client_id: 0xFE,
576 },
577 session_id: 0xFFFE,
578 },
579 protocol_version: 0x01,
580 interface_version: 0x01,
581 message_type: MessageType::TPError,
582 return_code: ReturnCode::E_TIMEOUT,
583 data: &[],
584 };
585 round_trip_test(repr);
586 }
587
588 #[test]
590 fn test_repr_round_trip_unknown_service() {
591 let repr = Repr {
592 message_id: MessageId {
593 service_id: 0x1234,
594 method_id: 0x0001,
595 },
596 length: 0,
597 request_id: RequestId {
598 client_id: ClientId {
599 client_id_prefix: 0x01,
600 client_id: 0x02,
601 },
602 session_id: 0x0001,
603 },
604 protocol_version: 0x01,
605 interface_version: 0x01,
606 message_type: MessageType::Error,
607 return_code: ReturnCode::E_UNKNOWN_SERVICE,
608 data: &[],
609 };
610 round_trip_test(repr);
611 }
612
613 #[test]
614 fn test_repr_round_trip_unknown_method() {
615 let repr = Repr {
616 message_id: MessageId {
617 service_id: 0x1234,
618 method_id: 0x9999,
619 },
620 length: 0,
621 request_id: RequestId {
622 client_id: ClientId {
623 client_id_prefix: 0x01,
624 client_id: 0x02,
625 },
626 session_id: 0x0001,
627 },
628 protocol_version: 0x01,
629 interface_version: 0x01,
630 message_type: MessageType::Error,
631 return_code: ReturnCode::E_UNKNOWN_METHOD,
632 data: &[],
633 };
634 round_trip_test(repr);
635 }
636
637 #[test]
638 fn test_repr_round_trip_not_ready() {
639 let repr = Repr {
640 message_id: MessageId {
641 service_id: 0x1234,
642 method_id: 0x0001,
643 },
644 length: 0,
645 request_id: RequestId {
646 client_id: ClientId {
647 client_id_prefix: 0x01,
648 client_id: 0x02,
649 },
650 session_id: 0x0001,
651 },
652 protocol_version: 0x01,
653 interface_version: 0x01,
654 message_type: MessageType::Error,
655 return_code: ReturnCode::E_NOT_READY,
656 data: &[],
657 };
658 round_trip_test(repr);
659 }
660
661 #[test]
662 fn test_repr_round_trip_wrong_protocol_version() {
663 let repr = Repr {
664 message_id: MessageId {
665 service_id: 0x1234,
666 method_id: 0x0001,
667 },
668 length: 0,
669 request_id: RequestId {
670 client_id: ClientId {
671 client_id_prefix: 0x01,
672 client_id: 0x02,
673 },
674 session_id: 0x0001,
675 },
676 protocol_version: 0x01,
677 interface_version: 0x01,
678 message_type: MessageType::Error,
679 return_code: ReturnCode::E_WRONG_PROTOCOL_VERSION,
680 data: &[],
681 };
682 round_trip_test(repr);
683 }
684
685 #[test]
686 fn test_repr_round_trip_wrong_interface_version() {
687 let repr = Repr {
688 message_id: MessageId {
689 service_id: 0x1234,
690 method_id: 0x0001,
691 },
692 length: 0,
693 request_id: RequestId {
694 client_id: ClientId {
695 client_id_prefix: 0x01,
696 client_id: 0x02,
697 },
698 session_id: 0x0001,
699 },
700 protocol_version: 0x01,
701 interface_version: 0x01,
702 message_type: MessageType::Error,
703 return_code: ReturnCode::E_WRONG_INTERFACE_VERSION,
704 data: &[],
705 };
706 round_trip_test(repr);
707 }
708
709 #[test]
710 fn test_repr_round_trip_malformed_message() {
711 let repr = Repr {
712 message_id: MessageId {
713 service_id: 0x1234,
714 method_id: 0x0001,
715 },
716 length: 0,
717 request_id: RequestId {
718 client_id: ClientId {
719 client_id_prefix: 0x01,
720 client_id: 0x02,
721 },
722 session_id: 0x0001,
723 },
724 protocol_version: 0x01,
725 interface_version: 0x01,
726 message_type: MessageType::Error,
727 return_code: ReturnCode::E_MALFORMED_MESSAGE,
728 data: &[],
729 };
730 round_trip_test(repr);
731 }
732
733 #[test]
734 fn test_repr_round_trip_wrong_message_type() {
735 let repr = Repr {
736 message_id: MessageId {
737 service_id: 0x1234,
738 method_id: 0x0001,
739 },
740 length: 0,
741 request_id: RequestId {
742 client_id: ClientId {
743 client_id_prefix: 0x01,
744 client_id: 0x02,
745 },
746 session_id: 0x0001,
747 },
748 protocol_version: 0x01,
749 interface_version: 0x01,
750 message_type: MessageType::Error,
751 return_code: ReturnCode::E_WRONG_MESSAGE_TYPE,
752 data: &[],
753 };
754 round_trip_test(repr);
755 }
756
757 #[test]
758 fn test_repr_round_trip_e2e_errors() {
759 let repr = Repr {
761 message_id: MessageId {
762 service_id: 0x1234,
763 method_id: 0x0001,
764 },
765 length: 0,
766 request_id: RequestId {
767 client_id: ClientId {
768 client_id_prefix: 0x01,
769 client_id: 0x02,
770 },
771 session_id: 0x0001,
772 },
773 protocol_version: 0x01,
774 interface_version: 0x01,
775 message_type: MessageType::Error,
776 return_code: ReturnCode::E_E2E_REPEATED,
777 data: &[],
778 };
779 round_trip_test(repr);
780
781 let repr = Repr {
783 return_code: ReturnCode::E_E2E_WRONG_SEQUENCE,
784 ..repr
785 };
786 round_trip_test(repr);
787
788 let repr = Repr {
790 return_code: ReturnCode::E_E2E,
791 ..repr
792 };
793 round_trip_test(repr);
794
795 let repr = Repr {
797 return_code: ReturnCode::E_E2E_NOT_AVAILABLE,
798 ..repr
799 };
800 round_trip_test(repr);
801
802 let repr = Repr {
804 return_code: ReturnCode::E_E2E_NO_NEW_DATA,
805 ..repr
806 };
807 round_trip_test(repr);
808 }
809
810 #[test]
811 fn test_repr_round_trip_reserved_someip_error() {
812 let repr = Repr {
814 message_id: MessageId {
815 service_id: 0x1234,
816 method_id: 0x0001,
817 },
818 length: 0,
819 request_id: RequestId {
820 client_id: ClientId {
821 client_id_prefix: 0x01,
822 client_id: 0x02,
823 },
824 session_id: 0x0001,
825 },
826 protocol_version: 0x01,
827 interface_version: 0x01,
828 message_type: MessageType::Error,
829 return_code: ReturnCode::from_u8(0x10).unwrap(),
830 data: &[],
831 };
832 round_trip_test(repr);
833
834 let repr = Repr {
835 return_code: ReturnCode::from_u8(0x1F).unwrap(),
836 ..repr
837 };
838 round_trip_test(repr);
839 }
840
841 #[test]
842 fn test_repr_round_trip_service_method_error() {
843 let repr = Repr {
845 message_id: MessageId {
846 service_id: 0x1234,
847 method_id: 0x0001,
848 },
849 length: 0,
850 request_id: RequestId {
851 client_id: ClientId {
852 client_id_prefix: 0x01,
853 client_id: 0x02,
854 },
855 session_id: 0x0001,
856 },
857 protocol_version: 0x01,
858 interface_version: 0x01,
859 message_type: MessageType::Error,
860 return_code: ReturnCode::from_u8(0x20).unwrap(),
861 data: &[],
862 };
863 round_trip_test(repr);
864
865 let repr = Repr {
866 return_code: ReturnCode::from_u8(0x42).unwrap(),
867 ..repr
868 };
869 round_trip_test(repr);
870
871 let repr = Repr {
872 return_code: ReturnCode::from_u8(0x5E).unwrap(),
873 ..repr
874 };
875 round_trip_test(repr);
876 }
877
878 #[test]
879 fn test_return_code_public_api() {
880 let ok = ReturnCode::E_OK;
882 assert!(ok.is_ok());
883 assert!(!ok.is_reserved_someip());
884 assert!(!ok.is_reserved_service_method());
885 assert_eq!(ok.as_u8(), 0x00);
886
887 let reserved_someip = ReturnCode::ReservedSomeIP(0x15);
889 assert!(!reserved_someip.is_ok());
890 assert!(reserved_someip.is_reserved_someip());
891 assert!(!reserved_someip.is_reserved_service_method());
892 assert_eq!(reserved_someip.as_u8(), 0x15);
893
894 let reserved_service = ReturnCode::ReservedServiceMethod(0x42);
896 assert!(!reserved_service.is_ok());
897 assert!(!reserved_service.is_reserved_someip());
898 assert!(reserved_service.is_reserved_service_method());
899 assert_eq!(reserved_service.as_u8(), 0x42);
900
901 match ReturnCode::from_u8(0x10).unwrap() {
903 ReturnCode::ReservedSomeIP(code) => assert_eq!(code, 0x10),
904 _ => panic!("Expected ReservedSomeIP variant"),
905 }
906
907 match ReturnCode::from_u8(0x20).unwrap() {
908 ReturnCode::ReservedServiceMethod(code) => assert_eq!(code, 0x20),
909 _ => panic!("Expected ReservedServiceMethod variant"),
910 }
911
912 }
915}