Réaliser un lecteur de badge avec rasberry pi (Partie 1)

raspberry-ban

Introduction

Un article en deux parties.Une première cette semaine pour vous expliquer comment installer la librairie sur votre raspberry pi. Le prochain article décrira comment réaliser un programme en C pour lire un badge de type badge d’entrée des immeubles.

La librairie libnfc

La librairie libnfc est une librairie dédiée à la communication en NFC. Cette librairie est publieé sous licence LGPL (libre de droit pour les applications libres ou commerciales).

Celle-ci fonctionne avec un hardware spécifique, on peut trouver la liste sur le wiki de libnfc.

Pour ma part, j’ai un dongle usb équipé d’un PN533 (fabriqué par NXP). La photo est ci dessous :

dongle_pn533.jpg

Télécharger la librairie

Les liens du wiki officiel sont brisés mais une petite recherche google nous permet de retrouver la release. Pour les projets sur le Pi, privilégiez les versions packagées aux versions développeurs.

wget https://libnfc.googlecode.com/files/libnfc-1.7.0-rc3.tar.gz
tar -xvzf libnfc-1.7.0-rc3.tar.gz 
cd libnfc-1.7.0-rc3/

Configuration

Si vous souhaitez configurer la librairie pour un pn532 en UART comme ceux de chez Adafruit il va falloir commencer par libérer l’UART du pi comme indiqué dans cette article :

Puis une fois l’UART libéré, il va falloir copier le fichier de configuration comme suit :

sudo mkdir -p /etc/nfc/devices.d
sudo cp contrib/libnfc/pn532_uart_on_rpi.conf.sample /etc/nfc/devices.d/pn532_uart_on_rpi.conf

Editez ensuite le fichier suivant :

sudo nano /etc/nfc/devices.d/pn532_uart_on_rpi.conf

Et modifiez la ligne suivante à la fin du fichier

allow_intrusive_scan = true

Compilation

Enfin nous pouvons maintenant compiler les sources :

./configure --with-drivers=pn532_uart --sysconfdir=/etc --prefix=/usr
autoreconf -vis
make clean
sudo make install

Et pour tester :

cd utils/
sudo ./nfc-scan-devices

Et vous devriez voir apparaître quelque chose comme ça :

1 NFC device(s) found:
- NXP / PN533:
    pn53x_usb:002:003

Conclusion

En attendant l’article de la semaine prochaine (il est déjà écrit, il ne reste qu’à le mettre en page), vous pouvez parcourir le dossier exemple/. Vous y trouverez de quoi vous amusez un peu avec diverses badges du quotidien.

Google MAP avec un fragment dynamique

android
Pour avoir Google Map dans son application, 4 étapes sont nécessaires :

  • Obtenir une clé pour utiliser l’API
  • Récupérer le Google Map service
  • Ajouter les informations nécessaires dans Google MAP
  • Implémenter le fragment dans l’application

Obtenir une clé pour utiliser l’API

Tout d’abord, il faut se connecter sur le site de Google API Console . Puis dans le menu gauche, il faut cliquer sur API Access et cliquer sur « Create New Android Key… ».

Nous avons besoin de récupérer l’empreinte de notre clé grâce au SHA1, pour cela il faut se placer dans le répertoire cd ~/.android/. C’est ici que se trouve votre clé debug.keystore.

keytool -list -v -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android

Grâce a cette commande, on peut récupérer une empreinte du certificat. En l’occurrence, la ligne qui nous intéresse est celle avec clé SHA1.

Copier cette ligne sur le site de google API et ajouter à la fin un ; + le nom du package.

Cela va générer une API clé qu’il faudra utiliser dans votre manifest.

Note: : Pour définir le nom du package, il faut regarder dans votre manifest le package définit. En ce qui me concerne, j’ai choisi : fr.oversimple.applicationdemo

Récupérer le Google Map service

Afin d’utiliser Google Map, il faut télécharger la librairie : Google Play services via le Android SDK Manager
Google Play Services

Une fois le téléchargement effectué il faut l’ajouter comme librairie dans l’environnement de développement. Le répertoire se trouve dans extra/google/google_play_services . Pour Eclipse, il faut le déclarer comme une librairie (Clic droit sur le projet -> Properties -> Android -> Is Library) Puis pour le projet, au lieu de le déclarer comme librairie, il faut l’ajouter comme librairie.

En ce qui concerne Android studio (ou Intellij), il faut l’importer comme module.

Ajouter les informations nécessaires dans Google MAP

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="fr.oversimple.applicationdemo"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />
 
    <permission
            android:name="fr.oversimple.applicationdemo.permission.MAPS_RECEIVE"
            android:protectionLevel="signature" />
 
    <uses-feature
            android:glEsVersion="0x00020000"
            android:required="true"/>
 
    <!-- Google map -->
    <uses-permission android:name="fr.oversimple.applicationdemo.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
 
    <uses-permission android:name="android.permission.INTERNET" />
 
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.OrangeNoActionBar" >
        <activity android:name=".activities.MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <!-- https://code.google.com/apis/console/ -->
        <meta-data
                android:name="com.google.android.gms.version"
                android:value="@integer/google_play_services_version" />
        <meta-data
                android:name="com.google.android.maps.v2.API_KEY"
                android:value="Votre API KEY" />
    </application>
 
</manifest>

Implémenter le fragment dans l’application

Le XML correspondant map_main_activity.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <com.google.android.gms.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
</RelativeLayout>

Le code correspondant pour la map :

public class MapsFragment extends Fragment {
 
    private MapView map;
 
    public MapsFragment() {
    }
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.map_main_activity, container, false);
 
        if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity().getApplicationContext()) == ConnectionResult.SUCCESS) {
 
            //Initialze mapview
            MapsInitializer.initialize(getActivity());
 
            map = (MapView) view.findViewById(R.id.mapView);
            map.onCreate(savedInstanceState);
 
            GoogleMap gMap = map.getMap();
            gMap.addMarker(new MarkerOptions().title("title").snippet("description").position(new LatLng(49.5594950, -1.8414880))).showInfoWindow();
 
        } else {
            Toast.makeText(getActivity(), "Please install google play services", Toast.LENGTH_LONG).show();
        }
        return view;
    }
 
    @Override
    public void onResume() {
        super.onResume();
        map.onResume();
    }
 
    @Override
    public void onPause() {
        super.onPause();
        map.onPause();
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
        map.onDestroy();
    }
 
    @Override
    public void onLowMemory() {
        super.onLowMemory();
        map.onLowMemory();
    }
}

Pour appeler le fragment, l’id content frame correspond à mon cœur d’application. En l’occurrence, je l’ai utilisé avec le navigation drawer d’Android afin d’avoir un menu sur la gauche.

mapFragment = new MapsFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, mapFragment).commit();

Ce fragment de Google Map peut être remplacé facilement par un autre fragment.

It’s oversimple, isn’t it?

Un peu de Volley sous Android!

android
Pour ceux qui ne connaisse pas Volley, c’est LE Framekwork de communication réseau.

Pour commencer, voici une trés bonne vidéo de présentation réalisée par Ficus Kirkpatrick .

L’article ci-dessous permet de faire une introduction à l’utilisation Volley.

Si vous n’avez pas regardé la vidéo, vous allez me dire, il existe déjà plusieurs framework réseau sous Android, pourquoi utiliser un autre framework?

A ma connaissance, il existe 2 possibilités de framework sous Android, afin de faire du HTTP. Le premier est Apache HTTP Client, c’est celui-ci que j’utilisais avant de découvrir Volley. Mais comme vous le savez sans doute, Apache HTTP Client possède des bugs et celui-ci n’est pas forcement maintenu par l’équipe Android.
La seconde API est HttpURLConnection que je n’ai jamais utilisé mais celle-ci possède des bugs.

Pour chacun de ces 2 frameworks, il faut rédefinir des Thread afin de ne pas rester dans le main thread. Cela impliquait l’utilisation des Asynctask.

Volley permet de s’abstenir de toute cette couche. C’est facile, puissant et rapide! De plus, celui-ci possède un cache mémoire ou disque.

C’est bien beau, mais comment ça fonctionne?

Son fonctionnement est aussi simple, il possède une queue que l’on doit initialiser UNE fois  (cette initialisation est assez coûteuse en performance). Ensuite, on ajoute dans cette queue les REQUETES que l’on doit effectuer. Le reste est géré par Volley.

Et comment on l’utilise?

Tout d’abord, il faut penser à mettre le user permission Internet dans le manifest d’Android :

<uses-permission android:name="android.permission.INTERNET" />

Puis, il faut récupérer le JAR ou le projet:

git clone https://android.googlesource.com/platform/frameworks/volley
cd volley
android list targets #Choisir l'ID pour la compilitation du JAR
android update project -p . --target ID_DE_TARGETS
ant jar

Une fois le JAR généré, il faut le placer dans le répertoire libs de votre projet. (Penser à l’ajouter au classpath en faisant clic droit add as library)

pour la création de la QUEUE,  je considère que l’on en a besoin partout dans notre Application donc on l’initialise qu’une fois. Cette initialisation est faite dans le contexte de l’application (extends Application) :

public class IntroApplication extends Application {
    private RequestQueue volleyRequestQueue;
 
    @Override
    public void onCreate() {
        super.onCreate();
        volleyRequestQueue = Volley.newRequestQueue(this);
        volleyRequestQueue.start();
    }
 
    @Override
    public void onTerminate() {
        volleyRequestQueue.stop();
        super.onTerminate();
    }
 
    public RequestQueue getVolleyRequestQueue() {
        return volleyRequestQueue;
    }
}

Vu que l’on extends Application, il faut penser à l’ajouter dans le manifest dans l’ application android:name= ».IntroApplication ».

Une fois cette initialisation faite, c’est bon, on peut travailler avec Volley. Il existe plusieurs type de Request dans Volley, String, JSONObject, JSONArray etc… (on peut bien sûr extends Request)

Un exemple avec String:

        StringRequest stringRequest = new StringRequest("url",new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Log.d("MainActivity","On doit traiter ici la reponse : " + s);
            }
        },new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Log.d("MainActivity","On doit gérer ici l'erreur");
            }
        });

En ce qui concerne les deux listener(la réponse et l’erreur), il faut implémenter les interfaces : Response.Listener et Response.ErrorListener.
Une fois que notre stringRequest est géré, il faut l’ajouter dans la Queue.

IntroApplication introApplication = (IntroApplication) getApplication();
mVolleyRequestQueue = introApplication.getVolleyRequestQueue();
mVolleyRequestQueue.add(stringRequest);

Cette exemple est valable pour String mais il fonctionne tout aussi bien avec les JsonObjectRequest, JsonArrayRequest. Il faut aussi remplacer les types des listener par JSONObject ou bien JSONArray.

En ce qui concerne les images au lieu d’utiliser les ImageView, nous allons utiliser les Images pour Volley, c’est à dire NetworkImageView (com.android.volley.toolbox.NetworkImageView). Cette modification doit être effectuée au niveau du XML et ainsi au niveau des CAST pour utiliser un objet de type NetworkImageView au lieu d’un ImageView.
Il faut également ajouter dans le contexte de l’application, le chargement des images.
mVolleyImageLoader = new ImageLoader(mVolleyRequestQueue, new BitmapLruCache());
Avant le start de volley request start de préférence.

Le XML:

    <com.android.volley.toolbox.NetworkImageView
            android:id="@+id/monImage"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher"/>

BitmapLruCache :

public class BitmapLruCache extends LruCache&lt;String, Bitmap&gt; implements ImageLoader.ImageCache {
 
    /**
     * @param maxSize for caches that do not override {@link #sizeOf}, this is
     *                the maximum number of entries in the cache. For all other caches,
     *                this is the maximum sum of the sizes of the entries in this cache.
     */
    public BitmapLruCache(int maxSize) {
        super(maxSize);
    }
 
    public BitmapLruCache() {
        this(getDefaultLruCacheSize());
    }
 
    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
        return cacheSize;
    }
 
    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }
 
    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }
 
    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}

Un exemple d’utilisation, super simple:

NetworkImageView networkImageView = (NetworkImageView) findViewById(R.id.monImage);
networkImageView.setImageUrl("lienDeLimage",mVolleyImageLoader);

Et si on désire passer des paramètres? Sans problème, il faut juste extends Request et redéfinir la méthode getParams (Hasmap de String/String).
Un exemple est présent dans l’archive ci-jointe : JSONParams

HashMap<String,String> map = new HashMap<String,String>();
map.put("UnParametre","laValeurDuParametre");
JSONParams jsonParams = new JSONParams("url",map,this,this);
mVolleyRequestQueue.add(jsonParams);

Et si on souhaite annuler une requête dans la QUEUE?
Super simple, il faut sur chaque Request mettre un setTag afin de pouvoir les identifier. Une fois identifiée, il faudra juste annuler celle que l’on désire:
Par exemple, si je reprends l’exemple de stringRequest avant de l’ajouter dans la queue, j’effectue un setTag

stringRequest.setTag("identifiantDeMaStringRequest");
mVolleyRequestQueue.add(stringRequest);
mVolleyRequestQueue.cancelAll("identifiantDeMaStringRequest");

Vous pouvez télécharger l’archive ici.

It’s Oversimple, isn’t it?

Utiliser le port série du Raspberry Pi

raspberry-ban

Le port série est un standard qui est très utilisé dans le monde de l’industrie. De nombreux informaticiens utilisent leur raspberry via le port ethernet pour ensuite y connecter une antenne wifi. Dans cet article,  nous verrons comment utiliser ce port série avec une librairie POSIX afin de dialoguer au travers d’un programme C.

Désactiver le terminal sur le port série du raspberry pi

Nous souhaitons maintenant utiliser le port série du raspberry non plus pour ouvrir un terminal dessus mais pour émettre et recevoir des trames.
Nous allons pour cela configurer le linux embarqué pour qu’il ne redirige plus vers un terminal mais vers le port série.
Avant de faire cela, il vous faut un autre moyen de vous connecter à votre raspberry pi. Vous pouvez soit utiliser un câble ethernet et ouvrir une session ssh ou bien configurer un hotspot wifi comme décrit dans cet article.
Cependant, si vous disposez d’un clavier et d’un écran hdmi, ceci peut tout aussi bien faire l’affaire.

Pour désactiver le bind du terminal sur le port série il vous faut éditer deux fichiers.
Le premier et le plus important est : /etc/inittab

Ce fichier contient la commande qui active le bind du terminal (type vt100) sur le port série à une vitesse de 115200 baud.
Allez à la fin du fichier et commentez la ligne suivante en ajoutant un ‘#’ devant :

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

La simple modification de ce fichier peut être suffisante. Cependant, le raspberry pi redirige automatiquement les informations du boot sur le port série. Si vous avez un système branché sur le port série lors de son démarrage,  il est possible que vous ne souhaitiez pas qu’il puisse recevoir les informations du boot.

Pour cela, il vous faut également éditer le fichier boot/cmdline.txt

Le fichier doit ressembler à ceci :

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Retirez toutes les références à ttyAMA0 qui est le nom du port série. Votre fichier doit maintenant ressembler à ceci :

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Pour appliquer les changements réalisés il vous est nécessaire de rebooter le raspberry pi. Vous pouvez vérifier le bon fonctionnement en utilisant le programme minicom. Par exemple,  vous pourriez utiliser votre raspberry pi pour ouvrir une session sur un autre raspberry pi via le port série.
Comment ça mes idées sont parfois tordues?

Programmer en C

Il existe de nombreuses choses déjà toutes faites pour contrôler les ports séries. Cependant,  rien ne vaut une bonne librairie POSIX qui a l’avantage d’être compatible avec tous les systèmes linux embarqués ou non.

Nous utilisons la librairie POSIX pour communiquer avec le Raspberry Pi. Celle ci est donc compatible sur l’ensemble des systèmes embarqués Linux.

Voici un exemple permettant de renvoyer le message reçu :

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
 
typedef int serialPort;
serialPort SerialLib_open(const char * portPath);
 
int main(int argc, char **argv) {
   serialPort p = SerialLib_open("/dev/ttyAMA0"); /* The serial port of the raspberry pi */
   char buffer[16];
 
   read(p, buffer ,15);
   write(p, buffer ,15);
   buffer[15] = "";
 
   printf("Message recu: %s n",buffer);
   return EXIT_SUCCESS;
}
 
