AeroToss: mDNS queries + имена устройств + типы
- Desktop отправляет mDNS-запросы каждые 5 секунд для обнаружения - При обнаружении читается TXT record: name, id, type, port - Тип устройства определяется из TXT (phone/desktop) - Android NSD: setAttribute для TXT записей (id, name, port, type) - Имена: Desktop = user@hostname, Android = manufacturer model - Исправлен тип устройства: DESKTOP → PHONE/DESKTOP из TXT
This commit is contained in:
@@ -7,11 +7,11 @@ import android.util.Log
|
||||
import com.aerotoss.model.Device
|
||||
import com.aerotoss.model.DeviceType
|
||||
import com.aerotoss.util.generateDeviceId
|
||||
import com.aerotoss.util.getDeviceName
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
|
||||
private val _devices = MutableStateFlow<List<Device>>(emptyList())
|
||||
@@ -21,6 +21,7 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
|
||||
private var registrationListener: NsdManager.RegistrationListener? = null
|
||||
private var discoveryListener: NsdManager.DiscoveryListener? = null
|
||||
private val deviceId = generateDeviceId()
|
||||
private val deviceName = getDeviceName()
|
||||
private val discoveredDevices = ConcurrentHashMap<String, Device>()
|
||||
private val resolvingServices = ConcurrentHashMap.newKeySet<String>()
|
||||
|
||||
@@ -34,21 +35,22 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
|
||||
serviceName = SERVICE_NAME
|
||||
serviceType = SERVICE_TYPE
|
||||
setPort(port)
|
||||
setAttribute("id", deviceId)
|
||||
setAttribute("name", deviceName)
|
||||
setAttribute("port", port.toString())
|
||||
setAttribute("type", "phone")
|
||||
}
|
||||
|
||||
registrationListener = object : NsdManager.RegistrationListener {
|
||||
override fun onServiceRegistered(info: NsdServiceInfo) {
|
||||
Log.d(TAG, "Service registered: ${info.serviceName}")
|
||||
Log.d(TAG, "Registered as: ${info.serviceName}")
|
||||
}
|
||||
|
||||
override fun onRegistrationFailed(info: NsdServiceInfo, errorCode: Int) {
|
||||
Log.e(TAG, "Registration failed: $errorCode")
|
||||
}
|
||||
|
||||
override fun onServiceUnregistered(info: NsdServiceInfo) {
|
||||
Log.d(TAG, "Service unregistered")
|
||||
Log.d(TAG, "Unregistered")
|
||||
}
|
||||
|
||||
override fun onUnregistrationFailed(info: NsdServiceInfo, errorCode: Int) {
|
||||
Log.e(TAG, "Unregistration failed: $errorCode")
|
||||
}
|
||||
@@ -60,33 +62,50 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
|
||||
private fun startServiceDiscovery() {
|
||||
discoveryListener = object : NsdManager.DiscoveryListener {
|
||||
override fun onDiscoveryStarted(serviceType: String) {
|
||||
Log.d(TAG, "Discovery started for type: $serviceType")
|
||||
Log.d(TAG, "Discovery started for: $serviceType")
|
||||
}
|
||||
|
||||
override fun onServiceFound(serviceInfo: NsdServiceInfo) {
|
||||
Log.d(TAG, "Service found: ${serviceInfo.serviceName} type=${serviceInfo.serviceType}")
|
||||
val matchesType = serviceInfo.serviceType.contains("aerotoss")
|
||||
if (matchesType &&
|
||||
serviceInfo.serviceName != SERVICE_NAME &&
|
||||
Log.d(TAG, "Found: ${serviceInfo.serviceName} type=${serviceInfo.serviceType}")
|
||||
if (serviceInfo.serviceName != SERVICE_NAME &&
|
||||
resolvingServices.add(serviceInfo.serviceName)
|
||||
) {
|
||||
nsdManager?.resolveService(serviceInfo, object : NsdManager.ResolveListener {
|
||||
override fun onResolveFailed(info: NsdServiceInfo, errorCode: Int) {
|
||||
resolvingServices.remove(info.serviceName)
|
||||
Log.e(TAG, "Resolve failed: $errorCode")
|
||||
Log.e(TAG, "Resolve failed: ${info.serviceName} error=$errorCode")
|
||||
}
|
||||
|
||||
override fun onServiceResolved(info: NsdServiceInfo) {
|
||||
resolvingServices.remove(info.serviceName)
|
||||
val host = info.host?.hostAddress ?: return
|
||||
|
||||
// Try to get device name from TXT records
|
||||
var name = info.serviceName
|
||||
var id = info.serviceName
|
||||
var deviceType = DeviceType.PHONE
|
||||
|
||||
try {
|
||||
val attributes = info.attributes
|
||||
attributes["name"]?.let { name = String(it) }
|
||||
attributes["id"]?.let { id = String(it) }
|
||||
attributes["type"]?.let { type ->
|
||||
if (String(type) == "desktop") {
|
||||
deviceType = DeviceType.DESKTOP
|
||||
}
|
||||
}
|
||||
} catch (_: Exception) {}
|
||||
|
||||
val device = Device(
|
||||
id = info.serviceName,
|
||||
name = info.serviceName,
|
||||
type = DeviceType.PHONE,
|
||||
id = id,
|
||||
name = name,
|
||||
type = deviceType,
|
||||
hostAddress = host,
|
||||
port = info.port
|
||||
)
|
||||
discoveredDevices[info.serviceName] = device
|
||||
|
||||
Log.d(TAG, "Resolved: $name ($id) at $host:${info.port}")
|
||||
discoveredDevices[id] = device
|
||||
_devices.value = discoveredDevices.values.toList()
|
||||
}
|
||||
})
|
||||
@@ -94,6 +113,7 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
|
||||
}
|
||||
|
||||
override fun onServiceLost(serviceInfo: NsdServiceInfo) {
|
||||
Log.d(TAG, "Lost: ${serviceInfo.serviceName}")
|
||||
discoveredDevices.remove(serviceInfo.serviceName)
|
||||
resolvingServices.remove(serviceInfo.serviceName)
|
||||
_devices.value = discoveredDevices.values.toList()
|
||||
@@ -116,14 +136,8 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
|
||||
}
|
||||
|
||||
override fun stopDiscovery() {
|
||||
try {
|
||||
discoveryListener?.let { nsdManager?.stopServiceDiscovery(it) }
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
try {
|
||||
registrationListener?.let { nsdManager?.unregisterService(it) }
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
try { discoveryListener?.let { nsdManager?.stopServiceDiscovery(it) } } catch (_: Exception) {}
|
||||
try { registrationListener?.let { nsdManager?.unregisterService(it) } } catch (_: Exception) {}
|
||||
discoveryListener = null
|
||||
registrationListener = null
|
||||
discoveredDevices.clear()
|
||||
@@ -136,7 +150,7 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "AndroidNsdDiscovery"
|
||||
private const val TAG = "AeroToss-NSD"
|
||||
private const val SERVICE_TYPE = "_aerotoss._tcp."
|
||||
private const val SERVICE_NAME = "AeroToss"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user