Простой переключатель компьютерных консолей на транзисторе и реле (KVM Switch). Полный контроль - переключатели KVM over IP Как изготовить kvm свитча своими руками

Mak2k2 4 октября 2017 в 17:41

IP KVM своими руками 3.0

  • Сетевое оборудование ,
  • DIY или Сделай сам
  • Tutorial

Это уже третья вариация на тему IP KVM"а, на этот раз концепт полностью пересмотрен, начнем строить нечто новенькое. Будет много интересного, не отходите от экрана. Появится еще один необычный девайс, отбросим почти все старые компоненты, вернемся обратно к родной ардуино и немножко поиграем в хакера.

Для тех, кто только что присоединился, краткое содержание предыдущих серий:


  • Собирали IP KVM на Arduino и Raspberry Pi, получилось дорого и с плохим качеством видео.

  • OrangePI и Atmega16u2, поучилось дешево, но качество изображения всё также отвратительно.
И вот, наконец, в этой статье будут исправлены все минусы предыдущих. Особый упор будет сделан на максимальное снижение стоимости компонентов.

По традиции рассмотрим составные части собираемого устройства:

1. Наша старая знакомая Atmega16u2:


Это единственный компонент, который перейдет из предыдущих статей.

2. Небезызвестный ESP8266, в данном случае ESP8266-12e:


Можно использовать и другую версию ESP8266, только необходимо учитывать количество и расположение портов.

3. И, собственно, виновник торжества LKV373A

Благодаря этому устройству стало возможным передавать видео по локальной сети, с высоким
разрешением вплоть до full-HD.

План мероприятия таков:

  1. Игра в прятки: Ищем LKV373A куда он спрятался в сети под каким ip адресом
  2. Игра в хакера: Заливаем прошивку, сбрасываем пароли и настраиваем LKV373A
  3. Заводим новых друзей: ESP8266, Arduino IDE и веселые картинки
  4. Финал торжества. Подключаем все компоненты и передаем нажатия клавиш через telnet

LKV373A, предыстория

Итак, приступим! LKV373A или HDMI Extender устройство для захвата изображения прямо с порта hdmi и трансляции в локальную сеть, эти устройства еще называют hdmi удлинителями. По задумке производителей комплект подобных устройств должен состоять из transmitter (передатчика) и receiver (приемника), обозначение TX и RX соответственно. Использоваться они должны, вероятно, для того, чтобы приносить производителю больше прибыли, только в паре. Но нашелся человек, под ником Danman вот ссылка на его блог, которому стало интересно как это работает. Открыл он Wireshark, поснифал трафик передаваемый TX устройством, что же оказалось?

Видеопоток передается без какого-либо шифрования, и при помощи VLC Player"a можно посмотреть его без лишних усилий. Но на этом он не остановился, «пощупал»: и веб интерфейс, и TTL, и телнет, и даже прошивку программатором стянул. Об этом он в подробностях рассказал в своем блоге. Там же была выложена прошивка, которая интересует нас в первую очередь: IPTV_TX_PKG_v4_0_0_0_20160427.PKG. В этой прошивке веб интерфейс с расширенными настройками, а не как у стандартной только кнопка обновить. К тому же, в этой прошивке есть телнет с множеством команд для настройки. Именно при помощи этой прошивки мы перенастроим HDMI Extender под наши задачи. Прошивку и все необходимое я выложил на github вот ссылка , она понадобится нам позднее, а пока заканчиваем с теорией. Переходим к практике.

Передатчик

Ищем LKV373A в сети

Мне попался в руки такой же extender что и Danman(у). Все что будет изложено далее подходит именно для HDMI Extender LKV373A версии V3.0!

Подключаем LKV373A к локальной сети, включаем питание. Теперь попробуем удостовериться, что устройство видно в сети ping 192.168.1.238 .

192.168.1.238 это IP-адрес по умолчанию. Если на extender"ре старая прошивка адрес не изменится, независимо от того, присутствует DHCP сервер в сети или нет. Более новые версии прошивки используют IP по умолчанию только, если устройство не смогло получить адрес от DHCP. Если на ping запрос получили ответ, продолжаем дальше. Если нет, не отчаивайтесь, попробуйте подключить extender напрямую к LAN порту компьютера и воспользоваться сниффером.

Прошиваем

HDMI Extender нашли, перейдем к прошивке. Зайдем на гитхаб и скачаем все, что там выложено. Теперь откроем веб интерфейс extender"а через браузер и увидим такую картину:

Нажимаем «Browse…», выбираем прошивку, файл с названием IPTV_TX_PKG_v4_0_0_0_20160427.PKG, и нажимаем «Upgrade». Тадам! Прошивка завершена, теперь подключимся к LKV373A по телнету, чтобы сбросить пароль.

Команда для подключения будет выглядеть примерно так Telnet 192.168.1.238 9999, где 9999 - это порт для подключения. КЭП предупреждает: адрес полученный от DHCP можно узнать при помощи сканера сети.

Подключаемся через телнет

При подключении должно появиться следующее сообщение:

IPTV TX Server======== ============================== input>
Пишем list . В ответ получаем список команд:

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
Для сброса всех настроек и пароля используем команду factory_reset . Пишем команду, нажимаем enter и получаем такую картину:

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

Веб интерфейс

Теперь мы можем настраивать устройство как нужно нам. Зайдем в веб интерфейс. Используем стандартные логин:admin пароль:123456 и вот он, «желанный» веб интерфейс с дополнительными пунктами настройки:

Хотя возможностей в веб интерфейсе прибавилось, но их всё же для наших целей недостаточно. Особенно не хватает более свободных настроек в части стриминга, там жестко задан, далеко не самый удобный, список ip-адресов на которые можно стримить. Есть конечно мультикаст, но это лучше оставить для телевидения. Ограничения можно обойти, об этом немного позднее.

Вот, устройство в сети нашли, прошивку «накатили», пароли сбросили. Передатчик почти готов перейдем к приемнику.

Приемник

Давайте определимся, на устройство, под управлением какой операционной системы, будем передавать поток. Муки выбора думаю испытывать не будете, варианта всего два:

Windows

Для виндовс попробовал несколько плееров, но результаты получились так себе. При захвате и последующем воспроизведении видеопотока появляется задержка, которая в первую очередь зависит от плеера воспроизводящего поток. На различных плеерах задержка варьировалась от одной секунды, до пяти и даже больше. Лучше всех, на виндовс, показал себя VLC Player.

Перейдем к делу. Запустим VLC Player, сверху в выпадающем меню «Медиа» выбираем пункт «Открыть URL…» в поле сетевого адреса пишем udp://@:5004 , ставим галку в чекбоксе «Показать дополнительные параметры» и в поле «Кэширование» ставим свое значение, этот параметр определяется индивидуально. Чем меньше значение в этом поле, тем меньше задержка, но слишком малое значение может привести к «артефактам» и выпадениям кадров, все будет зависеть от инфраструктуры локальной сети. Лучшие результаты, которых смог добиться, это задержка около одной секунды. На линуксе же, результаты получились гораздо лучше около 200-300 миллисекунд.

Linux

Как показывает практика, лучшие результаты получаются при использовании связки программ socat и mplayer. На моем компьютере установлена Ubuntu, поэтому команда для установки socat будет выглядеть так:

Sudo apt-get install socat
Mplayer устанавливается аналогично:

Sudo apt-get install mplayer
Ну, и прислушаемся совету Danman"а:

Sudo iptables -t raw -A PREROUTING -p udp -m length --length 28 -j DROP
Эта команда нужна для того что бы убрать из потока так называемые «Zero Length UDP Packets» - пакеты нулевого размера, которые «засоряют» поток.

Выходим в прямой эфир!

Приемник готов, можно запускать трансляцию! Набираем в консоли принимающего компьютера ifconfig или ipconfig в зависимости от операционной системы, Запоминаем IP-адрес приемника и вернемся к веб интерфейсу передатчика. Откроем веб-интерфейс, если вдруг уже закрыли, введем логин, пароль и прямо в адресной строке браузера пишем:

Http://АйПиПередатчика/dev/info.cgi?action=streaminfo&udp=n&rtp=y&multicast=n&unicast=y&mcastaddr=АйПиПриемника&port=5004
Подставляем свои IP-адреса и нажимаем enter. Эта строка настроит HDMI Extender для трансляции захваченного видео на выбранный вами ip и выключит мультикаст.

Запускаем VLC в Windows. Или в терминале Linux пишем:

Socat UDP-RECV:5004 - | mplayer –
Абра кадабра! И вот наш, или не наш, рабочий стол в прямом эфире.

Вот так, при помощи немного хакерских методов, мы заставили устройство выполнять то, что нам требуется.

С передачей видео разобрались, переходим к удаленному управлению.

Передача управления

Выбор комплектующих

Т.к. стоимость HDMI Extender"а невысока, около 1800 рублей, а так же из-за комментариев что, мол, дороговато, выдвигаю лозунг: «Даешь IP KVM за 2000 рублей!». На верность этого утверждения будет сильно влиять курс рубля, но не будем о грустном, хочется верить в светлое будущее. Для достижения цели нам понадобятся очень дешевые элементы, мой выбор пал: на ESP8266 в качестве контроллера, и все того же Atmega(8/16/32)u2 в качестве исполнительного устройства.

Можно конечно рассмотреть и другие кандидатуры на роль исполнительного устройства(клавиатуры). Прошивка, эмулирующая клавиатуру, написана на библиотеке LUFA(вроде как). Эта библиотека может использоваться для всего семейства AVR с возможностью подключения к USB. Из этого следует, что в качестве эмулятора клавиатуры можно подобрать, возможно более дешевый, микроконтроллер. Это информация к размышлению, а сейчас продолжим.

Приобрести ESP8266 можно примерно за 90 рублей, Atmega(8/16/32)u2 примерно за 100 рублей, и даже дешевле, если брать небольшими партиями по 5, или больше штук. Конечно, нужны будут расходные материалы для обвязки микроконтроллеров, но стоимость их крайне мала, поэтому рассматривать их не буду.

ESP8266

Это чудо китайской промышленности не нуждается в представлении, посему скажу только, что в этом проекте я использовал версию ESP8266-12e. Использовать другие версии конечно можно, только нужно учитывать расположение портов, т.к. в данном варианте один из портов ESP8266 используется для включения питания на Atmega(8/16/32)u2, ниже будет указано на схеме.

Прошивка

Прошивка для ESP8266 написана в среде ArduinoIDE так что давайте скачаем свежую версию с сайта разработчика . Далее нужно добавить поддержку ESP8266 - самый простой способ можете найти по этой ссылке . На той же странице можно найти много полезной информации, например схема подключения к питанию и TTL. Для тех, кто не в курсе ESP8266 использует строго 3.3 вольта! Если не уверены в собственных силах, лучше использовать вариант платы адаптированный для USB, вроде NodeMCU:

Если все готово открываем ArduinoIDE и копируем мой скетч:

Скетч

#include #include #include #include #include #include #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; const char* serverIndex = "

BACK";//Update //Возврат на главную страницу void handleRedirect(){ String content = ""; 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 = "
Enter the access point name and password
";//страница ввода SSID и пароля content += "Name AP:
"; content += "Password:

"; content += "
" + msg + "
"; content += "Firmware update UPDATE"; 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 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 BACK"); else server.send(200, "text/html", "Update error BACK"); 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", " zero file size BACK"); 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; 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); } } } } }


Подключим нужную библиотеку:

Выбираем вкладку «Скетч» → «Подключить библиотеку» → «Добавить.ZIP библиотеку» Выбираем библиотеку под названием «UNO-HIDKeyboard-Library-master(mod).zip», которую скачали с гитхаба. Компилируем и заливаем прошивку. Для загрузки прошивки подключаем ESP8266 TTL, выставляем нужный порт в ArduinoIDE. Настройки должны выглядеть примерно так:

Чтобы загрузить прошивку, нужно порт GPIO0 замкнуть на землю, и перезагрузить микроконтроллер кратковременно замкнув порт Reset так же на землю. Подробно расписывать не буду, чтоб не раздувать статью, гугл вам в помощь.

Логика работы ESP8266 такова: При подаче питания микроконтроллер в течении примерно тридцати секунд пытается подключиться к Wi-Fi точке доступа:

Если подключение удалось : открывает 23 порт, к которому можно подключиться, используя telnet и передавать нажатия клавиш. Кроме клавиш можно передавать комбинации, построенные на «Ctrl + key» которые будут нажимать определенные сочетания. Например, если передать «Ctrl + d», на управляемом компьютере будет нажато сочетание CTRL+ALT+DELETE.

Также имеются комбинации для управления портами ESP8266, можно, например, подсоединить реле и при помощи комбинации «Ctrl+q» включать и отключать реле, тем самым удаленно включать и отключать управляемый компьютер. Эти и другие комбинации можете посмотреть в исходниках.

Если не удалось : ESP8266 переходит в режим точки доступа, с названием «TD», Паролем «testtest» и открывает небольшой веб интерфейс, доступный по адресу 192.168.4.1, в котором можно задать настройки для подключения по WI-FI.

Таким образом, устройство можно легко подключить к другой точке доступа. Да, тут скрывается ложка дегтя, для работы нашего IP KVM"а потребуется и LAN кабель и Wi-Fi. Такова будет плата за дешевизну устройства.

С ESP8266 разобрались, с Atmega16u2 все как в предыдущих статьях, прошиваем программой Flip, прошивка есть в архиве скачанном с гитхаба.

Подключение компонентов

Для правильного подключения компонентов прикладываю схему. Только учтите, это условная схема, она служит для наглядности и не претендует на звание идеальной. Каждый волен «обставить» её как ему нравится.

Поясню некоторые моменты: Транзистор на схеме нужен для того, что бы включать Atmega16u2 уже после загрузки ESP8266 т.к при включении ESP8266 на все TX порты передается отладочная информация, и если Atmega16u2 включен и подключен к компьютеру, ему передается поток данных, с объемом которых не справляется драйвер. Доподлинно неизвестно что происходит в этот момент, предположительно переполняется буфер драйвера, эффект получается крайне неприятным: происходит нажатие(программное) сотен клавиш, если открыт текстовой редактор туда высыпает кучу тарабарщины, при этом залипают все служебные клавиши и в итоге работа с клавиатурой становится не возможной. Что бы избежать этого, питание на Atmega16u2 нужно подавать после загрузки ESP8266. В прошивке этот момент учтен.

Есть, конечно, альтернатива схеме, но это вариант для богатых, или ленивых. И кстати этот вариант не отменяет вышеизложенное:

На снимке Arduino UNO без чипа Atmega328p подключенный к китайскому аналогу NodeMCU. Линия 3.3 вольта подключена к линии того же уровня напряжения на Arduino, а так же подключена земля и контакт GPIO2(ESP8266) к контакту TX на Arduino.

Финальная проверка

Подключаемся по телнету на 23 порт и проверяем работоспособность. Сделать это можно: На Windows командой telnet .

На Linux будет немного сложнее:

$ telnet 192.168.***.*** Trying 192.168.***.***... Connected to 192.168.***.***. Escape character is "^]". ^] telnet> l
Все готово, можем проверять работу созданного нами устройства. Напомню возможные комбинации для нажатий «Alt + Tab», «Ctrl + Alt + Del» и д.р. можете посмотреть в скетче. Вот и все, третья инкарнация DIY IP KVM"а готова.

Подведем итоги

Плюсы:

  • Вероятно самый важный плюс это цена, получилось уложиться в 2000 рублей
  • К качеству видео теперь никаких претензий быть не должно, без проблем можно стримить вплоть до Full HD
  • Возможность расширить функционал, добавив до четырех реле или другие исполнительные устройства.

Минусы:

  • Необходимость в подключении и по Wi-Fi, и по Lan кабелю
  • При использовании с VGA необходим переходник, что естественно отразится на себестоимости
В общем и целом, устройство получилось достойное внимания, конечно, оно не конкурент серийным IP KVM"ам со всеми их «плюшками», но зато сильно выигрывает в цене. И для домашнего использования, а может и не только, вполне подходит.

Пользуясь случаем хотел поблагодарить пользователя

С приходом в офисы широкополосного интернета стало возможно полноценное удаленное администрирование. Благодаря этой технологии обслуживающие организации смогли существенно уменьшить время реагирования на заявку клиента, а системные администраторы получили возможность оказывать поддержку даже находясь за пределами офиса. Но инструменты удаленного администрирования работают только после того, как загрузится ОС, если это по каким либо причинам невозможно потребуется физическое присутствие специалиста. Решить эту проблему способны переключатели KVM over IP.

Что такое KVM переключатели знают наверное все администраторы, это устройство позволяющее использовать одну консоль (монитор, клавиатура и мышь) для управления несколькими ПК. KVM переключатели могут быть как простыми, рассчитанными на персональное использование:

Так и для монтажа в стойку, поддерживающими каскадирование и позволяющие управлять сразу большим числом серверов (до нескольких сотен) из одного места:

Особняком в этой компании стоят переключатели KVM over IP, позволяющие получать доступ к консоли ПК из любого места посредством протокола TCP/IP. Долгое время данные устройства считались "предметами роскоши", однако в последнее время на рынке появились предложения по вполне гуманной цене, делающее их вполне доступными и для небольших организаций.

Рассмотрим возможности KVM over IP переключателя на примере ATEN ALTUSEN KH1508i стоимостью 727 USD. Кроме привлекательной цены данное устройство позволяет управлять до 256 ПК (при каскадировании переключателей), поддерживает платформы PC, Mac, Sun, подключения к ПК через PS/2 и USB.

Переключатель выполнен в формате 1U и может быть смонтирован в стойку. На передней панели находятся кнопки переключения выходов, индикатор активного порта, разъем для обновления прошивки, индикатор питания и кнопка Reset.

Еще одной особенностью переключателя является использование для подключения управляемых ПК витой пары UTP 5e, что позволяет размещать их на расстоянии до 40 м. Теперь не возникает проблемы с подключением серверов, находящихся в соседней стойке (или этажом ниже) и не нужно ломать голову над приобретением и прокладкой дорогостоящих специализированных кабелей. Разъемы для подключения управляемых ПК, сети, подчиненных переключателей и консоли находятся с тыльной стороны переключателя:

Для подключения управляемых ПК используются клиентские модули эмулирующие необходимую периферию. Эмуляция производится непосредственно модулем, независимо от наличия управляющего устройства. Это значит, что если вы забыли включить переключатель, управляемые ПК при загрузке все равно обнаружат клавиатуру, мышь и монитор и вам не придется их перезагружать, дабы получить доступ.

Производитель предлагает широкий выбор клиентских модулей управления компьютерами разных платформ, для ПК доступны два типа клиентских модулей: KA9520 (PS/2) и KA9570 (USB) стоимостью в 71 USD. Каждый модуль представляет собой контроллер с интерфейсом RJ-45 и полуметровый кабель с разъемами VGA и PS/2 (USB), имеет собственную прошивку, регулярно обновляемую производителем, на корпусе модуля имеется переключатель, переводящий его в режим обновления прошивки. Ниже показан модуль KA9520:

Для крепления на вертикальную поверхность в комплекте с модулем поставляется специальная корзина.

Настройки переключателя производятся через экранное меню или веб-интерфейс (в несколько ограниченном объеме). Если у вас в хозяйстве нет компьютеров Mac или Sun, то все настройки будут доступны через веб (по умолчанию все порты переключателя настроены на платформу PC).

Соединение с устройством производится по защищённому протоколу HTTPS, несмотря на то, что переключатель принимает соединения по порту 80, все равно происходит редирект на защищенное соединение (443 порт). Для передачи данных между переключателем и программой-клиентом используется порт 9000, это стоит учитывать при форвардинге портов (т.е. кроме 80 и/или 443 нужно пробросить также 9000).

Перейдем к сетевым функциям переключателя, по умолчанию он настроен на получение настроек по DHCP, что, на наш взгляд, гораздо лучше чем заранее установленный IP, достаточно посмотреть какой адрес присвоен устройству в настройках DHCP сервера и зарезервировать его за соответствующим MAC адресом (указан на корпусе устройства).

Для доступа можно использовать любой браузер (оптимально IE), веб интерфейс не богат на настройки, вы можете запустить Windows (только через IE) или Java клиент, либо загрузить их, если запустить через браузер их каким либо образом не получается.

Отдельного внимания заслуживает параметр Network Transfer Rate , для комфортной работы с устройством там следует указать минимальную гарантированную скорость канала по которому осуществляется доступ к переключателю.

