private bool DecodeAndParseStatusMessage(RSMP_Messages.Header packetHeader, StatusMsgType statusMsgType, string sJSon, bool bUseStrictProtocolAnalysis, bool bUseCaseSensitiveIds, ref bool bHasSentAckOrNack, ref string sError) { StringComparison sc = bUseCaseSensitiveIds ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; bool bSuccess = true; // Values to return List <RSMP_Messages.Status_VTQ> sS = new List <RSMP_Messages.Status_VTQ>(); try { // StatusSubscribe, StatusUnsubscribe and StatusRequest are very much alike, differns by the uRt property only RSMP_Messages.StatusSubscribe_Over_3_1_4 StatusSubscribe = JSonSerializer.Deserialize <RSMP_Messages.StatusSubscribe_Over_3_1_4>(sJSon); foreach (RSMP_Messages.StatusSubscribe_Status_Over_3_1_4 StatusSubscribe_Status in StatusSubscribe.sS) { if (StatusSubscribe_Status.sCI == null) { sError = "StatusCode Id (sCI) in " + packetHeader.type + " is missing"; return(false); } } cRoadSideObject RoadSideObject = cHelper.FindRoadSideObject(StatusSubscribe.ntsOId, StatusSubscribe.cId, bUseCaseSensitiveIds); if (RoadSideObject != null) { foreach (RSMP_Messages.StatusSubscribe_Status_Over_3_1_4 StatusSubscribe_Status in StatusSubscribe.sS) { RSMP_Messages.Status_VTQ s = new RSMP_Messages.Status_VTQ(); s.sCI = StatusSubscribe_Status.sCI; s.n = StatusSubscribe_Status.n; s.s = null; // 3.1.1 = unknown //s.q = "unknown"; // 3.1.2 = undefined ?? s.q = "undefined"; // Find status in object cStatusObject StatusObject = RoadSideObject.StatusObjects.Find(x => x.sStatusCodeId.Equals(StatusSubscribe_Status.sCI, sc)); cStatusReturnValue StatusReturnValue = null; if (StatusObject != null) { StatusReturnValue = StatusObject.StatusReturnValues.Find(x => x.sName.Equals(StatusSubscribe_Status.n, sc)); } if (StatusReturnValue != null) { RSMPGS.ProcessImage.UpdateStatusValue(ref s, StatusReturnValue.Value.GetValueType(), StatusReturnValue.Value.GetValue()); switch (statusMsgType) { case StatusMsgType.Request: RSMPGS.SysLog.SysLog(cSysLogAndDebug.Severity.Info, "Got status request (NTSObjectId: {0}, ComponentId: {1}, StatusCodeId: {2}, Name: {3}, Status: {4})", StatusSubscribe.ntsOId, StatusSubscribe.cId, StatusObject.sStatusCodeId, StatusReturnValue.sName, StatusReturnValue.Value.GetValue()); break; case StatusMsgType.UnSubscribe: case StatusMsgType.Subscribe: // Delete subscription if it already exists foreach (cSubscription Subscription in RoadSideObject.Subscriptions) { if (Subscription.StatusReturnValue == StatusReturnValue) { RoadSideObject.Subscriptions.Remove(Subscription); break; } } if (statusMsgType == StatusMsgType.Subscribe) { string sUpdateRate = StatusSubscribe_Status.uRt; float fUpdateRate = 0; float.TryParse(StatusSubscribe_Status.uRt, out fUpdateRate); if (fUpdateRate == 0) { float.TryParse(StatusSubscribe_Status.uRt.Replace('.', ','), out fUpdateRate); } bool bAlwaysSendOnChange = StatusSubscribe_Status.sOc; RoadSideObject.Subscriptions.Add(new cSubscription(StatusObject, StatusReturnValue, fUpdateRate, bAlwaysSendOnChange)); RSMPGS.SysLog.SysLog(cSysLogAndDebug.Severity.Info, "Got status subscribe (NTSObjectId: {0}, ComponentId: {1}. StatusCodeId: {2}, Name: {3}, Status: {4})", StatusSubscribe.ntsOId, StatusSubscribe.cId, StatusObject.sStatusCodeId, StatusReturnValue.sName, StatusReturnValue.Value.GetValue()); } else { RSMPGS.SysLog.SysLog(cSysLogAndDebug.Severity.Info, "Got status unsubscribe, removed subscription (NTSObjectId: {0}, ComponentId: {1}. StatusCodeId: {2}, Name: {3}, Status: {4})", StatusSubscribe.ntsOId, StatusSubscribe.cId, StatusObject.sStatusCodeId, StatusReturnValue.sName, StatusReturnValue.Value.GetValue()); } break; } } if (s.s == null) { RSMPGS.SysLog.SysLog(cSysLogAndDebug.Severity.Error, "Got status request/subscribe, failed to update StatusCodeId or Object (could be unknown value) (NTSObjectId: {0}, ComponentId: {1}, StatusCodeId: {2}))", StatusSubscribe.ntsOId, StatusSubscribe.cId, StatusSubscribe_Status.sCI); } sS.Add(s); } } else { // Failed, fill return list with 'unknown' foreach (RSMP_Messages.StatusSubscribe_Status_Over_3_1_4 StatusSubscribe_Status in StatusSubscribe.sS) { RSMP_Messages.Status_VTQ s = new RSMP_Messages.Status_VTQ(); s.sCI = StatusSubscribe_Status.sCI; s.n = StatusSubscribe_Status.n; s.s = null; // 3.1.1 = unknown //s.q = "unknown"; // 3.1.2 = undefined ?? s.q = "undefined"; sS.Add(s); } RSMPGS.SysLog.SysLog(cSysLogAndDebug.Severity.Error, "Got status message, failed to find object (NTSObjectId: {0}, ComponentId: {1})", StatusSubscribe.ntsOId, StatusSubscribe.cId); } if (statusMsgType != StatusMsgType.UnSubscribe) { // Response message RSMP_Messages.StatusResponse StatusResponse = new RSMP_Messages.StatusResponse(); // Send response to client StatusResponse.mType = "rSMsg"; StatusResponse.type = (statusMsgType == StatusMsgType.Subscribe) ? "StatusUpdate" : "StatusResponse"; StatusResponse.mId = System.Guid.NewGuid().ToString(); StatusResponse.ntsOId = StatusSubscribe.ntsOId; StatusResponse.xNId = StatusSubscribe.xNId; StatusResponse.cId = StatusSubscribe.cId; StatusResponse.sTs = CreateISO8601UTCTimeStamp(); StatusResponse.sS = sS; string sSendBuffer = JSonSerializer.SerializeObject(StatusResponse); if (bHasSentAckOrNack == false) { bHasSentAckOrNack = SendPacketAck(true, packetHeader.mId, ""); } RSMPGS.JSon.SendJSonPacket(StatusResponse.type, StatusResponse.mId, sSendBuffer, true); if (RSMPGS.MainForm.checkBox_ViewOnlyFailedPackets.Checked == false) { RSMPGS.SysLog.SysLog(cSysLogAndDebug.Severity.Info, "Sent StatusResponse message, Type: " + StatusResponse.type + ", MsgId: " + StatusResponse.mId); } } } catch (Exception e) { sError = "Failed to deserialize packet: " + e.Message; bSuccess = false; } return(bSuccess); }
private bool DecodeAndParseStatusMessage(RSMP_Messages.Header packetHeader, string sJSon, bool bUseStrictProtocolAnalysis, bool bUseCaseSensitiveIds, ref bool bHasSentAckOrNack, ref string sError) { StringComparison sc = bUseCaseSensitiveIds ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; bool bSuccess = false; try { RSMP_Messages.StatusResponse StatusResponse = JSonSerializer.Deserialize <RSMP_Messages.StatusResponse>(sJSon); cRoadSideObject RoadSideObject = cHelper.FindRoadSideObject(StatusResponse.ntsOId, StatusResponse.cId, bUseCaseSensitiveIds); foreach (RSMP_Messages.Status_VTQ Reply in StatusResponse.sS) { cStatusObject StatusObject = RoadSideObject.StatusObjects.Find(x => x.sStatusCodeId.Equals(Reply.sCI, sc)); if (StatusObject == null) { continue; } cStatusReturnValue StatusReturnValue = StatusObject.StatusReturnValues.Find(x => x.sName.Equals(Reply.n, sc)); if (StatusReturnValue == null) { continue; } if (StatusReturnValue.Value.GetValueType().Equals("base64", StringComparison.OrdinalIgnoreCase)) { if (RSMPGS.MainForm.ToolStripMenuItem_StoreBase64Updates.Checked) { StatusReturnValue.Value.SetValue(RSMPGS.SysLog.StoreBase64DebugData(Reply.s)); } else { StatusReturnValue.Value.SetValue("base64"); } } else { StatusReturnValue.Value.SetValue(Reply.s); } StatusReturnValue.sQuality = Reply.q; if (ValidateTypeAndRange(StatusReturnValue.Value.GetValueType(), Reply.s)) { bSuccess = true; } else { string sStatusValue; if (Reply.s == null) { sStatusValue = "(null)"; } else { sStatusValue = (Reply.s.Length < 10) ? Reply.s : Reply.s.Substring(0, 9) + "..."; } sError = "Value and/or type is out of range or invalid for this RSMP protocol version, type: " + StatusReturnValue.Value.GetValueType() + ", quality: " + StatusReturnValue.sQuality + ", statusvalue: " + sStatusValue; RSMPGS.SysLog.SysLog(cSysLogAndDebug.Severity.Error, sError); } cStatusEvent StatusEvent = new cStatusEvent(); StatusEvent.sTimeStamp = UnpackISO8601UTCTimeStamp(StatusResponse.sTs); StatusEvent.sMessageId = StatusResponse.mId; StatusEvent.sEvent = "Received status"; StatusEvent.sStatusCommandId = Reply.sCI; StatusEvent.sName = Reply.n; if (StatusReturnValue.Value.GetValueType().Equals("base64", StringComparison.OrdinalIgnoreCase)) { StatusEvent.sStatus = "base64"; } else { StatusEvent.sStatus = Reply.s; } StatusEvent.sQuality = Reply.q; if (RSMPGS_Main.bWriteEventsContinous) { RSMPGS.SysLog.EventLog("Status;{0}\tMId: {1}\tComponentId: {2}\tStatusCommandId: {3}\tName: {4}\tStatus: {5}\tQuality: {6}\tUpdateRate: {7}\tUpdateOnChange: {8}\tEvent: {9}", StatusEvent.sTimeStamp, StatusEvent.sMessageId, StatusResponse.cId, StatusEvent.sStatusCommandId, StatusEvent.sName, StatusEvent.sStatus, StatusEvent.sQuality, StatusEvent.sUpdateRate, StatusEvent.bUpdateOnChange, StatusEvent.sEvent); } RoadSideObject.StatusEvents.Add(StatusEvent); RSMPGS.MainForm.HandleStatusListUpdate(RoadSideObject, StatusEvent, false); } } catch (Exception e) { sError = "Failed to deserialize packet: " + e.Message; bSuccess = false; } return(bSuccess); }