documentation: Parameter defaults and documentation

- Updated documentation files to describe parameters
- "Self-documenting" parameters added to code
- Parameter defaults revised
- Sample configuration file of defaults added

[cleanup commit message]
Signed-off-by: Nick Hainke <vincent@systemli.org>
This commit is contained in:
Ian Clowes 2022-02-17 16:36:07 +00:00 committed by Nick Hainke
parent ba305bb2c2
commit c54cd95abe
10 changed files with 725 additions and 244 deletions

View file

@ -1,123 +1,220 @@
# Configuring DAWN # Configuring DAWN
## Making Configuraton Changes ## Making Configuration Changes
Edit settings under Edit settings under
/etc/config/dawn /etc/config/dawn
After changes, restart daemon After changes, restart daemon
/etc/init.d/dawn restart /etc/init.d/dawn restart
The updated configuration can be shared with other DAWN instances via ubus: ## Resetting DAWN's Configuration
The configuration for several key sections (see per section notes below)
can be shared with other DAWN
instances via ubus. This can be used to "reset" the configuration file to
remove any items that are no longer used. To do this:
# Backup current config
cd /etc/config
mv dawn dawn.old
# Remove current config
vi dawn # Delete all 'config metric' and 'config times' sections
# Save and exit vi
# On another DAWN instance
ubus call dawn reload_config ubus call dawn reload_config
The configuration file on the original DAWN instance should
now have newly written sections containing only current parameter values.
You can also start two instances of DAWN with an empty configuration file
then use this method to write the default configuration for the relevant
sections.
## What Can Be Configured? ## What Can Be Configured?
The parameters that control DAWN are listed alphabetically below. This section describes how they are grouped to provide various features. The parameters that control DAWN are listed alphabetically below. This
section describes how they are grouped to provide various features.
### Client 'Kicking' ### Client 'Kicking'
DAWN's primary purpose is to move (aka "kick") client devices to the best AP. This is enabled via the `kicking` parameter. If it is zero you will see no devices being moved, but can use the log messages to see what would happen. DAWN's primary purpose is to move (aka "kick") client devices to the best
AP. This is enabled via the `kicking` parameter. If it is zero you will
see no devices being moved, but can use the log messages to see what would
happen.
See the following secions for details of the two main ways that DAWN may
decide to move a client device. If both methods are enabled RSSI Comparison
is evaluated first, and if it identifies a better target AP then the Absolute
RSSI method is not used.
Once DAWN has identified a device that might benefit from moving to a
different AP it does some final checks to ensure this won't be too disruptive.
- How busy the current client-AP connection is, see `bandwidth_threshold`
- Whether sufficiently better APs for the client have been consistently
found (rather than as a one-off, for example due to walking past a wall),
see `kicking_threshold` and `min_number_to_kick`
See also "Note 1: Legacy Clients" See also "Note 1: Legacy Clients"
### Client Connection Scoring ### Kicking Method 1: RSSI Comparison
DAWN calculates a "score" for the actual or potential connection between an AP and a client device. These values ar ehten compared to decide whether to move a client. The score includes several factors: This is enabled if the `kicking` parameter is set to 1 or 3.
DAWN calculates a "score" for the actual or potential connection between
an AP and a client device. These values are then compared to decide if a
client should be moved. The score includes several factors:
- The radio connection quality, see "Note 2: RSSI Scoring" - The radio connection quality, see "Note 2: RSSI Scoring"
- Support for 802.11 features that improve throughput, see `ht_support`, `no_ht_support`, `vht_support` and `no_vht_support` - Support for 802.11 features that improve throughput, see `ht_support`,
- How heavily the relevant radio is being used across all clients, see `chan_util`, `chan_util_val`, `max_chan_util` and `max_chan_util_val` `no_ht_support`, `vht_support` and `no_vht_support`
- How busy the current cliet-AP connection is, see `bandwidth_threshold` - How heavily the relevant radio is being used across all clients, see
- How many clients are connected to the AP, see `use_station_count` and `max_station_diff` `chan_util`, `chan_util_val`, `max_chan_util` and `max_chan_util_val`
- Whether sufficiently better APs for the client have been consistently found (rather than for example as a one-off due to walking past a wall), see `kicking_threshold` and `min_number_to_kick` - How many clients are connected to the AP, see `use_station_count` and
`max_station_diff`
### Kicking Method 2: Absolute RSSI
This is enabled if the `kicking` parameter is set to 2 or 3.
This is a simpler method where DAWN simply looks at the current RSSI radio
signal strength for the client device. If it is below the `rssi_centre`
value then a "soft" kick is done, which asks the device to look at other APs
but does not enforce this through a disconnection. Forced disconnection would be disruptive to legacy clients that may not be able to find a suitable AP to
connect to.
### Other Features ### Other Features
The following are less likely to need attention: The following are less likely to need attention:
- The way 802.11v Neighbor Reports are generated can be adjusted. - The way 802.11v Neighbor Reports are generated can be adjusted.
- `disassoc_nr_length` controls the number of entries in the list. - `disassoc_nr_length` controls the number of entries in the list.
- `set_hostapd_nr` controls the mechanism used to build the AP NR - `set_hostapd_nr` controls the mechanism used to build the AP NR
- "Static" will be sufficient for a small network, and contain all the AP entries - "Static" will be sufficient for a small network, and contain all
- "Dynamic" will allow a large network to automatically determine the optimal set for each AP, and contain a set of nearby APs the AP entries
- 802.11k has a number of methods for gathering BEACON reports. The preference for Passive, Active or Table can be set via `rrm_mode` - "Dynamic" will allow a large network to automatically determine
a suitable set for each AP, containing a set of nearby APs
- 802.11k has several methods for gathering BEACON reports. The
preference for Passive, Active or Table can be set via `rrm_mode`
## Configuration Notes ## Configuration Notes
### Note 1: Legacy Clients ### Note 1: Legacy Clients
802.11v introduced the capability for clients to be "politely" asked to move to a different AP, and DAWN uses this capability for clients that appear to support it. 802.11v introduced the capability for clients to be "politely" asked to
move to a different AP, and DAWN uses this capability for clients that
appear to support it.
By definition, there is no way to do this for clients that don't implement 802.11v. For these "legacy clients" DAWN can attempt to steer them away during the PROBE / ASSOCIATE / AUTHENTICATE process by returning status codes that indicate errors or unwillingness to accept. It can also force disconnection of a connected client by "tearing down" the connection, however this is quite brutal as the client then has to start a search for a new AP, and it may just want to come back to the same AP. If DAWN continues to try to not accept the client it is effectively denied wifi access. By definition, there is no way to do this for clients that don't implement
802.11v. For these "legacy clients" DAWN can attempt to steer them away
during the PROBE / ASSOCIATE / AUTHENTICATE process by returning status
codes that indicate errors or unwillingness to accept. It can also force
disconnection of a connected client by "tearing down" the connection,
however this is quite brutal as the client then must start a search for a
new AP, and it may just want to come back to the same AP. If DAWN
continues to try to not accept the client it is effectively denied wifi
access.
If you enable this legacy client behaviour via parameters indicated then you may hit challenges as it is less tested and reliable than the 802.11v supported steering. Reports on its success or otherwise are welcomed so it can be refined if necessary and possible (within the constriants of 802.11). If you enable this legacy client behaviour via parameters indicated then
you may hit challenges as it is less tested and reliable than the 802.11v
supported steering. Reports on its success or otherwise are welcomed so
it can be refined if necessary and possible (within the constraints of
802.11).
See: `eval_probe_req`, `eval_auth_req`, `eval_assoc_req`, `deny_auth_reason`, `deny_assoc_reason`, `min_probe_count` and `kicking` See: `eval_probe_req`, `eval_auth_req`, `eval_assoc_req`,
`deny_auth_reason`, `deny_assoc_reason`, `min_probe_count` and `kicking`
### Note 2: RSSI Scoring ### Note 2: RSSI Scoring
As a part of the scoring mechanism DAWN provides two mechanisms for evaluating the client-AP RSSI (radio signal) quality. Although DAWN does not prevent both mechanisms being enabled at the same time (via the relevant increment parameters) it may be difficult to obtain desired behaviour. As a part of the scoring mechanism DAWN provides two mechanisms for
evaluating the client-AP RSSI (radio signal) quality. Although DAWN does
not prevent both mechanisms being enabled at the same time (via the
relevant increment parameters) it may be difficult to obtain desired
behaviour.
Mechanism 1 is "stepped". If the RSSI value is better than the `rssi_val` value (or worse than the `low_rssi_val` value) then the AP score has the `rssi` (or `low_rssi`) increment values applied. This effective creates three "zones" of RSSI score, which may be sufficient for many cases. To disable this mode set both increment values to zero. Mechanism 1 is "stepped". If the RSSI value is better than the `rssi_val`
value (or worse than the `low_rssi_val` value) then the AP score has the
`rssi` (or `low_rssi`) increment values applied. This effective creates
three "zones" of RSSI score, which may be sufficient for many cases. To
disable this mode set both increment values to zero.
Mechanism 2 is "graduated". For each dB that the RSSI signal differs from the `rssi_centre` value the increment `rssi_weight` is applied. This can provide a more refined score, but may require more effort to get the parameters optimised. To disable this mode set the increment value to zero. Mechanism 2 is "graduated". For each dB that the RSSI signal differs from
the `rssi_centre` value the increment `rssi_weight` is applied. This can
provide a more refined score, but may require more effort to get the
parameters optimised. To disable this mode set the increment value to
zero.
## Feature Parameters ## Global Metric Parameters
These parameters go in the following section: These parameters go in the following section:
config metric 'global' config metric 'global'
And if marked with '+' are specified / repeated in each of these band specific sections (but not the 'global' section): This section is shared by `ubus call dawn reload_config`.
<!-- Use the following shell command to auto-generate the table rows from
DAWN source code:
grep 'CONFIG-G:' `find . -type f -name "*.[ch]"`| sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort
-->
|Parameter|Purpose|Notes [Default is bracketed]|
|---------|-------|-----|
|bandwidth_threshold|Maximum reported AP-client bandwidth permitted when kicking. Set to zero to disable the check.|[6] (Mbits/s)|
|chan_util_avg_period|Number of sampling periods to average channel utilization values over|[3]|
|deny_assoc_reason|802.11 code used when ASSOCIATION is denied|[17] (802.11 AP_UNABLE_TO_HANDLE_NEW_STA). See Note 1.|
|deny_auth_reason|802.11 code used when AUTHENTICATION is denied|[1] (802.11 UNSPECIFIED_FAILURE). See Note 1.|
|disassoc_nr_length|Number of entries to include in a 802.11v DISASSOCIATE Neighbor Report|[6] (Documented for use by iOS)|
|duration|802.11k BEACON request DURATION parameter|[0]|
|eval_assoc_req|Control whether ASSOCIATION frames are evaluated for rejection|[0 = No evaluation]; 1 = Evaluated. See Note 1.|
|eval_auth_req|Control whether AUTHENTICATION frames are evaluated for rejection|[0 = No evaluation]; 1 = Evaluated. See Note 1.|
|eval_probe_req|Control whether PROBE frames are evaluated for rejection|[0 = No evaluation]; 1 = Evaluated. See Note 1.|
|kicking|Method to select clients to move to better AP|0 = Disabled; 1 = RSSI Comparison; 2 = Absolute RSSI; [3 = Both] See note 1.|
|kicking_threshold|Minimum score difference to consider kicking to alternate AP|[20]|
|max_station_diff|Number of connected stations to consider "better" for use_station_count|[1]|
|min_number_to_kick|Number of consecutive times a client should be evaluated as ready to kick before actually doing it|[3]|
|min_probe_count|Number of times a client should retry PROBE before acceptance| [3] See Note 1.|
|neighbors|Space seperated list of MACS to use in "static" AP Neighbor Report| None|
|rrm_mode|Preferred order for using Passive, Active or Table 802.11k BEACON information|[PAT] String of 'P', 'A' and / or 'T'|
|set_hostapd_nr|Method used to set Neighbor Report on AP|[0 = Disabled]; 1 = "Static" based on all APs in network (plus set from configuration); 2 = "Dynamic" based on next nearest AP seen by current clients|
|use_station_count|Compare connected station counts when considering kicking|[0 = Disabled]; 1 = Enabled|
## Per Band Metric Parameters
These parameters are repeated in the following sections for each band:
config metric '802_11a' config metric '802_11a'
config metric '802_11g' config metric '802_11g'
<!-- Use the following shell command to auto-generate the table rows from DAWN source code: These sections are shared by `ubus call dawn reload_config`.
grep 'CONFIG-[FS]:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort
-->
|Parameter|Purpose|Notes|
|---------|-------|-----|
|bandwidth_threshold|Maximum reported AP-client bandwidth permitted when kicking|Default = 6 (Mbits/s)|
|chan_util_avg_period|Number of sampling periods to average channel utilization values over|Default = 3|
|chan_util+|Score increment if channel utilization is below chan_util_val|Default = 0|
|chan_util_val+|Threshold for good channel utilization|Default = 140|
|deny_assoc_reason|802.11 code used when ASSOCIATION is denied|17 = AP_UNABLE_TO_HANDLE_NEW_STA. See Note 1.|
|deny_auth_reason|802.11 code used when AUTHENTICATION is denied|1 = UNSPECIFIED_FAILURE. See Note 1.|
|disassoc_nr_length|Number of entries to include in a 802.11v DISASSOCIATE Neighbor Report|Default = 6, as documented for use by iOS|
|duration|802.11k BEACON request DURATION parameter|Default = 0|
|eval_assoc_req|Control whether ASSOCIATION frames are evaluated for rejection|0 = No evaluation; 1 = Evaluated. See Note 1.|
|eval_auth_req|Control whether AUTHENTICATION frames are evaluated for rejection|0 = No evaluation; 1 = Evaluated. See Note 1.|
|eval_probe_req|Control whether PROBE frames are evaluated for rejection|0 = No evaluation; 1 = Evaluated. See Note 1.|
|ht_support+|Score increment if HT is supported|Default = 10|
|initial_score+|Base score for AP based on operating band|2.4GHz = 0; 5Ghz = 100|
|kicking|Actively move clients to the best AP|0 = Disabled; 1 = Enabled for 802.11v clients; 2 = Also enabled for pre-802.11v clients. See note 1.|
|kicking_threshold|Minimum score difference to consider kicking to alternate AP|Default = 20|
|low_rssi+|Score addition when signal is below threshold|Default = -500. See note 2.|
|low_rssi_val+|Threshold for bad RSSI|Default = -80. See note 2.|
|max_chan_util+|Score increment if channel utilization is above max_chan_util_val|Default = -500|
|max_chan_util_val+|Threshold for bad channel utilization|Default = 170|
|max_station_diff|Number of connected stations to consider "better" for use_station_count|Default = 1|
|min_number_to_kick|Number of consecutive times a client should be evaluated as ready to kick before actually doing it|Default = 3|
|min_probe_count|Number of times a client should retry PROBE before acceptance| Default of 3. See Note 1.|
|neighbors+|Space seperated list of MACS to use in "static" AP Neighbor Report| None|
|no_ht_support+|Score incrment if HT is not supported|Default = 0 (Deprecated)|
|no_vht_support+|Score incrment if VHT is not supported|Default = 0 (Deprecated)|
|rrm_mode|Preferred order for using Passive, Active or Table 802.11k BEACON information|String of 'P', 'A' and / or 'T'|
|rssi_center+|Midpoint for weighted RSSI evaluation|Default = -70. See note 2.|
|rssi+|Score addition when signal exceeds threshold|Default = 10. See note 2.|
|rssi_val+|Threshold for an good RSSI|Default = -60. See note 2.|
|rssi_weight+|Per dB increment for weighted RSSI evaluation|Default = 0. See note 2.|
|set_hostapd_nr|Method used to set Neighbor Report on AP|0 = Disabled; 1 = "Static" based on all APs in network (plus set from configuration); 2 = "Dynamic" based on next nearest AP seen by current clients|
|use_station_count|Compare connected station counts when considering kicking|0 = Disabled; 1 = Enabled|
|vht_support+|Score increment if VHT is supported|Default = 100|
<!-- Use the following shell command to auto-generate the table rows from
DAWN source code:
grep 'CONFIG-B:' `find . -type f -name "*.[ch]"`| sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort
-->
|Parameter|Purpose|Notes [Default is bracketed]|
|---------|-------|-----|
|ap_weight|Per AP weighting|[0] (Deprecated)|
|chan_util|Score increment if channel utilization is below chan_util_val|[0]|
|chan_util_val|Upper threshold for good channel utilization|[140]|
|ht_support|Score increment if HT is supported|[5]|
|initial_score|Base score for AP based on operating band|[2.4GHz = 80; 5Ghz = 100]|
|low_rssi|Score addition when signal is below threshold|[-15] See note 2.|
|low_rssi_val|Threshold for bad RSSI|[-80] See note 2.|
|max_chan_util|Score increment if channel utilization is above max_chan_util_val|[-15]|
|max_chan_util_val|Lower threshold for bad channel utilization|[170]|
|no_ht_support|Score incrment if HT is not supported|[0] (Deprecated)|
|no_vht_support|Score incrment if VHT is not supported|[0] (Deprecated)|
|rssi_center|Midpoint for weighted RSSI evaluation|[-70] See note 2.|
|rssi|Score addition when signal exceeds threshold|[15] See note 2.|
|rssi_val|Threshold for an good RSSI|[-60] See note 2.|
|rssi_weight|Per dB increment for weighted RSSI evaluation|[0] See note 2.|
|vht_support|Score increment if VHT is supported|[5]|
## Networking Parameters ## Networking Parameters
TCP networking with UMDNS and without encryption is the most tested and stable configuration. TCP networking with UMDNS and without encryption is the most tested and
stable configuration.
Encryption has been reported to be broken, so use it with caution. Encryption has been reported to be broken, so use it with caution.
Other parameters have fallen out of use, but remain in the code. A tidy up of them is due. Other parameters have fallen out of use but remain in the code. A tidy up
of them is due.
These parameters go in the following section: These parameters go in the following section:
config network config network
<!-- Use the following shell command to auto-generate the table rows from DAWN source code:
This section is NOT shared by `ubus call dawn reload_config`.
<!-- Use the following shell command to auto-generate the table rows from
DAWN source code:
grep 'CONFIG-N:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort grep 'CONFIG-N:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort
--> -->
|Parameter|Purpose|Notes [Default is bracketed]| |Parameter|Purpose|Notes [Default is bracketed]|
@ -133,26 +230,35 @@ grep 'CONFIG-N:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\
|tcp_port|Port for TCP networking|[1025]| |tcp_port|Port for TCP networking|[1025]|
|use_symm_enc|Enable encryption of network traffic|[0 = Disabled]; 1 = Enabled| |use_symm_enc|Enable encryption of network traffic|[0 = Disabled]; 1 = Enabled|
## Local Parameters
Local parameters are not shared with other DAWN instances.
## Local Parameters
These parameters go in the following section: These parameters go in the following section:
config local config local
<!-- Use the following shell command to auto-generate the table rows from DAWN source code:
This section is NOT shared by `ubus call dawn reload_config`.
<!-- Use the following shell command to auto-generate the table rows from
DAWN source code:
grep 'CONFIG-L:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort grep 'CONFIG-L:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort
--> -->
|Parameter|Purpose|Notes [Default is bracketed]| |Parameter|Purpose|Notes [Default is bracketed]|
|---------|-------|-----| |---------|-------|-----|
|loglevel|Verbosity of messages in syslog|[0 = Important only - very few messages]; 1 = Show what DAWN is processing in a user friendly way; 2 = Trace certain operations - for debugging; 3 = Broad low level tracing - for debugging| |loglevel|Verbosity of messages in syslog|[0 = Important only - very few messages]; 1 = Show what DAWN is processing in a user friendly way; 2 = Trace certain operations - for debugging; 3 = Broad low level tracing - for debugging|
## Timing / Scheduling Parameters ## Timing / Scheduling Parameters
All timer values are in secinds. They are the main mechanism for DAWN collecting and managing much of the data that it relies on. All timer values are in seconds. They are the main mechanism for DAWN
collecting and managing much of the data that it relies on.
These parameters go in the following section: These parameters go in the following section:
config times config times
<!-- Use the following shell command to auto-generate the table rows from DAWN source code:
This section is shared by `ubus call dawn reload_config`.
<!-- Use the following shell command to auto-generate the table rows from
DAWN source code:
grep 'CONFIG-T:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort grep 'CONFIG-T:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort
--> -->
|Parameter|Purpose|Notes [Default is bracketed]| |Parameter|Purpose|Notes [Default is bracketed]|
@ -162,18 +268,22 @@ grep 'CONFIG-T:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\
|remove_probe|Timer to remove expired PROBE and BEACON entries from core data set|[30]| |remove_probe|Timer to remove expired PROBE and BEACON entries from core data set|[30]|
|update_beacon_reports|Timer to ask all connected clients for a new BEACON REPORT|[20]| |update_beacon_reports|Timer to ask all connected clients for a new BEACON REPORT|[20]|
|update_chan_util|Timer to get recent channel utilisation figure for each local BSSID|[5]| |update_chan_util|Timer to get recent channel utilisation figure for each local BSSID|[5]|
|update_client|Timer to send revised NEIGHBOR REPORT to all clients|[10]| |update_client|Timer to refresh local connection information and send revised NEIGHBOR REPORT to all clients|[10]|
|update_hostapd|Timer to (re-)register for hostapd messages for each local BSSID|[10]| |update_hostapd|Timer to (re-)register for hostapd messages for each local BSSID|[10]|
|update_tcp_con|Timer to refresh / remove the TCP connections to other DAWN instances found via uMDNS|[10]| |update_tcp_con|Timer to refresh / remove the TCP connections to other DAWN instances found via uMDNS|[10]|
## hostapd Parameters ## hostapd Parameters
These parameters go in the following section: These parameters go in the following section:
config hostapd config hostapd
<!-- Use the following shell command to auto-generate the table rows from DAWN source code:
This section is NOT shared by `ubus call dawn reload_config`.
<!-- Use the following shell command to auto-generate the table rows from
DAWN source code:
grep 'CONFIG-H:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort grep 'CONFIG-H:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\1|/'|sort
--> -->
|Parameter|Purpose|Notes [Default is bracketed]| |Parameter|Purpose|Notes [Default is bracketed]|
|---------|-------|-----| |---------|-------|-----|
|hostapd_dir|Path to hostapd runtime information|[/var/run/hostapd]| |hostapd_dir|Path to hostapd runtime information|[/var/run/hostapd]|

