You are on page 1of 100

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.

fr) - 10 décembre 2012 à 16:20

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) - 10 décembre 2012 à 16:20

SOMMAIRE
LABO

N°153

ÉDITORIAL
Pourquoi moi je dis GNU/Linux ? « Linux » ou « GNU/Linux » est un troll^Wsujet récurrent dans notre petit monde. Il est vrai que c’est toujours l’occasion de commenter, critiquer, argumenter, ... sur différentes bases philosophiques, linguistiques, sociales, ... Il y a cependant des cas où le sujet est abordé de manière si naïve et maladroite que l’initiateur ne fait que démontrer son manque de connaissances sur le sujet, avec des affirmations comme « [...] pour certains, Ubuntu et Linux sont deux choses différentes. » (récent billet d’un « geek accompli » sur CNET). C’est un sujet sensible, alors je ne vous dirai pas comment appeler le système que vous utilisez. Je vous dirai simplement pourquoi moi je l’appel GNU/Linux. Pour cela, j’ai ramené la question à sa forme la plus simple et sa base de réflexion la plus tangible. Tout ce qui est sentimental, idéologique, émotionnel et philosophique est donc temporairement mis de côté (ça aide, vous n’imaginez pas). On se retrouve ainsi avec des faits, un système composé d’un noyau, historiquement appelé Linux par son créateur, et d’une myriade d’autres éléments. Parmi ces éléments, un très grand nombre proviennent du projet GNU, donc la Libc, Bash, GCC, les binutils, GDB, GRUB pour les plus « gros », mais aussi gzip, find, grep, tar, les autotools, Emacs, Parted, Mailman, GNUPG, ... Sans oublier les langages et implémentations Awk, Lisp, Smalltalk, Eiffel, R, Octave, ... Et je ne parle même pas de toutes les bibliothèques ! La masse de code est ÉNORME, tout comme le travail qui en est la source, ce qui pour moi justifie seul l’utilisation des trois lettres de GNU dans le nom du système. Il y a d’autres gros morceaux dans GNU/Linux, comme Xorg, mais c’est sans commune mesure avec GNU. Voilà ! Ça s’arrête là et j’essaie de faire attention à ne pas oublier GNU dans GNU/Linux, afin d’afficher le respect que j’estime devoir témoigner à ces développeurs pour le travail titanesque qu’ils ont fait pour moi. J’essaie également, le plus souvent possible, de citer les auteurs des outils que je mentionne, ou encore de dire Vim et non Vi quand je parle de mon éditeur. Bien sûr, dans une conversation, quelques « Linux » fuseront, car le raccourci est facile et tellement courant. Des raccourcis, tout le monde en fait, comme « frigo » (réduction de Frigidaire) pour réfrigérateur, Kleenex pour mouchoir, Sopalin pour essuie-tout, ... Il est difficile de faire preuve de précision de manière constante, surtout à l’oral, même si parfois c’est très amusant de signifier à quelqu’un que non, son fruit préféré ne peut pas être la fraise ou qu’il ne mange jamais de fruits du pommier mais au contraire les jette systématiquement. Moi, j’aime signifier ce respect et cette reconnaissance en utilisant « GNU/Linux », d’autres préfèrent autre chose, ou encore utilisent aussi cette désignation, mais pour d’autres raisons.

04 La réception radiofréquence définie par logiciel (Software Defined Radio – SDR)

En COUVeRTURe Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) - 10 décembre 2012 à 16:20
34

Systemd vainqueur de Upstart et des scripts « System V » ?
Après plus de 30 ans de service (!), le vénérable processus init et ses scripts de service disparaissent petit à petit des systèmes Unix et de nos distributions Linux préférées. Si la technologie « Upstart » est connue des adeptes d'Ubuntu, quel sera le remplaçant sur RedHat, Debian et les autres ? systemd très probablement... L'objectif de cet article est de vous préparer à la migration vers cette nouvelle technologie.

SYSADMIN
43 à la découverte de Samba 4 50 Sauvegarde et clonage à chaud de vos machines avec MondoRescue

NeTADmIn
58 Testez vos applications web avec JMeter

MObILITÉ
64 À la découverte d'Android : Le système graphique

CODe(S)
75 PHP5 : la magie continue 80 01:59:60 : Une seconde SVP ! 84 C++ 11 et GCC

AbOnnemenTS
41/73/74 Bons d'abonnement et de commande
Responsable publicité : Valérie Fréchard, Tél. : 03 67 10 00 27 v.frechard@ed-diamond.com Service abonnement : Tél. : 03 67 10 00 20 Impression : VPM Druck Rastatt / Allemagne

GNU/Linux Magazine France est édité par Les Éditions Diamond

Distribution France : (uniquement pour les dépositaires de presse) B.P. 20142 – 67603 Sélestat Cedex Tél. : 03 67 10 00 20 – Fax : 03 67 10 00 21 E-mail : lecteurs@gnulinuxmag.com Service commercial : abo@gnulinuxmag.com Sites :  www.gnulinuxmag.com www.ed-diamond.com Directeur de publication : Arnaud Metzler Rédacteur en chef : Denis Bodor Secrétaire de rédaction : Véronique Sittler Réalisation graphique : Kathrin Scali MLP Réassort : Plate-forme de Saint-Barthélemy-d’Anjou. Tél. : 02 41 27 53 12 Plate-forme de Saint-Quentin-Fallavier. Tél. : 04 74 82 63 04 Service des ventes : Distri-médias : Tél. : 05 34 52 34 01 Imprimé en Allemagne - PRINTED in Germany Dépôt légal : À parution, N° ISSN : 1291-78 34 Commission paritaire : K78 976 Périodicité : Mensuel Prix de vente : 7,50 €

La rédaction n’est pas responsable des textes, illustrations et photos qui lui sont communiqués par leurs auteurs. La reproduction totale ou partielle des articles publiés dans GNU/Linux Magazine France est interdite sans accord écrit de la société Les éditions Diamond. Sauf accord particulier, les manuscrits, photos et dessins adressés à GNU/Linux Magazine France, publiés ou non, ne sont ni rendus, ni renvoyés. Les indications de prix et d’adresses figurant dans les pages rédactionnelles sont données à titre d’information, sans aucun but publicitaire. Toutes les marques citées dans ce numéro sont déposées par leur propriétaire respectif. Tous les logos représentés dans le magazine sont la propriété de leur ayant droit respectif.

GNU/Linux Magazine France N ° 1 5 3

3

Nous verrons comment. le traitement logiciel d’informations transmises sans fil se 1  ttp://www.gnulinuxm a g . Nous nous intéresserons en particulier au packet.Software Defined Radio (SDR) .baycom. Le flux de données brut issu du récepteur radio est traité par des blocs implémentant les fonctionnalités les plus classiques dans le logiciel gnuradio et son interface graphique gnuradiocompanion.dont l’étage de réception s’avère tellement simple qu’il est compatible avec de nombreux modes de transmission analogique et numérique de données par liaison radiofréquence. implémenter nos propres algorithmes de décodage sur le flux d’informations reçu du récepteur radiofréquence.fr) .10 décembre 2012 à 16:20 La réception radiofréquence définie par logiciel (Software Defined Radio – SDR) par J. des outils plus récents étant probablement disponibles aujourd’hui sous GNU/Linux) ou la réception d’images satellites que nous avions déjà présentée dans ces pages [5].LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. 3. Goavec-Mérou La diffusion à large échelle de la communication radiofréquence dans les appareils grand public induit la disponibilité de composants aux performances compatibles avec ces modes de communication (fonctionnement de 50 à 2500 MHz ou plus. il a été classiquement nécessaire de traiter un maximum d’informations par du matériel dédié.-M Friedt & G.DVB basé sur le composant Elonics E4000 . Mentionnons parmi ces exemples les habituels récepteurs radiofréquences FM et AM qui ne font appel à aucun logiciel. 1 Introduction à la radio définie par logiciel (SDR) La radio définie par logiciel . Classiquement. pour ne finalement qu’éventuellement traiter par logiciel le flux d’informations résultant.org/~tom/ham/linux/multimon. généralement dans les fréquences audibles (<100 kHz). aux récepteurs amateurs de mode numérique basés sur un modem audiofréquences (packet1). c o m . au delà de la simple utilisation des blocs de traitement disponibles. et aux radiomodems encodant l’information en FSK et AFSK. 2.html décode un certain nombre de modes numériques à partir des signaux sonores issus d’un récepteur radio et numérisés h par carte son 4 G N U / L i n u x M a g azine France N°153 www. Nous allons profiter de cette mode en présentant l’utilisation d’un récepteur de télévision numérique . transmission d’images (SSTV par le vénérable JVFAX sous MS-DOS. bandes passantes de l’ordre de la dizaine de MHz) et pour des prix ridiculement faibles grâce à la production de masse. 4]. au protocole ACARS.est une approche au traitement de données radiofréquences déportant un maximum de traitement sur du logiciel au lieu de dépendre du matériel [1. Compte tenu des fréquences et du débit d’informations mis en jeu lors des transmissions sans fil radiofréquences.

10 décembre 2012 à 16:20 .Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) .

Finalement. donc une centaine de kHz. nous nous attellerons ensuite à la tâche de traiter un flux de données inconnu. Bien que de coût raisonnable en comparaison des systèmes professionnels proposés. Les faibles volumes de production induisent un coût de l’ordre de la centaine d’euros. gnuradio-companion3.joshknows. Ce point est utile à mentionner car tous les outils faisant gnuradio. Récemment. la composante somme des fréquences étant éliminée par un filtre passe-bas. sensibilité). En particulier.la carte son équipant pratiquement tous les ordinateurs personnels depuis une dizaine d’années et la puissance de calcul requise qui n’est pas négligeable. autre que pour un aspect ludique. notamment par Analog Devices.ettus. pour un dispositif à la sensibilité acceptable pour de la réception de sources en orbite terrestre (satellites).reste matériel. Ce composant se limite en effet à amplifier le signal radiofréquence reçu par une antenne. le Elonics E4000 (récepteur radiofréquence direct . qui fournit un certain nombre de blocs de traitement de base qui permettent de rapidement appréhender le problème. Cependant. l’investissement de l’ordre du millier d’euros reste néanmoins cantonné à l’amateur motivé qui a besoin des performances de tels dispositifs dédiés (bande passante importante. et d’autre part le flux de données émis par les avions suivant le protocole ACARS.LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.com/ nous avions déjà exposé dans ces pages le principe du mélangeur qui transpose une fréquence incidente f et une fréquence de référence f0 pour générer f+/. le mélanger avec un oscillateur local pour transposer la fréquence5 suivi de filtres passe-bas pour ne conserver que la composante basse-fréquence. et ce en vue d’en interpréter les informations par traitement logiciel de l’information ? 2 3 4 Dans ce but. http://tetra. un environnement logiciel sympathique est gnuradio2. mais avec une bande passante réduite aux performances d’une carte son. La limitation sur les interfaces d’acquisitions a en partie changé avec l’avènement des cartes d’acquisition vidéo : capables d’échantillonner plusieurs millions de mesures par seconde. par un traitement en temps réel sous forme de bloc compatible avec gnuradio-companion. avant d’exploiter directement quelques blocs de traitement du signal disponibles sous gnuradio en s’appuyant pour la construction des applications sur son interface graphique. alors que les USRP ont pu voir le jour grâce à la chute vertigineuse des coûts de composants radiofréquences développés notamment pour les applications de communication numérique sans fil (synthétiseurs de fréquence. Maxim ou Semtech).funcubedongle. la disponibilité d’une puissance de calcul surdimensionnée est la seule garantie d’un traitement sans pertes d’informations.com/grc http://www. Ce signal analogique doit ensuite être numérisé pour traitement par un ordinateur personnel. l’étage le plus amont de traitement de l’information radiofréquence .fonctionnant de 64 à 1700 MHz) a été la source d’une explosion de circuits à très faible coût pour la SDR. référence à uhd nous seront inutiles dans la suite de cette discussion. Un premier projet exploite un convertisseur analogiquenumérique de carte audio : Funcube6. et surtout pas GNU/Linux dans sa version de base.com/ 5 6 6 G N U / L i n u x M a g azine France N°153 www. Ce composant analogique fournit donc les composantes I et Q (identité et en quadrature) sur une bande passante allant jusqu’à 8 MHz. même pour traiter un flux de données aussi « lent » que 100 kHz. cette tendance s’accélère aujourd’hui avec l’avènement de circuits compacts regroupant tous les éléments radiofréquences analogiques (front end) habituellement séparés en éléments discrets. le débit du traitement de l’information est imposé par le flux entrant. En effet. un récepteur de télévision numérique terrestre sous forme de clé USB a induit une explosion d’activité dans le domaine de la SDR libre lorsqu’il s’est avéré que le flux de données fourni au logiciel de décodage vidéo était généraliste (nous développerons plus loin le flux de données I/Q fourni par cette interface matérielle) : pourquoi donc se limiter aux bandes de télévision et ne pas sonder n’importe quelle bande de fréquence accessible par l’étage radiofréquence.org/trac/wiki/Funcube_Dongle et http://www. La séquence d’analyse que nous proposons commence par une brève présentation du matériel utilisé.f 0.org http://www. à savoir le flux de données issu d’un radiomodem d’une part. le flux de données devient compatible avec l’analyse par logiciel d’une bande de fréquences de plusieurs MHz de large. un nouveau composant. L’utilisation de blocs existants n’étant d’à peu près aucun intérêt technique pour le développeur.fr) .10 décembre 2012 à 16:20 cantonne aux fréquences audio du fait de la disponibilité d’une carte d’acquisition largement disponible .sans exploitation d’une fréquence intermédiaire .amplificateur et transposition vers une fréquence acceptable par un convertisseur analogique-numérique .osmocom. Les USRP sont supportées dans gnuradio au travers des pilotes gr-uhd (UHD signifiant USRP Hardware Driver). et toute interruption (par exemple pour gérer une autre tâche dévolue au système d’exploitation) se traduit par une perte irrémédiable de données. nous verrons comment remplacer le post-traitement des informations acquises pour en extraire les données numériques. le développement de SDR sur plateforme libre s’est organisé autour des systèmes USRP (Universal Software Radio Peripheral) développés par Ettus Research4. 2 Présentation du matériel Historiquement. modulateur et démodulateur I/Q sur des bandes allant de quelques MHz aux GHz. Aucun des systèmes d’exploitation grand public n’ayant de prétention de latence bornée (temps réel). En effet.gnulinuxm a g . c o m .

osmocom.uk/product.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. est issu de OsmoSDR et décrit à http://sdr. Afin de bien maîtriser la distinction entre les fonctions du composant analogique E4000 et du convertisseur analogique-numérique suivi de communication numérique RTL2832U.fr) . sauf uhd. Ainsi.com GNU/Linux Magazine France N° 1 5 3 7 .modems inutilisables dans un environnement libre en l’absence des pilotes appropriés9) et que ce flux de données I/Q serait approprié pour des applications bien plus intéressantes que la visualisation d’émissions de télévision. qui avaient engagé cette tendance de réduction du matériel en transposant le décodage au logiciel . nous pouvons prendre en main une clé USB de réception de télévision numérique terrestre EZCAP. modules Python) que nous finirons par atteindre l’objectif de compiler tous les modules. Le projet exploitant le convertisseur analogique-numérique embarqué sur ces clés. Le premier constat est que le connecteur de type antenne de télévision 75 ohm est à peu près inexploitable avec des antennes de radioamateur ou même pour nos propres expérimentations d’antennes dédiées à diverses bandes de fréquences.org https://har2009. l’appât du gain n’a pas de limites).1 Installation des outils gnuradio L’environnement gnuradio est dynamique et en particulier les outils autour des clés USB pour réception de télévision numérique changent rapidement. mais dont les volumes de production induisent des coûts d’achat imbattables. le Realtek RTL2832U.dealextreme. avec la participation de développeurs aussi célèbres que Harald Welte8. Il est donc de bon ton de recompiler ses outils depuis les dernières versions des sources. l’inclusion ou l’exclusion de morceaux de gnuradio est induite par une recherche des bibliothèques disponibles. En effet. 2. une première compilation se traduit par l’exclusion d’à peu près toutes les fonctionnalités de gnuradio.org/files/build-gnuradio.org/trac/wiki/rtl-sdr.wikipedia. qui ne sera pas nécessaire. donc nous commençons par le remplacer par une embase BNC. 2. En particulier.org/wiki/Softmodem w w w.10 décembre 2012 à 16:20 Afin de pallier cette carence sur la bande passante. et ce n’est qu’en installant petit à petit les bibliothèques nécessaires (libfftw3-dev. disponible à http://www.html http://en.co. Il est donc désormais possible de se lancer dans le domaine fantastique de la SDR pour un investissement matériel inférieur à 20 euros : nous avons pour notre part expérimenté avec des clés EZCAP (DVB-T/DAB/FM) telles que (par exemple) disponibles à http:// www.en. il est fondamental de compiler la partie gnuradio-companion. un projet introduisant un FPGA pour accélérer la fréquence d’échantillonnage a été engagé sous le nom de OsmoSDR7.org/program/speakers/253. Ce processus a été automatisé dans un script fort utile. une interface graphique pour accéder aux modules de traitement du signal. dont nous ferons intensivement usage dans la suite de ce document. aussi nommés winmodems.php?id_ product=104 pour les sources que nous avons testées (pourquoi un vendeur de plantes prétendues thérapeutiques vend des récepteurs de télévision ? Mystère.cosycave. le portage à V4L de ces clés USB de réception de télévision a fait apparaître que tout le décodage du flux de données se fait de façon logicielle (un triste rappel des modems d’il y a une quinzaine d’années. g n u l i n u x m a g. Les développements logiciels autour de ce projet ont finalement profité de la commercialisation de récepteurs de télévision numérique terrestre de qualité médiocre. nous allons injecter un signal sinusoïdal sur ce qui apparaît à l’évidence sur la carte électronique comme les signaux balancés Figure 1 : Utilisation d’un récepteur de télévision numérique terrestre comme oscilloscope avec une bande passante de plus de 2 MHz. Il est cependant significatif de réaliser un aspect quelque peu surprenant de la compilation de gnuradio : au lieu d’imposer les dépendances nécessaires à un ensemble de fonctionnalités. garantie de sérieux du projet.osmocom.sbrac.com/p/mini-dvb-tdigital-tv-usb-2-0-dongle-with-fm-dabremote-controller-92096 ou https:// www. 7 8 9 sdr.2 Utilisation en oscilloscope du RTL2832U Ayant installé les outils gnuradio et en particulier gnuradio-companion.

mais de dynamique réduite. puisque 10log10(50)/6≃3 soit un total de 11 bits sur le convertisseur équivalent fonctionnant à la même fréquence que la carte son. Dans le cas particulier de l’ADS-B qui occupe une bande de fréquences autour de 1090 MHz.e.de câble coaxial RG58 muni à une extrémité d’une fiche BNC (Fig. Cependant. 108 à 137 MHz pour la bande aérienne. l’écart type sur ces mesures (supposées poluées par un bruit uniforme) décroît comme √N.720 Hz pour que l’échantillonnage fasse exactement 10 points/période à 2 MS/s (en l’absence de déclenchement sur un front. à une fréquence de 200 kHz et échantillonné à 2 MS/s (10 points/période). un résultat impressionnant compte tenu de la simplicité du montage n’exploitant qu’un quartz de qualité commerciale pour cadencer l’électronique numérique.88 à 108 MHz pour la FM commerciale. I+ et I.LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. l’antenne se doit d’être démontable et tenir dans un sac à dos. En effet. Ce faisant. il est bien connu [6] qu’en appliquant une moyenne glissante sur N points acquis. 10log10(fse/fe)=10log10(4)*p soit. Le pré-amplificateur faible bruit (LNA) est alimenté en 5 V par un second port USB. Un étage de préamplification capable de s’adapter à la puissance radiofréquence reçue est donc souhaitable (ajustement automatique par le E4000 ou de façon logicielle en ajustant manuellement le gain de ce composant).10 décembre 2012 à 16:20 des composantes I et Q (i. ce chiffre ne doit pas cacher la dynamique médiocre du convertisseur analogique-numérique de ce composant qui ne code l’information que sur 8 bits. Ainsi. Pour ce faire.et nous exploiterons donc dans tous ces cas une antenne dipôle ajustée pour 137 MHz. en notant que 10log10(4)≃6.gnulinuxm a g . en passant en échelle logarithmique. 154 MHz pour le packet radio . une carte son sera plus efficace pour échantillonner des signaux avec une dynamique accrue. Le sur-échantillonnage d’un facteur 50 ne compense pas la médiocrité de la résolution des convertisseurs par rapport à ceux d’une carte son.fr) . L’horloge interne au convertisseur EZCAP et le quartz cadençant le synthétiseur de fréquence sont synchronisés à mieux que 2 parties par million (2 ppm) puisque nous avons dû programmer la fréquence de 199999. nous retrouvons [3] que le gain en résolution en bits p pour un sur-échantillonnage de fse/fe est 1/6*10log10(fse/fe). Ce rapide petit calcul nous incite à nous rappeler que la fréquence d’échantillonnage n’est pas nécessairement la caractéristique principale d’un convertisseur analogique-numérique. 2).l’absence de ce menu indique que la compilation des outils ne s’est pas faite convenablement . Nous constatons sur la Figure 1 que les voies I et Q présentent bien un signal sinusoïdal.5*106/48000≃ 50 sur la fréquence d’échantillonnage en exploitant le RTL2832U comme carte d’acquisition à la place d’une carte son. La référence [6] formalise ce point en notant que pour une fréquence d’échantillonnage fse. nous nous intéresserons à la réception d’images émises par des satellites sur des fréquences autour de 137 MHz. il faut quadrupler la fréquence d’échantillonnage pour diviser par 2 le bruit sur le signal acquis et donc ajouter un bit sur la résolution du convertisseur analogique-numérique. Afin de maintenir la portabilité d’un récepteur radiofréquence se branchant sur port USB. bien que le gain d’un tel montage reste à démontrer. Nous avons mentionné un gain d’un facteur de l’ordre de 2.55 avec 300 m/µs la célérité d’une onde électromagnétique et 137 la fréquence d’intérêt en MHz) et munis. Ce montage robuste s’assemble facilement sur un support en plastique muni de deux embases 4 mm femelles auxquelles est soudé un bout . 2). ou.aussi court que possible . le gain en résolution (p bits) par application d’une moyenne glissante par rapport aux acquisitions à fréquence fe est 3 Premiers pas : utilisation avec gnuradio-companion Nos essais de réception radiofréquence ont pour ambition de recevoir des signaux plus faibles que les émissions commerciales sur bande FM. nous sommes loin d’atteindre les 16 bits de résolution d’une carte son. Exceptionnellement. annoncée comme fonctionnelle entre 100 et 1500 MHz) (Fig. c o m . 8 G N U / L i n u x M a g azine France N°153 www. Si la bande passante ne se justifie pas.ainsi que Q+ et Q-). une antenne discone large bande a été exploitée (Diamond Antenna D190. et dans ce cas les plus de 2 Méchantillons/s ne se justifient que pour analyser un signal de bande passante importante. de fiches banane de 4 mm de diamètre.et un puits de données sous la forme d’un oscilloscope accessible dans le menu WX GUI Widget (bloc WX GUI Scope Sink). En particulier. nous générons le graphique de traitement du signal gnuradio le plus simple possible : une source de données sous la forme du bloc OsmoSDR Source (accessible dans le menu des fonctions OsmoSDR à droite de gnuradio-companion) . nous ajouterons un amplificateur faible bruit Hittite HMC478 (alimentation en 5 V. facteur de bruit 2 dB) entre l’antenne et le récepteur EZCAP. cette condition s’observe visuellement sur la sortie oscilloscope de gnuradio lorsque la sinusoïde arrête de se déplacer horizontalement à une vitesse égale à l’inverse de la différence des fréquences). en accord avec la forme du signal injecté. Dans tous les cas. Tous ces traitements se font sur un eeePC701 et ne nécessitent donc pas des ressources énormes en termes de puissance de calcul ou de mémoire. à chaque extrémité. un tube de cuivre creux de 8 mm de diamètre est coupé en deux morceaux de 55 cm de longueur (300/137/4 ≃ 0. Il s’avère que la majorité des fréquences qui vont nous intéresser dans ce document se situent autour de cette valeur . Une dynamique de 20*log10(28)=48 dB est médiocre compte tenu de la dynamique des signaux radiofréquences acquis qui atteint souvent 60 dB.

com GNU/Linux Magazine France N° 1 5 3 9 . Le lecteur est encouragé à changer les fréquences d’échantillonnage ou facteurs de décimations sur un tel graphique pour appréhender l’effet d’erreurs sur ces valeurs. l’emplacement sélectionné doit être aussi libre que possible d’obstacles. Le spectre. Le filtre passe bas effectue quant à lui une décimation d’un facteur 6.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Ici. La source OsmoSDR étant directement connectée au filtre passebas.e. Ainsi. apparemment. si nous partons de la fin de la chaîne de traitement (le puits qu’est la carte son du PC). nature du programme transmis.138]. ni faire attendre un bloc qui n’aura plus rien à faire. p. 108-137 MHz). On notera qu’une limitation de la source OsmoSDR est de ne pas pouvoir descendre sous quelques centaines de kHz de fréquence d’échantillonnage : on conservera donc habituellement une source échantillonnant entre 1 et 2. 3.1 La bande FM commerciale Le test le plus simple car permettant de recevoir un signal émis en continu avec une forte puissance est la bande FM commerciale. et sinon une antenne discone large bande. Cette bande de fréquences est qualifiée de large bande ( Wide FM) du fait de l’encombrement spectral important occupé par chaque station (180 kHz). faute de quoi la compilation échoue après avoir occupé toute la mémoire disponible. un balcon au 3ème étage d’un bâtiment orienté vers l’Est est acceptable pour la réception FM et d’avions. de données le long de la chaîne de traitement. Cet exemple est intéressant car il illustre 10 https://cgran. éventuellement information de trafic. présente une extension de -fe/2 à fe/2 avec fe=1152 kHz la fréquence d’échantillonnage : nous y trouvons évidemment un pic autour de la fréquence de la chaîne radio écoutée (100. sa fréquence d’échantillonnage est elle aussi sélectionnée à 1152 kS/s. rester en -O0).e. qui est bien la valeur que nous observons dans le sampling rate de ce bloc. Une extension proposée dans le cadre de gnuradio-companion est le décodage de l’information RDS (Radio Data System)10 qui fournit une information sous forme numérique sur la station écoutée (nom de la station.5 MS/s. pour un dysfonctionnement de l’option -fvar-tracking-assignement des versions récentes de GCC. nous devons fournir un flux continu de données à la fréquence d’échantillonnage choisie à 48 kHz. source OsmoSDR (comme utilisée auparavant pour l’exemple de l’oscilloscope). donc le flux de données en entrée de ce bloc doit être 4*48=192 kHz. Aussi importante que la nature de l’antenne.. Ce test fera office de validation du bon fonctionnement de l’installation : interface graphique gnuradio-companion. sort 4 fois moins de données qu’il en reçoit). nous avons été obligés de désactiver les options -g -O2 de la compilation (i. Les canaux alloués aux radios sont donc séparés d’environ 200 kHz [9. démodulation par le bloc WFM et puits de données sous forme de la carte son d’une part (après démodulation) et analyse du spectre acquis (avant démodulation) pour identifier la fréquence d’émission des stations d’autre part. Cet exemple fournit l’opportunité d’introduire une première contrainte sur l’assemblage des blocs de traitement : il nous faut garantir la continuité du flux Figure 3 : Exemple de chaînes de traitement pour le décodage de la bande FM commerciale (88-108 MHz) ou la bande d’aviation où les communications se font en AM (au-dessus de la bande FM commerciale. Le mode de démodulation FM étroite n’a pas fourni de résultat significativement différent du démodulateur WFM. . w w w. et donc ne pas fournir trop de données à un bloc qui ne peut tout traiter. qui n’interfère néanmoins pas avec la démodulation grâce au filtre passe-bas situé après l’analyseur de spectres. quitte à décimer par un filtre passe-bas si la suite des étapes ne nécessitent que des traitements sur des bandes passantes réduites. Nous constatons que le bloc de démodulation FM large bande (WFM) effectue une décimation d’un facteur 4 (i.).org/wiki/RDS : noter que. en bas à droite.10 décembre 2012 à 16:20 Figure 2 : Deux montages d’antennes exploités avec le récepteur EZCAP : une antenne dipôle facilement démontable pour les bandes de fréquences autour de 137 MHz. donc nécessite un flux en entrée de 192*6=1152 kHz.fr) .4 MHz) ainsi qu’un pic autour de la fréquence adjacente (100. mais est inclus pour illustrer la décimation en sortie de ce démodulateur par une fonction qui ne garde que 1 échantillon sur 4 (et donc fournit le flux de données au débit approprié à la carte son).9 MHz). fréquences correspondantes aux alentours.. dans l’exemple de la Figure 3. du signal acquis. g n u l i n u x m a g. mais insuffisamment dégagé pour la réception d’images issues de satellites. entre 88 et 108 MHz.

LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.3 Satellites Deux essais sur les satellites en orbite basse polaire de la NOAA11 et sur la station spatiale internationale (ISS) se sont révélés sans succès.org/ wiki/gr-air-modes et décrit en détail dans les transparents [10]. program:25) ==> VIRL N <== -TP.PTY:None (country:EG/FR/NO/BY/BA. area:Regional 9.PTY:None (country:EG/FR/NO/BY/BA. program:25) ==> IRL N <== -TP.AF:99.PTY:None (country:EG/ FR/NO/BY/BA. tel que par exemple disponible à http://www.org/redmine/projects/gnuradio/wiki/OutOfTreeModules 10 G N U / L i n u x M a g azine France N°153 www.-Music-STEREO .PTY:None (country:EG/FR/NO/BY/BA. Foster pour gnuradio inclut une sortie au format KML compatible avec Google Earth et Google Maps (Fig. probablement par manque de sensibilité du récepteur. program:17) ==> RTL <== -TP. program:17) @@@@@ Lost Sync (Got 46 bad blocks on 50 total) @@@@@ Sync State Detected @@@@@ Lost Sync (Got 46 bad blocks on 50 total) @@@@@ Sync State Detected 00A (BASIC) . program:103) Radio Text A: RADIO STAR TOUS LES HITS BESANCON 106. program:17) ==> RTL <== -TP.PTY:None (country:EG/FR/NO/BY/BA.10 décembre 2012 à 16:20 la souplesse du décodage d’informations transmises sur porteuse radiofréquence par logiciel.00MHz.90MHz 00A (BASIC) .PTY:None (country:EG/FR/NO/BY/BA. et d’autre part en un flux de données numériques.AF:102.org http://gnuradio.40MHz 00A (BASIC) .80MHz 00A (BASIC) . sans que le matériel n’ait été modifié (Fig.20MHz.60MHz.40MHz.PI:FC67 .6 GRAY 100.20MHz.PI:F211 .80MHz.oz9aec. 97.-Music-STEREO .60MHz.-Music-STEREO .PTY:None (country:EG/FR/NO/BY/BA. ADS-B fournit une information complémentaire à l’analyse purement passive de réflexion de l’onde électromagnétique par l’avion : au lieu de se contenter du temps de vol et orientation de l’antenne au moment de l’émission de l’impulsion électromagnétique.70MHz. Ce protocole a été implémenté sous forme de script généré par gnuradio.-Music-STEREO .PI:F211 . En effet.AF:100. disponible à https://www.PTY:None (country:EG/ FR/NO/BY/BA. program:33) Clocktime: 10.PI:F211 . area:National. Ci-dessous.AF:95.PI:F219 .08.80MHz 00A (BASIC) .2 ADS-B ADS-B (Automatic Dependent Surveillance-Broadcast) est un protocole numérique de communication entre un avion et le sol initié sur une requête provenant d’un RADAR qui sollicite une information de position d’un aéronef supposé être équipé d’un récepteur GPS.AF:100.PI:FC67 .-Music-STEREO .AF:99.PI:FC67 . 5).PTY:None (country:EG/FR/NO/BY/BA. un récepteur (nous) ne peut entendre que la réponse de l’avion à la sollicitation : cette réponse se fait à la fréquence de 1090 MHz. radarvirtuel. area:National. area:National.PI:F211 .PI:F221 .cgran. 87.AF:97.PTY:None (country:EG/FR/NO/BY/BA. program:103) ==> GRAY <== -TP.50MHz 00A (BASIC) .AF: 00A (BASIC) .PTY:None (country:EG/FR/NO/BY/BA. en asservissant une boucle verrouillée en phase (PLL) sur la sortie filtrée en passe-bas du récepteur radio. la position de l’avion est complétée par sa localisation GPS. program:17) ==> RTL <== -TP. program:25) ==> IRL <== -TP.php/gnu-radio/gnu-radio-blog/477-noaa-apt-reception-with-gqrx-and-rtlsdr https://cgran. notons que l’auteur a recréé un récepteur FM comme nous le ferions à base de composants électroniques analogiques.PTY:None (country:EG/FR/NO/BY/BA.com/. area:National. area:Regional 9. program:17) ==> RTL <== -TP.-Music-STEREO .-Music-STEREO . program:17) ==> RTL <== -TP. program:103) ==> GRAY <== -TP.PI:F219 . area:National. Ainsi.PTY:None (country:EG/FR/NO/BY/BA. 101. La mise en commun des informations acquises par de tels récepteurs d’ADS-B permet de cartographier la position des avions dans le monde de façon indépendante des contrôleurs aériens. 93. 99.gnulinuxm a g .PI:F221 . http://rof. area:National. area:National. area:Regional 9.AF:92.-Music-STEREO .li/pic/groundplane/ http://www. 98.AF:97.40MHz @@@@@ Lost Sync (Got 47 bad blocks on 50 total) @@@@@ Sync State Detected @@@@@ Lost Sync (Got 49 bad blocks on 50 total) @@@@@ Sync State Detected 00A (BASIC) . 99. 00A (BASIC) . Le logiciel proposé par N.PI:F211 . area:National. 17:27 (+2.fr) .-Music-STEREO .AF:104.net/index. 103. 4). c o m .AF:101.-Music-STEREO . au lieu d’utiliser le bloc de démodulation prêt à l’emploi de gnuradio-companion. area:National. area:National.-Music-STEREO .PI:F219 . program:17) ==> RTL <== -TP. Les trames que nous avons sélectionnées illustrent d’une part les champs de type AF (alternative frequencies) grâce auxquels un récepteur radio sait comment rechercher un nouveau canal pour le même programme radiophonique une fois la liaison courante trop faible.PI:F219 .AF:100.PTY:None (country:EG/FR/NO/BY/BA. quelques exemples de captures des signaux numériques transmis dans la bande FM commerciale à côté des signaux analogiques radiofréquences audibles.-Music-STEREO .10MHz 02A (RT) .AF: 00A (BASIC) . program:17) ==> RTL <== -TP. program:33) Radio Text A: Mozart : Concerto pour piano n 14:1er mvt 3.PTY:None (country:EG/FR/NO/BY/BA. et d’autre part le champ RT (radio text) dans lequel un texte libre d’au plus 64 caractères est transmis.00MHz 00A (BASIC) .PTY:None (country:EG/FR/NO/BY/BA.PI:FC67 .2 00A (BASIC) .PI:F211 . le même flux de données est d’une part démodulé en un flux audible.10MHz 00A (BASIC) . Un dernier exemple propose le transfert d’heure (champ CT) par RDS ainsi que l’utilisation du champ de texte libre (RT) pour annoncer le titre en cours de diffusion : 11 12 13 14 3.PI:F211 .0h) 02A (RT) . Depuis le sol. Nous n’avons pas eu l’occasion de tester TA (traffic announcement) qui est probablement une des applications les plus utiles de ce mode de communication numérique sur la bande FM commerciale.80MHz 04A (CT) .50MHz 00A (BASIC) . area:National. program:103) ==> 10AY <== -TP. illustrant quelques-uns des messages transmis sur ce mode de communication. area:National. area:Regional 9. program:25) ==> IRL <== -TP.-Music-STEREO . Les divers filtres passe-bande permettent ensuite de sélectionner la nature de l’information traitée dans les diverses bandes de fréquence audio (son ou RDS).PTY:None (country:EG/FR/NO/BY/BA.20MHz 00A (BASIC) .PTY:None (country:EG/FR/NO/BY/BA. Par ailleurs.PI:F211 . area:National. area:National.-Music-STEREO .2012.

g n u l i n u x m a g. avec une antenne située sur un balcon dégagé vers l’Est uniquement. protocole plus ancien mais plus « intéressant » que l’ADS-B puisque transportant des messages sur l’état de l’aéronef ou des messages de l’équipage vers le sol. les messages qui s’affichent (les même messages s’affichent dans le terminal d’où a été lancé gnuradio-companion). Figure 4 : Haut : capture d’écran du décodeur RDS en fonctionnement.crc.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) . Bas : schéma complet issu de http://mmbtools. Notre véritable intérêt consiste en la maîtrise des méthodes de démodulation en vue d’adapter ces techniques à des méthodes qui ne sont pas encore implémentées. et dans le menu de droite les fonctions RDS qui ont été ajoutées après compilation des blocs disponibles à https://cgran. qui semble être un handicap significatif pour la réception de signaux faibles12. et le protocole ACARS de communication des avions civils (et militaires par compatibilité avec le réseau civil). Droite : carte des avions suivis depuis un récepteur situé près d’Orléans. Nous allons proposer d’aborder 3 modes de communication numériques : la FSK des radiomodems. l’AFSK tel qu’utilisé en packet radio amateur ou commercial. Figure 5 : Gauche : spectre acquis lors de l’écoute de transmissions en ADS-B. 4 Décodage d’un mode numérique L’utilisation de fonctionnalités existantes n’est que d’un intérêt limité et le développeur se lasse vite d’utiliser les modules disponibles sur le dépôt des projets associés à gnuradio CGRAN13. Noter dans le terminal.org/wiki/RDS.10 décembre 2012 à 16:20 L’ajout d’un amplificateur à faible bruit de 25 dB n’ayant pas amélioré la situation. w w w. avec une fréquence centrale légèrement décalée par rapport à la fréquence d’intérêt. il n’est pas exclu que les réglages n’aient été mauvais.com GNU/Linux Magazine France N° 1 5 3 11 . et ainsi utiliser l’outil open source qu’est gnuradio comme un outil de prototypage souple. en bas de la fenêtre. L’aspect open source du projet est fondamental pour apprendre par la lecture des codes d’autrui14.ca/content/view/45/73/#fm_rds_rx mais épuré de quelques sorties graphiques qui consommaient trop de ressources de calcul sur eeePC 701. une mise à jour récente du pilote du convertisseur analogique-numérique permet de désactiver le contrôle de gain automatique. En particulier.

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) - 10 décembre 2012 à 16:20

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) - 10 décembre 2012 à 16:20

LAbO

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) - 10 décembre 2012 à 16:20

Bien que tous ces modes aient été conçus dans des débits de données compatibles avec les cartes son, la solution de récepteur de télévision numérique terrestre (DVB) offre néanmoins une solution intégrée qui évite l’achat d’un scanner radiofréquence. Bien qu’un scanner soit un outil souple d’emploi et bien plus sensible qu’une clé USB, son coût peut paraître rédhibitoire pour l’amateur désireux de s’engager dans la voie du décodage de modes numériques sans vouloir effectuer un investissement financier conséquent. Par ailleurs, le décodage numérique des signaux par logiciel permet de dynamiquement adapter les caractéristiques des filtres en n’étant limité que par la puissance de calcul disponible, alors qu’un scanner n’offre qu’un nombre fini de modes de décodage et généralement 2 ou 3 largeurs de filtres, implémentés sous forme matériel et donc inaccessibles pour l’acheteur de l’instrument.

de ces modulations a des propriétés d’encombrement spectral, de robustesse à diverses sources de bruit et de simplicité de mise en œuvre qui impliquent un choix contraint par les paramètres de communication recherchés. Un cas particulier que nous aborderons plus bas est l’AFSK - Audio Frequency Shift Keying - dans lequel les signaux ne sont pas codés par une fréquence ou une phase, mais par une modulation en fréquence audible de la porteuse radiofréquence. Il s’agit d’un mode développé spécifiquement pour l’utilisation avec des modes de communication de la voix (téléphonie dans le cas des modems, ou transceivers radiofréquences) qui ne nécessitent pas que la sortie soit adaptée pour des gammes de fréquences autres que les bandes de fréquences audibles (typiquement 1000-5000 Hz). Ayant introduit ces concepts, nous constatons que le décodage de signaux numériques consiste en l’extraction d’un de ces paramètres pour en tracer l’évolution dans le temps et par conséquent remonter aux signaux transmis. Le cas de l’ASK est le plus simple : nous calons le récepteur sur la fréquence de la porteuse (éventuellement avec un asservissement pour garantir que la dérive entre oscillateur de l’émetteur et du récepteur soit compensée), et un filtre passe-bas détecte l’enveloppe du signal. L’amplitude du signal traduit alors la valeur du bit transmis. La FSK est à peine plus compliquée dans le principe puisque nous exploitons le signal de contrôle de l’oscillateur local asservi par verrouillage de phase sur le signal reçu, mais son exploitation est rendue triviale par la disponibilité sous gnuradio-companion du bloc Modulators → WBFM receive. La démodulation d’un signal passe dans un premier temps par la génération des signaux I (In-phase) et Q (quadrature) que nous avons déjà mentionnés sans les définir (Fig. 6) : il s’agit du mélange du signal incident (dit RF - RadioFrequency) avec un oscillateur local de référence (dit LO - Local Oscillator) en vue de générer I=A(t)sin((RF-LO)*t) et Q=A(t)cos((RF−LO)*t). Alors I+j*Q=A(t)exp( j*2*π*(RF−LO)*t) avec j2=-1 [12] (noter que sin et cos sont

Figure 6 : Principe de la démodulation IQ pour extraire les deux grandeurs représentatives d’un signal d’entrée radiofréquence s(t) connaissant sa fréquence f (ou pulsation angulaire ω=2π f), à savoir son amplitude A(t) et sa phase ϕ(t), toutes deux pouvant être utilisées pour coder de l’information si elles varient avec le temps t. La fréquence de coupure des deux filtres passe-bas après les mélangeurs définissent la bande passante du détecteur (qui définit en partie le débit de communication puisqu’il s’agit de la vitesse à laquelle les symboles déterminés par A(t) et/ou ϕ(t) peuvent varier).

4.1 Les modes de modulation et traitement numérique du signal
Nous ne pouvons prétendre introduire ici tous les éléments de traitement du signal associés aux modulations sur porteuse radiofréquence en vue de transmettre un signal. Afin de faciliter l’introduction aux concepts pour le lecteur qui n’est pas familier avec ces notions, rappelons qu’un signal périodique s(t) est caractérisé pour son comportement temporel t par trois grandeurs : son amplitude A, sa fréquence f et sa phase ϕ selon s(t)=A(t)*sin(2π f(t)+ϕ(t)). Ces trois grandeurs peuvent évoluer dans le temps, individuellement ou simultanément, pour coder un signal transmis : A(t) implique une modulation d’amplitude (AM en analogique, ou ASK - Amplitude Shift Keying pour les modes numériques), f(t) implique une modulation de fréquence (FM en analogique, ou FSK - Frequency Shift Keying - pour les modes numériques) et ϕ(t) implique une modulation de phase (PSK - Phase Shift Keying) [11]. Chacune

séparés par un déphasage de 90o, donc en pratique les schémas de démodulateur I/Q indiquent ces opérations par un mélangeur, donc la composante LO a été sur une des voies déphasée de 90o). Ces deux signaux sont fournis par le composant Elonics E4000 après que l’utilisateur ait configuré LO. Dans ces conditions, une représentation simple des concepts de modulation que nous venons de citer est résumée dans le diagramme de constellation [12, p.11]. Ce diagramme trace en abscisse la composante I et en ordonnée la composante Q telles que nous venons de les définir et nous permet de revenir au plan complexe dont les propriétés sont bien connues : la distance d’un point à l’origine représente le module du complexe (dans notre cas A(t)) et l’angle entre l’axe des abscisses (I) et le point représenté dans le plan complexe représente sa phase ϕ(t). Ainsi, un diagramme de constellation représente dans le plan complexe (I, Q) les divers codes possibles. Une modulation en phase se traduit par des points distribués le long d’un cercle de rayon constant centré sur l’origine, tandis qu’une modulation en amplitude se traduit par des points à distance variable de l’origine. La modulation en fréquence est un peu particulière puisque

14

G N U / L i n u x M a g azine France N°153

www.gnulinuxm a g . c o m

L’application du démodulateur WFM (qui est approprié pour une excursion aussi importante que 55 kHz) donne le signal de la Figure 7 : nous observons de façon évidente des transitions représentatives du flux de données sur l’oscilloscope connecté en sortie de démodulateur.10 décembre 2012 à 16:20 4. soit il reçoit) susceptible de moduler un oscillateur en fréquence (FSK) pour coder les deux états possibles de la donnée numérique transmise.com GNU/Linux Magazine France N° 1 5 3 15 . Figure 7 : Haut : schéma blocs pour décoder le flux d’informations transmis par un radiomodem en FSK (il s’agit du même bloc de WFM que nous avions déjà utilisé pour les bandes FM commerciales). L’excursion de la modulation FM entre les deux états est programmable . illustrer le décodage de ces modes de modulation sur des exemples concrets mis en œuvre sur des émetteurs commercialement disponibles dont nous désirons décoder les informations transmises.com/apps/filedown/down. La fréquence de sa porteuse est programmable par pas de 500 Hz : nous sélectionnons 434 MHz.nous choisissons 55 kHz.php?file=xe1203f. g n u l i n u x m a g. bien que les bits de début (start) et de fin (stop) de communication introduisent quelques subtilités dans l’interprétation qu’en fait le radiomodem. Ces connexions de broches semblent être le mode de communication le plus simple entre le radiomodem XE1203F et le bus de communication asynchrone (RS232) d’un microcontrôleur. dans les sections qui vont suivre. Nous allons. la fréquence est la dérivée de la phase et par conséquent les points dans le plan complexe tournent sur un cercle centré sur l’origine. le 15 http://www.pdf w w w. La FSK ne nécessite aucun autre traitement particulier pour retrouver les valeurs des bits puisque l’oscillateur radiofréquence est directement attaqué par la valeur du signal numérique transmis : le démodulateur fournit un signal basse fréquence proportionnel au signal d’erreur de la boucle asservie en phase. Le radiomodem XE1203F de Semtech émet sur un codage modulé en fréquence.2 Cas de la FSK du Semtech XE1203F Le radiomodem XE1203F15 de Semtech est un transceiver half duplex (soit il émet.semtech. Scientifique et Médicale (ISM). donc directement une tension proportionnelle à la fréquence codant chaque bit. Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. et le protocole de communication avec les avions ACARS module un signal en amplitude. et le débit des informations est défini par le flux de données issu de l’interface asynchrone (UART) du microcontrôleur (dans notre cas un ST STM32F103) connecté aux broches DATA et DATAIN du radiomodem (flux de données numériques transmis). Bas : sortie oscilloscope au cours de l’enregistrement.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) packet radio émet des signaux modulés par des fréquences audibles. Les deux états de transmission des données sont déjà clairement visibles et laissent présager d’un décodage aisé.fr) . en plein milieu de la bande Industrielle.

y appliquer dans un premier temps un algorithme de traitement développé sous GNU/Octave. typiquement entre 1000 et 1550 Hz pour un état.150 et 154.2316). Comme divers protocoles de modulation sont disponibles (par exemple codage sur 1300 et 2100 Hz tel que défini dans ITU-V.fi/AFSK. et transmission de données au rythme de 1200 bits/s. Le mode le plus commun de packet radio est un codage des deux états possible du bit par un signal à 2200 et 1200 Hz (protocole Bell 202). notamment après avoir constaté que le bruit radiofréquence ambiant a tendance à être détecté comme une transmission erronée en l’absence de cette fonctionnalité (Pattern recognition block). et d’autre part le réseau de bus Ginko de Besançon exploite des modems basés sur ce protocole de communication pour localiser ses bus (émissions sur 154. avant de le traduire en C pour inclure cet algorithme dans le formalisme de gnuradio (section 5) avant de finalement appliquer à un « vrai » flux de données issu du récepteur radio. Afin de faciliter le développement du décodage. bruit qui a peu de chances de se retrouver au niveau du stop bit en l’absence d’une vraie transmission de données. Nous vérifions pour chaque octet décodé que le dernier bit (stop bit) est à 1. Enfin. 2.en 16 G N U / L i n u x M a g azine France N°153 www.fr) .LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. La Figure 8 propose un exemple de schéma bloc pour valider l’enregistrement et afficher en mode oscilloscope les valeurs stockées dans un fichier binaire (nous avons toujours exploité le mode par défaut d’un enregistrement mono-voie opposé à stéréo . 3. le caractère « U ».154 MHz). garantissant ainsi une compatibilité avec à peu près tous les cas décrits sur le Web. 4. le motif d’identification ayant été détecté. soit pour un échantillonnage à 46 kS/s.gnulinuxm a g .10 décembre 2012 à 16:20 Par ailleurs. sinon nous indiquons une erreur. l’intervalle de temps entre deux transitions est en accord avec un débit de 4800 bits/s. le message lui-même est transmis. et 2000 à 2500 Hz pour l’autre. c o m .en 8 bits/données). un débit d’information de 48000/40=1200 bits/s. L’intérêt pour ce mode tient en deux aspects : d’une part il s’agit d’un mode de communication numérique couramment utilisé par les radioamateurs.ham. la stratégie de développement que nous proposons consiste à systématiquement commencer par enregistrer dans un fichier binaire (ou WAV pour y ajouter un en-tête de format incluant taille des données et fréquence d’échantillonnage) un flux de données. Figure 8 : Bloc pour rejouer un signal enregistré dans un fichier binaire muni d’une en-tête WAV : noter l’utilisation du bloc throttle pour imposer le débit d’émission des données lues dans le fichier.  Nous utilisons la fonctionnalité de coder une adresse du radiomodem émetteur. l’analyse de ces données pour en extraire une séquence compréhensible nécessite de s’approprier la séquence d’émission que nous avons implémentée dans le microcontrôleur selon les consignes de la fiche de données de Semtech : 1.  La transmission commence par une séquence d’oscillations entre 0 et 1 nommée bit synchronizer pour que le récepteur cale son oscillateur sur le signal émis. 16 http://wiki. nous constatons qu’une alternance de 0 et de 1 s’obtient en envoyant la valeur 0x55 (le bit de poids le plus faible est envoyé en premier). Sur l’exemple de la Figure 9. En particulier.  Finalement. le mode de transmission packet hérite des protocoles mis en place à l’époque de la communication numérique sur lignes téléphoniques câblées analogiques au moyen de modems. Cette vérification permet en partie de s’affranchir du bruit sur le canal radiofréquence de transmission qui risquerait de nous laisser croire qu’un start bit s’est déclenché (transition de 1 à 0). Compte tenu du 0 en start bit et 1 en stop bit.3 Cas de l’AFSK L’Audio Frequency Shift Keying encode les deux états possibles sur une fréquence audible. nous avons choisi d’appliquer des filtres large bande coupant autour de 1700 Hz. i.e. les ronds bleus sont échantillonnés tous les 40 points.

fin= 488000.ham. et un 1 (1300 Hz) la reconduction de l’état précédent inchangé. % http://wiki. en approche avec les portes de débarquement et l’état des réacteurs. printf(‘%02x ‘. else end plot(ind.c).com GNU/Linux Magazine France N° 1 5 3 17 .8)*128. h=firls(42. 4. La procédure est réitérée pour un filtre passe-bande entre 2000 et 2600 Hz.10 décembre 2012 à 16:20 Le script GNU/Octave ci-dessous introduit les premiers pas pour le traitement des signaux enregistrés par gnuradio après démodulation FM en bande étroite (NFM) en vue d’en extraire les valeurs des bits successifs.fe.) 12 10 8 6 4 2 0 9000 1000-1500 Hz 2000-2600 Hz seuillage Initialisation des variables . binaire=reshape(tout(1:floor(length(tout)/8)*8). yc24=conv(abs(y24).code_asc). d=d-mean(d).d(1:N)). ind=[9160:40:48000]. une voie).inf. à la valeur précédente. Finalement.6)*32+binaire(:.tout(v1)=1.’uint8’).1.d=fread(f.4 Cas de l’AM et le protocole ACARS ACARS est un protocole de communication utilisé en aéronautique à l’échelle internationale pour transférer diverses informations au cours du vol d’un aéronef.0 Figure 9 : Résultat du décodage.1)+binaire(:. en accord avec nos observations sur la Figure 9).wav’). Dans ce cas. % +binaire(:.1. avec application de deux filtres passe-bande sur les signaux bruts issus du récepteur radiofréquence après démodulation en NFM (Narrow FM).3)*4+binaire(:.floor(length(tout)/8))’. un 0 (2400 Hz) encode un changement d’état du bit par rapport w w w. deb= 338100.tout(v2)=0. [H. v2=find(yc12(ind)<=yc24(ind)).’o’). f=fopen(filename=’120723_ginko. y12=filter(h.yc24=yc24(15:end-15). d=d(deb:fin). et lecture d’un segment de données dans un fichier enregistré par la fonction wav de gnuradiocompanion (8 bits/échantillon. en cours de vol avec par exemple l’horaire d’arrivée prévu et des informations météorologiques.[0 500 1000 1500 1900 fe/2]/fe*2. v1=find(yc12(ind)>yc24(ind)). nous laissons passer l’énergie entre 1000 et 1500 Hz (amplitude de 1) et coupons en dehors de ces fréquences. et ce en identifiant le baud rate (les protocoles associés au packet nous laissent penser qu’un flux de 1200 bits/s est le plus probable. les données sont réorganisées en paquets en faisant l’hypothèse d’un octet pour 8 bits.1)/30.freq]=freqz(h.fe).’c’). v1 et v2 définissent l’état de bit le plus probable en comparant la puissance en sortie des deux filtres passe-bande. Les bits successifs sont clairement visibles. Tel que décrit à http://n1vg.plot(yc12.tout. fe=48000.php. et le résultat affiché sous forme d’une séquence de valeurs hexadécimales (%02x) ou de caractères ASCII.’m’) 9500 10000 10500 11000 echantillon (48 kS/s) 11500 220.5)*16+binaire(:.[0 1700 2000 2600 4600 fe/2]/fe*2. printf(‘\n’). Finalement. 14 sortie apres filtrage (u. code_asc=binaire(:. g n u l i n u x m a g. Un filtre numérique est toujours défini pour des fréquences normalisées par rapport à la fréquence d’échantillonnage. f=linspace(0. après atterrissage avec le volume d’essence restant.yc12=yc12(15:end-15).fr) . Ces points n’ont pas encore été élucidés. et finalement la signification de chaque octet décodé. for k=1:length(tout) if (tout(k)==0) res(k+1)=1-res(k).a.end L’obtention de la séquence de bits n’est que le début de l’aventure : il faut maintenant être capable d’en extraire une information pertinente.en % 1300 Hz = 1 = mark % 2400 Hz = 0 = space res(k+1)=res(k).net/packet/index.fi/AFSK.plot(yc24.4)*8+binaire (:.[0 0 1 1 0 0]). des informations sur l’équipage ou des dysfonctionnements informatiques).N).LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. res(1)=0. après filtrage.7)*64. y24=filter(h. yc12=conv(abs(y12). c=ones(30.en partie de la fréquence d’échantillonnage fe.8. un filtre passe-bas est appliqué sous forme de convolution avec une fenêtre rectangulaire de 30 éléments de long.2)*2+binaire(:. et est donc souple d’emploi pour s’adapter à diverses valeurs de fréquences audio. compatibles avec un flux de données en 1200 bits/s. le nombre de bits/données et l’éventuel bit de parité.d(1:N)). h=firls(42.N=fin(m)-deb(m). Le choix de ne prendre qu’un point sur 40 est imposé par le débit supposé de 1200 bits/ seconde sur des données échantillonnées à 48 kHz.512.1. L’approche sélectionnée consiste en une paire de filtres passe-bande autour des deux fréquences supposées coder les deux états transmis.hold on Nous définissons un filtre de réponse impulsionnelle finie (FIR) dont le gabarit est défini par les amplitudes du second vecteur pour les fréquences du premier vecteur.[0 0 1 1 0 0]). que ce soit de façon automatique au cours de phases du vol bien définies (taxi avec des informations de type quantité d’essence. SEUIL=200.c).

525 MHz et 131. Il existe peu d’implémentations libres : acarsd à http://www.10 décembre 2012 à 16:20 La communication numérique en Europe suivant le protocole ACARS se fait sur la fréquence de 131.acarsd.tapr.TXT. où toute communication se fait en modulation d’amplitude (AM). toutes ces fréquences peuvent être analysées simultanément.  L e fait de coder un bit par une demi période audio et l’autre bit par une période complète exploite pleinement la capacité de l’intercorrélation à identifier la nature du bit encodé.net/src/acarsdec/ semble s’être arrêté à l’état de prototype qui n’a plus évolué depuis 2007 (ce qui ne retire rien à son intérêt pédagogique. bien documenté dans http:// files. car pour une fréquence de 48 kHz d’échantillonnage (compatible avec une sortie sur carte son). ou accessoirement sur 131.pdf et http://www.ru/files/download/file4094/acars.fr) . qui permettent de valider que la détection du mauvais état d’un bit se tra- Figure 10 : Spectres dans la bande aérienne de 108 à 137 MHz.550 MHz. Cette approche fonctionne. En effet. net/projects/acarsdec/ puis http://www. une fois que la porte de découpe des bits est synchronisée sur l’oscillateur générant les signaux audio. tandis que acarsdec à http://sourceforge. ACARS est un protocole ancien et simple à décoder. Pour des raisons que nous ne saurions expliquer. mais ne tire pas parti du choix judicieux des paramètres que nous venons de citer selon les considérations suivantes : 1. Cependant.org/ est gratuit mais ne diffuse pas ses sources. Nous allons développer ce dernier point qui est au cœur d’un décodeur plus efficace que la simple convolution d’un filtre passe-bande sur l’ensemble des données acquises. nous sommes certains que la sinusoïde du signal audio passe toujours par 0 à un changement de bit. Le choix des fréquences de modulation (1200 et 2400 Hz) relativement au débit (2400 bits/seconde) peut paraître surprenant tant que nous n’avons pas mis en œuvre un décodeur de ce protocole : la première approche naïve (que nous avons utilisée suite aux expérimentations décrites auparavant sur le packet) consiste à répartir des filtres passe-bande à réponse impulsionnelle finie (FIR) et filtrer les deux bandes de 1200 et 2400 Hz.LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. toutes les communications liées à l’aéronautique sont modulées en amplitude (AM). Compte tenu de la bande passante de la démodulation par gnuradio. cette approche nécessite un échantillonnage rapide du signal. un nombre réduit pour définir un filtre passe-bande efficace (et notamment présentant un coefficient nul à la fréquence nulle pour éliminer la composante DC qui rend les seuils difficiles à établir sinon). une période de signal à 2400 Hz ne comporte que 20 points. mais l’exemple fourni n’est plus fonctionnel et l’hébergeur actuel du code n’en connaît pas le fonctionnement). Nous y apprenons que deux fréquences encodent les deux états binaires possibles de l’information transmise : les fréquences de 1200 et 2400 Hz sont utilisées pour transmettre des informations à 2400 bits/seconde. 18 G N U / L i n u x M a g azine France N°153 www.  La proportionnalité du débit (bitrate) et des deux fréquences utilisées pour coder l’information garantit la continuité de la phase entre bits successifs. c o m .r-36.radioscanner.gnulinuxm a g .org/ aprsdoc/ACARS. 2.725 MHz. Notons dans un premier temps les relations suivantes.

soit 1.a.d). c=ones(60.pdf w w w.10 décembre 2012 à 16:20 duit par un signal de valeur moyenne nulle (intégrale sur la longueur d’un bit. fe=48000. % 2400 Hz dans 48 kHz = 20 points/periode *26 c2400x13=exp(i*t*2400/fe*2*pi).725 MHz avec application des algorithmes de filtrage à 1200 et 2400 Hz tel que décrit dans le texte. 11). N=fin-deb.’uint8’). il « suffit » d’initialement se synchroniser sur le flux de données . d=fread(f.25 ms à fe de 48 kHz).seuil) jmfdebug=0. Un exemple de mise en œuvre par prototypage sous GNU/ Octave propose l’implémentation suivante : function binaire=fft_decod(filename. Finalement. il s’agit d’une excellente occasion de tester le site de Wolfram à http://www.c). ayant obtenu un flux de bits. Pour ceux qui ont oublié leur table de trigonométrie. Ainsi.insyde. s=s(length(t)/2:end-length(t)/2). % max de ressemblance pour decallage de b % plot(d(b-260:b+260)/120. il reste à en interpréter le contenu : ACARS exploite un codage dans lequel les transitions d’un bit au suivant sont notifiées.) 18000 16000 14000 12000 10000 8000 6000 160 180 200 220 numero d’echantillon (48 kS/s) 240 10000 5000 0 0 500 1000 1500 2000 numero d’echantillon (48 kS/s) 2500 Figure 11 : Signaux issu d’un signal audio enregistré lors d’une transmission ACARS sur 131. puis effectuer deux produits des séquences suivantes avec sin(2π fm t) et sin(π fm t) pour retrouver l’état des bits successifs (Fig.’g’). d=d-dm. puissance (u.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.wolframalpha. soit 1/2400 s) tandis que la détection du bon bit se traduit par une valeur moyenne non nulle et égale pour les deux valeurs de bits détectés : voir cadre ci-dessus.deb.inf. Nous lisons le segment de données compris entre les indices deb et fin dans le fichier filename. Inséré à droite. Ainsi. g n u l i n u x m a g. au lieu de coder directement l’état des bits eux-mêmes.b]=max(real(s)).) 20000 1200 Hz 2400 Hz 20000 1200 Hz 2400 Hz 15000 puissance (u. plot(real(c2400x13).dm=dm(60/2:end-60/2). d=d(deb:fin). un signal à 1200 Hz indique un changement d’état par rapport au bit précédent. Nous constatons donc que le choix de moduler à fm=1200 Hz un état des données et à 2fm=2400 Hz l’autre état répond à un souci d’efficacité du décodage : la convolution du signal acquis avec sin(2π fm t) donne une valeur moyenne nulle si le segment de signal ne code pas le bon état et donne 1/2 si l’état recherché est présent.rôle des 16 premiers octets qui oscillent à 2400 Hz. t=[0:519]. [a.fin. et que l’intégrale du carré d’une fonction (donc dont toutes les valeurs sont positives) est non nulle (figure de droite dans le cadre ci-dessus).hold on.fr) . % retranche moyenne glissante sur 3 periodes application d’une moyenne glissante (fenêtre rectangulaire de 60 points de longueur. un zoom sur les premiers signaux exploitables en fin de synchronisation du récepteur sur l’émetteur (séquence de plusieurs périodes à 2400 Hz) : l’identification de ce point de départ est un élément clé du bon décodage de la suite de la trame car définit le premier bit du premier octet sur lequel tout le reste du décodage se base. f=fopen(filename).it/Corsi/AD/Documenti/ARINCTutorial.a.’r’). % recherche du max des 13 periodes a 2400 Hz s=conv(c2400x13. Noter par ailleurs qu’il est relativement trivial d’intuiter que l’intégrale sur une période d’une fonction paire par une fonction impaire de valeur moyenne nulle est nulle.com GNU/Linux Magazine France N° 1 5 3 19 .com/ en lui demandant de calculer int_0^1 sin^2(pi*x)dx.1)/60. dm=conv(d. 17 leonardodaga. alors que 2400 Hz code le maintien de l’état précédent17.

rs24=sum(rs24). Nous générons donc un vecteur c2400x13 qui contient les valeurs d’une sinusoïde échantillonnée à fe et de fréquence 2400 Hz. c o m . % les deux premiers 1 sont oublie’s car on se sync sur 1200 tout(n)=1. rs24=reshape(abs(s24). % bien se caler est fondamental pour la suite % est-il judicieux d’essayer a +/-1 ? if (jmfdebug==1) plot(rs12. ci-dessus) et les valeurs des bits par comparaison des sorties des deux filtres (convolutions.end if (jmfdebug==1) hold on. soit une demi période de 1200 Hz. l0=find((rs24+rs12)>seuil). for k=1:length(toutd) if (toutd(k)==0) tout(n)=1-tout(n-1). soit dans tous les cas 20 échantillons.6)*32+binaire(:.7)*64. end binaire=reshape(tout(1:floor(length(tout)/8)*8).rs24=rs24(l0). code_asc). En résumé. selon la méthode vue auparavant sur le radiomodem. Cette étape est peut-être inutile.checksommebinaire(:. c1200=exp(i*t*1200/fe*2*pi). hold on. Pour ce faire. 5)*16+binaire(:. rs12=reshape(abs(s12). et recherchons le maximum d’intercorrélation qui.n=n+1. printf(‘\n’).’2400’).endif n=n+1. revient à une convolution. rs12=sum(rs12). Ayant identifié le point de mesure permettant de synchroniser les sinusoïdes synthétisées de façon logicielle et les données acquises.  Identification de l’occurrence du début de trame sous forme de plusieurs oscillations à 2400 Hz : nous nous sommes imposés de trouver au moins 13 périodes du signal à 2400 Hz pour définir le début de trame et synchroniser notre traitement sur la phase du signal acquis. checksomme=1-mod(sum(binaire(:.’bo-’). la séquence d’échantillons est traitée pour la convertir en valeurs binaires : nous recherchons. % 2400 Hz dans 48 kHz = 20 points/periode c2400=exp(i*t*2400/fe*2*pi).2). tout(n)=1. code ASCII correspondant. Nous recherchons désormais les bits individuels.fr) .gnulinuxm a g .d). ll=find(rs24>seuil). printf(‘%d’. toutd(pos24)=1.  Identification des segments de 1 (2400 Hz) et de 0 (1200 Hz) par convolution d’une période de sinusoïde de chacune des fréquences avec le signal à traiter. else tout(n)=tout(n-1). b=mod(b. rs12 et rs24 contiennent les informations permettant d’identifier si un bit est plus problement à 1 ou 0 et mérite d’être affichées dans une phase préliminaire de déverminage (Fig. codés soit par une période de 2400 Hz.d).floor(length(tout)/8))’.n=n+1.20.plot(rs24. les valeurs pertinentes (signal au-dessus du bruit. code_asc=binaire(:. s12=s12(1:fin20). 20 G N U / L i n u x M a g azine France N°153 www.’ro-’). et validation du bit de parité. soit une période (48000/2400) de sinusoïde à 2400 Hz. mais évite de risquer de s’accrocher sur une séquence longue de signaux à 2400 Hz se trouvant au milieu du message ACARS transmis : t=[0:19].10 décembre 2012 à 16:20 le point clé de l’algorithme est de synchroniser le récepteur sur les oscillations de l’émetteur.ll=ll(1) rs12=rs12(ll:end).code_asc). rs24=rs24(l:end). printf(‘%c’. et pour ce faire nous devons trouver le maximum de l’intercorrélation entre la séquence des signaux à 2400 Hz émis par ACARS dans ce but de synchronisation.20)+5.8)). ci-dessous). n=1. l=find(rs12>rs24).1:7)’)’. ce code exploite la trame ACARS de la façon suivante : 1. toutd(pos12)=0. plot(real(s24).plot(real(s12). s12=conv(c1200.legend(‘1200’. t=[0:19]. % revient au debut par pas de 2pi d=d(b+400:end).1)+binaire(:. % 2400 Hz dans 48 kHz = 20 points/periode fin20=floor(length(s12)/20)*20.s24=s24(1:fin20). Finalement.8.l=l(1) rs12=rs12(l:end). % on ne garde que les points utiles rs12=rs12(l0). par critère de seuil. rs24=rs24(ll:end). printf(‘\nCRC:’). pour un signal réel.2)*2+binaire(:.20. Les valeurs binaires sont finalement réorganisées en octets.4)*8+binaire(:.’r’).end seuil=max(rs24)*0.55.LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. % verification printf(‘%02x ‘. 11). avec la valeur du bit codant la transition d’état ou le maintien de la valeur par rapport à la valeur courante du bit. Les valeurs sont affichées sous forme hexadécimale. Seule une unique convolution est utile car l’incertitude sur la phase (qui nécessiterait par exemple 20 convolutions pour le signal à 2400 Hz pour identifier la phase parmi contrairement au cas précédent du XE1203F où nous nous étions contentés de prendre un point sur 40 pour tenir compte de la fréquence de bits transmis. nous réorganisons les deux vecteurs de mesures filtrées par les séquences de sinusoïdes à 1200 et 2400 Hz sous forme d’une matrice de 20 points de large (la longueur en échantillons d’un bit). % plot(d). pos24=find(rs24>rs12). nous avons choisi de replacer le curseur au début de la séquence de mesure en nous déplaçant par pas de 20 échantillons. et allons sommer les éléments pour effectuer la moyenne. 2.3)*4+binaire(:.’r’). pos12=find(rs12>rs24).length(s12)/20). s24=conv(c2400. printf(‘\n’).length(s24)/20). cette fois nous allons moyenner les valeurs des échantillons au sein de chaque bit pour améliorer le rapport signal à bruit (et donc la capacité de décodage du message en milieu bruité).

tout le reste du message sera illisible. Dans le résultat ci-dessous. sauf les 9 dernières. le fait de coder la transition induit que dès la première erreur de décodage. Les abréviations des messages sont décrites à http://www.15e6+40000.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) les 20 valeurs possibles qui maximisent l’intercorrélation) a déjà été résolue lors de l’étape précédente. et finalement l’adéquation avec le bit de parité (0 pour la cohérence avec ce bit. Noter en particulier que la documentation à http://www. Par ailleurs. i∈[1.ici G-EUUG qui est un Airbus A320 de British Airways18 allant de Londres à l’Italie au cours du vol BA9216 . 2b 2a 16 16 01 58 2e 47 2d 45 55 55 47 15 48 31 39 02 43 30 33 41 42 41 39 32 31 36 23 43 46 42 57 52 4e 2f 57 4e 31 32 30 36 33 30 30 38 33 33 30 30 33 34 30 30 30 30 30 36 4e 41 56 20 49 4c 53 20 32 20 46 41 55 4c 54 20 20 20 20 20 20 20 20 20 0d 03 6d 1d 7f 7f 7f 7f 7f 7f 7f m*X.org/redmine/projects/gnuradio/wiki/BlocksCodingGuide w w w. Dans le cas du passage dans le domaine de Fourier.e.2). En effet.com/ ham/raftmode. L’application d’une convolution entre deux séries de données de longueur respective M et N pose toujours un problème de définition de l’origine. puisque le passage par Fourier impose de multiplier point par point deux séquences de longueurs égales. Nous allons donc traduire le code C d’exemple de décodage des trames FSK pour respecter les conventions de blocs gnuradio-companion et ainsi effectuer le traitement en temps réel (au lieu d’enregistrer les informations dans un fichier binaire en vue de son post-traitement). Nous affichons ci-dessous dans un premier temps les valeurs hexadécimales des octets décodés (commençant toujours par la séquence de synchronisation 0x2b 0x2a 0x16 0x16 si le décodage est effectué correctement). Ainsi.N]. affiche la séquence des valeurs hexadécimales décodées.com/sc/ scannerpost/acars. mais obtenir tout le contenu du message lui-même est difficile car dépendant de l’absence d’erreur de traitement des bits tout au long du message.M] et v j. ne passent que d’un bloc à l’autre sans être accessibles depuis le script Python (code 1. il reste à convertir la séquence de bits issue de la convolution en des valeurs interprétables en ASCII. les séquences u ou v sont complétées de 0 (zero padding ) pour avoir la même taille (et s’approcher de la puissance de 2 supérieure la plus proche dans le cas de la transformée de Fourier rapide). est Dans l’équation ci-dessus. nous aurons souvent l’identifiant de l’avion émettant le message.est en train de voler avec un défaut sur son instrumentation secondaire d’atterissage19. soit entre max(M. l’infini étant difficile à atteindre.htm#I76 est erronée concernant la parité du flux de données.net http://www. pour deux séries de points de longueurs M et N. http://gnuradio. Chacun de ces blocs est lui-même codé en Python ou C(++). et la principale difficulté rencontrée dans la conversion du code GNU/Octave vers C se trouve à ce niveau (sans compter les conventions de normalisation de la transformée de Fourier qui imposent de recalculer les seuils dans la nouvelle implémentation).. telles que le caractère 01 (début d’en-tête).com/Code-30_html_Source/acars.10 décembre 2012 à 16:20 3.com GNU/Linux Magazine France N° 1 5 3 21 . 18 19 20 www. 5 Du prototypage à l’exploitation sous gnuradio Gnuradio-companion convertit un schéma de traitement défini de façon graphique en script Python.scancat. Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. On intégrera donc. i. la version numérique (discrète) de la convolution c entre ui. le flux issu des démodulateurs I/Q.wav’. ou alternativement une série de M+N points si nous complétons une des deux séries par des 0 pour égaler la longueur des deux séries. faisant appel aux fonctions correspondantes. l’interprétation selon le code ASCII si le caractère est affichable.15e6. Cette approche est par exemple celle proposée dans le code traduit en C que nous développerons ci-dessous (section 5.101001+2.planespotters.  Le codage des informations représentant une transition d’un état à un autre et non l’état lui-même.N) points.. l’intégrale dont les bornes sont ± ∞ peut en pratique être longue à calculer.fr) . probablement sans importance car situées après le caractère ASCII 0x03 (fin de la chaîne de texte).N) si nous faisons glisser la série des u sur les v pour générer ainsi un total de max(M. 02 (début de texte) ou 03 (fin du texte) qui sont exploitées par ACARS. les données qui transitent entre les blocs. avec u et v égaux à 0 en dehors des intervalles cités ci-dessus.angelfire.7000). correspondant au schéma graphique de la Figure 8). Il est par ailleurs remarquable d’enfin comprendre la signification d’entrées étranges de la table ASCII (man ascii). suivant un protocole d’échange de données20.html pour le contenu des trames et en particulier de l’en-tête.pervisell. leur interprétation dans le code ASCII.html.G-EUUGH19C03ABA9216#CFBWRN/WN12063008330034000006NAV ILS 2 FAULT CRC:000000000000000000000000000000000000000000000000000000000000000000000000000000000000-100-1-1-1-1-1-1 Il est toujours intéressant de savoir qu’un avion . Le problème de la position de l’origine se pose donc selon le formalisme sélectionné. Le programme GNU/Octave ci-dessus identifie le début de trame (série d’oscillations à 2400 Hz). et l’application du bit de parité à la séquence ainsi décodée. g n u l i n u x m a g. nous constatons que toutes les valeurs ont été convenablement décodées. ±1 s’il y a erreur) : binaire=fft_decod(‘acars_orleans. Cependant. j∈[1.101001+2.

.wav".. - une méthode publique general_work. mais également de le peupler. .gr_file_source_0 = gr. les répertoires ont été peuplés avec les fichiers nécessaires et ceux-ci partiellement remplis.Add(self.file_source(gr. 0)) tb = top_block() tb. des décimateurs.un constructeur privé. including default arguments: Add Python QA code? [Y/n] Add C++ QA code? [Y/n] La première ligne permet de directement spécifier les paramètres que le bloc recevra au moment de son instanciation (type de donnée.).fr) . et le lecteur est encouragé à consulter le code d’exemple disponible à http://jmfriedt.h et lib/nomDuProjet_nomDuBloc. True) self.cc : la classe et son implémentation.gz ou sur le site de CGRAN à www.connect((self. . [.fr/gr-acars.0"?> <block> <name>decodeur</name> <key>acars_decodeur</key> <category>acars</category> <import>import acars</import> <make>acars.decodeur($seuil)</make> <param> <name>Threshold</name> <key>seuil</key> <type>real</type> </param> <sink> <name>in</name> <type>float</type> </sink> </block> Le développement de blocs pour la gnuradio nécessite l’utilisation d’un environnement particulier constitué d’un répertoire contenant lui-même des sous-répertoires dans lesquels seront stockés les différents fichiers nécessaires à l’exploitation du bloc. le type va impacter sur la signature de certaines méthodes 21 git://github.win) self. La création du projet se fait avec la commande suivante : gr_modtool.lib pour les fichiers sources C++ d’extension .cc. Un exemple d’un tel fichier qui passe un paramètre (valeur réelle seuil) à la méthode de traitement des données decodeur de la classe acars est : <?xml version="1. dans le cas présent nous demandons un type générique mais il existe d’autres types tels que des sinks.gnulinuxm a g . dans quelle catégorie il doit être rangé (balise category).throttle(gr. afin d’éviter l’étape fastidieuse de la création manuelle de l’arborescence.un destructeur public. Par défaut.3).connect((self. 0).tar.free. Les deux lignes suivantes correspondent à l’ajout (ou pas) de test-unitaire pour le bloc. gain.wxgui_scopesink2_0.scope_sink_f( self. c o m . entre autres.10 décembre 2012 à 16:20 self.gr_file_source_0.Run(True) Tableau 1 : Le code Python généré par gnuradio-companion ne donne pas accès au flux de données radiofréquences mais ne fait que définir des blocs et les connecter entre eux pour router les informations d’une unité de traitement à la suivante. (self.org/wiki/ACARS.. L’ajout d’un bloc de traitement du signal numérique dans le projet se fait avec la commande (il faut se trouver dans le répertoire du projet) : gr_modtool. Ces concepts abstraits de l’arborescence seront illustrés par des bouts de code plus loin dans ce document (section 5. seuil. Il stipule. le nom du bloc (balise name). L’argument -t spécifie le type de bloc.py create plop À l ’issue de cette commande.gr_throttle_0 = gr.sizeof_char*1. type et variables correspondantes. La première étape pour la création d’un (ou plusieurs) bloc(s) est donc de disposer de cet environnement de développement. Comme nous le verrons un peu plus bas.xml : ce fichier fournit - la description du bloc à gnuradio-companion. Trois fichiers retiendront principalement notre attention : grc/nomDuProjet_nomDuBloc. Cet outil sert à la fois à générer le squelette du répertoire et de ses sous-répertoires. title="Scope Plot". un réper toire g r nomduprojet apparaît dans le répertoire courant et comporte (entre autres) les répertoires : -g  rc pour les fichiers de descriptions utilisés par gr-companion .. des sources. .. . 1) self.gr_throttle_0. samp_rate) self.gr_char_to_float_0.sizeof_float*1.LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. (self.include pour les en-têtes .com/mbant/gr-modtool. 0).gr_char_to_float_0.char_to_float(1. 0)) self. "nom_du_ fichier..gr_char_to_float_0 = gr. 0). ils contiennent : . . 0)) self.] ) self. nous allons utiliser le script gr-modtool. Toutefois.GetWin().wxgui_scopesink2_0.wxgui_scopesink2_0 = scopesink2. et les entrées (sink) et les sorties (source). -u  ne fonction nomDuProjet_make_nomDuBloc définie comme friend vis-à-vis de la classe (donc pouvant accéder au constructeur) et dont le rôle est de retourner une instance de la classe.cgran.py add -t general plup -i  nclude/nomDuProjet_nomDuBloc.py21.gr_throttle_0.connect((self. (self. À l’issue de cette étape. Enter valid argument list. les paramètres (balise param) ainsi que leurs noms.git 22 G N U / L i n u x M a g azine France N°153 www.

En effet. Noter qu’une fois le bloc nouvellement créé dans gnuradio-companion (dans la liste des menus de la colonne de droite). en bas du menu à droite. g n u l i n u x m a g. 3. il est inutile de relancer l’interface graphique suite à chaque recompilation. représentatives des bouts de données qui seront fournis par les blocs de démodulation et de filtrage de gnuradio. output_items le tableau que le bloc doit remplir avec les données traitées. selon le type du bloc. et semble ne pas servir à grand chose. Figure 12 : Décodage du flux d’informations issu d’un radiomodem XE1203F par traitement logiciel des données I et Q pour en extraire l’information numérique émise. donne le nombre d’informations reçues. et le module nouvellement compilé rechargé. nous opérons comme avec toute archive rencontrée jusqu’ici pour gnuradio : création d’un sous-répertoire build dans l’arborescence des sources du module à compiler. input_items un tableau contenant les données entrantes et qui doit être recasté dans le bon type. dans un premier temps enregistré dans un fichier binaire (. puis make VERBOSE=1 && make install.  Conversion du programme cité ci-dessus pour travailler sur des segments de données de taille aléatoire (Fig.fr) .  Conversion d’un script GNU/Octave en C et vérification de toutes ses fonctionnalités en lisant un enregistrement d’un fichier audio (ou binaire si sa fréquence d’échantillonnage n’est pas compatible avec celle de la carte son) et application des filtres implémentés en C. Sa signature est la suivante : int plop_plup::general_work (int noutput_items. nous désirons pouvoir afficher les données décodées en temps réel.1 Cas du radiomodem XE1203F Ayant prototypé les méthodes de filtrage sous GNU/Octave.wav) et restitué pour valider le bon fonctionnement du bloc (nommé square). w w w. gr_vector_int &ninput_items. le code Python qui est exécuté en pratique est régénéré à chaque fois que nous cliquons sur l’icône avec des engrenages. Cette méthode est sans doute la plus importante car c’est elle qui reçoit le flux venant du bloc précédent dans la chaîne. Les étapes de ce portage se font en 3 étapes : 1.  Intégration du code C(++) ainsi généré dans le formalisme d’un bloc gnuradio./ après être rentré dans ce répertoire. exécuter cmake . 14). qui correspond au résultat de la compilation de notre module de traitement. Nous aurons donc toujours la dernière version du module compilé et installé par make install disponible lors de l’exécution de la chaîne de traitement (Fig. réalise le traitement et fournit les nouvelles données. gr_vector_const_void_star &input_items. 2. l’ajout d’une entrée HOWTO avec le module square. 5. Afin de compiler notre application. Noter. ninput_items peut ne pas exister. Cette étape a encore l’avantage de pouvoir traiter l’intégralité des données contenues dans le fichier (code 2).10 décembre 2012 à 16:20 La dernière méthode peut également s’appeler work selon le type du bloc.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Il est inutile de relancer gnuradiocompanion lors de modifications des fonctions de square : le bloc est rechargé lors de la génération du code Python à chaque nouvelle exécution de la séquence de traitements..com GNU/Linux Magazine France N° 1 5 3 23 . gr_vector_void_star &output_items) avec noutput_items qui comme son nom ne l’indique pas.12).

0 -> 2 2 .k). else dm[k]=0.1)/20. if (code_asc>0) { if (dm[courant+380]==0) {} // printf("err ").int N. } while (N==segment).out[k-len]=somme/len. Les trames de gauche commencent par le signal de synchronisation UUUU. else printf("\\%x".0 2 .} while ((dm[courant]==1)&&(courant<(N+pos-380))).int len) somme=0. // lecture de segment donnees dans le fichier de points k=segment. stop) donc 400 échantillons pour un signal échantillonné à 192000 Hz et transmis à 4800 bits/s (192000/4800×10=400).c).0 2 . Nous avons indiqué dans la table de droite une ligne préfixée par une flèche qui a complètement été omise lors du décodage par échec du décodage de la trame UUUU d’initialisation de la transmission. k=find(dm>=100).état au repos . // k=find(dm<100). int deb.org/wiki/Asynchronous_serial_communication 24 G N U / L i n u x M a g azine France N°153 www.N.N). // milieu du stop bit de l’octet qui vient d’etre traite’ } } memcpy(d.seuil. // stop bit error else {if (((code_asc>=32)&&(code_asc<128))||(code_asc==’\n’)||(code_asc==’\r’)) printf("%c".seuil=atoi(argv[3])."lseek error %d\n".0 2 .dm(k)=1.i. 22 http://en.0 0\bc00 203\bc31 419 13 02111 \ff\5\ff\f8\c0U5UU\bc\e7\93\822 .0 2 . Nous allons donc tout d’abord rechercher l’occurrence d’un start bit (passage de 1 .O_RDONLY).k). N=read(f.f. conv1(d.k++) somme+=(int)in[k]. // boucle sur deb pour simuler blocs grc printf("\n").0 \fc000 465 31 534 6002109 \c\f8\e0UUU\bc\e7\93\82\fe .&d[pos]. le start bit permet de se resynchroniser pour les 9 bits qui vont suivre : nous vérifions que le stop bit est bien à 1.0 2 .k++) if (dm[k]<seuil) dm[k]=1.dm(k)=0.0 0000\d02\f09 31 311 \859 02112 \ff\e0\f0\f0\e8\e0UUUU\bc\e7\93\822 . int b=0. Tableau 2 : Traduction en C du code prototypé sous GNU/Octave pour le décodage des transmissions d’un radiomodem XE1203F modulé en fréquence (FSK) pour une transmission numérique de données à 4800 bits/s.k<N.N.0 0000 465 31 0000 558 31 0000 595 31 0000 637 31 0000 225 31 0000 333 31 0000 203 31 0000 367 31 0000 195 31 0000 284 31 .à 0 .pos=0. int k. 40 points/bit {code_asc=dm[courant+60]+dm[courant+100]*2+dm[courant+140]*4+dm[courant+180]*8+ dm[courant+220]*16+dm[courant+260]*32+dm[courant+300]*64+dm[courant+340]*128.deb. nous continuons le traitement consistant à tester la valeur du bit tous les 40 échantillons (puisque 192000/4800=40). % 10 bits = START+9. // copie ce qui reste de donnees pos=N+pos-courant.} Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. la majorité des trames émises (droite) se retrouve dans les signaux décodés (gauche). // c=ones(20.dm=conv(d.char **argv) {char filename[255]. (k=0."%s".SEEK_SET).l0=0. if (courant<(N+pos-380)) // db=dm(20:40:20+40*9).&d[courant].0 0T00 225 31374 10 0210 \fc\f0UUUU\bc\e7\93\82\fe . int dm[MAXSIZE]. et recherchons échantillon par échantillon l’occurrence du prochain passage à 0 pour } UUUU\bc\e7\fb\822 .0 2 . i=lseek(f.0 0000 336 31 \e741 20 021\e52 2 . do {courant++.0 000 333 31 24 12 02110 \ff\ff\e0\c1UUU\bc\e7\93\822 .gnulinuxm a g . représentatif du flux de données que nous fournira gnuradio lors d’un décodage en temps réel.0 2 . suivi de la trame.0 0000 201 0000 209 31 0000 336 31 534 6 02109 500 7 02110 169 8 02110 426 9 02110 374 10 02110 324 12 02110 419 13 02111 246 14 02111 296 15 02111 305 17 02111 31 325 18 02112 311 19 02112 341 20 02112 Tableau 3 : Comparaison des trames issues du décodage par gnuradio des signaux reçus par récepteur EZCAP (gauche).k<N. start bit est passage a 0 courant=0. // moyenne glissante sur len points (k=len.int* out. else {sprintf(filename.N+pos-courant).20). Comme dans toute communication asynchrone.dm=1-dm.wikipedia.fe=192000. et si la masse de données à traiter dépasse 400 bits.code_asc). Le problème de la gestion de la taille des données à traiter est résolu de la façon suivante : nous savons qu’un octet complet tient sur 10 bits (start.LAbO #define MAXSIZE 100000 #define NSEARCH 260 // 13 periods * 20 pts/period void {int for for } conv1(unsigned char* in. c o m .0 00\e40 367 \e71 246 14 02111 \f8\f0\e0UUU\bc\e7\93\822 .0 2 .0 2 .0 000\94 195 3\95 296 15 02111 \f8\f0UUUU\bc\e7\93\822 \fe0 0000\fc284 31 30\fd 17 02111 \ff\e0\5\f0\f0\e0UUUU\bc\e7\93\822 .k<len. deb+=segment.dm.} deb=0. close (f).k. if (argc<4) printf("%s filename deb seuil\n".10 décembre 2012 à 16:20 #define segment 8192 int main(int argc. Nous avons laissé en commentaires les principales séquences du code pour GNU/ Octave que nous avons traduites. for (k=0. unsigned char d[MAXSIZE]. do { f=open(filename. } } courant+=380.fr) .code_asc). if (i!=deb) fprintf(stderr.code_asc.argv[1]).deb=atoi(argv[2]). // % etat au repos est 1. while (courant<(N+pos-380)) { // k=find(dm(courant:end)<1). Bien que la conversion ne soit pas parfaite. et concaténation des valeurs qui n’ont pu être traitées car ne formant pas un bit d’information complet.dm=dm(k(1)+courant-1:end).0 00\fc0 558 31 500 7 02110 \fc\c0UUU\bc\e7\93\822 0 0000595 31 16\f9 8 02110 U\e0UUUU\bc\93\822 .état du start bit22).k++) {somme=somme-in[k-len]+in[k]. printf("\nN=%d\n".argv[0]).0\fc0000 6\ff7 31 426 9 02110 \ff\b0E\e0UUUU\bc\e7\93\fe2 .courant. 8 bits de données. Noter la lecture du fichier par segments de segment éléments. suivi d’un identifiant du modem émetteur.0 2 .dm=dm(20/2:end-20/2). et les trames émises par le radiomodem.

5.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Si la quantité de données restant à traiter après détection d’un start bit est inférieure à 400. de l’affichage d’une variable N contenant le nombre de données fournies par le bloc de démodulation : nous constatons que cette valeur évolue de façon plus ou moins aléatoire. Ce signal sert donc à identifier le début d’un message. La solution proposée est décrite dans le texte. L’intérêt d’un bloc est déterminé par la convolution entre le signal acquis et un filtre centré sur 2400 Hz.wav exploité pour les traitements. pour le déverminage. et concaténons les nouvelles données pour relancer le traitement sur un jeu de données complet. alors nous copions en début de tableau les données restantes. Ensuite.attention.2 Cas de l’ACARS . soit 258 caractères compte tenu de la taille de texte la plus longue admissible. g n u l i n u x m a g.10 décembre 2012 à 16:20 N=1361 N=5444 N=6805 \fcUUUU\bc\e7\93\2 N=1361 2 . N=682 0 N=1361 000 N=1361 0 4\fe N=1361 6 3 N=1361 1 4\fd N=4083 0 31 01138 N=5444 *7C12 188 N=5444 N=1361 N=1361 N=1361 N=2722 N=1361 N=1361 N=5444 N=6805 \f0 \f0 \10\fc UUUU\bc\e7\93\822 Figure 14 : Le bloc compatible gnuradio équipé. la recherche de la transition du start bit atteint la fin du tableau et nous pouvons sereinement traiter le nouveau paquet de données sans craindre d’avoir coupé une transmission en cours. avec le radiomodem XE1203F commandé par un microcontrôleur STM32. pour revenir aux conditions déjà connues sous GNU/Octave. Noter le gain important (environ 3700) et le biais (128) qu’il faut ajouter pour ajuster la gamme des données issues du bloc de démodulation aux valeurs lues dans le fichier . paragraphe addictif La philosophie que nous avons adoptée ici pour convertir le code de traitement prototypé sous GNU/Octave vers un flux de données de taille aléatoire consiste à concaténer les données reçues pour former un bloc contenant l’intégralité des données. La traduction du code GNU/Octave en C se fait alors sans trop de problème si ce n’est pour la convolution qui n’est w w w. Bas : montage expérimental. relancer un décodage. Le résultat de cette implémentation (Fig. Figure 13 : Haut : schéma bloc de gnuradio-companion pour le décodage des trames acquises par EZCAP et fournies après démodulation au bloc de traitement que nous avons développé et testé sur carte son. 13) est visible sur la table 3. mais cette approche s’avère très sensible à la valeur du seuil de détection). et de n’appliquer la phase de décodage que sur l’intégralité de ce bloc.fr) .com GNU/Linux Magazine France N° 1 5 3 25 . et qu’il est donc impossible de faire une hypothèse sur la taille des données à traiter. Nous avons déjà vu que toute communication ACARS s’initie avec plusieurs périodes d’un signal à 2400 Hz pour laisser le temps au contrôle de gain automatique du récepteur radiofréquence de se stabiliser et synchroniser l’horloge du récepteur avec celle de l’avion. nous concaténons les données pour atteindre la taille maximale que pourrait atteindre un message ACARS (nous avions tenté de concaténer tant que la puissance du signal reçu dépasse un seuil prédéterminé. Si aucune transmission n’est détectée sur les données acquises. et le module EZCAP pour l’écoute du flux de données émis.

cmake. // c=ones(60.} // [a. c o m . et ce quel que soit l’environnement de développement. {c2400x13[t][0]=cos((double)t*2400. // initialise moyenne glissante for (k=0.lors de la recherche d’un motif dans une séquence de points de taille N par intercorrélation). fftw_complex *c2400x13.t. nous avons vu dans la présentation des séquences I et Q issues des mélangeurs que deux paramètres inconnus sont 26 G N U / L i n u x M a g azine France N°153 www. fd[k][0]=mul[0]/(float)N. [.*rs12.cmake.ss.k<fil_len.*rc24. avg-=d[k].t<N.seuil. Heureusement. printf("a=%f b=%d\n".un octet par donnée qui ne pose donc pas de problème d’endianness .k.. Les motifs recherchés sont définis sous forme de segments de sinusoïdes normalisés par la fréquence d’échantillonnage fe=48000 Hz.retire le résultat d’une fenêtre glissante de fil_len éléments du tableau d pour générer out. Cette identification est un point clé pour optimiser la suite des opérations car résout l’incertitude sur la phase. mul[1]=fc2400x13[k][1]*fd[k][0]+fc2400x13[k][0]*fd[k][1].out. fftw_destroy_plan (plan_R)..d).LAbO efficacement implémentée que par le passage dans le domaine de Fourier.N.i. for (k=0."open error %d\n". FFTW_BACKWARD..10 décembre 2012 à 16:20 k=lseek(f.dm=dm(60/2:end-60/2).k++) {s[k][0]=(double)out[k].com/p/qmcpack/source/ browse/trunk/CMake/FindFFTW. FFTW_ESTIMATE)./fe*2*M_PI). FFTW_FORWARD.fr) . fc2400x13. N=fin-deb. for (k=0. } fftw_execute (plan_R).b=k. fftw_execute (plan_b). fd[k][1]=mul[1]/(float)N. } for (t=520.*tout. c2400x13. et compléter le CMakeLists.. remove_avg(d. } f=open(filename.*rs24.int fil_len) {int tmp.k++) out[k]=d[k]-avg/fil_len. int main(int argc. dm=conv(d.k++) // produit des transformees de Fourier pour intercorrelation {mul[0]=fc2400x13[k][0]*fd[k][0]-fc2400x13[k][1]*fd[k][1].k<tot_len. Ce pré-traitement est fondamental pour toute la suite des opérations.k.*fc2400x13.google. MacOS X.*ss.N. cmake a pour ambition de trouver tout seul les bonnes bibliothèques aux bons emplacements. if (f<0) fprintf(stderr. FFTW_FORWARD.k<N.avg=0.char **argv) {char filename[255]."deb=%d fin=%d\n". L’appel aux fonctions de transformée de Fourier proposées par fftw3.d.*toutd.t++) // t=[0:520]. fprintf(stderr. nous avions déjà explicité dans ces pages [13] le gain en temps de calcul . deb.fe=48000.b=0.mul.b).l0=0. b=b%20. ss . fd. int deb.k++) if (ss[k+NSEARCH-2][0]>a) {a=ss[k+NSEARCH-2][0].} plan_a=fftw_plan_dft_1d(N. fd. out=(int*)malloc(sizeof(int)*N). fd . if (argc<5) printf("%s filename deb fin seuil\n". Alors qu’ajouter une bibliothèque dans un classique Makefile se résumait à ajouter le nom de la bibliothèque précédé de -l.. fftw_plan plan_a. pour lequel le motif des sinusoïdes à 2400 Hz a été identifié dans la séquence de points expérimentaux. c2400x13=exp(i*t*2400/fe*2*pi).*fd.k<tot_len-fil_len.int tot_len. s1200[20]. c1200[20]. unsigned char d[MAXSIZE]. fin=atoi(argv[3]).*s. fftw_execute (plan_a).fin-deb). idem pour initialiser fc2400x13. plan_R=fftw_plan_dft_1d(N.. s. else {sprintf(filename.int *out. plan_b. // puis retour dans le domaine reel par FFT inverse fftw_destroy_plan (plan_a). N=read(f. Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. } if ((fin-deb)>MAXSIZE) {fin=deb+MAXSIZE. // d=d(deb:fin). Cette première fonction de retrait de la valeur moyenne rappelons que l’intercorrélation qui sera utilisée pour trouver la séquence de sinusoïdes à 2400 Hz suppose un signal de valeur moyenne nulle .*rc12.k).h> #define MAXSIZE 1000000 #define NSEARCH 260 // 13 periods * 20 pts/period void remove_avg(unsigned char *d. close (f). deb=atoi(argv[2]).gnulinuxm a g .s[k][1]=0. En effet.t<520.txt (pendant du classique Makefile de notre enfance) par find_package(FFTW) et INCLUDE_ DIRECTORIES($FFTW_INCLUDE_DIR) pour la recherche d’en-tête et LINK_LIBRARIES($FFTW_LIBRARIES) pour la portabilité des bibliothèques. // s=conv(c2400x13. if (k!=deb) fprintf(stderr. passe par l’allocation de mémoire des divers tableaux exploités par les étapes intermédiaires de calcul de l’intercorrélation en passant dans le domaine de Fourier (pour rappel. fftw_destroy_plan (plan_b). nous avons dû piocher dans le script de recherche de l’arborescence disponible à http://code. org). #include <fftw3. seuil=atoi(argv[4]).et l’indice de début de la séquence analysée dans le fichier va nous servir par la suite à simuler le fait que le flux de données issu des démodulateurs de gnuradio peut avoir des tailles variables. ou le Cross Platform Make (www. cmake.] for (t=0. FFTW_ESTIMATE).fin.k++) {out[k]=d[k]-avg/fil_len.*out. d=d-dm.a.c2400[20].SEEK_SET). opération fastidieuse à implémenter par ailleurs. double a=0. une bibliothèque vient à notre secours pour éviter de réimplémenter ces fonctions : libfftw3. et MS-Windows.argv[0]).s2400[20].n. c2400x13[t][1]=sin((double)t*2400.argv[1]). Pour ajouter libfftw3.f. FFTW_ESTIMATE).fin).de N2 à Nln(N) . dans le temps. plan_R.t++) {c2400x13[t][0]=0. plan_b=fftw_plan_dft_1d(N. } La lecture du fichier de points acquis par gnuradio-companion est triviale ."%s".k++) avg+=d[k].1)/60. s. for (k=0."lseek error %d\n".60).} // 13 periodes 2400 Hz for (k=0. Le maximum d’intercorrélation identifie l’indice.k<N-NSEARCH. } for (k=tot_len-fil_len. avg+=d[k+fil_len]. Remarque gnuradio exploite un environnement de compilation visant à être portable entre un*x.k<N.c).deb. c2400x13 = (fftw_complex *) fftw_malloc (sizeof (fftw_complex) * N).O_RDONLY)./fe*2*M_PI).b]=max(real(s)).c2400x13[t][1]=0.f).

c2400x13=exp(i*t*2400/fe*2*pi). nous avons fait le choix de.t++) {rs24[l0]+=((double)out[k+t]*s2400[t]).toutd(pos24)=1.k+=8) printf("%02x ". à savoir 258 caractères.k<N-20. rs12=rs12(ll:end).. // cherche debut do l0++. et ceci ne nécessite que N multiplications en faisant glisser le motif d’une période de sinusoïde sur les points expérimentaux par pas d’une période (et non plus par pas d’un point d’échantillonnage).com GNU/Linux Magazine France N° 1 5 3 27 . for (t=0... // c2400=exp(i*t*2400/fe*2*pi). et ayant un flux de données binaires contenu dans toutd. C’est ce que nous allons faire ci-dessous avec une période de sinusoïde à 2400 Hz et une demi-période à 1200 Hz.k+=8) printf("%c". } for (k=0. // ll=find(rs24>seuil). rs12=rs12(l:end)./fe*2*M_PI). plutôt que concaténer juste le morceau final de données qui n’a pu être décodé tel que nous l’avions vu pour la radiomodem XE1203. % 2400 Hz dans 48 kHz = 20 points/periode s2400[t]=sin((double)t*2400.ll=ll(1).fr) . // t=[0:20].tout[k]+tout[k+1]*2+tout[k+2]*4+tout[k+3]*8+tout [k+4]*16+tout[k+5]*32+tout[k+6]*64)..rs24=rs24(ll:end). rc24[l0]+=((double) out[k+t]*c2400[t]). La FFT nécessitant un nombre minimum de données à traiter. rc24 . g n u l i n u x m a g. while ((rs24[l0]+rs12[l0])<2*seuil).une trame ACARS devant commencer par 2B 2A 16 16 01 puis la séquence des caractères affichables en les interprétant par leur code ASCII.k<fin-l0. } rs12[l0]=sqrt(rs12[l0]*rs12[l0]+rc12[l0]*rc12[l0]). un point peu satisfaisant qui mérite à être amélioré par l’utilisation de contrôles de gains automatiques.tout[n]=1. while (rs24[l0]<seuil). Le message décodé diffère légèrement de ce qui est obtenu avec le programme en C ci-dessus et contient : +*2. Ayant validé que le code en C fournit des résultats cohérents avec le script GNU/Octave observé initialement.1:7)’)’. alors il ne reste que l’amplitude à identifier./fe*2*M_PI). mais au prix d’un calcul lourd. for (t=0. for (k=0. } // checksomme=1-mod(sum(binaire(:. if (rs24[k]>rs12[k]) toutd[k-l0]=1.pos24=find(rs24>rs12) . [. Nous avons cependant observé une très grande sensibilité du décodage aux valeurs de seuils sélectionnés. idem pour rs24.. rs24[l0]=sqrt(rs24[l0]* rs24[l0]+rc24[l0]*rc24[l0]). while ((rs24[l0]+rs12[l0])>2*seuil). // c1200=exp(i*t*1200/fe*2*pi). L’algorithme de décodage que nous avons implémenté en C s’applique alors à ces 83000 points comme s’ils avaient été lus dans un fichier (Fig. {c2400[t]=cos((double)t*2400.k<fin-l0. n=n+1. do l0++.2). et lorsqu’une condition de seuil est atteinte (signifiant un début de trame). omis ici do l0++. 15.t<20. for (k=b.k++) {if (toutd[k]==0) tout[n]=1-tout[n-1].toutd(pos12)=0. rs12[l0]+=((double)out[k+t]*s1200[t]). l=l(1).LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. il ne reste plus maintenant qu’à comparer les amplitudes des signaux issus de chaque filtre pour estimer si le bit est plus probablement un 1 ou un 0 : l0=0.k<fin. nous achevons le décodage en inversant l’état courant des w w w.] l0=0. Le décodage des 13 séquences adjacentes d’oscillations à 2400 Hz se fait en continu sur le flux de données acquis (avec ici la contrainte d’un nombre minimum de 20 points/période×13 périodes=260 points).HB-JZTH2-M10DDS39AZ0G N47307E0060672854M380240049G N47317E0 060012986M410240050G N47333E005JLGLOHLrTLMMLFOJN8____1KHLJ2EPOJKHIL./fe*2*M_PI). l0=0.. while (rs12[l0]<rs24[l0]).n++. Si la phase est connue. n=0.. L’intercorrélation permet d’identifier les deux paramètres.10 décembre 2012 à 16:20 l’amplitude et la phase du signal. } bits selon les valeurs de toutd et affichons dans un premier temps les valeurs hexadécimales des octets décodés . rc12. // cherche fin fin=l0. toutd=(char*)malloc(fin-l0). // fin20=floor(length (s12)/20)*20. rs24=rs24(l:end).. // il faut liberer toutes les allocations de memoire (malloc) par free . page suivante). tout[n]=1. // l =find(rs12>rs24). s1200[t]=sin((double)t*1200. tout[k]+tout[k+1]*2+tout[k+2]*4+tout[k+3]*8+tout [k+4]*16+tout[k+5]*32+tout[k+6]*64). chacune encodant un état du flux de données numériques. else tout[n]=tout[n-1]. rc12[l0]=0. rc24[l0]=0. l0++. // les deux premiers 1 sont oublie’s car on se sync sur 1200 for (k=0.k++) // pos12=find(rs12>rs24).50145524@O%0G____1K038 1E00JKNGLML[2KHZ=C+05O8 N4H+AJ9OO53&4LC12MT&2""80:*8_ N$4DK7E@_Z31J@ Les données brutes sont passées dans le filtre qu’est la convolution. rs24[l0]=0./fe*2*M_PI). rc12[l0]+=((double) out[k+t]*c1200[t]).n++. else toutd[k-l0]=0. for (k=l0. printf("\n").k+=20) {rs12[l0]=0. accumuler autant de points que le nombre maximum de caractères que peut contenir un message ACARS. nous incluons ce programme dans l’environnement C++ imposé par gnuradio-companion tel que vu auparavant..t<20.t++) // t=[0:520].k<fin-l0. % verification Nous avons omis le calcul du bit de parité qui ne nous aide de toute façon pas à retrouver la valeur initiale de l’octet corrompu lors de la transmission.. c1200[t]=cos((double)t*1200. soit environ 83000 points. les codes correcteurs permettant ce genre de manipulation étant bien plus complexes qu’un simple bit en fin de chaque octet. tout=(char*)malloc(fin-l0+2). nous accumulons 40 points/bit×8 bit/caractère×258 caractères. Nous prendrons ensuite le module du produit de convolution pour éviter le cas de l’opposition de phase qui donnerait un résultat de magnitude élevée mais négatif. do l0++. } rs12=(double*)malloc(sizeof(double)*(N-b)/20).

LAbO

émis par un Airbus A319 (HB-JZT) de EasyJet suisse (cohérent pour une écoute effectuée à Besançon) et semble contenir des transmission de coordonnées (47,307 N, 6.607 E correspond bien au Nord-Est de la Franche-Comté) dont nous ne connaissons pas la signification. La fin du message est probablement corrompue.

+*R.OO-SNBH19C00ASN07LR#CFBFLR/ FR12081915430036110006PRESS REG-V 4001HA1 OR SOL 10HA1 OR SENSE LINE/IDBMC 1!

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) - 10 décembre 2012 à 16:20

Nous ne savons pas ce que « appuyer sur le bouton REG-V » effectue (apparemment une histoire de valve de régulation de la pression de la cabine), mais cela semble important pour que le pilote en informe le sol, et est un message récurent que nous retrouvons dans diverses archives de messages ACARS sur le Web ! Ces résultats ne semblent pas significativement plus mauvais que les décodeurs exploitant l’acquisition par carte son de la sortie d’un scanner radiofréquence que nous avons testé (le maintenant défunt KRACARS23 notamment, pour DOS). Les perspectives d’améliorations du récepteur de mode numérique ACARS tiennent probablement en une détection automatique d’un paramètre de seuil qui nous sert à identifier le premier bit du premier octet, dont toute la suite du message découle. Ce seuil est actuellement défini de façon statique, une façon peu apte à s’adapter aux vastes gammes de conditions de réception radiofréquence rencontrées en pratique. Par ailleurs, la découpe des trames (identifiant de l’avion, identifiant du vol, texte transmis) est actuellement embryonnaire et n’a que pour vocation de faciliter la prise en main du logiciel de décodage par l’utilisateur néophyte qui pourrait être rebuté par la lecture des séquences brutes d’octets. Toujours suivant les préconisations de http:// w w w.scancat.com/Code-30_html_ Source/acars.html, après avoir validé les 5 octets de synchronisation et d’en-tête (SOH, ASCII 0x01) en début de trame, nous extrayons l’identifiant de l’avion (octets 6 à 12), l’identifiant de début de texte (STX, code ASCII 0x03) avant de rechercher l’identifiant du vol (octets 22 à 27), qui sont les informations les plus utiles. Ensuite, dans le meilleur des cas, si le message est décodable, les caractères ASCII affichables au-delà du 28ème octet sont fournis.

Figure 15 : Décodage par un bloc gnuradio-companion implémentant les algorithmes de décodage décrits dans le texte d’une trame ACARS enregistrée dans un fichier audio échantillonné à 48 kéchantillons/s. Remplacer le fichier audio par la sortie du bloc osmosdr pour un traitement en temps réel (blocs en gris foncé) des données permet de bien identifier le début de transmission, mais le décodage du message échoue souvent, probablement du fait d’un mauvais ajustement des seuils.

Un exemple de décodage en temps réel du flux de données transmis par le bloc décrit dans ce paragraphe est (tout d’abord la valeur des octets reçus, puis leur interprétation dans le code ASCII pour les caractères affichables) :
63 70 5c 72 27 7d 04 09 5c 42 43 26 7e 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 2b 2a 16 16 01 47 2e 45 49 2d 44 54 4e 15 48 31 35 02 44 35 33 43 41 5a 30 32 34 33 23 44 46 42 33 2c 33 39 2c 30 35 39 2c 30 34 35 39 39 2c 30 31 33 36 2f 56 31 30 32 2c 31 32 2c 32 32 32 2c 32 39 32 2c 30 33 2c 30 31 2c 30 30 30 30 30 2f 56 32 30 32 2c 30 38 2c 30 38 31 2c 30 36 39 2c 30 30 2c 30 30 2c 30 30 30 30 30 2f 56 33 30 32 2c 30 36 2c 31 34 36 2c 33 31 32 2c 30 36 32 32 2f 56 34 31 30 2c 30 36 2c 32 32 33 2c 30 32 35 2c 30 36 32 31 2f 56 35 30 30 2c 30 30 2c 30 30 30 2c 30 30 30 2c 30 30 30 30 2f 56 36 30 30 2c 30 30 2c 30 30 30 2c 30 30 30 2c 30 30 30 30 2f 56 37 30 34 31 2c 30 38 37 2c 30 30 30 36 31 2c 32 32 32 32 32 32 32 32 32 32 32 47 31 31 2f 56 38 30 34 31 2c 30 38 36 2c 30 30 30 38 31 17 24 3e 7f cp\r’}\BC&~+*G.EI-DTNH15D53CAZ0243#DFB3,39,059,04599,0136/V102,12,222,292,03,01,00000/V202,08,081,069,00, 00,00000/V302,06,146,312,0622/V410,06,223,025,0621/V500,00,000,000,0000/V600,00,000,000,0000/V7041,087,00 061,22222222222G11/V8041,086,00081$>

Nous constatons que la séquence acquise est trop longue avant le préambule de 0x2b 0x2a 0x16 0x16, avec la séquence des 0x7f qui correspond aux octets à 2400 Hz pour la synchronisation du récepteur avec l’émetteur. Néanmoins, le décodage s’effectue bien, avec l’identification d’une trame émise par EI-DTN, un A320 de Alitalia qui cette fois volait au cours du trajet AZ0243 entre Londres et Milan (cohérent avec une réception depuis Paris vers 21h15 alors que cet avion est supposé partir, en l’absence de retard, de Londres à 19h50 pour arriver à Milan vers 21h45). Ici encore, le contenu du message semble cohérent mais incompréhensible. Ainsi, sans être parfaite, notre implémentation du décodage en temps réel des trames ACARS sous gnuradio-companion permet d’obtenir l’identification de la majorité des avions passant à proximité du récepteur, et dans certains cas des messages aussi longs que :
23

http://www.qsl.net/g4hbt/zips/krcrs12.zip

28

G N U / L i n u x M a g azine France N°153

www.gnulinuxm a g . c o m

LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR)

Ainsi, le message brut :
2b 2a 16 16 01 32 2e 2e 48 42 4a 4b 4c 15 31 37 30 02 4d 33 33 37 31 2f 32 37 32 37 31 39 33 34 4c 53 47 47 45 4e 5a 56 2f 4e 20 2f 32 36 32 2f 20 34 33 2f 33 30 32 2f 2d 20 33 39 2f 41 55 +*2..HBJKL170M33AGS0871POA01GS0871/27271934LSGGENZV/N47 17.1/E 41 34 54 6 47 53 30 38 37 31 50 4f 41 30 31 47 53 30 38 37 20 31 37 2e 31 2f 45 20 20 36 20 31 2e 35 4f 52 50 2f 31 35 03 43 6a 7f 1.5 /262/ 43/302/- 39/AUTORP/15Cj

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) - 10 décembre 2012 à 16:20

se traduit en :
Aircraft=..HBJKL STX Seq. No=4d 33 33 41 M33A Flight=GS0871 POA01GS0871/27271934LSGGENZV/N47 17.1/E 6 1.5 /262/ 43/302/- 39/AUTORP/15ETX

soit un Falcon 2000 répertorié par les autorités suisses24 comme basé à Genève, entendu vers 21h45 depuis Besançon, avec l’identifiant de vol GS0871, de nouveau fournissant des coordonnées GPS en accord avec la localisation du récepteur. Le lecteur possédant entre 15 et 20 millions de dollars pourra considérer de s’acheter ce jouet d’occasion. D’un autre côté, un tel investissement permet de réaliser une matrice de 1000*1000 récepteurs EZCAP et ainsi de former un récepteur RADAR à balayage de faisceau (http://www.haarp.alaska.edu/), autrement plus intéressant qu’une boîte de conserve volante. Par ailleurs, on notera une certaine cohérence dans la séquence des messages :
Mon Aug 27 22:03:31 Aircraft=.PH-XRX STX Seq. No=53 35 32 41 Flight=HV5078 ETX Mon Aug 27 22:04:30 Aircraft=.PH-XRX STX Seq. No=53 35 33 41 Flight=HV5078 ETX Mon Aug 27 22:09:00 Aircraft=.PH-XRX STX Seq. No=53 35 35 41 Flight=HV5OHG ... 2012 S52A 2012 S53A 2012 S55A

des arguments (valeurs numériques, chaînes de caractères) et nous désirons exploiter cette possibilité. Tout commence par la définition des arguments et l’ajout des prototypes associés dans l’interface graphique (répertoire grc), i.e. le fichier XML descriptif du bloc. Les balises définissant un passage de variable sont <param> ... </param> qui prennent comme champs le nom de la variable associée <key> et la nature de cette variable, par exemple un flottant <type> real </type>. Cette déclaration de variable doit impérativement se situer avant le paramètre <sink> sous peine d’obtenir un message d’erreur (cryptique) au chargement du bloc. Il reste dans le fichier XML à passer la variable au programme C++ en complétant la méthode <make> par le paramètre, dans notre cas acars. decodeur($seuil) (avec seuil le nom de la variable tel que définit dans key). Du point de vue de la déclaration de la classe (répertoire include), la signature de la fonction d’entrée ainsi que celle du constructeur de la classe doivent être adaptées pour contenir l’argument acars_make_decodeur (float seuil1); dans toutes ses occurrences. Finalement, le constructeur, au niveau de l’implémentation de la classe C++ elle-même (répertoire lib), reçoit l’argument sous forme de
acars_decodeur::acars_decodeur (float seuil1). Dans notre cas, une

indiquant que cette information (S52A, S53A, S55A) est convenablement décodée. Si le lecteur, en lisant ce code et en le mettant en œuvre, laisse tourner son PC la nuit dans l’espoir de recevoir le message d’un avion excessivement en retard, ou se réveille le matin en sursaut pour savoir combien de passages d’aéronefs il a enregistré - le mal est fait, le virus de la réception de signaux radiofréquences a infecté une nouvelle cible, le seul remède est de... lire le code pour l’améliorer et augmenter ses performances de décodage.

consigne de seuillage est ainsi transférée depuis l’interface graphique de gnuradio-companion vers la classe C++ sans nécessiter de recompilation de la bibliothèque (bloc). Un exemple simple de passage d’un unique paramètre est facilement accessible dans l’archive de gnuradio sous
gnuradio/gr-digital/*/digital_ diff_decoder_bb.* : la recherche de

5.3 Passage de paramètres à l’instanciation
Le dernier point qui peut faciliter la vie du développeur est de pouvoir changer, en remplissant le champ correspondant dans le bloc gnuradio-companion, des paramètres des blocs utilisés dans l’application, sans être obligé de recompiler la bibliothèque correspondante. Nous constatons que de nombreux blocs acceptent
24

l’occurrence du terme modulus permet de se retrouver dans le cheminement de la variable entre les divers fichiers définissant le bloc, et de s’en inspirer pour notre propre application (Fig. 16, page suivante).

http://www.bazl.admin.ch/fachleute/luftfahrzeugregister/index.html?lang=en

w w w. g n u l i n u x m a g.com

GNU/Linux Magazine France N° 1 5 3

29

LAbO

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) - 10 décembre 2012 à 16:20

Figure 16 : Le bloc complété par le passage de deux arguments que sont une valeur de seuil (flottant) et le nom de fichier d’enregistrement des données acquises (chaîne de caractères). Nous constatons dans l’xterm que les données sont bien stockées dans l’emplacement annoncé, et les valeurs sont cohérentes avec celles affichées par gnuradio-companion.

5.4 Passage dynamique de paramètres
Le passage de paramètres selon la méthode proposée ci-dessus définit la valeur de l’argument (seuil) au moment du lancement de l’application gnuradiocompanion par passage de paramètres au constructeur de la classe associée au bloc. Une fois ce paramètre fourni, il est impossible de le modifier depuis l’application en cours d’exécution. Cependant, de nombreux blocs permettent de faire varier des variables depuis des composants graphiques représentant des ascenceurs (sliders) : comment font-ils ? Un argument additionnel à la déclaration du bloc dans le fichier XML permet de définir une méthode pour mettre à jour une variable membre lorsque le paramètre qui lui est associé dans l’interface graphique change de valeur : dans
Figure 17 : Le bloc de décodage des trames ACARS accepte désormais la définition du paramètre seuil au moyen d’un ascenceur (bloc slider) avec modification de la valeur en cours d’exécution. Dans cet exemple, nous constatons qu’un ascenceur associé à la variable threshold a été défini avec une valeur par défaut de 150 (tel qu’annoncé dans le terminal en bas de gnuradio-companion), et changer la valeur dans l’onglet associé de l’interface graphique change bien la valeur du paramètre exploité lors du décodage des trames.

30

G N U / L i n u x M a g azine France N°153

www.gnulinuxm a g . c o m

l’exploitation sur des signaux plus « intéressants » que sont le GPS25 ou le GSM serait ambitieuse.org/wiki/ACARS. 17). avant de convertir l’algorithme en C pour inclusion dans gnuradio.$filename)</make> <callback>set_seuil($seuil)</callback> <param> <name>Threshold</name> <key>seuil</key> <type>real</type> </param> dont la signature associée est déclarée dans le fichier de définition de l’interface de la classe (répertoire include) : public: ~acars_decodeur (). nous avons identifié le cheminement du flux de données afin de développer nos propres blocs de traitement. est disponible à http://jmfriedt.fr/2012/04/spring-news-in-gnss-and-sdr-domain.tar. nous vérifierons que chaque fois que la valeur du paramètre seuil est modifiée en faisant glisser un ascenceur dans l’interface graphique.com GNU/Linux Magazine France N° 1 5 3 31 . Figure 18 : Exemple de trames ACARS acquises au moyen d’un récepteur EZCAP muni d’une antenne formée d’un bout de fil de cuivre émaillé de ≃50 cm de longueur.} Ainsi. ici à Athènes (Grèce). nous complétons la définition du bloc par le nom de la méthode appelée pour la mise à jour du paramètre (argument callback) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Nous nous sommes en particulier concentrés sur les périphériques faible coût centrés sur le composant E4000 couplé au convertisseur analogique-numérique RTL2832U.blogspot. un collègue d’un des auteurs (JMF) nous faisait remarquer récemment comment l’époque de Capitaine Crunch et de la naissance d’Apple devait être une époque bénie du hack. Au-delà de la simple utilisation des blocs de traitement de signaux fournis avec l’outil gnuradio.org/documentation/gnss-sdr-operation-realtek-rtl2832uusb-dongle-dvb-t-receiver démontrent le résultat impressionnant d’utiliser un récepteur de télévision numérique terrestre pour recevoir des signaux issus de satellites situés à une distance de 20000 km. Nous profitons de ces pages pour exprimer notre désaccord avec cette nostalgie : la disponibilité de puissances de calcul quasi-infinies. g n u l i n u x m a g.html mais surtout http://www. Conclusion Nous nous sommes efforcés de proposer une démarche de travail pour exploiter un récepteur radiofréquence fournissant un flux de données I et Q en vue de décoder des trames numériques. nous implémentons la méthode (setter) qui modifie le contenu de la variable membre (privée) : void acars_decodeur::set_seuil(float seuil1) {printf("new threshold: %f\n". w w w.cgran. Nous avons démontré la capacité à implémenter des traitements en temps réel sur le flux d’informations issu du récepteur en prototypant dans un premier temps sous GNU/Octave sur des enregistrements.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SOFTWARe DeFIneD RADIO – SDR) le fichier contenu dans le répertoire grc. et finalement. pour un coût abordable pour une majorité de la population 25 http://michelebavaro. la valeur est bien modifiée dans le bloc de traitement de l’information correspondant (Fig. incluant tous les concepts développés dans cet article. mais certainement source de nombreuses découvertes.fr/gr-acars.seuil1).gnss-sdr.fflush(stdout). Sans relation directe avec cette présentation. page suivante). Parmi les perspectives. 18 et 19. void set_seuil(float seuil1)._seuil=seuil1.decodeur($seuil.fr) . Cette activité rend les heures d’attente dans les aéroports beaucoup plus ludiques. L’archive finale de ce développement (Fig. dans la bibliothèque.free.gz ou sur le site de CGRAN à www.10 décembre 2012 à 16:20 <make>acars.

I’m learning about a system.gnulinuxm a g . et fournissent un complément idéal au décodeur ADS-B présenté au début de ce document.rus. I don’t do that anymore at all. And if I do it. d’un avion de Transavia.ec/. où nous obtenons la majorité des documents de la bibliographie.com/index-fr. c o m . et des documentations ou échantillons de composants électroniques facilement disponibles.html valide la présence. Computers. systems. J. tandis que le site airliners. Le gouvernement équatorien mérite toute notre gratitude. Bodor nous a informés de l’existence des récepteurs DVB à base de E4000+RTL2832U et de l’engouement qu’ils ont suscité dans la communauté des développeurs de SDR.html (lu en septembre 2012). Les informations acquises par ACARS sont donc cohérentes avec les autres données disponibles sur les sites web associés au suivi du trafic aérien.LAbO Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. A computer is a System.10 décembre 2012 à 16:20 Figure 19 : Analyse des trames ACARS obtenues en temps réel par notre module gr-acars : le site web radarvirtuel. that’s my bag. do you understand? If I do what I do. et autres actions politiques qui dépassent le cadre de cet article. sans en vérifier l’origine.wikipedia.fr) . 26 27 http://en. à proximité de Besançon (position de l’antenne réceptrice). I do it for one reason and one reason only. it is only to explore a system.slate. The phone company is a System.org/wiki/John_Draper http://www.lib. comme nous avons tenté de le démontrer dans cet exposé. I don’t do that. Carry (FEMTOST) ont. mais il n’y a aucun doute que cette découverte fortuite était précédée d’heures d’analyses des protocoles de communication et d’études fastidieuses des conventions de communication des réseaux téléphoniques d’antan (John Draper n’était-il pas ingénieur en dehors de ses activités de compréhension des systèmes téléphoniques) : un bon hack est impossible sans une compréhension détaillée de la technologie sous-jacente. 32 G N U / L i n u x M a g azine France N°153 www. d’Europe occidentale et d’Amérique du Nord.com/articles/technology/the_spectator/2011/10/the_article_that_inspired_steve_jobs_secrets_of_the_little_blue_. Nous osons copier ici les paroles reproduites du site de Wikipédia26. Les interlocuteurs de la mailing list osmocom-sdr ont levé un certain nombre d’incertitudes sur les données techniques des récepteurs radiofréquences à base de RTL2832U et E4000. amélioré le manuscrit. pour leur sagesse27 : Remerciements D. The phone company is nothing but a computer. font de l’époque actuelle une période au moins aussi excitante pour le hack que l’époque des blue box et autres activités de phreaking [14].single. par leurs corrections lors d’une relecture. Boibessot (Armadeus Systems) et E. La légende du détournement d’un sifflet pour communiquer avec les routeurs téléphoniques est certes attractive.net associe une immatriculation d’avion (PH-RXA) à un exploitant. un mode de communication rapide et sans censure pour les domaines et les régions qui nous concernent. ne serait-ce que pour son hébergement de http://gen.

Application Note 1298 disponible à cp.pdf [8]  M.dk/project/softgps/GNSS_SummerSchool_DGC. W.gov/SP-4227/Uplink-Downlink. Software Defined Radio Architectures. Tucson Amateur Packet Radio Corporation . disponible à http://jmfriedt.fr/ [14]  S. Un magazine complet pour s'initier comprendre progresser et explorer chez votre marchand 33 26 octobre GNU/Linux Magazine N° 1 5 3 de France journaux w w w. g n u l i n u x m a g. Microwave and RF design . N.edu/yuegroup/Teaching/ECE594BB/ Lectures/steer_rf_chapter1. N.gov/Monograph/ series3/complete1. McDermott.jpl. Parmi ceux que nous avons trouvé de peu d’intérêt car loin de la pratique. W. [5]  J.nasa. Communication Theory. disponible à http://descanso. Mudgway.pdf [11]  T.org/redmine/attachments/download/246/06foster-adsb. Wireless Digital Communications: Design and Theory 2nd Ed. GNU Radio Conference (2011).pdf [2]  J.ece. Uplink-Downlink . W. Madani. GNU/Linux Magazine France.ucsb.-M Friedt & S.jpl. D. Improving STM32F101xx and STM32F103xx ADC resolution by oversampling.free.free. NASA SP-2001-4227.An Introduction. Simon.pdf [6]  Note d’application AN2668. Tracking Aircraft With GNU Radio. 3. GNU/Linux Magazine France 139 (Juin 2011).dk/project/ softgps/ et en particulier http://kom. Thomas & S. Akos.10 décembre 2012 à 16:20 HORS-SÉRIE 63 GNU/LInuX MAgAZInE Le hard est de retour ! Débutez en et Électronique numérique Systèmes embarqués Partez de rien et montez en puissance : Arduino / Atmel AVR Ti Launchpad / MSP430 STM 32 Discovery / Cortex-M4 ACME Aria / ARM9 Raspberry Pi / ARM11 Sous réserve de toutes modifications. Deep Space Communications and Navigation Series Vol. Auto et intercorrélation. Birkhäuser Boston (2007) ainsi que les transparents à http://kom. 1957-1997. software defined radio . disponible à http://gnuradio. Wozniak & G.J. Hors-Série 24 (Février 2006). Co-Founded Apple. The NASA History Series (2001).TAPR (1998) [12]  Agilent. Kenington RF and baseband techniques for software defined radio Artech House (2005) [4] L  a littérature sur SDR pullule d’ouvrages plus ou moins intéressants. ST Microelectronics. Systems and Functions Wiley (2003). K. Guinot. Deep Space Communications and Navigation Series Vol.pdf [3]  P.pdf.fr/LM_sat1. disponible à http://jmfriedt.aau. disponible à http://descanso. Dillinger. Tata Mcgraw Hill Publishing (2006) [10]  N.A History of the Deep Space Network. Steer. Inc (2010) dont le premier chapitre est disponible à http://www.B. Smith. Borre. Norton & Company (2007) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.LA RÉCePTIOn RADIOFRÉQUenCe DÉFInIe PAR LOGICIeL (SDR) Références [1]  K.nasa. A Software-Defined GPS and Galileo Receiver: A Single-Frequency Approach. ou encore M.enabling technologies Wiley (2002).fr) .com . disponible à partir de history. iWoz: Computer Geek to Cult Icon: How I Invented the Personal Computer. Digital Modulation in Communications Systems . Simon. Alonistioti. ou M. recherche de ressemblance dans les signaux : application à l’identification d’images floutées. and Had Fun Doing It. Bandwidth-Efficient Digital Modulation with Application to Deep-Space Communications.-M Friedt. La réception d’images météorologiques issues de satellites : principes de base.K.literature. Rinder & S.pdf [9] T  .gov/Monograph/ series9/Descanso9_Full_rev2. 2008 [7]  D.nasa.aau. Chandra Sekhar. que le lecteur pourra éviter sans craindre de rater trop d’informations.com/litweb/ pdf/5965-7160E. Bertelsen. Tuttlebee.agilent.M. Jensen. Hamkins & M.K. Foster. P. Autonomous Software-Defined Radio Receivers for Deep Space Applications.a systems approach.G..H.pdf [13]  J. 9. SciTech Publishing.

aussi depuis quelques années deux alternatives ont émergé au sein des principales distributions Linux. Par exemple. Ainsi. Systemd va aussi jouer le rôle de coordinateur et d’arbitre pour gérer dépendances et conflits. D’un côté. Il ne s’agit pas ici de comparer ces deux successeurs du vénérable init. systemd lui passera la socket. le vénérable processus init et ses scripts de service disparaissent petit à petit des systèmes Unix et de nos distributions Linux préférées. dorénavant. peu robuste et limitée.d/ et dont l’appel avec les paramètres start ou stop produit les messages : Démarrage de . on trouve les partisans de Upstart (Ubuntu) et de l’autre les supporters de systemd (Fedora. Mais au-delà. Pourquoi ce choix partial ? Parce que systemd me semble mieux documenté.. Debian et les autres ? systemd très probablement. ainsi les «  clients  » bloqués pourront être servis ! 2 Concepts et architecture de systemd Il faut imaginer chaque unité comme un objet à part entière. systemd peut lancer en parallèle des processus interdépendants ! Comment cela ? Systemd va anticiper et créer une socket Unix pour tout service à démarrer.fr) . la gestion et le contrôle des PID des processus de service ainsi que ceux de leurs enfants sont à la charge de systemd. ce sont ces scripts shell. possédant systemd s’appelle une « unité » (unit). même indirectement).. Mandriva. connaissant l’arbre de dépendances des services. ainsi que leur mécanique de lancement via /etc/rc. mieux architecturé et surtout plus universel au vu du nombre de distributions qui l’ont choisi ou qui vont l’adopter. Ces scripts. Pourquoi systemd est-il meilleur que init ? (voir [LPOE2]) Dans un souci de rationalisation et d’optimisation. ceci explique cela. systemd adopte plusieurs techniques astucieuses : tout d’abord. OpenSuSE et bientôt RedHat et Debian).... quel sera le remplaçant sur RedHat. Notons que l’auteur de systemd – Lennart Poettering [LPOE1] – est employé chez RedHat.. [OK].10 décembre 2012 à 16:20 Systemd vainqueur de Upstart et des scripts « System V » ? par Jérôme Delamarche [Consultant indépendant en technologies open source] Après plus de 30 ans de service (!).En COUVeRTURe Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Si la technologie « Upstart » est connue des adeptes d’Ubuntu.. mais d’expliquer le fonctionnement de systemd. mais certains la trouvent lente. sont un héritage du vénérable Unix System V qui date de 1983. c o m . il est naturellement capable de paralléliser les lancements de processus (on peut lancer A et B s’ils ne dépendent pas l’un de l’autre.. L’objectif de cet article est de vous préparer à la migration vers cette nouvelle technologie. Le composant de base géré par 34 G N U / L i n u x M a g azine France N°153 www.gnulinuxm a g . [OK] ou Arrêt de . situés sous /etc/init. De même pour les logs. les « clients » d’un service (c’est à dire les services dépendants) vont se connecter dessus alors que le service réel n’est peut-être pas encore actif. systemd va réaliser des tâches qui étaient auparavant laissées au bon-vouloir du développeur des scripts System V. 1 Introduction Vous conna issez cer ta inement les scripts dits «  System V  » ou «  de service  » ? Vous savez. Cette architecture est simple.. Quand celuici le sera. Pour améliorer les performances du démarrage.

target (équivalent au runlevel 3 de RedHat/Fedora) ou graphical. graphical.service sera associé à une unité de type service.target. unités invoquées au démarrage ou lors de l’arrêt du système ou quand l’ordre correspondant est donné par la commande systemctl (voir §4). que faire quand l’utilisateur appuie sur Control-Alt-Suppr (lien symbolique vers reboot. Les « anciens » scripts de service peuvent être réécrits sous forme d’unités pour systemd.target sysinit.service (voir plus haut le principe de l’anticipation par création de sockets Unix). il a fallu concevoir des unités prédéfinies (ou unités spéciales). « inactif » ou « en erreur » (active.target halt. failed).target ctrl-alt-del.target.target socket unités invoquées très tôt lors du démarrage et indépendamment du runlevel. par exemple « actif ». vous noterez dès à présent que l’architecture de systemd fait un usage 2. swap. reboot. Par exemple.target (niveaux 2.target mount automount path gestion du fichier /etc/fstab.2 Unités prédéfinies Mais pour pouvoir se substituer au vieil init. lancé par le noyau au démarrage. pour la gestion des systèmes de fichiers auto-montés. shutdown. poweroff. pour l’activation des zones de swap (pas utilisé sur Fedora 17).target. L’activation du LVM en est un exemple. rescue.3.4). FIFO ou INET.1 Types d’unités Les unités sont des objets typés qui possèdent un état. target local-fs.target (niveau 5) et reboot. rescue. quoique le nombre des unités spéciales soit très consé- Nous allons voir que chaque unité possède son propre fichier de configuration.socket va démarrer le service nscd.target. default.target (niveau 1). emergency. un accès à la socket nscd.target service permet de déclencher et superviser des processus lancés à travers des scripts System V ou directement par systemd. Éventuellement les répertoires peuvent être créés par systemd. g n u l i n u x m a g.conf.target network.target (niveau 6). pour activer des unités sur le déclenchement de timers.target. est /usr/bin/systemd qui n’est autre qu’un lien symbolique vers /usr/lib/systemd/ systemd.fr) . inactive.Systemd vainqueur de Upstart et des scripts « System V » ? SySTemD généralement sa propre configuration.target timer snapshot swap 2. D’ailleurs le premier processus. C’est l’unité déclenchée en premier. le fichier sshd. Ces unités sont en fait des liens symboliques vers poweroff. (où X prend les valeurs 0 à 6) permet de simuler les changements de runlevel. de type Unix. certaines correspondant directement à la valeur du champ action des lignes du fichier /etc/inittab : abondant des liens symboliques. w w w. il faut maintenant se représenter concrétement comment sont conçues ses fameuses unités. mais ce ne seront pas les seuls ! (tableau non exhaustif) Nom de l’unité prédéfinie Description Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. multi-user. pour permettre un save/rollback pendant des changements de configuration de service.10 décembre 2012 à 16:20 2.target.com GNU/Linux Magazine France N° 1 5 3 35 . lien symbolique vers multi-user. pour le montage des systèmes de fichiers et l’activation du swap. La configuration est située dans le répertoire /etc/ systemd/ et le fichier de configuration principal va s’appeler /etc/systemd/system.target). permet d’activer d’autres services quand des fichiers ou des répertoires sont modifiés. mais le type de l’unité sera donné par le suffixe du nom du fichier de configuration. pour gérer correctement les dépendances entre les services et le réseau. Systemd est composé de nombreux exécutables situés sous /usr/lib/systemd/. quent. Les types d’unités supportés sont : Nom du type d’unité Description basic.target (équivalent au runlevel 5).target définit des tâches à déclencher très tôt. pour regrouper des unités logiquement ou pour définir des unités prédéfinies dites «  unités spéciales » (voir ci-dessous). elle est associée à un service..target (niveau 0). remote-fs. Si vous ne vous en doutiez pas déjà. runlevelX.. Par exemple.3 Organisation et syntaxe des fichiers de configuration Si on conçoit bien le besoin d’imiter le comportement de init.

ou --confirm-spawn sur sa ligne de commandes.target AllowIsolate=yes [Install] Alias=default. certains répertoires existent avec le même nom à la fois sous les répertoires /etc/ systemd/system/ ET /lib/systemd/system/.wants/.target doit être activée pour 36 G N U / L i n u x M a g azine France N°153 www.target qui est le nom de la première unité lancée par systemd (pour information.En COUVeRTURe Pour connaître l’emplacement des fichiers de configuration de systemd.2).conf. le paramètre WantedBy=xxxx indique qu’il faudra créer un lien symbolique dans le répertoire /etc/systemd/ system/xxxx. systemd propose un mode « pas-à-pas » pour permettre la résolution des problèmes si vous lui passez le paramètre systemd.target qui. en cas de problème. MountSwap DefaultControllers 2.yes tèmes de fichiers listés dans /etc/fstab. After. Une valeur usuelle est journal. /sbin et /lib sont en fait des liens symboliques sur /usr/bin.special(7) Requires=multi-user. Le fichier /etc/systemd/system.confirm_ spawn=1 comme option du noyau.conf est un fichier « à la .  L’affichage de la valeur de la variable systemdsystemunitpath avec la commande pkg-config montre bien que le répertoire /etc/systemd/ system/ est prioritaire.target Certaines options peuvent être surchargées en passant des options au noyau ou sur la ligne de commandes systemd. Notez que sur votre distribution.target Conflicts=rescue. Wants. choix du cgroup. Note 2 : Sur la distribution Fedora 17.fr) . Par exemple. systemd analyse ensuite le contenu du fichier bien nommé /etc/systemd/system/default. Before. il est possible d’utiliser la commande suivante : # pkg-config systemd --variable=systemdsystemconfdir /etc/systemd/system # pkg-config systemd --variable=systemdsystemunitdir /usr/lib/systemd/system Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. dans ce cas.gnulinuxm a g . et dans ce cas leur contenu diffère. des sections supplémentaires et leurs lots de paramètres seront nécessaires. Enfin du concret ! Nous pouvons examiner le contenu de ce fichier et commencer à explorer la syntaxe des fichiers de configuration des unités. pour connaître l’emplacement des fichiers de configuration des unités. Also indique des unités additionnelles à installer en plus.INI ». contenant une rubrique [Manager] et des options globales. son fichier de configuration principal est /etc/systemd/user. Un fichier de configuration d’unité contient les rubriques suivantes : Nom de la rubrique Description [Unit] décrit le service et les règles de dépendances à l’aide des paramètres : Description. dont les principales sont listées dans ce tableau : Paramètre Description Valeur par défaut Si les fichiers qui sont sous /etc/systemd/system/ sont en fait des liens symboliques sur leurs homonymes situés sous /lib/systemd/system/. utilisée ici comme exemple. /usr/sbin et /usr/lib.3. examinons le contenu du fichier /etc/systemd/system/default. sur la Fedora 17 lancée en mode graphique. cpu MountAuto Puis. je suis un adepte de la commande readlink qui permet de connaître le nom final du fichier référencé par une suite de liens symboliques) : # readlink -f /etc/systemd/system/default. c o m . qui exploite un processus supplémentaire (voir §3. les répertoires /bin. honore les montages de sys. LogLevel LogTarget définit le niveau de verbosité.target [Unit] Description=Graphical Interface Documentation=man:systemd. est un lien symbolique vers /lib/systemd/system/runlevel5.target /lib/systemd/system/graphical. info destination des messages de syslog logs. Requisite.10 décembre 2012 à 16:20 Notes Note 1 : systemd peut être invoqué par un utilisateur avec l’option --user. honore l’activation des zones de yes swap listées dans /etc/fstab.target After=multi-user.target # cat /etc/systemd/system/default. Par exemple. Le paramètre Requires= indique que l’unité multi-user.4 Exemples de configuration À tout seigneur tout honneur. selon le type de l’unité. il est possible d’utiliser la commande suivante : Nous retrouvons bien les sections [Unit] et [Install] dont nous avons parlé au §2. Condition*. mais nous occulterons cette possibilité ici. [Install] décrit ce qu’il faut faire quand on invoque systemctl enable | disable. Requires.target.

target.service rescue.service [Service] EnvironmentFile=/etc/sysconfig/sshd ExecStartPre=/usr/sbin/sshd-keygen ExecStart=/usr/sbin/sshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID [Install] WantedBy=multi-user.10 décembre 2012 à 16:20 que default. mais ce n’est pas tout ! Comme il existe un répertoire nommé /etc/systemd/system/ sysinit.com GNU/Linux Magazine France N° 1 5 3 37 ..target After=basic.target). il se transpose aisément pour la directive Requires=) : Prenons l’exemple de l’unité sysinit.target soit considérée comme active. mais en l’absence de précision sur l’ordonnancement.target.target rescue.target. mdmonitor-takeover.service -> /usr/lib/systemd/system/lvm2-monitor.target [Unit] Description=Muti-User Documentation=man:systemd.fr) .target dépend aussi de toutes les unités dont le nom apparaît dans les liens symboliques situés dans ce répertoire : # cd /etc/systemd/system # ls -l sysinit. Le paramètre After= précise qu’il faut attendre la fin de l’exécution de l’unité multi-user.target ne doit pas être lancée si rescue.wants/.target Vous commencez à comprendre le mécanisme ? On nage en pleine récursivité : w w w.target contient un nouveau paramètre intéressant : [Unit] .. l’unité sysinit. Dans le cas d’un changement de runlevel. target (il existe aussi un paramètre Before=.target.wants ..service . Parfois.target.. le lien symbolique default.target auditd.target. il faudra bien lancer des processus ! Notons que la rubrique [Install] définit un Alias qui porte le même nom que celui défini par l’unité graphical.special(7) Requires=basic.target et sockets. mais à un moment donné.target doit être activée après multi-user. systemd permet d’externaliser les dépendances d’une unité en permettant l’utilisation de répertoires associés à des liens symboliques (encore !). g n u l i n u x m a g. une unité peut dépendre de très nombreuses autres unités. Pour éviter cela. donc.target On se doute qu’il va falloir d’abord activer les systèmes de fichiers locaux ainsi que le swap avant de réaliser d’autres tâches.Systemd vainqueur de Upstart et des scripts « System V » ? SySTemD Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Wants=local-fs. Wants= indique que l’unité sysinit. Reprenons  : default.service est : [Unit] Description=OpenSSH server saemon After=syslog.service Les dépendances se règlent donc simplement à coups de création et destruction de liens symboliques.target Conflicts=rescue.. comme indiqué par son fichier de configuration. il est normal de ne pas lancer le mode multi-utilisateur et encore moins l’interface graphique ! Le paramètre AllowIsolate= est un hack : il permettra de faire en sorte qu’on puisse imiter le changement de niveau d’exécution comme on le faisait avec init.target network.service rescue. La configuration de sysinit.target swap. ce qui provoquerait l’écriture de directives Wants= ou Requires= assez fastidieuses avec le souci de devoir modifier ces lignes chaque fois que les dépendances sont modifiées.service qui est référencée par un lien symbolique situé sous /etc/systemd/system/multi-user. L’unité rescue. mais ici. Le paramètre Alias= de la rubrique [Install] indique que lors de l’activation de cette unité (dont le véritable nom est runlevel5.target pointera bien vers la bonne unité. Le principe est le suivant (nous le décrivons pour la directive Wants=.target .target ou ses dépendances seront arrêtés.target : ce n’est pas un problème car l’unité graphical. on constate que basic. elle dépend de local-fs.. les exécutions sont parallélisées). Rôle parfaitement rempli par la commande systemctl que nous verrons dans un instant. En continuant l’examen des unités selon leurs dépendances. lvm2-monitor.service -> /usr/lib/systemd/system/mdmonitor-takeover.target AllowIsolate=yes [Install] Alias=default. Ce comportement est différent du Requires= qui stipule que l’unité n’est activée que si toutes les unités dont elle dépend sont activées avec succès (c’est une forme de transaction !). tous les processus qui ne seront pas gérés par l’unité default. Prenons un autre exemple : comment est lancé le démon sshd  ? Il est décrit par l’unité /lib/systemd/system/sshd. il faudra créer un alias sous la forme d’un lien symbolique nommé default.target.target cette unité dépend de basic.target est déjà activée.target correspond au runlevel 1.target avant de finir l’exécution de default. Que fait cette unité ? # cat /lib/systemd/system/multi-user. Le paramètre Conflicts= indique que l’unité default.target.target ! Eh oui : autant décrire tous les liens symboliques dans des fichiers de configuration et laisser les outils fournis avec systemd gérer correctement ces liens.target et swap. Le contenu du fichier sshd.wants/.target se jouant après multi-user.target dépend de sysinit.target sera activée même si l’une des unités dont elle dépend échoue lors de son activation.

0. D’autres paramètres sont disponibles (voir man systemd. En effet.nodev.service). il faudrait donc définir autant d’unités que de terminaux virtuels à Ce qui permet d’avoir au démarrage un répertoire /media associé à un système de fichiers de type tmpfs.target. donc systemd Nous constatons la présence d’une rubrique [Socket] contenant les paramètres de création des sockets à créer. dbus.target.nosuid.unit). La configuration des services permet aussi d’imiter la fonctionnalité du respawn proposée par init.conf (2).target 2.0.En COUVeRTURe Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. [Service] Restart=always RestartSec=0 TTYPath=/dev/%I . puis une socket TCP (ListenStream) à l’écoute sur le port cherche la configuration de cette unité (4) et l’interprète. donc 38 G N U / L i n u x M a g azine France N°153 www. Sur notre Fedora 17.0:631 [Install] WantedBy=sockets.socket). Mais il existe un répertoire multi-user. systemd va rechercher une unité dont le nom est getty@. target). Pour imiter ce comportement. Regardez le contenu de la configuration de l’unité getty@.gnulinuxm a g . target.fr) . Ce fichier contient une directive After=multi-user . 631 pour toutes les adresses IP de la machine. un service dispose d’une nouvelle rubrique nommée [Service] dont les paramètres sont explicites. Ce specifier se nomme %I (lire « i » majuscule. il manque ici le paramètre Type= qui indique comment lancer le service. vous savez qu’habituellement vous disposez d’un certain nombre de terminaux virtuels.service  ? Il s’agit d’une astuce lexicale proposée par systemd pour permettre de créer des modèles d’unités (unit templates). ce qui est évidemment à éviter. Comme vous le subodorez peut-être déjà. idle et notify (voir la documentation man systemd. Voici un extrait du fichier getty@.noexec des unités. la surveillance et la regénération d’un processus de service est réalisée par les directives Restart= (sur quel état du processus fautil le relancer ?) et RestartSec= (au bout de combien de secondes faut-il le relancer ?). puis il créera une socket UDP (ListenDatagram) à l’écoute du port 631 en IPv4 uniquement. au sens «  classique » du terme.socket : [Unit] Description=CUPS Printing Service Sockets [Socket] ListenStream=/var/run/cups/cups. le nombre de paramètres possibles pour définir la configuration des unités est très important. Dans la configuration de l’unité sshd. chacun étant géré par une commande de la famille getty (par exemple. page suivante..target [Mount] : What=tmpfs Where=/media Type=tmpfs Options=mode=755.service. service. Il en existe d’autres – voir man systemd.. Les modèles d’unités prennent tout leur sens alors : si systemd doit activer une unité dont le nom est getty@tty1.target (3) qui est en réalité un lien symbolique vers runlevel5. sur RedHat cette commande est /sbin/ ming etty – à voir dans le fichier /etc/inittab). Avez-vous remarqué la présence du caractère @ dans le nom de l’unité getty@. le contenu du fichier media.10 décembre 2012 à 16:20 Oui. Avec systemd . c o m .5 Petite synthèse Récapitulons en prenant comme exemple le démarrage du système : voir Figure 1.wants/ lors de l’initialisation gérer.sock ListenStream=631 ListenDatagram=0. on trouve aussi la directive WantedBy= qui indique la dépendance entre ce service et l’unité multi-user. mount est : [Unit] Description=Media Directory Before=local-fs. service pour en avoir un exemple. Regardons la syntaxe de configuration d’une unité de type Socket. Toutefois.. Comme ultime exemple. puis il examine la première unité à lancer : default. à cause de la présence du caractère @ dans le nom de l’unité. ce qui nécessitera la création d’un lien symbolique dans /etc/systemd/system/multi-user.target (luimême lien symbolique vers graphical. alors. ce qui fait à la fois la richesse et la complexité de systemd ! Outre les services.sock. Il m’arrive souvent de placer ce type de montage dans le vénérable /etc/rc. oneshot. mais le faire gérer par s y s t e m d est un gage de robustesse. il lit son fichier /etc/systemd/ system. Lorsque systemd est lancé par le noyau (1). Ici. systemd va créer une socket du domaine UNIX qui s’appellera /var/run/ cups/cups. Comme cette unité existe. service sur Fedora17 : [Unit] Description=Getty on %I . La valeur par défaut est  simple pour indiquer que le processus nommé par ExecStart= est le processus principal du service. Remarquez aussi la ligne de commandes qui permet de faire un « reload » du démon : la variable $MAINPID est gérée par systemd et aura pour valeur le PID de sshd.service et que ce nom d’unité n’existe pas sous /lib/systemd/system/. par exemple cups.target.local.. c’est elle qui sera invoquée et la chaîne tty1 qui faisait partie du nom de l’unité initiale sera fournie sous forme de « specifier » accessible dans la configuration de l’unité. nous allons prendre l’exemple d’un montage à effectuer lors du démarrage. mais les autres possibilités sont  : forking.wants (5). nous avons dit en préambule que systemd allait aussi gérer les sockets afin d’accélérer les lancements des processus inter-dépendants.

nous avons montré les paramètres principaux de systemd dans le fichier /etc/systemd/ system. Par exemple. On y trouve par exemple sshd. quand un service est de type forked. 3. on exécute la commande : # journalctl _SYSTEMD_UNIT=sshd. S’il a lancé plusieurs processus fils.service). etc. Ces champs ont des noms prédéfinis comme MESSAGE.service. pid. Note Note : sur Fedora 17. _HOSTNAME.Systemd vainqueur de Upstart et des scripts « System V » ? SySTemD Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. donc rapide mais non persistant. systemd maintient automatiquement la relation entre PID et processus activés.3.fr) .service 4 Comment faire « comme avant. mais il est possible de limiter le nombre de lignes affichées avec l’option -n (comme le fait la commande tail) : # journalctl -n 10 systemd parcourt ce répertoire pour ac- tiver les unités qui y sont décrites. Ce processus est configuré par le fichier /etc/systemd/systemd-journald. le PID de notre démon sshd précédent est stocké par systemd dans le fichier /var/run/sshd. Les fichiers de logs sont à un format binaire. nous avons évoqué LogTarget=. Parmi ceux-ci. l’affichage peut être filtré (comme le ferait grep !) en précisant des valeurs spécifiques pour les champs des lignes de logs.conf dont voici un extrait : [Journal] ForwardToSyslog=yes MaxLevelSyslog=debug Compress=yes #SystemMaxUse= #ForwardToConsole=no Enfin. _SYSTEMD_UNIT (voir man systemd. essayons d’être un peu plus productifs et évitons de réécrire des commandes qui existent déjà. g n u l i n u x m a g. vous vous êtes habitué aux commandes simples mais néanmoins utiles chkconfig et service. le répertoire /var/run est en fait un lien symbolique vers /run qui est le point de montage d’un système de fichiers de type tmpfs. mais il peut aussi réémettre les logs vers le démon syslog (ou rsyslog dans notre cas) ou vers la Console système. Cela indique à systemd d’envoyer tous les messages de log à un nouveau démon nommé systemd-journald luimême activé par systemd car décrit par l’unité systemd-journald. On peut lui indiquer des tailles limites de fichiers à générer ou une taille maximale d’espace disque à utiliser. Sur Fedora 17.com GNU/Linux Magazine France N° 1 5 3 39 .2 Gestion des logs Dans le tableau du §2. 30 ans après. le stockage de PID du processus fils « principal » est à la charge du processus parent et il faut indiquer à systemd dans quel fichier est stocké ce PID. pour n’afficher que les logs relatifs à l’unité sshd.1 Gestion des processus Par défaut. cela signifie que le processus lancé par systemd va lancer un ou plusieurs processus fils puis va se terminer. par quoi va-t-il falloir les remplacer ? Voici un petit tableau qui met en parallèle vos commandes usuelles avec leur pendant « à la mode de » systemd : Le processus systemd-journald stocke les logs qu’il reçoit dans des fichiers w w w. avec init » ? Finalement. Unix/Linux ne change pas radicalement : on peut gérer systemd avec les commandes ln pour les liens symboliques et vi pour la configuration ! Néanmoins.journal-fields). On fait pour cela un usage de la directive PIDFile= dans le fichier de configuration de l’unité.service. la valeur de ce paramètre est : journal. Si.service. PRIORITY. il faut utiliser la commande journalctl pour en afficher le contenu : # journalctl Figure 1 affiche le contenu des logs avec votre paginateur préféré. _PID.conf. Ainsi. systemd peut se tromper dans son analyse du processus principal. 3 Gestion des processus et des logs 3.10 décembre 2012 à 16:20 situés sous /run/log/journal/. Mais pour les services dont la valeur de Type= est forked (alors que le type est simple pour sshd. En effet. comme moi.

c o m . selon moi.service service sshd stop systemctl reload sshd.target # systemctl dor | dot -Tsvg > fichier. il semble que le pas soit pris et que.de/ blog/projects/systemd. upstart et sysvinit (http://0pointer.svg Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Effectivement. peut-être avez-vous eu la réaction suivante : « mais pourquoi avoir fait si compliqué alors que finalement init ne fonctionnait pas si mal que ça ? » [NDLR : ce serait plutôt « mais c’est quoi ce #@$!& ? »]. petit à petit.or (http://fedoraproject. sur de telles plates-formes.service systemctl status sshd.gnulinuxm a g . la commande suivante permet de faire relire les fichiers par systemd : # systemctl daemon-reload - et si vous aimez les graphes bien « touffus » (et inexploitables !). les principales distributions Linux nous forcent ainsi à nous adapter.d/ commande service commande init systemd chkconfig et liens symboliques pour les scripts non encore migrés commande systemctl pour les processus pris en charge par systemd commande service ou commande systemctl commande init ou commande systemctl Démarrage ou arrêt d’un service Changement de niveau d’exécution Vous voyez l’intérêt de la nouvelle commande systemctl qui centralise toutes les opérations mais qui permet de réaliser d’autres opérations : - p our obtenir la liste de toutes les unités (situées sous /lib/systemd/ system/) et leur état courant : # systemctl list-unit-files Références [LPOE1] Blog de l’auteur Lennart Poettering (http://0pointer. Alors. Administrateur de serveurs Linux. Néanmoins. vous pouvez générer une image représentant les dépendances entre toutes les unités par : 40 G N U / L i n u x M a g azine France N°153 www. Mac OS X voire Windows (!).fr) . de/blog/projects/why.service systemctl disable sshd.10 décembre 2012 à 16:20 Remplacement de la commande service Conclusion À la lecture de cet article.service service sshd start systemctl stop sshd.service systemctl is-enabled sshd. étudiez dès à présent le fonctionnement de systemd dont le périmètre d’action va encore s’accroître avec la future intégration de udev  ! En résumé : Fonctionnalité Activation d’un service au démarrage init (system V) commande chkconfig liens symboliques vers /etc/init.html) [LPOE2] Comparaison faite par L.Poettering entre systemd. avant de vous retrouver face à une nouvelle version de votre Linux préféré où init et les scripts System V auront définitivement disparu. n’a aucun intérêt pour des serveurs. Le passage vers systemd (ou upstart) ne se justifie pas.En COUVeRTURe Systemd vainqueur de Upstart et des scripts « System V » ? SySTemD Remplacement de la commande chkconfig chkconfig sshd on chkconfig sshd off chkconfig sshd --list service sshd status service sshd start service sshd stop service sshd reload systemctl enable sshd. on peut considérer le temps de démarrage comme plutôt long. je me suis aussi posé cette question et me la pose encore.service service sshd reload Remplacement des commandes init et telinit init 0 init 6 init 3 systemctl poweroff init 0 systemctl reboot init 6 systemctl isolate runlevel3.org/wiki/Systemd) - pour obtenir la liste et la description des unités de type service : systemctl list-units -t service - si vous changez la configuration de systemd ou des unités.html) [FEDORA] le wiki de systemd sur Fedoraproject. Vouloir « faire la course » entre distributions Linux.target init 3 Choix du niveau d’exécution au démarrage valeur de initdefault dans /etc/inittab valeur du lien symbolique default.service service sshd status systemctl start sshd. ce n’est rien comparé aux délais de scans et de tests des Bios et firmwares des contrôleurs de toutes sortes. si parfois. je n’ai jamais connu de problème avec init et.

50 €* en kiosque Économie : 27.Abonnez-vous ! Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Tournez SVP pour découvrir toutes les offres d’abonnement  .ed-diamond. entre 9h-12h et 14h-18h au 03 67 10 00 20 au lieu de 82.67603 Sélestat Cedex Tél.50 €/an ! (soit plus de 3 magazines offerts !) 4 façons de commander facilement : p  ar courrier postal en nous renvoyant le bon ci-dessous p  ar le Web. consultez notre site : www. 20142 .com à l’adresse internet : www.fr) .com/cgv et reconnais que ces conditions de vente me sont opposables.P.50 €* * OFFRE VALABLE UNIQUEMENT EN FRANCE MÉTROPOLITAINE Pour les tarifs hors France Métropolitaine.com p  ar fax au 03 67 10 00 21 p  ar téléphone. R  ecevez GNU/Linux Magazine chaque mois chez vous ou dans 11 * Sur le prix de vente unitaire France Métropolitaine 30% Numéros de par ABONNEMENT : * GNU/Linux Magazine votre entreprise. É  conomisez 27.ed-diamond. g nsuivante ulinux m a g.ed-diamond.10 décembre 2012 à 16:20 Profitez de nos offres d’abonnement spéciales disponibles au verso ! Économisez plus de 03 67 10 00 Téléphonez 0 ou comman dez par le We b au 2 Les 3 bonnes raisons de vous abonner : N  e manquez plus aucun numéro. : + 33 (0) 3 67 10 00 20 Fax : + 33 (0) 3 67 10 00 21 Vos remarques : En envoyant ce bon de commande. sur www. je reconnais avoir pris connaissance des conditions générales de vente des Éditions Diamond ww w.com Tournez SVP pour découvrir toutes les offres d’abonnement >> 55 €* Bon d’abonnement à découper et à renvoyer à l’adresse ci-dessous Voici mes coordonnées postales : Société : Nom : Prénom : Adresse : Code Postal : Ville : Pays : Téléphone : e-mail : Édité par Les éditions Diamond Service des Abonnements B.

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.10 décembre 2012 à 16:20 .fr) .

la création d’un domaine ou d’un sousdomaine entraîne la création d’une relation d’approbation d’authentification transitive et bidirectionnelle. La notion de liberté est particulièrement chère aux développeurs du projet. Par exemple. Samba  4 vise à remplacer Samba  3.DC=local. Fonctionnellement. l’évolution apportée par la migration vers de nouveaux protocoles. si votre domaine DNS interne est reseau. alors l’arborescence LDAP de l’Active Directory sera DC=reseau.10 décembre 2012 à 16:20 A la découverte de Samba 4 par Julien Morot [Sysadmin passionné par les logiciels libres depuis 1998. il est possible de créer un ou plusieurs domaine(s) et sousdomaine(s) au sein de l’AD. comme la possibilité d’utiliser OpenLDAP comme backend de stockage ou encore un fonctionnement en cluster.SySADmIn Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. L’ensemble des domaines et sous-domaines regroupés au sein d’une même forêt partagent le même schéma Active Directory (et donc LDAP). En effet. Le nom de domaine DNS est par défaut utilisé pour le nommage du domaine Active Directory. afin de permettre la recherche d’objets situés dans d’autres domaines plus rapidement sans nécessiter une réplication complète du contenu des différents domaines. car il a été le premier projet d’envergure à adopter cette licence en passant Samba 3. bien que ces fonctionnalités soient relativement complexes à mettre en œuvre.et il devenait de plus en plus pressant de rattraper le retard accumulé. A noter qu’avec Windows 2008 Server. car stocké dans une base de données répliquée. logique. assurait les fonctions d’un domaine de type NT4. chaque contrôleur de domaine est un contrôleur de domaine maître. à l’exception 2. Jusqu’ici. Samba 4 a été démarré en 2003 et bien que la version finale commence à pointer le bout de son nez. c’est une évolution de ce qu’il était déjà possible de faire auparavant. Microsoft a introduit la notion de contrôleur de domaine en lecture seule. g n u l i n u x m a g. Samba 3 gère notamment l’authentification en mode serveur maître/esclave (PDC/ BDC pour Primary Domain Controler et Backup Domain Controler) et la fourniture des services de partage de fichiers et d’impression. la NTDS pour NT Directory Services. Par défaut.] En gestation depuis environ une dizaine d’années auprès de ses développeurs.2 sous GPL v3 dès 2007. 2 Qu’est-ce que l’Active Directory ? L’Active Directory consiste en une intégration particulièrement poussée d’un certain nombre de protocoles plus ou moins standardisés dans le but de fournir des services d’authentification. La fonctionnalité « Catalogue Global » au sein d’un contrôleur de domaine permet à celui-ci de contenir une vue partielle des objets des autres domaines. qui lui. il aura fallu presque dix ans pour achever le travail titanesque que représente la ré-implémentation de tous les protocoles en jeu.local. permet de partitionner les ressources de manière sécurisée. des groupes et des ordinateurs. w w w. Rentrons au cœur des réseaux Active Directory alors que la sortie d’une version se profile à l’horizon. le tout avec un passage à l’échelle plus important. ainsi que des relations d’approbation entre les domaines. La compatibilité avec l’Active Directory de Microsoft est cependant limitée à la possibilité de joindre un domaine au sens domaine de sécurité .com GNU/Linux Magazine France N ° 1 5 3 43 . Tout comme le DNS. 1 Introduction La suite de logiciels Samba est une ré-implémentation en logiciels libres des protocoles réseau clients et serveurs de Microsoft. il n’y a donc plus de notion de contrôleur de domaine secondaire.1 Notion de domaine et de contrôleur de domaine Chaque serveur hébergeant l’Active Directory ou une partition de celui-ci est appelé un contrôleur de domaine ou DC. car les principaux objets stockés dans l’Active Directory sont des utilisateurs.fr) . Samba 3 était capable de couvrir l’ensemble des fonctionnalités d’un réseau de type NT4 avec un certain nombre d’améliorations. Techniquement. Il assure l’ensemble des fonctions permises par un contrôleur de domaine. Active Directory est sorti en 2000. Contrairement à un réseau NT4/ Samba3. de configuration et d’administration (déploiement de logiciels et de configuration) centralisés.

c o m . Ensuite.).1 Préparation du serveur Quelques paquets seront nécessaires. L’Active Directory ayant pour but premier la gestion de l’authentification. qui nécessite une version de Bind plus récente que celle de la Debian stable. - Le rôle Maître de Schéma. Les clients notamment recherchent les contrôleurs de domaine via des requêtes DNS de type srv. ou toute la forêt. les types d’objets principaux sont donc tout à fait classiques dans ce type de configuration. afin de localiser un contrôleur de domaine et un certain nombre de mises à jour DNS dynamiques se font via Kerberos. - Les comptes d’ordinateur.errors=remount-ro 0 1 44 G N U / L i n u x M a g azine France N°153 www. Notez que contrairement aux groupes POSIX. soit pour affecter des droits. sites. - Les comptes utilisateurs. l’Active Directory prend en charge les groupes incluant d’autres groupes. Bien entendu.fr) . ces deux rôles principaux ne sont pas mutuellement exclusifs. Ce port permet de requêter en LDAP un contrôleur de domaine pour des objets se situant sur l’ensemble de la forêt. Le DNS est un élément clé d’une architecture Active Directory. - Le rôle Maître de Nommage de Domaine. des autorisations et du contrôle d’accès. unique au sein d’une forêt.2 Les types d’objets principaux Les objets de l’Active Directory sont stockés dans un annuaire compatible LDAP. LDAPS (636/TCP). Il existe trois étendues de groupes : locale. Deux types de groupes existent. Afin de rester concentré sur la partie Samba. afin d’assurer l’unicité de certaines informations au sein du domaine ou de la forêt. tout domaine ou sous-domaine. assure la consistance des SID/GUID au sein des objets du domaine. 3. le système de fichiers et le montage de vos partitions doit prendre en charge les ACL et les attributs étendus. soit à la compilation de Samba. unique au sein d’un domaine. je n’ai préféré pas alourdir la mise en place du contrôleur de domaine par la compilation de Bind en version 9. qu’une copie en lecture du domaine. Or. etc. permettant tout comme au niveau utilisateur d’auditer et d’authentifier l’accès aux ressources du domaine au niveau ordinateur. Il vous faudra donc modifier le fichier /etc/fstab en conséquence. assure l’unicité des identifiants alloués aux autres contrôleurs de domaine (l’équivalent des UID/GID Unix). Ce type de contrôleur de domaine est en cours de prise en charge par l’équipe Samba. Gère la consistance et la réplication du schéma au sein de la forêt. - Le rôle Maître d’Infrastructure. il gère surtout la consistance de la résolution de nom des objets dans les groupes de l’AD et le déplacement des objets entre domaines. Elles sont utilisées pour classer structurellement les objets en fonction de leur rôle au sein d’une organisation (services. certaines fonctionnalités sont uniques : - Le rôle d’émulateur de Contrôleur de Domaine Principal.10 décembre 2012 à 16:20 du fait qu’il est exclu de la réplication multi-maître et ne contient.gnulinuxm a g . Cependant. qui sont des conteneurs permettant de hiérarchiser les autres objets que l’on va retrouver. les groupes de sécurité pour l’affectation d’autorisations et les groupes de distribution. gère l’unicité des noms de domaines AD lors de l’ajout ou la suppression de ceux-ci. qui servent surtout pour les applications de messagerie.8 au minimum. l’équipe Samba a remonté un certain nombre de patchs à l’équipe des développeurs Bind pour une meilleure prise en charge de cette fonctionnalité. ainsi qu’un port spécial. Il est donc interrogeable naturellement via les ports LDAP (389/TCP).SySADmIn Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Ce choix est voulu pour simplifier cet article. - Le rôle Maître d’IDentifiants Relatifs. qui est la concaténation de l’identifiant de domaine et du RID de l’objet. On va donc retrouver : - Les unités d’organisation. En pratique. comme son nom l’indique. unique au sein d’un domaine. - Les groupes. assure la compatibilité descendante pour l’authentification de type NT4. permettant d’affecter des autorisations respectivement pour uniquement le domaine local. globale et universelle. « Relatif » vient du fait que chaque objet est identifié par un identifiant unique (le SID). On peut tous les installer en une fois de cette façon : apt-get -y install build-essential libacl1-dev libattr1-dev \ libblkid-dev libgnutls-dev libreadline-dev python-dev \ python-dnspython gdb pkg-config libpopt-dev libldap2-dev \ bind9utils dnsutils libtool git xsltproc libpam0g-dev \ attr acl psmisc bind9 ntp libtalloc2 libtalloc-dev 2.acl. soit à son bon fonctionnement. le port catalogue global (3268/TCP). 3 Mise en place d’un domaine sous Samba 4 La maquette utilisée pour cette mise en place se base sur une Debian testing. Exemple : /dev/sda1 / ext3 user_xattr.

acl. c’est-à-dire la bêta 5.DC=local Creating DomainDnsZones and ForestDnsZones partitions Populating DomainDnsZones and ForestDnsZones partitions See /usr/local/samba/private/named.ldb rootDSE marking as synchronized Fixing provision GUIDs A Kerberos configuration suitable for Samba 4 has been generated at /usr/local/samba/private/krb5. vous utilisez un nom de domaine DNS avec .0.pool.6 .9. g n u l i n u x m a g.DC=local Adding configuration container Setting up sam. member. Je supposerai d’ailleurs que c’est le cas pour la suite.org afin d’avoir une liste de serveurs sources fiables et disponibles. sans quoi vous serez honoré d’une belle exception Python.conf Once the above files are installed. Je vous recommande d’utiliser fr.0.php.samba.org/pub/samba/samba4/samba-4.1. La compilation du logiciel revient à faire un simple ./configure && make && make install echo "export PATH=$PATH:/usr/local/samba/bin/:/usr/local/samba/ sbin/:" >> ~/.tar. # provision Realm [DOMAIN.tar. standalone) [dc]: Administrator password: <secret !> Retype password: <secret !> Looking up IPv4 addresses Looking up IPv6 addresses No IPv6 address will be assigned Setting up share. comme moi./configure && make && make install wget ftp://ftp.0. Il faut donc indiquer le serveur NTP source et le firewall du réseau devra autoriser les requêtes NTP vers l’extérieur. afin de simplifier les commandes.user_xattr / Enfin.0beta5 .local DOMAIN SID: S-1-5-21-2813939429-2675192644-3843174914 A phpLDAPadmin configuration file suitable for administering the Samba 4 LDAP server has been created in /usr/local/samba/private/ phpldapadmin-config. il se peut que Avahi et son mécanisme de résolution mdns soit prioritaire dans le mécanisme de résolution de noms et que si. ntp.conf for an example configuration include file for BIND and /usr/local/samba/private/named. pour plus de commodité. Par convention.exe sur un DC Windows Server.bashrc 3.conf..0beta5.gz && cd samba-4.org/pub/ldb/ldb-1. Ce paramètre peut être multivalué. majuscules.gz && cd ldb-1.9. Petite note supplémentaire./configure && make && make install habituel.1. en cas d’utilisation d’une autre distribution. Une seule dépendance est requise.tar. il faudra paramétrer le fichier /etc/nsswitch. wget ftp://ftp. etc. j’ai créé un domaine avec un TLD .2 Compilation et installation Cet article se base sur la dernière version bêta lors de sa rédaction. Nous avons donc installé le serveur NTPD lors des pré-requis.ldb rootDSE Pre-loading the Samba 4 and AD schema Adding DomainDN: DC=domain.ldb partitions and settings Setting up sam.ldb schema Setting up sam.txt for further documentation required for secure DNS updates Setting up sam. your Samba4 server will be ready to use Server Role: active directory domain controller Hostname: srv-dc1 NetBIOS Domain: DOMAIN DNS Domain: domain. le protocole d’authentification par défaut de l’Active Directory étant Kerberos v5.gz tar -zxvf samba-4.ldb Setting up secrets.ldb users and groups Setting up self join Adding DNS accounts Creating CN=MicrosoftDNS.bashrc && source ~/.3 Création du domaine La commande provision est l’équivalent de la commande dcpromo. il est possible de les remonter avec les options adéquates de cette façon : Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.0beta5.ldb configuration data Setting up display specifiers Adding users container Modifying users container Adding computers container Modifying computers container Setting up sam.ldb data Setting up well known security principals Setting up sam.tar.LOCAL]: Domain [DOMAIN]: Server Role (dc.A LA DÉCOUVeRTe De SAmbA 4 Pour éviter de redémarrer le serveur pour les partitions actives.samba.rw. Cela revient à définir le paramètre serveur du fichier /etc/ntpd.local.DC=domain. Je vous invite également. il est important que les horloges soient à l’heure.gz tar -zxvf ldb-1.1.10 décembre 2012 à 16:20 mount -o remount. correspondant au nom retenu pour le domaine. Elle se charge de générer le domaine avec les comptes par défaut et les w w w.CN=System. ldb qui est une base de données avec une API proche de l’API LDAP et qui sert de backend de stockage à Samba.fr) .local comme suffixe. minuscules et signes de ponctuation).ldb Setting up the registry Setting up the privileges database Setting up idmap db Setting up SAM db Setting up sam.conf de la sorte : hosts: files dns fichiers de configuration Bind.com GNU/Linux Magazine France N° 1 5 3 45 . Kerberos. 3. Le provisionning du domaine vous demandera le mot de passe du compte administrateur (dénommé « administrator ») et devra répondre à des exigences de complexité (chiffres. à ajouter le chemin vers les binaires Samba au PATH de votre shell.

dnsupdate. Cette clé devra bien entendu être uniquement accessible par Bind.local /user:administrateur /password:secret MEMBER PC-JAMBON /joindomain Puis. il ne doit pas y avoir un décalage d’horloge de plus de cinq minutes entre le KDC et le client. backend de stockage par défaut. car la plupart des mises à jour dynamiques des zones passent par TSIG-GSSAPI. Je laisse donc au lecteur la 46 G N U / L i n u x M a g azine France N°153 www. winbind. les outils graphiques édités par Microsoft sont parfaitement fonctionnels et compatibles sur une infrastructure Samba. wrepl. La connexion au domaine devra être effectuée avec un compte disposant des droits admin du domaine. kcc.] tkey-gssapi-keytab "/usr/local/samba/private/dns. les mises à jour faites par les contrôleurs de domaines en lecture seule via les MSRPC. Notez qu’un serveur DNS.conf. dont la vocation n’est bien entendu pas de concurrencer Bind. Enfin..8 Un second contrôleur de domaine Comme je le disais plus haut. Sur un poste sous Windows XP. s3fs. il ne faudra pas lancer la commande provision. le poste client devra parvenir à résoudre votre zone DNS. Pour l’arrêter. Autant donc profiter de cette possibilité pour assurer une redondance du système d’authentification. en principe. et ceci est une contrainte inhérente au protocole Kerberos.conf avant de relancer Samba : server services = rpc. il faudra que le second serveur puisse résoudre votre domaine AD via le DNS.7 Administration graphique Le projet Samba tentant de reproduire au plus proche le comportement des différents composants de l’Active Directory. il suffit de lancer la commande samba. Dans un premier temps.options. cldap. permettant dans ce cas précis à Bind de s’authentifier sur le KDC de façon transparente. c o m .keytab". Une keytab est une clé Kerberos cryptée et stockée sur disque.8. ainsi que l’adminpak. Le but est de permettre de répondre facilement aux quatre méthodes de mise à jour du DNS qui existent sur un réseau Active Directory. L’installation du second serveur se déroule de façon similaire à celle du premier. Les postes sous Windows Vista ou Windows Seven.SySADmIn 3. est en développement par l’équipe Samba. rien de plus simple. La motivation est bien expliquée par le créateur de Samba.conf vers le premier contrôleur de domaine. il faut obligatoirement une version professionnelle. rédaction d’un script d’init qui sera donc d’une simplicité déconcertante. } 3. Il ne reste plus qu’à intégrer les postes comme suit (ou bien graphiquement si ça vous chante) : netdom /domain:domain. contrairement aux domaines Samba3/NT4. dans un post sur son blog qui va au-delà du souci de simplification de l’installation.keytab. voici ce qu’il faut indiquer dans le fichier /usr/local/samba/ etc/smb.local étant réalisé par Samba. nbt. La procédure de compilation et d’installation est strictement similaire lorsque l’on ajoute un contrôleur de domaine à un domaine existant. ntp_signd. Pour les plus aventureux qui souhaiteraient tester. les réplications de l’AD inter-contrôleurs de domaine via le DRS et enfin.10 décembre 2012 à 16:20 3. Ce point est nécessaire.local  include "/usr/local/samba/private/named. soit les mises à jour DDNS signées via TSIG (Kerberos). Debian fournissant en outre le modèle de script /etc/init. Andrew Trdigell. un chown root:bind /usr/local/samba/ private/dns. Je vous recommande donc également une Debian testing. la configuration de Bind est relativement simplifiée. Pensez à redémarrer le service bind pour que ces changements soient pris en compte. les modifications réalisées en LDAP. kdc. 3.gnulinuxm a g . Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. ldap. dans le fichier /etc/bind/named. dns allow dns updates = True dns forwarder = 8. nécessiteront les Remote Server Administration Tools. on indique le chemin vers la keytab. mais simplement démarrer samba. on définit le stockage des zones devant passer par le plugin Bind-dlz (Dynamically Loadable : Zones) à charger via le fichier /etc/bind/named.d/skeleton.4 Paramétrage du serveur DNS Le stockage des données de la zone DNS domain. drepl. options { [. un domaine Active Directory n’est pas limité à un contrôleur de domaine.8. les versions familiales n’étant pas prises en charge. Comme le serveur DNS est installé dans un second temps. suivi d’un chmod 0640 s’impose donc.conf. Cependant.5 Démarrage et arrêt Pour démarrer l’ensemble des processus.fr) . Il est donc également possible de gérer les stratégies de groupes depuis la console MMC appropriée si elle est installée sur un poste Windows. sans nécessiter d’entrer un mot de passe. il faudra donc installer le kit de ressources techniques pour Windows 2003 Server SP1.6 Intégrer un poste au domaine Pour intégrer un poste Windows à un domaine AD.. qui fournit les dépendances citées plus haut. quant à eux. Que ce soit en IP fixe ou en DHCP.conf". un killall samba suffit.8 dns recursive queries = yes 3. en faisant pointer le fichier /etc/resolv.

CN=Default-First-Site-Name. La syntaxe de la commande est très bien détaillée dans l’aide contextuelle. 4 Jouons un peu avec la ligne de commandes 4.OU=Domain Controllers.CN=Sites.DC=domain.domain.local --realm=DOMAIN. Il faudra donc penser à mettre en place une tâche Comme tout bon programme Unix.local Password for [administrator@domain.CN=Configuration.DC=domain.local]: workgroup is DOMAIN realm is domain.DC=local] objects[1550/1550] linked_values[0/0] Analyze and apply schema objects Partition[CN=Configuration.DC=local] objects[1608/1614] linked_values[0/0] Partition[CN=Configuration.1 samba-tool.DC=domain. de fait je ne m’y attarderai pas afin de rester ciblé sur les réelles nouveautés de Samba 4.local Password for [WORKGROUP\administrator]: Joined domain DOMAIN (S-1-5-21-2813939429-2675192644-3843174914) A noter que depuis la bêta 4.DC=domain.CN=Sites.DC=local] objects[98/98] linked_values[23/0] Partition[DC=domain.DC=domain.DC=domain. dont l’implémentation est encore jeune.DC=domain.1. le couteau suisse de l’administrateur Il restera donc ensuite à réaliser le paramétrage de Bind de façon tout à fait similaire au premier DC et adapter la résolution du second serveur afin qu’il s’interroge lui-même pour résoudre les enregistrements du domaine.10 décembre 2012 à 16:20 3. Les paramètres additionnels sont documentés en indiquant le paramètre -H à la sous-commande désirée sans indiquer de paramètre.168. Veuillez noter un point cependant.A LA DÉCOUVeRTe De SAmbA 4 On peut donc désormais intégrer le domaine en tant que DC additionnel : root@srv-dc2:~# samba-tool domain join domain. il peut être utile de déléguer la gestion de certains services. qui contient les stratégies de groupe et les scripts de connexion appliqués sur les postes ou les utilisateurs du domaine.CN=SRV-DC2.DC=local] objects[18/18] linked_values[0/0] Committing SAM database Sending DsReplicateUpdateRefs for all the partitions Setting isSynchronized and dsServiceName Setting up secrets database Joined domain DOMAIN (SID S-1-5-21-2813939429-2675192644-3843174914) as a DC cron régulière qui réalisera un rsync régulier de ce partage. le DRS.DC=local Adding CN=NTDS Settings.DC=domain.9 Ajout d’un serveur membre Je ne reviendrai pas sur les étapes de préparation du serveur ni sur l’installation de Samba 4.DC=local] objects[307/209] linked_values[23/0] Partition[DC=DomainDnsZones. après avoir préalablement mis en place un échange de clés SSH : */5 * * * * root rsync -azvp --delete /usr/local/samba/var/locks/ sysvol root@srv-dc2:/usr/local/samba/var/locks/sysvol Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.DC=local Adding CN=SRV-DC2.CN=Configuration.CN=Servers.250 Forest : domain. qui sont inchangées par rapport aux deux serveurs précédents.DC=domain.CN=Default-First-SiteName.DC=local Starting replication Schema-DN[CN=Schema.local DC -Uadministrator@domain.CN=Configuration.DC=local] objects[1614/1614] linked_values[28/0] Replicating critical objects from the base DN of the domain Partition[DC=domain.DC=local Adding SPNs to CN=SRV-DC2.DC=local] objects[804/1550] linked_values[0/0] Schema-DN[CN=Schema. g n u l i n u x m a g.DC=local] objects[1206/1550] linked_values[0/0] Schema-DN[CN=Schema.DC=local] objects[402/1550] linked_values[0/0] Schema-DN[CN=Schema.CN=C onfiguration.local’ Found DC srv-dc1.DC=domain.CN=Configuration.local DC -U administrator Les services de partage de fichiers sont désormais gérés par un build des démons Samba 3 (nmpd et smbd) intégré à Samba 4.DC=local] objects[804/1614] linked_values[0/0] Partition[CN=Configuration.CN=Servers.DC=local] objects[1206/1614] linked_values[0/0] Partition[CN=Configuration.local checking sAMAccountName Adding CN=SRV-DC2. comme le partage de fichiers. Prenons connaissance du domaine que nous avons mis en place : root@srv-dc1:~# samba-tool domain info 192. La littérature fleurit assez sur le sujet sur le net.DC=local] objects[402/1614] linked_values[0/0] Partition[CN=Configuration. Cependant. La commande samba-tool permet de réaliser l’ensemble des tâches courantes d’administration d’un réseau Microsoft Windows.DC=domain. le partage sysvol. Samba 4 est entièrement administrable en ligne de commandes.fr) .OU=Domain Controllers.DC=domain. à un serveur dédié : root@srv-member:~# samba-tool domain join domain.com GNU/Linux Magazine France N° 1 5 3 47 .DC=local] objects[40/40] linked_values[0/0] Partition[DC=ForestDnsZones.CN=Configuration.DC=local Setting account password for SRV-DC2$ Enabling account Calling bare provision No IPv6 address will be assigned Provision OK for domain DN DC=domain.DC=domain.DC=domain.local w w w.LOCAL Finding a writeable DC for domain ‘domain.local Domain : domain.DC=domain.local member -U administrator --realm=domain. dans le but de cloisonner les services réseau. est répliqué via un protocole. il est permis de proprement promouvoir un serveur membre en contrôleur de domaine sans perdre le SID du compte d’ordinateur de cette façon : root@srv-member:~# samba-tool domain dcpromo domain.

Dans les sources de Samba 4. certains admins téméraires ont déjà basculé en production des serveurs sur Samba 4.DC=local SchemaMasterRole owner: CN=NTDS Settings.CN=Default-First-Site-Name.CN=Servers.DC=local 4.CN=SRV-DC1. CN=Sites. exiger 8 caractères (contre 7).gumble’ created successfully root@srv-dc1:~# samba-tool group addmembers "Taverne de Moe" h.simpson b. il est extrêmement facile d’automatiser l’administration de son contrôleur de domaine via la ligne de commandes./samba_backup <répertoire d’installation> <répertoire de sauvegarde> Modifions la stratégie de sécurité de mot de passe pour.CN=Sites.gumble Spr1ngfi3l --given-name=Barney --surname=GUMBLE --must-change-at-next-login --company="Duff" --script-path login.CN=Configuration. Le script s’utilise de cette façon : # .simpson.CN=Configuration. car des écueils subsistent encore çà et là. par exemple.gumble Conclusion Notre escapade à la découverte du fonctionnement de l’Active Directory et sa mise en place au travers de Samba 4 s’arrête là. L’équipe Samba n’est pas encore prête à lancer une mouture finale du logiciel.DC=local’ Forest function level: (Windows) 2003 Domain function level: (Windows) 2003 Lowest function level of a DC: (Windows) 2008 R2 root@srv-dc1:~# samba-tool fsmo show InfrastructureMasterRole owner: CN=NTDS Settings.local DC netbios name : SRV-DC1 Server site : Default-First-Site-Name Client site : Default-First-Site-Name root@srv-dc1:~# samba-tool domain level show Domain and forest function level for domain ‘DC=domain.fr) .CN=Configuration. CN=Sites.CN=SRV-DC1. c o m .CN=Default-First-Site-Name. CN=Sites.). Bien qu’il y ait encore beaucoup à dire.DC=domain.CN=Servers. de la zone DNS.CN=Configuration.2 Sauvegarder Samba Tout bon administrateur système se pose bien évidemment la question de la sauvegarde.DC=local’ Password complexity: on Store plaintext passwords: off Password history length: 24 Minimum password length: 7 Minimum password age (days): 1 Maximum password age (days): 365 Il restera donc à planifier la tâche via l’habituelle crontab et à externaliser les sauvegardes sur un autre support. nous avons pu voir dans quelle mesure le projet avait avancé de manière impressionnante et avoir un premier aperçu de sa mise en place. CN=Configuration. il est donc possible de remonter l’AD sur le serveur.CN=Servers.domain. enfin je l’espère.simpson Spr1ngfi3l --given-name=Homer --surname=SIMPSON --must-change-at-next-login --company="Centrale Nucléaire" --script-path login.DC=domain.CN=Default-First-Site-Name. de la réplication. comme nous l’avons fait. sites. mais n’exiger qu’une modification de mot de passe annuelle (contre tous les 42 jours par défaut) : root@srv-dc1:~# samba-tool domain passwordsettings set --min-pwd-length=7 --max-pwd-age=365 Minimum password length changed! Maximum password age changed! All changes applied successfully! root@srv-dc1:~# samba-tool domain passwordsettings show Password informations for domain ‘DC=domain.CN=SRV-DC1. En cas de crash du système ou de corruption des bases LDB de Samba 4.bat User ‘h.CN=Default-First-Site-Name. La mise en place d’un second contrôleur de domaine. J’invite par ailleurs le lecteur à être curieux et à jeter un œil aux différents scripts présents dans ce répertoire. Créons un groupe et ajoutons deux nouveaux utilisateurs à ce groupe : root@srv-dc1:~# samba-tool group add "Taverne de Moe" Added group Taverne de Moe root@srv-dc1:~# samba-tool user create h.b. permet déjà de sauvegarder l’Active Directory en tant que tel.bat User ‘b.DC=domain.simpson’ created successfully root@srv-dc1:~# samba-tool user create b. groupes.gumble Added members to group Taverne de Moe root@srv-dc1:~# samba-tool group listmembers "Taverne de Moe" h.DC=domain. La sauvegarde des données étant acquise.10 décembre 2012 à 16:20 Netbios domain : DOMAIN DC name : srv-dc1. etc.CN=SRV-DC1. dans le répertoire source4/ scripting/bin/ est présent un script déjà réalisé nommé samba_backup. Comme vous le voyez.DC=local RidAllocationMasterRole owner: CN=NTDS Settings.DC=local DomainNamingMasterRole owner: CN=NTDS Settings. J’invite le lecteur à lancer la commande samba-tool sans paramètre pour prendre connaissance de l’étendue des possibilités offertes (gestion des utilisateurs.DC=domain.SySADmIn A LA DÉCOUVeRTe De SAmbA 4 Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. le script sauvegarde dans le répertoire /usr/local/backups et conserve un historique de 90 jours. Il reste néanmoins plus simple dans certains cas de ne réaliser qu’une restauration de ce dont on a besoin. 48 G N U / L i n u x M a g azine France N°153 www.DC=local PdcEmulationMasterRole owner: CN=NTDS Settings. CN=Sites.gnulinuxm a g .CN=SRV-DC1.CN=Servers. mais après tout. Par défaut.CN=Servers.CN=Default-First-Site-Name. voyons comment sauvegarder la partie système.

Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.10 décembre 2012 à 16:20 .fr) .

1 Le projet 1. Utilisé par mondoarchive. -n  ombreuses destinations et format de sauvegarde : locale. ext3. -s  auvegarde des attributs et ACL SELinux. en cas de crash pour restauration. Voici une liste non exhaustive de ses fonctionnalités : - support du RAID. Il ressort donc que toutes les partitions dont vous voudrez sauvegarder les données devront être montées. pour que Mondo Rescue puisse y accéder. contributeur des premières heures. mode mono-utilisateur dédié à la maintenance d’une machine. basé sur BusyBox. destinés à la sauvegarde et respectivement la restauration.10 décembre 2012 à 16:20 Sauvegarde et clonage à chaud de vos machines avec MondoRescue par Benoît Benedetti [Administrateur Systèmes Linux.. Pour soit démarrer sur la machine sauvegardée à l’origine. -r  estauration partielle de certains fichiers . NTFS et de manière générale la plupart des systèmes de fichiers supportés par le kernel Linux . sur périphérique à bandes. nfs. nouveau système de fichiers. Les deux premiers sont. mais vous pourrez ainsi sauvegarder des partitions Windows montées. au format iso. Dans le premier cas. directement vers un graveur CD/DVD . lisible avec les outils Linux usuels . qui a pris la tête de son développement. -c  ompression gzip. LVM. c o m ..SySADmIn Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. -l es sauvegardes sont dans un format. au début des années 2000. ext2. -r  estauration du MBR.gnulinuxm a g . pour de 50 G N U / L i n u x M a g azine France N°153 www.2 Installation Les différents paquets qui composent Mondo Rescue sont disponibles sur le serveur FTP du projet [FTP]. l’outil s’exécute à froid. ext4. vous l’aurez deviné. LILO . VFAT. Cela évite une coupure pour vos utilisateurs. compressé ou non. soit démarrer une autre machine pour déployer l’image. ou de sauvegarde basés sur rsync. Mondo Rescue effectue son travail à l’aide de trois commandes : mondoarchive. en démarrant sur un live CD. Mondo Rescue ne fonctionne que sous Linux. -p  ossibilité de modifier la configuration de la machine de restauration : nouvelle table de partitions. bzip2 ou lzo . Mondo Rescue offre l’intérêt de se placer entre ces deux méthodes. Ce média va contenir un Linux minimal. née de la frustration d’Hugo Rabson d’arriver à sauvegarder des systèmes Linux avec les solutions propriétaires. Le projet est depuis maintenu par Bruno Cornec.1 Présentation Mondo Rescue [MONDORESCUE] est une solution de sauvegarde sous GPL pour les systèmes Linux et FreeBSD. gestion de Grub. Dans le second cas. migration vers du RAID et/ou LVM. FAT. -s  auvegarde complète ou différentielle . périphérique amovible. machine éteinte. pour faire une image des disques au niveau bloc. . L’intérêt de MondoRescue tient du fait que vous n’avez pas à stopper la machine pour en faire une image. 1. par exemple en passant en runlevel 1. mindi est quant à lui un utilitaire pour générer un média bootable. Prenez également garde à stopper tout service qui pourrait altérer les données pendant la sauvegarde (par MySQL) et corrompre celle-ci.fr) . mondorestore et mindi. et la sauvegarde se fait au niveau système de fichiers. peu flexibles. Université de Nice Sophia Antipolis] Vous connaissez sûrement déjà des outils de clonage tels Clonezilla. la machine dont on désire sauvegarder les fichiers est forcément allumée. . et vous pouvez automatiser sa sauvegarde complète via une tâche Cron.

2 Sauvegarde Pour débuter.3..com GNU/Linux Magazine France N° 1 5 3 51 .fr) . vous devriez arriver sur l’invite de commande.iso Vous pouvez aussi créer une clé USB bootable à partir de cette image : Shall I make a bootable USB device ? (y/[n]) y Assurez-vous que la clé est bien branchée. Ainsi. un initrd avec des modules.g. Pour nous simplifier la vie. répondez par l’affirmative pour générer un ISO bootable contenant cette image. et les différences potentielles de pilotes nécessaires au démarrage. Cette situation ne devrait pas être utile. pour installer facilement le logiciel via votre gestionnaire de paquets habituel. Il sera possible de sauvegarder les données au format iso sur un seul CD. Vous avez la possibilité de modifier les fichiers de configuration /etc/mindi/* de Mindi pour lui indiquer tous les pilotes à inclure. qui consiste à se servir du kernel de la machine en cours d’utilisation et récupérer tous ses modules : Do you want to use your own kernel to build the boot disk ([y]/n) ? 2. L’utilisation directe de Mindi pour créer un média bootable n’est pas nécessaire.1. Dans la négative. Project Builder [PROJECTBUILDER].Installing an MBR (/usr/ /dev/sdb 2. sous Centos 6. Si Mindi a travaillé correctement.iso (pour une VM) ou le CD gravé à partir de celle-ci.mondorescue. le paramétrage des dépôts se déroule comme suit : $ sudo wget ftp://ftp. Mindi va créer une image bootable contenant un noyau de boot basé sur la machine sauvegardée. Nous sommes dans une situation simple.1 Mindi 2 Utilisation Nous allons commencer par tester Mindi. Cette large disponibilité est rendue possible grâce à un projet annexe de B. qui sera notre distribution de référence dans cet article. Dans d’autres cas. Attention de ne pas vous tromper. Corner. l’arborescence du serveur FTP est la suivante : ftp://ftp. et leurs différentes versions. /dev/sda) : / dev/sdb Il vous sera demandé si vous utilisez du RAID logique ou LVM. le périphérique en question sera complètement écrasé. L’installation est terminée : il est clair que Mondo Rescue ne vous demandera pas énormément d’efforts pour être déployé sur les machines à sauvegarder de votre parc. où l’image minimale générée par la machine permet de démarrer cette même machine.d/mondorescue. toujours dans /var/cache/mindi : Shall I make a bootable CD image? (y/[n]) y Created bootable ISO image at /var/cache/mindi/mindi. répondez « non » aux deux questions. disque) usuels étant contenus par défaut dans l’image créée par mindi. ou clonage d’une machine pour re-déploiement de l’image sur des machines identiques (comme l’installation d’une salle de cours dont les postes ont une configuration matérielle équivalente).SAUVeGARDe eT CLOnAGe À CHAUD De VOS mACHIneS AVeC MOnDOReSCUe Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Mieux vaut s’assurer que ce support de boot est généré correctement. et des outils issus de BusyBox utiles pour la restauration. et restaurer rapidement à partir de celui-ci. indiquez le périphérique /dev/sdX associé : Please enter the device name of your USB device (e.org/rhel/6/x86_64/mondorescue. Lancez mindi avec les privilèges root : $ sudo mindi Mindi Linux mini-distro generator v2.repo $ sudo yum clean all && yum makecache $ sudo yum -y install mondo À la question suivante.img w w w. Pour rappel. Pour trouver les paquets correspondant à votre distribution. Le programme vous demande quel kernel vous souhaitez utiliser pour générer l’image. chaque dossier de chaque distribution contient le fichier adéquat à ajouter à la configuration de vos dépôts. mindi est appelé automatiquement par mondoarchive lors de la sauvegarde. l’image mindi. où la machine a un volume de données faible. Laissez l’option par défaut. pour pouvoir le rendre bootable : WARNING: This will erase Are you sure you want to Transforming /dev/sdb in lib/syslinux/mbr. la plupart des pilotes (réseau. il vous faudra prendre en compte les spécificités des machines source et de destination. mondorescue. Nous verrons plus loin un Mindi va générer l’image dans /var/cache/mindi : In the directory ‘/var/cache/mindi’ you will find the images:mindi-bootroot.repo -O /etc/yum.bin) on all content on /dev/sdb use /dev/sdb (y/[n]) y a Bootable device . et valider le bon fonctionnement de notre média de boot. je vais présenter la sauvegarde et la restauration avec Mondo Rescue dans un cas simple.40960.org/<DISTRIBUTION>/<RELEASE NUMBER>. Tapez [Entrée].3-r3026 Redémarrez sur l’USB.10 décembre 2012 à 16:20 nombreuses distributions. car l’utilisation de la sauvegarde serait limitée voire compromise.repos. Vous devriez arriver sur un prompt. Nous allons tester Mindi dans un cas simple : la création d’un CD bootable pour redémarrer la machine locale en cas d’urgence. Cette situation devrait convenir dans la plupart des cas d’utilisation : clonage pour restauration d’une même machine (comme testé ici). g n u l i n u x m a g.

mais peut être utilisée pour restaurer seulement une partie des fichiers sauvegardés. vous pouvez lancer mondoarchive sans option. Le premier fichier de sauvegarde s’appellera Centos-1. bootable. lors du travail de mindi.. I am now backing up all large files.... mondoarchive reprend la main (le fichier journal de mondoarchive est /var/log/mondo/ mondoarchive. mondoarchive exécute Mindi pour créer l’image bootable : Calling MINDI to create boot+data disks ---evalcall---1--.. Ce n’est pas le cas et pour vous assurer qu’il continue bien sa tâche. Assurez-vous d’avoir assez d’espace pour la totalité de vos données à sauvegarder. jetez un œil à l’activité du fichier de log.SySADmIn scénario plus avancé avec nfs. des plus petits aux plus gros : ---progress-form---1-----progress-form---4--0:00 to go ---progress-form---1-----progress-form---4--0:00 to go I am backing up your live filesystem now. avant copie dans le répertoire de destination final.log) et commence la sauvegarde des fichiers. indiquées par l’option -I. TASK: [********************] 100% done.. une sauvegarde complète est débutée : parallèlement. -s 700m : précise la taille maximale d’un ISO à sauve- garder (4480M par défaut... utilisé par défaut.gnulinuxm a g . et faire connaissance avec Mondo Rescue. - -p Centos   : préfixe de la sauvegarde ISO. Quelle que soit sa valeur. 2. il serait idiot de la redémarrer sur CD pour restaurer quelques fichiers.3 Restauration partielle à chaud Mondo Rescue est une solution prévue pour faire des sauvegardes et restaurations complètes. incluant l’image boot+data de mindi .. /backup/Centos-1.. Aurait pu être omis ici). Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. cela nous permettra également 52 G N U / L i n u x M a g azine France N°153 www. Assurez-vous qu’il ait un espace libre minimal de la taille d’un ISO à générer..iso contenant le boot+data de mindi. le de quelques dizaines de Mo. taille d’un DVD).Calling MINDI to create boot+data disk ---evalcall---2--. Une interface ncurse vous pré- fichier /var/cache/mondo/difflevel..iso..) et des options passées à mondoarchive. Puis. depuis un autre terminal : $ sudo tail -f /var/log/mondo/mindi. 0:32 to go sentera différents écrans pour préciser les options de votre sauvegarde. TASK: [*. plus rapide que bzip2. - V : pour tester la sauvegarde générée. nous avons précisé les options suivantes : - -O : demande de créer une sauvegarde.....iso. - d /backup : destination de la sauvegarde (dans le cas d’une sauvegarde locale /var/cache/mondo par défaut). etc... Plus particulièrement pour nous ici.fr) . Attention. seulement les - dossiers locaux. Notre sauvegarde est terminée et contenue dans le fichier - T /tmp : dossier pour contenir d’autres fichiers temporaires durant l’exécution de mondoarchive. est également créé. - -N : ne pas sauvegarder les montages nfs. sans aucune donnée sauvegardée avec l’option -I. Un support bootable minimal /var/cache/ mindi/mondorescue. Toutes ces données faciliteront le processus de restauration.0 est créé.. dans un dossier local.. Cette fonctionnalité est intéressante.. séparés par un |. Ce boot+data disk indique que le support créé par Mindi contient l’image minimale de boot. Cela permet de bénéficier d’un support bootable supplémentaire pour démarrer le processus de restauration. Lancez la commande précédente. c o m ... fonctionnelle.] 3% done.. liste des partitions et montage. mondoarchive va commencer par créer une liste des fichiers à sauvegarder.. - I "/" : liste des chemins des dossiers à sauvegarder. et contient un horodatage pour permettre une éventuelle sauvegarde différentielle future. ainsi que des données. /run ni /tmp. parcourus récursivement ("/" par défaut. car elle peut être utilisée à chaud sans redémarrer la machine : si la machine est toujours en ligne. (le préfixe vaut mondorescue comme valeur par défaut). les suivants s’appelleront Centos-2. Par défaut.TASK: [*. /sys.] 1% done. - E : liste de dossiers à ne pas sauvegarder.. /proc. Utiliser mondoarchive en ligne de commandes permet néanmoins d’avoir accès à toutes les options de sauvegarde : $ sudo mondoarchive -OV -i -N -G -s 700m -p Centos -d /backup -S / tmp -T /tmp -I "/" -E "/var/cache/mondo" Dans la commande précédente.. Cela vous permettra d’utiliser une petite machine virtuelle pour effectuer les manipulations suivantes.... Une fois mindi terminé. mondoarchive ne sauvegarde pas /mnt/ floppy. l’inactivité de la barre de progression peut vous donner l’impression que mindi a planté. -i : sauvegarder au format ISO.iso.... /mnt/cdrom.. Si la taille des données à sauvegarder est supérieure à la taille maximale définie. -S /tmp : dossier temporaire dans lequel est créé le fi- chier ISO en cours.10 décembre 2012 à 16:20 Pour effectuer votre sauvegarde. Elles correspondent à des informations récupérées de la machine en cours de sauvegarde (configuration.log - G : utilisez gzip... Ces données sauvegardées ne correspondent pas aux données que vous désirez sauvegarder. .. pour faire une sauvegarde complète du système.

Tapez simplement [ENTREE]. autrement dit leur chemin original. qui vous présente les différents modes de restauration : nuke. Étant donné que celle-ci est dans un dossier local. CD-RW ou DVD.10 décembre 2012 à 16:20 Une série d’écrans ncurse nous demande d’abord d’insérer un éventuel média amovible contenant la sauvegarde. g n u l i n u x m a g. ce qui a pour effet de démarrer le mode interactif par défaut. Utilisez les flèches droite et gauche ou [TAB] pour naviguer vers le menu inférieur et au besoin étendre (menu More) ou réduire (menu Less) l’arborescence d’un dossier. dans le troisième écran. / par défaut. puis sélectionnez Hard disks comme source de la sauvegarde (Figure 1). Notez que le clavier est en QWERTY avec Lilo. bénéficiant de plus de fonctionnalités et nécessaire en cas de crash sérieux de la machine.fr) . que ce soit dans notre exemple ou même en situation réelle. Figure 3 Figure 1 Choisissez Compare Only ! (équivalent au mode compare de lilo). La liste des fichiers va être récupérée. Cliquez OK . w w w. Figure 2 2. pour comparer les fichiers présents sur le disque avec ceux de la sauvegarde. cliquez OK . et indiquez le dossier contenant celle-ci. ce mode est tellement interactif qu’il vous affiche encore un menu vous présentant les mêmes options que LILO (Figure 3) ! Sélectionner Exit to shell est l’équivalent du mode Expert : vous êtes dans une console et pouvez exécuter des commandes au besoin avant d’initier la restauration. mondorestore vous propose de spécifier dans quel répertoire extraire les fichiers sélectionnés. Vous devez ensuite valider la table de partitionnement enregistrée lors de la sauvegarde. et démarrez votre machine dessus. Cliquez sur [Entrée] pour sélectionner un fichier ou un dossier (son contenu) pour restauration (une étoile indique les éléments marqués comme à restaurer). Préférez. Choisissez CD-R.4 Restauration Nous allons maintenant voir la restauration en démarrant sur le live CD.com GNU/Linux Magazine France N° 1 5 3 53 . Lancez simplement mondorestore : $ sudo mondorestore Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Vous arrivez sur un prompt lilo. pour éviter d’écraser le fichier existant et pouvoir le comparer avec celui restauré. La restauration a eu lieu. Précisez ensuite Centos comme préfixe de notre sauvegarde. simple. Vous devez préciser où se trouve la sauvegarde. Une fois démarré. cliquez OK . compare ou expert. qui vous fait déjà apprécier Mondo Rescue. /backup. lancez mondoestore sans argument pour ré-afficher le menu de la figure 3.SAUVeGARDe eT CLOnAGe À CHAUD De VOS mACHIneS AVeC MOnDOReSCUe de vérifier notre sauvegarde. Gravez le fichier Centos-1. interactive. un dossier différent tel que /tmp.iso généré (ou montez-le sur une VM). étant donné que les fichiers sont contenus sur le disque avec lequel nous avons booté en live CD. et mondorestore va afficher un explorateur de fichiers (Figure 2). pour sélectionner plus précisément des éléments contenus pour restauration. rapide et efficace. Depuis la console (en mode expert ou après Exit to shell). Dès que votre sélection est faite.

Figure 4 Les menus Automatically (équivalent à nuke depuis LILO) et Interactively (équivalent à interactive) sont ceux vous permettant d’effectuer la restauration. un écran vous permet de modifier la table de partitionnement sauvegardée de la machine source (Figure 5).).gnulinuxm a g . Figure 2). Exécutez mondorestore pour ré-afficher le menu. en suivant les mêmes tâches : partitionnement. Il reste que dans certains cas. dans la console en mode expert. Dans ce mode. tout se passe sans votre intervention. un message de confirmation s’affichera. Si vous ne souhaitez que restaurer certains fichiers. Une fois satisfait de la comparaison. nous venons d’effectuer la sauvegarde. La différence est qu’en mode automatique. Une fois les modifications faites. et lancez la restauration en mode automatique ou interactif. et choix Hard Disk sous ncurse). Dans ce cas. redémarrage. si vous changez la disposition de la machine cible (ajout d’un disque. copie de tous les fichiers sauvegardés. au format iso (option -i en ligne de commandes. Figure 5 Un autre écran vous permet de modifier /etc/fstab. Ainsi. /etc/mtab ou la configuration de grub pour prendre en compte une éventuelle modification des partitions. etc. Vous pouvez accéder aux informations récupérées par Mindi. Le mode interactif convient pour les autres cas de restauration.10 décembre 2012 à 16:20 pour que la comparaison puisse se faire. préfixe utilisé. Un explorateur de fichiers similaire à celui présent dans la partie précédente pour la restauration à chaud vous permettra de sélectionner seulement les fichiers désirés (cf. D’autres messages vous donneront la possibilité de re-générer initrd. ajout ou suppression de partitions. etc.SySADmIn Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Ce mode convient donc si vous souhaitez faire une restauration totale. le mode interactif permet vraiment de maîtriser tout le déroulement du processus de restauration. avant les étapes de formatage et partitionnement. Celle-ci devrait être courte. avec une commande telle que : # cd /boot # mkinitrd -v -f initrd-`uname -r`. mondorestore charge les fichiers sauvegardés et les compare avec les fichiers sur le disque. mondorestore vous permettra d’exécuter e2label ou tune2fs pour que vos labels soient corrects avant de r edémarrer. il faut choisir le mode expert. Finalement. et/ou de ne pas restaurer l’ensemble des données. avant chacune des tâches listées précédemment. vous pouvez décider de ne pas re-partitionner. pour passer en console. ne pas formater. exécution de Grub.img `uname -r` 3 Pour aller plus loin 3. si vous utilisez des labels sur vos partitions. Vous le voyez. Vous pouvez sélectionner un CD-R. et exécuter d’éventuelles commandes : configurer le réseau car les paramètres réseau récupérés de la machine sauvegardée ne peuvent être utilisés lors de la restauration. configuration réseau. Vous revenez dans la console. et de vous rappeler et vous permettre d’effectuer des opérations additionnelles pour ajuster le nouveau système. situées dans le dossier tmp. avec les mêmes paramètres qu’à la sauvegarde (les fameuses informations récupérées par Mindi). cliquez Close.1 Destinations de sauvegarde Nous n’avons vu que la sauvegarde et la restauration vers un dossier local. Vous avez d’autres destinations à disposition. des écrans de confirmation supplémentaires sont disponibles pour répondre à d’autres scénarios de restauration. c o m . Ensuite. créer un RAID ou du LVM. lancez mondorestore pour ré-afficher le menu. formatage.cfg contient par exemple tous les paramètres de la commande de sauvegarde et plus : compression. non disponibles en mode interactif. Le fichier tmp/mondorestore. CD-RW ou DVD comme support de sauvegarde 54 G N U / L i n u x M a g azine France N°153 www. Toujours dans ce mode. etc. et vous affiche une liste des différences (Figure 4).fr) . des manipulations supplémentaires sont à effectuer avant de commencer la restauration.

10 décembre 2012 à 16:20 L’option -U sauvegarde vos données vers un périphérique USB. le support généré sera bien sûr rendu bootable. Ils seront générés dans le dossier /backups/CentosServer du serveur NFS. Par exemple.168. 3.10:/backups -d "Centos-Server" -T /tmp -S /tmp -E "/var/cache/mondo" Nous n’avons pas précisé le préfixe (avec -p). C’est pourquoi la sauvegarde vers un dossier partagé en NFS ou SSHFS est intéressante : la souplesse du stockage de l’option Hard Disk. Ce dossier contient un répertoire par serveur à sauvegarder. cela nous donne : $ sudo mondoarchive -O -N -G -2 -n nfs://192. Pour un CD-RW. si la taille des données à sauvegarder est supérieure à la taille d’un support.. exportant un dossier /backups. Dans tous ces cas de figure. et faire votre w w w. pour pouvoir être utilisé.0. Un dossier distant. De plus.fr) . mondorescue-2.0.168. g n u l i n u x m a g. doit être monté (présent dans /etc/mtab) et/ou montable (présent dans /etc/fstab). donc toutes les options utilisables avec -i sont disponibles.SAUVeGARDe eT CLOnAGe À CHAUD De VOS mACHIneS.2 -i ou -n pour vos sauvegardes ? Vous vous demandez peut-être l’intérêt d’utiliser -n. pour organiser et retrouver facilement les sauvegardes.10. Il vous faudra également prévoir l’éventualité de changer manuellement un support. lecteur de bande ou clé/disque USB) et le renseigner à mondoarchive avec l’option -d. le ou les différents fichiers iso auront donc le nom par défaut mondorescue-1.iso. pour sauvegarder un serveur de nom Centos-Server. si votre volume de données à sauvegarder est supérieur à la taille d’un support. mondoarchive se chargera d’effacer le CD-RW s’il a déjà été utilisé. du nom du serveur. alors que vous pourriez monter le dossier distant NFS ou SSHFS dans un dossier local. Il vous faut pour cela utiliser l’option -n. Utilisez l’option -t pour sauvegarder vers un support à bandes magnétiques..com GNU/Linux Magazine France N° 1 5 3 55 . Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. et la centralisation de toutes vos sauvegardes en un point unique de votre réseau. La sauvegarde est faite par défaut au format ISO. imaginons que nous ayons un serveur à l’adresse 192. vous devrez insérer un support supplémentaire dès que mondoarchive vous le demandera.. vous devrez connaître le périphérique /dev/XXX concerné (graveur de CD ou DVD. -w et -r respectivement).iso. En ligne de commandes. Pour un CD/DVD comme un périphérique USB.. (option -c. avec NFS.

gnulinuxm a g . les champs demandés par l’option Net Mount seront remplis automatiquement avec les paramètres de la sauvegarde. Avec l’option -D. À vous de vous assurer que vous avez bien une sauvegarde complète. il y a une sauvegarde complète. ça ne fonctionnera pas. Si vous faites une sauvegarde avec l’option répertoire distant. dans ce type de stratégie de sauvegarde. Que ce soit pour restaurer en mode interactif. pourquoi ne pas coupler sa capacité à sauvegarder à chaud avec une tâche cron. quelles que soient les options utilisées.0 ! Il vous faut donc obligatoirement exécuter mondoarchive sans l’option -D. Comme indiqué précédemment. 3.4 Automatiser tout ça Maintenant que nous connaissons un peu plus Mondo Rescue. avec une possibilité de restauration des données datant seulement d’au plus une semaine. mondorestore montera automatiquement le bon dossier NFS depuis le serveur. c o m .0.168. Les sauvegardes seront stockées de manière similaire à celle évoquée précédemment. si un tel fichier difflevel.3 Sauvegarde différentielle Par défaut.fr) .. et de changer de préfixe pour ne pas écraser une complète par l’exécution d’une différentielle. les paramètres NFS/SSHFS de cette sauvegarde seront utilisés par défaut. mais sur ce fichier difflevel. ou son contenu. À tout moment.SySADmIn Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. les suivantes différentielles contiennent les fichiers modifiés depuis cette sauvegarde.0 n’existe pas. pour générer un tel fichier par une sauvegarde complète explicitement demandée. sauvegardez ce script dans /etc/crond. lorsque vous allez restaurer.5 Restauration en PXE Dans le cas d’une sauvegarde au format ISO. 3. vous pouvez bénéficier d’une solution de clonage à chaud automatisée rapidement avec Mondo Rescue. La documentation officielle de Mondo Rescue propose une partie pour vous aider à mettre en place une tâche cron interactive à l’aide de at et screen [BACKUPCRON]. vous pouvez utiliser une installation PXE pour démarrer sur le réseau une machine à restaurer.10" NFS_SHARE="/backups" NFS_MOUNT="/mnt/backups" PREFIXE="full" DIFFERENTIELLE="" 3. Les sauvegardes doivent être mises à disposition sur un serveur NFS. Pour rappel. mondoarchive se base sur le temps au format epoch contenu dans le fichier /var/ cache/mondo/difflevel. pour automatiser la sauvegarde complète d’une machine ? Nous allons écrire un script shell pour vous servir de base de sauvegarde. Il supporte également les sauvegardes différentielles avec l’option -D passée à mondoarchive.0. pour que la 56 G N U / L i n u x M a g azine France N°153 www. Une sauvegarde complète est exécutée le lundi. une restauration nécessite au plus deux sauvegardes : la complète et la différentielle correspondant au jour désiré. une différentielle les autres jours : #!/bin/bash DAY=`date +%A` NAME=`hostname` NFS_SERVER="192. sur un serveur NFS. Tout fichier postérieur à cette date est sauvegardé.iso ${NFS_MOUNT}/${NAME} umount ${NFS_MOUNT} Pour qu’il soit exécuté tous les jours. Soyez conscient également que l’exécution sous cron de mondoarchive ne permet pas de l’utiliser de manière interactive: si vous sauvegardez vers un support qui peut nécessiter un changement manuel (insérer une nouvelle cassette par exemple).. Mindi sauve également les paramètres de cette sauvegarde. then PREFIXE="diff-${DAY}" DIFFERENTIELLE="-D" fi mount -t nfs ${NFS_SERVER}:${NFS_SHARE} ${NFS_MOUNT} service mysqld stop #sauvegarde mondoarchive -O ${DIFFERENTIELLE} -N -G -2 -n nfs://${NFS_ SERVER}:${NFS_SHARE} -p ${PREFIXE} -d "${NAME}" -T /tmp -S /tmp -E "/var/cache/mondo" service mysqld start #On récupère au passage le média bootable minimal mv /var/cache/mindi/mondorescue. mais ne crée pas de fichier /var/cache/mondo/difflevel. chaque machine stockant ses sauvegardes dans un dossier à son nom. une sauvegarde complète est automatiquement effectuée.daily/mondoarchive Le script et la stratégie de sauvegarde sont basiques. Mais cela vous démontre qu’en ajustant cet exemple. Mondo Rescue sauvegarde tous les fichiers des répertoires qui lui sont demandés.10 décembre 2012 à 16:20 sauvegarde au format ISO avec l’option -i dans ce dossier local.0.daily/mondoarchive et donnez-lui les droits d’exécution : $ sudo chmod u+rwx. Une sauvegarde différentielle avec mondoarchive ne se base donc absolument pas sur l’existence ou non d’une sauvegarde complète. à la sauvegarde. if [ $DAY != "lundi" ]. pour récupérer le(s) média(s) de sauvegarde. L’intérêt est d’automatiser la sauvegarde et la restauration au maximum. Ou encore en mode nuke/automatique.go-rwx /etc/cron. Pour connaître les fichiers à sauvegarder depuis la dernière sauvegarde complète.

img load_ramdisk=1 prompt_ramdisk=0 ramdisk_size=131072 selinux=0 rw root=/dev/ram iso acpi=off apm=off devfs=nomount exec-shield=0 pxe ipconf=eth0:dhcp netfsmount=192.com GNU/Linux Magazine France N° 1 5 3 57 . En particulier. vous pouvez juste utiliser un unique couple de fichiers initrd. il ne connaît pas d’alternative et mérite de vous y intéresser quelle que soit la taille de votre parc. dont on n’entend pas assez parler. Dans tous ces cas. Mondo Rescue est facile à mettre en place. et la restauration se passe sur celle-ci. vous sauvera la mise et vous évitera bien des regrets lors de plantage. Vous trouverez également sur la documentation officielle un processus détaillé pour faire de la virtualisation de serveurs physiques [P2V]. il ne peut rivaliser avec des projets dédiés plus poussés comme CloneZilla.iso. Mais son énorme avantage est de travailler à chaud. à mon avis.org/ [BACKUPCRON] http://www. pour prendre en compte une nouvelle configuration ip de la machine à restaurer et NFS du serveur de stockage des sauvegardes : LABEL Centos-Server MENU LABEL Centos-Server kernel vmlinuz append initrd=initrd. Une fois en place.img/vmlinuz pour démarrer en PXE. elle va charger en mémoire les fichiers nécessaires en TFTP. Les différents paramètres utilisables dans le menu sont présentés dans /usr/share/doc/mindi-2. À part que la restauration peut avoir lieu sur une machine dont la configuration diffère de la machine sauvegardée. utilisés pour restaurer la machine.mondorescue.fr) .mondorescue. Conclusion Mondo Rescue est un projet mature et stable. Ce n’est pas le sujet de l’article. Il va falloir préciser les bons paramètres dans le menu de PXE.html Grâce à ces options. À ma connaissance. Pour vos autres machines qui seraient dans le même cas. et créer une entrée dans pxelinux.org/docs/mondorescue-howto.mondorescue. html#BACKUP-CRON [PXE] http://www. contenus et visibles dans tmp depuis le mode expert.168.3/README. Ce cas de restauration simple fonctionne dans le cas où la machine sauvegardée l’a été en NFS. les fameux paramètres sauvés par Mindi lors de la sauvegarde. qui peuvent travailler en Multicast. w w w. ne serait-ce que pour faire des sauvegardes et restauration sans PXE.cfg/default : LABEL Centos-Server MENU LABEL Centos-Server kernel vmlinuz append initrd=initrd. Dans tous les cas.www1. À noter que Mondo Rescue offre une intégration et des fonctionnalités poussées sur les serveurs HP Proliant.img load_ramdisk=1 prompt_ramdisk=0 ramdisk_size=131072 selinux=0 rw root=/dev/ram iso acpi=off apm=off devfs=nomount exec-shield=0 pxe Démarrez la machine à restaurer sur le réseau.mondorescue. pour comparer les fichiers.img et vmlinuz dans /tftpboot (en leur donnant un autre nom ou en créant des répertoires par machine bien sûr).pdf [iLO] http://h18013. ou les paramètres du serveur NFS hébergeant les sauvegardes utiles au PXE ne sont pas les mêmes que celui du serveur NFS ayant servi à la sauvegarde. g n u l i n u x m a g. récupérez les fichiers initrd.org/ [PROJECTBUILDER] http://projectbuilder.cfg.hp. en récupérant les fichiers respectifs initrd. Il est vrai que comme outil de clonage. La sauvegarde peut avoir eu lieu avec l’option -i ou -n en SSHFS. Si vous êtes une petite structure.10:/backup-images netfspath=centos6-server Références [MONDORESCUE] http://www. et paramétrer les entrées des menus de chaque machine au besoin. comme expliqué précédemment.100. il pourra aussi largement faire office de solution de clonage et de déploiement d’images. le responsable du projet étant employé et spécialiste open source chez HP. pour finalement vous présenter le menu interactif de mondorestore. générés par mondoarchive : $ $ $ $ sudo sudo sudo sudo mount /backups/centos6/Centos-1.thenoccave.org/ docs/p2v. ou la sauvegarde n’a pas été faite avec l’option -n de NFS. la restauration via Mondo Rescue s’intègre avec la technologie iLO [iLO] de HP. ou depuis le média bootable minimal /var/cache/mindi/mondorescue.pxe.10 décembre 2012 à 16:20 Il vous faut déjà disposer d’une installation PXE.img et vmlinuz depuis le premier ISO de la sauvegarde.iso /mnt/cdrom -o loop cp /mnt/cdrom/initrd.SAUVeGARDe eT CLOnAGe À CHAUD De VOS mACHIneS AVeC MOnDOReSCUe machine démarrée puisse y accéder en NFS.com/ 2012/03/28/centos-6-pxe-server/ [P2V] http://www.img /tftpboot/ cp /mnt/cdrom/vmlinuz /tftpboot/ umount /mnt/cdrom/ Les fichiers n’ont pas à faire partie de la sauvegarde que vous souhaitez restaurer.org [FTP] ftp://ftp. ne sont pas bons. vous pourrez trouver facilement des informations récentes sur Internet pour Centos 6 [PXE]. ou lancer la restauration automatique ou interactive depuis les sauvegardes du serveur NFS. mais la restauration. vous pouvez procéder de même. Créez ensuite le fichier /tftpboot/pxelinux. Dans notre exemple.1. sera plus simple si la sauvegarde a été faite directement en NFS avec l’option -n. Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.com/ products/servers/management/ remotemgmt.

c’est-à-dire qu’il n’y a pas de répartition du nombre de threads entre les 2 instances. Les résultats de ces tests permettent d’anticiper d’éventuels problèmes de charge des serveurs et ainsi d’ajuster les ressources matérielles au trafic attendu. il est toujours intéressant voire essentiel de tester son application avant sa mise en production en lui faisant subir un test de charge afin d’évaluer ses performances. ou encore avant de grands événements tels que les soldes pour les sites marchands. Un test de charge vous permettra donc d’avoir une estimation du nombre de requêtes par seconde que votre infrastructure pourra supporter et d’avoir une idée du nombre de visiteurs simultanés que votre site pourra accueillir. bien que le plus important sur un site web soit le contenu qu’il propose. Cette instance vous permettra également de contrôler les injecteurs qui eux se chargent d’exécuter le scénario. . et ne pas risquer de perdre des visiteurs. un outil permettant d’effectuer ce type de tests. Son utilisation consiste dans un premier temps à établir un scénario de test. Ils peuvent également mettre en avant les possibles faiblesses L de l’application testée et orienter les recherches d’optimisation.. etc. En effet. Après une présentation de JMeter.NeTADmIn Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.). JMeter est écrit en Java et son développement est géré par la fondation Apache.fr) . les élections pour les sites d’info. ’un des critères les plus importants pour qu’un site soit apprécié de ses visiteurs est que son chargement soit performant. ces tests sont généralement effectués avant la mise en production d’un site ou d’une nouvelle version d’un site. mais nous nous concentrerons ici sur la mise en œuvre d’un test de charge d’une application web. le même scénario est exécuté par chacun d’entre eux. Bien qu’ils puissent être utilisés à tout moment. les internautes sont généralement vite lassés par les éventuelles lenteurs qu’ils peuvent rencontrer. c o m . Illustration 1 : Fonctionnement global de JMeter 58 G N U / L i n u x M a g azine France N°153 www. Lorsque vous fournissez un scénario à plusieurs injecteurs à la fois.10 décembre 2012 à 16:20 Testez vos applications web avec JMeter par Jérémy Hage [Ingénieur Systèmes et Réseaux à Oxalide] À la fin du développement d’un site internet. ldap. puis à faire répéter ce scénario autant de fois et par autant de visiteurs (ou threads) simultanés que vous l’aurez décidé. nous verrons la façon de créer un scénario et l’exécuter. Pour ne pas avoir de mauvaises surprises. c’est-à-dire un exemple de session de navigation d’un visiteur. il est important de savoir si l’architecture dédiée à votre site est adaptée aux exigences de votre application en matière de consommation des ressources en situation de fort trafic.. Pour ce faire. les grands championnats pour les sites de sport. Le contrôleur est la machine à partir de laquelle vous avez créé votre scénario. Nous verrons ensuite comment exploiter et interpréter les résultats que vous obtiendrez. mail.gnulinuxm a g . La figure 1 représente de manière générale le fonctionnement de JMeter. je vous propose de découvrir JMeter. 1 Présentation de JMeter JMeter est un logiciel permettant d’effectuer des tests de charge de plusieurs services différents (ftp.

je n’ai pas réellement d’objectifs. 3 Installation et utilisation de JMeter 3. Le scénario que l’on utilisera se divise en fait en 2 parties : 1-C  onsultation de 2 articles (200 threads simultanés maximum) - L’internaute arrive sur la page d’accueil et y reste 10 secondes. j’ai utilisé Cacti qui est un outil simple permettant d’obtenir ces informations. c’est-à-dire que nous augmenterons le nombre de threads de manière périodique jusqu’à atteindre la limite spécifiée par notre configuration. - I l attend une minute et recommence. le lit et rédige un commentaire en 50 secondes. j’utiliserai la dernière version récupérée depuis le site de JMeter (http:// jmeter. Heureusement. - Il clique sur le deuxième article et le lit durant 30 secondes. la consommation mémoire et la bande passante. 2Go de mémoire vive et 1Go de bande passante. Seulement ce n’est pas toujours le cas et on pourrait plus simplement se contenter d’une seule instance de JMeter à partir de laquelle vous élaborerez le scénario et lancerez le test de charge. L’exécution du scénario se fera de manière progressive. mais dans cet article. Cependant. J’ai fait le choix de tester un blog car les scénarios possibles ne sont pas vraiment nombreux.fr) . Il serait intéressant d’avoir au moins les informations portant sur le load average.Lors d’un trafic normal ? . JMeter étant un programme Java. L’application de test que j’utiliserai dans cet article est un « Dotclear » hébergé sur un petit serveur physique possédant 2 CPU dual core. il faut noter que lors d’un test. - Il recommence.cgi). donc un seul test nous permettra d’avoir des résultats significatifs. Par défaut. Pour l’installer.7.google. Dans le cas de ce test. Le graphage des résultats n’est pas vraiment le point fort de JMeter. com/p/jmeter-plugins/. - Il retourne sur la page d’accueil durant 5 secondes. La division en deux parties est nécessaire car la fréquence des deux scénarios n’est pas identique puisque la consultation d’article est généralement plus fréquente que le dépôt d’un commentaire. 2 Avant de commencer Il est essentiel d’avoir un objectif avant de commencer un test afin de savoir si votre infrastructure est dimensionnée selon vos attentes de trafic. la charge générée par JMeter n’est pas négligeable. donc plus l’infrastructure de votre site est robuste et plus vous aurez besoin d’injecteurs et de bande passante afin de pousser vos tests le plus loin possible. il faut installer le JRE préalablement. Vous pouvez le télécharger à cette adresse : http://code.2 Présentation de l’interface Bien que JMeter nous offre un bel environnement graphique. - Il clique sur le premier article.jar dans le répertoire lib/ext du répertoire d’installation de JMeter. C’est pourquoi il est important pour l’analyse de vos résultats d’avoir des graphes de comportement de vos serveurs. C’est pourquoi vous devez vous poser les questions suivantes : - Quel est le nombre moyen de visiteurs simultanés attendus : . Il est important de ne pas monter trop vite en charge afin que nous puissions visualiser la manière dont réagit notre infrastructure. la décompresser et lancer l’exécutable jmeter qui se trouve dans le répertoire bin de l’archive. Les résultats obtenus sur JMeter sont représentatifs de ce que l’on obtiendra côté client mais ne vous permettront pas de déterminer clairement quelles ressources arrivent à saturation lors de la montée en charge.TeSTeZ VOS APPLICATIOnS Web AVeC JMeTeR Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. il suffit de copier le fichier JmeterPlugins.1 Installation JMeter est présent dans les dépôts de la plupart des distributions.10 décembre 2012 à 16:20 Ce schéma représente le cas idéal où vous posséderiez des ressources matérielles disponibles.Lors d’un pic de trafic ? - Quel scénario de navigation sera le plus représentatif d’une visite « standard » ? Le choix du scénario est essentiel dans les tests de charge et il mérite 3. Notre test s’étalera donc sur un peu plus de 8 heures. Comme il s’agit d’un test d’un site n’existant que pour cet article. 2-C  onsultation d’un article et dépôt d’un commentaire (50 threads maximum) - L’internaute arrive sur la page d’accueil et y reste 10 secondes. son utilisation n’est pas très intuitive. g n u l i n u x m a g. il suffit de télécharger l’archive. il existe un plugin qui gère très bien cela.com GNU/Linux Magazine France N° 1 5 3 59 . que l’on y réfléchisse sérieusement afin que les résultats obtenus collent le plus à la réalité. ils ne sont pas très lisibles. - Il clique sur le premier article et le lit durant 30 secondes. Il s’agit de la version 2. Je me contenterai donc de fixer le nombre de threads simultanés assez haut pour atteindre le seuil critique et me faire une idée de sa valeur.apache. La configuration d’un scénario passe par celle de différents éléments plus ou moins indépendants que vous pouvez ajouter selon vos besoins. L’installation est très simple. Commençons par une présentation de l’écran d’accueil de JMeter : w w w.org/download_jmeter.

c’est-à-dire le temps que devra mettre JMeter pour lancer tous les threads. Enfin. c’est dans l’encadré vert que s’effectuera la configuration des éléments sélectionnés dans la partie orange. L’encadré orange est la partie où seront listés les différents éléments du test. - le nombre d’itérations. les éléments visibles ci-dessous sont suffisants pour créer un scénario. Nous en avons 2 dans notre exemple : Consultation et Commentaire. Le plan de test contiendra toutes les informations nécessaires au test de charge. Cette partie n’est pas sauvegardée à l’enregistrement d’un scénario. 3. la gestion des requêtes ou encore des cookies. Vous pourrez à partir de là lancer vos tests. 60 G N U / L i n u x M a g azine France N°153 www. On peut déjà voir que nous avons 2 parties principales : le plan de test et le plan de travail.fr) . c o m . Nous verrons par la suite quelques-uns des éléments les plus utilisés dans les tests de performance web. Cet élément permet de : .gnulinuxm a g .NeTADmIn Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Le groupe d’unités s’obtient en cliquant droit sur Plan de puis Ajouter -> Moteurs d’utilisateurs -> Groupe d’unités. - la durée de montée en charge.3 Élaboration du scénario Nous pouvons commencer à ajouter des éléments. c’est-à-dire le nombre de fois que le scénario devra être répété par chaque thread.10 décembre 2012 à 16:20 Écran d’accueil de JMeter L’encadré rouge représente les raccourcis des menus. il contiendra tous les éléments hors test et tout ce que vous souhaitez conserver temporairement. je vous conseille de cliquer sur Programmateur de démarrage afin de configurer la durée du test. Pour un test de charge de site web. Arbre de configuration du test test. Il est possible d’effectuer une répétition infinie. Ils représentent les 2 parties du scénario que nous avons vu plus haut. gérer le nombre de threads simultanés et visualiser les résultats du test. Dans ce cas. les stopper ou encore les réinitialiser. c’est-à-dire les éléments de configuration du nombre de threads. Quant au plan de travail.fixer le nombre de threads simultanés. Le groupe d’unités est l’élément obligatoire pour tout test de charge avec JMeter.

il faut dans un premier temps configurer votre navigateur afin qu’il utilise le proxy local écoutant sur le port 8080. JMeter est assez gourmand en ressources. etc. Pour ajouter cet élément. L’élément « Serveur Proxy HTTP » nous permettra d’enregistrer un scénario simplement en naviguant sur les pages que nous voulons y inclure. sauf si vous souhaitez tester votre bande passante.fr) . Pour ajouter cet élément. il faut cliquer droit sur Plan de travail puis : Ajouter -> Éléments Hors Test -> Serveur Proxy HTTP. vous appuyez sur Arrêter. En effet. Le principe est que JMeter deviendra notre proxy le temps de l’enregistrement du scénario. N’oubliez pas de restaurer la configuration de votre navigateur dans son état d’origine. Il faut maintenant ajouter l’élément qui nous permettra d’enregistrer les résultats obtenus dans un fichier que nous pourrons exploiter après le test. il faut ajouter des compteur de temps afin de marquer des pauses après chaque page. il faut sélectionner l’ élément « Serveur Proxy HTTP » puis choisir le contrôleur dans lequel s’enregistrera la liste de requêtes. Si vous déroulez le contrôleur sélectionné. la charge générée par les requêtes d’éléments statiques est négligeable face à celle générée par PHP ou autres langages de script. Je vous conseille donc de toujours w w w.Response Codes per Second. au niveau de JMeter. Pour ce faire. Pour l’ajouter. Ainsi. il faut cliquer sur Lancer. Le gestionnaire de cookies n’est réellement important que pour les sites utilisant des cookies ou des sessions gérées par des cookies. Pour ce faire. Il existe une quinzaine de types de contrôleurs différents. De manière générale. Tous les éléments permettant de faire le test ont été ajoutés. Pour ajouter cet élément. Il faut noter que durant les tests de charge. vous pourrez voir la liste de toutes les requêtes effectuées lors de votre navigation. Enfin. comme nous l’avons vu dans la présentation du scénario. surtout lorsqu’il doit afficher les résultats en temps réel. le cookie soit généré à nouveau. Comme la visite d’un site est ponctuée par des temps de lecture du contenu des pages.TeSTeZ VOS APPLICATIOnS Web AVeC JMeTeR Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Il pourrait être intéressant pour la configuration de cet élément de cocher Nettoyer les cookies à chaque itérations  ?  afin que lors de la répétition d’un scénario par un même thread.com GNU/Linux Magazine France N° 1 5 3 61 . Sa configuration est simple. il faut cliquer droit sur Groupe d’unités puis  : Ajouter -> Configurations -> Paramètres HTTP par défaut . Ensuite. le port à utiliser. il pourra enregistrer toutes les requêtes que nous faisons.10 décembre 2012 à 16:20 L’élément « Paramètres HTTP par défaut » vous permettra de fournir au groupe d’unités des paramètres HTTP tels que le nom de domaine du site (ou son IP). Un contrôleur est l’élément qui vous permettra de gérer un groupe de requêtes HTTP. Vous pouvez maintenant naviguer dans votre site en suivant le scénario que vous avez établi préalablement. nous nous contenterons d’un contrôleur simple. Ces éléments permettent de spécifier comment seront gérées les requêtes d’un groupe. il faut cliquer droit sur Plan de test puis : Ajouter -> Configurations -> Gestionnaire de cookie HTTP. Vous pouvez exclure des URL ou des types de fichiers en spécifiant les motifs dans le champ «  Motifs à exclure  ». il faut cliquer sur la requête concernée puis Ajouter -> Compteur de temps -> Compteur de temps fixe. nous allons ajouter un des éléments du plugin que nous avons installé en cliquant droit sur Plan de test : Ajouter -> Recepteur -> jp@gc . g n u l i n u x m a g. il faut cliquer droit sur Groupe d’unités puis : Ajouter -> Contrôleurs Logiques -> Contrôleur Simple. il suffit de spécifier le nombre de millisecondes à patienter. il n’est pas très utile de conserver tout le contenu statique. Il existe une dizaine de compteurs de temps. Pour l’ajouter. Nous allons utiliser un compteur de temps fixe. Pour terminer. Le scénario que nous présenterons ici étant assez simple.

on peut visualiser les résultats obtenus en lançant JMeter et en ajoutant les différents récepteurs que l’on souhaite. nous ouvrirons ce même fichier en cliquant sur Parcourir et le graphe sera généré. vers 23h00./jmeter -n -X -t /chemin/vers/fichier. Un seul récepteur est nécessaire pour recueillir les résultats.10 décembre 2012 à 16:20 lancer vos tests en ligne de commandes.gnulinuxm a g .jp@gc . À peu près au même moment. voici le graphe du nombre de réponses obtenues par seconde : On remarque que l’on atteint vers 23h40 un seuil de 10 requêtes par seconde. je n’ai eu à ajouter que « Nombre d’unités active » en plus de la sélection par défaut. Vous trouverez ci-dessous les résultats obtenus pour ce test. on peut voir que les 4 de load sont franchis vers 23h également. .jp@gc . . Pour ce faire. Lorsque le test sera fini. c o m . Cette option permettra d’obtenir des graphes de temps de réponse en fonction du nombre de threads actifs. Si vous cliquez sur Configurer.jp@gc . Les récepteurs que j’utilise le plus souvent sont : .NeTADmIn Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Temps de réponse en fonction du temps En regardant le graphe de load average du serveur obtenu grâce à Cacti. Vous pourrez exploiter les résultats obtenus après le test.Active Threads Over Time .Response Times Over Time .fr) . Nous pouvons enfin enregistrer notre plan de test et entrer la commande suivante pour lancer le test : .Response Times vs Threads . Load Average durant les 6 premières heures 62 G N U / L i n u x M a g azine France N°153 www.1 Les graphes JMeter Tout d’abord. Pour faire ce test. le temps de réponse des requêtes subit une forte augmentation : Nombre de réponses par seconde (code 200) 4 Exploitation des résultats Une fois le test terminé. j’ai utilisé 2 instances Jmeter : un contrôleur et un injecteur. on retrouve le phénomène. Pour cela. cela indique un début de surcharge.Response Codes per Second . et comme nous avons 4 cœurs. mais plusieurs pourront être utilisés pour les visionner une fois que le test sera fini. Si nous jetons un œil au détail du temps de réponse moyen. Pour ce test. il faut juste spécifier le chemin du fichier dans le champ Nom du fichier. vous pourrez sélectionner ce qui sera enregistré dans le fichier. la procédure n’est pas très compliquée et est bien expliquée sur le site du projet JMeter.jp@gc .jmx 4. Je ne m’attarderai pas sur la configuration d’un test en utilisant un injecteur. . il faut spécifier le fichier dans lequel vous enregistrerez vos résultats.

On aurait également pu ajouter un reverse proxy afin de voir combien de requêtes par seconde supplémentaire notre serveur pourrait supporter. Les testeurs de charge sont donc les outils idéaux pour justifier le choix d’un composant par rapport à un autre si la performance est l’un des critères de décision. d’après le graphe des temps de réponse en fonction du nombre de threads. Nombre de thread actifs en fonction du temps Donc pour conclure. Temps de réponse en fonction du nombre de threads Graphe de consommation de la RAM Consommation CPU w w w.10 décembre 2012 à 16:20 On peut également conclure que c’est la ressource CPU qui est saturée et qui empêche d’obtenir des résultats plus élevés puisque les CPU ont atteint les 100  % d’utilisation et le load average a été élevé pendant le test alors que la RAM n’est pas entièrement consommée. notre serveur pourrait accueillir entre 170 et 200 internautes simultanément sans qu’ils ne subissent de lenteur de chargement sur le blog. On aurait pu étendre l’utilisation de Jmeter à des tests de composants logiciels.TeSTeZ VOS APPLICATIOnS Web AVeC JMeTeR Ainsi. En effet. on aurait pu s’amuser à tester notre application sur différents serveurs web en refaisant le match Apache vs Nginx vs LightHTTPd pour voir lequel est le plus performant. g n u l i n u x m a g. il suffit de regarder sur la figure 7 le nombre de threads actifs entre 22h40 et 23h40 : Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.com GNU/Linux Magazine France N° 1 5 3 63 . le temps de réponse moyen ne dépasse pas 1 seconde. En effet. Conclusion Nous venons donc de voir un test de charge qui.fr) . on peut voir que pour la tranche 170-200 threads. constitue une bonne base pour vos prochains tests. bien qu’il soit simple. pour déterminer une approximation du nombre de visiteurs simultanés que peut accueillir notre plateforme.

C'est intéressant. Le noyau fourni par Google pour cette carte s’arrête cependant à la gestion d'un écran numérique via connectique HDMI. permet d’interfacer plusieurs entrées et sorties en parallèle.10 décembre 2012 à 16:20 Le système graphique par Benjamin Zores [Architecte Android et Linux Embarqué @ Alcatel-Lucent] Nous nous sommes arrêtés lors du précédent chapitre de cette série au mécanisme d’initialisation du système. L’écran LCD et la dalle tactile consistent en 2 périphériques différents qu’il va falloir faire interagir (nous verrons ça dans le prochain numéro). P Fig. Place maintenant à la compréhension d’un composant clé de tout système embarqué moderne avec la gestion de l’affichage graphique.MObILITÉ À la découverte d’Android : Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Dans la plupart des cas. c'est au niveau le plus bas. propres au chipset de TI. au sein de la mémoire principale. à savoir le noyau Linux. dont la gestion native de l'affichage. Ce dernier. Cette dernière. supporte bien évidemment un grand nombre de fonctionnalités. via un ensemble de «  Managers » et « Overlays ». tel que présenté dans la figure 2. certes. Le processeur écrit les données graphiques dans le framebuffer. Le framebuffer représente donc un espace mémoire fixe. D’une manière générale dans l’embarqué. et le plus générique. qui dispose de sa propre mémoire dédiée. Dans notre cas. C'est évidemment là que commencent les problèmes. soyons clairs. Voyons donc comment répondre à ce besoin. et le contrôleur graphique se charge d’afficher réellement les pixels à l’écran. l’écran LCD à piloter ne dispose pas de sa propre mémoire graphique. mais également de gérer et multiplexer les éléments purement graphiques en provenance du framebuffer et les flux vidéo. 64 G N U / L i n u x M a g azine France N°153 www. Certains systèmes très évolués peuvent cependant adresser un écran LCD via un second contrôleur. VENC et HDMI) de manière électronique. notre précédente expérimentation se basait sur une carte PandaBoard à base de processeur OMAP4 de TI. qui se charge de faire l’interface entre le logiciel et le matériel. l’écran LCD est relié via une interface spécifique au contrôleur graphique intégré au SoC comme le montre la figure 1. L’affichage du framebuffer vers notre écran LCD est donc à la responsabilité du contrôleur graphique intégré. c o m . son tampon mémoire représentant la zone d’affichage. et protégé.fr) . cette dernière est donc partagée avec le reste du système. Nous souhaiterions plutôt utiliser un écran LCD avec une dalle tactile afin d'utiliser notre périphérique comme une tablette ou un smartphone en lieu et place d'une TV. sur lequel le processeur va écrire des données et sur lequel le contrôleur graphique va les lire. mais pas forcément adapté à notre besoin. dédié.gnulinuxm a g . mais c’est un cas très rare. Avant donc même de rentrer dans les méandres d'Android et l'architecture logicielle de son sous-système graphique. our rappel. qu'il va falloir intégrer notre écran.0. s’occupe de piloter les différentes interfaces graphiques possibles (DSI. intégré à l’afficheur LCD. mais s’occupe également de la composition graphique des différentes couches logiques logicielles. il n’existe pas à proprement parler d’écran tactile. DPI. RFBI. Il existe cependant différents types d’écrans et différentes façons de les adresser. avec gestion des signaux et horloges. nativement supportée par Android 4. 1 : Architecture interne d’un contrôleur graphique intégré 1 Écrans LCD Avant toute chose. avec une carte qui effectuait un premier démarrage. Différents types d’interfaces graphiques existent et il faut donc comprendre quelles sont les capacités proposées par le contrôleur graphique de notre SoC. Le composant DSS (pour « Display SubSystem »). notre processeur OMAP4 utilise un contrôleur appelé DSS2.

et de superposer le tout. Cette dernière supporte à la fois les transmissions de données en série ou en parallèle et. également définie par l’alliance MIPI. il va donc falloir renseigner ces valeurs manuellement. - D PI (pour «  Display Pixel Interface »). Il n’est donc pas. simple à piloter et donc à expliquer. le vert et le bleu). elle fonctionne dans un seul et unique sens. qui correspond à une norme électrique de transmission de signaux (et accessoirement un connecteur standardisé) et non pas une norme d’interface. C’est la norme d’affichage historique. 18 ou 24 bits. 2 Interface DPI Nous choisirons donc de nous baser sur une interface DPI. comme le montre la figure 3. elle peut cependant créer des problèmes d’interférences électromagnétiques. - VENC (pour «  Video Encoder  »). la fré- quence d’horloge . - RFBI (pour « Remote FrameBuffer Interface »). De par sa forte consommation électrique. la synchronisation verticale . que l’interface DPI est une interface parallèle. notifiant si des données sont transmises . permet de faire véhiculer à la fois les flux audio et vidéo et de s’interfacer sur les TV modernes. -V  SYNC. w w w. Je vous laisserai libre choix du modèle d’écran que vous déciderez d’utiliser pour cet exercice et ne détaillerai pas l’assemblage électronique sur votre carte. permet de convertir notre signal numérique en analogique pour affichage sur une TV d’antan. De plus. 2 : Architecture logicielle du composant DSS2 du chipset OMAP4 -D  E (pour « Data Enable »). mais c’est un cas d’école qui finalement arrive très souvent dans la pratique. Sachez cependant. mais également les temporisations associées aux différents signaux. et des signaux de données (8 bits par couleur. Il est donc nécessaire de souder davantage de fils (ici 28) qu’avec une interface série. telles que les résolutions et fréquences supportées.fr) . -H  DMI (pour « High Definition Multimedia Interface »). de par sa faible consommation électrique. pour le rouge. 3 : Signaux de contrôles et de données de l’interface DPI Cette dernière fait intervenir plusieurs signaux de contrôles : -H  SYNC. fréquemment utilisé dans la littérature. est une interface parallèle d’affichage des données permettant de contrôler des écrans 16. la moins chère.com GNU/Linux Magazine France N° 1 5 3 65 . le processeur (source de l’image) et le périphérique LCD (destinataire des données). PCLK (pour « Pixel Clock »). sur lesquelles nous allons revenir : -D  SI (pour «  Display Serial Interface ») est une norme définie par l’alliance MIPI (« Mobile Industry Processor Interface ») pour interfacer à haute vitesse et via un bus de données série. À noter également le terme LVDS (pour « Low Voltage Differential Signaling ». Notez que je complexifie volontairement l’exercice. du processeur vers l’écran. en théorie.10 décembre 2012 à 16:20 Fig. la synchronisation horizontale . et celle sur laquelle nous allons nous baser. g n u l i n u x m a g. Cette norme a été remplacée dans l’industrie par la norme DSI mais fut la référence. Certains écrans utilisent pour ce faire un lien I2C ou SPI pour échanger des informations via le format EDID (pour « Extended Display Identification Data »). possible pour le processeur de détecter et configurer l’écran automatiquement (comme nous en avons désormais l’habitude avec nos écrans PC et TV). Fig. Ce dernier supporte donc plusieurs types d’interfaces pour piloter notre écran LCD. chacun transitant sur un fil dédié. est extrêmement utilisée dans les périphériques embarqués pour interconnecter SoC et un écran LCD. Notre écran LCD n’utilise absolument pas ce genre d’informations.À LA DÉCOUVeRTe D'AnDROID : Le SySTÈme GRAPHIQUe Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. est une interface permettant de contrôler un framebuffer et un écran distant.

Mais voilà. En pratique. ou HBI pour «  Horizontal Blanking Interval »). puis s’éteignait et devait revenir en début de ligne pour parcourir la suivante et ainsi de suite.). chaque écran LCD dispose de ses propres caractéristiques physiques. Réciproquement.10 décembre 2012 à 16:20 Revenons quelques instants sur la théorie du signal graphique en termes d’électronique. 4 : Temporisation des signaux électriques LCD La durée nécessaire au retour horizontal du canon constitue l’intervalle de synchronisation horizontale (ou HSYNC. 5 : Temporisation des signaux LCD horizontaux et verticaux Qu’il s’agisse de balayage horizontal ou vertical.MObILITÉ 3 Signaux électriques LCD Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Fig. que nous souhaitons rafraîchir à 60Hz. l’envoi du signal de synchronisation (appelé « Pulse Width ») nécessite un court instant.fr) .gnulinuxm a g .04 MHz. appelée « Pixel Clock ». Il nous est donc nécessaire d’afficher 800x480x60 pixels toutes les secondes. comme représenté sur la figure 4. appelées « Front Porch » et « Back Porch » correspondent aux durées pré et post scanline. telles que décrites dans ses spécifications (ou « datasheet ») et il est nécessaire de les comprendre pour les renseigner dans notre pilote Linux. Dans notre cas... Les écrans LCD n’utilisent plus de canon à électrons et leur affichage est globalement instantané. la durée de retour de fin de la dernière ligne au début de la première constitue l’intervalle de synchronisation verticale (ou VSYNC. notre écran LCD offre une résolution WVGA de 800x480 pixels. Les premiers écrans cathodiques (CRT) utilisaient un canon à électrons qui balayait l’écran de haut (en partant de la gauche) en bas (en arrivant vers la droite) selon un principe appelé « raster scanning ». durant lequel aucune donnée valide n’est transmise. telles que présentées dans la figure 5. ou VBI pour «  Vertical Blanking Interval  »). 66 G N U / L i n u x M a g azine France N°153 www. Fig. soit une fréquence. ainsi que le pilote pour écran DPI générique. le support pour contrôleur DPI. Le tableau (Figure 6) représente donc un exemple de spécifications LCD et la façon dont nous allons les implémenter. mais les principes ont été conservés pour des raisons de compatibilité. La première chose à faire est donc de modifier les caractéristiques de notre noyau. Le canon générait une intensité lumineuse et parcourait l’ensemble d’une ligne (appelée « scan line »). Assurons-nous d’avoir le support DSS activé. 6 : Exemple de spécifications matérielles d’écran LCD 4 Pilote LCD Ouf. estimée à 23. c’en est fini avec l’aspect électronique et matériel ! Place enfin aux modifications logicielles (il était temps. que se passe-t-il si notre contrôleur graphique ou notre écran Voilà pour la théorie. Deux autres temporisations. LCD ne sont pas capables de fonctionner à cette fréquence ? Il est pour cela nécessaire de jouer sur les temporisations des signaux de données. c o m . Paramètre Valeur type HS Period HS Active Time HS Pulse Width HS First Horizontal Data Time VS Period VS Active Time VS Pulse Width VS First Vertical Data Time TH THd THp THs TV TVd TVp TVs Fig.

phy.data_lines. }.hbp = THs . Ceci peut se faire en passant la valeur suivante en argument de ligne de commandes noyau à U-Boot : omapdss. ceci ne représente pas grand chose hélas. Ceci peut poser des problèmes futurs.reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO. . . Reste maintenant à signaler à notre SoC OMAP de bien l’utiliser. mais ça s’arrête là. .THp. . il ne vous reste plus qu’à recompiler votre noyau : ARCH=arm CROSS_COMPILE=arm-eabi.vbp = TV – TVs . Ça y est. .config = OMAP_DSS_LCD_TFT.def_disp=lcd2 Ceci devrait donc suffire à faire correspondre les caractéristiques de votre écran LCD maison vers votre pilote de périphérique. vous pourrez également le spécifier via le champ omap4_panda_dvi_ device.com GNU/Linux Magazine France N° 1 5 3 67 . . Ceci se fait via modification du fichier arch/ arm/mach-omap2/board-omap4panda.TVp. = TVp.name pour y faire correspondre notre structure mon_ecran_lcd à la place du generic (qui n’a pas grand sens finalement. . . Ceci étant fait. .acbi = 0x0.hfp = TH – THs .name = "mon_ecran_lcd". Mais jusqu’à présent. certes. Au passage. Modifiez donc le fichier drivers/video/omap2/displays/panel-genericdpi.hsw = THp.c pour ajouter le contenu suivant au tableau generic_ dpi_panels[ ]. .x_res = THd. }. Le plus simple est alors de désactiver le support HDMI en supprimant la ligne omap4_panda_hdmi_device de la structure précédente. nous sommes restés dans l’univers Linux et ses pilotes bien connus. et tel que présenté dans la structure suivante : static struct omap_dss_device *omap4_panda_dss_devices[] = { &omap4_panda_dvi_device. votre écran LCD est désormais opérationnel et vous devriez désormais voir le logo Android s’animer jusqu’à l’apparition du menu.power_on_delay = 0.c : static struct panel_generic_dpi_data omap4_dvi_panel = { .type = OMAP_DISPLAY_TYPE_DPI.driver_name = "generic_dpi_panel".name = "mon_ecran_lcd". vous constaterez également l’absence de la barre w w w.pixel_clock = FREQUENCE_DE_RAFRAICHISSEMENT * THd * TVd. Les chances étant faibles sur la capacité de votre écran LCD à supporter les résolutions typiques du HDMI (720p. L’affichage basique 2D est opérationnel. = TVs .data_lines = 24. .make zImage et à remplacer le noyau pré-compile de votre carte par votre noyau nouvellement généré : cp omap/arch/arm/boot/zImage device/ma_compagnie/mon_appareil/kernel Recompilez ensuite votre environnement AOSP et redémarrez votre périphérique.channel = OMAP_DSS_CHANNEL_LCD2.data = &omap4_dvi_panel. Si votre écran n’est pas 24 bits. l’idée globale est de modifier le champ omap4_dvi_panel.phy. Pour Android. }. Android ne supportant qu’une seule résolution d’écran à la fois.dpi. g n u l i n u x m a g. Une autre alternative est de forcer l’écran primaire à utiliser le canal logique (LCD2) de notre écran.THd .vfp . vous noterez que la « Pixel Clock » réelle diffère maintenant grandement de notre première estimation.vsw .power_off_delay = 0.10 décembre 2012 à 16:20 Les structures de données existant déjà.TVd. .dpi. 1080p). les « valeurs » étant reprises de la figure 6 : /* Mon écran LCD */ { { . chaque écran étant spécifique). Notez également la valeur de canal logique OMAP_DSS_ CHANNEL_LCD2. }. notre noyau supporte à la fois les périphériques DVI (mais il s’agit en fait de notre écran LCD) et HDMI. Ceci étant fait. Au premier démarrage. . 5 Tablette ou téléphone ? Le plus dur est désormais fait et vous disposez d’un écran fonctionnel.y_res = TVd. . .fr) . &omap4_panda_hdmi_device.name = "dvi".platform_disable = omap4_panda_disable_dvi. reste à modifier les sources de notre pilote d’écran LCD pour y ajouter le notre.À LA DÉCOUVeRTe D'AnDROID : Le SySTÈme GRAPHIQUe ARCH=arm make menuconfig Device Driver → Graphics support → [*] OMAP2+ Display Subsystem support → (16) VRAM size [*] DPI support OMAP2/3 Display Device Drivers [*] Generic DPI Panel Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. . . }. . .platform_enable = omap4_panda_enable_dvi.acb = 0x0. struct omap_dss_device omap4_panda_dvi_device = { . il risque de passer hors spécifications si vous branchez les 2 écrans en même temps. Par défaut.

d’effets visuels 3D ou de rendu vidéo.DENSITY_DEVICE. la densité de pixels par pouce (ou dpi) vaut 133. La résolution basse étant 480.devicy. int shortSizeDp = shortSize * DisplayMetrics. les ingénieurs de Google ont décidé d’implémenter leur propre compositeur graphique qui répond au nom de «  SurfaceFlinger  ». c o m . tel que présenté dans la figure 7. SurfaceFlinger s’occupe lui-même de composer son écran en superposant les surfaces en provenance des différents clients (les applications). Cela impacte l’affichage même de l’interface graphique (présence ou non des menus tactiles et orientation des boutons). 7 : Composition graphique des surfaces 68 G N U / L i n u x M a g azine France N°153 www.type"). Pour contrer cela. //tablet resolution width or height may define >= 480 //system according it to use system_bar or status_bar. } mStatusBarCanHide = shortSizeDp < standDp. notre shortSizeDp vaut alors 576 (donc moins que standDp. D’ailleurs.type=tablet PRODUCT_PROPERTY_OVERRIDES += ro. //and properity sys.mk : PRODUCT_PROPERTY_OVERRIDES += sys. if(! "". SurfaceFlinger gérant lui-même toutes les surfaces affichables. String deviceType = SystemProperties.equals("tablet")) { standDp = 480. Je vous suggère donc l’ajout de ces 2 paramètres au sein de votre BoardConfig.DENSITY_DEFAULT / DisplayMetrics.sf.gnulinuxm a g . il est possible soit de forcer le mode tablette. Ces dernières peuvent être en 2D ou en 3D. encore une fois.type used to distinguish tablet and phone. indispensable à l’utilisation de notre périphérique. à savoir 600) et Android n’affichera pas la barre de menu. Une recherche dans les sources nous présente des informations intéressantes au sein du fichier frameworks/base/policy/src/com/android/internal/policy/ impl/PhoneWindowManager. 6 Composition graphique Android est un OS résolument orienté graphique et multi-applications. selon les besoins des applications clientes. Android se base donc sur la résolution de votre écran et la densité de pixels de ce dernier pour déterminer son mode de fonctionnement.get("sys. Android n’utilise pas le serveur de fenêtres X. un seul et unique processus contrôlant ainsi l’accès au framebuffer. les applications créent ellesmêmes les surfaces destinées à être affichées et les envoient à SurfaceFlinger sous la forme d’un buffer géré par Binder.org. Afin de maximiser les performances (ou surtout pour éviter de rendre le système inutilement lent).equals(deviceType) && deviceType. les choses se compliquent grandement et il est alors temps de rentrer à proprement parler dans l’architecture graphique d’Android pour comprendre de quoi il en retourne.fr) . } else { standDp = 600. Il n’y a donc aucune opération coûteuse de recopie mémoire d’un espace d’adressage à un autre. Qt ou EFL . Fig. c’est à chaque application de créer elle-même sa propre surface et de l’envoyer à SurfaceFlinger. Comme illustré dans la figure 8. Contrairement à un gestionnaire de fenêtres classiques. int standDp. bien qu’OS embarqué.devicy. de nombreux processus peuvent vouloir dessiner quelque chose à l’écran en même temps et donc prendre le contrôle du framebuffer. Vous l’aurez deviné. Cela s’explique par le mode de fonctionnement d’Android 4. Il est donc beaucoup plus facile d’ajouter des effets visuels 3D ou de transparence.0 qui supporte désormais à la fois les téléphones et les tablettes. On gagne ainsi en stabilité et évite tout artefact visuel.java : // Determine whether the status bar can hide based on the size // of the screen.lcd_density=120 Si on souhaite maintenant un tant soit peu de performances. Contrairement aux systèmes GNU/Linux classiques. Dans notre cas (écran 7 pouces de 800x480). De ce fait.devicy. SurfaceFlinger traite des objets appelés « Surface  ».10 décembre 2012 à 16:20 de menu tactile. où un message est envoyé à chaque fenêtre (client) pour demander un ré-affichage de sa partie de l’écran.MObILITÉ Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. We assume sizes > 600dp are tablets where we // will use the system bar. soit de jouer sur la densité par pixels en définissant sa valeur (et empêchant l’auto-détection). il n’utilise pas non plus les compositeurs d’affichage que l’on peut retrouver au sein des projets DirectFB.

Un pilote noyau est également nécessaire et généralement fourni sous licence GPLv2.so └── ti └── panda └── device-vendor. Le contenu de l’archive fournie (disponible via [13] ) correspond bien aux bibliothèques dont nous avons besoin : vendor/ ├── imgtec │   └── panda │   └── proprietary │   ├── libEGL_POWERVR_SGX540_120. qui permet de maximiser les performances graphiques.mk) 7 API 2D et 3D Plusieurs API sont disponibles aux applications pour la génération de surfaces. lui-même basé sur le projet Mesa3D (que l’on retrouve sur nos distributions GNU/Linux comme implémentation open source de référence pour nos cartes 3D) et utilise le projet LLVM pour compiler les shaders 3D à la volée sur le système. la gestion des couches basses graphiques sur les systèmes embarqués Android (mais c’est également le cas pour du Linux « classique ») n’est pas de tout repos et loin d’être « propre ». Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Développées sous forme d’API par le groupe Khronos (cf. Ce dernier permet le rendu de différents types d’objets : objets géométriques 2D classiques.so │   ├── libGLESv2_POWERVR_SGX540_120. elles offrent aux applications un protocole normalisé et multi-plateformes d’accès aux ressources de rendu 3D et d’affichage à l’écran. Vous l’aurez compris. Dans 99 % des cas. au Makefile d’extensions propriétaires fournies par Google pour notre carte PandaBoard. g n u l i n u x m a g. [11] et [12]).0. API de référence dans le monde de l’embarqué et autres consoles de jeux. images ou encore textes.com GNU/Linux Magazine France N° 1 5 3 69 . Non pas que ce paramètre soit théoriquement nécessaire (Android est censé détecter cette valeur automatiquement).À LA DÉCOUVeRTe D'AnDROID : Le SySTÈme GRAPHIQUe sans passer par le framework Java. Lorsque l’on souhaite utiliser des canevas 3D.mk pour y ajouter la ligne suivante : Fig.fr) . C’est le cas sur notre SoC OMAP4. il devient inconcevable de ne pas utiliser l’accélération matérielle tant les effets visuels sont développés (si tant est que l’on souhaite un peu de performance en hautes résolutions).3). Si vous vous souvenez bien du 3ème article. Depuis GingerBread (Android 2. Google l’utilise en effet également comme moteur de rendu pour son navigateur Chrome. un framework de rendu 2D encore une fois développé par Google (cf. s’il existe. L’accélération matérielle. les composants OpenGL|ES et EGL sont fournis sous la forme de bibliothèques propriétaires. tournant en espace utilisateur. dont le but est de déterminer le type de moteur de rendu à utiliser (hgl ou agl). Le contenu de ce dernier se présente sous la forme suivante : 0 0 android 0 1 POWERVR_SGX540_120 w w w.so │   ├── libGLESv1_CM_POWERVR_SGX540_120. C’est notamment très utilisé dans le développement de jeux vidéo. Contrairement à l’habitude. Android propose cependant un astucieux mécanisme d’abstraction des API. les applications ont cette fois la capacité de passer par les bibliotèhques OpenGL|ES et EGL . Skia n’est pour une fois pas spécifique à Android. nous allons modifier le fichier device/ma_compagnie/mon_ appareil/device. L’implémentation logicielle se base sur le composant PixelFlinger. dont le GPU est basé sur un PowerVR SGX540 de la société Imagination Technologies. quant à elle.10 décembre 2012 à 16:20 Mais revenons un instant sur la mise en place. À noter que les bibliothèques OpenGL|ES et EGL font partie du NDK et permettent donc aux développeurs de bas niveau de les utiliser directement Cette dernière faisait appel. présentant la génération de la plateforme. AngryBirds) refusent de tourner sans cette propriété : PRODUCT_PROPERTY_OVERRIDES += ro.g. vendor/ti/ panda/device-vendor. version=131072 Notons également l’utilisation du fichier de configuration /system/lib/ egl/egl. $(call inherit-product-if-exists.cfg. 8 : Passage de surfaces graphiques des applications vers SurfaceFlinger. permettant de faire cohabiter à la fois une implémentation purement logicielle (agl) également appelée « software rasterizer » (où le traitement graphique est effectué par le processeur) et une implémentation matérielle (hgl). est souvent fournie par le constructeur du SoC lui-même (ou par un partenaire lorsqu’il n’est pas détenteur de l’IP graphique). mais la pratique veut qu’un certain nombre d’applications (e. Le lien noyau/bibliothèque est cependant très fort et il est très souvent nécessaire de s’assurer d’avoir des versions compatibles (ce qui force des migrations noyau) pour que le tout fonctionne.mk. [10]).mk Profitons-en également pour ajouter la ligne suivante au fichier BoardConfig. qui permet de figer un paramètre indiquant la version OpenGL|ES supportée. avec Android 4. où le traitement est accéléré par le GPU (pour « Graphics Processing Unit »). le support d’OpenGL|ES est désormais un pré-requis. Tout ce qui est canevas 2D passe par le projet Skia . Soyons clairs.opengles.

cfg:system/lib/egl/egl. vous disposez désormais d’une accélération 2D/3D matérielle complète et le système devrait être on ne peut plus fluide. Le désavantage est bien évidemment une consommation mémoire doublée. vous pouvez réinstaller et redémarrer votre carte. c o m . L’un constitue la zone de travail. l’autre la zone d’affichage. Au plus bas se retrouve un autre composant appelé «  GFX HAL  » (pour «  Graphics Hardware Abstraction Library  »). Ce composant. mais dans dans notre résolution de 800x480.5 Mo de mémoire supplémentaire. Pour ce faire. 9 : Vue d’ensemble de l’architecture logicielle graphique d’Android 9 SurfaceFlinger SurfaceFlinger a donc pour rôle de fusionner les surfaces 2D/3D en provenance de différentes applications et de créer une image complète à afficher à partir de là. Comme d’habitude. 8 Architecture graphique Histoire de remettre les choses dans l’ordre. profitons de la gigantesque figure 9 pour mieux comprendre la relation entre les différents composants du système. Fig.cfg Reste enfin à modifier notre configuration noyau afin d’activer le support du pilote pour GPU PowerVR : ARCH=arm make menuconfig Device Driver → Graphics support → [*] PowerVR SGX support → PowerVR SGX core (SGX 540) PowerVR build type (Release) et à recompiler le tout comme précédemment indiqué.MObILITÉ Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. notre compositeur graphique. le fichier peut être inclus très facilement via un ajout dans notre BoardConfig. ou simplement de fusion de calques avec transparence. Ceci a pour but d’éviter les effets de déchirements graphiques («  tearing  ») où le processeur est en train de modifier une partie de l’écran (nouvelle image) alors que le contrôleur LCD est encore en train de dessiner l’ancienne image. partiellement implémenté via la libhardware.gnulinuxm a g . Il utilise un mécanisme simple mais classique de double tampon mémoire (« double buffering ») pour gérer 2 instances de framebuffer.fr) . À partir de ce point. C’est directement le composant SurfaceFlinger qui va interagir avec cette HAL pour afficher les différents éléments à l’écran.10 décembre 2012 à 16:20 Le premier chiffre de chaque ligne indique l’identifiant de l’écran (« display ») et le second s’il s’agit d’accélération logicielle (0) ou matérielle (1). Le principe du « page flipping » 70 G N U / L i n u x M a g azine France N°153 www. cela ne représente toujours qu’1. il repose également sur l’utilisation d’OpenGL|ES pour permettre l’accélération matérielle de différentes opérations graphiques telles qu’agrandissement et réduction de surfaces. encore une fois très souvent fourni par le manufacturier lui-même (et sous forme binaire propriétaire) permet une composition matérielle et une gestion optimisée de la mémoire graphique. Les différentes applications Java peuvent accéder aux couches graphiques les plus basses de manière naturelle par communication avec SurfaceFlinger.mk : PRODUCT_COPY_FILES += device/ma_compagnie/mon_appareil/egl. et l’ensemble des opérations de création de surfaces telles qu’évoquées précédemment peut se faire par l’utilisation de différents moteurs de rendu 2D ou 3D que sont les bibliothèques Skia et OpenGL|ES.

- R éc upérat ion de s ex ten sion s OpenGL|ES et création du contexte OpenGL|ES . sondes. au fur et à mesure des différentes versions d’Android. Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. g n u l i n u x m a g. lumières. mais notre préoccupation d’aujourd’hui concerne la partie graphique.so. qui permet de dessiner à l’écran un buffer graphique. - Initialisation du GPU et du contrôleur LCD . le premier module rencontré étant choisi. deux modules intéressants  : gralloc et hwcomposer.so. l’idée est de fournir un lien entre le framework applicatif Java et les pilotes matériels spécifiques à chaque constructeur ou à chaque SoC. c’est bien à l’intégrateur de développer ses propres modules pour les adapter à son matériel. - Rendu de l’image sur le framebuffer. de par leur nom et via dlopen(). À noter que seule la libhardware est liée au framework applicatif. qui seront chargés dynamiquement. dans l’archive fournie par Imagination qui contenait les bibliothèques OpenGL|ES et EGL. pour économiser d’autant la bande passante mémoire (qui est.so. caméra. de manière à ne pas continuellement réinventer la roue.. au lieu de forcer le rafraîchissement complet à 60Hz. les modules sont chargés par la libhardware qui recherche ce qui est disponible dans /vendor/lib/hw. résolution. à proprement parler. gralloc. énergie. vibrateur et Wi-Fi) au sein d’une bibliothèque liée avec le framework et d’un ensemble de modules. Les modules sont chargés dynamiquement. gralloc (pour «  Graphics Allocator  ») est le module qui va s’occuper d’interagir avec le framebuffer. vous comprendrez donc qu’il agit très étroitement avec le GPU. après démarrage du service par le daemon SystemServer : - Récupération des extensions EGL supportées . C’est fort appréciable lorsque l’on considère des hautes résolutions de type 720p/1080p. NFC. C’est un des moyens qu’a trouvé Google pour s’affranchir des problèmes de licence GPL des pilotes noyau.so Nous verrons chacun des différents modules de HAL en leur temps au fur et à mesure des articles. Le format de recherche permet également de choisir le module depuis une liste du plus spécifique au plus générique. dans /system/lib/hw. Dans le principe. w w w.À LA DÉCOUVeRTe D'AnDROID : Le SySTÈme GRAPHIQUe est utilisé. La partie sensible peut désormais se faire en espace utilisateur dans une bibliothèque propriétaire. - Composition des surfaces pour former une image cohérente. reste cependant l’allocation de buffers graphiques en mémoire. nous retrouvons justement notre module gralloc pour la HAL : vendor └── imgtec └── panda └── proprietary └── gralloc. le premier tendant à remplacer le second. de l’accélérateur 2D ou de l’encodeur vidéo. dont vous trouverez les sources « par défaut ». dans hardware/ libhardware/modules/{gralloc. Hormis le cas simple du framebuffer.so.omap4. Notons justement que. en supplément de ce que propose nativement le noyau Linux.arm.com GNU/Linux Magazine France N° 1 5 3 71 . GPS. souvenez-vous. ro.mon_appareil. via utilisation des valeurs des différentes propriétés système que sont ro.board. que l’on devine à son nom. allocateur mémoire graphique. fréquence de rafraîchissement.default.10 décembre 2012 à 16:20 Le principe global de fonctionnement de SurfaceFlinger est fort simple. 11 GFX HAL Il y a. Dans le cas qui va nous intéresser présentement (à savoir le composant gralloc). Les buffers alloués peuvent être de plusieurs types : texture ou zone de rendu OpenGL|ES. mais au final. pour chaque type de matériel à gérer. Il n’est donc pas rare que le module gralloc soit 10 Hardware Abstraction Library Android fournit aux différents constructeurs un moyen de créer une pseudo abstraction avec le matériel. gralloc. Il est également possible (mais facultatif) d’implémenter la méthode setUpdateRect() qui permet de ne réafficher qu’une partie de l’écran (via DMA) à la demande. Globalement.omap4. ou tout simplement le framebuffer. la fin d’affichage d’une page) de manière atomique (gralloc s’occupant de bloquer l’accès à la ressource graphique pour éviter les conflits). framebuffer. Cette couche d’abstraction matérielle (ou HAL) se retrouve dans les sources de l’AOSP sous les composants hardware /libhardware et hardware / libhardware_legacy.fr) .board.) mais également d’implémenter la méthode post().. sans en livrer les sources.product. qui consiste à alterner d’une image à l’autre le pointeur mémoire du framebuffer sur la première zone (« front buffer ») ou la seconde (« back buffer »). Son rôle principal. puis à défaut. le choix se ferait donc par exemple dans l’ordre suivant : gralloc. . - Mise en boucle événementielle : - Attente de transaction de surfaces de la part des applications. Cette HAL propose une API d’accès à différentes couches matérielles (audio. dont la plupart peuvent être repris à titre d’exemple. Le buffer (lui-même alloué par gralloc) sera écrit lors du prochain signal VSYNC reçu par le contrôleur LCD (souvenez-vous.arch. hwcomposer}. platform et ro. commune à tout le SoC). Il permet de décrire les propriétés physiques de l’écran (taille. compositeur matériel. Google fournit nativement un ensemble de modules basiques. - Création des surfaces EGL d’accès à l’écran et association au framebuffer . gralloc. zone de travail du compositeur matériel. permettant donc aux équipementiers d’intégrer un traitement spécifique et de le livrer sous forme propriétaire.

le graphisme est globalement bien géré sous Android. le module se base majoritairement sur l’utilisation d’EGL pour la création et manipulation de différentes couches graphiques (ou « layers ») et pour leur appliquer différents effets (intersection entre rectangles. pour former une animation graphique. se charge d’ouvrir un fichier appelé bootanimation. à savoir comment modifier et personnaliser le logo de démarrage. dont le but est justement d’afficher un logo animé. 72 G N U / L i n u x M a g azine France N°153 www.org/egl [13]  https://developers. part0/f0075..com/p/skia/ [11]  h t t p://w w w. ces bibliothèques étant chargées dynamiquement. le second module HAL graphique se prénomme hwcomposer (pour « hardware composer »). com/ Ceci devrait vous fournir une animation personnalisée de 76 images et donc d’une durée de 3s. exécutant du code non vérifié et surtout.10 décembre 2012 à 16:20 fourni directement au même titre que les bibliothèques OpenGL et EGL.MObILITÉ À LA DÉCOUVeRTe D'AnDROID : Le SySTÈme GRAPHIQUe Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.. la durée de pause demandée avant affichage de la première image (en nombre d’images) et le chemin vers les images au sein de l’archive. Internet en est peuplé. OpenGL|ES et EGL que nous avons vu plus haut. du format suivant : 800 480 24 p 0 0 part0 Conclusion Nous voici donc arrivés à la fin du gros morceau qu’est la gestion graphique sous Android.khronos. dépendantes des API de Google. Les 3 paramètres de la première ligne correspondent respectivement à la largeur. fusion avec ou sans transparence. Android recherche ce fichier dans /system/media. C’est ce que nous aborderons dans le prochain numéro avec une plongée dans la couche d’entrées/sorties d’Android. pas de problèmes non plus.com/ android/nexus/drivers#panda [14]  http://androidbootanimation. il devient nécessaire d’avoir les nouveaux binaires adéquats de la part du fournisseur. si vous vous sentez l’âme du hacker puriste de pilotes graphiques libres.. c’est SurfaceFlinger qui s’en occupera de manière logicielle (comprendre : plus lentement). miroir. juste la fonctionnalité d’archivage (option -0) sous peine de rejet. . et il vous suffit d’en choisir une via [14] par exemple.). mais l’utilisateur a la possibilité de le personnaliser via /data/local. Mais trêve de débats. Vous aurez cependant remarqué l’utilisation massive d’un grand nombre de blobs binaires propriétaires.jpg . Si vous souhaitez réaliser la votre.zip. sous la forme d’une application utilisant les bibliothèques Skia. le temps nécessaire au système d’initialiser le reste des composants. Enfin. Ce dernier. n’utilisez pas la compression ZIP. Elle décrit une partie de l’animation et commence donc par la lettre « p ». Si vous souhaitez réutiliser une animation existante. que nous verrons dans un article futur. mais TI fournit également les sources de son implémentation optimisée au sein de hardware/ ti/omap4xxx/hwc. Il vous suffit de créer un fichier de description appelé desc. Dans tous les cas. Une implémentation de référence se retrouve là encore dans hardware/libhardware/ modules/hwcomposer. Une astuce simple et efficace pour générer votre animation à partir d’une vidéo existante est d’utiliser MPlayer pour en extraire les images. permettant son utilisation avec autre chose qu’un clavier ou une souris. À chaque changement d’API (et donc souvent de version d’Android). via la méthode prepare(). contenant un ensemble de ressources JPEG ou PNG qui seront affichées l’une après l’autre Rassemblez ensuite votre ensemble de fichiers et générez votre archive ZIP sous la forme suivante : desc. hwco m poser s’en chargera. c o m . d’y aller de votre propre implémentation. va le notifier des capacités matérielles disponibles. Ainsi.google. Nous voici donc désormais capables de démarrer notre propre système avec l’accélération graphique matérielle nécessaire à sa bonne utilisation. hauteur et fréquence de rafraîchissement (en nombre d’images par seconde) de vos images. Aussi surprenant que cela puisse paraître. Le cas échéant.avi -vo jpeg:quality=90 12 Boot Animation Finissons de jouer avec le graphisme par une modification très simple bien qu’inutile (et donc indispensable).. Par défaut. Contrairement à la gestion audio.k h rono s .jpg Références [10]  http://code.fr) . si la composition matérielle est possible.txt. tel que présenté ci-dessous : mplayer ma_video. rotations.txt part0/f0000. Libre à vous cependant. Que se passe-t-il alors lorsqu’un constructeur décide de mettre fin au support de son produit pour privilégier le nouveau ? Cela signifie généralement l’impossibilité pour l’utilisateur de migrer vers une nouvelle version.org / opengles/ [12]  http://www.google. Si vous vous souvenez de l’article précédent. Il est possible de réitérer la seconde ligne plusieurs fois. Il lui manque cependant encore quelque chose d’essentiel : le support d’une dalle tactile. SurfaceFlinger interagit directement avec hwcomposer qui. nous avions vu que le daemon init démarre une application appelée bootanimation.gnulinuxm a g . notre système maison avance doucement mais sûrement. Les 3 paramètres suivants indiquent respectivement le nombre de cycles d’affichage (0 pour tourner en boucle). utilisant l’accélération matérielle disponible dès qu’il peut le faire.

50 € 6.50 € 6.com.. programmation objet et optimisation du code Spécial C & C++ Java . : Frais de port HORS France Métro.B.50 € 6.10 décembre 2012 à 16:20  du numéro.50 € 6.00 € 8.50 € Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. et/ou bon de commande administratif) à remplir (ou photocopier) et à retourner aux Éditions Diamond . : +3.ed-diamond.50 € 6.au numéro HS N° 60 HS N° 61 Code Postal : Ville : Téléphone : e-mail :    Je souhaite recevoir des infos des Edtions Diamond   Je souhaite recevoir des infos des partenaires des Editions Diamond Bon de commande GNU/Linux Magazine Hors-série Réf.50 € 8..50 € 6. Par le Web : Sur notre site : www.00 € 8.. .50 € 6.50 € 7.50 € 6.au numéro N° 152 Bon de commande Bon de commande GNU/Linux Magazine Réf. Par téléphone : Entre 9h-12h & 14h-18h au 03 67 10 00 20 (paiement C.50 € 6..Rendez vos développements multiplateformes ! Carnet de ROOT ZEND Framework 2 Développer des applications web plus rapidement et avec moins de code ? Django 20 Recettes pour développer vos applications Android Créez vos applications Android comme un pro ! Prix / Nos 6.50 € 7.50 € 6.Introduction.GNU/Linux Magazine .LES 4 FAÇONS dE cOMMANdER ! D'ANcIENS NUMÉROS N° 100 N° 132 COMPLÉTEZ VOTRE cOLLEcTION Par courrier : En nous renvoyant ce bon de commande..50 € 6.509 + SSH Découvrez les nouveautés DEBIAN 6.50 € 6..Sécurisation .50 € 6.50 € Prix / Nos 7.ed-diamond. LM100 LM132 LM133 LM134 LM136 LM137 LM138 LM139 LM140 LM141 LM142 LM143 LM144 LM145 LM146 LM148 LM149 LM150 LM151 LM152 Désignation Le serveur PARFAIT + BONUS : plus de 550 Articles de GLMF sur CD Configurez et optimisez un antispam adaptif avec dspam Clustering et systèmes de fichiers répartis Virtualisation avec XEN 4 Besoin d'un annuaire pour enfin tout centraliser ? OPENLDAP .BP 20142 67603 Sélestat Cedex / France Référence Prix / No 6.50 € 6.50 € 6.50 € 6.50 € 6.50 € 7.fr) .50 € 6. .50 € 7.50 € 7. LMHS51 LMHS52 LMHS53 LMHS54 LMHS55 LMHS56 LMHS57 LMHS58 LMHS59 LMHS60 LMHS61 Désignation Hacks..avec Git et Redmine Débarrassez-vous de votre serveur mail ! Grâce à Google Visite au cœur de l'émulateur QEMU Migrez votre système de fichiers vers BTRFS ! Créez votre VPN avec OPENVPN Installez votre groupware Kolab Protégez vos applications web Qté 1 Total 6.B.) Par fax : Au 03 67 10 00 21 (C.9 € +6 € TOtAL : Voici mes coordonnées postales : Nom : Prénom : Adresse : HS N° 51  du numéro. électronique & embarqué Développement Android Initiation à PYthon Spécial PHP .50 € 6.50 € 6.Réplication Renforcez la sécurité de vos connexions distantes avec OPENSSH et les certificats Centralisez la gestion des authentifications X.00 € Je choisis de régler par :   Chèque bancaire ou postal à l’ordre des Éditions Diamond   Carte bancaire n° Expire le : Cryptogramme visuel : Date et signature obligatoire http://www.com Retrouvez les sommaires et commandez tous nos magazines sur notre site : .50 € EXeMPLe : LM111 TOtAL : Frais de port France Métro..Installation .50 € 6.0 Simplifiez et automatisez la gestion de votre virtualisation Noyau & CGROUPS Testez le CLOUD Installez une solution Single Sign-On complète et multiplateforme avec Kerberos Jouons avec le Kernel ! Gérez vos sources & projets proprement ! .

GNU/Linux Magazine . N°72..3  N°104 Gestion des services avec OpenSolaris  N°105 Domotique avec MisterHouse  N°106 Récupérez vos données après une Défaillance RAID  N°107 Sauvegardez vos bases de données MySQL  N°108 Comment vos utilisateurs traversent votre Firewall  N°109 Port Knocking . N°147 Numéros GNU/Linux Magazine épuisés : Bon de commande à remplir (ou photocopier) et à retourner aux Éditions Diamond .B. flexible et facile à configurer !  N°126 V  ous utilisez encore une Apache surdimensionné ? .CLAM AV face aux produits propriétaires  N°120 B  esoin d’une PKI libre pour gérer HTTPS. VPN et S/MIME ? PKI OPENSSL en pratique avec EJBCA.et sans MySQL D  éveloppez vos applications Mozilla avec XPFE & XPCOM Adamoto Le crash disque vous guette La réponse de Sun à Linux ? SOLARIS 10 Découvrez et comprenez la technologie GRID Présentation et installation du Hurd Compression théorie.Complétez votre collection de TTc Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.25 € par numéro* ! Les 4 façons de commander ! Par courrier Par le Web En nous renvoyant ce bon de commande.Ne laissez pas la porte ouverte aux intrusions  N°110 Sécurisez votre système en le migrant vers LVM2 & RAID 1  N°111 18 Recettes pour tirer le meilleur de OPENLDAP  N°112  Besoin d’une solution centralisée et efficace d’ADMINISTRATION SYSTÈME ? Installez et déployez Puppet !  N°113 S  ingle Sign-On / SSO et authentification centralisée avec CAS-TOOLBOX  N°114  Découvrir. une solution libre pour systèmes embarqués Greylist Eliminez le SPAM à la racine Déploiement de hotspots Wifi sécurisés Le point sur Mono . protocoles et configuration Sécurisation du Noyau avec PAX Run in memory  Comment fonctionnent les générateurs de nombres pseudo-aléatoires eCos.Passer à ZFS ! Le système de fichiers révolutionnaire  N°115 C  réez et personnalisez votre système DEBIAN 5. votre prochain serveur Web ! A  près MySQL & PostgreSQL SAP DB : La base de données libre & puissante C  réez un album Photo avec PHP .0 .ed-diamond. et programmation VFS : Système de fichiers virtuel Systèmes de fichiers chiffrés Bluetooth .Detection d'intrusion .90 € NOUS CONSULTER Prénom : Adresse : TOtAL : Je choisis de régler par :   Chèque bancaire ou postal à l’ordre des Éditions Diamond   Carte bancaire n° Expire le : Cryptogramme visuel : Date et signature obligatoire Code Postal : Ville : Téléphone : e-mail :    Je souhaite recevoir des infos des Édtions Diamond   Je souhaite recevoir des infos des partenaires des Éditions Diamond .ed-diamond.25 € = Total Voici mes coordonnées postales : Nom : Frais de port France Métro. PPP et XL2TPD GNU/Linux Magazine Numéro 100 à commander sur www. N°76.com * dans la limite des stocks disponibles. N°88 à N°90. configuration.Installation. et mise en œuvre Choisissez vos numéros dans le tableau ci-dessous : GNUstep : le petit frère de MacOS X? Caudium. N°135.0 LIVE sur CD/DVD ou clef USB  N°116 C  onstruisez et administrez votre VPN L2TP/IPSEC avec OpenSSL.BP 20142 . Openswan. SSH.Spécifications. : + 3. Par téléphone Par fax Entre 9h-12h & 14h-18h au 03 67 10 00 20 (paiement C.6. JAVA et JBOSS  N°121 C  omment tester des solutions sans toucher votre infrastructure ? Virtualisez votre réseau ! avec netkit ou vde2  N°122 N  ouveautés du Kernel 2.avec l'HIDS OSSEC  N°129 C  omment étendre vos capacités de supervision ? .NET Java et les Brevets Ajax Avancé Paravirtualisation XEN & SLO      Répartition de charge  N°93  N°94  N°95  N°96  N°99 Développez vos extensions Firefox PABX Vidéo avec Asterisk A  dministration et configuration centralisées avec Cfengine G  éolocalisation de photos numériques Java & JNI Tirez le meilleur de Java  N°47  N°48  N°49  N°50  N°56  N°64  N°68  N°69  N°70  N°71  N°73  N°74  N°77  N°78  N°79  N°80  N°81  N°82  N°83  N°84  N°87  N°91  N°92  N°101 Chiffrez vos disques  N°102 LTSP 5 Clients légers  N°103 PostgreSQL 8.fr) . N°65 à N°67.com pour consulter le sommaire détaillé de chaque magazine !  N°117 Base de données orientée document : APACHE COUCHDB  N°118 Utilisez GFS NBD over SSH pour votre Stockage réseau  N°119 B  esoin d'une solution antivirus crédible ? .32  N°123  Créez des modules d'authentification Radius et étendez les fonctionnalités de votre solution SINGLE SIGN-ON  N°124 C  onstruisez simplement votre portail Wifi captif avec Chilispot et CAS  N°125 V  ous cherchez une alternative à apache ? .com.NGINX HTTP Serveur web et reverse proxy orientés performance  N°127  Vous souaitez optimiser l'accès à vos serveurs ? QOS & Contrôle du trafic  N°128  Besoin de sécuriser vos systèmes ? . N°98.10 décembre 2012 à 16:20 au tarif promotionnel de 3.CHEROKEE WEB SERVER Rapide. algorithmes.Développez vos propres sondes Nagios !  N°130 E  t si vous vous débarrassiez de votre serveur EXCHANGE ?  N°131 P  OSTGRESQL 9. N°86. N°57 à N°63. N°97. N°75.) Au 03 67 10 00 21 (C.. N°85. N°01 à N°46. N°51 à N°55.B. : Frais de port HORS France Métro. et/ou bon de commande administratif) Vous recherchez un numéro spécifique ? Rendez-vous sur www. installer et configurer .ed-diamond. Sur notre site : www.67603 Sélestat Cedex Quantité x Prix / No 3.

Celles-ci peuvent se montrer très utiles dans le cadre d’une programmation objet avancée. Tout cela est cohérent. Cette méthode doit donc renvoyer le même objet et ne pas le récréer. mais sur les méthodes. un identifiant permettant d’instancier un objet PHP depuis un enregistrement en base de données. et si tel est le cas. une fois pour toutes. elles sont cependant assez retorses à utiliser. Dans ce contexte... Remarquez que si vous avez la mauvaise habitude d’appeler de manière dynamique des méthodes statiques. autant les bogues qu’elles pourraient provoquer sont difficiles à déceler. un simple cache sur la méthode permet donc de résoudre le problème. non sur les propriétés de l’objet. surtout dans le contexte d’un travail d’équipe ou de longs enchaînements d’héritage dans les classes. La dernière fois.fr) . g n u l i n u x m a g.com GNU/Linux Magazine France N° 1 5 3 75 . il en avait résulté un code bien plus court et plus lisible. vous ne pourrez appeler ces méthodes de manière statique. En fait. en programmation PHP avancée dans le cadre d’un projet MVC (Modèle/Vue/ Contrôleur). vous ne devriez recourir aux appels dynamiques que si vous avez besoin de $this.net/ manual/fr/language. w w w.net/manual/fr/ref. les méthodes manux Magazine n° giques de PHP sont une fonctionnalité avancée de ce langage. protégée et appelée hors de l’objet ou encore privée et appelée hors de la classe qui la définit).10 décembre 2012 à 16:20 par Stéphane Mourey Nous continuons notre découverte des méthodes magiques de PHP en élaborant un cache. _   _call() est appelée dynamiquement.funchand. Une telle méthode doit veiller à ne pas créer deux objets identiques qui pourraient ensuite évoluer indépendamment l’un de l’autre : lors de l’enregistrement de cet objet... Sachez seulement que ces méthodes ne sont pas appelées « magiques » par hasard  : autant leur utilisation peut améliorer grandement votre code à de nombreux points de vue. La difficulté que posent de telles méthodes est qu’elles se font facilement oublier par le développeur.magic. _   _callStatic() est appelée de façon statique.oop5.. La seconde. qui pourrait avoir de grandes difficultés à comprendre l’origine de certains bogues. Sachez tout de même que PHP est considérablement plus performant avec des méthodes statiques que des méthodes dynamiques. c’est-à-dire comme méthode de la classe : maclasse::maMethodeInaccessibleStatique().CODe(S) PHP5 : la magie continue Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.php). 1 Rappel sur les méthodes magiques Pour ceux d’entre vous qui auraient manqué l’épisode précédent (GNU/Li151). vous devrez implémenter deux fois le même traitement (ou le mutualiser dans une méthode que vous appellerez les deux fois) pour couvrir ces deux types d’appel. En plus des méthodes magiques.php). une part des modifications serait perdue. Un cache sur la classe parente de tous les modèles serait donc une solution définitive. Ce point est simplifié par le fait que PHP passe les objets par référence et non par valeur. N’est pas Gandalf qui veut ! 2 Présentations des méthodes magiques à utiliser Nous allons travailler avec deux méthodes magiques ici  : _   _ call et _   _callStatic. puisqu’il s’agira d’implémenter un cache automatique sur les méthodes d’une classe. permettant de modifier profondément le comportement attendu des objets de la classe à laquelle elle s’applique. La première. nous allons devoir faire appel aux « fonctions sur la gestion des fonctions » (http:// php. je vous renvoie à la page du manuel officiel de PHP qui leur est consacrée (http://php. typiquement. Pour en savoir plus sur les méthodes magiques en général. Un premier intérêt est évident : éviter la ré-exécution inutile d’une méthode appelée avec les mêmes paramètres sans avoir à gérer le cache à l’intérieur même de la fonction. il est fréquent de définir une méthode statique sur la classe parente des modèles. qui crée une instance de cette classe à partir de paramètres restreints. Cette fois-ci. Dans notre exemple. Ces fonctions sont appelées lorsque PHP détecte un appel à une méthode inaccessible (inexistante.. nous avions utilisé la _get pour permettre à un méthode _   objet de déterminer lui-même ses propriétés. c’est-à-dire depuis un objet existant : $monobjet->maMethodeInaccessibleDynamique(). ainsi qu’un gain de performance notable. Il y a toutefois un autre intérêt. notre travail sera plus élaboré.

celui qui permet le fonctionnement de notre cache de la façon la plus ordinaire.$cachedMethod).CODe(S) 3 Convention de nommage Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Si un appel est fait à ousontmeslunettes() et que ousontmeslunettes() n’existe pas ou n’est pas accessible.3). static $staticMethodsCache=array(). Mais cette transformation. une propriété est définie : $methodsCache. une telle liste d’arguments peut se révéler très longue et il n’est pas utile de conserver toutes ces informations. nous allons utiliser une convention de nommage : nous allons préfixer toutes les méthodes auxquelles le cache s’appliquera par _C_.$args).0. // traitement de cas particuliers if (substr($method. Bref.$method)) { // la méthode cachée a été appelée explicitement: on rafraichit le cache return $this->methodsCache[$method][$key]=call_user_func_array(array(get_called_ class(). dans notre exemple. d’autres objets. Si tel est le cas.1 Le code classwithCachedMethods{ var $methodsCache=array(). n’est sans doute pas optimale : il est fréquent d’appeler une fonction avec des arguments très complexes et très lourds. Détaillons le fonctionnement de notre méthode magique _   _call. la fonction _   _call. c o m . nous ne pouvons les utiliser en l’état.$method). return call_user_func_array(array(get_called_class().$args). if (method_exists($this.$args) { $key = md5(serialize($args)). qui contient le cache des méthodes sous forme d’un tableau.3)==’_C_’) { if (method_exists($this. Nous utilisons la fonction method_ exists pour savoir si elle existe effectivement. PHP ne nous permettant pas d’utiliser un tableau comme index d’un autre tableau (ce qui ne serait d’ailleurs pas judicieux). Toutefois. mais nous voulons seulement rendre inaccessibles certaines méthodes pour permettre à l’objet d’utiliser son cache avant d’appeler la méthode si nécessaire. que le code qui la compose se structure en deux parties. Le deuxième élément qui nous permet de déterminer si le résultat recherché se trouve déjà dans le cache est la liste des arguments. 76 G N U / L i n u x M a g azine France N°153 www. Il peut être de deux types : soit on trouve la valeur recherchée dans le cache. nous l’avons dit. nous déduisons celui de la méthode cible que nous plaçons dans la variable $c a c h e d M e t h o d . la première clé que nous utilisons est le nom de la méthode cachée. mais le code demande un rafraichissement du cache.$args). Ainsi. Nous allons utiliser le hash md5() des arguments sérialisés comme deuxième clef de notre cache : 4 Implémentation dynamique 4. _   _call() reçoit deux arguments : le premier est le nom de la méthode inaccessible. } } } Voici donc notre nouvelle classe que nous avons appelée withCachedMethods.$method). } } // traitement normal $cachedMethod = ‘_C_’. en guise de préambule. Ceux-ci nous sont connus sous la forme d’un tableau. }else{ // le cache a été désactivé pour cette fonction.. Notre cache. le second un tableau contenant les arguments envoyés à cette méthode. } return $this->methodsCache[$cachedMethod][$key]. Il faut donc que l’objet ait un moyen de déterminer s’il doit ou non appliquer ce traitement lors d’un appel de méthode inaccessible. Remarquons.fr) . Il s’agit de serialize().$this>methodsCache[$cachedMethod])) { $this->methodsCache[$cachedMethod][$key]=call_user_func_array(array(get_called_ class(). cela signifie que le traitement du cache doit être effectué.$cachedMethod)) { if (!is_array($this->methodsCache[$cachedMethod]) || !array_key_exists($key.$method. il nous sera possible d’activer ou de désactiver le cache sur une méthode simplement en ajoutant ou en supprimant ce préfixe. qui prend en charge l’interception de méthodes inaccessibles. _C_ousontmeslunettes. est un tableau. Pour y stocker les données.gnulinuxm a g . nous ne voulons pas rendre accessibles toutes les méthodes inaccessibles de l’objet.. soit on exécute la méthode et on place le résultat dans le cache. La seconde est le traitement normal. Du nom de la méthode. on rappelle simplement la fonction $method = substr($method. Par ailleurs. des objets contenant des tableaux de valeurs.10 décembre 2012 à 16:20 Comme dans notre précédent article. nous allons travailler avec_C_ousontmeslunettes(). PHP nous fournit heureusement une fonction qui permet de convertir un tableau en chaîne de caractères sans perte de données (une autre fonction existe permettant le traitement inverse si nécessaire). bien que fonctionnant. La première est consacrée au traitement de cas particuliers sur lesquels nous reviendrons plus loin. function _   _call($method. Pour y parvenir. Nous n’avons pour le moment implémenté qu’une seule méthode.

d’une part. Cela signifie que le programmeur qui a écrit cet appel sait qu’il s’agit d’une méthode cachée  : c’est exactement ce qu’il ferait s’il voulait contourner le cache. Et c’est ce que nous faisons ici. Peut-être a-t-il détecté une erreur. Cet appel étant tout de même intercepté par _   _call(). produira : No cache! 3 3 No cache! 3 Le résultat sera : No cache! 3 No cache! 7 3 Voilà. se dissimule un autre cas particulier  : nous avons défini que nous pouvions désactiver le cache d’une méthode simplement en supprimant son préfixe (et sa protection). g n u l i n u x m a g. cela implique que même préfixée. $test->plus(1. si ce cache contient la clef correspondant à nos arguments. c’est que le résultat présent dans le cache ne le satisfait pas. Toutefois. Ici. ou bien sait-il que la donnée est périmée suite à une action de sa part ? Peu importe : nous pouvons interpréter cet appel comme une demande de correction du cache.10 décembre 2012 à 16:20 Ensuite. nous déterminons s’il existe un cache pour notre méthode et si oui. lever des erreurs. une demande de rafraîchissement de cache serait fait pour cette méthode. Peut être appelée ainsi : call_user_func_array(‘Y’."\n". 4. il faut créer cette clef et déterminer la valeur qui lui correspond. print $test->_C_plus(1. print $test->plus(1. Il est important de vérifier si le cache existe bel et bien (is_array()) avant d’y chercher la clef car array_key_exists() peut. dans ce cas particulier."\n".$b){ print "No cache!\n". nous allons ajouter une ligne à notre méthode qui affichera un petit texte indiquant que non. Si nous voulons pouvoir continuer ainsi.2). comme si cette fonction cible avait été appelée normalement. car elle a été déclarée protected et appelée extérieurement à l’objet. qui aura pour seule tâche d’effectuer une addition. il nous faut alors appeler la méthode non-préfixée et renvoyer directement ce résultat. la méthode appelée reste inaccessible. Le premier argument de call_user_func_array() permet d’appeler une méthode plutôt qu’une fonction lorsqu’il contient un tableau dont le premier élément est le nom de la classe et le second le nom de la méthode. il faut également que notre interception soit capable de traiter le cas où. Dans ce cas-là.2). d’autre part."\n". w w w."\n".. le code suivant : print $test->plus(1. Quels sont-ils ? Il y en a deux. le cache aurait été désactivé pour la méthode et. return $a+$b. Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. 4. Celle-ci permet d’appeler une autre fonction en lui passant un tableau d’arguments de longueur arbitraire.3 Traitement des cas particuliers Nous l’avons indiqué plus haut.2 Le test Pour tester notre cache.2). le code appelant la méthode y accède explicitement en utilisant le préfixe de cache. Dès lors.2).com GNU/Linux Magazine France N° 1 5 3 77 .2). Nous pouvons donc maintenant passer à l’.’argC’)). Par exemple : functionY($a. il va nous falloir faire appel à la fonction fournie par PHP call_user_func_array. mais que le deuxième appel à plus() avec comme arguments 1 et 2 nous fournit un résultat issu du cache. Si une telle clef n’existe pas.."\n". $test->plus(1.PHP5 : LA mAGIe COnTInUe $key=md5(serialize($args)). notre méthode _   _call supporte le traitement de certains cas particuliers. } Maintenant.4). puis 3 et 4.’argB’. Il est à noter que cet appel est effectué de manière dynamique. Voici donc la méthode que nous ajoutons : function _C_plus($a."\n". $test->plus(3. nous en avons terminé avec la partie dynamique. nous allons ajouter à notre objet une méthode simple. écrivons encore quelques lignes en dehors de la classe pour la tester : $test print print print = newwithCachedMethods().$c){ //traitement } Nous constatons que le premier appel à plus() avec comme arguments 1 et 2. Nous allons donc rappeler la fonction et rafraîchir la valeur stockée dans le cache. selon la configuration et la version de PHP. nous fournit un résultat déterminé par la méthode _C_plus.fr) . Pour autant.$b. nous n’allons pas laisser tomber notre développeur : s’il appelle explicitement la méthode de cette façon.array(‘argA. Dans les deux cas. Pour savoir si le résultat que nous obtenons est issu du cache ou non.

nous voulons que nos classes aient chacune un cache bien indépendant. aussi utilisons-nous systématiquement static dans nos méthodes qui gèrent le cache. qui en hérite mais qui redéfinit la méthode deQuelCote. A l’intérieur d’une classe.1 Avertissement Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. } return static::$staticMethodsCache[$calledClass][$cachedMethod][$key]. mais le code demande un rafraichissement du cache. 78 G N U / L i n u x M a g azine France N°153 www. c o m . // traitement des cas particuliers if (substr($method.$args) { $key = md5(serialize($args)). A l’intérieur d’un objet.3.2 Le code Ajoutons maintenant le code suivant à notre classe withCachedMethods : static $staticMethodsCache = array(). on rappelle simplement la fonction $method = substr($method.$method). Dans notre contexte. mais l’une en utilisant self et l’autre en utilisant static. if (method_exists($calledClass."\n". soit static. qui tient à l’héritage  : self va faire une réflexion sur la classe où il est écrit.3).CODe(S) 5 Implémentation statique 5.$args). } Un tel code affichera : Obscur Lumière Qu’avons-nous fait ? Nous avons défini une classe Vador avec trois méthodes statiques : dequelCote() qui retourne toujours "Obscur". mais de manière statique. print Luke::quelEstTonDestin().3)==’_C_’) { if (method_exists($calledClass. il n’en est plus de même et la différence entre static et self devient flagrante. puis deux autres qui appellent cette première. nous ne connaîtrons pas les dilemmes de Luke. } static function quelEstTonDestin() { return static::deQuelCote().10 décembre 2012 à 16:20 La version 5 de PHP a beaucoup évolué dans ses différentes sous-versions en élargissant les possibilités offertes au programmeur pour utiliser les classes d’objets de manière statique. }else{ // le cache a été désactivé pour cette fonction. return forward_static_call_array(array($calledClass. 5. qui contiendra le cache statique.fr) . Il y a une grande différence entre les deux. } } print Luke::faisTonChoix().$args). Un peu confus ? Prenons un exemple : class Vador { static $force. il n’y a rien de surprenant à ce que les deux méthodes se ressemblent autant.$method). il est impératif de disposer d’une version de PHP au moins égale à 5. En ce qui concerne les techniques de programmation développées dans la suite de cet article.$args).static::$staticMethodsCache[$calledClass][$cachedMethod])) { static::$staticMethodsCache[$calledClass][$cachedMethod][$key]=forward_static_call_arra y(array($calledClass. L’algorithme fondamental étant le même que pour l’implémentation dynamique. Attention ! Il y a une différence fondamentale entre le fonctionnement statique et le fonctionnement dynamique. static function deQuelCote() { return "Obscur". Les différences tiennent au fonctionnement statique. sans quoi. alors que static va faire une réflexion sur la classe dans laquelle la méthode est exécutée.$cachedMethod). PHP permet également d’appeler ces propriétés de ma- nière réflexive et de deux façons différentes.0. cela ne fonctionnera pas.$cachedMethod)) { if (!is_array(static::$staticMethodsCache[$calledClass][$cachedMethod]) || !array_key_exi sts($key. ces méthodes fourniraient toujours le même résultat.$method)) { // la méthode cachée a été appelée explicitement: on rafraichit le cache return static::$staticMethodsCache[$calledClass][$method][$key]=forward_static_call_arr ay(array($calledClass. static function _   _callStatic($method. forward_static_call_array() effectue le même travail que call_user_ func_array(). } } class Luke extends Vador { static function deQuelCote() { return "Lumière". on peut utiliser soit self. Notons que nous commençons par définir une propriété de la classe $staticMethodsCache. Sur la classe Vador. qui si elle n’est pas prise en compte au moment d’une implémentation statique.$method. Mais dès lors que nous les utilisons sur la classe Luke . } } // traitement normal $cachedMethod = ‘_C_’. $calledClass = get_called_class().gnulinuxm a g . Une telle variable est habituellement appelée en utilisant la syntaxe nom_de_la_classe::$nom_ de_la_propriété . } static function faisTonChoix() { return self::deQuelCote(). un appel réflexif est fait en utilisant la variable $this."\n".

nous avons ajouté une dimension à notre tableau. } Les variables statiques $test de la fille et de la mère seront bien différentes. fille::$test = ‘ok’. Dans notre code. simplement parce que ces classes auraient des méthodes synonymes.fr) . elles pourraient fournir des résultats différents. Pour pallier cela.."\n". tel que donné par get_call_class(). nous ne voulons pas que les caches de l’une ou l’autre classe se mélangent. les méthodes magiques et les fonctions de manipulation de fonctions."\n".PHP5 : LA mAGIe COnTInUe pourrait être à l’origine de bogues très retords : les variables statiques sont héritées par référence. Nous aborderons ce concept dans un prochain article. Cela signifie que ce code : Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. avec le code suivant : class fille extends maman { static $test. n’affichera pas : ko ok comme on pourrait s’y attendre. Cette précaution est suffisante et permet d’éviter de redéfinir le cache dans toutes les classes qui utiliseront cette méthode de cache. qui propose les « traits » pour répondre à cette difficulté. si c’est un problème. g n u l i n u x m a g.10 décembre 2012 à 16:20 class maman { static $test. PHP 5. Tout cela est bien joli. Heureusement est arrivé. consiste à redéfinir la variable statique dans la classe fille. 6 Pour finir Nous avons vu lors de ces deux articles comment implémenter des caches automatiques et puissants sur des classes d’objets PHP en utilisant certaines des fonctions les plus avancées de PHP. mais dans un contexte où les développeurs sont amenés de plus en plus souvent à étendre des classes fournies par des frameworks et PHP ne permettant pas l’héritage multiple. print maman::$test.4.. print fille::$test. } class fille extends maman {} maman::$test = ‘ko’. Même héritées. leurs contextes statiques pouvant être différents. mais : ok ok La solution. le premier index étant toujours le nom de la classe appelée. cela peut rester lettre morte dans les cas les plus intéressants. Ainsi. w w w.com GNU/Linux Magazine France N° 1 5 3 79 .

en tenant compte des particularités et des exceptions. L’intervalle peut être supérieur à 60 pour autoriser des secondes de rattrapage.6. Alors. se manifestait sous forme d’une forte charge CPU accompagnée d’une surconsommation de la mémoire et d’autres effets de bord. # /etc/init. en quoi un traitement peut-il être impacté par une minute qui dure 61 secondes ? L’informatique n’est pas vraiment conçue pour qu’un nombre de secondes dépassant 60 génère un débordement de tampon (buffer overflow). Et puis.. Notez que les serveurs ne se mettant pas a l’heure avec ntpd n’ont pas eu ce décalage d’une seconde. que si MySQL ou Java se sont retrouvés être les cibles principales de ce bug. corriger le problème consistait simplement à remettre chaque serveur à l’heure avec la commande date. qui nous intéresse ici. en désactivant puis réactivant le démon ntpd au passage.d/ntpd stop # date -s "$(LC_ALL=C date )" # /etc/init. Par chance. tel qu’il a été ressenti. que s’est-il passé dans la nuit du 30 juin au 1er juillet 2012 ? 2 Les problèmes Le problème.Formater la date et l’heure [. Une autre façon de formuler ce problème est de savoir déterminer si le bug est encore présent ou non sur un serveur.d/ntpd start Une minute de plus de 60 secondes. Le problème suivant a été d’identifier la cause du problème initial.. Pour un ingénieur système administrant un grand parc. -u  n timer haute résolution. pour mesurer le temps. Sa résolution dépend de la constante noyau HZ. Précisons tout de suite que la surconsommation mémoire s’est avérée être également un effet de bord de programmes surpris par cette charge CPU qu’ils provoquaient et.fr) . lié au matériel. c’est comment s’assurer que les commandes sont bien passées. sur les distributions GNU/Linux avec un noyau de version 2. sous forme de nombre décimal (00-60). Le problème. 1 Introduction $ man strftime NOM strftime . le dernier. Ceux qui vont nous intéresser sont : -u  n timer lié à l’horloge système (CLOCK_REALTIME). la problématique est vite devenue celle qu’il rencontre souvent : passer un jeu de commandes sur un parc hétérogène. telle que la nouvelle s’est rapidement répandue sur Internet.gnulinuxm a g . ceux arrivant face à leur console de supervision toute rouge le lundi. Pour le résoudre. le temps se mesure de plusieurs façons.10 décembre 2012 à 16:20 par Yves Mettier [Auteur de C en action (2ième édition) paru chez ENI et du guide de survie Langage C paru chez Pearson] Auriez-vous une seconde ? Nous allons revenir sur cette seconde intercalaire apparue le 1er juillet 2012 dernier juste avant 2h du matin en France et plus précisément le 30 juin à 23h 59min 60s en Temps Universel Coordonné (UTC).] %S La seconde. et s’assurer que les commandes sont bien passées. tels ceux ouverts chez Mozilla ou Red Hat. c o m . Le bug ne s’est donc pas manifesté. Les premiers à s’en rendre compte dans le monde ont ouvert des incidents chez leur support respectif et certains sont visibles de tous. ont pu profiter de ces rapports de bug et des premiers éléments de résolution. comme en témoigne cette page de manuel. à prendre en compte par les programmeurs. Par contre.. Plus précisément. il faut un timer et Linux en dispose de plusieurs. rien n’empêchait d’autres programmes de le manifester. telle une menace latente qui risque de se manifester à tout moment tant que le serveur n’a pas rebooté ou que la commande date (ou toute autre commande plus complexe résolvant également le problème) n’a pas été exécutée. Les suivants. puis place le résultat dans la chaîne s de taille max. pas d’autre moyen que d’essayer de comprendre ce bug. [. appelé hrtimer. 80 G N U / L i n u x M a g azine France N°153 www. cela existe et cela est même prévu. 3 Linux et le temps Avec Linux.] DESCRIPTION La fonction strftime() formate les divers champs de la structure tm en fonction de la chaîne de spécification format. vous devez alors les remettre à l’heure le cas échéant..21 ou ultérieure. Sa résolution dépend du matériel.CODe(S) 01:59:60 : Une seconde SVP ! Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. généralement exécutant un serveur Mysql ou des programmes Java.

. largement inspiré du code de John Stultz publié sur LKML (https://lkml. ns = a. ns -= b.tv_nsec. g n u l i n u x m a g. .org/lkml/2012/7/1/203) sous licence GPL. ns = -ns.tv_sec * NSEC_PER_SEC + a.tv_nsec -= NSEC_PER_SEC. Voici un exemple théorique : - O n demande l’heure avec clock_ gettime(CLOCK_ REALTIME. Mais voilà.. Par ailleurs. unsigned long long ns) { ts. Solaris. while (ts. ce code va mettre votre code en attente le temps d’un pouillème de seconde.h> <sys/timex. #define NSEC_PER_SEC 1000000000ULL /* Fonction pour ajouter à un struct timespec */ struct timespec timespec_add (struct timespec ts. Si l’heure renvoyée par clock_nanosleep() est antérieure à l’heure système renvoyée par clock_gettime() (test lignes 82 à 95). - On demande au système d’attendre jusqu’à T1+p (« p » correspondant précisément à la notion de pouillème de seconde) avec clock_nanosleep(CLOCK_REALTIME. il faut appeler clock_was_set(). Si le bug est absent. En effet..10 décembre 2012 à 16:20 Le hrtimer a été introduit avec le noyau 2.fr) . Sinon. vous ne devriez pas avoir de problème. ts. Si par contre le bug est présent.6. d’attente est déjà passée depuis longtemps (depuis une seconde moins un pouillème).h> <time.h> <sys/time. Il est ensuite possible d’imaginer tout dysfonctionnement généré par un processeur rendu ainsi indisponible. int neg = 0. vous vous retrouvez dans ce cas à monopoliser un processeur. 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 /* Leap second timer test * inspired by: john stultz (johnstul@us. Pendant que l’horloge système était remise à l’heure..).com) * (C) Copyright IBM 2012 * Licensed under the GPL */ #include #include #include #include #include <stdio. ni ceux dont la version du noyau est antérieure. Ici encore. un appel à adjtimex() et le tour est joué : ntpd a ajouté une seconde à l’horloge système CLOCK_ REALTIME.. Le plus simple est d’utiliser la commande date qui. Normalement. il existe au moins deux façons de procéder. outre le fait de mettre le serveur à l’heure. Pour corriger.ibm.tv_nsec >= NSEC_PER_SEC) { ts. tout va bien. } /* Fonction pour calculer la différence entre * deux timespec */ struct timespec timespec_diff (struct timespec a.21 ou postérieur. Nous allons voir plus loin que le bug est lié à ce timer. sur un noyau 2.tv_sec * NSEC_PER_SEC + b. } return ts. toujours allumée grâce à une pile .tv_sec++. l’heure de fin w w w. le hrtimer n’a pas été décalé d’une seconde. si vous effectuez des opérations nécessitant l’un des deux timers. mais uniquement celui-là.). les deux timers CLOCK_REALTIME et hrtimer ont un décalage d’une seconde. du point de vue du hrtimer. } 5 Attendre.. le système n’attendra pas et redonnera immédiatement la main..tv_nsec. En d’autres termes.01:59:60 : Une SeCOnDe SVP ! Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. - en utilisant un serveur de temps (avec la commande ntpdate pour se mettre à l’heure et avec le démon ntpd pour ajuster l’heure de façon fine). il fallait également mettre le hrtimer à jour. if (ns < 0) { neg = 1. et jusqu’à ce que le bug soit corrigé sur le serveur. C’est lorsque vous vous servez des deux à la fois que cela va mal se passer. appelle cette fonction. il est généralement important d’avoir un serveur à l’heure.h> <stdlib. dont vous avez un jour pris soin de mettre à l’heure. Et voici le cœur du problème : si vous effectuez une boucle en comptant redonner la main au noyau avec un tel mécanisme.tv_nsec += ns...21. ce qui pouvait être fait avec un appel à clock_was_set(). Il suffit de coder cette attente (lignes 64 à 73) et d’analyser le résultat renvoyé par clock_nanosleep() (lignes 75 à 79). Voici le code d’un tel programme. qui ne sont d’ailleurs pas propres à GNU/Linux : - en utilisant l’horloge système. Le 1er juillet 2012.com GNU/Linux Magazine France N° 1 5 3 81 .). cela occupe. 6 Comment savoir si le système est impacté ? Au point où nous en sommes.. voici ce qui s’est passé sur les serveurs dont l’heure est ajustée avec ntpd.. c’est relativement facile. le hrtimer a pris une seconde d’avance. Windows..6. À ce moment. struct timespec b) { long long ns. Cela explique pourquoi il ne se manifeste ni sur les systèmes d’exploitation autres que ceux propulsés par Linux (FreeBSD. Appelons T1 cet instant. le bug se manifeste. Sur Linux.h> 4 Attendez une seconde. la fameuse seconde intercalaire. Ce dernier a été informé d’ajuster l’heure en insérant une seconde.

tv_sec < 0) || (diff. pour être certain de disposer un serveur avec un hrtimer décalé. } exit(retcode).h> <unistd. Exécutons ce programme sur un système sain : $ test_seconde_intercalaire OK 82 G N U / L i n u x M a g azine France N°153 www. NULL). Le tester signifie le lancer sur un serveur dont on sait qu’il est sain et sur un serveur dont on sait que le bug de la seconde intercalaire peut se manifester. if (neg) { a.h> <time.tv_sec += 86400 .tv_sec % 86400.h> <stdlib. c o m . /* Combien de temps avons-nous attendu ? */ diff = timespec_diff (ts. il attend un pouillème avant de dire que tout va bien.h> Pour compiler ce code avec gcc. rem.h> <sys/time. rem. ts.tv_nsec. retcode = EXIT_FAILURE. /* clear TIME_WAIT */ tx. rem.tv_sec. nous avons déjà trop attendu avant même d’avoir commencé.tv. retcode = EXIT_SUCCESS. Ce programme est à compiler et à lancer sur tous les serveurs Linux pour voir l’étendue des dégâts. 7 Comment tester ce programme ? Avant de mettre au point ce petit programme de test. Notons aussi que le temps d’attente restant est nul (0:0) puisque du point de vue du hrtimer.tv_sec. vous devez également préciser que votre code est conforme à la norme POSIX de décembre 2001 avec la constante _POSIX_C_SOURCE (voyez la page de manuel des fonctions clock_gettime() et clock_nanosleep() à ce sujet). Par contre. Nous reprenons le code de John Stultz : 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 /* Leap second timer add * inspired by: john stultz (johnstul@us. /* Get the current time */ gettimeofday (&tv. /* Le moment de vérité : avons-nous attendu un temps négatif ? */ if ((diff. il faut pouvoir le tester.status = 0. le plus simple est encore de forcer ce décalage.tv_nsec. rem.com) * (C) Copyright IBM 2012 * Licensed under the GPL */ #include #include #include #include #include #include <stdio. &ts). int flag = TIMER_ABSTIME. } L’heure est affichée (1344470399 secondes plus 147497347 nanosecondes depuis l’origine des temps).tv_sec. flag. diff. } else { printf ("OK\n").modes = ADJ_STATUS. } return a. vous devez indiquer à l’éditeur de liens d’utiliser la bibliothèque librt (avec l’option -lrt après votre fichier source).tv_sec = -a. target).CODe(S) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.c -o test_seconde_intercalaire -lrt int main (void) { struct timeval tv. Plus précisément.fr) .tv_nsec = -a. /* Set the time to be 10 seconds from that time */ tv. /* Fin de l’attente : quelle heure est-il ? */ clock_gettime (clock_type. adjtimex (&tx). sleeptime). &target. sleep (2).10 décembre 2012 à 16:20 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 } a.tv_sec -= 10. tx.tv_nsec). struct timex tx.tv_nsec < 0)) { printf ("ERREUR\n"). /* Quelle heure est-il ? */ clock_gettime (clock_type. &rem).tv_nsec = ns % NSEC_PER_SEC. settimeofday (&tv. /* Attendons */ clock_nanosleep (clock_type. NULL).h> <sys/timex. target = timespec_add (ts. int retcode = 0. Exécutons-le maintenant sur un système sur lequel la seconde intercalaire pourrait faire des ravages : $ test_seconde_intercalaire ERREUR now: 1344470399:147497347 diff: 0:-999984513 rem: 0:0 int main (void) { struct timespec ts.tv_nsec = 0. /* Calculate the next leap second */ tv. Si comme l’auteur. Il bloque un instant puis indique « OK ». &ts).gnulinuxm a g . ts.ibm. Donc ERREUR. $ gcc --std=c1x -D_POSIX_C_SOURCE=200112L test_seconde_intercalaire. struct timespec target. et la différence entre avant et après est négative. diff. a.tv_sec = ns / NSEC_PER_SEC. Obtenir un serveur sain est facile : exécutez la commande date comme on l’a vu. /* Préparons-nous à attendre (sleeptime = un pouilleme) */ rem.tv_nsec. long long sleeptime = NSEC_PER_SEC / 2.tv_sec. int clock_type = CLOCK_REALTIME. a.tv_sec = 0. printf ("now: %ld:%ld diff: %ld:%ld rem: %ld:%ld\n". vous voulez en profiter pour vous amuser avec la nouvelle norme C11. diff.

dans un cas moins probable.01:59:60 : Une SeCOnDe SVP ! Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Pour compiler avec la norme C11.. Le principe consiste à calculer quand faire survenir la prochaine seconde intercalaire (lignes 26 à 29). -h  ttp://fr. Avec la rotation de la Terre sur elle-même qui ralentit. mais à ce qu’il affiche. Avec les remerciements de l’auteur pour ce mail assez explicite. Attendez quelques secondes le changement de date. Nous avons laissé ici les commentaires du code de John Stultz. dans le contexte informatique. w w w. Rien à voir avec les étoiles. les secondes intercalaires dépendent du Temps Universel. C’est de là que vient cette seconde intercalaire. la journée s’allonge et. Puis l’heure est changée pour être 10 secondes avant ce moment-là (lignes 31 et 32). vous venez de reproduire ce qui s’est passé le 1er juillet 2012 ! Vous pouvez maintenant jouer avec le programme de test. La prochaine est prévue pour.04s (HZ vaut maintenant 250) depuis la version 2. Mais dans ce cas.13. Références - https://lkml. ajoutez encore -D_BSD_SOURCE pour settimeofday(). Cela revient à calculer le changement de date. vous devez avoir les droits suffisants pour changer l’heure (autrement dit. ce qui nous amenait au 1er juillet à 1h 59 min 60s..status = STA_INS. ainsi que son code largement réutilisé dans cet article. chaque 30 juin et chaque 31 décembre. vous devrez vous fier non pas à la valeur de retour du programme. La fois précédente.4 inclus). compilé sur une architecture 64 bits. la prochaine fois. En effet.01 seconde.fr) . et qu’au niveau des machines. Enfin. Avec HZ valant 100 ( jusqu’aux noyaux 2.. C’est fait (ligne 38). comme le temps entre deux interruptions du timer de l’horloge système. Il est maintenant configurable..com GNU/Linux Magazine France N° 1 5 3 83 . Mais lorsque vous allez le faire tester l’ensemble de votre parc GNU/Linux. il faut ajouter 2 heures pour tenir compte du décalage horaire et de l’heure d’été. Il semble communément admis qu’il vaudrait mieux supprimer cette seconde intercalaire.org/wiki/Seconde_intercalaire : quelques explications de Wikipédia au sujet de la seconde intercalaire. nous calculons que 86400 est le nombre de secondes dans 24 heures. Et c’est un patch de.10 décembre 2012 à 16:20 34 35 36 37 38 39 } /* Set the leap second insert flag */ tx. Ah oui. Il faut s’attendre donc à devoir redéfinir la seconde dans les années qui viennent. comme pour la révolution..9 seconde maximum). nous ajoutons cette fameuse seconde intercalaire (lignes 34 à 37). Mais l’on se rend bien compte que ce décalage d’une seconde n’a aucune importance au niveau humain. Comme il s’agit de temps UTC et que l’auteur a écrit cet article en France. exit (EXIT_SUCCESS). -m  an 7 time : Panorama des fonctions liées au temps et aux temporisations. Ce code compile comme le précédent. Depuis. il valait 0. d’où le titre de cet article.0. mais pensez que d’autres encore afficheront des résultats complètement différents. tx..wikipedia. Mais cela ne se prévoit pas. Contrairement aux 29 février qui surviennent tous les 4 ans. 8 La prochaine fois. on ajoute une seconde au temps UTC. adjtimex (&tx). les problèmes que cette solution résolvait se posent à nouveau et il faudra trouver une nouvelle solution. la prochaine fois. Cependant. si votre serveur inventorié Linux s’avère être un AIX ou Solaris. défini par l’orientation de la Terre par rapport aux étoiles. La Terre tourne sur elle-même en 24h et autour du Soleil en 365 jours.6.6. c’était le 31 décembre 2008 (soit en France le 1er janvier 2009 à 1h du matin). correspond à 1/HZ secondes.modes = ADJ_STATUS. Un jiffy est défini. Mais cela est imprécis. Attention. g n u l i n u x m a g.. être root). cela se mesure.. Lorsque le décalage entre le Temps Universel et le Temps Universel Coordonné (UTC) est trop important (0. Vous aurez ainsi un autre genre de message d’erreur si votre binaire. Ça y est. il faut compenser. venue la première fois le 30 juin 1972 et à nouveau le 31 décembre de la même année.001s par défaut (HZ valait 1000) puis 0. nous commençons à pouvoir effectuer des mesures plus précises du temps. le Bureau Central du Service International de la Rotation Terrestre et Systèmes de Référence (il est à l’observatoire de Paris) décide s’il faut ajouter une seconde ou non. De tête (ou presque).. John Stultz ! 9 Le saviez-vous ? Une seconde est définie depuis 1967 comme la durée de 9 192 631 770 périodes de la radiation correspondant à la transition entre les niveaux hyperfins F=3 et F=4 de l’état fondamental 6S½ de l’atome de césium 133. mais pas les années multiples de 100 mais quand même les années multiples de 400 (comme l’an 2000 qui était finalement bissextile alors que 1900 ne l’était pas). puis exécutez ce programme.. d’autres ERREUR. la modification du temps pose au moins autant de problèmes qu’elle en résout. Ce test fonctionne sur votre serveur. Le bug est corrigé dans le noyau 3.5. 1 jiffy valait 0. Notez que depuis le noyau 2.org/lkml/2012/7/1/203 : l’explication de John Stultz à l’origine de cet article. certains afficheront OK. de 1 jiffy... s’exécute sur un serveur en 32 bits ou. Alors. Tellement imprécis pour la révolution qu’il faut ajouter une journée chaque année bissextile. le jiffy n’a plus la même valeur. La durée entre deux ticks de l’horloge système.

donc. a été approuvée en août 2011 mais son implémentation dans les compilateurs a commencée bien avant.gnulinuxm a g . Intel C++ compiler supporte une bonne partie. c’est-à-dire que je ne recherche pas à être exhaustif car de nombreuses évolutions du langage s’adressent à la minorité des développeurs qui développent des bibliothèques telles que la STL.7. Dans l’article précédent.7 (4. permettant d’initialiser tout type de variable.4..CODe(S) C++ 11 et GCC Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.). qui sont d’une complexité qui dépasse le plus grand nombre (moi y compris). Une nouvelle syntaxe d’initialisation uniforme est apparue. mais Microsoft annonce qu’il sera complété par des mises à jour intermédiaires. Je vais donc poursuivre avec cet article dans le même esprit. qui explique dans quelle version de GCC les évolutions du langage sont apparues. Pour information. c o m .fr) . Pour activer C++ 11 dans votre GCC préféré. il faut activer l’option -std=c++11 qui remplace -std=c++0x dans la ligne de commandes. c’està-dire qu’il peut y avoir des choses qui ne sont pas encore en conformité avec la norme et que rien ne sera fait pour maintenir une rétrocompatibilité et que vous ne pourrez pas blâmer GCC pour cela. Elle utilise les accolades et permet d’écrire ceci : int a3{3}. Je conserve le même objectif de présenter au développeur C++ comment il peut profiter de cette nouvelle version du langage dans son quotidien. ne soyons pas trop sectaires. C++ Builder était un peu en retrait sur C++0x mais promet un bon support de C++11 dans la version prévue pour septembre 2012 (du moins sur le compilateur 64 bits. le support de la totalité des nouveautés de la nouvelle norme sera disponible « rapidement » dans la plupart des compilateurs. int TableauEntier[3]{1. et que du coup.0.2. La priorité sera de respecter la norme.5.7. Comme la dernière fois. il vous faudra donc peut-être modifier votre code dans une future version de GCC. Nous allons aborder ici les nouveautés des versions 4. Pour nos amis windowsiens.1 sortie en juin 2012). Cette option est toujours considérée comme expérimentale. Ubuntu 12. c’est que de nombreux compilateurs ont commencé à la supporter avant la sortie finale de la norme. Un des avantages à cette lenteur.5. MingW est livrée avec la toute récente 4.6. Les listes d’initialiseurs permettent d’initialiser des objets de façon similaire à des tableaux et permettent d’écrire ceci : 84 G N U / L i n u x M a g azine France N°153 www.3}.7.04 (LTS) avec la version 4. je vous propose d’étudier les nouveautés des versions 4. 1 Rappel des épisodes précédents 1. Nous aborderons les nouveautés du langage. le fil rouge de cet article va être la page suivante L [GCCStatus].6 et 4.7 de GCC dans le même esprit. ma Debian Squeeze est livrée avec une version 4. ainsi que celles de la bibliothèque Standard C++ / STL (Standard Template Library). la nouvelle version de la norme C++.6 et 4.10 décembre 2012 à 16:20 par Laurent NAVARRO [Développeur/formateur freelance – Altidev Toulouse] C++ 11. c’est à vous de voir en fonction de vos compétences système. à commencer par votre compilateur préféré GCC. mais juste vous faire un résumé (très) concis de ce qu’il s’y est dit. Visual Studio supporte déjà une bonne partie et la version 2012 complète ce support qui est encore partiel.3 à 4. int a4={4}.5 de GCC. a nouvelle version du langage C++ est arrivée : elle s’appelle C++ 11. Aujourd’hui.3 à 4. Cet article fait suite à celui publié l’été dernier dans GNU/Linux Magazine HS n° 55 : Spécial C & C++.1 Nouveautés du langage : Je ne vais pas reprendre ici l’article précédent. nous avions couvert les versions 4. L’installation d’une version plus récente de GCC est probablement un peu complexe.3 et Fedora 17 avec GCC 4.. L’été dernier. Cet article s’adresse donc au développeur C++ moyen qui utilise les bibliothèques plus qu’il ne les écrit. mon article vous parlait de ce qui était alors connu sous le nom de C++0x et de son implémentation partielle dans les versions GCC 4. Cette nouvelle version a mis beaucoup de temps à voir le jour.

un exemple sur plusieurs lignes avec "azerty(comme délimiteur : cout<<R"azerty(On peut ecrire ce qu’on veut et "même" revenir à la ligne (si on veut) La coloration syntaxique ne suit pas forcement .Nom<D.2. dont quelques classes d’un intérêt relatif. Voilà un exemple utilisant la nouvelle version du binder : using namespace placeholders. int y)> UnCallback.Nom.)azerty"<<endl. vector<int> V(5)."Bjarne"}. 10. vector<float> vf = {25."Linus"}.end(). Ici. // On invalide l’objet source } GrosObjet& operator =( GrosObjet &&Src) {// Operateur d’assignation par déplacement.com GNU/Linux Magazine France N° 1 5 3 85 .Bas}. vector<int> V{1.5}.{"N avarro". if(UnCallback) // Permet de tester si c’est assigné. Par une version évitant de déclarer une fonction prédicat : vector<personne> VP={{"Stroustrup".begin().."Linus"}. // Les membres du class enum ne sont plus globaux (c’est le coté class) a=HAlign::Centre. nouveauté C++11 if(x) // Si l’objet courant est valide. elles commencent par un R. qui permet au passage de traiter plus de 2 paramètres.{"Torvalds".end(). // Valign utilise un char en sous-jacent.const personne &D) {return G. Exemple d’utilisation : enum class HAlign {Gauche=0. for(auto it=V.Centre.TriPersonneParNom).4.it!=V.)"<<endl.begin().x.vf. V={1. unordered_multiset qui apportent fréquemment des gains de performance. On retrouve ensuite les pointeurs intelligents (Smart pointers) qui étaient déjà présents dans la bibliothèque BOOST.Centre._1.."Laurent"}}.set.bind(greater<float>().3.Nom. La norme introduit un nouveau type de binder plus générique que bind1st & bind2nd nommé bind.2 La STL La STL a eu aussi son lot de nouveautés.2. Elles permettent de remplacer : bool TriPersonneParNom(const personne &G. - Des versions par table de hachage de map. Exemple avec une fonction C classique : float CBParFonction(int x.begin(). sort(VP. } Les expressions Lambda ont pour but de remplacer les foncteurs les plus simples en écrivant le code directement au lieu d’utilisation.10 décembre 2012 à 16:20 Est apparu aussi le mot-clé auto. Les énumérations fortement typées ou enum class permettent de réduire la portée des identificateurs de l’énumération en exigeant qu’ils soient préfixés du nom de l’énumération.it++) cout << *it<<endl.const personne &D) {return G.fr) . // Version C++11 cout <<"Nbr element >50 = " <<count_if(vf. Elles permettent aussi de spécifier le type sous-jacent utilisé par l’énumération. VP. 150. Les chaînes brutes permettent d’écrire plus facilement des chaînes contenant des antislash (\).3."Bjarne"}. 80}.[](const personne &G.5}."Laurent"}}. objet fonction ou méthode d’objet. g n u l i n u x m a g.x=NULL. 1.{"Torvalds". // On libère d’abord sa mémoire x=Src. function qui peut être utilisée pour stocker indifféremment Autre nouveauté dans les utilitaires. on s’en sert comme ceci : auto x=43.x=NULL. La partie la plus visible est l’apparition de constructeur par déplacement et d’opérateur d’affectation par déplacement qui ont des paramètres avec des && comme ceci : GrosObjet ( GrosObjet &&Src) {// Constructeur de déplacement. shared_ptr et son acolyte weak_ptr. -L  a classe array qui est un tableau de taille fixe. qui permet de déduire le type d’une variable grâce à son initialisation (on parle d’inférence de type).30)..end(). VP. Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.C++ 11 eT GCC vector<int> V={1. // exemple de tri utilisant une expression lambda sort(VP.x.. enum HAlign a. ont pour délimiteur "( et peuvent avoir un délimiteur configurable : cout<<R"(Une chaine \tsans tab.4.begin().4.50)) <<endl. des callbacks qu’ils soient fonction C classique. une classe tuple et une liste chaînée simple forward_list. vector<personne> VP={{"Stroustrup". delete x. cout<<"Callback = "<<UnCallback(10. }). } .end().{"N avarro".multimap et multiset nommées unordered_map. unordered_multimap. UnCallback=CBParFonction. des doubles quotes (") ou des retours chariots.3. int y) {return x+y. nouveauté C++11 x=Src. } function<float (int x. c’est l’apparition de w w w.Nom<D.Droite}. unordered_ set.2. enum class VAlign :char {Haut=100. // On s’approprie la zone mémoire de l’objet source Src. // On invalide l’objet source return *this. Est apparu un concept un peu barbare nommé RValue référence qui permet d’introduire le concept de déplacement d’objet qui était précédemment réalisé par une succession de copie + destruction.5}. On retrouve donc unique_ptr. // On s’approprie la zone mémoire de l’objet source Src.

1 Range-based for (boucle foreach) (GCC>=4. 86 G N U / L i n u x M a g azine France N°153 www.CODe(S) 1. Il est aussi possible de spécifier que cette référence est constante. // Toujours possible // Version C++ 03 for(vector<int>::iterator it=V.va_Bas}.5}. On remarquera que l’itérateur devient invisible et que c’est directement la valeur qui est manipulée.it!=V.5 & errata Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Exemple de déclaration d’une énumération style C avec le type char sous-jacent : enum VAlignement :char {va_Haut=100.3. // Mais enum seul est suffisant en c++11 J’en profite pour faire un errata de l’article précédent : Concernant unique_ptr. vector<int> V(5).6 for( auto x: V) cout << x<<endl.begin(). Cela reste possible sur une classe telle que vecteur. enum class HAlign a. // Version C++ 11. Il est à présent possible (comme pour une classe ou une fonction) de déclarer l’existence d’une énumération et de ne la déclarer complètement (c’est-à-dire avec ses valeurs) que plus tard. Dans l’exemple sur les Rvalues. Il est aussi possible d’utiliser cette boucle sur une liste d’initialiseurs : for( auto s: {"Bonjour".10 décembre 2012 à 16:20 Certaines choses ont changé dans GCC par rapport à ce que j’avais écrit la dernière fois. for( auto x: Tableau) cout << x<<endl.fr) . Voilà ce que cela donne sur un tableau d’entiers : int Tableau[]{1.begin().end().6 for(auto it=V. // fonctionnait en GCC 4. Cette boucle permet de parcourir une collection. enum class VAlign. de cette variable.it++) cout << *it<<endl. TableauEntier={1. il ne faut plus préciser que c’est un class enum lors de l’instanciation de la variable. pour récupérer le pointeur (pour le passer en paramètre à une fonction.va_Centre.it!=V.5 enum HAlign a. V={1. Elle fait son apparition dans C++ 11 sous le nom de Range-based for en tant que syntaxe particulière de la boucle for. 2. // Plus possible.2.4.gnulinuxm a g . for(const auto x: V) 2 Nouveautés du langage 2. (copier/coller quand tu nous tiens). ce type de boucle est utilisable sur tout objet qui implémente begin() et end(). ce qui permettra d’éviter la copie de l’objet en cours tout en bloquant sa modification.6) La boucle foreach est présente dans de nombreux langages. Dans sa version de base. il suffit d’utiliser la méthode get(). La syntaxe est la suivante : for (Type VariableDeBoucle : CollectionAParcourir) Il n’est pas possible de spécifier que la variable de boucle est un pointeur ou un itérateur. GCC >= 4. mais il est possible de manipuler une référence sur la valeur afin de pouvoir modifier la collection en utilisant la notation suivante : for( auto &x: V) Lors de l’utilisation d’une énumération fortement typée. GCC < 4. un bug s’était glissé dans l’opérateur = classique. // Version C++ 11.2 Énumération (suite) (GCC>=4.2. ce qui est le cas de toutes les collections de la STL.end().3}."les".it++) cout << *it<<endl.2.5}."amis"}) cout << s<<endl. le Range-based for manipule une copie de la valeur. Il n’est plus possible d’utiliser une liste d’initialiseurs pour affecter un tableau ailleurs que lors de son initialisation. par exemple). Type sera vraisemblablement souvent remplacé par le mot-clé auto qui déterminera automatiquement le type En plus des tableaux.4. il ne fallait pas faire le if(x) delete x. c o m .3 Ce qui a changé depuis GCC 4. Voilà donc l’évolution pour parcourir un vecteur : Cette version introduit aussi la capacité de faire des déclarations « forward » des énumérations.3. for(const auto &x: V) Il est aussi possible de spécifier que la variable de boucle par valeur est constante afin de provoquer une erreur de compilation si vous la modifiez par mégarde. enum est suffisant. void TestForwardEnum(VAlign Alignement).6) En plus des énumérations fortement typées est apparue la possibilité de spécifier le type sous-jacent sur une énumération classique.

std::string GetSecret(). cout <<CS. Il y a principalement deux motivations de cette évolution. Dans la version précédente de C++. Cette technique peut aussi être utilisée pour avoir des variantes d’implémentation (par exemple sur du code multi-plateforme) qui requièrent d’avoir des données stockées différentes.GetSecret()<<endl. s’il sait juste qu’elle existe et connaît son type sous-jacent. le fichier appelant n’a pas besoin de connaître les détails de la classe ClasseSecrete_members puisqu’il doit juste gérer un pointeur. Exemple : void Container::SetAlignement(VAlign Alignement) { for( auto &child: Childs) child->SetAlignement(Alignement). } Remarque Juste un petit aparté que m’a inspiré l’envie de cacher les choses de la déclaration forward des enums.h qui définit l’énumération complète. Seule l’implémentation de la classe ClasseSecrete a besoin d’en savoir plus. il peut travailler. il n’était pas possible (simplement) d’utiliser un enum privé qu’on ne déclarait pas dans l’interface. 2. ~ClasseSecrete(). Ainsi. CS. Une technique classique pour masquer les attributs contenus dans une classe est de créer une classe qui ne contiendra que les attributs et de n’intégrer dans la classe visible qu’un pointeur vers cette classe qui elle restera complètement invisible en étant déclarée dans l’implémentation de la classe. }. Illustration : ClasseSecrete. } void ClasseSecrete::SetSecret(std::string secret) { MembresSecrets->LeSecret=secret. NULL a pour valeur l’adresse 0 qui.C++ 11 eT GCC Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. } Dans ce code. seule la connaissance du type est nécessaire. } std::string ClasseSecrete::GetSecret() { return MembresSecrets->LeSecret. class ClasseSecrete { public: ClasseSecrete(). le compilateur n’a pas besoin de connaître le détail de l’énumération.h class ClasseSecrete_members. La première est de réduire le couplage. private: ClasseSecrete_members *MembresSecrets. g n u l i n u x m a g.com GNU/Linux Magazine France N° 1 5 3 87 . car il y a pas mal de cas où il n’est pas nécessaire de connaître les valeurs d’une énumération.h).10 décembre 2012 à 16:20 Il est ainsi possible de déclarer un paramètre de fonction ou un attribut de classe du type d’une énumération sans avoir à déclarer l’énumération elle-même (ou inclure le fichier header qui la déclare).SetSecret("I love C++"). } ClasseSecrete::~ClasseSecrete() { delete MembresSecrets.3 nullptr (GCC>=4.fr) .6) En C++ (en héritage du C). ClasseSecrete. La notion de réduction du couplage s’étend aussi au niveau des dépendances dans les fichiers d’en-tête (. Le problème vient du fait qu’en C++. il doit être spécifié dans la déclaration forward.cpp class ClasseSecrete_members { public: std::string LeSecret. il suffit de dire que cette énumération existe. si cette énumération utilise un type sous-jacent spécifique (ce qui ne devrait pas être le cas le plus courant). }. il n’est plus nécessaire d’inclure le . On arrive ainsi à masquer complètement les détails du stockage des données. Fichier utilisateur de la classe : ClasseSecrete CS. w w w. même les attributs privés doivent être déclarés dans l’interface et leurs types doivent être connus. ClasseSecrete::ClasseSecrete() { MembresSecrets=new ClasseSecrete_members(). NULL désigne un pointeur spécial qui signifie pointeur invalide ou non affecté. void SetSecret(std::string secret). À noter que. La seconde motivation des déclarations forward des enums est de pouvoir cacher une énumération qui est utilisée sur un attribut privé. dans de nombreux environnements est une Cela fonctionne car la taille d’un pointeur est connue même si on ne connaît pas la taille de la classe pointée.

-)). l’objet est considéré comme initialisé). Ceci peut poser. qui est un pointeur sur l’adresse 0 mais qui ne peut pas être considéré comme un entier. 2. un problème quand le compilateur doit choisir entre un entier et un pointeur. Le problème n’est que partiellement résolu. }.gnulinuxm a g . Pour le résoudre complètement. 88 G N U / L i n u x M a g azine France N°153 www. si nullptr est adopté. il sera envisageable de faire ce changement (en attendant. dans certains cas. Aujourd’hui. Afin de pallier partiellement ce problème.4 Initialisation des attributs non statiques (GCC>=4. c o m . l’appel MaFonction(NULL) est ambigu (GCC va d’ailleurs vous le faire savoir).5 Délégation de constructeurs (GCC>=4. MaFonction(NULL) . Chez nos camarades qui font du Java.10 décembre 2012 à 16:20 NULL n’est pas un mot-clé mais une macro C qui vaut 0 ou ((void*)0) et une règle dans le langage dit que la valeur 0 peut être considérée comme un entier ou comme un pointeur. il sera possible d’initialiser les attributs lors de leur déclaration et donc d’écrire ceci : class Maclasse { public: Maclasse() {} Maclasse(void *p) { ptr=p. du coup MaFonction(nullptr) n’est pas ambigu. Je vous concède que c’est une subtilité à la C++. L’initialisation ne sera pas effectuée si l’attribut est déjà initialisé avec la notation de liste d’initialisation du constructeur suivante : MaClasse(void *p):ptr(p) {} Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Dorénavant. Ceci était un peu fastidieux quand il y avait pas mal de constructeurs. nullptr est un synonyme typé de NULL que vous risquez de croiser dans le futur. }.CODe(S) valeur spéciale où une application classique n’est pas supposée accéder (sous certains OS.fr) . En résumé. 2. À noter que le destructeur sera invoqué si une exception est levée dans un constructeur alors qu’au moins un constructeur délégué a été exécuté entièrement (car si au moins un constructeur est terminé.7) Les attributs non statiques (c’est-à-dire les attributs classiques) ne pouvaient être initialisés que dans les constructeurs. depuis un constructeur. En revanche. mais la délégation de constructeur est une approche plus complète. void MaFonction(int v) . il est possible d’invoquer un autre constructeur dans la liste d’initialisation du constructeur. Le premier constructeur invoque le second avec une valeur constante. il aurait fallu en plus supprimer la règle qui dit que la valeur 0 peut être considérée comme un pointeur. et que la valeur initiale était tout le temps la même et du style 0 ou NULL ( je devrais dire nullptr . ceci est déjà possible et l’expérience a montré que c’était largement utilisé. l’initialisation aura lieu et sera écrasée par le code du constructeur.7) Il est fréquent.} private: void *ptr=NULL. L’initialisation peut être effectuée avec des constantes ou des appels de fonctions. un nouveau mot-clé nullptr a été introduit. int nbr=0. Par exemple : void MaFonction(char *v) . un accès au 1er Mo de la mémoire provoquera même une erreur d’exécution). La nouveauté présentée au paragraphe précédent résout le problème dans certains cas. donc mieux vaut connaître sa signification.} Ici. ce qui aurait sans doute posé de gros problèmes de rétrocompatibilité. quand on a plusieurs constructeurs. Exemple : class Maclasse { public: Maclasse():Maclasse(50) {} Maclasse(int p):nbr(p) { } int nbr. l’impact sera mineur la plupart du temps. mais dans les faits. Mais cette technique. nullptr peut être comparé à n’importe quel pointeur et est également considéré comme un booléen false. Dorénavant. l’option GCC -Wzero-as-null-pointer-constant s’en rapproche un peu). Peut-être que dans 10 ou 15 ans. Le constructeur de copie peut lui aussi invoquer un constructeur. se heurte à quelques limitations telles que l’utilisation de la notation de la liste d’initialisation du constructeur (MaClasse(x):p(x)) obligatoire dans certains cas. en plus de sa lourdeur pour les petites classes. qu’il y ait du code commun à ces constructeurs. avec la notation suivante : MaClasse(void *p): {ptr=p . une technique classique pour factoriser ce code est d’utiliser une méthode privée d’initialisation commune qui sera invoquée par les constructeurs.

Exemple qui marche : class Personne { public: Personne(string _Nom):Nom(_Nom) {} virtual void DisBonjour() {cout<<"Bonjour "<<Nom<<endl. localStorage. g n u l i n u x m a g. ● de la technique (animations. P->DisBonjour().fr) . ex : float devient double ou ajout/perte d’un const) qui du coup crée une nouvelle méthode virtuelle au lieu de surcharger l’existante. - Erreur dans le nom (oubli d’une lettre ou d’une majuscule) ou dans les paramètres (mauvais nombre ou type.10 décembre 2012 à 16:20 Parfois. }. on peut commettre une erreur difficile à déceler.. du Toutes les Ficelles pouR cRéeR VotRe pRopRe Jeu ViDéo pouR le Web. une erreur sera levée. avec la découverte d'outils pour accélérer vos développements w w w. canevas. car ne provoquant aucun message du compilateur. Afin d’aider à diagnostiquer ces problèmes sans casser la compatibilité avec l’existant. Voici par exemple le message d’erreur qui apparaîtrait si on décidait de déclarer la méthode de base const sans changer les classes héritières : virtual void DisBonjour() const erreur: ‘virtual void Homme::DisBonjour()’ marked override.7) Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. 2 nouveaux marqueurs de méthode ont été introduits : final et override.. un nouVeau numéRo HoRs-séRie De LinuX PRatiQue : SPÉCIAL Les cas d’erreurs les plus fréquents sont : - Oubli du mot-clé virtual (appellera toujours la méthode associée au type du pointeur et non celle associée à l’objet pointé).com À DécouVRiR cHeZ VotRe maRcHanD De JouRnauX DÈs le 12 octobRe 2012 !89 GNU/Linux Magazine France N° 1 5 3 . but does not override ● des rappels sur le game design.C++ 11 eT GCC 2. mais juste un comportement qui n’est pas celui de la surcharge d’une méthode dans une héritage qu’on désirait. } Le 12 octobRe.6 Syntaxe de surcharge explicite (GCC>=4. coup si ce n’est pas le cas pour une raison quelconque. musique.. gRÂce auX nouVelles Fonctionnalités D'HTML 5 ! si vous prenez l’habitude de toujours ajouter override.. lorsque l’on surcharge une méthode lors d’un héritage. websockets. la monétisation des jeux. class Homme:public Personne { public: Homme(string _Nom):Personne(_Nom) {} virtual void DisBonjour() {cout<<"Bonjour Mr "<<Nom<<endl. { Personne* P=new Homme("Laurent"). les graphismes. polices.) ● et de la pratique. virtual void DisBonjour() override {cout<<"Bonjour Mr "<<Nom<<endl. le compilateur fera des contrôles supplémentaires pour vous aider. } string Nom. } override permet de dire que l’ont fait une surcharge. } }.

5i qui créerait un nombre complexe. } Gardez en tête que.5 est un littéral flottant. . Le suffixe i est implémenté pour les complex<double> dans GCC. Heureusement. En termes de performance. while(*p) { res<<=1. on aurait pu se retrouver à introduire un beau bug qui aurait été délicat à déceler. l’évaluation d’expression constante à la compilation. . ceux sans _ sont réservés pour de futures standardisations ( je n’ai aucun doute sur le fait que cette règle ne sera pas trop respectée malgré le warning de GCC . seule la syntaxe est disponible.7) Les littéraux sont les valeurs écrites dans le code : 12.5km pour intégrer des unités ou faire des conversions. Certains usages possibles pour les littéraux définis par l’utilisateur ont été imaginés : . "Bonjour" est un littéral char*. quant à lui. l’utilisation de ces marqueurs est optionnelle.1 Gestion des Threads Le C++ supporte depuis toujours les Threads. On remarque que la fonction n’a plus qu’un seul paramètre (la taille n’est présente que pour les littéraux chaîne). virtual void DisBonjour() final {cout<<"Bonjour "<<Nom<<endl. À présent. La meilleure source d’information que j’ai trouvée est le standard lui-même [C++11Std]. La plupart des choses que je vais raconter ici sont aussi applicables à boost::thread à condition de changer quelques #include et quelques noms. un exemple traitant des littéraux non chaîne en tant que format binaire : 90 G N U / L i n u x M a g azine France N°153 www. Il se place sur l’ancêtre qui décide qu’il n’y a plus de sens pour un héritier de surcharger une méthode. mais c’est une extension historique de GCC et non pas une implémentation de cette nouvelle syntaxe.7 Littéraux définis par l’utilisateur(GCC>=4. maintenant override et le compilateur vont vous aider. p++.CODe(S) Voilà comment d’une bonne intention. soit de se protéger d’un écrasement accidentel par un héritier. permet soit d’empêcher une surcharge. mais juste de vous expliquer comment mettre en œuvre les nouveaux modules de programmation concurrente. un espoir d’exécution à la compilation existe au travers du nouveau concept de constexpr que j’ai éludé. Il est convenu que les littéraux utilisateurs devront commencer par un _.gnulinuxm a g . mais il manquait une classe standard au langage.34. Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. Donc.10101010b pour traiter les binaires. Un exemple simple permettant de créer un objet string glané sur le net : std::string operator "" _s (const char* p. Cela est à présent chose faite avec std::thread qui est fortement inspiré de boost::thread dans une version plus simple. c o m .n). Je vous conseille de les utiliser systématiquement car ce genre d’erreur subtile est vite arrivé. if(*p==’1’) res|=1. } auto str="Bonjour"_s. } return res."Bonjour"s qui créerait un objet string. Il faut bien garder en tête que ces littéraux sont en fait des appels de fonctions et sont donc exécutés lors de l’exécution du programme et pour chaque apparition du littéral. ne jetez donc pas encore vos macros ou la notation GCC 0b0101. dans certains cas. #include <stdexcept> unsigned long operator "" _b (const char* p) { unsigned long res=0. } auto binaire=0101010_b. Cependant. et qui pourrait permettre. str est de type std::string. Pour l’exemple des binaires.-)). voire dans le standard. L’objectif ici n’est pas de faire un cours de programmation parallèle. Pour l’instant. c’est donc très différent d’une exécution à la compilation. le compilateur ne vous aidera que si vous vous aidez en utilisant ces marqueurs. 3 Nouveautés de la bibliothèque standard C++ 3. . 2. afin de ne pas casser la compatibilité avec l’historique.10.10 décembre 2012 à 16:20 Le marqueur final. size_t n) { return string(p. else if(*p!=’0’) throw std::range_error("Seuls les 0 et 1 sont autorisés pour les litérraux binaires").fr) . La documentation disponible est plutôt maigre dans la doc GNU libstdc++. mais je suis sûr que dans un futur proche. de nombreux formats de littéraux évolués seront disponibles dans des bibliothèques.

Si vous voulez lancer votre thread sur un objet et non pas sur une copie d’un objet. Pour résoudre ceci. } void MyMethod() {// Pour appel par Methode classique Write10Char(c). soit le détacher avec detach() pour qu’il conti- w w w. ceci a une tête de bug et il suffit d’ajouter de façon peu élégante -D_GLIBCXX_USE_NANOSLEEP aux options du compilateur pour arranger ce problème. La création d’un objet thread suffit à lancer l’exécution d’un thread. c’est-à-dire une classe surchargeant l’opérateur () et même une méthode d’un objet en utilisant un binder : class ClassCharWriter { public: ClassCharWriter(char _c):c(_c){} char c. Mais il n’y aura pas de problème. ce qui poserait un problème.com GNU/Linux Magazine France N° 1 5 3 91 . void operator()() {// Pour appel par operateur () / Foncteur Write10Char(c). une petite difficulté peut apparaître si vous souhaitez passer une référence en paramètre.} }. du coup le thread ne sera pas lancé sur SWriter mais sur une copie de SWriter.’ terminé" << endl. il est aussi possible de lancer un thread sur une expression lambda : thread t5{ []() {Write10Char(‘L’).’<<endl. Cet exemple lance la fonction Write10Point dans un thread séparé et attend la fin de son exécution (t1.SWriter)}. ça ne marche pas car la classe thread n’a pas encore été portée. } cout << "Worker: ‘. il vous faudra utiliser ref(MonObjet). } thread t2{Write10Char. } void DemoThread() { thread t1{Write10Point}. comme toujours avec les expressions lambda.10 décembre 2012 à 16:20 #include <iostream> #include <thread> #include <chrono> using namespace std.join(). g n u l i n u x m a g.join). Il est aussi possible d’appeler un foncteur. Quelques explications : t3 a en paramètre l’appel d’un constructeur. void Write10Point() { for(int i=0. Le second problème risque d’être à l’exécution où le lancement du thread provoquera une erreur de runtime fatale à votre programme. lors du passage. ce qui dans le cas présent donne un résultat similaire. thread t4{bind(&ClassCharWriter::MyMethod.join(). } }. t1. car l’objet est copié et le thread est lancé sur une copie. Pour être exhaustif. // Exemple avec un foncteur thread t3{ClassCharWriter(‘C’)}. il suffira d’ajouter -pthread comme paramètre du compilateur et du linker. Une fois lancé. } Au niveau du passage des paramètres. vous risquez de rencontrer quelques difficultés.milli>(200)).1 La classe std::thread La classe std::thread est la classe qui encapsule la gestion des threads. } cout << "Worker: ‘"<<c<<"’ terminé" << endl.i<10. // Exemple avec une méthode de l’objet SWriter ClassCharWriter SWriter(‘S’). La fonction Write10Point affiche 10 points en attendant 200ms entre chaque affichage. Cet objet a pour durée de vie l’instruction qui le contient. il faut en user avec parcimonie.LeParamParValeur.fr) . cout << c<<endl. on pourrait craindre que cet objet soit détruit avant que le thread ne soit lancé. Bien sûr. il faudra en plus. encapsuler le paramètre dans la fonction ref() : thread MonThread{MaFonction. ceci a pour effet de construire un objet (instance d’une classe) non nommé.i++) { this_thread::sleep_for(chrono::duration<int.join(). t4. l’objet SWriter est passé en paramètre et le comportement sera le même. Si vous exécutez ce petit bout de code sur votre Fedora 17 (et probablement ailleurs aussi). Si vous êtes arrivé à exécuter le premier exemple. sachez qu’il est possible de lancer le thread en passant des paramètres à la fonction tout simplement en ajoutant les paramètres à la suite du nom de la fonction : void Write10Char(char c) { for(int i=0.i<10. Voici un exemple : Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.ref(LeParamParReference)}.1. La première risque d’être que this_thread::sleep _for n’est pas reconnue.i++) { this_thread::sleep_for(chrono::duration<int. Si vous exécutez ce code sur MinGW. il faut soit attendre la fin de son exécution avec join(). t2.C++ 11 eT GCC 3.’x’}.join(). Pour t4. cout << ‘.milli>(200)). Du coup. Le fait de mettre un & dans la fonction ne sera pas suffisant. t3.

idéalement.CODe(S) C++ 11 eT GCC nue son exécution indépendamment de la vie de l’objet thread. Il existe deux variantes de mutex. thread t2{ExceptionCatcher(). Voilà la variante plus C++ : void Test1(char c) { lock_guard<mutex> LG(M).. comme moi. comme souvent._Args&&.Write10Point}.. __args) { try { f(__args.. La variable LG ne sera pas utilisée. } } }. son destructeur sera invoqué et appellera M. } Celui-ci. permet de gérer les paramètres grâce à un template variadique (qui est une autre nouveauté de C++ 11 que je ne vous ai pas présentée) et permet de mémoriser de façon optionnelle le nom du thread (cela peut être utile lors de la lecture des logs). Il faut donc veiller à toujours avoir un catch global dans chaque thread qui.Tout appel à lock() sur un mutex déjà pris suspendra l’exécution du thread jusqu’à ce que le mutex soit libéré par le thread qui l’a pris. Cependant. on utilisera un gardien qui prendra le mutex et le gardera jusqu’à ce que le gardien disparaisse.). Une solution consiste à emballer notre thread dans un foncteur qui sera catcheur/loggeur de dernier ressort.unlock(). } Dans cet exemple. Ceci arrive aussi si vous faites un return avant le unlock.Write10Char. 92 G N U / L i n u x M a g azine France N°153 www. soit détaché le thread sous peine de terminer le programme de façon brutale. c o m . } void DemoMutex() { thread T1(Test1. } catch (exception &e) { cout <<"Exception non catchee dans thread "<<ThreadName<<" : "<< e..gnulinuxm a g . La déclaration de la variable LG appellera le constructeur de lock_guard qui appellera M.T2.. } 3. Write10Char(c). L’utilisation typedef. template <class F. thread T2(Test1. tracera l’événement et éventuellement prendra une action adéquate si cela est possible. Ici. les 2 appels à Write10Char se font de façon succes- sive et non pas parallèle car le mutex exclut le second thread pendant qu’il exécute le premier.’2’). il est possible que.. Un mutex ne peut être pris qu’une seule fois au moyen de lock() et est relâché au moyen de unlock(). thread t1{ExceptionCatcher("Write10Point").join().’x’}. typedef lock_guard<mutex> mutex_guard.unlock().what()<<"\n". void Test1(char c) { mutex_guard MG(M). l’utilisation de lock est très C-iène et risque de rendre le programme instable (deadlock) si une exception est levée dans Write10Char car le mutex ne sera pas libéré. #include <mutex> mutex M. un autre cas d’arrêt brutal est l’apparition d’une exception non traitée dans un thread qui aura pour effet d’arrêter l’ensemble du programme.. La méthode native_handle() permet de récupérer un handle propre à la plate-forme pour accéder au thread système sous-jacent afin d’utiliser des primitives systèmes dessus.10 décembre 2012 à 16:20 En parlant d’arrêt brutal. Write10Char(c). Pour éviter ces problèmes. vous soyez un peu fainéant et pensiez qu’il soit possible d’avoir un traitement uniforme et simple à mettre en œuvre pour chaque thread. M. } catch (.2 Les mutex Les classes mutex permettent de gérer les besoins d’exclusion mutuelle qui sont nécessaires pour gérer la problématique classique de la concurrence d’accès à des ressources. la variable LG disparaîtra. Write10Char(c).) { cout << "Exception non catchee inconnue dans thread "<<ThreadName<<"\n". _Args> void operator()(F f. seul son constructeur et son destructeur nous intéressent.fr) . Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.. de mon cru. struct ExceptionCatcher { ExceptionCatcher(string _ThreadName=""):ThreadName(_ThreadName) {} string ThreadName. void Test1(char c) { M.typename. T1.1. vous permettra d’alléger un peu le code. Il ne faut surtout pas laisser l’objet se détruire sans avoir soit rejoint.’1’).lock(). try_lock() permet de prendre le mutex s’il est libre et retourne false s’il est déjà pris.lock().join(). Lors de la sortie de la fonction (quelle qu’en soit la raison).

fr) . g n u l i n u x m a g. RDP et cassage oFFline De session Minitel Rose et cRYpto : ReVeRse D’une Vieille application 16 bits Sous réserve de toutes modifications.au sommaiRe Du pRocHain Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.com GNU/Linux Magazine France N° 1 5 3 93 . à paRaÎtRe le 12 octobRe 2012 ! w w w.10 décembre 2012 à 16:20 n°6 De la tHéoRie à la pRatiQue » Le FutuR De la cRYpto : Quel algo De 3 lettRes seRa le pRocHain Titanic ? » » état Des lieuX Du logaRitHme DiscRet Les mains Dans la cRYptogRapHie Les eRReuRs à ne pas commettRe en pRogRammant De la cRYpto SHA-3 Vue De l’intéRieuR PRotections logicielles contRe les attaQues paR canauX auXiliaiRes » Les RisQues liés à SSL/TSS » La compétition pouR » » » CRYpto.

si un try_lock() échoue (retourne false ou lève une exception). Dans unique_lock. Cette 94 G N U / L i n u x M a g azine France N°153 www. unlock.1). La bibliothèque fournit aussi 2 fonctions de gestion des verrouillages multiples. qu’il devra rendre autant de fois qu’il l’a pris. try_lock des mutex ainsi que owns_lock() et l’opérateur d’évaluation booléenne pour savoir si le mutex associé est pris ou pas.3 Les variables condition (Condition variables) Les variables condition sont un moyen de s’abonner à des événements associés à une donnée qui est protégée par un mutex. } cout << "notify_one A"<<endl.2). Write10Char(c). } } void Producteur() { thread T1(Consommateur. sleep(1). once_flag of_test1.notify_one(). qui permet au même thread de reprendre autant de fois qu’il veut le mutex. La seconde. cout << No<<"=>"<<MyData<<endl. sleep(1). } cout << "notify_one B"<<endl. char MyData=’?’. { Le second paramètre du constructeur à try_to_lock permet d’essayer de prendre le mutex de façon non bloquante. prend de 2 à n paramètres (mutex ou unique_ lock) et va appeler try_lock() pour tous. La première. unlock() sera appelée pour tous ceux qui ont pu être verrouillés. defer_lock). qui n’est pas encore implémentée. mais dont une seule a besoin d’être effectuée. qui permet de déverrouiller et verrouiller le mutex en cours d’exécution tout en étant dans la portée du gardien. fonction s’assure que l’initialisation c’est effectuée avec succès (sans lever d’exception) qu’une seule fois et que tous ceux qui la demandent. L’implémentation est libre mais il est suggéré d’utiliser des successions try_lock() et unlock().notify_one(). Cette fonction aide à mettre en place une initialisation tardive (lazy initialization) plutôt que de faire une initialisation systématique bien avant qu’elle ne soit nécessaire dans un des threads. try_lock(). #include <condition_variable> mutex Mcv. Nous allons commencer par un exemple simple qui va nous permettre de faire le tour des méthodes. lock().fr) . { lock_guard<mutex> LG(Mcv). while(1) { MyCV. thread T2(Consommateur. MyData=’B’. 3. Il est possible de créer ce gardien sans prendre le mutex avec defer_ lock ainsi : unique_lock<mutex> MyLock(M. est similaire mais va appeler lock() et va nous garantir de ne pas créer de deadlock.CODe(S) La première est recursive_mutex.gnulinuxm a g . Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. sont bloqués jusqu’à ce qu’elle soit terminée. Cette fonction à été imaginée afin de traiter le besoin d’une initialisation unique lancée depuis plusieurs threads.wait(LG). MyCV. sleep(1). c o m . condition_variable MyCV.DoInitOnce. } C’est la variable of_test1 qui gère l’état de l’initialisation et l’exclusion mutuelle.// On laisse les thread se lancer et se mettre en attente sur la condition { lock_guard<mutex> LG(Mcv). Elles constituent un mécanisme de base pour gérer un modèle producteur/consommateur dans des threads différents.c). on retrouve les méthodes lock.10 décembre 2012 à 16:20 La seconde.1. } void Test1(char c) { call_once(of_test1. MyData=’A’. Une autre fonctionnalité est fournie. void DoInitOnce(char c) { cout <<"Init done by "<<c<<endl. void Consommateur(int No) { unique_lock<mutex> LG(Mcv). il s’agit de call_once. MyCV. est timed_mutex qui propose une méthode try_lock_for qui essaye de prendre le mutex pendant un certains temps. Il existe aussi une version plus complète du gardien qui se nomme unique_ lock. mutex_guard MG(M).

Donc le producteur prend le mutex pour pouvoir tranquillement écrire dans la donnée puis libère le mutex et avertit un consommateur à travers notify_one(). une expression lambda est parfaitement adaptée). notify_all() est plutôt adaptée à avertir un ensemble de consommateurs qui consomment la même donnée alors que notify_one() est plutôt adaptée pour une donnée consommée une seule fois par un seul consommateur. CV. sleep(1). La présence de cette méthode confirme bien le fait qu’une variable condition est souvent utilisée avec une condition booléenne pour savoir si des données sont prêtes ou s’il s’agit d’un réveil intempestif. une queue synchronisée bloquante peut être intéressante. T2.wait(LG). le thread sera débloqué puis prendra le mutex (il attendra jusqu’à ce qu’il soit libre). }. LG. } bool is_empty() const { lock_guard<mutex> LG(Mutex). } private: queue<DataType> Q. Nous allons utiliser un exemple d’implémentation basique pour illustrer l’utilisation des variables condition dans un cas plus classique. T1. ret_value=Q. La variante de CV.10 décembre 2012 à 16:20 } } cout << "notify_all C"<<endl. Ainsi. Le consommateur prend le mutex puis se met en attente avec wait(mutex) sur la condition en y associant le mutex (ou un gardien associé au mutex).empty()) CV. alors qu’une notification est envoyée à chaque push. MyData=’C’.}).C++ 11 eT GCC Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. mutex Mutex.unlock(). l’utilisation de unique_lock pour pouvoir faire un unlock() avant le notify_one() (cela réduit le risque de réveiller le thread pour qu’il se bloque ensuite sur le mutex) alors que is_empty() peut se contenter d’un lock_guard plus léger. condition_variable CV. mais il servira de base pour implémenter un mécanisme de plus haut niveau plus pratique à utiliser. } void pop(DataType &ret_value) { unique_lock<mutex> LG(Mutex).wait(LG. CV. Q.[&]{return (!Q.detach().notify_one().notify_all(). Les points à remarquer sont : Dans push. mais réveille tout thread en attente sur la condition.detach(). Par exemple. g n u l i n u x m a g.com GNU/Linux Magazine France N° 1 5 3 95 . Pourquoi des réveils intempestifs ? Étant donné qu’un thread regarde s’il y a des données à traiter avant de se mettre en attente. w w w.push(data). Q. qui est équivalent à : while(Q. qui donne la sortie suivante : notify_one A 2=>A notify_one B 1=>B notify_all C 2=>C 1=>C Nous avons donc 2 threads exécutant Consommateur qui ont pour rôle de consommer la donnée représentée par la variable MyData quand elle est prête en l’affichant avec le numéro du thread qui fait l’opération. mais cela réduit le degré de parallélisme).pop(). ce qui va de façon atomique mettre le thread en attente sur MyCV et libérer le mutex (ainsi le producteur pourra produire).fr) . vous ne serez réveillé qu’à la notification suivante (une solution consiste à garder le mutex pendant le traitement. return Q. Ce mécanisme est un peu basique pour être utilisé en l’état dans pas mal de cas. pour un modèle 1 producteur avec 1 ou n consommateurs et avec un souhait de ne perdre aucune donnée produite.empty(). lorsque la condition sera notifiée. lock_guard<mutex> LG(Mcv). si vous venez d’être réveillé par un notify et que vous mettez un peu de temps à traiter la donnée avant de refaire un wait et qu’entre temps un notify a eu lieu.empty()). Il faut garder en tête que les notify_xxx ne notifient que les threads qui sont en attente sur un wait .wait qui prend en second paramètre un foncteur prédicat (dans le cas présent. Voilà notre classe template queue synchronisée/sécurisée : #include <queue> template<typename DataType> class Squeue { public: void push(const DataType &data) { unique_lock<mutex> LG(Mutex). La méthode notify_all() est similaire à notify_one(). MyCV. C’est pour cela qu’il y a souvent un booléen qui dit s’il y a des données à consommer et qu’il est testé sous la protection d’un mutex avant de faire le wait.front(). Cette donnée est protégée par le mutex Mcv et les notifications se feront à travers la variable condition MyCV.

à savoir la fonction async. dans un souci de simplicité et parce que je n’ai pas bien saisi l’intérêt de faire plus compliqué. elle pourrait être complétée d’attente temporisée. cout << "push A"<<endl.get()<<endl. je suis arrivé à la conclusion qu’il ne valait mieux pas détruire le future généré par async tant qu’il n’était pas terminé.CODe(S) C++ 11 eT GCC Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo. j’attends le résultat Ajoute 6 Ajoute 6 Le résultat est 24 Par rapport à l’exemple précédent.10 décembre 2012 à 16:20 il est possible qu’un thread déjà réveillé traite une donnée fraîchement poussée avant que le thread qui était endormi ne se réveille pour la traiter. nous pencher seulement sur la version simplifiée de ce mécanisme.wait_for(chrono::duration<int. T1. cout<<"Le résultat est "<<Resultat. void Consommateur(int No) { char c.CalculMult. ils sont disponibles dans boost. d’en récupérer le résultat. un async est aussi capable de remonter dans le thread appelant une exception survenue dans le thread exécutant. launch::deferred permet de différer l’exécution de l’appel au moment du get() tout en l’exécutant dans la même thread. cout << No<<"=>"<<c<<endl.push(‘A’). D’ailleurs s’il ne faisait pas ce test. cout << "Ajoute "<<valeur<<endl.4).1. cout<<"J’ai fini. le transfert des données (plus de variable globale) et la problématique d’une production plus rapide que la consommation grâce à une bufferisation dans la queue. cout<<"Je fais un truc"<<endl. Peut-être qu’avec l’utilisation de la version complète des futures. ce qui lèverait une exception.push(‘B’). Peut être qu’une queue par thread y répondrait. De plus. j’aurais plutôt tendance à vous conseiller de spécifier le type de lancement que vous souhaitez. Si le paramètre est omis. cout << "push B"<<endl.pop(c). Ici. thread T2(Consommateur. while(--multiplicateur) { sleep(1). et dans mon cas. 96 G N U / L i n u x M a g azine France N°153 www. c o m . r+=valeur. sleep(1). bloquera l’appelant jusqu’à ce que le résultat soit prêt. sous peine d’arrêt du programme (le thread sous-jacent n’étant ni joint ni détaché provoque probablement un appel à terminate dans son destructeur). cela dépend de ce que l’on v eut faire. et plus tard. c’est la bibliothèque qui choisit. Le résultat du calcul sera obtenu par l’appel à get() qui. sleep(1).unsigned multiplicateur) { int r=valeur. Nous n’allons ici. j’avoue ne pas avoir vu trop d’intérêt à cette seconde option.4 Les futures Les futures et leurs comparses les promises sont un mécanisme de transfert de valeurs entre 2 (ou plus) tâches. Du coup. } return r. sleep(1). SQ2. Le premier paramètre de async permet de spécifier le mode d’exécution. } #include <future> int CalculMult(int valeur.6.2). } void DemoFuture1() { future<int> Resultat=async(launch::async. La fonction async va nous permettre de lancer une tâche avec des paramètres (ou pas). } void Producteur() { thread T1(Consommateur. l’utilisation de cette queue synchronisée traite la synchronisation. SQ2. il peut faire ceci : if(Resultat. mais l’absence des timed_ mutex dans l’implémentation actuelle nous manquera.fr) . il est possible de gérer ce point. } qui donne la sortie suivante : Je fais un truc Ajoute 6 J’ai fini. la tâche est simulée par une multiplication qui prend du temps. en plus de retourner le résultat. Cette queue synchronisée pourra être utilisée ainsi : Squeue<char> SQ2.milli>(0))!=future_ status::ready) 3. elle avait tendance à ne pas lancer de nouveau thread. SQ2. launch::async dans un thread séparé.gnulinuxm a g .1). Elle ne répond par contre pas à ce que faisait le notify_all. T2. Si le thread appelant veut savoir où en est l’autre tâche sans appel bloquant.detach(). il risquerait de faire un pop sur une queue vide. Un petit exemple : Suite à quelques tests. sleep(1).detach(). Cette implémentation est basique. j’attends le résultat"<<endl.

fr) .Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.10 décembre 2012 à 16:20 .

normale) : 0 -> 93 . 2). std::mt19937 engine. . -i  sgreater(a. normale. none_of qui permettent de tester un prédicat sur une collection.88 8 -> 94 . list<string> ls. Pensez bien à faire le seed si vous ne voulez pas vous retrouver toujours avec la même séquence de valeurs. ..end(). Ici. . std::normal_distribution<float> distributionN(5.3 Autres évolutions  Quelques autres évolutions de la bibliothèque standard : Dans les algorithmes : Apparition de all_of.7 en implémente une bonne partie. c o m . bool res=all_of(Valeurs.int> ResN.push_back(string("Chaine 1")). Références [GCCStatus] http://gcc.[](int x){return (x<300). nbr dist.wikipedia.fr) .10 décembre 2012 à 16:20 La bibliothèque mathématique a été enrichie de nombreuses nouveautés. binomiale. engine).203 6 -> 96 .z) : version rapide de x*y+z.2 Générateurs pseudo-aléatoires À présent. n<1000.org/jtc1/sc22/wg21/ docs/papers/2011/n3242.begin().144 4 -> 93 . engine. -i  sfinite(x) : teste si x est valeur finie/valide (voir aussi : isinf. alors que la distribution normale a plus d’occurrences autour de 5 que sur les extrêmes.165 7 -> 84 .boost. J’espère que tout cela vous aura donné envie de tester les apports de ce nouveau C++ quel que soit votre compilateur. any_of.begin().html qui donne (valeur. Ils se composent d’un moteur de génération de nombre avec de nombreux paramètres (on choisira probablement un des pré-configurés) et éventuellement d’un postprocessing permettant de faire correspondre les données à une loi statistique (uniforme. Dans les containers : emplace permet d’ajouter une valeur en la construisant en même temps.44 9 -> 94 .gnu.<."chaine 2").<>) . std::uniform_int_distribution<int> distributionU(0.40 2 -> 80 .CODe(S) C++ 11 eT GCC 3. html [Wikipedia] http://en.emplace(ls. map<int.com/~bs/C++0xFAQ.first]<<endl.2.pdf [CppReference] Site avec doc sur la lib std C++.org/onlinedocs/libstdc++/api. ++n) { ResU[generatorU()]++. Un troisième article viendra peut-être compléter ce qui manque (expressions régulières et quelques autres choses).40. On voit bien que la distribution uniforme a un nombre similaire d’occurrences pour chaque valeur. isnan) . .int> ResU.).hypot(a. ResN[generatorN()]++. Je vous en donne quelques-unes qui ont attiré mon attention : .30.20. Uniforme. 3. Voir [CppReference] pour plus de détails. auto generatorN = std::bind(distributionN.gnulinuxm a g .first<<" -> "<<setw(4)<<v.50}.open-std.2. 3.org [C++11Std] Une des dernières versions du draft du standard C++ 11 : http://www. 10).b) : calcul de l’hypoténuse sqrt(a²+b²) . un exemple avec une loi uniforme et une loi normale. } for(auto v : ResU) cout <<setw(2)<<v.att. avec la partie C++ 11 mise en évidence : http://en.cppreference.fma(x. plutôt que de la créer puis de la copier dans le container.17 1 -> 83 .round(x) : arrondi à l’entier le plus proche .gnu.y. il y a plusieurs générateurs pseudo-aléatoires disponibles.seed(static_cast<unsigned int>(std::time(0))).185 5 -> 108 . arguments au constructeur). nbr occurrence dist.2 Math 3. emplace(position.<=.research. Conclusion Nous voilà au bout de ce second article sur les nouveautés C++ 11.cbrt(x) : racine cubique . La plupart des nouveautés de c++ 11 ont été présentées car GCC 4. ls. engine).org/wiki/C%2B%2B0x [Boost] http://www.b)  : teste a>b sans lever d’exception si une des valeurs n’est pas valide (voir aussi équivalence de >=. ls. map<int.html [FAQBjarne] http://www2.93 3 -> 79 .com/ La doc de la libc++ de GCC : http://gcc. for(int n=0.}). vector<int> Valeurs={10.13 10 -> 96 7 98 G N U / L i n u x M a g azine France N°153 www.1 Améliorations Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.second<<" "<<setw(4)<<ResN[v.org/projects/cxx0x..Valeurs. auto generatorU = std::bind(distributionU.

ed-diamond.Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.fr) .10 décembre 2012 à 16:20 Ne QuitteZ plus Vos seRVeuRs Des YeuX ! Actuellement en kiosque ! LMHS 62 Disponible cHeZ VotRe maRcHanD De JouRnauX JusQu'au 26 octobRe 2012 et suR : www.com .

10 décembre 2012 à 16:20 .fr) .Ce document est la propriété exclusive de FELY ANDRIANANTOANDRO (a_djefe@yahoo.