Add Storage Operation Commands (#374)
This commit is contained in:
Родитель
3299eeed2b
Коммит
e9212f79d8
|
@ -27,30 +27,33 @@
|
|||
<Button Content="Disconnect" HorizontalAlignment="Left" Margin="250,102,0,0" VerticalAlignment="Top" Width="98" Click="DisconnectDeviceButton_Click"/>
|
||||
<Button Content="Ping" HorizontalAlignment="Left" Margin="250,129,0,0" VerticalAlignment="Top" Width="98" Click="PingButton_Click" />
|
||||
|
||||
<Button Content="Get Execution" HorizontalAlignment="Left" Margin="250,195,0,0" VerticalAlignment="Top" Width="98" Click="GetExecutionModeButton_Click"/>
|
||||
<Button Content="Deploy Test" HorizontalAlignment="Left" Margin="162,235,0,0" VerticalAlignment="Top" Width="75" Click="DeployTestButton_Click" />
|
||||
<Button Content="Get Deployment Map" HorizontalAlignment="Left" Margin="162,275,0,0" VerticalAlignment="Top" Width="75" Click="GetDeploymentMapButton_Click" />
|
||||
<Button Content="Get Execution" HorizontalAlignment="Left" Margin="250,187,0,0" VerticalAlignment="Top" Width="98" Click="GetExecutionModeButton_Click"/>
|
||||
<Button Content="Deploy Test" HorizontalAlignment="Left" Margin="162,216,0,0" VerticalAlignment="Top" Width="75" Click="DeployTestButton_Click" />
|
||||
<Button Content="Get Deployment Map" HorizontalAlignment="Left" Margin="162,245,0,0" VerticalAlignment="Top" Width="75" Click="GetDeploymentMapButton_Click" />
|
||||
|
||||
<Button Content="Device Capabilites" HorizontalAlignment="Left" Margin="39,195,0,0" VerticalAlignment="Top" Width="110" Click="DeviceCapabilitesButton_Click" />
|
||||
<Button Content="Flash Map" HorizontalAlignment="Left" Margin="39,275,0,0" VerticalAlignment="Top" Width="110" Click="FlashMapButton_Click" />
|
||||
<Button Content="Resolve Assemblies" HorizontalAlignment="Left" Margin="39,235,0,0" VerticalAlignment="Top" Width="110" Click="ResolveAssembliesButton_Click" />
|
||||
<Button Content="Device Capabilites" HorizontalAlignment="Left" Margin="39,187,0,0" VerticalAlignment="Top" Width="110" Click="DeviceCapabilitesButton_Click" />
|
||||
<Button Content="Flash Map" HorizontalAlignment="Left" Margin="39,245,0,0" VerticalAlignment="Top" Width="110" Click="FlashMapButton_Click" />
|
||||
<Button Content="Resolve Assemblies" HorizontalAlignment="Left" Margin="39,216,0,0" VerticalAlignment="Top" Width="110" Click="ResolveAssembliesButton_Click" />
|
||||
|
||||
<Button Content="Pause Execution" HorizontalAlignment="Left" Margin="250,235,0,0" VerticalAlignment="Top" Width="98" Click="PauseExecutionButton_Click" />
|
||||
<Button Content="Resume Execution" HorizontalAlignment="Left" Margin="250,275,0,0" VerticalAlignment="Top" Width="98" Click="ResumeExecutionButton_Click" />
|
||||
<Button Content="Pause Execution" HorizontalAlignment="Left" Margin="250,216,0,0" VerticalAlignment="Top" Width="98" Click="PauseExecutionButton_Click" />
|
||||
<Button Content="Resume Execution" HorizontalAlignment="Left" Margin="250,245,0,0" VerticalAlignment="Top" Width="98" Click="ResumeExecutionButton_Click" />
|
||||
|
||||
<Button Content="Reboot CLR" HorizontalAlignment="Left" Margin="378,77,0,0" VerticalAlignment="Top" Width="121" Click="RebootDeviceButton_Click"/>
|
||||
<Button Content="Soft Reboot" HorizontalAlignment="Left" Margin="378,102,0,0" VerticalAlignment="Top" Width="121" Click="SoftRebootDeviceButton_Click"/>
|
||||
<Button Content="Reboot to bootloader" HorizontalAlignment="Left" Margin="378,129,0,0" VerticalAlignment="Top" Width="121" Click="RebootToBootloaderButton_Click"/>
|
||||
<Button Content="Stop Processing" HorizontalAlignment="Left" Margin="378,195,0,0" VerticalAlignment="Top" Width="121" Click="StopProcessingButton_Click"/>
|
||||
<Button Content="Erase Deployment" HorizontalAlignment="Left" Margin="378,235,0,0" VerticalAlignment="Top" Width="121" Click="EraseDeploymentButton_Click" />
|
||||
<Button Content="Is Init State" HorizontalAlignment="Left" Margin="162,195,0,0" VerticalAlignment="Top" Width="75" Click="IsInitStateButton_Click" />
|
||||
<Button Content="Get Device Config" HorizontalAlignment="Left" Margin="378,275,0,0" VerticalAlignment="Top" Width="121" Click="GetDeviceConfigButton_Click" />
|
||||
<Button Content="Set Device Config" HorizontalAlignment="Left" Margin="378,313,0,0" VerticalAlignment="Top" Width="121" Click="SetDeviceConfigButton_Click" />
|
||||
<Button Content="Reboot CLR" HorizontalAlignment="Left" Margin="364,77,0,0" VerticalAlignment="Top" Width="121" Click="RebootDeviceButton_Click"/>
|
||||
<Button Content="Soft Reboot" HorizontalAlignment="Left" Margin="364,102,0,0" VerticalAlignment="Top" Width="121" Click="SoftRebootDeviceButton_Click"/>
|
||||
<Button Content="Reboot to bootloader" HorizontalAlignment="Left" Margin="364,129,0,0" VerticalAlignment="Top" Width="121" Click="RebootToBootloaderButton_Click"/>
|
||||
<Button Content="Stop Processing" HorizontalAlignment="Left" Margin="364,187,0,0" VerticalAlignment="Top" Width="121" Click="StopProcessingButton_Click"/>
|
||||
<Button Content="Erase Deployment" HorizontalAlignment="Left" Margin="364,216,0,0" VerticalAlignment="Top" Width="121" Click="EraseDeploymentButton_Click" />
|
||||
<Button Content="Is Init State" HorizontalAlignment="Left" Margin="162,187,0,0" VerticalAlignment="Top" Width="75" Click="IsInitStateButton_Click" />
|
||||
<Button Content="Get Device Config" HorizontalAlignment="Left" Margin="364,245,0,0" VerticalAlignment="Top" Width="121" Click="GetDeviceConfigButton_Click" />
|
||||
<Button Content="Set Device Config" HorizontalAlignment="Left" Margin="364,275,0,0" VerticalAlignment="Top" Width="121" Click="SetDeviceConfigButton_Click" />
|
||||
<Button Content="ReScan devices" HorizontalAlignment="Left" Margin="250,157,0,0" VerticalAlignment="Top" Width="98" Click="ReScanDevices_Click" />
|
||||
<Button Content="Read Test" HorizontalAlignment="Left" Margin="250,313,0,0" VerticalAlignment="Top" Width="98" Click="ReadTestButton_Click" />
|
||||
<Button Content="Target Info" HorizontalAlignment="Left" Margin="39,313,0,0" VerticalAlignment="Top" Width="110" Click="TargetInfoButton_Click" />
|
||||
<Button Content="Reboot to nanoBooter" HorizontalAlignment="Left" Margin="378,157,0,0" VerticalAlignment="Top" Width="121" Click="RebootToNanoBooterButton_Click"/>
|
||||
<Button Content="Deploy File" HorizontalAlignment="Left" Margin="162,313,0,0" VerticalAlignment="Top" Width="75" Click="DeployFileTestButton_Click" />
|
||||
<Button Content="Read Test" HorizontalAlignment="Left" Margin="250,275,0,0" VerticalAlignment="Top" Width="98" Click="ReadTestButton_Click" />
|
||||
<Button Content="Target Info" HorizontalAlignment="Left" Margin="39,275,0,0" VerticalAlignment="Top" Width="110" Click="TargetInfoButton_Click" />
|
||||
<Button Content="Reboot to nanoBooter" HorizontalAlignment="Left" Margin="364,157,0,0" VerticalAlignment="Top" Width="121" Click="RebootToNanoBooterButton_Click"/>
|
||||
<Button Content="Deploy File" HorizontalAlignment="Left" Margin="162,275,0,0" VerticalAlignment="Top" Width="75" Click="DeployFileTestButton_Click" />
|
||||
<Button Content="Reboot CLR" HorizontalAlignment="Left" Margin="364,77,0,0" VerticalAlignment="Top" Width="121" Click="RebootDeviceButton_Click"/>
|
||||
<Button Content="Upload File I:\" HorizontalAlignment="Left" Margin="39,306,0,0" VerticalAlignment="Top" Width="110" Click="UploadFileInternalStorage_Click"/>
|
||||
<Button Content="Rm file I:\" HorizontalAlignment="Left" Margin="162,306,0,0" VerticalAlignment="Top" Width="75" Click="RemoveFileInternalStorage_Click"/>
|
||||
|
||||
|
||||
</Grid>
|
||||
|
|
|
@ -1092,5 +1092,46 @@ rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt
|
|||
// enable button
|
||||
(sender as Button).IsEnabled = true;
|
||||
}
|
||||
|
||||
private void UploadFileInternalStorage_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string fileContent = "1. This is a test file to upload in internal storage. A long message to test more than just a line.\r\n" +
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
|
||||
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
|
||||
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
|
||||
"2. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n" +
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
|
||||
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
|
||||
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
|
||||
"3. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n" +
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
|
||||
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
|
||||
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
|
||||
"4. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n";
|
||||
//string fileContent = "simple test file";
|
||||
string fileName = "I:\\upload.txt";
|
||||
|
||||
// disable button
|
||||
(sender as Button).IsEnabled = false;
|
||||
|
||||
var reply1 = (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.AddStorageFile(fileName, Encoding.UTF8.GetBytes(fileContent));
|
||||
Debug.WriteLine($"File upload internal success: {reply1}");
|
||||
|
||||
// enable button
|
||||
(sender as Button).IsEnabled = true;
|
||||
}
|
||||
|
||||
private void RemoveFileInternalStorage_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string fileName = "I:\\upload.txt";
|
||||
// disable button
|
||||
(sender as Button).IsEnabled = false;
|
||||
|
||||
var reply1 = (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.DeleteStorageFile(fileName);
|
||||
Debug.WriteLine($"File upload internal success: {reply1}");
|
||||
|
||||
// enable button
|
||||
(sender as Button).IsEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,45 @@ namespace nanoFramework.Tools.Debugger.WireProtocol
|
|||
Unknown = 0xFFFF,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Storage operation error codes.
|
||||
/// </summary>
|
||||
public enum StorageOperationErrorCode : uint
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NEED TO KEEP THESE IN SYNC WITH native 'StorageOperationErrorCode' enum in Debugger.h //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// No error.
|
||||
/// </summary>
|
||||
NoError = 0x0001,
|
||||
|
||||
/// <summary>
|
||||
/// Write error.
|
||||
/// </summary>
|
||||
WriteError = 0x0010,
|
||||
|
||||
/// <summary>
|
||||
/// Delete error.
|
||||
/// </summary>
|
||||
DeleteError = 0x0020,
|
||||
|
||||
/// <summary>
|
||||
/// Platform dependent error.
|
||||
/// </summary>
|
||||
PlatformError = 0x0030,
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// The following element is not present in native code //
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// Target does not support storage operations.
|
||||
/// </summary>
|
||||
NotSupported = 0xFFFF,
|
||||
}
|
||||
|
||||
public class Commands
|
||||
{
|
||||
public const uint c_Monitor_Ping = 0x00000000; // The payload is empty, this command is used to let the other side know we are here...
|
||||
|
@ -58,6 +97,7 @@ namespace nanoFramework.Tools.Debugger.WireProtocol
|
|||
public const uint c_Monitor_OemInfo = 0x0000000E;
|
||||
public const uint c_Monitor_QueryConfiguration = 0x0000000F;
|
||||
public const uint c_Monitor_UpdateConfiguration = 0x00000010;
|
||||
public const uint c_Monitor_StorageOperation = 0x00000011;
|
||||
public const uint c_Monitor_TargetInfo = 0x00000020;
|
||||
|
||||
public class Monitor_Message : IConverter
|
||||
|
@ -529,6 +569,136 @@ namespace nanoFramework.Tools.Debugger.WireProtocol
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform storage operation on the target device.
|
||||
/// </summary>
|
||||
public class Monitor_StorageOperation : OverheadBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Storage operation to be performed.
|
||||
/// </summary>
|
||||
public uint Operation = (byte)StorageOperation.None;
|
||||
|
||||
/// <summary>
|
||||
/// File name for the the storage operation.
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
public string FileName = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Length of the name of the file to be used in the operation.
|
||||
/// </summary>
|
||||
public uint NameLength = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Length of the data to be used in the operation.
|
||||
/// </summary>
|
||||
public uint DataLength = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Offset in the file data of the chunck in this operation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is to be used by the target device to know where to start writing the chunk data.
|
||||
/// </remarks>
|
||||
public uint Offset = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Data buffer to be sent to the device.
|
||||
/// </summary>
|
||||
public byte[] Data;
|
||||
|
||||
public class Reply
|
||||
{
|
||||
public uint ErrorCode;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prepare for sending a storage operation to the target device.
|
||||
/// </summary>
|
||||
/// <param name="operation"><see cref="StorageOperation"/> to be performed.</param>
|
||||
/// <param name="name">Name of the file to be used in the operation.</param>
|
||||
public void SetupOperation(
|
||||
StorageOperation operation,
|
||||
string name)
|
||||
{
|
||||
Operation = (uint)operation;
|
||||
FileName = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepare for sending a storage operation to the target device.
|
||||
/// </summary>
|
||||
/// <param name="buffer">Data buffer to be sent to the device.</param>
|
||||
/// <param name="offset">Offset in the <paramref name="buffer"/> to start copying data from.</param>
|
||||
/// <param name="length">Length of the data to be copied from the <paramref name="buffer"/>.</param>
|
||||
public override bool PrepareForSend(
|
||||
byte[] buffer,
|
||||
int length,
|
||||
int offset = 0)
|
||||
{
|
||||
// setup the data payload
|
||||
DataLength = (uint)length;
|
||||
Data = new byte[length + FileName.Length];
|
||||
|
||||
// add the file name to the data property buffer
|
||||
var tempName = Encoding.UTF8.GetBytes(FileName);
|
||||
NameLength = (uint)tempName.Length;
|
||||
Array.Copy(tempName, 0, Data, 0, NameLength);
|
||||
|
||||
// copy the buffer data to the data property buffer
|
||||
Array.Copy(buffer, offset, Data, NameLength, length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void PrepareForSend()
|
||||
{
|
||||
// add the file name to the data property buffer
|
||||
Data = Encoding.UTF8.GetBytes(FileName);
|
||||
NameLength = (uint)FileName.Length;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// !!! KEEP IN SYNC WITH typedef enum Monitor_StorageOperation (in native code) !!! //
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// Storage operation to be performed.
|
||||
/// </summary>
|
||||
public enum StorageOperation : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Not specified.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Write to storage.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the file already exists, it will be overwritten.
|
||||
/// </remarks>
|
||||
Write = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Delete from storage.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the file doesn't exist, no action is taken.
|
||||
/// </remarks>
|
||||
Delete = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Append to a file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the file doesn't exist, no action is taken.
|
||||
/// </remarks>
|
||||
Append = 3
|
||||
}
|
||||
}
|
||||
|
||||
public const uint c_Debugging_Execution_BasePtr = 0x00020000; // Returns the pointer for the ExecutionEngine object.
|
||||
public const uint c_Debugging_Execution_ChangeConditions = 0x00020001; // Sets/resets the state of the debugger.
|
||||
public const uint c_Debugging_Execution_SecurityKey = 0x00020002; // Sets security key.
|
||||
|
@ -1857,7 +2027,7 @@ namespace nanoFramework.Tools.Debugger.WireProtocol
|
|||
while (len < num && buf[len] != 0) len++;
|
||||
|
||||
if (fUTF8) return Encoding.UTF8.GetString(buf, 0, len);
|
||||
else return Encoding.UTF8.GetString(buf, 0, len);
|
||||
else return Encoding.ASCII.GetString(buf, 0, len);
|
||||
}
|
||||
|
||||
public static object ResolveCommandToPayload(uint cmd, bool fReply, CLRCapabilities capabilities)
|
||||
|
@ -1878,6 +2048,7 @@ namespace nanoFramework.Tools.Debugger.WireProtocol
|
|||
case c_Monitor_FlashSectorMap: return new Monitor_FlashSectorMap.Reply();
|
||||
case c_Monitor_QueryConfiguration: return new Monitor_QueryConfiguration.Reply();
|
||||
case c_Monitor_UpdateConfiguration: return new Monitor_UpdateConfiguration.Reply();
|
||||
case c_Monitor_StorageOperation: return new Monitor_StorageOperation.Reply();
|
||||
|
||||
case c_Debugging_Execution_BasePtr: return new Debugging_Execution_BasePtr.Reply();
|
||||
case c_Debugging_Execution_ChangeConditions: return new DebuggingExecutionChangeConditions.Reply();
|
||||
|
@ -1951,6 +2122,7 @@ namespace nanoFramework.Tools.Debugger.WireProtocol
|
|||
case c_Monitor_DeploymentMap: return new Monitor_DeploymentMap();
|
||||
case c_Monitor_FlashSectorMap: return new Monitor_FlashSectorMap();
|
||||
case c_Monitor_QueryConfiguration: return new Monitor_QueryConfiguration();
|
||||
case c_Monitor_StorageOperation: return new Monitor_StorageOperation();
|
||||
|
||||
case c_Debugging_Execution_BasePtr: return new Debugging_Execution_BasePtr();
|
||||
case c_Debugging_Execution_ChangeConditions: return new DebuggingExecutionChangeConditions();
|
||||
|
|
|
@ -32,6 +32,11 @@ namespace nanoFramework.Tools.Debugger
|
|||
/// </summary>
|
||||
private const int _InterRequestSleep = 2;
|
||||
|
||||
/// <summary>
|
||||
/// This constant is to be used in progress report when performing delete operation.
|
||||
/// </summary>
|
||||
public const int StorageDeleteOperationProgressStep = 10;
|
||||
|
||||
internal IPort _portDefinition;
|
||||
internal Controller _controlller { get; set; }
|
||||
|
||||
|
@ -4423,6 +4428,224 @@ namespace nanoFramework.Tools.Debugger
|
|||
return (int)WireProtocolPacketSize - cmd.Overhead;
|
||||
}
|
||||
|
||||
#region Storage methods
|
||||
|
||||
/// <summary>
|
||||
/// Add a file to the device storage.
|
||||
/// </summary>
|
||||
/// <param name="fileName">File name.</param>
|
||||
/// <param name="fileContent">Content of the file.</param>
|
||||
/// <param name="operationExecutedLenght">Count of bytes already executed in this operation.</param>
|
||||
/// <param name="operationTotalLength">Total length of the operation, in bytes.</param>
|
||||
/// <param name="progress">An <see cref="IProgress<MessageWithProgress>"/> object to track the progress of the deploy operation.</param>
|
||||
/// <param name="log">An <see cref="IProgress<String>"/> object to log the progress of the deploy operation.</param>
|
||||
/// <returns>Operation result as a <see cref="StorageOperationErrorCode"/>.</returns>
|
||||
public StorageOperationErrorCode AddStorageFile(
|
||||
string fileName,
|
||||
byte[] fileContent,
|
||||
int operationExecutedLenght = 0,
|
||||
int operationTotalLength = 0,
|
||||
IProgress<MessageWithProgress> progress = null,
|
||||
IProgress<string> log = null)
|
||||
{
|
||||
// counters to manage the chunked update process
|
||||
int count = fileContent.Length;
|
||||
int position = 0;
|
||||
int packetLength = 0;
|
||||
|
||||
StorageOperationErrorCode operationOutcome = StorageOperationErrorCode.WriteError;
|
||||
|
||||
log?.Report($"Storing '{fileName}'...");
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
// Send by chunk, the first chunk is a write, the others will be appened
|
||||
var storageOperation = new Commands.Monitor_StorageOperation();
|
||||
|
||||
storageOperation.SetupOperation(
|
||||
position == 0 ? Commands.Monitor_StorageOperation.StorageOperation.Write : Commands.Monitor_StorageOperation.StorageOperation.Append,
|
||||
fileName);
|
||||
|
||||
// get packet length, either the maximum allowed size or whatever is still available to TX
|
||||
packetLength = Math.Min(GetPacketMaxLength(storageOperation), count);
|
||||
|
||||
storageOperation.PrepareForSend(fileContent, packetLength, position);
|
||||
|
||||
// update offset field
|
||||
storageOperation.Offset = (uint)position;
|
||||
|
||||
progress?.Report(new MessageWithProgress($"Storing '{fileName}' file in target storage...", (uint)(operationExecutedLenght + position + packetLength), (uint)operationTotalLength));
|
||||
log?.Report($"Sent {position + packetLength}/{fileContent.Length} bytes.");
|
||||
|
||||
// send the file chunk to the device
|
||||
IncomingMessage reply = PerformSyncRequest(Commands.c_Monitor_StorageOperation, 0, storageOperation);
|
||||
|
||||
if (reply != null)
|
||||
{
|
||||
if (!reply.IsPositiveAcknowledge())
|
||||
{
|
||||
// target doesn't support this command
|
||||
operationOutcome = StorageOperationErrorCode.NotSupported;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reply.Payload is Commands.Monitor_StorageOperation.Reply cmdReply)
|
||||
{
|
||||
operationOutcome = (StorageOperationErrorCode)cmdReply.ErrorCode;
|
||||
if (operationOutcome != StorageOperationErrorCode.NoError)
|
||||
{
|
||||
// done here
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// set generic write error
|
||||
operationOutcome = StorageOperationErrorCode.WriteError;
|
||||
|
||||
// done here
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// set generic write error
|
||||
operationOutcome = StorageOperationErrorCode.WriteError;
|
||||
|
||||
// done here
|
||||
break;
|
||||
}
|
||||
|
||||
// update counters
|
||||
count -= packetLength;
|
||||
position += packetLength;
|
||||
}
|
||||
|
||||
// clear progress report message
|
||||
progress?.Report(new MessageWithProgress(""));
|
||||
|
||||
if (operationOutcome != StorageOperationErrorCode.NoError)
|
||||
{
|
||||
// there was an error, compose error message...
|
||||
var errorMessage = new StringBuilder($"Error sending {packetLength} bytes to device. Store operation failed. ");
|
||||
|
||||
switch (operationOutcome)
|
||||
{
|
||||
case StorageOperationErrorCode.PlatformError:
|
||||
errorMessage.Append("Error is platform related.");
|
||||
break;
|
||||
|
||||
case StorageOperationErrorCode.NotSupported:
|
||||
errorMessage = new StringBuilder($"Target doesn't have support to access storage. "); ;
|
||||
break;
|
||||
|
||||
default:
|
||||
errorMessage.Append("Unknown error.");
|
||||
break;
|
||||
}
|
||||
|
||||
// ...and report it
|
||||
log?.Report(errorMessage.ToString());
|
||||
}
|
||||
|
||||
return operationOutcome;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete a file from the device storage.
|
||||
/// </summary>
|
||||
/// <param name="fileName">Name of file to delete.</param>
|
||||
/// <param name="operationExecutedLenght">Count of bytes already executed in this operation.</param>
|
||||
/// <param name="operationTotalLength">Total length of the operation, in bytes.</param>
|
||||
/// <param name="progress">An <see cref="IProgress<MessageWithProgress>"/> object to track the progress of the deploy operation.</param>
|
||||
/// <param name="log">An <see cref="IProgress<String>"/> object to log the progress of the deploy operation.</param>
|
||||
/// <returns>Operation result as a <see cref="StorageOperationErrorCode"/>.</returns>
|
||||
/// <remarks>
|
||||
/// When computing the operation total length, use the constant <see cref="StorageDeleteOperationProgressStep"/> as the step weight and consider that this will be executed in a single step.
|
||||
/// </remarks>
|
||||
public StorageOperationErrorCode DeleteStorageFile(
|
||||
string fileName,
|
||||
int operationExecutedLenght = 0,
|
||||
int operationTotalLength = 0,
|
||||
IProgress<MessageWithProgress> progress = null,
|
||||
IProgress<string> log = null)
|
||||
{
|
||||
StorageOperationErrorCode operationOutcome = StorageOperationErrorCode.DeleteError;
|
||||
|
||||
var storop = new Commands.Monitor_StorageOperation();
|
||||
|
||||
storop.SetupOperation(
|
||||
Commands.Monitor_StorageOperation.StorageOperation.Delete,
|
||||
fileName);
|
||||
|
||||
storop.PrepareForSend();
|
||||
|
||||
progress?.Report(new MessageWithProgress($"Deleting '{fileName}' from target storage...", (uint)(operationExecutedLenght + StorageDeleteOperationProgressStep), (uint)operationTotalLength));
|
||||
log?.Report($"Deleting '{fileName}' from target storage...");
|
||||
|
||||
IncomingMessage reply = PerformSyncRequest(
|
||||
Commands.c_Monitor_StorageOperation,
|
||||
0,
|
||||
storop);
|
||||
|
||||
if (reply != null)
|
||||
{
|
||||
if (!reply.IsPositiveAcknowledge())
|
||||
{
|
||||
// target doesn't support this command
|
||||
operationOutcome = StorageOperationErrorCode.NotSupported;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reply.Payload is Commands.Monitor_StorageOperation.Reply cmdReply)
|
||||
{
|
||||
operationOutcome = (StorageOperationErrorCode)cmdReply.ErrorCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set generic write error
|
||||
operationOutcome = StorageOperationErrorCode.DeleteError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear progress report message
|
||||
progress?.Report(new MessageWithProgress(""));
|
||||
|
||||
if (operationOutcome != StorageOperationErrorCode.NoError)
|
||||
{
|
||||
// there was an error, compose error message...
|
||||
var errorMessage = new StringBuilder($"Error deleting file from storage. ");
|
||||
|
||||
switch (operationOutcome)
|
||||
{
|
||||
case StorageOperationErrorCode.PlatformError:
|
||||
errorMessage.Append("Error platform related.");
|
||||
break;
|
||||
|
||||
case StorageOperationErrorCode.DeleteError:
|
||||
errorMessage.Append("Couldn't delete the file.");
|
||||
break;
|
||||
|
||||
case StorageOperationErrorCode.NotSupported:
|
||||
errorMessage = new StringBuilder($"Target doesn't have support to access storage. "); ;
|
||||
break;
|
||||
|
||||
default:
|
||||
errorMessage.Append("Unknown error.");
|
||||
break;
|
||||
}
|
||||
|
||||
// ...and report it
|
||||
log?.Report(errorMessage.ToString());
|
||||
}
|
||||
|
||||
return operationOutcome;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Writes a specific configuration block to the device.
|
||||
/// The configuration block is updated only with the changes for this configuration part.
|
||||
|
|
Загрузка…
Ссылка в новой задаче