#! /usr/bin/perl -w use threads; use threads::shared; use IO::Socket; use Device::SerialPort; use DateTime; $| = 1; my $listen = IO::Socket::INET->new( ReuseAddr => 1, Reuse => 1, Listen => SOMAXCONN, Proto => 'tcp', LocalAddr => 'localhost:9927', Timeout => 1 ) or die "Failed to create socket!\n"; our $usb_lock : shared; our $arduino = undef; sub getArduinoConnection { #my $oldport = shift; #$arduino->close() if defined; my $arduino = Device::SerialPort->new("/dev/serial/by-id/usb-Arduino__www.arduino.cc__Arduino_Mega_2560_74136333033351011152-if00"); if ( defined( $arduino ) ) { $arduino->baudrate(9600); $arduino->parity("none"); $arduino->databits(8); $arduino->stopbits(1); $arduino->read_char_time(0); $arduino->read_const_time(500); $arduino->write_settings || undef $arduino; writelog( "server:[portSet]" ); } else { writelog( "server:[portSet]: failed" ); } return $arduino; } .... sub handle_connection { #sleep( 1 ); my $socket = shift; my $local_arduino = shift; my $clientport = $socket->peerport(); $socket->autoflush(1); while ( my $cmd = <$socket> ) { # get full command or die my $count = 0; while ( !cmd_complete($cmd) ) { $cmd .= <$socket>; $count++; if ( $count > 20 ) { writelog( "server:" . $clientport . "[cmdInc]: no cmd end" ); return 0; } } chomp($cmd); writelog( "server:" . $clientport . "[cmdInc]: " . decode_cmd( $cmd ) ); { # send command to arduino lock( $usb_lock ); writelog( "server:" . $clientport . "[lockusb]" ); $local_arduino->write($cmd); # get arduinos answer my $answer = "."; while ( $answer ne "" ) { $answer = getLineFromArduino(); writelog( "server:" . $clientport . "[cmdAnswer]: $answer" ); #print $socket "$answer\n"; if ( $answer eq "Command end" ) { last; } } # respond to client if ( $answer eq "Command end" ) { writelog( "server:" . $clientport . "[sendToClient]: \"ok\"" ); print $socket "ok\n"; } else { writelog( "server:" . $clientport . "[sendToClient]: \"fail\"" ); print $socket "fail\n"; } writelog( "server:" . $clientport . "[unlockusb]" ); } return 1; } } my $last_validation = -10; #in the past #main loop while ( 1 ) { foreach $thr (threads->list) { # Don't join the main thread or ourselves #print $thr->tid; if ($thr->tid && $thr->is_joinable() ) { #&& !threads::equal($thr, threads->self) #$thr->join; } } # validate arduino every 10 seconds # sleep if arduino not alive if ( time > ( $last_validation + 30 ) ) { lock( $usb_lock ); $last_validation = time; $arduino = validateArduinoConnection( $arduino ); until ( defined( $arduino ) ) { $arduino = validateArduinoConnection( $arduino ); sleep( 1 ); } clearUSBdata(); } if (my $socket = $listen->accept) { #async(\&handle_connection, $socket); threads->create(\&handle_connection, $socket, $arduino ); } }