diff --git a/Agent/Program.cs b/Agent/Program.cs index 3258a39f7..224bbaeb1 100644 --- a/Agent/Program.cs +++ b/Agent/Program.cs @@ -92,6 +92,7 @@ private static void RegisterServices(IServiceCollection services) // TODO: All these should be registered as interfaces. services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddHostedService(services => services.GetRequiredService()); services.AddScoped(); services.AddTransient(); diff --git a/Server/Components/Devices/DeviceCard.razor.cs b/Server/Components/Devices/DeviceCard.razor.cs index 2567c7a22..9ce69b8d4 100644 --- a/Server/Components/Devices/DeviceCard.razor.cs +++ b/Server/Components/Devices/DeviceCard.razor.cs @@ -328,11 +328,15 @@ private async Task WakeDevice() var result = await CircuitConnection.WakeDevice(Device); if (result.IsSuccess) { - ToastService.ShowToast2("Wake command sent.", ToastType.Success); + ToastService.ShowToast2( + $"Wake command sent to {result.Value} peer devices.", + ToastType.Success); } else { - ToastService.ShowToast2($"Wake command failed. Reason: {result.Reason}", ToastType.Error); + ToastService.ShowToast2( + $"Wake command failed. Reason: {result.Reason}", + ToastType.Error); } } } diff --git a/Server/Components/Devices/DevicesFrame.razor b/Server/Components/Devices/DevicesFrame.razor index f916f2bd1..6cfc06734 100644 --- a/Server/Components/Devices/DevicesFrame.razor +++ b/Server/Components/Devices/DevicesFrame.razor @@ -8,17 +8,20 @@
Device Group
- - +
+ + + +
diff --git a/Server/Components/Devices/DevicesFrame.razor.cs b/Server/Components/Devices/DevicesFrame.razor.cs index d35fc2509..65c779cb5 100644 --- a/Server/Components/Devices/DevicesFrame.razor.cs +++ b/Server/Components/Devices/DevicesFrame.razor.cs @@ -358,7 +358,9 @@ private async Task WakeDevices() if (result.IsSuccess) { - ToastService.ShowToast2("Wake commands sent.", ToastType.Success); + ToastService.ShowToast2( + $"Wake commands sent to {result.Value} peer devices.", + ToastType.Success); } else { diff --git a/Server/Hubs/CircuitConnection.cs b/Server/Hubs/CircuitConnection.cs index f3c29d09b..e51efa76a 100644 --- a/Server/Hubs/CircuitConnection.cs +++ b/Server/Hubs/CircuitConnection.cs @@ -55,8 +55,22 @@ public interface ICircuitConnection Task UninstallAgents(string[] deviceIDs); Task UpdateTags(string deviceID, string tags); Task UploadFiles(List fileIDs, string transferID, string[] deviceIDs); - Task WakeDevice(Device device); - Task WakeDevices(Device[] deviceId); + + /// + /// Sends a Wake-On-LAN request for the specified device to its peer devices. + /// Peer devices are those in the same group or the same public IP. + /// + /// + /// The number of peer devices that broadcasted the WOL packet. + Task> WakeDevice(Device device); + + /// + /// Sends a Wake-On-LAN request for the specified device to its peer devices. + /// Peer devices are those in the same group or the same public IP. + /// + /// + /// The number of peer devices that broadcasted the WOL packet. + Task> WakeDevices(Device[] devices); } public class CircuitConnection : CircuitHandler, ICircuitConnection @@ -433,33 +447,34 @@ public Task UploadFiles(List fileIDs, string transferID, string[] device return Task.CompletedTask; } - public async Task WakeDevice(Device device) + public async Task> WakeDevice(Device device) { try { if (!_dataService.DoesUserHaveAccessToDevice(device.ID, User.Id)) { - return Result.Fail("Unauthorized.") ; + return Result.Fail("Unauthorized.") ; } var availableDevices = _serviceSessionCache .GetAllDevices() .Where(x => x.OrganizationID == User.OrganizationID && - (x.DeviceGroup == device.DeviceGroup || x.PublicIP == device.PublicIP)); + (x.DeviceGroup == device.DeviceGroup || x.PublicIP == device.PublicIP)) + .ToArray(); await SendWakeCommand(device, availableDevices); - return Result.Ok(); + return Result.Ok(availableDevices.Length); } catch (Exception ex) { _logger.LogError(ex, "Error waking device {deviceId}.", device.ID); - return Result.Fail(ex); + return Result.Fail(ex); } } - public async Task WakeDevices(Device[] devices) + public async Task> WakeDevices(Device[] devices) { try { @@ -483,6 +498,8 @@ public async Task WakeDevices(Device[] devices) { var group = devicesByGroupId.GetOrAdd(device.DeviceGroupID, key => new()); group.Add(device); + // We only need it added to one group. + continue; } if (!string.IsNullOrWhiteSpace(device.PublicIP)) @@ -492,27 +509,32 @@ public async Task WakeDevices(Device[] devices) } } + + var peerCount = 0; + foreach (var deviceToWake in filteredDevices) { if (!string.IsNullOrWhiteSpace(deviceToWake.DeviceGroupID) && devicesByGroupId.TryGetValue(deviceToWake.DeviceGroupID, out var groupList)) { await SendWakeCommand(deviceToWake, groupList); + peerCount += groupList.Count; } if (!string.IsNullOrWhiteSpace(deviceToWake.PublicIP) && - devicesByGroupId.TryGetValue(deviceToWake.PublicIP, out var ipList)) + devicesByPublicIp.TryGetValue(deviceToWake.PublicIP, out var ipList)) { await SendWakeCommand(deviceToWake, ipList); + peerCount += ipList.Count; } } - return Result.Ok(); + return Result.Ok(peerCount); } catch (Exception ex) { _logger.LogError(ex, "Error while waking devices."); - return Result.Fail(ex); + return Result.Fail(ex); } } diff --git a/Server/Services/DataService.cs b/Server/Services/DataService.cs index 0c02c0395..2d4e080f7 100644 --- a/Server/Services/DataService.cs +++ b/Server/Services/DataService.cs @@ -328,6 +328,7 @@ public async Task> AddOrUpdateDevice(Device device) using var dbContext = _appDbFactory.GetContext(); var resultDevice = await dbContext.Devices.FindAsync(device.ID); + if (resultDevice != null) { resultDevice.CurrentUser = device.CurrentUser; @@ -346,6 +347,7 @@ public async Task> AddOrUpdateDevice(Device device) resultDevice.TotalMemory = device.TotalMemory; resultDevice.TotalStorage = device.TotalStorage; resultDevice.AgentVersion = device.AgentVersion; + resultDevice.MacAddresses = device.MacAddresses; resultDevice.LastOnline = DateTimeOffset.Now; } else