Thursday, March 26, 2015

XBOX 360 monitoring

XBOX 360 is great even it's "old" already compared to XBOX One and other next gen consoles. Never the less I like XBOX 360 even though I'm missing few thinks (limited USB stack implementation, missing Wake On LAN).

However I've decided I shall monitor my entertaining systems to be able switch off AV reciever or Display if forget to. For this I need to know if my Xbox 360, PC or DVB-T is running.... I'll cover this "auto switch off system" in another post.

During my exploration I find following problems:
  1. ping is not the option, XBOX 360 doesn't reply to ICMP request
  2. UPnP is running only when not playing game
  3. arping works only with IP, if only MAC address is provide it will send request with broadcast IP which xbox will not respond
So the solution is to set for XBOX fixed IP and use:
  1. arping to verify if device is up
  2. gssdp-discovery to check if game is running (and get UPnP Port if not)

Below is script using arping to verify if device is up and if so then find what UPnP port is it listening(if game is not played), results are stored in sqlite db for purpose of further use

#! /bin/bash


#test ICMP connectivity with ping
testARPing()
{
  return `arping -c 4 $1 | grep "100% unanswered" | wc -l`
}

XBOXIP='10.0.0.41'
XBOXMAC='7c:1e:52:c2:6c:a7'
XBOXUUID='03166842-2743-2000-0000-7c1e52c26ca7'

DBFILE='/var/www/judo.db'

if `testARPing $XBOXIP`
  then
    new_status="Up"
    location=`gssdp-discover -n 10 -t uuid:$XBOXUUID | grep "Location:" | sed 's/ *Location: http:\/\///g'| cut -d/ -f1 | sed 's/\///g'`
    #echo "$location"
    #ip=$(echo "$location" | cut -d: -f1)
    upnp_port=$(echo "$location" | cut -d: -f2)
  else
    new_status="Down"
fi

new_polls=1
prev_status_polls=$(sqlite3 $DBFILE "SELECT cur_state,polls_in_state FROM dev_status WHERE mac = '$XBOXMAC';")
prev_status=$(echo "$prev_status_polls" | cut -d\| -f1)
prev_polls=$(echo "$prev_status_polls" | cut -d\| -f2)
if [ "$prev_status" == "$new_status" ]
then
  new_polls=$((prev_polls + 1))
fi
sqlite3 $DBFILE "UPDATE dev_status SET cur_state = '$new_status', polls_in_state = '$new_polls' WHERE mac = '$XBOXMAC';"
sqlite3 $DBFILE "UPDATE devices SET upnp_port = '$upnp_port' WHERE mac = '$XBOXMAC';"
echo "$XBOXIP,$XBOXMAC,$new_status,$prev_status,$new_polls"

No comments: