-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: feat(6lowpan_ble): Simplified esp_netif driver #600
Open
david-cermak
wants to merge
16
commits into
espressif:master
Choose a base branch
from
david-cermak:feat/6lowpan_ble
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Collaborator
david-cermak
commented
Jun 21, 2024
- Very WIP
- Based on https://github.com/geonavo/lowpan6_ble
- Cleanup esp_netif sources
- Make examples compatible with component manager projects
- Add lwip 6lowpan netif to IDF
- Make it work with simple linux router (e.g. as described here)
This dumps a BLE address to a static char buf. Note that this means it can only be used once per log line (as calling it twice means you'll overwrite that buffer).
This is the "driver" or "glue" code for ESP-NETIF. See https://docs.espressif.com/projects/esp-idf/en/v5.2.1/esp32/api-reference/network/esp_netif_driver.html for a more detailed overview of I/O drivers in ESP-IDF. A quick overview though -- this module is responsible for the BLE side of LoWPAN6 BLE. Given a BLE address to connect to (up to the user to decide what address that is), it will: * establish an L2CAP connection with: * the correct Protocol Service Multiplexer (PSM) for the Internet Protocol Support Profile (IPSP) * the correct MTU for LoWPAN6 (1280, as required by IPv6) * on receipt of data, pass the received data to `esp_netif_receive` * register and provide methods for transmitting data FROM esp_netif via the L2CAP channel * forward events to the user (e.g., GAP connect/disconnect, so they can restart the discovery process on disconnect) The driver/glue code does _not_ perform any of the protocol side of LoWPAN6 BLE (i.e., we don't feed any data to LwIP): that will be the job of a custom NETIF layer.
esp-lwip doesn't include the lowpan6 files in their build by default (fair enough, given that it's not officially supported). This is a quick workaround to pull those files in without changing ESP-IDF.
This defines the netstack required to support LoWPAN6 BLE with LwIP. See https://docs.espressif.com/projects/esp-idf/en/v5.2.1/esp32/api-reference/network/esp_netif_driver.html for a more detailed overview of how this fits into ESP-NETIF. A quick summary here though. This module provides the "netstack": this is the configuration used by ESP-NETIF to initialize the netif given to it and to handle incoming data. In our case, this means initializing the netif as an rfc7668 netif and providing received data to `rfc7668_input`, as required by LwIP's LoWPAN6 BLE module. Also important is for us to set the local and peer addresses (used by LwIP when compressing IPv6 headers for transmission over BLE) and to set our link-local IPv6 address based on our BLE MAC address, as required by the LoWPAN6 BLE standard.
Registering custom LwIP netstack functions was not supported in ESP-IDF prior to v5.0: From [this comment thread](espressif/esp-idf#13600 (comment)) > yes, registering custom lwip IO functions wasn't possible in IDF < v5.0. > (still possible, if you redefine the opaque structs, like this) > https://github.com/david-cermak/eth-ap-nat/blob/2279344e18a0b98b5368999aac9441c59871e6fa/eth-ap-idf4.3/main/ethernet_example_main.c#L90-L96 There are two things we need to do to shim this custom I/O driver into ESP-NETIF for ESP-IDF v4 and co. The first is to add implicitly required #include before "esp_netif_types.h". This is fixed in v4.4+ by the following commit: espressif/esp-idf@822129e but not backported to v4.3 (fair enough, seeing as it's EOL). The second is to define a netstack config struct compatible with `struct esp_netif_netstack_config_t`, which was not publically exported prior to v5.0. We do so following the example linked above in the david-cermak/eth-ap-nat repo: * define `struct esp_netif_lwip_vanilla_config` * cast our netstack to `esp_netif_netstack_config_t*` `esp_netif_netstack_config_t` is just a union of `struct esp_netif_lwip_vanilla_config` and some other struct we don't care about, so while a bit sketchy this does actually work out (i.e., we can correctly cast between them).
This commit introduces some helper functions for transforming BLE addresses into link-local addresses. This can be used by users to get the link-local address of their peer after establishing a connection.
We were adding the missing lwIP sources to `lowpan6_ble`. While this worked, it does break the link between `lwip` the target and the lwip lowpan6_ble sources. I bumped into this when enabling lwIP debug: some of their debug statements were failing ESP-IDF's -Werror=format checks. I tried to address this with: ``` idf_component_get_property(lwip lwip COMPONENT_LIB) target_compile_options(${lwip} PRIVATE -Wno-error=format) ``` but of course, the `lwip` target did not contain the sources that were causing an error -- `lowpan6_ble` did! Appending the sources to the `lwip` target is the more correct approach here.
This is a first stab at the additional "stuff" we'd need to support a LoWPAN6 BLE client (the device that gets connected to rather than the one that connects).
This example is a quick-and-dirty demo of how to communicate over LoWPAN6 BLE between 2 ESP devices. This demonstrates how to hook the lowpan6_ble component into the GAP discovery and connection process to ensure that generic networking APIs such as lwIP can successfully pass messages over our BLE connection.
The `ble_l2cap_send` implementation has a comment that says: > Transmits a packet over an L2CAP channel. This function only consumes > the supplied mbuf on success. This means that on _failure_, we're responsible for freeing the supplied mbuf, otherwise we'll leak memory.
This disconnects our L2CAP and GAP connections, if applicable.
|
david-cermak
force-pushed
the
feat/6lowpan_ble
branch
from
June 25, 2024 09:41
d3d7de7
to
d47b118
Compare
david-cermak
force-pushed
the
feat/6lowpan_ble
branch
from
June 25, 2024 09:56
d47b118
to
2999835
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.