Пример #1
0
        /// <summary>
        /// Add a noticiation when a variable changes or cyclic after a defined time in ms
        /// </summary>
        /// <param name="varHandle">The handle returned by GetSymhandleByName</param>
        /// <param name="length">The length of the data that must be send by the notification</param>
        /// <param name="transmissionMode">On change or cyclic</param>
        /// <param name="cycleTime">The cyclic time in ms. If used with OnChange, then the value is send once after this time in ms</param>
        /// <param name="userData">A custom object that can be used in the callback</param>
        /// <param name="TypeOfValue">The type of the returned notification value</param>
        /// <returns>The notification handle</returns>
        public override uint AddNotification(uint varHandle, uint length, AdsTransmissionMode transmissionMode, uint cycleTime, object userData, Type TypeOfValue)
        {
            AdsNotification note = new AdsNotification();

            note.Symhandle   = varHandle;
            note.UserData    = userData;
            note.TypeOfValue = TypeOfValue;
            note.ByteValue   = new byte[length];
            NotificationRequests.Add(note);

            string varName = GetNameBySymhandle(varHandle);

            byte[] buffer = new byte[length];
            adsStream = Activator.CreateInstance(t_AdsStream, new object[] { buffer });

            if (transmissionMode == AdsTransmissionMode.Cyclic)
            {
                adsTransMode = AdsTransMode_Cyclic;
            }
            else
            {
                adsTransMode = AdsTransMode_OnChange;
            }

            note.NotificationHandle =
                (uint)client.AddDeviceNotification(
                    varName,
                    adsStream, (int)0, (int)length,
                    adsTransMode, (int)cycleTime, (int)0,
                    userData);

            return(note.NotificationHandle);
        }
Пример #2
0
        private byte[] CreateNotificationStream(int handler, byte[] data)
        {
            var stream = new AdsNotification()
            {
                Length = (uint)(default(AdsNotification).GetSize() + data.Length),
                Stamps = 1,
                AdsNotificationHeader = new AdsNotificationHeader()
                {
                    Samples   = 1,
                    Timestamp = DateTime.UtcNow.ToFileTime(),
                    Sample    = new AdsNotificationSample()
                    {
                        Handle = (uint)handler,
                        Size   = (uint)data.Length
                    }
                }
            };

            var buffer = new List <byte>();

            buffer.AddRange(stream.GetBytes());
            buffer.AddRange(data);
            return(buffer.ToArray());
        }
Пример #3
0
        //This is different thread!
        private void ReadCallback(object sender, AmsSocketResponseArgs args)
        {
            if (args.Error != null)
            {
                // Lock the list.
                lock (pendingResultsLock)
                {
                    if (pendingResults.Count > 0)
                    {
                        foreach (var adsCommandResult in pendingResults.ToList())
                        {
                            adsCommandResult.UnknownException = args.Error;
                            adsCommandResult.Callback.Invoke(adsCommandResult);
                        }
                    }
                    else
                    {
                        throw args.Error;
                    }
                }
            }

            if ((args.Response != null) && (args.Response.Length > 0) && (args.Error == null))
            {
                uint amsErrorCode   = AmsHeaderHelper.GetErrorCode(args.Response);
                uint invokeId       = AmsHeaderHelper.GetInvokeId(args.Response);
                bool isNotification = (AmsHeaderHelper.GetCommandId(args.Response) == AdsCommandId.DeviceNotification);

                if (AmsPortTarget != AmsHeaderHelper.GetAmsPortSource(args.Response))
                {
                    return;
                }
                if (!AmsNetIdTarget.Bytes.SequenceEqual(AmsHeaderHelper.GetAmsNetIdSource(args.Response)))
                {
                    return;
                }

                //If notification then just start the callback
                if (isNotification && (OnNotification != null))
                {
                    var notifications = AdsNotification.GetNotifications(args.Response);
                    foreach (var notification in notifications)
                    {
                        var notificationRequest = NotificationRequests.FirstOrDefault(n => n.NotificationHandle == notification.NotificationHandle);
                        if (notificationRequest != null)
                        {
                            notificationRequest.ByteValue = notification.ByteValue;

                            if ((args.Context != null) && (RunNotificationsOnMainThread))
                            {
                                args.Context.Post(
                                    new SendOrPostCallback(delegate
                                {
                                    OnNotification(null, new AdsNotificationArgs(notificationRequest));
                                }), null);
                            }
                            else
                            {
                                OnNotification(null, new AdsNotificationArgs(notificationRequest));
                            }
                        }
                    }
                }

                //If not a notification then find the original command and call async callback
                if (!isNotification)
                {
                    AdsCommandResponse adsCommandResult = null;

                    // Do some locking before fiddling with the list.
                    lock (pendingResultsLock)
                    {
                        adsCommandResult = pendingResults.FirstOrDefault(r => r.CommandInvokeId == invokeId);
                        if (adsCommandResult == null)
                        {
                            return;
                        }
                        //throw new AdsException("I received a response from a request I didn't send?");

                        pendingResults.Remove(adsCommandResult);
                    }

                    if (amsErrorCode > 0)
                    {
                        adsCommandResult.AmsErrorCode = amsErrorCode;
                    }
                    else
                    {
                        adsCommandResult.SetResponse(args.Response);
                    }
                    adsCommandResult.Callback.Invoke(adsCommandResult);
                }
            }
        }