domingo, 30 de agosto de 2020

Comunicación con Null Modem

El módem nulo (null modem) es un sistema para conectar dos dispositivos entre si mediante un cable entre sus puertos serie usando el estándar RS-232 con las líneas de transmisión y recepción cruzadas. Es un método similar al cable cruzado ethernet y permite utilizar los mismos programas que en las comunicaciones de módem a módem para iniciar sesión o transferencia de archivos. RS-232 es el sistema más utilizado para la conexión por puerto serie con cualquier dispositivo pero los puertos serie del ordenador pueden estar configurados en el BIOS para usar otro sistema.

El ordenador "servidor2" que utilicé en el artículo Comunicaciones de Módem a Módem lo conecté a otro ordenador con nombre "cliente1" mediante un cable módem nulo con dos conectores DE-9 hembra.


Los dos ordenadores tienen un chip puente sur VIA VT82C686B que incluye dos puertos serie compatibles con el UART 16550. Además entre este chip y cada uno de los conectores de puerto serie se encuentra un transceptor GD75232 para adaptar las señales del chip VT82C686B a las del estándar RS-232.


El ordenador "cliente1", al igual que "servidor2", tiene Debian como sistema operativo. En los dos ordenadores conecté el cable al segundo puerto serie. Con el comando setserial podemos ver las características del puerto, entre ellas la velocidad en baudios que necesitaremos para configurar mgetty y minicom.

# setserial -a /dev/ttyS1

/dev/ttyS1, Line 1, UART: 16550A, Port: 0x02f8, IRQ: 3
	Baud_base: 115200, close_delay: 50, divisor: 0
	closing_wait: 3000
	Flags: spd_normal skip_test

La velocidad del puerto serie es de un bit/s por baudio, por lo que 115200 baudios = 115200 b/s. En "servidor2" es necesario modificar la unidad de systemd para añadir los parámetros -r y -s al comando mgetty. El parámetro -r indica que la conexión es directa por cable y -s la velocidad del puerto serie.

[Unit]
Description=Mgetty
Documentation=man:mgetty(8)
Requires=systemd-udev-settle.service
After=systemd-udev-settle.service

[Service]
Type=simple
ExecStart=/sbin/mgetty -r -s 115200 /dev/ttyS1
Restart=always
PIDFile=/run/mgetty.pid.ttyS1

[Install]
WantedBy=multi-user.target

En "cliente1" debemos ejecutar minicom y configurar el puerto serie /dev/ttyS1 con la misma velocidad indicada a mgetty.

+-------------------------------------------------------------+
| A - Dispositivo Serie      : /dev/ttyS1                     |
| B - Localización del Fichero de Bloqueo : /var/lock         |
| C - Programa de Acceso           :                          |
| D - Programa de Salida             :                        |
| E - Bps/Paridad/Bits             : 115200 8N1               |
| F - Control de Flujo por Hardware: Sí                       |
| G - Control de Flujo por Software: No                       |
| H -     RS485 Enable      : No                              |
| I -   RS485 Rts On Send   : No                              |
| J -  RS485 Rts After Send : No                              |
| K -  RS485 Rx During Tx   : No                              |
| L -  RS485 Terminate Bus  : No                              |
| M - RS485 Delay Rts Before: 0                               |
| N - RS485 Delay Rts After : 0                               |
|                                                             |
|    ¿Qué configuración alterar?                              |
+-------------------------------------------------------------+

Si reiniciamos el programa y presionamos Enter se realizará la conexión con "servidor2", se mostrará el mensaje de bienvenida y podremos iniciar sesión, ejecutar comandos y transferir archivos. Todo exactamente igual que en la conexión por módem con la diferencia de que en lugar de mostrar la velocidad de la conexión entre módems se muestra el texto "(DIRECT)" indicando que la conexión es directa por cable.

Bienvenido a minicom 2.7.90

OPCIONES: I18n                                                               
Compilado en Jul 26 2020, 10:44:57.                                          
Puerto /dev/ttyS1, 18:31:52                                                  
                                                                             
Presione CTRL-A Z para obtener ayuda sobre teclas especiales                 
                                                                             
Debian GNU/Linux ttyS1 115200 (DIRECT)                                       
                                                                             
servidor2 login: usuario1                                                        
Contraseña:                                                                  
Último inicio de sesión:mar ago 18 18:03:06 CEST 2020en ttyS1                
Linux servidor2 4.19.0-10-686-pae #1 SMP Debian 4.19.132-1 (2020-07-24) i686 
                                                                             
