Projets:Can2RNET

De wikilab

MHK: control wheelchair hack based on the can2RNET project

Description du projet

  • Ce projet est une partie du projet global "Magic Joystick"
  • Ce projet a été débuté lors du Fabrikarium chez ArianeGroup (Les Mureaux) du 16 au 18 octobre 2019 avec la collaboration des salariés d'ArianeGroup
  • La réalisation de ce projet a pû être réalisé grâce aux créateurs de "Can2RNET" et de leurs différentes documentations.

TODO move this below to official MHK wiki/github ?

Cahier des charges

Démontrer la faisabilité de prise de controle à distance d'un fauteuil roulant à l'aide d'un appareil externe tel qu'un joystick. - Porteur de projet : Jonathan Menir

- Contributeurs: Florian, Régis, Jonathan, Laetitia, Luc, André, Federico, Julien, Nicolas et Stéphane

- Coordinateur du projet : Stéphane

- Responsable de documentation Margaux

Equipe (Porteur de projet et contributeurs)

  • Porteur de projet : Janathan Menir
  • Contributeurs: Florian, Régis, Jonathan, Laetitia, Luc, André, Federico, Julien, Nicolas et Stéphane
  • Coordinateur du projet : Stéphane
  • Responsable de documentation Margaux

Matériels nécessaires

- Raspberry Pi 3 (Model B+) avec Carte SD 2GB

- Carte PiCan2 (non testé)

- R-Net cable

- Manette Xbox360

Coût

RaspberryPI 3 : https://www.ldlc.com/fiche/PB00246555.html

Carte Pican2 : https://www.elektor.fr/pican-2-can-bus-board-for-raspberry-pi

Câble r-net : Exemple : https://www.warmex.net/r-net-stuurkastkabel-2-5m.html

Ressources

Présentation du protocole R-NET sur le bus CAN
File:canPPT.pdf
File:ChipHackingV07B.pdf

Documentation technique
File:RNETdictionary_catagorized.txt
File:RNETdictionary_V2.txt
File:R-net-Electronics-Technical-Manual-v6.pdf

Autre exemple de hack de fauteuil electrique
File:DEFCON24_chairhacking.pdf

Processus de réalisation

Schema jsmerror.png

Installer la raspberry

1. Mettre en place la raspberry : https://www.raspberrypi-france.fr/guide/

2. (Non testé) Installer PiCan2 sur la rasppi3 https://www.elektormagazine.fr/news/avec-pican2-le-raspberry-pi-prend-le-bus-can

TODO: ajouter photo raspberry + pican2

D'après le projet can2rnet, il faudrait ajouter à /boot/config.txt

dtparam=spi=on 
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25         
dtoverlay=spi-bcm2835

Puis ajouter les lignes suivantes au fichier /etc/network/interfaces. A noter que le bitrate est fixé à 1250000.

allow-hotplug can0
iface can0 can static
       bitrate 125000
       up /sbin/ip link set $IFACE down
       up /sbin/ip link set $IFACE up

Puis charger les modules noyaux sous : /etc/modules

mcp251x
can_dev


Ensuite, redémarrer la Raspberry, puis vérifier que l'interface "can0" est bien montée. Utiliser la commande `ifconfig` ou 'ip a' selon la distribution linux

Mise en place de la dérivation R-Net entre le fauteuil et la raspberry

1. Couper et dénuder le cable R-Net. 2. Connecter le cable à la pican2 selon le code couleur suivant: ``` white is can high blue is can low black is gnd red is +vin ``` TODO: ajouter photo du cables (4 pins) TODO: ajouter photo de la dérivation de Frédérico TODO: ajouter photo/schéma du système

Installer l'utilitaire CAN-UTILS (non testé)

$ git clone https://github.com/linux-can/can-utils

ou

$ sudo apt-get install can-utils

Superviser & Controler les trames RNET-over-CAN (partiellement testé)

Espionner les trames CAN pendant vos essais de la mise au point, c'est à dire : - mise sous tension la JSM - commandes joystick, ... - activation des voyants, des bips, ...


Avant de passer à la suite, prendre le temps de dérouler le scénario suivant et de comprendre la stratégie : - doc/canPPT.pdf - doc/RNETdictionary_*.txt

Etapes à suivre :

1. Identifier la trame du heartbeat périodique de la JSM  
- "03c30F0F#8787878787878787" @10Hz
2. Identifier le contrôle XY du joystick (JSM) au power module (PM)  
- "02000000#XxYy" @100Hz (device JSM n°0) 
- "02001000#XxYy" @100Hz (device JSM n°1) 
- ...
3. Plusieurs modes possibles :
* [Mode JSMError] Mettre la JSM en mode erreur. Envoyer en moins d'une milliseconde ces trames:
- "0c000000#"
- "0c000000#"
- "0c000000#"
* On ne sait pas à quoi cette trame correspond mais elle permet de mettre la JSM en état erreur.
* La JSM n'envoie alors plus ses trames de contrôle XY.
* Profiter pour envoyer vos trames de controleXY au power module (PM) en vous faisant passer pour le joystick (JSM).
* On s'attend à que les roues se mettent à tourner en cohérence de la commande envoyée.
*[Mode JSMFollow] TODO
Ce cas est intéressant pour garder le contrôle du JSM.
Exemples:
$ candump can0 -L   # -L puts in log format
(1469933235.191687) can0 00C#
(1469933235.212450) can0 00E#08901C8A00000000
(1469933235.212822) can0 7B3#
(1469933235.251708) can0 7B3#
$ cansend can0 181C0D00#0840085008440840  #play a tune
$ cangen can0 -e -g 10  -v -v     #fuzz buss with random extended frames+data
$ candump -n 1 can0,7b3:7ff     #wait for can id 7B3
* Mode JSMEmulate]
Avec ce mode de fonctionnement il est possible de remplacer complètement le JSM.
C'est ce mode qui permettrait de développer de nouvelles possibilités d'utilisation du fauteuil (Domotique, ... )
4. Démo Manette Xbox360
Lancer sur la raspberry `python3 runJSMExploit.py` to control a R-Net based PWC using any usb gamepad connected to the pi3.
Python 3 is required.
MHK-can2RNET/runJSMExploit.py
#!/python3
import can2RNET
import threading
from common import logger, dec2hex, createJoyFrame, FRAME_JSM_INDUCE_ERROR
from time import time, sleep


def run(cansocket):
   logger.warning("Inducing JSM error:")
   # send in less than 1ms theses frames to induce
   # JSM error
   for _ in range(5):
       can2RNET.cansend(cansocket, FRAME_JSM_INDUCE_ERROR)
   # now let's take over by sending our own
   # joystick frame @100Hz
   mintime = .01
   nexttime = time() + mintime
   while True:
       # get new XY joystick increment
       joystick_x, joystick_y = get_new_joystick_position()
       # building joy frame
       joyframe = createJoyFrame(joystick_x, joystick_y)
       # sending frame
       can2RNET.cansend(cansocket, joyframe)
       # .. at 100 Hz ..
       nexttime += mintime
       t = time()
       if t < nexttime:
           sleep(nexttime - t)
       else:
           nexttime += mintime


if __name__ == "__main__":
   AG = False
   logger.info("try opening socketcan:")
   try:
       cansocket = can2RNET.opencansocket(0)
   except Exception as e:
       if AG:
           logger.warn(
               "opening specific ag udp sockets to send can frames:")
           import udp2can
           cansocket = udp2can.getUDP2CANSock()
       else:
           raise e
   logger.info("loading gamepad")
   import devXbox360
   dev = devXbox360.DevXbox360()
   watcher = devXbox360.Watcher(dev)
   dev.start()
   watcher.start()
   # set 'get_new_joystick_position' method
   # to fetch new joystick position from xbox360 gamepad device
   def get_new_joystick_position():
       return dev.joystick_x, dev.joystick_y
   logger.info("run exploit JSM Error")
   run(cansocket)
   © 2019 GitHub, Inc.
   Terms
   Privacy
   Security
   Status
   Help
   Contact GitHub
   Pricing
   API
   Training
   Blog
   About

Développement à venir

  • Changer le mode de fonctionnement de communication à distance, actuellement JSMerror (contrôlé par une manette xbox), par le mode FollowJSM.