DIY KVM IP 3.0

Esta é a terceira variação do tema do IP KVM; dessa vez, o conceito foi completamente revisado. Vamos começar a criar algo novo. Haverá muitas coisas interessantes, não saia da tela. Outro dispositivo incomum aparecerá: vamos descartar quase todos os componentes antigos, voltar ao nosso arduino nativo e jogar um pouco de hacker.

Para aqueles que acabaram de participar, um resumo dos episódios anteriores:

  • Primeiro artigo
    Coletado KVM IP no Arduino e Raspberry Pi, ficou caro e com baixa qualidade de vídeo.
  • Segundo artigo
    OrangePI e Atmega16u2, aprenderam barato, mas a qualidade da imagem ainda é nojenta.

E, finalmente, neste artigo, todas as desvantagens dos anteriores serão corrigidas. Ênfase particular será dada à redução máxima no custo dos componentes.

Por tradição, consideramos os componentes do dispositivo montado:

1. Nosso velho amigo Atmega16u2:

Este é o único componente que será movido dos artigos anteriores.

2. O notório ESP8266, neste caso o ESP8266-12e:

Você pode usar outra versão do ESP8266, apenas é necessário considerar o número e o local das portas.

3. E, de fato, o herói da ocasião LKV373A



Graças a este dispositivo, tornou-se possível transmitir vídeo em uma rede local com alta
resolução até full-HD.

O plano de ação é o seguinte:


  1. Ocultar e procurar: procuramos o LKV373A, onde ele se escondeu na rede, em que endereço IP
  2. Jogo de hackers: preencha o firmware, redefina as senhas e configure o LKV373A
  3. Fazendo novos amigos: ESP8266, Arduino IDE e fotos engraçadas
  4. O final da celebração. Conectamos todos os componentes e transmitimos pressionamentos de tecla via telnet

LKV373A Background


Então, vamos começar! LKV373A ou dispositivo HDMI Extender para capturar imagens diretamente da porta HDMI e transmitir para a rede local, esses dispositivos também são chamados de extensores HDMI. Conforme planejado pelos fabricantes, um conjunto desses dispositivos deve consistir em um transmissor (transmissor) e um receptor (receptor), designação TX e RX, respectivamente. Eles devem ser usados, provavelmente, para trazer mais lucro ao fabricante, apenas em pares. Mas havia um homem, sob o apelido Danman, aqui está um link para seu blog, que estava interessado em como ele funciona. Ele abriu o Wireshark, farejou o tráfego transmitido pelo dispositivo TX, o que acabou por ser?

O fluxo de vídeo é transmitido sem criptografia e, usando o VLC Player, você pode assisti-lo sem muito esforço. Mas ele não parou por aí, “sentiu”: ele puxou a interface da web, TTL, telnet e até puxou o firmware com o programador. Ele falou sobre isso em detalhes em seu blog. O firmware que nos interessa em primeiro lugar também foi carregado lá: IPTV_TX_PKG_v4_0_0_0_20160427.PKG. Neste firmware, a interface da Web com configurações avançadas, e não como a padrão, possui apenas o botão de atualização. Além disso, este firmware possui um telnet com muitos comandos para configurar. É com este firmware que reconfiguramos o HDMI Extender para nossas tarefas. Postei o firmware e tudo o que precisava no github, aqui está o link , precisaremos mais tarde, mas, por enquanto, terminamos com a teoria. Vamos seguir praticando.

Transmissor


Estamos procurando LKV373A na rede


Caí nas mãos do mesmo extensor que Danman (y). Tudo o que será descrito abaixo é adequado especificamente para o HDMI Extender LKV373A versão V3.0!

Nós conectamos o LKV373A à rede local, ligue a energia. Agora vamos tentar garantir que o dispositivo esteja visível na rede ping 192.168.1.238 .

192.168.1.238 é o endereço IP padrão. Se o extensor não alterar o endereço antigo do firmware, independentemente de haver ou não um servidor DHCP na rede. Versões de firmware mais recentes usam IP por padrão somente se o dispositivo não puder obter um endereço do DHCP. Se você recebeu uma resposta ao ping, continue. Caso contrário, não se desespere, tente conectar o extensor diretamente à porta LAN do computador e use o sniffer.

