#!/usr/bin/perl
# 
###########################################################################
# navini_monitor.pl 
# Copyright 2006 Gavin McCullagh 
# gmccullagh _AT_ gmail.com
#
# This file is part of the Navini Monitor.
# The Navini Monitor is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option) any
# later version.
# 
# The Navini Monitor is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# The Navini Monitor; if not, write to the Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA  02111-1307  USA
############################################################################
#
# navini_monitor.pl version 0.002
# A quick and dirty tool to read some of the information from the UDP packets
# sent by the Navini (aka Ripwave/Unwired) modem.
# 
# Some of this code (the UDP reading loop) was inspired by: 
# Figure 18.4: A UDP reverse-echo server
# http://www.modperl.com/perl_networking/source/ch18/udp_echo_serv.pl
# 

use strict;
use IO::Socket;
use constant MY_ECHO_PORT => 3859;
use constant MAX_MSG_LEN  => 400;

$|=1;
$SIG{'INT'} = sub { exit 0 };

sub parse_packet($) {
	my $packet = shift @_;

	#  address:  0x001c 2e 33 34 35 36 37 38  39 49 ....<fill me in soon>
	my $template = "H36 H8 H2 H2 H2 H2 H2 H2 H34 H2 H30 H2 H8 H4 H52  H2 H10  H4 H78 H2 H*";
	my ($stuff,$modemid,$month,$day,$year,$hour,$minute,$second,$stuff,$syncstrength1,
	    $stuff,$bts,$stuff,$networkid,$stuff,$antenna,$stuff,$syncstrength2,$stuff,$temperature) 
		= unpack($template, $packet);
	$month = sprintf("%2d",hex($month));
	$day = sprintf("%2d",hex($day));
	$year = sprintf("%2d",hex($year));
	$hour = sprintf("%2d",hex($hour));
	$minute = sprintf("%2d",hex($minute));
	$second = sprintf("%2D",hex($second));
	$temperature = sprintf("%2D",hex($temperature));
	$networkid = sprintf("%d",hex($networkid));
	$bts = sprintf("%d",hex($bts));
        $syncstrength1 = sprintf("%d",hex($syncstrength1));
        $syncstrength2 = sprintf("%d",hex($syncstrength2));
	$antenna = ($antenna / 20);
	my $time = "20$year-$month-$day $hour\:$minute\:$second";
	print "$time\t$modemid\t$networkid\t$bts\t$antenna\t-$syncstrength1",
		"\t-$syncstrength2\t$temperature\n";
}

my $port = MY_ECHO_PORT;
my $sock = IO::Socket::INET->new(Proto=>'udp', LocalPort=>$port) or die $@;
my ($msg_in,$msg_out);

print "#Time             \tModemID \tNet\tBTS\tAntn\tStr\tStr\tTemp\n";

while (1) {
	next unless $sock->recv($msg_in,MAX_MSG_LEN);
	my $peerhost = gethostbyaddr($sock->peeraddr,AF_INET) 
					|| $sock->peerhost;
	my $peerport = $sock->peerport;
	my $length   = length($msg_in);
	parse_packet($msg_in);
}

$sock->close;

__END__

