using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using BLEProtocol; /// /// OTA版本信息 /// [Serializable] public class OTAVersionInfo { public uint FirmwareVersion; // 固件版本 (4字节) public uint HardwareVersion; // 硬件版本 (4字节) public uint OTAVersion; // OTA版本 (4字节) public override string ToString() { return $"固件版本: {FirmwareVersion}, 硬件版本: {HardwareVersion}, OTA版本: {OTAVersion}"; } } /// /// OTA升级状态 /// public enum OTAState { Idle, // 空闲 QueryingVersion, // 查询版本中 Starting, // 开始升级中 Transferring, // 传输数据中 Ending, // 结束传输中 Cancelling, // 取消升级中 Completed, // 完成 Error // 错误 } /// /// OTA升级管理器 - 处理固件OTA升级 /// public class OTAManager : MonoBehaviour { public static OTAManager Instance { get; private set; } // 事件定义 public event Action OnVersionInfoReceived; // 收到版本信息 public event Action OnStartUpgradeResult; // 开始升级结果 public event Action OnTransferProgress; // 传输进度 (当前包, 总包数, 重试次数, 最大重试次数) public event Action OnTransferComplete; // 传输完成 public event Action OnCancelResult; // 取消结果 public event Action OnError; // 错误事件 public event Action OnStateChanged; // 状态变化 // 状态 public OTAState CurrentState { get; private set; } = OTAState.Idle; // 升级参数 private byte[] _firmwareData; // 固件数据 private uint _firmwareVersion; // 固件版本 private int _currentPacketIndex; // 当前包序号 private int _totalPackets; // 总包数 private const int PACKET_SIZE = 512; // 每包数据大小(根据设备MTU调整) private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } private void OnDestroy() { if (Instance == this) { Instance = null; } } #region OTA命令接口 /// /// 查询OTA版本信息 (命令 0x80) /// public void QueryVersionInfo(Action callback = null) { if (!CheckConnection()) return; SetState(OTAState.QueryingVersion); var frame = new BLEFrame { Header1 = BLEConstants.FRAME_HEADER_1, Header2 = BLEConstants.FRAME_HEADER_2, Command = BLEConstants.CMD_OTA_QUERY_VERSION, ReadWrite = BLEConstants.RW_READ, Length = 0, Data = null }; SendFrame(frame, (response) => { if (response.IsSuccess && response.Data != null && response.Data.Length >= 12) { var info = new OTAVersionInfo { FirmwareVersion = BitConverter.ToUInt32(response.Data, 0), HardwareVersion = BitConverter.ToUInt32(response.Data, 4), OTAVersion = BitConverter.ToUInt32(response.Data, 8) }; SetState(OTAState.Idle); OnVersionInfoReceived?.Invoke(info); callback?.Invoke(info); } else { SetState(OTAState.Error); OnError?.Invoke("查询OTA版本信息失败"); callback?.Invoke(null); } }); } /// /// 开始OTA升级 (命令 0x81) /// /// 固件数据 /// 固件版本 /// 回调 public void StartUpgrade(byte[] firmwareData, uint firmwareVersion, Action callback = null) { if (!CheckConnection()) { callback?.Invoke(false); return; } if (firmwareData == null || firmwareData.Length == 0) { LogError("固件数据为空"); callback?.Invoke(false); return; } _firmwareData = firmwareData; _firmwareVersion = firmwareVersion; _currentPacketIndex = 0; _totalPackets = (int)Math.Ceiling((double)firmwareData.Length / PACKET_SIZE); SetState(OTAState.Starting); // 计算CRC16 ushort crc16 = CalculateCRC16(firmwareData); // 构建数据: 版本号(4) + 大小(4) + CRC16(2) byte[] data = new byte[10]; BitConverter.GetBytes(firmwareVersion).CopyTo(data, 0); BitConverter.GetBytes((uint)firmwareData.Length).CopyTo(data, 4); BitConverter.GetBytes(crc16).CopyTo(data, 8); var frame = new BLEFrame { Header1 = BLEConstants.FRAME_HEADER_1, Header2 = BLEConstants.FRAME_HEADER_2, Command = BLEConstants.CMD_OTA_START, ReadWrite = BLEConstants.RW_WRITE, Length = (byte)data.Length, Data = data }; // 使用协程来处理响应和延迟 StartCoroutine(StartUpgradeCoroutineInternal(frame, callback)); } private IEnumerator StartUpgradeCoroutineInternal(BLEFrame frame, Action callback) { BLEResponse response = new BLEResponse { Status = BLEConstants.STATUS_DEVICE_ERROR }; bool completed = false; SendFrame(frame, (resp) => { response = resp; completed = true; }); yield return new WaitUntil(() => completed); bool success = response.IsSuccess; if (success) { // 检查连接状态,如果断开则等待重连 int retryCount = 0; const int maxRetries = 10; while (BluetoothManager.Instance != null && !BluetoothManager.Instance.IsConnected && retryCount < maxRetries) { yield return new WaitForSeconds(0.5f); retryCount++; } if (BluetoothManager.Instance == null || !BluetoothManager.Instance.IsConnected) { SetState(OTAState.Error); OnStartUpgradeResult?.Invoke(false); callback?.Invoke(false); yield break; } // 实际测试连接是否可用 - 发送一个查询版本命令 bool testCompleted = false; bool testSuccess = false; var testFrame = new BLEFrame { Header1 = BLEConstants.FRAME_HEADER_1, Header2 = BLEConstants.FRAME_HEADER_2, Command = BLEConstants.CMD_OTA_QUERY_VERSION, ReadWrite = BLEConstants.RW_READ, Length = 0, Data = null }; SendFrame(testFrame, (testResponse) => { testSuccess = testResponse.IsSuccess; testCompleted = true; }); // 等待最多3秒 float testStartTime = Time.time; while (!testCompleted && Time.time - testStartTime < 3f) { yield return null; } if (!testCompleted) { LogError("[OTA-DEBUG] 连接测试超时,BLE连接可能已断开"); SetState(OTAState.Error); OnStartUpgradeResult?.Invoke(false); callback?.Invoke(false); yield break; } if (!testSuccess) { SetState(OTAState.Error); OnStartUpgradeResult?.Invoke(false); callback?.Invoke(false); yield break; } SetState(OTAState.Transferring); OnStartUpgradeResult?.Invoke(true); callback?.Invoke(true); } else { SetState(OTAState.Error); OnStartUpgradeResult?.Invoke(false); callback?.Invoke(false); } } /// /// 传输固件数据包 (命令 0x82) /// public IEnumerator TransferFirmware(Action callback = null) { if (_firmwareData == null) { LogError("没有固件数据"); callback?.Invoke(false); yield break; } SetState(OTAState.Transferring); // 每包实际数据长度(不包括包序号) const int DATA_PER_PACKET = 253; // 255 - 2 (包序号) // 重新计算总包数 _totalPackets = (_firmwareData.Length + DATA_PER_PACKET - 1) / DATA_PER_PACKET; for (int i = 0; i < _totalPackets; i++) { _currentPacketIndex = i; int offset = i * DATA_PER_PACKET; // 使用实际数据长度计算偏移 int length = Mathf.Min(DATA_PER_PACKET, _firmwareData.Length - offset); // 构建数据包: 包序号(2) + 数据(N) byte[] packetData = new byte[2 + length]; BitConverter.GetBytes((ushort)i).CopyTo(packetData, 0); Buffer.BlockCopy(_firmwareData, offset, packetData, 2, length); var frame = new BLEFrame { Header1 = BLEConstants.FRAME_HEADER_1, Header2 = BLEConstants.FRAME_HEADER_2, Command = BLEConstants.CMD_OTA_TRANSFER_DATA, ReadWrite = BLEConstants.RW_WRITE, Length = (byte)packetData.Length, Data = packetData }; // 发送数据包,带重试机制 bool packetSuccess = false; int retryCount = 0; const int maxRetries = 5; while (!packetSuccess && retryCount < maxRetries) { if (retryCount > 0) { OnTransferProgress?.Invoke(i + 1, _totalPackets, retryCount, maxRetries); yield return new WaitForSeconds(0.5f); } yield return SendFrameCoroutine(frame, (response) => { packetSuccess = response.IsSuccess; }); if (!packetSuccess) { retryCount++; } } if (!packetSuccess) { SetState(OTAState.Error); OnError?.Invoke($"传输包 {_currentPacketIndex} 失败"); callback?.Invoke(false); yield break; } // 报告进度(无重试) OnTransferProgress?.Invoke(i + 1, _totalPackets, 0, 0); // 每包之间添加小延迟,避免设备处理不过来 if (i < _totalPackets - 1) { yield return new WaitForSeconds(0.01f); } } SetState(OTAState.Ending); OnTransferComplete?.Invoke(true); callback?.Invoke(true); } /// /// 结束传输 (命令 0x83) /// public void EndTransfer(Action callback = null) { if (!CheckConnection()) { callback?.Invoke(false); return; } SetState(OTAState.Ending); // 数据: 总大小(4) + CRC16(2) byte[] data = new byte[6]; BitConverter.GetBytes((uint)_firmwareData.Length).CopyTo(data, 0); ushort crc16 = CalculateCRC16(_firmwareData); BitConverter.GetBytes(crc16).CopyTo(data, 4); var frame = new BLEFrame { Header1 = BLEConstants.FRAME_HEADER_1, Header2 = BLEConstants.FRAME_HEADER_2, Command = BLEConstants.CMD_OTA_END_TRANSFER, ReadWrite = BLEConstants.RW_WRITE, Length = (byte)data.Length, Data = data }; SendFrame(frame, (response) => { bool success = response.IsSuccess; if (success) { SetState(OTAState.Completed); } else { SetState(OTAState.Error); } callback?.Invoke(success); }); } /// /// 取消升级 (命令 0x85) /// public void CancelUpgrade(Action callback = null) { if (!CheckConnection()) { callback?.Invoke(false); return; } SetState(OTAState.Cancelling); // 数据: 取消标志(1) byte[] data = new byte[] { 0x01 }; var frame = new BLEFrame { Header1 = BLEConstants.FRAME_HEADER_1, Header2 = BLEConstants.FRAME_HEADER_2, Command = BLEConstants.CMD_OTA_CANCEL, ReadWrite = BLEConstants.RW_WRITE, Length = (byte)data.Length, Data = data }; SendFrame(frame, (response) => { bool success = response.IsSuccess; if (success) { SetState(OTAState.Idle); _firmwareData = null; } else { SetState(OTAState.Error); } OnCancelResult?.Invoke(success); callback?.Invoke(success); }); } #endregion #region 完整升级流程 /// /// 执行完整OTA升级流程 /// public IEnumerator PerformFullUpgrade(byte[] firmwareData, uint firmwareVersion, Action callback = null) { // 0. 先取消可能存在的未完成升级 bool cancelSuccess = false; yield return CancelUpgradeCoroutine((success) => cancelSuccess = success); if (cancelSuccess) { yield return new WaitForSeconds(1f); } // 1. 查询版本信息 OTAVersionInfo versionInfo = null; yield return QueryVersionInfoCoroutine((info) => versionInfo = info); if (versionInfo == null) { callback?.Invoke(false); yield break; } // 2. 开始升级 bool startSuccess = false; yield return StartUpgradeCoroutine(firmwareData, firmwareVersion, (success) => startSuccess = success); if (!startSuccess) { callback?.Invoke(false); yield break; } // 3. 传输数据 bool transferSuccess = false; yield return TransferFirmware((success) => transferSuccess = success); if (!transferSuccess) { callback?.Invoke(false); yield break; } // 4. 结束传输 bool endSuccess = false; yield return EndTransferCoroutine((success) => endSuccess = success); if (!endSuccess) { callback?.Invoke(false); yield break; } callback?.Invoke(true); } #endregion #region 辅助方法 private bool CheckConnection() { if (BLECommunicationManager.Instance == null) return false; if (BluetoothManager.Instance == null || !BluetoothManager.Instance.IsConnected) return false; return true; } private void SetState(OTAState newState) { if (CurrentState != newState) { CurrentState = newState; OnStateChanged?.Invoke(newState); } } private void SendFrame(BLEFrame frame, Action callback) { BLECommunicationManager.Instance.SendFrameInternal(frame, callback); } private IEnumerator SendFrameCoroutine(BLEFrame frame, Action callback) { bool completed = false; BLEResponse response = new BLEResponse { Status = BLEConstants.STATUS_DEVICE_ERROR }; SendFrame(frame, (resp) => { response = resp; completed = true; }); yield return new WaitUntil(() => completed); callback?.Invoke(response); } private IEnumerator QueryVersionInfoCoroutine(Action callback) { OTAVersionInfo info = null; QueryVersionInfo((result) => info = result); yield return new WaitUntil(() => CurrentState != OTAState.QueryingVersion || info != null); callback?.Invoke(info); } private IEnumerator StartUpgradeCoroutine(byte[] firmwareData, uint firmwareVersion, Action callback) { bool completed = false; bool success = false; StartUpgrade(firmwareData, firmwareVersion, (result) => { success = result; completed = true; }); yield return new WaitUntil(() => completed); callback?.Invoke(success); } private IEnumerator CancelUpgradeCoroutine(Action callback) { bool completed = false; bool success = false; CancelUpgrade((result) => { success = result; completed = true; }); yield return new WaitUntil(() => completed); callback?.Invoke(success); } private IEnumerator EndTransferCoroutine(Action callback) { bool completed = false; bool success = false; EndTransfer((result) => { success = result; completed = true; }); yield return new WaitUntil(() => completed); callback?.Invoke(success); } /// /// 计算CRC16校验 /// private ushort CalculateCRC16(byte[] data) { ushort crc = 0xFFFF; for (int i = 0; i < data.Length; i++) { crc ^= (ushort)(data[i] << 8); for (int j = 0; j < 8; j++) { if ((crc & 0x8000) != 0) crc = (ushort)((crc << 1) ^ 0x1021); else crc <<= 1; } } return crc; } private void Log(string message) { Debug.Log($"[OTAManager] {message}"); } private void LogError(string message) { Debug.LogError($"[OTAManager] {message}"); } #endregion }