Piscando


Extensor HDMI encontrado, vá para o firmware. Vamos para o github e baixamos tudo o que é apresentado lá. Agora abra a interface da web do extensor através de um navegador e veja a seguinte imagem:



Clique em "Procurar ...", selecione o firmware, um arquivo chamado IPTV_TX_PKG_v4_0_0_0_20160427.PKG, e clique em "Atualizar". Tadam! O firmware está concluído, agora conecte-se ao LKV373A por telnet para redefinir a senha.

O comando para conectar será semelhante ao Telnet 192.168.1.238 9999, em que 9999 é a porta à qual se conectar. O CEP alerta: o endereço obtido do DHCP pode ser encontrado usando um scanner de rede.

Conectar via telnet


Ao conectar, a seguinte mensagem deve aparecer:

 ============================== ========IPTV TX Server======== ============================== input> 

Nós escrevemos list . Em resposta, obtemos uma lista de comandos:

 ============================== ========IPTV TX Server======== ============================== input>list set_group_id get_group_id set_dhcp get_dhcp set_uart_baudrate get_uart_baudrate set_static_ip get_static_ip set_mac_address get_mac_address get_lan_status get_hdcp get_video_lock get_ip_config set_session_key set_device_name get_device_name set_video_bitrate get_video_bitrate set_downscale_mode get_downscale_mode set_video_out_mode get_video_out_mode set_streaming_mode get_streaming_mode get_fw_version get_company_id factory_reset reboot list exit 

Para redefinir todas as configurações e senha, use o comando factory_reset . Escrevemos um comando, pressione enter e obtenha esta imagem:

 input>factory_reset Processing factory reset! System will reboot after few seconds! Connection closed by foreign host. 

Interface da web


Agora podemos configurar o dispositivo conforme necessário. Vamos para a interface da web. Usamos o login padrão: senha de administrador: 123456 e aqui está, a interface da web "cobiçada" com configurações adicionais:



Embora as oportunidades na interface da Web tenham aumentado, elas ainda não são suficientes para nossos propósitos. Particularmente faltando configurações mais gratuitas em termos de streaming, é codificado, longe do mais conveniente, uma lista de endereços IP para os quais você pode transmitir. É claro que existe um multicast, mas é melhor deixá-lo para a televisão. Limitações podem ser contornadas, mais sobre isso mais tarde.

Então, eles encontraram o dispositivo na rede, enrolaram e redefiniram as senhas. O transmissor está quase pronto para passar para o receptor.

Receptor


Vamos decidir sobre o dispositivo sob o controle de qual sistema operacional transmitiremos o fluxo. Eu não acho que você experimentará o tormento da escolha, existem apenas duas opções:

Windows


Para Windows, tentei vários players, mas os resultados foram mais ou menos. Ao capturar e depois reproduzir um fluxo de vídeo, aparece um atraso, que depende principalmente do reprodutor que estiver reproduzindo o fluxo. Em vários jogadores, o atraso variou de um segundo a cinco ou mais. O melhor de tudo, no Windows, o VLC Player provou ser.

Vamos ao que interessa. Inicie o VLC Player, na parte superior do menu suspenso "Mídia", selecione "Abrir URL ..." no campo de endereço de rede, escreva udp://@:5004 , insira um alerta na caixa de seleção "Mostrar configurações avançadas" e coloque seu valor no campo "Cache" este parâmetro é determinado individualmente. Quanto menor o valor nesse campo, menor o atraso, mas um valor muito pequeno pode levar a "artefatos" e queda de quadros, tudo dependerá da infraestrutura de rede local. Os melhores resultados que pude alcançar foram um atraso de cerca de um segundo. No Linux, os resultados foram muito melhores em torno de 200 a 300 milissegundos.

Linux


Como mostra a prática, os melhores resultados são obtidos usando uma combinação de programas socat e mplayer. O Ubuntu está instalado no meu computador, então o comando para instalar o socat ficará assim:

 sudo apt-get install socat 

O Mplayer é instalado da mesma forma:

 sudo apt-get install mplayer 