View file

@ -1,36 +1,75 @@
# DAWN Developer Guide # DAWN Developer Guide
This is an introduction to DAWN for developers that want to understand how it works so that they can modify, fix, etc its behaviour. This is an introduction to DAWN for developers that want to understand how
it works so that they can modify, fix, etc its behaviour.
## Component Overview ## Component Overview
DAWN collects and shares information about the APs and clients in the network by using a number of standard components. The below assumes it is running on an OpenWrt device. DAWN collects and shares information about the APs and clients in the
network by using several standard components. The below assumes it is
running on an OpenWrt device.
![OpenWrtInANuthshell](https://raw.githubusercontent.com/PolynomialDivision/upload_stuff/master/dawn_pictures/openwrt_in_a_nutshell_dawn.png) ![OpenWrtInANuthshell](https://raw.githubusercontent.com/PolynomialDivision
/upload_stuff/master/dawn_pictures/openwrt_in_a_nutshell_dawn.png)
Information about capability of the AP and current clients is discovered via the hostapd and iwinfo. The task to do this is scheduled by a timer. Information about capability of the AP and current clients is discovered
via the hostapd and iwinfo. The task to do this is scheduled by a timer.
hostapd also shares information about potential clients that are trying to connect, as received in 802.11 PROBE, AUTH and ASSOC requests, plus BEACON frames for 802.11k capable devices. hostapd also shares information about potential clients that are trying to
connect, as received in 802.11 PROBE, AUTH and ASSOC requests, plus BEACON
frames for 802.11k capable devices.
Communication with hostapd is via UBUS messages and callbacks. Communication with hostapd is via UBUS messages and callbacks.
This data is then exchanged with other DAWN instances that have been discovered via uMDNS. This means that every DAWN instance has a list of all clients and APs in the network, plus which APs have seen a clients (even if it is not a client). The most tested and stable method of doing this is via TCP. There are options for multicast and broadcast, but these are less tested and may fail. This data is then exchanged with other DAWN instances that have been
discovered via uMDNS. This means that every DAWN instance has a list of
all client devices and APs in the network, plus which APs have seen a
client device (even if it has not joined the network). The most tested
and stable method of doing this is via TCP. There are options for
multicast and broadcast, but these are less tested and may fail.
Internally to DAWN these sets of data are stored as linked lists, which allow scalability while ensuring that memory usage is reduced in a small network. Additional timers are used to remove "expired" data from these lists, so only a reasonably recent set is retained. Internally to DAWN these sets of data are stored as linked lists, which
allow scalability while ensuring that memory usage is reduced in a small
network. Additional timers are used to remove "expired" data from these
lists, so only a reasonably recent set is retained.
Another timer triggers periodically to ask the AP to look at each locally connected client and see if a better AP might be available. This is achieved by calculating a score for every AP that has a recent BEACON or PROBE entry for the client based on signal strength, band, etc. The scoring mechanism is described in the Configuration page. Another timer triggers periodically to ask the AP to look at each locally
connected client and see if a better AP might be available. This is
achieved by calculating a score for every AP that has a recent BEACON or
PROBE entry for the client based on signal strength, band, etc. The
scoring mechanism is described in the Configuration page.
If one or more other APs have a sufficiently better score then the current AP the device is asked to move using an 802.11 frame that DAWN requests (via UBUS) hostapd to send. For an 802.11v capable device a Disassociation Imminent frame is sent to encourage it to select one of the better APs in a DAWN generated Neighbor Report. For pre-802.11k devices a Deauthentication can be forced [TODO: Check this]. If one or more other APs have a sufficiently better score then the DAWN
instance on the current AP of the device uses hostapd (via UBUS) to send
an 802.11v Disassociation Imminent frame encouraging it to select one of
the better APs listed in the frame's Neighbor Report. This is followed by
Disassociation of the device (for 802.11v capable and legacy devices).
Additionally, for an 802.11k capable AP DAWN will use the BEACON reports from other APs to create a Neighbor Report for the AP. For instance if clients CL-A, CL-B and CL-C of AP-X report that they have reasonable signal strength to AP-M, AP-Q and AP-T then the NR for AP-X will be AP-M + AP-Q + AP-T. Other APs in the network that those clients can't see will not be in the NR. Additionally, for an 802.11k capable AP DAWN can use the BEACON reports
from other APs to create a Neighbor Report for the AP. For instance, if
clients CL-A, CL-B and CL-C of AP-X report that they have reasonable
signal strength to AP-M, AP-Q and AP-T then the NR for AP-X will be AP-M +
AP-Q + AP-T. Other APs in the network that those clients can't see will
not be in the NR. For simpler networks DAWN can use a simple list of all
APs for the NR.
# Creating a DAWN Development Environment # Creating a DAWN Development Environment
The code base for the main DAWN applicaton is C. It makes heavy use of pointers and pointer related structures such as linked lists. Although it is a single executable there are multiple code entry points that are used by callback functions, etc. Familiarity with C memory management, simple event based programming and resource management in a multi-threaded application is a baseline for working effectively with the code. The code base for the main DAWN application is C. It makes heavy use of
pointers and pointer related structures such as linked lists. Although it
is a single executable there are multiple code entry points that are used
by callback functions, etc. Familiarity with C memory management, simple
event-based programming and resource management in a multi-threaded
application is a baseline for working effectively with the code.
## Compiling DAWN ## Compiling DAWN
This section describes how to add tha currently published version of DAWN to a local OpenWrt build environment, so that you can add DAWN to locally built firmware images or the Image Builder target. It assumes you have some familiarity with building OpenWrt, so is more of an "aide memoir" than specific steps. In other words, just copying and pasting the below will not work! This section describes how to add the currently published version of DAWN
to a local OpenWrt build environment, so that you can add DAWN to locally
built firmware images or the Image Builder target. It assumes you have
some familiarity with building OpenWrt, so is more of an "aide memoir"
than specific steps. In other words, just copying and pasting the below
will not work!
Clone Openwrt Clone OpenWrt
https://git.openwrt.org/openwrt/openwrt.git https://git.openwrt.org/openwrt/openwrt.git
@ -51,9 +90,12 @@ Compile
make package/dawn/compile make package/dawn/compile
## Creating a local DAWN development instance ## Creating a local DAWN development instance
This section describes how to configure the OpenWrt build environment to use an alternate source code version, so you can work on that code. Do the above Compiling Dawn steps first. This section describes how to configure the OpenWrt build environment to
use an alternate source code version, so you can work on that code. Do
the above Compiling Dawn steps first.
Enable local source code (under `Advanced Configuration -> Enable package source-tree override`) Enable local source code (under `Advanced Configuration -> Enable package
source-tree override`)
make menuconfig make menuconfig
@ -61,7 +103,7 @@ Now you need to clone DAWN, e.g. into your home directory
git clone https://github.com/berlin-open-wireless-lab/DAWN.git ~/DAWN git clone https://github.com/berlin-open-wireless-lab/DAWN.git ~/DAWN
You have to add now a symlink. In the openwrt branch do something like You must then add a symlink. In the OpenWrt branch do something like
ln -s ~/DAWN/.git/ ~openwrt/feeds/packages/net/dawn/git-src ln -s ~/DAWN/.git/ ~openwrt/feeds/packages/net/dawn/git-src
@ -69,34 +111,72 @@ Now compile dawn
make package/dawn/{clean,compile} make package/dawn/{clean,compile}
You should then be able to copy the dawn binary executable file to your device to test your changes. You should then be able to copy the dawn binary executable file to your
device to test your changes.
## DAWN Quality Assurance ## DAWN Quality Assurance
### Runtime Messages ### Runtime Messages
Helper macros and functions are provied to assist with appropriate management of messages. The general convention is to issue messages one of the following priorities: Helper macros and functions named dawnlog_... are provided to assist with appropriate
- ERROR (0): A significant runtime failure, such as memory exhaustion or unexpected ability to write to a network socket. management of messages. The general convention is to issue messages one
- WARNING (0): An algorithmically unexpected event, such as no AP seeming to be the host for a client device. of the following priorities:
- ALWAYS (0): An infrequent information message that a user or administrator will want to see, such as a device being kicked from one AP to another. - ERROR (0): A significant runtime failure, such as memory exhaustion or
- INFO (1): Reasonably frequent messages that indicate normal operation, such as the arrival of hostapd messages. The log should still be "user friendly" at this level. unexpected ability to write to a network socket.
- TRACE (2): Messages that help indicate why a decision or code path was taken. - WARNING (0): An algorithmically unexpected event, such as no AP seeming
to be the host for a client device.
- ALWAYS (0): An infrequent information message that a user or
administrator will want to see, such as a device being kicked from one AP
to another.
- INFO (1): Reasonably frequent messages that indicate normal operation,
such as the arrival of hostapd messages. The log should still be "user
friendly" at this level.
- TRACE (2): Messages that help indicate why a decision or code path was
taken.
- DEBUG (3): Verbose tracing of code paths, etc. - DEBUG (3): Verbose tracing of code paths, etc.
The minimum logging level (as specified in /etc/config/dawn) at which the priority appears is indicated, eg (0). The minimum logging level (as specified in /etc/config/dawn) at which the
priority appears is indicated, eg (0).
### Memory handling ### Memory handling
There are wrappers for the standard C memory management functions malloc(), free(), etc. These help ensure that memory allocation is managed correctly by building a list of resources that have been allocated but not released. There are dawn_... wrappers for the standard C memory management functions
malloc(), free(), etc. These help ensure that memory allocation is
managed correctly by building a list of resources that have been allocated
but not released.
While DAWN is running sending a HUP signal to the process will generate a list of currently allocated blocks in the system log, visible with logread. While DAWN is running sending a HUP signal to the process will generate a
list of currently allocated blocks in the system log, visible with logread.
In a small network ony a few tens of blocks are needed. A longer list may suggest a memory leak, and inspection of the list to find multiple items allocated at the same line of code may indicate where it is arising. In a small network only a few tens of blocks are needed. A longer list
may suggest a memory leak, and inspection of the list to find multiple
items allocated at the same line of code with steadily increasing sequence
numbers may indicate where it is arising.
### MUTEX Handling ### MUTEX Handling
DAWN has a set of data lists that are accessed by code which is triggered by multiple event types (timer, network message, ubus message, etc). Because of this there is a chance that data could become corrupted by competing blocks of code, leading to invalid memory access, process faults, etc. Access to these resources is therefore managed by POSIX Threads mutex objects. DAWN has a set of data lists that are accessed by code which is triggered
by multiple event types (timer, network message, ubus message, etc).
Because of this there is a chance that data could become corrupted by
competing blocks of code, leading to invalid memory access, process
faults, etc. Access to these resources is therefore managed by POSIX
Threads mutex objects.
These potential problems will not be seen on a platform that is highly non-preemptive, so to help track down mutex handling errors such as accessing a resource without an appropriate lock helper functions are available. This helps ensure that when the same code is run on platforms which use pre-emptive scheduling it is less likely to hit threading bugs. These potential problems will not be seen on a platform that is highly
non-pre-emptive, so helper functions are available to help track down
mutex handling errors such as accessing a resource without an appropriate
lock. This helps ensure that when the same code is run on platforms which
use pre-emptive scheduling it is less likely to hit threading bugs.
dawn_mutex_require() can be used to indicate that a segment of code is accessing a resource that should be locked. Often the lock should be taken by a "higher up" block of code, and if it hasn't been a runtime warning will appear in the system log. Further messages in the logs from dawn_mutex_lock() and ..._unlock() can be used to help review threading issues, such as trying to take a lock twice, not at all, etc. dawn_mutex_require() can be used to indicate that a segment of code is
accessing a resource that should be locked. Often the lock should be
taken by a "higher up" block of code, and if it hasn't been a runtime
warning will appear in the system log. Further messages in the logs from
dawn_mutex_lock() and ..._unlock() can be used to help review threading
issues, such as trying to take a lock twice, not at all, etc.
### Test Harness ### Test Harness
In addition to the dawn binary another named test_storage is built by CMAKE. This can be used to excercise the core data storage and scoring algorithms to ensure that expected behaviour occurs. At the time of writing a number of *.script files exist that can be passed to test_storage, but these haven't necessrily been maintained as the code has evolved from when they were originally written. In addition to the main dawn binary another named test_storage is built by
CMAKE. This can be used to exercise the core data storage and scoring
algorithms to ensure that expected behaviour occurs. At the time of
writing a number of *.script files exist that can be passed to
test_storage, but these haven't necessarily been maintained as the code
has evolved from when they were originally written.

