Minitel 0.2

De Centre de Ressources Numériques - Labomedia
Révision de 15 décembre 2014 à 13:58 par Mushussu (discussion | contributions)

(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à : navigation, rechercher

L'idée est de Transformer 2 Minitels en système de visioconférence low tech low bandwith strong crypt (gstreamer, true bitmap, autowebconnect, vpn)

Ce projet de recherche & recyclage consiste à transformer notre adulé Minitel en terminal de visioconférence moderne. Détournant le titre d'une conférence de Benjamin Bayart « Internet Libre ou Minitel 2.0 ? », cette installation met en communication 2 endroits équipés de Minitel 0.2 et permet à qui veut d'échanger en direct en son et en image avec son correspondant distant. Cette conversation passe par internet via un tunnel chiffré, clin d’œil malicieux aux atteintes à la neutralité du net et au secret de la correspondance, à la concentration du réseau aux antipodes du partage de personne à personne.

Pour mener à bien ce projet, il nous a tout d'abord fallu faire renaître un Minitel et lui donner un peu plus de muscle. Nous avons pour cela remplacé toute la partie "système" par une Raspberry Pi en conservant l'écran pour l'affichage et le clavier pour le contrôle.

Cette étape, est documentée sur cette page.

Gestion de l'image

Nous avons fait le choix de travailler sur du vrai bitmap, c'est à dire que chaque pixel est codé sur 1 bit (0 = noir, 1 = blanc).

Solution avec Python + OpenCV

L'image est capturée en Python par une webcam grâce la librairie OpenCV. Elle est ensuite traitée selon ce format: 2200 pixels > 2200 bits > 275 octets par image, pour être envoyée par UDP sur le second minitel en passant par un VPN.

Captation et envoi

# -*- coding: utf8 -*-
 
# Ce script récupère le flux d'une webcam et le traite de manière à pouvoir
# l'envoyer en bitmap (1 bit = 1 pixel) par UDP sur un serveur
 
# Librairie OpenCV de traitement d'image.
# Non standard, donc à installer :
# sudo apt-get install python-opencv
import cv2
 
# Va nous permettre de faire de l'UDP.
import socket
 
# Va nous permettre de lire l'argument donné au lancement
import sys

from affichage import affichage

la_bas = sys.argv[1]

DICO_IP = {
"Nantes":"127.0.0.1",
"Toulouse":"127.0.0.1"
}

# IP et port de notre serveur.
UDP_IP_LA_BAS = DICO_IP[la_bas]
UDP_PORT = 5005
 
# On choisi /dev/video0 comme périphérique.
cap = cv2.VideoCapture(0)
 
# 160x120 étant la plus petite définition que l'on puisse capturer avec notre
# webcam, on définit la capture avec ces valeurs.
 
# Largeur.
cap.set(3, 160)
# Hauteur.
cap.set(4, 120)
 
# On définit les dimensions finales.
# Cela correspond au nombre de caractères affichables par défaut
# dans la console d'un RaspberryPi (lowtech powa).
larg_minitel = 71
haut_minitel = 31
 
# n° de la permier image (nécessaire si sauvegarde)
#num_image = 0


while True:
 
    # Lit la frame.
    ret, frame = cap.read()
 
    # Retaille la frame aux dimensions voulues.
    image_retaillee = cv2.resize(frame, (larg_minitel, haut_minitel))

    # Passe la frame en niveau de gris (une seule valeure pour chaque pixel)
    image_grise = cv2.cvtColor(image_retaillee,cv2.COLOR_BGR2GRAY)

    # Passe la frame en bitmap (0 ou 255 pour chaque pixel)
    ret, image_bitmap = cv2.threshold(image_grise, 127, 255, cv2.THRESH_BINARY)
 
    # Nous avons fait le choix d'utiliser des images en bitmap.
    # C'est à dire que les pixels sont, soit noirs, soit blancs.
    # Ils sont donc transmis sous forme binaire (1 bit = 1 pixel).
    # Pour cela nous avons besoin de les stocker par octet dans un tableau.
    tab_octet = []
 
    # Premier octet vide.
    octet = ''
 
    # Initialisation des n° de pixel
    num_pixel = 0
 
    image_01 = ""    
    
    # Pour chaque ligne de l'image.
    for ligne in range(haut_minitel):    
 
        # Pour chaque pixel que chaque ligne.
        for pixel in range(larg_minitel):
 
            # On extrait la valeur de niveau de gris
            # de chaque pixel (0-255).
            val_coul = image_bitmap[ligne][pixel]            
 
            # En fonction d'un seuil,
            if val_coul == 255:
 
                # le pixel est stocké sous la forme d'un 1,
                # dans un "octet" pour l'envoi
                octet += "1"
                # dans un fichier général pour l'affichage
                image_01 += "1"
 
            else:
 
                # il est stocké sous la forme d'un 0.
                # dans un "octet" pour l'envoi
                octet += "0"
                # dans un fichier général pour l'affichage
                image_01 += "0"
 
            # On incrémente le n° du pixel traité,
            # pour pouvoir les compter par paquet de 8.
            num_pixel += 1
 
            # Quand un octet est complet,
            if (num_pixel%8 == 0):
 
                # il est converti sous forme décimale,
                # puis stocké dans un tableau.
                tab_octet.append(int(octet, 2))
                # On repart alors sur un octet vide.
                octet = ''
 
    # Affiche l'image.
    #cv2.imshow('video test',image_grise)
 
    # Les octets, stockés jusque là dans un tableau sous forme décimale,
    # sont convertis sous forme binaire,
    data = bytearray(tab_octet)
 
    # puis envoyés en UDP sur un serveur.
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    sock.sendto(data, (UDP_IP_LA_BAS, UDP_PORT))
 
    # Petite sauvegarde en local au besoin.
    #with open ("./img/{0}".format(num_image), 'w') as base:
    #    base.write(data)
 
    # On incrémente le n° de l'image.
    #num_image += 1
 
    affichage(image_01)
    # On attend 40 ms pour obtenir du 25 fps
    key = cv2.waitKey(40)

Lecture et affichage

# -*- coding: utf8 -*-
import socket

# Va nous permettre de lire l'argument donné au lancement
import sys

# Fonction maison pour afficher le flux en console
from affichage import affichage

ici = sys.argv[1]

DICO_IP = {
"Nantes":"127.0.0.1",
"Toulouse":"127.0.0.1"
}

# IP et port de notre serveur.
UDP_IP_ICI = DICO_IP[ici]
UDP_PORT = 5005

# On écoute le port 5005
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP_ICI, UDP_PORT))
 
