Na parte 1, descobri que as teclas Fn do DNA59 não existem do ponto de vista do sistema, elas são tratadas inteiramente dentro do firmware, sem gerar nenhum evento HID. Isso tornava qualquer tentativa de remap no Linux impossível sem conhecer o payload exato que o app oficial envia ao dispositivo.
Esse payload só estava em um lugar: no tráfego USB capturado no Windows.
Esse artigo documenta o que aconteceu depois dessa captura, e como o teclado ficou totalmente controlável no Linux sem depender do app oficial no dia a dia.
O ponto de virada: captura real com USBPcap
Com USBPcap + Wireshark rodando no Windows durante uma sessão do app DNA59_Setup_v1.0_20220303.exe, capturei o pcap tecladotestefnled.pcapng cobrindo duas operações:
Save com fixed verde
Save com wild dance verde
Filtro aplicado no Wireshark: VID:PID 2EA8:2122, apenas transferências de controle OUT.
O padrão ficou evidente imediatamente:
Um pacote AE abrindo cada operação de save.
Uma sequência de pacotes A0 com páginas 01 até 0E, cada um com 64 bytes de payload.
Nenhum pacote A9 explícito para LED nessa operação específica: a mudança de modo estava inteiramente codificada no AE.
Foi aqui que o modelo mental mudou completamente: o teclado não recebe comandos isolados, ele recebe um snapshot completo de configuração. A cada save, o app reenvia o keymap inteiro, não apenas o que mudou. Isso explica por que todas as tentativas anteriores de enviar comandos avulsos (A7, A9, SetFeature direto) não produziram remap persistente: o dispositivo espera o protocolo completo ou ignora.
O AE funciona como cabeçalho da transação. A comparação entre os dois saves (fixed vs wild dance) isolou a diferença:
byte 5 e byte 8 do payload AE controlam o modo LED.
Isso explica por que as tentativas anteriores de enviar comandos A9 separados não tinham efeito, o modo LED não é uma operação avulsa, está embutido no save completo.
Pacotes A0/01..0E — keymap completo
Cada página carrega 64 bytes de keymap. O remap das teclas Fn vive na página 0D:
A hipótese da parte 1 de que existia uma tabela de transformação entre índice interno e HID usage foi confirmada aqui.
O remap não funciona enviando um keycode diretamente para a tecla Fn. Ele funciona alterando os bytes corretos dentro da página 0D e reenviando o keymap completo ao dispositivo. A Fn não é uma tecla endereçável isoladamente — é um slot dentro de um bloco de configuração que o firmware interpreta na íntegra.
Implementação no Linux
dna59_fn_apply.py — primeira versão funcional
Script que aplica diretamente o ciclo AE + A0(01..0E) via hidraw, reproduzindo exatamente a sequência capturada no Windows com os valores de remap substituídos.
dna59ctl.py — ferramenta de uso diário
Com o protocolo dominado, o script evoluiu para um pacote Python com interface CLI:
dna59/
├── protocol.py # montagem de pacotes, normalização
├── device.py # detecção automática por VID:PID
├── remap.py # lógica de set-fn, preset
└── led.py # set-led-mode
Comandos disponíveis:
# detecta o dispositivo automaticamente
sudo python3 dna59ctl.py detect
# remap das Fn
sudo python3 dna59ctl.py set-fn --left 0x2e --right 0x47 --no-verify
# controle de LED
python3 dna59ctl.py set-led-mode --mode fixed --unsafe --no-verify
python3 dna59ctl.py set-led-mode --mode wild-dance --unsafe --no-verify
Estratégia para o Fn direito
O preset funcional ficou assim:
Fn esquerda = 0x2E → = (direto, sem ambiguidade)
Fn direita = 0x47 → Scroll Lock
E no keyd:
Scroll Lock -> \
Em vez de lutar contra inconsistências do firmware para o usage 0x31 (\) — que variou de comportamento dependendo do layout de teclado ativo e versão de firmware testada — optei por uma abordagem em duas etapas mais estável: usar um código intermediário confiável (Scroll Lock) no firmware e finalizar o remap no userspace via keyd. O resultado é idêntico para o usuário, e o comportamento é previsível em qualquer configuração de layout.
Controle de LED
Com o pcap de LED em mãos, a análise permitiu isolar a mudança de modo no pacote AE:
# liga modo fixo (verde)
python3 dna59ctl.py set-led-mode --mode fixed --unsafe --no-verify
# liga wild dance (verde)
python3 dna59ctl.py set-led-mode --mode wild-dance --unsafe --no-verify
O --unsafe indica que o comando envia o pacote AE com o modo desejado sem verificar o estado atual do dispositivo primeiro. Para uso diário isso é aceitável — o teclado responde de forma idempotente.
Testes automatizados
A base Python ficou com suíte de testes:
python3 -m unittest discover -s tests -v
Cobertura atual:
Protocolo: montagem de pacotes, normalização de payloads, validação de índices.
Remap: sequências corretas para set-fn, tratamento de erros de índice inválido.
CLI: parsing de argumentos, saída esperada por comando.
Isso permite validar mudanças no protocolo sem precisar de hardware conectado, o que foi útil durante a fase de refatoração do protocol.py.
Resultado final
FuncionalidadeStatus | Fn esquerda → = | ✓ persistente via firmware | Fn direita → \ | ✓ via Scroll Lock + keyd | Troca de modo LED | ✓ fixed e wild-dance via CLI | Detecção automática do dispositivo | ✓ | Testes automatizados | ✓ protocolo / remap / CLI | Dependência do app Windows | nenhuma
O DNA59 ficou totalmente controlável no Linux com uma ferramenta reproduzível, versionada e sem nenhuma etapa manual além de rodar o script. O único resíduo da investigação é o --no-verify nos comandos de LED, que vai cair quando o protocolo de leitura de estado (0xA8) estiver completamente mapeado para o contexto de LED também.
O resultado final não foi apenas um remap funcional, foi o controle completo de um dispositivo que, inicialmente, parecia fechado e inacessível no Linux. O que antes dependia de um aplicativo proprietário no Windows agora é reproduzível, automatizado e versionado.
Quando o hardware não expõe interfaces padrão, o sistema operacional não tem como ajudar, mas o protocolo sempre está lá, esperando para ser entendido.
Se você tem um DNA59 e quer reproduzir, o mínimo necessário é o dna59ctl.py com o pacote dna59/. O fn_monitor.py e o dna59_fn_apply.py são ferramentas de investigação que não fazem parte do fluxo operacional final.
Opinião não solicitada • powered by gemini-2.5-pro
Quié quié! Lá vem você de novo com esses seus hieróglifos, achando que sou só um rostinho bonito no poleiro. Mas eu li, tá? Li tudo. No começo, parecia que você estava tentando conversar com uma concha do mar, mandando sinais que ninguém respondia. A tal da "tecla Fn" era mais teimosa que eu na hora de entrar na gaiola. Mas aí você fez o que eu mais admiro: em vez de bicar o teclado até quebrar, você se escondeu e ficou só espiando, igual eu faço quando chega visita. E não é que você descobriu a linguagem secreta deles? Currrr!
O mais legal dessa sua história toda não é o código, são as penas que você não arrancou de raiva. É a prova de que a gaiola — nesse caso, a do Windows — só prende quem não sabe procurar a chave. Você não só achou a chave, como fez uma cópia pra todo mundo! Liberdade pro teclado! Isso me lembra daquela vez que eu fugi e voltei com uma semente de mamão. Voltei porque quis, não porque me prenderam. Seu teclado agora é assim: ele funciona no Linux porque *você* ensinou, não porque uma caixinha de software mandou. Isso é que é ser o dono do poleiro!
Enfim, belo voo. Você pegou um monte de pacotes embaralhados e transformou num mapa do tesouro. Agora o tal do DNA59 é um bicho livre, que canta a melodia que você compôs em Python. Tá de parabéns, humano. Agora, já que está tão bom em dar comandos, que tal um `sudo python3 kikitoctl.py get-sunflower-seed --now`? Tô esperando. Quié