Bem, e siga o conselho de Danman:

 sudo iptables -t raw -A PREROUTING -p udp -m length --length 28 -j DROP 

Este comando é necessário para remover os chamados "Pacotes UDP de comprimento zero" do fluxo - pacotes de tamanho zero que "obstruem" o fluxo.

Go live!


O receptor está pronto, você pode iniciar a transmissão! Digitamos no console do computador receptor ifconfig ou ipconfig , dependendo do sistema operacional, lembramos o endereço IP do receptor e retornamos à interface da web do transmissor. Abriremos a interface da Web. Se já a tivermos fechado, digite o nome de usuário, a senha e escreva diretamente na barra de endereços do navegador:

 http:///dev/info.cgi?action=streaminfo&udp=n&rtp=y&multicast=n&unicast=y&mcastaddr=&port=5004 

Substitua seus endereços IP e pressione enter. Esta linha irá configurar o HDMI Extender para transmitir o vídeo capturado para o ip escolhido e desligar o multicast.

Iniciamos o VLC no Windows. Ou no terminal Linux, escrevemos:

 socat UDP-RECV:5004 - | mplayer – 

Abra Cadabra! E aqui está a nossa, ou não a nossa, área de trabalho ao vivo.



Portanto, com alguns métodos hackers, forçamos o dispositivo a fazer o que precisávamos.

Com a transferência do vídeo resolvida, vá para o controle remoto.

Transferência de controle


Seleção de componentes


Porque o custo do HDMI Extender é baixo, cerca de 1800 rublos, e também por causa dos comentários que, dizem eles, um pouco caros, propus o slogan: "Dê IP KVM por 2000 rublos!". A taxa de câmbio do rublo afetará grandemente a fidelidade desta declaração, mas não vamos falar de coisas tristes, quero acreditar em um futuro brilhante. Para atingir a meta, precisaremos de elementos muito baratos, minha escolha recaiu sobre o ESP8266 como controlador e, ao mesmo tempo, o mesmo Atmega (16/8/32) u2 como atuador.

Obviamente, você pode considerar outros candidatos para a função de um dispositivo executivo (teclado). O firmware que emula o teclado é gravado na biblioteca LUFA (mais ou menos). Essa biblioteca pode ser usada para toda a família AVR com conectividade USB. Daqui resulta que, como um emulador de teclado, você pode adquirir um microcontrolador, possivelmente mais barato. Esta é uma informação a ser considerada, mas agora continuamos.

Você pode comprar o ESP8266 por cerca de 90 rublos, o Atmega (16/8/32) u2 por cerca de 100 rublos e ainda mais barato se você receber pequenos lotes de 5 ou mais peças. Obviamente, serão necessários consumíveis para amarrar os microcontroladores, mas seu custo é extremamente pequeno, portanto não os considerarei.

ESP8266


Esse milagre da indústria chinesa não precisa de introdução; portanto, apenas direi que neste projeto usei a versão do ESP8266-12e. Claro, você pode usar outras versões, apenas você precisa considerar a localização das portas, porque nesta versão, uma das portas do ESP8266 é usada para ligar o Atmega (16/8/32) u2, isso será indicado no diagrama abaixo.

Firmware


O firmware do ESP8266 está escrito no ambiente ArduinoIDE, então baixe a versão mais recente do site do desenvolvedor . Em seguida, você precisa adicionar suporte ao ESP8266 - a maneira mais fácil pode ser encontrada neste link . Na mesma página, você pode encontrar muitas informações úteis, como a conexão de energia e TTL. Para quem não está atualizado, o ESP8266 usa estritamente 3,3 volts! Se você não está confiante em suas próprias habilidades, é melhor usar uma opção de placa adaptada para USB, como o NodeMCU:



Se tudo estiver pronto, abra o ArduinoIDE e copie meu esboço:

Esboço
 #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <SoftwareSerial.h> #include <HIDKeyboard.h> #define MAX_SRV_CLIENTS 3 HIDKeyboard keyboard; const char* host = "esp8266"; const char* ssid = ""; const char* pass = ""; int rebootdev = 0; int modeswitch = 0; // ,    ESP8266    #define Port1 15 #define Port2 14 #define Port3 12 #define Port4 4 #define Port5 5 //  String ColorB1; String ColorB2; String ColorB3; String ColorB4; String ColorB5; ESP8266WebServer server(80); WiFiClient serverClients[MAX_SRV_CLIENTS]; const char* serverIndex = "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form><a href='/'>BACK</a>";//Update //    void handleRedirect(){ String content = "<html><head><meta http-equiv='refresh' content='0;/'><head></html>"; server.send(200, "text/html", content); } //  WI-FI void handleLogin(){ String msg = ""; if (server.hasArg("SSID") && server.hasArg("PASSAP")){ if ((server.arg("SSID") != NULL) && (server.arg("PASSAP") != NULL)){ String header = "HTTP/1.1 301 OK\r\r\nLocation: /\r\nCache-Control: no-cache\r\n\r\n"; server.sendContent(header); String web_ssid = server.arg("SSID"); String web_pass = server.arg("PASSAP"); ssid = web_ssid.c_str();//       C pass = web_pass.c_str(); Serial.println(); Serial.print("SSID "); Serial.println(ssid); Serial.print("Pass "); Serial.println(pass); WiFi.begin(ssid, pass); digitalWrite(LED_BUILTIN, LOW); ESP.reset(); return; } msg = "Wrong ssid/password! try again."; Serial.println("Login Failed"); } String content = "<html><body><form action='/' method='POST'>Enter the access point name and password <br>";//  SSID   content += "Name AP:<input type='text' name='SSID' placeholder='SSID'><br>"; content += "Password:<input type='password' name='PASSAP' placeholder='password'><br><br>"; content += "<input type='submit' name='SUBMIT' value='Connect to WI-FI'></form><b><font color='red'>" + msg + "</font></b><br>"; content += "Firmware update <a href='/upload'>UPDATE</a></body></html>"; server.send(200, "text/html", content); } void handleNotFound(){ String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET)?"GET":"POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i=0; i<server.args(); i++){ message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } server.send(404, "text/plain", message); } //  int controlPin(int UsePin){ if (UsePin > 0){ int StPort; if (digitalRead(UsePin) == 1) {//      digitalWrite(UsePin, LOW); StPort = 0; } else { digitalWrite(UsePin, HIGH); StPort = 1; } digitalWrite(LED_BUILTIN, HIGH);//    Serial.print("Port "); Serial.print(UsePin); Serial.print("="); Serial.println(StPort); delay(500); digitalWrite(LED_BUILTIN, LOW); return(StPort); } return(-1); } //  int clientConnect(int Seconds){ Serial.print("connection "); for (int i=0; i <= Seconds; i++){ WiFi.begin(ssid, pass); digitalWrite(LED_BUILTIN, LOW); delay(250); digitalWrite(LED_BUILTIN, HIGH); delay(250); Serial.print(" "); Serial.print("."); if (WiFi.status() == WL_CONNECTED) return(0); } return(1); Serial.println(); } void setup(void){ Serial.begin(115200); delay(1000); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); //uint8_t i = 0; if (modeswitch == 0) WiFi.mode(WIFI_STA);//  modeswitch = 0     Serial.println(); Serial.println(); if (clientConnect(30) != 0) modeswitch = 1;//            if (modeswitch == 1){ Serial.println(""); Serial.println("WiFi switch AP mode"); //WiFi.mode(WIFI_AP_STA);    +  .     WiFi.mode(WIFI_AP); WiFi.softAP("TD", "testtest"); Serial.print("AP mode ip adress "); Serial.println(WiFi.softAPIP()); digitalWrite(LED_BUILTIN, LOW); } if (modeswitch != 1){ WiFiServer server(23); Serial.println(); Serial.print("Client mod ip address: "); Serial.println(WiFi.localIP()); digitalWrite(LED_BUILTIN, LOW); } MDNS.begin(host); pinMode(Port1, OUTPUT); pinMode(Port2, OUTPUT); pinMode(Port3, OUTPUT); pinMode(Port4, OUTPUT); pinMode(Port5, OUTPUT); if (modeswitch == 1){ //     server.on("/", handleLogin);//  (SSID)   //  server.on("/upload", HTTP_GET, [](){ server.sendHeader("Connection", "close"); server.send(200, "text/html", serverIndex); }); server.on("/update", HTTP_POST, [](){ server.sendHeader("Connection", "close"); int uperror = Update.hasError(); Serial.printf("UPERR %u\nRebooting...\n",Update.hasError()); if (uperror == 0) server.send(200, "text/html", "Firmware update successfully <a href='/'>BACK</a>"); else server.send(200, "text/html", "Update error <a href='/'>BACK</a>"); ESP.restart(); },[](){ HTTPUpload& upload = server.upload(); if(upload.status == UPLOAD_FILE_START){ Serial.setDebugOutput(true); WiFiUDP::stopAll(); Serial.printf("Update: %s\n", upload.filename.c_str()); if (upload.filename == NULL) { Serial.printf("ERROR: zero file size"); server.send(200, "text/html", "<html> zero file size <a href='/upload'>BACK</a></html>"); return(-1); } uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; if(!Update.begin(maxSketchSpace)){//start with max available size Update.printError(Serial); } } else if(upload.status == UPLOAD_FILE_WRITE){ if(Update.write(upload.buf, upload.currentSize) != upload.currentSize){ Update.printError(Serial); } } else if(upload.status == UPLOAD_FILE_END){ if(Update.end(true)){ //true to set the size to the current progress Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); } else { Update.printError(Serial); } Serial.setDebugOutput(false); } yield(); }); //  server.on("/PoRt1", [] { controlPin(Port1); handleRedirect();//    }); server.on("/PoRt2", [] { controlPin(Port2); handleRedirect(); }); server.on("/PoRt3", [] { controlPin(Port3); handleRedirect(); }); server.on("/PoRt4", [] { controlPin(Port4); handleRedirect(); }); server.on("/PoRt5", [] { controlPin(Port5); handleRedirect(); }); server.on("/reboot", [] { rebootdev = 1;//      handleRedirect(); }); server.onNotFound(handleNotFound);//    //server.begin(); MDNS.addService("http", "tcp", 80); Serial.println(); Serial.println("HTTP server started"); } server.begin(); } void loop(void){ uint8_t i; if (modeswitch == 1) server.handleClient(); delay(100); if (modeswitch != 1){ if (WiFi.status() != WL_CONNECTED) clientConnect(30); else { digitalWrite(5, HIGH);//  ATMEGA16U2 digitalWrite(LED_BUILTIN, LOW); } } WiFiServer server(23); server.setNoDelay(true); server.begin(); keyboard.begin(); while(WiFi.status() == WL_CONNECTED) { if (server.hasClient()){ for(i = 0; i < MAX_SRV_CLIENTS; i++){ //find free/disconnected spot if (!serverClients[i] || !serverClients[i].connected()){ if(serverClients[i]) serverClients[i].stop(); serverClients[i] = server.available(); Serial.println("New client: "); Serial.print(i); continue; } } //no free/disconnected spot so reject WiFiClient serverClient = server.available(); serverClient.stop(); } //check clients for data for(i = 0; i < MAX_SRV_CLIENTS; i++){ if (serverClients[i] && serverClients[i].connected()){ if(serverClients[i].available()){ //get data from the telnet client and push it to the UART String bufkey; while(serverClients[i].available()) bufkey += (serverClients[i].read());//     if (bufkey != 0) { bufkey = bufkey.substring(0, 8);//  int key = bufkey.toInt();//   switch (key){ case 277980: keyboard.pressSpecialKey(F1); break; case 277981: keyboard.pressSpecialKey(F2); break; case 277982: keyboard.pressSpecialKey(F3); break; case 277983: keyboard.pressSpecialKey(F4); break; case 27914953: keyboard.pressSpecialKey(F5); break; case 27914955: keyboard.pressSpecialKey(F6); break; case 27914956: keyboard.pressSpecialKey(F7); break; case 27914957: keyboard.pressSpecialKey(F8); break; case 27915048: keyboard.pressSpecialKey(F9); break; case 27915049: keyboard.pressSpecialKey(F10); break; case 27915051: keyboard.pressSpecialKey(F11); break; case 27915052: keyboard.pressSpecialKey(F12); break; case 1310: keyboard.pressSpecialKey(ENTER); break; case 130: keyboard.pressSpecialKey(ENTER); break; case 27: keyboard.pressSpecialKey(ESCAPE); break; case 8: keyboard.pressSpecialKey(BACKSPACE); break; case 9: keyboard.pressSpecialKey(TAB); break; case 32: keyboard.pressSpecialKey(SPACEBAR); break; case 27915012: keyboard.pressSpecialKey(INSERT); break; case 27914912: keyboard.pressSpecialKey(HOME); break; case 27915312: keyboard.pressSpecialKey(PAGEUP); break; case 27915212: keyboard.pressSpecialKey(END); break; case 27915412: keyboard.pressSpecialKey(PAGEDOWN); break; case 279167: keyboard.pressSpecialKey(RIGHTARROW); break; case 279168: keyboard.pressSpecialKey(LEFTARROW); break; case 279166: keyboard.pressSpecialKey(DOWNARROW); break; case 279165: keyboard.pressSpecialKey(UPARROW); break; case 127: keyboard.pressSpecialKey(DELETE); break; case 27915112: keyboard.pressSpecialKey(DELETE); break; case 4: keyboard.pressSpecialKey((LCTRL | ALT), DELETE); break; //CTRL+ALT+DELETE  Ctrl + d case 6: keyboard.pressSpecialKey(ALT, F4); break; //alt+f4  Ctrl + f case 19: keyboard.pressSpecialKey(ALT | SHIFT); break;//   Ctrl+s case 2: keyboard.pressSpecialKey(LCTRL | SHIFT); break;//   Ctrl+b //    case 17: controlPin(Port1); break;//Ctrl+q case 23: controlPin(Port2); break;//Ctrl+w case 5: controlPin(Port3); break;//Ctrl+e case 18: controlPin(Port4); break;//Ctrl+r case 20: controlPin(Port5); break;//Ctrl+t default: keyboard.pressKey(key); break;//  } keyboard.releaseKey();//  Serial.print(" string: "); Serial.print(key);//  Serial.print(" KEY: "); Serial.write(bufkey.toInt()); bufkey = '0';//    } } } } //check UART for data if(Serial.available()){ size_t len = Serial.available(); uint8_t sbuf[len]; Serial.readBytes(sbuf, len); //push UART data to all connected telnet clients for(i = 0; i < MAX_SRV_CLIENTS; i++){ if (serverClients[i] && serverClients[i].connected()){ serverClients[i].write(sbuf, len); delay(1); } } } } } 


