125 lines
No EOL
4.3 KiB
Kotlin
125 lines
No EOL
4.3 KiB
Kotlin
package com.srtk.airlink
|
|
|
|
import android.content.Context
|
|
import android.net.nsd.NsdManager
|
|
import android.net.nsd.NsdServiceInfo
|
|
import android.util.Log
|
|
import kotlinx.coroutines.channels.awaitClose
|
|
import kotlinx.coroutines.flow.Flow
|
|
import kotlinx.coroutines.flow.callbackFlow
|
|
import java.net.InetAddress
|
|
|
|
data class ServerInfo(
|
|
val name: String,
|
|
val ip: InetAddress,
|
|
val port: Int
|
|
) {
|
|
override fun equals(other: Any?): Boolean {
|
|
if (this === other) return true
|
|
if (other !is ServerInfo) return false
|
|
return ip == other.ip && port == other.port
|
|
}
|
|
|
|
override fun hashCode(): Int {
|
|
return 31 * ip.hashCode() + port
|
|
}
|
|
}
|
|
|
|
class DiscoveryManager(context: Context) {
|
|
private val TAG = "DiscoveryManager"
|
|
private val nsdManager = context.getSystemService(
|
|
Context.NSD_SERVICE
|
|
) as NsdManager
|
|
private val SERVICE_TYPE = "_procam._udp."
|
|
|
|
fun discover(): Flow<ServerInfo> = callbackFlow {
|
|
val discoveryListener = object : NsdManager.DiscoveryListener {
|
|
override fun onDiscoveryStarted(regType: String) {
|
|
Log.d(TAG, "Discovery started")
|
|
}
|
|
|
|
override fun onServiceFound(service: NsdServiceInfo) {
|
|
if (service.serviceType.contains("_procam")) {
|
|
try {
|
|
nsdManager.resolveService(
|
|
service,
|
|
object : NsdManager.ResolveListener {
|
|
override fun onResolveFailed(
|
|
serviceInfo: NsdServiceInfo,
|
|
errorCode: Int
|
|
) {
|
|
Log.w(TAG, "Resolve failed: $errorCode")
|
|
}
|
|
|
|
override fun onServiceResolved(
|
|
serviceInfo: NsdServiceInfo
|
|
) {
|
|
try {
|
|
val server = ServerInfo(
|
|
name = serviceInfo.serviceName,
|
|
ip = serviceInfo.host,
|
|
port = serviceInfo.port
|
|
)
|
|
trySend(server)
|
|
} catch (e: Exception) {
|
|
Log.e(
|
|
TAG,
|
|
"Error creating ServerInfo: ${e.message}"
|
|
)
|
|
}
|
|
}
|
|
}
|
|
)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "Resolve error: ${e.message}")
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onServiceLost(service: NsdServiceInfo) {
|
|
Log.d(TAG, "Service lost: ${service.serviceName}")
|
|
}
|
|
|
|
override fun onDiscoveryStopped(serviceType: String) {
|
|
Log.d(TAG, "Discovery stopped")
|
|
}
|
|
|
|
override fun onStartDiscoveryFailed(
|
|
serviceType: String,
|
|
errorCode: Int
|
|
) {
|
|
Log.e(TAG, "Start discovery failed: $errorCode")
|
|
try {
|
|
nsdManager.stopServiceDiscovery(this)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "Stop discovery error: ${e.message}")
|
|
}
|
|
}
|
|
|
|
override fun onStopDiscoveryFailed(
|
|
serviceType: String,
|
|
errorCode: Int
|
|
) {
|
|
Log.e(TAG, "Stop discovery failed: $errorCode")
|
|
}
|
|
}
|
|
|
|
try {
|
|
nsdManager.discoverServices(
|
|
SERVICE_TYPE,
|
|
NsdManager.PROTOCOL_DNS_SD,
|
|
discoveryListener
|
|
)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "Discovery start error: ${e.message}")
|
|
}
|
|
|
|
awaitClose {
|
|
try {
|
|
nsdManager.stopServiceDiscovery(discoveryListener)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "Discovery cleanup error: ${e.message}")
|
|
}
|
|
}
|
|
}
|
|
} |