#! /usr/bin/perl -w

use strict;

## This stuff you may want to modify.
sub getpin {
	# -- uncomment if you want a fixed pin -- #
	# return "1234";
	
	my $xuser = `/usr/bin/who | /usr/bin/awk '\$NF=="(:0)" { print \$1 }'`;
	$xuser =~ s/\s+$//s;

	if (!$xuser) {
		printf STDERR "Unable to obtain xuser for pin verification.";
		exit (1);
	}

	my $pin = `/bin/su - ${xuser} -c 'DISPLAY=:0 /usr/bin/Xdialog --title "3G Connect" --stdout --passwordbox "Your PIN is required:" 10 40' </dev/null`;
	$pin =~ s/\s+$//s;

	return $pin;
}

sub getapn {
	return "Internet";
}

## From here on can probably remain as is.
$|=1;

sub issue {
	my $cmd;
	$cmd = $_[0];
	printf STDERR "Sending $cmd\r\n";
	print "$cmd\r\n";

	while (<>) {
		s/\s+$//s;
		if ($_ eq $cmd) {
			last
		}
		printf STDERR "Discarding input: $_\r\n";
	}
}

sub request {
	while (<>) {
		s/\s+$//s;
		if ($_) {
			printf STDERR "Received: $_\r\n";
			return $_;
		}
	}
}

sub command {
	my $reply;
	my $response;
	issue($_[0]);
	my $ok = "^OK\$";
	if (defined($_[1])) {
		$ok = $_[1];
	}
	while (1) {
		$reply = request();
		if ($reply =~ $ok) {
			if (!defined($response)) {
				$response = $reply;
			}
			return $response;
		} elsif ($reply =~ "^\\+") {
			$response = $reply;
		} else {
			printf STDERR "Failing due to $reply\r\n";
			exit(1);
		}
	}
}

printf STDERR "Initializing modem\r\n";

alarm(10);

command("ATZ");
command("AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0");
my $pinreq = command("AT+CPIN?");

if ($pinreq eq "+CPIN: SIM PIN") {
	alarm(0);
	printf STDERR "Attempting to obtain PIN.\r\n";

	my $pin = getpin("3G PIN");

	alarm(10);
	command("AT+CPIN=$pin");
}

my $apn = getapn("3G");
command("ATE1V1&D2&C1S0=0+IFC=2,2");
command("AT+CGDCONT=1,\"IP\",\"$apn\"");
command("AT+IPR=115200");
command("ATE");
my $connect = command("ATDT*99***1#", "^CONNECT");
if ($connect =~ "^CONNECT (.*)\$") {
	printf STDERR "Connected at $1.\r\n";
}
exit(0);
