libcoap icon indicating copy to clipboard operation
libcoap copied to clipboard

esp-open-rtos compatibility

Open malachib opened this issue 8 years ago • 16 comments

I am attempting to get this working in esp-open-rtos, but there seems to be a snag with the custom lwip memp allocation pool.

Using the custom memory pool is a great idea, but is it possible to use libcoap without it? The RTOS seems to disable it on purpose

malachib avatar Dec 21 '16 04:12 malachib

Unfortunately, I am not familiar with esp-open-rtos. You can use libcoap without the lwip memory pools (the POSIX and Contiki ports, e.g.,, do not use it). The lwip port is a bit special here but I would think that it should be possible to make the lwip pools optional -- all memory allocations in libcoap are done through the include/coap/mem.h API. Can you suggest an (optional) alternate memory allocation technique for lwIP?

obgm avatar Dec 21 '16 08:12 obgm

Unfortunately I don't know the tools well enough to make a suggestion. I would merely think straight up heap allocation. Unclear if that's even a good idea though.

It seems close to compiling though on my fork. I'm asking on the esp-open-rtos side, 'cause keeping the memory pools seems like a good idea.

malachib avatar Dec 21 '16 08:12 malachib

Heap-allocation using malloc() might not be a good idea on an RTOS but in that case, you could use the posix-functions which map to malloc/free.

obgm avatar Dec 21 '16 10:12 obgm

Sorry to leave this dangling so long. Taking another crack it it now

EDIT: I am getting pretty overwhelmed. The esp-open-rtos utilizes FreeRTOS + LWIP environment also really wants to use its own makefiles, so I'm trying to yank in libcoap via esp-open-rtos native makefile/component architecture.

It seems like one can do a Contiki or Posix or LWIP scenario, with maybe Contiki having a non reflexive dependency on LWIP. Is that a correct assumption?

malachib avatar Jul 07 '17 23:07 malachib

LWIP has emerged from Contiki AFAIK but since they have been split the gap continually increases.

FWIW: The embedded platform ports (Contiki, LWIP, RIOT, and even TinyOS) all use their own Makefiles to integrate with the OS's build system. I think it is valid to build another Makefile for the esp-open-rtos integration.

obgm avatar Jul 11 '17 10:07 obgm

OK good to know. I was about ready to throw in the towel, but maybe I can post my build errors here and you can point me in the right direction...I never knew LWIP actually came from Contiki... interesting!

malachib avatar Jul 12 '17 02:07 malachib

Yes, please do. This platform is interesting enough to spend some development cycles :-)

obgm avatar Jul 12 '17 09:07 obgm

OK, so here's the very beginning of a long list of errors I get. It seems that some LWIP glue still needs application somewhere !

/home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io.c: In function 'coap_network_send':
/home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io.c:260:3: warning: implicit declaration of function 'CMSG_LEN' [-Wimplicit-function-declaration]
   char buf[CMSG_LEN(sizeof(struct sockaddr_storage))];
   ^
/home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io.c:260:28: error: invalid application of 'sizeof' to incomplete type 'struct sockaddr_storage'
   char buf[CMSG_LEN(sizeof(struct sockaddr_storage))];
                            ^
/home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io.c:263:17: error: storage size of 'mhdr' isn't known
   struct msghdr mhdr;
                 ^
/home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io.c:264:16: error: array type has incomplete element type
   struct iovec iov[1];

I run configure first also, and I have a question about that - I compile my esp-open-rtos from inside a docker image, but I had to run autogen.sh outside the image. configure itself ran well inside the image. Is that OK?

malachib avatar Jul 13 '17 03:07 malachib

The POSIX network I/O functions are not available in LWIP, and apparently, the toolchain for esp-open-rtos does not provide a compatibility wrapper. I suggest you build on the existing LWIP support for libcoap as done in examples/lwip. The Makefile there ensures that the preprocessor symbol WITH_LWIP is set so that the LWIP I/O functions are used. And here is the bad news: The latest changes (i.e., the new 4.2 API) currently breaks the LWIP-specific code as that still uses the old API. Thus, once you have the build process running it will bail out on some functions such as coap_send() as they now use an additional parameter. (I am planning to write some more documentation on this within the next days.)

obgm avatar Jul 13 '17 10:07 obgm