/**
 * Open the specified serial port
 * and return the associated file descriptor
 * 
 */
serialPort SerialLib_open(const char * serialPortPath) {
   int fd; /* File descriptor for the port */
 
   fd = open(serialPortPath, O_RDWR | O_NOCTTY);
   if (fd == -1) {
      /* Error opening the serial port */
      printf("Could not open the serial port : %s - ", serialPortPath);
   }else {
      fcntl(fd, F_SETFL, 0);
   }
   return (serialPort)fd;
}

Conclusion

Vous pouvez tester le code précédent avec un second rapberry pi par exemple. Ceci peut s’avérer très utile lors de l’utilisation de devices externes. Nous l’avons par exemple utilisé pour connecter notre rapsberry pi à un microcontrôleur 8bits.

It’s oversimple isn’t it?

Installation d’un Web Services sous Eclipse

Cet article va traiter uniquement de l’installation du Web Service. Un prochain article présentera le fonctionnement entre un Android et le Web Service.

Vous devez déjà avoir installé un serveur Tomcat. (J’ai écrit un article ici)

On utilisera comme web service le Apache Axis2.

La définition de Wikipédia :

Apache Axis2 is a core engine for Web services. It is a complete re-design and re-write of the widely used Apache Axis SOAP stack. Implementations of Axis2 are available in Java and C.

Axis2 not only provides the capability to add Web services interfaces to Web applications, but can also function as a standalone server application.

On va commencer par le télécharger ici

La dernière version pour moi est actuellement : 1.6.2 Release

On décompresse l’archive dans le répertoire /opt/ (et on met les droits utilisateurs)

$ unzip axis2-1.6.2-bin.zip
$ chown -R pierre:pierre axis2-1.6.2

Une fois l’archive décompressée, on va dans Eclipse :
Window > Preferences > Web Services > Axis2 Preferences.

On sélectionne le chemin où on a extrait notre archive : /opt/axis2-1.6.2
Et si tout va bien on a : Axis2 runtime loaded successfully

Après on va dans Server and Runtime (toujours dans Window > Preferences > Web Services).

On choisit notre serveur Tomcat avec la version désirée et on le met en Web Service : Apache Axis2

L’installation du Web Service est fonctionnel.

Création d’un projet pour tester notre Web Service.

File > New > Dynamic Web Project

On sélectionne la version du module à 2.5 Car la version 3.0 n’est pas compatible avec Axis2.

On va modifier notre configuration afin d’ajouter Axis2 Web Services (Core et Extensions).

Ci-dessous la configuration a réaliser :
ConfigurationAxis2WS

Si vous désirez pour les prochaines fois vous pouvez créer une configuration dédiée en cliquant sur « Save as ».

On peut cliquer sur terminer.

Je vais créer une classe Login qui aura une méthode login et prendra deux paramètres (un nom et mot de passe).

Voici le code :

public class Login {
 
	public String login(String username, String password){
		System.out.println("Appel WS : " + username +" "+ password);
		if(username.equals("oversimple") &amp;&amp; password.equals("oversimple")){
			return "Mot de passe OK";
		}
		return "Mot de passe KO";
	}
}

Une fois la classe créée, clic droit dessus > Web Services > Create Web Service :
On laisse la configuration par défaut c’est à dire :
Service implementation : Login et on laisse à l’état démarré
Client type : Java Proxy et on laisse à aucun client.

On termine. Il faut patienter environ une minute.

Notre serveur est démarré : On peut allé sur la page suivante : http://localhost:8080/Oversimple/ et cliquer sur « Services »
On peut voir notre service :
Axis2

On a un web service qui fonctionne, dans un prochain article je vais vous présenter le fonctionnement avec Android (ksoap2).

Wake me up !

raspberry-ban

Aujourd’hui, ajout de la fonctionnalité réveil matin à notre Raspberry pi. Pour réaliser tout ça, nous allons greffer à notre raspberry pi : un bouton champignon.

Réalisation du bouton champignon

Pour éteindre notre réveil, nous allons hacker la petite veilleuse pour enfant.

