mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-24 22:25:19 +00:00
Fix: Unicast source-routed packets at origin instead of broadcasting
This commit is contained in:
@@ -37,7 +37,7 @@ class BluetoothConnectionManager(
|
||||
// Component managers
|
||||
private val permissionManager = BluetoothPermissionManager(context)
|
||||
private val connectionTracker = BluetoothConnectionTracker(connectionScope, powerManager)
|
||||
private val packetBroadcaster = BluetoothPacketBroadcaster(connectionScope, connectionTracker, fragmentManager)
|
||||
private val packetBroadcaster = BluetoothPacketBroadcaster(connectionScope, connectionTracker, fragmentManager, myPeerID)
|
||||
|
||||
// Delegate for component managers to call back to main manager
|
||||
private val componentDelegate = object : BluetoothConnectionManagerDelegate {
|
||||
|
||||
@@ -42,7 +42,8 @@ import kotlinx.coroutines.channels.actor
|
||||
class BluetoothPacketBroadcaster(
|
||||
private val connectionScope: CoroutineScope,
|
||||
private val connectionTracker: BluetoothConnectionTracker,
|
||||
private val fragmentManager: FragmentManager?
|
||||
private val fragmentManager: FragmentManager?,
|
||||
private val myPeerID: String
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -350,6 +351,47 @@ class BluetoothPacketBroadcaster(
|
||||
val route = packet.route
|
||||
val routeInfo = if (!route.isNullOrEmpty()) "routed: ${route.size} hops" else null
|
||||
|
||||
// Source Routing for Originating Packets
|
||||
// If we are the sender and a source route is defined, we must send ONLY to the first hop.
|
||||
if (packet.senderID.toHexString() == myPeerID && !packet.route.isNullOrEmpty()) {
|
||||
val firstHop = packet.route!![0].toHexString()
|
||||
Log.d(TAG, "Source Routing: Packet has explicit route, attempting to send to first hop: $firstHop")
|
||||
|
||||
var sent = false
|
||||
|
||||
// Try to find first hop in server connections (subscribedDevices)
|
||||
val serverTarget = connectionTracker.getSubscribedDevices()
|
||||
.firstOrNull { connectionTracker.addressPeerMap[it.address] == firstHop }
|
||||
|
||||
if (serverTarget != null) {
|
||||
Log.d(TAG, "Source Routing: sending directly to first hop (server conn) $firstHop: ${serverTarget.address}")
|
||||
if (notifyDevice(serverTarget, data, gattServer, characteristic)) {
|
||||
val toPeer = connectionTracker.addressPeerMap[serverTarget.address]
|
||||
logPacketRelay(typeName, senderPeerID, senderNick, incomingPeer, incomingAddr, toPeer, serverTarget.address, packet.ttl, packet.version, routeInfo)
|
||||
sent = true
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find first hop in client connections if not sent yet
|
||||
if (!sent) {
|
||||
val clientTarget = connectionTracker.getConnectedDevices().values
|
||||
.firstOrNull { connectionTracker.addressPeerMap[it.device.address] == firstHop }
|
||||
|
||||
if (clientTarget != null) {
|
||||
Log.d(TAG, "Source Routing: sending directly to first hop (client conn) $firstHop: ${clientTarget.device.address}")
|
||||
if (writeToDeviceConn(clientTarget, data)) {
|
||||
val toPeer = connectionTracker.addressPeerMap[clientTarget.device.address]
|
||||
logPacketRelay(typeName, senderPeerID, senderNick, incomingPeer, incomingAddr, toPeer, clientTarget.device.address, packet.ttl, packet.version, routeInfo)
|
||||
sent = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sent) return
|
||||
|
||||
Log.w(TAG, "Source Routing: First hop $firstHop not connected. Falling back to standard broadcast logic.")
|
||||
}
|
||||
|
||||
if (packet.recipientID != SpecialRecipients.BROADCAST) {
|
||||
val recipientID = packet.recipientID?.let {
|
||||
String(it).replace("\u0000", "").trim()
|
||||
|
||||
Reference in New Issue
Block a user