fix OTA
This commit is contained in:
parent
877cf4ba7a
commit
835ce1375b
|
@ -11,4 +11,29 @@ public class ProcessTopics
|
||||||
/// 证书更新事件反馈
|
/// 证书更新事件反馈
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string LicenseUpdateEventFeedback = "LicenseUpdateEventFeedback";
|
public const string LicenseUpdateEventFeedback = "LicenseUpdateEventFeedback";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OTA请求事件
|
||||||
|
/// </summary>
|
||||||
|
public const string OTAQueryEvent = "OTAUpdataQueryEvent";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OTA请求反馈事件
|
||||||
|
/// </summary>
|
||||||
|
public const string OTAQueryEventFeedback = "OTAQueryEventFeedback";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OTA更新事件
|
||||||
|
/// </summary>
|
||||||
|
public const string OTAUpdateEvent = "OTAUpdateEvent";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载更新包事件
|
||||||
|
/// </summary>
|
||||||
|
public const string DownloadUpdatePackageEvent = "DownloadUpdatePackageEvent";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载更新包事件反馈
|
||||||
|
/// </summary>
|
||||||
|
public const string DownloadUpdatePackageEventFeedback = "DownloadUpdatePackageEventFeedback";
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ using System.Reflection;
|
||||||
[assembly: System.Reflection.AssemblyCompanyAttribute("MasstransferCommon")]
|
[assembly: System.Reflection.AssemblyCompanyAttribute("MasstransferCommon")]
|
||||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+64cf3396835594f835ea904d6fccf95de4bc3e01")]
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+877cf4ba7ae74758a89a91f7ed677f7e83789ca8")]
|
||||||
[assembly: System.Reflection.AssemblyProductAttribute("MasstransferCommon")]
|
[assembly: System.Reflection.AssemblyProductAttribute("MasstransferCommon")]
|
||||||
[assembly: System.Reflection.AssemblyTitleAttribute("MasstransferCommon")]
|
[assembly: System.Reflection.AssemblyTitleAttribute("MasstransferCommon")]
|
||||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
namespace MasstransferExporter.OTA.Model;
|
||||||
|
|
||||||
|
public class OTAUpdateFileManager
|
||||||
|
{
|
||||||
|
public string UpdatePackagePath;
|
||||||
|
|
||||||
|
public string AppDir;
|
||||||
|
|
||||||
|
public string CriticalBackupDir;
|
||||||
|
|
||||||
|
public string[] CriticalFileExtension;
|
||||||
|
|
||||||
|
public string CriticalSourceLogPath;
|
||||||
|
|
||||||
|
public string PreviousBackupPath;
|
||||||
|
}
|
|
@ -1,81 +1,92 @@
|
||||||
using MasstransferCommon.Model.Constant;
|
using System.Diagnostics;
|
||||||
|
using MasstransferCommon.Model.Constant;
|
||||||
using MasstransferCommon.Utils;
|
using MasstransferCommon.Utils;
|
||||||
using MasstransferCommunicate.Mqtt.Client;
|
using MasstransferCommunicate.Mqtt.Client;
|
||||||
|
using MasstransferCommunicate.Process.Service;
|
||||||
using MasstransferExporter.OTA.Client;
|
using MasstransferExporter.OTA.Client;
|
||||||
using MasstransferExporter.OTA.Model;
|
using MasstransferExporter.OTA.Model;
|
||||||
|
using MasstransferInfrastructure.Database.Sqlite;
|
||||||
|
|
||||||
namespace MasstransferExporter.OTA.Service;
|
namespace MasstransferExporter.OTA.Service;
|
||||||
|
|
||||||
public class OTAService
|
public class OTAService
|
||||||
{
|
{
|
||||||
private readonly string _appDir;
|
private static readonly SqliteHelper Db = SqliteHelper.GetInstance();
|
||||||
private readonly string _criticalBackupDir;
|
private static OTAUpdateFileManager _otaUpdateFileManager;
|
||||||
private readonly string _criticalSourceLogPath;
|
|
||||||
private readonly string[] _criticalFileExtension;
|
|
||||||
private readonly string _previousBackupPath;
|
|
||||||
private readonly string _updatePackagePath;
|
|
||||||
|
|
||||||
|
|
||||||
public OTAService(string appDir, string criticalBackupDir, string criticalSourceLogPath, string[] criticalFileExtension, string previousBackupPath, string updatePackagePath)
|
|
||||||
{
|
|
||||||
_appDir = appDir;
|
|
||||||
_criticalBackupDir = criticalBackupDir;
|
|
||||||
_criticalSourceLogPath = criticalSourceLogPath;
|
|
||||||
_criticalFileExtension = criticalFileExtension;
|
|
||||||
_previousBackupPath = previousBackupPath;
|
|
||||||
_updatePackagePath = updatePackagePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订阅OTA更新
|
/// 启动OTA服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task ListenOTAUpdateEvent()
|
public static async Task StartOTAService()
|
||||||
{
|
{
|
||||||
await MessageQueueHelper.Subscribe(Topics.IssuedOTAPackage, HandleUpdateOTAEvent);
|
|
||||||
|
_otaUpdateFileManager = GetOTAUpdateFileManager();
|
||||||
|
|
||||||
|
//订阅云端发包
|
||||||
|
await MessageQueueHelper.Subscribe(Topics.IssuedOTAPackage, HandleIssuedOTAPackage);
|
||||||
|
|
||||||
|
//订阅Masstransfer进程 请求OTA事件
|
||||||
|
ProcessCommunicator.Subscribe(ProcessTopics.OTAQueryEvent, HandleOTAQueryEvent);
|
||||||
|
|
||||||
|
//订阅Masstransfer进程 启动更新事件
|
||||||
|
ProcessCommunicator.Subscribe(ProcessTopics.OTAUpdateEvent, HandleOTAUpdateEvent);
|
||||||
|
|
||||||
|
//订阅订阅Masstransfer进程 下载安装包事件
|
||||||
|
ProcessCommunicator.Subscribe(ProcessTopics.DownloadUpdatePackageEvent, HandleDownloadUpdatePackageEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询OTA更新
|
/// 从数据库读取文件操作地址、关键文件后缀
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <returns></returns>
|
||||||
public static async Task QueryOTAUpdate()
|
private static OTAUpdateFileManager? GetOTAUpdateFileManager()
|
||||||
{
|
{
|
||||||
await MessageQueueHelper.Publish(Topics.QueryOTA, null);
|
return Db.Query<OTAUpdateFileManager>("").FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task HandleIssuedOTAPackage(string topic, OTAUpdateData otaUpdateData)
|
||||||
|
{
|
||||||
|
await ProcessCommunicator.Send(ProcessTopics.OTAQueryEventFeedback, otaUpdateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// OTA更新反馈
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="resutl"></param>
|
|
||||||
public async Task OTALicenseUpdateEventFeedback(OTAResultData resutl)
|
|
||||||
{
|
|
||||||
await MessageQueueHelper.Publish(Topics.OTAUpgradeFeedback, resutl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理OTA更新
|
/// Masstransfer 请求OTA事件响应,向云端发送请求信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="topic"></param>
|
/// <param name="topic"></param>
|
||||||
/// <param name="otaUpdateData"></param>
|
public static async Task HandleOTAQueryEvent(string topic)
|
||||||
private async Task HandleUpdateOTAEvent(string topic, OTAUpdateData otaUpdateData)
|
|
||||||
{
|
{
|
||||||
var type = otaUpdateData.Type;
|
await MessageQueueHelper.Publish(Topics.QueryOTA, new object());
|
||||||
var url = otaUpdateData.Url;
|
}
|
||||||
var version = otaUpdateData.Version;
|
|
||||||
var module = otaUpdateData.Module;
|
|
||||||
var size = otaUpdateData.Size;
|
|
||||||
var checksum = otaUpdateData.Checksum;
|
|
||||||
var name = otaUpdateData.Name;
|
|
||||||
var description = otaUpdateData.Description;
|
|
||||||
|
|
||||||
|
public static async Task HandleDownloadUpdatePackageEvent(string topic, (string Url, string Checksum) data)
|
||||||
|
{
|
||||||
|
var updatePackagePath = _otaUpdateFileManager.UpdatePackagePath;
|
||||||
|
string url = data.Url;
|
||||||
|
string checksum = data.Checksum;
|
||||||
|
bool result = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ApiClient.DownloadFileAsync(url, updatePackagePath);
|
||||||
|
if(!OTAClient.CheckMD5(checksum, updatePackagePath)) throw new Exception("MD5 check failed.");
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ProcessCommunicator.Send(ProcessTopics.DownloadUpdatePackageEventFeedback, result);
|
||||||
|
|
||||||
|
}
|
||||||
|
//Masstransfer 通知-启动更新
|
||||||
|
public static async Task HandleOTAUpdateEvent(string topic, OTAUpdateData otaUpdateData)
|
||||||
|
{
|
||||||
|
var version = "";
|
||||||
|
|
||||||
OTAResultData otaResultData = new OTAResultData();
|
OTAResultData otaResultData = new OTAResultData();
|
||||||
//下载更新包
|
|
||||||
await ApiClient.DownloadFileAsync(url, _updatePackagePath);
|
|
||||||
|
|
||||||
//校验压缩包
|
|
||||||
if(!OTAClient.CheckMD5(checksum, _updatePackagePath)) return;
|
|
||||||
|
|
||||||
//kill masstransfer
|
|
||||||
|
|
||||||
//启动更新
|
//启动更新
|
||||||
otaResultData.Result = Install() ? (byte)1 : (byte)0;
|
otaResultData.Result = Install() ? (byte)1 : (byte)0;
|
||||||
|
@ -86,48 +97,54 @@ public class OTAService
|
||||||
otaResultData.OtaSoftwareVersion = version;
|
otaResultData.OtaSoftwareVersion = version;
|
||||||
otaResultData.CurrentSoftwareVersion = version; //**需要修改为当前版本
|
otaResultData.CurrentSoftwareVersion = version; //**需要修改为当前版本
|
||||||
|
|
||||||
await OTALicenseUpdateEventFeedback(otaResultData);
|
await MessageQueueHelper.Publish(Topics.OTAUpgradeFeedback, otaResultData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 安装压缩包
|
/// 安装压缩包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Install()
|
public static bool Install()
|
||||||
{
|
{
|
||||||
|
var appDir = _otaUpdateFileManager.AppDir;
|
||||||
|
var criticalBackupDir = _otaUpdateFileManager.CriticalBackupDir;
|
||||||
|
var criticalFileExtension = _otaUpdateFileManager.CriticalFileExtension;
|
||||||
|
var criticalSourceLogPath = _otaUpdateFileManager.CriticalSourceLogPath;
|
||||||
|
var previousBackupPath = _otaUpdateFileManager.PreviousBackupPath;
|
||||||
|
var updatePackagePath = _otaUpdateFileManager.UpdatePackagePath;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//初始化
|
//初始化
|
||||||
initDir();
|
initDir(criticalBackupDir);
|
||||||
|
|
||||||
//备份重要文件
|
//备份重要文件
|
||||||
OTAClient.BackupEssentialFiles(_appDir, _criticalBackupDir, _criticalFileExtension, _criticalSourceLogPath);
|
OTAClient.BackupEssentialFiles(appDir, criticalBackupDir, criticalFileExtension, criticalSourceLogPath);
|
||||||
|
|
||||||
//备份旧版本文件
|
//备份旧版本文件
|
||||||
OTAClient.CompressDirectory(_appDir, _previousBackupPath);
|
OTAClient.CompressDirectory(appDir, previousBackupPath);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//删除旧版本原文件
|
//删除旧版本原文件
|
||||||
OTAClient.DeleteDirectory(_appDir);
|
OTAClient.DeleteDirectory(appDir);
|
||||||
|
|
||||||
//解压更新包
|
//解压更新包
|
||||||
OTAClient.ExtractDirectory(_updatePackagePath, _appDir);
|
OTAClient.ExtractDirectory(updatePackagePath, appDir);
|
||||||
|
|
||||||
//恢复重要文件
|
//恢复重要文件
|
||||||
OTAClient.RecoverCriticalFiles(_criticalSourceLogPath);
|
OTAClient.RecoverCriticalFiles(criticalSourceLogPath);
|
||||||
|
|
||||||
//删除旧版本备份文件
|
//删除旧版本备份文件
|
||||||
OTAClient.DeleteFile(_previousBackupPath);
|
OTAClient.DeleteFile(previousBackupPath);
|
||||||
|
|
||||||
//删除更新包
|
//删除更新包
|
||||||
OTAClient.DeleteFile(_updatePackagePath);
|
OTAClient.DeleteFile(updatePackagePath);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
RollBack();
|
RollBack(appDir, criticalBackupDir, updatePackagePath, previousBackupPath);
|
||||||
Console.WriteLine($"更新异常,已回滚: {ex.Message}");
|
Console.WriteLine($"更新异常,已回滚: {ex.Message}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -137,9 +154,9 @@ public class OTAService
|
||||||
Console.WriteLine($"更新异常e: {ex.Message}");
|
Console.WriteLine($"更新异常e: {ex.Message}");
|
||||||
|
|
||||||
//如果重要文件备份已经产生,则删除
|
//如果重要文件备份已经产生,则删除
|
||||||
if(Directory.Exists(_criticalBackupDir))
|
if(Directory.Exists(criticalBackupDir))
|
||||||
{
|
{
|
||||||
OTAClient.DeleteDirectory(_criticalBackupDir);
|
OTAClient.DeleteDirectory(criticalBackupDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -149,24 +166,24 @@ public class OTAService
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化重要文件备份目录
|
/// 初始化重要文件备份目录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void initDir()
|
private static void initDir(string criticalBackupDir)
|
||||||
{
|
{
|
||||||
if (Directory.Exists(_criticalBackupDir))
|
if (Directory.Exists(criticalBackupDir))
|
||||||
{
|
{
|
||||||
Directory.Delete(_criticalBackupDir, true);
|
Directory.Delete(criticalBackupDir, true);
|
||||||
}
|
}
|
||||||
Directory.CreateDirectory(_criticalBackupDir);
|
Directory.CreateDirectory(criticalBackupDir);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 回滚
|
/// 回滚
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void RollBack()
|
private static void RollBack(string appDir, string criticalBackupDir, string updatePackagePath, string previousBackupPath)
|
||||||
{
|
{
|
||||||
//删除安装过程中创建的文件、目录
|
//删除安装过程中创建的文件、目录
|
||||||
var directoryList = new string[] { _appDir, _criticalBackupDir};
|
var directoryList = new string[] { appDir, criticalBackupDir};
|
||||||
var filePath = new String[] { _updatePackagePath };
|
var filePath = new String[] { updatePackagePath };
|
||||||
|
|
||||||
foreach (var directory in directoryList)
|
foreach (var directory in directoryList)
|
||||||
{
|
{
|
||||||
|
@ -185,10 +202,10 @@ public class OTAService
|
||||||
}
|
}
|
||||||
|
|
||||||
//恢复旧版本文件
|
//恢复旧版本文件
|
||||||
OTAClient.ExtractDirectory(_previousBackupPath, _appDir);
|
OTAClient.ExtractDirectory(previousBackupPath, appDir);
|
||||||
|
|
||||||
//删除旧版本备份
|
//删除旧版本备份
|
||||||
OTAClient.DeleteFile(_previousBackupPath);
|
OTAClient.DeleteFile(previousBackupPath);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using MasstransferCommunicate.Mqtt.Client;
|
using MasstransferCommunicate.Mqtt.Client;
|
||||||
using MasstransferExporter.DataExporter;
|
using MasstransferExporter.DataExporter;
|
||||||
|
using MasstransferExporter.OTA.Service;
|
||||||
using MasstransferInfrastructure.Mqtt.Model;
|
using MasstransferInfrastructure.Mqtt.Model;
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
|
@ -13,11 +14,10 @@ class Program
|
||||||
EnableTls = false
|
EnableTls = false
|
||||||
};
|
};
|
||||||
|
|
||||||
// await MessageQueueHelper.InitConnect(options);
|
await MessageQueueHelper.InitConnect(options);
|
||||||
|
|
||||||
await FormulaService.FormulaDataExporter();
|
|
||||||
|
|
||||||
|
|
||||||
|
CoordinateService.CoordinateExporter();
|
||||||
|
await OTAService.StartOTAService();
|
||||||
Console.WriteLine("按任意键退出");
|
Console.WriteLine("按任意键退出");
|
||||||
Console.ReadKey();
|
Console.ReadKey();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ using System.Reflection;
|
||||||
[assembly: System.Reflection.AssemblyCompanyAttribute("MasstransferExporter")]
|
[assembly: System.Reflection.AssemblyCompanyAttribute("MasstransferExporter")]
|
||||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+64cf3396835594f835ea904d6fccf95de4bc3e01")]
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+877cf4ba7ae74758a89a91f7ed677f7e83789ca8")]
|
||||||
[assembly: System.Reflection.AssemblyProductAttribute("MasstransferExporter")]
|
[assembly: System.Reflection.AssemblyProductAttribute("MasstransferExporter")]
|
||||||
[assembly: System.Reflection.AssemblyTitleAttribute("MasstransferExporter")]
|
[assembly: System.Reflection.AssemblyTitleAttribute("MasstransferExporter")]
|
||||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
Loading…
Reference in New Issue