Je viens de mettre en ligne mon serveur Minitel ! Il est accessible à ce numéro :
09 72 62 92 67
Il s’agit d’un véritable serveur Minitel, avec seulement quelques services pour l’instant, où on s’y connecte via une ligne téléphonique analogique avec son Minitel comme à l’époque du 3615. Comme pas mal de serveurs amateurs de cette époque (aussi appelés micro-serveurs), mon serveur est un serveur mono-voie. C’est à dire qu’une seule connexion est possible à la fois. Donc si ça sonne occupé quand on appelle, c’est que quelqu’un occupe déjà le serveur.
En 2015, j’avais un Minitel 2 qui traînais dans un placard et qui ne servait plus à rien depuis l’arrêt de tous les services Minitel en Juin 2012. Je trouvais dommage de laisser traîner à la poussière cet ancêtre d’Internet.
J’ai donc commencé mes expériences à ce moment là en essayant de juste de faire fonctionner cette grosse boite.
En cherchant un peu sur les caractéristiques techniques de la bête, j’ai trouvé que la communication entre un serveur et un Minitel client se faisait via une connexion série 1200/75 bits/s avec 7 bits par caractères, parité paire et 1 bit de stop et suivant une norme appelée V.23 Mode 2. Les données sont codés en son d’une certaine fréquence pour passer sans problème sur une ligne téléphonique standard. En transmission, 1300Hz correspond à un 1 et 2100Hz correspond à un 0, ce qui permet d’avoir un débit à 1200 bits/s du serveur au Minitel. En réception, 390Hz correspond à un 1 et 450Hz correspond à 0, ce qui permet d’avoir un débit à 75 bits/s du Minitel au serveur.
Ne connaissant pas, au début de mes tests, de puce électronique spécialisé V.23 et ne cherchant pas à me casse la tête juste pour ça, j’ai réalisé un petit modem V.23 expérimental avec ce que j’avais sous la main :
- un XR2206 [pdf] : un générateur de fonction qui permet une faire de la transmission FSK avec deux fréquences de signaux définis par des résistances/condensateurs. Il servit pour la transmission vers le Minitel.
- un XR2211 [pdf] : un démodulateur FSK. Il servit pour la réception des signaux envoyés par Minitel.
- deux PL2303HX, adaptateurs série-USB connectés au XR2206 et au XR2211, qui supporte la configuration série imposée par le Minitel. J’ai testé un temps la puce CH340G, petite et plus facile à souder, mais elle ne supporte pas la transmission de mots en 7 bits, uniquement 8 bits.
J’ai relié les connecteurs 1 et 3 de la prise téléphonique téléphonique du Minitel à la masse et aux entrées et sorties des puces XR2206 et XR2211.
Je l’ai allumé, un "F" fixe est apparu dans le coin de l’écran. J’appuie "Connexion/Fin", on entend un relais s’enclencher, je vois le "F" fixe devenir un "C" clignotant puis devenir fixe au bout quelques secondes. La connexion était établie et fonctionnelle !
J’ai pu commencer à m’amuser à reproduire les anciens services et à faire des tests :
J’ai commencé à coder mes test en Java avec la librairie JSSC (Java Simple Serial Connector) (Maven) qui me permet d’avoir une interface série très simple dans ce langage comme son nom l'indique.
Code:1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.String portReader = "/dev/ttyUSB0"; String portWritter = "/dev/ttyAMA0"; SerialPort serialPortWritter = new SerialPort(portWritter); serialPortWritter.openPort(); serialPortWritter.setParams(SerialPort.BAUDRATE_1200, SerialPort.DATABITS_7,
SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN); SerialPort serialPortReader = new SerialPort(portReader); serialPortReader.openPort(); serialPortReader.setParams(75, SerialPort.DATABITS_7,SerialPort.STOPBITS_1,
SerialPort.PARITY_EVEN); // Ecrit "test" serialPortWritter.writeBytes("test".getBytes()); // Attente et réception d'un octet (7 bits convertis en 8 bits) byte[] bytes = serialPortReader.readBytes(1); // Récupération d'un octet dans le cache // Si cache viden, retourne null byte[] bytes = serialPortReader.readBytes(); serialPortReader.closePort(); serialPortWritter.closePort();
Bon ... Faire du texte blanc sur fond noir, c’est joli mais on pouvais voir des trucs plus classe que ça à l’époque. J’ai cherché sur le net pour trouver de la doc technique et j’ai trouvé "Minitel 1B - Spécifications Techniques d’Utilisation" [pdf]. C’était la documentation contenant toutes les instructions pour manipuler un Minitel, la documentation du développeur ! (Merci à Pila pour l’upload de cet documentation rare) Ce sont essentiellement les pages 83 à 108 qui sont les plus intéressantes.
Au final, ça marche, oui ... mais alors qu’est ce que c’est tordu à mettre en place ! Surtout le XR2211, très difficile à régler correctement. Ça n’a pas marché du premier coup et il faut plein de composants autour pour que ça marche.
J’ai donc cherché s’il existait une puce simple spécialisée dans la transmission FSK et qui supporterais la norme V.23. J’ai trouvé mon bonheur avec la puce TCM3105 [pdf] ! Ultra basique, très peu de composants autour, je la met en place, j’allume, ça marche direct !
Puis je l’ai amélioré pour pouvoir créer un modem V.23 plus complet, le commander et connaître différents états de la ligne.
J’ai rajouté :
- une détection de sonnerie, pour que le logiciel détecte quand quelqu'un appelle.
- une détection de signal Minitel, pour indiquer si la liaison série est établie.
- une commande de décrochage de la ligne qui commande un relais et fait connecter le TCM3103 via des transformateurs téléphoniques.
- une commande d’activation de liaison série entre le port série et le TCM3103. Ça n’a pas vraiment d’utilité. La connexion série pourrait rester tout le temps activée entre le port et la puce. Mais je voulais reproduire un effet qu’il y avait sur les vrais serveurs après avoir fait le numéro où on entendait, à la connexion, d’abord un son aiguë puis 2 secondes après, un son plus grave qui indiquait que la liaison était active et qu’on pouvais appuyer sur "Connexion/Fin". C’est juste pour le coté nostalgique.
J’ai ensuite commencé la réalisation du serveur ! Fin 2015, j’avais déjà un début de la partie hardware du serveur qui fonctionnait.
Le tout fonctionnait avec :
- la carte modem V.23 maison
- un RaspberryPi 2
- un vieux disque IDE 8Go pour l’OS (je n’ai pas confiance dans les cartes SD/microSD, elles se sont pas prévus pour des lectures/écritures répétés et finissent par lâcher rapidement)
- une alimentation basique avec des régulateurs 7805 et 7812
Ça marchait pas trop mal sauf quelques problèmes de surchauffe du RaspberryPi lorsque le boîtier était fermé, dû au disque dur qui chauffe, aux régulateurs et au transformateur. Ça sera corrigé plus tard.
Voici le brouillon du schéma de mon modem V.23 :
Pour me lancer dans le développement du logiciel serveur, il fallait bien que j’ai une ligne pour le serveur.
J’ai pris une ligne VoIP basique chez OVH à 1,19€/mois (ça va, c’est gérable) et j’ai utilisé un vieux adaptateur VoIP/analogique Linksys PAP2T pour obtenir une ligne analogique standard dédié à mon serveur Minitel.
Point important sur la configuration de l'adaptateur VoIP : le choix de l'encodeur audio. Certains marchent plus ou moins bien avec le V.23. Je laisse le codec G711u qui ne semble pas poser de problème.
Je branchais mon Minitel sur la prise téléphonique analogique de ma box et j’appelais le serveur pour faire mes tests.
J’ai continué à me développer des outils en Java pour manipuler le Minitel, notamment l’affichage d’images JPEG/PNG/BMP et autres sur un écran Minitel :
C’était un peu compliqué pour y arriver. Déjà, le minitel ne peut pas afficher d’images graphiques mais utilise à la place des caractères semi-graphiques. Ce sont des caractères spécifiques qui représentent une combinaison de 3*2 pixels.
Mais en jouant la couleur des caractères et la couleur de fond, on arriver à obtenir des trucs sympas qui donnent des images maximum 80*69 en 8 niveaux de gris sur un écran monochrome. Je précise monochrome car le contrôleur d’écran du Minitel ne gère que des couleurs biens distinctes et non plusieurs niveaux de gris. C’est en affichant sur un écran monochrome qu’on peut obtenir plusieurs nuances de gris.
J’ai laissé ensuite de coté pendant quelques temps l’idée de faire un serveur Minitel ...
Puis je l’ai reprise fin Juillet 2017 !
J’ai corrigé le problème de surchauffe : le précédent disque dur était un disque IDE 3.5" qui demandé du +5V et du +12V. Cela demandait donc un transformateur qui fournisse au moins 14V continu pour que le 7812 fasse sont boulot correctement. Sauf que tout les autres éléments du serveur fonctionne avec du +5V donc les régulateurs 7805 chauffaient beaucoup. J’ai donc remplacé le disque 3.5" par un disque IDE 2.5" de 20Go qui ne demande que +5V. L’ensemble de l’électronique ne fonctionnant plus que sous +5V, j’ai entièrement refait l’alimentation avec un plus petit transformateur et j’y ajouté un circuit de reset général automatique dans le cas où le RaspberryPi planterais (plus de détails ici).
J’ai également ajouté une alimentation +50V pour simuler une ligne téléphonique pour un modem V23 de développement où j’y connecte directement un Minitel pour faire mes tests. La carte modem V.23 "normale" servira uniquement pour le serveur public. Le boîtier va donc héberger un logiciel serveur public, auquel tout le monde pourra se connecter, et un logiciel serveur de développement (c’est le même mais avec une configuration différente) pour moi uniquement.
La partie hardware du serveur est désormais terminée !
Schémas :
Cliquez pour agrandir ou version pdf
Cliquez pour agrandir ou version pdf
Cliquez pour agrandir ou version pdf
Le modem de développement apportant 2 adaptateurs série-USB de plus, je ne pouvais en brancher qu’un seul car il ne me restait plus qu’un seul port USB sur le RaspberryPi 2 :
- port 1 : adaptateur USB-IDE
- port 2 : dongle Wifi
- port 3 : adaptateur série-USB modem V.23 75bits/s (la transmission 1200bits/s passe par l’interface série sur le connecteur GPIO)
- port 4 : - vide -
Je pouvais utiliser un hub USB mis en vrac à l’intérieur mais j’ai préféré faire plus propre en changeant le RaspberryPi 2 pour un RaspberryPi 3 avec Wifi intégré pour me retrouver comme ceci :
- port 1 : adaptateur USB-IDE
- port 2 : adaptateur série-USB modem V.23 75bits/s
- port 3 : adaptateur série-USB modem V.23 de développement 1200bits/s
- port 4 : adaptateur série-USB modem V.23 de développement 75bits/s
Sauf qu’avec tous ces adaptateurs série, un nouveau problème est apparu : Rasbian lie de façon aléatoire le nom d’un périphérique de type "/dev/ttyUSB*" au matériel au démarrage. A un moment, je retrouve avec la réception 75bits/s du modem V.23 sur l’interface "/dev/ttyUSB0" et après redémarrage, elle est sur "/dev/ttyUSB1" ou "/dev/ttyUSB2". Pas terrible pour définir une configuration sur le logiciel serveur. Je ne vais pas rechercher à chaque fois quel nom d’interface correspond à quel adaptateur !
Pour remédier à ce problème, j’ai ajouté une règle qui crée une nouvelle interface en "/dev/modem*" et qui la lie à la bonne interface en "/dev/ttyUSB*" en fonction du numéro du port.
Il est possible d’identifier le code du port USB avec les logs dans "dmesg" (captures précédentes) ou en utilisant la commande suivante qui donne directement le code du port USB en fonction de l’interface
Commandes:1.
2.
3.udevadm info -a -n /dev/ttyUSB0 | grep '{devpath}' | head -n1 udevadm info -a -n /dev/ttyUSB1 | grep '{devpath}' | head -n1 udevadm info -a -n /dev/ttyUSB2 | grep '{devpath}' | head -n1
Il faut créer en ensuite une nouvelle règle dans "/etc/udev/rules.d" :
Commandes:1.sudo nano /etc/udev/rules.d/99-modem.rules
Contenu:1.
2.
3.SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", ATTRS{devpath}=="1.2",
SYMLINK+="modemdev75" SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", ATTRS{devpath}=="1.4",
SYMLINK+="modemdev1200" SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", ATTRS{devpath}=="1.5",
SYMLINK+="modem75"
Les informations "{idVendor}" et "{idProduct}" se trouve avec "dmesg" mais aussi se trouver avec la commande "udvadmn" précédente :
Commandes:1.
2.
3.
4.
5.
6.udevadm info -a -n /dev/ttyUSB0 | grep '{idVendor}' | head -n1 udevadm info -a -n /dev/ttyUSB0 | grep '{idProduct}' | head -n1 udevadm info -a -n /dev/ttyUSB1 | grep '{idVendor}' | head -n1 udevadm info -a -n /dev/ttyUSB1 | grep '{idProduct}' | head -n1 udevadm info -a -n /dev/ttyUSB2 | grep '{idVendor}' | head -n1 udevadm info -a -n /dev/ttyUSB2 | grep '{idProduct}' | head -n1
" SYMLINK+="modem*" " va permettre d’ajouter une nouvelle interface en "modem*". On sauvegarde, on redémarre et normalement c’est bon !
Ensuite, en testant l’interface série qui se trouve sur le connecteur GPIO, je me suis rendu que, depuis que je suis passé du RaspberryPi 2 au RaspberryPi 3, elle ne marchait plus correctement ! Mon minitel affichait n’importe quoi ! Et pour cause : le RaspberryPi 3 est possède le Wifi et de Bluetooth pré-intégré. C’est cool en général ... mais pas vraiment pour les bricoleurs.
Les concepteurs du RaspberryPi 3 ont lié "/dev/ttyAMA0" au Bluetooth et maintenant "/dev/ttyS0" à l’interface série sur le connecteur GPIO. Ça, encore, c’est pas méchant, juste une histoire de nom. Le truc, c’est que maintenant l’interface série en "/dev/ttyS0" gère sa fréquence en fonction de celle du CPU ... qui est dynamique (s’adapte en fonction de l’utilisation). C’est très c** comme choix et pas pratique du tout ! Il faut donc fixer la fréquence du CPU en ajoutant "enable_uart=1" et "dtoverlay=pi3-miniuart-bt" à la fin de "/boot/config.txt".
Commande:1.sudo nano /boot/config.txt
Cela va avoir pour effet d’activer l’interface série, de fixer la fréquence du CPU et de désactiver le Bluetooth pour en "/dev/ttyAMA0" pour retrouver le port série normal.
Plus d’infos : ici et là
Maintenant que le matériel étant fabriqué et bien configuré, j’ai pu me lancer dans la création du logiciel serveur. J’avais déjà commencé un premier logiciel mais il était trop complexe et je m’étais trop pris la tête avec. J’ai donc recommencé à zéro ! Je ne vais pas m’attarder sur la description du code. Si vous savez lire d Java, vous n’aurez problème pour comprendre.
Le logiciel serveur : ServeurMinitel.jar / ServeurMinitel-sources.zip
Un fichier de config est ajouté à la racine où ce trouve le jar.
Contenu fichier "config.properties" :1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.modeDev=false modemReception75=/dev/modem75 modemTransmission1200=/dev/ttyAMA0 pinDecrochageLigne=GPIO23 pinDetectionSonnerie=GPIO24 pinActivationLiaisonDonnees=GPIO12 pinDectectionConnexionMinitel=GPIO25 db.serveur=localhost db.nom=baseDeDonnes db.identifiant=identifiantBDD db.motdepasse=motDePasseBDD
J’ai créé un script pour initialiser tous les ports GPIO proprement avec "sudo" et lancer le serveur avec le compte "pi" :
Code:1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.#!/bin/sh # Initialisation ports if [ ! -d /sys/class/gpio/gpio23 ]; then sudo echo 23 > /sys/class/gpio/export sudo echo out > /sys/class/gpio/gpio23/direction sudo chmod 766 /sys/class/gpio/gpio23/direction sudo chmod 766 /sys/class/gpio/gpio23/value sudo chmod 766 /sys/class/gpio/gpio23/active_low fi if [ ! -d /sys/class/gpio/gpio12 ]; then sudo echo 12 > /sys/class/gpio/export sudo echo out > /sys/class/gpio/gpio12/direction sudo chmod 766 /sys/class/gpio/gpio12/direction sudo chmod 766 /sys/class/gpio/gpio12/value sudo chmod 766 /sys/class/gpio/gpio12/active_low fi if [ ! -d /sys/class/gpio/gpio24 ]; then sudo echo 24 > /sys/class/gpio/export sudo echo in > /sys/class/gpio/gpio24/direction sudo chmod 766 /sys/class/gpio/gpio24/direction sudo chmod 766 /sys/class/gpio/gpio24/value sudo chmod 766 /sys/class/gpio/gpio24/active_low fi if [ ! -d /sys/class/gpio/gpio25 ]; then sudo echo 25 > /sys/class/gpio/export sudo echo in > /sys/class/gpio/gpio25/direction sudo chmod 766 /sys/class/gpio/gpio25/direction sudo chmod 766 /sys/class/gpio/gpio25/value sudo chmod 766 /sys/class/gpio/gpio25/active_low fi echo 0 > /sys/class/gpio/gpio23/value echo 0 > /sys/class/gpio/gpio12/value # Lancement serveur entant qu'utilisateur "pi" cd /home/pi/public/ sudo -H -u pi bash -c 'java -jar ServeurMinitel.jar'
Il est possible de lancer le démarrage du logiciel au démarrage du RaspberryPi :
Commandes:1.sudo nano /etc/init.d/serveur_minitel
Contenu:1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.#!/bin/sh case "$1" in start) echo "Lancement Serveur Minitel" sleep 10 screen -A -m -d -S serveur_minitel screen -S serveur_minitel -p 0 -X stuff 'sudo sh /home/pi/public/start.sh ' ;; stop) echo "Arrêt serveur" screen -rd serveur_minitel -X -p0 eval "stuff '^C'^m" screen -rd serveur_minitel -X -p0 eval "stuff 'exit'^m" ;; *) echo "Usage: /etc/init.d/serveur_minitel {start|stop}" exit 1 ;; esac exit 0
Commandes:1.
2.sudo chmod 755 /etc/init.d/serveur_minitel sudo update-rc.d serveur_minitel defaults
C'est bien joli tout ça mais que fait ce logiciel serveur ? Et bien voici :
Lorsqu’on se connecte, on arrive sur l’accueil. Il suffit de taper un code indiquant quel service on souhaite accéder.
Comme indiqué sur l’écran, il est possible de connaître la liste actuelle est des services disponibles avec leur code en tapant sur la touche "Guide".
Le service de jeu d’échecs :
Le service de chat :
Voilà ! Ceci clos un peu plus de 2 ans de recherches et de tests !
Photo noir&blanc "Je suis de retour" :
Pellicule: Lomography Lady Grey 400
Appareil photo: Minolta Dynax 500si
Lentille: Minolta AF Zoom 35-70mm
Développement: Ilford ID-11 + Ilford Rapidfixer
J'ai commencé le développement en réalisant des services Minitel, il y a...huhu, énormément d'années :)
Bravo pour ce Retour vers le futur
Good Job