OK, good intel. I thought for sure I "enabled all" the LWIP stuff, but clearly I missed a spot. It's worth the effort to diverge from POSIX for me (no beef with POSIX, but the name clashing is good to avoid). Side note: I do think there is a POSIX compatibility wrapper in esp-open-rtos... not sure. But moot, for me. I'll chip away at that one

Hopefully we can work around LWIP breaking API changes with some clever #ifdef'ing...and I wouldn't know to look for those runtime errors without your input, so thank you

malachib avatar Jul 13 '17 17:07 malachib

OK trying with the WITH_LWIP flag, but hitting this error:

In file included from ../../ext/libcoap/libcoap/include/coap/address.h:22:0,
                 from ../../ext/libcoap/libcoap/include/coap/coap_io.h:16,
                 from ../../ext/libcoap/libcoap/include/coap/net.h:25,
                 from ../../ext/libcoap/libcoap/include/coap/lwippools.h:13,
                 from /home/esp/esp-open-rtos/lwip/lwip/src/include/lwip/priv/memp_std.h:139,
                 from /home/esp/esp-open-rtos/lwip/lwip/src/include/lwip/memp.h:49,
                 from /home/esp/esp-open-rtos/lwip/lwip/src/include/lwip/stats.h:43,
                 from /home/esp/esp-open-rtos/lwip/lwip/src/include/lwip/netif.h:50,
                 from /home/esp/esp-open-rtos/lwip/lwip/src/include/lwip/dhcp.h:45,
                 from /home/esp/esp-open-rtos/open_esplibs/libmain/user_interface.c:14:
../../ext/libcoap/libcoap/include/coap/libcoap.h:27:24: fatal error: netinet/in.h: No such file or directory
 #include <netinet/in.h>
                        ^
compilation terminated.

Seems to me at this point the code isn't watching for the WITH_LWIP flag and instead assumes a posix availability. Otherwise, I'd expect we'd be detecting/including something more like <lwip/inet.h> around https://github.com/obgm/libcoap/blob/develop/include/coap/libcoap.h#L26. This is my best guess. What do you think?

malachib avatar Jul 14 '17 02:07 malachib

There is definitely a guard for !defined(WITH_LWIP) missing. Commit 9b647d5d has removed some of these to ensure reasonable defaults for POSIX-like platforms but did not clean up the guards for other platforms.

obgm avatar Jul 14 '17 20:07 obgm

OK; with that in mind, I'll add some code along those lines to my fork

malachib avatar Jul 14 '17 21:07 malachib

So this sounds a bit like what you were talking about with parameter mismatch, but not in the area I was expecting:

/home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io_lwip.c: In function 'coap_recv':
/home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io_lwip.c:59:2: warning: passing argument 2 of 'coap_handle_message' from incompatible pointer type [enabled by default]
  coap_handle_message(ep->context, packet);
  ^
In file included from ../../ext/libcoap/libcoap/include/coap/lwippools.h:13:0,
                 from /home/esp/esp-open-rtos/lwip/lwip/src/include/lwip/priv/memp_std.h:139,
                 from /home/esp/esp-open-rtos/lwip/lwip/src/include/lwip/memp.h:49,
                 from ../../ext/libcoap/libcoap/include/coap/mem.h:89,
                 from /home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io_lwip.c:11:
../../ext/libcoap/libcoap/include/coap/net.h:406:5: note: expected 'struct coap_session_t *' but argument is of type 'struct coap_packet_t *'
 int coap_handle_message(coap_context_t *ctx, coap_session_t *session, uint8_t *data, size_t data_len);
     ^
/home/esp/esp-open-rtos/examples/project/ext/libcoap/libcoap/src/coap_io_lwip.c:59:2: error: too few arguments to function 'coap_handle_message'
  coap_handle_message(ep->context, packet);

Rooting through endpoint, it looks like one could find the session* there but it seems multiple sessions would be present so I'm not sure how you would decide which one to grab.

malachib avatar Jul 15 '17 00:07 malachib

This is exactly the spot where it was expected to break :-) Picking the right session is handled by the new function coap_read_endpoint(), which is called from coap_read() for all sockets that have their flags set to COAP_SOCKET_HAS_DATA. For LWIP, this needs some additional work as it has a somewhat different handling of incoming packets right now.

obgm avatar Jul 15 '17 06:07 obgm

libcoap LwIP support has been re-written in PR https://github.com/obgm/libcoap/pull/884, and so this should no longer be an issue.

mrdeep1 avatar Jul 23 '22 15:07 mrdeep1