public static IMessage CreateEndUploadRequest(ushort unitId, PlcBlockType blockType, int blockNumber, uint controlId) { var msg = Message.Create(); FillCommHeader(msg, (byte)PduType.Job, 0, 8, unitId); AddUploadParameter(msg, (byte)FunctionCode.EndUpload, blockType, blockNumber, 0, controlId); return(msg); }
public static IMessage CreateStartDownloadRequest(ushort unitId, PlcBlockType blockType, int blockNumber, byte[] data) { var msg = Message.Create(); FillCommHeader(msg, (byte)PduType.Job, 0, 32, unitId); AddDownloadParameter(msg, (byte)FunctionCode.RequestDownload, blockType, blockNumber, 9, 0); return(msg); }
public static IMessage CreateBlocksOfTypeRequest(ushort unitId, PlcBlockType blockType, byte sequenceNumber = 0) { var msg = Message.Create(); FillCommHeader(msg, (byte)PduType.UserData, sequenceNumber == 0x00 ? (ushort)6 : (ushort)4, sequenceNumber == 0x00 ? (ushort)8 : (ushort)12, unitId); AddUserDataParameter(msg, sequenceNumber == 0x00 ? (byte)4 : (byte)8, UserDataFunctionType.Request, UserDataFunctionGroup.Block, (byte)UserDataSubFunctionBlock.ListType, sequenceNumber); AddData(msg, sequenceNumber == 0 ? new byte[] { 0x30, // ?? (byte)blockType //Block Type } : new byte[0]); return(msg); }
public async Task <S7PlcBlockInfoAckDatagram> ReadBlockInfoAsync(PlcBlockType type, int blocknumber) { if (ConnectionState != ConnectionState.Opened) { ThrowHelper.ThrowNotConnectedException(); } var id = GetNextReferenceId(); using (var dg = S7UserDataDatagram.TranslateToMemory(S7UserDataDatagram.BuildBlockInfoRequest(_s7Context, id, type, blocknumber), out var memoryLength)) { using (var sendData = _transport.Build(dg.Memory.Slice(0, memoryLength), out var sendLength)) { try { CallbackHandler <S7PlcBlockInfoAckDatagram> cbh; S7PlcBlockInfoAckDatagram blockinfoResult = null; using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false)) { cbh = new CallbackHandler <S7PlcBlockInfoAckDatagram>(id); _blockInfoHandler.TryAdd(cbh.Id, cbh); try { if (await _transport.Client.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success) { return(null); } blockinfoResult = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false); } finally { _blockInfoHandler.TryRemove(cbh.Id, out _); } } HandlerErrorResult(id, cbh, blockinfoResult); return(blockinfoResult); } catch (TaskCanceledException) { ThrowHelper.ThrowTimeoutException(); } } } return(null); }
/// <summary> /// Add parameter for upload datagram. /// </summary> /// <param name="message">Message on which the parameter are set</param> /// <param name="function">Function to set</param> /// <param name="blockType"><see cref="PlcBlockType"/></param> /// <param name="blockNumber">number of plc block</param> /// <param name="length">LengthPart1</param> /// <param name="controlId">Reserved2</param> private static void AddUploadParameter(IMessage message, byte function, PlcBlockType blockType, int blockNumber, byte length = 0, uint controlId = 0) { message.SetAttribute("Function", function); message.SetAttribute("Reserved", (byte)0x00); message.SetAttribute("ErrorCode", (ushort)0x0000); message.SetAttribute("Reserved2", controlId); if (function == 0x1d) { message.SetAttribute("LengthPart1", length); message.SetAttribute("FileIdentifier", (byte)0x5f); message.SetAttribute("Unknown1", (byte)0x30); message.SetAttribute("BlockType", (byte)blockType); message.SetAttribute("BlockNumber", Encoding.ASCII.GetBytes(string.Format("{0:00000}", blockNumber))); message.SetAttribute("DestFilesystem", (byte)0x41); } }
public static IMessage CreateBlockInfoRequest(ushort unitId, PlcBlockType blockType, int blockNumber) { var msg = Message.Create(); FillCommHeader(msg, (byte)PduType.UserData, 12, 8, unitId); AddUserDataParameter(msg, 4, UserDataFunctionType.Request, UserDataFunctionGroup.Block, (byte)UserDataSubFunctionBlock.BlockInfo); var b = new List <byte> { 0x30, (byte)blockType }; b.AddRange(Encoding.ASCII.GetBytes(string.Format("{0:00000}", blockNumber))); b.Add(0x41); AddData(msg, b.ToArray()); return(msg); }
/// <summary> /// Add parameters for download datagram /// </summary> /// <param name="message">Message on which the parameter are set</param> /// <param name="function">Function to set</param> /// <param name="blockType"><see cref="PlcBlockType"/></param> /// <param name="blockNumber">number of plc block</param> /// <param name="loadMemSize">LoadMemLength</param> /// <param name="Mc7Size">Size of mc7Code</param> /// <param name="lastDu">Is last data unit</param> private static void AddDownloadParameter(IMessage message, byte function, PlcBlockType blockType, int blockNumber, int loadMemSize, int Mc7Size, bool lastDu = false) { message.SetAttribute("Function", function); message.SetAttribute("Reserved", lastDu ? (byte)0x01 : (byte)0x00); if (function == 0x1a) { message.SetAttribute("ErrorCode", (ushort)0x0100); message.SetAttribute("Reserved2", (uint)0); message.SetAttribute("LengthPart1", 9); message.SetAttribute("FileIdentifier", (byte)0x5f); message.SetAttribute("Unknown1", (byte)0x30); message.SetAttribute("BlockType", (byte)blockType); message.SetAttribute("BlockNumber", Encoding.ASCII.GetBytes(string.Format("{0:00000}", blockNumber))); message.SetAttribute("DestFilesystem", (byte)0x50); message.SetAttribute("LengthPart2", 13); message.SetAttribute("Unknown2", (byte)0x31); message.SetAttribute("LoadMemLength", Encoding.ASCII.GetBytes(string.Format("{0:00000}", loadMemSize))); message.SetAttribute("MC7Length", Encoding.ASCII.GetBytes(string.Format("{0:00000}", Mc7Size))); } }
/// <summary> /// Read the meta data of a block from the PLC. /// </summary> /// <param name="blockType">Specify the block type to read. e.g. DB <see cref="PlcBlockType"/></param> /// <param name="blocknumber">Specify the Number of the block</param> /// <returns><see cref="IPlcBlockInfo"/> where you have access tho the detailed meta data of the block.</returns> public static async Task <IPlcBlockInfo> ReadBlockInfoAsync(this Dacs7Client client, PlcBlockType type, int blocknumber) { var result = await client.ProtocolHandler.ReadBlockInfoAsync(type, blocknumber).ConfigureAwait(false); if (result != null) { return(new PlcBlockInfo { ADDLength = result.ADDLength, Author = result.Author?.Trim('\0'), BlockFlags = result.BlockFlags, BlockLanguage = result.BlockLanguage, BlockNumber = result.BlockNumber, BlockSecurity = result.BlockSecurity, Checksum = result.Checksum, CodeSize = result.CodeSize, Family = result.Family?.Trim('\0'), LastCodeChange = result.LastCodeChange, LastInterfaceChange = result.LastInterfaceChange, LengthLoadMemory = result.LengthLoadMemory, LocalDataSize = result.LocalDataSize, Name = result.Name?.Trim('\0'), SSBLength = result.SSBLength, SubBlockType = result.SubBlockType, VersionHeaderMajor = result.VersionHeaderMajor, VersionHeaderMinor = result.VersionHeaderMinor }); } return(null); }
public static S7UserDataDatagram BuildBlockInfoRequest(SiemensPlcProtocolContext context, int id, PlcBlockType blockType, int blockNumber) { var result = new S7UserDataDatagram { Parameter = new S7UserDataParameter { ParamDataLength = 4, TypeAndGroup = ((byte)UserDataFunctionType.Request << 4) | (byte)UserDataFunctionGroup.Block, SubFunction = (byte)UserDataSubFunctionBlock.BlockInfo, SequenceNumber = 0, ParameterType = (byte)UserDataParamTypeType.Request }, Data = new S7UserData { ReturnCode = (byte)ItemResponseRetValue.Success, TransportSize = (byte)DataTransportSize.OctetString, } }; result.Header.ProtocolDataUnitReference = (ushort)id; result.Header.DataLength = 12; result.Header.ParamLength = 8; result.Data.Data = new byte[] { 0x30, (byte)blockType, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41 }; Encoding.Default.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0:00000}", blockNumber)).AsSpan().CopyTo(result.Data.Data.Span.Slice(2, 5)); result.Data.UserDataLength = (ushort)result.Data.Data.Length; return(result); }
public static S7UserDataDatagram BuildBlocksOfTypeRequest(SiemensPlcProtocolContext context, int id, PlcBlockType type, byte sequenceNumber) { var result = new S7UserDataDatagram { Parameter = new S7UserDataParameter { ParamDataLength = sequenceNumber == 0x00 ? (byte)4 : (byte)8, TypeAndGroup = ((byte)UserDataFunctionType.Request << 4) | (byte)UserDataFunctionGroup.Block, SubFunction = (byte)UserDataSubFunctionBlock.ListType, SequenceNumber = sequenceNumber, ParameterType = sequenceNumber == 0x00 ? (byte)UserDataParamTypeType.Request : (byte)UserDataParamTypeType.Response }, Data = new S7UserData { ReturnCode = (byte)ItemResponseRetValue.DataError, TransportSize = (byte)DataTransportSize.Null } }; result.Header.ProtocolDataUnitReference = (ushort)id; result.Header.DataLength = sequenceNumber == 0x00 ? (ushort)6 : (ushort)4; result.Header.ParamLength = sequenceNumber == 0x00 ? (ushort)8 : (ushort)12; result.Data.Data = sequenceNumber == 0 ? new byte[] { 0x30, (byte)type } : Array.Empty <byte>(); result.Data.UserDataLength = (ushort)result.Data.Data.Length; return(result); }
public async Task <S7PlcBlockInfoAckDatagram> ReadBlockInfoAsync(PlcBlockType type, int blocknumber) { if (_closeCalled || ConnectionState != ConnectionState.Opened) { ThrowHelper.ThrowNotConnectedException(); } var id = GetNextReferenceId(); using (var dg = S7UserDataDatagram.TranslateToMemory(S7UserDataDatagram.BuildBlockInfoRequest(_s7Context, id, type, blocknumber), out var memoryLength)) { using (var sendData = _transport.Build(dg.Memory.Slice(0, memoryLength), out var sendLength)) { try { CallbackHandler <S7PlcBlockInfoAckDatagram> cbh = null; S7PlcBlockInfoAckDatagram blockinfoResult = null; try { if (_concurrentJobs == null) { return(null); } using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false)) { cbh = new CallbackHandler <S7PlcBlockInfoAckDatagram>(id); if (_blockInfoHandler.TryAdd(id, cbh)) { _logger?.LogTrace("Metadata read handler with id {id} was added.", id); try { if (await _transport.Connection.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success) { // we return false, because if one send faild we expect also all other ones failed. _logger?.LogWarning("Could not send metadata read package with reference <{id}>.", id); return(null); } blockinfoResult = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false); } finally { _blockInfoHandler.TryRemove(id, out _); _logger?.LogTrace("Metadata read handler with id {id} was removed.", id); } } else { _logger?.LogWarning("Could not add metadata read handler with reference <{id}>.", id); } } } catch (ObjectDisposedException) { if (cbh == null) { return(null); } } HandlerErrorResult(id, cbh, blockinfoResult); return(blockinfoResult); } catch (TaskCanceledException) { ThrowHelper.ThrowTimeoutException(); } } } return(null); }
public async Task <IEnumerable <IPlcBlock> > ReadBlocksOfTypesAsync(PlcBlockType type) { if (ConnectionState != ConnectionState.Opened) { ThrowHelper.ThrowNotConnectedException(); } var id = GetNextReferenceId(); var sequenceNumber = (byte)0x00; var blocks = new List <IPlcBlock>(); IMemoryOwner <byte> memoryOwner = null; var currentPosition = 0; var totalLength = 0; try { S7PlcBlocksOfTypeAckDatagram blocksOfTypeResults = null; do { using (var dg = S7UserDataDatagram.TranslateToMemory(S7UserDataDatagram.BuildBlocksOfTypeRequest(_s7Context, id, type, sequenceNumber), out var memoryLength)) { using (var sendData = _transport.Build(dg.Memory.Slice(0, memoryLength), out var sendLength)) { CallbackHandler <S7PlcBlocksOfTypeAckDatagram> cbh; using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false)) { cbh = new CallbackHandler <S7PlcBlocksOfTypeAckDatagram>(id); _blocksOfTypeHandler.TryAdd(cbh.Id, cbh); try { if (await _transport.Connection.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success) { return(null); } blocksOfTypeResults = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false); } finally { _blocksOfTypeHandler.TryRemove(cbh.Id, out _); } } HandlerErrorResult(id, cbh, blocksOfTypeResults); if (blocksOfTypeResults.UserData.Data.UserDataLength > 0) { totalLength += blocksOfTypeResults.UserData.Data.UserDataLength; // 6 is the header if (memoryOwner == null) { memoryOwner = MemoryPool <byte> .Shared.Rent(totalLength); } else { var newMem = MemoryPool <byte> .Shared.Rent(totalLength); memoryOwner.Memory.CopyTo(newMem.Memory); memoryOwner?.Dispose(); memoryOwner = newMem; } blocksOfTypeResults.UserData.Data.Data.CopyTo(memoryOwner.Memory.Slice(currentPosition, blocksOfTypeResults.UserData.Data.UserDataLength)); currentPosition += blocksOfTypeResults.UserData.Data.UserDataLength; sequenceNumber = blocksOfTypeResults.UserData.Parameter.SequenceNumber; } else { totalLength = 0; } } } } while (blocksOfTypeResults.UserData.Parameter.LastDataUnit == 0x01); if (memoryOwner != null) { blocks = S7PlcBlocksOfTypeAckDatagram.TranslateFromSslData(memoryOwner.Memory, totalLength); } } finally { memoryOwner?.Dispose(); } return(blocks); }
public static Task <IEnumerable <IPlcBlock> > ReadBlocksOfTypeAsync(this Dacs7Client client, PlcBlockType type) => client.ProtocolHandler.ReadBlocksOfTypesAsync(type);