def reception():

    image_01 = ''

    # On réceptionne le petit paquet
    data, addr = sock.recvfrom(275)

    image_binaire = bytearray(data)

    for octet in image_binaire:

        octet = bin(octet)[2:]
        octet = octet.zfill(8)
        image_01 += octet

    return image_01

while True:

    image_01 = reception()
    affichage(image_01)

La fonction affichage

import os

brique = u'\u2588'
trou = u' '

def affichage(image_01):

    image = ''
    fin_ligne = 0

    for pixel in image_01:

        image += pixel
        fin_ligne += 1

        if (fin_ligne%71 == 0):
            image += "\n"
    
    image = image.replace('1', brique).replace('0', trou)

    os.system('clear')
    print image

Script qui gère à la fois la réception et l'envoi

Ce lance avec des arguments.

  • si l'on est à Nantes et que l'on veut communiquer avec Toulouse:
python Minitotal.py Nantes Toulouse
  • si l'on est à Toulouse et que l'on veut communiquer avec Nantes:
python Minitotal.py Toulouse Nantes
# -*- coding: utf8 -*-

# Ce script récupère le flux d'une webcam et le traite de manière à pouvoir
# l'envoyer en bitmap (1 bit = 1 pixel) par UDP sur un serveur

# IP Pi-Nantes : 11.0.0.3 // 10.0.0.197
# IP Pi-Toulouse : 11.0.0.4 // 10.0.0.155

# Librairie OpenCV de traitement d'image.
# Non standard, donc à installer :
# sudo apt-get install python-opencv
import cv2

# Va nous permettre de faire de l'UDP.
import socket

