Finally got 802.11v working (FULLY) - Few pointers

If u left all settings with default, load balancing is currently not activated?

The settings are here:

Maybe you should look here:

And disable use_station_count. Maybe something is calculated wrong.
Is this line correct?

Maybe just wait until 802.11k is implemented.

Adding wan to umdns config let each R7800 see one another. As a result also pace of switching between APs is lower.
Reduced rssi_val to -80 and low_rssi_val to -100 but not sure there is an improvement. Not even sure if those values make sense :slight_smile:.


I implemented 802.11k but I have several problems:

  • How to compare RCPI, RSNI, RSSI?
  • Strange behavior in 5 GHz (beacon report requests are just ignored if they are send from 5 GHz radio)

Otherwise, it works. :wink:

I tested your scripts and I'm having problems with my Samsung S8 as client. It keeps disconnecting after a few seconds even while not sleeping and when it sleeps it reverts to LTE and never reconnects to wifi.

I can get the neighbor report and can steer clients manually so I guess it may be something related to my mobile phone that's somehow not compatible with the script. You said you had the same problem if hostapd-cli is used too frequently but I could not figure out how to modify your code to troubleshoot the problem (I'm not a coding expert, particularly php).

Very nice work nevertheless!

What version of OpenWRT are you running?

Not sure how fluent you are in PHP but its pretty simple, where ever you see the commands to force a roam compare them to the commands that work...

When ever I had that issue it was because either A) the abridged parameter was not present, or B) I was trying to force a roam to a non-existent OR incorrectly entered AP. Make sure your neighbor reports are 100% correct and the mac addresses are too. Macs in the config file should all be lower case.


RCPI / RSNI / RSSI : Good question! I have no idea... I spent about 1 hour googling but I ran out of time... For the time being I use strictly RSSI... 99% of the time its fine. In my setup I can do this because my 5ghz APs (and others) are so close that there is quite a bit of overlap... And worst case I bounce back and forth between APs a bit as I move around... I found that even things like Skype don't mind and there is no lag / stalls.

Becaons @ 5GHZ : Does hostapd report ack=1 for the beacon request at all? If it shows ack=1, then it was received by the client... Usually when I had problems with not getting back beacon reports when I should be able to get one back it was because of the "scan type" + "scan duration" + "scan randomization interval". EDIT : I should note that I set my APs to beacon interval @ 50... Not sure if this helps, but the logic was... More beacons, short scan durations = higher chance to picking up a beacon.... EDIT 2: I'm sure you know, but make sure your "op class", "phy type" and "channel" are all correct in the beacon request...

WARNING, I know nothing, I'm guessing here, but it does work:

For me what I found worked 99.9999% of the time was:

Scan type = Active (01)

Scan duration = 25-35 (converted dec to hex) - Could never figure this out fully... I checked the hostapd source... 2 x 2byte... but no matter what combo I tried, going up from (lets say) 100 (guessing? ms?) it would not make any difference. All the 802.11 documentation I read said this is "time units"...

Randomization interval = 0000 (hex)

Here is a snippet from the code I use... 25-30 btw... I use this because it gets returned back in the beacon response. So using this I am able to double check that the response is actually for the beacon request I am waiting for.

// duration *** still have not figured this out fully, but i am using this to identify the beacon request ***
// mode [ 0 = passive, 1 = active, 2 = table ]

Note, you are now reaching the part where I was not able to figure things out fully... Let me know if you can figure out how to get a proper RSSI with noise accounted for OR how to set an actual scan duration in the beacon request OR what "randomization interval" does.

1 Like

Thanks a lot! :slight_smile: I'm guessing too and reading some specs... xD
All that weird parameters and options u can use. Often, it seems that all vendor implementations handle that differently. And the spec is very complicated.

The beacon report is not containing RSSI information?

I will test your parameter settings. :slight_smile: Soon, I will push the 802.11k and 802.11v upstream and making the 802.11k parameters easily configurable. Hopefully, people will test the report stuff and give feedback. :smiley:


I am pulling the RSSI out via:

$rssi=unpack("l", pack("l", hexdec("FFFFFF".strtoupper(substr($content,26,2)))))[1]; // pull out the rssi from the beacon response

Characters 26 + 27.

1 Like

Hmmm, how did u know that on 26-27 is the RSSI?

You mean that the RSSI is in the /* Optional Subelements */?
I will look in the specs again.

For those having logs flooded with dawn[8778]: No station connected and seeing
procd: Seccomp support for umdns::instance1 not available EM when the service starts you might need to include following line in the .config:


Also there seems to be unspecified dependency for DAWN on:


That's just a warning of umdns. :slight_smile:

You are right. I can fix that. Printing that to stderr is just wrong. This is a call to libiwinfo. Currently, I don't use active kicking because I try to get 802.11k and 802.11v running, that I merged now into the master branch.

I fixed this 6 days ago? Now the dependency is present

Thanks. I didn't check the dependency in last few days. Good to know. Any idea what is the cause of that:

Network Overview
500 Internal Server Error
Sorry, the server encountered an unexpected error.

/usr/lib/lua/luci/template.lua:97: Failed to execute template 'cbi/map'.
A runtime error occurred: /usr/lib/lua/luci/template.lua:97: Failed to execute template '[string]'.
A runtime error occurred: [string "[string]"]:8: bad argument #1 to 'pairs' (table expected, got nil)
stack traceback:
	[C]: in function 'pairs'
	[string "[string]"]:8: in main chunk
