using System; using System.Collections.Generic; using System.Text; using ZigBee.Device; namespace Shared.Phone { /// /// 固件升级的逻辑类 /// public class HdlFirmwareUpdateLogic { #region ■ 变量声明___________________________ /// /// 固件升级的逻辑类 /// private static HdlFirmwareUpdateLogic m_Current = null; /// /// 固件升级的逻辑类 /// public static HdlFirmwareUpdateLogic Current { get { if (m_Current == null) { m_Current = new HdlFirmwareUpdateLogic(); } return m_Current; } } #endregion #region ■ 执行固件更新_______________________ /// /// 执行下一个固件的更新 /// public void DoUpdateNextFirmware() { //下一个要执行更新的网关 DeviceUpdateCommon gwControl = null; //下一个要执行更新的设备 DeviceUpdateCommon deviceControl = null; foreach (var contr in HdlFirmwareUpdateResourse.dicUpdateList.Values) { //如果别的还在升级中,则不再处理 if (contr.IsFinishUpdate == false) { return; } //如果这个在等待列表的话 if (contr.UpdateStatu == UpdateStatuMode.Wait && gwControl == null) { if (contr.ClassDiv == 1 && gwControl == null) { //下一个升级的就是它了 gwControl = contr; } else if (contr.ClassDiv == 2 && deviceControl == null) { //下一个升级的就是它了 deviceControl = contr; } } } HdlThreadLogic.Current.RunThread(() => { if (gwControl != null) { //开始执行更新操作 gwControl.DoStartUpdate(); return; } if (deviceControl != null) { //开始执行更新操作 deviceControl.DoStartUpdate(); } }); } #endregion #region ■ 添加升级固件信息___________________ /// /// 添加升级固件信息 1:正常 -1:没网,获取不到东西 /// /// 固件阶级分类 /// 硬件版本 /// 镜像类型 /// public int AddFirmwareVersionInfo(FirmwareLevelType levelType, string HardwareVersion, string imgType) { //检测本地是否已经有这个缓存了 if (IsEsixtFirmwareVersionInfo(levelType, HardwareVersion, imgType) == true) { return 1; } var Pra = new GetFirmwareVersionPra(); Pra.PageSetting.Page = 1; Pra.PageSetting.PageSize = 9999; if (levelType == FirmwareLevelType.Linux) { //获取网关Linux模块升级信息 Pra.FirmwareManaFirstType = 1; Pra.FirmwareManaSecondType = 0; Pra.HardwareVersion = HardwareVersion; Pra.DeviceType = imgType; var result = GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.Linux, Pra); return result; } else if (levelType == FirmwareLevelType.A协调器) { //协调器模块 Pra.FirmwareManaFirstType = 1; Pra.FirmwareManaSecondType = 1; Pra.HardwareVersion = HardwareVersion; Pra.DeviceType = imgType; var result = GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.A协调器, Pra); return result; } else if (levelType == FirmwareLevelType.A虚拟驱动) { //虚拟设备模块 Pra.FirmwareManaFirstType = 1; Pra.FirmwareManaSecondType = 2; Pra.HardwareVersion = HardwareVersion; Pra.DeviceType = imgType; var result = GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.A虚拟驱动, Pra); return result; } else { //一般设备 Pra.FirmwareManaFirstType = 2; Pra.FirmwareManaSecondType = null; Pra.HardwareVersion = HardwareVersion; Pra.DeviceType = imgType; var result = GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.A设备, Pra); return result; } } /// /// 获取云端的固件,然后存入缓存中 1:正常 -1:没网,获取不到东西 /// /// /// /// private int GetFirmwareVersionAndSetToMemmory(FirmwareLevelType levelType, GetFirmwareVersionPra pra) { var result = this.RequestZigbeeHttps("FirmwareMana/DetectionPlatformUploadFirmware", pra, 4); if (result == null || result.Length == 0) { return -1; } var jobject = Newtonsoft.Json.Linq.JObject.Parse(Encoding.UTF8.GetString(result)); if (jobject.Property("StateCode") == null || jobject["StateCode"].ToString().ToUpper() != "SUCCESS") { return -1; } string resultValue = jobject["ResponseData"].ToString(); var verResult = Newtonsoft.Json.JsonConvert.DeserializeObject(resultValue); if (verResult.PageData.Count == 0) { return 1; } //硬件版本 if (HdlFirmwareUpdateResourse.dicFirmwareInfo.ContainsKey(levelType) == false) { HdlFirmwareUpdateResourse.dicFirmwareInfo[levelType] = new Dictionary(); } var dicHardData = HdlFirmwareUpdateResourse.dicFirmwareInfo[levelType]; foreach (var data in verResult.PageData) { //固件版本显示: //10101 3个byte 显示为:ver.1.01.01 if (data.FirmwareVersion.Length != 6 && data.FirmwareVersion.Length != 5) { //非正规的固件版本,不再考虑范围内 continue; } //硬件分类 FirmwareHardInfo hardInfo = null; string hardCode = data.HardwareVersion; if (dicHardData.ContainsKey(hardCode) == false) { //添加 hardInfo = new FirmwareHardInfo(); dicHardData[hardCode] = hardInfo; } hardInfo = dicHardData[hardCode]; //镜像分类 string imgType = data.DeviceType; Dictionary dicimgType = hardInfo.dicImgType; FirmwareImgTypeInfo imgTypeInfo = null; if (dicimgType.ContainsKey(imgType) == false) { //添加 imgTypeInfo = new FirmwareImgTypeInfo(); dicimgType[imgType] = imgTypeInfo; } imgTypeInfo = dicimgType[imgType]; try { //固件版本 var info = new FirmwareVersionInfo(); info.DistributedMark = data.DistributedMark; info.FirmwareVersion = Convert.ToInt32(data.FirmwareVersion); info.ShowName = data.Name; info.Name = data.Name; info.HardwareVersion = hardCode; info.ImagType = imgType; info.CreatedOnUtc = data.CreatedOnUtc; imgTypeInfo.listVeison.Add(info); //固件的信息处理 DoAdjustFirmwareInformation(info, data.Remarks); } catch { continue; } } return 1; } #endregion #region ■ 获取最新固件版本信息_______________ /// /// 获取固件的最新版本信息(如果返回Null,则表示没有最新版本,或者当前已经是最新版本) /// /// 固件阶级分类 /// 硬件版本 /// 镜像类型 /// 现在的版本 /// public FirmwareVersionInfo GetFirmwareMostVersionInfo(FirmwareLevelType levelType, string HardwareVersion, string imgType, int nowVersion) { //镜像类型 var listdata = GetFirmwareVersionListInfo(levelType, HardwareVersion, imgType); FirmwareVersionInfo newFirInfo = null; foreach (var verInfo in listdata) { if (verInfo.Name.EndsWith(".bin") == true) { //它不是升级固件, .bin是特殊的 continue; } int testVersion = Convert.ToInt32(verInfo.FirmwareVersion.ToString().PadLeft(6, '0').Substring(2, 2)); if (testVersion % 2 != 0) { //中间那个byte为奇数时,代表是测试版本,在显示最新版本时,不需要显示,但是在历史版本那里可以显示 //中间那个byte为偶数时,代表是正式版本 continue; } if (verInfo.FirmwareVersion > nowVersion) { nowVersion = verInfo.FirmwareVersion; newFirInfo = verInfo; } } return newFirInfo; } /// /// 获取固件列表的固件版本信息 /// /// 固件阶级分类 /// 硬件版本 /// 镜像类型 /// public List GetFirmwareVersionListInfo(FirmwareLevelType levelType, string HardwareVersion, string imgType) { if (HdlFirmwareUpdateResourse.dicFirmwareInfo == null || HdlFirmwareUpdateResourse.dicFirmwareInfo.ContainsKey(levelType) == false) { return new List(); } //硬件版本号级别 var dicHard = HdlFirmwareUpdateResourse.dicFirmwareInfo[levelType]; //硬件版本 if (dicHard.ContainsKey(HardwareVersion) == false) { return new List(); } //镜像类型 var dicImgInfo = GetImageVersionListInfo(levelType, HardwareVersion); if (dicImgInfo.ContainsKey(imgType) == false) { return new List(); } var listData = new List(); var imgInfo = dicImgInfo[imgType]; foreach (var verInfo in imgInfo.listVeison) { listData.Add(verInfo); } return listData; } /// /// 获取固件列表的镜像版本信息 /// /// 固件阶级分类 /// 硬件版本 /// public Dictionary GetImageVersionListInfo(FirmwareLevelType levelType, string HardwareVersion) { if (HdlFirmwareUpdateResourse.dicFirmwareInfo == null || HdlFirmwareUpdateResourse.dicFirmwareInfo.ContainsKey(levelType) == false) { return new Dictionary(); } //硬件版本号级别 var dicHard = HdlFirmwareUpdateResourse.dicFirmwareInfo[levelType]; //硬件版本 if (dicHard.ContainsKey(HardwareVersion) == false) { return new Dictionary(); } //镜像类型 return dicHard[HardwareVersion].dicImgType; } #endregion #region ■ 获取指定固件版本信息_______________ /// /// 获取指定固件的版本信息(如果返回Null,则表示没有这个固件) /// /// 固件阶级分类 /// 硬件版本 /// 镜像类型 /// 现在的版本 /// public FirmwareVersionInfo GetFirmwareVersionInfo(FirmwareLevelType levelType, string HardwareVersion, string imgType, int nowVersion) { //镜像类型 var listdata = GetFirmwareVersionListInfo(levelType, HardwareVersion, imgType); foreach (var verInfo in listdata) { if (verInfo.Name.EndsWith(".bin") == true) { //它不是升级固件, .bin是特殊的 continue; } if (verInfo.FirmwareVersion == nowVersion) { return verInfo; } } return null; ; } #endregion #region ■ 固件存在检测_______________________ /// /// 固件缓存存在检测 /// /// 固件阶级分类 /// 硬件版本 /// 镜像类型 /// private bool IsEsixtFirmwareVersionInfo(FirmwareLevelType levelType, string HardwareVersion, string imgType) { //第一大类 if (HdlFirmwareUpdateResourse.dicFirmwareInfo == null || HdlFirmwareUpdateResourse.dicFirmwareInfo.ContainsKey(levelType) == false) { return false; } //硬件 if (HdlFirmwareUpdateResourse.dicFirmwareInfo[levelType].ContainsKey(HardwareVersion) == false) { return false; } //镜像 if (HdlFirmwareUpdateResourse.dicFirmwareInfo[levelType][HardwareVersion].dicImgType.ContainsKey(imgType) == false) { return false; } return true; } /// /// 检测该Ota设备的升级固件是否存在 /// /// 设备对象 /// public bool IsEsixtDeviceFirmwareFile(OTADevice device) { var fileFullName = GetDeviceFirmwareFile(device); return System.IO.File.Exists(fileFullName); } /// /// 获取ota指定的升级固件名字(全路径) /// /// 设备对象 /// public string GetDeviceFirmwareFile(OTADevice device) { //硬件版本_镜像ID_固件版本 string fileName = device.HwVersion + "_" + device.ImgTypeId + "_" + device.ImgVersion; return System.IO.Path.Combine(HdlFileNameResourse.FirmwareUpdateDirectory, "Device_" + fileName + ".ota"); } /// /// 获取网关Linux的升级固件名字(全路径) /// /// 网关对象 /// public string GetGatewayLinuxFirmwareFile(ZbGateway zbGateway) { string fileName = zbGateway.LinuxHardVersion + "_" + zbGateway.LinuxImageType + "_" + zbGateway.LinuxFirmwareVersion; return System.IO.Path.Combine(HdlFileNameResourse.FirmwareUpdateDirectory, "Linux_" + fileName + ".ota"); } /// /// 获取网关协调器的升级固件名字(全路径) /// /// 网关对象 /// public string GetGatewayCoordinatorFirmwareFile(ZbGateway zbGateway) { string fileName = zbGateway.CoordinatorHardVersion + "_" + zbGateway.CoordinatorImageId + "_" + zbGateway.CoordinatorFirmwareVersion; return System.IO.Path.Combine(HdlFileNameResourse.FirmwareUpdateDirectory, "Coordinator_" + fileName + ".ota"); } /// /// 获取网关虚拟驱动的升级固件名字(全路径) /// /// 虚拟驱动数据 /// public string GetGatewayDriveCodeFirmwareFile(ZbGatewayData.DriveCodeObj codeObj) { string fileName = codeObj.DriveHwVersion + "_" + codeObj.DriveImageType + "_" + codeObj.DriveFwVersion; return System.IO.Path.Combine(HdlFileNameResourse.FirmwareUpdateDirectory, "DriveCode_" + fileName + ".ota"); } #endregion #region ■ 下载模板固件_______________________ /// /// 下载模板中网关和设备的固件 /// /// /// public int DownLoadTemplateDeviceFirmware(string fullFileName, string i_Msg) { //从模板当中获取设备和网关对象 var listTempDevice = new List(); var listTempGateway = new List(); HdlTemplateCommonLogic.Current.GetDeviceObjectFromTemplate(fullFileName, ref listTempDevice, ref listTempGateway); //获取需要下载的固件数据 var listVersion = GetNeedToDownLoadVersionData(listTempDevice, listTempGateway); //获取需要下载的空调模块 var listAcOta = new List(); var listAcUpdate = GetNeedDownLoadAirConditionerModule(listTempDevice, ref listAcOta); if (listVersion.Count == 0 && listAcUpdate.Count == 0) { return 0; } //打开进度条 ProgressFormBar.Current.Start(); ProgressFormBar.Current.SetMsg(i_Msg); ProgressFormBar.Current.SetValue(0, 1); System.Threading.Thread.Sleep(1000); var dicFirmwareName = new Dictionary(); var fileData = HdlFileLogic.Current.ReadFileTextContent(HdlFileNameResourse.FirmwareUpdateList); if (fileData != null) { //本地存放的固件原来的名字(因为设备升级时,它需要识别文件名字里面包含的特殊字符) //key:全路径,硬件版本_镜像ID_固件版本 value:固件原来的名字 dicFirmwareName = Newtonsoft.Json.JsonConvert.DeserializeObject>(fileData); } //固件存储路径 string firmwareDir = HdlFileNameResourse.FirmwareUpdateDirectory; int nowCount = 0; int macCount = listVersion.Count + listAcUpdate.Count; foreach (var versionData in listVersion) { nowCount++; //获取升级固件信息 var result = AddFirmwareVersionInfo(versionData.levelType, versionData.HwVersion, versionData.ImageType); if (result == -1) { ProgressFormBar.Current.Close(); //保存列表名字 HdlFileLogic.Current.SaveFileContent(HdlFileNameResourse.FirmwareUpdateList, dicFirmwareName); return -1; } //获取当前这个版本的固件信息 var versionFirmware = GetFirmwareVersionInfo(versionData.levelType, versionData.HwVersion, versionData.ImageType, versionData.FirmwareVersion); if (versionFirmware == null) { //云端没有这个版本 进度值 ProgressFormBar.Current.SetValue(nowCount, macCount); continue; } //去下载这个固件 var byteData = this.DowLoadFirmware(versionData.levelType, versionFirmware.DistributedMark); if (byteData == null) { ProgressFormBar.Current.Close(); //保存列表名字 HdlFileLogic.Current.SaveFileContent(HdlFileNameResourse.FirmwareUpdateList, dicFirmwareName); return -1; } //保存固件 var saveFile = System.IO.Path.Combine(firmwareDir, versionData.FileDiv + versionData.HwVersion + "_" + versionData.ImageType + "_" + versionData.FirmwareVersion + ".ota"); HdlFileLogic.Current.SaveByteToFile(saveFile, byteData); dicFirmwareName[saveFile] = versionFirmware.Name; //进度值 ProgressFormBar.Current.SetValue(nowCount, macCount); } for (int i = 0; i < listAcUpdate.Count; i++) { //下载空调模块 var deviceFirmwareByte = this.DowLoadFirmware(FirmwareLevelType.A设备, listAcUpdate[i].DistributedMark); if (deviceFirmwareByte == null) { ProgressFormBar.Current.Close(); //保存列表名字 HdlFileLogic.Current.SaveFileContent(HdlFileNameResourse.FirmwareUpdateList, dicFirmwareName); return -1; } //保存固件 string fileName = "AC_" + listAcOta[i].HwVersion + "_" + listAcOta[i].ImgTypeId + "_" + listAcUpdate[i].Name; var saveFile = System.IO.Path.Combine(firmwareDir, fileName); HdlFileLogic.Current.SaveByteToFile(saveFile, deviceFirmwareByte); //进度值 ProgressFormBar.Current.SetValue(nowCount, macCount); } //保存列表名字 HdlFileLogic.Current.SaveFileContent(HdlFileNameResourse.FirmwareUpdateList, dicFirmwareName); ProgressFormBar.Current.Close(); return 1; } /// /// 获取需要下载的固件数据 /// /// 设备列表 /// 网关列表 /// private List GetNeedToDownLoadVersionData(List listDevice, List listGateway) { //存储路径 string firmwareDir = HdlFileNameResourse.FirmwareUpdateDirectory; HdlFileLogic.Current.CreateDirectory(firmwareDir); var listVersion = new List(); var listCheck = new HashSet(); foreach (var device in listDevice) { //设备的升级固件名字 var fileFullName = GetDeviceFirmwareFile(device); if (System.IO.File.Exists(fileFullName) == false && listCheck.Contains(fileFullName) == false) { listCheck.Add(fileFullName); //设备 listVersion.Add(new TemplateDeviceVersion { FileDiv = "Device_", levelType = FirmwareLevelType.A设备, HwVersion = device.HwVersion.ToString(), ImageType = device.ImgTypeId.ToString(), FirmwareVersion = device.ImgVersion }); } } foreach (var gateway in listGateway) { //Linux的升级固件名字 var fileFullName = GetGatewayLinuxFirmwareFile(gateway); if (System.IO.File.Exists(fileFullName) == false && listCheck.Contains(fileFullName) == false) { listCheck.Add(fileFullName); //Linux listVersion.Add(new TemplateDeviceVersion { FileDiv = "Linux_", levelType = FirmwareLevelType.Linux, HwVersion = gateway.LinuxHardVersion.ToString(), ImageType = gateway.LinuxImageType.ToString(), FirmwareVersion = gateway.LinuxFirmwareVersion }); } //协调器的升级固件名字 fileFullName = GetGatewayCoordinatorFirmwareFile(gateway); if (System.IO.File.Exists(fileFullName) == false && listCheck.Contains(fileFullName) == false) { listCheck.Add(fileFullName); //协调器 listVersion.Add(new TemplateDeviceVersion { FileDiv = "Coordinator_", levelType = FirmwareLevelType.A协调器, HwVersion = gateway.CoordinatorHardVersion.ToString(), ImageType = gateway.CoordinatorImageId.ToString(), FirmwareVersion = gateway.CoordinatorFirmwareVersion }); } //这个网关需要有虚拟驱动这个东西才行 if (HdlGatewayLogic.Current.CheckGatewayHadDriveCode(gateway) == true) { //虚拟驱动号 foreach (var data in gateway.DriveCodeList) { //虚拟驱动号的升级固件名字 fileFullName = GetGatewayDriveCodeFirmwareFile(data); if (System.IO.File.Exists(fileFullName) == false && listCheck.Contains(fileFullName) == false) { listCheck.Add(fileFullName); //虚拟驱动号 listVersion.Add(new TemplateDeviceVersion { FileDiv = "DriveCode_", levelType = FirmwareLevelType.A虚拟驱动, HwVersion = data.DriveHwVersion.ToString(), ImageType = data.DriveImageType.ToString(), FirmwareVersion = data.DriveFwVersion }); } } } } return listVersion; } /// /// 获取需要下载的空调模块 /// /// 设备列表 /// 与返回值对应的东西 private List GetNeedDownLoadAirConditionerModule(List listDevice, ref List listTaget) { var listUpdate = new List(); //固件存储路径 string firmwareDir = HdlFileNameResourse.FirmwareUpdateDirectory; foreach (var otaDevice in listDevice) { var myType = HdlDeviceCommonLogic.Current.GetMyDeviceEnumInfo(new List { otaDevice }); if (myType.ConcreteType != DeviceConcreteType.AirConditioner_ZbGateway) { //只处理中央空调 continue; } var list = GetFirmwareVersionListInfo(FirmwareLevelType.A设备, otaDevice.HwVersion.ToString(), otaDevice.ImgTypeId.ToString()); foreach (var data in list) { if (data.Name.EndsWith(".bin") == true && System.IO.File.Exists(firmwareDir) == false) { //只要.bin文件 listUpdate.Add(data); listTaget.Add(otaDevice); } } } return listUpdate; } /// /// 下载固件 /// /// 下载的类型 /// 主键 /// public byte[] DowLoadFirmware(FirmwareLevelType levelType, string i_Mainkey) { var pra = new { RequestVersion = Common.CommonPage.RequestVersion, DistributedMark = i_Mainkey }; //默认为10秒 int waitTime = 10; if (levelType != FirmwareLevelType.A设备) { //网关的比较大,给多一点时间 waitTime = 25; } int count = 3; while (count > 0) { var result = this.RequestZigbeeHttps("FirmwareMana/DownloadPlatformUploadFirmware", pra, waitTime); if (result != null) { return result.Length == 0 ? null : result; } count--; } return null; } /// /// 模板设备的版本信息 /// private class TemplateDeviceVersion { /// /// 文件区分 /// public string FileDiv = string.Empty; /// /// 固件阶级区分 /// public FirmwareLevelType levelType; /// /// 硬件版本 /// public string HwVersion = string.Empty; /// /// 镜像ID /// public string ImageType = string.Empty; /// /// 固件版本 /// public int FirmwareVersion = 0; } #endregion #region ■ 访问云端的方法_____________________ /// /// 云端固件的网址 /// public string RequestHttpsHost = "https://global.hdlcontrol.com/ProposedProductionApi"; /// /// 访问云端固件的方法 /// /// 接口名字 /// body数据 /// 超时时间 /// public byte[] RequestZigbeeHttps(string i_interfaceName, object i_body, int i_waitTime) { string fullUrl = this.RequestHttpsHost + "/" + i_interfaceName; var result = HdlHttpLogic.Current.DoRequestZigbeeHttps(fullUrl, null, RestSharp.Method.POST, i_body, null, null, CheckMode.A不检测, i_waitTime, false); return result; } #endregion #region ■ 一般方法___________________________ /// /// 固件的信息处理 /// /// /// private void DoAdjustFirmwareInformation(FirmwareVersionInfo Info, string remark) { if (string.IsNullOrEmpty(remark) == true) { return; } //更新内容 string[] Arry = remark.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); Info.UpdateContent.AddRange(Arry); } #endregion } }