Для доступа к управляемым ПК необходимо запустить клиент. Нам не удалось запустить Windows Client на Windows 7 64-bit, в данном случае выручает Java клиент, работающий на любой платформе с поддержкой Java. Уже в клиенте мы можем произвести более тонкую настройку устройства:

Для перехода к управляемым устройствам используется закладка Main , на которой отображаются все подключенные к переключателю (или цепочке переключателей) клиентские модули:

При правильной настройке скорости передачи данных работа через удаленного клиента довольно комфортна, единственным недостатком можно назвать некоторое (иногда значительное) отставание курсора мыши на удаленной системе от курсора на управляющем ПК.

Однако следует помнить, что работа через KVM Over IP требуется по большей части при нештатных ситуациях, когда требуется контроль на уровне загрузки ПК, в остальных случаях будет гораздо комфортней работать через RDP. Если вы используете USB-модуль (KA9570) убедитесь, что в BIOS включена поддержка USB клавиатуры и мыши, во избежание неприятных сюрпризов.

Также советуем настроить в BIOS сервера включение по сигналу с клавиатуры или по сети. Это позволит удаленно включить сервер, если вы вдруг его по ошибке выключите или выключит кто-то из излишне усердных сотрудников.

Переключатели KVM over IP позволяют администратору получить практически полный контроль над управляемым ПК из любой точки мира, был бы доступ в интернет. А кажущаяся на первый взгляд относительно высокая цена устройства с лихвой компенсируется предоставляемыми возможностями. В любом случае стоит прикинуть, что обойдется дешевле, KVM IP переключатель или время простоя предприятия, необходимое для приезда технического специалиста.

  • Теги:

Please enable JavaScript to view the

Эта статья написана под впечатлением от - большое спасибо автору! В этой статье почти удалось сделать собственный IP KVM Switch, и это круто! Но объясню, почему почти. Да, там все работает как и написал автор… До момента перезагрузки в биос - там вся магия рассеивается и сколько не старайся, ничего не происходит.

Решено было исправить это досадное недоразумение и как можно дешевле и компактней. Начнем со стереотипов Raspberry Pi и Arduino, а в следующей будет продолжение уже на другом железе.

Итак, что нам понадобится:

1. Плата видеозахвата обязательно с поддержкой UVC драйвера, вроде этой.Вариантов
полно на алиекспрессе и других китайских магазинах.

UVC это стандартизированный открытый драйвер который по умолчанию входит в большинство линукс дистрибутивов, с другими драйверами могут быть проблемы.

2. VGA to AV Конвертер:



Обратите внимание! Нужен именно VGA to AV, а не наоборот.

3. Arduino UNO, именно UNO, так как на ней есть чип Atmega16u2, он нас интересует в первую очередь. Вот он рядом с USB портом, так же бывают ардуины с чипом Atmega8u2 подойдут и с тем и с тем.

4. Ну и конечно Raspberry Pi, у меня был версии 2 b поэтому все написанное в этой статье актуально именно для него, но в целом думаю не должно возникнуть особых сложностей и с другими моделями малины.

Заливаем дистрибутив

Что ж вводные данные даны, пожалуй приступим.Я использовал дистрибутив 2015-05-05-raspbian-wheezy, вероятно это не принципиально, дальнейшие манипуляции должны подойти для любого дистрибутива основанного на Debian.

Подключаем плату видеозахвата к распберри, подключать лучше напрямую к USB не используя USB удлинителей особенно того что идет в комплекте с платой, иначе может возникнуть торможение видео, подвисания распберри и т.д.

Переходим в консоль, обновляем пакеты:

Sudo apt-get update && sudo apt-get upgrade –y

Передача видео

Проверяем определилась ли плата:

Ls /dev/video*
Должно выдать что-то вроде: /dev/video0.

Устанавливаем Motion, трансляцию захваченного изображения будем вести именно через него:

Sudo apt-get install motion -y
Редактируем конфиг автозапуска:

Sudo nano /etc/default/motion
В строке start_motion_daemon ставим ‘yes’. Сохраняем изменения Ctrl + x, y, Enter.

Редактируем конфиг самого motion(а):

Sudo nano /etc/motion/motion.conf
Меняем значения параметров как указано далее:

Параметр определяет запуск приложения в качестве службы:

Daemon on
Эти параметры определяют разрешение передаваемого изображения, смысла ставить большее разрешение нет, т.к. захват видео ограничен стандартами PAL или SECAM, разрешение коих 720х576. Это кстати досадный недостаток, но об этом позднее.

Width 800 height 600
Частота захвата кадров:

Framerate 25
Отключаем сохранение скриншотов:

Output_normal off
Качество передачи изображения:

Webcam_quality 100
Частота передачи кадров:

Webcam_maxrate 25
Отмена ограничения на подключение с других ip

Webcam_localhost off
Сохраняем изменения Ctrl + x, y, Enter.

Перезагружаем распберри:

Sudo reboot
Ждем пару минут если все сделали правильно должен загореться светодиод на плате видео захвата.

Подключаемся браузером к порту 8081 распберри и видим серый или синий прямоугольник с бегущим снизу временем.

Процесс пошел, ищем жертву для захвата сигнала с VGA порта, подключаем к порту “VGA IN” конвертера, а плату видеозахвата к “VIDEO OUT”. Должна получиться примерно такая картинка, не пугайтесь у меня плохой кабель поэтому изображение «двоит», пробовал с другим изображение было лучше, но разрешение не изменить. 720х576 это ограничение конвертера и платы видео захвата, которое при всем желании не преодолеть.

Что ж передавать изображение научились, осталось дело за малым - передать управление.

Передача управления

Для этого, как вы уже догадались, будем использовать ардуину. Выбор пал на Arduino UNO неспроста, там есть очень нужная для наших целей микросхема с названием Atmega16u2, только благодаря ей мне удалось заставить БИОС компьютера определить arduino как USB клавиатуру. По умолчанию в составе платы ардуино эта микросхема выполняет роль USB to Serial конвертера для заливки прошивки в микроконтроллер Atmega328p, большая прямоугольная микросхема на плате ардуино. По сути же Atmega16u2 является то же микроконтроллером, но с важным отличием, она способна напрямую работать с шиной USB. Atmega16u2, при наличии нужной прошивки, может эмулировать практически любое USB устройство. Понимаете к чему я веду? Мы прошьем это чудо инженерной мысли и заставим трудиться на благо общества.

Прошивка Atmega16u2

На просторах интернета была найдена прошивка , которая превращает Atmega16u2 в USB клавиатуру принимающую команды, определенного вида, через Serial Port.

Инструкция в данной статье написана для windows, линуксоиды же могут воспользоваться этой .

И так приступим, для прошивки потребуется утилита от производителя под названием Flip . Качаем, устанавливаем, запускаем и вот перед нами окно программы:

Сначала кнопки(галки) не активны, это нормально, подключаем ардуину к компьютеру и замыкаем – размыкаем два крайних контакта со стороны USB порта, RESET и GND.

