31.5. Bluetooth
Anterior | Capítulo 31. Rede Avançada | Próxima

## 31.5. Bluetooth

Escrito por Pav Lucistnik .

O bluetooth é uma tecnologia sem fio para a criação de redes pessoais que operam na faixa não licenciada de 2,4 GHz, com um alcance de 10 metros. As redes geralmente são formadas em modo ad-hoc a partir de dispositivos portáteis, como telefones celulares, computadores de mão e laptops. Ao contrário da tecnologia sem fio Wi-Fi, o Bluetooth oferece perfis de serviços de nível superior, como servidores de arquivos semelhantes ao FTP, envio de arquivos, transporte de voz, emulação de linha serial e muito mais.

Esta seção descreve o uso de um dongle Bluetooth USB em um sistema FreeBSD. Em seguida, descreve os vários protocolos e utilitários Bluetooth.

### 31.5.1. Carregando o Suporte Bluetooth

A pilha Bluetooth no FreeBSD é implementada usando o framework netgraph(4). Uma ampla variedade de dongles Bluetooth USB é suportada pelo ng_ubt(4). Os dispositivos Bluetooth baseados no Broadcom BCM2033 são suportados pelos drivers ubtbcmfw(4) e ng_ubt(4). A placa 3Com Bluetooth PC Card 3CRWB60-A é suportada pelo driver ng_bt3c(4). Dispositivos Bluetooth baseados em Portas Seriais e UART são suportados por sio(4), ng_h4(4), e hcseriald(8).

Antes de conectar um dispositivo, determine qual dos drivers acima ele usa e, em seguida, carregue o driver. Por exemplo, se o dispositivo usar o driver ng_ubt(4):

    # kldload ng_ubt

Se o dispositivo Bluetooth for conectado ao sistema durante a inicialização do sistema, o sistema pode ser configurado para carregar o módulo no momento da inicialização, adicionando o driver ao `/boot/loader.conf`:

    ng_ubt_load="YES"

Quando o driver estiver carregado, conecte o dongle USB. Se a carga do driver tiver sido bem-sucedida, uma saída semelhante à seguinte deve aparecer no console e em `/var/log/messages`:

    ubt0: vendor 0x0a12 product 0x0001, rev 1.10/5.25, addr 2
    ubt0: Interface 0 endpoints: interrupt=0x81, bulk-in=0x82, bulk-out=0x2
    ubt0: Interface 1 (alt.config 5) endpoints: isoc-in=0x83, isoc-out=0x3,
          wMaxPacketSize=49, nframes=6, buffer size=294

Para iniciar e parar a stack Bluetooth, use seu script de inicialização. É uma boa ideia parar a stack antes de desconectar o dispositivo. Iniciar a stack bluetooth pode exigir que o hcsecd(8) seja iniciado. Ao iniciar a stack, a saída deve ser semelhante à seguinte:

    # service bluetooth start ubt0
    BD_ADDR: 00:02:72:00:d4:1a
    Features: 0xff 0xff 0xf 00 00 00 00 00
    <3-Slot> <5-Slot> <Encryption> <Slot offset>
    <Timing accuracy> <Switch> <Hold mode> <Sniff mode>
    <Park mode> <RSSI> <Channel quality> <SCO link>
    <HV2 packets> <HV3 packets> <u-law log> <A-law log> <CVSD>
    <Paging scheme> <Power control> <Transparent SCO data>
    Max. ACL packet size: 192 bytes
    Number of ACL packets: 8
    Max. SCO packet size: 64 bytes
    Number of SCO packets: 8

### 31.5.2. Encontrando outros dispositivos Bluetooth

A Interface do Controlador do Host (HCI) fornece um método uniforme para acessar os recursos de banda básica do Bluetooth. No FreeBSD, um nó netgraph HCI é criado para cada dispositivo Bluetooth. Para mais detalhes, consulte ng_hci(4).

