Site menu Bluetooth MCAP: Multi Channel Adaptation Protocol

Bluetooth MCAP: Multi Channel Adaptation Protocol

O MCAP é um protocolo relativamente novo na pilha Bluetooth, e encaixa-se na camada 5 do modelo OSI (ou seja, é um protocolo de sessão). Numa comparação direta com TCP/IP, ele tem semelhanças com o SCTP e principalmente com o BEEP.

A ideia do MCAP é administrar um conjunto de conexões de transporte L2CAP, que façam parte de uma mesma sessão. Uma conexão MCAP tem exatamente uma conexão L2CAP de controle (denominada MCL) e qualquer número de conexões L2CAP de dados (denominadas MDL).

Além de "enfeixar" conexões que façam parte de uma mesma sessão, o MCAP suporta o conceito de sessão persistente, que sobrevive a eventuais desconexões L2CAP. Uma sessão pode continuar existindo após inúmeras desconexões e reconexões (voluntárias ou involuntárias). A sessão MCAP só deixa de existir quando a aplicação decidir matá-la ou o outro lado reportar que a sessão não é mais conhecida.

O MCAP inclui uma parte opcional que é o CSP (Clock Synchronization Protocol), descrito neste artigo.

Debaixo do capô

Um serviço MCAP ocupa duas "portas" L2CAP: um PSM de controle e outro de dados. O MCAP não prescreve PSMs fixos, eles devem ser dinanicamente alocados, na faixa de PSMs acima de 4096. Se os PSMs mais baixos estiverem livres, um serviço MCAP ficaria ouvindo nos PSMs 4097 e 4099 (apenas os PSMs ímpares podem ser usados no L2CAP).

Pelo fato dos PSMs não serem fixos, é praticamente obrigatório que um serviço MCAP seja anunciado via SDP, para que "o outro lado" possa descobrir os PSMs. Mas o MCAP não prescreve um formato de registro SDP. Isso fica a cargo do profile de serviço que usa MCAP, como o HDP.

O MCAP é apenas um protocolo, e faz pouco sentido usá-lo fora do contexto de um serviço — ainda menos que RFCOMM e L2CAP, já que não há um número fixo de porta.

Ainda assim, se de alguma forma os PSMs forem conhecidos (ou forem hardcoded na aplicação), é possível trafegar MCAP sem ter um serviço "de verdade".

É fácil entender o PSM de controle. Cada conexão L2CAP envolvendo o PSM de controle é uma conexão MCAP, existe uma relação de um para um.

Já o PSM de dados é mais enrolado. Cada canal de dados tem um identificador (MDEP ID). Então, por exemplo, se um serviço oferecer cinco canais de dados (imagine um dispositivo com cinco sensores embutidos), o "outro lado" pode conectar apenas os canais de dados desejados. Porém, o PSM de dados é sempre o mesmo.

Se, por exemplo, forem criados cinco canais de dados, o lado que tomou a iniciativa vai conectar cinco vezes no mesmo PSM. Isto cria cinco conexões L2CAP separadas (cada uma com seu próprio CID), cada um correspondente a um MDEP ID diferente.

Ok, e como o MCAP sabe que "aquela" conexão L2CAP corresponde a "aquele" canal de dados? Esta é a parte mais esquisita do MCAP: o atrelamento entre as duas coisas é puramente temporal. A requisição do MDL é feita via canal de controle (MCL), e imediatamente em seguida o requisitante conecta ao PSM de dados. Aí obviamente tem uns timeouts etc.

Isto significa que a requisição de canais de dados tem de ser feita sequencialmente. Requisita, conecta. Deu certo, requisita o próximo e conecta. Não se pode requisitar cinco canais "por atacado" e só depois fazer as conexões L2CAP. É o tipo da coisa que dá arrepios em quem está acostumado com a robustez dos protocolos TCP/IP.

Se esquecermos por um momento o mecanismo troncho descrito acima, o MCAP é até interessante. Cada MDEP ID possui um mapa de configuração onde está especificado se o canal solicita ou força algum recurso especial do L2CAP (ERTM, sreaming).

Como é de se esperar, o canal de controle tem um protocolo bem definido. Já os canais de dados não impõem nenhum protocolo. Uma vez aberto o canal, ele é um soquete L2CAP como qualquer outro e a aplicação trafega o que quiser.

O recurso de reconexão do MCAP é opcional; a aplicação pode escolher não utilizar este recurso, e considerar a sessão perdida em caso de desconexão. Por outro lado, se a aplicação quer reconexão, terá de preservar informações de sessão.

Além, disso o MCAP não garante que os canais de dados serão "perfeitos" durante uma sessão. Em caso de desconexão/reconexão, dados "em voo" podem ser perdidos. O protocolo de aplicação precisa implementar algum método de "replay" de requisição, bem como tratar requisições duplicadas.

Isto complica bastante as coisas, e creio que muitas aplicações baseadas em MCAP vão simplesmente optar em não suportar reconexão.

Implementação do MCAP

O MCAP é bastante novo e apenas um perfil, o HDP (também novo) o utiliza. O suporte em sistemas operacionais de uso geral é escasso. O Linux possui, mas é implementado em user-level, dentro do BlueZ, e é utilizado diretamente pelo HDP; não pode ser utilizado por aplicativos externos ao BlueZ.

Como o MCAP é um protocolo de sessão que usa nada além do L2CAP como transporte, é possível implementar MCAP de diversas formas: como uma biblioteca, na parte user-level do serviço Bluetooth (caso do BlueZ) ou mesmo no kernel.

De um ponto de vista "purista", o melhor lugar seria no kernel, pois isto permitiria criar soquetes MCAP, manipuláveis como qualquer outro soquete ou file descriptor, em vez de usar uma API especial.

Porém o MCAP é cheio de operações que não cabem na metáfora connect/read/write/close. E é claro, implementar qualquer coisa dentro do kernel é muito mais difícil de fazer e principalmente de manter (qualquer bug implica em atualizar o kernel — operação particularmente difícil em certas plataformas como celulares Android).