[mdk-re] HOWTO transmit RS-232 over TCP/IP

"Баталов Григорий" =?iso-8859-1?q?bga_=CE=C1_kovgok=2Eru?=
Пт Фев 22 14:45:07 MSK 2002


   Предлагаю вариант решения академической задачи "проброски
 RS-232" через TCP/IP. Вопросы и поправки крайне приветствуются.

---
   Задача в следующем:
 - имеются два устройства, работающие друг с другом по RS-232
 - желательно разнести их в пространстве, а тянуть физически
   пару проводов от одного к другому неудобно
 - есть локальная сеть вблизи обоих устройств

   Схематично это можно изобразить так:

   .----, RS-232              RS-232  .----,
   | У1 |--------> ( среда ) -------->| У2 |
   `----'                             `----'

   Вариант решения:

   Оба устройства подключаются через COM-порты к низко-бюджетным
 Линукс-машинам:

 .----, RS-232  .-------, TCP/IP              TCP/IP   .-------, RS-232  .----,
 | У1 |-------->| Linux |--------> ( среда ) --------> | Linux |-------->| У2 |
 `----'         `-------'                              `-------'         `----'
   На машинах запускаются COM-порт-сервер и COM-порт-клиент,
 причём клиент ставится на машине, инициирующей соединение.

  ttyS0-->getty-->ckermit/telnet-->sredird-->ttyS1
---


   Итак, подробности.
 "Зашарить" COM-порт, то есть сделать его доступным через сеть
 можно при помощи демона sredird:
 http://www.ibiblio.org/pub/Linux/system/serial/sredird-2.0.0.tar.gz
---------------------------------------------------------------
Sredird is a serial port redirector that is compliant with
the RFC 2217 "Telnet Com Port Control Option" protocol.
This protocol lets you share a serial port through the network.
RFC 2217 was orginally implemented in Cisco Terminal Servers
in IOS version 11.x.
---------------------------------------------------------------
   Клиентом к нему может выступать обычный telnet, хотя
 рекомендуется пользоваться C-Kermit-ом, поскольку он
 поддерживает RFC 2217.
 ( http://www.columbia.edu/kermit/ckermit.html,
   ftp://kermit.columbia.edu/kermit/archives/cku201.tar.gz )

 1. Скомпилируем sredird, скопируем его в /usr/sbin/sredird
    на второй машине. Для работы с xinetd понадобится файл
 /etc/xinetd.d/sredir:
---
# default: off
# description: sredir allows to share serial port on the net
service sredir
{
        disable                 = no
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/sbin/sredird
        server_args             = 5 /dev/ttyS1 /var/lock/LCK..ttyS1
}
---
   /dev/ttyS1 - порт на Устройстве-2, /var/lock/LCK..ttyS1 -
 файл блокировки, 5 - log level.

   В /etc/services добавим строку:
 sredir          7200/tcp                        # serial port redirector
 Порт может быть любой не занятый.
   Делаем '#service xinetd reload' и проверяем:
 '$telnet localhost 7200'.
 Видим в логах:
---
Feb 22 13:23:01 bga xinetd[1111]: START: sredir pid=2353 from=127.0.0.1
Feb 22 13:23:01 bga sredird[2353]: SRedird started.
Feb 22 13:23:01 bga sredird[2353]: Client doesn't support Telnet COM Port Protocol Option (RFC 2217), trying to serve anyway.

   На консоли:
---
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

   Если мы подключались к модему, то команда 'at' ответит
 'OK'. Выход: 'Ctrl-]', 'telnet> quit', в логах видим:
---
Feb 22 13:24:04 bga sredird[2353]: Error reading from network.
Feb 22 13:24:04 bga sredird[2353]: Unlocked lock file /var/lock/LCK..ttyS1.
Feb 22 13:24:04 bga sredird[2353]: SRedird stopped.
Feb 22 13:24:04 bga xinetd[1111]: EXIT: sredir status=0 pid=2353 duration=63(sec)
---

 2. Скомпилируем C-Kermit, либо возьмём с сайта готовый.
    Скопируем его (wermit при компиляции) в /usr/bin/ckermit
 на первой машине. Можно его запустить и ещё раз проверить:

C-Kermit> telnet 193.125.167.57 7200
 где 193.125.167.57 - IP адрес второй машины,
 7200 - назначенный нами порт.
 Выход по 'Ctrl-|', 'C', 'C-Kermit> exit'.

   В /etc/inittab на первой машине добавим строку:
s0:345:respawn:/sbin/getty ttyS0 DT9600 tty
 Таким образом, при активности на линии ttyS0 будет вызываться
 /sbin/getty. В /etc/gettydefs должно присутствовать описание
 DT9600 или другого DTxxxxx, если нам мало скорости 9600.
 У меня вот так:
---
# 9600 baud Dumb Terminal entry
DT9600# B9600 CS8 CLOCAL # B9600 SANE -ISTRIP CLOCAL #@S login: #DT9600
---
   Getty первым делом запросит логин и передаст его в
 /bin/login. Нам это не нужно, по этому вместо /bin/login
 напишем свой скрипт /usr/bin/ckermit-login:
---
/usr/bin/ckermit -0 -8 -q -J 193.125.167.57 7200
---
   При его вызове будет запускаться C-Kermit и обращаться
 telnet-ом на 193.125.167.57:7200. Ctrl-последовательности
 отключены параметром '-0'.
   Пропишем этот скрипт в /etc/conf.getty.ttyS0 на первой
 машине:
---
LOGIN=/usr/bin/ckermit-login
ISSUE=/dev/null
---
 ISSUE - это заставка перед логином, нам она тоже не нужна.
 Естественно, скрипт должен иметь права на запуск.

   Теперь реинициализируем init: '#init q'.
 В процессах должна появиться строка вроде:
2562 ttyS0 S 0:00 /sbin/getty ttyS0 DT9600 tty
 После подключения клиента:
2562 ttyS0    S      0:00 sh -c /usr/bin/ckermit-login
2564 ttyS0    S      0:00 /usr/bin/ckermit -0 -8 -q -J 193.125.167.57 7200
---

   Теперь о том, как я это проверял. Рассчитано данное решение
 на подключение датчиков, работающих по RS-232, к контроллеру.
 Датчики эти мне ни кто не давал, и, думаю, не даст.

   По этому я водрузил всё это хозяйство на один единственный
 компьютер с IP 193.125.167.57, инициирующим устройством
 сделал ноутбук с терминалкой от Norton Commander, отвечающим
 устройством - внутренний модем компьютера.

   Терминалка была настроена на 9600 бод, без аппаратного
 или программного управления потоком. Тип терминала: tty.
   Строка инициализации: "at^MATZ^M". Дело в том, что getty
 передаёт управление в LOGIN только после получения некоего
 логина, завершающегося возвратом каретки. Иначе ругается.
 Пусть это будет "at" маленькими буквами. Если мы используем
 этот ноутбук на настоящем модеме, то это "at" также должно
 правильно обработаться.

   При включении терминалки идёт ругань на ошибку инициализации
 модема. Не знаю, что она ожидает получить, этот вопрос я
 не разбирал. Можно эти сообщения игнорировать. После них
 я попадал прямо на модем, 'at', 'ati4' нормально отрабатывали.
   При выходе из терминалки процесс ckermit оставался
 запущенным, по этому при следующем входе отрабатывала уже
 и строка инициализации, поскольку передавалась сразу в модем.

   На этом всё. Буду рад комментариям от более грамотных
 товарищей, поскольку вполне мог где-то свалять дурака.

-- 
 Баталов Григорий,
 системный администратор
 АО "Ковдорский ГОК"





Подробная информация о списке рассылки community