mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 20:25:21 +00:00
feat: Implement iOS-compatible selective padding for BLE messages (#501)
* feat: Implement iOS-compatible selective padding for BLE messages * regression tests for padding --------- Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package com.bitchat.android.mesh
|
||||
|
||||
import com.bitchat.android.protocol.MessageType
|
||||
|
||||
/**
|
||||
* iOS-compatible BLE padding policy.
|
||||
*
|
||||
* Keep this aligned with iOS BLEOutboundPacketPolicy.padsBLEFrame(for:):
|
||||
* only Noise frames are padded over BLE.
|
||||
*/
|
||||
object BLEPacketPaddingPolicy {
|
||||
fun shouldPadForBLE(type: UByte): Boolean {
|
||||
return when (MessageType.fromValue(type)) {
|
||||
MessageType.NOISE_ENCRYPTED, MessageType.NOISE_HANDSHAKE -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,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 = BLEPacketPaddingPolicy.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")
|
||||
@@ -261,7 +263,9 @@ class BluetoothPacketBroadcaster(
|
||||
characteristic: BluetoothGattCharacteristic?
|
||||
) {
|
||||
val packet = routed.packet
|
||||
val data = packet.toBinaryData() ?: return
|
||||
// iOS-compatible: Use selective padding policy for BLE
|
||||
val padForBLE = BLEPacketPaddingPolicy.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
|
||||
|
||||
@@ -79,8 +79,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)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +198,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
|
||||
@@ -310,11 +310,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}")
|
||||
|
||||
Reference in New Issue
Block a user