黄学彪
2020-09-01 dee21bf452a8979d0515d13e534fbb69ed9715dd
ZigbeeApp/Shared/Phone/UserCenter/CommonBase/Logic/HdlFirmwareUpdateLogic.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
@@ -18,38 +18,33 @@
        public static void DoUpdateNextFirmware()
        {
            //下一个要执行更新的网关
            HdlGatewayUpdateLogic gwControl = null;
            foreach (var contr in FirmwareUpdateResourse.dicGatewayUpdateList.Values)
            HdlDeviceUpdateCommonLogic gwControl = null;
            //下一个要执行更新的设备
            HdlDeviceUpdateCommonLogic deviceControl = null;
            foreach (var contr in FirmwareUpdateResourse.dicUpdateList.Values)
            {
                //如果别的还在升级中,则不再处理
                if (contr.IsFinishUpdate == false)
                {
                    return;
                }
                //如果这个网关是在等待列表的话
                //如果这个在等待列表的话
                if (contr.UpdateStatu == UpdateStatuMode.Wait && gwControl == null)
                {
                    //下一个升级的就是它了
                    gwControl = contr;
                    if (contr.ClassDiv == 1 && gwControl == null)
                    {
                        //下一个升级的就是它了
                        gwControl = contr;
                    }
                    else if (contr.ClassDiv == 2 && deviceControl == null)
                    {
                        //下一个升级的就是它了
                        deviceControl = contr;
                    }
                }
            }
            HdlDeviceUpdateLogic deviceControl = null;
            foreach (var contr in FirmwareUpdateResourse.dicDeviceUpdateList.Values)
            {
                //如果别的还在升级中,则不再处理
                if (contr.IsFinishUpdate == false)
                {
                    return;
                }
                //如果这个设备是在等待列表的话
                if (contr.UpdateStatu == UpdateStatuMode.Wait && deviceControl == null)
                {
                    //下一个升级的就是它了
                    deviceControl = contr;
                }
            }
            HdlThreadLogic.Current.RunMain(() =>
            HdlThreadLogic.Current.RunThread(() =>
            {
                if (gwControl != null)
                {
@@ -71,18 +66,18 @@
        #region ■ 添加升级固件信息___________________
        /// <summary>
        /// 添加升级固件信息
        /// 添加升级固件信息 1:正常  -1:没网,获取不到东西
        /// </summary>
        /// <param name="levelType">固件阶级分类</param>
        /// <param name="HardwareVersion">硬件版本</param>
        /// <param name="imgType">镜像类型</param>
        /// <returns></returns>
        public async static Task<bool> AddFirmwareVersionInfo(FirmwareLevelType levelType, string HardwareVersion, string imgType)
        public static int AddFirmwareVersionInfo(FirmwareLevelType levelType, string HardwareVersion, string imgType)
        {
            //检测本地是否已经有这个缓存了
            if (IsEsixtFirmwareVersionInfo(levelType, HardwareVersion, imgType) == true)
            {
                return true;
                return 1;
            }
            var Pra = new GetFirmwareVersionPra();
            Pra.PageSetting.Page = 1;
@@ -95,27 +90,27 @@
                Pra.FirmwareManaSecondType = 0;
                Pra.HardwareVersion = HardwareVersion;
                Pra.DeviceType = imgType;
                var result = await GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.Linux, Pra);
                var result = GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.Linux, Pra);
                return result;
            }
            else if (levelType == FirmwareLevelType.Coordinator)
            else if (levelType == FirmwareLevelType.A协调器)
            {
                //协调器模块
                Pra.FirmwareManaFirstType = 1;
                Pra.FirmwareManaSecondType = 1;
                Pra.HardwareVersion = HardwareVersion;
                Pra.DeviceType = imgType;
                var result = await GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.Coordinator, Pra);
                var result = GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.A协调器, Pra);
                return result;
            }
            else if (levelType == FirmwareLevelType.VirtualDevice)
            else if (levelType == FirmwareLevelType.A虚拟驱动)
            {
                //虚拟设备模块
                Pra.FirmwareManaFirstType = 1;
                Pra.FirmwareManaSecondType = 2;
                Pra.HardwareVersion = HardwareVersion;
                Pra.DeviceType = imgType;
                var result = await GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.VirtualDevice, Pra);
                var result = GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.A虚拟驱动, Pra);
                return result;
            }
            else
@@ -125,37 +120,48 @@
                Pra.FirmwareManaSecondType = null;
                Pra.HardwareVersion = HardwareVersion;
                Pra.DeviceType = imgType;
                var result = await GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.ZigbeeDevice, Pra);
                var result = GetFirmwareVersionAndSetToMemmory(FirmwareLevelType.A设备, Pra);
                return result;
            }
        }
        /// <summary>
        /// 获取云端的固件,然后存入缓存中
        /// 获取云端的固件,然后存入缓存中 1:正常  -1:没网,获取不到东西
        /// </summary>
        /// <param name="levelType"></param>
        /// <param name="pra"></param>
        /// <returns></returns>
        private async static Task<bool> GetFirmwareVersionAndSetToMemmory(FirmwareLevelType levelType, GetFirmwareVersionPra pra)
        private static int GetFirmwareVersionAndSetToMemmory(FirmwareLevelType levelType, GetFirmwareVersionPra pra)
        {
            var listNotShow = new List<string>() { "NotSetAgain" };
            string resultValue = await UserCenterLogic.GetResponseDataByRequestHttps("FirmwareMana/DetectionPlatformUploadFirmware", false, pra, listNotShow);
            var listCheck = new List<string> { "NotCheck" };
            string resultValue = UserCenterLogic.GetResponseDataByRequestHttps("FirmwareMana/DetectionPlatformUploadFirmware", false, pra, listCheck, false);
            if (string.IsNullOrEmpty(resultValue) == true)
            {
                return false;
                return -1;
            }
            var verResult = Newtonsoft.Json.JsonConvert.DeserializeObject<FirmwareVersionResult>(resultValue);
            if (verResult.PageData.Count == 0)
            {
                return true;
                return 1;
            }
            //硬件版本
            Dictionary<string, FirmwareHardInfo> dicHardData = new Dictionary<string, FirmwareHardInfo>();
            FirmwareUpdateResourse.dicFirmwareInfo[levelType] = dicHardData;
            Dictionary<string, FirmwareHardInfo> dicHardData = null;
            if (FirmwareUpdateResourse.dicFirmwareInfo.ContainsKey(levelType) == false)
            {
                FirmwareUpdateResourse.dicFirmwareInfo[levelType] = new Dictionary<string, FirmwareHardInfo>();
            }
            dicHardData = FirmwareUpdateResourse.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;
@@ -189,6 +195,7 @@
                    info.Name = data.Name;
                    info.HardwareVersion = hardCode;
                    info.ImagType = imgType;
                    info.CreatedOnUtc = data.CreatedOnUtc;
                    imgTypeInfo.listVeison.Add(info);
                    //固件的信息处理
                    DoAdjustFirmwareInformation(info, data.Remarks);
@@ -196,7 +203,7 @@
                catch { continue; }
            }
            return true;
            return 1;
        }
        #endregion
@@ -218,6 +225,19 @@
            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;
@@ -291,6 +311,37 @@
        #endregion
        #region ■ 获取指定固件版本信息_______________
        /// <summary>
        /// 获取指定固件的版本信息(如果返回Null,则表示没有这个固件)
        /// </summary>
        /// <param name="levelType">固件阶级分类</param>
        /// <param name="HardwareVersion">硬件版本</param>
        /// <param name="imgType">镜像类型</param>
        /// <param name="nowVersion">现在的版本</param>
        /// <returns></returns>
        public static 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 ■ 固件存在检测_______________________
        /// <summary>
@@ -320,6 +371,262 @@
            return true;
        }
        /// <summary>
        /// 检测该Ota设备的升级固件是否存在
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <returns></returns>
        public static bool IsEsixtDeviceFirmwareFile(OTADevice device)
        {
            var fileFullName = GetDeviceFirmwareFile(device);
            return System.IO.File.Exists(fileFullName);
        }
        /// <summary>
        /// 获取ota指定的升级固件名字(全路径)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <returns></returns>
        public static string GetDeviceFirmwareFile(OTADevice device)
        {
            //硬件版本_镜像ID_固件版本
            string fileName = device.HwVersion + "_" + device.ImgTypeId + "_" + device.ImgVersion;
            return System.IO.Path.Combine(DirNameResourse.FirmwareUpdateDirectory, "Device_" + fileName + ".ota");
        }
        /// <summary>
        /// 获取网关Linux的升级固件名字(全路径)
        /// </summary>
        /// <param name="zbGateway">网关对象</param>
        /// <returns></returns>
        public static string GetGatewayLinuxFirmwareFile(ZbGateway zbGateway)
        {
            string fileName = zbGateway.LinuxHardVersion + "_" + zbGateway.LinuxImageType + "_" + zbGateway.LinuxFirmwareVersion;
            return System.IO.Path.Combine(DirNameResourse.FirmwareUpdateDirectory, "Linux_" + fileName + ".ota");
        }
        /// <summary>
        /// 获取网关协调器的升级固件名字(全路径)
        /// </summary>
        /// <param name="zbGateway">网关对象</param>
        /// <returns></returns>
        public static string GetGatewayCoordinatorFirmwareFile(ZbGateway zbGateway)
        {
            string fileName = zbGateway.CoordinatorHardVersion + "_" + zbGateway.CoordinatorImageId + "_" + zbGateway.CoordinatorFirmwareVersion;
            return System.IO.Path.Combine(DirNameResourse.FirmwareUpdateDirectory, "Coordinator_" + fileName + ".ota");
        }
        /// <summary>
        /// 获取网关虚拟驱动的升级固件名字(全路径)
        /// </summary>
        /// <param name="codeObj">虚拟驱动数据</param>
        /// <returns></returns>
        public static string GetGatewayDriveCodeFirmwareFile(ZbGatewayData.DriveCodeObj codeObj)
        {
            string fileName = codeObj.DriveHwVersion + "_" + codeObj.DriveImageType + "_" + codeObj.DriveFwVersion;
            return System.IO.Path.Combine(DirNameResourse.FirmwareUpdateDirectory, "DriveCode_" + fileName + ".ota");
        }
        #endregion
        #region ■ 下载模板固件_______________________
        /// <summary>
        /// 下载模板中网关和设备的固件
        /// </summary>
        /// <param name="fullFileName"></param>
        /// <param name="i_Msg"></param>
        public static int DownLoadTemplateDeviceFirmware(string fullFileName, string i_Msg)
        {
            //从模板当中获取设备和网关对象
            var listTempDevice = new List<OTADevice>();
            var listTempGateway = new List<ZbGateway>();
            TemplateData.TemplateCommonLogic.Current.GetDeviceObjectFromTemplate(fullFileName, ref listTempDevice, ref listTempGateway);
            //获取需要下载的固件数据
            var listVersion = GetNeedToDownLoadVersionData(listTempDevice, listTempGateway);
            if (listVersion.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<string, string>();
            var fileData = HdlFileLogic.Current.ReadFileTextContent(DirNameResourse.FirmwareUpdateList);
            if (fileData != null)
            {
                //本地存放的固件原来的名字(因为设备升级时,它需要识别文件名字里面包含的特殊字符)
                //key:全路径,硬件版本_镜像ID_固件版本  value:固件原来的名字
                dicFirmwareName = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(fileData);
            }
            //固件存储路径
            string firmwareDir = DirNameResourse.FirmwareUpdateDirectory;
            int nowCount = 0;
            foreach (var versionData in listVersion)
            {
                nowCount++;
                //获取升级固件信息
                var result = AddFirmwareVersionInfo(versionData.levelType, versionData.HwVersion, versionData.ImageType);
                if (result == -1)
                {
                    ProgressFormBar.Current.Close();
                    return -1;
                }
                //获取当前这个版本的固件信息
                var versionFirmware = GetFirmwareVersionInfo(versionData.levelType, versionData.HwVersion, versionData.ImageType, versionData.FirmwareVersion);
                if (versionFirmware == null)
                {
                    //云端没有这个版本  进度值
                    ProgressFormBar.Current.SetValue(nowCount, listVersion.Count);
                    continue;
                }
                //去下载这个固件
                var pra = new { RequestVersion = Common.CommonPage.RequestVersion, DistributedMark = versionFirmware.DistributedMark };
                var byteData = UserCenterLogic.GetByteResponseDataByRequestHttps("FirmwareMana/DownloadPlatformUploadFirmware", false, pra, null, true);
                if (byteData == null)
                {
                    ProgressFormBar.Current.Close();
                    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, listVersion.Count);
            }
            //保存列表名字
            HdlFileLogic.Current.SaveFileContent(DirNameResourse.FirmwareUpdateList, dicFirmwareName);
            ProgressFormBar.Current.Close();
            return 1;
        }
        /// <summary>
        /// 获取需要下载的固件数据
        /// </summary>
        /// <param name="listDevice">设备列表</param>
        /// <param name="listGateway">网关列表</param>
        /// <returns></returns>
        private static List<TemplateDeviceVersion> GetNeedToDownLoadVersionData(List<OTADevice> listDevice, List<ZbGateway> listGateway)
        {
            //存储路径
            string firmwareDir = DirNameResourse.FirmwareUpdateDirectory;
            HdlFileLogic.Current.CreateDirectory(firmwareDir);
            var listVersion = new List<TemplateDeviceVersion>();
            var listCheck = new HashSet<string>();
            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 (gateway.LinuxImageType != 6)
                {
                    //虚拟驱动号
                    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;
        }
        /// <summary>
        /// 模板设备的版本信息
        /// </summary>
        private class TemplateDeviceVersion
        {
            /// <summary>
            /// 文件区分
            /// </summary>
            public string FileDiv = string.Empty;
            /// <summary>
            /// 固件阶级区分
            /// </summary>
            public FirmwareLevelType levelType;
            /// <summary>
            /// 硬件版本
            /// </summary>
            public string HwVersion = string.Empty;
            /// <summary>
            /// 镜像ID
            /// </summary>
            public string ImageType = string.Empty;
            /// <summary>
            /// 固件版本
            /// </summary>
            public int FirmwareVersion = 0;
        }
        #endregion
        #region ■ 一般方法___________________________
@@ -340,23 +647,6 @@
            Info.UpdateContent.AddRange(Arry);
        }
        /// <summary>
        /// 将十六进制转为十进制
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private static int ConvertHexToInt(string text)
        {
            if (text.StartsWith("0x"))
            {
                text = text.Substring(2);
            }
            try
            {
                return Convert.ToInt32(text, 16);
            }
            catch { return -1; }
        }
        #endregion
    }
}