The programs included with the Debian GNU/Linux system are free software;    
the exact distribution terms for each program are described in the           
individual files in /usr/share/doc/*/copyright.                              
                                                                             
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent            
permitted by applicable law.
usuario1@servidor2:~$ ls /
bin   home            lib64       mnt   run   tmp      vmlinuz.old
boot  initrd.img      libx32      opt   sbin  usr
dev   initrd.img.old  lost+found  proc  srv   var
etc   lib             media       root  sys   vmlinuz
usuario1@servidor2:~$ 

Si enviamos un archivo con ZMODEM podremos ver que la velocidad de transmisión es de 11247 B/s = 11,247 KB/s, algo más de lo que sería posible con módems de 56 Kb/s = 7 KB/s. La velocidad máxima del puerto serie es de 115200 b/s = 14400 B/s. La comunicación del puerto está configurada como 8N1, por cada 8 bits de datos se transmiten 10 bits, por lo que la velocidad de transferencia máxima es del 80% de 14400 B/s = 11520 B/s = 11,520 KB/s. Además parte de esa velocidad es usada por el protocolo ZMODEM. Teniendo todo esto en cuenta podemos comprobar que el envío del archivo se ha producido correctamente aproximadamente a la máxima velocidad posible.

+--------[zmodem subida - Presione CTRL-C para salir]--------+                                  
|Sending: archivo-prueba                                     |                                  
|Bytes Sent:3422164   BPS:11247                              |                                  
|                                                            |                                  
|Transfer complete                                           |                                  
|                                                            |                                  
| LISTO: presione alguna tecla para continuar...             |                                  
|                                                            |                                  
+------------------------------------------------------------+

Como la conexión es por un cable a poca distancia no existen los problemas de seguridad que al realizar la conexión mediante módems a través de la línea telefónica. Por esta razón es un sistema muy útil para conectar a servidores o dispositivos electrónicos que no tengan pantalla y teclado. Si aún así queremos realizar alguna comunicación entre los dos ordenadores con algún protocolo sobre IP podemos realizar una conexión PPP. En "cliente1" debemos instalar el paquete ppp. En ambos ordenadores debemos ejecutar el programa pppd con una serie de parámetros, lo único que cambia entre un ordenador y otro es la dirección IP local y remota. La comunicación se mantiene mientras se ejecute el programa en ambos ordenadores.

root@servidor2:~# pppd nodetach crtscts lock noauth local 192.168.10.1:192.168.10.2 /dev/ttyS1 115200

Using interface ppp0
Connect: ppp0 <--> /dev/ttyS1
Deflate (15) compression enabled
local  IP address 192.168.10.1
remote IP address 192.168.10.2

root@cliente1:~# pppd nodetach crtscts lock noauth local 192.168.10.2:192.168.10.1 /dev/ttyS1 115200

Using interface ppp0
Connect: ppp0 <--> /dev/ttyS1
Deflate (15) compression enabled
local  IP address 192.168.10.2
remote IP address 192.168.10.1

En los servidores es importante que podamos interactuar con ellos lo antes posible en el proceso de inicio para detectar problemas y poder solucionarlos. Los servidores profesionales como el Fujitsu Primergy TX150 S5 suelen permitir la conexión al puerto serie mediante hardware desde el principio del arranque para interactuar de igual forma que con pantalla y teclado.

Si no existe esa posibilidad podemos configurarlo en el primer software que se ejecuta, en el gestor de arranque. Por ejemplo en GRUB se puede activar con las siguientes variables en /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="console=tty1 console=ttyS1,115200"
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --unit=1 --speed=115200"

Las variables tienen las siguientes funciones:

  • GRUB_CMDLINE_LINUX_DEFAULT: Parámetros de arranque en el modo normal. Es conveniente quitar el parámetro quiet para que muestre los mensajes del kernel y de la inicialización de servicios.
  • GRUB_CMDLINE_LINUX: Parámetros de arranque en el modo normal y de recuperación. Aquí se indica que muestre los mensajes del kernel e inicialización de servicios por la consola virtual /dev/tty1 y por el puerto serie /dev/ttyS1 con la velocidad de 115200 b/s.
  • GRUB_TERMINAL: Entrada y salida de GRUB. Se configura para utilizar la consola del ordenador y el puerto serie.
  • GRUB_SERIAL_COMMAND: Comando de GRUB para mostrar su salida por el puerto serie. Se le indica el puerto serie (unit) y la velocidad (speed).

Una vez configurado se debe ejecutar el comando update-grub para aplicar la configuración.

# update-grub 

Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.19.0-10-686-pae
Found initrd image: /boot/initrd.img-4.19.0-10-686-pae
Found linux image: /boot/vmlinuz-4.19.0-9-686-pae
Found initrd image: /boot/initrd.img-4.19.0-9-686-pae
done

Por último debemos desactivar mgetty y reiniciar el ordenador mientras tenemos una conexión serie abierta con minicom desde el ordenador "cliente1" a "servidor2".

# systemctl disable mgetty
# reboot

En el minicom de "cliente1" podremos ver como se inicia "servidor2" y muestra el menú de GRUB con las diferentes opciones de arranque. Podremos elegir cualquiera de las opciones y editarlas para solucionar problemas o hacer pruebas. Al pasar el tiempo de espera o elegir una opción se producirá el proceso de arranque y podremos verlo paso a paso. A continuación se mostrará el mensaje de bienvenida con el nombre del sistema operativo, el nombre del ordenador y el puerto serie. Finalmente podremos iniciar sesión.

            GNU GRUB  version 2.02+dfsg1-20+deb10u2

 +------------------------------------------------------------+
 |*Debian GNU/Linux                                           | 
 | Advanced options for Debian GNU/Linux                      |
 |                                                            |
 |                                                            |
 |                                                            |
 |                                                            |
 |                                                            |
 |                                                            |
 |                                                            |
 |                                                            |
 |                                                            |
 |                                                            | 
 +------------------------------------------------------------+

 Use the ^ and v keys to select which entry is highlighted.          
 Press enter to boot the selected OS, `e' to edit the commands       
 before booting or `c' for a command-line.

...
[  OK  ] Started Login Service.
[  OK  ] Started System Logging Service.
[  OK  ] Started controls configuration of serial ports.
[  OK  ] Started controls configuration of serial ports.
[  OK  ] Started Permit User Sessions.
[  OK  ] Started Serial Getty on ttyS1.
[  OK  ] Created slice system-getty.slice.
[  OK  ] Started Getty on tty1.
[  OK  ] Reached target Login Prompts.
[  OK  ] Started LSB: Conexant HCF controllerless PCI modem.
[  OK  ] Started OpenBSD Secure Shell server.
[  OK  ] Reached target Multi-User System.
[  OK  ] Reached target Graphical Interface.
         Starting Update UTMP about System Runlevel Changes...
[  OK  ] Started Update UTMP about System Runlevel Changes.

Debian GNU/Linux 10 servidor2 ttyS1

servidor2 login: usuario1
Contraseña: 
Último inicio de sesión:mié ago 19 15:02:24 CEST 2020en ttyS1
Linux servidor2 4.19.0-10-686-pae #1 SMP Debian 4.19.132-1 (2020-07-24) i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
usuario1@servidor2:~$ ls /
bin   home            lib64       mnt   run   tmp      vmlinuz.old
boot  initrd.img      libx32      opt   sbin  usr
dev   initrd.img.old  lost+found  proc  srv   var
etc   lib             media       root  sys   vmlinuz
usuario1@servidor2:~$

Al reiniciar o apagar el equipo también podremos ver el proceso.

root@servidor2:~# reboot
root@servidor2:~# [  OK  ] Stopped target Timers.
[  OK  ] Stopped Daily Cleanup of Temporary Directories.
[  OK  ] Stopped target Sound Card.
[  OK  ] Stopped Daily man-db regeneration.
[  OK  ] Stopped target Graphical Interface.
[  OK  ] Stopped Daily rotation of log files.
[  OK  ] Stopped Daily apt upgrade and clean activities.
[  OK  ] Stopped Daily apt download ac         Stopping Session 3 of user root.
[  OK  ] Stopped target Multi-User System.
[  OK  ] Stopped target Login Prompts.
...

Debian utiliza para el inicio de sesión el programa agetty. Este programa también es usado por GRUB para el inicio de sesión por el puerto serie. Es una alternativa a mgetty que podemos arrancar mediante una unidad de systemd si no configuramos GRUB para usar el puerto serie desde el arranque.

# agetty ttyS1 115200

Si ejecutamos minicom con el parámetro -C podremos guardar todo el proceso de arranque, inicio de sesión, uso del ordenador, reinicio y apagado en un archivo para poder analizarlo después.

# minicom -C /var/tmp/servidor2.log

Por último puede ser muy útil utilizar un portátil para conectar al servidor o dispositivo electrónico. En este caso seguramente nos encontraremos con el problema de que el portátil no dispone de puerto serie y necesitaremos un adaptador USB a puerto serie con conector DE-9 macho para conectar al cable módem nulo. El adaptador puede tener incorporado un cable para llegar más lejos y/o conectar a dispositivos que tengan conector hembra y no necesiten el cable módem nulo. Si queremos que sea lo más pequeño posible se puede comprar sin cable.


El adaptador no es solo un cable con dos conectores sino que tiene una electrónica para conectar al puerto USB como dispositivo serie y adaptar las señales a RS-232. Al conectar al ordenador mi adaptador puedo ver con el comando lsusb que ha sido detectado y utiliza el chip Prolific PL2303. Este chip y el resto de la electrónica del adaptador seguramente se alojen en el conector serie que es donde hay más espacio.

# lsusb

Bus 003 Device 002: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

Con el comando lsmod se puede ver como se ha cargado el modulo controlador del chip y su relación con otros módulos del sistema USB.

# lsmod | grep pl2303

pl2303                 24576  0
usbserial              53248  1 pl2303
usbcore               294912  6 pl2303,usbserial,ehci_pci,uvcvideo,ehci_hcd,uhci_hcd

En el sistema operativo se accede al puerto serie mediante el dispositivo /dev/ttyUSB0. Con setserial se puede ver como tiene un UART 16654 y una velocidad de 460800 baudios.

# setserial -a /dev/ttyUSB0 

/dev/ttyUSB0, Line 0, UART: 16654, Port: 0x0000, IRQ: 0
	Baud_base: 460800, close_delay: 0, divisor: 0
	closing_wait: infinite
	Flags: spd_normal

Podremos usar este puerto serie como cualquier otro y utilizar los mismos programas para conectar a ordenadores o dispositivos.

2 comentarios: