mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-24 23:45:19 +00:00
avoid duplicate conenctions to same peer, may cause infinite reconnections, not tested yet
This commit is contained in:
@@ -302,7 +302,23 @@ class BluetoothConnectionManager(
|
|||||||
* Public: connect/disconnect helpers for debug UI
|
* Public: connect/disconnect helpers for debug UI
|
||||||
*/
|
*/
|
||||||
fun connectToAddress(address: String): Boolean = clientManager.connectToAddress(address)
|
fun connectToAddress(address: String): Boolean = clientManager.connectToAddress(address)
|
||||||
fun disconnectAddress(address: String) { connectionTracker.disconnectDevice(address) }
|
fun disconnectAddress(address: String) {
|
||||||
|
connectionScope.launch {
|
||||||
|
try {
|
||||||
|
val dc = connectionTracker.getDeviceConnection(address)
|
||||||
|
if (dc != null) {
|
||||||
|
if (dc.gatt != null) {
|
||||||
|
try { dc.gatt.disconnect() } catch (_: Exception) { }
|
||||||
|
} else {
|
||||||
|
// Try canceling server-side connection if present
|
||||||
|
try { serverManager.getGattServer()?.cancelConnection(dc.device) } catch (_: Exception) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_: Exception) { }
|
||||||
|
// Cleanup tracking regardless
|
||||||
|
connectionTracker.cleanupDeviceConnection(address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Optionally disconnect all connections (server and client)
|
// Optionally disconnect all connections (server and client)
|
||||||
|
|||||||
@@ -124,6 +124,23 @@ class BluetoothConnectionTracker(
|
|||||||
fun getSubscribedDevices(): List<BluetoothDevice> {
|
fun getSubscribedDevices(): List<BluetoothDevice> {
|
||||||
return subscribedDevices.toList()
|
return subscribedDevices.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given peer already has an active direct connection.
|
||||||
|
*/
|
||||||
|
fun isPeerDirectlyConnected(peerID: String): Boolean {
|
||||||
|
val address = getConnectedAddressForPeer(peerID)
|
||||||
|
return address != null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the connected device address for a peer, if currently connected.
|
||||||
|
*/
|
||||||
|
fun getConnectedAddressForPeer(peerID: String): String? {
|
||||||
|
// Find any address mapped to this peer that is still connected
|
||||||
|
val address = addressPeerMap.entries.firstOrNull { it.value == peerID }?.key
|
||||||
|
return address?.takeIf { connectedDevices.containsKey(it) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current RSSI for a device address
|
* Get current RSSI for a device address
|
||||||
|
|||||||
@@ -408,18 +408,28 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
val deviceAddress = routed.relayAddress
|
val deviceAddress = routed.relayAddress
|
||||||
val pid = routed.peerID
|
val pid = routed.peerID
|
||||||
if (deviceAddress != null && pid != null) {
|
if (deviceAddress != null && pid != null) {
|
||||||
// First ANNOUNCE over a device connection defines a direct neighbor.
|
// Only process on first ANNOUNCE seen for this device connection
|
||||||
if (!connectionManager.hasSeenFirstAnnounce(deviceAddress)) {
|
if (!connectionManager.hasSeenFirstAnnounce(deviceAddress)) {
|
||||||
// Bind or rebind this device address to the announcing peer
|
// If we're already directly connected to this peer via another address, drop the new one.
|
||||||
connectionManager.addressPeerMap[deviceAddress] = pid
|
val existingAddress = connectionManager.addressPeerMap
|
||||||
connectionManager.noteAnnounceReceived(deviceAddress)
|
.entries.firstOrNull { it.value == pid }?.key
|
||||||
Log.d(TAG, "Mapped device $deviceAddress to peer $pid on FIRST-ANNOUNCE for this connection")
|
|
||||||
|
|
||||||
// Mark as directly connected (upgrades from routed if needed)
|
val existingConnected = existingAddress != null &&
|
||||||
try { peerManager.setDirectConnection(pid, true) } catch (_: Exception) { }
|
connectionManager.isClientConnection(existingAddress!!) != null
|
||||||
|
|
||||||
// Initial sync for this newly direct peer
|
if (existingAddress != null && existingAddress != deviceAddress && existingConnected) {
|
||||||
try { gossipSyncManager.scheduleInitialSyncToPeer(pid, 1_000) } catch (_: Exception) { }
|
Log.i(TAG, "Peer $pid already connected via $existingAddress; dropping new connection $deviceAddress")
|
||||||
|
// Disconnect the newer duplicate connection
|
||||||
|
connectionManager.disconnectAddress(deviceAddress)
|
||||||
|
} else {
|
||||||
|
// Bind this device address to peer and mark direct
|
||||||
|
connectionManager.addressPeerMap[deviceAddress] = pid
|
||||||
|
connectionManager.noteAnnounceReceived(deviceAddress)
|
||||||
|
Log.d(TAG, "Mapped device $deviceAddress to peer $pid on FIRST-ANNOUNCE for this connection")
|
||||||
|
|
||||||
|
try { peerManager.setDirectConnection(pid, true) } catch (_: Exception) { }
|
||||||
|
try { gossipSyncManager.scheduleInitialSyncToPeer(pid, 1_000) } catch (_: Exception) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Track for sync
|
// Track for sync
|
||||||
|
|||||||
Reference in New Issue
Block a user