Linux / Unix

Raspberry Pi, WiFi, ssh et ligne de commande

J’ai rebranché mon vieux Raspberry Pi pour les besoins de geekeries personnelles. J’ai vu qu’il existait une version Lite de Raspbian et j’ai choisi de l’utiliser car mon Raspberry Pi n’est pas de première jeunesse et ma carte SD ne fait que 4 Go. J’ai eu une petite surprise en démarrant le système : il n’y a pas de serveur X. Il faut donc tout faire en ligne de commande. Challenged accepted!

Démarrer le Raspberry Pi

Raspbian Lite est téléchargeable sur le site de la fondation Raspberry. La version actuelle est Jessie. Je me suis aidé de deux articles que j’avais écrit il y a déjà longtemps pour créer ma carte SD avec l’image du système. J’ai branché mon clavier, ma télé, l’alimentation et j’ai obtenu prompt.

Changer le layout du clavier

Parce que qu’un système qwerty quand on a un clavier azerty c’est pas sympa, surtout si on a besoin d’utiliser des symboles, j’ai commencé par passer en azerty. Internet vous propose plusieurs techniques, j’ai utilisée celle-ci :

sudo dpkg-reconfigure keyboard-configuration

La configuration est intuitive avec une interface type ncurse. Quand c’est terminé, il suffit de redémarrer avec la commande reboot.

Configuration du WiFi

Aucune difficulté à ce que Raspbian reconnaisse mon dongle WiFi. Je l’ai branché et il est directement apparu comme wlan0 quand j’ai appelé la commande ifconfig. La partie un peu moins fun est la configuration du réseau WiFi (SSID + passphrase). La fondation Raspberry propose un tutoriel pour cela. Je crois avoir eu besoin de redémarrer à nouveau pour que ça fonctionne (en plus de la procédure expliquée dans le lien).

Configuration IP manuelle

En général, le serveur DHCP de votre box assignera toujours la même IP à votre Raspberry Pi. Il est quand même plus prudent de lui affecter une adresse IP fixe pour le retrouver facilement. Idéalement, il faudrait aussi demander à votre box de ne plus attribuer cette adresse IP par DHCP…

J’ai tout d’abord regardé quelle était mon adresse actuelle, quel masque de sous-réseau était utilisé et quelle était l’adresse de la gateway :

$ ifconfig wlan0
wlan0     Link encap:Ethernet  HWaddr 74:da:38:5d:fc:6b  
          inet addr:192.168.1.17  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: 2a01:cb05:8980:9400:944d:6692:7db0:9552/64 Scope:Global
          inet6 addr: fe80::9d35:79ba:e404:4253/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14436 errors:0 dropped:400 overruns:0 frame:0
          TX packets:4818 errors:0 dropped:1 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:17129734 (16.3 MiB)  TX bytes:701974 (685.5 KiB)
$ ip route
default via 192.168.1.1 dev wlan0  metric 303 
192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.17  metric 303

J’ai ensuite modifié le fichier /etc/network/interfaces de manière adaptée :

cat /etc/network/interfaces
[...]

allow-hotplug wlan0
iface wlan0 inet static
    address 192.168.1.17
    netmask 255.255.255.0
    gateway 192.168.1.1
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

[...]

Activation de ssh

La dernière étape pour que mon système puisse être headless était d’activer le serveur SSH et ainsi pouvoir me connecter depuis mon ordinateur de bureau. La fondation Raspberry explique comment faire ceci dans ce tutoriel. Avec Raspbian Lite, il suffit de créer un fichier ayant pour nom ssh, à la racine de la carte SD. J’ai donc éteint mon Raspberry Pi et j’ai inséré ma carte mémoire dans mon Mac et j’ai utilisé le terminal :

$ cd /Volumes/boot/
$ touch ssh

Une fois le Raspberry Pi redémarré, vous pouvez regarder si le serveur SSH est démarré avec la commande suivante :

ps -eaf | grep ssh

Si vous un brin plus optimiste, vous pouvez essayé directement depuis votre PC :

$ ping 192.168.1.17
PING 192.168.1.17 (192.168.1.17): 56 data bytes
64 bytes from 192.168.1.17: icmp_seq=0 ttl=64 time=18.548 ms
64 bytes from 192.168.1.17: icmp_seq=1 ttl=64 time=6.127 ms
^C
--- 192.168.1.17 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 6.127/12.337/18.548/6.211 ms
imac-de-pierre:/ pierregradot$ ssh pi@192.168.1.17
The authenticity of host '192.168.1.17 (192.168.1.17)' can't be established.
ECDSA key fingerprint is SHA256:xv5CB0epvX+e8sKhgLFp2bP+1jzU8j7PzGAVAnZs8q4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.17' (ECDSA) to the list of known hosts.
pi@192.168.1.17's password: 

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.
Last login: Mon Apr  3 16:22:55 2017
pi@raspberrypi:~ $ echo "Hell yeah!"
Hell yeah!
pi@raspberrypi:~ $ 

Et voilà ! J’ai débranché le Raspberry Pi de la télé, j’ai rangé mon clavier, et c’était bon !

PS : en fait, si vous avez un câble Ethernet, vous pouvez vous passer d’un clavier et d’une télé. Voici comment faire : Headless Raspberry Pi Setup.

 

 

Publicités

XBee et XCTU sous Linux

Cela doit bien faire 2 ans que deux modules XBee (des Pro S1 de chez Digi) traînent dans mes tiroirs et je n’en avais rien fait. Ayant pour projet de faire des capteurs de température et d’humidité sans fil, je me suis dit que c’était le bon moment de les utiliser. L’idée est d’envoyer les données à un Raspberry Pi pour traitement. J’ai donc pris mon XBee Explrer Dongle, j’y ai connecté un module Xbee et je l’ai branché à mon PC. Digi fournit un logiciel pour gérer les modules XBee connectés à un PC, les configurer, envoyer et recevoir des données : il s’agit de XCTU. De nombreux tutoriels sur Internet disent que XCTU n’est disponible que sous Windows mais cette époque est révolue ! Vous pouvez télécharger les différentes versions pour Windows, Linux et Mac ici.

Installation et lancement

Si vous êtes sous Linux et que vous ne savez pas si vous devez opter pour la version 32 ou la version 64 bits, il vous suffit de taper la commande uname -a pour savoir si vous avez un processeur 32 ou 64 bits. Exemple dans mon cas :

~$ uname -a
Linux pgradot-xubuntu 4.4.0-53-generic #74-Ubuntu SMP 
Fri Dec 2 15:58:04 UTC 2016 i686 i686 i686 GNU/Linux

Le i686 m’indique que mon processeur est 32 bits.

Une fois le téléchargement terminé, rendez le fichier exécutable et lancez-le avec les droits administrateurs :

$ chmod u+x 40002880_G.run
$ sudo ./40002880_G.run

Un wizard vous guide dans l’installation de XCTU. Par défaut, le logiciel s’installe dans /opt/Digi où un sous-dossier XCTU-NG est créé. On y trouve launcher et app (le premier lançant le second). Si vous lancez l’un des deux sans les droits administrateurs, cela ne fera qu’ouvrir une petite fenêtre qui ne contient rien et que vous ne pourrez pas fermer… Ayez le réflexe sudo, ça marchera beaucoup mieux ! Vous verrez alors ceci :

xbee 1 startup

Ajout de modules

Vous pouvez ajouter des modules radios ou les découvrir en cliquant que les icônes en haut à gauche. L’ info-bulle vous avait sans doute déjà fait deviner le mode opératoire. Le mien étant branché via un dongle USB, il apparaît comme étant /dev/ttyUSB0 :

xbee 2 add device

XCTU récupère et affiche tout la configuration du nouveau module :

xbee 3 device added

Onglets configuration, console et réseau

XCTU est intuitif et l’info-bulle de droite nous dit qu’il existe 3 onglets, chacun correspondant à un mode :

  1. Le mode configuration, ouvert par défaut, permet de voir la configuration des modules comme montré précédemment mais aussi de la modifier et d’envoyer la nouvelle configuration au module.
  2. Le monde console permet soit d’interagir via des commandes AT avec un module, soit d’envoyer des paquets sur le réseau. Vous pouvez enregistrer des paquets et jouer des séquences d’envoi. Certainement très pratique pour des tests.
  3. Le mode réseau, pour avoir un aperçu de la topologie du réseau sans fil à portée.

Commandes AT

Si vous souhaitez envoyez des commandes AT à votre module, il suffit d’aller dans l’onglet console et d’appuyer sur le bouton Open (qui se transforme en bouton Close, visible en vert dans l’image ci-dessous). Vous tapez alors +++ dans à gauche, vous attendez une seconde et le module répond OK pour indiquer qu’il est bien passé en mode commande. Tapez alors vos commandes en les terminant par entrée et le module vous répondra. Sans activité de votre part pendant 3 secondes, le module sort automatiquement et silencieusement du mode commande et l’envoi d’une nouvelle commande sera alors sans réponse. Sparkun a écrit un très bon aide-mémoire pour les commandes AT disponibles.

xbee 4 at

Pour aller plus loin

Exploring XBees and XCTU par Sparkun


Utiliser Linux pour lire un disque Time Machine

OS X propose le très pratique Time Machine pour sauvegarder ses données automatiquement sur un disque dur externe. Presque en même temps que mon iMac, j’ai acheté un disque dur externe sur lequel je sauvegarde régulièrement l’intégralité de mon disque interne. Il y a quelques jours, mon iMac m’a lâché et ne s’allume plus. Je vais l’emmener voir le docteur mais en attendant j’ai besoin de certains fichiers importants. Il s’avère que ces fichiers sont sur mon disque Time Machine car je fais régulièrement mes sauvegardes 🙂

Je n’ai pas de deuxième Mac pour lire ce disque mais j’ai plein d’autres PC, avec Windows ou Linux. Petit hic : Time Machine utilise des disques au format HFS+. Windows ne comprend pas ce format par défaut, il faut utiliser des logiciels additionnels ; en revanche, Linux le comprend très bien car il est directement supporté par le noyau. J’ai donc ressorti un vieux PC portable et, malgré une vieille version de Mint, j’ai immédiatement pu accéder à mes fichiers !

time machine linux1

Il y a un second hic : Time Machine stocke les sauvegardes de manière un peu ésotériques, à grands coups de liens, et cela mène à des problèmes de permissions empêchant l’accès aux fichiers de mon user. Comme par hasard, les fichiers que je veux sont là-dedans…

time machine linux 2

Je ne suis bien sûr pas le premier à rencontrer cette difficulté, d’autres se sont déjà penchés sérieusement sur le sujet et un gentil développeur a publié sur Github un script pour copier une arborescence d’un disque Time Machine vers un dossier local. Ça fait un peu mal pour récupérer beaucoup de données, mais on ne va pas se plaindre et remercier le monsieur, Marcello Barnaba !

J’ai donc copié mon dossier $HOME/Documents vers mon PC Linux :

$ sudo ./copy-from-time-machine.sh "/media/Seagate Backup Plus Drive/Backups.backupdb/iMac de pierregradot/2016-03-05-112442/iMac/Users/pierregradot/Documents" ./time_restored/

Mes fichiers étaient là, mission accomplie 🙂


update-alternatives

Hier, j’ai voulu installé Eclipse sous Xubuntu avec le nouvel installateur Oomph. Au lancement de l’installateur, j’ai eu un message d’erreur car je ne disposais que de Java 7 et que l’installateur avait besoin de Java 8. Je me suis alors dit qu’il était temps de mettre en oeuvre la technique des update-alternatives dont m’avait parlé mon administrateur système préféré.

État des lieux de Java

Tout d’abord, commençons par regarder ce vers quoi pointe la commande java :

$ ls -la $(which java)
 lrwxrwxrwx 1 root root 22 sept. 20 19:05 /usr/bin/java -> /etc/alternatives/java

Le principe d’update-alternatives est de ne pas faire de lien direct vers la vraie implémentation mais un lien vers une alternative, qui est dans /etc/alternatives qui pointe à son tour vers le programme réellement chargé de la commande. Regardons les alternatives connues du système des alternatives pour java :

$ update-alternatives --list java
/usr/lib/jvm/java-7-openjdk-i386/jre/bin/java

Il n’y a pour l’instant qu’un seul programme connu pour la commande java et c’est sans surprise un Java 7.

Installation d’une nouvelle alternative pour Java

Personnellement, j’ai choisi d’utiliser le JDK 8 d’Oracle et j’ai récupéré la dernière version disponible sur le site officiel. J’ai décompressé l’archive tar.gz dans /usr/local :

$ ls
bin/ etc/ games/ include/ jdk1.8.0_60/ lib/ man@ sbin/ share/ src/

Pour installer une nouvelle alternative, il faut utiliser une ligne de commande de la forme suivante :

update-alternatives --install <link> <name> <path> <priority>

<link> est l’endroit où placer le lien qui pointera vers /etc/alternatives, <name> est la commande pour laquelle on installe une alternative et <path> est le chemin vers le programme concret. <priority> sert pour les groupes de liens et quand le mode automatique est utilisé. Plus la priorité est élevée, plus l’alternative aura une priorité forte. Pour installer une nouvelle alternative vers mon JDK 8, j’ai utilisé la commande suivante :

$ sudo update-alternatives --install /usr/bin/java java
    /usr/local/jdk1.8.0_60/bin/java 3000
update-alternatives: using /usr/local/jdk1.8.0_60/bin/java 
    to provide /usr/bin/java (java) in auto mode

C’est maintenant Java 8 qui est utilisé par défaut car la nouvelle alternative a une priorité plus forte que l’alternative déjà disponible :

$ which java
/usr/bin/java
pgradot@pgradot-xubuntu:~$ java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) Client VM (build 25.60-b23, mixed mode)

A titre d’exemple, voici ce qui se passe pour une installation avec une priorité à 1000 au lieu de 3000 :

$ sudo update-alternatives --install /usr/bin/java java
    /usr/local/jdk1.8.0_60/bin/java 1000
pgradot@pgradot-xubuntu:~/Documents/git/PyTweet$ java -version
java version "1.7.0_79"
OpenJDK Runtime Environment (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.14.04.1)
OpenJDK Client VM (build 24.79-b02, mixed mode, sharing)

Changer d’alternative

Il est simple de passer d’une alternative à une autre et il est donc pratique de garder plusieurs versions installées sur le système et de changer la cible concrète de la commande au besoin. Cela est utile quand un projet particulier réclame une version différente que la version utilisée généralement, que ce soit Java ou autre.

On commence par lister les alternatives pour la commande souhaitée :

$ sudo update-alternatives --list java
[sudo] password for pgradot:
/usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
/usr/local/jdk1.8.0_60/bin/java

Il suffit ensuite d’utiliser la commande --set :

$ sudo update-alternatives --set java
    /usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
update-alternatives: using /usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
    to provide /usr/bin/java (java) in manual mode
$ java -version
java version "1.7.0_79"
OpenJDK Runtime Environment (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.14.04.1)
OpenJDK Client VM (build 24.79-b02, mixed mode, sharing)

Il est pratique de lister les alternatives avant d’utiliser --set pour pouvoir copier-coller le chemin souhaité. Il n’est pas possible d’utiliser un programme qui n’a pas encore été ajouté comme alternative :

$ sudo update-alternatives --set java /usr/local/jdk1.8.0_60/bin/jav
update-alternatives: error: alternative /usr/local/jdk1.8.0_60/bin/jav
    for java not registered; not setting

L’erreur dit bien que l’alternative n’est pas connue et non que le programme n’existe pas.

Supprimer une alternative

Rien de bien compliqué pour supprimer une alternative. Si c’est l’alternative est actuellement utilisé, le gestionnaire des alternatives se rabat sur une autre alternative en se basant sur les priorités :

