reorg source code tree to make trunk
authorDobrica Pavlinusic <dpavlin@rot13.org>
Fri, 26 Oct 2007 11:42:39 +0000 (11:42 +0000)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Fri, 26 Oct 2007 11:42:39 +0000 (11:42 +0000)
git-svn-id: https://perl-cwmp.googlecode.com/svn/trunk@111 836a5e1a-633d-0410-964b-294494ad4392

39 files changed:
Makefile.PL [new file with mode: 0644]
bin/acs.pl [new file with mode: 0755]
bin/cli.pl [new file with mode: 0755]
bin/dump.pl [new file with mode: 0755]
lib/CWMP.pod [new file with mode: 0644]
lib/CWMP/Request.pm [new file with mode: 0644]
lib/CWMP/Response.pm [new file with mode: 0644]
lib/CWMP/Server.pm [new file with mode: 0644]
lib/CWMP/Session.pm [new file with mode: 0644]
lib/CWMP/Store.pm [new file with mode: 0644]
lib/CWMP/Tree.pm [new file with mode: 0644]
lib/CWMP/_MODULE.pm [new file with mode: 0644]
net.sh [new file with mode: 0755]
t/00-load.t [new file with mode: 0755]
t/05-store.t [new file with mode: 0755]
t/07-tree.t [new file with mode: 0755]
t/10-request.t [new file with mode: 0755]
t/20-response.t [new file with mode: 0755]
t/30-server.t [new file with mode: 0755]
t/SpeedTouch-706/Fault.pl [new file with mode: 0644]
t/SpeedTouch-706/Fault.xml [new file with mode: 0644]
t/SpeedTouch-706/GetParameterNamesResponse.pl [new file with mode: 0644]
t/SpeedTouch-706/GetParameterNamesResponse.xml [new file with mode: 0644]
t/SpeedTouch-706/GetRPCMethodsResponse.pl [new file with mode: 0644]
t/SpeedTouch-706/GetRPCMethodsResponse.xml [new file with mode: 0644]
t/SpeedTouch-706/Inform.pl [new file with mode: 0644]
t/SpeedTouch-706/Inform.xml [new file with mode: 0644]
t/SpeedTouch-780/Fault.pl [new file with mode: 0644]
t/SpeedTouch-780/Fault.xml [new file with mode: 0644]
t/SpeedTouch-780/GetParameterNamesResponse.pl [new file with mode: 0644]
t/SpeedTouch-780/GetParameterNamesResponse.xml [new file with mode: 0644]
t/SpeedTouch-780/GetRPCMethodsResponse.pl [new file with mode: 0644]
t/SpeedTouch-780/GetRPCMethodsResponse.xml [new file with mode: 0644]
t/SpeedTouch-780/Inform.pl [new file with mode: 0644]
t/SpeedTouch-780/Inform.xml [new file with mode: 0644]
t/_MODULE.t [new file with mode: 0755]
t/data/http-chunked [new file with mode: 0644]
t/pod-coverage.t [new file with mode: 0755]
t/pod.t [new file with mode: 0755]

diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..bc8ee72
--- /dev/null
@@ -0,0 +1,22 @@
+use inc::Module::Install;
+
+name           'CWMP';
+version                '0.04';
+license                'GPL';
+requires       'Net::Server';
+requires       'HTTP::Daemon';
+requires       'XML::Rules';
+requires       'XML::Generator';
+requires       'Data::Dump';
+requires       'Carp';
+requires       'Class::Accessor';
+requires       'Net::HTTP';
+requires       'Cwd';
+requires       'File::Slurp';
+requires       'DBM::Deep';
+requires       'Getopt::Long';
+requires       'Term::Shelly'  =>      '0.03';
+
+auto_install;
+
+WriteAll;
diff --git a/bin/acs.pl b/bin/acs.pl
new file mode 100755 (executable)
index 0000000..39e4d0f
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/perl -w
+
+# acs.pl
+#
+# 06/18/07 09:19:54 CEST Dobrica Pavlinusic <dpavlin@rot13.org>
+
+use strict;
+
+use lib './lib';
+use CWMP::Server;
+use Getopt::Long;
+
+my $port = 3333;
+my $debug = 0;
+my $store_path = 'state.db';
+
+GetOptions(
+       'debug+' => \$debug,
+       'port=i' => \$port,
+       'store-path=s' => \$store_path,
+);
+
+my $server = CWMP::Server->new({
+       port => $port,
+       store_path => $store_path,
+       debug => $debug,
+       default_queue => [ qw/
+               GetRPCMethods
+               GetParameterNames
+       / ],
+#              Reboot
+});
+$server->run();
+
diff --git a/bin/cli.pl b/bin/cli.pl
new file mode 100755 (executable)
index 0000000..b00088e
--- /dev/null
@@ -0,0 +1,138 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib 'lib';
+
+use Term::Shelly;
+use CWMP::Store;
+use CWMP::Tree;
+use DBM::Deep;
+use Data::Dump qw/dump/;
+use Getopt::Long;
+use Carp qw/confess/;
+
+my $debug = 0;
+my $store_path = 'state.db';
+
+GetOptions(
+       'debug+' => \$debug,
+       'store-path=s' => \$store_path,
+);
+
+my $sh = Term::Shelly->new();
+my $tree = CWMP::Tree->new({ debug => $debug });
+
+our $store = CWMP::Store->new({
+       debug => $debug,
+       path => $store_path,
+});
+
+$sh->out(
+"You can issue commenads in form using tab-complete:
+
+CPE_Serial ( parametar [ [=] value ] | command )
+"
+);
+
+$sh->{"completion_function"} = \&completer;
+$sh->{"readline_callback"} = \&command;
+
+my @history = ( 'exit' );
+my $pos = $#history;
+$sh->{'mappings'}->{'up-history'} = [ sub {
+       my $self = shift;
+       if ( $pos >= 0 ) {
+               $self->{'input_line'} = $history[ $pos ];
+               $pos--;
+               $self->{'input_position'} = length( $self->{'input_line'} );
+               $self->fix_inputline;
+       }
+} ];
+$sh->{'mappings'}->{'down-history'} = [ sub {
+       my $self = shift;
+       my $line = '';
+       if ( $pos < $#history ) {
+               $pos++;
+               $line = $history[ $pos ];
+       }
+       $self->{'input_line'} = $line;
+       $self->{'input_position'} = length( $self->{'input_line'} );
+       $self->fix_inputline;
+} ];
+
+$sh->prompt( '> ' );
+
+while (1) {
+       $sh->do_one_loop();
+}
+
+sub completer {
+       my ($line, $bword, $pos, $curword) = @_;
+
+       $sh->out( "line: '$line' [ $bword - $pos ] -> '$curword'" );
+
+       my @matches;
+
+       # do we have list (part) of CPE?
+       if ( $line =~ /^(\S*)\s*$/ ) {
+               @matches = sort grep { /^\Q$curword\E/ } $store->known_CPE;
+               $sh->out( "CPE available: ", join(",", @matches ) );
+       } elsif ( $line =~ /^(\w+)\s+(\S+)$/ ) {
+               $sh->out("finding completes for '$2'");
+               my ( $cpe_uid, $name ) = ( $1, $2 );
+
+               my $beginning = $name;
+               my $part = '';
+               if ( $beginning =~ s/\.([^\.]+)$// ) {
+                       $part = $1;
+               } elsif ( $beginning =~ s/^(\S+)$// ) {
+                       $part = $1;
+               } else {
+                       confess "can't extract suffix";
+               }
+
+               $sh->out( "## $cpe_uid ## beginning: $beginning -- part: $part" );
+               my $perl = "\$store->db->{state}->{'$cpe_uid'}->{ParameterInfo}";
+               $perl .= '->' . $tree->name2perl( $beginning ) if ( defined( $beginning ) && $beginning ne '' );
+               $sh->out( "## $cpe_uid ## $perl" );
+
+               @matches = eval "keys %{ $perl }";
+
+       }
+
+       return @matches;
+}
+
+sub command {
+       my ( $line ) = @_;
+
+       return unless ( $line && $line ne '' );
+
+       # just CPE uid
+       if ( $line =~ /^(\w+)\s*$/ ) {
+               if ( main->can( $1 ) ) {
+                       $sh->out( "# execute command $1" );
+                       eval " \&$1( \$line ) ";
+               } elsif ( defined ( $store->db->{state}->{$1} ) ) {
+                       $sh->out(
+                               join(" ", keys %{ $store->db->{state}->{$1}->{ParameterInfo} })
+                       );
+                       push @history, $line;
+                       $pos = $#history;
+               } else {
+                       $sh->out( "$line: CPE not found" );
+               }
+       } else {
+               $sh->out( "$line: command not recognized" );
+       }
+}
+
+sub history {
+       $sh->out( "history: ", dump ( @history ) );
+}
+
+sub exit {
+       CORE::exit();
+}
diff --git a/bin/dump.pl b/bin/dump.pl
new file mode 100755 (executable)
index 0000000..c96bc95
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/perl -w
+
+# dump.pl
+#
+# 06/22/07 16:23:05 CEST Dobrica Pavlinusic <dpavlin@rot13.org>
+
+use strict;
+use DBM::Deep;
+use Data::Dump qw/dump/;
+
+my $path = shift @ARGV || 'state.db'; #die "usage: $0 state.db";
+
+my $db = DBM::Deep->new(
+       file => $path,
+);
+
+warn "file: $path\n";
+print dump( $db );
diff --git a/lib/CWMP.pod b/lib/CWMP.pod
new file mode 100644 (file)
index 0000000..c3591b3
--- /dev/null
@@ -0,0 +1,37 @@
+=head1 NAME
+
+CWMP - CPE WAN Management Protocol
+
+=head1 DESCRIPTION
+
+  CPE methods             Responding  Calling
+  GetRPCMethods           Required    Optional
+  SetParameterValues      Required    Required
+  GetParameterValues      Required    Required
+  GetParameterNames       Required    Required
+  SetParameterAttributes  Required    Optional
+  GetParameterAttributes  Required    Optional
+  AddObject               Required    Optional
+  DeleteObject            Required    Optional
+  Reboot                  Required    Optional
+  Download                Required    Required
+  Upload                  Optional    Optional
+  FactoryReset            Optional    Optional
+  GetQueuedTransfers      Optional    Optional
+  ScheduleInform          Optional    Optional
+  SetVouchers             Optional    Optional
+  GetOptions              Optional    Optional
+
+  Server methods   Calling    Responding
+  GetRPCMethods    Optional   Required
+  Inform           Required   Required
+  TransferComplete Required   Required
+  RequestDownload  Optional   Optional
+  Kicked           Optional   Optional
+
+
+=head1 AUTHOR
+
+Dobrica Pavlinusic, C<< dpavlin@rot13.org >>
diff --git a/lib/CWMP/Request.pm b/lib/CWMP/Request.pm
new file mode 100644 (file)
index 0000000..eb1b577
--- /dev/null
@@ -0,0 +1,157 @@
+package CWMP::Request;
+
+use warnings;
+use strict;
+
+use XML::Rules;
+use CWMP::Tree;
+use Data::Dump qw/dump/;
+use Carp qw/confess cluck/;
+
+=head1 NAME
+
+CWMP::Request - parse SOAP request
+
+=head1 METHODS
+
+=head2 _tag
+
+Get value of tag. Tag name is case insensitive (don't ask why),
+we ignore namespaces and can take optional C<sub_key>
+(usually C<_content>).
+
+  _tag( $tag_hash, $name, $sub_key )
+
+=cut
+
+sub _tag {
+       my ( $tag_hash, $name, $sub_key ) = @_;
+       confess "need hash as first argument" unless ( ref $tag_hash eq 'HASH' );
+       $name = (grep { m/^(?:\w+:)*$name$/i } keys %$tag_hash )[0];
+#      $name =~ s/^\w+://;
+       if ( defined $tag_hash->{$name} ) {
+               if ( ! defined $sub_key ) {
+                       return $tag_hash->{$name};
+               } elsif ( defined $tag_hash->{$name}->{$sub_key} ) {
+                       return $tag_hash->{$name}->{$sub_key};
+               } else {
+                       return if ( $name =~ m/^value$/i );
+                       warn "can't find '$name/$sub_key' in ", dump( $tag_hash );
+                       return;
+               }
+       } else {
+               warn "can't find '$name' in ", dump( $tag_hash );
+               return;
+       }
+}
+
+our $state;    # FIXME check this!
+
+my $tree = CWMP::Tree->new({ debug => 0 });
+
+my $parser = XML::Rules->new(
+#      start_rules => [
+#              '^division_name,fax' => 'skip',
+#      ],
+       namespaces => {
+               'http://schemas.xmlsoap.org/soap/envelope/' => 'soapenv',
+               'http://schemas.xmlsoap.org/soap/encoding/' => 'soap',
+               'http://www.w3.org/2001/XMLSchema' => 'xsd',
+               'http://www.w3.org/2001/XMLSchema-instance' => 'xsi',
+               'urn:dslforum-org:cwmp-1-0' => '',
+       },
+       rules => [
+               #_default => 'content trim',
+               x_default => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       warn dump( $tag_name, $tag_hash, $context );
+               },
+               'ID' => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       $state->{ID} = $tag_hash->{_content};
+               },
+               #
+               # Inform
+               #
+               'Inform' => sub {
+                       $state->{_dispatch} = 'InformResponse';         # what reponse to call
+               },
+               'DeviceId' => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       foreach my $name ( keys %$tag_hash ) {
+                               next if $name eq '_content';
+                               my $key = $name;
+                               $key =~ s/^\w+://;      # stip namespace
+                               $state->{DeviceID}->{ $key } = _tag( $tag_hash, $name, '_content' );
+                       }
+               },
+               'EventStruct' => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       push @{ $state->{EventStruct} }, $tag_hash->{EventCode}->{_content};
+               },
+               qr/(MaxEnvelopes|CurrentTime|RetryCount)/ => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       $state->{$tag_name} = $tag_hash->{_content};
+               },
+               'ParameterValueStruct' => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       # Name/Value tags must be case insnesitive
+                       my $value = (grep( /value/i, keys %$tag_hash ))[0];
+                       $state->{Parameter}->{ _tag($tag_hash, 'Name', '_content') } = _tag($tag_hash, 'Value', '_content' );
+               },
+               #
+               # GetRPCMethodsResponse
+               #
+               qr/^(?:^\w+:)*string$/ => 'content array',
+               'MethodList' => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       $state->{MethodList} = _tag( $tag_hash, 'string' );
+               },
+               #
+               # GetParameterNamesResponse
+               #
+               'ParameterInfoStruct' => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       my $name = _tag($tag_hash, 'Name', '_content');
+                       my $writable = _tag($tag_hash, 'Writable', '_content' );
+
+                       confess "need state" unless ( $state ); # don't remove!
+
+                       # XXX dragons ahead: convert name to tree rewriting it into perl
+                       my $s = '$state->{ParameterInfo}->' . $tree->name2perl( $name ) . "->{writable} = $writable;";
+                       eval "$s";
+                       confess "can't eval $s : $@" if ($@);
+
+                       #warn "## state = dump( $state ), "\n";
+               },
+               #
+               # Fault
+               #
+               'Fault' => sub {
+                       my ($tag_name, $tag_hash, $context, $parent_data) = @_;
+                       $state->{Fault} = {
+                               FaultCode => _tag( $tag_hash, 'FaultCode', '_content' ),
+                               FaultString => _tag( $tag_hash, 'FaultString', '_content' ),
+                       };
+                       warn "FAULT: ", $state->{Fault}->{FaultCode}, " ", $state->{Fault}->{FaultString}, "\n";
+               }
+       ]
+);
+
+=head2 parse
+
+  my $state = CWMP::Request->parse( "<soap>request</soap>" );
+
+=cut
+
+sub parse {
+       my $self = shift;
+
+       my $xml = shift || confess "no xml?";
+
+       $state = {};
+       $parser->parsestring( $xml );
+       return $state;
+}
+
+1;
diff --git a/lib/CWMP/Response.pm b/lib/CWMP/Response.pm
new file mode 100644 (file)
index 0000000..6b2a866
--- /dev/null
@@ -0,0 +1,134 @@
+package CWMP::Response;
+
+use strict;
+use warnings;
+
+
+use base qw/Class::Accessor/;
+__PACKAGE__->mk_accessors( qw/debug/ );
+
+use XML::Generator;
+use Carp qw/confess/;
+use Data::Dump qw/dump/;
+
+=head1 NAME
+
+CWMP::Response - generate SOAP meesage for response
+
+=head2 METHODS
+
+=head2 new
+
+  my $response = CWMP::Response->new({ debug => 1 });
+
+=cut
+
+sub new {
+       my $class = shift;
+       my $self = $class->SUPER::new( @_ );
+
+       warn "created XML::Generator object\n" if $self->debug;
+
+       return $self;
+}
+
+
+my $cwmp = [ cwmp => 'urn:dslforum-org:cwmp-1-0' ];
+my $soap = [ soap => "http://schemas.xmlsoap.org/soap/envelope/" ];
+
+=head2 InformResponse
+
+  $response->InformResponse( $state );
+
+=cut
+
+sub InformResponse {
+       my ( $self, $state ) = @_;
+       $self->xml( $state, sub {
+               my ( $X, $state ) = @_;
+               $X->InformResponse( $cwmp,
+                       $X->MaxEnvelopes( $cwmp, 1 )
+               );
+       });
+}
+
+=head2 GetRPCMethods
+
+  $response->GetRPCMethods( $state );
+
+=cut
+
+sub GetRPCMethods {
+       my ( $self, $state ) = @_;
+       $self->xml( $state, sub {
+               my ( $X, $state ) = @_;
+               $X->GetRPCMethods();
+       });
+};
+
+=head2 Reboot {
+
+  $response->Reboot( $state );
+
+=cut
+
+sub Reboot {
+       my ( $self, $state ) = @_;
+       $self->xml( $state, sub {
+               my ( $X, $state ) = @_;
+               $X->Reboot();
+       });
+}
+
+=head2 GetParameterNames {
+
+  $response->GetParameterNames( $state, $ParameterPath, $NextLevel );
+
+=cut
+
+sub GetParameterNames {
+       my ( $self, $state, $ParameterPath, $NextLevel ) = @_;
+       $ParameterPath ||= '';  # all
+       $NextLevel ||= 0;               # all
+       warn "# GetParameterNames( '$ParameterPath', $NextLevel )\n" if $self->debug;
+       $self->xml( $state, sub {
+               my ( $X, $state ) = @_;
+
+               $X->GetParameterNames( $cwmp,
+                       $X->ParameterPath( $cwmp, $ParameterPath ),
+                       $X->NextLevel( $cwmp, $NextLevel ),
+               );
+       });
+}
+
+=head2 xml
+
+Used to implement methods which modify just body of soap message.
+For examples, see source of this module.
+
+=cut
+
+sub xml {
+       my $self = shift;
+
+       my ( $state, $closure ) = @_;
+
+       confess "no state?" unless ($state);
+       confess "no body closure" unless ( $closure );
+
+       confess "no ID in state ", dump( $state ) unless ( $state->{ID} );
+
+       #warn "state used to generate xml = ", dump( $state ) if $self->debug;
+
+       my $X = XML::Generator->new(':pretty');
+
+       return $X->Envelope( $soap, { 'soap:encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/" },
+               $X->Header( $soap,
+                       $X->ID( $cwmp, { mustUnderstand => 1 }, $state->{ID} ),
+                       $X->NoMoreRequests( $cwmp, $state->{NoMoreRequests} || 0 ),
+               ),
+               $X->Body( $soap, $closure->( $X, $state ) ),
+       );
+}
+
+1;
diff --git a/lib/CWMP/Server.pm b/lib/CWMP/Server.pm
new file mode 100644 (file)
index 0000000..0a67293
--- /dev/null
@@ -0,0 +1,154 @@
+# Dobrica Pavlinusic, <dpavlin@rot13.org> 06/22/07 14:35:38 CEST
+package CWMP::Server;
+
+use strict;
+use warnings;
+
+use base qw/Class::Accessor/;
+__PACKAGE__->mk_accessors( qw/
+port
+store_path
+default_queue
+background
+debug
+
+server
+/ );
+
+use CWMP::Session;
+
+use Carp qw/confess/;
+use Data::Dump qw/dump/;
+
+=head1 NAME
+
+CWMP::Server - description
+
+=head1 METHODS
+
+=head2 new
+
+  my $server = CWMP::Server->new({
+       port => 3333,
+       store_path => 'state.db',
+       default_queue => [ qw/GetRPCMethods GetParameterNames/ ],                                                           
+       background => 1,
+       debug => 1
+  });
+
+Options:
+
+=over 4
+
+=item port
+
+port to listen on
+
+=item store_path
+
+path to L<DBM::Deep> database file to preserve state
+
+=item default_queue
+
+commands which will be issued to every CPE on connect
+
+=back
+
+=cut
+
+sub new {
+       my $class = shift;
+       my $self = $class->SUPER::new( @_ );
+
+       warn "created ", __PACKAGE__, "(", dump( @_ ), ") object\n" if $self->debug;
+
+       warn "ACS waiting for request on port ", $self->port, "\n";
+
+       $self->debug( 0 ) unless $self->debug;
+       warn "## debug level: ", $self->debug, "\n" if $self->debug;
+
+       $self->server(
+               CWMP::Server::Helper->new({
+                       proto => 'tcp',
+                       port => $self->port,
+                       default_queue => $self->default_queue,
+                       store_path => $self->store_path,
+                       debug => $self->debug,
+                       background => $self->background,
+               })
+       );
+
+       return $self;
+}
+
+=head2 run
+
+=cut
+
+sub run {
+       my $self = shift;
+
+       $self->server->run;
+}
+
+package CWMP::Server::Helper;
+
+use warnings;
+use strict;
+
+use base qw/Net::Server/;
+use Carp qw/confess/;
+use Data::Dump qw/dump/;
+
+sub options {
+       my $self     = shift;
+       my $prop     = $self->{'server'};
+       my $template = shift;
+
+       ### setup options in the parent classes
+       $self->SUPER::options($template);
+
+       # new single-value options
+       foreach my $p ( qw/ store_path debug / ) {
+               $prop->{ $p } ||= undef;
+               $template->{ $p } = \$prop->{ $p };
+       }
+
+       # new multi-value options
+       foreach my $p ( qw/ default_queue / ) {
+               $prop->{ $p } ||= [];
+               $template->{ $p } = $prop->{ $p };
+       }
+}
+
+
+=head2 process_request
+
+=cut
+
+sub process_request {
+       my $self = shift;
+
+       my $prop = $self->{server};
+       confess "no server in ", ref( $self ) unless $prop;
+       my $sock = $prop->{client};
+       confess "no sock in ", ref( $self ) unless $sock;
+
+       warn "default CPE queue ( " . join(",",@{$prop->{default_queue}}) . " )\n" if defined($prop->{default_queue});
+
+       my $session = CWMP::Session->new({
+               sock => $sock,
+               queue => $prop->{default_queue},
+               store_path => $prop->{store_path},
+               debug => $prop->{debug},
+       }) || confess "can't create session";
+
+       while ( $session->process_request ) {
+               warn "...another one bites the dust...\n";
+       }
+
+       warn "...returning to accepting new connections\n";
+
+}
+
+1;
diff --git a/lib/CWMP/Session.pm b/lib/CWMP/Session.pm
new file mode 100644 (file)
index 0000000..40e5822
--- /dev/null
@@ -0,0 +1,209 @@
+# Dobrica Pavlinusic, <dpavlin@rot13.org> 06/18/07 10:19:50 CEST
+package CWMP::Session;
+
+use strict;
+use warnings;
+
+use base qw/Class::Accessor/;
+__PACKAGE__->mk_accessors( qw/
+debug
+store_path
+
+sock
+state
+queue
+store
+/ );
+
+use HTTP::Daemon;
+use Data::Dump qw/dump/;
+use Carp qw/confess cluck croak/;
+use File::Slurp;
+
+use CWMP::Request;
+use CWMP::Response;
+use CWMP::Store;
+
+=head1 NAME
+
+CWMP::Session - implement logic of CWMP protocol
+
+=head1 METHODS
+
+=head2 new
+
+  my $server = CWMP::Session->new({
+       sock => $io_socket_object,
+       store_path => 'state.db',
+       queue => [ qw/GetRPCMethods GetParameterNames/ ],
+       debug => 1,
+  });
+
+=cut
+
+sub new {
+       my $class = shift;
+       my $self = $class->SUPER::new( @_ );
+
+       confess "need sock" unless $self->sock;
+
+       $self->debug( 0 ) unless $self->debug;
+
+       warn "created ", __PACKAGE__, "(", dump( @_ ), ") for ", $self->sock->peerhost, "\n" if $self->debug;
+
+       $self->store( CWMP::Store->new({
+               debug => $self->debug,
+               path => $self->store_path,
+       }) );
+
+       croak "can't open ", $self->store_path, ": $!" unless $self->store;
+
+       return $self;
+}
+
+=head2 process_request
+
+One request from client/response from server cycle. Call multiple times to
+facilitate brain-dead concept of adding state to stateless protocol like
+HTTP.
+
+If used with debugging level of 3 or more, it will also create dumps of
+requests named C<< nr.dump >> where C<nr> is number from 0 to total number
+of requests in single session.
+
+=cut
+
+my $dump_nr = 0;
+
+sub process_request {
+       my $self = shift;
+
+       my $sock = $self->sock || die "no sock?";
+
+#      die "not IO::Socket::INET but ", ref( $sock ) unless ( ref($sock) eq 'Net::Server::Proto::TCP' );
+
+       if ( ! $sock->connected ) {
+               warn "SOCKET NOT CONNECTED\n";
+               return 0;
+       }
+
+       bless $sock, 'HTTP::Daemon::ClientConn';
+
+       # why do I have to do this?
+       # solution from http://use.perl.org/~Matts/journal/12896
+       ${*$sock}{'httpd_daemon'} = HTTP::Daemon->new;
+
+       my $r = $sock->get_request || confess "can't get_request";
+
+       my $chunk = $r->content;
+
+       my $size = length( $chunk );
+
+       warn "<<<< ", $sock->peerhost, " [" . localtime() . "] ", $r->method, " ", $r->uri, " $size bytes\n";
+
+       if ( $self->debug > 2 ) {
+               my $file = $dump_nr++ . '.dump';
+               write_file( $file, $r->as_string );
+               warn "### request dump: $file\n";
+       }
+
+       my $state;
+
+       if ( $size > 0 ) {
+
+               die "no SOAPAction header in ",dump($chunk) unless defined ( $r->header('SOAPAction') );
+
+
+               if ( $chunk ) {
+                       warn "## request chunk: ",length($chunk)," bytes\n$chunk\n" if $self->debug;
+
+                       $state = CWMP::Request->parse( $chunk );
+
+                       warn "## acquired state = ", dump( $state ), "\n";
+
+                       $self->state( $state );
+                       $self->store->update_state( ID => $state->{ID}, $state );
+
+               } else {
+                       warn "## empty request\n";
+               }
+
+       } else {
+               $state = $self->state;
+               warn "last request state = ", dump( $state ), "\n" if $self->debug > 1;
+       }
+
+
+       $sock->send(join("\r\n",
+               'HTTP/1.1 200 OK',
+               'Content-Type: text/xml; charset="utf-8"',
+               'Server: AcmeCWMP/42',
+               'SOAPServer: AcmeCWMP/42'
+       )."\r\n");
+
+       $sock->send( "Set-Cookie: ID=" . $state->{ID} . "; path=/\r\n" ) if ( $state->{ID} );
+       
+       my $xml = '';
+
+       if ( my $dispatch = $state->{_dispatch} ) {
+               $xml = $self->dispatch( $dispatch );
+       } elsif ( $dispatch = shift @{ $self->queue } ) {
+               $xml = $self->dispatch( $dispatch );
+       } elsif ( $size == 0 ) {
+               warn ">>> closing connection\n";
+               return 0;
+       } else {
+               warn ">>> empty response\n";
+               $state->{NoMoreRequests} = 1;
+               $xml = $self->dispatch( 'xml', sub {} );
+       }
+
+       $sock->send( "Content-Length: " . length( $xml ) . "\r\n\r\n" );
+       $sock->send( $xml ) or die "can't send response";
+
+       warn ">>>> " . $sock->peerhost . " [" . localtime() . "] sent ", length( $xml )," bytes\n";
+
+       warn "### request over\n" if $self->debug;
+
+       return 1;       # next request
+};
+
+=head2 dispatch
+
+  $xml = $self->dispatch('Inform', $response_arguments );
+
+=cut
+
+sub dispatch {
+       my $self = shift;
+
+       my $dispatch = shift || die "no dispatch?";
+
+       my $response = CWMP::Response->new({ debug => $self->debug });
+
+       if ( $response->can( $dispatch ) ) {
+               warn ">>> dispatching to $dispatch\n";
+               my $xml = $response->$dispatch( $self->state, @_ );
+               warn "## response payload: ",length($xml)," bytes\n$xml\n" if $self->debug;
+               return $xml;
+       } else {
+               confess "can't dispatch to $dispatch";
+       }
+};
+
+
+=head2 error
+
+  return $self->error( 501, 'System error' );
+
+=cut
+
+sub error {
+  my ($self, $number, $msg) = @_;
+  $msg ||= 'ERROR';
+  $self->sock->send( "HTTP/1.1 $number $msg\r\n" );
+  warn "Error - $number - $msg\n";
+  return 0;    # close connection
+}
+
+1;
diff --git a/lib/CWMP/Store.pm b/lib/CWMP/Store.pm
new file mode 100644 (file)
index 0000000..8425ec2
--- /dev/null
@@ -0,0 +1,189 @@
+# Dobrica Pavlinusic, <dpavlin@rot13.org> 06/22/07 14:35:38 CEST
+package CWMP::Store;
+
+use strict;
+use warnings;
+
+
+use base qw/Class::Accessor/;
+__PACKAGE__->mk_accessors( qw/
+debug
+path
+
+db
+/ );
+
+use Carp qw/confess/;
+use Data::Dump qw/dump/;
+use DBM::Deep;
+
+=head1 NAME
+
+CWMP::Store - parsist CPE state on disk
+
+=head1 METHODS
+
+=head2 new
+
+  my $store = CWMP::Store->new({
+       path => '/path/to/state.db',
+       debug => 1,
+  });
+
+=cut
+
+sub new {
+       my $class = shift;
+       my $self = $class->SUPER::new( @_ );
+
+       warn "created ", __PACKAGE__, "(", dump( @_ ), ") object\n" if $self->debug;
+
+       confess "need path to state.db" unless ( $self->path );
+
+       $self->db(
+               DBM::Deep->new(
+                       file => $self->path,
+                       locking => 1,
+                       autoflush => 1,
+               )
+       );
+
+       foreach my $init ( qw/ state session / ) {
+               $self->db->put( $init => {} ) unless $self->db->get( $init );
+       }
+
+       return $self;
+}
+
+=head2 update_state
+
+  $store->update_state( ID => $ID, $state );
+  $store->update_state( uid => $uid, $state );
+
+=cut
+
+sub update_state {
+       my $self = shift;
+
+       my ( $k, $v, $state ) = @_;
+
+       confess "need ID or uid" unless $k =~ m/^(ID|uid)$/;
+       confess "need $k value" unless $v;
+       confess "need state" unless $state;
+
+       warn "## update_state( $k => $v, ", dump( $state ), " )\n" if $self->debug;
+
+       my $uid;
+
+       if ( $k eq 'ID' ) {
+               if ( $uid = $self->ID_to_uid( $v, $state ) ) {
+                       # nop
+               } else {
+                       warn "## no uid for $v, first seen?\n" if $self->debug;
+                       return;
+               }
+       } else {
+               $uid = $v;
+       }
+
+       if ( my $o = $self->db->get('state')->get( $uid ) ) {
+               warn "## update state of $uid [$v]\n" if $self->debug;
+               return $o->import( $state );
+       } else {
+               warn "## create new state for $uid [$v]\n" if $self->debug;
+               return $self->db->get('state')->put( $uid => $state );
+       }
+}
+
+=head2 state
+
+  my $state = $store->state( ID => $ID );
+  my $state = $store->state( uid => $uid );
+
+Returns normal unblessed hash (actually, in-memory copy of state in database).
+
+=cut
+
+sub state {
+       my $self = shift;
+       my ( $k, $v ) = @_;
+       confess "need ID or uid" unless $k =~ m/^(ID|uid)$/;
+       confess "need $k value" unless $v;
+
+       warn "## state( $k => $v )\n" if $self->debug;
+
+       my $uid;
+
+       if ( $k eq 'ID' ) {
+               if ( $uid = $self->ID_to_uid( $v ) ) {
+                       # nop
+               } else {
+                       warn "## no uid for $v so no state!\n" if $self->debug;
+                       return;
+               }
+       } else {
+               $uid = $v;
+       }
+
+       if ( my $state = $self->db->get('state')->get( $uid ) ) {
+               return $state->export;
+       } else {
+               return;
+       }
+
+}
+
+=head2 known_CPE
+
+  my @cpe = $store->known_CPE;
+
+=cut
+
+sub known_CPE {
+       my $self = shift;
+       my @cpes = keys %{ $self->db->{state} };
+       warn "all CPE: ", dump( @cpes ), "\n" if $self->debug;
+       return @cpes;
+}
+
+=head2 ID_to_uid
+
+  my $CPE_uid = $store->ID_to_uid( $ID, $state );
+
+It uses C<< DeviceID.SerialNumber >> from C<Inform> message as unique ID
+for each CPE.
+
+=cut
+
+sub ID_to_uid {
+       my $self = shift;
+       my ( $ID, $state ) = @_;
+
+       confess "need ID" unless $ID;
+
+       warn "ID_to_uid",dump( $ID, $state ),$/ if $self->debug;
+
+       $self->db->{session}->{ $ID }->{last_seen} = time();
+
+       my $uid;
+
+       if ( $uid = $self->db->{session}->{ $ID }->{ ID_to_uid } ) {
+               return $uid;
+       } elsif ( $uid = $state->{DeviceID}->{SerialNumber} ) {
+               warn "## created new session for $uid session $ID\n" if $self->debug;
+               $self->db->{session}->{ $ID } = {
+                       last_seen => time(),
+                       ID_to_uid => $uid,
+               };
+               return $uid;
+       } else {
+               warn "## can't find uid for ID $ID, first seen?\n";
+               return;
+       }
+
+       # TODO: expire sessions longer than 30m
+
+       return;
+}
+
+1;
diff --git a/lib/CWMP/Tree.pm b/lib/CWMP/Tree.pm
new file mode 100644 (file)
index 0000000..3a512b3
--- /dev/null
@@ -0,0 +1,73 @@
+# Dobrica Pavlinusic, <dpavlin@rot13.org> 06/22/07 14:35:38 CEST
+package CWMP::Tree;
+
+use strict;
+use warnings;
+
+
+use base qw/Class::Accessor/;
+__PACKAGE__->mk_accessors( qw/
+debug
+/ );
+
+use Carp qw/confess/;
+use Data::Dump qw/dump/;
+
+=head1 NAME
+
+CWMP::Tree - description
+
+=head1 METHODS
+
+=head2 new
+
+  my $obj = CWMP::Tree->new({
+       debug => 1
+  });
+
+=cut
+
+sub new {
+       my $class = shift;
+       my $self = $class->SUPER::new( @_ );
+
+       warn "created ", __PACKAGE__, "(", dump( @_ ), ") object\n" if $self->debug;
+
+       return $self;
+}
+
+=head2 name2perl
+
+Perl is dynamic language and we want parametars from TR-069 as
+a tree. So we do rewrite of parametar to perl code and eval that.
+
+  my $perl = $self->name2perl( 'InternetGatewayDevice.DeviceSummary' );
+
+=cut
+
+sub name2perl {
+       my ( $self, $s ) = @_;
+
+       confess "no name?" unless $s;
+
+       warn "===> $s\n" if $self->debug;
+       $s =~ s/^([^\.]+)/{'$1'}/;
+       warn "---> $s\n"  if $self->debug;
+
+       my $stat;
+       while ( $s =~ s/\.(\d+)/->[$1]/ ) {
+               $stat->{array}++;
+               warn "-\@-> $s\n" if $self->debug;
+       }
+       while ( $s =~ s/\.([a-zA-Z0-9_]+)/->{'$1'}/ ) {
+               $stat->{scalar}++;
+               warn "-\$-> $s\n" if $self->debug;
+
+       };
+
+       warn "## $s ", dump( $stat ), $/ if $self->debug;
+
+       return $s;
+}
+
+1;
diff --git a/lib/CWMP/_MODULE.pm b/lib/CWMP/_MODULE.pm
new file mode 100644 (file)
index 0000000..074db75
--- /dev/null
@@ -0,0 +1,40 @@
+# Dobrica Pavlinusic, <dpavlin@rot13.org> 06/22/07 14:35:38 CEST
+package CWMP::_MODULE;
+
+use strict;
+use warnings;
+
+
+use base qw/Class::Accessor/;
+__PACKAGE__->mk_accessors( qw/
+debug
+/ );
+
+#use Carp qw/confess/;
+use Data::Dump qw/dump/;
+
+=head1 NAME
+
+CWMP::_MODULE - description
+
+=head1 METHODS
+
+=head2 new
+
+  my $obj = CWMP::_MODULE->new({
+       debug => 1
+  });
+
+=cut
+
+sub new {
+       my $class = shift;
+       my $self = $class->SUPER::new( @_ );
+
+       warn "created ", __PACKAGE__, "(", dump( @_ ), ") object\n" if $self->debug;
+
+       return $self;
+}
+
+
+1;
diff --git a/net.sh b/net.sh
new file mode 100755 (executable)
index 0000000..4458482
--- /dev/null
+++ b/net.sh
@@ -0,0 +1,11 @@
+
+if [ -z "$1" ] ; then
+       eth=eth0
+#      eth=ath0:0
+else
+       eth=$1
+fi
+
+sudo ifconfig $eth 192.168.1.90 up
+sudo route add -host 192.168.1.254 dev $eth
+echo "Setup of $eth to 192.168.1.90 ready"
diff --git a/t/00-load.t b/t/00-load.t
new file mode 100755 (executable)
index 0000000..89ef933
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $debug = shift @ARGV;
+
+use Test::More tests => 4;
+use blib;
+
+BEGIN {
+       use_ok('CWMP::Server');
+       use_ok('CWMP::Request');
+       use_ok('CWMP::Response');
+       use_ok('CWMP::Store');
+}
+
+
diff --git a/t/05-store.t b/t/05-store.t
new file mode 100755 (executable)
index 0000000..7295f40
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $debug = shift @ARGV;
+
+use Test::More tests => 17;
+use Data::Dump qw/dump/;
+use Cwd qw/abs_path/;
+use lib 'lib';
+
+BEGIN {
+       use_ok('CWMP::Store');
+}
+
+ok(my $abs_path = abs_path($0), "abs_path");
+$abs_path =~ s!/[^/]*$!/!;     #!fix-vim
+
+my $path = "$abs_path/var/state.db";
+
+unlink $path if -e $path;
+
+ok( my $store = CWMP::Store->new({
+       debug => $debug,
+       path => $path,
+}), 'new' );
+isa_ok( $store, 'CWMP::Store' );
+
+cmp_ok( $store->path, 'eq', $path, 'path' );
+
+my $state = {
+       foo => 'bar',
+       DeviceID => {
+               SerialNumber => 123456,
+       },
+};
+
+cmp_ok( $store->ID_to_uid( 42, $state ), 'eq', 123456, 'ID_to_uid' );
+
+ok( $store->update_state( ID => 42, $state ), 'update_state new' );
+
+ok( my $store_state = $store->state( ID => '42'), 'db->get' );
+
+is_deeply( $store_state, $state, 'state ID' );
+
+ok( $store_state = $store->state( uid =>  123456 ), 'db->get' );
+
+is_deeply( $store_state, $state, 'state uid' );
+
+ok( $store->update_state( ID => 42, { baz => 12345 } ), 'update_state existing' );
+
+$state->{baz} = 12345;
+
+is_deeply( $store->state( ID => 42 ), $state, 'store->state ID' );
+
+is_deeply( $store->state( uid => 123456 ), $state, 'store->state uid' );
+
+is_deeply( [ $store->known_CPE ], [ 123456 ], 'known_CPE' );
+
+ok( $store->update_state( ID => 11, { DeviceID => { SerialNumber => 99999 } } ), 'new device' );
+
+is_deeply( [ $store->known_CPE ], [ 123456, 99999 ], 'known_CPE' );
+
diff --git a/t/07-tree.t b/t/07-tree.t
new file mode 100755 (executable)
index 0000000..ba6824b
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $debug = shift @ARGV;
+
+use Test::More tests => 6;
+use Data::Dump qw/dump/;
+use lib 'lib';
+
+BEGIN {
+       use_ok('CWMP::Tree');
+}
+
+#use Cwd qw/abs_path/;
+#ok(my $abs_path = abs_path($0), "abs_path");
+#$abs_path =~ s!/[^/]*$!/!;    #!fix-vim
+
+ok( my $obj = CWMP::Tree->new({
+       debug => $debug,
+}), 'new' );
+isa_ok( $obj, 'CWMP::Tree' );
+
+my @perl = qw/
+{'InternetGatewayDevice'}->{'DeviceInfo'}->{'HardwareVersion'}
+{'InternetGatewayDevice'}->{'DeviceInfo'}->{'VendorConfigFile'}->[1]->{'Date'}
+{'InternetGatewayDevice'}->{'Services'}->{'VoiceService'}->[1]->{'PhyInterface'}->[2]->{'PhyPort'}
+/;
+
+foreach my $name ( qw/
+InternetGatewayDevice.DeviceInfo.HardwareVersion
+InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Date
+InternetGatewayDevice.Services.VoiceService.1.PhyInterface.2.PhyPort
+/ ) {
+       my $expect = shift @perl;
+       cmp_ok( $obj->name2perl( $name ), 'eq', $expect, "name2perl( $name )" );
+}
diff --git a/t/10-request.t b/t/10-request.t
new file mode 100755 (executable)
index 0000000..80243a7
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $debug = shift @ARGV;
+
+use Test::More tests => 53;
+use Data::Dump qw/dump/;
+use Cwd qw/abs_path/;
+use File::Slurp;
+use blib;
+
+BEGIN {
+       use_ok('CWMP::Request');
+}
+
+my @models = ( qw/SpeedTouch-706 SpeedTouch-780/ );
+
+ok( $#models + 1, 'got models' );
+
+ok(my $abs_path = abs_path($0), "abs_path");
+$abs_path =~ s!/[^/]*$!/!;     #!fix-vim
+
+sub file_is_deeply {
+       my ( $path ) = @_;
+
+       ok( my $xml = read_file( $path ), "read_file( $path )" );
+
+       diag $xml if $debug;
+
+       ok( my $state = CWMP::Request->parse( $xml ), 'parse' );
+
+       my $dump_path = $path;
+       $dump_path =~ s/\.xml/\.pl/;
+
+       write_file( $dump_path, dump( $state ) ) unless ( -e $dump_path );
+
+       diag "$path ? $dump_path" if $debug;
+
+       ok( my $hash = read_file( $dump_path ), "read_file( $dump_path )" );
+       ok ( $hash = eval "$hash", 'eval' );
+
+       is_deeply( $state, $hash, 'same' );
+}
+
+foreach my $model ( @models ) {
+
+       my $dir = "$abs_path/$model/";
+       opendir(DIR, $dir) || die "can't opendir $dir: $!";
+       my @xmls = map { "$dir/$_" } grep { /\.xml$/ && -f "$dir/$_" } readdir(DIR);
+       closedir DIR;
+
+       diag "$model has ", $#xmls + 1, " xml tests";
+
+       ok( $#xmls, "xmls" );
+
+       foreach my $xml_path ( @xmls ) {
+               ok ( $xml_path, 'xml path' );
+               file_is_deeply( $xml_path );
+       }
+}
+
diff --git a/t/20-response.t b/t/20-response.t
new file mode 100755 (executable)
index 0000000..b273606
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $debug = shift @ARGV;
+
+use Test::More tests => 11;
+use Data::Dump qw/dump/;
+use blib;
+
+BEGIN {
+       use_ok('CWMP::Response');
+}
+
+#ok( my $xml = join("",<DATA>), 'xml' );
+#diag $xml if $debug;
+
+ok( my $response = CWMP::Response->new({ debug => $debug }), 'new' );
+isa_ok( $response, 'CWMP::Response' );
+
+sub is_like {
+       my ( $command, $template_xml ) = @_;
+
+       ok( my $xml = $response->$command({ ID => 42 }), $command );
+       diag $xml if $debug;
+       chomp( $xml );
+       chomp( $template_xml );
+       like( $xml, qr{^\Q$template_xml\E$}, $command . ' xml' );
+}
+
+is_like( 'InformResponse', <<__SOAP__
+<soap:Envelope xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
+  <soap:Header>
+    <cwmp:ID mustUnderstand="1">42</cwmp:ID>
+    <cwmp:NoMoreRequests>0</cwmp:NoMoreRequests>
+  </soap:Header>
+  <soap:Body>
+    <cwmp:InformResponse>
+      <cwmp:MaxEnvelopes>1</cwmp:MaxEnvelopes>
+    </cwmp:InformResponse>
+  </soap:Body>
+</soap:Envelope>
+__SOAP__
+);
+
+is_like( 'GetRPCMethods', <<__SOAP__
+<soap:Envelope xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
+  <soap:Header>
+    <cwmp:ID mustUnderstand="1">42</cwmp:ID>
+    <cwmp:NoMoreRequests>0</cwmp:NoMoreRequests>
+  </soap:Header>
+  <soap:Body>
+    <GetRPCMethods />
+  </soap:Body>
+</soap:Envelope>
+__SOAP__
+);
+
+is_like( 'Reboot', <<__SOAP__
+<soap:Envelope xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
+  <soap:Header>
+    <cwmp:ID mustUnderstand="1">42</cwmp:ID>
+    <cwmp:NoMoreRequests>0</cwmp:NoMoreRequests>
+  </soap:Header>
+  <soap:Body>
+    <Reboot />
+  </soap:Body>
+</soap:Envelope>
+__SOAP__
+);
+
+is_like( 'GetParameterNames', <<__SOAP__
+<soap:Envelope xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
+  <soap:Header>
+    <cwmp:ID mustUnderstand="1">42</cwmp:ID>
+    <cwmp:NoMoreRequests>0</cwmp:NoMoreRequests>
+  </soap:Header>
+  <soap:Body>
+    <cwmp:GetParameterNames>
+      <cwmp:ParameterPath></cwmp:ParameterPath>
+      <cwmp:NextLevel>0</cwmp:NextLevel>
+    </cwmp:GetParameterNames>
+  </soap:Body>
+</soap:Envelope>
+__SOAP__
+);
diff --git a/t/30-server.t b/t/30-server.t
new file mode 100755 (executable)
index 0000000..b82d1e2
--- /dev/null
@@ -0,0 +1,191 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $debug = shift @ARGV;
+
+use Test::More tests => 19;
+use Data::Dump qw/dump/;
+use Cwd qw/abs_path/;
+use blib;
+
+BEGIN {
+       use_ok('Net::HTTP');
+       use_ok('CWMP::Server');
+       use_ok('CWMP::Store');
+}
+
+my $port = 4242;
+
+eval {
+       $SIG{ALRM} = sub { die; };
+       alarm 30;
+};
+
+ok(my $abs_path = abs_path($0), "abs_path");
+$abs_path =~ s!/[^/]*$!/!;     #!fix-vim
+
+my $store_path = "$abs_path/var/state.db";
+unlink $store_path if -e $store_path;
+
+ok( my $server = CWMP::Server->new({
+       debug => $debug,
+       port => $port,
+       store_path => $store_path,
+}), 'new' );
+isa_ok( $server, 'CWMP::Server' );
+
+my $pid;
+
+if ( $pid = fork ) {
+       ok( $pid, 'fork ');
+       diag "forked $pid";
+} elsif (defined($pid)) {
+       # child
+       $server->run;
+       exit;
+} else {
+       die "can't fork";
+}
+
+sleep 1;       # so server can start
+
+ok( my $s = Net::HTTP->new(Host => "localhost:$port"), 'client' );
+$s->keep_alive( 1 );
+
+ok( $s->write_request(
+       POST => '/',
+       'Transfer-Encoding' => 'chunked',
+       'SOAPAction' => '',
+       'Content-Type' => 'text/xml',
+), 'write_request' );
+
+foreach my $chunk (qq{
+
+<soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-0">
+ <soapenv:Header>
+<cwmp:ID soapenv:mustUnderstand="1">1_THOM_TR69_ID</cwmp:ID>
+ </soapenv:Header>
+ <soapenv:Body>
+<cwmp:Inform>
+<DeviceId>
+ <Manufacturer>THOMSON</Manufacturer>
+ <OUI>00147F</OUI>
+ <ProductClass>SpeedTouch 780</ProductClass>
+ <SerialNumber>CP0644JTHJ4</SerialNumber>
+</DeviceId>
+<Event soap:arrayType="cwmp:EventStruct[03]">
+<EventStruct>
+ <EventCode>0 BOOTSTRAP</EventCode>
+ <CommandKey></CommandKey>
+</EventStruct>
+<EventStruct>
+ <Event},qq{Code>1 BOOT</EventCode>
+ <CommandKey></CommandKey>
+</EventStruct>
+<EventStruct>
+ <EventCode>4 VALUE CHANGE</EventCode>
+ <CommandKey></CommandKey>
+</EventStruct>
+</Event>
+<MaxEnvelopes>2</MaxEnvelopes>
+<CurrentTime>1970-01-01T00:04:33Z</CurrentTime>
+<RetryCount>01</RetryCount>},qq{
+<ParameterList soap:arrayType="cwmp:ParameterValueStruct[12]">
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.DeviceSummary</Name>
+ <Value xsi:type="xsd:string">InternetGatewayDevice:1.1[] (Baseline:1, EthernetLAN:1, ADSLWAN:1, Bridging:1, Time:1, WiFiLAN:1)</Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>}, qq{
+InternetGatewayDevice.DeviceInfo.SpecVersion</Name>
+ <Value xsi:type="xsd:string">1.1</Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.DeviceInfo.HardwareVersion</Name>
+ <Value xsi:type="xsd:string">BANT-R</Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.DeviceInfo.SoftwareVersion</Name>
+ <Value xsi:type="xsd:string">6.2.15.5</Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.DeviceInfo.ProvisioningCode</Name>
+ <Value xsi:type="xsd:string"></Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Name</Name>
+ <Value xsi:type="xsd:string">Routed PPPoE on 0/35 and 8/35</Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Version</Name>
+ <Value xsi:type="xsd:string"></Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Date</Name>
+ <Value xsi:type="xsd:dateTime">0000-00-00T00:00:00</Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Description</Name>
+ <Value xsi:type="xsd:string">Factory Defaults</Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.ManagementServer.ConnectionRequestURL</Name>
+ <Value}, qq{ xsi:type="xsd:string">http://192.168.1.254:51005/</Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>InternetGatewayDevice.ManagementServer.ParameterKey</Name>
+ <Value xsi:type="xsd:string"></Value>
+</ParameterValueStruct>
+<ParameterValueStruct>
+ <Name>.ExternalIPAddress</Name>
+ <Value xsi:type="xsd:string">192.168.1.254</Value>
+</ParameterValueStruct>
+</ParameterList>
+</cwmp:Inform>
+ </soapenv:Body>
+</soapenv:Envelope>
+} ) {
+       ok( $s->write_chunk( $chunk ), "chunk " . length($chunk) . " bytes" );
+}
+ok( $s->write_chunk_eof, 'write_chunk_eof' );
+
+sleep 1;
+
+ok( my $store = CWMP::Store->new({ path => $store_path, debug => $debug }), 'another store' );
+
+my $state = {
+  CurrentTime    => "1970-01-01T00:04:33Z",
+  DeviceID       => {
+                      Manufacturer => "THOMSON",
+                      OUI => "00147F",
+                      ProductClass => "SpeedTouch 780",
+                      SerialNumber => "CP0644JTHJ4",
+                    },
+  EventStruct    => ["0 BOOTSTRAP", "1 BOOT", "4 VALUE CHANGE"],
+  ID             => "1_THOM_TR69_ID",
+  MaxEnvelopes   => 2,
+  NoMoreRequests => undef,
+  Parameter      => {
+                      "\nInternetGatewayDevice.DeviceInfo.SpecVersion"                  => "1.1",
+                      ".ExternalIPAddress"                                              => "192.168.1.254",
+                      "InternetGatewayDevice.DeviceInfo.HardwareVersion"                => "BANT-R",
+                      "InternetGatewayDevice.DeviceInfo.ProvisioningCode"               => undef,
+                      "InternetGatewayDevice.DeviceInfo.SoftwareVersion"                => "6.2.15.5",
+                      "InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Date"        => "0000-00-00T00:00:00",
+                      "InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Description" => "Factory Defaults",
+                      "InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Name"        => "Routed PPPoE on 0/35 and 8/35",
+                      "InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Version"     => undef,
+                      "InternetGatewayDevice.DeviceSummary"                             => "InternetGatewayDevice:1.1[] (Baseline:1, EthernetLAN:1, ADSLWAN:1, Bridging:1, Time:1, WiFiLAN:1)",
+                      "InternetGatewayDevice.ManagementServer.ConnectionRequestURL"     => "http://192.168.1.254:51005/",
+                      "InternetGatewayDevice.ManagementServer.ParameterKey"             => undef,
+                    },
+  RetryCount     => "01",
+  _dispatch      => "InformResponse",
+};
+
+is_deeply( $store->state( ID => '1_THOM_TR69_ID' ), $state, 'new store->state' );
+
+ok( kill(9,$pid), 'kill ' . $pid );
+
+ok( waitpid($pid,0), 'waitpid' );
diff --git a/t/SpeedTouch-706/Fault.pl b/t/SpeedTouch-706/Fault.pl
new file mode 100644 (file)
index 0000000..1a710e9
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  Fault => { FaultCode => 9001, FaultString => "Request Denied" },
+  ID => "22_THOM_TR69_ID",
+}
\ No newline at end of file
diff --git a/t/SpeedTouch-706/Fault.xml b/t/SpeedTouch-706/Fault.xml
new file mode 100644 (file)
index 0000000..778d0ab
--- /dev/null
@@ -0,0 +1,17 @@
+<soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-0">
+ <soapenv:Header>
+<cwmp:ID soapenv:mustUnderstand="1">22_THOM_TR69_ID</cwmp:ID>
+ </soapenv:Header>
+ <soapenv:Body>
+  <soapenv:Fault>
+   <faultcode>Client</faultcode>
+   <faultstring>CWMP fault</faultstring>
+   <detail>
+    <cwmp:Fault>
+     <FaultCode>9001</FaultCode>
+     <FaultString>Request Denied</FaultString>
+    </cwmp:Fault>
+   </detail>
+  </soapenv:Fault>
+ </soapenv:Body>
+</soapenv:Envelope>
diff --git a/t/SpeedTouch-706/GetParameterNamesResponse.pl b/t/SpeedTouch-706/GetParameterNamesResponse.pl
new file mode 100644 (file)
index 0000000..cd0c7e9
--- /dev/null
@@ -0,0 +1,5013 @@
+{
+  ID => "22_THOM_TR69_ID",
+  ParameterInfo => {
+        "InternetGatewayDevice" => {
+              DeviceConfig => { X_000E50_AutoSave => { writable => 1 } },
+              DeviceInfo => {
+                    "AdditionalHardwareVersion"       => { writable => 0 },
+                    Description                       => { writable => 0 },
+                    HardwareVersion                   => { writable => 0 },
+                    Manufacturer                      => { writable => 0 },
+                    ManufacturerOUI                   => { writable => 0 },
+                    ModelName                         => { writable => 0 },
+                    ModemFirmwareVersion              => { writable => 0 },
+                    ProductClass                      => { writable => 0 },
+                    ProvisioningCode                  => { writable => 1 },
+                    SerialNumber                      => { writable => 0 },
+                    SoftwareVersion                   => { writable => 0 },
+                    SpecVersion                       => { writable => 0 },
+                    UpTime                            => { writable => 0 },
+                    VendorConfigFile                  => [
+                                                           undef,
+                                                           {
+                                                             Date => { writable => 0 },
+                                                             Description => { writable => 0 },
+                                                             Name => { writable => 0 },
+                                                             Version => { writable => 0 },
+                                                           },
+                                                         ],
+                    "VendorConfigFileNumberOfEntries" => { writable => 0 },
+                    X_000E50_Country                  => { writable => 1 },
+                    X_000E50_SIMLocked                => { writable => 0 },
+                  },
+              DeviceSummary => { writable => 0 },
+              LANDevice => [
+                    undef,
+                    {
+                      Hosts => {
+                            Host => [
+                                  undef,
+                                  {
+                                    Active             => { writable => 0 },
+                                    AddressSource      => { writable => 0 },
+                                    HostName           => { writable => 0 },
+                                    IPAddress          => { writable => 0 },
+                                    InterfaceType      => { writable => 0 },
+                                    LeaseTimeRemaining => { writable => 0 },
+                                    MACAddress         => { writable => 1 },
+                                  },
+                                ],
+                            HostNumberOfEntries => { writable => 0 },
+                          },
+                      "LANEthernetInterfaceConfig" => [
+                            undef,
+                            {
+                              DuplexMode => { writable => 1 },
+                              Enable => { writable => 1 },
+                              MACAddress => { writable => 0 },
+                              "MACAddressControlEnabled" => { writable => 0 },
+                              MaxBitRate => { writable => 1 },
+                              Status => { writable => 0 },
+                            },
+                            {
+                              DuplexMode => { writable => 1 },
+                              Enable => { writable => 1 },
+                              MACAddress => { writable => 0 },
+                              "MACAddressControlEnabled" => { writable => 0 },
+                              MaxBitRate => { writable => 1 },
+                              Status => { writable => 0 },
+                            },
+                          ],
+                      "LANEthernetInterfaceNumberOfEntries" => { writable => 0 },
+                      "LANHostConfigManagement" => {
+                            "DHCPConditionalServing"                => { writable => 0 },
+                            "DHCPConditionalServingNumberOfEntries" => { writable => 0 },
+                            "DHCPConditionalServingPool"            => [
+                                                                         undef,
+                                                                         {
+                                                                           Chaddr                      => { writable => 1 },
+                                                                           DHCPLeaseTime               => { writable => 1 },
+                                                                           "DHCPOptionNumberOfEntries" => { writable => 0 },
+                                                                           DNSServers                  => { writable => 1 },
+                                                                           DomainName                  => { writable => 1 },
+                                                                           IPRouters                   => { writable => 1 },
+                                                                           MaxAddress                  => { writable => 1 },
+                                                                           MinAddress                  => { writable => 1 },
+                                                                           SubnetMask                  => { writable => 1 },
+                                                                           UserClass                   => { writable => 1 },
+                                                                           VendorClass                 => { writable => 1 },
+                                                                         },
+                                                                       ],
+                            DHCPLeaseTime                           => { writable => 1 },
+                            "DHCPOptionNumberOfEntries"             => { writable => 0 },
+                            DHCPRelay                               => { writable => 1 },
+                            DHCPServerEnable                        => { writable => 1 },
+                            DNSServers                              => { writable => 1 },
+                            DomainName                              => { writable => 1 },
+                            IPInterface                             => [
+                                                                         undef,
+                                                                         {
+                                                                           IPInterfaceIPAddress    => { writable => 1 },
+                                                                           "IPInterfaceSubnetMask" => { writable => 1 },
+                                                                         },
+                                                                         {
+                                                                           IPInterfaceIPAddress    => { writable => 1 },
+                                                                           "IPInterfaceSubnetMask" => { writable => 1 },
+                                                                         },
+                                                                       ],
+                            "IPInterfaceNumberOfEntries"            => { writable => 0 },
+                            IPRouters                               => { writable => 1 },
+                            MaxAddress                              => { writable => 1 },
+                            MinAddress                              => { writable => 1 },
+                            SubnetMask                              => { writable => 1 },
+                          },
+                    },
+                  ],
+              "LANDeviceNumberOfEntries" => { writable => 0 },
+              Layer2Bridging => {
+                    AvailableInterface => [
+                          undef,
+                          {
+                            "AvailableInterfaceKey" => { writable => 0 },
+                            InterfaceReference      => { writable => 0 },
+                            InterfaceType           => { writable => 0 },
+                          },
+                          {
+                            "AvailableInterfaceKey" => { writable => 0 },
+                            InterfaceReference      => { writable => 0 },
+                            InterfaceType           => { writable => 0 },
+                          },
+                          {
+                            "AvailableInterfaceKey" => { writable => 0 },
+                            InterfaceReference      => { writable => 0 },
+                            InterfaceType           => { writable => 0 },
+                          },
+                          {
+                            "AvailableInterfaceKey" => { writable => 0 },
+                            InterfaceReference      => { writable => 0 },
+                            InterfaceType           => { writable => 0 },
+                          },
+                        ],
+                    "AvailableInterfaceNumberOfEntries" => { writable => 0 },
+                    Bridge => [
+                          undef,
+                          {
+                            BridgeEnable => { writable => 1 },
+                            BridgeKey    => { writable => 0 },
+                            BridgeName   => { writable => 1 },
+                            BridgeStatus => { writable => 0 },
+                          },
+                        ],
+                    "BridgeNumberOfEntries" => { writable => 0 },
+                    Filter => [
+                          undef,
+                          {
+                            BridgeReference => { writable => 1 },
+                            FilterEnable    => { writable => 1 },
+                            FilterInterface => { writable => 1 },
+                            FilterKey       => { writable => 0 },
+                            FilterStatus    => { writable => 0 },
+                          },
+                          {
+                            BridgeReference => { writable => 1 },
+                            FilterEnable    => { writable => 1 },
+                            FilterInterface => { writable => 1 },
+                            FilterKey       => { writable => 0 },
+                            FilterStatus    => { writable => 0 },
+                          },
+                          {
+                            BridgeReference => { writable => 1 },
+                            FilterEnable    => { writable => 1 },
+                            FilterInterface => { writable => 1 },
+                            FilterKey       => { writable => 0 },
+                            FilterStatus    => { writable => 0 },
+                          },
+                        ],
+                    "FilterNumberOfEntries" => { writable => 0 },
+                    MaxBridgeEntries => { writable => 0 },
+                    MaxFilterEntries => { writable => 0 },
+                  },
+              Layer3Forwarding => {
+                    "DefaultConnectionService" => { writable => 0 },
+                    "ForwardNumberOfEntries" => { writable => 0 },
+                    Forwarding => [
+                          undef,
+                          {
+                            DestIPAddress    => { writable => 1 },
+                            DestSubnetMask   => { writable => 1 },
+                            ForwardingMetric => { writable => 1 },
+                            GatewayIPAddress => { writable => 1 },
+                            Interface        => { writable => 1 },
+                          },
+                          {
+                            DestIPAddress    => { writable => 1 },
+                            DestSubnetMask   => { writable => 1 },
+                            ForwardingMetric => { writable => 1 },
+                            GatewayIPAddress => { writable => 1 },
+                            Interface        => { writable => 1 },
+                          },
+                        ],
+                  },
+              ManagementServer => {
+                    "ConnectionRequestPassword" => { writable => 1 },
+                    ConnectionRequestURL => { writable => 0 },
+                    "ConnectionRequestUsername" => { writable => 1 },
+                    ParameterKey => { writable => 0 },
+                    Password => { writable => 1 },
+                    PeriodicInformEnable => { writable => 1 },
+                    "PeriodicInformInterval" => { writable => 1 },
+                    PeriodicInformTime => { writable => 1 },
+                    URL => { writable => 1 },
+                    UpgradesManaged => { writable => 1 },
+                    Username => { writable => 1 },
+                  },
+              Services => {
+                    VoiceService                  => [
+                                                       undef,
+                                                       {
+                                                         Capabilities => {
+                                                               ButtonMap                => { writable => 0 },
+                                                               Codecs                   => [
+                                                                                             undef,
+                                                                                             {
+                                                                                               BitRate => { writable => 0 },
+                                                                                               Codec => { writable => 0 },
+                                                                                               EntryID => { writable => 0 },
+                                                                                               PacketizationPeriod => { writable => 0 },
+                                                                                               SilenceSuppression => { writable => 0 },
+                                                                                             },
+                                                                                             {
+                                                                                               BitRate => { writable => 0 },
+                                                                                               Codec => { writable => 0 },
+                                                                                               EntryID => { writable => 0 },
+                                                                                               PacketizationPeriod => { writable => 0 },
+                                                                                               SilenceSuppression => { writable => 0 },
+                                                                                             },
+                                                                                             {
+                                                                                               BitRate => { writable => 0 },
+                                                                                               Codec => { writable => 0 },
+                                                                                               EntryID => { writable => 0 },
+                                                                                               PacketizationPeriod => { writable => 0 },
+                                                                                               SilenceSuppression => { writable => 0 },
+                                                                                             },
+                                                                                             {
+                                                                                               BitRate => { writable => 0 },
+                                                                                               Codec => { writable => 0 },
+                                                                                               EntryID => { writable => 0 },
+                                                                                               PacketizationPeriod => { writable => 0 },
+                                                                                               SilenceSuppression => { writable => 0 },
+                                                                                             },
+                                                                                             {
+                                                                                               BitRate => { writable => 0 },
+                                                                                               Codec => { writable => 0 },
+                                                                                               EntryID => { writable => 0 },
+                                                                                               PacketizationPeriod => { writable => 0 },
+                                                                                               SilenceSuppression => { writable => 0 },
+                                                                                             },
+                                                                                             {
+                                                                                               BitRate => { writable => 0 },
+                                                                                               Codec => { writable => 0 },
+                                                                                               EntryID => { writable => 0 },
+                                                                                               PacketizationPeriod => { writable => 0 },
+                                                                                               SilenceSuppression => { writable => 0 },
+                                                                                             },
+                                                                                             {
+                                                                                               BitRate => { writable => 0 },
+                                                                                               Codec => { writable => 0 },
+                                                                                               EntryID => { writable => 0 },
+                                                                                               PacketizationPeriod => { writable => 0 },
+                                                                                               SilenceSuppression => { writable => 0 },
+                                                                                             },
+                                                                                           ],
+                                                               DSCPCoupled              => { writable => 0 },
+                                                               DigitMap                 => { writable => 0 },
+                                                               "EthernetTaggingCoupled" => { writable => 0 },
+                                                               FaxPassThrough           => { writable => 0 },
+                                                               FaxT38                   => { writable => 0 },
+                                                               MaxLineCount             => { writable => 0 },
+                                                               MaxProfileCount          => { writable => 0 },
+                                                               MaxSessionCount          => { writable => 0 },
+                                                               MaxSessionsPerLine       => { writable => 0 },
+                                                               ModemPassThrough         => { writable => 0 },
+                                                               NumberingPlan            => { writable => 0 },
+                                                               PSTNSoftSwitchOver       => { writable => 0 },
+                                                               RTCP                     => { writable => 0 },
+                                                               RTPRedundancy            => { writable => 0 },
+                                                               Regions                  => { writable => 0 },
+                                                               RingGeneration           => { writable => 0 },
+                                                               SIP                      => {
+                                                                                             EventSubscription => { writable => 0 },
+                                                                                             Extensions        => { writable => 0 },
+                                                                                             ResponseMap       => { writable => 0 },
+                                                                                             Role              => { writable => 0 },
+                                                                                             Transports        => { writable => 0 },
+                                                                                             URISchemes        => { writable => 0 },
+                                                                                           },
+                                                               SRTP                     => { writable => 0 },
+                                                               SignalingProtocols       => { writable => 0 },
+                                                               ToneGeneration           => { writable => 0 },
+                                                               VoicePortTests           => { writable => 0 },
+                                                             },
+                                                         PhyInterface => [
+                                                               undef,
+                                                               {
+                                                                 Description => { writable => 0 },
+                                                                 InterfaceID => { writable => 0 },
+                                                                 PhyPort     => { writable => 0 },
+                                                               },
+                                                               {
+                                                                 Description => { writable => 0 },
+                                                                 InterfaceID => { writable => 0 },
+                                                                 PhyPort     => { writable => 0 },
+                                                               },
+                                                             ],
+                                                         VoiceProfile => [
+                                                               undef,
+                                                               {
+                                                                 DTMFMethod => { writable => 1 },
+                                                                 DTMFMethodG711 => { writable => 1 },
+                                                                 Enable => { writable => 1 },
+                                                                 FaxPassThrough => { writable => 1 },
+                                                                 FaxT38 => {
+                                                                       Enable => { writable => 1 },
+                                                                       HighSpeedRedundancy => { writable => 1 },
+                                                                       LowSpeedRedundancy => { writable => 1 },
+                                                                     },
+                                                                 Line => [
+                                                                       undef,
+                                                                       {
+                                                                         CallingFeatures => {
+                                                                               AnonymousCalEnable               => { writable => 1 },
+                                                                               "CallForwardOnBusyEnable"        => { writable => 1 },
+                                                                               "CallForwardOnBusyNumber"        => { writable => 1 },
+                                                                               "CallForwardOnNoAnswerEnable"    => { writable => 1 },
+                                                                               "CallForwardOnNoAnswerNumber"    => { writable => 1 },
+                                                                               "CallForwardUnconditionalEnable" => { writable => 1 },
+                                                                               "CallForwardUnconditionalNumber" => { writable => 1 },
+                                                                               CallReturnEnable                 => { writable => 1 },
+                                                                               CallTransferEnable               => { writable => 1 },
+                                                                               CallWaitingEnable                => { writable => 1 },
+                                                                               CallerIDEnable                   => { writable => 1 },
+                                                                               CallerIDName                     => { writable => 1 },
+                                                                               CallerIDNameEnable               => { writable => 1 },
+                                                                               MWIEnable                        => { writable => 1 },
+                                                                               MaxSessions                      => { writable => 0 },
+                                                                             },
+                                                                         CodecList => [
+                                                                               undef,
+                                                                               {
+                                                                                 BitRate => { writable => 0 },
+                                                                                 Codec => { writable => 0 },
+                                                                                 Enable => { writable => 1 },
+                                                                                 EntryID => { writable => 0 },
+                                                                                 PacketizationPeriod => { writable => 1 },
+                                                                                 Priority => { writable => 1 },
+                                                                                 SilenceSuppression => { writable => 1 },
+                                                                               },
+                                                                               {
+                                                                                 BitRate => { writable => 0 },
+                                                                                 Codec => { writable => 0 },
+                                                                                 Enable => { writable => 1 },
+                                                                                 EntryID => { writable => 0 },
+                                                                                 PacketizationPeriod => { writable => 1 },
+                                                                                 Priority => { writable => 1 },
+                                                                                 SilenceSuppression => { writable => 1 },
+                                                                               },
+                                                                               {
+                                                                                 BitRate => { writable => 0 },
+                                                                                 Codec => { writable => 0 },
+                                                                                 Enable => { writable => 1 },
+                                                                                 EntryID => { writable => 0 },
+                                                                                 PacketizationPeriod => { writable => 1 },
+                                                                                 Priority => { writable => 1 },
+                                                                                 SilenceSuppression => { writable => 1 },
+                                                                               },
+                                                                               {
+                                                                                 BitRate => { writable => 0 },
+                                                                                 Codec => { writable => 0 },
+                                                                                 Enable => { writable => 1 },
+                                                                                 EntryID => { writable => 0 },
+                                                                                 PacketizationPeriod => { writable => 1 },
+                                                                                 Priority => { writable => 1 },
+                                                                                 SilenceSuppression => { writable => 1 },
+                                                                               },
+                                                                               {
+                                                                                 BitRate => { writable => 0 },
+                                                                                 Codec => { writable => 0 },
+                                                                                 Enable => { writable => 1 },
+                                                                                 EntryID => { writable => 0 },
+                                                                                 PacketizationPeriod => { writable => 1 },
+                                                                                 Priority => { writable => 1 },
+                                                                                 SilenceSuppression => { writable => 1 },
+                                                                               },
+                                                                               {
+                                                                                 BitRate => { writable => 0 },
+                                                                                 Codec => { writable => 0 },
+                                                                                 Enable => { writable => 1 },
+                                                                                 EntryID => { writable => 0 },
+                                                                                 PacketizationPeriod => { writable => 1 },
+                                                                                 Priority => { writable => 1 },
+                                                                                 SilenceSuppression => { writable => 1 },
+                                                                               },
+                                                                               {
+                                                                                 BitRate => { writable => 0 },
+                                                                                 Codec => { writable => 0 },
+                                                                                 Enable => { writable => 1 },
+                                                                                 EntryID => { writable => 0 },
+                                                                                 PacketizationPeriod => { writable => 1 },
+                                                                                 Priority => { writable => 1 },
+                                                                                 SilenceSuppression => { writable => 1 },
+                                                                               },
+                                                                             ],
+                                                                         Enable => { writable => 1 },
+                                                                         PhyReferenceList => { writable => 1 },
+                                                                         SIP => {
+                                                                               AuthPassword => { writable => 1 },
+                                                                               AuthUserName => { writable => 1 },
+                                                                               URI => { writable => 1 },
+                                                                             },
+                                                                         Session => [
+                                                                               undef,
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                               {
+                                                                                 SessionDuration  => { writable => 1 },
+                                                                                 SessionStartTime => { writable => 0 },
+                                                                               },
+                                                                             ],
+                                                                         Status => { writable => 0 },
+                                                                         VoiceProcessing => {
+                                                                               "EchoCancellationEnable" => { writable => 1 },
+                                                                               EchoCancellationTail     => { writable => 0 },
+                                                                             },
+                                                                       },
+                                                                     ],
+                                                                 MaxSessions => { writable => 0 },
+                                                                 Name => { writable => 1 },
+                                                                 NumberOfLines => { writable => 0 },
+                                                                 NumberingPlan => {
+                                                                       PrefixInfo => [
+                                                                             undef,
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                             {
+                                                                               FacilityAction            => { writable => 1 },
+                                                                               "NumberOfDigitsToRemove"  => { writable => 1 },
+                                                                               PosOfDigitsToRemove       => { writable => 1 },
+                                                                               "PrefixMaxNumberOfDigits" => { writable => 1 },
+                                                                               "PrefixMinNumberOfDigits" => { writable => 1 },
+                                                                               PrefixRange               => { writable => 1 },
+                                                                             },
+                                                                           ],
+                                                                       PrefixInfoMaxEntries => { writable => 0 },
+                                                                       "PrefixInfoNumberOfEntries" => { writable => 0 },
+                                                                     },
+                                                                 PSTNFailOver => { writable => 1 },
+                                                                 RTP => {
+                                                                       DSCPMark     => { writable => 1 },
+                                                                       LocalPortMax => { writable => 1 },
+                                                                       LocalPortMin => { writable => 1 },
+                                                                     },
+                                                                 Region => { writable => 1 },
+                                                                 Reset => { writable => 1 },
+                                                                 SIP => {
+                                                                       DSCPMark                            => { writable => 1 },
+                                                                       InboundAuth                         => { writable => 0 },
+                                                                       InboundAuthPassword                 => { writable => 1 },
+                                                                       InboundAuthUsername                 => { writable => 1 },
+                                                                       InviteExpires                       => { writable => 1 },
+                                                                       Organization                        => { writable => 1 },
+                                                                       OutboundProxy                       => { writable => 1 },
+                                                                       OutboundProxyPort                   => { writable => 1 },
+                                                                       ProxyServer                         => { writable => 1 },
+                                                                       ProxyServerPort                     => { writable => 1 },
+                                                                       ProxyServerTransport                => { writable => 1 },
+                                                                       ReInviteExpires                     => { writable => 1 },
+                                                                       RegisterExpires                     => { writable => 1 },
+                                                                       "RegisterRetryInterval"             => { writable => 1 },
+                                                                       RegistersMinExpires                 => { writable => 1 },
+                                                                       RegistrarServer                     => { writable => 1 },
+                                                                       RegistrarServerPort                 => { writable => 1 },
+                                                                       "RegistrarServerTransport"          => { writable => 1 },
+                                                                       RegistrationPeriod                  => { writable => 1 },
+                                                                       "SIPEventSubscribeNumberOfElements" => { writable => 0 },
+                                                                       "SIPResponseMapNumberOfElements"    => { writable => 0 },
+                                                                       TimerA                              => { writable => 1 },
+                                                                       TimerB                              => { writable => 1 },
+                                                                       TimerC                              => { writable => 1 },
+                                                                       TimerD                              => { writable => 1 },
+                                                                       TimerE                              => { writable => 1 },
+                                                                       TimerF                              => { writable => 1 },
+                                                                       TimerG                              => { writable => 1 },
+                                                                       TimerH                              => { writable => 1 },
+                                                                       TimerI                              => { writable => 1 },
+                                                                       TimerJ                              => { writable => 1 },
+                                                                       TimerK                              => { writable => 1 },
+                                                                       TimerT1                             => { writable => 1 },
+                                                                       TimerT2                             => { writable => 1 },
+                                                                       TimerT4                             => { writable => 1 },
+                                                                       "UseCodecPriorityInSDPResponse"     => { writable => 1 },
+                                                                       UserAgentDomain                     => { writable => 1 },
+                                                                       UserAgentPort                       => { writable => 1 },
+                                                                       UserAgentTransport                  => { writable => 1 },
+                                                                     },
+                                                                 SignalingProtocol => { writable => 1 },
+                                                               },
+                                                             ],
+                                                         "VoiceProfileNumberOfEntries" => { writable => 0 },
+                                                       },
+                                                     ],
+                    X_000E50_DynamicDNS           => {
+                                                       "ClientNumberOfEntries" => { writable => 0 },
+                                                       Service => [
+                                                             undef,
+                                                             {
+                                                               MaxRetries => { writable => 1 },
+                                                               Name => { writable => 0 },
+                                                               Request => { writable => 1 },
+                                                               RetryInterval => { writable => 1 },
+                                                               Server => { writable => 1 },
+                                                               ServerPort => { writable => 1 },
+                                                               UpdateInterval => { writable => 1 },
+                                                             },
+                                                             {
+                                                               MaxRetries => { writable => 1 },
+                                                               Name => { writable => 0 },
+                                                               Request => { writable => 1 },
+                                                               RetryInterval => { writable => 1 },
+                                                               Server => { writable => 1 },
+                                                               ServerPort => { writable => 1 },
+                                                               UpdateInterval => { writable => 1 },
+                                                             },
+                                                             {
+                                                               MaxRetries => { writable => 1 },
+                                                               Name => { writable => 0 },
+                                                               Request => { writable => 1 },
+                                                               RetryInterval => { writable => 1 },
+                                                               Server => { writable => 1 },
+                                                               ServerPort => { writable => 1 },
+                                                               UpdateInterval => { writable => 1 },
+                                                             },
+                                                             {
+                                                               MaxRetries => { writable => 1 },
+                                                               Name => { writable => 0 },
+                                                               Request => { writable => 1 },
+                                                               RetryInterval => { writable => 1 },
+                                                               Server => { writable => 1 },
+                                                               ServerPort => { writable => 1 },
+                                                               UpdateInterval => { writable => 1 },
+                                                             },
+                                                             {
+                                                               MaxRetries => { writable => 1 },
+                                                               Name => { writable => 0 },
+                                                               Request => { writable => 1 },
+                                                               RetryInterval => { writable => 1 },
+                                                               Server => { writable => 1 },
+                                                               ServerPort => { writable => 1 },
+                                                               UpdateInterval => { writable => 1 },
+                                                             },
+                                                             {
+                                                               MaxRetries => { writable => 1 },
+                                                               Name => { writable => 0 },
+                                                               Request => { writable => 1 },
+                                                               RetryInterval => { writable => 1 },
+                                                               Server => { writable => 1 },
+                                                               ServerPort => { writable => 1 },
+                                                               UpdateInterval => { writable => 1 },
+                                                             },
+                                                           ],
+                                                       "ServiceNumberOfEntries" => { writable => 0 },
+                                                     },
+                    X_000E50_Internet             => {
+                                                       LANConnection => { writable => 1 },
+                                                       WANConnection => { writable => 1 },
+                                                     },
+                    "X_000E50_NATApplicationList" => {
+                                                       Application => [
+                                                             undef,
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                                                       ExternalPortRangeEnd => { writable => 1 },
+                                                                       InternalPort => { writable => 1 },
+                                                                       Protocol => { writable => 1 },
+                                                                     },
+                                                                   ],
+                                                               RuleNumberOfEntries => { writable => 0 },
+                                                             },
+                                                             {
+                                                               HostIPAddress => { writable => 1 },
+                                                               Name => { writable => 1 },
+                                                               Rule => [
+                                                                     undef,
+                                                                     {
+                                                                       ExternalPort => { writable => 1 },
+                                            &nb