FileTransfer.kt 1.85 KB
Newer Older
Anon's avatar
Anon committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
package com.github.antweb.donkey

import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic
import android.os.Environment
import java.io.BufferedInputStream
import java.io.File
import java.io.FileInputStream
import java.nio.ByteBuffer

class FileTransfer(
    private val gatt: BluetoothGatt,
    private val dataCharacteristic: BluetoothGattCharacteristic,
    private val mtu: Int
) {
    private val filePath = "/Download/SEND.txt"

    private val iterator = openFile().iterator()
    private var offset: Int = 0

    private fun openFile(): ByteArray {
        // TODO: Don't listen to Android Docs, use stuff that is not deprecated
        val file = File(
            Environment.getExternalStorageDirectory()
                .absolutePath, filePath
        )

        val size = file.length()
        val bytes = ByteArray(size.toInt())
        val buf = BufferedInputStream(FileInputStream(file))
        buf.read(bytes, 0, bytes.size)
        buf.close()

        return bytes
    }

    fun sendFile() {
        // Send first chunk
        sendNext()
    }

    fun sendNext() {
        if (!iterator.hasNext()) {
            return
        }

        gatt?.beginReliableWrite()



        val chunk = mutableListOf<Byte>()
        for (i in 0 until (mtu - 5)) {
            chunk.add(iterator.next())
        }

        // Our packet:
        // 4 byte header + chunk
        val header = offset
        offset += chunk.size

        val sendBuffer = ByteBuffer.allocate(chunk.size + 4)
        sendBuffer.putInt(header)
        sendBuffer.put(chunk.toByteArray())


        dataCharacteristic?.value = sendBuffer.array()
        gatt?.writeCharacteristic(dataCharacteristic)

        // This will trigger the onCharacteristicWrite callback once the other side ACKs
        // In there, we can call the actual gatt?.executeReliableWrite()
    }
}