Uma das tarefas mais comuns é a descoberta de dispositivos Bluetooth dentro da proximidade RF. Esta operação é chamada inquiry. Investigação e outras operações relacionadas a HCI são feitas usando hccontrol(8). O exemplo abaixo mostra como descobrir quais dispositivos Bluetooth estão ao alcance. A lista de dispositivos deve ser exibida em alguns segundos. Note que um dispositivo remoto só irá responder a pergunta se estiver configurado para o modo detectável.

    % hccontrol -n ubt0hci inquiry
    Inquiry result, num_responses=1
    Inquiry result #0
           BD_ADDR: 00:80:37:29:19:a4
           Page Scan Rep. Mode: 0x1
           Page Scan Period Mode: 00
           Page Scan Mode: 00
           Class: 52:02:04
           Clock offset: 0x78ef
    Inquiry complete. Status: No error [00]

O `BD_ADDR` é o endereço exclusivo de um dispositivo Bluetooth, semelhante ao endereço MAC de uma placa de rede. Este endereço é necessário para uma comunicação posterior com um dispositivo e é possível atribuir um nome legível a um `BD_ADDR`. Informações sobre os hosts Bluetooth conhecidos estão contidas em `/etc/bluetooth/hosts`. O exemplo a seguir mostra como obter o nome legível que foi atribuído ao dispositivo remoto:

    % hccontrol -n ubt0hci remote_name_request 00:80:37:29:19:a4
    BD_ADDR: 00:80:37:29:19:a4
    Name: Pav's T39

Se uma consulta for realizada em um dispositivo Bluetooth remoto, ele encontrará o computador como “your.host.name (ubt0)”. O nome atribuído ao dispositivo local pode ser alterado a qualquer momento.

Dispositivos remotos podem receber aliases em `/etc/bluetooth/hosts`. Maiores informações sobre o arquivo `/etc/bluetooth/hosts` podem ser encontradas em bluetooth.hosts(5).

O sistema Bluetooth fornece uma conexão ponta-a-ponto entre duas unidades Bluetooth ou uma conexão ponto-a-multiponto que é compartilhada entre vários dispositivos Bluetooth. O exemplo a seguir mostra como criar uma conexão a um dispositivo remoto:

    % hccontrol -n ubt0hci create_connection BT_ADDR

O `create_connection` aceita `BT_ADDR`, bem como aliases de host em `/etc/bluetooth/hosts`.

O exemplo a seguir mostra como obter a lista de conexões de banda base ativas para o dispositivo local:

    % hccontrol -n ubt0hci read_connection_list
    Remote BD_ADDR    Handle Type Mode Role Encrypt Pending Queue State
    00:80:37:29:19:a4     41  ACL    0 MAST    NONE       0     0 OPEN

Um identificador de conexão é útil quando a finalização da conexão de banda base é necessária, embora normalmente não seja necessário fazer isso manualmente. A stack terminará automaticamente as conexões de banda básica inativas.

    # hccontrol -n ubt0hci disconnect 41
    Connection handle: 41
    Reason: Connection terminated by local host [0x16]

Digite `hccontrol help` para obter uma lista completa dos comandos HCI disponíveis. A maioria dos comandos HCI não requer privilégios de superusuário.

### 31.5.3. Emparelhamento de dispositivos

Por padrão, a comunicação Bluetooth não é autenticada e qualquer dispositivo pode conversar com qualquer outro dispositivo. Um dispositivo Bluetooth, como um telefone celular, pode optar por exigir autenticação para fornecer um serviço específico. A autenticação Bluetooth é normalmente feita com um PIN code, uma string ASCII com até 16 caracteres de comprimento. O usuário é obrigado a digitar o mesmo código de PIN em ambos os dispositivos. Depois que o usuário inserir o código de PIN, ambos os dispositivos gerarão uma chave de link. Depois disso, a chave de link pode ser armazenada nos dispositivos ou em um armazenamento persistente. Na próxima vez, os dois dispositivos usarão a chave de link gerada anteriormente. Este procedimento é chamado de emparelhamento. Observe que, se a chave de link for perdida por um dos dispositivos, o emparelhamento deverá ser repetido.

O daemon hcsecd(8) é responsável por tratar os pedidos de autenticação Bluetooth. O arquivo de configuração padrão é o `/etc/bluetooth/hcsecd.conf`. Uma seção de exemplo para um telefone celular com o código PIN definido como `1234` é mostrada abaixo:

    device {
            bdaddr  00:80:37:29:19:a4;
            name    "Pav's T39";
            key     nokey;
            pin     "1234";
          }

A única limitação nos códigos de PIN é o comprimento. Alguns dispositivos, como fones de ouvido Bluetooth, podem ter um código PIN integrado fixo. A opção `-d` força o hcsecd(8) a ficar em primeiro plano, então é fácil ver o que está acontecendo. Configure o dispositivo remoto para receber o emparelhamento e inicie a conexão Bluetooth ao dispositivo remoto. O dispositivo remoto deve indicar que o pareamento foi aceito e solicitar o código de PIN. Digite o mesmo código de PIN listado em `hcsecd.conf`. Agora o computador e o dispositivo remoto estão emparelhados. Alternativamente, o emparelhamento pode ser iniciado no dispositivo remoto.

A seguinte linha pode ser adicionada ao `/etc/rc.conf` para configurar o hcsecd(8) para iniciar automaticamente quando o sistema inicializar:

    hcsecd_enable="YES"

A seguir, um exemplo da saída do daemon hcsecd(8):

    hcsecd[16484]: Got Link_Key_Request event from 'ubt0hci', remote bdaddr 0:80:37:29:19:a4
    hcsecd[16484]: Found matching entry, remote bdaddr 0:80:37:29:19:a4, name 'Pav's T39', link key doesn't exist
    hcsecd[16484]: Sending Link_Key_Negative_Reply to 'ubt0hci' for remote bdaddr 0:80:37:29:19:a4
    hcsecd[16484]: Got PIN_Code_Request event from 'ubt0hci', remote bdaddr 0:80:37:29:19:a4
    hcsecd[16484]: Found matching entry, remote bdaddr 0:80:37:29:19:a4, name 'Pav's T39', PIN code exists
    hcsecd[16484]: Sending PIN_Code_Reply to 'ubt0hci' for remote bdaddr 0:80:37:29:19:a4

### 31.5.4. Acesso à rede com perfis PPP

Um perfil de rede dial-up (DUN) pode ser usado para configurar um telefone celular como um modem sem fio para a conexão a um servidor de acesso à Internet dial-up. Também pode ser usado para configurar um computador para receber chamadas de dados de um telefone celular.

O acesso à rede com um perfil PPP pode ser usado para fornecer acesso LAN a um único dispositivo Bluetooth ou a vários dispositivos Bluetooth. Ele também pode fornecer uma conexão PC para PC usando uma rede PPP sobre uma emulação de cabo serial.

No FreeBSD, esses perfis são implementados com o ppp(8) e o wrapper rfcomm_pppd(8) que converte uma conexão Bluetooth em algo que o PPP pode usar. Antes que um perfil possa ser usado, um novo label PPP deve ser criado em `/etc/ppp/ppp.conf`. Consulte rfcomm_pppd(8) para exemplos.

Neste exemplo, o rfcomm_pppd(8) é usado para abrir uma conexão com um dispositivo remoto com um `BD_ADDR` de `00:80:37:29:19:a4` em um canal DUN RFCOMM:

    # rfcomm_pppd -a 00:80:37:29:19:a4 -c -C dun -l rfcomm-dialup

O número real do canal será obtido a partir do dispositivo remoto usando o protocolo SDP. É possível especificar manualmente o canal RFCOMM e, nesse caso, o rfcomm_pppd(8) não executará a consulta SDP. Use o sdpcontrol(8) para descobrir o canal RFCOMM no dispositivo remoto.

Para fornecer acesso à rede com o serviço PPP LAN, o sdpd(8) precisa estar sendo executado e uma nova entrada para clientes LAN deve ser criada em `/etc/ppp/ppp.conf`. Consulte rfcomm_pppd(8) para exemplos. Por fim, inicie o servidor RFCOMM PPP em um número de canal RFCOMM válido. O servidor RFCOMM PPP registrará automaticamente o serviço Bluetooth LAN com o daemon local SDP. O exemplo abaixo mostra como iniciar o servidor RFCOMM PPP.

    # rfcomm_pppd -s -C 7 -l rfcomm-server

### 31.5.5. Protocolos Bluetooth

Esta seção fornece uma visão geral dos vários protocolos Bluetooth, suas funções e utilitários associados.

#### 31.5.5.1. Controle de Link Lógico e Protocolo de Adaptação (L2CAP)

O Protocolo de Adaptação e Controle de Link Lógico (L2CAP) fornece serviços de dados orientados a conexão e sem conexão para protocolos de camada superior. O L2CAP permite que protocolos e aplicativos de alto nível transmitam e recebam pacotes de dados L2CAP de até 64 kilobytes de comprimento.

O L2CAP é baseado no conceito de canais. Um canal é uma conexão lógica em cima de uma conexão de banda base, na qual cada canal é vinculado a um único protocolo de maneira many-to-one. Vários canais podem ser vinculados ao mesmo protocolo, mas um canal não pode ser vinculado a vários protocolos. Cada pacote L2CAP recebido em um canal é direcionado para o protocolo apropriado de nível superior. Vários canais podem compartilhar a mesma conexão de banda base.

No FreeBSD, um nó netgraph L2CAP é criado para cada dispositivo Bluetooth. Esse nó é normalmente conectado ao nó Bluetooth HCI downstream e aos nós de soquete Bluetooth upstream. O nome padrão para o nó L2CAP é “devicel2cap”. Para mais detalhes, consulte ng_l2cap(4).

Um comando útil é o l2ping(8), que pode ser usado para executar ping em outros dispositivos. Algumas implementações Bluetooth podem não retornar todos os dados enviados para elas, portanto, a saída `0 bytes` no exemplo a seguir é normal.

    # l2ping -a 00:80:37:29:19:a4
    0 bytes from 0:80:37:29:19:a4 seq_no=0 time=48.633 ms result=0
    0 bytes from 0:80:37:29:19:a4 seq_no=1 time=37.551 ms result=0
    0 bytes from 0:80:37:29:19:a4 seq_no=2 time=28.324 ms result=0
    0 bytes from 0:80:37:29:19:a4 seq_no=3 time=46.150 ms result=0

O utilitário l2control(8) é usado para executar várias operações em nós L2CAP. Este exemplo mostra como obter a lista de conexões lógicas (canais) e a lista de conexões de banda base para o dispositivo local:

    % l2control -a 00:02:72:00:d4:1a read_channel_list
    L2CAP channels:
    Remote BD_ADDR     SCID/ DCID   PSM  IMTU/ OMTU State
    00:07:e0:00:0b:ca    66/   64     3   132/  672 OPEN
    % l2control -a 00:02:72:00:d4:1a read_connection_list
    L2CAP connections:
    Remote BD_ADDR    Handle Flags Pending State
    00:07:e0:00:0b:ca     41 O           0 OPEN

Outra ferramenta de diagnóstico é o btsockstat(1). Ele é semelhante ao netstat(1), mas para estruturas de dados relacionadas à rede Bluetooth. O exemplo abaixo mostra a mesma conexão lógica que l2control(8) acima.

    % btsockstat
    Active L2CAP sockets
    PCB      Recv-Q Send-Q Local address/PSM       Foreign address   CID   State
    c2afe900      0      0 00:02:72:00:d4:1a/3     00:07:e0:00:0b:ca 66    OPEN
    Active RFCOMM sessions
    L2PCB    PCB      Flag MTU   Out-Q DLCs State
    c2afe900 c2b53380 1    127   0     Yes  OPEN
    Active RFCOMM sockets
    PCB      Recv-Q Send-Q Local address     Foreign address   Chan DLCI State
    c2e8bc80      0    250 00:02:72:00:d4:1a 00:07:e0:00:0b:ca 3    6    OPEN

#### 31.5.5.2. Comunicação por radiofrequência (RFCOMM)

O protocolo RFCOMM fornece emulação de portas seriais sobre o protocolo L2CAP. O RFCOMM é um protocolo de transporte simples, com disposições adicionais para emular os 9 circuitos das portas seriais RS-232 (EIATIA-232-E). Suporta até 60 conexões simultâneas (canais RFCOMM) entre dois dispositivos Bluetooth.

Para fins do RFCOMM, um caminho de comunicação completo envolve dois aplicativos em execução nos terminais de comunicação com um segmento de comunicação entre eles. O RFCOMM destina-se a abranger aplicativos que fazem uso das portas seriais dos dispositivos em que residem. O segmento de comunicação é um link Bluetooth de conexão direta de um dispositivo para outro.

