#!/usr/bin/perl use Device::SerialPort; my $port_path = '/dev/ttyS1'; my %map = (); # devices.map file is a list # Message processing module must expose a gotMessage and a terminate method. # The gotMessage method receives the sender address and the data values as integer as arguments. open(my $f, ') { if($_ =~ /([0-9]{1, 3})\s+([a-z][a-z0-9_]+)/) { if(int($1) && -f $2.'.pm') { use $2; $map{int($1)} = $2; } } } close $f; our $end = 0; $SIG{'TERM'} = sub { $end = 1; }; my $port = Device::SerialPort->new($port_path) or die('Cannot open port !'); $port->baudrate(4800) or die('Failed to set baudrate !'); $port->parity('even') or die('Failed to set parity !'); $port->databits(8) or die('Failed to set data length !'); $port->stty_icml(1) or die('Failed to set cr as new line !'); $port->handshake('none') or die('Failed to set handshaking !'); $port->write_settings or die('Failed to write settings !'); sub readPort { my $port = shift; my ($n, $c) = $port->read(1); return ord($c); } sub fletcher { my $sum1 = 15, $sum2 = 15; $sum2 += ($sum1 += shift) for(my $i=0; $i<=17; $i++); $sum1 = ($sum1 & 0x0f) + int($sum1 / 16); $sum1 = ($sum1 & 0x0f) + int($sum1 / 16); $sum2 = ($sum2 & 0x0f) + int($sum2 / 16); $sum2 = ($sum2 & 0x0f) + int($sum2 / 16); return 16*$sum2 + $sum1; } my $i, $n, $c, @d, $s; while(!$end) { if(readPort($port) == 2) { # STX @d = (); for($i=0; $i<17; $i++) { push(@d, readPort($port)); } $s = readPort($port); if( (readPort($port) == 3) # ETX && $d[0] && (fletcher(@d) == $s) ) { eval $map{$d[0]}.'::gotMessage('.join(', ', @d).')' if(defined $map{$d[0]}); } } } my %m = (); $m{$map{$_}} = 1 foreach(keys %map); eval $_.'::terminate()' foreach(keys %m); undef $port; 0;