WiFi Direct and Bluetooth Meshing

As hinted in my last blog article, for us to really be able to move forward we needed to do some experimentation with the new technologies we have to adapt. The primary candidate in the beginning of that phase was WiFi Direct, a type of WiFi mode setting which is an official standard published by the WiFi consortium which is meant to replace the ad-hoc wifi mode. But only partially: WiFi Direct was mostly designed to make integration with IoT products easier. As such, using it for the meshing applications is a bit outside of it’s primary use case. The idea behind it is to make two WiFi devices talk to each other without needing a router to be the middleman for negotiation and frequency selection. Even groups of devices are possible create, electing a group leader that then manages the group.

Unfortunately…that sounded a lot better in theory than it turned out to be in practice.

Also as hinted in my last blog post we built some little prototype applications to test WiFi direct between multiple devices and ran into some issues. The APIs that are provided by Android are okay to use, but not super convenient. But most of the issues come from bugs that we haven’t exactly been able to trace down yet. The system WiFi Direct interface (System Settings > WiFi > Advanced > WiFi Direct) detects all devices in the vicinity whereas our application, using the WiFi Direct interface in the Android SDK would sometimes (nondeterministically) fail to detect devices or open sessions between them. We also had some bad experience creating groups between the devices.

All in all…it was underwhelming. WiFi Direct really wasn’t meant to do the kind of networking we’re trying to do with it and even if we can figure out the bugs we encountered, there are other concerns to work out. Debugging these issues aren’t easy but there are a few things we can do. For one, there are other (open source) applications that exist (serbal, briar, …) that use this technology and we can study to see how they solved these issues. There is also the option of wireshark-ing packets that are being transmitted between the two devices to get a better understanding of where handshakes are going wrong. Simple debugging via Android/ Java debugger unfortunately hasn’t yielded many useful results.

We need a convenient way for people to be able to join the network. We need to figure out a way to create a captive portal for people just connecting without the software. The handoff between a WiFi Direct network section and a legacy ad-hoc section that might be created between infrastructure nodes that don’t support WiFi Direct. The last week or so I’ve had my head in the WiFi Direct specification, trying to answer these questions. And while I think we have solved most problems, there’s still a few left to answer.

The second technology we are investigating to complement WiFi Direct wherever it isn’t applicable is Bluetooth P2P Meshing. In contrast to WiFi Direct, it was actually developed for devices to mesh with each other which makes the adaptation of it easier for us in the long run. So far we’ve only done some simple experiments with 2 devices (due to a lack of Android devices in one location 😉 ) but these have been a lot more promising than what WiFi Direct has offered.

The biggest take-away from the last 2 weeks of experimentation is that we can’t dedicate the routing core to a single networking backend.

In the design of the actual code interface that I’ve built in the first few weeks of GSoC this means that there are some adjustments to be made before writing more code. This includes being more generic when binding interfaces and allowing a client to use multiple backends at the same time. This was not intended to be used in the initial design. But for the time being those interfaces will simply be mocked by some stub methods or maybe a simple simulation so we can test the actual routing algorithms. This is an interesting challenge because so many parts of qaul.net will have to change in lockstep with each other to make it all work.

There are some corner cases to test when it comes to bluetooth mesh networking such as groups and how they handle devices joining in and out of them

The Turnantenna – Second evaluation update

Time is passing, and work is proceeding.

Last month I reported a problem concerning speed of our beloved Turnantenna: the acceleration was not constant during movement of the stepper engine, as I wanted. The error was caused by implementation of a bad algorithm. A constant acceleration is important to provide a smoother movement, and is needed to reduce the load on the engine. Force is equal to mass times the acceleration; if the acceleration is constant, so is the force; but if the acceleration grows, the stepper’s force grows as well, as long as it can keep up. Uncontrollable acceleration lead to unpredictable forces (or better, toques).

To understand the issue, a brief summary should be given: the way to control the stepper’s speed consists of changing the time between two consecutive steps. The shorter the time, the faster the movement. The previous (and wrong) algorithm, is documented in the older post. It wasn’t a good way to control a torque-limited engine because, as said before, the acceleration was not constant. In the previous algorithm, speed was taken like this:

vn = vn-1 + const

namely, at time tn the speed was a fixed amount more than tn-1.
Time between two steps was

dt = (n – n-1)/vn = 1 / vn

It may appear correct, but the resulting graph was the following:

As can be seen, the speed is not linear. This mean that the acceleration is not constant, but increasing.

I found a solution thanks to a document written by Atmel Corporation. It made me think about the relationships between speed (v), space (s), time (t) and acceleration (a) that comes from physics laws:

s = a ½  t² + v₀ * t + s₀

this equation is always true, when accelerating, when the speed is constant, and even when decelerating. Quantities change inside the formula, but it always remain true.

Now, to keep it simple, let’s consider the first phase: the acceleration. A the beginning of its movement, the engine is still (v0 = 0), and it starts without having already done one single step (s0 = 0). The resulting equation is evaluated at v₀ =0  and s₀= 0:

s = a ½  t² + 0 * t + 0
s = a ½  t²

Now, let’s think about what is known: the acceleration a, that it is constant (because I want it so), s and t; s is the number of steps already done at time t. If I know how many steps -s- I have to do I can find how much time I have to wait –t-, and vice versa.

To find the time between two steps (the step #n and the step #n+1) the formula is:

s = a ½  t²
==>  t = sqrt(2 * s / a)

# at the step number ‘n’
tn = sqrt(2 * n / a)

# time between step ‘n’ and ‘n+1’
dt = tn-1 – tn = sqrt(2 / a) * (sqrt(n+1)-sqrt(n))

Using this calculation, acceleration is constant, and speed increases linearly, as it can be seen in the graph below:

AAAAAH.. a perfect blue line! 😀

Problem: Solved!

Working on tests

Now, more progresses have been done in tests. For those who don’t knows, I’ve started my programming adventure with with this project. Everything for me is anexciting discovery, and during this month I learned and implemented the “argparse” and “logging” libraries. Now it is possible to execute the tests with three verbose levels: the first is silent, the second shows debugging informations and the third shows the info level.
It could appear trivial, but I’d never done it before, and now tests are smarter!

It is not all: I reviewed all the tests, fixed problems and improved their reliability. They’re still not perfect, but I’m working on them daily to get details right.

Fly across borders

It was time to go outside the boundaries, and to think about an interface that bring into communication the web interface and the driver. This is what I’m working on in these days.

To achieve that goal, the problem has to be studied starting from an high level. The main process, which is constantly running, float between a small number of determined states: initialising, still, moving and error handling. Together with the Ninux Florence developers community I built the following state machine graph:

This was realized with the GraphMachine module of the “transmissions” library. Now I’m working on the full representation of this map in code lines. But there is something more.. In fact, at this point, multiprocessing became necessary to provide a safe environment: when the engine is in the MOVING state, for example, and a new command is sent to make a new different rotation, the main process should have the possibility to manage simultaneously the ongoing movement and newer requests.

That’s why we choose to keep the main process always active and make it decide when to run the movement procedure in a dedicated process, like a traffic light.

Turnantenna.me

The greatest effort, this month, was done writing down a full, detailed documentation of the project. 80 pages on what is the Turnantenna, how it works, and when and why to use it.

Many people expressed their interest in the project, someone has offered to support us but, without a complete documentation available, it is difficult to provide a starting point.

The whole doc will be soon available, and this post will be updated with the dedicated link. So, if you are interested in the project, let us know! For the moment, GitHub repository is available here.

See you next month!

Meshenger – P2P local network messenger – Update 2

Just a few days after the first update I figured out how to use WebRTC, which I shortly after implemented into Meshenger.

To shortly describe the way signalling is working in my app:

  1. On phone A a call to phone B is issued by tapping the contact, hence phone A already knows the destination address
  2. A sends a call request to B, which B may accept or decline. This is done through a custom JSON-based protocol designed by me
  3. In case of success A creates a Session Description, also called SDP offer, which it transmits to B, using the same protocol
  4. B creates an SDP answer which it transmits back to A, still using my JSON-based protocol
  5. Using the exchanged offer and answer a RTCPeerconnection is established, where the data is transmitted through separate DataChannels/Streams. Upon this moment, WebRTC handles all the communication
  6. Finally, the phones have a RTCPeerconnection which they use to send Audio/Video as well as service messages, e.g. when a camera is connected

 

Besides the sheer implementation of WebRTC the front/back camera can be turned on and even switched on the fly.

The app has undergone some graphical improvements, all buttons containing text has been replaced with Image Buttons,

many of them even show a animation depending on their effect.

 

I even tried to cover the case of the user switching a network, if the link-local address loses its reachability.

Instead of simply trying to reach the last known address, the app now examines every address the phone has

and tries to replace its own MAC address in those addresses with the MAC of the target.

This leads to a higher chance of re-finding a contact even if the phones have switched networks.

 

As you can see in the following screenshot, bidirectional video-transmission is enabled, and the buttons at the bottom now have cute icons.

 

Phone A
Phone B

 

 

 

 

 

 

 

 

 

 

 

From now on I will focus on polishing the app, cleaning the source code, finding and resolving bugs and,

last but not least, writing sufficient documentation.

I may even write a blog post somewhere, explaining how to archieve a serverless WebRTC connection,

since the documentation i have found so far was not really helpful and mainly focused on JavaScript.

Routing and WiFi experimentation

The beginning of my work period was pretty busy, not always with Summer of Code things. My mentor math and I had already talked about a lot of the things that needed to happen in order to move qaul.net away from an OLSR based routing protocol and make it extendable as well.

As previously hinted, we are using Rust for the protocol implementation, allowing for easy integrating into the existing C code as well as giving us the option to bit-by-bit rewrite the entire software in Rust, a much more modern and forgiving language. The first thing I tackled was to design a common API for the qaul.net library (libqaul) to use to talk to any networking backend. The routing code holds the state of the network and allows the sending of direct and flooded messages into a network (regardless of implementation under the hood). But to do that we also had to define some common characteristics for nodes and messages.

In the end, a lot of the work was sitting down, going through old notes and determining what our protocol was supposed to do. We looked at existing protocols a lot, thinking about extendability and backwards compatibility. The protocol itself will be binary encoded, although not yet sure which format. There is msgpack, cpnproto/ protobuf as well as some Rust specifics (Rust Object Notation to mention one) to look at. But that shouldn’t actually matter for now. All the versioning and extend-ability are being done in the struct level of the protocol, meaning that we could even switch binary encoding half way through. Keeping the encoding and decoding written in Rust, this is actually incredibly easy with the `From` traits. But I digress…

The protocl we ended up designing can handle any type that already exists in qaul.net, as well as allows for custom user extentions – messages that have a type field and a random binary message payload which allows plugins on both sides to interact with it.

 

So…so far the routing core isn’t doing much routing. But that’s okay, that comes later 🙂 With the networking API in place, we actually have something what we’ve wanted for the last 2 years: a hardware abstraction over any networking backend. The API is implemented in Rust as a trait (think like a Java interface), which makes implementations and even implementation specific code very easy.

The next thing on our todo list is working out how WiFi direct behaves. This is kinda disconnected from the rest of the project, but it’s something that has to happen. For this purpose I’ve written a small demo app (still WIP at the time of this writing), which will let us explore the way that WiFi direct works, how to build mesh groups, etc. These experiments are still ongoing, and we hope to have something to show until the end of the week. I will probably publish a small article on my blog about it – check it out (if you’re reading this in the future 😉 )

All in all, the amount of code written in the first section of GSoC2018 is medium. We have however answered a lot of open questions, have a good plan on how to continue and hope to have more to show off by the time of the next evaluation.

If you’re curious about the progress being made, check out the github repository.

 

Until next time,
Katharina

A module for OLSRv2 to throughput estimation of 2-hop wireless links

Hi to community members!

In the phase 1 period, we designed and prototyped a throughput estimation client/server in PRINCE based on iperf3 library. The basic idea is that each node has an iperf3 server and a node can estimate the neighbor throughput by running an iperf3 evaluation. The code is available at https://github.com/pasquimp/prince/tree/iperf.

In order to keep the throughput estimation in OONF, we are evaluating the best strategy among forwarding the estimation from PRINCE to OONF or introduce a new plugin in OONF to perform throughput evaluation. A possible prototype of a new plugin in OONF is available at https://github.com/pasquimp/OONF/tree/neighbor-throughput.

In the next weeks, we will decide on the best strategy in order to keel reliable neighbor throughput estimation and keep aware OONF about the estimation. We will update you in the coming weeks!

 

nodewatcher: Build system rework and package upstreaming – First update

Since last update I spent most of time on fully understanding current build system and nodewatcher internals.

Build system

During the time spent into looking how the whole system works I belive that I was able to figure out what every step and script does in the current build system.
During that I found a lot of relatively simple improvements that can really reduce custom stuff that we have. Most of it was added 3-5 years ago when OpenWrt wasnt really in the state it is now. Custom mirror for source was added,which is now useless as it was not updated and on some really old custom packages it is really slow. Also,building all packages that are added to the package list during build time is not really efficient as during its building OpenWrt default feeds are replaced with our custom package feeds.
This causes users to be stuck on really old and quite limited number of packages. This will be revorked to only replace the target feed as it contains all of the kernel mods that are tied to specific kernel version.
Other packages have no such requirments and versions in upstream can be used.
Also,wget was used during the build time to pull dependecies instead of curl which is recommended tool. Wget is fine for simple downloads but a lof of packages are pulled from behind CDNs and with lot of redirects from mirrors such as Sourcefourge,those curl can handle fine but wget cant.

I have started dropping unused and old packages as well as those that had custom patches that were upstreamed a long time ago.
Stuff like iwinfo from 2015 and old curl.

Also,I have started to move both the buildsystem docker image and runtime docker image from Ubuntu 14.04 to 18.04 Bionic.
This does not yet fully work as Imagebuilder does not detect GCC and Ncurses in the runtime image as working despite the fact that GCC works fine. This will be hard to diagnose,but I feel that it is quite simple.

Custom Wlan Slovenija packages are being prepared for upstreaming.

This is all for now,next two weeks should be bring solutions to most issues.

Robert Marko

VRConfig Update

Hi,

I have some quick updates about VRConfig for you.
Short recap: VRConfig aims to introduce a graphical configuration mode for OpenWrt’s Webinterface LuCI.
For that need to collect pictures of the backside of all supported routers. The idea is to do this in a crowdsourcing manner. The community can submit pictures of their routers together with a metadata file which contains the locations of the components on the picture.

I spent the last weeks developing a web application to provide the annotation functionality of the router components.
A working prototype is now ready and can be tested at the following URL: https://vrconfig.gitlab.io/annotator/
Source code: https://gitlab.com/vrconfig/annotator

The annotator produces a JSON file which in turn can be parsed by the LuCI Application to provide the graphical configuration mode.

The LuCI application is being developed right now and will be provided shorty under the following URL: https://gitlab.com/vrconfig/luci-app-vrconfig

More info about that in the next blog post.

GSoC 2018 – DAWN a decentralized WiFi controller (1st update)

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.

Bootstrapping

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));
ubus_add_subscriber(ctx, sub);

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! 😉

GSoC 2018 – Better map for nodewatcher (1st update)

Since my last update I made a lot of progress in understanding how nodewatcher works, mostly around Django, and implementing some of the elements I stated in my last post.

My progress in the beginning was very slow because I hadn’t used Django in such capacity used in nodewatcher. But after a couple of trial and error moments and a lot of help from Django forums and wlan-si members I was able to get a grip of the things I needed. There should be a more detailed description as to how to some parts of the nodewatcher system work. Currently only a handful of people know how the whole system work and that shouldn’t be the case, I will try to document most of my findings and contribute them to the project to help others later on.

I started my own leaflet map in order to begin progress on the map while I learned everything around the current nodewatcher schema. I tried to implement the basic functionalities first to see how the whole code is layed out. As you can see from the picture below I tested out the fullscreen option of the map and also the color representation of the different nodes. In the top-right corner I also added the support for selecting which nodes to show.

This is just a test example and there is a lot of work implementing this into nodewatcher because here I wrote my own script and added the markers by hand. The biggest part is that I need to figure out where to add this code to nodewatcher and make it work with real nodes. I hope to have this figured out until the next update so that some of the features get added. These features are subject to changes and will most likely change in appearance.

I also had some problems with implementing new scripts but that shouldn’t pose a problem in the future. As I said earlier the main problem is adapting to the current code and maintaining its structure so that there isn’t any confusion when someone else takes over. But as I said this involves a lot of asking around for help and will be helpful later on because I hope to continue with this project after GSoC.

After that I will start working on the side menu and anything else that shows as a good addition to the map but for now it is important to learn how the system works and add basic upgrades so that later on it is easier to focus just on adding new elements not wasting time with learning how everything works again.

GSoC 2018 – Kernel-space SOCKS proxy for Linux – June progress

Assembling the testbed

I decided to give you a brief intorduction to the development of my testbed. In the past month most of the time I experimented with different virtual environments for kernel development. The pros of virtualization:

  • Fast test cycles: multiple virtual machine (VM) can use the same, freshly compiled kernel
  • No physical devices, you dont have to reboot your machine every time when you want to test your recent kernel changes. VMs reboots very fast (about 6-7 sec in my current setup)
  • Flexible network virtualization: you can connect your VMs with virtual ethernet links to virtual switches

My current worflow looks like this:
1. Make changes in the kernel code or configuration (make menuconfig or .config file)
2. Compile the modified kernel
3. Boot the virtual machines with the new kernel
4. Test if works, debug, etc.
5. Goto 1.

In the following you can find a detailed intro how to setup the kernel development and test environment with QEMU and virtual networking

Continue reading “GSoC 2018 – Kernel-space SOCKS proxy for Linux – June progress”