diff --git a/lib/ble/ble_winrt.cpp b/lib/ble/ble_winrt.cpp index 8ab74725..a8659594 100644 --- a/lib/ble/ble_winrt.cpp +++ b/lib/ble/ble_winrt.cpp @@ -2,6 +2,7 @@ * Каждая отправка адресована link/subscribedClient; одна незавершённая операция на link. * Слабые ссылки в WinRT handlers и отменяемый posted_task исключают обращения к уничтоженному core. */ #include "ble_backend.h" +#include "ble_identity.h" #include "../u_async.h" #include "../mem.h" #include "../debug_config.h" diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/BleRadio.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/BleRadio.kt index 579cb655..9a98d7ad 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/BleRadio.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/BleRadio.kt @@ -176,8 +176,8 @@ object BleRadio { } override fun onDescriptorWriteRequest(device: BluetoothDevice, requestId: Int, descriptor: BluetoothGattDescriptor, preparedWrite: Boolean, responseNeeded: Boolean, offset: Int, value: ByteArray) = post { - val expected = if (descriptor.characteristic.uuid == txUuid) BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE - else BluetoothGattDescriptor.ENABLE_INDICATION_VALUE + val expected = if (descriptor.characteristic.uuid == inviteUuid) BluetoothGattDescriptor.ENABLE_INDICATION_VALUE + else BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE val valid = incoming && descriptor.uuid == cccUuid && descriptor.characteristic.uuid in listOf(txUuid, inviteUuid, ackUuid) && !preparedWrite && offset == 0 && value.contentEquals(expected) var link = links.values.find { !it.outgoing && it.device.address == device.address } @@ -207,7 +207,7 @@ object BleRadio { preparedWrite: Boolean, responseNeeded: Boolean, offset: Int, value: ByteArray) = post { val link = links.values.find { !it.outgoing && it.device.address == device.address } val valid = link != null && link.opened && characteristic.uuid in listOf(rxUuid, inviteUuid, ackUuid) && - !preparedWrite && responseNeeded == (characteristic.uuid != rxUuid) && offset == 0 + !preparedWrite && responseNeeded == (characteristic.uuid == inviteUuid) && offset == 0 if (valid) emit(3, link!!.token, arg = wireChannel(characteristic.uuid), data = value.copyOf()) if (responseNeeded) respond(device, requestId, if (valid) 0 else BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED) if (!valid) log("WARN", "Write rejected address=${device.address} characteristic=${characteristic.uuid} " + @@ -253,7 +253,7 @@ object BleRadio { } service.addCharacteristic(invite) ack = BluetoothGattCharacteristic(ackUuid, - BluetoothGattCharacteristic.PROPERTY_WRITE or BluetoothGattCharacteristic.PROPERTY_INDICATE, + BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_WRITE).apply { addDescriptor(BluetoothGattDescriptor(cccUuid, BluetoothGattDescriptor.PERMISSION_WRITE)) } @@ -405,8 +405,10 @@ object BleRadio { if (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY == 0) { close(link, "TX lacks Notification properties=${characteristic.properties}"); return@dispatch } - val controlProperties = BluetoothGattCharacteristic.PROPERTY_WRITE or BluetoothGattCharacteristic.PROPERTY_INDICATE for (control in listOf(checkNotNull(link.invite), checkNotNull(link.ack))) { + val controlProperties = if (control.uuid == inviteUuid) + BluetoothGattCharacteristic.PROPERTY_WRITE or BluetoothGattCharacteristic.PROPERTY_INDICATE + else BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or BluetoothGattCharacteristic.PROPERTY_NOTIFY if (control.properties and controlProperties != controlProperties || control.getDescriptor(cccUuid) == null) { close(link, "Control characteristic invalid uuid=${control.uuid} properties=${control.properties}"); return@dispatch } @@ -414,7 +416,7 @@ object BleRadio { if (!gatt.setCharacteristicNotification(characteristic, true)) { close(link, "DATA local subscription refused characteristic=${characteristic.uuid}"); return@dispatch } - log("INFO", "Client DATA configured link=$token write=without_response receive=notification mtu=${link.mtu}") + log("INFO", "Client DATA/ACK configured link=$token write=without_response receive=notification mtu=${link.mtu}") val result = if (Build.VERSION.SDK_INT >= 33) gatt.writeDescriptor(ccc, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE) else { ccc.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE; if (gatt.writeDescriptor(ccc)) 0 else -1 } if (result != 0) close(link, "DATA CCC write refused status=$result") @@ -427,8 +429,10 @@ object BleRadio { if (ccc == null || !gatt.setCharacteristicNotification(characteristic, true)) { close(link, "control subscription unavailable after=${descriptor.characteristic.uuid}"); return@dispatch } - val result = if (Build.VERSION.SDK_INT >= 33) gatt.writeDescriptor(ccc, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE) - else { ccc.value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE; if (gatt.writeDescriptor(ccc)) 0 else -1 } + val value = if (characteristic?.uuid == inviteUuid) BluetoothGattDescriptor.ENABLE_INDICATION_VALUE + else BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE + val result = if (Build.VERSION.SDK_INT >= 33) gatt.writeDescriptor(ccc, value) + else { ccc.value = value; if (gatt.writeDescriptor(ccc)) 0 else -1 } if (result != 0) close(link, "Control CCC write refused uuid=${characteristic?.uuid} status=$result") } else if (descriptor.characteristic.uuid == ackUuid) { link.opened = true; emit(2, token, link.mtu, address) } else close(link, "unexpected CCC completion") @@ -458,7 +462,7 @@ object BleRadio { val bytes = checkNotNull(link.pending) val status = if (link.outgoing) { val characteristic = checkNotNull(when (link.channel) { 0 -> link.rx; 1 -> link.invite; else -> link.ack }) - val type = if (link.channel != 0) BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT + val type = if (link.channel == 1) BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT else BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE if (Build.VERSION.SDK_INT >= 33) link.gatt!!.writeCharacteristic(characteristic, bytes, type) else { @@ -467,10 +471,10 @@ object BleRadio { } } else { val characteristic = checkNotNull(when (link.channel) { 0 -> tx; 1 -> invite; else -> ack }) - if (Build.VERSION.SDK_INT >= 33) server!!.notifyCharacteristicChanged(link.device, characteristic, link.channel != 0, bytes) + if (Build.VERSION.SDK_INT >= 33) server!!.notifyCharacteristicChanged(link.device, characteristic, link.channel == 1, bytes) else { characteristic.value = bytes - if (server!!.notifyCharacteristicChanged(link.device, characteristic, link.channel != 0)) 0 else -1 + if (server!!.notifyCharacteristicChanged(link.device, characteristic, link.channel == 1)) 0 else -1 } } if (status == 0) {