With the rem0te package of r0ket software you can build a game or other installation that can be interacted with, using a r0ket.
The system consists of three elements: The game server, the bridge and the l0dable r_player.
The game server uses the bridge to announce the game, receive button presses and (in the future) send text to the display of a player.
The bridge is a r0ket running a special firmware. It is attached via USB to the computer running the game server. It can receive and send on any channel and with any address.
The l0dable runs on the r0kets of the players. It displays a list of available games and lets the player join a game. It can also transmit the nickname of the player to the game. In a future version it will be able to display text on the LCD.
To implement your own game server you can use our python library r0ketrem0te. It is located in the git at https://github.com/r0ket/r0ket/tree/master/tools/game .
It depends on the python library crcmod. You can use pypi to install it. With Ubuntu run:
sudo apt-get install python-stdeb sudo pypi-install crcmod
Now you can install the library:
cd tools/game sudo python setup.py install
The py-pong directory contains a sample implementation for a multi-player pong using the game server. Run it with:
cd tools/game/py-pong python main.py
The game will wait until two players have connected and transmitted their nick name. It will then start the game until one of the players shuts down the l0dable or gets out of reach.
You need to have pygame installed for py-pong.
The library is currently only tested with Linux.
The firmware for the bridge is located in the file firmware/applications/bridge.c
cd firmware make clean make APP=bridge USBSERIAL=YES
Now flash it using
A precompiled image can be found at https://brezn.muc.ccc.de/~schneider/bridge.bin
The host can configure several different parameters of the bridge.
Both the host and the bridge use escape sequences to synchronise the data flow.
A frame starts with a “\\” and the command byte. A frame ends with “\\0”. Data sits between the start and the end of a frame. If the data contains a “\\” it has to be escaped with “\\\\”
The following commands are implemented:
|“1”||New packet||A new packet that has been received or should be sent|
|“2”||Done||Only sent by the bridge: The last command has been processed|
|“3”||Set the TX MAC||5 bytes containing the destination address of new packets|
|“4”||Set the RX MAC||5 bytes containing the address on which the radio listens|
|“5”||Set channel||1 byte with the channel to RX/TX|
|“6”||Set MAC len||1 byte with the length of incoming packets|
send a packet: send(“\\1<packet data>\\0”); while receive() != “\\2\\0”;
set the channel: send(“\\5<channel>\\0”); while receive() != “\\2\\0”;
The bridge does not alter the content of the packets. The game l0dable checks for a CRC in the last two bytes of the data. You have to take care of these your self. If you are sending 32 Byte packets, compute the CCITT CRC16 over the first 30 bytes and put it in the last two bytes. Do not include the framing information for the bridge.
The l0dable is located at firmware/l0dables/r_player.c
To build it run:
cd firmware make APP=final make APP=final l0dables
Then copy l0dables/r_player.c0d to the r0ket. We will put up a pre compiled l0dable before 28C3. We are still actively developing for it.
If you have a game server running in the vicinity the l0dable will show you the games it found. Select the game you want to play and press right. The game can now request your nickname. The l0dable then transmits it to the game and starts to send the state of the button. You can now interact with the game. The l0dable transmits the state of the button on a regular basis. Currently about every 50ms.
Currently there is no way to exit the l0dable and there is no code to display text.
To write your own game server you can use the r0ketrem0te Python library. Have a look at the main.py and pypong/player.py for an example application. The r0ketrem0te.game.Game class implements most of the things that have to be taken care of.
In the constructor you have to specify the following parameters:
The Game class keeps track of active players. If a player does not send a packet for 10 seconds she is removed from the list of active players.
There are callbacks for
Have a look at the top of l0dables/r_player.c. It contains the definitions of the packets and the flags used.
To host a game do the following:
1) Select a random 16bit GameID, select a random 5 Byte GameMAC, set a global ctr variable to 0, select the channel you want your game to run on
2) Every second set the bridge channel and TX mac to the values recommended above and send an announce packet with the following content:
Now set the bridge back to receive on the gameChannel
3) When a player sends a Join packet it will contain:
Now send the following packet:
As destination MAC use the gameMac with the last byte incremented by 1. 4) The player will start to send: