mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 11:45:19 +00:00
wifi aware wip
This commit is contained in:
@@ -121,6 +121,45 @@ class MainActivity : OrientationAwareActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bridge Wi‑Fi Aware callbacks into ChatViewModel (reusing BLE delegate methods)
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
com.bitchat.android.wifiaware.WifiAwareController.running.collect { running ->
|
||||||
|
val svc = com.bitchat.android.wifiaware.WifiAwareController.getService()
|
||||||
|
if (running && svc != null) {
|
||||||
|
svc.delegate = object : com.bitchat.android.wifiaware.WifiAwareMeshDelegate {
|
||||||
|
override fun didReceiveMessage(message: com.bitchat.android.model.BitchatMessage) {
|
||||||
|
chatViewModel.didReceiveMessage(message)
|
||||||
|
}
|
||||||
|
override fun didUpdatePeerList(peers: List<String>) {
|
||||||
|
chatViewModel.didUpdatePeerList(peers)
|
||||||
|
}
|
||||||
|
override fun didReceiveChannelLeave(channel: String, fromPeer: String) {
|
||||||
|
chatViewModel.didReceiveChannelLeave(channel, fromPeer)
|
||||||
|
}
|
||||||
|
override fun didReceiveDeliveryAck(messageID: String, recipientPeerID: String) {
|
||||||
|
chatViewModel.didReceiveDeliveryAck(messageID, recipientPeerID)
|
||||||
|
}
|
||||||
|
override fun didReceiveReadReceipt(messageID: String, recipientPeerID: String) {
|
||||||
|
chatViewModel.didReceiveReadReceipt(messageID, recipientPeerID)
|
||||||
|
}
|
||||||
|
override fun decryptChannelMessage(encryptedContent: ByteArray, channel: String): String? {
|
||||||
|
return chatViewModel.decryptChannelMessage(encryptedContent, channel)
|
||||||
|
}
|
||||||
|
override fun getNickname(): String? {
|
||||||
|
return chatViewModel.getNickname()
|
||||||
|
}
|
||||||
|
override fun isFavorite(peerID: String): Boolean {
|
||||||
|
return try {
|
||||||
|
com.bitchat.android.favorites.FavoritesPersistenceService.shared.getFavoriteStatus(peerID)?.isMutual == true
|
||||||
|
} catch (_: Exception) { false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only start onboarding process if we're in the initial CHECKING state
|
// Only start onboarding process if we're in the initial CHECKING state
|
||||||
// This prevents restarting onboarding on configuration changes
|
// This prevents restarting onboarding on configuration changes
|
||||||
if (mainViewModel.onboardingState.value == OnboardingState.CHECKING) {
|
if (mainViewModel.onboardingState.value == OnboardingState.CHECKING) {
|
||||||
|
|||||||
@@ -72,9 +72,15 @@ class MessageRouter private constructor(
|
|||||||
|
|
||||||
val hasMesh = mesh.getPeerInfo(toPeerID)?.isConnected == true
|
val hasMesh = mesh.getPeerInfo(toPeerID)?.isConnected == true
|
||||||
val hasEstablished = mesh.hasEstablishedSession(toPeerID)
|
val hasEstablished = mesh.hasEstablishedSession(toPeerID)
|
||||||
|
// Check Wi‑Fi Aware availability as a secondary transport
|
||||||
|
val aware = try { com.bitchat.android.wifiaware.WifiAwareController.getService() } catch (_: Exception) { null }
|
||||||
|
val hasAware = try { aware?.getPeerInfo(toPeerID)?.isConnected == true && aware.hasEstablishedSession(toPeerID) } catch (_: Exception) { false }
|
||||||
if (hasMesh && hasEstablished) {
|
if (hasMesh && hasEstablished) {
|
||||||
Log.d(TAG, "Routing PM via mesh to ${toPeerID} msg_id=${messageID.take(8)}…")
|
Log.d(TAG, "Routing PM via mesh to ${toPeerID} msg_id=${messageID.take(8)}…")
|
||||||
mesh.sendPrivateMessage(content, toPeerID, recipientNickname, messageID)
|
mesh.sendPrivateMessage(content, toPeerID, recipientNickname, messageID)
|
||||||
|
} else if (hasAware) {
|
||||||
|
Log.d(TAG, "Routing PM via Wi‑Fi Aware to ${toPeerID} msg_id=${messageID.take(8)}…")
|
||||||
|
aware?.sendPrivateMessage(content, toPeerID, recipientNickname, messageID)
|
||||||
} else if (canSendViaNostr(toPeerID)) {
|
} else if (canSendViaNostr(toPeerID)) {
|
||||||
Log.d(TAG, "Routing PM via Nostr to ${toPeerID.take(32)}… msg_id=${messageID.take(8)}…")
|
Log.d(TAG, "Routing PM via Nostr to ${toPeerID.take(32)}… msg_id=${messageID.take(8)}…")
|
||||||
nostr.sendPrivateMessage(content, toPeerID, recipientNickname, messageID)
|
nostr.sendPrivateMessage(content, toPeerID, recipientNickname, messageID)
|
||||||
@@ -83,14 +89,21 @@ class MessageRouter private constructor(
|
|||||||
val q = outbox.getOrPut(toPeerID) { mutableListOf() }
|
val q = outbox.getOrPut(toPeerID) { mutableListOf() }
|
||||||
q.add(Triple(content, recipientNickname, messageID))
|
q.add(Triple(content, recipientNickname, messageID))
|
||||||
Log.d(TAG, "Initiating noise handshake after queueing PM for ${toPeerID.take(8)}…")
|
Log.d(TAG, "Initiating noise handshake after queueing PM for ${toPeerID.take(8)}…")
|
||||||
mesh.initiateNoiseHandshake(toPeerID)
|
if (hasMesh) mesh.initiateNoiseHandshake(toPeerID) else aware?.initiateNoiseHandshake(toPeerID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendReadReceipt(receipt: ReadReceipt, toPeerID: String) {
|
fun sendReadReceipt(receipt: ReadReceipt, toPeerID: String) {
|
||||||
if ((mesh.getPeerInfo(toPeerID)?.isConnected == true) && mesh.hasEstablishedSession(toPeerID)) {
|
val aware = try { com.bitchat.android.wifiaware.WifiAwareController.getService() } catch (_: Exception) { null }
|
||||||
|
val viaMesh = (mesh.getPeerInfo(toPeerID)?.isConnected == true) && mesh.hasEstablishedSession(toPeerID)
|
||||||
|
val viaAware = try { aware?.getPeerInfo(toPeerID)?.isConnected == true && aware.hasEstablishedSession(toPeerID) } catch (_: Exception) { false }
|
||||||
|
if (viaMesh) {
|
||||||
Log.d(TAG, "Routing READ via mesh to ${toPeerID.take(8)}… id=${receipt.originalMessageID.take(8)}…")
|
Log.d(TAG, "Routing READ via mesh to ${toPeerID.take(8)}… id=${receipt.originalMessageID.take(8)}…")
|
||||||
mesh.sendReadReceipt(receipt.originalMessageID, toPeerID, mesh.getPeerNicknames()[toPeerID] ?: mesh.myPeerID)
|
mesh.sendReadReceipt(receipt.originalMessageID, toPeerID, mesh.getPeerNicknames()[toPeerID] ?: mesh.myPeerID)
|
||||||
|
} else if (viaAware) {
|
||||||
|
Log.d(TAG, "Routing READ via Wi‑Fi Aware to ${toPeerID.take(8)}… id=${receipt.originalMessageID.take(8)}…")
|
||||||
|
val me = try { aware?.myPeerID } catch (_: Exception) { null }
|
||||||
|
aware?.sendReadReceipt(receipt.originalMessageID, toPeerID, me ?: "")
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Routing READ via Nostr to ${toPeerID.take(8)}… id=${receipt.originalMessageID.take(8)}…")
|
Log.d(TAG, "Routing READ via Nostr to ${toPeerID.take(8)}… id=${receipt.originalMessageID.take(8)}…")
|
||||||
nostr.sendReadReceipt(receipt, toPeerID)
|
nostr.sendReadReceipt(receipt, toPeerID)
|
||||||
|
|||||||
@@ -671,7 +671,7 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
|
|
||||||
val cb = object : ConnectivityManager.NetworkCallback() {
|
val cb = object : ConnectivityManager.NetworkCallback() {
|
||||||
override fun onAvailable(network: Network) {
|
override fun onAvailable(network: Network) {
|
||||||
cm.bindProcessToNetwork(network)
|
// Do not bind process for Aware; use per-socket binding instead
|
||||||
}
|
}
|
||||||
override fun onCapabilitiesChanged(network: Network, nc: NetworkCapabilities) {
|
override fun onCapabilitiesChanged(network: Network, nc: NetworkCapabilities) {
|
||||||
if (peerSockets.containsKey(peerId)) return
|
if (peerSockets.containsKey(peerId)) return
|
||||||
@@ -679,9 +679,11 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
val addr = info.peerIpv6Addr as Inet6Address
|
val addr = info.peerIpv6Addr as Inet6Address
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val sock = network.socketFactory
|
// Some devices deny bindSocket() (EPERM). Rely on scoped IPv6 to route correctly.
|
||||||
.createSocket(addr, port)
|
val sock = Socket()
|
||||||
.apply { keepAlive = true }
|
sock.tcpNoDelay = true
|
||||||
|
sock.keepAlive = true
|
||||||
|
sock.connect(java.net.InetSocketAddress(addr, port), 7000)
|
||||||
|
|
||||||
Log.d(TAG, "CLIENT: TCP connected to ${peerId.take(8)}… addr=$addr:$port")
|
Log.d(TAG, "CLIENT: TCP connected to ${peerId.take(8)}… addr=$addr:$port")
|
||||||
peerSockets[peerId] = sock
|
peerSockets[peerId] = sock
|
||||||
@@ -696,7 +698,6 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
override fun onLost(network: Network) {
|
override fun onLost(network: Network) {
|
||||||
cm.bindProcessToNetwork(null)
|
|
||||||
networkCallbacks.remove(peerId)
|
networkCallbacks.remove(peerId)
|
||||||
Log.d(TAG, "CLIENT: network lost for ${peerId.take(8)}…")
|
Log.d(TAG, "CLIENT: network lost for ${peerId.take(8)}…")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user