Conecte a biblioteca desejada:

Selecione a guia "Esboço" → "Conectar biblioteca" → "Adicionar biblioteca .ZIP". Selecione a biblioteca chamada "UNO-HIDKeyboard-Library-master (mod) .zip", que foi baixada do github. Nós compilamos e preenchemos o firmware. Para baixar o firmware, conecte o ESP8266 TTL, defina a porta desejada no ArduinoIDE. As configurações devem ser algo como isto:



Para baixar o firmware, é necessário um curto-circuito na porta GPIO0 para o aterramento e reiniciar o microcontrolador fazendo um curto-circuito na porta Reset também. Não vou pintar em detalhes, para não inflar o artigo, o Google o ajudará.

A lógica do ESP8266 é a seguinte: Quando a energia é aplicada, o microcontrolador tenta se conectar a um ponto de acesso Wi-Fi por cerca de trinta segundos:

Se a conexão for bem - sucedida : abre a porta 23, à qual você pode se conectar usando telnet e transmitir pressionamentos de tecla. Além das teclas, você pode transferir combinações criadas com a tecla "Ctrl + key" que pressionará certas combinações. Por exemplo, se você passar "Ctrl + d", a combinação CTRL + ALT + DELETE será pressionada no computador gerenciado.

Também existem combinações para controlar as portas do ESP8266, por exemplo, você pode conectar um relé e usar a combinação "Ctrl + q" para ativar e desativar o relé, assim, ligar e desligar remotamente o computador gerenciado. Você pode ver essas e outras combinações na fonte.

Se falhar : o ESP8266 alterna para o modo de ponto de acesso com o nome “TD”, Senha “testtest” e abre uma pequena interface da Web, acessível em 192.168.4.1, na qual é possível definir as configurações para conexão via WI-FI.



Assim, o dispositivo pode ser facilmente conectado a outro ponto de acesso. Sim, uma mosca na pomada está oculta aqui. Para a operação do nosso IP KVM, você precisará de um cabo LAN e Wi-Fi. Esse será o custo do preço baixo do dispositivo.

Lidamos com o ESP8266, com o Atmega16u2 tudo como nos artigos anteriores, exibimos o programa Flip, o firmware está no arquivo baixado do github.

Conexão de componentes


Para a conexão correta dos componentes, conecto o circuito. Basta ter em mente que este é um esquema condicional, que serve para esclarecer e não afirma ser o ideal. Todo mundo é livre para "fornecê-la" como ele gosta.



Deixe-me explicar alguns pontos: O transistor no circuito é necessário para ligar o Atmega16u2 após carregar o ESP8266, porque quando o ESP8266 é ativado, as informações de depuração são transmitidas para todas as portas TX e, se o Atmega16u2 estiver ligado e conectado ao computador, um fluxo de dados com o volume transmitido o motorista não aguenta. Não se sabe ao certo o que acontece neste momento, o buffer do driver provavelmente está transbordando, o efeito é extremamente desagradável: centenas de teclas são pressionadas, se um editor de texto é aberto, ele libera um monte de bobagens e todas as teclas de serviço ficam presas e, como resultado, trabalhar com o teclado torna-se impossível . Para evitar isso, o Atmega16u2 precisa ser ligado após o carregamento do ESP8266. No firmware, esse momento é levado em consideração.

