/// <summary> /// Encryptes a dictionary to a byte array /// </summary> /// <param name="pVal">Dictionary to be encrypted</param> /// <returns></returns> public byte[] EncryptKV(Dictionary <string, string> pVal) { try { string t = CU.SerializeObjectToJSONString(pVal); return(Encrypt(CU.CUnicodeString2Array(t), MySecrets?.GetAK(), MySecrets?.GetAI())); } catch (Exception) { TheBaseAssets.MySYSLOG?.WriteToLog(TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheCommonUtils", $"Error during KV encrypt...", eMsgLevel.l1_Error), 5016); return(null); } }
internal string GetCanonicalLicense() { TheLicense tempLicense = new TheLicense(this); // Bug in original License constructor did not copy the Description field, so it was not included in the signature. Only shipped license was this one (P08 Project, OPC Client) //CODE-REVIEW: Is this still necessary? if (tempLicense.LicenseId == new Guid("6a78a4cb-1d9b-4a53-a41b-c57497085026")) { tempLicense.Description = null; } tempLicense.Signatures = new string[0]; return(CU.SerializeObjectToJSONString(tempLicense)); }
/// <summary> /// Encryptes a dictionary to a byte array /// </summary> /// <param name="pVal">Dictionary to be encrypted</param> /// <returns></returns> public byte[] EncryptKV(Dictionary <string, string> pVal) { try { string t = CU.SerializeObjectToJSONString(pVal); var tFinal = $"{CU.GetRandomUInt(0, 10000)}:{t.Length}@" + t; return(Encrypt(CU.CUnicodeString2Array(tFinal), MySecrets?.GetAK(), MySecrets?.GetAI())); } catch (Exception) { MySYSLOG?.WriteToLog(0, 5016, "ICDECrypto", $"Error during KV encrypt...", eMsgLevel.l1_Error); return(null); } }
/// <summary> /// Adds a signature to the license. /// </summary> /// <param name="rsaPrivateKeyCSPBlob">Private key to use for generating the signature.</param> /// <returns></returns> public bool AddSignature(byte[] rsaPrivateKeyCSPBlob) { bool success = false; try { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.ImportCspBlob(rsaPrivateKeyCSPBlob); if (rsa.PublicOnly) { return(false); } // JWS inspired, but // 1) jwk is RSA key in XML format // 2) Empty payload string header = Convert.ToBase64String(CU.CUTF8String2Array(CU.SerializeObjectToJSONString(new Header { jwk = rsa.ToXmlString(false), alg = "RS256" }))); string payload = GetCanonicalLicense(); byte[] payloadBytes = CU.CUTF8String2Array(payload); byte[] tBytes = rsa.SignData(payloadBytes, "SHA1"); payload = ""; // Don't store the payload again as would be required by JWS string signature = Convert.ToBase64String(tBytes); var newSignatures = new string[Signatures.Length + 1]; Signatures.CopyTo(newSignatures, 0); newSignatures[newSignatures.Length - 1] = String.Format("{0}.{1}.{2}", header, "", signature); Signatures = newSignatures; success = true; } catch (Exception) { //ignored? } return(success); }
/// <summary> /// Validates the signatures of license using the public keys of the signer /// </summary> /// <param name="rsaPublicKeyCSPBlobs">The public key(s) for each of the signatures.</param> /// <returns></returns> public bool ValidateSignature(List <byte[]> rsaPublicKeyCSPBlobs) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); var payload = CU.CUTF8String2Array(GetCanonicalLicense()); foreach (var key in rsaPublicKeyCSPBlobs) { rsa.ImportCspBlob(key); string keyAsXml; try { keyAsXml = rsa.ToXmlString(false); } catch (PlatformNotSupportedException) { keyAsXml = TheBaseAssets.MyCrypto.GetRSAKeyAsXML(rsa, false); } string header = Convert.ToBase64String(CU.CUTF8String2Array(CU.SerializeObjectToJSONString(new Header { jwk = keyAsXml, alg = "RS256" }))); foreach (var signature in Signatures) { var parts = signature.Split('.'); if (parts.Length == 3) { if (parts[0] == header) { if (rsa.VerifyData(payload, "SHA1", Convert.FromBase64String(parts[2]))) { return(true); } } } } } return(false); }
public virtual void SendEnergyData(eEnergyThingCaps pSenderType, TheEnergyData LastEnergyData, bool Force = false) { if (LastEnergyData == null || (Force == false && (PublishInterval == 0 || DateTimeOffset.Now.Subtract(LastPublish).TotalSeconds < PublishInterval))) { return; } LastPublish = DateTimeOffset.Now; LastEnergyData.Time = DateTime.Now; LastEnergyData.StationID = MyBaseThing.cdeMID; string tMessageTxt = eEnergyMessages.EnergyConsumerUpdate; switch (pSenderType) { case eEnergyThingCaps.EnergyBreaker: tMessageTxt = eEnergyMessages.EnergyBreakerUpdate; break; case eEnergyThingCaps.EnergyStorage: tMessageTxt = eEnergyMessages.EnergyStorageUpdate; break; case eEnergyThingCaps.EnergyPanel: tMessageTxt = eEnergyMessages.EnergyPanelUpdate; break; case eEnergyThingCaps.EnergyProducer: tMessageTxt = eEnergyMessages.EnergyProducerUpdate; break; case eEnergyThingCaps.EnergyTank: tMessageTxt = eEnergyMessages.EnergyTankUpdate; break; } LastEnergyData.StationName = $"{tMessageTxt}: {MyBaseThing.FriendlyName}";; TSM msgEnergy2 = new TSM("EnergyMessages", $"{tMessageTxt}:{MyBaseThing.cdeMID}", CU.SerializeObjectToJSONString(LastEnergyData)); msgEnergy2.SetNoDuplicates(true); TCC.PublishCentral(msgEnergy2, true); }
internal static void InitAssets(TheBaseApplication pApp) { if (IsInitialized) { return; } IsInitialized = true; if (MyServiceHostInfo == null || !(MySecrets?.IsApplicationIDValid() == true)) { MasterSwitch = false; return; } MyApplication = pApp; #region step 1: Moved from StartApplication to here as all the following code is updating TheBaseAssets //The following section are "app.config" only settings required before cdeTPI is loaded. These settings cannot be set via the Provisioning Service int delay = TheCommonUtils.CInt(MySettings.GetSetting("StartupDelay")); if (delay > 0) { TheCommonUtils.SleepOneEye((uint)(delay * 1000), 100); } string temp = MySettings.GetSetting("AllowEnvironmentVarsToOverrideConfig"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.AllowEnvironmentVarsToOverrideConfig = TheCommonUtils.CBool(temp); } temp = MySettings.GetSetting("AllowEnvironmentVars"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.AllowEnvironmentVars = TheCommonUtils.CBool(temp); } temp = MySettings.GetSetting("DEBUGLEVEL"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.DebugLevel = (eDEBUG_LEVELS)TheCommonUtils.CInt(temp); } //Clouds have special behavior and the CDE needs to know this upfront temp = MySettings.GetSetting("IsCloudService"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.IsCloudService = TheCommonUtils.CBool(temp); } temp = MySettings.GetSetting("ISOEN"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.IsIsolated = true; MyServiceHostInfo.IsoEngine = temp; MyServiceHostInfo.cdeNodeType = cdeNodeType.Active; } else { temp = MySettings.GetSetting("UseRandomDeviceID"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.UseRandomDeviceID = TheCommonUtils.CBool(temp); } } //Step 2: Restore from backup if exists #if CDE_NET45 // Backup/Restore only support on NET45 // To ensure that restored backups are not overwritten during shutdown, we write them to a temp directory and move them into place on start up if (!MyServiceHostInfo.UseRandomDeviceID && !MyServiceHostInfo.IsIsolated) { string cacheParentPath = TheCommonUtils.GetCurrentAppDomainBaseDirWithTrailingSlash() + "ClientBin\\"; if (Directory.Exists(cacheParentPath + "__CacheToRestore")) { // Keep the old Cache around just in case try { // First make space for the old copy, in case there was one already if (Directory.Exists(cacheParentPath + "__CacheOld")) { Directory.Delete(cacheParentPath + "__CacheOld", true); } } catch { //ignored } try { Directory.Move(cacheParentPath + "Cache", cacheParentPath + "__CacheOld"); } catch { //ignored } // Now move the restored cache into place try { Directory.Move(cacheParentPath + "__CacheToRestore", cacheParentPath + "Cache"); } catch { TheSystemMessageLog.ToCo("Failure while restoring backup"); } } } #endif MyServiceHostInfo.EnableTaskKPIs = TheCommonUtils.CBool(MySettings.GetSetting("EnableTaskKPIs")); if (MyServiceHostInfo.EnableTaskKPIs) { var taskKpiThread = new Thread(() => { do { var kpis = TheCommonUtils.GetTaskKpis(null); TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: {TheCommonUtils.SerializeObjectToJSONString(kpis)}"); Thread.Sleep(1000); // Keeping it simple here, to minimize interference on task scheduler/thread scheduler etc. (Assumption: not used on production systems) // TheCommonUtils.SleepOneEye(1000, 1000); } while (MasterSwitch && !Engines.TheCDEngines.IsHostReady && MyServiceHostInfo.EnableTaskKPIs); TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: KPIs Handoff to NodeHost"); }); taskKpiThread.Start(); } #endregion if (MyActivationManager == null) { MyActivationManager = new TheDefaultActivationManager(MySecrets, MySYSLOG); } #region step 3: analyse os environment information OperatingSystem os = Environment.OSVersion; var osInfoForLog = $"C-DEngine version: {BuildVersion} OS:{Environment.OSVersion} OS Version:{os.VersionString} OS Version Numbers: {os.Version.Major}.{os.Version.Minor}.{os.Version.Build}.{os.Version.Revision} Platform:{os.Platform} SP:{os.ServicePack} Processor Count: {Environment.ProcessorCount} IsMono:{(Type.GetType("Mono.Runtime") != null)} IsNetCore:{TheCommonUtils.IsNetCore()} Product: {TheCommonUtils.GetAssemblyProduct(typeof(TheBaseAssets))} "; TheSystemMessageLog.ToCo(osInfoForLog); MyServiceHostInfo.OSInfo = osInfoForLog; string dotNetInfoForLog = string.Empty; #if !CDE_NET35 && !CDE_NET4 try { string frameworkDescription = null; string osDescription = null; string processArchitecture = null; string osArchitecture = null; #if CDE_STANDARD frameworkDescription = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription; osDescription = System.Runtime.InteropServices.RuntimeInformation.OSDescription; processArchitecture = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString(); osArchitecture = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture.ToString(); #else var rtInfoType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); if (rtInfoType != null) { frameworkDescription = rtInfoType.GetProperty("FrameworkDescription").GetValue(null).ToString(); osDescription = rtInfoType.GetProperty("OSDescription").GetValue(null).ToString(); processArchitecture = rtInfoType.GetProperty("ProcessArchitecture").GetValue(null).ToString(); osArchitecture = rtInfoType.GetProperty("OSArchitecture").GetValue(null).ToString(); } #endif if (!string.IsNullOrEmpty(frameworkDescription)) { dotNetInfoForLog = $"NetFrameWork:{frameworkDescription} Processor:{processArchitecture} OS:{osDescription } OS Arch:{osArchitecture}"; TheSystemMessageLog.ToCo(dotNetInfoForLog); MyServiceHostInfo.OSInfo += $" {dotNetInfoForLog}"; } } catch { } #endif if (TheCommonUtils.IsMono()) // CODE REVIEW: Need to clean this up - do we mean Mono or Linux or case-insensitive file systems? CM: No- here we need this to find out if we are running in the MONO Runtime { MyServiceHostInfo.cdePlatform = cdePlatform.MONO_V3; } else { #if CDE_NET35 MyServiceHostInfo.cdePlatform = cdePlatform.X32_V3; #elif CDE_NET4 MyServiceHostInfo.cdePlatform = Environment.Is64BitProcess ? cdePlatform.NETV4_64 : cdePlatform.NETV4_32; #elif CDE_STANDARD MyServiceHostInfo.cdePlatform = cdePlatform.NETSTD_V20; #else MyServiceHostInfo.cdePlatform = TheCommonUtils.GetAssemblyPlatform(Assembly.GetEntryAssembly(), false, out var empty);// old: Environment.Is64BitProcess ? cdePlatform.X64_V3 : cdePlatform.X32_V4; #endif } TheSystemMessageLog.ToCo("BaseDir: " + MyServiceHostInfo.BaseDirectory); #endregion #region step 4: Prepare essential Subsystems (Syslog, ScopeManager, Diagnostics, Caches, AppInfo) MySYSLOG = new TheSystemMessageLog(500); // No more ToCo after this point (will be ignored) TheCDEKPIs.Reset(); MyServiceHostInfo.MiniHostInfo.MySYSLOG = MySYSLOG; MyServiceHostInfo.MiniHostInfo.MyKPIs = new TheKPIs(); if (MyScopeManager == null) { MyScopeManager = new TheDefaultScopeManager(); } MyScopeManager.SetMiniHSI(MyServiceHostInfo.MiniHostInfo); MyScopeManager.RegisterScopeChanged(localEventScopeChanged); TheDiagnostics.InitDiagnostics(); TheDiagnostics.SetThreadName("MAIN THREAD"); TheQueuedSenderRegistry.Startup(); MyBlobCache = new TheMirrorCache <TheBlobData>(MyServiceHostInfo.TO.StorageCleanCycle); MyReceivedParts = new TheMirrorCache <TheReceivedParts>(MyServiceHostInfo.TO.StorageCleanCycle); //TODO: I hope there is a better way to do this for Metro! MyServiceTypes.Add(typeof(TheBaseAssets)); MyServiceHostInfo.TO.MakeHeartNormal(); MyAppInfo = new ThePluginInfo { cdeMID = MyServiceHostInfo.cdeMID, CurrentVersion = MyServiceHostInfo.CurrentVersion, Developer = MyServiceHostInfo.VendorName, DeveloperUrl = MyServiceHostInfo.VendorUrl, HomeUrl = MyServiceHostInfo.SiteName, IconUrl = MyServiceHostInfo.UPnPIcon, LongDescription = MyServiceHostInfo.Description, Platform = MyServiceHostInfo.cdePlatform, Copyrights = MyServiceHostInfo.Copyrights, Price = 0, ServiceDescription = MyServiceHostInfo.Title, ServiceName = MyServiceHostInfo.ApplicationName, Capabilities = new List <eThingCaps> { eThingCaps.Host }, Categories = new List <string>(), FilesManifest = new List <string>() }; if (MyServiceHostInfo.ManifestFiles != null) { MyAppInfo.FilesManifest.AddRange(MyServiceHostInfo.ManifestFiles); } #endregion //Now load provisioning and local settings then parse them #pragma warning disable CS0618 // Type or member is obsolete - its allowed here if (!TheCDESettings.ParseSettings(MyCmdArgs, true, false)) #pragma warning restore CS0618 // Type or member is obsolete { MasterSwitch = false; return; } if (MyCodeSigner == null) { MyCodeSigner = new TheDefaultCodeSigning(MySecrets, MySYSLOG); } string tBaseDir = MyServiceHostInfo.BaseDirectory; if (MyServiceHostInfo.cdeHostingType == cdeHostType.IIS) { tBaseDir += "bin\\"; } string uDir = tBaseDir; if (!string.IsNullOrEmpty(MyServiceHostInfo.ISMMainExecutable)) { uDir += MyServiceHostInfo.ISMMainExecutable; if (MyServiceHostInfo.cdeHostingType != cdeHostType.IIS) { var hostPath = uDir + ".exe"; if (!File.Exists(hostPath)) { // We may be running under .Net Core with a .dll-based host hostPath = uDir + ".dll"; } uDir = hostPath; } } else { uDir += "C-DEngine.dll"; } MyServiceHostInfo.CodeSignThumb = MyCodeSigner.GetAppCert(MyServiceHostInfo.DontVerifyTrust, uDir, MyServiceHostInfo.VerifyTrustPath, MyServiceHostInfo.DontVerifyIntegrity); //Must be loaded here to set trust level in HSI if (MyLoc as TheDefaultLocalizationUtils != null) { (MyLoc as TheDefaultLocalizationUtils).DoPseudoLoc = TheCommonUtils.CBool(MySettings.GetSetting("DoPseudoLoc")); } #region step 5: output some system information if (MyServiceHostInfo.IsMemoryOptimized) { MySYSLOG.SetMaxLogEntries(10); } MySYSLOG.WriteToLog(4151, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", osInfoForLog, eMsgLevel.l4_Message)); if (!string.IsNullOrEmpty(dotNetInfoForLog)) { MySYSLOG.WriteToLog(4152, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", dotNetInfoForLog, eMsgLevel.l4_Message)); } MySYSLOG.WriteToLog(4153, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("TheBaseAssets", "BaseDir: " + MyServiceHostInfo.BaseDirectory, eMsgLevel.l4_Message)); #endregion #region step 6: determine WebSocket8 vs. WebSocketsSharp var ws8FlagTemp = MySettings.GetSetting("DisallowWebSocket8"); if (!string.IsNullOrEmpty(ws8FlagTemp)) { MyServiceHostInfo.IsWebSocket8Active = !TheCommonUtils.CBool(ws8FlagTemp); MySYSLOG.WriteToLog(4154, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", $"Setting IsWebSocket8Active to {MyServiceHostInfo.IsWebSocket8Active} due to config", eMsgLevel.l4_Message)); } else { MyServiceHostInfo.IsWebSocket8Active = true; } if ((os.Platform != PlatformID.Win32NT && !TheCommonUtils.IsNetCore()) || (os.Platform == PlatformID.Win32NT && (os.Version.Major < 6 || (os.Version.Major == 6 && os.Version.Minor < 2)))) { MyServiceHostInfo.IsWebSocket8Active = false; string tWSMsg = "Older Windows or non-Windows OS Detected - No OS Support for WebSockets Found: "; #if !CDE_USECSWS //OK TheBaseAssets.MyServiceHostInfo.DisableWebSockets = true; tWSMsg += "WebSockets are turned Off"; #else tWSMsg += "Switching to WebSockets-Sharp"; #endif MySYSLOG.WriteToLog(4155, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", tWSMsg, eMsgLevel.l4_Message)); } #endregion #region step 7: Initialize Localization subsystem (ILocalizationHooks) bool bLocInitialized = false; try { var entryAssembly = Assembly.GetEntryAssembly(); //This does not work in IIS! if (entryAssembly != null) { var CDEPlugins = from t in entryAssembly.GetTypes() let ifs = t.GetInterfaces() where ifs != null && ifs.Length > 0 && (ifs.Contains(typeof(ILocalizationHooks))) select new { Type = t, t.Namespace, t.Name, t.FullName }; if (CDEPlugins != null && CDEPlugins.Any()) { MyLoc = Activator.CreateInstance(CDEPlugins.First().Type) as ILocalizationHooks; } bLocInitialized = true; } } catch { } if (!bLocInitialized) { MySYSLOG.WriteToLog(4156, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", "3rd Party ILocalization Hooks not found - using built-in", eMsgLevel.l4_Message)); } #endregion #region step 8: Set MyStationUrl switch (MyServiceHostInfo.cdeHostingType) { case cdeHostType.Phone: case cdeHostType.Metro: MyServiceHostInfo.MyDeviceMoniker = "CDEV://"; break; case cdeHostType.Silverlight: MyServiceHostInfo.MyDeviceMoniker = "CDES://"; break; case cdeHostType.Device: MyServiceHostInfo.MyDeviceMoniker = "CDEC://"; break; case cdeHostType.Mini: MyServiceHostInfo.MyDeviceMoniker = "CDEM://"; break; default: //Services MyServiceHostInfo.MyDeviceMoniker = "CDEB://"; break; } if (TheCommonUtils.IsHostADevice()) { MyServiceHostInfo.MyStationURL = MyServiceHostInfo.MyDeviceMoniker + "{" + MyServiceHostInfo.MyDeviceInfo.DeviceID + "}".ToUpper(); //MSU-OK } else { if (MyServiceHostInfo.MyAltStationURLs.Count(s => s.StartsWith("CDEB")) == 0) { MyServiceHostInfo.MyAltStationURLs.Add("CDEB://{" + MyServiceHostInfo.MyDeviceInfo.DeviceID + "}"); //TODO: Backchannel Possibly save to Config File } } #endregion #region step 9: Start Localhost QSender and SessionStateManager MySession = new TheSessionStateManager(MyServiceHostInfo); LocalHostQSender = new TheQueuedSender(); //NO connected or Error Event necessary LocalHostQSender.StartSender(new TheChannelInfo(MyServiceHostInfo.MyDeviceInfo.DeviceID, MyScopeManager.ScopeID, MyServiceHostInfo.MyDeviceInfo.SenderType, MyServiceHostInfo.GetPrimaryStationURL(false)), null, false); //NEW:2.06 Setting Realscope here ///null correct - no subs on LocalhostQS in beginning //RScope-OK if ((MyServiceHostInfo.DisableWebSockets || MyServiceHostInfo.MyStationWSPort == 0) && !TheCommonUtils.IsHostADevice()) { MySYSLOG.WriteToLog(4157, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", $"WebSockets Disabled - no WSPort specified {MyServiceHostInfo.MyStationWSPort} or DisableWebSocket={MyServiceHostInfo.DisableWebSockets}", eMsgLevel.l4_Message)); } #endregion // Post Device ID settings //Step 10: Save all settings to local cdeTPI MySettings.UpdateLocalSettings(); }
void WriteToLogInternal(int pLogID, TSM MyText, bool NoLog, long tLogSerial) { bool AddEntry = true; if (LogFilter.Count > 0) { AddEntry = false; foreach (string t in LogFilter) { if (MyText.ENG.Equals(t)) { AddEntry = true; break; } } } if (LogOnly.Count > 0) { bool Found = false; foreach (string t in LogOnly) { if (MyText.ENG == null || MyText.ENG.Equals(t)) { Found = true; break; } } if (!Found) { return; } } if (LogIgnore.Count > 0) { foreach (string t in LogIgnore) { if (MyText.ENG == null || MyText.ENG.Equals(t)) { return; } } } if (!TheBaseAssets.MyServiceHostInfo.DisableConsole) { switch (MyText.LVL) { case eMsgLevel.l1_Error: Console.ForegroundColor = ConsoleColor.Red; break; case eMsgLevel.l2_Warning: Console.ForegroundColor = ConsoleColor.Yellow; break; case eMsgLevel.l3_ImportantMessage: Console.ForegroundColor = ConsoleColor.Green; break; case eMsgLevel.l6_Debug: case eMsgLevel.l7_HostDebugMessage: Console.ForegroundColor = ConsoleColor.Gray; break; default: Console.ForegroundColor = ConsoleColor.White; break; } string tout = null; if (TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat == true) { var t = new TheGELFLogEntry() { version = "1.1", host = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false), level = (int)MyText?.LVL, #if CDE_NET45 || CDE_NET4 || CDE_NET35 timestamp = TheCommonUtils.CDbl($"{(MyText.TIM.Subtract(new DateTime(1970, 1, 1))).TotalSeconds}.{MyText.TIM.Millisecond}"), #else timestamp = TheCommonUtils.CDbl($"{MyText.TIM.ToUnixTimeSeconds()}.{MyText.TIM.Millisecond}"), #endif full_message = TheBaseAssets.MyServiceHostInfo.ShowMarkupInLog ? TheCommonUtils.cdeStripHTML(MyText?.PLS) : MyText?.PLS, short_message = TheBaseAssets.MyServiceHostInfo.ShowMarkupInLog? TheCommonUtils.cdeStripHTML(MyText?.TXT):MyText?.TXT, _serial_no = tLogSerial, _log_id = pLogID, _engine = MyText?.ENG, _device_id = MyText.ORG, // _status_level = ? // _topic = ? }; tout = TheCommonUtils.SerializeObjectToJSONString <TheGELFLogEntry>(t); } else { tout = $"ID:{pLogID} SN:{tLogSerial} {MyText.ToAllString()}"; } Console.WriteLine(tout); Console.ForegroundColor = ConsoleColor.White; } if (AddEntry) { //if (MyText.Text == "True") return; if (MyMessageLog != null) { Add(pLogID, tLogSerial, "", MyText); } if (MyText.LVL == eMsgLevel.l1_Error) { LastError = MyText; } #if CDE_DEBUGVIEW System.Diagnostics.Debug.WriteLine(string.Format("ID:{0} SN:{1} {2}", pLogID, tLogSerial, MyText.ToAllString())); #endif if (LogWriteBuffer > 0 && MyText.LVL < LogWriteFilterLevel) { LogCounter++; if (LogCounter > LogWriteBuffer) { LogCounter = 0; WriteLogToFile(false); } } if (TheBaseAssets.MyApplication != null && MyText.LVL < MessageFilterLevel) { TheBaseAssets.MyApplication.ShowMessageToast(MyText, ""); } if (TheCDEngines.MyIStorageService != null && TheBaseAssets.MyServiceHostInfo.StoreLoggedMessages && !NoLog && (MyText.LVL < LogFilterLevel) && TheCDEngines.MyIStorageService.GetBaseEngine().GetEngineState().IsEngineReady) { TheCDEngines.MyIStorageService.EdgeDataStoreOnly(MyText, null); } } }