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
}