- Проброс COM-порта с линукса на винду
- Re: Проброс COM-порта с линукса на винду
- Re: Проброс COM-порта с линукса на винду
- Re: Проброс COM-порта с линукса на винду
- Re: Проброс COM-порта с линукса на винду
- Как пробросить com порты (RS-232) с компьютера под управлением debian linux на компьютер под управлением ms windows
- Пробрасываем порт UART из Linux в Windows через SSH-соединение
- 1. Введение
- 2. Теория со стороны Linux
- 2.1 Полезная утилита socat
- 2.2 Специально настроенный пользователь
- 2.3 Пишем autoexec.bat
- 3. Практическая проверка со стороны Linux
- 3.1 Сбойный прогон
- 3.2 Успешный прогон
- 4. Работа со стороны Windows на C#
- 4.1 Почему C#
- 4.2 Как добыть и подключить библиотеку
- 4.3 Подключаемся к серверу
- 4.4 Создание потока данных
- 4.5 Передача на сервер
- 4.6 Приём с сервера
- 4.7 Проверяем
- 5. Работа со стороны Windows на прочих языках
- 6. Заключение
Проброс COM-порта с линукса на винду
Есть настроенный тонкий клиент ThinStation 2.2. Сервер терминалов Win2k. Подключаюсь через rdesktop. В параметрах rdesktop пишу «-r comport:COM3=/dev/ttyS0», захожу на сервер терминалов — COM порта нету.
К этому тонкому клиенту будет подключен кассовый апарат. Есть ли какое-нибудь решение для создания виртуального порта на офтопике, который будет пробрасываться на ThinStation?
Исходники ThinStation есть, могу что-нибудь поправить. Уже гуглил на эту тему, но там все только для винды, и все платное. Есть ли какой GPL-ный виртуальный ком-порт и для винды, и для линукса?
Re: Проброс COM-порта с линукса на винду
Насколько я понимаю, это не проблема linux-а. Это проблема винды. Точнее её терминал-сервера, который является сознательно урезанной версией Citrix-metaframe и не поддерживает мапинг ком-портов. Microsoft приобрела лицензию у citrix на условиях, что не будет составлять citrix конкуренцию. А для этого порезали функционал.
Как выход — поставить Citrix-metaframe на сервер и переброс портов сразу заработает.
Re: Проброс COM-порта с линукса на винду
>Насколько я понимаю, это не проблема linux-а. Это проблема винды
Согласен. Задача в том, чтобы пробросить порт сторонними средствами (не RDP). А в гугле виртуальных портов полно, только денег они хотят.
Re: Проброс COM-порта с линукса на винду
Для обсуждения проблем винды линукс.орг.ру не самое подходящее место 😉
Re: Проброс COM-порта с линукса на винду
>Для обсуждения проблем винды линукс.орг.ру не самое подходящее место 😉
Ищу программу под лицензией GPL. Где еще можно поискать, кроме как здесь?
Как пробросить com порты (RS-232) с компьютера под управлением debian linux на компьютер под управлением ms windows
На работе понадобилось всё реорганизовать, ибо до меня настраивал сеть и компьютеры инвалид третьей степени, его на полном серьёзе увезли в психиатрическую клинику. До него компьютеры настраивал повёрнутый на религии баптист который забивал на работу и славил господа. А да него человек просто спился. Теперь там работаю я.
Есть программа «Мираж» от НПП «Стелс» http://nppstels.ru/products/pcn/software-pcn/ эта программа через GSM-модемы держит связь с охранными устройствами. Для хранения событий и конфигурации объектов, программа использует PostgreSQL . Как я понял сам и подтвердил это в разговоре со специалистом службы технической поддержки, периодические мистические неисправности возникают от того что все компоненты системы (сервер, база, клиент) поставлены на одном обычном компьютере. И не на диске «C», а на диске «D».
Базу данных я перенесу на linux-сервер, это не так уж и трудно. Но, модемы расположены в диспетчерской которая уже забита компьютерами и отдельный системный блок для сервера, ещё более стеснит там обстановку. Поэтому думаю перенести модемы модемы на второй этаж. Но если поставить сервер на втором этаже, то все офисные крысы взвоют от того что я их стесняю и к тому же второй этаж на ночь запирают. А если понадобиться иметь доступ к серверу, то будут большие трудности.
В идеале хотелось бы расположить на верху модемный сервер на linux (что бы точно не зависал). То есть сервер со множеством com-портов. А на windows серверах использовать те порты удалённо через локальную сеть. Так же это могло бы позволить легко переключить GSM оборудование на резервный сервер.
Подскажите мне какие нибудь способы это сделать?
Пробрасываем порт UART из Linux в Windows через SSH-соединение
Не так давно в нашем сервисе All-Hardware произошло знаковое событие. Если раньше порт UART был подключён только к терминалу внутри браузера, то теперь можно установить в Windows специальный драйвер, через который этот порт будет проброшен в вашу локальную систему. Теперь работа с удалённой платой даёт что-то большее, чем написание «Hello World». Вы можете запустить на своей локальной машине программы, которые работают с COM-портом, и обмениваться с удалённой платой по сложным протоколам. Из того, что уже реализовано на практике, – измерение тока потребления платой STM32G474RE DPOW1 Discovery.
Лично я в эпопее по внедрению данной функциональности участия не принимал, так как в то время одомашнивал оборотней (осваивал работу с синтезируемым ядром RISC-V — SweRVolf), но расспросил участников, какие технологии они применяли. В этой статье я покажу физические принципы, лежащие в основе проброса. Практический выхлоп будет состоять в том, что вы сможете пробрасывать порт, не устанавливая никаких драйверов, но реализуя особую (а не универсальную) логику в своей программе. Ну, и вы поймёте, как можно пробросить порт не только для нашего сервиса, а вообще из ОС Linux.
1. Введение
Сначала стоит напомнить, что такое сервис All-Hardware. Подробно про него можно почитать в моих предыдущих статьях (раз и два). Есть также статья моего коллеги. А если кратко, то это такой сайт, через который можно поработать с отладочными платами на базе микроконтроллеров. Сейчас там есть STM32 и NXP. При этом вы пишете и компилируете код на своей машине, а затем просто подключаетесь отладчиком к нашему серверу. Все современные средства отладки позволяют работать не только локально, но и удалённо, и сервис эту возможность использует. Ну, а для обратной связи на сервере имеется видеокамера, которая снимает состояние платы (её светодиоды и экран).
Но реальная работа с платами обычно подразумевает что-то большее, чем пошаговую отладку и просмотр экрана. Платы должны что-то делать. И для этого у них имеются порты. С древнейших времён в нашем сервисе был терминал, через который можно было общаться с UART. Однако интерактивная работа – это хорошо, но работа собственных программ – лучше. И при внедрении платы STM32G474RE DPOW1 Discovery производитель решил, что на локальных машинах пользователей просто необходимо запускать готовую программу, которая в обычной жизни общается с платой через COM-порт Windows. Ребята написали драйвер уровня ядра, благодаря которому на локальных машинах появляется обычный COM-порт. Но физически он пробрасывается на наш сервер. Какие при этом используются технологии – мы сейчас и рассмотрим. Свой драйвер мы не сделаем. Но при разработке своей программы под Windows нет особой разницы, общаться с COM-портом или вызывать иные функции. А вот вызывать функции, которые будут реализовывать проброс на любой Линуксовый сервер, а не только наш – мы научимся.
Однако сначала я просто обязан упомянуть про конкурс разработки прошивок для плат, размещенных на сервисе All-Hardware, который идёт как раз в то время, когда статья выкладывается в публикацию. Вдруг это будет кому-то интересно. Конкурс продлится до 24 апреля.
2. Теория со стороны Linux
2.1 Полезная утилита socat
Центральным элементом для проброса портов является забавная утилита socat. Она позволяет пробрасывать данные из одного источника в другой. Список возможных источников – просто широчайший. Установите эту программу:
sudo apt-get install socat
и затем – подайте:
socat –h
Под катом – простыня, описывающая все возможности пробросов…
Впечатляет? Сейчас мы попробуем при помощи этой утилиты пробросить порт UART в терминал. Я подключил к системе наш интеллектуальный контроллер реле, который был описан в этой статье. В ней же был описан способ, как определить имя получившегося устройства.
Собственно, конкретно у меня в системе сейчас имеется всего один последовательный порт, но если бы их было несколько, я бы догадался, с каким из них работать, по ID (голубая часть идентификатора). Для простоты, я буду использовать короткое имя (оранжевая часть идентификатора). В общем, имя – /dev/ttyACM0.
Вбиваю вот такое заклинание:
Это я запустил программу socat, соединив устройство tty (терминал) с последовательным портом. Работа неблокирующая, данные передаются в сыром виде. Все служебные сообщения уйдут в пустоту.
И тишина. Но зная, что наш контроллер интеллектуального реле реагирует на символ «знак вопроса», я нажимаю его и вижу ответ «abc»:
Нажимая управляющие клавиши для контроллера, я вижу, что вообще-то нахожусь в терминале для последовательного порта, так как все они прекрасно обрабатываются USB-устройством.
Наверняка, кто-то уже хочет задать вопрос, как это я так лихо настроился на работу с портом, не указав его скорость? Ну, просто контроллер интеллектуально реле – это USB-устройство с интерфейсом CDC. Данные из канала USB сразу попадают в память, а в физический интерфейс UART они никогда не поступают. Именно поэтому я эту поделку и взял для проверки. Минимум возможных мест для сбоя! Но вопрос про скорость – верный. Чтобы её задать, перед запуском socat следовало подать команду вида:
То есть, совсем честный запуск терминала должен был выглядеть так (на самом деле, можно обойтись и без sudo, как – скоро расскажу):
Для проверки я подключу к системе настоящий переходник USB-UART и задам скорость не 115200, а какую-нибудь не самую типовую. Скажем, 38400. Это надо, чтобы исключить случайное совпадение, вдруг мы запросили стандартную скорость, а она уже была выставлена. Сначала я хотел задать совсем нестандартную, но система не дала мне это сделать. В Windows таких проблем не возникало, хочу 12345 – задаю 12345. Линукс так не позволил.
После установки скорости я пошлю свой любимый символ «U» (его код 0x55, то есть, чередующиеся нули и единицы) и измерю фактическую скорость при помощи курсорных измерений осциллографа.
Скорость установлена верно (c поправкой на погрешность переходника). Замечательно. Мы смогли пробросить терминал ОС в последовательный порт. Теперь надо подключиться к системе и начать работать с этим терминалом. Но желательно сделать это с максимальным уровнем автоматизации. Давайте рассмотрим, как это сделали наши разработчики.
2.2 Специально настроенный пользователь
При работе сторонних пользователей с нашим сервером не стоит давать им вводить команды в терминал. И дело даже не в безопасности (хотя, и в ней тоже). Дело в том, что пользователь зашёл на сервис All-Hardware, чтобы поработать с микроконтроллерами, а не для того, чтобы поработать с Линуксом. Своё отношение к работе с ним я уже многократно высказывал. Лично мне эта работа не нравится. 50 на 50, что приходящие на сервис пользователи будут такого же мнения. Скрываем работу с ОС, и вопрос «нравится или нет» исчезает сам собой. Поэтому мы создадим пользователя, при подключении которого к системе, автоматически будет проброшен порт. И пользователь, работая через SSH-терминал, сразу будет общаться именно с этим портом. Никакой подготовительной работы от него не потребуется.
Итак, начинаю цитировать методичку. Создаём аккаунт пользователя с именем, скажем, uart01:
Важный ключик здесь «-s». Он задаёт скрипт, который будет запускаться при входе пользователя. У меня на языке крутится имя autoexec.bat или, скажем, STARTS.COM, если кто-то такое ещё помнит. Но здесь файл будет называться /var/lib/redd/bin/uart/uart01.
В скрипте бесполезно использовать команду sudo – некому вводить пароль. Чтобы созданному пользователю разрешали запускать программы socat, stty и прочие, работающие с портами, без прав администратора, добавляем его в группу dialout, для чего подаём команду:
Что мы видим, когда подключаемся к удалённой машине по SSH? А давайте проверим на практике:
Чтобы эта простыня не выдавалась на экран при каждом подключении, надо подать следующую команду, настраивающую свойства пользователя:
Ну что ж. Методичку я с умным видом процитировал. Давайте хоть сам проверю, сработает ли эта последовательность.
Да-с. Фальстарт… Но мы знаем, что не хватает прав – добавляй sudo. Пробуем ещё раз, применяя это знание:
Было предупреждение, что нет того самого autoexec.bat, но мы его сейчас добавим. В остальном –всё чистенько. Как выяснилось в дальнейшем, чего в методичке не хватает, так это пароля для пользователя. Немного погуглив, я выяснил, что его можно назначить так:
2.3 Пишем autoexec.bat
На самом деле, боевой вариант скрипта у нас на сервере просто огромен. Сначала полтора экрана занимает зачистка ресурсов. Она необходима на случай, если предыдущая сессия неожиданно завершилась.
Даже основная работа занимает пол экрана. Там прописан цикл, на случай, если у переходника UART->USB будет отключено питание, ведь чаще всего мы пользуемся портом UART из состава JTAG-адаптера. Обесточили плату – обесточился и адаптер, физически распаянный на ней. Тогда утилита socat вылетит с ошибкой, но бесконечный цикл не даст вылететь сессии, а восстановит соединение.
Дальше большой участок занимает установка скорости UART в зависимости от заранее заданных параметров.
Но для понимания принципа всё это нам не только бесполезно, но ещё и крайне вредно. Мы утонем в куче строк, и рискуем не приметить слона. Поэтому для статьи я сделаю совершенно спартанский вариант скрипта. Он будет состоять из тех двух строк, которые мы вводили выше вручную. Первая задаёт скорость порта (я вбил константу 115200), вторая – делает проброс (опять же, я вбил имя пробрасываемого порта намертво). Ну, и перед ними – чисто технологическая строка.
3. Практическая проверка со стороны Linux
3.1 Сбойный прогон
Хорошо, пользователь добавлен, файл autoexec.bat – создан. Давайте попробуем подключиться к системе по SSH от имени этого пользователя:
Ошибка авторизации. Почему? Начальник, знающий Linux в совершенстве, объяснил мне, что ответ на этот вопрос можно найти в файле
/var/log/auth.log
Начальник посоветовал мне написать:
но я, будучи в душе мышевозником, решил поправить атрибуты через утилиту mc, для чего навёлся в ней на файл и выбрал пункт меню «Файл->Права Доступа»:
И надобавлял прав запуска там (вновь установленные флаги отмечены звёздочкой).
3.2 Успешный прогон
Ошибок нет… Нажимаю «знак вопроса».
Работает! Есть проброс!
Ну всё. Через обычный терминал мы уже можем достучаться. На самом деле, это, конечно, лучше, чем терминал в браузере, но не сильно. Поэтому приступаем к работе из собственной Windows-программы. Ведь цель проброса порта – именно реализовывать сложный обмен своей программы с удалённым контроллером.
4. Работа со стороны Windows на C#
4.1 Почему C#
Вообще, со стороны Windows необходимо и достаточно взять любую библиотеку, реализующую функцию SSH-клиента. Но всё не так просто. У разных библиотек разные лицензии. Как объяснил мне разработчик, принимавший соответствующее решение, библиотека SSH.NET от Renci бесплатна для коммерческих применений. А та же библиотека для C++ уже платная. Именно поэтому за основу в нашей системе был взят .NET вариант. С его разбора и начнём.
4.2 Как добыть и подключить библиотеку
Создаём проект на языке C#. Я в своё время немного работал с этим языком через Windows Forms, поэтому создал именно такой проект. В дереве проектов нажимаем правую кнопку «Мыши» и выбираем пункт меню «Управление пакетами NuGet».
В открывшемся окне выбираем вкладку «Обзор» и вбиваем в поиск слово SSH. У меня нужная библиотека оказалась первой в списке.
У меня проект в решении один, но, когда меня обучали, мне разработчик рассказывал, что он затем выбирал вкладку «Установлено» и отмечал, в какие проекты эту библиотеку добавить. Но это я пересказываю на уровне «слышал звон, да не знаю, где он». Просто вдруг у вас будут проблемы – вы будете знать, как их решать. А для случая первичной установки при одном проекте в решении – всё. У нас всё получилось. Вот она сама добавилась в зависимости моего проекта:
Я добавлю на форму три элемента – кнопку «Открыть соединение», строку для отсылки в UART и текст, принятый из UART.
В программе должна быть переменная-член:
4.3 Подключаемся к серверу
В сервисе All-Hardware мы подключаемся к серверу с использованием SSL-сертификата. Но для демонстрации можно использовать и метод попроще, с использованием имени пользователя и пароля. Тогда вся функциональность умещается в две строки плюс немного технологической мишуры:
4.4 Создание потока данных
Для того чтобы передавать данные, надо обязательно создать поток (не тот поток, который Thread, а который Stream). Для этого вызываем функцию CreateShellStream(). Удивительно, но ей надо передать массу сведений о консольном окне (число строк, число столбцов, размер окна в точках), хотя никакого физического терминала создано не будет. Просто так надо. Ну, и последний параметр функции – размер буфера. Итого, функция открытия соединения разрастается на одну строку и теперь выглядит так:
Теперь мы можем передавать данные, пользуясь этим потоком.
4.5 Передача на сервер
Как мы видим, функции библиотеки SSH.NET достаточно простые. Работать с нею – одно удовольствие. Функция передачи не является исключением в целом, но имеет один нюанс в частности. Если просто вызывать её, то данные сначала будут копиться в большом буфере, а затем – оптом улетят из него. Латентность системы окажется весьма высокой. Чтобы этого избежать, необходимо и достаточно, записав минимально необходимый блок (какой именно – это уже виднее прикладному программисту, он же знает, какие данные гоняет через порт), вызвать функцию Flush. В моём тестовом примере получаем (ловлю исключений я не стал добавлять, чтобы не перегружать пример, а так-то она нужна):
4.6 Приём с сервера
Для чтения есть блокирующая и асинхронная функции. Давайте я в примере сделаю приём через асинхронную функцию по таймеру.
4.7 Проверяем
Для проверки открываем соединение, после чего шлём строку из трёх знаков вопроса. Убеждаемся, что пришли три ответа (а каждый ответ у интеллектуального реле выглядит, как строка из символов abc). Значит, система работает.
5. Работа со стороны Windows на прочих языках
Как пробросить данные из .NET библиотеки в обычную программу, я расскажу весьма тезисно. Дело в том, что тема, с одной стороны, для полного раскрытия требует ещё одной большой статьи, а текущую, боюсь, уже все устали читать. Так что если вдруг интересно – можно сделать ещё одну. С другой же стороны, тема весьма хорошо документирована, хоть в MSDN, хоть у того же Джеффри Рихтера.
Итак. Для проброса данных между процессами в Windows предусмотрен механизм именованных каналов (Named Pipes). В WIN32 API это функция CreateNamedPipe() с последующими ReadFile/WriteFile. В .NET можно воспользоваться классом NamedPipeClientStream. Правда, разработчик нашей системы сказал (напомню, в этой статье я – простой корреспондент, всё пишу с чужих слов), что очень важно даже для однонаправленного канала задавать направление PipeDirection.InOut. Почему-то у него в иных случаях ничего не работало.
Собственно, всё. Создаём канал от .NET к обычному коду и канал от обычного кода к .NET, создаём потоки (на этот раз – которые Thread) и начинаем обмениваться данными.
Муторно? Согласен. Но с организационной точки зрения, так было проще всего. Иначе пришлось бы либо покупать библиотеку для работы с SSH, либо писать свою, что вышло бы сложнее. По крайней мере, так мне сказали.
6. Заключение
Мы рассмотрели механизмы, позволяющие пробросить порты UART из ОС Linux в ОС Windows. Именно на таком методе реализован проброс портов и в сервисе All-Hardware, но для полной унификации ещё разработан драйвер виртуального порта. Поэтому все программы, которые работают с COM-портом, смогут работать и с проброшенным портом, как будто он установлен на локальной Windows-машине.
Пользуясь описанными методиками, пользователи смогут подключаться к нашему сервису, не устанавливая драйвера.
А лично автор при подготовке данной статьи почерпнул вещь, никак не связанную с её темой. В скриптах есть запись вида:
anyUtility 2>log.txt
Оказывается, это всё работает даже в Windows (не само перенаправление, а именно перенаправление с двойкой). Теперь автор умеет сохранять перечень ошибок, выдаваемых GNU компилятором, в файл. Перенаправлять поток надо именно так. Как учит народная мудрость: «Век живи – век учись».