#!/usr/local/bin/perl5 -w
#========================================================================
#
#              wakeup_for_pls.pl
#
#   This is another example script of determining and reporting position
#   at some periodic interval.  This script, however, will power the 
#   modem off after reporting position.  The modem is then powered up
#   again for each reporting period.  Powering the modem up and down is
#   controlled by the DTR signals on the data and control ports.  When a
#   port is "open", DTR is asserted and the modem powers up.  Closing all
#   the ports (both data and control) will power the modem down.
#
#   This script assumes that AT commands are sent to the control port which 
#   is configured for COM1.  COM2 is used for the data port which is 
#   opened just to assert DTR in order to establish the data call.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#  (c) COPYRIGHT 2001 QUALCOMM, Incorporated. All Rights Reserved
#                     QUALCOMM Proprietary
#
#  Export of this technology or software is regulated by the U.S. Government.
#  Diversion contrary to U.S. law prohibited.
#
#  All ideas, data and information contained in or disclosed by
#  this document are confidential and proprietary information of
#  QUALCOMM Incorporated and all rights therein are expressly reserved.
#  By accepting this material the recipient agrees that this material
#  and the information contained therein are held in confidence and in
#  trust and will not be used, copied, reproduced in whole or in part,
#  nor its contents revealed in any manner to others without the express
#  written permission of QUALCOMM Incorporated.
#
#========================================================================

#===========================================================================
#               INCLUDE FILES
#===========================================================================

use strict;
use CommLib;
use AtCmdLib;

#===========================================================================
#               DEFINITIONS AND DECLARATIONS
#===========================================================================

# Set global to specify that Control port is on COM1

$CommLib::COM_DATA    = "COM2";
$CommLib::COM_CONTROL = "COM1";

my $number_to_dail = "#777";                 # Packet data call.
my $time_interval_for_position_update = 600; # Seconds between position updates

#===========================================================================
#               FUNCTION DEFINITIONS
#===========================================================================

#===========================================================================
# Function:     wait_for_service
#
# Description:
#   Waits the specified amount of time for service to become available.
#   This routine polls the modem status until either service is available
#   or the wait_time is exceeded.
#
# Parameters:
#   wait_time - The number of seconds to wait for service
#
# Returns:
#   "YES" if service is available, "NO" otherwise.
#===========================================================================

sub wait_for_service
{
  my ( $wait_time ) = @_;

  my $service_avail = "NO";

  for (0..$wait_time)
  {
    #-----------------------------------------------------------------------
    # Get status to determine if service is available.  Exit loop on "YES".
    #-----------------------------------------------------------------------

    my $status = at_qcstatus();

    die "Unable to get status from the modem" if ( !defined($status) );

    $service_avail = $status->{"SERVICE AVAILABLE"};

    last if (defined($service_avail) && $service_avail =~ /YES/);

    #-----------------------------------------------------------------------
    # Sleep for about 1 second (very crude timing).
    #-----------------------------------------------------------------------

    sleep 1;
  }

  return $service_avail;
}

#===========================================================================
# Function:     wait_for_registration
#
# Description:
#   Waits the specified amount of time for the modem to register with the
#   current gateway.
#
# Parameters:
#   wait_time - The number of seconds to wait for registration
#
# Returns:
#   "YES" if registered, "NO" otherwise.
#===========================================================================

sub wait_for_registration
{
  my ( $wait_time ) = @_;

  my $registered = "NO";

  my $status = at_qcstatus();

  die "Unable to get status from the modem" if ( !defined($status) );

  for (0..$wait_time)
  {
    #-----------------------------------------------------------------------
    # Get status to determine if registered.  Exit loop on "YES".
    #-----------------------------------------------------------------------

    $status = at_qcstatus();

    die "Unable to get status from the modem" if ( !defined($status) );

    $registered = $status->{"REGISTRATION"};

    last if ($registered =~ /YES/);

    #-----------------------------------------------------------------------
    # Sleep for about 1 second (very crude timing).
    #-----------------------------------------------------------------------

    sleep 1;
  }

  if ($registered =~ /YES/)
  {
    print "Registered with $status->{\"PROVIDER\"}, Gateway ID $status->{\"GATEWAY\"}\n";
  }

  return $registered;
}