O RFCOMM está relacionado apenas com a conexão entre os dispositivos no caso de conexão direta ou entre o dispositivo e um modem no caso de rede. O RFCOMM pode suportar outras configurações, como módulos que se comunicam via tecnologia sem fio Bluetooth de um lado e fornecem uma interface com fio no outro lado.

No FreeBSD, o RFCOMM é implementado na camada de sockets do Bluetooth.

#### 31.5.5.3. Protocolo de Descoberta de Serviços (SDP)

O Protocolo de Descoberta de Serviços (SDP) fornece os meios para os aplicativos clientes descobrirem a existência de serviços fornecidos por aplicativos de servidor, bem como os atributos desses serviços. Os atributos de um serviço incluem o tipo ou classe de serviço oferecido e as informações de mecanismo ou protocolo necessárias para utilizar o serviço.

O SDP envolve a comunicação entre um servidor SDP e um cliente SDP. O servidor mantém uma lista de registros de serviço que descrevem as características dos serviços associados ao servidor. Cada registro de serviço contém informações sobre um único serviço. Um cliente pode recuperar informações de um registro de serviço mantido pelo servidor SDP emitindo uma solicitação SDP. Se o cliente, ou um aplicativo associado ao cliente, decidir usar um serviço, ele deverá abrir uma conexão separada com o provedor de serviços para utilizar o serviço. O SDP fornece um mecanismo para descobrir serviços e seus atributos, mas não fornece um mecanismo para utilizar esses serviços.

Normalmente, um cliente SDP procura serviços baseados em algumas características desejadas dos serviços. No entanto, há momentos em que é desejável descobrir quais tipos de serviços são descritos pelos registros de serviço de um servidor SDP, sem qualquer informação prévia sobre os serviços. Este processo de procurar por qualquer serviço oferecido é chamado de navegação.

O servidor Bluetooth SDP, sdpd(8) e o cliente de linha de comandos, sdpcontrol(8), estão incluídos na instalação padrão do FreeBSD. O exemplo a seguir mostra como executar uma consulta de navegação SDP.

    % sdpcontrol -a 00:01:03:fc:6e:ec browse
    Record Handle: 00000000
    Service Class ID List:
            Service Discovery Server (0x1000)
    Protocol Descriptor List:
            L2CAP (0x0100)
                    Protocol specific parameter #1: u/int/uuid16 1
                    Protocol specific parameter #2: u/int/uuid16 1

    Record Handle: 0x00000001
    Service Class ID List:
            Browse Group Descriptor (0x1001)

    Record Handle: 0x00000002
    Service Class ID List:
            LAN Access Using PPP (0x1102)
    Protocol Descriptor List:
            L2CAP (0x0100)
            RFCOMM (0x0003)
                    Protocol specific parameter #1: u/int8/bool 1
    Bluetooth Profile Descriptor List:
            LAN Access Using PPP (0x1102) ver. 1.0

Observe que cada serviço tem uma lista de atributos, como o canal RFCOMM. Dependendo do serviço, o usuário pode precisar anotar alguns dos atributos. Algumas implementações Bluetooth não suportam a navegação de serviço e podem retornar uma lista vazia. Nesse caso, é possível procurar pelo serviço específico. O exemplo abaixo mostra como pesquisar o serviço OBEX Object Push (OPUSH) :

    % sdpcontrol -a 00:01:03:fc:6e:ec search OPUSH

A oferta de serviços no FreeBSD para clientes Bluetooth é feita com o servidor sdpd(8). A seguinte linha pode ser adicionada ao `/etc/rc.conf`:

    sdpd_enable="YES"

Então o daemon sdpd(8) pode ser iniciado com:

    # service sdpd start

O aplicativo de servidor local que deseja fornecer um serviço Bluetooth a clientes remotos registrará o serviço com o daemon SDP local . Um exemplo de tal aplicativo é o rfcomm_pppd(8). Uma vez iniciado, ele registrará o serviço LAN Bluetooth com o daemon local SDP.

A lista de serviços registrados no servidor SDPlocal pode ser obtida através da emissão de uma consulta de navegação SDP através do canal de controle local:

    # sdpcontrol -l browse

#### 31.5.5.4. OBEX Object Push (OPUSH)