# Va nous permettre de lire les arguments donné au lancement
import sys
ici = sys.argv[1]
la_bas = sys.argv[2]

import os
import threading

DICO_IP = {
"Nantes":"11.0.0.3",
"Toulouse":"11.0.0.4"
}

UDP_IP_ICI = DICO_IP[ici]
UDP_IP_LA_BAS = DICO_IP[la_bas]

UDP_PORT = 5005

# On écoute le port 5005
sock_recep = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_recep.bind((UDP_IP_ICI, UDP_PORT))

# 
sock_env = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# On choisi les caractères d'affichage
brique = u'\u2588'
trou = u' '

# On choisi /dev/video0 comme périphérique.
cap = cv2.VideoCapture(0)

# 160x120 étant la plus petite définition que l'on puisse capturer avec notre
# webcam, on définit la capture avec ces valeurs.

# Largeur.
cap.set(3, 160)
# Hauteur.
cap.set(4, 120)

# On définit les dimensions finales.
# Cela correspond au nombre de caractères affichables par défaut
# dans la console d'un RaspberryPi (lowtech powa).
larg_minitel = 71
haut_minitel = 31

etat = True

def captation_et_envoi():

    while etat:

        # Lit la frame.
        ret, frame = cap.read()

        # Retaille la frame aux dimensions voulues.
        image_retaillee = cv2.resize(frame, (larg_minitel, haut_minitel))

        # Passe la frame en niveau de gris.
        image_grise = cv2.cvtColor(image_retaillee,cv2.COLOR_BGR2GRAY)

        # Nous avons fait le choix d'utiliser des images en bitmap.
        # C'est à dire que les pixels sont, soit noirs, soit blancs.
        # Ils sont donc transmis sous forme binaire (1 bit = 1 pixel).
        # Pour cela nous avons besoin de les stocker par octet dans un tableau.
        tab_octet = []

        # Premier octet vide.
        octet = ''

        # Initialisation des n° de pixel
        num_pixel = 0

        # Pour chaque ligne de l'image.
        for ligne in range(haut_minitel):    

            # Pour chaque pixel que chaque ligne.
            for pixel in range(larg_minitel):

                # On extrait la valeur de niveau de gris
                # de chaque pixel (0-255).
                val_coul = image_grise[ligne][pixel]            

                # En fonction d'un seuil,
                if val_coul > 100:

                    # le pixel devient soit blanc
                    image_grise[ligne][pixel] = 255
                    # et est stocké sous la forme d'un 1,
                    octet += "1"

                else:
                     
                    # soit noir   
                    image_grise[ligne][pixel] = 0
                    # et est stocké sous la forme d'un 0.
                    octet += "0"

                # On incrémente le n° du pixel traité,
                # pour pouvoir les compter par paquet de 8.
                num_pixel += 1

                # Quand un octet est complet,
                if (num_pixel%8 == 0):
                    
                    # il est converti sous forme décimale,
                    # puis stocké dans un tableau.
                    tab_octet.append(int(octet, 2))
                    # On repart alors sur un octet vide.
                    octet = ''

        # Affiche l'image.
        #cv2.imshow('video test',image_grise)

        # Les octets, stockés jusque là dans un tableau sous forme décimale,
        # sont convertis sous forme binaire,
        data = bytearray(tab_octet)

        # puis envoyés en UDP sur un serveur.
        sock_env.sendto(data, (UDP_IP_LA_BAS, UDP_PORT))

        # On attend 40 ms pour obtenir du 25 fps
        key = cv2.waitKey(40)

def reception_et_affichage():

    while etat:

        image_01 = ''
        image = ''
        fin_ligne = 0

        # On réceptionne le petit paquet
        data, addr = sock_recep.recvfrom(1024)

        image_binaire = bytearray(data)

        for octet in image_binaire:

            octet = bin(octet)[2:]
            octet = octet.zfill(8)
            image_01 += octet
        
        for pixel in image_01:

            image += pixel
            fin_ligne += 1

            if (fin_ligne%71 == 0):
                image += "\n"
        
        image = image.replace('1', brique).replace('0', trou)

        os.system('clear')
        print image