В системе должно появиться новое устройство под названием, как ни странно, ATmega16u2 устанавливаем драйвер(в папке с программой), выбираем в программе flip вкладку «Settings» → «Communication» → «USB» → «open», кнопки должны стать активны. На всякий случай можно сделать бэкап прошивки, чтоб можно было все вернуть на место. В меню «File» нажимаем «Load HEX File», программа требовательна к путям, лучше всего положить файл прошивки в корень диска C:, выбираем нужный hex файл с прошивкой, проверяем стоят ли галки «Erase», «Program», «Verify» и нажимаем «Run». Отключаем - подключаем arduino и вуаля… Теперь мы больше не сможем загружать прошивки в ардуино через встроенный USB, зато получили отличную клавиатуру без кнопок.

Не переживайте по поводу прошивки arduino, прошивку можно будет загрузить из Arduino IDE через отдельный USB To TTL адаптер, хотя надо сказать, теперь это будет менее удобно.

Подключаем USB To TTL адаптер, например такой:

Нам понадобятся Белый, зеленый и черный контакты это RX, TX и GND соответственно, подключаем их к пинам с такими же обозначениями на ардуине, только наоборот RX к TX, а TX к RX. Красный контакт использовать не следует!

Подключаем USB To TTL к компьютеру, устанавливаем драйвера, в диспетчере устройств должен появиться новый COM Port. Открываем arduino IDE и выставляем: Плата - Arduino/Genuino Uno, Порт – наш новоиспеченный последовательный порт.

Приступаем к прошивке arduino

Добавим необходимую библиотеку в arduino IDE: Переходим по ссылке github.com/SFE-Chris/UNO-HIDKeyboard-Library нажимаем «Clone or download» → «Download ZIP». далее в arduino IDE выбираем вкладку «Скетч» → «Подключить библиотеку» → «Добавить.ZIP библиотеку» и выбираем только что скачанный zip архив.

Подготовка закончена, переходим непосредственно к прошивке. Копируем мою писанину:

Arduino - Sketch

#include HIDKeyboard keyboard; int sbor; void setup() { keyboard.begin(); } void loop() { while (Serial.available()) {//запуск цикла при появлении данных sbor += Serial.read();//считывание данных, сложение в десятичном виде if (sbor == 27){//появление символа управляющей последовательности for (int i=0; i<=4; i++){//сложение последовательности if (sbor == 165) {//для определения F1-F12 на разных терминалах могут быть разные значения sbor += sbor; } sbor += Serial.read(); delay(1); } } } if (sbor > 0) { //переход по десятичной сумме последовательности switch (sbor){ case 505: keyboard.pressSpecialKey(F1); break; case 506: keyboard.pressSpecialKey(F2); break; case 507: keyboard.pressSpecialKey(F3); break; case 508: keyboard.pressSpecialKey(F4); break; case 509: keyboard.pressSpecialKey(F5); break; case 511: keyboard.pressSpecialKey(F6); break; case 512: keyboard.pressSpecialKey(F7); break; case 513: keyboard.pressSpecialKey(F8); break; case 340: keyboard.pressSpecialKey(F9); break; case 341: keyboard.pressSpecialKey(F10); break; case 343: keyboard.pressSpecialKey(F11); break; case 344: keyboard.pressSpecialKey(F12); break; case 13: keyboard.pressSpecialKey(ENTER); break; case 22: keyboard.pressSpecialKey(ESCAPE); break; case 127: keyboard.pressSpecialKey(BACKSPACE); break; case 9: keyboard.pressSpecialKey(TAB); break; case 32: keyboard.pressSpecialKey(SPACEBAR); break; case 26: keyboard.pressSpecialKey(PAUSE); break; case 292: keyboard.pressSpecialKey(INSERT); break; case 456: keyboard.pressSpecialKey(HOME); break; case 295: keyboard.pressSpecialKey(PAGEUP); break; case 294: keyboard.pressSpecialKey(END); break; case 296: keyboard.pressSpecialKey(PAGEDOWN); break; case 182: keyboard.pressSpecialKey(RIGHTARROW); break; case 183: keyboard.pressSpecialKey(LEFTARROW); break; case 181: keyboard.pressSpecialKey(DOWNARROW); break; case 180: keyboard.pressSpecialKey(UPARROW); break; case 293: keyboard.pressSpecialKey(DELETE); break; case 320: keyboard.pressSpecialKey((CTRL | ALT), DELETE); break; //для вызова ctl+alt+del нажать alt + del case 346: keyboard.pressSpecialKey(ALT, F4); break; //для вызова alt+f4 нажать shift + F4 default: keyboard.pressKey(sbor); break; } //Serial.println(sbor);//только для отладки без подключения к usb keyboard.releaseKey(); sbor = NULL; } }


вставляем в arduino IDE и нажимаем кнопку проверки. Вот сейчас начнется самый ответственный этап, тут самое главное поймать момент, мало у кого получается с первого раза. Нажимаем кнопку загрузки в arduino IDE, сначала побегут белые строчки с логом компиляции, за ними последуют оранжевые, это уже установка соединения с последовательным портом, вот этот самый момент надо поймать и успеть нажать на плате ардуины кнопку RESET. Должна произойти загрузка прошивки, если все удачно вы увидите надпись вроде этой

Avrdude: reading on-chip flash data: Reading | ################################################## | 100% 0.34s avrdude: verifying ... avrdude: 2934 bytes of flash verified avrdude done. Thank you.
Если после нескольких попыток загрузка прошивки так и не произошла, попробуйте поменять местами контакты RX и TX, а также проверьте надежно ли подключен контакт GND.

Финишная прямая

Открываем консоль на распберри и пишем:

Sudo raspi-config
Откроется меню настройки распберри, выбираем «Advanced Options» → «Serial» и выбираем «No».

Возможно эти манипуляции и не понадобятся, так, перестраховка. Этот параметр определяет, будет ли ОС на малине взаимодействовать с serial портом, это взаимодействие нужно в основном для отладки, так что смело отключаем, нам оно будет только мешать, т.к. с ардуиной мы будем общаться именно через этот порт, а система будет засорять эфир.

Устанавливаем программу minicom.

Minicom - простенькая программа для работы с serial портом.

Sudo apt-get install minicom -y
Задаем права на доступ к устройству, /dev/ttyAMA0 - это тот самый сериал порт.

Sudo chown pi /dev/ttyAMA0 sudo chmod 744 /dev/ttyAMA0
Запускаем minicom:

Sudo minicom -s
Откроется меню программы, выбираем пункт «Serial port setup», откроется еще одно меню, выбираем «Serial Device» нажатием на клавишу A, прописываем /dev/ttyAMA0, нажимаем Enter, далее выбираем пункт Bps/Par/Bits под буквой E, появляется очередное меню нажимаем C и Q строчка Current: должна выглядеть вот так «9600 8N1» нажимаем Enter. Убедимся что в строчках F - Hardware Flow Control: и G - Software Flow Control: стоит No, в общем все должно быть как на скриншоте ниже, нажимаем Enter.

