source: core/trunk/client/flarmclient.pl @ 212

Last change on this file since 212 was 212, checked in by smoser, 12 years ago

#123

  • Property svn:mime-type set to text/plain
File size: 5.0 KB
Line 
1#!/usr/bin/perl
2#-------------------------------------------------------------------------------
3# This file is part of the FLARM¨-Radar Project.
4#   
5#   Copyright 2013 Netzschmiede GmbH (http://www.netzschmiede.ch)
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#-------------------------------------------------------------------------------
22
23use strict;
24use warnings;
25use Getopt::Std;
26use File::Basename;
27use POSIX qw(strftime);
28use POSIX qw(setsid);
29use LWP::UserAgent;
30
31my %config;
32my %options;
33my $ua;
34my $trace = 0;
35my $interval = 1;
36
37# default values
38my $log = "$ENV{'HOME'}/.flarmclient/client.trace";
39my $cfile = "$ENV{'HOME'}/.flarmclient/flarmclient.conf";
40my $fifo = "$ENV{'HOME'}/.flarmclient/client.fifo";
41
42# functions
43sub usage {
44  print <<EOF;
45NAME
46  $0 -- stream flarm data to server
47
48SYNOPSIS
49  $0 [-c config_file] [-f data_file] [-h]
50
51DESCRIPTION
52  The following options are available:
53 
54  -c    Use the specified configuration file. Use the default configuration
55                file as a starting point for customization.
56               
57  -i    Interval in seconds for sending data to the server. Defaults to one
58                second.
59               
60  -f    Read the data from the specified data file. This is mainly used for
61                testing and development.
62               
63  -h    Print this help.
64
65EOF
66  exit 0;
67}
68
69# print statistic information to logfile
70$SIG{USR1} = sub {
71        if ($trace) {
72                $trace = 0;
73        } else {
74                $trace = 1;
75        }
76};
77
78sub logit {
79        my ($level, $msg) = @_;
80        if ($trace) {
81                open(LOG, "> $log");
82                #print LOG localtime() . " $level $msg\n";
83                print LOG "$msg\n";
84                close(LOG);
85        }
86}
87
88sub cleanup {
89        if (-e "$fifo") {
90                unlink($fifo) || die("unable to remove $fifo: $!");
91        }
92}
93
94sub readconfig {
95        open(CONF, "< $cfile") || die("failed to open config file for reading: $!");
96        while(my $line = <CONF>) {
97                chomp($line);
98                next if $line =~ /^\s*#/;
99                next if $line =~ /^\s*$/;
100                if ($line =~ /^\s*(\S*)\s*=\s*(\S*)\s*$/) {
101                        $config{$1} = $2;
102                }
103        }
104        close(CONF);
105}
106
107# send the records to the server. We don't make a request for each record for
108# performance reasons.
109sub flush {
110        my ($records, $url) = @_;
111        logit("TRACE", $records);
112        my $date = strftime "%Y/%m/%d", localtime;
113        my $resturl = $url . "/" . $date;
114        my $request = HTTP::Request->new('PUT');
115        $request->url($resturl);
116        $request->header('stationKey'=>$config{'key'});
117        $request->content($records);
118        # run the request
119        my $response = $ua->request($request);
120        # analyze the response
121        my $code = $response->code;
122        $response->code == 200 || logit("ERROR", "error processing records (" . $response->code . ") records=[" . $records . "]");
123}
124
125# parse options
126getopts('c:i:f:h', \%options);
127
128# read config file
129if (defined($options{'c'})) {
130        $cfile = $options{'c'};
131}
132if (defined($options{'i'})) {
133        $interval = $options{'i'};
134}
135if (defined($options{'h'})) {
136        usage();
137}
138
139# read config file
140readconfig();
141
142# validation: key must be present in config file
143die("no key found in config file (option: key)") unless defined($config{'key'});
144
145# remove old leftovers
146cleanup();
147
148# create pipe
149die("no fifo found in config file (option: fifo)") unless defined($fifo);
150if (! -d dirname($fifo)) {
151        system("mkdir", "-p", dirname($fifo)) == 0 || die("failed to create fifo directory " . dirname($fifo) . ": $!")
152}
153system("mkfifo", $fifo) == 0 || die("failed to create fifo: $!");
154
155# force a flush right away and after every write or print
156local $| = 1;
157
158# fork minicom and write to pipe
159defined( my $pid = fork() ) or die "can't fork: $!";
160unless ($pid) {
161        # we're the child
162        # detach from session
163        setsid() or die "can't start a new session: $!";
164        close(STDIN);
165        close(STDOUT);
166        close(STDERR);
167       
168        if (defined($options{'f'})) {
169                open(DATA, "< $options{'f'}") || die("failed to open data file $options{'f'}: $!");
170                open(FIFO, "> $fifo") || die("failed to open fifo for writing: $!");
171                while(my $line = <DATA>) {
172                        chomp($line);
173                        next if ($line =~ /^\s*$/);
174                        print FIFO $line, "\n" || die("failed to execute child command: $!");
175                }
176                close(DATA);
177                close(FIFO);
178        } else {
179                exec("minicom", "-t", "xterm-color", "-C", $fifo) == 0 || die("failed to run minicom: $!");
180        }
181        exit 0;
182}
183
184# create UserAgent object
185$ua = new LWP::UserAgent;
186my $buf;
187# read data from pipe
188open(FIFO, "< $fifo") || die("failed to open fifo for reading: $!");
189my $i = 0;
190while(my $record = <FIFO>) {
191        chomp($record);
192        $buf = (defined($buf)) ? "$buf;$record" : $record;
193        if ($record =~ /^\$GPGGA,/) {
194                flush($buf, $config{'url'}) if ($i % $interval == 0);
195                if (defined($options{'f'})) {
196                        sleep(1);
197                }
198                $buf = undef;
199                $i++;
200        }
201}
202close(FIFO);
203
204cleanup();
205exit 0;
206
Note: See TracBrowser for help on using the repository browser.