/// <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); }
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()); }
//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); } } }