#===========================================================================
# Function:     display_position
#
# Description:
#   Displays the position location information returned from a PLS request.
#
#    Hash key     Data contents
#    --------     -----------------------------------------------
#    W            Latitude as DDD MM SS (Degrees, Minutes, and Seconds)
#    N            Longitude as DDD MM SS (Degrees, Minutes, and Seconds)
#    TIME         The time of the measurement as (DD MM YYYY HH:MM:SS)
#    ERR          The estimated accuracy of the position.
#
# Parameters:
#   pls_data  - A hash containing the position information
#
# Returns:
#   None
#===========================================================================

sub display_position
{
  my ( $pls_data ) = @_;

  if ( defined($pls_data) )
  {
    print "\n";
    print "LAT : $pls_data->{W}\n";
    print "LNG : $pls_data->{N}\n";
    print "TIME: $pls_data->{TIME}\n";
    print "Estimate accuracy is $pls_data->{ERR}\n\n";
  }
}

#===========================================================================
#                   MAIN SCRIPT
#===========================================================================

#---------------------------------------------------------------------------
# Initialize CommLib
#---------------------------------------------------------------------------

comm_lib_init();

#------------------------------------------------------------------------
# Update the position information at the specified interval.
#------------------------------------------------------------------------

for(;;)
{
  my $response;

  #---------------------------------------------------------------------------
  # Open both the data and control ports.  This will cause the modem to
  # power up if it is currently powered down.  The code should wait for DSR
  # to be asserted before attempting to write to either port.  The CommPort
  # driver has some delay built in to account for this.
  #---------------------------------------------------------------------------

  print "Powering up the modem\n";

  comm_set_config($COMM_CONFIG_BOTH);

  #------------------------------------------------------------------------
  # The modem has just powered up so service isn't going to be available
  # yet.  Give the modem about a minute to acquire service.  If nothing is
  # found, then go back to sleep until the next interval.
  #------------------------------------------------------------------------

  print "Waiting for service\n";

  if (wait_for_service(60) =~ /YES/)
  {
    #------------------------------------------------------------------------
    # Wait for registration.  Try to make the call even without registration
    #------------------------------------------------------------------------

    wait_for_registration(45);

    #------------------------------------------------------------------------
    # Originate the call.  Don't bother with PLS if the call fails.
    #------------------------------------------------------------------------

    print "Originating a data call\n";

    if ( ($response = at_dial($number_to_dail)) =~ /CONNEC/ ) 
    {
      print "$response... Requesting position information\n";

      #------------------------------------------------------------------------
      # Get and display the current position.
      #------------------------------------------------------------------------

      display_position( at_qcpls( 0 ) );    # 0 indicates get current position

      #------------------------------------------------------------------------
      # Release the call.
      #------------------------------------------------------------------------

      print "Releasing the data call\n";

      $response = at_hook_control("0");

      print "Unable to release data call\n" if ($response !~ /OK/);
    }

    else
    {
      print "Call setup failed, response = $response\n";
    }
  }

  #---------------------------------------------------------------------------
  # Close both the control and data ports.  This will effectively power
  # down the modem.  The code should wait for DSR to go inactive to indicate
  # that the modem has indeed powered down.  
  #---------------------------------------------------------------------------

  print "Powering the modem off\n";

  comm_set_config($COMM_CONFIG_NONE);

  #------------------------------------------------------------------------
  # Sleep until the next interval.
  #------------------------------------------------------------------------

  print "Going to sleep for $time_interval_for_position_update seconds\n\n";

  sleep $time_interval_for_position_update;
}

#---------------------------------------------------------------------------
# Shutdown CommLib
#---------------------------------------------------------------------------

comm_lib_shutdown();

