Skip to content
This repository has been archived by the owner on Jun 10, 2022. It is now read-only.

Support for lwIP #8

Open
6 tasks
snej opened this issue Jun 25, 2018 · 5 comments · May be fixed by #13
Open
6 tasks

Support for lwIP #8

snej opened this issue Jun 25, 2018 · 5 comments · May be fixed by #13

Comments

@snej
Copy link
Contributor

snej commented Jun 25, 2018

I'd like to use libnyoci on an Espressif ESP32 system (SparkFun's ESP32 Thing.) The software stack for this is the ESP IoT Development Framework, ESP-IDF, which uses lwIP for IP networking. This is apparently a pretty widespread IP stack; Wikipedia says "lwIP is used by many manufacturers of embedded systems. Examples include Altera (in the Nios II operating system), Analog Devices (for the Blackfin DSP chip), Xilinx, Honeywell ... and Freescale."

Most of libnyoci builds fine, but there are a bunch of errors in plat-net/posix/ due to missing functionality in lwIP:

  • poll isn't supported, so nyoci_plat_update_pollfds needs to be #ifdef'd out, but then nyoci_plat_wait and nyoci_plat_process break because they call it.
  • cmsgheader and all its ancillary types and constants aren't defined. This breaks sendtofrom.
  • ipv6_mreq is called ip6_mreq for some reason, and its ipv6mr_interface field is of type in6_addr not int, i.e. it wants the IP address of the interface, not its index in the interface list (which doesn't seem to exist; there is no getifaddrs.)
  • in_pktinfo and in6_pktinfo aren't defined. This breaks the pktinfo field of nyoci_plat_s (which seems to be unused. It's written to in nyoci_plat_process, but never read.)
  • IN6_IS_ADDR_V4MAPPED is not defined. I worked around this by copying in the definition from macOS's <in6.h>.
  • Some supported APIs are in different headers; for example there is no <sys/select.h> for some reason, instead select is in <lwip/sockets.h>.

The first issue is the hardest one for me, since I don't know much about either poll or select. Looks like I need to reimplement nyoci_plat_wait and nyoci_plat_process using nyoci_plat_update_fdsets. Probably easy, but I'd appreciate any clues.

The second and third issues seem to be related to multihoming; not a problem for my use case because my board only has a single (WiFi) interface.

The other issues I think I've fixed locally.

@darconeous
Copy link
Owner

First of all, this sounds great! Thanks for having a look. I always intended to add LWIP support but never got around to it.

My first suggestion would be to not attempt to adapt plat_posix, but to instead write a new plat_lwip that uses LWIP directly instead of the LWIP BSD-sockets emulation layer. LWIP has it's own constructs for this purpose which I think would be easier to use directly.

@darconeous
Copy link
Owner

Some hints:

  • Check out this documentation for some (very sparse) guidance on implementing a new net platform.
  • Strictly speaking, both nyoci_plat_wait() and nyoci_plat_process() are optional.

That being said, it is usually convenient to have nyoci_plat_process() around because otherwise you will end up just writing that code somewhere else. nyoci_plat_process() does two things: It checks to see if there is any data from the UDP port that needs to be ingested, and if there is it ingests it via nyoci_plat_set_session_type () and nyoci_inbound_packet_process(). It also checks to see if any timers have expired and handles them if they have (via nyoci_handle_timers()). See the uIP implementation to get a feel for what is required. If you handle packet ingestion as it happens, and call nyoci_handle_timers() appropriately, then strictly speaking you wouldn't need nyoci_plat_process().

You could also implement nyoci_plat_wait() to just return NYOCI_STATUS_OK (basically forcing a tight loop), like I do in plat_uip.

Again, I recommend using LwIP directly instead of using the BSD-Sockets emulation that comes with LwIP. It will give you a tighter, better integrated solution.

@snej
Copy link
Contributor Author

snej commented Jun 26, 2018

Thanks for the quick reply! For now I'm hacking the plat_posix code, because it's faster and I've got a demo on Thursday 😱 It's compiling and basically running now; I will know if it works properly in a few hours when I get the rest of my demo functional.

@darconeous
Copy link
Owner

How'd the demo go?

@snej
Copy link
Contributor Author

snej commented Jul 2, 2018

Pretty well, thanks. It had a tendency to stop responding after a minute or so, but I worked around that. Afterwards I found the reason — I had an uninitialized variable, which was sometimes causing huge timeout values to be passed to select(). After I fixed that, it became pretty reliable.

I have a branch with my changes; I'll clean it up and submit it to you as a PR. (As I said earlier, it adapts the existing POSIX code to make it compatible with lwIP's POSIX adapter layer, instead of creating a new implementation.)

@snej snej linked a pull request Jul 2, 2018 that will close this issue
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants