Device-WS2500PC

 view release on metacpan or  search on metacpan

lib/Device/WS2500PC.pm  view on Meta::CPAN

	my $data = shift;
	my $result = '';

	return "<no data>" if $data eq '';

	for (my $x=0;$x<length($data);$x++) { 
		my $char = substr($data,$x,1);
		my $printed = 0;

		foreach (keys %{$data{'markers'}}) {
			if ($char eq $data{'markers'}->{$_} and !$printed) {
				$result.=sprintf("<%s> ",$_);
				$printed=1;
			}
		}
		$result.=sprintf("%02X ",ord($char)) unless $printed;
	}

	return $result;
}

# Sends a command to the interface
# This subroutine only encodes and sends a message, it does not care wether
# the sent message has been received/acknowledged or not
# Params: token  A command from $data{'commands'}
#         param  An optional parameter containing additional data
# Return: 1      Always true
sub send_Command {
	my $token = shift;
	my ($checksum,$message,$command,$param);
	
	# Is this a valid command, when not die as this is an internal error
	die "Unknown command '$token'" unless exists $data{'commands'}->{$token};
	$param='';
	$param = shift if scalar @_;
	$command = $data{'commands'}->{$token}.$param;

	# Checksum is negative sum of command value, Bit 7 always set
	foreach (split //, $command) { $checksum+=ord($_); }
	$checksum = (0x100-($checksum & 0xFF)) | 0x80;
	
	# Build message and write to port
	$message = $data{'markers'}->{'SOH'}.$command.chr($checksum).$data{'markers'}->{'EOT'};
	print "Sending '$token': ".(printhex($message))."\n" if $data{'debug'};
	$data{'port'}->write ($message);
	# Bad hack, we have to wait until the command is processed
	# Otherwise we will read only partial data
	sleep (0.03);

	return 1;
}

# Reads a response from the interface
# This routine reads a message from the interface, decodes it and does all integrity checking
# Params: bytes_expected  The number of *message* bytes expected, -1 if not known
#         response        A hash-reference which will be filled with the reponse
# Return: 1               Always true
# The filled in hash reference has the following keys:
# {ok}          1 if the response has been valid and passed all checks, 0 upon failure
# {raw}         Actual data received from the interface
# {message}     The actual message, already decoded without any headers
# {datalength}  The lenght in bytes of the message
# {checksum}    The checksum of the message
sub read_Response ($;$) {
	my $bytes_expected = shift;
	my $response	   = shift;
	
	print "Reading Response ... \n" if $data{'debug'};
	
	# Read data
	# As we do not know how many bytes we expect (due to special char encoding)
	# we poll as long we receive any data in a reasonable interval -> again a bad hack
	$$response{'raw'}='';
	while (my $received=$data{'port'}->read (100)) {
		$$response{'raw'}.=$received;
		sleep (0.01);
	}

	# Did we receive a message with a least 5 bytes (shortest possible message)
	if (length($$response{'raw'})>=5) {
		$$response{'ok'}  = 1;
		# First decode any message sequences for STX/ETX/ENQ
		$$response{'message'} = '';
		for (my $x=1;$x<=length($$response{'raw'})-2;$x++) {
			my $char1 = substr($$response{'raw'},$x,1);
			my $char2 = substr($$response{'raw'},$x+1,1);
			if ($char1 eq $data{'markers'}->{'ENQ'}) {
				if    ($char2 eq $data{'markers'}->{'DC2'}) { $char1 = $data{'markers'}->{'STX'} }
				elsif ($char2 eq $data{'markers'}->{'DC3'}) { $char1 = $data{'markers'}->{'ETX'} }
				elsif ($char2 eq $data{'markers'}->{'NAK'}) { $char1 = $data{'markers'}->{'ENQ'} }
				else  { 
					$$response{'ok'} = 0;
					print "ERROR: Unknown encoding char ".(ord($char2))."\n" if $data{'debug'};
				};
				$x++;
			};
			# WTF ? This isn't documented anywhere ? 
			if (ord($char1)==0xff and ord($char2)==0xff) {
				$x++;
			}
			$$response{'message_all'}.= $char1;
		}
		$$response{'message'} = substr($$response{'message_all'},1,ord(substr($$response{'message_all'},0,1)));
		# Check if the received frame is consistent
		$$response{'datalength'} = ord(substr($$response{'message_all'},0,1));
		$$response{'checksum'}   = ord(substr($$response{'message_all'},length($$response{'message_all'})-1,1));
		# Did we receive enough data
		if ($bytes_expected!=-1 and $$response{'datalength'}!=$bytes_expected and $$response{'ok'}) {
			$$response{'ok'} = 0; 
			print "ERROR: Expected datalength is not correct\n" if $data{'debug'};
		};
		# Are the start and end markers ok ?
		if (substr($$response{'raw'},0,1) ne $data{'markers'}->{'STX'} and $$response{'ok'}) {
			$$response{'ok'} = 0;
			print "ERROR: Start marker not found\n" if $data{'debug'};
		}
		if (substr($$response{'raw'},length($$response{'raw'})-1,1) ne $data{'markers'}->{'ETX'} and $$response{'ok'}) {
			$$response{'ok'} = 0;
			print "ERROR: End marker not found\n" if $data{'debug'};
		}
		# Check for a error message from the interface



( run in 0.653 second using v1.01-cache-2.11-cpan-2398b32b56e )