# Définie un processus différent pour chaque partie

thread_cap_env = threading.Thread(target=captation_et_envoi)
thread_recp_aff = threading.Thread(target=reception_et_affichage)

thread_cap_env.start()
thread_recp_aff.start()

Solution avec OpenFramework

La vidéo a une définition de 80 x 72 pour simuler celle qui est obtenue par le minitel avec les caractères graphiques. Donc ce sont des paquets de 720 octets qui transitent par UDP. ofApp.h

#pragma once

#include "ofxNetwork.h"
#include "ofxXmlSettings.h"
#include "ofMain.h"

class ofApp : public ofBaseApp{
	public:
		void setup();
		void update();
		void draw();
		
		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y);
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);
	
		ofxUDPManager emissionUDP, receptionUDP;
	
		ofVideoGrabber 		vidGrabber;
		unsigned char * 	videoPixelisee;
		char * 				tableauPixelEmission;
		char * 				tableauPixelReception;
		string				IPEmission;
		int 				portEmission, portReception;
	
		ofTexture			videoTexture;
		int 				camWidth;
		int 				camHeight;
};

ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
	
	ofxXmlSettings XML;
	int nombreImages;
	
	if (XML.loadFile("data.xml")) {
		IPEmission = XML.getValue("IPEmission", "");
		portEmission = XML.getValue("portEmission", 0);
		portReception = XML.getValue("portReception", 0);
		nombreImages = XML.getValue("nombreImages", 0);
		XML.clear();
	} else {
		ofLogError("Le fichier n'a pu etre lu");
	}
	ofSetFrameRate(nombreImages);

	emissionUDP.Create();
	emissionUDP.Connect(IPEmission.c_str(), portEmission);
	emissionUDP.SetNonBlocking(true);
	emissionUDP.SetSendBufferSize(720);

	receptionUDP.Create();
	receptionUDP.Bind(portReception);
	receptionUDP.SetNonBlocking(true);
	
	camWidth = 80;
	camHeight = 72;
	
	vector<ofVideoDevice> devices = vidGrabber.listDevices();
	
    for(int i = 0; i < devices.size(); i++){
		cout << devices[i].id << ": " << devices[i].deviceName;
        if( devices[i].bAvailable ){
            cout << endl;
        } else {
            cout << " - non disponible " << endl;
        }
	}
    
	vidGrabber.setDeviceID(0);
	vidGrabber.setDesiredFrameRate(nombreImages);
	vidGrabber.initGrabber(camWidth,camHeight);
	
	//videoPixelisee 	= new unsigned char[camWidth*camHeight * 3];
	//videoTexture.allocate(camWidth,camHeight, GL_RGB);
	
	tableauPixelEmission = new char[720];
	tableauPixelReception = new char[720];
	ofSetVerticalSync(true);
}


//--------------------------------------------------------------
void ofApp::update(){
	vidGrabber.update();
	
	if (vidGrabber.isFrameNew()){
		int totalPixels = camWidth * camHeight;
		unsigned char * pixels = vidGrabber.getPixels();
		for (int i = 0; i < totalPixels; i++){
			if (pixels[3 * i] + pixels[3 * i + 1] + pixels[3 * i + 2] > 382) {
				//videoPixelisee[3 * i] = 255;
				//videoPixelisee[3 * i + 1] = 255;
				//videoPixelisee[3 * i + 2] = 255;
				tableauPixelEmission[i / 8] |= (1 << i % 8);
			} else {
				//videoPixelisee[3 * i] = 0;
				//videoPixelisee[3 * i + 1] = 0;
				//videoPixelisee[3 * i + 2] = 0;
				tableauPixelEmission[i / 8] &= ~(1 << i % 8);
			}
		}
		//videoTexture.loadData(videoPixelisee, camWidth,camHeight, GL_RGB);
		emissionUDP.Send(tableauPixelEmission, 720);
	}
	
	receptionUDP.Receive(tableauPixelReception, 720);
}

//--------------------------------------------------------------
void ofApp::draw(){
	//videoTexture.draw(20+camWidth,20,camWidth,camHeight);
	for (int i = 0; i < 720; i++) {
		for (int j = 0; j < 8; j++) {
			if ((tableauPixelReception[i] & (1 << j)) == 0) {
				ofSetColor(0, 0, 0);
			} else {
				ofSetColor(255, 255, 255);
			}
			ofFill();
			ofRect(4 * ((i * 8 + j) % 80), 3 * ((i * 8 + j) / 80), 4, 3);
		}
	}
}

Modifier dans le main.cpp la ligne suivante :

ofSetupOpenGL(320,218, OF_WINDOW);

Le fichier data.xml qui permet de modifier les paramètres de connexion pour une utilisation aisée :

<IPEmission>
	192.168.1.2
</IPEmission>

<portEmission>
	1200
</portEmission>

<portReception>
	1201
</portReception>

<nombreImages>
	6
</nombreImages>

Gestion du son

pseudo stream via arecord/aplay

L'idée est d'enregistrer et lire simultanément un fichier audio en l'envoyant via ssh sur un autre pc...

arecord -D plughw:1,0 -f dat | ssh -C user@remoteip aplay -f dat

source : http://mutsuda.com/2012/09/07/raspberry-pi-into-an-audio-spying-device/

genre de vrai streaming avec gstreamer

installer

sudo apt-get install gstreamer0.10-alsa gstreamer0.10-plugins-base gstreamer0.10-plugins-good gstreamer0.10-plugins-bad gstreamer0.10-plugins-ugly gstreamer0.10-tools

Pour envoyer :

gst-launch-0.10 -v alsasrc device=hw:1 ! audioconvert ! audioresample ! 'audio/x-raw-int,rate=8000,width=16,channels=1' ! speexenc ! rtpspeexpay ! udpsink host=10.0.0.190 port=6666


Pour recevoir :

gst-launch-0.10 udpsrc port=6666 caps="application/x-rtp, media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" ! gstrtpjitterbuffer ! rtpspeexdepay ! speexdec ! audioconvert ! audioresample ! volume volume=10 ! autoaudiosink

Mise en place d'un VPN pour échanges à l'intérieur d'un tunnel chiffré

Installation de tinc sur le serveur

L'installation s'appuie sur ce tutoriel : http://xmodulo.com/2012/05/how-to-install-and-configure-tinc-vpn.html, il s'agit pour nous d'installer le VPN sur 3 machines : le serveur "dedibox", le "minitel1" et le "minitel2" dans le but de pouvoir faire communiquer les 2 minitels via le serveur/vpn sans avoir à se soucier de l'ouverture de ports et de la NSA (en théorie car tinc s'appuie sur openssl ....) soit :

  • Installer tinc sur le serveur
sudo apt-get install tinc
  • Créer le fichier de config de tinc sur le host "dedibox" (le serveur)
sudo mkdir -p /etc/tinc/myvpn/hosts
  • Créer a tinc configuration file called tinc.conf, and host configuration file(s) as follows.
sudo nano /etc/tinc/myvpn/tinc.conf
Name = dedibox
AddressFamily = ipv4
Interface = tun0

In the above example, the directory "myvpn" under /etc/tinc is the name of the VPN network to be established between dedibox and minitel1. VPN name can be any alphanumeric name without containing "-". In tinc.conf example, "Name" field indicates the name of tinc-running local host, which doesn't have to be actual hostname. You can choose any generic name.

On crée ensuite un les fichiers de configuration du premier host :

sudo mkdir /etc/tinc/myvpn/hosts/
sudo nano /etc/tinc/myvpn/hosts/dedibox
Address = 88.190.13.94
Subnet = 11.0.0.1/32

The name of host configuration file (e.g., dedibox) should be the same as the one you defined in tinc.conf. The "Address" field indicates a globally routable public IP address associated with dedibox. This field is required for at least one host in a given VPN network so that other hosts can initiate VPN connections to it. In this example, dedibox will serve as the bootstrapping server, and so has a public IP address (e.g., 88.190.13.94). The "Subnet" field indicates the VPN IP address to be assigned to dedibox.

On génère ensuite la clef publique et privé.

sudo tincd -n myvpn -K4096
(faire entrée quand nom clef privé publique demandé)