Object Exchange (OBEX) é um protocolo amplamente utilizado para transferências de arquivos simples entre dispositivos móveis. Seu principal uso é na comunicação por infravermelho, onde é usado para transferências de arquivos genéricos entre notebooks ou PDAs, e para enviar cartões de visita ou entradas de calendário entre telefones celulares e outros dispositivos com Personal Information Manager (PIM).

O servidor e o cliente OBEX são implementados pelo obexapp, que pode ser instalado usando o pacote ou port comms/obexapp.

O cliente OBEX é usado para empurrar e/ou puxar objetos do servidor OBEX. Um exemplo de objeto é um cartão de visita ou um compromisso. O cliente OBEX pode obter o número do canal RFCOMM do dispositivo remoto via SDP. Isso pode ser feito especificando o nome do serviço em vez do número do canal RFCOMM. Os nomes de serviços suportados são: `IrMC`, `FTRN` e `OPUSH`. Também é possível especificar o canal RFCOMM como um número. Abaixo está um exemplo de uma sessão OBEX em que o objeto de informações do dispositivo é extraído do telefone celular e um novo objeto, o cartão de visita, é inserido no diretório do telefone.

    % obexapp -a 00:80:37:29:19:a4 -C IrMC
    obex> get telecom/devinfo.txt devinfo-t39.txt
    Success, response: OK, Success (0x20)
    obex> put new.vcf
    Success, response: OK, Success (0x20)
    obex> di
    Success, response: OK, Success (0x20)

Para fornecer o serviço OPUSH, o sdpd(8) deve estar em execução e uma pasta raiz, onde todos os objetos recebidos serão armazenados, deve ser criado. O caminho padrão para a pasta raiz é `/var/spool/obex`. Por fim, inicie o servidor OBEX em um número de canal RFCOMM válido. O servidor OBEX registrará automaticamente o serviço OPUSH com o daemon SDP local. O exemplo abaixo mostra como iniciar o servidor OBEX.

    # obexapp -s -C 10

#### 31.5.5.5. Perfil de porta serial (SPP)

O perfil de porta serial (SPP) permite que dispositivos Bluetooth executem emulação de cabo serial. Este perfil permite que aplicativos legados usem o Bluetooth como um substituto de cabos, através de uma abstração de porta serial virtual.

No FreeBSD, o rfcomm_sppd(1) implementa o SPP e uma pseudo tty é usada como uma abstração de porta serial virtual. O exemplo abaixo mostra como se conectar ao serviço de porta serial de um dispositivo remoto. Um canal RFCOMM não precisa ser especificado uma vez que o rfcomm_sppd(1) pode obtê-lo a partir do dispositivo remoto via SDP. Para sobrescrever isso, especifique um canal RFCOMM na linha de comando.

    # rfcomm_sppd -a 00:07:E0:00:0B:CA -t
    rfcomm_sppd[94692]: Starting on /dev/pts/6...
    /dev/pts/6

Uma vez conectado, o pseudo-tty pode ser usado como porta serial:

    # cu -l /dev/pts/6

A pseudo-tty é impressa no stdout e pode ser lida por scripts de wrapper:

    PTS=`rfcomm_sppd -a 00:07:E0:00:0B:CA -t`
    cu -l $PTS

### 31.5.6. Solução de problemas

Por padrão, quando o FreeBSD está aceitando uma nova conexão, ele tenta executar uma troca de função e se tornar o mestre. Alguns dispositivos Bluetooth mais antigos que não suportam a troca de função não poderão se conectar. Como a troca de função é executada quando uma nova conexão está sendo estabelecida, não é possível perguntar ao dispositivo remoto se ele suporta a troca de função. No entanto, há uma opção HCI para desativar a alternância de funções no lado local:

    # hccontrol -n ubt0hci write_node_role_switch 0

Para exibir pacotes Bluetooth, use o pacote de terceiros hcidump, que pode ser instalado usando o pacote ou port comms/hcidump. Este utilitário é semelhante ao tcpdump(1) e pode ser usado para exibir o conteúdo dos pacotes Bluetooth no terminal e para descarregar os pacotes Bluetooth para um arquivo.

Anterior | Acima | Próxima
31.4. USB Tethering | Principal | 31.6. Bridging

All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.