/// <summary>
        /// Show settings of selected media.
        /// </summary>
        private void MediaCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                MediaFrame.Controls.Clear();
                GXClient cl = new GXClient();
                SelectedMedia = cl.SelectMedia(MediaCB.Text);
                if (SelectedMedia == null)
                {
                    throw new Exception(MediaCB.Text + " media not found.");
                }
                if (!string.IsNullOrEmpty(Gurux.DeviceSuite.Properties.Settings.Default.CommandPrompSettings))
                {
                    List<string> arr = new List<string>(Gurux.DeviceSuite.Properties.Settings.Default.CommandPrompSettings.Split(new char[]{';'}));
                    if (arr.Count > 1)
                    {
                        arr.RemoveAt(0);
                        SelectedMedia.Settings = string.Join(";", arr.ToArray());
                    }
                }

                if (SelectedMedia is GXSerial)
                {
                    (SelectedMedia as GXSerial).AvailablePorts = DataCollector.SerialPorts;
                }
                if (SelectedMedia is GXAmiGateway)
                {
                    GXAmiGateway gw = SelectedMedia as GXAmiGateway;
                    gw.Host = Gurux.DeviceSuite.Properties.Settings.Default.AmiHostName;
                    gw.UserName = Gurux.DeviceSuite.Properties.Settings.Default.AmiUserName;
                    gw.Password = Gurux.DeviceSuite.Properties.Settings.Default.AmiPassword;
                }
                PropertiesForm = SelectedMedia.PropertiesForm;
                ((IGXPropertyPage)PropertiesForm).Initialize();
                while (PropertiesForm.Controls.Count != 0)
                {
                    Control ctr = PropertiesForm.Controls[0];
                    if (ctr is Panel)
                    {
                        if (!ctr.Enabled)
                        {
                            PropertiesForm.Controls.RemoveAt(0);
                            continue;
                        }
                    }
                    MediaFrame.Controls.Add(ctr);
                }
            }
            catch (Exception ex)
            {
                GXCommon.ShowError(this, ex);
            }
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="collectors"></param>
 /// <param name="medias"></param>
 /// <param name="media"></param>
 public RedundantForm(GXClient client, GXAmiDataCollector[] collectors, GXAmiMediaType[] medias, GXAmiDeviceMedia media)
 {
     InitializeComponent();
     Client = client;
     Collectors = collectors;
     Medias = medias;
     SelectedMedia = media;
     UpdateCollectors();
     if (media.DataCollectorId == null)
     {
         UpdateMedias();
     }
     if (!string.IsNullOrEmpty(SelectedMedia.Settings))
     {
         Media.Settings = SelectedMedia.Settings;
         ((IGXPropertyPage)PropertiesForm).Initialize();
     }
 }
		/// <summary>
		/// Create a copy of the GXPacket.
		/// </summary>
        public void Copy(GXPacket source)
        {
            Clear();
            lock (source.SyncRoot)
            {
                AppendData(source.ExtractData(typeof(byte[]), 0, -1));
                this.Bop = source.Bop;
                this.Eop = source.Eop;
                this.ChecksumSettings.Copy(source.ChecksumSettings);
				this.Sender = source.Sender;
            }
        }
 /// <summary>
 /// Remove client from the server.
 /// </summary>
 /// <param name="server"></param>
 /// <param name="client"></param>
 public static void Release(GXServer server, GXClient client)
 {
     lock (m_syncRoot)
     {
         try
         {
             if (client.Tracing)
             {
                 server.Media.OnTrace -= new TraceEventHandler(client.media_OnTrace);
                 client.Tracing = false;
             }
         }
         catch (Exception ex)
         {
             //Ignore if fails.
             System.Diagnostics.Debug.WriteLine(ex.Message);
         }
         int cnt = 0;
         lock (server.Clients.SyncRoot)
         {                    
             cnt = server.Clients.Count;
         }
         if (cnt == 1)
         {
             server.m_Sender.Closing.Set();
             server.m_Receiver.Closing.Set();
             server.m_SendThread.Join();
             server.m_ReceiverThread.Join();
             if (server.Media != null)
             {                        
                 if (server.Media != null)
                 {
                     server.Media.Close();
                 }                        
             }
             server.Clients.Remove(client);
             m_instances.Remove(server.m_Name);
         }
         else
         {
             server.Clients.Remove(client);
         }
     }
 }
        /// <summary>
        /// GXServer class factory.
        /// </summary>
        public static GXServer Instance(Gurux.Common.IGXMedia media, GXClient client)
        {
            lock (m_syncRoot)
            {                
                if (m_instances == null)
                {
                    m_instances = new Dictionary<string, GXServer>();
                    Handlers = new Dictionary<IGXEventHandler, object>();
                }
                string name = media.Name;
                if (string.IsNullOrEmpty(name))
                {
                    name = media.MediaType;
                }
                GXServer server;
                if (m_instances.ContainsKey(name))
                {
                    server = m_instances[name];
                    if (server.m_bParseReceivedPacket != client.ParseReceivedPacket)
                    {
                        throw new Exception(Resources.ServerFailedToAcceptNewClientParseReceivedPacketValueIsInvalid);
                    }
					if (!object.Equals(server.m_ReplyPacket.Eop, client.Eop))
                    {
                        throw new Exception(Resources.ServerFailedToAcceptNewClientEopValueIsInvalid);
                    }
                    if (!object.Equals(server.m_ReplyPacket.Bop, client.Bop))
                    {
                        throw new Exception(Resources.ServerFailedToAcceptNewClientBopValueIsInvalid);
                    }
                    if (server.m_ReplyPacket.ByteOrder != client.ByteOrder)
                    {
                        throw new Exception(Resources.ServerFailedToAcceptNewClientByteOrdersAreNotSame);
                    }
                    if (server.m_ReplyPacket.MinimumSize != client.MinimumSize)
                    {
                        throw new Exception(Resources.ServerFailedToAcceptNewClientMinimumSizeValueIsInvalid);
                    }
                    if (!server.m_ReplyPacket.ChecksumSettings.Equals(client.ChecksumSettings))
                    {
                        throw new Exception(Resources.ServerFailedToAcceptNewClientChecksumSettingsAreNotSame);
                    }                    
                    lock (server.Clients.SyncRoot)
                    {
                        server.Clients.Add(client);
                    }
                    return server;
                }                
                server = new GXServer(name);
                server.m_ReplyPacket = client.CreatePacket();
                lock (server.Clients.SyncRoot)
                {
                    server.Clients.Add(client);
                }
                server.m_bParseReceivedPacket = client.ParseReceivedPacket;
                media.OnClientDisconnected += new Gurux.Common.ClientDisconnectedEventHandler(server.OnClientDisconnected);
                media.OnClientConnected += new Gurux.Common.ClientConnectedEventHandler(server.OnClientConnected);
                media.OnError += new Gurux.Common.ErrorEventHandler(server.OnError);
                media.OnMediaStateChange += new Gurux.Common.MediaStateChangeEventHandler(server.OnMediaStateChange);
                media.OnReceived += new Gurux.Common.ReceivedEventHandler(server.OnReceived);
                server.m_Media = media;
                m_instances[name] = server;
                server.m_Sender = new GXServerSender(server);
                server.m_Receiver = new GXServerReceiver(server);                
                server.m_SendThread = new Thread(new ThreadStart(server.m_Sender.Run));
                server.m_SendThread.IsBackground = true;
                server.m_SendThread.Start();
                server.m_ReceiverThread = new Thread(new ThreadStart(server.m_Receiver.Run));
                server.m_ReceiverThread.IsBackground = true;
                server.m_ReceiverThread.Start();
                return server;
            }
        }
 /// <summary>
 /// Copy client and media settings from the source.
 /// </summary>
 /// <param name="source">Source where settings are copied.</param>
 public void Copy(GXClient source)
 {
     lock (this.SyncRoot)
     {
         lock (source.SyncRoot)
         {
             CloseServer();
             this.Bop = source.Bop;
             this.ByteOrder = source.ByteOrder;
             this.ChecksumSettings.Copy(source.ChecksumSettings);
             this.Eop = source.Eop;
             this.Eop = source.PacketParser;
             this.ParseReceivedPacket = source.ParseReceivedPacket;
             this.ResendCount = source.ResendCount;
             this.WaitTime = source.WaitTime;
             //Copy media settings.                    
             if (source.Media != null)
             {
                 IGXMedia media = this.SelectMedia(source.Media.MediaType) as IGXMedia;
                 media.Settings = source.Media.Settings;
                 this.AssignMedia(media);
             }
         }
     }
 }
 /// <summary>
 /// Creates a copy of the client.
 /// </summary>
 /// <returns>Cloned client.</returns>
 public GXClient Clone()
 {
     GXClient client = new GXClient();
     client.Copy(this);
     return client;
 }
 private void MediaCB_SelectedIndexChanged(object sender, EventArgs e)
 {
     try
     {
         MediaFrame.Controls.Clear();
         if (Target.Media == null || Target.Media.MediaType != MediaCB.Text)
         {
             GXClient cl = new GXClient();
             Target.Media = cl.SelectMedia(MediaCB.Text);
             if (Target.Media == null)
             {
                 throw new Exception(MediaCB.Text + " media not found.");
             }
         }
         if (Target.GXClient != null && Target.GXClient.PacketParser != null)
         {
             Target.GXClient.PacketParser.InitializeMedia(Target.GXClient, Target.Media);
         }
         if (!string.IsNullOrEmpty(Target.MediaSettings))
         {
             Target.Media.Settings = Target.MediaSettings;
         }
         if (Target.Media is GXSerial)
         {
             (Target.Media as GXSerial).AvailablePorts = (DataCollectorCB.SelectedItem as GXAmiDataCollector).SerialPorts;
         }
         else if (Target.Media is GXTerminal)
         {
             (Target.Media as GXTerminal).AvailablePorts = (DataCollectorCB.SelectedItem as GXAmiDataCollector).SerialPorts;
         }
         PropertiesForm = Target.Media.PropertiesForm;
         ((IGXPropertyPage)PropertiesForm).Initialize();
         while (PropertiesForm.Controls.Count != 0)
         {
             Control ctr = PropertiesForm.Controls[0];
             if (ctr is Panel)
             {
                 if (!ctr.Enabled)
                 {
                     PropertiesForm.Controls.RemoveAt(0);
                     continue;
                 }
             }
             MediaFrame.Controls.Add(ctr);
         }
     }
     catch (Exception ex)
     {
         GXCommon.ShowError(this, ex);
     }
 }
