public override void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } var cmd = TheCommonUtils.cdeSplit(pMsg.Message.TXT, ":", false, false); switch (cmd[0]) { case nameof(MsgAddConnectionThing <TConnectionThingParam>): var addMsg = TheCommRequestResponse.ParseRequestMessageJSON <MsgAddConnectionThing <TConnectionThingParam> >(pMsg.Message); var responseMsg = new MsgAddConnectionThingResponse { Error = "Unexpected" }; if (addMsg != null) { var thingToAdd = addMsg.ThingToAdd; if (thingToAdd != null) { var currentThing = MyConnectionThings.MyMirrorCache.GetEntryByID(thingToAdd.cdeMID); var newThing = new TConnectionThing(); newThing.Initialize(thingToAdd); if (currentThing == null) { MyConnectionThings.AddAnItem(newThing); responseMsg.Error = null; } else { if (!newThing.IsEqual(currentThing)) { UpdateConnectionThing(currentThing, newThing); MyConnectionThings.UpdateItem(newThing); Connect(); } responseMsg.Error = null; } } else { responseMsg.Error = "INVALIDARGS"; } } TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, responseMsg); break; default: base.HandleMessage(sender, pIncoming); break; } }
/// <summary> /// Handles Messages sent from a host sub-engine to its clients /// </summary> /// <param name="sender"></param> /// <param name="pIncoming"></param> public void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null) { return; } string[] cmd = pMsg.Message.TXT.Split(':'); switch (cmd[0]) { case "CDE_INITIALIZED": MyBaseEngine.SetInitialized(pMsg.Message); break; case nameof(MsgMileRecordHolder): if (g_EnableMeshDataResponse) { // Request from another node for mile record holder information. var request = TheCommRequestResponse.ParseRequestMessageJSON <MsgMileRecordHolder>(pMsg.Message); var MsgResponse = new MsgMileRecordHolderResponse(); if (request != null) { MsgResponse.data = TheRecordHolder.QueryRecordHolder(request.id); } TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, MsgResponse); MsgResponse = null; // Prevent legacy response handler for being sent. } break; default: break; } }
private void HandleMessage(ICDEThing arg1, object arg2) { var msg = (arg2 as TheProcessMessage).Message; if (msg == null) { return; } var messageName = TheCommRequestResponse.ParseRequestOrResponseMessage(msg, out var messageParameters, out var correlationToken); switch (messageName) { case nameof(MsgChatHello): { var request = TheCommRequestResponse.ParseRequestMessageJSON <MsgChatHello>(msg); if (request != null) { // Messages come in on a .Net Threadpool thread, so need to dispatch it to the WPF main thread before we can access any WPF controls this.Dispatcher.InvokeAsync(() => { var chatMessage = new ChatMessage { MessageId = correlationToken, SenderName = request.SenderName, Message = request.Message, SeenBy = 0, Sent = msg.TIM, Received = DateTimeOffset.Now, }; MessageList.Items.Insert(0, chatMessage); }); TheCommRequestResponse.PublishResponseMessageJson(msg, new MsgChatHelloResponse { Acknowledged = true }); } else { TheCommRequestResponse.PublishResponseMessageJson(msg, new MsgChatHelloResponse { Acknowledged = false }); } } break; case nameof(MsgChatHello) + "_RESPONSE": { var request = TheCommRequestResponse.ParseRequestMessageJSON <MsgChatHelloResponse>(msg); if (request != null) { this.Dispatcher.InvokeAsync(() => { if (request.Acknowledged) { int i = 0; foreach (var item in MessageList.Items) { var chatMessage = item as ChatMessage; if (chatMessage != null) { if (chatMessage.MessageId == correlationToken) { chatMessage.SeenBy++; MessageList.Items.RemoveAt(i); MessageList.Items.Insert(i, chatMessage); break; } } i++; } } else { MessageBox.Show($"Somebody ({msg.ORG}) rejected our message {correlationToken}"); } }); } else { // Somebody is sending MsgChatHelloResponse messages in an unknown/incompatible format, or somebody rejected a message for some reason this.Dispatcher.InvokeAsync(() => { MessageBox.Show($"Received invalid MsgChatHelloResponse: {msg}"); }); } } break; } }
public override void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } var cmd = pMsg.Message.TXT.Split(':'); switch (cmd[0]) { case "CALL_METHOD": case nameof(MsgOPCUAMethodCall): string error = "Unexpected"; string exceptionText = ""; MsgOPCUAMethodCall callInfo = null; byte[] largeOutput = null; string outParamsAsJson = null; IList <object> outputArguments = null; if (m_Method == null) { error = "Method meta data not initialized"; } else if (m_Method.MyOPCServer == null) { error = "Method not inititialized"; } else if (m_Method.MyOPCServer.m_session == null) { error = "OPC UA session not created"; } else { try { if (TheCommonUtils.cdeIsLocked(m_Method)) { TheBaseAssets.MySYSLOG.WriteToLog(78401, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM(MyBaseThing.EngineName, String.Format("[{0}] Method called concurrently", m_Method.MyOPCServer.GetLogAddress()), eMsgLevel.l4_Message, String.Format("{0}", MyBaseThing.Address))); } lock (m_Method) { if (m_Method.Args == null) { var browseError = m_Method.MyOPCServer.MethodBrowser(m_Method.TagRef, m_Method.DisplayName, m_Method); if (!string.IsNullOrEmpty(browseError)) { error = "Unable to retrieve method metadata from server: " + browseError; } } if (m_Method.Args == null) { error = "Unable to retrieve method metadata from server"; } else { if (!string.IsNullOrEmpty(pMsg.Message.PLS)) { if (cmd[0] == nameof(MsgOPCUAMethodCall)) { callInfo = TheCommRequestResponse.ParseRequestMessageJSON <MsgOPCUAMethodCall>(pMsg.Message); foreach (var argument in callInfo.Arguments) { TheThing.SetSafeProperty(this, argument.Key, argument.Value, ePropertyTypes.NOCHANGE); } } else { var tLst = TheCommonUtils.cdeSplit(pMsg.Message.PLS, ":;:", true, true).ToList(); foreach (string t in tLst) { TheThing.SetPropertyFromBagItem(this, t); } } } object[] tArgs = new object[InputArgCnt]; for (int i = 0; i < InputArgCnt; i++) { tArgs[i] = TheOPCTag.GetOPCValueFromCDEValue(InputArgs[i].cdeProperty == null ? null : InputArgs[i].cdeProperty.Value, InputArgs[i].OPCType); } #if OLD_UA outputArguments = m_Method.MyOPCServer.m_session.CallWithTimeout(m_Method.ParentId, m_Method.TagRef, MethodCallTimeout, tArgs); #else outputArguments = m_Method.MyOPCServer.m_session.Call(m_Method.ParentId, m_Method.TagRef, tArgs); //CM: C-labs extension: .CallWithTimeout(m_Method.ParentId, m_Method.TagRef, MethodCallTimeout, tArgs); #endif if (cmd[0] != nameof(MsgOPCUAMethodCall)) { if (TheThing.GetSafePropertyBool(this, "ReturnOutputAsJson")) { outParamsAsJson = TheCommonUtils.SerializeObjectToJSONString(outputArguments); //TheThing.SetSafePropertyString(this, "OutputAsJson", outParamsAsJson); } else { if (outputArguments != null && outputArguments.Count > 0) { for (int i = 0; i < outputArguments.Count; i++) { if (i < OutputArgs.Count) { object value; if (outputArguments[i] is byte[] && (outputArguments[i] as byte[]).Length > 4096 && largeOutput == null) { largeOutput = outputArguments[i] as byte[]; value = ""; } else { value = outputArguments[i]; } cdeP tP = OutputArgs[i].cdeProperty; if (tP != null) { //TheOPCTag.UpdateValueProperty(outputArguments[i] as DataValue, tP, outputArguments[i] as DataValue); tP.Value = value; // tP.SetValue(outputArguments[i], pMsg.Message.GetOriginator().ToString()); // CODE REVIEW: Why did we set the originator here? It's only really needed for remote things to break update cycles... } } else { TheBaseAssets.MySYSLOG.WriteToLog(78402, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM(MyBaseThing.EngineName, String.Format("[{0}] Error processing method response for OPC Server", m_Method.MyOPCServer.GetLogAddress()), eMsgLevel.l2_Warning, String.Format("{0}: too many out parameters in method", MyBaseThing.Address))); } } } } MyBaseThing.LastUpdate = DateTimeOffset.Now; LastMessage = string.Format("Success at {0}", MyBaseThing.LastUpdate); } error = ""; } } } catch (Exception e) { error = "Method Call failed: " + e.Message; exceptionText = e.ToString(); LastMessage = error; TheBaseAssets.MySYSLOG.WriteToLog(78403, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyBaseThing.EngineName, String.Format("[{0}] Method Call failed", m_Method.MyOPCServer.GetLogAddress()), eMsgLevel.l1_Error, String.Format("{0}:{1}", MyBaseThing.Address, e.ToString()))); } } if (cmd[0] == nameof(MsgOPCUAMethodCall)) { if (callInfo?.ReturnRawJSON == true) { TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, new MsgOPCUAMethodCallResponse { OutputArguments = new List <object> { TheCommonUtils.SerializeObjectToJSONString(outputArguments) }, Error = error }); } else { TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, new MsgOPCUAMethodCallResponse { OutputArguments = (List <object>)outputArguments, Error = error }); } } else { TSM tTSN = new TSM(MyBaseThing.EngineName, string.Format(String.IsNullOrEmpty(error) ? "CALL_METHOD_RESPONSE:{0}:{1}" : "CALL_METHOD_RESPONSE:{0}:{1}:{2}:{3}", MyBaseThing.ID, cmd[1], error.Replace(":", " "), exceptionText.Replace(":", " "))); if (largeOutput != null && String.IsNullOrEmpty(error)) { tTSN.PLB = largeOutput; } if (outParamsAsJson != null && String.IsNullOrEmpty(error)) { tTSN.PLS = outParamsAsJson; } if (pMsg.LocalCallback != null) { pMsg.LocalCallback(tTSN); } else { TheCommCore.PublishToOriginator(pMsg.Message, tTSN); } } break; } base.HandleMessage(this, pMsg); }
/// <summary> /// Handles Messages sent from a host sub-engine to its clients /// </summary> /// <param name="Command"></param> /// <param name="pMessage"></param> public override void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null) { return; } string[] cmd = pMsg.Message.TXT.Split(':'); switch (cmd[0]) { case nameof(TheThing.MsgBrowseSensors): var browseRequest = TheCommRequestResponse.ParseRequestMessageJSON <TheThing.MsgBrowseSensors>(pMsg.Message); var browseResponse = new TheThing.MsgBrowseSensorsResponse { Error = "Internal error", Sensors = new List <TheThing.TheSensorSourceInfo>() }; foreach (FieldMapping fld in MyModFieldStore.TheValues) { browseResponse.Sensors.Add(new TheThing.TheSensorSourceInfo { SourceType = fld.SourceType, cdeType = ePropertyTypes.TNumber, SensorId = TheCommonUtils.CStr(fld.cdeMID), ExtensionData = new Dictionary <string, object> { { nameof(FieldMapping.SourceOffset), fld.SourceOffset }, { nameof(FieldMapping.SourceSize), fld.SourceSize }, { nameof(FieldMapping.AllowWrite), fld.AllowWrite } }, DisplayNamePath = new string[] { MyBaseEngine.GetEngineName(), MyBaseThing.FriendlyName, fld.PropertyName } }); } browseResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, browseResponse); break; case nameof(TheThing.MsgSubscribeSensors): var subscribeRequest = TheCommRequestResponse.ParseRequestMessageJSON <TheThing.MsgSubscribeSensors>(pMsg.Message); var subscribeResponse = new TheThing.MsgSubscribeSensorsResponse { Error = "Internal error", SubscriptionStatus = new List <TheThing.TheSensorSubscriptionStatus>() }; if (subscribeRequest.ReplaceAll) { MyModFieldStore.RemoveAllItems(); } var subscriptionStatus = new List <TheThing.TheSensorSubscriptionStatus>(); foreach (TheThing.TheSensorSubscription sub in subscribeRequest.SubscriptionRequests) { FieldMapping fld = new FieldMapping() { PropertyName = sub.TargetProperty, cdeMID = TheCommonUtils.CGuid(sub.SensorId) }; if (fld.cdeMID == Guid.Empty) { fld.cdeMID = Guid.NewGuid(); } object sourceType; if (sub.ExtensionData != null) { if (sub.ExtensionData.TryGetValue(nameof(TheThing.TheSensorSourceInfo.SourceType), out sourceType)) { fld.SourceType = TheCommonUtils.CStr(sourceType); } object offset; if (sub.ExtensionData.TryGetValue("SourceOffset", out offset)) { fld.SourceOffset = TheCommonUtils.CInt(offset); } object size; if (sub.ExtensionData.TryGetValue("SourceSize", out size)) { fld.SourceSize = TheCommonUtils.CInt(size); } object allowWrite; if (sub.ExtensionData.TryGetValue("AllowWrite", out allowWrite)) { fld.AllowWrite = TheCommonUtils.CBool(allowWrite); } MyModFieldStore.AddAnItem(fld); subscriptionStatus.Add(CreateSubscriptionStatusFromFieldMapping(fld)); } else { subscriptionStatus.Add(new TheThing.TheSensorSubscriptionStatus { Error = "Missing source info", Subscription = sub, }); } } subscribeResponse.SubscriptionStatus = subscriptionStatus; subscribeResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, subscribeResponse); break; case nameof(TheThing.MsgGetSensorSubscriptions): var getResponse = new TheThing.MsgGetSensorSubscriptionsResponse { Error = "Internal error" }; getResponse.Subscriptions = MyModFieldStore.TheValues.Select(fld => CreateSubscriptionStatusFromFieldMapping(fld).Subscription).ToList(); getResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, getResponse); break; case nameof(TheThing.MsgUnsubscribeSensors): var unsubscribeRequest = TheCommRequestResponse.ParseRequestMessageJSON <TheThing.MsgUnsubscribeSensors>(pMsg.Message); var unsubscribeResponse = new TheThing.MsgUnsubscribeSensorsResponse { Error = "Internal error", Failed = new List <TheThing.TheSensorSubscriptionStatus>() }; if (unsubscribeRequest.UnsubscribeAll) { MyModFieldStore.RemoveAllItems(); if (MyModFieldStore.GetCount() > 0) { unsubscribeResponse.Failed = MyModFieldStore.TheValues.Select(fld => CreateSubscriptionStatusFromFieldMapping(fld)).ToList(); } } else { List <FieldMapping> toRemove = MyModFieldStore.TheValues.FindAll(fld => unsubscribeRequest.SubscriptionIds.Contains(fld.cdeMID)); MyModFieldStore.RemoveItems(toRemove, null); foreach (FieldMapping fld in MyModFieldStore.TheValues) { if (toRemove.Any(t => t.cdeMID == fld.cdeMID)) { unsubscribeResponse.Failed.Add(CreateSubscriptionStatusFromFieldMapping(fld)); } } } unsubscribeResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, unsubscribeResponse); break; case nameof(TheThing.MsgExportConfig): var exportRequest = TheCommRequestResponse.ParseRequestMessageJSON <TheThing.MsgExportConfig>(pMsg.Message); var exportResponse = new TheThing.MsgExportConfigResponse { Error = "Internal error" }; // No custom config beyond config properties and subscriptions exportResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, exportResponse); break; case nameof(TheThing.MsgApplyConfig): break; default: break; } TheThing.TheSensorSubscriptionStatus CreateSubscriptionStatusFromFieldMapping(FieldMapping fld) { return(new TheThing.TheSensorSubscriptionStatus { Subscription = new TheThing.TheSensorSubscription { TargetProperty = fld.PropertyName, SensorId = TheCommonUtils.CStr(fld.cdeMID), SubscriptionId = fld.cdeMID, ExtensionData = new Dictionary <string, object> { { nameof(FieldMapping.SourceType), fld.SourceType }, { nameof(FieldMapping.SourceOffset), fld.SourceOffset }, { nameof(FieldMapping.SourceSize), fld.SourceSize }, { nameof(FieldMapping.AllowWrite), fld.AllowWrite } }, TargetThing = new TheThingReference(MyBaseThing), SampleRate = (int?)this.Interval }, Error = null, }); } }
virtual void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } var cmd = TheCommonUtils.cdeSplit(pMsg.Message.TXT, ":", false, false); switch (cmd[0]) { case "RUREADY": if (cmd.Length > 1 && cmd[1] == TheCommonUtils.cdeGuidToString(MyBaseThing.cdeMID)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(pMsg.Message.ENG, "IS_READY:" + TheCommonUtils.cdeGuidToString(MyBaseThing.cdeMID), mIsInitialized.ToString()) { FLG = 8 }, true); } break; case "CONNECT_SERVER": Connect(); break; case nameof(MsgConnectDisconnect): { var request = TheCommRequestResponse.ParseRequestMessageJSON <MsgConnectDisconnect>(pMsg.Message); var responseMsg = new MsgConnectDisconnectResponse(); if (request == null) { responseMsg.Error = "Error parsing request message"; } else { try { if (request.Connect.HasValue && request.Reconnect.HasValue) { responseMsg.Error = "Can specify at most one of Connect Reconnect"; } else if (!request.Connect.HasValue && !request.Reconnect.HasValue && !request.AutoConnect.HasValue) { responseMsg.Error = "Must specify at least one of Connect Reconnect AutoConnect"; } else { if (request.Connect.HasValue) { if (request.Connect == true) { Connect(); } else { Disconnect(true); } } if (request.Reconnect.HasValue) { Disconnect(true); if (request.WaitTimeBeforeReconnect.HasValue) { try { #if !NET40 await TheCommonUtils.TaskDelayOneEye(request.WaitTimeBeforeReconnect.Value, 100).ConfigureAwait(false); #else TheCommonUtils.TaskDelayOneEye(request.WaitTimeBeforeReconnect.Value, 100).Wait(); #endif } catch (System.Threading.Tasks.TaskCanceledException) { } } Connect(); } if (request.AutoConnect.HasValue) { AutoConnect = request.AutoConnect.Value; } responseMsg.Connected = IsConnected; } } catch (Exception e) { responseMsg.Error = e.Message; } } TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, responseMsg); } break; } }