source: core/trunk/client/adsbclient.pl @ 411

Last change on this file since 411 was 399, checked in by smoser, 10 years ago

remove duplicate copyright information

  • Property svn:executable set to *
File size: 7.6 KB
Line 
1#!/usr/bin/perl
2#-------------------------------------------------------------------------------
3# This file is part of the FLARM®-Radar Project.
4#   
5#   Copyright by the Authors
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11#   http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
19#   Project Website: www.flarmradar.ch
20#   Email: info@flarmradar.ch
21#   Authors:
22#     2012-2014 Simon Moser
23#     2013-2014 Dominic Spreitz
24#     2014-2014 Giorgio Tresoldi
25#-------------------------------------------------------------------------------
26
27use strict;
28use warnings;
29use Getopt::Std;
30use File::Basename;
31use Time::HiRes qw(gettimeofday);
32use POSIX qw(strftime);
33use POSIX qw(setsid);
34use LWP::UserAgent;
35
36my %config;
37my %options;
38my $ua;
39my $debug = 0;
40my $trace = 0;
41my $interval = 3;
42my $skip = 1;
43
44# default values
45my $cfile = "/etc/adsbclient.conf";
46my $log = "$ENV{'HOME'}/flarmclient.trace";
47my $fifo = "/tmp/my_fifo";
48
49# functions
50sub usage {
51  print <<EOF;
52NAME
53  $0 -- stream flarm data to server
54
55SYNOPSIS
56  $0 [-c config_file] [-d] [-f data_file] [-i n] [-j m] [-t] [-h]
57
58DESCRIPTION
59  The following options are available:
60 
61  -c    Use the specified configuration file. Use the default configuration
62                file as a starting point for customization.
63               
64  -d    Write debug information. The debug information is written to STDOUT
65                unless tracing (option -t) is turned on. With tracing switched on,
66                the debug information is written to the trace file (see below).                 
67               
68  -f    Read the data from the specified data file. This is mainly used for
69                testing and development.
70
71  -i    Bundle records, send a request to the server every i-th GPGGA record.
72                Used for bandwidth optimization. Defaults to 3.
73               
74  -j    Send every j-th record to the server. Used for bandwidth
75                optimization. Defaults to 1.
76               
77  -t    Trace client operations. A trace file is created in
78                \$HOME/flarmclient.trace
79                WARNING: Do not use that in Production, the trace file is not truncated
80                and might fill up the file system.
81               
82  -h    Print this help.
83
84EOF
85  exit 0;
86}
87
88# print statistic information to logfile
89$SIG{USR1} = sub {
90        if ($trace) {
91                $trace = 0;
92        } else {
93                $trace = 1;
94        }
95};
96
97
98sub openlog {
99        if (tell(LOG) == -1) {
100                open(LOG, ">> $log") || print "Failed to open trace file $log: $!";
101        }
102        return 1;
103}
104
105sub logit {
106        my ($target, $msg) = @_;
107        if ($trace && $target eq "TRACE") {
108                openlog() && print LOG "$msg\n";
109        }
110        if ($debug && $target eq "DEBUG") {
111                print "$msg\n";
112                # if tracing is turned on, write debug messages also to the trace file
113                if ($trace) {
114                        openlog() && print LOG "$msg\n";
115                } 
116        }
117        if ($target eq "ALL") {
118                print "$msg\n";
119                # if tracing is turned on, write debug messages also to the trace file
120                if ($trace) {
121                        openlog() && print LOG "$msg\n";
122                } 
123        }
124}
125
126sub cleanup {
127        if (-e "$fifo") {
128                # print "$fifo vorhanden\n"
129                # unlink($fifo) || die("unable to remove $fifo: $!");
130        }
131        close(LOG);
132}
133
134sub readconfig {
135        open(CONF, "< $cfile") || die("failed to open config file for reading: $!");
136        while(my $line = <CONF>) {
137                chomp($line);
138                next if $line =~ /^\s*#/;
139                next if $line =~ /^\s*$/;
140                if ($line =~ /^\s*(\S*)\s*=\s*(\S*)\s*$/) {
141                        $config{$1} = $2;
142                }
143        }
144        close(CONF);
145}
146
147sub exact_time {
148        return strftime("%H:%M:%S", localtime()) . "." . (gettimeofday())[1];
149}
150
151# send the records to the server. We don't make a request for each record for
152# performance reasons.
153sub flush {
154        my ($records, $url) = @_;
155        # print "$records\n";
156        logit("DEBUG", exact_time() . " Start flushing data to server");
157       
158        my $date = `date -u +%Y/%m/%d`;
159        chomp($date);
160        my $resturl = $url . "/" . $date;
161        logit("DEBUG", exact_time() . " Request resource: " . $resturl);
162       
163        # compose the request
164        my $request = HTTP::Request->new('PUT');
165        $request->url($resturl);
166        $request->header('stationKey'=>$config{'key'});
167        my $content = compress($records);
168        logit("DEBUG", exact_time() . " Put on wire: " . $content);
169        $request->content($content);
170        # print "Content: $request\n";
171        # print "Records: $records\n";
172       
173        # run the request
174        logit("DEBUG", exact_time() . " Start server push");
175        my $response = $ua->request($request);
176        logit("DEBUG", exact_time() . " End server push");
177       
178        # analyze the response
179        my $code = $response->code;
180        $response->code == 200 || logit("DEBUG", "Error processing records (" . $response->code . ") records=[" . $records . "]");
181        logit("DEBUG", exact_time() . " End flushing data");
182        # print "Data flushing done.\n";
183}
184
185# remove all unused records, debug information, etc.
186sub compress {
187        my ($records) = @_;
188        my $on_wire;
189        foreach my $record (split(';', $records)) {
190                # print "$record\n";
191                if ($record =~ /^\$GPGGA,/ || $record =~ /^\$PFLAA,/) {
192                        $on_wire = (defined($on_wire)) ? $on_wire . ";" . $record : $record;
193                }               
194        }
195        return $on_wire;
196}
197
198# remove old leftovers
199cleanup();
200
201# parse options
202getopts('c:di:j:f:th', \%options);
203
204# read config file
205if (defined($options{'c'})) {
206        $cfile = $options{'c'};
207}
208if (defined($options{'d'})) {
209        $debug = 1;
210}
211if (defined($options{'i'})) {
212        $interval = $options{'i'};
213}
214if (defined($options{'j'})) {
215        $skip = $options{'j'}
216}
217if (defined($options{'h'})) {
218        usage();
219}
220if (defined($options{'t'})) {
221        $trace = 1;
222}
223
224# read config file
225readconfig();
226
227# validation: key must be present in config file
228die("no key found in config file " . $cfile . " (option: key)") unless defined($config{'key'});
229
230logit("ALL", "Start client, connect to " . $config{'url'});
231
232# create pipe
233die("no fifo found in config file (option: fifo)") unless defined($fifo);
234if (! -d dirname($fifo)) {
235        # system("mkdir", "-p", dirname($fifo)) == 0 || die("failed to create fifo directory " . dirname($fifo) . ": $!")
236}
237# system("mkfifo", $fifo) == 0 || die("failed to create fifo: $!");
238# print "mkfifo erfolgreich\n";
239# force a flush right away and after every write or print
240local $| = 1;
241
242# let the kernel raper dead childs
243$SIG{CHLD} = 'IGNORE';
244
245#fork minicom and write to pipe
246#defined( my $pid = fork() ) or die "can't fork: $!";
247#unless ($pid) {
248        # we're the child
249        # detach from session
250#    setsid() or die "can't start a new session: $!";
251#    close(STDIN);
252#       close(STDOUT);
253#       close(STDERR);
254       
255#       if (defined($options{'f'})) {
256#               open(DATA, "< $options{'f'}") || die("failed to open data file $options{'f'}: $!");
257#               open(FIFO, "> $fifo") || die("failed to open fifo for writing: $!");
258#               while(my $line = <DATA>) {
259#                       chomp($line);
260#                       next if ($line =~ /^\s*$/);
261#                       print FIFO $line, "\n" || die("failed to execute child command: $!");
262#               }
263#               close(DATA);
264#               close(FIFO);
265#       } else {
266#               exec("exec minicom -t xterm-color -C $fifo> /dev/null 2>&1") == 0 || die("failed to run minicom: $!");
267#       }
268#       exit 0;
269#}
270
271# create UserAgent object
272$ua = new LWP::UserAgent;
273my $buf;
274# read data from pipe
275open(FIFO, "< $fifo") || die("failed to open fifo for reading: $!");
276my $i = 0;
277while(my $record = <FIFO>) {
278        # print "Read data from pipe\n";
279        # send only n-th record to the server (option -s)
280        if ($i % $skip == 0) {
281                chomp($record);
282                logit("TRACE", $record);
283                $buf = (defined($buf)) ? "$buf;$record" : $record;
284        }
285       
286        # a GPGGA record terminates the sequence
287        if ($record =~ /^\$GPGGA,/) {
288                if ($i % ($interval * $skip) == 0) {
289                        #print "Flushing ...\n";
290                        flush($buf, $config{'url'}) ;
291                        $buf = undef;
292                        sleep($interval * $skip) if (defined($options{'f'})); 
293                }
294               
295                $i++;
296        }
297}
298close(FIFO);
299
300cleanup();
301exit 0;
302
Note: See TracBrowser for help on using the repository browser.