private void RxReset() { _nodeIdWaitResponded = 0; _srcNodeId = 0; _reassemblingData = null; _rxTimerAction = null; }
protected override CustomDataFrame SubstituteIncomingInternal(CustomDataFrame packet, byte destNodeId, byte srcNodeId, byte[] cmdData, int lenIndex, out ActionBase additionalAction, out ActionBase completeAction) { CustomDataFrame ret = packet; additionalAction = null; completeAction = null; if (IsActive) { if (cmdData.Length > 1 && cmdData[0] == COMMAND_CLASS_TRANSPORT_SERVICE_V2.ID && ValidateCRC16Checksum(cmdData)) { byte id = (byte)(cmdData[1] & COMMAND_CLASS_TRANSPORT_SERVICE_V2.COMMAND_FIRST_SEGMENT.ID_MASK); if (id == (COMMAND_CLASS_TRANSPORT_SERVICE_V2.COMMAND_FIRST_SEGMENT.ID) && TransportServiceManagerInfo.TestNeedToIgnoreFirstSegment.CanBeUsed && TransportServiceManagerInfo.TestNeedToIgnoreFirstSegment.PullValue().Value ) { return(ret); } if (id == (COMMAND_CLASS_TRANSPORT_SERVICE_V2.COMMAND_SUBSEQUENT_SEGMENT.ID) && TransportServiceManagerInfo.TestNeedToIgnoreSubsequentSegment.CanBeUsed && TransportServiceManagerInfo.TestOffset.CanBeUsed ) { var datagramOffset = SegmentsContainer.GetSegmentOffset(cmdData); var payloadLength = SegmentsContainer.GetSegmentPayloadLength(cmdData); if (TransportServiceManagerInfo.TestOffset.PullValue( val => { return(val >= datagramOffset && val <= (datagramOffset + payloadLength)); }) != null && TransportServiceManagerInfo.TestNeedToIgnoreSubsequentSegment.PullValue().Value ) { return(ret); } } lock (_lockObject) { if (_reassemblingData == null || _reassemblingData.SegmentsContainer.IsCompleted) { if (id == (COMMAND_CLASS_TRANSPORT_SERVICE_V2.COMMAND_FIRST_SEGMENT.ID)) { RxReset(); _srcNodeId = srcNodeId; var cmdHeader = new byte[lenIndex]; Array.Copy(packet.Data, 0, cmdHeader, 0, cmdHeader.Length); var cmdFooter = new byte[packet.Data.Length - cmdHeader.Length - cmdData.Length - 1]; Array.Copy(packet.Data, lenIndex + packet.Data[lenIndex] + 1, cmdFooter, 0, cmdFooter.Length); _reassemblingData = new ReassemblingData { SegmentsContainer = new SegmentsContainer(cmdData), CompletedCmdHeader = cmdHeader, CompletedCmdFooter = cmdFooter }; if (_reassemblingData.SegmentsContainer.IsCompleted) { additionalAction = new SendDataOperation(srcNodeId, CreateSegmentCompletedCmd(), TransportServiceManagerInfo.TxOptions) { SubstituteSettings = new SubstituteSettings(SubstituteFlags.DenySecurity, 0) }; ret = CreateDataFrameOnReassemblingCompleted(packet); } else { // Start fragment rx timer. _rxTimerAction = CreateRxTimerAction(); additionalAction = _rxTimerAction; } } else if (id == (COMMAND_CLASS_TRANSPORT_SERVICE_V2.COMMAND_SUBSEQUENT_SEGMENT.ID)) { if (_reassemblingData != null && _reassemblingData.SegmentsContainer.CheckForLastSegment(cmdData)) { additionalAction = new SendDataOperation(srcNodeId, CreateSegmentCompletedCmd(), TransportServiceManagerInfo.TxOptions) { SubstituteSettings = new SubstituteSettings(SubstituteFlags.DenySecurity, 0) }; } else if (srcNodeId != _nodeIdWaitResponded) { _nodeIdWaitResponded = srcNodeId; additionalAction = new SendDataOperation(srcNodeId, CreateSegmentWaitCmd(1), TransportServiceManagerInfo.TxOptions) { SubstituteSettings = new SubstituteSettings(SubstituteFlags.DenySecurity, 0) }; } } } else if (_srcNodeId == srcNodeId && id == (COMMAND_CLASS_TRANSPORT_SERVICE_V2.COMMAND_SUBSEQUENT_SEGMENT.ID)) { if (_rxTimerAction != null) { _rxTimerAction.Actions[0].Token.Reset(FRAGMENT_RX_TIMEOUT); // Reset fragment rx timer. } else { _rxTimerAction = CreateRxTimerAction(); additionalAction = _rxTimerAction; } _reassemblingData.SegmentsContainer.AddSegment(cmdData); if (_reassemblingData.SegmentsContainer.IsLastSegmentReceived) { if (_reassemblingData.SegmentsContainer.IsCompleted) { _rxTimerAction.Token.SetCompleted(); // Complete fragment rx timer. completeAction = _rxTimerAction; _rxTimerAction = null; additionalAction = new SendDataOperation(srcNodeId, CreateSegmentCompletedCmd(), TransportServiceManagerInfo.TxOptions) { SubstituteSettings = new SubstituteSettings(SubstituteFlags.DenySecurity, 0) }; ret = CreateDataFrameOnReassemblingCompleted(packet); } else { ushort missingOffset = _reassemblingData.SegmentsContainer.GetFirstMissingFragmentOffset(); additionalAction = new SendDataOperation(srcNodeId, CreateSegmentRequestCmd(missingOffset), TransportServiceManagerInfo.TxOptions) { SubstituteSettings = new SubstituteSettings(SubstituteFlags.DenySecurity, 0) }; } } } else { if (srcNodeId != _nodeIdWaitResponded) { _nodeIdWaitResponded = srcNodeId; additionalAction = new SendDataOperation(srcNodeId, CreateSegmentWaitCmd(_reassemblingData.SegmentsContainer.PendingSegmentsCount), TransportServiceManagerInfo.TxOptions) { SubstituteSettings = new SubstituteSettings(SubstituteFlags.DenySecurity, 0) }; } } } } } return(ret); }