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