diff --git a/app/src/main/java/com/bitchat/android/mesh/BluetoothPacketBroadcaster.kt b/app/src/main/java/com/bitchat/android/mesh/BluetoothPacketBroadcaster.kt index b34742177..b415b1764 100644 --- a/app/src/main/java/com/bitchat/android/mesh/BluetoothPacketBroadcaster.kt +++ b/app/src/main/java/com/bitchat/android/mesh/BluetoothPacketBroadcaster.kt @@ -57,6 +57,17 @@ class BluetoothPacketBroadcaster( nicknameResolver = resolver } + /** + * iOS-compatible padding policy: only pad encrypted messages for BLE transmission + * Announce, message, leave, sync, fragment, and file transfer are sent unpadded over BLE + */ + private fun shouldPadForBLE(type: UByte): Boolean { + return when (MessageType.fromValue(type)) { + MessageType.NOISE_ENCRYPTED, MessageType.NOISE_HANDSHAKE -> true + else -> false + } + } + /** * Debug logging helper - can be easily removed/disabled for production */ @@ -202,7 +213,9 @@ class BluetoothPacketBroadcaster( characteristic: BluetoothGattCharacteristic? ): Boolean { val packet = routed.packet - val data = packet.toBinaryData() ?: return false + // iOS-compatible: Use selective padding policy for BLE + val padForBLE = shouldPadForBLE(packet.type) + val data = packet.toBinaryData(padding = padForBLE) ?: return false val isFile = packet.type == MessageType.FILE_TRANSFER.value if (isFile) { Log.d(TAG, "📤 Broadcasting FILE_TRANSFER: ${packet.payload.size} bytes") @@ -285,7 +298,9 @@ class BluetoothPacketBroadcaster( characteristic: BluetoothGattCharacteristic? ) { val packet = routed.packet - val data = packet.toBinaryData() ?: return + // iOS-compatible: Use selective padding policy for BLE + val padForBLE = shouldPadForBLE(packet.type) + val data = packet.toBinaryData(padding = padForBLE) ?: return val typeName = MessageType.fromValue(packet.type)?.name ?: packet.type.toString() val senderPeerID = routed.peerID ?: packet.senderID.toHexString() val incomingAddr = routed.relayAddress diff --git a/app/src/main/java/com/bitchat/android/protocol/BinaryProtocol.kt b/app/src/main/java/com/bitchat/android/protocol/BinaryProtocol.kt index 2d15b86e4..7f416261b 100644 --- a/app/src/main/java/com/bitchat/android/protocol/BinaryProtocol.kt +++ b/app/src/main/java/com/bitchat/android/protocol/BinaryProtocol.kt @@ -78,8 +78,8 @@ data class BitchatPacket( ttl = ttl ) - fun toBinaryData(): ByteArray? { - return BinaryProtocol.encode(this) + fun toBinaryData(padding: Boolean = true): ByteArray? { + return BinaryProtocol.encode(this, padding = padding) } /** @@ -189,7 +189,7 @@ object BinaryProtocol { } } - fun encode(packet: BitchatPacket): ByteArray? { + fun encode(packet: BitchatPacket, padding: Boolean = true): ByteArray? { try { // Try to compress payload if beneficial var payload = packet.payload @@ -275,11 +275,13 @@ object BinaryProtocol { buffer.rewind() buffer.get(result) - // Apply padding to standard block sizes for traffic analysis resistance - val optimalSize = MessagePadding.optimalBlockSize(result.size) - val paddedData = MessagePadding.pad(result, optimalSize) + // Apply padding if requested (iOS-compatible: selective padding for privacy) + if (padding) { + val optimalSize = MessagePadding.optimalBlockSize(result.size) + return MessagePadding.pad(result, optimalSize) + } - return paddedData + return result } catch (e: Exception) { Log.e("BinaryProtocol", "Error encoding packet type ${packet.type}: ${e.message}")