View file

@ -1,60 +1,105 @@
# DAWN Installation and Configuration # DAWN Installation
This guide should allow you to get DAWN running, and check its basic behaviour. This guide should allow you to get DAWN running, and check its basic
behaviour.
## Setting up Routers ## Setting up Routers
DAWN will typically run in a network where one AP is providing core networking services like DHCP and internet gateway, while other APs are being used to extend wifi network range. For example the "main" AP near the telecoms provider entry point, and one or more other AP on the other side of the house, in the garden, etc. Or a number of AP distributed about an office building. DAWN will typically run in a network where one AP is providing core
networking services like DHCP and internet gateway, while other APs are
being used to extend wifi network range. For example, the "main" AP near
the telecoms provider entry point, and one or more other AP on the other
side of the house, in the garden, etc. Or several AP distributed about an
office building.
The term "dumb AP" is typically used for the extending APs, meaning that they don't directly provide those DHCP type services. If adding APs for the first time as a part of the plan to make DAWN work then it's important to have them configured correctly, and you can find a good guide to that [here](https://gist.github.com/braian87b/bba9da3a7ac23c35b7f1eecafecdd47d). The term "dumb AP" is typically used for the extending APs, meaning that
they don't directly provide those DHCP type services. If adding APs for
the first time as a part of the plan to make DAWN work then it's important
to have them configured correctly, and you can find a good guide to that
[here](https://gist.github.com/braian87b/bba9da3a7ac23c35b7f1eecafecdd47d).
Once those basics are in place DAWN is installed on each of the APs
("main" and "dumb") so that a full view of the network can be gathered.
## Installing DAWN ## Installing DAWN
### Install a full version of WPAD ### Install a full version of WPAD
Use the local package manager to install a full version of wpad, for example on OpenWrt: Use the local package manager to install a full version of wpad, for
example on OpenWrt:
opkg update opkg update
opkg remove wpad-basic wpad-mini opkg remove wpad-basic wpad-mini
opkg install wpad-openssl # Use one of the following, or similar
opkg install wpad-wolfssl
opkg install wpad-openssl
Once it is installed you should be able to see the ubus methods that DAWN
uses to ask hostapd to tell clients to do things.
ubus -v list hostapd.wlan0
You should see at least the first of these two entires in the result (note
that the parameter lists have been removed to make it clear what method names
should be there):
"wnm_disassoc_imminent":{...}
"bss_transition_request":{...}
`wnm_disassoc_imminent` is used by the RSSI Comparison algorithm, while
`bss_transition_request` is used by the Absolute RSSI algorihm. If you don't
see the relevant method then the respective algorithm will not work. See the
Configuration page for furhter details on what this means.
### Install DAWN ### Install DAWN
The published verson of DAWN should install easily: The published version of DAWN should install easily:
opkg install dawn opkg install dawn
### Developers ### Developers
If you want to install versions of DAWN that are not fully packaged yet or to work on a fork of the code yourself then see the [Developer Guide](DEVELOPER.md). If you want to install versions of DAWN that are not fully packaged yet or
to work on a fork of the code yourself then see the [Developer
Guide](DEVELOPER.md).
## Configuring DAWN ## Configuring DAWN
Review the configuration guide to see what you might want to change [configuration guide](CONFIGURE.md). At a minimum: Review the configuration guide to see what you might want to change
[configuration guide](CONFIGURE.md). At a minimum:
- Be sure to enable the DAWN functions that you want (at least "kicking") - Be sure to enable the DAWN functions that you want (at least "kicking")
## Check That DAWN Is Running ## Check That DAWN Is Running
By default DAWN won't send much to the system log, so it can be hard to see if it is working at all. By default, DAWN won't send much to the system log, so it can be hard to
see if it is working at all.
If you have an 802.11k/v enaled device then if you place it close to one AP until it connects, and then move it close to another you should see a message after a minute or so where DAWN is asking the device to move to the other AP: If you have an 802.11k/v enabled device then if you place it close to one
AP until it connects, and then move it close to another you should see a
message indicating that DAWN is asking the device to move to
the other AP:
logread -f | grep dawn logread -f | grep dawn
<Message here that shows transfer> <Message here that shows transfer>
If you'd like to see more messages to help confirm DAWN is interacting with the relevant services then edit the config file to set the messaging level to '1'. If you'd like to see more messages to help confirm DAWN is interacting
with the relevant services then edit the config file to set the messaging
level to '1'.
## See What DAWN Is Seeing ## See What DAWN Is Seeing
Once it has been running for a few minutes you can query the running DAWN instance via UBUS to understand what view of the network it has constructed. Once it has been running for a few minutes you can query the running DAWN
instance via UBUS to understand what view of the network it has
constructed.
To get an overview of all connected Clients sorted by the SSID, then AP BSSID, then device MAC: To get an overview of all connected Clients sorted by the SSID, then AP
BSSID, then device MAC:
root@OpenWrt:~# ubus call dawn get_network root@OpenWrt:~# ubus call dawn get_network
{ {
"Free-Cookies": { "Free-Cookies": { <-- This SSID...
"00:27:19:XX:XX:XX": { "00:27:19:XX:XX:XX": { <-- ...is provided by this AP BSSID...
"78:02:F8:XX:XX:XX": { "78:02:F8:XX:XX:XX": { <-- ...and has these client MACs
"freq": 2452, "freq": 2452,
"ht": 1, "ht": 1,
"vht": 0, "vht": 0,
"collision_count": 4 "collision_count": 4
} }
}, },
"A4:2B:B0:XX:XX:XX": { "A4:2B:B0:XX:XX:XX": { <-- The SSID is also provided by this BSSID
"48:27:EA:XX:XX:XX: { "48:27:EA:XX:XX:XX: {
"freq": 2412, "freq": 2412,
"ht": 1, "ht": 1,
@ -63,18 +108,21 @@ To get an overview of all connected Clients sorted by the SSID, then AP BSSID, t
}, },
} }
}, },
"Free-Cookies_5G": { "Free-Cookies_5G": { <-- Alternate SSIDS may also be offered
} }
} }
To get the view of which AP each client can see you can use: To get the view of which AP each client can see you can use the following.
Note that DAWN will try to move a clent between APs when the difference
between 'score' value for the current AP and an alternative exceeds the
kicking_threshold parameter.
root@OpenWrt:~# ubus call dawn get_hearing_map root@OpenWrt:~# ubus call dawn get_hearing_map
{ {
"Free-Cookies": { "Free-Cookies": {
"0E:5B:DB:XX:XX:XX": { "0E:5B:DB:XX:XX:XX": { <--This is the client device MAC
"00:27:19:XX:XX:XX": { "00:27:19:XX:XX:XX": { <-- This is AP1...
"signal": -64, "signal": -64,
"freq": 2452, "freq": 2452,
"ht_support": true, "ht_support": true,
@ -83,9 +131,9 @@ To get the view of which AP each client can see you can use:
"num_sta": 1, "num_sta": 1,
"ht": 1, "ht": 1,
"vht": 0, "vht": 0,
"score": 10 "score": 10 <-- These scores are compared
}, },
"A4:2B:B0:XX:XX:XX": { "A4:2B:B0:XX:XX:XX": { <-- This is AP2...
"signal": -70, "signal": -70,
"freq": 2412, "freq": 2412,
"ht_support": true, "ht_support": true,
@ -99,3 +147,4 @@ To get the view of which AP each client can see you can use:
} }
} }
} }

View file

@ -1,14 +1,25 @@
![DAWN PICTURE](https://image.ibb.co/nbmNfJ/dawn_bla.png) ![DAWN PICTURE](https://image.ibb.co/nbmNfJ/dawn_bla.png)
# DAWN # DAWN
DAWN is a decentralized controller for wi-fi clients (eg, laptops, phones) that aims to ensure that each client is connected to an access point (AP, aka "wifi router") that will give good network throughput. This reduces wastage of radio capacity due to weak / distant radio connections that cause transmission retry, degredation of speed, etc. DAWN is a decentralized controller for wi-fi clients (eg, laptops, phones)
that aims to ensure that each client is connected to an access point (AP,
aka "wifi router") that will give good network throughput. This reduces
wastage of radio capacity due to weak / distant radio connections that
cause transmission retry, degradation of speed, etc.
Decentralised means that DAWN is a peer-peer network of instances - there is no controlling "master" node. Every instance of DAWN will find its peers via uMDNS (aka Bonjour) network discovery. Further DAWN instances can therfore be added without explicit configuration of the whole network, reducing network maintenance overhead. Decentralised means that DAWN is a peer-peer network of instances - there
is no controlling "master" node. Every instance of DAWN will find its
peers via uMDNS (aka Bonjour) network discovery. Further DAWN instances
can therefore be added without explicit configuration of the whole
network, reducing network maintenance overhead.
## Installation and Configuration ## Installation and Configuration
Installing DAWN is quite simple. The TL;DR version for anyone not wanting to read the [installation guide](INSTALL.md) is: Installing DAWN is quite simple. The TL;DR version for anyone not wanting
to read the [installation guide](INSTALL.md) is:
- Install DAWN on each AP that you want to be a part of the optimisation
network
- **Be sure to install a full wpad-\* version and not wpad-basic** - **Be sure to install a full wpad-\* version and not wpad-basic**
- Be sure to configure extender routers as "dumb AP" - Be sure to configure extender routers as "dumb AP"
@ -17,20 +28,49 @@ Top tip from the [configuration guide](CONFIGURE.md):
- Be sure to enable the DAWN functions that you want (at least "kicking") - Be sure to enable the DAWN functions that you want (at least "kicking")
## How DAWN Works ## How DAWN Works
Each DAWN instance gathers information about two types of client: those that are currently connected to the host AP, plus those querying whether to connect. It then shares that information with other DAWN instances. Each then has a view of how well any AP can "see" each client device, and that then allows DAWN to steer a client to a different AP when appropriate. Each DAWN instance gathers information about two types of client: those
that are currently connected to the host AP, plus those querying whether
to connect. It then shares that information with other DAWN instances.
Each then has a view of how well any AP can "see" each client device, and
that then allows DAWN to steer a client to a different AP when appropriate.
For example, if a device is currently connected to AP1 with a signal strength of -65dB it may be quite happy to stay there because many devices will not look to roam until the signal goes past -70dB (note the minus sign: -70dB is more negative / worse than -65dB). However, if DAWN on AP1 knows that the same device can see AP2 at a level of -55dB then DAWN can tell the device to switch to AP2, which will improve overall radio performance if applied to multiple devices across multiple AP. For example, if a device is currently connected to AP1 with a signal
strength of -65dB it may be quite happy to stay there because many devices
will not look to roam until the signal goes past -70dB (note the minus
sign: -70dB is more negative / worse than -65dB). However, if DAWN on AP1
knows that the same device can see AP2 at a level of -55dB then DAWN can
tell the device to switch to AP2, which will improve overall radio
performance if applied to multiple devices across multiple AP.
DAWN can also evaluate other parameters that a device may not include in its roaming decisions, such as currently connected clients per AP, availability of speed enhancing capabilities, etc. However, it is ultimately for a client device to decide which AP it will connect to so it may ignore DAWN's proposal, especially if it is using a significantly different algorithm to DAWN. DAWN can also evaluate other parameters that a device may not include in
its roaming decisions, such as currently connected clients per AP,
availability of speed enhancing capabilities, etc. However, it is
ultimately for a client device to decide which AP it will connect to so it
may ignore DAWN's proposal, especially if it is using a significantly
different algorithm to DAWN.
DAWN works best with networks where AP and devices have 802.11k capailites for discovering the quality of radio signals, plus 802.11v for requesting devices to move to a different AP. If 802.11r is enabled for fast, seamless transfer of a device across APs then it enhances the overall user experience, but DAWN doesn't directly use it. DAWN works best with networks where AP and devices have 802.11k
capabilities for discovering the quality of radio signals, plus 802.11v
for requesting devices to move to a different AP. If 802.11r is enabled
for fast, seamless transfer of a device across APs then it enhances the
overall user experience, but DAWN doesn't directly use it.
802.11k/r/v were developed to enable the type of functionality that DAWN provides, so older devices that do not have these capabilites are by definition harder to control. DAWN will try to steer "legacy" devices if configured to do so, but it can be a less than perfect user experience due to the time taken to create connections to the new AP. 802.11k/r/v were developed to enable the type of functionality that DAWN
provides, so older devices that do not have these capabilities are by
definition harder to control. DAWN will try to steer "legacy" devices if
configured to do so, but it can be a less than perfect user experience due
to the time taken to create connections to the new AP.
## LuCI App ## LuCI App
There is an luci app called [luci-app-dawn](https://github.com/openwrt/luci/tree/master/applications/luci-app-dawn) that adds some DAWN information to the management interface of an OpenWrt device. There is a luci app called
[luci-app-dawn](https://github.com/openwrt/luci/tree/master/applications/luci-app-dawn)
that adds some DAWN information to the management interface of an OpenWrt device.
NB: As of early-2022 it hasn't had the developer attention it needs recently, so may not be working as well as you might like. NB: As of early-2022 it hasn't had the developer attention it needs
recently, so may not be working as well as you might like.
## Developers ## Developers
If you want to use versions of DAWN that are not fully packaged yet or to work on a fork of the code yourself then see the [Developer Guide](DEVELOPER.md). If you want to use versions of DAWN that are not fully packaged yet or to
work on a fork of the code yourself then see the [Developer
Guide](DEVELOPER.md).

View file

@ -3,31 +3,35 @@
## Overview ## Overview
The core purpose of DAWN is the processing of information relating The core purpose of DAWN is the processing of information relating to the
to the set of access points (AP) and clients (STA - meaning stations in 802.11 set of access points (AP) and clients (STA - meaning stations in 802.11
vernacular) that form the wi-fi network under DAWN's management. vernacular) that form the wi-fi network under DAWN's management.
The required data storage and processing capabilites are generally held in the 'storage' The required data storage and processing capabilites are generally held in
part of DAWN's source code tree. The remaining parts are mainly for the 'storage' part of DAWN's source code tree. The remaining parts are
interfacing with resources of the AP environment rhat provide updated information and allow mainly for interfacing with resources of the AP environment rhat provide
DAWN to indicate to stations what they should do next following processing of the latest data. updated information and allow DAWN to indicate to stations what they
Specifically, this means components such as iwinfo, ubus and uci that are commonly found on an should do next following processing of the latest data. Specifically,
AP running OpenWRT variant of Linux. this means components such as iwinfo, ubus and uci that are commonly found
on an AP running OpenWRT variant of Linux.
## Testing Approach ## Testing Approach
The principal focus of DAWN's test harness is on these storage and processing components. This is achieved by The principal focus of DAWN's test harness is on these storage and
having a build target named test_storage which builds these parts processing components. This is achieved by having a build target named
without the environment interaction dependencies. This "test harness" can then be executed on the test_storage which builds these parts without the environment interaction
build host (e.g. a Linux desktop development environment) or on the target AP. dependencies. This "test harness" can then be executed on the build host
(e.g. a Linux desktop development environment) or on the target AP.
To configure the imaginary AP (SUT, or "system under test" in testing parlance) To configure the imaginary AP (SUT, or "system under test" in testing
a script that mimics many of the messages from ubus and other sources is created to represent parlance) a script that mimics many of the messages from ubus and other
the simulated network by describing APs, connected STAs and DAWN's own configuration parameters. sources is created to represent the simulated network by describing APs,
The data evaluation algorithms are then executed, and resultant outputs to stations are simulated as connected STAs and DAWN's own configuration parameters. The data
text output. evaluation algorithms are then executed, and resultant outputs to stations
are simulated as text output.
For example consider a simple network of two AP with 2 stations. The following (simplifed) script is For example consider a simple network of two AP with 2 stations. The
used to configure what one AP will be aware of: following (simplifed) script is used to configure what one AP will be
aware of:
CONFIG RSSI=10db CONFIG RSSI=10db
SELF 01:01:01:01:01:01 SELF 01:01:01:01:01:01
@ -39,34 +43,41 @@ used to configure what one AP will be aware of:
KICK CONSUME KICK CONSUME
KICK KICK
This means our test AP has the BSSID 01:..., and there is another AP in the network with BSSID 02:.... This means our test AP has the BSSID 01:..., and there is another AP in
Two stations with MAC 99:... and 88:... are in the network, both connected to AP01:... but also the network with BSSID 02:.... Two stations with MAC 99:... and 88:...
able to see AP02:.... The dB values indicate RSSI levels, and will be evalutated to determine if stations are in the network, both connected to AP01:... but also able to see
are connected to an appropriate AP. We'ed also configured AP02:.... The dB values indicate RSSI levels, and will be evalutated to
AP01:... to have an RSSI transition threshold of 10dB. When "kicking evaluation" is performed determine if stations are connected to an appropriate AP. We'ed also
STA99:... can improve its RSSI by over 10dB by switching to AP02:..., so will be instructed to do so, configured AP01:... to have an RSSI transition threshold of 10dB. When
resulting in the test actions: "kicking evaluation" is performed STA99:... can improve its RSSI by over
10dB by switching to AP02:..., so will be instructed to do so, resulting
in the test actions:
REMOVE 99:99:99:99:99:99 01:01:01:01:01:01 REMOVE 99:99:99:99:99:99 01:01:01:01:01:01
CONNECT 99:99:99:99:99:99 02:02:02:02:02:02 -65dB CONNECT 99:99:99:99:99:99 02:02:02:02:02:02 -65dB
Note that this is also valid input to the test_harness, and the parameter CONSUME Note that this is also valid input to the test_harness, and the parameter
on the KICK action will cause it to be reinjested for consideration when the CONSUME on the KICK action will cause it to be reinjested for
second KICK action is evaluated. consideration when the second KICK action is evaluated.
## Types of Testing ## Types of Testing
Three main areas of testing are performed by the supplied test scripts: Three main areas of testing are performed by the supplied test scripts:
* Data management: Ensuring data is stored correctly and soes not cause buffer overruns, etc * Data management: Ensuring data is stored correctly and soes not cause
* Algorithm functionality: Review the outcomes of evaluation for somple and complex network data buffer overruns, etc
* Scalability: Evaluate the ability of DAWN to sacle linearly to hundreds and thousands of AP and STA * Algorithm functionality: Review the outcomes of evaluation for somple
and complex network data
* Scalability: Evaluate the ability of DAWN to sacle linearly to hundreds
and thousands of AP and STA
A number of scenarios are defined for each type of testing, along with scripts to execute them. A number of scenarios are defined for each type of testing, along with
scripts to execute them.
### Data Management Scenarios ### Data Management Scenarios
Data management scenarios excercise DAWN's internal data structures by filling and emptying them to ensure no Data management scenarios excercise DAWN's internal data structures by
overflow conditions occur, and where appropriate that sorting is applied correctly. They are independent filling and emptying them to ensure no overflow conditions occur, and
of any functional testing, so each data structure is excercised alone in a way that would never occur in where appropriate that sorting is applied correctly. They are independent
real usage. of any functional testing, so each data structure is excercised alone in a
way that would never occur in real usage.
#### Test DM001: AP list #### Test DM001: AP list
Fill, print, empty and print Fill, print, empty and print
@ -81,9 +92,11 @@ Fill, print, empty and print
Fill, print, empty and print Fill, print, empty and print
### Algorithm Scenarios ### Algorithm Scenarios
Algorithm scenarios are used to ensure that DAWN creates the intended outputs to manage which stations Algorithm scenarios are used to ensure that DAWN creates the intended
connect to APs. They require more intricate crafting of the scripted synthetic data to represent the outputs to manage which stations connect to APs. They require more
input to DAWN's evaluation algortithms to blend situation data with decision metrics. intricate crafting of the scripted synthetic data to represent the input
to DAWN's evaluation algortithms to blend situation data with decision
metrics.
#### Test AL001: 2+2 Stable #### Test AL001: 2+2 Stable
Two AP with two stations connected to AP1, and will remain there. Two AP with two stations connected to AP1, and will remain there.
@ -95,17 +108,27 @@ Two AP with two stations connected to AP1, both switching to AP2.
Two AP with one station connected each, and will cross to the other. Two AP with one station connected each, and will cross to the other.
#### Test AL003: Load balance #### Test AL003: Load balance
Three AP with 40 stations connected to AP1, all with same metrics. DAWN should balance load to other APs. Three AP with 40 stations connected to AP1, all with same metrics. DAWN
should balance load to other APs.
### Scalability Scenarios ### Scalability Scenarios
Scalability scenarios explore how well DAWN can function in environments with many APs and clients. Scalability scenarios explore how well DAWN can function in environments
Using commodity equipment this might mean tens of APs with a total of a thousand or so connected stations. with many APs and clients. Using commodity equipment this might mean tens
Subject to use of appropriate hardware (eg small PC rather than SoC platform) there is an aspiration for of APs with a total of a thousand or so connected stations. Subject to
DAWN to be stable while managing hundreds of APs each with tens of connected stations, allowing networks use of appropriate hardware (eg small PC rather than SoC platform) there
to support 10,000 or more concurrent stations. is an aspiration for DAWN to be stable while managing hundreds of APs each
with tens of connected stations, allowing networks to support 10,000 or
more concurrent stations.
Scalability requires a number of design aspects to function together: Scalability requires a number of design aspects to function together:
* Data storage scalability: To allow efficient use of memory the amount required should be approximately linear, so simple networks on small devices require small amounts of memory while more complex environments can function on moderately scaled hardware. * Data storage scalability: To allow efficient use of memory the amount
* Algorithm scalability: Similar to memory usage, ensuring that calculation times are more linear than exponential as numbers of APs and stations grow. required should be approximately linear, so simple networks on small
* Algorithm efficiency: As well as being scaleable the processing of data must fit within absolute limits to ensure that APs can keep up with the rate of data arriving from the network. devices require small amounts of memory while more complex environments
can function on moderately scaled hardware.
* Algorithm scalability: Similar to memory usage, ensuring that
calculation times are more linear than exponential as numbers of APs and
stations grow.
* Algorithm efficiency: As well as being scaleable the processing of data
must fit within absolute limits to ensure that APs can keep up with the
rate of data arriving from the network.

79
dawn-config Normal file
View file

@ -0,0 +1,79 @@
config local
option loglevel '0'
config network
option broadcast_ip '10.0.0.255'
option broadcast_port '1025'
option tcp_port '1026'
option network_option '2'
option shared_key 'Niiiiiiiiiiiiick'
option iv 'Niiiiiiiiiiiiick'
option use_symm_enc '0'
option collision_domain '-1'
option bandwidth '-1'
config hostapd
option hostapd_dir '/var/run/hostapd'
config times
option update_client '10'
option remove_client '15'
option remove_probe '30'
option remove_ap '460'
option update_hostapd '10'
option update_tcp_con '10'
option update_chan_util '5'
option update_beacon_reports '20'
config metric 'global'
option min_probe_count '3'
option bandwidth_threshold '6'
option use_station_count '0'
option max_station_diff '1'
option eval_probe_req '0'
option eval_auth_req '0'
option eval_assoc_req '0'
option kicking '3'
option kicking_threshold '20'
option deny_auth_reason '1'
option deny_assoc_reason '17'
option min_number_to_kick '3'
option chan_util_avg_period '3'
option set_hostapd_nr '0'
option duration '0'
option rrm_mode 'pat'
config metric '802_11g'
option initial_score '80'
option ht_support '5'
option vht_support '5'
option no_ht_support '0'
option no_vht_support '0'
option rssi '15'
option rssi_val '-60'
option low_rssi_val '-80'
option low_rssi '-15'
option chan_util '0'
option chan_util_val '140'
option max_chan_util '-15'
option max_chan_util_val '170'
option rssi_weight '0'
option rssi_center '-70'
config metric '802_11a'
option initial_score '100'
option ht_support '5'
option vht_support '5'
option no_ht_support '0'
option no_vht_support '0'
option rssi '15'
option rssi_val '-60'
option low_rssi_val '-80'
option low_rssi '-15'
option chan_util '0'
option chan_util_val '140'
option max_chan_util '-15'
option max_chan_util_val '170'
option rssi_weight '0'
option rssi_center '-70'

View file

@ -101,18 +101,18 @@ struct probe_metric_s {
}; };
struct time_config_s { struct time_config_s {
time_t update_client; time_t update_client; // Query locally connected clients
time_t remove_client; time_t remove_client; // Delete aged client records
time_t remove_probe; time_t remove_probe; // Delete aged PROBE / BEACON records
time_t remove_ap; time_t remove_ap; // Delete aged AP records
time_t update_hostapd; time_t update_hostapd; // Refresh wifi radio / SSID data from hostapd
time_t update_tcp_con; time_t update_tcp_con; // Refresh network connections
time_t update_chan_util; time_t update_chan_util; // Refresh per radio / SSID channel util info
time_t update_beacon_reports; time_t update_beacon_reports; // Request BEACON from capable clients
}; };
struct local_config_s { struct local_config_s {
int loglevel; int loglevel; // Select the level of messgae in syslog
}; };
// FIXME: Are these with or without NUL terminator? Adjust values, string allocation and strncpy() to agree. // FIXME: Are these with or without NUL terminator? Adjust values, string allocation and strncpy() to agree.
@ -124,7 +124,7 @@ struct network_config_s {
int broadcast_port; int broadcast_port;
char server_ip[MAX_IP_LENGTH + 1]; char server_ip[MAX_IP_LENGTH + 1];
int tcp_port; int tcp_port;
int network_option; int network_option; // 0:Broadcast; 1:Multicast; 2:TCP+UMDNS; 3:TCP
char shared_key[MAX_KEY_LENGTH + 1]; char shared_key[MAX_KEY_LENGTH + 1];
char iv[MAX_KEY_LENGTH + 1]; char iv[MAX_KEY_LENGTH + 1];
int use_symm_enc; int use_symm_enc;

View file

@ -536,7 +536,7 @@ int kick_clients(struct dawn_mac bssid_mac, uint32_t id) {
// only use rx_rate for indicating if transmission is going on // only use rx_rate for indicating if transmission is going on
// <= 6MBits <- probably no transmission // <= 6MBits <- probably no transmission
// tx_rate has always some weird value so don't use ist // tx_rate has always some weird value so don't use ist
if (have_bandwidth_iwinfo && rx_rate > dawn_metric.bandwidth_threshold) { if (have_bandwidth_iwinfo && dawn_metric.bandwidth_threshold != 0 && rx_rate > dawn_metric.bandwidth_threshold) {
dawnlog_info("Client " MACSTR ": Client is probably in active transmission. Don't kick! RxRate is: %f\n", MAC2STR(j->client_addr.u8), rx_rate); dawnlog_info("Client " MACSTR ": Client is probably in active transmission. Don't kick! RxRate is: %f\n", MAC2STR(j->client_addr.u8), rx_rate);
} }
else else

View file

@ -89,13 +89,21 @@ struct time_config_s uci_get_time_config() {
struct uci_section *s = uci_to_section(e); struct uci_section *s = uci_to_section(e);
if (strcmp(s->type, "times") == 0) { if (strcmp(s->type, "times") == 0) {
//CONFIG-T: update_client|Timer to send refresh local connection information and revised NEIGHBOR REPORT to all clients|[10]
DAWN_SET_CONFIG_TIME(ret, s, update_client); DAWN_SET_CONFIG_TIME(ret, s, update_client);
//CONFIG-T: remove_client|Timer to remove expired client entries from core data set|[15]
DAWN_SET_CONFIG_TIME(ret, s, remove_client); DAWN_SET_CONFIG_TIME(ret, s, remove_client);
//CONFIG-T: remove_probe|Timer to remove expired PROBE and BEACON entries from core data set|[30]
DAWN_SET_CONFIG_TIME(ret, s, remove_probe); DAWN_SET_CONFIG_TIME(ret, s, remove_probe);
//CONFIG-T: update_hostapd|Timer to (re-)register for hostapd messages for each local BSSID|[10]
DAWN_SET_CONFIG_TIME(ret, s, update_hostapd); DAWN_SET_CONFIG_TIME(ret, s, update_hostapd);
//CONFIG-T: remove_ap|Timer to remove expired AP entries from core data set|[460]
DAWN_SET_CONFIG_TIME(ret, s, remove_ap); DAWN_SET_CONFIG_TIME(ret, s, remove_ap);
//CONFIG-T: update_tcp_con|Timer to refresh / remove the TCP connections to other DAWN instances found via uMDNS|[10]
DAWN_SET_CONFIG_TIME(ret, s, update_tcp_con); DAWN_SET_CONFIG_TIME(ret, s, update_tcp_con);
//CONFIG-T: update_chan_util|Timer to get recent channel utilisation figure for each local BSSID|[5]
DAWN_SET_CONFIG_TIME(ret, s, update_chan_util); DAWN_SET_CONFIG_TIME(ret, s, update_chan_util);
//CONFIG-T: update_beacon_reports|Timer to ask all connected clients for a new BEACON REPORT|[20]
DAWN_SET_CONFIG_TIME(ret, s, update_beacon_reports); DAWN_SET_CONFIG_TIME(ret, s, update_beacon_reports);
return ret; return ret;
} }
@ -117,6 +125,7 @@ struct local_config_s uci_get_local_config() {
struct uci_section* s = uci_to_section(e); struct uci_section* s = uci_to_section(e);
if (strcmp(s->type, "local") == 0) { if (strcmp(s->type, "local") == 0) {
// CONFIG-L: loglevel|Verbosity of messages in syslog|[0 = Important only - very few messages]; 1 = Show what DAWN is processing in a user friendly way; 2 = Trace certain operations - for debugging; 3 = Broad low level tracing - for debugging
DAWN_SET_CONFIG_INT(ret, s, loglevel); DAWN_SET_CONFIG_INT(ret, s, loglevel);
} }
} }
@ -229,41 +238,78 @@ static struct uci_section *uci_find_metric_section(const char *name) {
struct probe_metric_s uci_get_dawn_metric() { struct probe_metric_s uci_get_dawn_metric() {
struct probe_metric_s ret = { struct probe_metric_s ret = {
.kicking = 0, // CONFIG-G: kicking|Method to select clients to move to better AP|0 = Disabled; 1 = RSSI Comparison; 2 = Absolute RSSI; [3 = Both] See note 1.
.min_probe_count = 0, .kicking = 3,
.use_station_count = 1, //CONFIG-G: kicking_threshold|Minimum score difference to consider kicking to alternate AP|[20]
.kicking_threshold = 20,
// CONFIG-G: min_probe_count|Number of times a client should retry PROBE before acceptance| [3] See Note 1.
.min_probe_count = 3,
// CONFIG-G: use_station_count|Compare connected station counts when considering kicking|[0 = Disabled]; 1 = Enabled
.use_station_count = 0,
// CONFIG-G: eval_auth_req|Control whether AUTHENTICATION frames are evaluated for rejection|[0 = No evaluation]; 1 = Evaluated. See Note 1.
.eval_auth_req = 0, .eval_auth_req = 0,
// CONFIG-G: eval_assoc_req|Control whether ASSOCIATION frames are evaluated for rejection|[0 = No evaluation]; 1 = Evaluated. See Note 1.
.eval_assoc_req = 0, .eval_assoc_req = 0,
// CONFIG-G: deny_auth_reason|802.11 code used when AUTHENTICATION is denied|[1] (802.11 UNSPECIFIED_FAILURE). See Note 1.
.deny_auth_reason = 1, .deny_auth_reason = 1,
// CONFIG-G: deny_assoc_reason|802.11 code used when ASSOCIATION is denied|[17] (802.11 AP_UNABLE_TO_HANDLE_NEW_STA). See Note 1.
.deny_assoc_reason = 17, .deny_assoc_reason = 17,
// CONFIG-G: eval_probe_req|Control whether PROBE frames are evaluated for rejection|[0 = No evaluation]; 1 = Evaluated. See Note 1.
.eval_probe_req = 0, .eval_probe_req = 0,
// CONFIG-G: min_number_to_kick|Number of consecutive times a client should be evaluated as ready to kick before actually doing it|[3]
.min_number_to_kick = 3, .min_number_to_kick = 3,
.set_hostapd_nr = 1, // CONFIG-G: set_hostapd_nr|Method used to set Neighbor Report on AP|[0 = Disabled]; 1 = "Static" based on all APs in network (plus set from configuration); 2 = "Dynamic" based on next nearest AP seen by current clients
.set_hostapd_nr = 0,
// CONFIG-G: disassoc_nr_length|Number of entries to include in a 802.11v DISASSOCIATE Neighbor Report|[6] (Documented for use by iOS)
.disassoc_nr_length = 6, .disassoc_nr_length = 6,
// CONFIG-G: max_station_diff|Number of connected stations to consider "better" for use_station_count|[1]
.max_station_diff = 1, .max_station_diff = 1,
// CONFIG-G: bandwidth_threshold|Maximum reported AP-client bandwidth permitted when kicking. Set to zero to disable the check.|[6] (Mbits/s)
.bandwidth_threshold = 6, .bandwidth_threshold = 6,
// CONFIG-G: chan_util_avg_period|Number of sampling periods to average channel utilization values over|[3]
.chan_util_avg_period = 3, .chan_util_avg_period = 3,
.duration = 0, // CONFIG-G: duration|802.11k BEACON request DURATION parameter|[0]
.duration = 600,
// CONFIG-G: rrm_mode|Preferred order for using Passive, Active or Table 802.11k BEACON information|[PAT] String of 'P', 'A' and / or 'T'
.rrm_mode_mask = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE | .rrm_mode_mask = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
WLAN_RRM_CAPS_BEACON_REPORT_TABLE, WLAN_RRM_CAPS_BEACON_REPORT_TABLE,
.rrm_mode_order = { WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE, .rrm_mode_order = { WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE,
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE, WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE,
WLAN_RRM_CAPS_BEACON_REPORT_TABLE }, WLAN_RRM_CAPS_BEACON_REPORT_TABLE },
// CONFIG-B: ap_weight|Per AP weighting|[0] (Deprecated)
.ap_weight = { 0, 0 }, .ap_weight = { 0, 0 },
.ht_support = { 0, 0 }, // CONFIG-B: ht_support|Score increment if HT is supported|[5]
.vht_support = { 0, 0 }, .ht_support = { 5, 5 },
// CONFIG-B: vht_support|Score increment if VHT is supported|[5]
.vht_support = { 5, 5 },
// CONFIG-B: no_ht_support|Score incrment if HT is not supported|[0] (Deprecated)
.no_ht_support = { 0, 0 }, .no_ht_support = { 0, 0 },
// CONFIG-B: no_vht_support|Score incrment if VHT is not supported|[0] (Deprecated)
.no_vht_support = { 0, 0 }, .no_vht_support = { 0, 0 },
.rssi = { 10, 10 }, // CONFIG-B: rssi|Score addition when signal exceeds threshold|[15] See note 2.
.rssi = { 15, 15 },
// CONFIG-B: rssi_val|Threshold for an good RSSI|[-60] See note 2.
.rssi_val = { -60, -60 }, .rssi_val = { -60, -60 },
.initial_score = { 0, 100 }, // CONFIG-B: initial_score|Base score for AP based on operating band|[2.4GHz = 80; 5Ghz = 100]
.initial_score = { 80, 100 },
// CONFIG-B: chan_util|Score increment if channel utilization is below chan_util_val|[0]
.chan_util = { 0, 0 }, .chan_util = { 0, 0 },
.max_chan_util = { -500, -500 }, // CONFIG-B: max_chan_util_val|Lower threshold for bad channel utilization|[170]
.chan_util_val = { 140, 140 },
.max_chan_util_val = { 170, 170 }, .max_chan_util_val = { 170, 170 },
.low_rssi = { -500, -500 }, // CONFIG-B: chan_util_val|Upper threshold for good channel utilization|[140]
.chan_util_val = { 140, 140 },
// CONFIG-B: max_chan_util|Score increment if channel utilization is above max_chan_util_val|[-15]
.max_chan_util = { -15, -15 },
// CONFIG-B: low_rssi|Score addition when signal is below threshold|[-15] See note 2.
.low_rssi = { -15, -15 },
// CONFIG-B: low_rssi_val|Threshold for bad RSSI|[-80] See note 2.
.low_rssi_val = { -80, -80 }, .low_rssi_val = { -80, -80 },
// CONFIG-B: rssi_center|Midpoint for weighted RSSI evaluation|[-70] See note 2.
.rssi_center = { -70, -70 },
// CONFIG-B: rssi_weight|Per dB increment for weighted RSSI evaluation|[0] See note 2.
.rssi_weight = { 0, 0 },
.neighbors = {NULL, NULL},
}; };
struct uci_section *global_s, *band_s[__DAWN_BAND_MAX]; struct uci_section *global_s, *band_s[__DAWN_BAND_MAX];
struct uci_option *global_neighbors = NULL, *neighbors; struct uci_option *global_neighbors = NULL, *neighbors;
@ -337,7 +383,7 @@ struct network_config_s uci_get_dawn_network() {
.network_option = 2, .network_option = 2,
.shared_key = "Niiiiiiiiiiiiiik", .shared_key = "Niiiiiiiiiiiiiik",
.iv = "Niiiiiiiiiiiiiik", .iv = "Niiiiiiiiiiiiiik",
.use_symm_enc = 1, .use_symm_enc = 0,
.collision_domain = -1, .collision_domain = -1,
.bandwidth = -1, .bandwidth = -1,
}; };
@ -350,28 +396,38 @@ struct network_config_s uci_get_dawn_network() {
struct uci_section *s = uci_to_section(e); struct uci_section *s = uci_to_section(e);
if (strcmp(s->type, "network") == 0) { if (strcmp(s->type, "network") == 0) {
// CONFIG-N: broadcast_ip|IP address for broadcast and multicast|No default
const char* str_broadcast = uci_lookup_option_string(uci_ctx, s, "broadcast_ip"); const char* str_broadcast = uci_lookup_option_string(uci_ctx, s, "broadcast_ip");
if (str_broadcast) if (str_broadcast)
strncpy(ret.broadcast_ip, str_broadcast, MAX_IP_LENGTH); strncpy(ret.broadcast_ip, str_broadcast, MAX_IP_LENGTH);
// CONFIG-N: server_ip|IP address when not using UMDNS|No default
const char* str_server_ip = uci_lookup_option_string(uci_ctx, s, "server_ip"); const char* str_server_ip = uci_lookup_option_string(uci_ctx, s, "server_ip");
if(str_server_ip) if(str_server_ip)
strncpy(ret.server_ip, str_server_ip, MAX_IP_LENGTH); strncpy(ret.server_ip, str_server_ip, MAX_IP_LENGTH);
// CONFIG-N: broadcast_port|IP port for broadcast and multicast|[1026]
DAWN_SET_CONFIG_INT(ret, s, broadcast_port); DAWN_SET_CONFIG_INT(ret, s, broadcast_port);
// CONFIG-N: shared_key|Unused|N/A
const char* str_shared_key = uci_lookup_option_string(uci_ctx, s, "shared_key"); const char* str_shared_key = uci_lookup_option_string(uci_ctx, s, "shared_key");
if (str_shared_key) if (str_shared_key)
strncpy(ret.shared_key, str_shared_key, MAX_KEY_LENGTH); strncpy(ret.shared_key, str_shared_key, MAX_KEY_LENGTH);
// CONFIG-N: iv|Unused|N/A
const char* str_iv = uci_lookup_option_string(uci_ctx, s, "iv"); const char* str_iv = uci_lookup_option_string(uci_ctx, s, "iv");
if (str_iv) if (str_iv)
strncpy(ret.iv, str_iv, MAX_KEY_LENGTH); strncpy(ret.iv, str_iv, MAX_KEY_LENGTH);
// CONFIG-N: network_option|Method of networking between DAWN instances|0 = Broadcast; 2 = Multicast; [2 = TCP with UMDNS discovery]; 3 = TCP w/out UMDNS discovery
DAWN_SET_CONFIG_INT(ret, s, network_option); DAWN_SET_CONFIG_INT(ret, s, network_option);
// CONFIG-N: tcp_port|Port for TCP networking|[1025]
DAWN_SET_CONFIG_INT(ret, s, tcp_port); DAWN_SET_CONFIG_INT(ret, s, tcp_port);
// CONFIG-N: use_symm_enc|Enable encryption of network traffic|[0 = Disabled]; 1 = Enabled
DAWN_SET_CONFIG_INT(ret, s, use_symm_enc); DAWN_SET_CONFIG_INT(ret, s, use_symm_enc);
// CONFIG-N: collision_domain|Unused|N/A
DAWN_SET_CONFIG_INT(ret, s, collision_domain); DAWN_SET_CONFIG_INT(ret, s, collision_domain);
// CONFIG-N: bandwidth|Unused|N/A
DAWN_SET_CONFIG_INT(ret, s, bandwidth); DAWN_SET_CONFIG_INT(ret, s, bandwidth);
return ret; return ret;
} }
@ -389,11 +445,18 @@ bool uci_get_dawn_hostapd_dir() {
struct uci_section *s = uci_to_section(e); struct uci_section *s = uci_to_section(e);
if (strcmp(s->type, "hostapd") == 0) { if (strcmp(s->type, "hostapd") == 0) {
// CONFIG-H: hostapd_dir|Path to hostapd runtime information|[/var/run/hostapd]
const char* str = uci_lookup_option_string(uci_ctx, s, "hostapd_dir"); const char* str = uci_lookup_option_string(uci_ctx, s, "hostapd_dir");
strncpy(hostapd_dir_glob, str, HOSTAPD_DIR_LEN); if (str)
strncpy(hostapd_dir_glob, str, HOSTAPD_DIR_LEN);
return true; return true;
} }
} }
// If we get to here we haven't set a value yet
strncpy(hostapd_dir_glob, "/var/run/hostapd", HOSTAPD_DIR_LEN);
return false; return false;
} }
@ -451,6 +514,7 @@ int uci_init() {
int uci_clear() { int uci_clear() {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
// CONFIG-G: neighbors|Space seperated list of MACS to use in "static" AP Neighbor Report| None
for (int band = 0; band < __DAWN_BAND_MAX; band++) for (int band = 0; band < __DAWN_BAND_MAX; band++)
free_neighbor_mac_list(dawn_metric.neighbors[band]); free_neighbor_mac_list(dawn_metric.neighbors[band]);
@ -468,10 +532,8 @@ int uci_clear() {
int uci_set_network(char* uci_cmd) int uci_set_network(char* uci_cmd)
{ {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("UCI command = \"%s\"...", uci_cmd);
struct uci_ptr ptr;
int ret = UCI_OK;
struct uci_context *ctx = uci_ctx; struct uci_context *ctx = uci_ctx;
if (!ctx) { if (!ctx) {
@ -482,18 +544,46 @@ int uci_set_network(char* uci_cmd)
ctx->flags |= UCI_FLAG_STRICT; ctx->flags |= UCI_FLAG_STRICT;
if (uci_lookup_ptr(ctx, &ptr, uci_cmd, 1) != UCI_OK) { int ret = UCI_OK;
return 1; struct uci_ptr ptr;
if (ret == UCI_OK)
{
ret = uci_lookup_ptr(ctx, &ptr, uci_cmd, 1);
}
if (ret == UCI_OK)
{
// Magic code to add unnamed section like 'config times' exactly once - no idea if this is quite right
if (ptr.target == UCI_TYPE_SECTION && ptr.value == NULL)
{
char new_cmd[1024]; // Magic number
sprintf(new_cmd, "%s.@%s[0]", ptr.package, ptr.section);
struct uci_ptr ptr2;
ret = uci_lookup_ptr(ctx, &ptr2, new_cmd, 1);
if (ret == UCI_OK && ptr2.s == NULL)
{
ret = uci_add_section(ctx, ptr.p, ptr.section, &ptr.s);
}
}
else
{
ret = uci_set(ctx, &ptr);
}
} }
ret = uci_set(ctx, &ptr); if (ret == UCI_OK)
{
ret = uci_lookup_ptr(ctx, &ptr, "dawn", 1);
if (uci_lookup_ptr(ctx, &ptr, "dawn", 1) != UCI_OK) {
return 1;
} }
if (uci_commit(ctx, &ptr.p, 0) != UCI_OK) { if (ret == UCI_OK)
{
ret = uci_commit(ctx, &ptr.p, 0);
}
if (ret != UCI_OK) {
dawnlog_error("Failed to commit UCI cmd: %s\n", uci_cmd); dawnlog_error("Failed to commit UCI cmd: %s\n", uci_cmd);
} }

View file

@ -719,6 +719,22 @@ static const struct blobmsg_policy uci_times_policy[__UCI_TIMES_MAX] = {
[UCI_UPDATE_BEACON_REPORTS] = {.name = "update_beacon_reports", .type = BLOBMSG_TYPE_INT32}, [UCI_UPDATE_BEACON_REPORTS] = {.name = "update_beacon_reports", .type = BLOBMSG_TYPE_INT32},
}; };
static void set_uci_item(char* m, struct blob_attr* a)
{
// TODO: Magic number?
char cmd_buffer[1024];
if (!a)
{
dawnlog_trace("%s had NULL source!", m);
}
else
{
sprintf(cmd_buffer, m, blobmsg_get_u32(a));
uci_set_network(cmd_buffer);
}
}
static int handle_uci_config(struct blob_attr* msg) { static int handle_uci_config(struct blob_attr* msg) {
dawnlog_debug_func("Entering..."); dawnlog_debug_func("Entering...");
@ -862,32 +878,26 @@ static int handle_uci_config(struct blob_attr* msg) {
struct blob_attr* tb_times[__UCI_TIMES_MAX]; struct blob_attr* tb_times[__UCI_TIMES_MAX];
blobmsg_parse(uci_times_policy, __UCI_TIMES_MAX, tb_times, blobmsg_data(tb[UCI_TABLE_TIMES]), blobmsg_len(tb[UCI_TABLE_TIMES])); blobmsg_parse(uci_times_policy, __UCI_TIMES_MAX, tb_times, blobmsg_data(tb[UCI_TABLE_TIMES]), blobmsg_len(tb[UCI_TABLE_TIMES]));
sprintf(cmd_buffer, "dawn.@times[0].update_client=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_CLIENT])); sprintf(cmd_buffer, "dawn.times");
uci_set_network(cmd_buffer); uci_set_network(cmd_buffer);
sprintf(cmd_buffer, "dawn.@times[0].denied_req_threshold=%d", blobmsg_get_u32(tb_times[UCI_DENIED_REQ_THRESHOLD])); set_uci_item("dawn.@times[0].update_client=%d", tb_times[UCI_UPDATE_CLIENT]);
uci_set_network(cmd_buffer);
sprintf(cmd_buffer, "dawn.@times[0].remove_client=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_CLIENT])); set_uci_item("dawn.@times[0].remove_client=%d", tb_times[UCI_REMOVE_CLIENT]);
uci_set_network(cmd_buffer);
sprintf(cmd_buffer, "dawn.@times[0].remove_probe=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_PROBE])); set_uci_item("dawn.@times[0].remove_probe=%d", tb_times[UCI_REMOVE_PROBE]);
uci_set_network(cmd_buffer);
sprintf(cmd_buffer, "dawn.@times[0].remove_ap=%d", blobmsg_get_u32(tb_times[UCI_REMOVE_AP])); set_uci_item("dawn.@times[0].remove_ap=%d", tb_times[UCI_REMOVE_AP]);
uci_set_network(cmd_buffer);
sprintf(cmd_buffer, "dawn.@times[0].update_hostapd=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_HOSTAPD])); set_uci_item("dawn.@times[0].denied_req_threshold=%d", tb_times[UCI_DENIED_REQ_THRESHOLD]);
uci_set_network(cmd_buffer);
sprintf(cmd_buffer, "dawn.@times[0].update_tcp_con=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_TCP_CON])); set_uci_item("dawn.@times[0].update_hostapd=%d", tb_times[UCI_UPDATE_HOSTAPD]);
uci_set_network(cmd_buffer);
sprintf(cmd_buffer, "dawn.@times[0].update_chan_util=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_CHAN_UTIL])); set_uci_item("dawn.@times[0].update_tcp_con=%d", tb_times[UCI_UPDATE_TCP_CON]);
uci_set_network(cmd_buffer);
sprintf(cmd_buffer, "dawn.@times[0].update_beacon_reports=%d", blobmsg_get_u32(tb_times[UCI_UPDATE_BEACON_REPORTS])); set_uci_item("dawn.@times[0].update_chan_util=%d", tb_times[UCI_UPDATE_CHAN_UTIL]);
uci_set_network(cmd_buffer);
set_uci_item("dawn.@times[0].update_beacon_reports=%d", tb_times[UCI_UPDATE_BEACON_REPORTS]);
uci_reset(); uci_reset();
dawn_metric = uci_get_dawn_metric(); dawn_metric = uci_get_dawn_metric();