-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmetrics.c
111 lines (73 loc) · 2.86 KB
/
metrics.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* Copyright (C) 2006 BATMAN contributors:
* Axel Neumann
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
*
*/
#include <stdio.h>
#include <string.h>
#include "batman.h"
#include "os.h"
#include "originator.h"
#include "metrics.h"
void flush_sq_record( struct sq_record *sqr ) {
sqr->wa_val = sqr->wa_unscaled = 0;
sqr->wa_clr_sqn = sqr->wa_set_sqn = ((SQ_TYPE) (sqr->wa_clr_sqn - (MAX_PATH_LOUNGE + MAX_PWS + 1)));
}
void update_lounged_metric(uint8_t probe, uint8_t lounge_size, SQ_TYPE sqn_incm, SQ_TYPE sqn_max, struct sq_record *sqr, uint8_t ws)
{
SQ_TYPE sq_upd;
if ( probe )
sq_upd = sqn_incm;
else if ( ((SQ_TYPE)(sqn_max - sqr->wa_clr_sqn )) > lounge_size )
sq_upd = sqn_max - lounge_size;
else
return;
uint32_t m_weight = ws/2;
SQ_TYPE i, offset = sq_upd - sqr->wa_clr_sqn;
if ( offset >= ws ) {
sqr->wa_unscaled = 0;
} else {
for ( i=0; i < offset; i++ )
sqr->wa_unscaled -= ( sqr->wa_unscaled / m_weight );
}
sqr->wa_clr_sqn = sq_upd;
if ( probe /* && sqr->wa_set_sqn != sq_upd */ ) {
// paranoia( -500197, (sqr->wa_set_sqn == sq_upd) /*check validate_considered_order()*/ );
if ( sqr->wa_set_sqn != sq_upd ) {
sqr->wa_unscaled += ((probe * WA_SCALE_FACTOR) / m_weight);
sqr->wa_set_sqn = sq_upd;
} else {
dbg_mute( 20, DBGL_SYS, DBGT_ERR,
"update_lounged_metric() probe %d ls %d sqn_in %d sqn_max %d ws %d",
probe, lounge_size, sqn_incm, sqn_max, ws );
}
}
sqr->wa_val = sqr->wa_unscaled/WA_SCALE_FACTOR;
}
uint32_t upd_wavg( uint32_t *wavg, uint32_t probe, uint8_t weight_exp ) {
#ifndef NOPARANOIA
if ( weight_exp > 10 || (weight_exp && probe >= (uint32_t)(0x01<<(32-weight_exp))) )
dbg( DBGL_SYS, DBGT_ERR,
"probe or weight_exp value to large to calculate weighted average!"
"upd_wavg(wavg: %d, probe: %d, weight_exp: %d ) = %d:",
*wavg, probe, weight_exp, *wavg>>weight_exp );
#endif
if ( *wavg )
*wavg += probe - ((*wavg)>>weight_exp);
else
*wavg = probe<<weight_exp;
return WAVG(*wavg,weight_exp);
}