mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-26 07:05:20 +00:00
Fix Wi-Fi Aware connectivity and UI integration post-merge
- Replace bindProcessToNetwork with bindSocket for VPN compatibility. - Implement Scoped IPv6 address resolution (aware0) for mesh routing. - Bridge Wi-Fi Aware incoming messages to AppStateStore for UI visibility. - Fix syntax errors and variable name conflicts in Debug UI.
This commit is contained in:
@@ -170,6 +170,13 @@ class MainActivity : OrientationAwareActivity() {
|
|||||||
if (running && svc != null) {
|
if (running && svc != null) {
|
||||||
svc.delegate = object : com.bitchat.android.wifiaware.WifiAwareMeshDelegate {
|
svc.delegate = object : com.bitchat.android.wifiaware.WifiAwareMeshDelegate {
|
||||||
override fun didReceiveMessage(message: com.bitchat.android.model.BitchatMessage) {
|
override fun didReceiveMessage(message: com.bitchat.android.model.BitchatMessage) {
|
||||||
|
if (message.isPrivate) {
|
||||||
|
message.senderPeerID?.let { pid -> com.bitchat.android.services.AppStateStore.addPrivateMessage(pid, message) }
|
||||||
|
} else if (message.channel != null) {
|
||||||
|
com.bitchat.android.services.AppStateStore.addChannelMessage(message.channel, message)
|
||||||
|
} else {
|
||||||
|
com.bitchat.android.services.AppStateStore.addPublicMessage(message)
|
||||||
|
}
|
||||||
chatViewModel.didReceiveMessage(message)
|
chatViewModel.didReceiveMessage(message)
|
||||||
}
|
}
|
||||||
override fun didUpdatePeerList(peers: List<String>) {
|
override fun didUpdatePeerList(peers: List<String>) {
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ class DebugSettingsManager private constructor() {
|
|||||||
private val _packetRelayEnabled = MutableStateFlow(true)
|
private val _packetRelayEnabled = MutableStateFlow(true)
|
||||||
val packetRelayEnabled: StateFlow<Boolean> = _packetRelayEnabled.asStateFlow()
|
val packetRelayEnabled: StateFlow<Boolean> = _packetRelayEnabled.asStateFlow()
|
||||||
|
|
||||||
private val _packetRelayEnabled = MutableStateFlow(true)
|
|
||||||
val packetRelayEnabled: StateFlow<Boolean> = _packetRelayEnabled.asStateFlow()
|
|
||||||
|
|
||||||
// Master transport toggles
|
// Master transport toggles
|
||||||
private val _bleEnabled = MutableStateFlow(true)
|
private val _bleEnabled = MutableStateFlow(true)
|
||||||
val bleEnabled: StateFlow<Boolean> = _bleEnabled.asStateFlow()
|
val bleEnabled: StateFlow<Boolean> = _bleEnabled.asStateFlow()
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ fun DebugSettingsSheet(
|
|||||||
val verboseLogging by manager.verboseLoggingEnabled.collectAsState()
|
val verboseLogging by manager.verboseLoggingEnabled.collectAsState()
|
||||||
val gattServerEnabled by manager.gattServerEnabled.collectAsState()
|
val gattServerEnabled by manager.gattServerEnabled.collectAsState()
|
||||||
val gattClientEnabled by manager.gattClientEnabled.collectAsState()
|
val gattClientEnabled by manager.gattClientEnabled.collectAsState()
|
||||||
val packetRelayEnabled by manager.packetRelayEnabled.collectAsState()
|
val packetRelayed by manager.packetRelayEnabled.collectAsState()
|
||||||
val maxOverall by manager.maxConnectionsOverall.collectAsState()
|
val maxOverall by manager.maxConnectionsOverall.collectAsState()
|
||||||
val maxServer by manager.maxServerConnections.collectAsState()
|
val maxServer by manager.maxServerConnections.collectAsState()
|
||||||
val maxClient by manager.maxClientConnections.collectAsState()
|
val maxClient by manager.maxClientConnections.collectAsState()
|
||||||
@@ -280,7 +280,7 @@ fun DebugSettingsSheet(
|
|||||||
Icon(Icons.Filled.PowerSettingsNew, contentDescription = null, tint = Color(0xFFFF9500))
|
Icon(Icons.Filled.PowerSettingsNew, contentDescription = null, tint = Color(0xFFFF9500))
|
||||||
Text(stringResource(R.string.debug_packet_relay), fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
|
Text(stringResource(R.string.debug_packet_relay), fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
|
||||||
Spacer(Modifier.weight(1f))
|
Spacer(Modifier.weight(1f))
|
||||||
Switch(checked = packetRelayEnabled, onCheckedChange = { manager.setPacketRelayEnabled(it) })
|
Switch(checked = packetRelayed, onCheckedChange = { manager.setPacketRelayEnabled(it) })
|
||||||
}
|
}
|
||||||
// Removed aggregate labels; we will show per-direction compact labels below titles
|
// Removed aggregate labels; we will show per-direction compact labels below titles
|
||||||
// Toggle: overall vs per-connection vs per-peer
|
// Toggle: overall vs per-connection vs per-peer
|
||||||
|
|||||||
@@ -619,7 +619,7 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
}
|
}
|
||||||
override fun onLost(network: Network) {
|
override fun onLost(network: Network) {
|
||||||
networkCallbacks.remove(peerId)
|
networkCallbacks.remove(peerId)
|
||||||
Log.d(TAG, "SERVER: network lost for \${peerId.take(8)}…")
|
Log.d(TAG, "SERVER: network lost for ${peerId.take(8)}…")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,11 +656,13 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
) {
|
) {
|
||||||
// TCP keep-alive pings
|
// TCP keep-alive pings
|
||||||
serviceScope.launch {
|
serviceScope.launch {
|
||||||
val os = client.getOutputStream()
|
try {
|
||||||
while (peerSockets.containsKey(peerId)) {
|
val os = client.getOutputStream()
|
||||||
try { os.write(0) } catch (_: IOException) { break }
|
while (peerSockets.containsKey(peerId)) {
|
||||||
delay(2_000)
|
try { os.write(0) } catch (_: IOException) { break }
|
||||||
}
|
delay(2_000)
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {}
|
||||||
}
|
}
|
||||||
// Discovery keep-alive
|
// Discovery keep-alive
|
||||||
serviceScope.launch {
|
serviceScope.launch {
|
||||||
@@ -711,14 +713,7 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
override fun onCapabilitiesChanged(network: Network, nc: NetworkCapabilities) {
|
override fun onCapabilitiesChanged(network: Network, nc: NetworkCapabilities) {
|
||||||
if (peerSockets.containsKey(peerId)) return
|
if (peerSockets.containsKey(peerId)) return
|
||||||
val info = (nc.transportInfo as? WifiAwareNetworkInfo) ?: return
|
val info = (nc.transportInfo as? WifiAwareNetworkInfo) ?: return
|
||||||
val addr = info.peerIpv6Addr as Inet6Address
|
val addr = info.peerIpv6Addr as? Inet6Address ?: return
|
||||||
|
|
||||||
val lp = cm.getLinkProperties(network)
|
|
||||||
val iface = lp?.interfaceName
|
|
||||||
|
|
||||||
try {
|
|
||||||
val sock = Socket()
|
|
||||||
network.bindSocket(sock)
|
|
||||||
|
|
||||||
val lp = cm.getLinkProperties(network)
|
val lp = cm.getLinkProperties(network)
|
||||||
val iface = lp?.interfaceName
|
val iface = lp?.interfaceName
|
||||||
@@ -731,13 +726,17 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
|
|
||||||
// Use scoped IPv6 if interface name is available
|
// Use scoped IPv6 if interface name is available
|
||||||
val scopedAddr = if (iface != null && addr.scopeId == 0) {
|
val scopedAddr = if (iface != null && addr.scopeId == 0) {
|
||||||
Inet6Address.getByAddress(null, addr.address, java.net.NetworkInterface.getByName(iface))
|
try {
|
||||||
|
Inet6Address.getByAddress(null, addr.address, java.net.NetworkInterface.getByName(iface))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
addr
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
addr
|
addr
|
||||||
}
|
}
|
||||||
|
|
||||||
sock.connect(java.net.InetSocketAddress(scopedAddr, port), 7000)
|
sock.connect(java.net.InetSocketAddress(scopedAddr, port), 7000)
|
||||||
Log.d(TAG, "CLIENT: TCP connected to \${peerId.take(8)}… addr=\$scopedAddr:\$port (iface=\$iface)")
|
Log.d(TAG, "CLIENT: TCP connected to ${peerId.take(8)}… addr=$scopedAddr:$port (iface=$iface)")
|
||||||
|
|
||||||
peerSockets[peerId] = sock
|
peerSockets[peerId] = sock
|
||||||
try { peerManager.setDirectConnection(peerId, true) } catch (_: Exception) {}
|
try { peerManager.setDirectConnection(peerId, true) } catch (_: Exception) {}
|
||||||
@@ -776,11 +775,13 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
) {
|
) {
|
||||||
// TCP keep-alive
|
// TCP keep-alive
|
||||||
serviceScope.launch {
|
serviceScope.launch {
|
||||||
val os = sock.getOutputStream()
|
try {
|
||||||
while (peerSockets.containsKey(peerId)) {
|
val os = sock.getOutputStream()
|
||||||
try { os.write(0) } catch (_: IOException) { break }
|
while (peerSockets.containsKey(peerId)) {
|
||||||
delay(2_000)
|
try { os.write(0) } catch (_: IOException) { break }
|
||||||
}
|
delay(2_000)
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {}
|
||||||
}
|
}
|
||||||
// Discovery keep-alive
|
// Discovery keep-alive
|
||||||
serviceScope.launch {
|
serviceScope.launch {
|
||||||
@@ -1047,9 +1048,7 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
senderID = myPeerID,
|
senderID = myPeerID,
|
||||||
payload = tlvPayload
|
payload = tlvPayload
|
||||||
)
|
)
|
||||||
val signed = encryptionService.signData(announcePacket.toBinaryDataForSigning()!!)?.let {
|
val signed = signPacketBeforeBroadcast(announcePacket)
|
||||||
announcePacket.copy(signature = it)
|
|
||||||
} ?: announcePacket
|
|
||||||
|
|
||||||
broadcastPacket(RoutedPacket(signed))
|
broadcastPacket(RoutedPacket(signed))
|
||||||
try { gossipSyncManager.onPublicPacketSeen(signed) } catch (_: Exception) { }
|
try { gossipSyncManager.onPublicPacketSeen(signed) } catch (_: Exception) { }
|
||||||
@@ -1074,9 +1073,7 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
senderID = myPeerID,
|
senderID = myPeerID,
|
||||||
payload = tlvPayload
|
payload = tlvPayload
|
||||||
)
|
)
|
||||||
val signed = encryptionService.signData(packet.toBinaryDataForSigning()!!)?.let {
|
val signed = signPacketBeforeBroadcast(packet)
|
||||||
packet.copy(signature = it)
|
|
||||||
} ?: packet
|
|
||||||
|
|
||||||
broadcastPacket(RoutedPacket(signed))
|
broadcastPacket(RoutedPacket(signed))
|
||||||
peerManager.markPeerAsAnnouncedTo(peerID)
|
peerManager.markPeerAsAnnouncedTo(peerID)
|
||||||
|
|||||||
Reference in New Issue
Block a user