stack traceback:
	[C]: in function 'error'
	/usr/lib/lua/luci/template.lua:97: in function 
	(tail call): ?
	/usr/lib/lua/luci/model/cbi/dawn/dawn_network.lua:10: in function 'render'
	/usr/lib/lua/luci/cbi.lua:266: in function 'render_children'
	[string "/usr/lib/lua/luci/view/cbi/map.htm"]:6: in main chunk
stack traceback:
	[C]: in function 'error'
	/usr/lib/lua/luci/template.lua:97: in function 
	(tail call): ?
	/usr/lib/lua/luci/cbi.lua:257: in function 'render'
	/usr/lib/lua/luci/cbi.lua:440: in function 'render'
	/usr/lib/lua/luci/dispatcher.lua:1325: in function '_cbi'
	/usr/lib/lua/luci/dispatcher.lua:927: in function 'dispatch'
	/usr/lib/lua/luci/dispatcher.lua:441: in function 

It was happening with OpenWrt SNAPSHOT r12948-97c5fb4709 but restarting dawn was sorting it out. Doesn't work anymore with r12986-a7423fef32.

Should I ignore it than?

You can just ignore it.

I pushed 802.11v (fast bss transition) upstream. Further I started sending beacon reports to clients (802.11k). If the package gets for your target available (you need openwrt master build), could u look if it's working?

If u type in

ubus call dawn get_network

You should see in the json output:

   "OpenWrt-Test": {
   	"XX:XX:XX:XX:XX:XX": {
   		"freq": 2412,
   		"channel_utilization": 60,
   		"num_sta": 1,
   		"ht_support": true,
   		"vht_support": false,
   		"neighbor_report": "aodiwjdoiamdimdsmdiwmidwwdasd",
   		"EE:EE:EE:EE:EE:EE": {
   			"ht": true,
   			"vht": false,
   			"collision_count": 2,
   			"signal": -66

The most important line is the "neighbor_report" line. It would be nice if u could check the line.

Further, please check with

ubus call dawn get_hearing_map
		"AA:AA:AA:AA:AA:AA": {
			"XX:XX:XX:XX:XX:XX": {
				"signal": -76,
				"rcpi": 185,
				"rsni": 0,
				"freq": 2412,
				"ht_capabilities": true,
				"vht_capabilities": false,
				"channel_utilization": 56,
				"num_sta": 1,
				"ht_support": true,
				"vht_support": false,
				"score": 0

If some rcpi or rsni is set. (802.11k)
Currently, those values are not used for load balancing, but soon they will be very important.

You can check your own neighbor report line with

ubus call hostapd.wlan0 rrm_nr_get_own
1 Like

Amazing, I'm following your work and wanna test it this weekend.
Keep your work going on. :sunglasses:

The example output from you looks confusing to me... What does it stand for and for which value should we check?

1 Like

An AP is presented in 802.11v by its neighbor report. That is a string in which AP information is encoded. Here is the function in the ubus call.
A Neighbor Report element consits of:

Element ID | Length | BSSID | BSSID Information | Operating Class | Class Number | PHY Type | Optional Subelements

I'm not sure if everything is correct.
With a neighbor report element the client directly knows bssid, and channel, so it does not need to scan or do other procedures.

If you now want to steer a client, you need to give the client the information to which AP it should connect. And you do that by sending this famous "bss transistion" frame (forgot the name) and include a list of neighbor reports (so a list of APs that are represented by the neighbor reports).
Currently, I'm trying to pick the best AP for a client and send it a wmn_diassoc (so I tell the client I will kick it in x-seconds, but here is some list of APs you can connect to/ or if the abridged flag is set: you must/should connect to).

Don't expect that much. Currently, I'm not testing load balancing stuff and steering (just sometimes). I'm fixing stuff and monitoring my network and look if somethings breaks or if I did somewhere a memory leak or mistake.
Sometimes it is hard to check if something is actual working. For example, if you want to know if a client did a bss transition, you have do increase the debug level of hostapd. Otherwise, it could be that just a kick happend.

So please look:

  • something is wrong
  • 802.11k frames are exchanged
  • neighbor reports are exchanged
  • ...

I need to port my load balancing score mechanism to work with 802.11k. But without probe exchange, I don't know the capabilities of my clients (can a client do vht or just ht) and all that problems...

Further, I'm sending 802.11k frames periodically to all clients to get a hearing map. Actually, this does not make sense for clients that do not support 802.11k (but that is no problem since hostapd checks that). In addition, I'm spamming the network with useless 802.11k frames, if no load balancing is required. Further, load balancing should happen if the channel utilization is high, ... It does not make sense to load balance clients of an AP with very low channel utilization...

So I have to do a lot and always test if I crashed something, because every driver implements something differently... It's annoying to work with so heterogeneous devices. xD

I'm very thankful for test reports! :smiley:

1 Like

Actually, dawn can replace the script @ParanoidZoid wrote if I would add

ubus call hostapd.wlan0 rm_nr_set [nr_reports ]

Then hostapd can answer on a request from a client, that the AP should give it possible roaming canidates, to reduce the energy and time costs of doing a scan.

I think I will do this and set a flag to disable it again. I'm afraid that if I feed the hostapd with nr-reports, it will have a negative effect on steering clients because my control logic will be ignored.

Here is the script:

I managed to get your script up and running. It's working flawlessly after a few adjustments that I'll post soon enough. The main error was that the script was failing the random ID check that you introduced. In my case, the beacon report always returns "6100" (S8 phone) or "6400" (iPhone 10) in that "duration" placeholder.

Thanks for sharing your work!

Glad it works!

Do share what changes you have made, I will add the random ID as a true / false in the configuration file.

I never had an issues with it, but I only tested / use it on one client (my S7 Edge).