gnrc: MAC layer selection

Dear developers, Currently there are two different MAC layers for gnrc in the master branch: basic gnrc_netdev, and gnrc_lwmac. gnrc_netdev is basically a no-op MAC layer, only passes packets between the netdev driver and the upper layers, while LWMAC is a duty cycling MAC implementation which manages a schedule for the radio, including sleep.

Which layer is used is selected by which init function is called during boot, if gnrc_lwmac_init is called, then the device will run LWMAC, or if gnrc_netdev_init is called, then the device will use gnrc_netdev. auto_init has an `#ifdef` block checking for `MODULE_GNRC_LWMAC` and uses that to select which init function is called, but this is only implemented for the at86rf2xx driver, any other drivers will need to have similar changes to their auto_init functions as well.

This current model is not going to scale well when new devices are added and new MAC layers are implemented. All MAC layer implementations will need to touch all netif auto_init implementations.

I am asking for ideas on how to make this more modular and less #ifdeffy.

One possible solution is to add a function pointer member to the `at86rf2xx_params_t` (and similar parameter structs for the other netdev drivers) for initializing the MAC layer, and let the user select the MAC layer there. By default, we can use a macro GNRC_DEFAULT_INIT or similar to choose the default MAC layer depending on the module selection. This would behave like it is today for LWMAC, but the #ifdef hell would be kept in a common header file, like gnrc_mac_default.h or something.

What are your thoughts on this?

I have a ContikiMAC MAC layer implementation queued up in the pipe for inclusion in master and it will only make this situation worse if we don't alter the current model.

Best regards, Joakim Nohlgård Eistec AB

Hi, Joakim,

This is a very good topic which also confuses me (with also my GoMacH MAC implementation queued up in pipe).

One possible solution is to add a function pointer member to the `at86rf2xx_params_t` (and similar parameter structs for the other netdev drivers) for initializing the MAC layer, and let the user select the MAC layer there.

This sounds like a good solution to me. Waiting for responses from more experienced RIOT developers. :wink:

Bests, Shuguo

Hi Joakim, Hi Shuguo,

First of all: We know of this problem and I try to come up with a solution for this for a long time, so thanks for picking this up. A step into that direction (but not the final solution) was the refactoring of GNRC’s interface layer (aka gnrc_netif2, see [1], should also simplify implementing new MAC-layers a lot ;-)).