Skip to main content

Android UART Transport SDK

SDK Version: 1.0.0

The UART SDK connects to an xTalk device through an Android serial port. It opens/closes the TTY, sends AT commands and binary RF payloads, and provides a common RadioTransport adapter. Authentication, device initialization, Mesh, PTT, and UI are separate products.

Open and close

Add the supplied UART SDK and Radio Transport SDK artifacts. The device image must grant the application access to the selected TTY.

val opened = XTalkUartClient.open(
applicationContext,
XTalkUartClient.Config(
baudRate = 115200,
devicePath = "/dev/ttyS1",
),
)
require(opened)

getConfig(), getDeviceInfo(), and isOpen() expose current state. reopenWithBaud(context, baudRate) closes and reopens with another speed. close() releases the reader and streams and is safe to call repeatedly.

Inbound data

val listener: (ByteArray) -> Unit = inboundRouter::accept
XTalkUartClient.addListener(listener)
// Later:
XTalkUartClient.removeListener(listener)

Callbacks contain raw chunks and may split or combine AT lines. Prefer UartRadioTransport with RadioTransportEventBridge for common line/RF parsing.

AT commands

val probe = XTalkUartClient.probeAtStatus(1_500)
when (probe?.status) {
XTalkUartClient.AtProbeStatus.OK -> continueStartup()
XTalkUartClient.AtProbeStatus.NEED_VERIFY -> authenticateDevice()
XTalkUartClient.AtProbeStatus.ERROR, null -> showConnectionError()
}

val response = XTalkUartClient.runAtCommand(
command = "AT+VER?",
timeoutMs = 3_000,
log = false,
)

sendAtCommand(command) sends without collecting a response. runAtCommand(...) serializes access and supports an error policy, custom stopWhen, and optional response-tail drain through the common transport API.

RF transmission

val sent = XTalkUartClient.sendRfPayload(payload)
val completed = XTalkUartClient.sendRfPayloadAndWaitSendFinish(payload, 3_000)
val realtimeAccepted = XTalkUartClient.sendRfPayloadNoWait(payload)

The first sends a binary-escaped RF payload. The second waits for both command success and device send completion. The no-wait variant uses a non-blocking lock and returns false while an AT/completion session owns the port. Empty payload, closed port, contention, and write failure return false.

Common transport adapter

val transport = UartRadioTransport(
eventBridge = eventBridge,
localDeviceLongIdProvider = { authenticatedDeviceId },
)

if (transport.isReadyForSend()) {
val result = transport.sendRfPayload(payload, timeoutMs = 3_000)
}

UartRadioTransport implements readiness, local identity, AT execution, normal/completion/no-wait RF sends, packet/realtime/CRC listeners, expected realtime source selection, local echo filtering, frequency and RATE writes, RATE/WORKMODE queries, and restoreTextPttDefaults(...). Its mode is UART and label is uart.

Lifecycle and errors

Open the port, probe AT, authenticate if required, initialize wireless defaults, attach inbound routing, then enable business SDKs. Before switching devices, stop RF users, release their leases, remove listeners, and close the port. A false return or thrown host I/O error is a connection failure; do not loop indefinitely on an inaccessible TTY. Diagnostic log storage is not part of the customer API.