Beispiel #9
0
 private void SendPacket(GXClient client, int delay, GXPacket packet)
 {
     if (ReserveMedia)
     {
         lock (client.SyncCommunication)
         {
             Statistics.PacketSendTime = DateTime.Now;
             if (delay > 0 && Statistics.PacketReceiveTime != DateTime.MinValue)
             {
                 delay -= (int)(DateTime.Now - Statistics.PacketReceiveTime).TotalMilliseconds;
                 if (delay > 0)
                 {
                     if (Tracing && m_OnTrace != null)
                     {
                         m_OnTrace(this, new TraceEventArgs(TraceTypes.Info, string.Format(Resources.Wait0MsBeforeNextPacketIsSend, delay), null));
                     }
                     System.Threading.Thread.Sleep(delay);
                 }
             }
             client.Send(packet, true);
         }
     }
     else
     {
         Statistics.PacketSendTime = DateTime.Now;
         if (delay > 0 && Statistics.PacketReceiveTime != DateTime.MinValue)
         {
             delay -= (int)(DateTime.Now - Statistics.PacketReceiveTime).TotalMilliseconds;
             if (delay > 0)
             {
                 if (Tracing && m_OnTrace != null)
                 {
                     m_OnTrace(this, new TraceEventArgs(TraceTypes.Info, string.Format(Resources.Wait0MsBeforeNextPacketIsSend, delay), null));
                 }
                 System.Threading.Thread.Sleep(delay);
             }
         }
         client.Send(packet, true);
     }
     if (!IsCancelled)
     {
         Statistics.PacketReceiveTime = DateTime.Now;
     }
 }
