#!/usr/bin/perl use diagnostics; use Data::Dumper; use statemachine; use Event qw (loop unloop); use Config::General; use Thread; use IO::Handle; # read config file to use from commandline my $cfg = Config::General->new ("inet.cfg"); my %tmp = $cfg->getall(); &initAppControl ($tmp{'Inet'}); # TODO # how to set sequences to test inside of the loop? Timer Event which fires at deviceControl and appControl? # apparently, Event loop and "bidirectional named pipes" are in conflict with each other (pipes are blocked in reading), so testing is currently moved into a shell script print "Errors found in initialization: $!\n\n"; #### TESTING STATE MACHINE ### FSM only has direct access to the internet control device ### all other things must be handled by the handling script (PPP/UDEV events) my $sm = new statemachine( {config => $tmp{'Inet'} }); $sm->start(); my $cfd = $sm->{config}->{fifo}->{appControl}->{control}; print Dumper $sm; # set Event watchers on APP CONTROL # mapping commands -> FSM my $ctrlWatch = Event->io ( fd => ${$sm->{config}->{fifo}->{appControl}->{control}}, cb => sub { my $str = readline ($sm->{config}->{fifo}->{appControl}->{control}); my $fd = $sm->{config}->{fifo}->{appControl}->{status}; # check command if ($str =~ m/connect to device/i) { print "CONNECT TO DEVICE CMD\n"; $sm->connectDevice (); } elsif ($str =~ m/disconnect device/i) { print "DISCONNECT DEVICE CMD\n"; $sm->disconnectDevice (); } elsif ($str =~ m/connect to internet/i) { print "CONNECT TO INTERNET CMD\n"; $sm->connectInternetStart (); } elsif ($str =~ m/internet connected/i) { print "INTERNET CONNECTED CMD\n"; $sm->connectInternetComplete (); } elsif ($str =~ m/disconnect internet/i) { print "DISCONNECT INTERNET CMD\n"; $sm->connectInternetStop (); } print "EEEEEEE $str\n"; print $fd "EEEEEEE $str\n"; }); my $testsequenceThread = Thread->new (\&testSequence); $testsequenceThread->join (); loop; exit; sub testSequence () { # shorthands for pipe handles my $appControlFifo = $sm->{config}->{fifo}->{appControl}->{control}; my $deviceControlFifo = $sm->{config}->{fifo}->{deviceControl}; # autoflush pipes $| = 1; select ($appControlFifo); $| = 1; select ($deviceControlFifo); $| = 1; # test sequence print $appControlFifo "connect to device\n"; # state transition: 01 -> 02, currently automatically set print $deviceControlFifo "^MODE:1,1\n"; # state transition: 02 -> 03 # execution stops HERE unless pipe is not fed from Bash print "Instance>>> " . $sm->Instance . "\n"; if ($sm->Instance() =~ "Statemachine::03") # check if transition succeeded (kind of ASSERT) { print "transition succeeded\n"; } print $appControlFifo "connect to internet\n"; # state transition: 03 -> 04 print $appControlFifo "internet connected\n"; # state transition: 03 -> 04 } sub initAppControl () { my $config = shift; $config->{deviceControlCallback} = \&addDeviceControlCB; # create and open control FIFO if ('' eq (-p "$config->{fifoControl}->{status}" )) { POSIX::mkfifo ("$config->{fifoControl}->{status}", 0700); } if ('' eq (-p "$config->{fifoControl}->{control}" )) { POSIX::mkfifo ("$config->{fifoControl}->{control}", 0700); } # open pipes, set status pipe to "autoflush" open ($config->{fifo}->{appControl}->{control}, "+<", $config->{fifoControl}->{control}) || die "Could not open status pipe ($!)\n"; open ($config->{fifo}->{appControl}->{status}, "+>", $config->{fifoControl}->{status}) || die "Could not open control pipe ($!)\n"; $config->{fifo}->{appControl}->{status}->autoflush(1); } # callback for FSM when device is made available # mapping device events from deviceControl -> FSM sub addDeviceControlCB() { my $state = shift; # TODO Event shall be created only if deviceControl is available # -> move it into FSM? Possibly as a callback to FSM? # set Event watches of DEVICE CONTROL my $eventWatch = Event-> io ( fd => ${$sm->{config}->{fifo}->{deviceControl}}, cb => sub { my $str = readline ($sm->{config}->{fifo}->{deviceControl}); my $fd = $sm->{config}->{fifo}->{appControl}->{status}; # check status if ($str =~ m/\^MODE:(.*),(.*)/i) { if (($1 ne 0) && ($2 ne 0)) { print "devCtrl: LINK AVAILABLE ...\n"; # notify FSM $sm->setLink(); } else { print "devCtrl: LINK DROPPED\n"; # notify FSM $sm->clearLink(); } } elsif ($str =~ m/\^RSSI:(.*)/i) { if ($1 ne 0) { print "devCtrl: SIGNAL AVAILABLE\n"; # notify FSM $sm->setSignalStrength(); } else { print "devCtrl: SIGNAL DROPPED\n"; # notify FSM $sm->clearSignalStrength(); } } print "FFFFF $str\n"; print $fd "FFFFF $str\n"; }); }