ÍNDICE DE CONTEÚDO
Já pensou o quão útil pode ser saber se um determinado periférico USB (mouse, teclado, câmera e afins) foi conectado ou desconectado de seu projeto Linux embarcado?
Vamos exemplificar pensando em um terminal de autoatendimento ou tótem, o qual possui periféricos como display touchscreen, máquina de cartões e etc, acredito ser interessante saber se houve alteração na conexão dos periféricos e quando isto ocorreu. Podendo criar scripts para salvar logs de conexões ou até mesmo enviar os dados para a internet.
Recentemente em um projeto pessoal, me deparei com a necessidade de saber quando um determinado dispositivo USB foi conectado ou desconectado de uma Raspberry pi. Portanto, gostaria de compartilhar nesse artigo a experiência que tive em atender a necessidade.
Por razões didáticas, simplificaremos a situação utilizando um dispositivo Linux embarcado, no caso uma Beaglebone Green e um pendrive para simular o periférico que desejamos monitorar a conexão e desconexão. O intuito dessa simplificação será apenas criar um arquivo txt informando a data do evento e o tipo de evento (conexão ou desconexão).
Apenas evidenciando, o intuito desse artigo é apresentar que é possível aproveitar os eventos de conexão e desconexão dos periféricos USB para criar automações em aplicações Linux, apresentando um exemplo inicial de como criar as automações utilizando a ferramenta udev do Linux.
Requisitos
Este artigo é destinado a todas as pessoas que tenham contato ou interesse em trabalhar com Linux e criar automações. Entretanto, é recomendando principalmente para a execução da parte prática conhecimentos nos seguintes assuntos:
- Básico em Linux;
- Básico em manipulação do terminal do Linux;
- Básico em python.
Conhecendo o uDEV
O uDEV trata-se de um gerenciador de dispositivos para Linux, considerado como sucessor do devfsd e hotplug. Na prática, o udev é responsável por comunicar ao sistema operacional sobre os dispositivos físicos conectados ao hardware, baseado nas informações recebidas do kernel. Caso deseje obter mais informações acerca do udev, recomendo a leitura do seguinte artigo.
Assim como seus antecessores já citados, o udev também gerencia os dispositivos conectados, criando um subdiretório específico para cada dispositivo em /dev, por exemplo:
1 |
/dev/sda |
Uma característica interessante do udev de mencionar é a possibilidade de criar scripts para os eventos recebidos via kernel, scripts os quais são chamados de rules. Na próxima secção abordamos em detalhes as rules do udev.
Regras uDEV
Como já mencionado, o udev é capaz de notificar o sistema operacional sobre as alterações nas conexões dos periféricos, além disso, ele permite o registro de manipuladores de eventos (em inglês, Event Handlers) personalizados, ou seja, é possível criar scripts para serem executados quando o udev detecta uma alteração específica no periférico. Exemplificando, é possível criar um script para ser executado sempre que um determinado dispositivo é desconectado.
Os scripts mencionados são chamados de regras (em inglês, rules). Existem dois níveis de regras, as regras de administrador salvas em /etc/udev/rules.d/ e as regras de usuários salvas em /usr/lib/udev/rules.d/. As regras de administrador precedem as regras de usuário na inicialização do udev.
Existe uma sintaxe própria para a criação de regras, baseadas em comandos e chaves, recomendo a leitura dessa especificação para maior detalhamento. Para este artigo, vamos nos ater aos seguintes comandos.
Comando | Descrição |
+= | Adicionar valor ao final da lista de valores presentes na chave |
== | Comparar igualdade entre valores |
= | Definir valor para chave |
Com relação as chaves, o quadro abaixo apresenta as chaves abordadas no exemplo prático.
Chave | Descrição |
ACTION | Nome da ação do evento desejado (exemplos: “add”, “remove”) |
SUBSYSTEM | Nome do subsistema onde deseja-se capturar o evento |
ENV{chave} | Utilizado para acessar uma propriedade do dispositivo |
RUN | Corresponde à ação que se deseja executar caso a regra seja ativada |
Desenvolvimento prático
Certo, chegou o momento de “colocarmos a mão na massa”. Utilizei uma Beaglebone green para fazer o artigo, mas na prática, esse procedimento é válido para qualquer dispositivo Linux que possua o udev. Foi utilizado um pen drive San Disk para fazermos os testes de conexão/desconexão.
Coletando informações do dispositivo USB
A primeira etapa é verificar como o udev identifica os eventos de conexão e desconexão do periférico de testes, para isso digite no terminal.
1 |
sudo udevadm monitor -p |
Com a inserção do comando, você poderá verificar as informações dos eventos recebidos e os detalhes do dispositivo. Conecte o periférico USB e verifique a saída do terminal, deve ver algo parecido com a imagem abaixo.
Da imagem acima utilizaremos as informações de ID_VENDOR_ID, ID_MODEL_ID, DEVTYPE e SUBSYSTEM, de preferência salve as informações mencionadas. Em seguida, desconecte o periférico USB. A imagem abaixo exemplifica como devem ser as mensagens recebidas na saída no terminal.
Utilizaremos as informações de SUBSYSTEM, DEVTYPE e PRODUCT. Com todas as informações coletadas, é possível criar a rule no udev.
Criando os scripts
Como mencionado no início desse artigo, deseja-se criar um arquivo de log simples indicando a conexão e desconexão do pen drive. Com o intuito puramente didático, criaremos dois scripts python, um para salvar o evento de conexão e o outro para salvar o evento de desconexão.
O código do script de conexão (arquivo connected.py) é apresentado abaixo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from datetime import datetime import os ''' Funcao principal ''' def main(): #pega a data atual now = datetime.now() caminho = "/home/debian/usb-automation/" #salvar o log with open(caminho + "log.txt", "a") as file: file.write(f'{now.strftime("%d/%m/%Y %H:%M:%S")} - Dispositivo Conectado\r\n') #executa a funcao principal main() |
O código do script de desconexão (arquivo disconnected.py) é apresentado abaixo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from datetime import datetime import os ''' Funcao principal ''' def main(): #pega a data atual now = datetime.now() caminho = "/home/debian/usb-automation/" #salvar o log with open(caminho + "log.txt", "a") as file: file.write(f'{now.strftime("%d/%m/%Y %H:%M:%S")} - Dispositivo Desconectado\r\n') #executa a funcao principal main() |
Caso você não tenha conhecimento em python, recomendo a leitura desse artigo que indica alguns livros para o estudo da tecnologia.
Dando sequência ao procedimento, coloque ambos os scripts em uma pasta, no meu caso coloquei os arquivos em /home/debian/usb-automation. Caso você queira alterar o caminho onde os scripts serão salvos, altere a variável caminho presente nos scripts, com o caminho atual de onde estão localizados os scripts.
Criando as regras
Conhecendo as informações do dispositivo, podemos criar a regra udev para detectar a conexão e desconexão do pen drive. Usando o terminal, criaremos o arquivo de regra chamado “pen-drive.rules” por meio do editor de texto nano. Para isso, digite o seguinte comando.
1 |
sudo nano /etc/udev/rules.d/pen-drive.rules |
Após inserção do comando, o nano abrirá um arquivo em branco. Agora basta digitar a seguinte regra.
1 2 |
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_VENDOR_ID}=="0781", ENV{ID_MODEL_ID}=="5567", RUN+="/usr/bin/python3 /home/debian/usb-automation/connected.py" ACTION=="remove", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="781/5567/127", RUN+="/usr/bin/python3 /home/debian/usb-automation/disconnected.py" |
Analisando a regra acima e destacando os principais pontos, começando pela primeira linha de comando, temos a chave ACTION com o valor “add” o que significa que deseja-se criar uma regra para o evento de conexão, temos a chave ENV{ID_MODEL_ID} com o valor “5567” o qual indica o device id do dispositivo que queremos monitorar.
Prosseguindo a análise, a chave ENV{ID_VENDOR_ID} está com o valor “0781” indicando o vendor id do pen drive, por fim, a chave RUN recebe o valor “/usr/bin/python3 /home/debian/usb-automation/connected.py” indicando que o script python de conexão deve ser executado quando o udev detectar a conexão do pen drive.
Ainda fazendo análise, a segunda linha da regra é similar a primeira linha, porém com algumas ressalvas, sendo elas:
- Chave ACTION recebe valor “remove”, pois é desejado verificar a desconexão.
- Chave RUN recebe o valor que indica a execução do script python para desconexão.
Após a criação do arquivo de regra, devemos atualizar a tabela de regras e forçar o recarregamento das regras. Digite o seguinte comando no terminal.
1 |
sudo udevadm control --reload-rules ; sudo udevadm trigger |
Após inserção dos comandos, a regra deve ser recarregada e já estará em execução.
Teste Prático
Certo, chegou o momento de validar a regra salva no udev e os scripts python. Para testar, conecte o periférico usb desejado e verifique no arquivo log.txt se o script registou o evento de conexão, faça o mesmo para o evento de desconexão.
Conclusão
O udev é um gerenciador de dispositivos para Linux, o qual proporciona a abstração dos periféricos conectados, facilitando o uso dos periféricos nos ambientes Linux. Outro ponto importante de ser mencionado é a capacidade de criar scripts, chamados de rules, que são executados quando o udev detecta uma alteração específica no periférico.
A capacidade de criar rules amplia as possibilidades para os projetos Linux, pois é possível agregar mais dados sobre os periféricos conectados em sua aplicação, podendo assim, agregar maior valor para seu projeto.
Os resultados demonstrados nesse artigo comprovam a eficácia e a facilidade de uso do udev em aplicações.
Referências
BUENO, Cleiton. Linux – O poderoso udev. 2015. Disponível em: https://cleitonbueno.com/linux-o-poderoso-udev/. Acesso em: 05 fev. 2022.
UDEV. Disponível em: https://wiki.archlinux.org/title/udev#About_udev_rules. Acesso em: 05 fev. 2022.
Será que tem como eu enganar o android conectado na porta usb do meu pc, fazendo o sistema android ver um mouse em vez de um pc conectado, para mandar os sinais do mouse do pc para o android?
Sabe como se meu pc fosse o “cabo OTG” que liga o meu mouse ao android
Fala Miqueias!! Tudo certo?
Até onde eu vi, aparentemente é possível fazer algo parecido com o que você deseja usando o ADB. Dá uma procurada no google sobre “ADB Mouse Events” você consegue simular um mouse enviando comandos no ADB.
Agradeço o comentário. Abraços!!
Yago Caetano
Ficou muito bom o artigo e de forma clara!