2022-02-06 17:58:20 +00:00
|
|
|
# DAWN Developer Guide
|
2022-02-17 16:36:07 +00:00
|
|
|
This is an introduction to DAWN for developers that want to understand how
|
|
|
|
it works so that they can modify, fix, etc its behaviour.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
## Component Overview
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
![OpenWrtInANuthshell](https://raw.githubusercontent.com/PolynomialDivision
|
|
|
|
/upload_stuff/master/dawn_pictures/openwrt_in_a_nutshell_dawn.png)
|
2022-02-06 17:58:20 +00:00
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
Communication with hostapd is via UBUS messages and callbacks.
|
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
|
|
|
|
|
|
|
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 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 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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
# Creating a DAWN Development Environment
|
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
## Compiling DAWN
|
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
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!
|
2022-02-06 17:58:20 +00:00
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
Clone OpenWrt
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
https://git.openwrt.org/openwrt/openwrt.git
|
|
|
|
|
|
|
|
Update Feeds
|
|
|
|
|
|
|
|
./scripts/feeds update -a
|
|
|
|
|
|
|
|
Install DAWN
|
|
|
|
|
|
|
|
./scripts/feeds install dawn
|
|
|
|
|
|
|
|
Add DAWN to the build (under `Network -> dawn`)
|
|
|
|
|
|
|
|
make menuconfig
|
|
|
|
|
|
|
|
Compile
|
|
|
|
|
|
|
|
make package/dawn/compile
|
|
|
|
|
|
|
|
## Creating a local DAWN development instance
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
Enable local source code (under `Advanced Configuration -> Enable package
|
|
|
|
source-tree override`)
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
make menuconfig
|
|
|
|
|
|
|
|
Now you need to clone DAWN, e.g. into your home directory
|
|
|
|
|
|
|
|
git clone https://github.com/berlin-open-wireless-lab/DAWN.git ~/DAWN
|
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
You must then add a symlink. In the OpenWrt branch do something like
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
ln -s ~/DAWN/.git/ ~openwrt/feeds/packages/net/dawn/git-src
|
|
|
|
|
|
|
|
Now compile dawn
|
|
|
|
|
|
|
|
make package/dawn/{clean,compile}
|
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
You should then be able to copy the dawn binary executable file to your
|
|
|
|
device to test your changes.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
## DAWN Quality Assurance
|
|
|
|
|
|
|
|
### Runtime Messages
|
2022-02-17 16:36:07 +00:00
|
|
|
Helper macros and functions named dawnlog_... are provided to assist with appropriate
|
|
|
|
management of messages. The general convention is to issue messages one
|
|
|
|
of the following priorities:
|
|
|
|
- ERROR (0): A significant runtime failure, such as memory exhaustion or
|
|
|
|
unexpected ability to write to a network socket.
|
|
|
|
- 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.
|
2022-02-06 17:58:20 +00:00
|
|
|
- DEBUG (3): Verbose tracing of code paths, etc.
|
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
The minimum logging level (as specified in /etc/config/dawn) at which the
|
|
|
|
priority appears is indicated, eg (0).
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
### Memory handling
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
### MUTEX Handling
|
2022-02-17 16:36:07 +00:00
|
|
|
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-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.
|
2022-02-06 17:58:20 +00:00
|
|
|
|
|
|
|
### Test Harness
|
2022-02-17 16:36:07 +00:00
|
|
|
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.
|
|
|
|
|