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 > 4 && cmdData[0] == COMMAND_CLASS_CRC_16_ENCAP.ID && cmdData[1] == COMMAND_CLASS_CRC_16_ENCAP.CRC_16_ENCAP.ID) { COMMAND_CLASS_CRC_16_ENCAP.CRC_16_ENCAP cmd = cmdData; if (Tools.CalculateCrc16Array(cmdData, 0, cmdData.Length - 2).SequenceEqual(cmd.checksum)) { byte[] newFrameData = new byte[packet.Data.Length - 4]; Array.Copy(packet.Data, 0, newFrameData, 0, lenIndex); newFrameData[lenIndex] = (byte)(cmdData.Length - 4); Array.Copy(cmdData, 2, newFrameData, lenIndex + 1, cmdData.Length - 4); Array.Copy(packet.Data, lenIndex + 1 + cmdData.Length, newFrameData, lenIndex + 1 + cmdData.Length - 4, packet.Data.Length - lenIndex - 1 - cmdData.Length); ret = CreateNewFrame(packet, newFrameData); } } } return(ret); }
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 > 4 && cmdData[0] == COMMAND_CLASS_SUPERVISION.ID && cmdData[1] == COMMAND_CLASS_SUPERVISION.SUPERVISION_GET.ID) { COMMAND_CLASS_SUPERVISION.SUPERVISION_GET cmd = cmdData; if (cmd.encapsulatedCommand != null && cmd.encapsulatedCommand.Count > 0) { byte[] newFrameData = new byte[packet.Data.Length - 4]; Array.Copy(packet.Data, 0, newFrameData, 0, lenIndex); newFrameData[lenIndex] = (byte)(cmdData.Length - 4); Array.Copy(cmdData, 4, newFrameData, lenIndex + 1, cmdData.Length - 4); Array.Copy(packet.Data, lenIndex + 1 + cmdData.Length, newFrameData, lenIndex + 1 + cmdData.Length - 4, packet.Data.Length - lenIndex - 1 - cmdData.Length); ret = CreateNewFrame(packet, newFrameData); } } } return(ret); }
private CustomDataFrame SubstituteIncoming(CustomDataFrame dataFrame, List <ActionHandlerResult> ahResults, Dictionary <SubstituteIncomingFlags, CustomDataFrame> substitutedDataFrames) { ActionBase additionalAction; ActionBase completeAction; lock (_actionStateLock) { foreach (var item in Enumerable.Reverse(_substituteManagers)) { substitutedDataFrames.Add(item.Id, dataFrame); dataFrame = item.SubstituteIncoming(dataFrame, out additionalAction, out completeAction); if (additionalAction != null) { var ahRes = new ActionHandlerResult(null); ahRes.NextActions.Add(additionalAction); ahResults.Add(ahRes); } if (completeAction != null) { ProcessCompleted(completeAction); } } return(dataFrame); } }
protected CustomDataFrame CreateNewFrame(CustomDataFrame packet, byte[] newFrameData, int cmdLength) { var ret = new DataFrame(packet.SessionId, packet.DataFrameType, false, false, packet.SystemTimeStamp); byte[] buffer = DataFrame.CreateFrameBuffer(newFrameData); ret.SetBuffer(buffer, cmdLength); ret.SubstituteIncomingFlags = packet.SubstituteIncomingFlags | GetId(); return(ret); }
private void ProcessSubstituteManagers(CustomDataFrame dataFrame, List <ActionHandlerResult> ahResults, Dictionary <SubstituteIncomingFlags, CustomDataFrame> substitutedDataFrames) { // 32 bits in int for (int i = 31; i >= 0; i--) { int mask = 1 << i; if ((dataFrame.SubstituteIncomingFlags & (SubstituteIncomingFlags)mask) > 0 && _substituteManagersDictionary.ContainsKey((SubstituteIncomingFlags)mask)) { var smgr = _substituteManagersDictionary[(SubstituteIncomingFlags)mask]; var dataFrameOri = substitutedDataFrames[(SubstituteIncomingFlags)mask]; smgr.OnIncomingSubstituted(dataFrameOri, dataFrame, ahResults); } } }
public CustomDataFrame SubstituteIncoming(CustomDataFrame packet, out ActionBase additionalAction, out ActionBase completeAction) { CustomDataFrame ret = packet; additionalAction = null; completeAction = null; byte[] cmdData; byte srcNodeId; byte destNodeId; int lenIndex; if (TryParseCommand(packet, out destNodeId, out srcNodeId, out lenIndex, out cmdData)) { ret = SubstituteIncomingInternal(packet, destNodeId, srcNodeId, cmdData, lenIndex, out additionalAction, out completeAction); } return(ret); }
private void TryHandleDataFrame(CustomDataFrame actionCase, List <ActionHandlerResult> ahResults) { lock (_actionStateLock) { RunningActions.ForEach(x => { if (!actionCase.IsHandled) { var ahr = x.TryHandle(actionCase); if (ahr != null) { ahResults.Add(ahr); } } return(false); }); } }
public override void OnIncomingSubstituted(CustomDataFrame dataFrameOri, CustomDataFrame dataFrameSub, List <ActionHandlerResult> ahResults) { if (IsActive) { bool hasSendData = ahResults.FirstOrDefault( x => x.NextActions != null && x.NextActions.FirstOrDefault( y => y is SendDataOperation || y is SendDataExOperation) != null) != null; if (!hasSendData) { byte[] cmdData; byte srcNodeId; byte destNodeId; int lenIndex; if (TryParseCommand(dataFrameOri, out destNodeId, out srcNodeId, out lenIndex, out cmdData)) { if (cmdData[0] == COMMAND_CLASS_SUPERVISION.ID && cmdData[1] == COMMAND_CLASS_SUPERVISION.SUPERVISION_GET.ID) { COMMAND_CLASS_SUPERVISION.SUPERVISION_GET cmd = cmdData; var data = new COMMAND_CLASS_SUPERVISION.SUPERVISION_REPORT() { duration = 0, properties1 = new COMMAND_CLASS_SUPERVISION.SUPERVISION_REPORT.Tproperties1() { sessionId = cmd.properties1.sessionId }, status = 0xFF }; var tempAction = new SendDataOperation(srcNodeId, data, TxOptions); if ((((SubstituteIncomingFlags)dataFrameOri.SubstituteIncomingFlags) & SubstituteIncomingFlags.Security) > 0) { tempAction.SubstituteSettings.SetFlag(SubstituteFlags.UseSecurity); } var ahRes = new ActionHandlerResult(null); ahRes.NextActions.Add(tempAction); ahResults.Add(ahRes); } } } } }
public override bool WaitingFor(IActionCase actionCase) { bool ret = false; if (actionCase is CustomDataFrame) { CustomDataFrame receivedValue = (CustomDataFrame)actionCase; if (Substituted == BoolFlag.NotSpecified || Substituted == BoolFlag.True && receivedValue.IsSubstituted || Substituted == BoolFlag.False && !receivedValue.IsSubstituted) { byte[] payload = receivedValue.Data; ret = IsExpectedData(payload); if (ret) { DataFrame = receivedValue; } } } //"{0}: {1} - {2}"._DLOG(ret, actionCase.ToString(), mMask.GetHex()); return(ret); }
private CustomDataFrame CreateDataFrameOnReassemblingCompleted(CustomDataFrame incomePacket) { var dataHeader = _reassemblingData.CompletedCmdHeader; var dataFooter = _reassemblingData.CompletedCmdFooter; var reasembledCmd = _reassemblingData.SegmentsContainer.GetDatagram(); var packetData = new byte[_reassemblingData.CompletedCmdHeader.Length + _reassemblingData.CompletedCmdFooter.Length + reasembledCmd.Length + 1]; int offset = 0; Array.Copy(dataHeader, packetData, dataHeader.Length); offset += dataHeader.Length; packetData[offset] = (byte)reasembledCmd.Length; offset++; Array.Copy(reasembledCmd, 0, packetData, offset, reasembledCmd.Length); offset += reasembledCmd.Length; Array.Copy(dataFooter, 0, packetData, offset, dataFooter.Length); return(CreateNewFrame(incomePacket, packetData, reasembledCmd.Length)); }
public static bool TryParseCommand(CustomDataFrame packet, out byte destNodeId, out byte srcNodeId, out int lenIndex, out byte[] cmdData) { bool ret = false; cmdData = null; srcNodeId = 0; destNodeId = 0; lenIndex = 0; if (packet != null && packet.Data != null && packet.Data.Length > 1 && (packet.Data[1] == (byte)CommandTypes.CmdApplicationCommandHandler || packet.Data[1] == (byte)CommandTypes.CmdApplicationCommandHandler_Bridge)) { int srcIndex = 3; lenIndex = 4; int destIndex = -1; byte[] frameData = packet.Data; if (frameData[1] == (byte)CommandTypes.CmdApplicationCommandHandler_Bridge) { destIndex = 3; srcIndex = 4; lenIndex = 5; } if (frameData.Length > lenIndex + 2) { srcNodeId = frameData[srcIndex]; if (destIndex > 0) { destNodeId = frameData[destIndex]; } cmdData = new byte[frameData[lenIndex]]; Array.Copy(frameData, lenIndex + 1, cmdData, 0, cmdData.Length); if (cmdData.Length > 2) { ret = true; } } } return(ret); }
public static DataFrame CreateDataFrame(CustomDataFrame packet, int lenIndex, byte[] cmd, byte lastUsedSecurityScheme, bool hasActiveKeyForNode, byte activeSecuritySchemeForNode) { byte[] frameData = packet.Data; byte rssi = 0; int multiDestsOffsetNodeMaskLen = 0; byte[] multiDestsNodeMask = new byte[0]; byte[] tail = new byte[2]; if (frameData[1] == (byte)CommandTypes.CmdApplicationCommandHandler_Bridge) { int multiDestsOffsetNodeMaskLenIndex = lenIndex + 1 + frameData[lenIndex]; if (frameData.Length > multiDestsOffsetNodeMaskLenIndex) { multiDestsOffsetNodeMaskLen = frameData[multiDestsOffsetNodeMaskLenIndex]; } if (multiDestsOffsetNodeMaskLen > 0 && frameData.Length > multiDestsOffsetNodeMaskLenIndex + 1 + multiDestsOffsetNodeMaskLen) { multiDestsNodeMask = frameData.Skip(multiDestsOffsetNodeMaskLenIndex + 1).Take(multiDestsOffsetNodeMaskLen).ToArray(); } if (frameData.Length > multiDestsOffsetNodeMaskLenIndex + 1 + multiDestsOffsetNodeMaskLen) { rssi = frameData[multiDestsOffsetNodeMaskLenIndex + 1 + multiDestsOffsetNodeMaskLen]; } if (multiDestsOffsetNodeMaskLen == 0) { tail = new byte[3]; } else { tail = new byte[multiDestsOffsetNodeMaskLen + 1 + tail.Length]; Array.Copy(multiDestsNodeMask, 0, tail, 1, multiDestsOffsetNodeMaskLen); } tail[0] = (byte)multiDestsOffsetNodeMaskLen; } else { if (frameData.Length > lenIndex + 1 + frameData[lenIndex]) { rssi = frameData[lenIndex + 1 + frameData[lenIndex]]; } } tail[tail.Length - 2] = rssi; tail[tail.Length - 1] = lastUsedSecurityScheme; "set scheme {0}"._DLOG(lastUsedSecurityScheme); byte[] payload = new byte[lenIndex + 1 + cmd.Length + tail.Length]; for (int i = 0; i < lenIndex + 2; i++) { payload[i] = frameData[i]; } payload[lenIndex] = (byte)cmd.Length; Array.Copy(cmd, 0, payload, lenIndex + 1, cmd.Length); Array.Copy(tail, 0, payload, lenIndex + 1 + cmd.Length, tail.Length); if (hasActiveKeyForNode) { payload[payload.Length - 1] = activeSecuritySchemeForNode; } DataFrame df = new DataFrame(packet.SessionId, packet.DataFrameType, packet.IsHandled, packet.IsOutcome, packet.SystemTimeStamp) { IsSubstituted = true }; byte[] t = DataFrame.CreateFrameBuffer(payload); df.SetBuffer(t, 0, t.Length); var currentFlags = packet.SubstituteIncomingFlags; df.SubstituteIncomingFlags = (currentFlags | SubstituteIncomingFlags.Security); return(df); }
private void HandleActionCaseInner(IActionCase actionCase) { var customDataFrame = actionCase as CustomDataFrame; var timeInterval = actionCase as TimeInterval; var action = actionCase as ActionBase; if (customDataFrame != null) { CustomDataFrame dataFrameOri = customDataFrame; var ahResults = new List <ActionHandlerResult>(); Dictionary <SubstituteIncomingFlags, CustomDataFrame> substitutedDataFrames = new Dictionary <SubstituteIncomingFlags, CustomDataFrame>(); var dataFrame = SubstituteIncoming(dataFrameOri, ahResults, substitutedDataFrames); if (dataFrame != null) { TryHandleDataFrame(dataFrame, ahResults); if (dataFrame.Parent != null) { TryHandleDataFrame(dataFrame.Parent, ahResults); } ProcessSubstituteManagers(dataFrame, ahResults, substitutedDataFrames); foreach (var ahResult in ahResults) { ProcessNext(ahResult); if (ahResult.Parent != null) { ProcessCompleted(ahResult.Parent); } } } } else if (timeInterval != null) { if (timeInterval.ParentAction != null) { ProcessNext(timeInterval.ParentAction.TryHandle(actionCase)); if (timeInterval.ParentAction != null) { ProcessCompleted(timeInterval.ParentAction); } } } else if (action != null) { if (action.Token.IsStateFinished) { ProcessCompleted(action); if (action.IsExclusive) { _isExclusiveBusy = false; var pendingAction = PendingExclusiveActions.Dequeue(); if (pendingAction != null) { _actionCaseConsumer.Add(pendingAction); } } RunningActions.ForEach(x => { if (x.ParentAction == action) { if (x.ParentAction.Token.State == ActionStates.Expired || x.ParentAction.Token.State == ActionStates.Cancelled) { x.Token.SetCancelling(); var ahResult = x.TryHandleStopped(); ProcessNext(ahResult); x.Token.SetCancelled(); ProcessCompleted(x); } else { x.Token.SetCancelled(); ProcessCompleted(x); } } return(false); }); if (action.ParentAction != null && action.ParentAction.Token.IsStateActive) { var ahResult = action.ParentAction.TryHandle(action); ProcessNext(ahResult); action.ParentAction.FixStates(); ProcessCompleted(action.ParentAction); } } else { if (action.Token.State == ActionStates.None) { var actionStartSignal = action.Token.StartSignal; action.SessionId = SessionId; if (action.IsSequenceNumberRequired) { action.SequenceNumber = NextFuncId(); } action = SubstituteAction(action); if (action.IsExclusive) { if (!SuppressDebugOutput) { "{0:X2} (W){1}"._DLOG(SessionId, action.GetName() + action.AboutMeSafe()); } if (_isExclusiveBusy) { PendingExclusiveActions.Enqueue(action); return; } else { _isExclusiveBusy = true; } //CheckPoint.Pass(action); } var ahResult = action.Start(); if (_actionChangeCallback != null) { _actionChangeCallback(action.Token); } if (action.IsFirstPriority) { RunningActions.AddFirst(action); } else { RunningActions.AddLast(action); } if (!SuppressDebugOutput) { "{0:X2} {1}"._DLOG(SessionId, action.GetName() + action.AboutMeSafe()); } ProcessNext(ahResult); if (action.Token.TimeoutMs > 0) { TimeoutManager.AddTimer(action.Token); } if (actionStartSignal != null && !isDisposing) { actionStartSignal.Set(); } } else if (action.Token.Result.State == ActionStates.Cancelling) { var ahResult = action.TryHandleStopped(); ProcessNext(ahResult); } else if (action.Token.Result.State == ActionStates.Expiring) { var ahResult = action.TryHandleStopped(); ProcessNext(ahResult); } action.FixStates(); ProcessCompleted(action); } } }
protected virtual CustomDataFrame SubstituteIncomingInternal(CustomDataFrame packet, byte destNodeId, byte srcNodeId, byte[] cmdData, int lenIndex, out ActionBase additionalAction, out ActionBase completeAction) { additionalAction = null; completeAction = null; return(null); }
public virtual void OnIncomingSubstituted(CustomDataFrame dataFrameOri, CustomDataFrame dataFrameSub, List <ActionHandlerResult> ahResults) { }
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); }