debug
This commit is contained in:
parent
d5eec25b7d
commit
cec4f941ec
7
.gitignore
vendored
7
.gitignore
vendored
@ -30,8 +30,8 @@
|
|||||||
# Gradle cache directory
|
# Gradle cache directory
|
||||||
.gradle/
|
.gradle/
|
||||||
# 资源包
|
# 资源包
|
||||||
AssetBundles/
|
/AssetBundles/
|
||||||
Assets/StreamingAssets/
|
/Assets/StreamingAssets/
|
||||||
# Autogenerated VS/MD/Consulo solution and project files
|
# Autogenerated VS/MD/Consulo solution and project files
|
||||||
ExportedObj/
|
ExportedObj/
|
||||||
.consulo/
|
.consulo/
|
||||||
@ -74,3 +74,6 @@ crashlytics-build.properties
|
|||||||
# Streaming Assets (build artifacts, don't commit)
|
# Streaming Assets (build artifacts, don't commit)
|
||||||
/[Aa]ssets/[Ss]treamingAssets/
|
/[Aa]ssets/[Ss]treamingAssets/
|
||||||
|
|
||||||
|
ProjectSettings/ProjectVersion.txt
|
||||||
|
Assets/Resources/BillingMode.json
|
||||||
|
Assets/Resources/BillingMode.json.meta
|
||||||
|
|||||||
@ -850,19 +850,14 @@ extern "C" {
|
|||||||
|
|
||||||
NSString *message = nil;
|
NSString *message = nil;
|
||||||
|
|
||||||
|
// 始终发送5字段消息格式,确保 C# 层 DiscoveredPeripheralWithAdvertisingInfoAction 始终被调用
|
||||||
|
NSString *dataBase64 = @"";
|
||||||
if (advertisementData != nil && [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey] != nil)
|
if (advertisementData != nil && [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey] != nil)
|
||||||
{
|
{
|
||||||
NSData* bytes = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey];
|
NSData* bytes = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey];
|
||||||
message = [NSString stringWithFormat:@"DiscoveredPeripheral~%@~%@~%@~%@", identifier, name, RSSI, [UnityBluetoothLE base64StringFromData:bytes length:bytes.length]];
|
dataBase64 = [UnityBluetoothLE base64StringFromData:bytes length:bytes.length];
|
||||||
}
|
|
||||||
else if (RSSI != 0 && _rssiOnly)
|
|
||||||
{
|
|
||||||
message = [NSString stringWithFormat:@"DiscoveredPeripheral~%@~%@~%@~", identifier, name, RSSI];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
message = [NSString stringWithFormat:@"DiscoveredPeripheral~%@~%@", identifier, name];
|
|
||||||
}
|
}
|
||||||
|
message = [NSString stringWithFormat:@"DiscoveredPeripheral~%@~%@~%@~%@", identifier, name, RSSI, dataBase64];
|
||||||
|
|
||||||
if (message != nil)
|
if (message != nil)
|
||||||
UnitySendMessage ("BluetoothLEReceiver", "OnBluetoothMessage", [message UTF8String]);
|
UnitySendMessage ("BluetoothLEReceiver", "OnBluetoothMessage", [message UTF8String]);
|
||||||
|
|||||||
@ -1121,18 +1121,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "100225",
|
"key": "100225",
|
||||||
"zh": "正在更新固件,请勿断开设备电源",
|
"zh": "正在向设备传输固件,请勿断开设备电源",
|
||||||
"en": "Updating firmware. Please do not disconnect the device power."
|
"en": "Transferring firmware to device. Please do not disconnect the device power."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "100226",
|
"key": "100226",
|
||||||
"zh": "固件更新成功,请等待设备重启",
|
"zh": "固件传输成功,请等待设备安装后重启",
|
||||||
"en": "Firmware update successful. Please wait for the device to restart."
|
"en": "Firmware transfer successful. Please wait for the device to restart after installation."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "100227",
|
"key": "100227",
|
||||||
"zh": "固件更新失败,请重试",
|
"zh": "固件传输失败,请重试",
|
||||||
"en": "Firmware update failed. Please try again."
|
"en": "Firmware transfer failed. Please try again."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "100228",
|
"key": "100228",
|
||||||
@ -1463,6 +1463,11 @@
|
|||||||
"key": "100293",
|
"key": "100293",
|
||||||
"zh": "WiFi模式下暂不支持指纹设置,请通过蓝牙连接操作",
|
"zh": "WiFi模式下暂不支持指纹设置,请通过蓝牙连接操作",
|
||||||
"en": "Fingerprint settings are not supported in WiFi mode. Please connect via Bluetooth."
|
"en": "Fingerprint settings are not supported in WiFi mode. Please connect via Bluetooth."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "100294",
|
||||||
|
"zh": "正在下载固件,请保持屏幕常亮",
|
||||||
|
"en": "Downloading firmware. Please keep the screen on."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2819,7 +2819,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 89f1d49b50a31514787b4e268b1c73bb, type: 3}
|
m_Script: {fileID: 11500000, guid: 89f1d49b50a31514787b4e268b1c73bb, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
textKey: 100158
|
textKey: 100171
|
||||||
--- !u!1 &6567085060546488150
|
--- !u!1 &6567085060546488150
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
8
Assets/Resources.meta
Normal file
8
Assets/Resources.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 97433af688e6372478beead315bd1777
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -585,7 +585,7 @@ MonoBehaviour:
|
|||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
AutoConnect: 0
|
AutoConnect: 0
|
||||||
ConnectionTimeout: 5
|
ConnectionTimeout: 15
|
||||||
--- !u!114 &609900195
|
--- !u!114 &609900195
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -598,7 +598,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 988c4ecb3723c08459756ef8e35db200, type: 3}
|
m_Script: {fileID: 11500000, guid: 988c4ecb3723c08459756ef8e35db200, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
ResponseTimeout: 5
|
ResponseTimeout: 15
|
||||||
ServiceUUID: 0000ffe0-0000-1000-8000-00805f9b34fb
|
ServiceUUID: 0000ffe0-0000-1000-8000-00805f9b34fb
|
||||||
WriteCharacteristicUUID: 0000ffe1-0000-1000-8000-00805f9b34fb
|
WriteCharacteristicUUID: 0000ffe1-0000-1000-8000-00805f9b34fb
|
||||||
NotifyCharacteristicUUID: 0000ffe1-0000-1000-8000-00805f9b34fb
|
NotifyCharacteristicUUID: 0000ffe1-0000-1000-8000-00805f9b34fb
|
||||||
|
|||||||
@ -12,15 +12,43 @@ namespace Kill.Bluetooth
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public class BluetoothDevice
|
public class BluetoothDevice
|
||||||
{
|
{
|
||||||
public string Address; // 设备地址
|
public string Address; // 设备地址(Android为MAC,iOS为UUID)
|
||||||
public string Name; // 设备名称
|
public string Name; // 设备名称
|
||||||
public int Rssi; // 信号强度
|
public int Rssi; // 信号强度
|
||||||
|
public byte[] info; // 广播/制造商数据
|
||||||
|
public string MacFromBroadcast; // 从广播数据解析出的真实MAC地址(iOS端使用)
|
||||||
|
|
||||||
public BluetoothDevice(string address, string name, int rssi = 0)
|
public BluetoothDevice(string address, string name, int rssi=0,byte[] bytes=null)
|
||||||
{
|
{
|
||||||
Address = address;
|
Address = address;
|
||||||
Name = name;
|
Name = name;
|
||||||
Rssi = rssi;
|
Rssi = rssi;
|
||||||
|
info=bytes;
|
||||||
|
MacFromBroadcast = ParseMacFromBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从广播数据中解析真实MAC地址
|
||||||
|
/// 广播数据格式: [2字节头部] + [6字节MAC地址]
|
||||||
|
/// </summary>
|
||||||
|
public static string ParseMacFromBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (bytes == null || bytes.Length < 8)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// MAC地址位于 bytes[2]~bytes[7](共6字节)
|
||||||
|
return string.Format("{0:X2}:{1:X2}:{2:X2}:{3:X2}:{4:X2}:{5:X2}",
|
||||||
|
bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取用于匹配和显示的有效地址
|
||||||
|
/// iOS: 优先使用广播中的MAC,否则使用UUID
|
||||||
|
/// Android: Address本身就是MAC,直接使用
|
||||||
|
/// </summary>
|
||||||
|
public string GetEffectiveAddress()
|
||||||
|
{
|
||||||
|
return MacFromBroadcast ?? Address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +75,7 @@ namespace Kill.Bluetooth
|
|||||||
public bool IsScanning { get; private set; }
|
public bool IsScanning { get; private set; }
|
||||||
public bool IsConnected { get; private set; }
|
public bool IsConnected { get; private set; }
|
||||||
public string ConnectedDeviceAddress { get; private set; }
|
public string ConnectedDeviceAddress { get; private set; }
|
||||||
|
public string ConnectedDeviceMacAddress { get; private set; } // iOS端连接后存储的真实MAC地址
|
||||||
private string aimMac = "";
|
private string aimMac = "";
|
||||||
// 扫描到的设备列表
|
// 扫描到的设备列表
|
||||||
public List<BluetoothDevice> DiscoveredDevices { get; private set; } = new List<BluetoothDevice>();
|
public List<BluetoothDevice> DiscoveredDevices { get; private set; } = new List<BluetoothDevice>();
|
||||||
@ -402,60 +431,6 @@ namespace Kill.Bluetooth
|
|||||||
// StartScanForAutoConnect(lastAddress);
|
// StartScanForAutoConnect(lastAddress);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 为自动连接扫描设备
|
|
||||||
/// </summary>
|
|
||||||
private void StartScanForAutoConnect(string targetAddress)
|
|
||||||
{
|
|
||||||
if (!IsInitialized)
|
|
||||||
{
|
|
||||||
Log("蓝牙未初始化,无法扫描");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log("[BLE-DEBUG] 自动连接: 开始扫描...");
|
|
||||||
|
|
||||||
// 清空设备列表
|
|
||||||
DiscoveredDevices.Clear();
|
|
||||||
|
|
||||||
// 扫描5秒
|
|
||||||
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null,
|
|
||||||
(address, name) =>
|
|
||||||
{
|
|
||||||
// 先添加到设备列表
|
|
||||||
AddOrUpdateDevice(address, name, 0);
|
|
||||||
|
|
||||||
// 检查是否是要找的设备(统一使用大写比较)
|
|
||||||
if (address.ToUpper() == targetAddress.ToUpper())
|
|
||||||
{
|
|
||||||
Log($"[BLE-DEBUG] 自动连接: 找到设备 {name}");
|
|
||||||
BluetoothLEHardwareInterface.StopScan();
|
|
||||||
// 延迟100ms再连接,确保扫描完全停止(与手动连接流程一致)
|
|
||||||
_pendingAutoConnectAddress = targetAddress;
|
|
||||||
Invoke(nameof(DelayedAutoConnect), 0.1f);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(address, name, rssi, bytes) =>
|
|
||||||
{
|
|
||||||
// 先添加到设备列表
|
|
||||||
AddOrUpdateDevice(address, name, rssi);
|
|
||||||
|
|
||||||
// 检查是否是要找的设备(统一使用大写比较)
|
|
||||||
if (address.ToUpper() == targetAddress.ToUpper())
|
|
||||||
{
|
|
||||||
Log($"[BLE-DEBUG] 自动连接: 找到设备 {name}, RSSI: {rssi}");
|
|
||||||
BluetoothLEHardwareInterface.StopScan();
|
|
||||||
// 延迟100ms再连接,确保扫描完全停止(与手动连接流程一致)
|
|
||||||
_pendingAutoConnectAddress = targetAddress;
|
|
||||||
Invoke(nameof(DelayedAutoConnect), 0.1f);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
// 5秒后停止扫描
|
|
||||||
Invoke(nameof(StopScan), 5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用于自动连接的临时地址存储
|
// 用于自动连接的临时地址存储
|
||||||
private string _pendingAutoConnectAddress;
|
private string _pendingAutoConnectAddress;
|
||||||
@ -512,18 +487,13 @@ namespace Kill.Bluetooth
|
|||||||
Log($"开始扫描蓝牙设备 (超时: {timeout}秒)...");
|
Log($"开始扫描蓝牙设备 (超时: {timeout}秒)...");
|
||||||
OnStartScan?.Invoke();
|
OnStartScan?.Invoke();
|
||||||
// 开始扫描
|
// 开始扫描
|
||||||
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null,
|
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null,null,
|
||||||
// 回调1:基础设备信息(地址和名称)
|
|
||||||
(address, name) =>
|
|
||||||
{
|
|
||||||
AddOrUpdateDevice(address, name, 0);
|
|
||||||
},
|
|
||||||
// 回调2:包含RSSI和制造商数据
|
// 回调2:包含RSSI和制造商数据
|
||||||
(address, name, rssi, bytes) =>
|
(address, name, rssi, bytes) =>
|
||||||
{
|
{
|
||||||
AddOrUpdateDevice(address, name, rssi);
|
AddOrUpdateDevice(address, name, rssi,bytes);
|
||||||
},
|
},
|
||||||
true // 允许不带有制造商数据的RSSI
|
false // 接收完整的广播/制造商数据
|
||||||
);
|
);
|
||||||
|
|
||||||
// 设置超时自动停止
|
// 设置超时自动停止
|
||||||
@ -540,16 +510,12 @@ namespace Kill.Bluetooth
|
|||||||
DiscoveredDevices.Clear();
|
DiscoveredDevices.Clear();
|
||||||
IsScanning = true;
|
IsScanning = true;
|
||||||
|
|
||||||
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null,
|
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null,null,
|
||||||
(address, name) =>
|
|
||||||
{
|
|
||||||
AddOrUpdateDevice(address, name, 0);
|
|
||||||
},
|
|
||||||
(address, name, rssi, bytes) =>
|
(address, name, rssi, bytes) =>
|
||||||
{
|
{
|
||||||
AddOrUpdateDevice(address, name, rssi);
|
AddOrUpdateDevice(address, name, rssi,bytes);
|
||||||
},
|
},
|
||||||
true
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
Invoke(nameof(StopScan), 10f);
|
Invoke(nameof(StopScan), 10f);
|
||||||
@ -635,6 +601,7 @@ namespace Kill.Bluetooth
|
|||||||
// 保存连接的设备信息
|
// 保存连接的设备信息
|
||||||
var device = DiscoveredDevices.Find(d => d.Address.ToUpper() == address.ToUpper());
|
var device = DiscoveredDevices.Find(d => d.Address.ToUpper() == address.ToUpper());
|
||||||
string deviceName = device != null ? device.Name : "Unknown";
|
string deviceName = device != null ? device.Name : "Unknown";
|
||||||
|
ConnectedDeviceMacAddress = device?.GetEffectiveAddress()?.ToUpper();
|
||||||
//SaveLastConnectedDevice(address, deviceName);
|
//SaveLastConnectedDevice(address, deviceName);
|
||||||
|
|
||||||
OnConnected?.Invoke(address);
|
OnConnected?.Invoke(address);
|
||||||
@ -660,6 +627,7 @@ namespace Kill.Bluetooth
|
|||||||
IsConnected = false;
|
IsConnected = false;
|
||||||
string disconnectedAddr = ConnectedDeviceAddress;
|
string disconnectedAddr = ConnectedDeviceAddress;
|
||||||
ConnectedDeviceAddress = null;
|
ConnectedDeviceAddress = null;
|
||||||
|
ConnectedDeviceMacAddress = null;
|
||||||
Log($"设备断开连接: {disconnectAddress}");
|
Log($"设备断开连接: {disconnectAddress}");
|
||||||
OnDisconnected?.Invoke(disconnectAddress);
|
OnDisconnected?.Invoke(disconnectAddress);
|
||||||
|
|
||||||
@ -756,6 +724,7 @@ namespace Kill.Bluetooth
|
|||||||
// 立即清理状态
|
// 立即清理状态
|
||||||
IsConnected = false;
|
IsConnected = false;
|
||||||
ConnectedDeviceAddress = null;
|
ConnectedDeviceAddress = null;
|
||||||
|
ConnectedDeviceMacAddress = null;
|
||||||
OnDisconnected?.Invoke(addressToDisconnect);
|
OnDisconnected?.Invoke(addressToDisconnect);
|
||||||
|
|
||||||
// 延迟清理
|
// 延迟清理
|
||||||
@ -824,6 +793,7 @@ namespace Kill.Bluetooth
|
|||||||
|
|
||||||
IsConnected = false;
|
IsConnected = false;
|
||||||
ConnectedDeviceAddress = null;
|
ConnectedDeviceAddress = null;
|
||||||
|
ConnectedDeviceMacAddress = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消所有Invoke
|
// 取消所有Invoke
|
||||||
@ -903,33 +873,35 @@ namespace Kill.Bluetooth
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加或更新设备到列表
|
/// 添加或更新设备到列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void AddOrUpdateDevice(string address, string name, int rssi)
|
private void AddOrUpdateDevice(string address, string name, int rssi,byte[] bytes)
|
||||||
{
|
{
|
||||||
// 调试日志:显示所有发现的设备(包括无名称的)
|
// 调试日志:显示所有发现的设备(包括无名称的)
|
||||||
// Log($"扫描到设备: Name='{name}', Address={address}, RSSI={rssi}");
|
// Log($"扫描到设备: Name='{name}', Address={address}, RSSI={rssi}");
|
||||||
|
|
||||||
// 查找是否已存在
|
// 从广播数据中解析真实MAC地址(iOS端关键:address是UUID,MAC在bytes里)
|
||||||
var existingDevice = DiscoveredDevices.Find(d => d.Address.ToUpper() == address.ToUpper());
|
string macFromBroadcast = BluetoothDevice.ParseMacFromBytes(bytes);
|
||||||
|
string effectiveAddress = macFromBroadcast ?? address;
|
||||||
|
|
||||||
|
// 查找是否已存在(使用有效地址匹配,避免iOS端UUID变化导致重复添加)
|
||||||
|
var existingDevice = DiscoveredDevices.Find(d => d.GetEffectiveAddress().ToUpper() == effectiveAddress.ToUpper());
|
||||||
if (existingDevice != null)
|
if (existingDevice != null)
|
||||||
{
|
{
|
||||||
// 更新RSSI
|
// 更新RSSI
|
||||||
existingDevice.Rssi = rssi;
|
existingDevice.Rssi = rssi;
|
||||||
// Log($"更新设备信号: {existingDevice.Name} [{address}] RSSI: {rssi}");
|
// Log($"更新设备信号: {existingDevice.Name} [{effectiveAddress}] RSSI: {rssi}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 过滤掉没有名称的设备
|
// 过滤掉没有名称的设备
|
||||||
if (string.IsNullOrEmpty(name) || name == "No Name" || name == "Unknown")
|
if (string.IsNullOrEmpty(name) || name == "No Name" || name == "Unknown")
|
||||||
{
|
{
|
||||||
// Log($"过滤无名称设备: [{address}]");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加新设备
|
// 添加新设备(Address保留原始值用于Connect,MacFromBroadcast由构造函数自动解析)
|
||||||
var newDevice = new BluetoothDevice(address, name, rssi);
|
var newDevice = new BluetoothDevice(address, name, rssi,bytes);
|
||||||
DiscoveredDevices.Add(newDevice);
|
DiscoveredDevices.Add(newDevice);
|
||||||
Log($"发现新设备: {name} [{address}] RSSI: {rssi}");
|
if (aimMac.ToUpper() == effectiveAddress.ToUpper())
|
||||||
if (aimMac.ToUpper() == address.ToUpper())
|
|
||||||
{
|
{
|
||||||
StopScan();
|
StopScan();
|
||||||
|
|
||||||
@ -964,13 +936,13 @@ namespace Kill.Bluetooth
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (IsConnected && mac.ToUpper() == ConnectedDeviceAddress.ToUpper())
|
if (IsConnected && mac.ToUpper() == (ConnectedDeviceMacAddress ?? ConnectedDeviceAddress).ToUpper())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (IsConnected && mac.ToUpper() != ConnectedDeviceAddress.ToUpper())
|
if (IsConnected && mac.ToUpper() != (ConnectedDeviceMacAddress ?? ConnectedDeviceAddress).ToUpper())
|
||||||
{
|
{
|
||||||
Disconnect();
|
Disconnect();
|
||||||
StartScan(10);
|
StartScan(10);
|
||||||
|
|||||||
@ -196,67 +196,7 @@ namespace Kill.Bluetooth
|
|||||||
bool success = response.IsSuccess;
|
bool success = response.IsSuccess;
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
// 检查连接状态,如果断开则等待重连
|
yield return new WaitForSeconds(3);
|
||||||
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);
|
SetState(OTAState.Transferring);
|
||||||
OnStartUpgradeResult?.Invoke(true);
|
OnStartUpgradeResult?.Invoke(true);
|
||||||
callback?.Invoke(true);
|
callback?.Invoke(true);
|
||||||
|
|||||||
@ -14,7 +14,7 @@ namespace Kill.UI.Components
|
|||||||
public void Init(BluetoothDevice bluetoothDevice)
|
public void Init(BluetoothDevice bluetoothDevice)
|
||||||
{
|
{
|
||||||
deviceNameText.text = bluetoothDevice.Name;
|
deviceNameText.text = bluetoothDevice.Name;
|
||||||
deviceAddressText.text = bluetoothDevice.Address;
|
deviceAddressText.text = bluetoothDevice.GetEffectiveAddress();
|
||||||
deviceRssiText.text = bluetoothDevice.Rssi.ToString();
|
deviceRssiText.text = bluetoothDevice.Rssi.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,8 +71,8 @@ namespace Kill.UI.Components
|
|||||||
}
|
}
|
||||||
public void SetPrecent(float p)
|
public void SetPrecent(float p)
|
||||||
{
|
{
|
||||||
int fullP=(int)(p*100);
|
float fullP=p*100;
|
||||||
precent.text=fullP+"%";
|
precent.text=fullP.ToString("f1")+"%";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using Kill.Bluetooth;
|
using Kill.Bluetooth;
|
||||||
using Kill.Core;
|
using Kill.Core;
|
||||||
using Kill.Managers;
|
using Kill.Managers;
|
||||||
@ -40,12 +41,19 @@ public class ConnectDevicePageCtrl : MonoBehaviour
|
|||||||
BluetoothManager.Instance.OnConnectFailed -= OnConnectFailed;
|
BluetoothManager.Instance.OnConnectFailed -= OnConnectFailed;
|
||||||
BluetoothManager.Instance.OnDisconnected -= OnDeviceDisconnected;
|
BluetoothManager.Instance.OnDisconnected -= OnDeviceDisconnected;
|
||||||
}
|
}
|
||||||
|
IEnumerator WaitToScan()
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(1);
|
||||||
|
EnterConnectPage();
|
||||||
|
}
|
||||||
public void EnterConnectPage()
|
public void EnterConnectPage()
|
||||||
{
|
{
|
||||||
OnStopScanClick();
|
|
||||||
if(BluetoothManager.Instance.IsConnected)
|
if(BluetoothManager.Instance.IsConnected)
|
||||||
|
{
|
||||||
BluetoothManager.Instance.Disconnect();
|
BluetoothManager.Instance.Disconnect();
|
||||||
BluetoothManager.Instance.StopScan();
|
StartCoroutine(WaitToScan());
|
||||||
|
}
|
||||||
|
OnStopScanClick();
|
||||||
BluetoothManager.Instance.ChangeAimMac("");
|
BluetoothManager.Instance.ChangeAimMac("");
|
||||||
topBar.SetActive(true);
|
topBar.SetActive(true);
|
||||||
titleText.SetActive(false);
|
titleText.SetActive(false);
|
||||||
@ -273,14 +281,15 @@ public class ConnectDevicePageCtrl : MonoBehaviour
|
|||||||
{
|
{
|
||||||
if(string.IsNullOrEmpty(device.Name))
|
if(string.IsNullOrEmpty(device.Name))
|
||||||
return;
|
return;
|
||||||
|
Debug.Log($"[发现新设备] {device.Name} Address={device.Address} MAC={device.GetEffectiveAddress()} RSSI={device.Rssi} 广播数据(Hex)={BitConverter.ToString(device.info)}");
|
||||||
foreach(var d in DataManager.Instance.OwnedDevices)
|
foreach(var d in DataManager.Instance.OwnedDevices)
|
||||||
{
|
{
|
||||||
if(d.ble_mac==device.Address)
|
if(d.ble_mac==device.GetEffectiveAddress())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foreach(var d in DataManager.Instance.SharedDevices)
|
foreach(var d in DataManager.Instance.SharedDevices)
|
||||||
{
|
{
|
||||||
if(d.ble_mac==device.Address)
|
if(d.ble_mac==device.GetEffectiveAddress())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AddOneDevice(device);
|
AddOneDevice(device);
|
||||||
@ -362,7 +371,7 @@ public class ConnectDevicePageCtrl : MonoBehaviour
|
|||||||
deviceList.Add(device);
|
deviceList.Add(device);
|
||||||
GameObject deviceObject = Instantiate(devicePrefab, deviceListParent.transform);
|
GameObject deviceObject = Instantiate(devicePrefab, deviceListParent.transform);
|
||||||
deviceObject.transform.Find("name").GetComponent<Text>().text=device.Name;
|
deviceObject.transform.Find("name").GetComponent<Text>().text=device.Name;
|
||||||
deviceObject.transform.Find("mac").GetComponent<Text>().text=device.Address;
|
deviceObject.transform.Find("mac").GetComponent<Text>().text=device.GetEffectiveAddress();
|
||||||
deviceObject.SetActive(true);
|
deviceObject.SetActive(true);
|
||||||
deviceObjects.Add(deviceObject);
|
deviceObjects.Add(deviceObject);
|
||||||
int index = deviceObjects.Count-1;
|
int index = deviceObjects.Count-1;
|
||||||
@ -379,8 +388,8 @@ public class ConnectDevicePageCtrl : MonoBehaviour
|
|||||||
if (selectedIndex >= 0 && selectedIndex < deviceList.Count)
|
if (selectedIndex >= 0 && selectedIndex < deviceList.Count)
|
||||||
{
|
{
|
||||||
var device = deviceList[selectedIndex];
|
var device = deviceList[selectedIndex];
|
||||||
Debug.Log("设备mac:"+device.Address);
|
Debug.Log("设备mac:"+device.GetEffectiveAddress());
|
||||||
nowDeviceMac=device.Address;
|
nowDeviceMac=device.GetEffectiveAddress();
|
||||||
BluetoothManager.Instance.Connect(device.Address);
|
BluetoothManager.Instance.Connect(device.Address);
|
||||||
LoadingUI.Show();
|
LoadingUI.Show();
|
||||||
deviceObjects[index].transform.Find("状态").Find("loading").gameObject.SetActive(true);
|
deviceObjects[index].transform.Find("状态").Find("loading").gameObject.SetActive(true);
|
||||||
|
|||||||
@ -385,9 +385,8 @@ namespace Kill.UI.Pages
|
|||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
BluetoothManager.Instance.ChangeAimMac("");
|
BluetoothManager.Instance.ChangeAimMac("");
|
||||||
BLECommunicationManager.Instance.Disconnect();
|
BluetoothManager.Instance.Disconnect();
|
||||||
LoadingUI.Hide();
|
StartCoroutine(BackToHomePage());
|
||||||
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -440,24 +439,23 @@ namespace Kill.UI.Pages
|
|||||||
{
|
{
|
||||||
Loom.QueueOnMainThread(() =>
|
Loom.QueueOnMainThread(() =>
|
||||||
{
|
{
|
||||||
LoadingUI.Hide();
|
|
||||||
if (unregisterSuccess.IsSuccess)
|
if (unregisterSuccess.IsSuccess)
|
||||||
{
|
{
|
||||||
BLECommunicationManager.Instance.Disconnect();
|
BluetoothManager.Instance.Disconnect();
|
||||||
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
|
StartCoroutine(BackToHomePage());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.LogError("取消设备共享成功,但蓝牙用户注销失败");
|
Debug.LogError("取消设备共享成功,但蓝牙用户注销失败");
|
||||||
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
|
StartCoroutine(BackToHomePage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LoadingUI.Hide();
|
StartCoroutine(BackToHomePage());
|
||||||
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (code, msg) =>
|
onError: (code, msg) =>
|
||||||
@ -478,6 +476,12 @@ namespace Kill.UI.Pages
|
|||||||
AboutDevicePage settingPage = Instantiate(aboutDevicePage.gameObject, transform).GetComponent<AboutDevicePage>();
|
AboutDevicePage settingPage = Instantiate(aboutDevicePage.gameObject, transform).GetComponent<AboutDevicePage>();
|
||||||
settingPage.gameObject.SetActive(true);
|
settingPage.gameObject.SetActive(true);
|
||||||
}
|
}
|
||||||
|
public IEnumerator BackToHomePage()
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(2);
|
||||||
|
LoadingUI.Hide();
|
||||||
|
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,22 +93,24 @@ namespace Kill.UI.Pages
|
|||||||
{
|
{
|
||||||
UIManager.Instance.RegisterBackAction(GetComponentInParent<DeviceInfoPage>().Back);
|
UIManager.Instance.RegisterBackAction(GetComponentInParent<DeviceInfoPage>().Back);
|
||||||
Destroy(gameObject);
|
Destroy(gameObject);
|
||||||
|
Screen.sleepTimeout = SleepTimeout.SystemSetting;
|
||||||
}
|
}
|
||||||
public async void OnUpdateButtonClick()
|
public async void OnUpdateButtonClick()
|
||||||
{
|
{
|
||||||
LoadingUI.Show();
|
Screen.sleepTimeout = SleepTimeout.NeverSleep;
|
||||||
|
ToastUI.Show("100294");
|
||||||
|
UpdateLoadingUI.Instance.Show();
|
||||||
string savePath = Application.persistentDataPath + "/ota.bin";
|
string savePath = Application.persistentDataPath + "/ota.bin";
|
||||||
var success= await NetworkCtrl.Instance.DownloadFile(otaData.download_url, savePath, GetDownloadProcess);
|
var success= await NetworkCtrl.Instance.DownloadFile(otaData.download_url, savePath, UpdateLoadingUI.Instance.GetDownloadProcess);
|
||||||
|
UpdateLoadingUI.Instance.Hide();
|
||||||
if(!success.IsSuccess)
|
if(!success.IsSuccess)
|
||||||
{
|
{
|
||||||
LoadingUI.Hide();
|
|
||||||
ToastUI.Show("100224");
|
ToastUI.Show("100224");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string md5=NetworkCtrl.Instance.CalculateMD5(savePath);
|
string md5=NetworkCtrl.Instance.CalculateMD5(savePath);
|
||||||
if(md5!=otaData.md5)
|
if(md5!=otaData.md5)
|
||||||
{
|
{
|
||||||
LoadingUI.Hide();
|
|
||||||
ToastUI.Show("100223");
|
ToastUI.Show("100223");
|
||||||
Debug.LogError("下载的文件MD5校验失败");
|
Debug.LogError("下载的文件MD5校验失败");
|
||||||
File.Delete(savePath);
|
File.Delete(savePath);
|
||||||
@ -117,7 +119,10 @@ namespace Kill.UI.Pages
|
|||||||
// TODO: continue OTA update via BLE
|
// TODO: continue OTA update via BLE
|
||||||
LoadFirmwareFile(savePath);
|
LoadFirmwareFile(savePath);
|
||||||
ToastUI.Show("100225");
|
ToastUI.Show("100225");
|
||||||
|
UpdateLoadingUI.Instance.SetPrecent(0);
|
||||||
|
UpdateLoadingUI.Instance.Show();
|
||||||
uint firmwareVersion = ParseFirmwareVersion(otaData.version);
|
uint firmwareVersion = ParseFirmwareVersion(otaData.version);
|
||||||
|
OTAManager.Instance.OnTransferProgress += OnOTATransferProgress;
|
||||||
StartCoroutine(OTAManager.Instance.PerformFullUpgrade(_selectedFirmwareData, firmwareVersion, (success) =>
|
StartCoroutine(OTAManager.Instance.PerformFullUpgrade(_selectedFirmwareData, firmwareVersion, (success) =>
|
||||||
{
|
{
|
||||||
Loom.QueueOnMainThread(() =>
|
Loom.QueueOnMainThread(() =>
|
||||||
@ -125,20 +130,16 @@ namespace Kill.UI.Pages
|
|||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
ToastUI.Show("100226");
|
ToastUI.Show("100226");
|
||||||
|
DataManager.Instance.selectedDevice.firmware_version=otaData.version;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ToastUI.Show("100227");
|
ToastUI.Show("100227");
|
||||||
}
|
}
|
||||||
LoadingUI.Hide();
|
UpdateLoadingUI.Instance.Hide();
|
||||||
Back();
|
UIManager.Instance.OpenMainPage(UIManager.PageName.loginPage);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
private void GetDownloadProcess(DownloadProgress progress)
|
|
||||||
{
|
|
||||||
Debug.Log($"下载进度: {progress.ProgressPercentage}%");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选中的固件文件数据
|
// 选中的固件文件数据
|
||||||
@ -200,5 +201,13 @@ namespace Kill.UI.Pages
|
|||||||
// 默认返回版本号 1
|
// 默认返回版本号 1
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OTA传输进度回调
|
||||||
|
/// </summary>
|
||||||
|
private void OnOTATransferProgress(int current, int total, int retryCount, int maxRetries)
|
||||||
|
{
|
||||||
|
UpdateLoadingUI.Instance.SetPrecent((float)current/ total);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -537,6 +537,7 @@ namespace Kill.UI.Pages
|
|||||||
|
|
||||||
private void OnLockReceived(DeviceLockControl setting)
|
private void OnLockReceived(DeviceLockControl setting)
|
||||||
{
|
{
|
||||||
|
moreSettingButton.interactable = true;
|
||||||
Debug.Log($"[HomePageCtrl] 锁定状态: {setting.IsLocked}");
|
Debug.Log($"[HomePageCtrl] 锁定状态: {setting.IsLocked}");
|
||||||
pendingUIUpdates.Add(() =>
|
pendingUIUpdates.Add(() =>
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user