diff --git a/.gitignore b/.gitignore index bd60ff8d..db1e92a3 100644 --- a/.gitignore +++ b/.gitignore @@ -395,3 +395,4 @@ essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/Pepp _site/ api/ *.DS_Store +/._PepperDash.Essentials.4Series.sln diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs index ab059244..a4476cd8 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Text.RegularExpressions; +using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.UI; @@ -106,6 +108,11 @@ namespace PepperDash.Essentials.Touchpanel public ReadOnlyCollection ConnectedIps => Panel.ConnectedIpList; + private System.Net.IPAddress csIpAddress; + + private System.Net.IPAddress csSubnetMask; + + /// /// Initializes a new instance of the MobileControlTouchpanelController class. /// @@ -182,6 +189,13 @@ namespace PepperDash.Essentials.Touchpanel }; RegisterForExtenders(); + + var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter); + var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId); + var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId); + + this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask); + this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress); } /// @@ -381,19 +395,81 @@ namespace PepperDash.Essentials.Touchpanel McServerUrlFeedback.LinkInputSig(Panel.StringInput[3]); UserCodeFeedback.LinkInputSig(Panel.StringInput[4]); + Panel.IpInformationChange += (sender, args) => + { + if (args.Connected) + { + this.LogVerbose("Connection from IP: {ip}", args.DeviceIpAddress); + this.LogInformation("Sending {appUrl} on join 1", AppUrlFeedback.StringValue); + + var appUrl = GetUrlWithCorrectIp(_appUrl); + Panel.StringInput[1].StringValue = appUrl; + + SetAppUrl(appUrl); + } + else + { + this.LogVerbose("Disconnection from IP: {ip}", args.DeviceIpAddress); + } + }; + Panel.OnlineStatusChange += (sender, args) => { - UpdateFeedbacks(); - this.LogInformation("Sending {appUrl} on join 1", AppUrlFeedback.StringValue); - Panel.StringInput[1].StringValue = AppUrlFeedback.StringValue; + UpdateFeedbacks(); + Panel.StringInput[1].StringValue = _appUrl; Panel.StringInput[2].StringValue = QrCodeUrlFeedback.StringValue; Panel.StringInput[3].StringValue = McServerUrlFeedback.StringValue; Panel.StringInput[4].StringValue = UserCodeFeedback.StringValue; }; } + /// + /// Gets the URL with the correct IP address based on the connected devices and the Crestron processor's IP address. + /// + /// + /// + private string GetUrlWithCorrectIp(string url) + { + var lanAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter); + + var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId); + + if(csIpAddress == null || csSubnetMask == null || url == null) + { + this.LogWarning("CS IP Address Subnet Mask or url is null, cannot determine correct IP for URL"); + return url; + } + + this.LogVerbose("Processor IP: {processorIp}, CS IP: {csIpAddress}, CS Subnet Mask: {csSubnetMask}", processorIp, csIpAddress, csSubnetMask); + this.LogVerbose("Connected IP Count: {connectedIps}", ConnectedIps.Count); + + var ip = ConnectedIps.Any(ipInfo => + { + if (System.Net.IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp)) + { + return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask); + } + this.LogWarning("Invalid IP address: {deviceIpAddress}", ipInfo.DeviceIpAddress); + return false; + }) ? csIpAddress.ToString() : processorIp; + + var match = Regex.Match(url, @"^http://([^:/]+):\d+/mc/app\?token=.+$"); + if (match.Success) + { + string ipa = match.Groups[1].Value; + // ip will be "192.168.1.100" + } + + // replace ipa with ip but leave the rest of the string intact + var updatedUrl = Regex.Replace(url, @"^http://[^:/]+", $"http://{ip}"); + + this.LogVerbose("Updated URL: {updatedUrl}", updatedUrl); + + return updatedUrl; + } + private void SubscribeForMobileControlUpdates() { foreach (var dev in DeviceManager.AllDevices) @@ -443,7 +519,8 @@ namespace PepperDash.Essentials.Touchpanel /// public void SetAppUrl(string url) { - _appUrl = url; + _appUrl = GetUrlWithCorrectIp(url); + AppUrlFeedback.FireUpdate(); } diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs index 0ebb0707..8fcfd11f 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs @@ -327,18 +327,22 @@ namespace PepperDash.Essentials.WebSocketServer } string ip = processorIp; - if (touchpanel.Touchpanel is IMobileControlCrestronTouchpanelController crestronTouchpanel && csIpAddress != null) - { - ip = crestronTouchpanel.ConnectedIps.Any(ipInfo => - { - if (System.Net.IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp)) - { - return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask); - } - this.LogWarning("Invalid IP address: {deviceIpAddress}", ipInfo.DeviceIpAddress); - return false; - }) ? csIpAddress.ToString() : processorIp; - } + + // Moved to the MobileControlTouchpanelController class in the GetUrlWithCorrectIp method + // triggered by the Panel.IpInformationChange event so that we know we have the necessary info + // to make the determination of which IP to use. + //if (touchpanel.Touchpanel is IMobileControlCrestronTouchpanelController crestronTouchpanel && csIpAddress != null) + //{ + // ip = crestronTouchpanel.ConnectedIps.Any(ipInfo => + // { + // if (System.Net.IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp)) + // { + // return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask); + // } + // this.LogWarning("Invalid IP address: {deviceIpAddress}", ipInfo.DeviceIpAddress); + // return false; + // }) ? csIpAddress.ToString() : processorIp; + //} var appUrl = $"http://{ip}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}";