diff --git a/src/mod/endpoints/mod_skinny/Net/Skinny.pm b/src/mod/endpoints/mod_skinny/Net/Skinny.pm index 93b0f3056d..e0ae460eac 100644 --- a/src/mod/endpoints/mod_skinny/Net/Skinny.pm +++ b/src/mod/endpoints/mod_skinny/Net/Skinny.pm @@ -16,7 +16,7 @@ sub new { shift->SUPER::new(PeerPort => 2000, @_); } -sub send_message +sub send_data { my $self = shift; my $type = shift; @@ -29,6 +29,17 @@ sub send_message printf ".\n"; } +sub send_message +{ + my $self = shift; + my $type = shift; + return Net::Skinny::Message->new( + $self, + $type, + @_ + )->send(); +} + sub receive_message { my $self = shift; diff --git a/src/mod/endpoints/mod_skinny/Net/Skinny/Message.pm b/src/mod/endpoints/mod_skinny/Net/Skinny/Message.pm index e16e39aeb8..e69a80f4ba 100644 --- a/src/mod/endpoints/mod_skinny/Net/Skinny/Message.pm +++ b/src/mod/endpoints/mod_skinny/Net/Skinny/Message.pm @@ -7,4 +7,52 @@ package Net::Skinny::Message; use strict; use warnings; +use Net::Skinny::Protocol qw/:all/; +use Data::Dumper; + +require Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(send); + +sub new { + my $class = shift; + my $self = {}; + bless $self, $class; + $self->{'socket'} = shift; + $self->{'type'} = shift; + %{$self->{'data'}} = @_; + return $ self; +} + +sub send { + my $self = shift; + my $struct = Net::Skinny::Protocol::skinny_message_struct($self->{'type'}); + my $raw = ''; + my $parsed_count = 0; + for my $info ( @$struct) { + last if !defined($self->{'data'}{@$info[1]}); + if(@$info[0] eq 'char') { + $raw .= pack("a".@$info[2], $self->{'data'}{@$info[1]}); + } elsif(@$info[0] eq 'uint32_t') { + $raw .= pack("V".@$info[2], $self->{'data'}{@$info[1]}); + } elsif(@$info[0] eq 'uint16_t') { + $raw .= pack("n".@$info[2], $self->{'data'}{@$info[1]}); + } elsif(@$info[0] eq 'struct in_addr') { + $raw .= pack("V".@$info[2], $self->{'data'}{@$info[1]}); + } elsif(@$info[0] eq 'struct station_capabilities') { + $raw .= $self->{'data'}{@$info[1]}; + } else { + printf "Unknown type: %s\n", @$info[0]; + return; + } + $parsed_count++; + } + if($parsed_count != scalar(keys %{$self->{'data'}})) { + printf "Incomplete message: %d out of %d\n", $parsed_count, scalar(keys %{$self->{'data'}}); + return; + } + $self->{'socket'}->send_data($self->{'type'}, $raw); +} + +1; diff --git a/src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm b/src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm index a8b502e816..bfe0202787 100644 --- a/src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm +++ b/src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm @@ -8,13 +8,16 @@ use strict; no strict "refs"; use warnings; use Carp; +use Data::Dumper; require Exporter; our @ISA = qw(Exporter); -our @EXPORT = qw(skinny_message_type2str); +our @EXPORT = qw(skinny_message_type2str skinny_message_struct); my %const; my %sub; +my %struct; + my $skinny_protocol_h = 'src/mod/endpoints/mod_skinny/skinny_protocol.h'; sub import { @@ -46,6 +49,27 @@ sub _find { my ($name, $value) = ($1,hex($2)); $sub{$name} = sub () { $value }; $const{$name} = $value; + } elsif(/^\s*struct\s+([a-z_]+)\s*\{\s*$/) { + my $struct_name = $1; + $struct{$struct_name} = []; + while(<$fh>) { + if(/^\s*\}\s*;\s*$/) { + last; + } elsif(/^\s*(((struct)\s+)?([a-z_0-9]+))\s+([a-z_0-9]+)(\[([0-9A-Z_]+)\])?\s*;?\s*(\/\*.*\*\/)?\s*$/) { + my $var_name = $1; + my $var_type = $5; + my $var_size = $7; + $var_size = 1 if !defined($var_size); + push @{$struct{$struct_name}}, [$var_name, $var_type, $var_size]; + } elsif(/^\s*union\s*skinny_data data;\s*$/) { + # union + } elsif(/^\s*(\/\*.*\*\/)?\s*$/) { + # Simple comment + } else { + printf "Unparsed line '%s' in %s\n", $_, $struct_name; + } + } + #print "$name: ".Dumper($struct{$name}); } } @sub{@_}; @@ -62,3 +86,10 @@ sub skinny_message_type2str { } return "UnknownMessage"; } + +sub skinny_message_struct { + my $message_type = shift; + my $struct_name = lc(Net::Skinny::Protocol::skinny_message_type2str($message_type)); + return $struct{$struct_name}; +} + diff --git a/src/mod/endpoints/mod_skinny/test-skinny.pl b/src/mod/endpoints/mod_skinny/test-skinny.pl index 3cf207e1dc..4821fc9b50 100644 --- a/src/mod/endpoints/mod_skinny/test-skinny.pl +++ b/src/mod/endpoints/mod_skinny/test-skinny.pl @@ -11,9 +11,9 @@ BEGIN { use strict; use warnings; -use Data::Dumper; use Net::Skinny; use Net::Skinny::Protocol qw/:all/; +use Net::Skinny::Message; #Config my $skinny_server = '127.0.0.1'; @@ -32,50 +32,58 @@ if(!$socket) { exit 1; } # ============================================================================= -$socket->send_message(REGISTER_MESSAGE, # Register - pack("a16VVVVV", - $device_name, - 0, # userId; - 1, # instance; - $device_ip,# ip; - 7, # deviceType; - 0, # maxStreams; - )); +$socket->send_message( + REGISTER_MESSAGE, + device_name => $device_name, + user_id => 0, + instance => 1, + ip => $device_ip, + device_type => 7, + max_streams => 0, + ); $socket->receive_message(); # RegisterAck -$socket->send_message(0x0002, # Port - pack("n", 2000 - )); - -$socket->send_message(HEADSET_STATUS_MESSAGE, - pack("V", - 2, # Off - )); +$socket->send_message( + PORT_MESSAGE, + port => 2000, + ); +$socket->send_message( + HEADSET_STATUS_MESSAGE, + mode => 2, #Off + ); $socket->receive_message(); # CapabilitiesReq -$socket->send_message(CAPABILITIES_RES_MESSAGE, - pack("V"."Vva10"."Vva10", - 2, # count - 2, 8, "", # codec, frames, res - 4, 16, "", # codec, frames, res - )); +$socket->send_message( + CAPABILITIES_RES_MESSAGE, + count => 2, + caps => pack("Vva10"."Vva10", + 2, 8, "", # codec, frames, res + 4, 16, "", # codec, frames, res + ) + ); -$socket->send_message(BUTTON_TEMPLATE_REQ_MESSAGE, ""); +$socket->send_message(BUTTON_TEMPLATE_REQ_MESSAGE); $socket->receive_message(); # ButtonTemplateMessage -$socket->send_message(SOFT_KEY_TEMPLATE_REQ_MESSAGE, ""); +$socket->send_message(SOFT_KEY_TEMPLATE_REQ_MESSAGE); $socket->receive_message(); # SoftKeyTemplateRes -$socket->send_message(SOFT_KEY_SET_REQ_MESSAGE, ""); +$socket->send_message(SOFT_KEY_SET_REQ_MESSAGE); $socket->receive_message(); # SoftKeySetRes -$socket->send_message(LINE_STAT_REQ_MESSAGE, pack("V", 1)); +$socket->send_message( + LINE_STAT_REQ_MESSAGE, + number => 1, + ); $socket->receive_message(); # LineStat -$socket->send_message(REGISTER_AVAILABLE_LINES_MESSAGE, pack("V", 2)); +$socket->send_message( + REGISTER_AVAILABLE_LINES_MESSAGE, + count => 2 + ); while(1) { $socket->sleep(20); - $socket->send_message(KEEP_ALIVE_MESSAGE, ""); + $socket->send_message(KEEP_ALIVE_MESSAGE); $socket->receive_message(); # keepaliveack }