Tutorial Android-BLE L2Cap

Apr 05 2023
Olá pessoal…!! Bem-vindo ao tutorial do Bluetooth L2cap, neste blog, aprenderemos como podemos fazer conexões com central usando l2cap, Como ler e escrever de periférico e central, e vice-versa. Para iniciantes, recomendo fortemente ter uma compreensão básica do BLE antes de ler este artigo.

Olá pessoal…!!

Bem-vindo ao tutorial do Bluetooth L2cap, neste blog, aprenderemos como podemos fazer conexões com central usando l2cap, Como ler e escrever de periférico e central, e vice-versa.

Para iniciantes, recomendo fortemente ter uma compreensão básica do BLE antes de ler este artigo. O blog punchthrough me ajudou a entender melhor o BLE porque esta foi minha primeira tarefa no Bluetooth.

Foi-me atribuída a tarefa de fazer uma app android para uma central que irá trocar grandes payloads com a ajuda do l2cap.

Depois de pesquisar muito na internet, descobri que não há muito conteúdo disponível para implementar o l2cap. Escrevendo este blog para compartilhar meu conhecimento com outras pessoas.

Definição de algumas das palavras-chave que são utilizadas neste artigo.

Central /Cliente
Um dispositivo que procura e se conecta a periféricos BLE para executar alguma operação. No contexto do desenvolvimento de aplicativos, geralmente é um dispositivo Android.

Periférico/Servidor
Dispositivo que anuncia sua presença e é conectado por uma central para realizar alguma tarefa. No contexto do desenvolvimento de aplicativos, geralmente é um dispositivo BLE com o qual você está trabalhando, como um monitor de frequência cardíaca.

Tudo bem, chega de história, vamos pular para a ação

Foto de Aziz Acharki no Unsplash

Em nosso aplicativo Android, devemos iniciar a operação de pesquisa de dispositivos ble, para isso criamos um layout simples com um botão e o nomeamos como “search BLE”. Ao clicar nesse botão, precisamos realizar a busca pela central/servidor (a central pode ser um firmware e deve ser o anúncio da descoberta).

Adicione a permissão abaixo em seu arquivo de manifesto.

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

Etapa 1: Definir um adaptador Bluetooth

Representa o adaptador Bluetooth do dispositivo local. O BluetoothAdapterpermite executar tarefas fundamentais do Bluetooth, como iniciar a descoberta de dispositivos, consultar uma lista de dispositivos vinculados (emparelhados), instanciar um BluetoothDeviceusando um endereço MAC conhecido e criar um BluetoothServerSocketpara ouvir solicitações de conexão de outros dispositivos e iniciar uma verificação de Bluetooth Dispositivos LE.

private val bluetoothAdapter: BluetoothAdapter by lazy {
    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothManager.adapter
}

Esta classe fornece métodos para executar operações relacionadas à varredura para dispositivos Bluetooth LE. Um aplicativo pode procurar um determinado tipo de dispositivo Bluetooth LE usando ScanFilter. Ele também pode solicitar diferentes tipos de callbacks para entregar o resultado.

private val bleScanner by lazy {
    bluetoothAdapter.bluetoothLeScanner
}

Critérios para filtragem resultam de varreduras de Bluetooth LE . Um ScanFilter permite que os clientes restrinjam os resultados da varredura apenas àqueles que são de seu interesse. Isso é opcional.

val filters: MutableList<ScanFilter> = ArrayList()

val macAddressFilter = ScanFilter.Builder()
                .setDeviceAddress("xx:xx:xx:xx:xx:xx") // add your device mac address here
                .build()

filters.add(macAddressFilter)

private val scanSettings = ScanSettings.Builder()
    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
    .build()

O modo de varredura pode ser SCAN_MODE_LOW_POWER, SCAN_MODE_BALANCED ou SCAN_MODE_LOW_LATENCY.

Leia mais sobre a configuração Scan no documento oficial

Etapa 5: Etapa importante, uma vez que iniciamos a varredura, precisamos de uma função de retorno de chamada para obter o resultado, então vamos definir uma diversão de retorno de chamada.

private val scanCallback = object : ScanCallback() {
    @RequiresApi(Build.VERSION_CODES.O)
    override fun onScanResult(callbackType: Int, result: ScanResult) {
        if (result.isConnectable){
            // result.device will consist of central details
            Log.i("ScanCallBack","Device Name: ${result.device.name?:"No Name"}")
            Log.i("ScanCallBack","Device Address: ${result.device.address}")
        }
    }
    override fun onScanFailed(errorCode: Int) {
        Timber.e("onScanFailed: code $errorCode")
    }
}

Se você não tiver um filtro de verificação, poderá passar o valor como nulo no primeiro parâmetro

bleScanner.startScan(null, scanSettings, scanCallback)

bleScanner.startScan(filters, scanSettings, scanCallback)

Portanto, a função de digitalização final ficará assim.

private fun startBleScan() {
        val filters: MutableList<ScanFilter> = ArrayList()

        val macAddressFilter = ScanFilter.Builder()
            .setDeviceAddress("xx:xx:xx:xx:xx:xx")
            .build()
        filters.add(macAddressFilter)


        /*val macAddressDevBoard = ScanFilter.Builder()
            .setDeviceAddress("84:71:27:44:36:02")
            .build()
        filters.add(macAddressDevBoard)*/


        scanResultAdapter.notifyDataSetChanged()
        bleScanner.startScan(null, scanSettings, scanCallback)
        isScanning = true

        mHandler.postDelayed({
            stopBleScan()
            progress_horizontal.visibility = View.GONE }, 20000)
}

Portanto, a próxima etapa aprenderá sobre l2cap e como podemos usá-lo para troca de carga útil.

O que é L2CAP?

Logical Link Control and Adaptation Protocol (L2CAP) é um protocolo usado no padrão Bluetooth que fornece adaptação entre as camadas superiores e a camada de banda base da pilha Bluetooth .

Parte 2 : implementação L2cap