@@ -505,18 +505,15 @@ SERARD_PRIVATE bool rxTryParseHeader(const uint8_t* const payloa
505505/// Returns <0 on error. The transfer shall be discarded and the error code returned to the user.
506506/// Returns 0 if the header is invalid or not subscribed to. The transfer shall be silently discarded.
507507/// Returns 1 if the header is valid and should be processed further.
508- SERARD_PRIVATE int8_t rxValidateHeader (struct SerardRx * const ins ,
509- struct SerardReassembler * const reassembler ,
510- struct SerardRxTransfer * const out_transfer )
508+ SERARD_PRIVATE int8_t rxValidateHeader (struct SerardRx * const ins , struct SerardReassembler * const reassembler )
511509{
512510 SERARD_ASSERT (ins != NULL );
513511 SERARD_ASSERT (reassembler != NULL );
514- SERARD_ASSERT (out_transfer != NULL );
515512 SERARD_ASSERT (reassembler -> counter == (HEADER_SIZE - 1 ));
516513
517514 int8_t ret = 0 ;
518515
519- struct SerardTransferMetadata * const metadata = & out_transfer -> metadata ;
516+ struct SerardTransferMetadata * const metadata = & reassembler -> metadata ;
520517 SerardNodeID destination_node_id = SERARD_NODE_ID_UNSET ;
521518 if (rxTryParseHeader (reassembler -> header , metadata , & destination_node_id ))
522519 {
@@ -547,20 +544,19 @@ SERARD_PRIVATE int8_t rxValidateHeader(struct SerardRx* const ins,
547544 // even though it is not included in the final payload size.
548545 const size_t extent = sub -> extent + TRANSFER_CRC_SIZE_BYTES ;
549546 SERARD_ASSERT (extent > 0 );
550- reassembler -> max_payload_size = extent ;
551547
552548 void * const payload = ins -> memory_payload .allocate (ins -> memory_payload .user_reference , extent );
553549 if (payload != NULL )
554550 {
555- out_transfer -> payload = payload ;
556- out_transfer -> payload_extent = extent ;
557- ret = 1 ;
551+ reassembler -> payload = payload ;
552+ reassembler -> payload_extent = extent ;
553+ ret = 1 ;
558554 }
559555 else
560556 {
561- out_transfer -> payload = NULL ;
562- out_transfer -> payload_extent = 0 ;
563- ret = - SERARD_ERROR_MEMORY ;
557+ reassembler -> payload = NULL ;
558+ reassembler -> payload_extent = 0 ;
559+ ret = - SERARD_ERROR_MEMORY ;
564560 }
565561 }
566562 else
@@ -624,8 +620,7 @@ SERARD_PRIVATE bool rxSessionUpdate(struct SerardRx* const ins,
624620// TODO: test this
625621SERARD_PRIVATE int8_t rxAcceptTransfer (struct SerardRx * const ins ,
626622 struct SerardReassembler * const reassembler ,
627- struct SerardRxTransfer * const transfer ,
628- const uint8_t redundant_iface_index )
623+ struct SerardRxTransfer * const transfer )
629624{
630625 SERARD_ASSERT (ins != NULL );
631626 SERARD_ASSERT (reassembler != NULL );
@@ -637,7 +632,7 @@ SERARD_PRIVATE int8_t rxAcceptTransfer(struct SerardRx* const ins,
637632 // FIXME: maybe we can just use the out_transfer->size to track the counter?
638633 const size_t payload_size = reassembler -> counter - HEADER_SIZE ;
639634 TransferCRC payload_crc = TRANSFER_CRC_INITIAL ;
640- payload_crc = transferCRCAdd (payload_crc , payload_size , transfer -> payload );
635+ payload_crc = transferCRCAdd (payload_crc , payload_size , reassembler -> payload );
641636 payload_crc = payload_crc ^ TRANSFER_CRC_OUTPUT_XOR ;
642637 bool valid = payload_crc == TRANSFER_CRC_RESIDUE_AFTER_OUTPUT_XOR ;
643638
@@ -714,13 +709,33 @@ SERARD_PRIVATE int8_t rxAcceptByte(struct SerardRx* const ins,
714709 {
715710 // if the state machine is accepting the payload, try to accept
716711 // the received transfer payload and return to the user
717- ret = rxAcceptTransfer (ins , reassembler , out_transfer , redundant_iface_index );
712+ // FIXME: what is the redundant interface index for?
713+ ret = rxAcceptTransfer (ins , reassembler , out_transfer );
714+ if (ret == 1 )
715+ {
716+ // copy the relevant metadata from the reassembler
717+ // because the transfer is valid, the application takes ownership
718+ // of the payload buffer.
719+ memcpy (& out_transfer -> metadata , & reassembler -> metadata , sizeof (struct SerardTransferMetadata ));
720+ out_transfer -> payload_extent = reassembler -> payload_extent ;
721+ out_transfer -> payload = reassembler -> payload ;
722+ out_transfer -> timestamp_usec = reassembler -> timestamp_usec ;
723+ }
718724 }
719725 else
720726 {
721727 // in other cases, the delimiter is premature so consider the transfer
722728 // to be invalid and silently discard it
723729 ret = 0 ;
730+ if (reassembler -> payload != NULL )
731+ {
732+ // deallocate the payload buffer if it was allocated
733+ ins -> memory_payload .deallocate (ins -> memory_payload .user_reference ,
734+ reassembler -> payload_extent ,
735+ reassembler -> payload );
736+ reassembler -> payload = NULL ;
737+ reassembler -> payload_extent = 0 ;
738+ }
724739 }
725740
726741 // delimiter bytes unconditionally reset the state machine
@@ -732,7 +747,7 @@ SERARD_PRIVATE int8_t rxAcceptByte(struct SerardRx* const ins,
732747 if (state_payload )
733748 {
734749 const size_t offset = reassembler -> counter - HEADER_SIZE ;
735- uint8_t * const payload = out_transfer -> payload ;
750+ uint8_t * const payload = reassembler -> payload ;
736751 payload [offset ] = cobs_byte ;
737752 }
738753 else
@@ -744,11 +759,11 @@ SERARD_PRIVATE int8_t rxAcceptByte(struct SerardRx* const ins,
744759 {
745760 // record the fragment timestamp when the first header byte is received
746761 // see: https://github.com/OpenCyphal/pycyphal/issues/112
747- out_transfer -> timestamp_usec = timestamp_usec ;
762+ reassembler -> timestamp_usec = timestamp_usec ;
748763 }
749764 else if (offset == (HEADER_SIZE - 1 ))
750765 {
751- const int8_t out = rxValidateHeader (ins , reassembler , out_transfer );
766+ const int8_t out = rxValidateHeader (ins , reassembler );
752767 if (out < 0 )
753768 {
754769 // rx pipeline encountered error, reject transfer and propogate to user
@@ -804,13 +819,15 @@ struct SerardRx serardRxInit(const struct SerardMemoryResource memory_payload,
804819struct SerardReassembler serardReassemblerInit (void )
805820{
806821 struct SerardReassembler reassembler = {
807- .code = BYTE_MAX ,
808- .copy = 0 ,
809- .counter = 0 ,
810- .discard = false,
811- .header = {0 },
812- .sub = NULL ,
813- .max_payload_size = 0 ,
822+ .counter = 0 ,
823+ .discard = false,
824+ .code = BYTE_MAX ,
825+ .copy = 0 ,
826+ .metadata = {0 },
827+ .header = {0 },
828+ .payload_extent = 0 ,
829+ .payload = NULL ,
830+ .sub = NULL ,
814831 };
815832
816833 return reassembler ;
0 commit comments