// Using a template, with a constraint of IMessage allows us to pass the message without boxing reducing garbage generation
        private unsafe void ReadMessage <T>(DateTime now, Command command) where T : unmanaged, IMessage
        {
            int length = 0;

            try
            {
                while (length < sizeof(T))
                {
                    length += m_SerialPort.Read(m_ReadBuffer, length, sizeof(T) - length);
                }

                if (length != sizeof(T))
                {
                    throw new ArgumentException($"Message Length: {length}. Expected Length: {sizeof(T)}.");
                }
            }
            catch (Exception e)
            {
                AppLogging.DebugLogException(nameof(ReadMessage), e);
                Interlocked.Increment(ref m_ErrorCount);
                return;
            }

            T message = new T();

            message.SetBytes(m_ReadBuffer);
            AppLogging.DebugLog(nameof(ReadMessage), command.ToString(), message.ToString());

            Interlocked.Add(ref m_ReadBytes, length);
            m_LastMessageRead = now;
            m_MessageContext.Post(x => OnMessageRecieved?.Invoke(command, message), null);
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseDefaultFiles();
            app.UseStaticFiles();
            app.UseAuthentication();

            AppLogging.SetPath(Configuration["Logging:LogFile"]);
            AppLogging.ConfigureLogger(loggerFactory);
            AppLogging.LoggerFactory = loggerFactory;


            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "catch-all",
                    template: "{*url}",
                    defaults: new { controller = "Default", action = "Index" }

                    );
            });
        }
Пример #3
0
        /// <summary>
        /// Handles wrapping the session into a higher level object, registering
        /// it in the service and notifying of the event.
        /// </summary>
        /// <param name="session_"></param>
        private void OnSessionCreated(AudioSessionControl session_)
        {
            var session = new AudioSession(session_);

            AppLogging.DebugLog(nameof(OnSessionCreated), session.SessionIdentifier, session.DisplayName, session.Id.ToString());
            RegisterSession(session);
        }
Пример #4
0
        /// <summary>
        /// Registers the device with the service so it's aware
        /// of events and they're handled properly.
        /// </summary>
        /// <param name="device"></param>
        private void RegisterDevice(IAudioDevice device)
        {
            AppLogging.DebugLog(nameof(RegisterDevice), device.DeviceId, device.DisplayName, device.Device.DataFlow.ToString());
            if (_devices.ContainsKey(device.Id))
            {
                device.Dispose();
                return;
            }

            _devices.Add(device.Id, device);
            device.DeviceDefaultChanged += OnDefaultDeviceChanged;
            device.DeviceVolumeChanged  += OnDeviceVolumeChanged;
            device.DeviceRemoved        += OnDeviceRemoved;

            RaiseDeviceCreated(device.Id, device.DisplayName, device.Volume, device.IsMuted, device.Flow);

            if (device.Flow == DeviceFlow.Output)
            {
                var sessionManager = AudioSessionManager2.FromMMDevice(device.Device);
                sessionManager.SessionCreated += OnSessionCreated;
                _sessionManagers.Add(device.Id, sessionManager);

                foreach (var session in sessionManager.GetSessionEnumerator())
                {
                    OnSessionCreated(session);
                }
            }
        }
Пример #5
0
        private void Connect(DateTime now)
        {
            string[] portNames = null;
            try { portNames = SerialPort.GetPortNames(); }
            catch { }

            if (portNames == null || portNames.Length == 0)
            {
                return;
            }

            foreach (string portName in portNames)
            {
                string firmware = "";
                try
                {
                    AppLogging.DebugLog(nameof(Connect), portName);
                    m_SerialPort              = new SerialPort(portName, 115200);
                    m_SerialPort.ReadTimeout  = k_ReadTimeout;
                    m_SerialPort.WriteTimeout = k_WriteTimeout;
                    m_SerialPort.Open();
                    m_SerialPort.DiscardInBuffer();
                    m_SerialPort.DiscardOutBuffer();

                    WriteMessage(now, Command.TEST);
                    Thread.Sleep(20);
                    Command command = (Command)m_SerialPort.ReadByte();
                    if (command != Command.TEST)
                    {
                        throw new InvalidOperationException($"Firmware Test reply failed. Reply: '{command}' Bytes: '{m_SerialPort.BytesToRead}'");
                    }
                    firmware = m_SerialPort.ReadLine().Replace("\r", "");
                    if (!FirmwareVersions.IsCompatible(firmware))
                    {
                        throw new ArgumentException($"Incompatible Firmware: '{firmware}'.");
                    }
                    m_SerialPort.DataReceived += Read;
                    m_DeviceConnected          = true;
                    m_DeviceReady              = true;
                    m_MessageContext.Post(x => OnDeviceConnected?.Invoke(), null);
                    m_LastMessageRead = now;
                    return;
                }
                catch (Exception e)
                {
                    AppLogging.DebugLogException(nameof(Connect), e);
                    m_SerialPort.Close();
                    m_SerialPort.Dispose();
                    m_SerialPort = null;

                    if (e is ArgumentException) // Incompatible Firmware
                    {
                        m_MessageContext.Post(x => OnFirmwareIncompatible?.Invoke(firmware), null);
                    }
                }
            }
        }