Beispiel #10
0
		/// <summary>
		/// Execute transaction.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="client"></param>
		/// <param name="att"></param>
		/// <param name="initialTransaction"></param>
		/// <param name="read"></param>
		/// <returns>Returs False if if there are more items to read.</returns>
		internal bool Execute(object sender, object parameters, GXClient client, GXCommunicationMessageAttribute att, bool initialTransaction, bool read)
		{
            //If transaction is cancelled.
            if (IsCancelled)
            {
                return false;
            }
            if (Keepalive.TransactionResets)
			{
				if (client.Trace >= System.Diagnostics.TraceLevel.Info)
				{
					Gurux.Common.GXCommon.TraceWriteLine(DateTime.Now.ToShortTimeString() + " Resets keepalive.");
				}
				Keepalive.Reset();
			}
			if (att != null)
			{
                if (!initialTransaction && att.EnableParentRead)
				{
					return true;
				}
                int delay = 0;
				GXProperty prop = null;
				GXCategory cat = null;
				GXTable table = null;
				GXDevice device = null;
				if (sender is GXProperty)
				{
					prop = sender as GXProperty;
					prop.NotifyPropertyChange(read ? PropertyStates.ReadStart : PropertyStates.WriteStart);
                    delay = prop.TransactionDelay;
                    //If device transaction delay is used.
                    if (delay == -1)
                    {
                        delay = prop.Device.TransactionDelay;
                    }
				}
				else if (sender is GXCategory)
				{
					cat = sender as GXCategory;
				}
				else if (sender is GXTable)
				{
					table = sender as GXTable;
                    delay = table.TransactionDelay;
                    //If device transaction delay is used.
                    if (delay == -1)
                    {
                        delay = table.Device.TransactionDelay;
                    }
				}
				else if (sender is GXDevice)
				{
					device = sender as GXDevice;
                    delay = device.TransactionDelay;
				}
				DateTime start = DateTime.Now;
                List<GXPacket> packets = new List<GXPacket>();
                try
                {
                    GXPacket packet = client.CreatePacket();
                    packets.Add(packet);
                    if (!string.IsNullOrEmpty(att.RequestMessageHandler))
                    {
                        if (att is GXEventMessage)
                        {
                            object[] tmp = (object[])parameters;
                            this.PacketHandler.ExecuteNotifyCommand(sender, att.RequestMessageHandler, packet, (byte[])tmp[0], (string)(tmp[1]));
                        }
                        else
                        {
                            this.PacketHandler.ExecuteSendCommand(sender, att.RequestMessageHandler, packet);
                        }
                        //If there is no data to send.
                        if (packet.GetSize(PacketParts.Data) == 0)
                        {
                            return true;
                        }
                        //If we are not expected reply.
                        if (string.IsNullOrEmpty(att.ReplyMessageHandler))
                        {
                            packet.ResendCount = -1;
                        }

                        SendPacket(client, delay, packet);
                        //If transaction is cancelled.
                        if (IsCancelled)
                        {
                            return false;
                        }
                        if ((packet.Status & (PacketStates.Timeout | PacketStates.SendFailed)) != 0)
                        {
                            //If connection is closed.
                            if (!client.MediaIsOpen)
                            {
                                return false;
                            }
                            if ((packet.Status & PacketStates.Timeout) != 0)
                            {
                                throw new Exception(Resources.TimeoutOccurred);
                            }
                            else
                            {
                                throw new Exception(Resources.SendFailed);
                            }
                        }
                        if (string.IsNullOrEmpty(att.IsAllSentMessageHandler))
                        {
                            if (!string.IsNullOrEmpty(att.ReplyMessageHandler))
                            {
                                this.PacketHandler.ExecuteParseCommand(sender, att.ReplyMessageHandler, packets.ToArray());

                            }
                        }
                        else
                        {
                            while (!Closing && !this.PacketHandler.IsTransactionComplete(sender, att.IsAllSentMessageHandler, packet))
                            {
                                if (Keepalive.TransactionResets)
                                {
                                    if (client.Trace >= System.Diagnostics.TraceLevel.Info)
                                    {
                                        Gurux.Common.GXCommon.TraceWriteLine(DateTime.Now.ToShortTimeString() + " Resets keepalive.");
                                    }
                                    Keepalive.Reset();
                                }
                                packet = client.CreatePacket();
                                packets.Add(packet);
                                this.PacketHandler.ExecuteSendCommand(sender, att.AcknowledgeMessageHandler, packet);
                                //If there is no data to send.
                                if (packet.GetSize(PacketParts.Data) == 0)
                                {
                                    throw new Exception(Resources.InvalidAcknowledgeMessage + att.AcknowledgeMessageHandler + ".");
                                }
                                SendPacket(client, delay, packet);
                                if ((packet.Status & (PacketStates.Timeout | PacketStates.SendFailed)) != 0)
                                {
                                    //If connection is closed.
                                    if (!client.MediaIsOpen)
                                    {
                                        return false;
                                    }
                                    if ((packet.Status & PacketStates.Timeout) != 0)
                                    {
                                        throw new Exception(Resources.TimeoutOccurred);
                                    }
                                    else
                                    {
                                        throw new Exception(Resources.SendFailed);
                                    }
                                }
                            }
                            this.PacketHandler.ExecuteParseCommand(sender, att.ReplyMessageHandler, packets.ToArray());
                        }
                        if (prop != null)
                        {
                            if (read)
                            {
                                ++prop.Statistics.ReadCount;
                            }
                            else
                            {
                                ++prop.Statistics.WriteCount;
                            }
                            prop.Statistics.UpdateExecutionTime(DateTime.Now - start);
                            prop.NotifyPropertyChange(read ? PropertyStates.ReadEnd : PropertyStates.WriteEnd);
                        }
                        else if (cat != null)
                        {
                            if (read)
                            {
                                ++cat.Statistics.ReadCount;
                            }
                            else
                            {
                                ++cat.Statistics.WriteCount;
                            }
                            cat.Statistics.UpdateExecutionTime(DateTime.Now - start);
                        }
                        else if (table != null)
                        {
                            if (read)
                            {
                                ++table.Statistics.ReadCount;
                            }
                            else
                            {
                                ++table.Statistics.WriteCount;
                            }
                            table.Statistics.UpdateExecutionTime(DateTime.Now - start);
                        }
                        else if (device != null && !(att is GXInitialActionMessage))
                        {
                            if (read)
                            {
                                ++device.Statistics.ReadCount;
                            }
                            else
                            {
                                ++device.Statistics.WriteCount;
                            }
                            device.Statistics.UpdateExecutionTime(DateTime.Now - start);
                        }
                    }
                }
                catch (Exception Ex)
                {
                    if (prop != null)
                    {
                        if (read)
                        {
                            ++prop.Statistics.ReadFailCount;
                        }
                        else
                        {
                            ++prop.Statistics.WriteFailCount;
                        }

                    }
                    else if (cat != null)
                    {
                        if (read)
                        {
                            ++cat.Statistics.ReadFailCount;
                        }
                        else
                        {
                            ++cat.Statistics.WriteFailCount;
                        }
                    }
                    else if (table != null)
                    {
                        if (read)
                        {
                            ++table.Statistics.ReadFailCount;
                        }
                        else
                        {
                            ++table.Statistics.WriteFailCount;
                        }
                    }
                    else if (device != null && !(att is GXInitialActionMessage))
                    {
                        if (read)
                        {
                            ++device.Statistics.ReadFailCount;
                        }
                        else
                        {
                            ++device.Statistics.WriteFailCount;
                        }
                    }
                    if (prop != null)
                    {
                        throw new Exception(string.Format(Resources.ReadFailed, prop.Name, Ex.Message), Ex);
                    }
                    else if (cat != null)
                    {
                        throw new Exception(string.Format(Resources.ReadFailed, cat.Name, Ex.Message), Ex);
                    }
                    else if (table != null)
                    {
                        throw new Exception(string.Format(Resources.ReadFailed, table.Name, Ex.Message), Ex);
                    }
                    NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(sender, 1, 1, DeviceStates.ReadEnd));
                    throw Ex;
                }
                finally
                {
                    client.ReleasePacket(packets);
                }
			}
			else //If selected item do not have transaction messages.
			{
                if ((Status & DeviceStates.Disconnecting) != 0)
                {
                    return false;
                }
				//If we have read all items...
				if (TransactionObject == sender)
				{
					return false;
				}
				if (TransactionObject == null)
				{
					TransactionObject = sender;
				}
				if (sender is GXDevice)
				{
					//If we have read all items...
					if (TransactionObject is GXTable || TransactionObject is GXTable || TransactionObject is GXProperty)
					{
						return false;
					}
					bool bFound = false;
					if (TransactionObject == sender)
					{
						TransactionPos = 1;
						TransactionCount = this.Tables.Count;
						foreach (GXCategory cat in this.Categories)
						{
                            if (Closing)
                            {
                                break;
                            }
                            if (GXDeviceList.CanExecute(cat.DisabledActions, Status, read))
                            {
                                TransactionCount += cat.Properties.Count + 1;
                            }
						}
						NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(sender, 0, TransactionCount, read ? DeviceStates.ReadStart : DeviceStates.WriteStart));
					}
					try
					{
						foreach (GXCategory it in this.Categories)
						{
                            if (!Closing && GXDeviceList.CanExecute(it.DisabledActions, Status, read))
                            {
                                List<KeyValuePair<GXCommunicationMessageAttribute, object>> attributes = new List<KeyValuePair<GXCommunicationMessageAttribute, object>>();
                                GetCommunicationMessageAttributes(it, read ? typeof(GXReadMessage) : typeof(GXWriteMessage), attributes, false);
                                if (attributes.Count == 0)
                                {
                                    if (!Execute(it, parameters, client, null, initialTransaction, read))
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    foreach (var it2 in attributes)
                                    {
                                        TransactionObject = null;
                                        if (!Execute(it2.Value, parameters, this.GXClient, it2.Key, true, read))
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
						}
						foreach (GXTable it in this.Tables)
						{
                            if (!Closing && GXDeviceList.CanExecute(it.DisabledActions, Status, read))
                            {
                                List<KeyValuePair<GXCommunicationMessageAttribute, object>> attributes = new List<KeyValuePair<GXCommunicationMessageAttribute, object>>();
                                GetCommunicationMessageAttributes(it, read ? typeof(GXReadMessage) : typeof(GXWriteMessage), attributes, false);
                                if (attributes.Count == 0)
                                {
                                    if (!Execute(it, parameters, client, null, initialTransaction, read))
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    foreach (var it2 in attributes)
                                    {
                                        TransactionObject = null;
                                        if (!Execute(it2.Value, parameters, this.GXClient, it2.Key, true, read))
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
						}
						if (read)
						{
							++this.Statistics.ReadCount;
						}
						else
						{
							++this.Statistics.WriteCount;
						}
					}
					catch (Exception Ex)
					{
						if (read)
						{
							++this.Statistics.ReadFailCount;
						}
						else
						{
							++this.Statistics.WriteFailCount;
						}
						throw Ex;
					}
					finally
					{
						if (TransactionObject == sender)
						{
							NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(sender, TransactionCount, TransactionCount, read ? DeviceStates.ReadEnd : DeviceStates.WriteEnd));
							TransactionCount = TransactionPos = 1;
						}
					}
					return bFound;
				}
				if (sender is GXProperty)
				{
					if (TransactionObject is GXProperty)
					{
						try
						{
							NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(sender, 0, 1, read ? DeviceStates.ReadStart : DeviceStates.ReadStart));
                            object it = (sender as GXProperty).Parent.Parent;
							List<KeyValuePair<GXCommunicationMessageAttribute, object>> attributes = new List<KeyValuePair<GXCommunicationMessageAttribute, object>>();
							GetCommunicationMessageAttributes(it, read ? typeof(GXReadMessage) : typeof(GXWriteMessage), attributes, false);
							foreach (var cAtt in attributes)
							{
                                if (Closing)
                                {
                                    break;
                                }
                                if (!Execute(it, parameters, client, cAtt.Key, initialTransaction, read))
								{
									return false;
								}
							}
							return true;
						}
						finally
						{
							NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(sender, 1, 1, read ? DeviceStates.ReadEnd : DeviceStates.WriteEnd));
						}
					}
					return false;
				}
				if (sender is GXCategory)
				{
					if (TransactionObject is GXProperty)
					{
                        GXDevice device = (sender as GXCategory).Device;
						List<KeyValuePair<GXCommunicationMessageAttribute, object>> attributes = new List<KeyValuePair<GXCommunicationMessageAttribute, object>>();
						GetCommunicationMessageAttributes(device, read ? typeof(GXReadMessage) : typeof(GXWriteMessage), attributes, false);
						foreach (var cAtt in attributes)
						{
                            if (Closing)
                            {
                                break;
                            }
                            if (!Execute(device, parameters, client, cAtt.Key, initialTransaction, read))
							{
								return false;
							}
						}
						return true;
					}
					bool bFound = false;
					if (TransactionObject == sender)
					{
						TransactionPos = 1;
                        TransactionCount = (sender as GXCategory).Properties.Count + 1;
						NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(sender, 0, TransactionCount, read ? DeviceStates.ReadStart : DeviceStates.ReadStart));
					}
					try
					{
						bFound = true;
                        foreach (GXProperty it in (sender as GXCategory).Properties)
						{
                            if (!Closing && GXDeviceList.CanExecute(it.DisabledActions, Status, read))
                            {
                                NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(it, TransactionPos++, TransactionCount, read ? DeviceStates.ReadStart : DeviceStates.ReadStart));
                                List<KeyValuePair<GXCommunicationMessageAttribute, object>> attributes = new List<KeyValuePair<GXCommunicationMessageAttribute, object>>();
                                GetCommunicationMessageAttributes(it, read ? typeof(GXReadMessage) : typeof(GXWriteMessage), attributes, false);
                                foreach (var cAtt in attributes)
                                {
                                    if (!Execute(it, parameters, client, cAtt.Key, initialTransaction, read))
                                    {
                                        break;
                                    }
                                }                                
                                NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(it, TransactionPos, TransactionCount, read ? DeviceStates.ReadEnd : DeviceStates.WriteEnd));
                            }
						}
						if (read)
						{
                            ++(sender as GXCategory).Statistics.ReadCount;
						}
						else
						{
                            ++(sender as GXCategory).Statistics.WriteCount;
						}
					}
					catch (Exception Ex)
					{
						if (read)
						{
                            ++(sender as GXCategory).Statistics.ReadFailCount;
						}
						else
						{
                            ++(sender as GXCategory).Statistics.WriteFailCount;
						}
						throw Ex;
					}
					finally
					{
						if (TransactionObject == sender)
						{
							NotifyTransactionProgress(this, new GXTransactionProgressEventArgs(sender, TransactionCount, TransactionCount, read ? DeviceStates.ReadEnd : DeviceStates.WriteEnd));
							TransactionCount = TransactionPos = 1;
						}
					}
					return bFound;
				}
				if (sender is GXTable)
				{
					try
					{
						GXDevice device = ((GXTable)sender).Device;
						List<KeyValuePair<GXCommunicationMessageAttribute, object>> attributes = new List<KeyValuePair<GXCommunicationMessageAttribute, object>>();
						GetCommunicationMessageAttributes(device, read ? typeof(GXReadMessage) : typeof(GXWriteMessage), attributes, false);
						foreach (var cAtt in attributes)
						{
                            if (Closing)
                            {
                                break;
                            }
                            if (!Execute(device, parameters, client, cAtt.Key, initialTransaction, read))
							{
								return false;
							}
						}						
						if (read)
						{
							++((GXTable)sender).Statistics.ReadCount;
						}
						else
						{
							++((GXTable)sender).Statistics.WriteCount;
						}
						return true;
					}
					catch (Exception Ex)
					{
						if (read)
						{
							++((GXTable)sender).Statistics.ReadFailCount;
						}
						else
						{
							++((GXTable)sender).Statistics.WriteFailCount;
						}
						throw Ex;
					}
				}
			}
			return true;
		}