@code
diff --git a/Basestation_Software.Web/Core/Services/CookieService.cs b/Basestation_Software.Web/Core/Services/CookieService.cs
index 5576bc9..f73967b 100644
--- a/Basestation_Software.Web/Core/Services/CookieService.cs
+++ b/Basestation_Software.Web/Core/Services/CookieService.cs
@@ -1,79 +1,83 @@
using Microsoft.JSInterop;
-namespace Basestation_Software.Web.Core.Services
+namespace Basestation_Software.Web.Core.Services;
+
+public class CookieService
{
- public class CookieService
+ // Declare member variables.
+ private readonly IJSRuntime _JSRuntime;
+ string expires = "";
+
+ ///
+ /// Constructor
+ ///
+ /// Implicitly passed in.
+ public CookieService(IJSRuntime jsRuntime)
{
- // Declare member variables.
- private readonly IJSRuntime _JSRuntime;
- string expires = "";
+ _JSRuntime = jsRuntime;
+ ExpireDays = 30;
+ }
- ///
- /// Constructor
- ///
- /// Implicitly passed in.
- public CookieService(IJSRuntime jsRuntime)
- {
- _JSRuntime = jsRuntime;
- ExpireDays = 30;
- }
+ ///
+ /// Stores a cookie in the browser.
+ ///
+ /// The key to reference the cookie by later.
+ /// The calue to store in the cookie
+ /// The number of days before the cookie expires.
+ ///
+ public async Task SetValue(string key, string value, int? days = null)
+ {
+ var curExp = (days != null) ? (days > 0 ? DateToUTC(days.Value) : "") : expires;
+ await SetCookie($"{key}={value}; expires={curExp}; path=/");
+ }
- ///
- /// Stores a cookie in the browser.
- ///
- /// The key to reference the cookie by later.
- /// The calue to store in the cookie
- /// The number of days before the cookie expires.
- ///
- public async Task SetValue(string key, string value, int? days = null)
- {
- var curExp = (days != null) ? (days > 0 ? DateToUTC(days.Value) : "") : expires;
- await SetCookie($"{key}={value}; expires={curExp}; path=/");
- }
+ ///
+ /// Gets a cookie from the browser.
+ ///
+ /// The name of the cookie.
+ /// The default value if the cookie isn't found.
+ ///
+ public async Task GetValue(string key, string def = "")
+ {
+ var cValue = await GetCookie();
+ if (string.IsNullOrEmpty(cValue)) return def;
- ///
- /// Gets a cookie from the browser.
- ///
- /// The name of the cookie.
- /// The default value if the cookie isn't found.
- ///
- public async Task GetValue(string key, string def = "")
+ var vals = cValue.Split(';');
+ foreach (var val in vals)
{
- var cValue = await GetCookie();
- if (string.IsNullOrEmpty(cValue)) return def;
-
- var vals = cValue.Split(';');
- foreach (var val in vals)
- if(!string.IsNullOrEmpty(val) && val.IndexOf('=') > 0)
- if(val.Substring(0, val.IndexOf('=')).Trim().Equals(key, StringComparison.OrdinalIgnoreCase))
- return val.Substring(val.IndexOf('=') + 1);
- return def;
+ if (!string.IsNullOrEmpty(val) && val.IndexOf('=') > 0)
+ {
+ if (val.Substring(0, val.IndexOf('=')).Trim().Equals(key, StringComparison.OrdinalIgnoreCase))
+ return val.Substring(val.IndexOf('=') + 1);
+ }
}
- ///
- /// Sets a cookie.
- ///
- /// Cookie info.
- ///
- private async Task SetCookie(string value)
- {
- await _JSRuntime.InvokeVoidAsync("eval", $"document.cookie = \"{value}\"");
- }
+ return def;
+ }
- ///
- /// Gets a cookie.
- ///
- /// The cookie info.
- private async Task GetCookie()
- {
- return await _JSRuntime.InvokeAsync("eval", $"document.cookie");
- }
+ ///
+ /// Sets a cookie.
+ ///
+ /// Cookie info.
+ ///
+ private async Task SetCookie(string value)
+ {
+ await _JSRuntime.InvokeVoidAsync("eval", $"document.cookie = \"{value}\"");
+ }
- public int ExpireDays
- {
- set => expires = DateToUTC(value);
- }
+ ///
+ /// Gets a cookie.
+ ///
+ /// The cookie info.
+ private async Task GetCookie()
+ {
+ return await _JSRuntime.InvokeAsync("eval", $"document.cookie");
+ }
- private static string DateToUTC(int days) => DateTime.Now.AddDays(days).ToUniversalTime().ToString("R");
+ public int ExpireDays
+ {
+ set => expires = DateToUTC(value);
}
+
+ private static string DateToUTC(int days) => DateTime.Now.AddDays(days).ToUniversalTime().ToString("R");
}
\ No newline at end of file
diff --git a/Basestation_Software.Web/Core/Services/GPSWaypointService.cs b/Basestation_Software.Web/Core/Services/GPSWaypointService.cs
index 0bb1f09..ef00bde 100644
--- a/Basestation_Software.Web/Core/Services/GPSWaypointService.cs
+++ b/Basestation_Software.Web/Core/Services/GPSWaypointService.cs
@@ -1,119 +1,118 @@
using Basestation_Software.Models.Geospatial;
-namespace Basestation_Software.Web.Core.Services
+namespace Basestation_Software.Web.Core.Services;
+
+public class GPSWaypointService
{
- public class GPSWaypointService
- {
- // Injected services.
- private readonly HttpClient _HttpClient;
- // Declare member variables.
- private List _gpsWaypoints = new List();
+ // Injected services.
+ private readonly HttpClient _HttpClient;
+ // Declare member variables.
+ private List _gpsWaypoints = [];
- // Method delegates and events.
- public delegate Task SyncWaypointsCallback();
- private event SyncWaypointsCallback? SyncWaypointsNotifier;
+ // Method delegates and events.
+ public delegate Task SyncWaypointsCallback();
+ private event SyncWaypointsCallback? SyncWaypointsNotifier;
- ///
- /// Constructor
- ///
- /// Implicitly passed in, used to talk to the basestation API.
- public GPSWaypointService(HttpClient httpClient)
- {
- // Assign member variables.
- _HttpClient = httpClient;
- }
+ ///
+ /// Constructor
+ ///
+ /// Implicitly passed in, used to talk to the basestation API.
+ public GPSWaypointService(HttpClient httpClient)
+ {
+ // Assign member variables.
+ _HttpClient = httpClient;
+ }
- ///
- /// Refreshes the cached waypoints list from the API database.
- ///
- ///
- public async Task RefreshGPSWaypoints()
+ ///
+ /// Refreshes the cached waypoints list from the API database.
+ ///
+ ///
+ public async Task RefreshGPSWaypoints()
+ {
+ List? waypoints = await _HttpClient.GetFromJsonAsync>("http://localhost:5000/api/GPSWaypoint");
+ if (waypoints is not null)
{
- List? waypoints = await _HttpClient.GetFromJsonAsync>("http://localhost:5000/api/GPSWaypoint");
- if (waypoints is not null)
- {
- _gpsWaypoints = waypoints;
- }
-
- // Invoke the callback to refresh page data.
- await SyncWaypointsNotifier!.Invoke();
+ _gpsWaypoints = waypoints;
}
- ///
- /// Add a callback to get invoked when the waypoints list changes.
- ///
- /// The method callback to add.
- public void SubscribeToWaypointsChanges(SyncWaypointsCallback callback)
- {
- SyncWaypointsNotifier += callback;
- }
+ // Invoke the callback to refresh page data.
+ await SyncWaypointsNotifier!.Invoke();
+ }
- ///
- /// Remove a callback from getting invoked when the waypoints list changes.
- ///
- /// The method callback to remove.
- public void UnsubscribeFromWaypointsChanges(SyncWaypointsCallback callback)
- {
- SyncWaypointsNotifier -= callback;
- }
+ ///
+ /// Add a callback to get invoked when the waypoints list changes.
+ ///
+ /// The method callback to add.
+ public void SubscribeToWaypointsChanges(SyncWaypointsCallback callback)
+ {
+ SyncWaypointsNotifier += callback;
+ }
- ///
- /// Add a new waypoint to the database.
- ///
- /// The waypoint to add.
- ///
- public async Task AddGPSWaypoint(GPSWaypoint waypoint)
- {
- // Add the waypoint to the database with the API.
- await _HttpClient.PutAsJsonAsync($"http://localhost:5000/api/GPSWaypoint", waypoint);
- // Refresh data.
- await RefreshGPSWaypoints();
- }
+ ///
+ /// Remove a callback from getting invoked when the waypoints list changes.
+ ///
+ /// The method callback to remove.
+ public void UnsubscribeFromWaypointsChanges(SyncWaypointsCallback callback)
+ {
+ SyncWaypointsNotifier -= callback;
+ }
- ///
- /// Update a waypoint in the database.
- ///
- /// The waypoint to update. ID must match an existing ID.
- ///
- public async Task UpdateGPSWaypoint(GPSWaypoint waypoint)
- {
- // Write the waypoint data to the database with the API.
- await _HttpClient.PostAsJsonAsync($"http://localhost:5000/api/GPSWaypoint", waypoint);
- // Refresh data.
- await RefreshGPSWaypoints();
- }
+ ///
+ /// Add a new waypoint to the database.
+ ///
+ /// The waypoint to add.
+ ///
+ public async Task AddGPSWaypoint(GPSWaypoint waypoint)
+ {
+ // Add the waypoint to the database with the API.
+ await _HttpClient.PutAsJsonAsync($"http://localhost:5000/api/GPSWaypoint", waypoint);
+ // Refresh data.
+ await RefreshGPSWaypoints();
+ }
- ///
- /// Given a waypoint ID delete it from the database.
- ///
- /// The waypoint to delete.
- ///
- public async Task DeleteGPSWaypoint(GPSWaypoint waypoint)
- {
- // Delete the waypoint from the database.
- await _HttpClient.DeleteAsync($"http://localhost:5000/api/GPSWaypoint/{waypoint.ID}");
- // Refresh data.
- await RefreshGPSWaypoints();
- }
+ ///
+ /// Update a waypoint in the database.
+ ///
+ /// The waypoint to update. ID must match an existing ID.
+ ///
+ public async Task UpdateGPSWaypoint(GPSWaypoint waypoint)
+ {
+ // Write the waypoint data to the database with the API.
+ await _HttpClient.PostAsJsonAsync($"http://localhost:5000/api/GPSWaypoint", waypoint);
+ // Refresh data.
+ await RefreshGPSWaypoints();
+ }
- ///
- /// Return a reference to the list of GPSWaypoints.
- ///
- ///
- public List GetGPSWaypoints()
- {
- return _gpsWaypoints;
- }
+ ///
+ /// Given a waypoint ID delete it from the database.
+ ///
+ /// The waypoint to delete.
+ ///
+ public async Task DeleteGPSWaypoint(GPSWaypoint waypoint)
+ {
+ // Delete the waypoint from the database.
+ await _HttpClient.DeleteAsync($"http://localhost:5000/api/GPSWaypoint/{waypoint.ID}");
+ // Refresh data.
+ await RefreshGPSWaypoints();
+ }
- ///
- /// Returns the waypoint with the given ID.
- ///
- /// The ID of the waypoint to retrieve.
- ///
- public GPSWaypoint? GetGPSWaypoint(int waypointID)
- {
- return _gpsWaypoints.FirstOrDefault(x => x.ID == waypointID);
- }
+ ///
+ /// Return a reference to the list of GPSWaypoints.
+ ///
+ ///
+ public List GetGPSWaypoints()
+ {
+ return _gpsWaypoints;
+ }
+
+ ///
+ /// Returns the waypoint with the given ID.
+ ///
+ /// The ID of the waypoint to retrieve.
+ ///
+ public GPSWaypoint? GetGPSWaypoint(int waypointID)
+ {
+ return _gpsWaypoints.FirstOrDefault(x => x.ID == waypointID);
}
}
\ No newline at end of file
diff --git a/Basestation_Software.Web/Core/Services/MapTileService.cs b/Basestation_Software.Web/Core/Services/MapTileService.cs
index 99f02f7..45710a0 100644
--- a/Basestation_Software.Web/Core/Services/MapTileService.cs
+++ b/Basestation_Software.Web/Core/Services/MapTileService.cs
@@ -1,92 +1,91 @@
using Basestation_Software.Models.Geospatial;
-namespace Basestation_Software.Web.Core.Services
+namespace Basestation_Software.Web.Core.Services;
+
+public class MapTileService
{
- public class MapTileService
+ // Declare member variables.
+ private readonly HttpClient _HttpClient;
+
+
+ ///
+ /// Constructor
+ ///
+ /// Implicitly passed in, used to talk to the basestation API.
+ public MapTileService(HttpClient httpClient)
{
- // Declare member variables.
- private readonly HttpClient _HttpClient;
-
+ // Assign member variables.
+ _HttpClient = httpClient;
+ }
- ///
- /// Constructor
- ///
- /// Implicitly passed in, used to talk to the basestation API.
- public MapTileService(HttpClient httpClient)
- {
- // Assign member variables.
- _HttpClient = httpClient;
- }
+ ///
+ /// Add a new tile to the database.
+ ///
+ /// The tile to add.
+ ///
+ public async Task AddMapTile(MapTile tile)
+ {
+ // Add the tile to the database with the API.
+ await _HttpClient.PutAsJsonAsync($"http://localhost:5000/api/MapTiles", tile);
+ }
- ///
- /// Add a new tile to the database.
- ///
- /// The tile to add.
- ///
- public async Task AddMapTile(MapTile tile)
- {
- // Add the tile to the database with the API.
- await _HttpClient.PutAsJsonAsync($"http://localhost:5000/api/MapTiles", tile);
- }
+ ///
+ /// Update a tile in the database.
+ ///
+ /// The tile to update. ID must match an existing ID.
+ ///
+ public async Task UpdateMapTile(MapTile tile)
+ {
+ // Write the tile data to the database with the API.
+ await _HttpClient.PostAsJsonAsync($"http://localhost:5000/api/MapTiles", tile);
+ }
+
+ ///
+ /// Given a tile ID delete it from the database.
+ ///
+ /// The tile to delete.
+ ///
+ public async Task DeleteMapTile(MapTile tile)
+ {
+ // Delete the tile from the database.
+ await _HttpClient.DeleteAsync($"http://localhost:5000/api/MapTiles/{tile.ID}");
+ }
- ///
- /// Update a tile in the database.
- ///
- /// The tile to update. ID must match an existing ID.
- ///
- public async Task UpdateMapTile(MapTile tile)
+ ///
+ /// Returns the tile image with the given x, y, z
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task GetMapTileImage(int x, int y, int z)
+ {
+ try
{
- // Write the tile data to the database with the API.
- await _HttpClient.PostAsJsonAsync($"http://localhost:5000/api/MapTiles", tile);
+ return await _HttpClient.GetFromJsonAsync($"http://localhost:5000/api/MapTiles/{z}/{y}/{x}.png");
}
-
- ///
- /// Given a tile ID delete it from the database.
- ///
- /// The tile to delete.
- ///
- public async Task DeleteMapTile(MapTile tile)
+ catch (Exception)
{
- // Delete the tile from the database.
- await _HttpClient.DeleteAsync($"http://localhost:5000/api/MapTiles/{tile.ID}");
+ return null;
}
+ }
- ///
- /// Returns the tile image with the given x, y, z
- ///
- ///
- ///
- ///
- ///
- public async Task GetMapTileImage(int x, int y, int z)
+ ///
+ /// Returns the tile with the given x, y, z
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task GetMapTile(int x, int y, int z)
+ {
+ try
{
- try
- {
- return await _HttpClient.GetFromJsonAsync($"http://localhost:5000/api/MapTiles/{z}/{y}/{x}.png");
- }
- catch (Exception)
- {
- return null;
- }
+ return await _HttpClient.GetFromJsonAsync($"http://localhost:5000/api/MapTiles/{z}/{y}/{x}");
}
-
- ///
- /// Returns the tile with the given x, y, z
- ///
- ///
- ///
- ///
- ///
- public async Task GetMapTile(int x, int y, int z)
+ catch (Exception)
{
- try
- {
- return await _HttpClient.GetFromJsonAsync($"http://localhost:5000/api/MapTiles/{z}/{y}/{x}");
- }
- catch (Exception)
- {
- return null;
- }
+ return null;
}
}
}
\ No newline at end of file
diff --git a/Basestation_Software.Web/Core/Services/RoveComm/RoveCommService.cs b/Basestation_Software.Web/Core/Services/RoveComm/RoveCommService.cs
new file mode 100644
index 0000000..295c1df
--- /dev/null
+++ b/Basestation_Software.Web/Core/Services/RoveComm/RoveCommService.cs
@@ -0,0 +1,362 @@
+using Basestation_Software.Models.RoveComm;
+
+namespace Basestation_Software.Web.Core.Services.RoveComm;
+
+public class RoveCommService : IHostedService
+{
+
+ public RoveCommUDP UDP;
+ public RoveCommTCP TCP;
+
+ private readonly CancellationTokenSource _cts = new();
+ private readonly ILogger _logger;
+
+ public RoveCommService(ILogger logger)
+ {
+ _logger = logger;
+ UDP = new RoveCommUDP(_logger);
+ TCP = new RoveCommTCP(_logger);
+ }
+
+ public Task StartAsync(CancellationToken cancelToken)
+ {
+ Begin(cancelToken);
+ SubscribeAll();
+ return Task.CompletedTask;
+ }
+
+ public void Begin(CancellationToken cancelToken)
+ {
+ _logger.LogInformation("Starting RoveComm.");
+ UDP.Begin(cancelToken);
+ TCP.Begin(cancelToken);
+ }
+
+ ///
+ /// Attach the given callback to be triggered when a RoveCommPacket with the given DataID is received.
+ ///
+ /// The DataID to listen for.
+ /// The function to call when the DataID is received.
+ /// Thrown if the type was invalid.
+ public void On(int dataId, RoveCommCallback handler)
+ {
+ TCP.On(dataId, handler);
+ UDP.On(dataId, handler);
+ _logger.LogInformation("Subscribed to {DataID} with type {DataType}.", dataId, RoveCommUtils.DataTypeFromType(typeof(T)));
+ }
+
+ ///
+ /// Attach the given callback to be triggered when a RoveCommPacket from the Manifest is received.
+ ///
+ /// The name of the board as shown in the Manifest.
+ /// The name of the Telemetry or Error message as shown in the Manifest.
+ /// The function to call when the DataID is received.
+ ///
+ /// Thrown if the packet descriptor was not found in the Manifest or did not match the given type.
+ ///
+ public void On(string boardName, string dataIdString, RoveCommCallback handler)
+ {
+ RoveCommUtils.FindDataIDByName(boardName, dataIdString, out var boardDesc, out var packetDesc);
+ if (boardDesc is null)
+ {
+ throw new RoveCommException($"Failed to subscribe to RoveComm: {boardName} Board not found in RoveCommManifest.");
+ }
+ else if (packetDesc is null)
+ {
+ throw new RoveCommException($"Failed to subscribe to RoveComm: {dataIdString} not found for {boardName} Board.");
+ }
+
+ RoveCommDataType handlerType = RoveCommUtils.DataTypeFromType(typeof(T));
+ if (packetDesc.DataType != handlerType)
+ {
+ throw new RoveCommException($"Failed to subscribe to RoveComm: {handlerType} does not match type of {dataIdString} ({packetDesc.DataType}).");
+ }
+
+ On(packetDesc.DataID, handler);
+ }
+
+ ///
+ /// Clear the given callback from all DataID's.
+ ///
+ /// The callback to remove.
+ /// Thrown if the type was invalid.
+ public void Clear(RoveCommCallback handler)
+ {
+ UDP.Clear(handler);
+ TCP.Clear(handler);
+ }
+
+ ///
+ /// Clear the given callback from the given DataID.
+ ///
+ /// The DataID to remove the callback from.
+ /// The callback to remove.
+ /// Thrown if the type was invalid.
+ public void Clear(int dataId, RoveCommCallback handler)
+ {
+ UDP.Clear(dataId, handler);
+ TCP.Clear(dataId, handler);
+ _logger.LogInformation("Unsubscribed from {DataID} with type {DataType}.", dataId, RoveCommUtils.DataTypeFromType(typeof(T)));
+ }
+
+ ///