$ sudo update-alternatives --remove java /usr/local/jdk1.8.0_60/bin/java
update-alternatives: removing manually selected
    alternative - switching java to auto mode
update-alternatives: using /usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
    to provide /usr/bin/java (java) in auto mode

C’est aussi l’un des avantages du système des alternatives. Il sera charge de mettre à jour les différents liens quand des alternatives sont modifiées.


Installation d’Autobahn|Testsuite sous Xubuntu

L’année dernière, dans le cadre du travail, j’ai fait une implémentation de la partie client du protocole WebSocket, décrit par la RFC 6455, pour une utilisation dans un environnement Java embarqué contraint. Au début, j’utilisais un petit serveur, écrit en Java SE,  pour avoir quelques tests simples. Quand mon implémentation à commencer à devenir mature, j’ai cherché comment tester de manière un peu plus complète ma bibliothèque et j’ai trouvé Autobahn|Testsuite. C’est une test suite automatique, écrite en Python 2 et elle est plutôt réputée pour ce protocole, à en juger par la liste affirmée des utilisateurs. Elle est en tout cas, elle est suffisamment réputée pour qu’Oracle fasse un article quand leur implémentation de référence de WebSocket en Java a atteint pour la première fois un score de 100 %. J’ai remis en branle cette test suite cette semaine car je vais me resservir de cette bibliothèque pour un nouveau projet.

Le site officiel donne une procédure d’installation qui est en apparence simple mais j’ai rencontré plusieurs problèmes en l’installant sous Xubutu. J’écris cet article pour retracer les problèmes et les solutions.

La première étape est d’installer les dépendance décrites. Python 2.7 est installé par défaut, il me suffit donc d’installer les modules pip et Twisted :

sudo apt-get install python-pip
sudo apt-get install python-twisted

On peut ensuite passer à l’installation de la test suite en elle-même. Je vous conseille de demander les droits root pour éviter des erreurs telles que error: could not create '/usr/local/lib/python2.7/dist-packages/autobahntestsuite': Permission denied. Dans le terminal :

sudo pip install autobahntestsuite>

Après des téléchargements et un peu de défilement dans la console, vous rencontrerez sans doute une erreur comme celle-ci :

wsaccel/utf8validator.c:8:22: fatal error: pyconfig.h: No such file or directory

 #include "pyconfig.h"

                      ^

compilation terminated.

error: command 'i686-linux-gnu-gcc' failed with exit status 1

Pour que l’installation réussisse, j’ai dû installé quelques paquets supplémentaires :

sudo apt-get install python-dev
sudo apt-get install libffi-dev
sudo apt-get install libssl-dev

L’installation est maintenant terminée ! Il n’y a plus qu’à lancer le test d’installation, qui vérifie que tout s’est bien installé :

$ wstest --help
Traceback (most recent call last):
  File "/usr/local/bin/wstest", line 5, in 
    from pkg_resources import load_entry_point
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2749, in 
    working_set = WorkingSet._build_master()
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 444, in _build_master
    ws.require(__requires__)
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 725, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 628, in resolve
    raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: characteristic>=14.0.0
$ echo $?
1

Caramba ! Encore raté ! Python ne possède pas le module characteristic ou alors il en possède une version trop ancienne. pip est la solution pour installer des modules Python :

sudo pip install characteristic

Histoire de vous faire gagner du temps, je vous annonce qu’il manque aussi d’autres modules, installez-les avant de retenter wtest :

sudo pip install pyasn1-modules
sudo pip install cryptography
sudo pip install unittest2

Finalement :

$ wstest --help && echo $?
Usage: wstest [options]
Options:
  -d, --debug            Debug output [default: off].
  -a, --autobahnversion  Print version information for Autobahn and
                         AutobahnTestSuite.
  -m, --mode=            Test mode, one of: echoserver, echoclient,
                         broadcastclient, broadcastserver, fuzzingserver,
                         fuzzingclient, testeeserver, testeeclient, massconnect,
                         serializer [required]
  -t, --testset=         Run a test set from an import test spec.
  -s, --spec=            Test specification file [required in some modes].
  -o, --outfile=         Output filename for modes that generate testdata.
  -w, --wsuri=           WebSocket URI [required in some modes].
  -u, --webport=         Web port for running an embedded HTTP Web server;
                         defaults to 8080; set to 0 to disable. [optionally used
                         in some modes: fuzzingserver, echoserver,
                         broadcastserver, wsperfmaster]. [default: 8080]
  -i, --ident=           Testee client identifier [optional for client testees].
  -k, --key=             Server private key file for secure WebSocket (WSS)
                         [required in server modes for WSS].
  -c, --cert=            Server certificate file for secure WebSocket (WSS)
                         [required in server modes for WSS].
      --version          Display Twisted version and exit.
      --help             Display this help and exit.

0

\o/

Quand j’avais réussi à faire fonctionner wtest au travail, l’aventure n’était pas vraiment terminée. J’avais fait cela sur mon PC avec Internet mais je souhaitais monter un serveur de tests sur le réseau privé non relié à Internet… Il y avait une solution !

pip install --download . autobahntestsuite

Cette commande permet de télécharger toutes les dépendances nécessaires (y compris les récalcitrants pyasn1-modules et autre characteristic…) dans le dossier courant. On peut ensuite déplacer ce dossier sur le PC non connecté à Internet et lancer une installation hors-ligne. En effet, pip est capable d’installer à partir de dépendances qu’il cherche dans le dossier précisé plutôt que d’aller les chercher dans ses dépôts habituels :

pip install --no-index --find-links="/path/to/downloaded/dependencies" packagename

Dans mon cas, les dépendances n’étaient pas super bien gérées. J’ai eu des erreurs tels que distutils.errors.DistutilsError: Could not find suitable distribution for Requirement.parse('enum34') que j’ai corrigé en installant manuellement enum34 et cffi. Ces dépendances avaient pourtant bien été téléchargées mais l’installation du module autobahntestsuite n’arrivait pas à les installer toute seule.

Maintenant que tout est installé, on va quand même essayé de faire un vrai test du protocole, non ? Vous trouverez des détails sur l’utilisation de wtest sur cette page dédiée. Pour faire simple, je vais lancer un serveur de tests et je vais y connecter mon navigateur pour quel score il obtient. Le serveur se lance avec la commande suivante :

$ wstest -m fuzzingserver
Auto-generating spec file 'fuzzingserver.json'
Loading spec from /home/pgradot/fuzzingserver.json

Using Twisted reactor class 
Using UTF8 Validator class 
Using XOR Masker classes 

Autobahn WebSockets 0.7.2/0.10.9 Fuzzing Server (Port 9001)
Ok, will run 521 test cases for any clients connecting
Cases = ['1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.
...
'13.7.16', '13.7.17', '13.7.18']

La commande ne rend pas la main tant que le serveur tourne. J’ai tronqué (avec ...) la liste des 521 test cases qui sont en attente de clients. Il suffit ensuite de lancer Firefox et d’aller à l’adresse http://localhost:8080 :

autobahn start test

Vous l’aurez deviner, il suffit de cliquer sur Test your browser pour lancer le test :

autobahn test running

On voit le compteur de tests exécutés se mettre à jour sur la page. Dans le terminal, on peut voir les traces d’exécution du serveur. En voici un extrait :

Running test case ID 12.5.11 for agent Firefox/40.0-20100101 from peer tcp4:127.0.0.1:60352
Running test case ID 12.5.12 for agent Firefox/40.0-20100101 from peer tcp4:127.0.0.1:60353
Running test case ID 12.5.13 for agent Firefox/40.0-20100101 from peer tcp4:127.0.0.1:60354

Quand les tests sont terminés, il faut cliquer sur le bouton Update Reports (Manual) pour mettre à jour les résultats, retourner à la page précédente et afficher les résultats des tests locaux :

autobahn results

Cette version 40 de Firefox ne fait pas un score de 100 %, certains tests sur les trames de fermeture de connexion sont à « fail« . Il affiche tout de même de très bons résultats 🙂

Bons tests !