/[cwmp]/google/trunk/lib/CWMP/Store.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /google/trunk/lib/CWMP/Store.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 112 - (hide annotations)
Fri Oct 26 11:42:39 2007 UTC (16 years, 6 months ago) by dpavlin
File size: 3459 byte(s)
reorg source code tree to make trunk
1 dpavlin 77 # Dobrica Pavlinusic, <dpavlin@rot13.org> 06/22/07 14:35:38 CEST
2     package CWMP::Store;
3    
4     use strict;
5     use warnings;
6    
7    
8     use base qw/Class::Accessor/;
9     __PACKAGE__->mk_accessors( qw/
10     debug
11     path
12    
13 dpavlin 79 db
14 dpavlin 77 / );
15    
16 dpavlin 79 use Carp qw/confess/;
17 dpavlin 77 use Data::Dump qw/dump/;
18     use DBM::Deep;
19    
20     =head1 NAME
21    
22     CWMP::Store - parsist CPE state on disk
23    
24     =head1 METHODS
25    
26     =head2 new
27    
28     my $store = CWMP::Store->new({
29     path => '/path/to/state.db',
30     debug => 1,
31     });
32    
33     =cut
34    
35     sub new {
36     my $class = shift;
37     my $self = $class->SUPER::new( @_ );
38    
39     warn "created ", __PACKAGE__, "(", dump( @_ ), ") object\n" if $self->debug;
40    
41 dpavlin 84 confess "need path to state.db" unless ( $self->path );
42    
43 dpavlin 79 $self->db(
44 dpavlin 77 DBM::Deep->new(
45     file => $self->path,
46     locking => 1,
47     autoflush => 1,
48     )
49     );
50    
51 dpavlin 95 foreach my $init ( qw/ state session / ) {
52     $self->db->put( $init => {} ) unless $self->db->get( $init );
53     }
54    
55 dpavlin 77 return $self;
56     }
57    
58 dpavlin 79 =head2 update_state
59 dpavlin 77
60 dpavlin 100 $store->update_state( ID => $ID, $state );
61     $store->update_state( uid => $uid, $state );
62 dpavlin 79
63     =cut
64    
65     sub update_state {
66     my $self = shift;
67    
68 dpavlin 100 my ( $k, $v, $state ) = @_;
69 dpavlin 79
70 dpavlin 100 confess "need ID or uid" unless $k =~ m/^(ID|uid)$/;
71     confess "need $k value" unless $v;
72 dpavlin 79 confess "need state" unless $state;
73    
74 dpavlin 100 warn "## update_state( $k => $v, ", dump( $state ), " )\n" if $self->debug;
75    
76     my $uid;
77    
78     if ( $k eq 'ID' ) {
79     if ( $uid = $self->ID_to_uid( $v, $state ) ) {
80     # nop
81 dpavlin 95 } else {
82 dpavlin 100 warn "## no uid for $v, first seen?\n" if $self->debug;
83     return;
84 dpavlin 95 }
85 dpavlin 81 } else {
86 dpavlin 100 $uid = $v;
87 dpavlin 81 }
88 dpavlin 100
89     if ( my $o = $self->db->get('state')->get( $uid ) ) {
90     warn "## update state of $uid [$v]\n" if $self->debug;
91     return $o->import( $state );
92     } else {
93     warn "## create new state for $uid [$v]\n" if $self->debug;
94     return $self->db->get('state')->put( $uid => $state );
95     }
96 dpavlin 79 }
97 dpavlin 85
98     =head2 state
99    
100 dpavlin 100 my $state = $store->state( ID => $ID );
101     my $state = $store->state( uid => $uid );
102 dpavlin 85
103     Returns normal unblessed hash (actually, in-memory copy of state in database).
104    
105     =cut
106    
107     sub state {
108     my $self = shift;
109 dpavlin 100 my ( $k, $v ) = @_;
110     confess "need ID or uid" unless $k =~ m/^(ID|uid)$/;
111     confess "need $k value" unless $v;
112    
113 dpavlin 102 warn "## state( $k => $v )\n" if $self->debug;
114 dpavlin 100
115     my $uid;
116    
117     if ( $k eq 'ID' ) {
118     if ( $uid = $self->ID_to_uid( $v ) ) {
119     # nop
120 dpavlin 95 } else {
121 dpavlin 100 warn "## no uid for $v so no state!\n" if $self->debug;
122 dpavlin 95 return;
123     }
124     } else {
125 dpavlin 100 $uid = $v;
126     }
127    
128     if ( my $state = $self->db->get('state')->get( $uid ) ) {
129     return $state->export;
130     } else {
131 dpavlin 95 return;
132     }
133 dpavlin 100
134 dpavlin 85 }
135    
136 dpavlin 95 =head2 known_CPE
137    
138     my @cpe = $store->known_CPE;
139    
140     =cut
141    
142     sub known_CPE {
143     my $self = shift;
144     my @cpes = keys %{ $self->db->{state} };
145     warn "all CPE: ", dump( @cpes ), "\n" if $self->debug;
146     return @cpes;
147     }
148    
149     =head2 ID_to_uid
150    
151     my $CPE_uid = $store->ID_to_uid( $ID, $state );
152    
153     It uses C<< DeviceID.SerialNumber >> from C<Inform> message as unique ID
154     for each CPE.
155    
156     =cut
157    
158     sub ID_to_uid {
159     my $self = shift;
160     my ( $ID, $state ) = @_;
161    
162     confess "need ID" unless $ID;
163    
164 dpavlin 100 warn "ID_to_uid",dump( $ID, $state ),$/ if $self->debug;
165 dpavlin 95
166     $self->db->{session}->{ $ID }->{last_seen} = time();
167    
168     my $uid;
169    
170 dpavlin 100 if ( $uid = $self->db->{session}->{ $ID }->{ ID_to_uid } ) {
171 dpavlin 95 return $uid;
172     } elsif ( $uid = $state->{DeviceID}->{SerialNumber} ) {
173     warn "## created new session for $uid session $ID\n" if $self->debug;
174     $self->db->{session}->{ $ID } = {
175     last_seen => time(),
176     ID_to_uid => $uid,
177     };
178     return $uid;
179     } else {
180     warn "## can't find uid for ID $ID, first seen?\n";
181     return;
182     }
183    
184     # TODO: expire sessions longer than 30m
185    
186     return;
187     }
188    
189 dpavlin 77 1;

  ViewVC Help
Powered by ViewVC 1.1.26