63 lines
2.2 KiB
Kotlin
63 lines
2.2 KiB
Kotlin
package com.helible.pilot.viewmodels
|
|
|
|
import android.bluetooth.BluetoothSocket
|
|
import android.util.Log
|
|
import com.helible.pilot.dataclasses.GeneralMessage
|
|
import com.helible.pilot.dataclasses.MessageType
|
|
import com.helible.pilot.exceptions.TransferFailedException
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.flow.Flow
|
|
import kotlinx.coroutines.flow.flow
|
|
import kotlinx.coroutines.flow.flowOn
|
|
import kotlinx.coroutines.withContext
|
|
import java.io.BufferedInputStream
|
|
import java.io.IOException
|
|
|
|
const val maxPackageSize = 512 // [bytes]
|
|
|
|
class BluetoothDataTransferService(
|
|
private val socket: BluetoothSocket,
|
|
) {
|
|
fun listenForIncomingMessages(): Flow<GeneralMessage> {
|
|
return flow {
|
|
if (!socket.isConnected)
|
|
return@flow
|
|
|
|
val buffer = BufferedInputStream(socket.inputStream, maxPackageSize)
|
|
while (true) {
|
|
val message: String = try {
|
|
buffer.bufferedReader().readLine()
|
|
} catch (e: IOException) {
|
|
Log.e("BluetoothController", "Failed to receive incoming data")
|
|
throw TransferFailedException()
|
|
}
|
|
try {
|
|
val messageType =
|
|
MessageType.values().elementAtOrNull(message.split(";").first().toInt())
|
|
val messageData = message.split(";").last()
|
|
if (messageType != null) {
|
|
emit(GeneralMessage(messageType, messageData))
|
|
}
|
|
} catch (e: NoSuchElementException) {
|
|
Log.e("BluetoothController", "Message type is invalid: $message")
|
|
} catch (e: NumberFormatException) {
|
|
Log.e("BluetoothController", "Message invalid, may be device buffer congested: $message")
|
|
}
|
|
}
|
|
}.flowOn(Dispatchers.IO)
|
|
}
|
|
|
|
suspend fun sendMessage(bytes: ByteArray): Boolean {
|
|
return withContext(Dispatchers.IO) {
|
|
try {
|
|
socket.outputStream.write(bytes)
|
|
} catch (e: IOException) {
|
|
Log.e("BluetoothController", "Failed to write message: $e")
|
|
return@withContext false
|
|
}
|
|
true
|
|
}
|
|
}
|
|
}
|
|
|