diff --git a/app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt b/app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt index bacf17c57..d3d0ad0b2 100644 --- a/app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt @@ -68,8 +68,9 @@ class BTScanModel @Inject constructor( val devices = MutableLiveData>(mutableMapOf()) val errorText = MutableLiveData(null) - private val showMockInterface: StateFlow get() = - MutableStateFlow(radioInterfaceService.isMockInterface()).asStateFlow() + private val showMockInterface: StateFlow + get() = + MutableStateFlow(radioInterfaceService.isMockInterface()).asStateFlow() init { combine( @@ -84,7 +85,13 @@ class BTScanModel @Inject constructor( } // Include a placeholder for "None" - addDevice(DeviceListEntry(context.getString(R.string.none), NO_DEVICE_SELECTED, true)) + addDevice( + DeviceListEntry( + context.getString(R.string.none), + NO_DEVICE_SELECTED, + true + ) + ) if (showMockInterface) { addDevice(DeviceListEntry("Demo Mode", "m", true)) @@ -97,7 +104,19 @@ class BTScanModel @Inject constructor( // Include Network Service Discovery tcp.forEach { service -> val address = service.toAddressString() - addDevice(DeviceListEntry(address, "t$address", true)) + val txtRecords = service.attributes // Map + val shortNameBytes = txtRecords["shortname"] + val idBytes = txtRecords["id"] + + val shortName = shortNameBytes?.let { String(it, Charsets.UTF_8) } + ?: context.getString(R.string.meshtastic) + val deviceId = + idBytes?.let { String(it, Charsets.UTF_8) }?.replace("!", "") + var displayName = shortName + if (deviceId != null) { + displayName += "_$deviceId" + } + addDevice(DeviceListEntry(displayName, "t$address", true)) } usb.forEach { (_, d) -> @@ -160,10 +179,6 @@ class BTScanModel @Inject constructor( private var scanJob: Job? = null - val selectedAddress get() = radioInterfaceService.getDeviceAddress() - val selectedBluetooth: Boolean get() = selectedAddress?.getOrNull(0) == 'x' - - // / Use the string for the NopInterface val selectedAddressFlow: StateFlow = radioInterfaceService.currentDeviceAddressFlow val selectedNotNullFlow: StateFlow = selectedAddressFlow diff --git a/app/src/main/java/com/geeksville/mesh/repository/network/NetworkRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/network/NetworkRepository.kt index 0c63ccc49..13dced15a 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/network/NetworkRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/network/NetworkRepository.kt @@ -41,16 +41,13 @@ class NetworkRepository @Inject constructor( .conflate() val resolvedList: Flow> - get() = nsdManagerLazy.get().serviceList(SERVICE_TYPES, SERVICE_NAME) + get() = nsdManagerLazy.get().serviceList(SERVICE_TYPE) .flowOn(dispatchers.io) .conflate() companion object { - // To find all available services use SERVICE_TYPE = "_services._dns-sd._udp" - internal const val SERVICE_NAME = "Meshtastic" internal const val SERVICE_PORT = 4403 private const val SERVICE_TYPE = "_meshtastic._tcp" - internal val SERVICE_TYPES = setOf("_http._tcp", SERVICE_TYPE) fun NsdServiceInfo.toAddressString() = buildString { append(@Suppress("DEPRECATION") host.toString().substring(1)) diff --git a/app/src/main/java/com/geeksville/mesh/repository/network/NsdManager.kt b/app/src/main/java/com/geeksville/mesh/repository/network/NsdManager.kt index 3e7317b2a..4c88bd046 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/network/NsdManager.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/network/NsdManager.kt @@ -24,27 +24,16 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.suspendCancellableCoroutine import java.util.concurrent.CopyOnWriteArrayList import kotlin.coroutines.resume -internal fun NsdManager.serviceList( - serviceTypes: Set, - serviceName: String, -): Flow> { - val flows = serviceTypes.map { serviceType -> serviceList(serviceType, serviceName) } - return combine(flows) { lists -> lists.flatMap { it } } -} - @OptIn(ExperimentalCoroutinesApi::class) internal fun NsdManager.serviceList( serviceType: String, - serviceName: String, ): Flow> = discoverServices(serviceType).mapLatest { serviceList -> serviceList - .filter { it.serviceName.contains(serviceName) } .mapNotNull { resolveService(it) } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt index a72b344d1..07b71e190 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt @@ -81,6 +81,11 @@ fun DeviceListItem( contentDescription ) }, + supportingContent = { + if (device.isTCP) { + Text(device.address) + } + }, trailingContent = { if (selected) { Icon( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f4dc3d57c..cfc7d53cd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -705,4 +705,5 @@ No Network devices found. No USB Serial devices found. Scroll to bottom + Meshtastic