From: Dobrica Pavlinusic Date: Sun, 18 Nov 2007 12:58:40 +0000 (+0000) Subject: r228@brr: dpavlin | 2007-11-18 13:58:05 +0100 X-Git-Url: http://git.rot13.org/?p=perl-cwmp.git;a=commitdiff_plain;h=73114373a890391990bba21f0b4eadb18a4a859b;ds=sidebyside r228@brr: dpavlin | 2007-11-18 13:58:05 +0100 - version bump [0.11] - rewrote CPE state management to actually work for multiple devices and simplify code in the process - CWMP::Store::DBMDeep don't return blessed objects any more git-svn-id: https://perl-cwmp.googlecode.com/svn/trunk@207 836a5e1a-633d-0410-964b-294494ad4392 --- diff --git a/Makefile.PL b/Makefile.PL index d34fa11..7e96075 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -3,7 +3,7 @@ use lib './lib'; use inc::Module::Install; name 'CWMP'; -version '0.10'; +version '0.11'; license 'GPL'; requires 'Net::Server'; requires 'HTTP::Daemon'; @@ -16,6 +16,7 @@ requires 'Net::HTTP'; requires 'Cwd'; requires 'File::Slurp'; requires 'DBM::Deep'; +requires 'Clone'; # CWMP::Store::DBMDeep requires 'Getopt::Long'; #requires 'Term::Shelly' => '0.03'; requires 'Module::Pluggable'; diff --git a/lib/CWMP/Session.pm b/lib/CWMP/Session.pm index b971331..c9c1f1f 100644 --- a/lib/CWMP/Session.pm +++ b/lib/CWMP/Session.pm @@ -139,7 +139,7 @@ sub process_request { } $self->state( $state ); - $self->store->update_state( ID => $state->{ID}, $state ); + $self->store->update_state( $state ); } else { @@ -160,7 +160,7 @@ sub process_request { $sock->send( "Set-Cookie: ID=" . $state->{ID} . "; path=/\r\n" ) if ( $state->{ID} ); - my $uid = $self->store->ID_to_uid( $state->{ID}, $state ); + my $uid = $self->store->state_to_uid( $state ); my $queue = CWMP::Queue->new({ id => $uid, diff --git a/lib/CWMP/Store.pm b/lib/CWMP/Store.pm index 2c79628..6d9a784 100644 --- a/lib/CWMP/Store.pm +++ b/lib/CWMP/Store.pm @@ -73,42 +73,26 @@ sub current_store { =head2 update_state - $store->update_state( ID => $ID, $state ); - $store->update_state( uid => $uid, $state ); + $store->update_state( $state ); =cut sub update_state { my $self = shift; - my ( $k, $v, $state ) = @_; + my ( $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 > 4; - - 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; - } + my $uid = $self->state_to_uid( $state ); + warn "#### update_state( ", dump( $state ), " ) for $uid\n" if $self->debug > 2; $self->current_store->update_uid_state( $uid, $state ); } =head2 get_state - my $state = $store->get_state( ID => $ID ); - my $state = $store->get_state( uid => $uid ); + my $state = $store->get_state( $uid ); Returns normal unblessed hash (actually, in-memory copy of state in database). @@ -116,24 +100,10 @@ Returns normal unblessed hash (actually, in-memory copy of state in database). sub get_state { my $self = shift; - my ( $k, $v ) = @_; - confess "need ID or uid" unless $k =~ m/^(ID|uid)$/; - confess "need $k value" unless $v; - - warn "#### get_state( $k => $v )\n" if $self->debug > 4; + my ( $uid ) = @_; + confess "need uid" unless $uid; - 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; - } + warn "#### get_state( $uid )\n" if $self->debug > 4; return $self->current_store->get_state( $uid ); @@ -152,47 +122,25 @@ sub all_uids { return @cpes; } -=head2 ID_to_uid +=head2 state_to_uid - my $CPE_uid = $store->ID_to_uid( $ID, $state ); + my $CPE_uid = $store->ID_to_uid( $state ); It uses C<< DeviceID.SerialNumber >> from C message as unique ID for each CPE. =cut -my $session; - -sub ID_to_uid { +sub state_to_uid { my $self = shift; - my ( $ID, $state ) = @_; - - confess "need ID" unless $ID; - - warn "#### ID_to_uid",dump( $ID, $state ),$/ if $self->debug > 4; - - warn "##### current session = ",dump( $session ), $/ if $self->debug > 5; - - $session->{ $ID }->{last_seen} = time(); - - my $uid; + my ( $state ) = @_; - if ( $uid = $session->{ $ID }->{ ID_to_uid } ) { - return $uid; - } elsif ( $uid = $state->{DeviceID}->{SerialNumber} ) { - warn "## created new session for $uid session $ID\n" if $self->debug; - $session->{ $ID } = { - last_seen => time(), - ID_to_uid => $uid, - }; - return $uid; - } else { - warn "## can't find uid for ID $ID, first seen?\n"; - } + warn "#### state_to_uid",dump( $state ),$/ if $self->debug > 4; - # TODO: expire sessions longer than 30m + my $uid = $state->{DeviceID}->{SerialNumber} || + confess "no DeviceID.SerialNumber in ",dump( $state ); - return; + return $uid; } 1; diff --git a/lib/CWMP/Store/DBMDeep.pm b/lib/CWMP/Store/DBMDeep.pm index 04e4959..80fabd1 100644 --- a/lib/CWMP/Store/DBMDeep.pm +++ b/lib/CWMP/Store/DBMDeep.pm @@ -6,6 +6,7 @@ use warnings; use DBM::Deep; use Data::Dump qw/dump/; +use Clone qw/clone/; use Carp qw/confess/; =head1 NAME @@ -62,12 +63,14 @@ sub open { sub update_uid_state { my ( $self, $uid, $state ) = @_; + my $data = clone( $state ); + if ( my $o = $db->get( $uid ) ) { warn "## update state of $uid\n" if $debug; - return $o->import( $state ); + $o->import( $data ); } else { warn "## create new state for $uid\n" if $debug; - return $db->put( $uid => $state ); + $db->put( $uid => $data ); } } @@ -81,9 +84,7 @@ sub get_state { my ( $self, $uid ) = @_; if ( my $state = $db->get( $uid ) ) { - return $state->export; - } else { - return; + $state->export; } } diff --git a/lib/CWMP/Vendor.pm b/lib/CWMP/Vendor.pm index f09f120..cc055da 100644 --- a/lib/CWMP/Vendor.pm +++ b/lib/CWMP/Vendor.pm @@ -42,12 +42,19 @@ sub new { my $cpe_faulty; my $serial2ip = { - 'CP0636JT3SH' => '192.168.1.242', - 'CP0644JTHJ4' => '192.168.1.253', + 'CP0636JT3SH' => '10.0.0.1', + 'CP0644JTHJ4' => '10.0.0.2', + 'CP0624BH55U' => '10.0.0.3', }; my ( $last_ip, $last_serial ); +=head2 state2serial + + my $serial = state2serial( $state ); + +=cut + sub state2serial { my $state = shift; @@ -61,6 +68,14 @@ sub state2serial { return ( $serial, $ip ); } +=head2 add_triggers + +Install all custom triggers + + CWMP::Vendor->add_triggers; + +=cut + sub add_triggers { warn __PACKAGE__, "->add_triggers\n" if $debug; diff --git a/scripts/software-upgrade.txt b/scripts/software-upgrade.txt new file mode 100644 index 0000000..1b5e1bf --- /dev/null +++ b/scripts/software-upgrade.txt @@ -0,0 +1 @@ +:software upgrade diff --git a/t/05-store.t b/t/05-store.t index 6e315a3..746ad4c 100755 --- a/t/05-store.t +++ b/t/05-store.t @@ -4,7 +4,7 @@ use warnings; my $debug = shift @ARGV; -use Test::More tests => 34; +use Test::More tests => 32; use Data::Dump qw/dump/; use Cwd qw/abs_path/; use lib 'lib'; @@ -42,29 +42,37 @@ sub test_store { }, }; - cmp_ok( $store->ID_to_uid( 42, $state ), 'eq', 123456, 'ID_to_uid' ); + cmp_ok( $store->state_to_uid( $state ), 'eq', 123456, 'state_to_uid' ); - ok( $store->update_state( ID => 42, $state ), 'update_state new' ); + ok( $store->update_state( $state ), 'update_state new' ); - ok( my $store_state = $store->get_state( ID => '42'), 'get_state ID' ); + ok( my $store_state = $store->get_state( 123456 ), 'get_state' ); - is_deeply( $store_state, $state, 'state ID' ); + isa_ok( $state, 'HASH' ); + isa_ok( $store_state, 'HASH' ); - ok( $store_state = $store->get_state( uid => 123456 ), 'get_state uid' ); + if ( $debug ) { - is_deeply( $store_state, $state, 'state ID same as uid' ); + diag "store_state = ",dump( $store_state ); + + } - ok( $store->update_state( ID => 42, { baz => 12345 } ), 'update_state existing' ); + is_deeply( $state, $store_state, 'state ID same as uid' ); - $state->{baz} = 12345; + ok( $store->update_state( { + DeviceID => { + SerialNumber => 123456, + }, + baz => 12345 + } ), 'update_state existing' ); - is_deeply( $store->get_state( ID => 42 ), $state, 'get_state ID' ); + $state->{baz} = 12345; - is_deeply( $store->get_state( uid => 123456 ), $state, 'get_state uid' ); + is_deeply( $store->get_state( 123456 ), $state, 'get_state' ); is_deeply( [ $store->all_uids ], [ 123456 ], 'all_uids' ); - ok( $store->update_state( ID => 11, { DeviceID => { SerialNumber => 99999 } } ), 'new device' ); + ok( $store->update_state( { DeviceID => { SerialNumber => 99999 } } ), 'new device' ); is_deeply( [ $store->all_uids ], [ 123456, 99999 ], 'all_uids' );