This commit is contained in:
geeksville 2020-06-05 11:53:50 -07:00
parent cecc369598
commit 76f3df94df
5 changed files with 120 additions and 27 deletions

View file

@ -179,26 +179,23 @@ class BluetoothInterfaceService : InterfaceService() {
/// Send a packet/command out the radio link
override fun handleSendToRadio(p: ByteArray) {
// Do this in the IO thread because it might take a while (and we don't care about the result code)
serviceScope.handledLaunch {
try {
debug("sending to radio")
doWrite(
BTM_TORADIO_CHARACTER,
p
) // Do a synchronous write, so that we can then do our reads if needed
if (logSends) {
sentPacketsLog.write(p)
sentPacketsLog.flush()
}
if (isFirstSend) {
isFirstSend = false
doReadFromRadio(false)
}
} catch (ex: Exception) {
errormsg("Ignoring sendToRadio exception: $ex")
try {
debug("sending to radio")
doWrite(
BTM_TORADIO_CHARACTER,
p
) // Do a synchronous write, so that we can then do our reads if needed
if (logSends) {
sentPacketsLog.write(p)
sentPacketsLog.flush()
}
if (isFirstSend) {
isFirstSend = false
doReadFromRadio(false)
}
} catch (ex: Exception) {
errormsg("Ignoring sendToRadio exception: $ex")
}
}

View file

@ -8,6 +8,7 @@ import android.os.RemoteException
import com.geeksville.android.BinaryLogFile
import com.geeksville.android.Logging
import com.geeksville.concurrent.DeferredExecution
import com.geeksville.concurrent.handledLaunch
import com.geeksville.mesh.IRadioInterfaceService
import com.geeksville.util.toRemoteExceptions
import kotlinx.coroutines.CoroutineScope
@ -109,7 +110,7 @@ abstract class InterfaceService : Service(), Logging {
*/
private var isFirstSend = true
/// Send a packet/command out the radio link
/// Send a packet/command out the radio link, this routine can block if it needs to
protected abstract fun handleSendToRadio(p: ByteArray)
// Handle an incoming packet from the radio, broadcasts it as an android intent
@ -168,20 +169,28 @@ abstract class InterfaceService : Service(), Logging {
/**
* do a synchronous write operation
*/
protected abstract fun doWrite(uuid: UUID, a: ByteArray)
protected open fun doWrite(uuid: UUID, a: ByteArray) {
throw NotImplementedError("Only implemented temporarily until rev1 api is removed")
}
/**
* do an asynchronous write operation
* Any error responses will be ignored (other than log messages)
*/
protected abstract fun doAsyncWrite(uuid: UUID, a: ByteArray)
protected open fun doAsyncWrite(uuid: UUID, a: ByteArray) {
throw NotImplementedError("Only implemented temporarily until rev1 api is removed")
}
protected abstract fun setBondedDeviceAddress(addr: String?)
protected open fun setBondedDeviceAddress(addr: String?) {
TODO()
}
/**
* do a synchronous read operation
*/
protected abstract fun doRead(uuid: UUID): ByteArray?
protected open fun doRead(uuid: UUID): ByteArray? {
throw NotImplementedError("Only implemented temporarily until rev1 api is removed")
}
private val binder = object : IRadioInterfaceService.Stub() {
@ -189,7 +198,10 @@ abstract class InterfaceService : Service(), Logging {
setBondedDeviceAddress(deviceAddr)
}
override fun sendToRadio(a: ByteArray) = handleSendToRadio(a)
override fun sendToRadio(a: ByteArray) {
// Do this in the IO thread because it might take a while (and we don't care about the result code)
serviceScope.handledLaunch { handleSendToRadio(a) }
}
//
// NOTE: the following methods are all deprecated and will be removed soon

View file

@ -0,0 +1,79 @@
package com.geeksville.mesh.service
import com.google.android.things.pio.PeripheralManager
import com.google.android.things.pio.UartDevice
import com.google.android.things.pio.UartDeviceCallback
class SerialInterfaceService : InterfaceService() {
companion object {
fun findPorts(): List<String> {
val manager = PeripheralManager.getInstance()
return manager.uartDeviceList
}
private val START1 = 0x94.toByte()
private val START2 = 0xc3.toByte()
}
private var uart: UartDevice? = null
/** The index of the next byte we are hoping to receive */
private var rxPtr = 0
private val callback = object : UartDeviceCallback {
override fun onUartDeviceDataAvailable(p0: UartDevice): Boolean {
return uart != null // keep reading until our device goes away
}
override fun onUartDeviceError(uart: UartDevice, error: Int) {
super.onUartDeviceError(uart, error)
}
}
override fun handleSendToRadio(p: ByteArray) {
uart?.apply {
val header = ByteArray(4)
header[0] = START1
header[1] = START2
header[2] = (p.size shr 8).toByte()
header[3] = (p.size and 0xff).toByte()
write(header, header.size)
write(p, p.size)
// flush(UartDevice.FLUSH_OUT) - I don't think we need to stall for htis
}
}
/*
private fun readerLoop() {
val scratch = ByteArray(1)
var ptr = 0
while (true) { // FIXME wait for someone to ask us to exit, and catch continuation exception
uart?.apply {
read(scratch, 1)
when (ptr) {
0 ->
}
}
}
} */
override fun onCreate() {
super.onCreate()
val port = findPorts()[0]
val manager = PeripheralManager.getInstance()
uart = manager.openUartDevice(port)
uart?.apply {
setBaudrate(921600)
registerUartDeviceCallback(callback)
}
}
override fun onDestroy() {
uart?.close()
uart = null
super.onDestroy()
}
}