Skip to content

Commit

Permalink
feat: support custom ports in TCP interface
Browse files Browse the repository at this point in the history
  • Loading branch information
andrekir committed Jan 9, 2025
1 parent 7794c08 commit c2e728e
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 12 deletions.
11 changes: 3 additions & 8 deletions app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import android.app.Application
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.hardware.usb.UsbManager
import android.net.nsd.NsdServiceInfo
import android.os.RemoteException
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
Expand All @@ -32,6 +31,7 @@ import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.R
import com.geeksville.mesh.repository.bluetooth.BluetoothRepository
import com.geeksville.mesh.repository.network.NetworkRepository
import com.geeksville.mesh.repository.network.NetworkRepository.Companion.toAddressString
import com.geeksville.mesh.repository.radio.InterfaceId
import com.geeksville.mesh.repository.radio.RadioInterfaceService
import com.geeksville.mesh.repository.usb.UsbRepository
Expand Down Expand Up @@ -91,7 +91,8 @@ class BTScanModel @Inject constructor(

// Include Network Service Discovery
tcp.forEach { service ->
addDevice(TCPDeviceListEntry(service))
val address = service.toAddressString()
addDevice(DeviceListEntry(address, "t$address", true))
}

usb.forEach { (_, d) ->
Expand Down Expand Up @@ -140,12 +141,6 @@ class BTScanModel @Inject constructor(
usbManager.hasPermission(usb.device),
)

class TCPDeviceListEntry(val service: NsdServiceInfo) : DeviceListEntry(
service.host.toString().substring(1),
service.host.toString().replace("/", "t"),
true
)

override fun onCleared() {
super.onCleared()
debug("BTScanModel cleared")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ class NetworkRepository @Inject constructor(
companion object {
// To find all available services use SERVICE_TYPE = "_services._dns-sd._udp"
internal const val SERVICE_NAME = "Meshtastic"
internal val SERVICE_TYPES = listOf("_http._tcp.", "_meshtastic._tcp.")
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))
if (serviceType.trim('.') == SERVICE_TYPE && port != SERVICE_PORT) {
append(":$port")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ import java.util.concurrent.CopyOnWriteArrayList
import kotlin.coroutines.resume

internal fun NsdManager.serviceList(
serviceTypes: List<String>,
serviceTypes: Set<String>,
serviceName: String,
): Flow<List<NsdServiceInfo>> {
val flows = serviceTypes.map { serviceType -> serviceList(serviceType, serviceName) }
return combine(flows) { lists -> lists.flatMap { it }.distinctBy { it.serviceName } }
return combine(flows) { lists -> lists.flatMap { it } }
}

@OptIn(ExperimentalCoroutinesApi::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.geeksville.mesh.repository.radio

import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.concurrent.handledLaunch
import com.geeksville.mesh.repository.network.NetworkRepository
import com.geeksville.mesh.util.Exceptions
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
Expand All @@ -42,6 +43,7 @@ class TCPInterface @AssistedInject constructor(
const val MAX_RETRIES_ALLOWED = Int.MAX_VALUE
const val MIN_BACKOFF_MILLIS = 1 * 1000L // 1 second
const val MAX_BACKOFF_MILLIS = 5 * 60 * 1000L // 5 minutes
const val SERVICE_PORT = NetworkRepository.SERVICE_PORT
}

private var retryCount = 1
Expand Down Expand Up @@ -100,7 +102,11 @@ class TCPInterface @AssistedInject constructor(
// Create a socket to make the connection with the server
private suspend fun startConnect() = withContext(Dispatchers.IO) {
debug("TCP connecting to $address")
Socket(InetAddress.getByName(address), 4403).use { socket ->

val (host, port) = address.split(":", limit = 2)
.let { it[0] to (it.getOrNull(1)?.toIntOrNull() ?: SERVICE_PORT) }

Socket(InetAddress.getByName(host), port).use { socket ->
socket.tcpNoDelay = true
socket.soTimeout = 500
this@TCPInterface.socket = socket
Expand Down

0 comments on commit c2e728e

Please sign in to comment.