• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/usteer/node.c

  1 /*
  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.
  5  *
  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.
 10  *
 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.
 14  *
 15  *   Copyright (C) 2020 embedd.ch 
 16  *   Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> 
 17  *   Copyright (C) 2020 John Crispin <john@phrozen.org> 
 18  */
 19 
 20 #include "node.h"
 21 #include "usteer.h"
 22 
 23 struct usteer_remote_node *usteer_remote_node_by_bssid(uint8_t *bssid) {
 24         struct usteer_remote_node *rn;
 25 
 26         for_each_remote_node(rn) {
 27                 if (!memcmp(rn->node.bssid, bssid, 6))
 28                         return rn;
 29         }
 30 
 31         return NULL;
 32 }
 33 
 34 struct usteer_node *usteer_node_by_bssid(uint8_t *bssid) {
 35         struct usteer_remote_node *rn;
 36         struct usteer_local_node *ln;
 37 
 38         rn = usteer_remote_node_by_bssid(bssid);
 39         if (rn)
 40                 return &rn->node;
 41 
 42         ln = usteer_local_node_by_bssid(bssid);
 43         if (ln)
 44                 return &ln->node;
 45 
 46         return NULL;
 47 }
 48 
 49 void usteer_node_set_blob(struct blob_attr **dest, struct blob_attr *val)
 50 {
 51         int new_len;
 52         int len;
 53 
 54         if (!val) {
 55                 free(*dest);
 56                 *dest = NULL;
 57                 return;
 58         }
 59 
 60         len = *dest ? blob_pad_len(*dest) : 0;
 61         new_len = blob_pad_len(val);
 62         if (new_len != len)
 63                 *dest = realloc(*dest, new_len);
 64         memcpy(*dest, val, new_len);
 65 }
 66 
 67 static struct usteer_node *
 68 usteer_node_higher_bssid(struct usteer_node *node1, struct usteer_node *node2)
 69 {
 70         int i;
 71 
 72         for (i = 0; i < 6; i++) {
 73                 if (node1->bssid[i] == node2->bssid[i])
 74                         continue;
 75                 if (node1->bssid[i] < node2->bssid[i])
 76                         return node2;
 77 
 78                 break;
 79         }
 80 
 81         return node1;
 82 }
 83 
 84 static struct usteer_node *
 85 usteer_node_higher_roamability(struct usteer_node *node, struct usteer_node *ref)
 86 {
 87         uint64_t roamability_node, roamability_ref;
 88 
 89         roamability_node = ((uint64_t)(node->roam_events.source + node->roam_events.target)) * current_time / ((current_time - node->created) + 1);
 90         roamability_ref = ((uint64_t)(ref->roam_events.source + ref->roam_events.target)) * current_time / ((current_time - ref->created) + 1);
 91 
 92         if (roamability_node < roamability_ref)
 93                 return ref;
 94 
 95         return node;
 96 }
 97 
 98 static struct usteer_node *
 99 usteer_node_better_neighbor(struct usteer_node *node, struct usteer_node *ref)
100 {
101         struct usteer_node *n1, *n2;
102 
103         /**
104          * 1. Return one node if the other one is NULL
105          * 2. Return the node with the higher roam events.
106          * 3. Return the node with the higher BSSID.
107          * 4. Return first method argument.
108          */
109 
110         if (!ref)
111                 return node;
112 
113         if (!node)
114                 return ref;
115 
116         n1 = usteer_node_higher_roamability(node, ref);
117         n2 = usteer_node_higher_roamability(ref, node);
118         if (n1 == n2)
119                 return n1;
120 
121         /* Identical roam interactions. Check BSSID */
122         n1 = usteer_node_higher_bssid(node, ref);
123         n2 = usteer_node_higher_bssid(ref, node);
124         if (n1 == n2)
125                 return n1;
126 
127         return node;
128 }
129 
130 struct usteer_node *
131 usteer_node_get_next_neighbor(struct usteer_node *current_node, struct usteer_node *last)
132 {
133         struct usteer_remote_node *rn;
134         struct usteer_node *next = NULL, *n1, *n2;
135 
136         for_each_remote_node(rn) {
137                 if (next == &rn->node)
138                         continue;
139 
140                 if (strcmp(current_node->ssid, rn->node.ssid))
141                         continue;
142 
143                 /* Skip nodes which can't handle additional STA */
144                 if (rn->node.max_assoc && rn->node.n_assoc >= rn->node.max_assoc)
145                         continue;
146 
147                 /* Check if this node is ranked lower than the last one */
148                 n1 = usteer_node_better_neighbor(last, &rn->node);
149                 n2 = usteer_node_better_neighbor(&rn->node, last);
150                 if (n1 != n2) {
151                         /* Identical rank. Skip. */
152                         continue;
153                 } else if (last && n1 == &rn->node) {
154                         /* Candidate rank is higher than the last neighbor. Skip. */
155                         continue;
156                 }
157 
158                 /* Check with current next candidate */
159                 n1 = usteer_node_better_neighbor(next, &rn->node);
160                 n2 = usteer_node_better_neighbor(&rn->node, next);
161                 if (n1 != n2) {
162                         /* Identical rank. Skip. */
163                         continue;
164                 } else if (n1 != &rn->node) {
165                         /* Next candidate ranked higher. */
166                         continue;
167                 }
168 
169                 next = n1;              
170         }
171 
172         return next;
173 }
174 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt