/// <summary> /// Writes a single tag /// </summary> /// <param name="tag">Tag to write</param> /// <returns>True if the write was successful</returns> /// <remarks>This is not the preferred method of updating tag information. If you have /// multiple tags that you want to update, use the <see cref="UpdateGroups"/> method.</remarks> public bool WriteTag(ITag tag) { lock (_lockObject) { LogixTag lgxTag = tag as LogixTag; if (lgxTag == null) { throw new ArgumentException(Resources.ErrorStrings.IncorrectArgTagType, "tag"); } WriteDataServiceReply lgxWrite = LogixServices.WriteLogixData(_session, lgxTag.Address, lgxTag.DataType, (ushort)lgxTag.Elements, lgxTag.GetWriteData(), lgxTag.StructHandle); if (lgxWrite == null) { return(false); } if (lgxWrite.Status == 0x00) { lgxTag.ClearPendingWrite(); return(true); } } return(false); }
internal void GenerateRequests() { int rSize = 0; _readRequest = LogixServices.BuildLogixReadDataRequest(_address, _elements, out rSize); _writeRequest = LogixServices.BuildLogixWriteDataRequest(_address, _dataType, _elements, new byte[] { }); }
/// <summary> /// Reads a single tag /// </summary> /// <param name="tag">Tag to read</param> /// <returns>True if the read was successful</returns> /// <remarks>This is not the preferred method of updating tag information. If you have /// multiple tags that you want to update, use the <see cref="UpdateGroup"/> method.</remarks> public bool ReadTag(ITag tag) { lock (_lockObject) { LogixTag lgxTag = tag as LogixTag; if (lgxTag == null) { throw new ArgumentException(Resources.ErrorStrings.IncorrectArgTagType, "tag"); } ReadDataServiceReply lgxRead = LogixServices.ReadLogixData(_session, lgxTag.Address, (ushort)lgxTag.Elements); if (lgxRead == null || lgxRead.Data == null) { if (lgxRead != null) { lgxTag.SetTagError(lgxRead.ByteStatus); } lgxTag.LastError = Resources.ErrorStrings.TagNotFound + _ipAddress; lgxTag.LastErrorNumber = (int)LogixErrors.TagNotFound; return(false); } lgxTag.SetTagError(lgxRead.ByteStatus); CIPType tagType = (CIPType)lgxRead.DataType; byte[] temp = new byte[lgxRead.Data.Length + 2]; Buffer.BlockCopy(BitConverter.GetBytes(lgxRead.DataType), 0, temp, 0, 2); Buffer.BlockCopy(lgxRead.Data, 0, temp, 2, lgxRead.Data.Length); lgxTag.UpdateValue(temp); uint offset = (uint)lgxRead.Data.Length; if (lgxRead.Status == 0x06) { //We are going to have to request more data... while (lgxRead.Status == 0x06) { lgxRead = LogixServices.ReadLogixDataFragmented(_session, lgxTag.Address, (ushort)lgxTag.Elements, offset); lgxTag.SetTagError(lgxRead.ByteStatus); tagType = (CIPType)lgxRead.DataType; temp = new byte[lgxRead.Data.Length + 2]; Buffer.BlockCopy(BitConverter.GetBytes(lgxRead.DataType), 0, temp, 0, 2); Buffer.BlockCopy(lgxRead.Data, 0, temp, 2, lgxRead.Data.Length); lgxTag.UpdateValue(temp, offset); offset += (uint)lgxRead.Data.Length; } } } //End Lock return(true); }
private void DistributeWriteRequest(PacketMap pm, byte[] requestData, int alignment) { //Ok, the request may have to be broken up into multiple requests... if (requestData.Length > MAX_MSR_SIZE) { //This will have to be broken up... the overhead of an MSR packet is 12 bytes, so //that means we can only fit up to MAX_MSR_SIZE - 12 bytes into a single packet. //We need to figure out how much data we can stuff into one packet, then make //multiple ones based on that... //The first packet should always be the maximum size we can fit into one request... WriteDataServiceRequest fragReq = LogixServices.BuildFragmentedWriteRequest( _tags[pm.TagIndex].Address, _tags[pm.TagIndex].DataType, _tags[pm.TagIndex].Elements, 0, null, _tags[pm.TagIndex].StructHandle); int maxSize = MAX_MSR_SIZE - 12 - fragReq.Size; int alignedSize = maxSize - (maxSize % alignment); int remainingSize = requestData.Length; uint offset = 0; while (remainingSize > 0) { //We can fit up to alignedSize bytes in the array... byte[] temp; if (remainingSize < alignedSize) { temp = new byte[remainingSize]; remainingSize = 0; } else { temp = new byte[alignedSize]; remainingSize -= alignedSize; } Buffer.BlockCopy(requestData, (int)offset, temp, 0, temp.Length); fragReq = LogixServices.BuildFragmentedWriteRequest(_tags[pm.TagIndex].Address, _tags[pm.TagIndex].DataType, _tags[pm.TagIndex].Elements, offset, temp, _tags[pm.TagIndex].StructHandle); offset += (uint)temp.Length; FindWritePacketOrCreate(pm, fragReq); } } else { //We can fit it into a single packet, we just need to find //one WriteDataServiceRequest request = LogixServices.BuildLogixWriteDataRequest( _tags[pm.TagIndex].Address, _tags[pm.TagIndex].DataType, _tags[pm.TagIndex].Elements, requestData, _tags[pm.TagIndex].StructHandle); FindWritePacketOrCreate(pm, request); } }
private void AddOrCreateReadPacket(LogixTag tag, int idx) { //First we create the request... int temp = 0; ReadDataServiceRequest request = LogixServices.BuildLogixReadDataRequest( tag.Address, tag.Elements, out temp); //Now we read it from the PLC to find out if it's fragmented... CommonPacketItem addressItem = CommonPacketItem.GetConnectedAddressItem(_parent.SessionInfo.ConnectionParameters.O2T_CID); CommonPacketItem dataItem = CommonPacketItem.GetConnectedDataItem(request.Pack(), SequenceNumberGenerator.SequenceNumber); EncapsReply reply = _parent.SessionInfo.SendUnitData(addressItem, dataItem); if (reply != null) { //It's a good tag, let's figure out if it's fragmented... ReadDataServiceReply rdReply = new ReadDataServiceReply(reply); PacketMap pm = new PacketMap() { TagIndex = idx }; pm.PacketIndex = new List <int>(); pm.ServiceIndex = new List <int>(); pm.Offsets = new List <uint>(); pm.NumReplies = 1; if (rdReply.Status == 0x06) { //Partial read... We'll have to request more data, but first let's make this packet request = LogixServices.BuildFragmentedReadDataRequest(tag.Address, tag.Elements, 0, out temp); int[] status = FindPacketOrCreate(request.Pack(), (ushort)(rdReply.Data.Length + 2)); uint offset = (uint)rdReply.Data.Length; pm.PacketIndex.Add(status[0]); pm.ServiceIndex.Add(status[1]); pm.Offsets.Add(0); while (rdReply.Status == 0x06) { rdReply = LogixServices.ReadLogixDataFragmented(_parent.SessionInfo, tag.Address, tag.Elements, offset); request = LogixServices.BuildFragmentedReadDataRequest(tag.Address, tag.Elements, offset, out temp); status = FindPacketOrCreate(request.Pack(), (ushort)(rdReply.Data.Length + 2)); pm.PacketIndex.Add(status[0]); pm.ServiceIndex.Add(status[1]); offset += (uint)rdReply.Data.Length; pm.Offsets.Add(offset); pm.NumReplies++; } } else if (rdReply.Status == 0x00 && rdReply.Data != null) { //Full read, create the packet... int[] status = FindPacketOrCreate(request.Pack(), (ushort)(rdReply.Data.Length + 2)); pm.PacketIndex.Add(status[0]); pm.ServiceIndex.Add(status[1]); pm.Offsets.Add(0); } _readPackets.Add(pm); } }