#!/usr/bin/perl
# vim:ts=4:sw=4:smartindent

#
# gnokii-init.pl
#
# ABOUT
#
#   Copyright Roy Sigurd Karlsbakk 2008 <roy@karlsbakk.net>
#
#   Licensed under GPL v2.0. See LICENSE file for details.
#
#   This software resets a GSM modem, logs into it, and waits until it's ready,
#   indicating GSM signalling is ok, or fails with a non-zero error code.
#
# KNOWN ISSUES
#  - Error codes not documented in this comment, only in the code.
#  - Configuration should be settable with command-line arguments.
#

use strict;
use warnings;
use Device::SerialPort qw( :PARAM :STAT 0.07 );

#
# Here goes our config
#
my $port_name = '/dev/ttyS0';				# This is the serial port device.
my $pin = '0000';							# Here goes our pin code.
my $read_timeout = 10;						# I/O timeout for serial device in seconds.
my $ready_timeout = 60;						# GSM-ready timeout in seconds.

# Communication settings
my $baudrate = 9600;						# Set to current speed.
my $parity = 'none';						# Set to 'none', 'even', or 'odd'.
my $databits = 8;							# Between 5 and 8. Only 8 is commonly used.
my $stopbits = 1;							# Set to 1 or 2. 1 is most common.
my $handshake = 'rts';						# Set to 'none', 'rts' or 'xoff'

# Other globals
my $answer = undef;

#
# Main code - no changes should be needed below this line
#

# Don't buffer output
$|++;

print "Initialising GSM modem at $port_name...";

my $PortObj = new Device::SerialPort ($port_name) or
	die "Can't open device $port_name: $!\n";

$PortObj->handshake($handshake);
$PortObj->baudrate($baudrate);
$PortObj->parity($parity);
$PortObj->databits($databits);
$PortObj->stopbits($stopbits); 

$PortObj->read_char_time(0);     # don't wait for each character
$PortObj->read_const_time(1000); # 1 second per unfulfilled "read" call

my $chars = 0;
my $buffer = "";
my $seconds_elapsed = 0;
my ($count,$bit,$data);
my $timed_out = 0;
my $connected = 0;

$PortObj->write("AT+CFUN=1,1\r\n"); sleep(2);
$PortObj->write("ATZ\r\n");
$PortObj->write("AT+CPIN=$pin\r\n"); sleep(2);
while (!$connected and !$timed_out)
{
	$PortObj->write("AT+CIND?\r\n");
	($count,$bit) = $PortObj->read(255);
	$data .= $bit;

# Look for this string, the third inditcator tells us whether or not we're online.
# +CIND: 5,99,1,0,0,0,0,0,4

	if ($data =~ m/\+CIND:\s(\d),(\d+),1,/ and $1 > 0 and $2 > 0)
	{
		$connected=1;
	}
	$timed_out = ($seconds_elapsed++ > $read_timeout)
}

$PortObj->close;

if ($connected)
{
	print " Connected\n";
	exit 0;
}

print " Failed\n";
exit 1;
