Playing Fallout 3 on Linux with PlayOnLinux and Steam

September 25th, 2013

This week I bought a bottle of “Nuka Cola” (www.nukacola.eu) in a geek shop which has opened in Munich recently. This remembered me of the good time I had when playing Fallout 3 – so I decided to give it a try to get the game running on my current Mint 14 machine.

Remembering I had the game running once using Wine on Snow Leopard, I was confident get it working on Linux, too. I read about something called “PlayOnLinux” some time ago, I wanted to try this handy tool also. And, it really helped me and saved precious time which I would have normally wasted on configuring Wine.
To keep the long story short, here my approach:

– get PlayOnLinux (apt-get install playonlinux)
– install Steam inside of PlayOnLinux (the automatically chosen version of Wine 1.5.25 works fine for me)
– install d3dx9 and msasn1 packages for the Steam virtual drive
– start steam, log in with your account and install Fallout 3
– launch Fallout 3 and have fun!

The game runs fine with me GeForce 210 graphics card and the NVIDIA binary Xorg driver (304).

Hacking the Withings WiFi Body Scale

April 14th, 2013

Keeping track of weight development just got a lot easier, now that scales like the “Wifi Body Scale” by Withings (available at e.g. Amazon) can post their measurements via Wifi.

Unfortunately, the scales post their results to the webpage of the manufacturer, which some people are not comfortable with. Fortunately, the communication is unencrypted and easy understandable (JSON based).

Other folks have paved the way by analyzing the protocol. The general approach stays the same

  1. Pair the scales via the instructions (need an account at my.withings.com) with the wifi network
  2. Redirect the DNS requests from the scales to your own server
  3. Setup some script which simulates a Withings server
  4. Communicate!
  5. Do something with the data

1. Pairing
There are different models that have different pairing approaches, consult the FAQ for additional information. The document also provides information on error codes and how to reset the device (or perform firmware updates).

UPDATE: Withings now uses Zendesk for support information.

2. DNS Spoofing
In order to redirect the requests from the device, many ways lead to Rome. Depending on your network configuration, you could use dnsmasq on your router and configure it to respond with a modified ip via:

address=/withings.net/10.0.0.5
address=/withings.com/10.0.0.5

where 10.0.0.5 is the ip of your own server. While the WebGUI is hosted at withings.com, the scales try to communicate with scalews.withings.net. Both resolve to ‘89.30.121.150’. If you have your own bind service running, configure a zone for the withings domains.

3. Server
Now that the scales talk to your webserver at 10.0.0.5, the conversation has to be performed. “Prox” wrote a python script, while “sd” (german) used PHP.

The configuration of the webserver might have to be changed in order to redirect the requests from

  • /cgi-bin/once
  • /cgi-bin/session
  • /cgi-bin/maint
  • /cgi-bin/measure

to your own script. Running nginx, add the following to your server configuration

# allow POST requests to static content
error_page 405 = $uri;

# redirect withings scale requests
location /cgi-bin {
rewrite ^/cgi-bin/(.*)$ /withings/index.php?s=$1;
}

and the requests will be forwared to the PHP script “index.php” at /withings on your webserver.

4. The communication
The communication consists of 5 Steps and is handled via POST requests containing JSON data

  1. Request to /cgi-bin/once:

    POST: Array
    (
    [action] => get
    )

    Response:
    {
    "status": 0,
    "body": {
    "once": "87a6549c-93f7bce8"
    }
    }

    Remarks:
    – status 0 means no error (query the withings service to get some error codes like 2554)
    – the once UID can be random 8 chars, dash, 8 chars

  2. Request to /cgi-bin/session:

    POST: Array
    (
    [action] => new
    [auth] => 00:00:be:ef:00:07
    [hash] => e26b6c7dcb05ac46bde912d2bc951d83
    [mfgid] => 114700
    [currentfw] => 79
    [batterylvl] => 100
    [duration] => 30
    [zreboot] => 0
    )

    Response:
    {
    "status": 0,
    "body": {
    "sessionid": "7bf5-382a9b74-183dcfe5",
    "sp": {
    "users": [
    {
    "id": 5555,
    "sn": "BEN",
    "wt": 80,
    "ht": 1.75,
    "agt": 23.4,
    "sx": 0,
    "fm": 131,
    "cr": 1365963066,
    "att": 0
    },
    {
    "id": 6666,
    "sn": "SEN",
    "wt": 80,
    "ht": 1.75,
    "agt": 42,
    "sx": 1,
    "fm": 131,
    "cr": 1365963066,
    "att": 0
    }
    ]
    },
    "ind": {
    "lg": "en_US",
    "imt": 1,
    "stp": 1,
    "f": 2,
    "g": 98124
    },
    "syp": {
    "utc": 1365974415
    },
    "ctp": {
    "goff": 7200,
    "dst": 0,
    "ngoff": 0
    }
    }
    }

    Remarks:
    – auth in request: MAC address of scales (can be found in the battery compartment)
    – response: list of user profiles, scale settings and time information

    “id”: numeric id for user
    “sn”:” three chars displayed in the scales (usernick)
    “wt”: weight in kilograms, used for identification
    “ht”: height of user in meters
    “agt”: age in years
    “sx”: sex of user (0: male, 1: female)
    “fm”: unknown
    “cr”: timestamp of last measurement or account creation
    “att”: unkown
    lg”: language, like “en_US” or “en_GB”
    “imt”: perform induction measurement (0: off, 1: on)
    “stp”: 1 (unknown)
    “f”: autocalibrate mode (0: measure directly, 2: calibrate via tap before measuring)
    “g”: value for gravity (98124). This highly influences the weight result!
    “utc”: current UNIX timestamp}
    goff”: unkown
    “dst”:0 (DST switch?)
    “ngoff”: unkown

  3. Request to /cgi-bin/maint:

    POST: Array
    (
    [action] => store
    [sessionid] => 7bf5-382a9b74-183dcfe5
    [source] => 1
    [type] => 2
    [data] => [WDEBUG] dac: 1419 1508 1638 1791
    [WDEBUG] adc: 21800 21500 21900 21800
    )

    Response:
    {
    "status": 0
    }

    Remarks:
    – Maintenance values (seem like raw values from ADC and DAC)
    – Response from real server is much longer, but since its not needed for now, status: 0 should be enough

  4. Request to /cgi-bin/measure:

    POST: Array
    (
    [action] => store
    [sessionid] => 7bf5-382a9b74-183dcfe5
    [macaddress] => 00:00:be:ef:00:07
    [userid] => 5555
    [meastime] => 1365974385
    [devtype] => 1
    [attribstatus] => 0
    [measures] => {“measures”:[{“value”:80050,”type”:1,”unit”:-3},{“value”:239,”type”:16,”unit”:0}]}
    )

    Response:
    {
    "status": 0
    }

    Remarks:
    – Measurement from scales, type: 1 seems like weight
    – Response from server is just the usual “ACK”

  5. Another request to /cgi-bin/maint, ignored for now.
  6. Request to /cgi-bin/session:

    POST: Array
    (
    [action] => delete
    [sessionid] => 7bf5-382a9b74-183dcfe5
    )

    Response:
    {
    "status": 0
    }

    Remarks:
    – Logoff from service
    – Response from server is just the usual “ACK”

5. The data
Since the device can buffer some measurements, it can happen that multiple results are transfered at once.

Once the data is saved, its up to you how to analyze it. More to come (like my index.php).

Simple script for changing wallpaper using RSS feed

July 16th, 2012

Just had the idea to change the wallpaper of my desk according to an RSS feed.

Here’s the shellscript:

#!/bin/sh
 
IMGPATH="/home/chris/Pictures/Wallpapers/factsandchicks"
IMGURL=$(wget -q -O- "http://www.factsandchicks.com/rss" | grep -o 'src="[^"]*' | grep -m 1 -o '[^"]*$')
LOCALFILENAME=$(echo $IMGPATH/$(date +"%Y%m%d").jpg)
 
wget -q -O$LOCALFILENAME $IMGURL
 
gsettings set org.gnome.desktop.background picture-uri file:///$LOCALFILENAME

For this example, I used the RSS feed from factsandchicks.com (o.O)
The command in the last line depends on your distribution, this one works for newer Ubuntus. You probably want to run this script via cron or rc.local to get the new wallpapers regularly.

Have fun!

UCF Filetype for Geany

June 30th, 2012

Geany is currently my favorite graphical editor. Soon, I was missing a syntax highlighting for UCF (user constraints file) files and recently I was motivated to create an UCF Filetype.

I built it according to the information in the Geany Manual, and here it is (sorry for the horrible formatting, but some stuff has to be in one single line):

# For complete documentation of this file, please see Geany's main documentation [styling] 
# foreground;background;bold;italic 
default=default 
comment=comment 
number=number 
word=keyword 
word2=keyword2 
string=string 
preprocessor=preprocessor
 
[keywords] # all items must be in one line 
primary=AREA_GROUP ASYNC_REG BEL BLKNM BUFG COLLAPSE COMPGRP CONFIG CONFIG_MODE COOL_CLK DATA_GATE DCI_VALUE DISABLE DROP_SPEC ENABLE FEEDBACK FILE FLOAT FROM HBLKNM HU_SET IN INREG IOB IOBDELAY IOSTANDARD KEEP KEEP_HIERARCHY KEEPER LOC LOCATE LOCK_PIN MAP MAXDELAY MAXPT MAXSKEW NET NODELAY NOREDUCE OFFSET OPEN_DREIN OPT_EFFORT OPTIMIZE OUT PERIOD PIN PRIORITY PROHIBIT PWR_MODE REG RLOC RLOC_ORIGIN RLOC_RANGE SCHMITT_TRIGGER SLEW SYSTEM_JITTER TEMPERATURE THRU TIG TIMEGRP TIMESPEC TNM TO TPSYNC TPTHRU U_SET USE_RLOC USELOWSKEWLINES VFEF VOLTAGE WIREAND XBLKNM 
secondary=COMPRESSION DATAPATHONLY GROUP IMPLEMENT INST MODE PLACE RANGE ROUTE TNM_NET AFTER BEFORE DRIVE FALLING FAST HIGH NOT PULLDOWN PULLUP RISING SLOW 
#docComment=
 
[settings] 
# Vala uses the C lexer
lexer_filetype=C
tag_parser=Python
 
# default extension used when saving files
extension=ucf
 
# the following characters are these which a "word" can contains, see documentation 
#wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
 
# if only single comment char is supported like 
# in this file, leave comment_close blank 
comment_single=#

Create the file ~/.config/geany/filedefs/filetypes.ucf.conf and insert the text above.

Then open Geany and insert the following line to filetypes_extensions.conf (Tools -> Configuration Files)

ucf=*.ucf;

Now, Geany should do some basic but useful syntax highlighting for ucf files!


				

Simple FM Receiver with OsmoSDR in GNURadio

May 14th, 2012

Finally, my 20$ EZcap USB DVB-T stick has arrived, and I wanted to start with a simple FM receiver to see how to operate this thing with OsmoSDR in GNURadio!

I’ve already installed GNURadio, RTL-SDR and OsmoSDR using the GNURadio build script on my Ubuntu 11.10 machine. To start out with the USB-receiver, you can just run the example contained in the OsmoSDR sources (./gr-osmosdr/apps/osmosdr_source.grc) to see if the stick works. It should do its job out of the box, at least it did for me. When running this example, you should see a nice FFT of the received radio signal at the defined frequency with sample-rate dependent bandwidth.

Slightly altered osmosdr_source.grc example

If this example works, you can go on and work on bigger things instantly. As already mentioned, I wanted build a very basic FM receiver. GNURadio has everything you need for that on-board, and therefore the grc model for such a receiver looks like this:

Basic FM Receiver in GNURadio Companion

Some comments on the used blocks and their parameters:

  • OsmoSDR Source: gets the desired frequency from the osmo_freq slider, samplerate is chosen in the osmo_samp_rate variable
  • Rational Resampler: gets the decimation and interpolation values from osmo_samp_rate and samp_rate
  • Frequency Xlating FIR Filter: sample rate from samp_rate, filter_taps is defined as a firdes.low_pass(1,samp_rate,100e3,1e3) (feel free to play around with the latter two parameters of the filter!). The center frequency can be changed with xlate_tune
  • WBFM Receive: Quadrature rate is samp_rate
  • For the FFTs, I’ve chosen a configurable refresh rate, you can tweak it according to the performance of your computer (as well as the FFT size…). Also, their baseband frequency is set to osmo_freq, respectively osmo_frequ+xlate_tune to change the x-axis of the FFTs according to the currently slider settings.

After putting everything together, the following GUI should appear and you can tune and listen to your favorite FM station!

Running and receiving fm_rcv

 

Known issues:

When I’m running GNURadio simultaneousely with other sound sources (e.g. a video in a browser), the grc model throws the following error:

audio_alsa_sink[hw:0,0]: Das Gerät oder die Ressource ist belegt
Traceback (most recent call last):
  File "/home/chris/ufsdr/osmosdr/fm_rcv/fm_rcv.py", line 280, in <module>
    tb = FM_rcv()
  File "/home/chris/ufsdr/osmosdr/fm_rcv/fm_rcv.py", line 201, in __init__
    self.audio_sink_0 = audio.sink(48000, "", True)
  File "/usr/local/lib/python2.7/dist-packages/gnuradio/audio/audio_swig.py", line 345, in sink
    return _audio_swig.sink(*args, **kwargs)
RuntimeError: audio_alsa_sink

I solve this problem by a forced restart of the alsa-device by identifying the process(es) using PCM currently with

lsof | grep pcm

and killing the appearing tasks by their ids with

kill <id>

 

For further (basic) information see:
OsmoSDR Wiki: http://sdr.osmocom.org/trac/wiki/rtl-sdr
GNURadio Homepage: http://gnuradio.org