Merge branch 'main' into fix/android-ios-fragmentation-compatibility

This commit is contained in:
callebtc
2025-07-13 21:25:11 +02:00
committed by GitHub
68 changed files with 2102 additions and 969 deletions
@@ -5,6 +5,7 @@ import android.util.Log
import com.bitchat.android.crypto.EncryptionService
import com.bitchat.android.crypto.MessagePadding
import com.bitchat.android.model.BitchatMessage
import com.bitchat.android.model.RoutedPacket
import com.bitchat.android.model.DeliveryAck
import com.bitchat.android.model.ReadReceipt
import com.bitchat.android.protocol.BitchatPacket
@@ -47,6 +48,9 @@ class BluetoothMeshService(private val context: Context) {
internal val connectionManager = BluetoothConnectionManager(context, myPeerID, fragmentManager) // Made internal for access
private val packetProcessor = PacketProcessor(myPeerID)
// Service state management
private var isActive = false
// Delegate for message callbacks (maintains same interface)
var delegate: BluetoothMeshDelegate? = null
@@ -66,10 +70,10 @@ class BluetoothMeshService(private val context: Context) {
while (isActive) {
try {
delay(10000) // 10 seconds
val debugInfo = getDebugStatus()
Log.d(TAG, "=== PERIODIC DEBUG STATUS ===")
Log.d(TAG, debugInfo)
Log.d(TAG, "=== END DEBUG STATUS ===")
if (isActive) { // Double-check before logging
val debugInfo = getDebugStatus()
Log.d(TAG, "=== PERIODIC DEBUG STATUS ===\n$debugInfo\n=== END DEBUG STATUS ===")
}
} catch (e: Exception) {
Log.e(TAG, "Error in periodic debug logging: ${e.message}")
}
@@ -98,7 +102,14 @@ class BluetoothMeshService(private val context: Context) {
// SecurityManager delegate for key exchange notifications
securityManager.delegate = object : SecurityManagerDelegate {
override fun onKeyExchangeCompleted(peerID: String) {
override fun onKeyExchangeCompleted(peerID: String, peerPublicKeyData: ByteArray, receivedAddress: String?) {
// Notify delegate about key exchange completion so it can register peer fingerprint
delegate?.registerPeerPublicKey(peerID, peerPublicKeyData)
receivedAddress?.let { address ->
connectionManager.addressPeerMap[address] = peerID
}
// Send announcement and cached messages after key exchange
serviceScope.launch {
delay(100)
@@ -121,7 +132,7 @@ class BluetoothMeshService(private val context: Context) {
}
override fun sendPacket(packet: BitchatPacket) {
connectionManager.broadcastPacket(packet)
connectionManager.broadcastPacket(RoutedPacket(packet))
}
}
@@ -154,11 +165,11 @@ class BluetoothMeshService(private val context: Context) {
// Packet operations
override fun sendPacket(packet: BitchatPacket) {
connectionManager.broadcastPacket(packet)
connectionManager.broadcastPacket(RoutedPacket(packet))
}
override fun relayPacket(packet: BitchatPacket) {
connectionManager.broadcastPacket(packet)
override fun relayPacket(routed: RoutedPacket) {
connectionManager.broadcastPacket(routed)
}
override fun getBroadcastRecipient(): ByteArray {
@@ -215,32 +226,32 @@ class BluetoothMeshService(private val context: Context) {
peerManager.updatePeerLastSeen(peerID)
}
override fun handleKeyExchange(packet: BitchatPacket, peerID: String): Boolean {
return runBlocking { securityManager.handleKeyExchange(packet, peerID) }
override fun handleKeyExchange(routed: RoutedPacket): Boolean {
return runBlocking { securityManager.handleKeyExchange(routed) }
}
override fun handleAnnounce(packet: BitchatPacket, peerID: String) {
serviceScope.launch { messageHandler.handleAnnounce(packet, peerID) }
override fun handleAnnounce(routed: RoutedPacket) {
serviceScope.launch { messageHandler.handleAnnounce(routed) }
}
override fun handleMessage(packet: BitchatPacket, peerID: String) {
serviceScope.launch { messageHandler.handleMessage(packet, peerID) }
override fun handleMessage(routed: RoutedPacket) {
serviceScope.launch { messageHandler.handleMessage(routed) }
}
override fun handleLeave(packet: BitchatPacket, peerID: String) {
serviceScope.launch { messageHandler.handleLeave(packet, peerID) }
override fun handleLeave(routed: RoutedPacket) {
serviceScope.launch { messageHandler.handleLeave(routed) }
}
override fun handleFragment(packet: BitchatPacket): BitchatPacket? {
return fragmentManager.handleFragment(packet)
}
override fun handleDeliveryAck(packet: BitchatPacket, peerID: String) {
serviceScope.launch { messageHandler.handleDeliveryAck(packet, peerID) }
override fun handleDeliveryAck(routed: RoutedPacket) {
serviceScope.launch { messageHandler.handleDeliveryAck(routed) }
}
override fun handleReadReceipt(packet: BitchatPacket, peerID: String) {
serviceScope.launch { messageHandler.handleReadReceipt(packet, peerID) }
override fun handleReadReceipt(routed: RoutedPacket) {
serviceScope.launch { messageHandler.handleReadReceipt(routed) }
}
override fun sendAnnouncementToPeer(peerID: String) {
@@ -251,15 +262,15 @@ class BluetoothMeshService(private val context: Context) {
storeForwardManager.sendCachedMessages(peerID)
}
override fun relayPacket(packet: BitchatPacket) {
connectionManager.broadcastPacket(packet)
override fun relayPacket(routed: RoutedPacket) {
connectionManager.broadcastPacket(routed)
}
}
// BluetoothConnectionManager delegates
connectionManager.delegate = object : BluetoothConnectionManagerDelegate {
override fun onPacketReceived(packet: BitchatPacket, peerID: String, device: android.bluetooth.BluetoothDevice?) {
packetProcessor.processPacket(packet, peerID)
packetProcessor.processPacket(RoutedPacket(packet, peerID, device?.address))
}
override fun onDeviceConnected(device: android.bluetooth.BluetoothDevice) {
@@ -276,11 +287,16 @@ class BluetoothMeshService(private val context: Context) {
* Start the mesh service
*/
fun startServices() {
// Prevent double starts (defensive programming)
if (isActive) {
Log.w(TAG, "Mesh service already active, ignoring duplicate start request")
return
}
Log.i(TAG, "Starting Bluetooth mesh service with peer ID: $myPeerID")
if (connectionManager.startServices()) {
Log.i(TAG, "Bluetooth services started successfully")
isActive = true
// Send initial announcements after services are ready
serviceScope.launch {
delay(1000)
@@ -295,7 +311,13 @@ class BluetoothMeshService(private val context: Context) {
* Stop all mesh services
*/
fun stopServices() {
if (!isActive) {
Log.w(TAG, "Mesh service not active, ignoring stop request")
return
}
Log.i(TAG, "Stopping Bluetooth mesh service")
isActive = false
// Send leave announcement
sendLeaveAnnouncement()
@@ -351,7 +373,7 @@ class BluetoothMeshService(private val context: Context) {
// Send with random delay and retry for reliability
// delay(Random.nextLong(50, 500))
connectionManager.broadcastPacket(packet)
connectionManager.broadcastPacket(RoutedPacket(packet))
}
}
}
@@ -404,7 +426,7 @@ class BluetoothMeshService(private val context: Context) {
// Send with delay
delay(Random.nextLong(50, 500))
connectionManager.broadcastPacket(packet)
connectionManager.broadcastPacket(RoutedPacket(packet))
}
} catch (e: Exception) {
@@ -430,13 +452,13 @@ class BluetoothMeshService(private val context: Context) {
// Send multiple times for reliability
delay(Random.nextLong(0, 500))
connectionManager.broadcastPacket(announcePacket)
connectionManager.broadcastPacket(RoutedPacket(announcePacket))
delay(500 + Random.nextLong(0, 500))
connectionManager.broadcastPacket(announcePacket)
connectionManager.broadcastPacket(RoutedPacket(announcePacket))
delay(1000 + Random.nextLong(0, 500))
connectionManager.broadcastPacket(announcePacket)
connectionManager.broadcastPacket(RoutedPacket(announcePacket))
}
}
@@ -454,7 +476,7 @@ class BluetoothMeshService(private val context: Context) {
payload = nickname.toByteArray()
)
connectionManager.broadcastPacket(packet)
connectionManager.broadcastPacket(RoutedPacket(packet))
peerManager.markPeerAsAnnouncedTo(peerID)
}
@@ -470,7 +492,7 @@ class BluetoothMeshService(private val context: Context) {
payload = publicKeyData
)
connectionManager.broadcastPacket(packet)
connectionManager.broadcastPacket(RoutedPacket(packet))
Log.d(TAG, "Sent key exchange")
}
@@ -486,7 +508,7 @@ class BluetoothMeshService(private val context: Context) {
payload = nickname.toByteArray()
)
connectionManager.broadcastPacket(packet)
connectionManager.broadcastPacket(RoutedPacket(packet))
}
/**
@@ -547,4 +569,5 @@ interface BluetoothMeshDelegate {
fun decryptChannelMessage(encryptedContent: ByteArray, channel: String): String?
fun getNickname(): String?
fun isFavorite(peerID: String): Boolean
fun registerPeerPublicKey(peerID: String, publicKeyData: ByteArray)
}