AVSystem / Anjay

C implementation of the client-side OMA LwM2M protocol

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wrong CoAP endpoint path for send update

termarfr opened this issue · comments

Hi,

I'm trying to implement a basic Anjay client on a STM32F437 with FreeRTOS and lwip.
I've implemented your BC3 example, which simply register the client to the server and update periodically. I'm using STML32CubeIDE and I've imported and built the Anjay library following the instructions you provided. I'm using the Leshan demo server for testing purpose.

I managed to have the connection between the server and the client working, but the update part doesn't work. By looking at CoAP traces with Wireshark, I've noticed that Anjay send an incorrect endpoint path to the server:
POST, TKN:2e d0 54 01 65 20 ae d2, /rd/../Middlewares/Anjay/src/core/servers/anjay_reload.c/
while it should send something like:
POST, TKN:2e d0 54 01 65 20 ae d2, /rd/c0k6tG2QsY

The server replies with a 4.00 "Bad URI" error because of the '/' in the path.
I've tried the BC3 example from an Ubuntu VM and there isn't any issue, Anjay send a correct endpoint path when updating:
POST, TKN:b4 dc c3 ba 23 63 29 72, /rd/r7OOav9dIP
This is something handled by the Anjay lib so I don't see why it should not work on an embedded environment.

You can find both traces attached: coap_traces.zip

The embedded client also crash when sending this update, but I'm not certain that this is related to the wrong endpoint path. Here's the stacktrace when the hardfault occurs:
image

Do you have any idea why a C file filepath ends up in the CoAP request? Do you think this is related to the hardfault also occuring during the update?

I already had to tweak a few things on the Anjay lib in order to avoid crashes related to memory management on the STM32, I'll report them later after reviewing, I think that might be of interest for you.

Thanks for your help

Hello,

The invalid endpoint path is a part of a log message. This is not expected to happen and my suspicion is that you have some problems with memory management (possibly a stack overflow) and definitely the crash afterwards is related to it.

Did you try to configure the logging feature? It's possible to enable the global buffer by defining AVS_COMMONS_LOG_USE_GLOBAL_BUFFER in avs_commons_config.h, so the single global buffer will be used instead of allocating buffers on stack in every call, so it could help in your case.

You may also want to take a look at Anjay-freertos-client. It's for STM32L496 and uses X-CUBE-CELLULAR, but maybe you'll be able to reuse some of the code.

Hello,

Thanks for your quick reply. I've used the Anjay-freertos-client demo as a start-up point, but I had to redefine the allocation system, contrary to your example and indeed the issue came from memory management. AVS_COMMONS_LOG_USE_GLOBAL_BUFFER was enabled though, but that didn't helped much.

In implementing the avs_realloc function, I didn't think about copying the existing data when reallocating a bigger memory chunk, that was my mistake.

However, that did not solve my issue until I added a memset(p, 0, size) before returning the newly allocated pointer in avs_malloc. At some point in your code it seems to me that you're assuming some data are set to 0 when allocated, which is not supposed to be necessarily always true.
(I previously had some issue with the realloc_membuf function in avs_stream_membuf.c with uninitialized data for instance)

I can currently run the BC3 example from my embedded device, I'll let you know if I encounter further issues and if that's not the case I'll look further into that memset issue within the avs_malloc to see if that came from me or not.

According to the ISO C standard, malloc() does not guarantee that the allocated data will be zeroed, but calloc() does. The same assumptions are made for avs_malloc() and avs_calloc() - whenever avs_malloc() is called by the library, we do not assume that the data will be all zeroes, but when avs_calloc() is called (which is admittedly the majority of cases), we do. If you found a place where this is not true, then please mention a specific location in the code or steps to reproduce, as this would indeed be a bug that needs fixing.

You didn't mention anything about your avs_calloc() implementation, but I suppose that this may actually be the place where memset() was missing. If you call avs_malloc() from avs_calloc() then of course adding memset() in avs_malloc() will fix the problem as well.

Anyway, it's great to hear that you got it to work :)

Indeed, I didn't know that calloc() guarantee that the allocated data will be set at 0. My implementation of avs_calloc() simply called avs_malloc() so the memset() in avs_malloc() resolved the issue, but that wasn't neat.

On top of that, my implementation of avs_malloc() was calling pvPortMalloc() from FreeRTOS, which does not seems to handle border case like a wanted size of 0 bytes. Looking at the ISO C standard I was able to implement proper memory management functions and Anjay is now working perfectly fine!

Thanks for your help, hope this ticket will help anyone else that needs to override the default allocator.