73 |
|
|
74 |
=head2 update_state |
=head2 update_state |
75 |
|
|
76 |
$store->update_state( ID => $ID, $state ); |
$store->update_state( $state ); |
|
$store->update_state( uid => $uid, $state ); |
|
77 |
|
|
78 |
=cut |
=cut |
79 |
|
|
80 |
sub update_state { |
sub update_state { |
81 |
my $self = shift; |
my $self = shift; |
82 |
|
|
83 |
my ( $k, $v, $state ) = @_; |
my ( $state ) = @_; |
84 |
|
|
|
confess "need ID or uid" unless $k =~ m/^(ID|uid)$/; |
|
|
confess "need $k value" unless $v; |
|
85 |
confess "need state" unless $state; |
confess "need state" unless $state; |
86 |
|
|
87 |
warn "#### update_state( $k => $v, ", dump( $state ), " )\n" if $self->debug > 4; |
my $uid = $self->state_to_uid( $state ); |
|
|
|
|
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; |
|
|
} |
|
88 |
|
|
89 |
|
warn "#### update_state( ", dump( $state ), " ) for $uid\n" if $self->debug > 2; |
90 |
$self->current_store->update_uid_state( $uid, $state ); |
$self->current_store->update_uid_state( $uid, $state ); |
91 |
} |
} |
92 |
|
|
93 |
=head2 get_state |
=head2 get_state |
94 |
|
|
95 |
my $state = $store->get_state( ID => $ID ); |
my $state = $store->get_state( $uid ); |
|
my $state = $store->get_state( uid => $uid ); |
|
96 |
|
|
97 |
Returns normal unblessed hash (actually, in-memory copy of state in database). |
Returns normal unblessed hash (actually, in-memory copy of state in database). |
98 |
|
|
100 |
|
|
101 |
sub get_state { |
sub get_state { |
102 |
my $self = shift; |
my $self = shift; |
103 |
my ( $k, $v ) = @_; |
my ( $uid ) = @_; |
104 |
confess "need ID or uid" unless $k =~ m/^(ID|uid)$/; |
confess "need uid" unless $uid; |
105 |
confess "need $k value" unless $v; |
|
106 |
|
warn "#### get_state( $uid )\n" if $self->debug > 4; |
|
warn "#### get_state( $k => $v )\n" if $self->debug > 4; |
|
|
|
|
|
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; |
|
|
} |
|
107 |
|
|
108 |
return $self->current_store->get_state( $uid ); |
return $self->current_store->get_state( $uid ); |
109 |
|
|
122 |
return @cpes; |
return @cpes; |
123 |
} |
} |
124 |
|
|
125 |
=head2 ID_to_uid |
=head2 state_to_uid |
126 |
|
|
127 |
my $CPE_uid = $store->ID_to_uid( $ID, $state ); |
my $CPE_uid = $store->ID_to_uid( $state ); |
128 |
|
|
129 |
It uses C<< DeviceID.SerialNumber >> from C<Inform> message as unique ID |
It uses C<< DeviceID.SerialNumber >> from C<Inform> message as unique ID |
130 |
for each CPE. |
for each CPE. |
131 |
|
|
132 |
=cut |
=cut |
133 |
|
|
134 |
my $session; |
sub state_to_uid { |
|
|
|
|
sub ID_to_uid { |
|
135 |
my $self = shift; |
my $self = shift; |
136 |
my ( $ID, $state ) = @_; |
my ( $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; |
|
137 |
|
|
138 |
if ( $uid = $session->{ $ID }->{ ID_to_uid } ) { |
warn "#### state_to_uid",dump( $state ),$/ if $self->debug > 4; |
|
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"; |
|
|
} |
|
139 |
|
|
140 |
# TODO: expire sessions longer than 30m |
my $uid = $state->{DeviceID}->{SerialNumber} || |
141 |
|
confess "no DeviceID.SerialNumber in ",dump( $state ); |
142 |
|
|
143 |
return; |
return $uid; |
144 |
} |
} |
145 |
|
|
146 |
1; |
1; |