#!/usr/bin/perl -w
use strict;
use Time::HiRes;
use Time::Local;

sub get_system_time {
    return Time::HiRes::time();
}

sub get_pcf50633_time {
    open(my $fd, '<', '/sys/class/rtc/rtc0/since_epoch');
    my $ret = <$fd>;
    close($fd);
    chomp($ret);
    return $ret;
}

sub get_calypso_time {
    my $ret = `dbus-send --system --print-reply --dest=org.freesmartphone.ogsmd /org/freesmartphone/GSM/Device org.freesmartphone.GSM.Debug.DebugCommand string:AT+CCLK?\r\n`;
    my @lines = split(/\n/, $ret);
    foreach my $line (@lines) {
	if ($line =~ /\+CCLK: \"(\d+)\/(\d+)\/(\d+),(\d+):(\d+):(\d+)\"/) {
	    my $year = 2000 + $1;
	    my $mon = $2;
	    my $mday = $3;
	    my $hour = $4;
	    my $min = $5;
	    my $sec = $6;
	    $year -= 1900;
	    $mon -= 1;
	    my $time = timegm($sec, $min,$hour,$mday,$mon,$year);
	    return $time;
	}
    }
    return "unknown";
}

sub set_system_time {
    my ($time) = @_;
    system("date --set -u $time");
}

sub set_calypso_time {
    my ($time) = @_;
    my ($sec, $min, $hour, $mday, $mon, $year) = gmtime($time);
    $year += 1900;
    $mon += 1;
    my $time2 = sprintf("%02d/%02d/%02d,%02d:%02d:%02d+00", 
		       $year - 2000, $mon,
		       $mday, $hour, $min, $sec);
    system("dbus-send --system --print-reply --dest=org.freesmartphone.ogsmd /org/freesmartphone/GSM/Device org.freesmartphone.GSM.Debug.DebugCommand string:AT+CCLK=\"$time2\"\r\n");
}

sub gps_tick {
    my ($gps_time) = @_;
    print($gps_time . " " . get_system_time() . " " . get_pcf50633_time() . " " . get_calypso_time() . "\n");
}

sub main {
    while (<>) {
	my $line = $_;
	chomp($line);
	my @c = split(/,/, $line);
	# $GPRMC,204744.00,A,6009.69808,N,02456.04487,E,0.070,87.43,240509,,,A*50
	if ($#c == 12 && $c[0] eq "\$GPRMC") {
	    my $hour = substr($c[1], 0, 2);
	    my $min = substr($c[1], 2, 2);
	    my $sec = substr($c[1], 4, 2);
	    my $mday = substr($c[9], 0, 2);
	    my $mon = substr($c[9], 2, 2);
	    my $year = 2000 + substr($c[9], 4, 2);
	    $year -= 1900;
	    $mon -= 1;
	    my $time = timegm($sec,$min,$hour,$mday,$mon,$year);
	    gps_tick($time);
	}
    }
}

main();

# gps
#  read /dev/ttySAC1
#   how to get rid of useless traffic?
#  gpsd

# system clock
#  date
#   73 ms
#  gettimeofday

# pcf50633 rtc
#  hwclock
#   278 ms
#  cat /proc/driver/rtc
#   132 ms
#  cat /sys/class/rtc/rtc0/since_epoch
#   80 ms

# calypso rtc
#  dbus-send --system --print-reply --dest=org.freesmartphone.ogsmd /org/freesmartphone/GSM/Device org.freesmartphone.GSM.Debug.DebugCommand $'string:AT+CCLK?\r\n'
#   170 - 392 ms

# s3c rtc?
#  rtc-s3c module does not seem to create rtc1

# /sys/class/rtc/rtc0/name
#  pcf50633-rtc


# dbus-send --system --print-reply --dest=org.freesmartphone.ogsmd /org/freesmartphone/GSM/Device org.freesmartphone.GSM.Debug.DebugCommand $'string:AT+CCLK="09/05/24,20:23:05+00"\r\n'

# http://metafoo.de/gta02-s3c-rtc.patch

# perl bin/compare-clock-sources.pl /dev/ttySAC1 > /dev/shm/clock.log
# plot "clock.log" using 1:($2 - $1) title "sys", '' using 1:($3 - $1) title "pcf", '' using 1:($4 - $1) title "calypso"

# -5.499544 + (0.057)*24 = -4.131544 s in a day
# 1s in 20912.29 s
# adjtimex --tick 9999 --freq 3419747
# Mon May 25 02:02:42 EEST 2009

# pcf: 1s in 16185 s

