public PutBytesMessage(PutBytesTransferType transferType, byte[] buffer, InstallProgressHandler progressHandler, uint index = 0) : base(Endpoint.PutBytes) { this._transferType = transferType; this._buffer = new List <byte>(buffer); this._progressHandler = progressHandler; this._index = index; this._state = PutBytesState.NotStarted; }
/// <summary> /// Installs a firmware bundle. /// </summary> /// <param name="bundle">The firmware.</param> /// <param name="recovery">Whether to install recovery firmware.</param> /// <returns> /// An async task to wait /// </returns> public async Task InstallFirmwareAsync(Bundle bundle, bool recovery) { if (bundle.BundleType != BundleType.Firmware) { throw new ArgumentException("Only firmware bundles can be installed"); } double progress = 0; double totalBytes = bundle.Manifest.Firmware.Size + bundle.Manifest.Resources.Size; InstallProgressHandler handler = null; if (this.InstallProgress != null) { // Derive overall progress from the bytes sent for the part... handler = new InstallProgressHandler((partProgress) => { progress += partProgress; int percentComplete = (int)(progress / totalBytes * 100); ServiceLocator.Logger.WriteLine("Installation " + percentComplete.ToString() + "% complete - " + progress.ToString() + " / " + totalBytes.ToString()); this.InstallProgress(percentComplete); }); } await this._protocol.WriteMessage(new SystemMessage(SystemCommand.FirmwareStart)); if (bundle.HasResources) { PutBytesMessage resourcesMsg = new PutBytesMessage(PutBytesTransferType.SystemResources, bundle.Resources, handler); try { var resourceResult = await this.SendMessageAndAwaitResponseAsync <PutBytesMessage>(resourcesMsg, 720000); if (resourceResult == null || resourceResult.Errored) { throw new CannotInstallException(string.Format("Failed to send resources {0}", bundle.Manifest.Resources.Filename)); } } catch (ProtocolException pex) { throw new CannotInstallException("Sorry, an internal error occurred: " + pex.Message); } } PutBytesMessage binMsg = new PutBytesMessage(recovery ? PutBytesTransferType.Recovery : PutBytesTransferType.Firmware, bundle.BinaryContent, handler); try { var binResult = await this.SendMessageAndAwaitResponseAsync <PutBytesMessage>(binMsg, 720000); if (binResult == null || binResult.Errored) { throw new CannotInstallException(string.Format("Failed to send binary {0}", bundle.Manifest.Firmware.Filename)); } } catch (ProtocolException pex) { throw new CannotInstallException("Sorry, an internal error occurred: " + pex.Message); } await this._protocol.WriteMessage(new SystemMessage(SystemCommand.FirmwareComplete)); await bundle.DeleteFromStorage(); if (this.InstallProgress != null) { this.InstallProgress(100); } }
/// <summary> /// Installs an application. /// </summary> /// <param name="bundle">The application.</param> /// <returns> /// An async task to wait /// </returns> public async Task InstallAppAsync(Bundle bundle) { if (bundle.BundleType != BundleType.Application) { throw new ArgumentException("Only app bundles can be installed"); } // Get list of installed apps... var installedApps = await this.GetInstalledAppsAsync(); // Find the first free slot... uint firstFreeBank = 1; foreach (var installedApp in installedApps.ApplicationsInstalled) { if (installedApp.Index == firstFreeBank) { firstFreeBank++; } if (firstFreeBank == installedApps.ApplicationBanks) { throw new CannotInstallException("There are no memory slots free"); } } double progress = 0; double totalBytes = bundle.Manifest.ApplicationManifest.Size + bundle.Manifest.Resources.Size; InstallProgressHandler handler = null; if (this.InstallProgress != null) { // Derive overall progress from the bytes sent for the part... handler = new InstallProgressHandler((partProgress) => { progress += partProgress; int percentComplete = (int)(progress / totalBytes * 100); ServiceLocator.Logger.WriteLine("Installation " + percentComplete.ToString() + "% complete - " + progress.ToString() + " / " + totalBytes.ToString()); this.InstallProgress(percentComplete); }); } ServiceLocator.Logger.WriteLine(string.Format("Attempting to add app to bank {0} of {1}", firstFreeBank, installedApps.ApplicationBanks)); PutBytesMessage binMsg = new PutBytesMessage(PutBytesTransferType.Binary, bundle.BinaryContent, handler, firstFreeBank); try { var binResult = await this.SendMessageAndAwaitResponseAsync <PutBytesMessage>(binMsg, 60000); if (binResult == null || binResult.Errored) { throw new CannotInstallException(string.Format("Failed to send binary {0}", bundle.Manifest.ApplicationManifest.Filename)); } } catch (ProtocolException pex) { throw new CannotInstallException("Sorry, an internal error occurred: " + pex.Message); } if (bundle.HasResources) { PutBytesMessage resourcesMsg = new PutBytesMessage(PutBytesTransferType.Resources, bundle.Resources, handler, firstFreeBank); try { var resourceResult = await this.SendMessageAndAwaitResponseAsync <PutBytesMessage>(resourcesMsg, 240000); if (resourceResult == null || resourceResult.Errored) { throw new CannotInstallException(string.Format("Failed to send resources {0}", bundle.Manifest.Resources.Filename)); } } catch (ProtocolException pex) { throw new CannotInstallException("Sorry, an internal error occurred: " + pex.Message); } } var appMsg = new AppMessage(Endpoint.AppManager) { Command = AppCommand.FinaliseInstall, AppIndex = firstFreeBank }; await this.SendMessageAndAwaitResponseAsync <AppManagerMessage>(appMsg); await bundle.DeleteFromStorage(); if (this.InstallProgress != null) { this.InstallProgress(100); } // Now launch the new app await this.LaunchAppAsync(bundle.Application.Uuid); }
public PutBytesMessage(PutBytesTransferType transferType, byte[] buffer, InstallProgressHandler progressHandler, uint index = 0) : base(Endpoint.PutBytes) { this._transferType = transferType; this._buffer = new List<byte>(buffer); this._progressHandler = progressHandler; this._index = index; this._state = PutBytesState.NotStarted; }