dimanche 24 février 2013

Dongle wifi DWA-121 et Raspberry Pi

Mon dernier achat est un dongle WIFI. Avant cet achat compulsif, j'ai vérifié dans la liste fournie sur le wiki de raspberry pi, quel modèle acheter. C'est déjà pas forcément facile avec du matériel certifié alors si on part dans l'inconnu, c'est encore plus galère....

L'heureux élu est le dongle DWA-121 de la marque D-LINK.

Le but de ce tutoriel est de configurer le dongle wifi sur une distribution de type buildroot (oubliez network-manager et tout ce qui va avec ....)


Pour ce tutoriel, nous allons :

  • Utiliser l'outil de configuration wifi : wpa_supplicant
  • Compiler, installer et charger le driver de chez realtek : 8192cu
  • Compiler et installer les outils sans fil fournis avec le driver
  • Créer un script pour la configuration du dongle au lancement du système de fichiers.

Lors de l’insertion du dongle wifi sur la raspberry pi, voici les informations indiquant qu'il est bien reconnu par le système :
# dmesg
[...]
[258285.789273] usb 1-1.2: new high-speed USB device number 4 using dwc_otg
[258285.911171] usb 1-1.2: New USB device found, idVendor=2001, idProduct=3308
[258285.918191] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[258285.926230] usb 1-1.2: Product: 802.11n WLAN Adapter
[258285.931734] usb 1-1.2: Manufacturer: Realtek
[258285.936151] usb 1-1.2: SerialNumber: 00e04c000001
[258285.998142] cfg80211: Calling CRDA to update world regulatory domain

et les informations sur le bus USB :
# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 2001:3308 D-Link Corp. DWA-121 802.11n Wireless N 150 Pico Adapter [Realtek RTL8188CUS]

Outil de configuration : wpa_supplicant


L'outil est disponible dans le menuconfig de buildroot (Package selection for target -> Network Applications) :
# make menuconfig


Après avoir intégrer les outils au système de fichiers, il faut éditer les fichiers de configuration /etc/wpa.conf et /etc/network/interfaces et entrer les bons paramètres en fonction de votre routeur wifi :

le fichier de configuration wpa.conf :
#On indique tout d'abord où se situe le programme (socket avec wpa_cli...)
ctrl_interface=/var/run/wpa_supplicant

#On protège l'accès à wpa_supplicant en l'attribuant à un groupe
#Le groupe peut être un identifiant (gid) ou un nom de groupe
#Par défaut le gid est à 0 pour signifier que c'est le root qui protège l'accès.
ctrl_interface_group=0

eapol_version=2

#On définit le mode de sélection du point d'accès (AP : Access Point)
#1 : Configuration classique
#0 : Utilisé pour le protocole IEEE 802.1X (et les réseaux établis).
#2 : Associe les points d'accès dans un mode sécurisé. !!!Utilisé pour le mode Ad-Hoc!!!
#    Associe le SSID (nom de votre réseau) mais pas le BSSID (n° attribué à votre carte réseau).
#    A utiliser si vous avez une clef installée sous NDIS(WRAPPER) pour utiliser pleinement votre réseau :
#     dans ce cas le block network devra comprendre les informations 'key_mgmt', 'pairwise', 'group' et les variables de protocole.
ap_scan=1

network={
        ssid="ma freebox"

        #psk: clef WPA (256bits)
        #   ="mon mot de passe" : entre guillemets pour un mot de passe 'texte' (entre 8 et 63caractères compris)
        psk="mon mot de passe"

        #proto: protocole
        #     =WPA : WPA(1) (WPA/IEEE 802.11i/D3.0)
        #     =RSN : WPA2 (IEEE 802.11i) (par défaut)
        proto=RSN WPA

        #key_mgmt: encryption
        #        =WPA-PSK : WPA 'pre-shared key' (requièrt une clef PSK)
        #        =WPA-EAP : WPA utilisant une authentification EAP (peut utiliser un programme externe (Xsupplicant)).
        #        =IEEE8021X : IEEE 802.1X utulisant une authentification EAP et, optionnellement la génération de clefs WEP dynamiques.
        #        =NONE : Pas de WPA : clef WEP ou connexion directe.
        #        =WPA-NONE : Pour réseaux Ad-Hoc (possibilité de groupage TKIP ou CCMP(AES))
        key_mgmt=WPA-PSK WPA-EAP

        #pairwise: !A ne pas confondre avec le 'group' qui est plus connu!
        #        =CCMP : AES (CBC-MAC : RFC 3610, IEEE 802.11i/D7.0)
        #        =TKIP : (IEEE 802.11i/D7.0)
        #        =NONE : Utilisé pour le mode ad-hoc principalement
        pairwise=CCMP TKIP

        #auth_alg: système d'authentification du réseau
        #        =OPEN : pour WPA et WPA2
        #        =SHARED : pour WEP
        #        =LEAP : pour LEAP sur réseau EAP
        auth_alg=OPEN
}

le fichier d'interfaces réseaux :
# Configure Loopback
auto lo
iface lo inet loopback
# Configure eth0
auto eth0
iface eth0 inet dhcp
# Configure wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa.conf

Driver Realtek RTL8192


Sur le noyau linux 3.2.27, les drivers pour le dongle sont déjà présents et chargés automatiquement grâce au démon udevd, mais le driver rtl8192cu.ko semble buggé (problème d'écriture synchrone, à priori), c'est pourquoi j'ai décidé de repartir des drivers fournis par le constructeur realtek (8192cu.ko), qui d'après ce que j'ai pu voir en traînant sur le web, une version complètement différentes (plus limité, pas de mode moniteur pour les connaisseurs) de celui fourni avec le noyau linux, mais suffisant pour une utilisation standard d'interface réseau.

Fil d'un post trouvé sur le forum raspberry pi : rtl8192cu module for Edimax EW-7811n Wifi dongle

Voici l'état du système d'origine :
# cd /lib/modules/3.2.27/kernel/drivers/net/wireless/rtlwifi
# ls -l
 | drwxr-xr-x 2 root root 4.0K Feb 23 18:36 ./
 | drwxr-xr-x 4 root root 4.0K Feb 23 18:36 ../
 | drwxr-xr-x  2 root root 4.0K Feb 23 18:36 rtl8192c/
 +--> -rw------- 1 root root  64K Feb 23 18:36 rtl8192c-common.ko
 |drwxr-xr-x  2 root root 4.0K Feb 23 19:06 rtl8192cu/
 +--> -rw------- 1 root root 113K Feb 23 18:36 rtl8192cu.ko
 |-rw-------  1 root root  85K Feb 23 18:36 rtlwifi.ko

et les drivers déjà chargés sur le système :
# lsmod
Module                  Size  Used by
rtl8192cu              97581  1
rtl8192c_common        53692  1 rtl8192cu
rtlwifi                64628  1 rtl8192cu
mac80211              203510  3 rtlwifi,rtl8192c_common,rtl8192cu
cfg80211              143188  2 mac80211,rtlwifi
i2c_dev                 4657  2
ipv6                  237083  14
spidev                  4274  0
i2c_bcm2708             3019  0
spi_bcm2708             3969  0

Compilation et insertion du nouveau driver


Il faut, dans un premier temps, télécharger les drivers linux sur le site de realtek puis décompresser les sources et entrer dans le sous dossier driver.

drwxrwxr-x 6 sinseman44 sinseman44  4096 2013-02-24 14:57 ./
drwxrwxr-x 3 sinseman44 sinseman44  4096 2013-02-23 19:19 ../
-rw-r--r-- 1 sinseman44 sinseman44   116 2012-07-30 14:51 clean
drwxrwxr-x 3 sinseman44 sinseman44 12288 2013-02-24 14:57 core/
drwxrwxr-x 3 sinseman44 sinseman44  4096 2013-02-24 14:57 hal/
-rw-r--r-- 1 sinseman44 sinseman44    54 2012-07-30 14:51 ifcfg-wlan0
drwxrwxr-x 3 sinseman44 sinseman44 16384 2013-02-23 19:19 include/
-rw-r--r-- 1 sinseman44 sinseman44   110 2012-07-30 14:51 Kconfig
-rw-r--r-- 1 sinseman44 sinseman44 14760 2013-02-23 19:56 Makefile
drwxrwxr-x 3 sinseman44 sinseman44  4096 2013-02-24 14:57 os_dep/
-rw-r--r-- 1 sinseman44 sinseman44   294 2012-07-30 14:51 wlan0dhcp

On va modifier le Makefile pour configurer correctement notre driver et intégrer la cible raspberry pi (ne pas oublier de mettre la chaîne de compilation croisée dans le PATH) :

[...]
CONFIG_PLATFORM_I386_PC = n
CONFIG_PLATFORM_ARM_BCM2708 = y
CONFIG_PLATFORM_TI_AM3517 = n
CONFIG_PLATFORM_ANDROID_X86 = n
CONFIG_PLATFORM_ARM_S3C2K4 = n
CONFIG_PLATFORM_ARM_PXA2XX = n
CONFIG_PLATFORM_ARM_S3C6K4 = n
CONFIG_PLATFORM_MIPS_RMI = n
CONFIG_PLATFORM_RTD2880B = n
CONFIG_PLATFORM_MIPS_AR9132 = n
[...]

ifeq ($(CONFIG_PLATFORM_ANDROID_X86), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/)
ARCH := $(SUBARCH)
CROSS_COMPILE := /media/DATA-2/android-x86/ics-x86_20120130/prebuilt/linux-x86/toolchain/i686-unknown-linux-gnu-4.2.1/bin/i686-unknown-linux-gnu-
KSRC := /media/DATA-2/android-x86/ics-x86_20120130/out/target/product/generic_x86/obj/kernel
MODULE_NAME :=wlan
endif

ifeq ($(CONFIG_PLATFORM_ARM_BCM2708), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE := arm-unknown-linux-gnueabi-
KVER  := 3.2.27
KSRC ?= <BUILDROOT_PATH>/output/build/linux-rpi-3.2.27
endif

ifeq ($(CONFIG_PLATFORM_ARM_PXA2XX), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE := arm-none-linux-gnueabi-
KVER  := 2.6.34.1
KSRC ?= /usr/src/linux-2.6.34.1
endif

ensuite, il suffit d'entrer la commande make pour compiler notre driver :
# make
[...]
# ls -al
-rw-r--r-- 1 sinseman44 sinseman44 631805 2013-02-24 15:09 8192cu.ko

On transfert ce driver sur notre cible dans le dossier des drivers /lib/modules/3.2.27/kernel/drivers/net/wireless/rtlwifi/rtl8192cu.


Compilation des outils fournis par le driver


Les outils fournis avec le driver sont les suivants :
  • iwconfig : outil similaire à ifconfig mais pour les interfaces réseaux sans fil.
  • iwlist : affiche des informations additionnelles sur les interfaces réseaux. 
  • iwpriv : outil traite les paramètres et attributs privés de chaque pilote.
  • iwspy : outil permettant d'obtenir des statistiques depuis un noeud donné.
  • iwgetid : rapporte l'ESSID ou Le nom du point d'accès d'un réseau sans fil.
  • iwevent : affiche les évènements sans fil

Dans le dossier wireless_tools, on va modifier le makefile pour cross-compiler les outils :
## Installation directory. By default, go in /usr/local.
## Distributions should probably use /, but they probably know better...
ifndef PREFIX
  PREFIX = /usr/local
endif

## Compiler to use (modify this for cross compile).
CC = arm-unknown-linux-gnueabi-gcc
## Other tools you need to modify for cross compile (static lib only).
AR = arm-unknown-linux-gnueabi-ar
RANLIB = arm-unknown-linux-gnueabi-ranlib

## Uncomment this to build tools using static version of the library.
## Mostly useful for embedded platforms without ldd, or to create
## a local version (non-root).
## Standard distros should comment that option to save space and to
## build libiw.so used by third parties...
BUILD_STATIC = y

On compile les outils à l'aide de la commande make et on les transfère sur la cible dans le dossier /usr/sbin :
# make

Test du driver compilé


On va dans un premier temps retirer le driver rtl8192cu.ko du noyau linux 3.2.27 pour qu'il ne soit pas chargé par notre système puis dans un deuxième temps, charger notre nouveau driver 8192cu.ko :
# cd /lib/modules/3.2.27/kernel/drivers/net/wireless/rtlwifi/rtl8192cu
# rmmod rtl8192cu.ko
# mv rtl8192cu.ko rtl8192cu.ko.origin
# insmod 8192cu.ko

Voici les nouveaux drivers chargés par le système :
# lsmod
Module                  Size  Used by
ipv6                  237083  14
8192cu                537834  0
rtl8192c_common        53692  0
rtlwifi                64628  0
mac80211              203510  2 rtlwifi,rtl8192c_common
cfg80211              143188  2 mac80211,rtlwifi
spidev                  4274  0
spi_bcm2708             3969  0
i2c_bcm2708             3019  0

Grâce à l'outil iwconfig, l'interface sans fil wlan0 apparaît :

# iwconfig
lo        no wireless extensions.

wlan0     unassociated  Nickname:""
          Mode:Auto  Frequency=2.412 GHz  Access Point: Not-Associated
          Sensitivity:0/0
          Retry:off   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality:0  Signal level:0  Noise level:0
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

eth0      no wireless extensions.

On lance ensuite l'outil wpa_supplicant avec les bons paramètres :
/usr/sbin/wpa_supplicant -B -Dwext -c /etc/wpa.conf -iwlan0

L'interface réseau wlan0 apparaît dans la liste, mais sans adresse IP configurée et la LED bleue du dongle s'allume et clignote :
# ifconfig
eth0      Link encap:Ethernet  HWaddr B8:27:EB:XX:XX:XX
          inet addr:192.168.1.10  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::ba27:ebff:fe91:ec1c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1187 errors:0 dropped:1 overruns:0 frame:0
          TX packets:2513 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:149219 (145.7 KiB)  TX bytes:386962 (377.8 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

wlan0     Link encap:Ethernet  HWaddr C8:BE:19:XX:XX:XX
          inet6 addr: fe80::cabe:19ff:fe86:be51/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3631 errors:0 dropped:3683 overruns:0 frame:0
          TX packets:323 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:633128 (618.2 KiB)  TX bytes:29376 (28.6 KiB)

L'outil iwconfig permet de vérifier que le dongle est bien associé au routeur wifi :

# iwconfig
lo        no wireless extensions.

wlan0     IEEE 802.11bgn  ESSID:"ma freebox"  Nickname:""
          Mode:Managed  Frequency:2.432 GHz  Access Point: F4:CA:E5:XX:XX:XX
          Bit Rate:150 Mb/s   Sensitivity:0/0
          Retry:off   RTS thr:off   Fragment thr:off
          Encryption key:****-****-****-****-****-****-****-****   Security mode:open
          Power Management:off
          Link Quality=100/100  Signal level=100/100  Noise level=0/100
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

eth0      no wireless extensions.

On va faire une requête DHCP pour récupérer l'adresse IP :
# dhclient wlan0 -v
Internet Systems Consortium DHCP Client 4.1-ESV-R6
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wlan0/c8:be:19:86:be:51
Sending on   LPF/wlan0/c8:be:19:86:be:51
Sending on   Socket/fallback
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 7
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
DHCPOFFER from 192.168.1.254
DHCPACK from 192.168.1.254
bound to 192.168.1.32 -- renewal in 17679 seconds.

et finalement configurer l'adresse IP de notre interface wlan0 :
# ifconfig wlan0 192.168.1.32 netmask 255.255.255.0

On peut maintenant pinger cette nouvelle interface sans fil.

Script de démarrage


Une fois le dongle testé et fonctionnel, on peut créer un script de démarrage pour automatiser les tâches. Dans le dossier, sur la cible, /etc/init.d/, nous allons créer le script S39wifi :

#!/bin/sh
#
# Start the wifi....
#

VENDOR_ID="2001"
PRODUCT_ID="3308"
INTERFACE="wlan0"
result_lsusb=""

case "$1" in
  start)
        result_lsusb=`lsusb -d "${VENDOR_ID}":"${PRODUCT_ID}"`
        if [ "${result_lsusb}" != "" ]; then
                insmod /lib/modules/3.2.27/kernel/drivers/net/wireless/rtlwifi/rtl8192cu/8192cu.ko
                /usr/sbin/wpa_supplicant -B -Dwext -c /etc/wpa.conf -i"${INTERFACE}"
        fi
        ;;
  stop)
        ;;
  restart|reload)
        "$0" stop
        "$0" start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit $?

Il suffit de redémarrer la raspberry pi pour que le dongle wifi soit automatiquement configuré et fonctionnel avec son adresse IP.

6 commentaires:

  1. Il faut utiliser un hub usb pour le connecter? ou on peut le connecter directement à la rpi?

    RépondreSupprimer
    Réponses
    1. J'ai fait tous les tests directement sur le port USB de la raspberry pi.

      Supprimer
    2. merci ! je vais le tester maintenant !

      Supprimer
  2. Pour info, pour le dongle wifi DWA-131 (donc pas le 121) et Raspberry Pi sur une distro 2013-02-09-wheezy-raspbian.img (ISO Raspi officiel), c'est beaucoup beaucoup plus simple : http://goo.gl/zGCF6

    RépondreSupprimer
  3. Hello,

    Je suis sous raspbian et lors que je fait make menuconfig j'ai l'erreur :

    make: *** No rule to make target 'menuconfig'. Stop.

    RépondreSupprimer