DAWN is using the ubus bindings of the hostapd. Ubus is a messaging system in OpenWrt to which processes can subscribe and publish information or services. The hostapd ubus bindings allow to collect probe-, auth- and assoc-requests. Furthermore, it is possible to deny these requests. Additionally, we can gather client information or deauthenticate clients.
I made my life easy by just extending the hostapd ubus calls with all information I need. I wanted to get these changes upstream but some of my pull request were rejected. I added the bssid, the essid and stuff like this to the hostapd notifications. The pull requests were rejected because I can gather these information through the netlink socket. The ubus bindings of the hostapd should only spread information that can not be gathered in other ways. Now I only have two pull requests left:
Already accepted pull requests:
Added channel survey data in libiwinfo
I had to made the decision, if I want to directly use nl80211 or some library. I already used libiwinfo to contentiously update the rssi of the connected clients. Furthermore, the libiwinfo library is often installed on OpenWrt devices. With the libiwinfo it was possible to gather the essid and the bssid of the WiFi interface. The only information I missed is the channel utilization. The channel utilization is a value between 0 and 255. It is a measure how much a channel is used and what capacity is left.
The channel utilization can be calculated:
Unfortunately, the needed information is not contained in the libiwinfo. So I extended the lib by the necessary information: https://github.com/PolynomialDivision/iwinfo/tree/feature/channel_util
There is some weird behavior of the ath10k driver that I tried to debug. The ath9k driver is working very smooth. If I try to obtain channel survey data without waiting a short time, the survey results become 0. Just waiting between 2 calls fixes the problem.
When I had to figure out how to contribute to the OpenWrt projects. (https://git.openwrt.org/project/iwinfo.git) This can be done via the mailing list. There is a nice tutorial how to send patches using git (https://burzalodowa.wordpress.com/2013/10/05/how-to-send-patches-with-git-send-email/) I’m still waiting that the patch will be merged.
Now I can calculate the channel utilization. Instead of always updating this value, the channel utilization should be averaged. (channel utilization value can be very dynamic)
That’s it. Now I had to rewrite the daemon to gather the informations from the libiwinfo.
I want to implement bootstrapping. If a router joins the decentralized controller, it should automatically get the configuration from one router of the decentralized group. Different solutions are possible. I could use scp, rsync to get a configuration from another node. I wanted a different solution. With uci (Unified Configuration Interface) you can configure daemons. I use uci to read my configuration into the daemon. My idea was to send the daemon configuration via the network as a string and use uci to configure the daemon configurations file. Unfortunately, I had some troubles with the uci lib. This approach is not finished.
Lesson Learned – Use calloc instead of malloc!
I spent a lot of time trying to fix some stupid mistake.
The ubus c-library has a function called ubus_add_subscriber which expects a ubus_subscriber. Everything was fine in my old implementation because I used a global variable. Now I wanted to add more subscriber using an array of pointers. What I did was:
struct ubus_subscriber *sub = malloc(sizeof(struct ubus_subscriber));
This crashed all the time and I was very confused. Finally, a friend of mine said that I should try calloc. It worked! The function ubus_add_subscriber goes through the existing pointers in this struct if they are not null!
Lesson learned: Use calloc. 😉
Lesson Learned 2 – Read header file comments carefully if they exist!
If you use uci_lookup_ptr(ptr,”bla.@bla.bla=blavalue”,true) it will not work!
uci_lookup_ptr needs a string that can be edited and that is not constant! 😉