#!/usr/bin/perl

# e-Badge 1.0 (C)2005 Veit Wahlich <cru@zodia.de>
# Released under the terms of the GNU Public License, version 2 (GPLv2)

use strict;
use warnings;
use IO::File;
use POSIX;

# Default configuration
my $conf={
		version  => '1.0',
		port     => '/dev/ttyS0', # i.e. '/dev/ttyS0'
		baudrate => 1200,         # 1200 baud is required for the e-Badge
		stty_bin => '/bin/stty',  # path to the stty utility
		speed    => 2,            # range is 0..4
		repeat   => 0,            # range is 0..255, 0 means forever
		maxlen   => 150           # fixed to 150 characters
	};

sub main{
	my $text;
	parseArgs()
		|| do{
			showUsage();
			exit(1);
		};
	$text=constructText($ARGV[0],$conf->{speed},$conf->{repeat});
	if(-c $conf->{port}){
		if(defined($text)){
			sendString($text);
		}
		else{
			showUsage();
			exit(1);
		}
	}
	else{
		die($conf->{port}.' is no character device!'."\n");
	}
}

# parseArgs()
# Parse the command line arguments and set config settings
#
sub parseArgs{
	my $arg;
	if(@ARGV == 0){
		return(0);
	}
	while(@ARGV > 1){
		$arg=shift(@ARGV);
		if($arg eq '-d'){
			$conf->{port}=shift(@ARGV) || return(0);
		}
		elsif($arg eq '-s'){
			$arg=shift(@ARGV);
			if(defined($arg) && $arg=~/^[0-4]$/){
				$conf->{speed}=$arg;
			}
			else{
				return(0);
			}
		}
		elsif($arg eq '-b'){
			$arg=shift(@ARGV);
			if(defined($arg) && $arg=~/^300|600|1200|2400|4800|9600|19200|38400|57600|115200$/){
				$conf->{baudrate}=$arg;
			}
			else{
				return(0);
			}
		}
		elsif($arg eq '-r'){
			$arg=shift(@ARGV);
			if(defined($arg) && $arg=~/^[0-9]+$/ && $arg >= 0 && $arg <= 255){
				$conf->{repeat}=int($arg);
			}
			else{
				return(0);
			}
		}
		else{
			print(STDERR 'Unknown option: '.$arg."\n");
			return(0);
		}
	}
	return(1);
}

# sendString($string)
# Sends a control string to the LED ticker device
#
# Parameters:
#   $string     : string to send to the device
#
sub sendString{
	my($string)=@_;
	my $fd;
	return(undef) unless(defined($string));
	$fd=new IO::File($conf->{port},'w')
		|| die('Error opening port '.$conf->{port}.': '.$!."\n");
	system($conf->{stty_bin},'-F',$conf->{port},$conf->{baudrate})
		&& die('Error setting serial port rate using "'.$conf->{baudrate}.'": '.$!."\n");
	print($fd $string);
	$fd->close;
	return(1);
}

# $string=constructText($text,$speed,$sign_id,$page)
# Builds a text transfer control string for the LED ticker
#
# Parameters:
#   $text       : a text string that shall be displayed, max. 420 characters
#                 for page B, 80 chars for page A (reserved for logos)
#   $speed      : scroll speed, integer 0..4
#   $sign_id    : the LED ticker's ID, integer 0..255
#   $page       : page to programm, either 'A' or 'B'
#
# Returns:
#   $string     : the control string ready to be sent to device
#
sub constructText{
	my($text,$speed,$repeat)=@_;
	my $string;
	return(undef) unless(defined($text) && defined($speed) && defined($repeat));
	$text=substr($text,0,$conf->{maxlen});
	$string=sprintf('01%02x%02x%02x',$repeat,(((4-$speed)*16)+1),length($text)).$text;
	return($string);
}

# showUsage()
# Print usage info to STDOUT
#
sub showUsage{
	print(<<__END);

E-Badge Ticker $conf->{version} (C)2005 Veit Wahlich <cru\@zodia.de>

Syntax: $0 [OPTIONS] <text>

Options [defaults]:
  -d <device>       Device the transmitter is connected to [$conf->{port}]
  -b <baudrate>     The serial device baud rate; 300..115200 [$conf->{baudrate}]
  -s <speed>        Ticker scroll speed; 0 slow, 4 fast; 0..4 [$conf->{speed}]
  -r <iterations>   Iterations of the text; 0 means forever; 0..255 [$conf->{repeat}]

Notes:
  Maximum text length is 150 characters. Oversized text will be truncated.

__END
}

main();
1;
