host address retrieving through assigned subnet information and broadcast message to learn host address
This commit is contained in:
@@ -19,6 +19,7 @@ import io.flutter.plugin.common.MethodChannel
|
||||
import java.net.BindException
|
||||
import java.net.DatagramPacket
|
||||
import java.net.DatagramSocket
|
||||
import java.net.Inet4Address
|
||||
import java.net.InetAddress
|
||||
import java.net.InetSocketAddress
|
||||
import java.util.concurrent.Executors
|
||||
@@ -167,11 +168,18 @@ class MlrsNetworkPlugin(
|
||||
val callback = object : ConnectivityManager.NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
currentNetwork = network
|
||||
val gateway = gatewayAddressOf(connectivityManager.getLinkProperties(network))
|
||||
val linkProperties = connectivityManager.getLinkProperties(network)
|
||||
val gateway = gatewayAddressOf(linkProperties)
|
||||
val broadcast = broadcastAddressOf(linkProperties)
|
||||
val ssid = ssidOf(connectivityManager.getNetworkCapabilities(network))
|
||||
if (ssid != null) reportedSsid = ssid
|
||||
eventSink?.success(
|
||||
mapOf("type" to "available", "gatewayAddress" to gateway, "ssid" to ssid),
|
||||
mapOf(
|
||||
"type" to "available",
|
||||
"gatewayAddress" to gateway,
|
||||
"broadcastAddress" to broadcast,
|
||||
"ssid" to ssid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -225,6 +233,32 @@ class MlrsNetworkPlugin(
|
||||
return route?.gateway?.hostAddress
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet die Subnetz-Broadcast-Adresse (z.B. 192.168.4.255 fuer
|
||||
* 192.168.4.42/24) aus der dem Geraet auf diesem Netz zugewiesenen
|
||||
* IPv4-Adresse + Praefixlaenge. Dient als Bootstrap-Ziel fuer die erste
|
||||
* MSP-Anfrage, wenn die tatsaechliche IP der mLRS-Bruecke (noch) nicht
|
||||
* bekannt ist (Doku Kommunikationsschicht v2, Abschnitt 4/9:
|
||||
* "Peer-Learning" versagt, wenn die Bruecke kein initiales Paket
|
||||
* schickt und die geratene Standard-IP falsch liegt) - eine an die
|
||||
* Broadcast-Adresse gesendete Anfrage erreicht die Bruecke unabhaengig
|
||||
* von ihrer konkreten IP, ihre (unicast) Antwort verrät dann die echte
|
||||
* Adresse.
|
||||
*/
|
||||
private fun broadcastAddressOf(linkProperties: LinkProperties?): String? {
|
||||
val linkAddress = linkProperties?.linkAddresses
|
||||
?.firstOrNull { it.address is Inet4Address } ?: return null
|
||||
val ipBytes = linkAddress.address.address
|
||||
val prefixLength = linkAddress.prefixLength
|
||||
val broadcastBytes = ByteArray(4)
|
||||
for (i in 0 until 4) {
|
||||
val hostBitsInByte = (prefixLength - i * 8).coerceIn(0, 8)
|
||||
val hostMaskByte = 0xFF shr hostBitsInByte
|
||||
broadcastBytes[i] = (ipBytes[i].toInt() or hostMaskByte).toByte()
|
||||
}
|
||||
return InetAddress.getByAddress(broadcastBytes).hostAddress
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die tatsaechliche SSID des verbundenen Netzes. Erfordert
|
||||
* normalerweise ACCESS_FINE_LOCATION, ausser fuer die anfragende App
|
||||
@@ -260,6 +294,10 @@ class MlrsNetworkPlugin(
|
||||
// hier erkennbar mit BindException scheitert (Doku 3/9: "ist
|
||||
// 14550 belegt, ausweichen, aber protokollieren").
|
||||
newSocket.reuseAddress = false
|
||||
// Ohne dies wirft send() an eine Broadcast-Adresse
|
||||
// (broadcastAddressOf()) eine SocketException - noetig fuer
|
||||
// den Bootstrap-Fallback in UdpTransport.connect().
|
||||
newSocket.broadcast = true
|
||||
var fallbackFromPort: Int? = null
|
||||
try {
|
||||
newSocket.bind(InetSocketAddress(requestedPort))
|
||||
|
||||
Reference in New Issue
Block a user