/// <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);
        }
Exemple #2
0
        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);
            }
        }