#!/usr/bin/perl -w
#
# This program receives UDP datagrams from Aspicore GSM Tracker,
# parses and stores them to a MySQL database
#
# Tested with WinXP and perl, v5.8.0 built for MSWin32-x86-multi-thread
# Binary build 806 provided by ActiveState Corp. http://www.ActiveState.com
# Built 00:45:44 Mar 31 2003
#
# Tested also with Windows 2003 Server and perl, v5.8.4 built for MSWin32-x86-multi-thread
# Binary build 810
# Built Jun 1 2004 11:52:21
# ------------------------------
# Installing MySQL API into perl:
# (The interface requires Perl Version 5.6.0 or later)
# ppm> install DBI
# ppm> install DBD-MySQL
# ------------------------------
# Change History:
# 2004-11-22 jje - SQL script created for MySQL 4.0
# 2005-03-31 jje - Adapted for MySQL 4.1.1 and above (renamed columns UTC_TIME and UTC_DATE into UTCTIME and UTCDATE)
# 2005-04-04 jje - REMOTE_IP added into database
require 5.008;
use strict;
BEGIN { $ENV{PATH} = '/usr/ucb:/bin' }
use Socket;
use DBI;
# =======
# GLOBALS (that are used from the subroutines)
# =======
my $sth;
# ============
# SUBROUTINES
# ============
sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }
sub parsedgram {
my $datagram = shift;
my $remoteip = shift;
$datagram =~ s/\r//g; # remove characters
# extract IMEI
my $phone_id;
if ($datagram =~ /IMEI (\d+)\n/) {
$phone_id = $1;
}
if (defined $phone_id) {
print "phone_id: <$phone_id>\n";
}
# extract Label
my $label;
if ($datagram =~ /\nLabel ([\S ]*)\n/) {
$label = $1;
}
if (defined $label) {
print "label: <$label>\n";
}
# extract the entire NMEA sentence
my $nmea;
my ( $utc_time, $status, $lat_deg_part, $lat_min_part, $lat_n_or_s,
$long_deg_part, $long_min_part, $long_e_or_w, $speed_knots,
$course_deg, $utc_date );
my ( $latitude, $longitude );
if ($datagram =~ /(\$GPRMC,[\S ]*)\n/) {
$nmea = $1;
}
if (defined $nmea) {
print "NMEA: <$nmea>\n";
# extract individual NMEA fields
if ($datagram =~ /\$GPRMC,([\d\.]*),([AV]),(\d\d)([\d\.]*),([NS]),(\d\d\d)([\d\.]*),([EW]),([\d\.]*),([\d\.]*),(\d\d\d\d\d\d),[\S ]*\n/) {
$utc_time = $1;
$status = $2;
$lat_deg_part = $3;
$lat_min_part = $4;
$lat_n_or_s = $5;
$long_deg_part = $6;
$long_min_part = $7;
$long_e_or_w = $8;
$speed_knots = $9;
$course_deg = $10;
$utc_date = $11;
# convert latitude into decimal degrees
if ($lat_n_or_s =~ /S/) {
$latitude = "-";
}
else {
$latitude = "";
}
$latitude = $latitude . ($lat_deg_part + ($lat_min_part / 60));
print "latitude: <$latitude>\n";
# convert longitude into decimal degrees
if ($long_e_or_w =~ /W/) {
$longitude = "-";
}
else {
$longitude = "";
}
$longitude = $longitude . ($long_deg_part + ($long_min_part / 60));
print "longitude: <$longitude>\n";
# Insert into the SQL database
my $rc = $sth->execute( $phone_id, $status, $latitude, $longitude, $speed_knots, $course_deg,
$utc_time, $utc_date, $label, $remoteip )
or die "Can't execute statement: $DBI::errstr";
}
} # if (defined $nmea)
}
# ============
# MAIN PROGRAM
# ============
# Show version
# print "Perl version $]\n";
# Open database connection
# For MySQL
my $data_source = "dbi:mysql:gsmtrack";
my $user = "root";
my $password = shift || ""; # you may give password at the command line
# For MSSQL
# my $data_source = "dbi:ODBC:DSNGSMTRACK";
# my $user = "";
# my $password = "";
my $dbh = DBI->connect($data_source, $user, $password)
or die "Can't connect to $data_source: $DBI::errstr";
# If you get the following error with MySQL 4.1.1 or newer
#
# DBI connect('gsmtrack','root',...) failed: Client does not support authenticatio
# n protocol requested by server; consider upgrading MySQL client ...
#
# Reset the root password to pre-4.1 style as follows:
# mysql> SET PASSWORD = OLD_PASSWORD('newpwd');
#
# (See http://dev.mysql.com/doc/mysql/en/old-client.html)
# Prepare the SQL statement for fast execution
my $sql_stmt;
$sql_stmt = q{
INSERT INTO GPS (PHONE,STATUS,LATITUDE,LONGITUDE,SPEED_KNOTS,COURSE_DEG,UTCTIME,UTCDATE,LABEL,REMOTE_IP)
VALUES (?,?,?,?,?,?,?,?,?,?)
};
$sth = $dbh->prepare( $sql_stmt ) or die "Can't prepare statement: $DBI::errstr";
# Open the UDP socket
my $port = shift || 1002;
my $proto = getprotobyname('udp');
socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) || die "socket: $!";
bind(SOCKET, sockaddr_in($port, INADDR_ANY)) or die "bind: $!";
logmsg "server started on port $port";
my ( $hisiaddr, $hispaddr, $host, $rdatagram);
# loop forever
while (1) {
$rdatagram = '';
($hispaddr = recv(SOCKET, $rdatagram, 260, 0)) || die "recv: $!";
($port, $hisiaddr) = sockaddr_in($hispaddr);
$host = gethostbyaddr($hisiaddr, AF_INET);
print "\n";
logmsg "connection from $host [",
inet_ntoa($hisiaddr), "] at port $port";
# print $rdatagram;
parsedgram $rdatagram, inet_ntoa($hisiaddr);
}
# This is never actually reached due to the infinite loop above
$dbh->disconnect;
exit;
This file was generated by Gabriel Knoy's perl2html script.