Пример #6
0
        public static int Main(string[] args)
        {
            Serilog.Debugging.SelfLog.Enable(Console.Error);

            LoggerConfiguration config = new LoggerConfiguration()
                                         .ReadFrom.Configuration(Configuration);

            //Email logging setup
            EmailConfiguration emailConfig = new EmailConfiguration();

            Configuration.Bind("SerilogEmail", emailConfig);

            if (emailConfig.Enabled)
            {
                config.WriteTo.Email(emailConfig.ToEmailConnectionInfo(Env),
                                     outputTemplate: emailConfig.OutputTemplate,
                                     batchPostingLimit: emailConfig.BatchPostingLimit,
                                     restrictedToMinimumLevel: emailConfig.RestrictedToMinimumLevel
                                     );
            }

            Log.Logger = config.CreateLogger();
            ApplicationInfo info = ApplicationInfo.BuildApplicationInfo();

            try
            {
                AppLogging
                .ForCategory("Lifecycle")
                .Information("Startup of {Application} version {Version} built {BuildDate}",
                             info.ApplicationName,
                             info.ApplicationVersion,
                             info.ApplicationBuildDate);

                CreateWebHostBuilder(args).Build().Run();

                AppLogging
                .ForCategory("Lifecycle")
                .Information("Shutdown of {Application}", info.ApplicationName);

                return(0);
            }
            catch (Exception ex)
            {
                AppLogging
                .ForCategory("Lifecycle")
                .Fatal(ex, "Application {Application} terminated unexpectedly", info.ApplicationName);

                return(1);
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
Пример #7
0
    /// <summary>
    /// Writes diagnostic data
    /// </summary>
    /// <param name="text"></param>
    public static void WriteLine(string text)
    {
        var sb = new StringBuilder();

        sb.AppendLine("#iws#####################################################");
        sb.Append("iws - writeline: ");
        sb.AppendLine(DateTime.UtcNow.ToString());
        sb.AppendLine(text);

        var writeText = sb.ToString();

        Debug.WriteLine(writeText);
        //Log it whereever else we want to output it
        AppLogging.LogDebugOutput(writeText);
    }
Пример #8
0
        private void OnDefaultDeviceChanged(object sender, DefaultDeviceChangedEventArgs e)
        {
            if (e.DataFlow != Flow.ToDataFlow())
            {
                return;
            }

            bool newDefault = e.DeviceId == DeviceId;

            if (IsDefault != newDefault)
            {
                AppLogging.DebugLog(nameof(OnDefaultDeviceChanged), DeviceId, newDefault.ToString());
                IsDefault = newDefault;
                DeviceDefaultChanged?.Invoke(this);
            }
        }
        private void WriteMessage(DateTime now, Command command, IMessage message = null)
        {
            m_WriteBuffer.SetLength(0);
            m_WriteBuffer.WriteByte((byte)command);
            message?.GetBytes(m_WriteBuffer);
            Interlocked.Add(ref m_WriteBytes, m_WriteBuffer.Length);

            // GetBuffer returns a reference to the underlying array, we can still use that after we reset the position if we store the length
            byte[] buffer = m_WriteBuffer.GetBuffer();
            int    length = (int)m_WriteBuffer.Length;

            AppLogging.DebugLog(nameof(WriteMessage), command.ToString(), message != null ? message.ToString() : "");

            try { m_SerialPort.Write(buffer, 0, length); }
            catch (Exception e)
            {
                AppLogging.DebugLogException(nameof(WriteMessage), e);
                return;
            }
            m_LastMessageWrite = now;
        }
Пример #10
0
        /// <summary>
        /// Unregisters the session from the service so events
        /// are not responded to anymore.
        /// <param name="device">The device to unregister</param>
        private void UnregisterDevice(IAudioDevice device)
        {
            AppLogging.DebugLog(nameof(UnregisterDevice), device.DeviceId, device.DisplayName);
            if (_sessionManagers.ContainsKey(device.Id))
            {
                _sessionManagers[device.Id].SessionCreated -= OnSessionCreated;
                _sessionManagers.Remove(device.Id);
            }

            device.DeviceDefaultChanged -= OnDefaultDeviceChanged;
            device.DeviceVolumeChanged  -= OnDeviceVolumeChanged;
            device.DeviceRemoved        -= OnDeviceRemoved;

            if (_devices.ContainsKey(device.Id))
            {
                _devices.Remove(device.Id);
                RaiseDeviceRemoved(device.Id, device.Flow);
            }

            device.Dispose();
        }
Пример #11
0
    /// <summary>
    /// This will serve as the debug-assert mechanism for this app
    /// </summary>
    /// <param name="condition"></param>
    /// <param name="text"></param>
    public static void Assert(bool condition, string text)
    {
        if (condition)
        {
            return;
        }

        //System assert...
        System.Diagnostics.Debug.Assert(false, text);

        //UNDONE: (1) Write to debug file. (2) Add mechanism to return assert failures to client
        string assertFailure = text;

        try
        {
            AppLogging.LogAssertData(text);
        }
        catch (Exception e)
        {
            string eMessage = e.Message;
        }
    }
        private void Read(DateTime now)
        {
#if POLLING_SERIAL
            try
            {
                if (m_SerialPort == null || !m_SerialPort.IsOpen || m_SerialPort.BytesToRead <= 0)
                {
                    return;
                }
            }
            catch { return; }
#endif

            Command command;
            try { command = (Command)m_SerialPort.ReadByte(); }
            catch (Exception ex)
            {
                AppLogging.DebugLogException(nameof(Read), ex);
                Interlocked.Increment(ref m_ErrorCount);
                return;
            }

            Interlocked.Increment(ref m_ReadCount);
            Interlocked.Increment(ref m_ReadBytes);
            switch (command)
            {
            case Command.TEST:
            {
                try
                {
                    var firmware = m_SerialPort.ReadLine().Replace("\r", "");
                    AppLogging.DebugLog(nameof(Read), command.ToString(), firmware);
                    m_LastMessageRead  = now;
                    m_LastMessageWrite = now;
                }
                catch (Exception e)
                {
                    AppLogging.DebugLogException(nameof(ReadMessage), e);
                    Interlocked.Increment(ref m_ErrorCount);
                    return;
                }
            }
            break;

            case Command.OK:
            {
                AppLogging.DebugLog(nameof(Read), command.ToString());
                m_DeviceReady      = true;
                m_LastMessageRead  = now;
                m_LastMessageWrite = now;
                Write(m_LastMessageRead);
            }
            break;

            case Command.SETTINGS:
                ReadMessage <DeviceSettings>(now, command);
                break;

            case Command.SESSION_INFO:
                ReadMessage <SessionInfo>(now, command);
                break;

            case Command.CURRENT_SESSION:
            case Command.ALTERNATE_SESSION:
            case Command.PREVIOUS_SESSION:
            case Command.NEXT_SESSION:
                ReadMessage <SessionData>(now, command);
                break;

            case Command.VOLUME_CURR_CHANGE:
            case Command.VOLUME_ALT_CHANGE:
            case Command.VOLUME_PREV_CHANGE:
            case Command.VOLUME_NEXT_CHANGE:
                ReadMessage <VolumeData>(now, command);
                break;

            case Command.MODE_STATES:
                ReadMessage <ModeStates>(now, command);
                break;

            case Command.ERROR:
            case Command.NONE:
            case Command.DEBUG:
                Interlocked.Increment(ref m_ErrorCount);
                break;
            }
        }
Пример #13
0
 /// <summary>
 /// Ctor.
 /// </summary>
 /// <param name="model">The model to validate.</param>
 /// <param name="data">The data needed for validation.</param>
 protected AbstractValidator(TModel model, TData data)
 {
     Logger = AppLogging.CreateLogger(GetType().Name);
     Model  = model;
     Data   = data;
 }
Пример #14
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        /// </summary>
        /// <param name="app">The application builder.</param>
        /// <param name="env">The environment.</param>
        /// <param name="applicationLifetime">The application lifetime.</param>
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
        {
            // set the current directory to the environment content root ... note this is only for AspNet.Core 2.2 ... not need for AspNet.Core 3.0 as issue is fixed.
            Directory.SetCurrentDirectory(env.ContentRootPath);

            // set up  logging
            AppLogging.LoggerFactory.AddSerilog();
            this.Logger = AppLogging.CreateLogger <Startup>();

            // register to flush logs if shutdown called
            applicationLifetime.ApplicationStopped.Register(Log.CloseAndFlush);

            // log the environment on startup
            this.Logger.LogInformation($"Environment is {env.EnvironmentName}");

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            // initialise health checks
            app.UseHealthChecks(
                "/health",
                new HealthCheckOptions()
            {
                Predicate = _ => true
            });
            app.UseHealthChecks(
                "/healthchecks",
                options: new HealthCheckOptions()
            {
                Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
            });
            app.UseHealthChecksUI(
                setup =>
            {
                // defaults
                setup.ApiPath       = "/healthchecks-api";
                setup.UIPath        = "/healthchecks-ui";
                setup.WebhookPath   = "/healthchecks-webhooks";
                setup.ResourcesPath = "/ui/resources";
            });

            // add middleware
            app.UseCors("CorsPolicy");
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();
            app.UseSwagger();
            app.UseCorrelationId();

            FluentMapper.Initialize(config =>
            {
                config.AddMap(new PriceMap());
                config.AddMap(new PortfolioMap());
                config.AddMap(new StaleYieldMap());
                config.AddMap(new UnderlyingMap());
                config.AddMap(new YieldPointMap());
            });

            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "PriceMovement");
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                //// To learn more about options for serving an Angular SPA from ASP.NET Core,
                //// see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }
Пример #15
0
        private void Read(object sender, SerialDataReceivedEventArgs e)
        {
            if (e.EventType == SerialData.Eof)
            {
                return;
            }

            Command command = (Command)m_SerialPort.ReadByte();

            Interlocked.Increment(ref m_ReadCount);
            Interlocked.Increment(ref m_ReadBytes);
            switch (command)
            {
            case Command.TEST:
            {
                var firmware = m_SerialPort.ReadLine().Replace("\r", "");
                AppLogging.DebugLog(nameof(Read), command.ToString(), firmware);
                m_LastMessageRead = DateTime.Now;
            }
            break;

            case Command.OK:
            {
                AppLogging.DebugLog(nameof(Read), command.ToString());
                m_DeviceReady = true;
                DateTime now = DateTime.Now;
                m_LastMessageRead  = now;
                m_LastMessageWrite = now;
                Write(m_LastMessageRead);
            }
            break;

            case Command.SETTINGS:
                ReadMessage <DeviceSettings>(command);
                break;

            case Command.SESSION_INFO:
                ReadMessage <SessionInfo>(command);
                break;

            case Command.CURRENT_SESSION:
            case Command.ALTERNATE_SESSION:
            case Command.PREVIOUS_SESSION:
            case Command.NEXT_SESSION:
                ReadMessage <SessionData>(command);
                break;

            case Command.VOLUME_CURR_CHANGE:
            case Command.VOLUME_ALT_CHANGE:
            case Command.VOLUME_PREV_CHANGE:
            case Command.VOLUME_NEXT_CHANGE:
                ReadMessage <VolumeData>(command);
                break;

            case Command.ERROR:
            case Command.NONE:
            case Command.DEBUG:
                Interlocked.Increment(ref m_ErrorCount);
                break;
            }
        }
Пример #16
0
 /// <summary>
 /// Should be called to log any potential security concerns
 /// </summary>
 /// <param name="text"></param>
 public static void WriteLineSecurityConcern(string text, SecurityConcernLevel concernLevel = SecurityConcernLevel.High)
 {
     WriteLine("Security: " + text);
     AppLogging.LogSecurityConcern(text, concernLevel);
 }