The above command will generate 4096-bit public/private keys for host "dedibox". The private key will be stored as /etc/tinc/myvpn/rsa_key.priv, and the public key will be appended to /etc/tinc/myvpn/hosts/dedibox

Ensuite, on configure les scripts qui seront exécutés après que le daemon tinc soit lancé et lorsque ce daemon est arrêté :

sudo nano /etc/tinc/myvpn/tinc-up
#!/bin/sh
ifconfig $INTERFACE 11.0.0.1 netmask 255.255.255.0
sudo vi /etc/tinc/myvpn/tinc-down
#!/bin/sh
ifconfig $INTERFACE down
sudo chmod 755 /etc/tinc/myvpn/tinc-*

Désormais, la configuration du host "dedibox" est terminée, il faut maintenant faire de même pour minitel1 et minitel2

Installation de tinc sur le minitel1

Créer un utilisateur :

sudo adduser minitel1

Ajouter cet utilisateur aux suoders :

sudo visudo

puis ajouter la ligne au fichier :

minitel1 ALL=(ALL) NOPASSWD: ALL

se délogguer et se reloguer pour que ça prenne effet

sudo apt-get install tinc
sudo mkdir -p /etc/tinc/myvpn
sudo nano /etc/tinc/myvpn/tinc.conf
Name = minitel1
AddressFamily = ipv4
Interface = tun0
ConnectTo = dedibox

In the above, note that unlike host "dedibox", I put "ConnectTo" field in minitel1's tinc configuration, since host "minitel1" will initiate a VPN connection to host "dedibox" when tinc daemon on bob is up.

sudo mkdir /etc/tinc/myvpn/hosts/
sudo nano /etc/tinc/myvpn/hosts/minitel1
Subnet = 11.0.0.2/32
sudo tincd -n myvpn -K4096
(faire entrée quand nom clef privé publique demandé)


De même, la clef privée de minitel1 sera stockée comme /etc/tinc/myvpn/rsa_key.priv et la clef publique sera ajoutée à /etc/tinc/myvpn/hosts/minitel1

sudo nano /etc/tinc/myvpn/tinc-up
ifconfig $INTERFACE 11.0.0.2 netmask 255.255.255.0
sudo nano /etc/tinc/myvpn/tinc-down
ifconfig $INTERFACE down
sudo chmod 755 /etc/tinc/myvpn/tinc-*

Installation de tinc sur le minitel2

identique à précédemment, adapter les noms et l'adresse réseau du "Subnet" (ie 11.0.0.3) pour le deuxième minitel

Échange des clefs

Quand la configuration de tinc est faite sur le serveur et les 2 mintels, il convient d'échanger les clefs : il faut placer les clefs publiques des 2 minitels sur le serveur et de rappatrier les clefs publiques des 2 minitels sur le serveur. Pour cela, on peut utiliser filezilla en sftp, copier les clefs là où l'on peut écrire sur les machines respectives et les déplacer "à la main", sinon, on peut aussi faire ça d'un coup avec la commande scp :

On host "dedibox":

scp /etc/tinc/myvpn/hosts/dedibox root@ip-minitel1:/etc/tinc/myvpn/hosts/

On host "minitel1":

scp /etc/tinc/myvpn/hosts/minitel1 root@ip-dedibox:/etc/tinc/myvpn/hosts/

Ou encore plus simplement par copier-coller :

sudo cat /etc/tinc/myvpn/hosts/dedibox
=== copier ===
Address = 88.190.13.94
Subnet = 11.0.0.1/32
-----BEGIN RSA PUBLIC KEY-----
chut
-----END RSA PUBLIC KEY-----
======

Sur mintel1 et 2 :

sudo nano /etc/tinc/myvpn/hosts/dedibox
=== coller & enregistrer ===

Lancer le daemon tinc sur les différentes machines

Enfin, on lance tout d'abord le daemon tinc d'abord sur le serveur dedibox puis sur les minitels, comme ceux_ci sont supposés se connecter sur le serveur :

sudo tincd -n myvpn
sudo tincd -n myvpn --debug=3 -D & (pour voir ce qui se passe)