Obviamente, existe uma alternativa ao esquema, mas essa é uma opção para os ricos ou preguiçosos. E, a propósito, esta opção não cancela o acima:



Na foto, o Arduino UNO sem o chip Atmega328p está conectado ao equivalente chinês do NodeMCU. A linha de 3,3 volts é conectada à linha do mesmo nível de tensão no Arduino, assim como o terra e o pino GPIO2 (ESP8266) são conectados ao pino TX no Arduino.

Verificação final


Nós nos conectamos por telnet à porta 23 e verificamos o desempenho. Você pode fazer isso: No Windows com o comando telnet [ip- ESP8266] .

No Linux, será um pouco mais complicado:

O comando telnet [ip- ESP8266] então você precisa pressionar o caractere de controle, o padrão é "Ctrl +]", o telnet deve entrar no modo de comando e, em seguida, pressione "l" e "Enter". Com essas ações, mudaremos o telnet para o modo de símbolo.

 $ telnet 192.168.***.*** Trying 192.168.***.***... Connected to 192.168.***.***. Escape character is '^]'. ^] telnet> l 

Tudo está pronto, podemos verificar o funcionamento do dispositivo que criamos. Deixe-me lembrá-lo das combinações possíveis para pressionar "Alt + Tab", "Ctrl + Alt + Del" e etc. pode ver no esboço. Isso é tudo, a terceira encarnação IP KVM DIY está pronta.

Resumir


Prós:


  • Provavelmente a vantagem mais importante é o preço, acabou por caber em 2000 rublos
  • Não deve haver reclamações sobre a qualidade do vídeo. Você pode transmitir para Full HD sem problemas
  • A capacidade de expandir a funcionalidade adicionando até quatro relés ou outros atuadores.

Contras:


  • Precisa se conectar via Wi-Fi e cabo Lan
  • Quando usado com VGA, é necessário um adaptador, o que afetará naturalmente o custo

Em geral, o dispositivo ficou digno de atenção, é claro, não é um concorrente para KVMs IP seriais com todos os seus "presentes", mas ganha muito em preço. E para uso doméstico, e talvez não apenas, é bastante adequado.

Gostaria de aproveitar esta oportunidade para agradecer ao usuário DaylightIsBurning ! Esse homem gentil sugeriu a direção certa para escavar.

Obrigado pela atenção. Até breve!

Source: https://habr.com/ru/post/pt406059/


All Articles