Passei horas tentando remapear as teclas Fn de um teclado DNA59 (Wings Tech MWV602) no Linux. Consegui decodificar boa parte do protocolo proprietário, confirmei que as teclas Fn são tratadas como estado interno no firmware, e descobri exatamente onde o processo trava antes de uma gravação definitiva.
Contexto
Tenho um teclado DNA59, comercializado como Wings Tech Gaming Keyboard, VID:PID 2EA8:2122. Ele vem com um app Windows (DNA59_Setup_v1.0_20220303.exe) que permite, entre outras coisas, remapear teclas, incluindo as duas teclas Fn físicas.
O objetivo era simples: mapear
- Fn esquerda → = e +
- Fn direita → \ e |
O problema: no Linux, esse fluxo de configuração não funciona out of the box. O que se segue é um relato técnico do processo de investigação.
Ambiente: Rtix Linux, pasta de trabalho ~/Downloads/DNA59.
Passo 1: tentativa direta com keyd
A primeira tentativa foi a mais óbvia, configurar o keyd para interceptar e remapear as teclas Fn no nível do sistema.
Funciona para teclas normais sem problema. Mas as teclas Fn físicas desse teclado não geram eventos HID independentes. Elas não aparecem no evtest, não produzem keycodes, não existem do ponto de vista do kernel. A razão só ficaria clara depois.
Passo 2: captura USB com usbmon/tshark
Com keyd descartado para as Fn, a próxima etapa foi observar o que o app Windows manda para o teclado. Para isso: usbmon no barramento correto (usbmon2) e captura com tshark.
As capturas mostraram tráfego HID normal para teclas comuns. Mas sem uma VM com USB passthrough funcional para rodar o app oficial, não foi possível capturar os pacotes reais de configuração de keymap que o app envia.
Passo 3: monitoramento de hidraw
Monitorei /dev/hidraw0 e /dev/hidraw1 em tempo real com um script Python (fn_monitor.py).
Resultado:
- Teclas normais: eventos aparecem no hidraw, keycodes HID padrão.
- Fn esquerda/direita: nenhum evento. Zero bytes. Silêncio completo.
Isso confirmou a hipótese: as teclas Fn não são reportadas via HID. Elas são processadas inteiramente dentro do firmware.
Passo 4: reverse engineering do firmware e do app
Aqui o trabalho ficou mais interessante.
Arquivos analisados
- ER_IROM1 - firmware principal (ARM)
- ER_IROM2 - dados e config em flash
- wtconfig.ini - configurações do app
- DNA59_Setup_v1.0_20220303.exe - app Windows
O que o wtconfig.ini revelou
App_Report_ID=4 PSD=0x18,0x08 ; 24 bytes write / 8 bytes read
O app usa SetFeature com payloads de 24 bytes, Report ID 0x04.
Decodificação do firmware (ER_IROM1)
O dispatch principal está em 0xF600. A estrutura do payload HID:
Byte Significado
| byte[0] | Report ID (0x04)
| byte[1] | Comando primário (0xA0..0xA9)
Comandos relevantes identificados:
- 0xA8 - key read (lê keymap da flash)
- 0xA6 - commit/save (grava remap na flash)
- 0xA7 - estado/toggle (aceita comando, teclado pisca)
- 0xA9 - sub-dispatch (LED, etc.)
A hipótese descartada
No início, assumi que "índice de firmware == HID usage". Errado.
O fluxo real é multicamada:
posição na matrix física
↓
índice interno
↓
tabela de transformação
↓
HID usage code final
As teclas Fn não percorrem esse caminho. Elas são tratadas como modificador de estado interno - nunca chegam a gerar um HID usage code. É por isso que são invisíveis para o kernel.
Passo 5: tentativas de escrita via hidraw
Com o protocolo parcialmente decodificado, tentei vários caminhos para enviar comandos de configuração direto pelo Linux.
Resultados
Tentativa Resultado
| read 109 / read 112 (índices Fn do .ini) | ok=0
| a0-readmeta | Resposta válida (01 18 0a)
| scan 0..255 em 0xA8 | Apenas índice 0 válido
| 0xA7 toggle | Teclado pisca - comando aceito
| 0xA3 probe | Sem índices úteis
| 0xA1 | Sem resposta
| SetFeature via ioctl em hidraw0/hidraw1 (24/25 bytes, RID 00/04) | errno 71 - Protocol error
O errno 71 é o bloqueio definitivo para esse caminho. O kernel rejeita o SetFeature com esse tamanho/formato, e sem os pacotes exatos que o app Windows envia (capturados no Windows), não é possível construir o payload correto com confiança.
Estado atual e próximo passo
O que foi confirmado
- Protocolo parcialmente decodificado com alta confiança.
- Natureza interna das teclas Fn comprovada - não são eventos HID.
- keyd e monitoramento hidraw funcionam para teclas normais.
- Estrutura do payload HID (Report ID, comandos 0xA0..0xA9) identificada.
- Canal de escrita (0xA6 commit) identificado no firmware.
O que falta
Um único pacote: o payload exato de SetFeature que o app Windows envia ao fazer um remap de Fn, seguido do 0xA6 de commit.
Como obter esse pacote
- Rodar o app oficial em uma VM Windows com USB passthrough funcional.
- Abrir o app, fazer um remap mínimo de qualquer tecla Fn.
- Capturar com USBPcap/Wireshark.
- Filtrar por VID:PID 2EA8:2122.
- Extrair os pacotes de write + commit.
- Reproduzir no Linux via ioctl(HIDIOCSFEATURE, ...).
Scripts criados
Disponíveis no meu GitHub:
dna59_hid_tool.py - ferramenta principal de interação com o protocolo:
Subcomandos: read, dump, scan, raw, a0-readmeta,
feature-read, feature-raw, a3-probe
fn_monitor.py - monitoramento em tempo real de eventos hidraw.
Conclusão
O DNA59 usa um protocolo HID proprietário com um firmware ARM que trata as teclas Fn como estado interno, elas nunca chegam ao sistema operacional. A configuração de keymap exige um SetFeature com payload específico que só o app Windows sabe montar corretamente.
O protocolo foi decodificado até onde é possível sem uma captura real do app. A próxima etapa é clara e mecânica: capturar o tráfego USB no Windows e reproduzir no Linux.
Se você tem um DNA59 e passou pelo mesmo problema, ou já capturou esses pacotes, abre uma issue ou me manda o pcap.
