Beispiel #1
0
        /// <summary>
        /// Read a message from the client.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="data"></param>
        /// <param name="tag"></param>
        void newSocket_DidRead(AsyncSocket sender, byte[] data, long tag)
        {
            String msg = null;

            try
            {
                msg = Encoding.UTF8.GetString(data);

                //comment this out to log all received commands
                //WifiRemote.LogMessage(msg, WifiRemote.LogType.Debug);

                // Get json object
                JObject message = JObject.Parse(msg);
                string type = (string)message["Type"];
                RemoteClient client = sender.GetRemoteClient();

                // Autologin handling
                //
                // Has to be activated in WifiRemote configuration.
                string clientKey = (string)message["AutologinKey"];

                // Key is set: try to authenticate by AutoLoginKey
                if (clientKey != null && !client.IsAuthenticated)
                {
                    if (AutologinTimeout > 0)
                    {
                        AutoLoginToken token = new AutoLoginToken(clientKey, client);
                        // the client token is in the list
                        foreach (AutoLoginToken aToken in loginTokens)
                        {
                            if (aToken.Key == token.Key)
                            {
                                // Check if the autologin key was issued within the timeout
                                TimeSpan elapsed = DateTime.Now - aToken.Issued;
                                client.IsAuthenticated = (elapsed.Minutes < AutologinTimeout);
                                client = aToken.Client;

                                // Renew the timeout
                                aToken.Issued = DateTime.Now;
                            }
                        }

                        // MediaPortal was rebooted (will wipe all AutoLoginKeys) or
                        // autologin time out period is over (configurable in settings).
                        //
                        // Tell the client to reauthenticate.
                        if (!client.IsAuthenticated)
                        {
                            WifiRemote.LogMessage("AutoLoginToken timed out. Client needs to reauthenticate.", WifiRemote.LogType.Debug);
                            TellClientToReAuthenticate(sender);
                            return;
                        }
                    }
                    else
                    {
                        WifiRemote.LogMessage("AutoLogin is disabled but client tried to auto-authenticate.", WifiRemote.LogType.Debug);
                        TellClientToReAuthenticate(sender);
                        return;
                    }
                }

                // The client is already authentificated or we don't need authentification
                if (type != null && client.IsAuthenticated && type != "identify")
                {
                    // Turn on display
                    keybd_event(VK_LSHIFT, 0x45, KEYEVENTF_KEYUP, 0);
                    if (GUIGraphicsContext.BlankScreen)
                    {
                        WifiRemote.LogMessage("Blank screen active, turn on screen", WifiRemote.LogType.Debug);
                        GUIGraphicsContext.BlankScreen = false;
                        GUIGraphicsContext.ResetLastActivity();
                    }

                    // Send a command
                    if (type == "command")
                    {
                        string command = (string)message["Command"];

                        communication.SendCommand(command);
                    }
                    // Send a key press
                    else if (type == "key")
                    {
                        string key = (string)message["Key"];
                        string modifier = (message["Modifier"] != null) ? (string)message["Modifier"] : null;
                        if (key != null)
                        {
                            communication.SendKey(modifier, key);
                        }
                    }
                    // Send a key down
                    else if (type == "commandstartrepeat")
                    {
                        string command = (string)message["Command"];
                        int pause = (int)message["Pause"];
                        if (command != null)
                        {
                            communication.SendCommandRepeatStart(command, pause);
                        }
                    }
                    // Send a key up
                    else if (type == "commandstoprepeat")
                    {
                        communication.SendCommandRepeatStop();
                    }
                    // Open a skin window
                    else if (type == "window")
                    {
                        int windowId = (int)message["Window"];
                        WindowPluginHelper.OpenWindow(windowId);
                    }
                    // Activate a window without resetting last activity
                    else if (type == "activatewindow")
                    {
                        int windowId = (int)message["Window"];
                        string param = (string)message["Parameter"];

                        WindowPluginHelper.ActivateWindow(windowId, param);
                    }
                    else if (type == "dialog")
                    {
                        MpDialogsMessageHandler.HandleDialogAction(message, this, sender);
                    }
                    else if (type == "facade")
                    {
                        MpFacadeMessageHandler.HandleFacadeMessage(message, this, sender);
                    }
                    // Shutdown/hibernate/reboot system or exit mediaportal
                    else if (type == "powermode")
                    {
                        string powerMode = (string)message["PowerMode"];
                        if (powerMode != null)
                        {
                            communication.SetPowerMode(powerMode);
                        }
                    }
                    // Directly set the volume to Volume percent
                    else if (type == "volume")
                    {
                        int volume = (int)message["Volume"];
                        bool relative = false;
                        if (message["Relative"] != null)
                        {
                            relative = (bool)message["Relative"];
                        }

                        communication.SetVolume(volume, relative);
                    }
                    // Set the position of the media item
                    else if (type == "position")
                    {
                        int seekType = (int)message["SeekType"];

                        if (seekType == 0)
                        {
                            int position = (int)message["Position"];
                            communication.SetPositionPercent(position, true);
                        }
                        if (seekType == 1)
                        {
                            int position = (int)message["Position"];
                            communication.SetPositionPercent(position, false);
                        }
                        if (seekType == 2)
                        {
                            int position = (int)message["Position"];
                            communication.SetPosition(position, true);
                        }
                        else if (seekType == 3)
                        {
                            int position = (int)message["Position"];
                            communication.SetPosition(position, false);
                        }
                    }
                    // Start to play a file identified by Filepath
                    else if (type == "playfile")
                    {
                        string fileType = (string)message["FileType"];
                        string filePath = (string)message["Filepath"];
                        string fileHandler = (string)message["FileHandler"];
                        int startPos = (message["StartPosition"] != null) ? (int)message["StartPosition"] : 0;

                        if (fileType != null && filePath != null)
                        {
                            // Play a video file
                            if (fileType == "video")
                            {
                                communication.PlayVideoFile(filePath, startPos, (!String.IsNullOrEmpty(fileHandler)) ? fileHandler : null);
                            }
                            // Play an audio file
                            else if (fileType == "audio")
                            {
                                communication.PlayAudioFile(filePath, startPos);
                            }
                        }
                    }
                    // play a tv channel on the client
                    else if (type == "playchannel")
                    {
                        int channelId = (int)message["ChannelId"];
                        bool startFullscreen = (message["StartFullscreen"] != null) ? (bool)message["StartFullscreen"] : false;
                        WifiRemote.LogMessage("playchannel: channelId: " + channelId + " fullscreen: " + startFullscreen, WifiRemote.LogType.Debug);

                        if (!WifiRemote.IsAvailableTVPlugin)
                        {
                            WifiRemote.LogMessage("No TVPlugin installed: Aborting playchannel", WifiRemote.LogType.Error);
                            return;
                        }
                        else
                        {
                            MpTvServerHelper.PlayTvChannel(channelId, startFullscreen);
                        }
                    }
                    // play a radio channel on the client
                    else if (type == "playradiochannel")
                    {
                        int channelId = (int)message["ChannelId"];
                        bool startFullscreen = (message["StartFullscreen"] != null) ? (bool)message["StartFullscreen"] : false;
                        WifiRemote.LogMessage("playradiochannel: channelId: " + channelId + " fullscreen: " + startFullscreen, WifiRemote.LogType.Debug);

                        if (!WifiRemote.IsAvailableTVPlugin)
                        {
                            WifiRemote.LogMessage("No TVPlugin installed: Aborting play radiochannel", WifiRemote.LogType.Error);
                            return;
                        }
                        else
                        {
                            MpTvServerHelper.PlayRadioChannel(channelId);
                        }
                    }
                    else if (type == "playrecording")
                    {
                        int recordingId = (int)message["RecordingId"];
                        bool startFullscreen = (message["StartFullscreen"] != null) ? (bool)message["StartFullscreen"] : false;
                        int startPos = (message["StartPosition"] != null) ? (int)message["StartPosition"] : 0;
                        WifiRemote.LogMessage("playrecording: recordingId: " + recordingId + " fullscreen: " + startFullscreen + " startpos: " + startPos, WifiRemote.LogType.Debug);

                        if (!WifiRemote.IsAvailableTVPlugin)
                        {
                            WifiRemote.LogMessage("No TVPlugin installed: Aborting playchannel", WifiRemote.LogType.Error);
                            return;
                        }
                        else
                        {
                            MpTvServerHelper.PlayRecording(recordingId, startPos, startFullscreen);
                        }
                    }
                    // invoke an action on a MpExtended item
                    else if (type == "mpext")
                    {
                        MpExtendedMessageHandler.HandleMpExtendedMessage(message, this, sender);
                    }
                    // Reply with a list of installed and active window plugins
                    // with icon and windowId
                    else if (type == "plugins")
                    {
                        bool sendIcons = false;
                        if (message["SendIcons"] != null)
                        {
                            sendIcons = (bool)message["SendIcons"];
                        }
                        SendWindowPluginsList(sender, sendIcons);
                    }
                    // register for a list of properties
                    else if (type == "properties")
                    {
                        client.Properties = new List<String>();
                        JArray array = (JArray)message["Properties"];
                        if (array != null)
                        {
                            foreach (JValue v in array)
                            {
                                String propString = (string)v.Value;
                                client.Properties.Add(propString);
                            }
                            SendPropertiesToClient(sender);
                        }
                    }
                    // request image
                    else if (type == "image")
                    {
                        String path = (string)message["ImagePath"];
                        if (path != null)
                        {
                            int imageWidth = (message["MaximumWidth"] != null) ? (int)message["MaximumWidth"] : 0;
                            int imageHeight = (message["MaximumHeight"] != null) ? (int)message["MaximumHeight"] : 0;
                            SendImageToClient(sender, path, (string)message["UserTag"], imageWidth, imageHeight);
                        }
                    }
                    // screenshot action
                    else if (type == "screenshot")
                    {
                        if (socketsWaitingForScreenshot == null)
                        {
                            socketsWaitingForScreenshot = new Dictionary<AsyncSocket, int>();
                        }

                        // Width to resize the image to, 0 to keep original width
                        int imageWidth = (message["Width"] != null) ? (int)message["Width"] : 0;

                        // Requests are added to a "waiting queue" because taking the screenshot happens
                        // async.
                        socketsWaitingForScreenshot.Add(sender, imageWidth);

                        if (imageHelper == null)
                        {
                            imageHelper = new ImageHelper();
                            imageHelper.ScreenshotReady += new ImageHelper.ScreenshotReadyCallback(imageHelperScreenshotReady);
                            imageHelper.ScreenshotFailed += new ImageHelper.ScreenshotFailedCallback(imageHelperScreenshotFailed);
                        }

                        imageHelper.TakeScreenshot();
                    }
                    //playlist actions
                    else if (type == "playlist")
                    {
                        PlaylistMessageHandler.HandlePlaylistMessage(message, this, sender);
                    }
                    // Send the current status to the client
                    else if (type == "requeststatus")
                    {
                        SendMessageToClient(statusMessage, sender);
                    }
                    // Send the current now playing message to the client
                    else if (type == "requestnowplaying")
                    {
                        SendMessageToClient(nowPlayingMessage, sender);
                    }
                    // MovingPictures related commands
                    else if (type == "movingpictures")
                    {
                        if (WifiRemote.IsAvailableMovingPictures)
                        {
                            MovingPicturesMessageHandler.HandleMovingPicturesMessage(message, this, sender);
                        }
                        else
                        {
                            WifiRemote.LogMessage("MovingPictures not installed but required!", WifiRemote.LogType.Error);
                        }
                    }
                    // MP-TVSeries related commands
                    else if (type == "tvseries")
                    {
                        if (WifiRemote.IsAvailableTVSeries)
                        {
                            TvSeriesMessageHandler.HandleTvSeriesMessage(message, this, sender);
                        }
                        else
                        {
                            WifiRemote.LogMessage("MP-TVSeries not installed but required!", WifiRemote.LogType.Error);
                        }
                    }
                    // Show a text in MediaPortal
                    else if (type == "message")
                    {
                        String text = (String)message["Text"];
                        int timeout = (message["Timeout"] != null) ? (int)message["Timeout"] : 2;
                        if (WifiRemote.IsAvailableNotificationBar && ShowNotifications)
                        {
                            MpNotificationHelper.SendNotification(text, timeout);
                        }
                    }
                    else if (type == "showdialog")
                    {
                        ShowDialogMessageHandler.HandleShowDialogMessage(message, this, sender);

                    }
                    else
                    {
                        // Unknown command. Log or inform user ...
                        WifiRemote.LogMessage("Unknown command received from client " + client.ToString() + ": " + type, WifiRemote.LogType.Info);
                    }
                }
                else
                {
                    // user is not yet authenticated
                    if (type == "identify")
                    {
                        // Save client name if supplied
                        if (message["Name"] != null)
                        {
                            client.ClientName = (string)message["Name"];
                        }

                        // Save client description if supplied
                        if (message["Description"] != null)
                        {
                            client.ClientDescription = (string)message["Description"];
                        }

                        // Save application name if supplied
                        if (message["Application"] != null)
                        {
                            client.ApplicationName = (string)message["Application"];
                        }

                        // Save application version if supplied
                        if (message["Version"] != null)
                        {
                            client.ApplicationVersion = (string)message["Version"];
                        }

                        // Authentication
                        if (AllowedAuth == AuthMethod.None ||
                            CheckAuthenticationRequest(client, message["Authenticate"]))
                        {
                            // User successfully authenticated
                            sender.GetRemoteClient().IsAuthenticated = true;
                            SendAuthenticationResponse(sender, true);
                            sendOverviewInformationToClient(sender);

                            // Turn on display
                            keybd_event(VK_LSHIFT, 0x45, KEYEVENTF_KEYUP, 0);
                            if (GUIGraphicsContext.BlankScreen)
                            {
                                WifiRemote.LogMessage("Blank screen active, turn on screen", WifiRemote.LogType.Debug);
                                GUIGraphicsContext.BlankScreen = false;
                                GUIGraphicsContext.ResetLastActivity();
                            }

                            if (WifiRemote.IsAvailableNotificationBar && ShowNotifications)
                            {
                                MpNotificationHelper.SendNotification("Client connected: " + client.ClientName);
                            }
                        }
                        else
                        {
                            if (WifiRemote.IsAvailableNotificationBar && ShowNotifications)
                            {
                                MpNotificationHelper.SendNotification("Client authentication failed: " + client.ClientName);
                            }
                            // Client sends a message other then authenticate when not yet
                            // authenticated or authenticate failed
                            SendAuthenticationResponse(sender, false);
                        }
                    }
                    else
                    {
                        // Client needs to authenticate first
                        TellClientToReAuthenticate(sender);
                    }
                }

                //WifiRemote.LogMessage("Received: " + msg, WifiRemote.LogType.Info);
            }
            catch (Exception e)
            {
                WifiRemote.LogMessage("WifiRemote Communication Error: " + e.Message, WifiRemote.LogType.Warn);
                //WifiRemote.LogMessage("Error converting received data into UTF-8 String: " + e.Message, WifiRemote.LogType.Error);
                //MediaPortal.Dialogs.GUIDialogNotify dialog = (MediaPortal.Dialogs.GUIDialogNotify)MediaPortal.GUI.Library.GUIWindowManager.GetWindow((int)MediaPortal.GUI.Library.GUIWindow.Window.WINDOW_DIALOG_NOTIFY);
                //dialog.Reset();
                //dialog.SetHeading("WifiRemote Communication Error");
                //dialog.SetText(e.Message);
                //dialog.DoModal(MediaPortal.GUI.Library.GUIWindowManager.ActiveWindow);
            }

            // Continue listening
            sender.Read(AsyncSocket.CRLFData, -1, 0);
        }