Eclairage-technique-Inspire-GELA-Veilleuse-LED-Vert-11270-444

Vous pouvez la trouvez en cliquant ici.

On commence par démonter la lampe et désolidariser la led de l’interrupteur poussoir. Nous voulons faire ressortir la masse, une entrée pour allumer la led et une sortie pour avoir l’état de l’interrupteur (ouvert ou fermé).

IMG_6027

IMG_6047

IMG_6049

Enfin pour le haut parleur, n’importe lequel peut faire l’affaire. En prévoir un qui soit tout de même auto alimenté, ou bien utiliser comme nous un ampli audio 5V que l’on a relié à l’alimentation du Raspberry pi.
Attention dans le cas où l’ampli audio est alimenté via le Raspberry pi, ne pas oublier de prendre une alimentation plus forte qu’un simple chargeur de téléphone.
Screenshot from 2013-07-24 20:02:20

Ce qui nous donne :

IMG_20130726_194125

Nous codons la détection en C. Pour cela nous réutilisons la même librairie que pour l’alarme de maison : Alarme de maison avec un raspberry pi
La fonction suivante nous permet d’allumer ou d’éteindre la led de notre lampe :

void detectInput(void) {
   uint8_t value;
   uint8_t refValue;
 
   refValue = bcm2835_gpio_lev(PIN_SENSOR);
 
   do {
      // lecture du niveau d'entre©e
      value = bcm2835_gpio_lev(PIN_SENSOR);
      delay(400);
   } while(refValue == value);
 
   bcm2835_gpio_write(PIN_ACTOR, HIGH);
}

Enfin pour ce qui est de jouer de la musique nous allons utiliser le programme aplay qui est présent par défaut.
Le fichier source est disponible en annexe.

Il nous suffit alors de lancer le programme à l’aide d’une tâche cron à l’heure du réveil.

Sources et Bibliographie

It’s Oversimple, isn’t it?

Attaque sur carte sans contact

Un petit retour sur le workshop de la Nuit du Hack.

La démonstration principale de ce workshop était une attaque sur les cartes sans contact. Celles-ci proposent de payer en sans contact à une distance d’une dizaine de centimètre du lecteur. Ce paiement ne nécessite pas de saisir son code PIN. Il est cependant limité à des transactions d’un montant maximal de 20€ et à 4 transactions consécutives. Après il faut passer en mode contact pour réaliser une transaction.

Description de l’attaque

L’idée est de réaliser un proxy permettant de faire une transaction à distance.

explain

Le téléphone est un téléphone NFC qui permet de réaliser des transactions en sans contact. Celui-ci est relié par un réseau, par exemple un réseau internet, à un lecteur de carte sans contact. Ce lecteur dans le schéma est représenté à droite à coté du personnage en costume. Il est relié à un ordinateur afin de pouvoir être accessible depuis un réseau.

Nous aurions aussi pu utiliser un autre téléphone NFC à la place du couple PC – lecteur sans contact. Cependant je n’avais à ma disposition qu’un seul téléphone NFC.

L’attaque consiste à réaliser un proxy passif afin de réaliser un paiement à l’aide d’une carte qui ne se trouve pas à proximité du lecteur. Puisque la technologie est sans contact, cela peut être réalisé à l’insu de la cible.

Réalisation

Afin de réaliser cette attaque, un téléphone Nexus S a été utilisé. Ce téléphone possède une puce NFC et permet l’installation de l’application simply tap avec une cyanogen mod 9.1. Cette application permet d’avoir accès à l’antenne NFC du téléphone depuis une application android. Le but premier est de réaliser des services de paiement en cloud.

Dans notre cas, au lieu d’interroger un cloud, nous interrogeons un lecteur distant afin de dialoguer directement avec une carte sans contact.

Démonstration :


Attaque par proxy par oversimple

Comment s’en protéger

Pour s’en protéger, c’est assez simple il suffit de mettre sa carte dans un étui en fer. Il existe des portes feuilles blindés qui font très bien l’affaire.

Bibliographie

SimplyTapp NFC Payment System Debuts with CyanogenMod 9.1
emulating pki smart card with cm9.1
NFC Proxy