/// <summary>
        /// the current session disconnected
        /// </summary>
        void OnSessionDisconnect(MiracastReceiverSession sender, MiracastReceiverDisconnectedEventArgs args)
        {
            Log("current session disconnected, creating new session...");

            if (AutoStartNewSession)
            {
                StartNewSession();
            }
        }
        /// <summary>
        /// a new connection was created
        /// </summary>
        void OnSessionConnectionCreated(MiracastReceiverSession sender, MiracastReceiverConnectionCreatedEventArgs args)
        {
            //configure connection
            CurrentConnection = args.Connection;
            CurrentConnection.InputDevices.Keyboard.TransmitInput = false;

            //send pin event
            if (!string.IsNullOrWhiteSpace(args.Pin))
            {
                PinAvailable?.Invoke(CurrentConnection.Transmitter.Name, args.Pin);
            }

            //start timeout task
            currentConnectionTimeoutCancellation = new CancellationTokenSource();
            if (DeadConnectionTimeout > 0)
            {
                Task.Run(async() =>
                {
                    try
                    {
                        //wait until timeout
                        await Task.Delay(DeadConnectionTimeout, currentConnectionTimeoutCancellation.Token);

                        //check if a media player was created
                        if (currentPlayer == null)
                        {
                            //no media source was created, kill connection
                            Log($"no media player was created, killing connection to {CurrentConnection?.Transmitter?.MacAddress}");
                            Invoke(() =>
                            {
                                StartNewSession();
                            });
                            return;
                        }

                        //connection looks fine to me
                        Log("connection looks healthy, timeout task will now shut down.");
                    }
                    catch (TaskCanceledException)
                    {
                        //timeout was cancelled
                        Log("connection timeout was cancelled");
                    }
                });
            }

            //log details
            Log($"new connection created with {CurrentConnection.Transmitter.Name} ({CurrentConnection.Transmitter.MacAddress}). Auth pin is {(string.IsNullOrWhiteSpace(args.Pin) ? "No Pin" : args.Pin)}");
        }
        /// <summary>
        /// end the current cast session, and call CastEnd event
        /// </summary>
        /// <param name="sendEvent">should CastEnd be called?</param>
        void EndCurrentSession(bool sendEvent)
        {
            currentPlayer?.Pause();
            currentPlayer?.Dispose();
            currentPlayer = null;

            CurrentConnection?.Disconnect(MiracastReceiverDisconnectReason.Finished);
            CurrentConnection = null;

            currentSession?.Dispose();
            currentSession = null;

            if (sendEvent)
            {
                CastEnd?.Invoke();
            }
        }
        /// <summary>
        /// ends the old cast session and starts a new one
        /// </summary>
        public SessionStartResult StartNewSession()
        {
            //check receiver was initialized
            if (castReceiver == null)
            {
                throw new InvalidOperationException("Miracast receiver was not yet initialized! Call InitReceiver first.");
            }

            //end old cast session
            if (currentSession != null)
            {
                EndCurrentSession(true);
            }

            //init cast session, allow takeover
            currentSession = castReceiver.CreateSession(/*MainView*/ null);
            currentSession.AllowConnectionTakeover    = true;
            currentSession.MaxSimultaneousConnections = 1;

            //register event
            currentSession.ConnectionCreated  += OnSessionConnectionCreated;
            currentSession.MediaSourceCreated += OnSessionMediaSourceCreated;
            currentSession.Disconnected       += OnSessionDisconnect;

            //start receive on session
            MiracastReceiverSessionStartResult startResult = currentSession.Start();

            Log($"new miracast session initialized. result: {startResult.Status} ({(startResult.ExtendedError == null ? "No Error" : startResult.ExtendedError.ToString())})");

            //return correct result, end session if init failed
            switch (startResult.Status)
            {
            case MiracastReceiverSessionStartStatus.Success:
                return(SessionStartResult.Success);

            case MiracastReceiverSessionStartStatus.MiracastNotSupported:
                EndCurrentSession(false);
                return(SessionStartResult.MiracastNotSupported);

            case MiracastReceiverSessionStartStatus.AccessDenied:
            case MiracastReceiverSessionStartStatus.UnknownFailure:
            default:
                EndCurrentSession(false);
                return(SessionStartResult.Failure);
            }
        }
        /// <summary>
        /// a media source was created for the current session (start rendering to ui)
        /// </summary>
        void OnSessionMediaSourceCreated(MiracastReceiverSession sender, MiracastReceiverMediaSourceCreatedEventArgs args)
        {
            //set flag
            currentConnectionTimeoutCancellation?.Cancel();

            //init mediaplayer
            currentPlayer = new UWPMediaPlayer()
            {
                Source = args.MediaSource,
                IsVideoFrameServerEnabled = false,
                AutoPlay         = true,
                RealTimePlayback = true
            };

            //call event
            CastStart?.Invoke(CurrentConnection.Transmitter.Name, currentPlayer);

            //start playback
            Log($"starting playback of {CurrentConnection.Transmitter.Name} ({CurrentConnection.Transmitter.MacAddress})");
            currentPlayer.Play();
        }