Configurer le NAT / Firewall quand il ne s'agit pas d'un réseau local

au labo, sur le serveur de dév qui n'a pas de firewall, il a suffit de faire une translation d'adresse sur IPCop vers le serveur de dév (192.168.0.1) du port 655 vers le port 655

sur la dedibox, configuration du firewall pour laisser passer les requêtes sur le port 655 :

cp /root/sbin/firewall /root/sbin/firewall.b01backup

ajouter des règles au firewall :

nano /root/sbin/firewall

ajouter les lignes

iptables -A INPUT -p tcp --dport 655 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 655 -j ACCEPT
(optionnel)  iptables -A INPUT -p udp --dport 655 -j ACCEPT

tests

sudo ifconfig

doit faire apparaitre un périphérique réseau "tun0" avec l'adresse ip correspondante (11.0.0.1 sur serveur, 11.0.0.2/3 sur minitels)

sudo route
$Table de routage IP du noyau
Destination     Passerelle      Genmask         Indic Metric Ref    Use Iface
default         bbox.lan        0.0.0.0         UG    0      0        0 wlan0
11.0.0.0        *               255.255.255.0   U     0      0        0 tun0
link-local      *               255.255.0.0     U     1000   0        0 wlan0
192.168.1.0     *               255.255.255.0   U     9      0        0 wlan0

il faut attendre un peu (une à deux minutes) le temps que la connexion vpn se fasse, ensuite, on doit être capable de :

ping 11.0.0.1

depuis les minitels 1 et 2 et

ping 11.0.0.3 

depuis le minitel1 vers le 2

Todo

  • lancement auto du daemon au démarrage du serveur et des minitels
  • voir comment configurer le serveur pour que les minitels puissent surfer en passant par le serveur (pas utile pour visio mais pour autres usages ...

Paquet final

Pour une réinstallation totale (paquets audio / vidéo / VPN) :

sudo apt-get update
sudo apt-get install python-opencv tinc gstreamer0.10-alsa gstreamer0.10-plugins-base gstreamer0.10-plugins-good gstreamer0.10-plugins-bad gstreamer0.10-plugins-ugly gstreamer0.10-tools htop

Pour le Minitel qui va à Nantes // Minitel1

Fichier:Paquet Nantes.zip ip 10.0.0.104 au labo ssh minitel1@10.0.0.104

Script script qui lance tout d'un coup (présent dans l'archive):

#!/bin/bash
# -*- coding: utf-8 -*-

# Envoi du son :
gst-launch-0.10 -v alsasrc device=hw:1 ! audioconvert ! audioresample ! 'audio/x-raw-int,rate=8000,width=16,channels=1' ! speexenc ! rtpspeexpay ! udpsink host=11.0.0.3 port=6666 &

# Réception du son :
gst-launch-0.10 udpsrc port=6666 caps="application/x-rtp, media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" ! gstrtpjitterbuffer ! rtpspeexdepay ! speexdec ! audioconvert ! audioresample ! volume volume=10 ! autoaudiosink &

# Envoi et réception de l'image :
cd Minitel-0.2
python sendMinitel.py Toulouse &
python receiveMinitel.py Nantes

Pour le Minitel qui va à Toulouse // Minitel2

Fichier:Paquet Toulouse.zip ip 10.0.0.155 au labo ssh pi@10.0.0.155

Script script qui lance tout d'un coup (présent dans l'archive) :

#!/bin/bash
# -*- coding: utf-8 -*-

# Envoi du son :
gst-launch-0.10 -v alsasrc device=hw:1 ! audioconvert ! audioresample ! 'audio/x-raw-int,rate=8000,width=16,channels=1' ! speexenc ! rtpspeexpay ! udpsink host=11.0.0.2 port=6666 &

# Réception du son :
gst-launch-0.10 udpsrc port=6666 caps="application/x-rtp, media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" ! gstrtpjitterbuffer ! rtpspeexdepay ! speexdec ! audioconvert ! audioresample ! volume volume=10 ! autoaudiosink &

# Envoi et réception de l'image :
cd Minitel-0.2
python sendMinitel.py Nantes &
python receiveMinitel.py Toulouse