En janvier, j'ai réalisé, avec trois autres étudiants (Mathieu Bivert, Calypso Petit et Sophie Valentin), un projet de fin de semestre à Polytech'Nice Sophia pendant 3 semaines. Nous avons pu choisir notre sujet parmi une liste prédéfinie. Nous avons décidé de réaliser un projet dont l'intitulé était "Créer un framework pour la mise en place des routeurs avec support pour notification de vitesse explicite (kernel space)". Le cahier des charges détaillé est ici. Ce sujet a été proposé par M. Dino Lopez qui nous a encadrés et aidés dans nos recherches.
Pour résumer, nous avons dû développer un module noyau destiné à effectuer des statistiques sur les paquets transitant par un routeur haut débit (> 100 Mbps) qui implémente un protocole de congestion nommé ERN (Explicit Rate Notification). Nous nous sommes concentrés sur le calcul de l'occupation de la file d'attente des paquets au sein du routeur. Le problème principal que nous avons rencontré est la localisation de cette file d'attente.
Nous sommes d'abord partis sur une mauvaise piste en essayant de créer un module Netfilter : en incrémentant une variable lors de l'entrée d'un paquet (dans le hook NF_IP_PRE_ROUTING) ou de son transfert pour routage (hook NF_IP_FORWARD) et en la décrémentant lors de la sortie d'un paquet (dans le hook NF_IP_POST_ROUTING). Cependant, les tests effectués nous ont montré qu'il n'y a aucune file d'attente entre ces hooks. En effet, même en limitant la vitesse maximale d'envoi (TX Rate) de l'interface de sortie du routeur, la valeur de la variable oscille entre 0 et 1.
Nous avons aussi essayé d'utiliser la fonction dev_get_stats() de linux/netdevice.h qui permet, entre autres, de connaître le nombre de paquets reçus et émis par une interface. Cependant, les statistiques fournies par cette fonction sont effectuées sur les paquets tous protocoles confondus : elle ne permet pas d'obtenir des statistiques uniquement sur les paquets TCP.
La file d'attente n'étant pas accessible au niveau de la couche réseau nous avons essayé de l'obtenir au niveau de la couche liaison. Pour cela, nous nous sommes résolus à créer un patch pour le noyau Linux, ce qui nous a demandé un énorme travail de recherche afin de comprendre au mieux la façon dont est implémentée la pile TCP/IP dans le noyau Linux (Linux Network Stack, plus d'informations ici et là).
Lorsqu'un paquet entre par une interface réseau, une interruption est levée et peut être traitée grâce à une fonction handler. Nous avons donc essayé d'incrémenter la variable correspondant au nombre de paquets présents dans la file d'attente dans ce handler en continuant de la décrémenter au niveau du hook NF_IP_POST_ROUTING de Netfilter, donc à la sortie d'un paquet. Nous avons cependant rapidement abandonné cette piste car, en plus d'être complexe à mettre en oeuvre, cela nous aurait fourni la taille de la file d'attente en entrée (ingress queue) or seule la taille de la file d'attente en sortie (egress queue) a un intérêt pour le protocole ERN.
Nous avons finalement réussi à déterminer que la file d'attente en sortie est présente entre les fonctions dev_queue_xmit() et dev_hard_start_xmit() du fichier net/core/dev.c (voir la partie 5.2 du rapport). Nous pouvons donc incrémenter notre variable dans dev_queue_xmit(), au moment où les paquets sont enfilés (enqueue) et la décrémenter dans dev_hard_start_xmit(), lorsque les paquets sont défilés pour être passés au driver de la carte réseau. Ces deux fonctions prennent un pointeur sur une struct sk_buff (qui représente un paquet) en paramètre. Il est possible d'extraire le type de protocole utilisé au niveau de la couche transport en passant cette structure en paramètre à la fonction skb_network_header() et en utilisant le champ protocol de la struct iphdr (le header IP) retournée par cette fonction. On peut donc modifier la variable uniquement si les paquets sont des paquets TCP (protocol == 6).
Vous trouverez ici une archive contenant le cahier des charges, le code du module netfilter, le patch noyau, le rapport, les diapos de la soutenance et un fichier ReadMe expliquant comment utiliser le code fourni.
L'année dernière, dans le cadre de mes études à Polytech'Nice Sophia, j'ai développé avec deux amis (Roman Mkrtchian et Guy Champollion) un jeu vidéo destiné aux déficients visuels. Cette année, nous aurons l'occasion d'aller présenter ce jeu au concours Jeux Accessibles (JVA) du 13 au 15 juin à Paris, après l'avoir amélioré. Une version du jeu (avec quelques bugs) est visible ici, sous forme de Java Web Start. Ci-dessous, une petite présentation du jeu extraite de la déclaration de candidature à ce concours.
À propos du projet
Nous avons développé « Songe » dans le langage Java et l’avons présenté deux fois à des enfants malvoyants :
- Une première fois à l’Institut d’Éducation Sensorielle « Clément Ader » à Nice pour obtenir des critiques de la part des enfants concernés.
- Une seconde fois lors des journées DeViNt, le 26 mai 2011 (un mois plus tard), pour présenter une version corrigée du jeu.
Le jeu est actuellement sous licence libre GPLv3. Notre souhait est qu’il rassemble une communauté de personnes issues de différents domaines (développeurs, graphistes, musiciens, enseignants, chercheurs…) autour de la problématique de l’accessibilité à des personnes malvoyantes ou non-voyantes.
Dans cette optique, nous avons lancé des appels à contribution sur le Site du Zéro et sur le site http://www.jeuxvideo.com/. Nous avons également créé un site et un forum. Cette communication a porté ses fruits car nous avons obtenu la participation d’un scénariste et d’un musicien. Nous aimerions obtenir l’aide d’un graphiste, de préférence familier avec les problématiques liées à la déficience visuelle, mais nous avons pour l’instant dû nous débrouiller par nos propres moyens.
Principe du jeu
Songe est un jeu d’aventure ludique. Le joueur peut choisir d’incarner différents personnages. En fonction du personnage sélectionné et des choix qu’il fera au cours du jeu, le scénario sera différent.
Au cours de son aventure, le joueur peut rencontrer d’autres personnages, bons ou mauvais, et interagir avec eux. Ces personnages lui poseront des questions et ses réponses orienteront le scénario dans différentes directions. Les personnages rencontrés pourront aussi aider le joueur à réussir sa quête.
Les personnages peuvent également poser des questions ou des devinettes au joueur. Celles-ci lui permettent de remporter des points afin d’établir plus tard un classement de tous les joueurs.
Dans l’univers, il y a aussi des ennemis que le joueur doit combattre. Ces ennemis peuvent blesser le joueur et lui faire perdre des points.
Songe est avant tout un jeu de plateformes : le joueur devra donc franchir des obstacles en sautant des murs, en poussant des caisses, etc.
Pourquoi « Songe » est-il adapté aux déficients visuels ?
Le jeu propose de commencer par un tutoriel pour prendre en main la navigation dans le monde de « Songe ». Le joueur est guidé par une voix qui lui explique chaque étape en détails.
Les touches utilisées sont limitées au strict minimum et correspondent à l’utilisation qui est attendue d’elles : la touche droite permet d’avancer (la situation du personnage étant expliquée au début du jeu), la touche « échap » permet de quitter, etc.
Nous avons combiné l’utilisation d’une bibliothèque de synthèse vocale à des voix enregistrées par nous-mêmes afin de guider au mieux le joueur. S’il se trouve en difficulté, le joueur a toujours la possibilité d’obtenir une aide.
L’utilisation de la bibliothèque Java Slick qui permet de faire des jeux 2D, et de la bibliothèque Phys2D qui permet de simuler la physique en 2D (gravité, collisions), alliée à l’utilisation de la bibliothèque OpenAL pour la gestion du son permet par exemple :
- De faire varier le volume ou la hauteur d’un son lorsque le joueur se rapproche d’un obstacle ou d’un personnage : il est possible de positionner la source du son de façon à entendre les bruits comme si l’on se trouvait dans un environnement 3D ;
- De jouer un son lorsqu’un joueur heurte un obstacle (un mur par exemple) ;
- De jouer des musiques adaptées au contexte : nous avons par exemple décidé d’utiliser des musiques récurrentes pour différencier le menu, le jeu principal, les questions de scénario, les devinettes et les mini-jeux.
Les graphismes sont adaptés : couleurs vives et contrastés, grande taille.
Il se passe plein de choses à proximité de Sophia Antipolis et ce serait dommage d'oublier. Ce post est là pour garder une trace des bons moments passés dans la région et me permettre de déprimer dans quelques années en relisant ces lignes :).
Le début de l'année a été bien rempli, en commençant pas la semaine au ski organisée par le BDE Polyt'Xtase qui, comme l'année dernière, a été l'occasion de faire du sport dans la journée et la fête le soir. Malgré quelques légers soucis d'organisation, la semaine s'est déroulée sans incident et nous avons pu nous assurer qu'il est possible de loger treize personnes dans une chambre prévue pour six :p. Parmi les choses que je retiendrai de cette semaine : le Big Air Bag, la descente en Yooner, le barbecue sur les pistes, les parties de Munchkin interminables, et un certain nombre de choses qu'il vaut mieux tenir secrètes :D.
Trois semaines plus tard, les 11 et 12 février, il y a eu Hisse & Glisse : une journée de ski dans la station d'Auron suivie d'une journée de bateau habitable à Antibes avec des membres du Club Nautique (CNA). Un évènement qui permet de profiter du plus gros atout de la région : la proximité de la mer et de la montagne. Le froid du samedi ne nous a pas empêché d'apprécier la neige. Le dimanche, l'équipage de choc que nous avions rassemblé pour la régate a été à la hauteur : des départs difficiles ne nous ont pas empêchés de finir 5ème malgré le handicap imposé à notre bateau (d'une catégorie différente de la plupart des autres).
Vendredi dernier, j'ai eu la chance de pouvoir participer à une partie de Donjons & Dragons à Nice. J'ai joué un elfe rôdeur muni d'un arc long capable de tirer deux flèches d'un seul coup, en compagnie d'un nain, d'une voleuse, d'un mage et d'un personnage peu recommandable mi-homme mi-dragon. Notre mission était de débarrasser une zone de la vermine gobeline qui l'infestait et de ramener comme preuve la tête d'une de ces immondes créatures au seigneur pour le compte duquel nous nous étions alliés. En passant dans Nice, nous avons pu avoir un aperçu du carnaval qui dure 15 jours.
Le 18 février, je suis allé au Festival International des Jeux de Cannes où j'ai pu voir et jouer à des jeux de société qui ne sont pas encore sortis. Il y avait aussi des concours d'échecs, et de divers jeux de cartes. Les jeux vidéos étaient aussi de la partie ainsi que le Laser Quest de Cannes, et des jeux tels que Stepmania. L'univers de Star Wars était lui-aussi très présent.
Le 19 février, bowling à Antibes qui m'a permis de confirmer que ce n'est pas l'activité dans laquelle je suis le plus doué puisque j'ai fini dernier à toutes les parties :). Après un repas au restaurant du bowling qui fait des pizzas d'une taille impressionnante, j'ai pu me rattraper un peu au billard...
Aujourd'hui, j'avais besoin de récupérer une liste de cocktails. J'en ai trouvé une assez jolie sur ce site mais avec un cocktail par page. Du coup, comme j'avais du temps à perdre (:p), j'ai décidé d'écrire un petit script pour les récupérer sous forme d'images de même taille. Comme je pense que c'est un script intéressant qui utilise 3 modules différents (mechanize pour récupérer les liens des différentes pages, webbrowser pour les ouvrir dans un navigateur et le module ImageGrab de la Python Imaging Library pour faire les captures d'écran) de manière plutôt compacte, je le publie. Je suis sûr qu'il y a des méthodes plus simples et plus propres de faire ça et je serais intéressé de les connaître. J'ai seulement pris la première solution qui m'est venue à l'esprit.
# -*- coding:utf-8 -*- from PIL import ImageGrab import time from mechanize import mechanize import webbrowser def grab_screen(filename): image = ImageGrab.grab((20,210,600,500)) image.save(filename + '.png') def get_cocktails(): BASE = 'http://www.iba-world.com' LIKE = '/index.php?option=com_content&id=' url = 'http://www.iba-world.com/index.php?option=com_content&view=article&id=88&Itemid=532#' browser = mechanize.Browser() page = browser.open(url) #print page.read() print dir(browser) for l in browser.links(): if l.url.startswith(LIKE): page_url = BASE + l.url num = l.url[len(LIKE):] num = num[:num.index('&')] print num, page_url webbrowser.open_new_tab(page_url) time.sleep(5) grab_screen(num) if __name__ == '__main__': get_cocktails()
Pour l'utiliser, il faut adapter les coordonnées de la zone à capturer en fonction de votre navigateur.
Le code est ici et les images récupérées sont là.
ifttt, pour "If This Then That" (littéralement : "Si ceci, alors cela") est un site qui permet de lier différents services web entre eux.
Par exemple, il permet de dire, "Si je mets à jour ma photo de profile sur Facebook, alors mets à jour ma photo de profil sur Twitter".
Le This est appelé "Trigger" (déclencheur) tandis que le That est appelé "Action". Il est possible de créer des "Recipes" (recettes) afin de partager des liens créés avec les autres utilisateurs du site.
D'après ce que j'ai lu sur leur compte Twitter, ils comptent mettre une API à disposition des développeurs pour leur permettre de créer leurs propres triggers et actions dans quelques temps.
J'en parle ici car c'est une idée que j'avais eu à moins grande échelle et qui, à mon avis, peut permettre de gagner énormément de temps lors du développement d'applications utilisant ces services. Je vois ce système comme un moyen de créer des plug-in utilisables de manière transparente pour plusieurs services semblables et de décharger le développeur de tout ce qui concerne la connexion aux services et des différences entre leurs API respectives.
| << | < | 0 | 1 | 2 | > | >> |