2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
15 * Copyright (C) 2020 embedd.ch
16 * Copyright (C) 2020 Felix Fietkau <nbd@nbd.name>
17 * Copyright (C) 2020 John Crispin <john@phrozen.org>
23 void usteer_node_set_blob(struct blob_attr
**dest
, struct blob_attr
*val
)
34 len
= *dest
? blob_pad_len(*dest
) : 0;
35 new_len
= blob_pad_len(val
);
37 *dest
= realloc(*dest
, new_len
);
38 memcpy(*dest
, val
, new_len
);
41 static struct usteer_node
*
42 usteer_node_higher_bssid(struct usteer_node
*node1
, struct usteer_node
*node2
)
46 for (i
= 0; i
< 6; i
++) {
47 if (node1
->bssid
[i
] == node2
->bssid
[i
])
49 if (node1
->bssid
[i
] < node2
->bssid
[i
])
58 static struct usteer_node
*
59 usteer_node_more_roam_interactions(struct usteer_node
*node
, struct usteer_node
*ref
)
61 int roam_actions_node
, roam_actions_ref
;
63 roam_actions_node
= node
->roam_source
+ node
->roam_destination
;
64 roam_actions_ref
= ref
->roam_source
+ ref
->roam_destination
;
65 if (roam_actions_node
< roam_actions_ref
)
71 static struct usteer_node
*
72 usteer_node_better_neighbor(struct usteer_node
*node
, struct usteer_node
*ref
)
74 struct usteer_node
*n1
, *n2
;
77 * 1. Return one node if the other one is NULL
78 * 2. Return the node with the higher roam events.
79 * 3. Return the node with the higher BSSID.
80 * 4. Return first method argument.
89 n1
= usteer_node_more_roam_interactions(node
, ref
);
90 n2
= usteer_node_more_roam_interactions(ref
, node
);
94 /* Identical roam interactions. Check BSSID */
95 n1
= usteer_node_higher_bssid(node
, ref
);
96 n2
= usteer_node_higher_bssid(ref
, node
);
104 usteer_node_get_next_neighbor(struct usteer_node
*current_node
, struct usteer_node
*last
)
106 struct usteer_remote_node
*rn
;
107 struct usteer_node
*next
= NULL
, *n1
, *n2
;
109 for_each_remote_node(rn
) {
110 if (next
== &rn
->node
)
113 if (strcmp(current_node
->ssid
, rn
->node
.ssid
))
116 /* Check if this node is ranked lower than the last one */
117 n1
= usteer_node_better_neighbor(last
, &rn
->node
);
118 n2
= usteer_node_better_neighbor(&rn
->node
, last
);
120 /* Identical rank. Skip. */
122 } else if (last
&& n1
== &rn
->node
) {
123 /* Candidate rank is higher than the last neighbor. Skip. */
127 /* Check with current next candidate */
128 n1
= usteer_node_better_neighbor(next
, &rn
->node
);
129 n2
= usteer_node_better_neighbor(&rn
->node
, next
);
131 /* Identical rank. Skip. */
133 } else if (n1
!= &rn
->node
) {
134 /* Next candidate ranked higher. */