Espelhamento dos sinais USB HID no Open WRT através do UART [closed]

1

A configuração: uma placa Linkit (Smart 7688 Duo) executando o OpenWRT e um teclado genérico conectado no host USB.

O objetivo: descarregar o sinal que recebemos do / dev / input / event0 e enviá-lo através do UART nativo do quadro para o Atmega32u4. Então, este Atmega age como um teclado para a máquina que está conectada.

O que eu tenho até agora: não é difícil obter os sinais do teclado no OpenWRT e enviá-lo para o atmega via serial. Mas fazer o Atmega agir como um teclado real (real!) É o verdadeiro problema.

Eu uso um script python com base nessa resposta para simplificar visualização dos dados e posso facilmente enviá-lo para o console do Arduino IDE via serial. Assim, com uma simples instrução Keyboard.press () em um esboço arduino eu reproduzo o pressionamento de tecla na máquina o que o ATmega está agindo como um HID.

Parece bastante simples, e é quando você só precisa imitar um simples pressionamento de tecla. Mas é muito complicado reproduzir todas as características de um teclado real, como pressionamentos simultâneos de teclas, modificadores, caps lock, etc.

Alguém já tentou algo parecido?

PS .: Minha idéia é modificar a classe de teclado do Arduino para poder enviar KeyReports da maneira que eu quiser com os dados brutos recebidos do OpenWRT, mas como eu disse, acaba sendo muito complicado. Eu só não quero fazer declarações para todos os tipos de dados recebidos e dizer ao Atmega para executar a chave correspondente. Eu acho que há uma maneira de simplesmente espelhar os sinais.

EDITAR:

Muito obrigado a @dirkt por colocar tanto esforço e tempo ajudando. Foi uma discussão muito produtiva e aprendi muito. Você chegou perto da resposta que eu preciso quando disse que o relatório que recebemos de / dev / hidraw0 implementará todas as chaves especiais do outro lado.

Então, reformulando a questão com as informações coletadas: Como obtenho o relatório do teclado no formato: [modificador, reservado, chave, chave, chave, chave, chave, tecla]

O / dev / hidraw0 retorna a chave e o evento (1: pressione 0: release 2: hold), mas não vejo como obter o byte modificador. (vamos esquecer o reservado por enquanto)

    
por Diego Dyan 04.09.2018 / 13:11

1 resposta

0

Resposta parcial:

Vamos organizar algumas coisas primeiro.

Se eu entendi corretamente, o OpenWRT está sendo executado no MPU (MT7688). O MPU vê o MCU (ATmega) atrás do UART, e o MPU tem um controlador USB ao qual um teclado genérico USB HID está conectado.

No kernel, a tecla pressiona e percorre as seguintes camadas:

keyboard -> USB -> HID -> input

Assim, o teclado envia pacotes USB como "interrupções", que contêm dados do relatório HID. Os dados HID são descritos no descritor HID e, para teclados, normalmente você tem o byte de um modificador e até seis pressionamentos de tecla simultâneos. Mas outros formatos são possíveis. Você pode ler relatórios ocultos brutos de /dev/hidrawX . Os relatórios HID são convertidos em eventos de camada de entrada do kernel, que contêm uma única tecla de pressionamento / liberação, e esses são aqueles que você lê em /dev/input/event0 .

Nada disso tem nada a ver com a UART ou o ATmega por trás dela.

Agora existem maneiras de conectar um dispositivo HID através de outros busses à camada do kernel, em vez de via USB. Por exemplo, sobre o I2C ou sobre o UART.

É isso que você quer? Novamente, isso não tem nada a ver com a presença dos eventos de teclado USB em /dev/input/event0 .

Outra opção é inventar seu próprio protocolo privado, qualquer que seja a sua cara, rodar um lado no ATmega e rodar um pequeno programa em C que registre um novo dispositivo em camada de entrada via uinput , lê o UART e, em seguida, envia o evento da camada de entrada.

É isso que você quer? Novamente, isso não tem nada a ver com a presença de eventos de teclado USB em /dev/input/event0 ou com o encaminhamento desses eventos para a UART.

Ou você quer pegar os eventos de teclado do MPU, enviá-los para o ATmega, processá-los lá, enviá-los de volta e fazer com que eles atuem como eventos de entrada reais? É claro que é possível, entretanto você tem que se perguntar por que você não faz este processamento no MPU em primeiro lugar.

Então, por favor descreva seu objetivo real . No momento, é um pouco incerto. Você pode mexer com a camada de entrada do Linux, você pode mexer com a camada HID do Linux, você pode injetar eventos em ambas as camadas e fazer tudo o que quiser. Os formatos não são particularmente difíceis. Você só precisa ser específico sobre o que você quer.

Modify the Arduino keyboard class to be able to send KeyReports the way I want with the raw data received from OpenWRT

não faz muito sentido. Não há "classe de teclado Arduino" na camada do kernel. Se você está usando uma "classe de teclado Arduino" como parte do seu sistema de desenvolvimento, por favor associe a ela. E provavelmente não vai ajudar muito, você precisará entender os outros formatos (relatório HID, evento da camada de entrada) também.

Editar

Então, para recapitular (na próxima vez que você fizer um problema, por favor, descreva-o de forma semelhante. Também dê uma olhada no problema com Perguntas XY ):

You want to have an intermediary device between a USB keyboard and some other computer, where the other computer should just see an ordinary keyboard, and on the device you can do keylogging, trigger other events etc. (You still haven't specified if it is necessary that this intermediary device is actual hardware, or if it is also possible to install something on the PC that will either help with the task, or do the extra processing of the keyboard events.)

For that, you wanted to use a Linkit board. The MPU on the Linkit board acts as USB host to the keyboard. It is connected via an UART to the MCU (an ATmega), which itself can act as a USB HID device, which in turn can be connected to the other PC.

Para atuar como um dispositivo USB HID, o MCU precisa fazer três coisas: ele precisa ter um descritor HID que descreva os relatórios, ele precisa enviar relatórios de imprensa do teclado HID e precisa reagir aos relatórios HID de o PC para definir os LEDs do teclado, etc. Eu suponho que você tem uma biblioteca para o ATmega que lida com tudo isso para você.

A abordagem mais simples é simplesmente copiar o descritor HID do teclado USB real. Você pode encontrar o descritor HID em formato legível em /sys/kernel/debug/hid/DEVICE_ID/rdesc , onde DEVICE_ID identifica seu teclado. Analise o hexadecimal no início dele ou descubra se há ioctls onde você pode obter essas informações diretamente.

Então você precisa de um pequeno programa no MPU que usa um protocolo ad-hoc para se comunicar com o ATmega. Ele tem que fazer o seguinte: (1) Se um dispositivo USB hid conectar, ler e analisar o descritor HID, envie o descritor HID para ATmega. (2) Agora insira um loop e reporte os relatórios HID de /dev/hidrawN , onde N é o número do teclado via UART, e também escreva os relatórios HID recebidos do UART para /dev/hidrawN . (3) Envie uma mensagem de "saída" se o teclado USB desconectar.

No ATmega, você precisa de um pequeno programa que implemente o outro lado, usando a biblioteca HID disponível.

Você pode escolher em qual lado implementar o registro de chaves, etc.

Pressionamentos simultâneos de teclas, maiúsculas e minúsculas, etc., são automaticamente tratados pelo encaminhamento dos relatórios da HID.

    
por 04.09.2018 / 15:22