|
|
|
@ -979,43 +979,54 @@ object BleService { |
|
|
|
val callAudioSvc = g.getService(BleConst.CALL_AUDIO_SERVICE_UUID) |
|
|
|
callWriteChar = callAudioSvc?.getCharacteristic(BleConst.CALL_WRITE_AUDIO_CHAR_UUID) |
|
|
|
callAudioChar = callAudioSvc?.getCharacteristic(BleConst.CALL_RECEIVE_AUDIO_CHAR_UUID) |
|
|
|
if (callWriteChar == null) { |
|
|
|
Log.e(TAG, "未找到通话音频主服务所需特征") |
|
|
|
updateConnectionState(BleConst.STATE_ERROR) |
|
|
|
return |
|
|
|
// 通话音频写特征仅用于发送翻译音频,缺失只影响发送能力,不再中断整个服务发现流程 |
|
|
|
if (callWriteChar != null) { |
|
|
|
Log.d(TAG, "找到通话音频写特征") |
|
|
|
callWriteChar?.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE |
|
|
|
} else { |
|
|
|
Log.w(TAG, "未找到通话音频写特征,通话音频发送不可用") |
|
|
|
} |
|
|
|
Log.d(TAG, "找到通话音频服务所需特征") |
|
|
|
startBytesStatistics() |
|
|
|
writeChar?.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE |
|
|
|
callWriteChar?.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE |
|
|
|
// 串行注册通知:等待上一个通道成功后再注册下一个 |
|
|
|
|
|
|
|
// 获取唤醒词OTA主服务特征(其通知通道与下面几路一起串行注册) |
|
|
|
val wakeupVoicesSvc = g.getService(BleConst.WakeupVoices_PRIMARY_SERVICE_UUID) |
|
|
|
wakeupVoicesNotifyChar = wakeupVoicesSvc?.getCharacteristic(BleConst.WakeupVoices_NOTIFY_UUID) |
|
|
|
wakeupVoicesWriteChar = wakeupVoicesSvc?.getCharacteristic(BleConst.WakeupVoices_WRITE_UUID) |
|
|
|
wakeupVoicesWriteChar?.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE |
|
|
|
|
|
|
|
// 串行注册所有通知通道:逐个写入 CCCD,等上一个 onDescriptorWrite 回调后再写下一个。 |
|
|
|
// Android 同一时刻只允许一个 GATT 操作,连发 writeDescriptor 会相互覆盖/失败, |
|
|
|
// 必须经由 notificationSetupQueue + processNextNotificationDescriptor 串行驱动。 |
|
|
|
notificationSetupQueue.clear() |
|
|
|
isDescriptorWriteInProgress = false |
|
|
|
notificationTargetsTotal = 0 |
|
|
|
notificationTargetsSucceeded = 0 |
|
|
|
if (callAudioChar != null && audioChar != null) { |
|
|
|
setupNotifications(g, callAudioChar) |
|
|
|
setupNotifications(g, audioChar) |
|
|
|
Log.i(TAG, "通话音频服务特征找到并设置通知") |
|
|
|
Handler(Looper.getMainLooper()).postDelayed({ |
|
|
|
getDeviceWakeupVersion() |
|
|
|
}, 1000) // 延迟3秒再请求版本,确保通知描述符写入完成 |
|
|
|
|
|
|
|
// 各特征独立判空入队,互不影响:某一路缺失只跳过该路,其余照常注册 |
|
|
|
val notifyTargets = listOf( |
|
|
|
"通话接收音频" to callAudioChar, |
|
|
|
"AI音频" to audioChar, |
|
|
|
"命令通知" to notifyChar, |
|
|
|
"唤醒词OTA通知" to wakeupVoicesNotifyChar |
|
|
|
) |
|
|
|
for ((name, ch) in notifyTargets) { |
|
|
|
if (ch != null) { |
|
|
|
notificationSetupQueue.addLast(ch) |
|
|
|
} else { |
|
|
|
Log.w(TAG, "通话音频服务特征未完整找到") |
|
|
|
Log.w(TAG, "未找到${name}特征,跳过其通知注册") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
setupNotifications(g, notifyChar) |
|
|
|
|
|
|
|
// 获取唤醒词OTA主服务特征 |
|
|
|
val wakeupVoicesSvc = g.getService(BleConst.WakeupVoices_PRIMARY_SERVICE_UUID) |
|
|
|
wakeupVoicesNotifyChar = wakeupVoicesSvc?.getCharacteristic(BleConst.WakeupVoices_NOTIFY_UUID) |
|
|
|
wakeupVoicesWriteChar = wakeupVoicesSvc?.getCharacteristic(BleConst.WakeupVoices_WRITE_UUID) |
|
|
|
if (wakeupVoicesNotifyChar != null && wakeupVoicesWriteChar != null) { |
|
|
|
wakeupVoicesWriteChar?.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE |
|
|
|
setupWakeupVoicesNotifications(g, wakeupVoicesNotifyChar) |
|
|
|
Log.i(TAG, "liwei------- 唤醒词OTA服务特征已找到") |
|
|
|
}else{ |
|
|
|
Log.w(TAG, "liwei------- 唤醒词OTA服务特征未找到") |
|
|
|
notificationTargetsTotal = notificationSetupQueue.size |
|
|
|
if (notificationTargetsTotal > 0) { |
|
|
|
Log.i(TAG, "开始串行注册 $notificationTargetsTotal 路通知通道") |
|
|
|
processNextNotificationDescriptor(g) |
|
|
|
// 延迟请求唤醒词版本,确保命令通道通知描述符已写入完成 |
|
|
|
Handler(Looper.getMainLooper()).postDelayed({ |
|
|
|
getDeviceWakeupVersion() |
|
|
|
}, 1000) |
|
|
|
} else { |
|
|
|
Log.w(TAG, "没有可注册通知的特征") |
|
|
|
} |
|
|
|
// 在服务发现完成后,请求最大MTU |
|
|
|
//requestMaxMtu(g) |
|
|
|
|