/// <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); }