Сохраним эти настройки как настройки по умолчанию «Save setup as dfl» и закрываем «Exit from Minicom».

Подключение

Едем дальше, теперь у нас практически все готово, осталось только подключить ардуину к serial порту малины, вот как-то так:

Здесь есть один момент, у ардуино и распберри разные уровни напряжения и по идее их нужно согласовать, советую ознакомиться со статьей .

Хотя у меня все заработало напрямую без согласования, не следует подражать плохому примеру и приобрести преобразователь логических уровней, самый простой выглядит так:

Или хотя бы собрать делитель напряжения на резисторах.

Запуск

Все готово, можно начинать.

Проверяем все соединения, вкючаем raspberry pi, переходим в консоль малины, запускаем minicom. Сразу оговорюсь я подключался к малине через ssh, в качестве клиента использовал KiTTY(модифицированную версию PuTTY), это важно т.к. с другими терминалами значения передаваемых клавиш могут быть иными и соответственно нужно будет сделать поправку на ветер - поменять номер перехода switch case.

В общем передаю вам в руки как говорится «as is». Что ж на этом пожалуй закончу, самодельный IP KVM готов.

P. S.

На последок опишу что получилось в сухом остатке.

Плюсы:

- Цена
- Устройство получилось относительно недорогим
- Raspberry Pi: примерно 2700руб.
- Arduino UNO: примерно 400руб.
- VGA to AV конвертер: примерно 700руб.
- Плата видеозахвата: 500руб.
- Итого: 4300руб.

- Тонкая настройка
Можно перехватывать практически любые комбинации и назначать на них практически любые клавиши вплоть до KEYBOARDPOWER и VOLUMEUP, кстати возможные значения можно посмотреть в заголовочном файле HIDKeyboard.h, а можно и добавить свои.

Минусы:

- Торможение как видео, так и передачи нажатий
- Второй и самый большой это качество изображения , здесь просто необходим грустный смайлик, оно ужасно, даже если убавить разрешение на целевом компьютере до минимума, максимум что можно будет сделать, это настроить БИОС и выбрать пункт в загрузчике. Но разве собственно не для этого нужен KVM?.. А для всего остального существует радмин и ему подобные.

Теги:

  • удаленное администрирование
  • ip kvm
  • how to
Добавить метки

Здравствуйте друзья! Для подключения двух компьютеров к одному интерфейсу, я приобрёл на Aliexpress-е за 4$ вот такой, самый простой KVM VGA переключатель.

Выбор пал на VGA, так как мой монитор не имел HDMI входа, а по входу DVI не захотел работать через адаптер.



Предположение, что на печатной плате хватит места на ещё два переключателя для коммутации аудио и USB разъёмов, полностью оправдалось.

Конечно, можно было бы приобрести уже готовый переключатель, но я не нашёл ни одной полностью удовлетворяющей моим запросам модели. Это касалось, как расположения кабелей, так и необходимости использования, либо специальных кабелей, либо USB и аудио кабелей с двумя разъёмами.

Так что, я решил, что будет проще и дешевле переделать именно вот этот девайс под свои запросы.


Правда, пришлось заменить переключатель мониторов, так как мне попался усечённый вариант KVM VGA, где не хватало одной группы контактов. Как потом выяснилось, нужно было выбирать вариант, где в технических данных было прописано разрешение Full HD. Но, и тут трудностей не возникло, так как необходимые дорожки были проложены на плате и осталось просто заменить П2К.


Два дополнительных переключателя распаял в пистонах, запрессованных в печатную плату.


Для дополнительных кнопок пришлось просверлить в лицевой панели два отверстия.


Ещё шесть отверстий просверлил в задней стенке для соединительных кабелей.

USB кабели тоже изготовил самостоятельно.


Для усиления резьбы, соединяющей половинки корпуса, запрессовал две буксы, чтобы с помощью дополнительных угольников можно было надёжно закрепить переключатель.


Вот что у меня получилось в результате.


С помощью этого KVM переключателя, я коммутировал интерфейсы двух ноутбуков, работающих десктопами.


Переключатель закрепил на полке, расположенной над столом. На этой фотографии видно, что кнопки переключения мониторов были заменены. Оригинальные кнопки оказались слишком короткими и их было неудобно нажимать.

Это уже третья вариация на тему IP KVM"а, на этот раз концепт полностью пересмотрен, начнем строить нечто новенькое. Будет много интересного, не отходите от экрана. Появится еще один необычный девайс, отбросим почти все старые компоненты, вернемся обратно к родной ардуино и немножко поиграем в хакера.

Для тех, кто только что присоединился, краткое содержание предыдущих серий:


  • Собирали IP KVM на Arduino и Raspberry Pi, получилось дорого и с плохим качеством видео.

  • OrangePI и Atmega16u2, поучилось дешево, но качество изображения всё также отвратительно.

И вот, наконец, в этой статье будут исправлены все минусы предыдущих. Особый упор будет сделан на максимальное снижение стоимости компонентов.

По традиции рассмотрим составные части собираемого устройства:

1. Наша старая знакомая Atmega16u2:

Это единственный компонент, который перейдет из предыдущих статей.

2. Небезызвестный ESP8266, в данном случае ESP8266-12e:


Можно использовать и другую версию ESP8266, только необходимо учитывать количество и расположение портов.

3. И, собственно, виновник торжества LKV373A


Благодаря этому устройству стало возможным передавать видео по локальной сети, с высоким
разрешением вплоть до full-HD.

План мероприятия таков:

  1. Игра в прятки: Ищем LKV373A куда он спрятался в сети под каким ip адресом
  2. Игра в хакера: Заливаем прошивку, сбрасываем пароли и настраиваем LKV373A
  3. Заводим новых друзей: ESP8266, Arduino IDE и веселые картинки
  4. Финал торжества. Подключаем все компоненты и передаем нажатия клавиш через telnet

LKV373A, предыстория

Итак, приступим! LKV373A или HDMI Extender устройство для захвата изображения прямо с порта hdmi и трансляции в локальную сеть, эти устройства еще называют hdmi удлинителями. По задумке производителей комплект подобных устройств должен состоять из transmitter (передатчика) и receiver (приемника), обозначение TX и RX соответственно. Использоваться они должны, вероятно, для того, чтобы приносить производителю больше прибыли, только в паре. Но нашелся человек, под ником Danman вот ссылка на его блог, которому стало интересно как это работает. Открыл он Wireshark, поснифал трафик передаваемый TX устройством, что же оказалось?

Видеопоток передается без какого-либо шифрования, и при помощи VLC Player"a можно посмотреть его без лишних усилий. Но на этом он не остановился, «пощупал»: и веб интерфейс, и TTL, и телнет, и даже прошивку программатором стянул. Об этом он в подробностях рассказал в своем блоге. Там же была выложена прошивка, которая интересует нас в первую очередь: IPTV_TX_PKG_v4_0_0_0_20160427.PKG. В этой прошивке веб интерфейс с расширенными настройками, а не как у стандартной только кнопка обновить. К тому же, в этой прошивке есть телнет с множеством команд для настройки. Именно при помощи этой прошивки мы перенастроим HDMI Extender под наши задачи. Прошивку и все необходимое я выложил на github вот ссылка , она понадобится нам позднее, а пока заканчиваем с теорией. Переходим к практике.

Передатчик

Ищем LKV373A в сети

Мне попался в руки такой же extender что и Danman(у). Все что будет изложено далее подходит именно для HDMI Extender LKV373A версии V3.0!

Подключаем LKV373A к локальной сети, включаем питание. Теперь попробуем удостовериться, что устройство видно в сети ping 192.168.1.238 .

192.168.1.238 это IP-адрес по умолчанию. Если на extender"ре старая прошивка адрес не изменится, независимо от того, присутствует DHCP сервер в сети или нет. Более новые версии прошивки используют IP по умолчанию только, если устройство не смогло получить адрес от DHCP. Если на ping запрос получили ответ, продолжаем дальше. Если нет, не отчаивайтесь, попробуйте подключить extender напрямую к LAN порту компьютера и воспользоваться сниффером.

Прошиваем

HDMI Extender нашли, перейдем к прошивке. Зайдем на гитхаб и скачаем все, что там выложено. Теперь откроем веб интерфейс extender"а через браузер и увидим такую картину:


Нажимаем «Browse…», выбираем прошивку, файл с названием IPTV_TX_PKG_v4_0_0_0_20160427.PKG, и нажимаем «Upgrade». Тадам! Прошивка завершена, теперь подключимся к LKV373A по телнету, чтобы сбросить пароль.

Команда для подключения будет выглядеть примерно так Telnet 192.168.1.238 9999, где 9999 - это порт для подключения. КЭП предупреждает: адрес полученный от DHCP можно узнать при помощи сканера сети.

Подключаемся через телнет

При подключении должно появиться следующее сообщение:

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

Пишем list . В ответ получаем список команд:

============================== ========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

Для сброса всех настроек и пароля используем команду factory_reset . Пишем команду, нажимаем enter и получаем такую картину:

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

Веб интерфейс

Теперь мы можем настраивать устройство как нужно нам. Зайдем в веб интерфейс. Используем стандартные логин:admin пароль:123456 и вот он, «желанный» веб интерфейс с дополнительными пунктами настройки:


Хотя возможностей в веб интерфейсе прибавилось, но их всё же для наших целей недостаточно. Особенно не хватает более свободных настроек в части стриминга, там жестко задан, далеко не самый удобный, список ip-адресов на которые можно стримить. Есть конечно мультикаст, но это лучше оставить для телевидения. Ограничения можно обойти, об этом немного позднее.

Вот, устройство в сети нашли, прошивку «накатили», пароли сбросили. Передатчик почти готов перейдем к приемнику.

Приемник

Давайте определимся, на устройство, под управлением какой операционной системы, будем передавать поток. Муки выбора думаю испытывать не будете, варианта всего два:

Windows

Для виндовс попробовал несколько плееров, но результаты получились так себе. При захвате и последующем воспроизведении видеопотока появляется задержка, которая в первую очередь зависит от плеера воспроизводящего поток. На различных плеерах задержка варьировалась от одной секунды, до пяти и даже больше. Лучше всех, на виндовс, показал себя VLC Player.

Перейдем к делу. Запустим VLC Player, сверху в выпадающем меню «Медиа» выбираем пункт «Открыть URL…» в поле сетевого адреса пишем udp://@:5004 , ставим галку в чекбоксе «Показать дополнительные параметры» и в поле «Кэширование» ставим свое значение, этот параметр определяется индивидуально. Чем меньше значение в этом поле, тем меньше задержка, но слишком малое значение может привести к «артефактам» и выпадениям кадров, все будет зависеть от инфраструктуры локальной сети. Лучшие результаты, которых смог добиться, это задержка около одной секунды. На линуксе же, результаты получились гораздо лучше около 200-300 миллисекунд.

Linux

Как показывает практика, лучшие результаты получаются при использовании связки программ socat и mplayer. На моем компьютере установлена Ubuntu, поэтому команда для установки socat будет выглядеть так:

Sudo apt-get install socat

Mplayer устанавливается аналогично:

Sudo apt-get install mplayer

Ну, и прислушаемся совету Danman"а:

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

Эта команда нужна для того что бы убрать из потока так называемые «Zero Length UDP Packets» - пакеты нулевого размера, которые «засоряют» поток.

Выходим в прямой эфир!

Приемник готов, можно запускать трансляцию! Набираем в консоли принимающего компьютера ifconfig или ipconfig в зависимости от операционной системы, Запоминаем IP-адрес приемника и вернемся к веб интерфейсу передатчика. Откроем веб-интерфейс, если вдруг уже закрыли, введем логин, пароль и прямо в адресной строке браузера пишем:

Http://АйПиПередатчика/dev/info.cgi?action=streaminfo&udp=n&rtp=y&multicast=n&unicast=y&mcastaddr=АйПиПриемника&port=5004

Подставляем свои IP-адреса и нажимаем enter. Эта строка настроит HDMI Extender для трансляции захваченного видео на выбранный вами ip и выключит мультикаст.

Запускаем VLC в Windows. Или в терминале Linux пишем:

Socat UDP-RECV:5004 - | mplayer –

Абра кадабра! И вот наш, или не наш, рабочий стол в прямом эфире.


Вот так, при помощи немного хакерских методов, мы заставили устройство выполнять то, что нам требуется.

С передачей видео разобрались, переходим к удаленному управлению.

Передача управления

Выбор комплектующих

Т.к. стоимость HDMI Extender"а невысока, около 1800 рублей, а так же из-за комментариев что, мол, дороговато, выдвигаю лозунг: «Даешь IP KVM за 2000 рублей!». На верность этого утверждения будет сильно влиять курс рубля, но не будем о грустном, хочется верить в светлое будущее. Для достижения цели нам понадобятся очень дешевые элементы, мой выбор пал: на ESP8266 в качестве контроллера, и все того же Atmega(8/16/32)u2 в качестве исполнительного устройства.

Можно конечно рассмотреть и другие кандидатуры на роль исполнительного устройства(клавиатуры). Прошивка, эмулирующая клавиатуру, написана на библиотеке LUFA(вроде как). Эта библиотека может использоваться для всего семейства AVR с возможностью подключения к USB. Из этого следует, что в качестве эмулятора клавиатуры можно подобрать, возможно более дешевый, микроконтроллер. Это информация к размышлению, а сейчас продолжим.

Приобрести ESP8266 можно примерно за 90 рублей, Atmega(8/16/32)u2 примерно за 100 рублей, и даже дешевле, если брать небольшими партиями по 5, или больше штук. Конечно, нужны будут расходные материалы для обвязки микроконтроллеров, но стоимость их крайне мала, поэтому рассматривать их не буду.

ESP8266

Это чудо китайской промышленности не нуждается в представлении, посему скажу только, что в этом проекте я использовал версию ESP8266-12e. Использовать другие версии конечно можно, только нужно учитывать расположение портов, т.к. в данном варианте один из портов ESP8266 используется для включения питания на Atmega(8/16/32)u2, ниже будет указано на схеме.

Прошивка

Прошивка для ESP8266 написана в среде ArduinoIDE так что давайте скачаем свежую версию с сайта разработчика . Далее нужно добавить поддержку ESP8266 - самый простой способ можете найти по этой ссылке . На той же странице можно найти много полезной информации, например схема подключения к питанию и TTL. Для тех, кто не в курсе ESP8266 использует строго 3.3 вольта! Если не уверены в собственных силах, лучше использовать вариант платы адаптированный для USB, вроде NodeMCU:


Если все готово открываем ArduinoIDE и копируем мой скетч:

Скетч

#include #include #include #include #include #include #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; const char* serverIndex = "

BACK";//Update //Возврат на главную страницу void handleRedirect(){ String content = ""; 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 OKrrnLocation: /rnCache-Control: no-cachernrn"; 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 = "
Enter the access point name and password
";//страница ввода SSID и пароля content += "Name AP:
"; content += "Password:

"; content += "
" + msg + "
"; content += "Firmware update UPDATE"; server.send(200, "text/html", content); } void handleNotFound(){ String message = "File Not Foundnn"; 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 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 %unRebooting...n",Update.hasError()); if (uperror == 0) server.send(200, "text/html", "Firmware update successfully BACK"); else server.send(200, "text/html", "Update error BACK"); ESP.restart(); },(){ HTTPUpload& upload = server.upload(); if(upload.status == UPLOAD_FILE_START){ Serial.setDebugOutput(true); WiFiUDP::stopAll(); Serial.printf("Update: %sn", upload.filename.c_str()); if (upload.filename == NULL) { Serial.printf("ERROR: zero file size"); server.send(200, "text/html", " zero file size BACK"); 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: %unRebooting...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; 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); } } } } }

Подключим нужную библиотеку:

Выбираем вкладку «Скетч» → «Подключить библиотеку» → «Добавить.ZIP библиотеку» Выбираем библиотеку под названием «UNO-HIDKeyboard-Library-master(mod).zip», которую скачали с гитхаба. Компилируем и заливаем прошивку. Для загрузки прошивки подключаем ESP8266 TTL, выставляем нужный порт в ArduinoIDE. Настройки должны выглядеть примерно так:


Чтобы загрузить прошивку, нужно порт GPIO0 замкнуть на землю, и перезагрузить микроконтроллер кратковременно замкнув порт Reset так же на землю. Подробно расписывать не буду, чтоб не раздувать статью, гугл вам в помощь.

Логика работы ESP8266 такова: При подаче питания микроконтроллер в течении примерно тридцати секунд пытается подключиться к FI-WI точке доступа:

Если подключение удалось : открывает 23 порт, к которому можно подключиться, используя telnet и передавать нажатия клавиш. Кроме клавиш можно передавать комбинации, построенные на «Ctrl + key» которые будут нажимать определенные сочетания. Например, если передать «Ctrl + d», на управляемом компьютере будет нажато сочетание CTRL+ALT+DELETE.

Также имеются комбинации для управления портами ESP8266, можно, например, подсоединить реле и при помощи комбинации «Ctrl+q» включать и отключать реле, тем самым удаленно включать и отключать управляемый компьютер. Эти и другие комбинации можете посмотреть в исходниках.

Если не удалось : ESP8266 переходит в режим точки доступа, с названием «TD», Паролем «testtest» и открывает небольшой веб интерфейс, доступный по адресу 192.168.4.1, в котором можно задать настройки для подключения по WI-FI.


Таким образом, устройство можно легко подключить к другой точке доступа. Да, тут скрывается ложка дегтя, для работы нашего IP KVM"а потребуется и LAN кабель и Wi-Fi. Такова будет плата за дешевизну устройства.

С ESP8266 разобрались, с Atmega16u2 все как в предыдущих статьях, прошиваем программой Flip, прошивка есть в архиве скачанном с гитхаба.

Подключение компонентов

Для правильного подключения компонентов прикладываю схему. Только учтите, это примерная схема, она служит для наглядности и не претендует на звание идеальной. Каждый волен «обставить» её как ему нравится.


Поясню некоторые моменты: Транзистор на схеме нужен для того, что бы включать Atmega16u2 уже после загрузки ESP8266 т.к при включении ESP8266 на все TX порты передается отладочная информация, и если Atmega16u2 включен и подключен к компьютеру, ему передается поток данных, с объемом которых не справляется драйвер. Доподлинно неизвестно что происходит в этот момент, предположительно переполняется буфер драйвера, эффект получается крайне неприятным: происходит нажатие(программное) сотен клавиш, если открыт текстовой редактор туда высыпает кучу тарабарщины, при этом залипают все служебные клавиши и в итоге работа с клавиатурой становится не возможной. Что бы избежать этого, питание на Atmega16u2 нужно подавать после загрузки ESP8266. В прошивке этот момент учтен.

Есть, конечно, альтернатива схеме, но это вариант для богатых, или ленивых. И кстати этот вариант не отменяет вышеизложенное:


На снимке Arduino UNO без чипа Atmega328p подключенный к китайскому аналогу NodeMCU. Линия 3.3 вольта подключена к линии того же уровня напряжения на Arduino, а так же подключена земля и контакт GPIO2(ESP8266) к контакту RX на Arduino(ошибка, следует подключать к TX ).

Финальная проверка

Подключаемся по телнету на 23 порт и проверяем работоспособность. Сделать это можно: На Windows командой telnet .

На Linux будет немного сложнее:

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

Все готово, можем проверять работу созданного нами устройства. Напомню возможные комбинации для нажатий «Alt + Tab», «Ctrl + Alt + Del» и д.р. можете посмотреть в скетче. Вот и все, третья инкарнация DIY IP KVM"а готова.

Подведем итоги

Плюсы:

  • Вероятно самый важный плюс это цена, получилось уложиться в 2000 рублей
  • К качеству видео теперь никаких претензий быть не должно, без проблем можно стримить вплоть до Full HD
  • Возможность расширить функционал, добавив до четырех реле или другие исполнительные устройства.

Минусы:

  • Необходимость в подключении и по Wi-Fi, и по Lan кабелю
  • При использовании с VGA необходим переходник, что естественно отразится на себестоимости

В общем и целом, устройство получилось достойное внимания, конечно, оно не конкурент серийным IP KVM"ам со всеми их «плюшками», но зато сильно выигрывает в цене. И для домашнего использования, а может и не только, вполне подходит.

Пользуясь случаем хотел поблагодарить пользователя DaylightIsBurning ! Этот добрый человек подсказал верное направление, в котором нужно вести раскопки.

Благодарю за внимание. До новых встреч!