lobaro / lobaro-coap Goto Github PK
View Code? Open in Web Editor NEWCoAP Implementation in C
License: MIT License
CoAP Implementation in C
License: MIT License
If CoAP_AllocRespMsg() returns null here, do you think we can just return without calling SendResp()?
Line 380 in 7f5fed4
Regarding the default /.well-known/core
handler; I think adding a CoAP_RemoveResource(...)
to complement CoAP_CreateResource(...)
would enable the application to remove the default handler and help by allowing the application to dynamically remove resources as they disappear from the device (for what ever reason).
Another idea is allowing the application layer to manually register WellKnown_GetHandler
(Might rename it to CoAP_DefaultWellKnownHandler
for clarity). Or possibly adding a flag to CoAP_Config_t
to disable automatic registration of the default handler
otherwise, maybe a callback could be added to CoAP_ResOpts_t
When it's not null, WellKnown_GetHandler
will call that for generating a string (i.e. </example/resource>;ct="0 50 60";rt="example";if="sensor"
) per resource.
then "pOption" and "pOption->next" are same pointer address.
https://github.com/Lobaro/lobaro-coap/blob/d7a4c79ad2217f744ac9757d2b4bc15599442450/src/coap_options.c#L423-L425
Is the free list correct?
https://github.com/Lobaro/lobaro-coap/blob/d7a4c79ad2217f744ac9757d2b4bc15599442450/src/interface/mem/coap_mem.c#L1015-L1024
The following include causes code to not compile.
From inspection seems like it was intended to be
#include <stdio.h> #include <string.h>
for the calls for following calls
and
The example is a coap-client , now i want to use lobaro-coap act a coap-server to deal with messages from a local area network。
How to implement this ?
Hello, I need an explanation about how this package works. for instance, NetAddr can be an uint32_t array with one entry and also an uint8_t array with 4 slots for IPV4.
I get the way for the 8-bit array but with 32-bit do we have to shift the numbers?
for example 192.168.1.2 is 2 + 1 + 256 + 168 + 256x256 + 192 + 256x256x256 ?
generally speaking, is there any documentation about how this package and its parts work?
I am already familiar with porting guide on GitHub and code examples on lobaro.com
thank you in advance.
pDescription
may be null and causes a hard-fault when observers are notified of a resource update.
https://github.com/Lobaro/lobaro-coap/blob/b6b5ced0f7d013022c848d5f3da4ddb757339b6c/src/coap_interaction.c#L279
It's set to NULL when an null or empty string is passed in as a resource description on CoAP_CreateResource
:
https://github.com/Lobaro/lobaro-coap/blob/d7a4c79ad2217f744ac9757d2b4bc15599442450/src/coap_resource.c#L335-L340
With a little manual how to build a lib (.a) file for a few platforms (e.g. Linux, Windows, STM32, Adruino) it should be sufficient to link that file and add a single .h file to a project in order to be able to use the lib.
CoAP_CreateMessage calls malloc. For the use case I am looking at, heap allocation for every message sent isn't an option.
Can a message pointer be reused? Or is there a way to allocate a message on the stack?
Thank you!
I spent sometime last week on getting a client request working from this library.
It spat the dummy on the return message. On investigation the code used to parse the Options made the assumption that there had to be 1 or more options, but in the spec options can be 0 or more.
coap_options.c: 178 if (srcArr[0] == OPTION_PAYLOAD_MARKER)
(This is a later version to the code I was looking at, but my reading of the spec implies that a payload can follow the tokens - something this doesn't allow for, and is always invoked as part of the message processing?)
I could be wrong here though, it was a quick fix to render the response of a coapthon server that may well be violating the spec.
Saw this while working on multicast support. Will be providing a PR to fix this shortly. but making an issue just in case.
interface/network/net_Endpoint.h:83
void CopyEndpoints(NetEp_t* Source, NetEp_t* Destination);
interface/network/net_Endpoint.c:55
void _rom CopyEndpoints(NetEp_t* Destination, NetEp_t* Source)
{
memmove((void*)Destination, (void*)Source, sizeof(NetEp_t));
}
For 64bit platform based on GNU/Linux (amd64) at least one type length mismatch between BGET <-> lobaro has been found causing stack smashing. The problem is that BGET originally is based on basic types e.g. int, long, etc. and lobaro uses fixed size ones, e.g. int32_t, etc. When BGET-functions return values via pointers to lobaro funcs. they (may) overwrite the stack on platforms where length mismatch occurs - e.g. for GNU/Linux amd64 long is 64bit vs. int32_t (as according to spec. long has to be at least 32bit).
The following example of affected code is related to nget, nrel variables (int32_t vs. long) :
void _rom coap_mem_stats()
{
bufsize curalloc, totfree, maxfree;
int32_t nget, nrel;
bstats(&curalloc, &totfree, &maxfree, &nget, &nrel);
void _rom bstats(curalloc, totfree, maxfree, nget, nrel)
bufsize *curalloc, *totfree, *maxfree;
long *nget, *nrel;
{
struct bfhead *b = freelist.ql.flink;
*nget = numget;
*nrel = numrel;
Of course mentioned issue does not occur when we compile it for 32bit - there no such mismatch occurs because long data type is 32bit.
I think that either BGET original implementation should be rewritten to use fixed size data types or at least some caution in README.md added that 64bit platforms may not be fully supported.
Hi!
Can someone provide example code of CoAP Lobaro usage?
how can i append notify and block transfer option to the request message from the client??
Goal should be to have a brief tutorial on how compile and use the library.
Something like: "compile" -> "run tests" -> "take .a file and one .h file to your own project" -> "how to setup a few different endpoints"
The getting started could be in the Wiki or Readme and in future might link to more detailed tutorials that could explain specific setups e.g. for Arduino, the EPS, setup with different IDE's etc. which are out of scope of this issue.
The goal would be to have no bget related code and have malloc
and free
as part of the API struct, so the user can choose what to use. If bget or the stdlib malloc and free is the default is up to discussion.
Currently we have 2 different handler functions that need to be implemented and registered separately but often share a lot of code in applications. I would like to reduce the API to a single handler for Observes and normal requests.
Before the rebase in 0fa8289, I set my makefile to include the base folder which lobaro-coap was residing in. So my project's includes looked like:
#include "lobaro-coap/coap.h"
Namespacing the include files makes it easier when dealing multiple libraries or project file names that conflict.
In my case, esp-idf has included it's own own ported version of libcoap which I don't want to use. So #include "coap.h"
could either mean libcoap's coap.h, or lobaro-coap's coap.h which my compiler isn't too happy about.
with the files now sitting under /src
It would require me to create a symbolic link to fix the issue or maybe branch and rename the folder.
Instead I would like to propose that header files are moved to /include/lobaro-coap/
under the project root directory to help clean up potentially conflicting names.
The client is requesting correctly with the observe option and getting an ACK from the server.
But after the first CON from the server my callback (sendRequestCB) is called and the interaction is getting deleted. (@see: coap_main.c:handleClientInteraction)
In return the client sends a RST instead of an ACK because he cannot find the previous deleted interaction. (@see: coap_main.c:CoAP_HandleIncomingPacket)
The server removes the subscriber because he received a RST (Cancel Observation).
CoAP_Result_t res = CoAP_StartNewGetObserveRequest_my("din0", mCoapSocket->Handle, &mReceiver, sendRequestCB);
CoAP_Result_t CoapClient::sendRequestCB(CoAP_Message_t* pRespMsg, NetEp_t* Sender) {
printf("--------------------------------->>>>> sendRequestCB done\n");
...
}
CoAP_Result_t _rom CoapClient::CoAP_StartNewGetObserveRequest_my(char* UriString, SocketHandle_t socketHandle, NetEp_t* ServerEp, CoAP_RespHandler_fn_t cb) {
CoAP_Message_t* pReqMsg = CoAP_CreateMessage(CON, REQ_GET, CoAP_GetNextMid(), NULL, 0, 0, CoAP_GenerateToken());
if (pReqMsg != NULL) {
CoAP_AppendUriOptionsFromString(&(pReqMsg->pOptionsList), UriString);
AddObserveOptionToMsg(pReqMsg, 0);
CoAP_blockwise_option_t blkOption;
blkOption.Type = BLOCK_2;
blkOption.BlockSize = BLOCK_SIZE_64;
blkOption.MoreFlag = 0;
blkOption.BlockNum = 0;
AddBlkOptionToMsg(pReqMsg, &blkOption);
return CoAP_StartNewClientInteraction(pReqMsg, socketHandle, ServerEp, cb);
}
INFO("- New GetRequest failed: Out of Memory\r\n");
return COAP_ERR_OUT_OF_MEMORY;
}
Confirmable messages that have an invalid token length (ie >8) do not respond with a valid message code. It's due to this error handling happening before message ID is stripped out of the header.
Header error handling should probably all be moved down to after header is decoded.
if (TokenLength > 8) {
INFO("CoAP-Parse Byte1 Error\r\n");
return COAP_PARSE_MESSAGE_FORMAT_ERROR;
} // return COAP_PARSE_MESSAGE_FORMAT_ERROR;
We are developing a little demo but lobarocoap can't parse a response with no options. it fails of the following code in /src/coap_options.c
if (srcArr[0] == OPTION_PAYLOAD_MARKER) {
INFO("- Options must not start with payload marker!\r\n");
return COAP_PARSE_MESSAGE_FORMAT_ERROR;
}
Other clients like libcoap or coapthon or java libraries have no problem with the packets. And i can't see anything in the rfc either.
O the contrary there is stated options (if any):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Ver| T | TKL | Code | Message ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Token (if any, TKL bytes) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| Payload (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 7: Message Format
Debug Output:
o<<<<<<<<<<<<<<<<<<<<<<
New Datagram received [7 Bytes], Interface #d
--------------->>> Sending Endpoint:
--------------->>> IPv4, 192.168.2.41:57095
--------------->>>
--------------->>> - Options must not start with payload marker!
--------------->>> CoAP-Parse Options Error
--------------->>> - (!) ERROR (!)
--------------->>> ParseResult:
--------------->>> COAP_PARSE_MESSAGE_FORMAT_ERROR
--------------->>> o<<<<<<<<<<<<<<<<<<<<<<
--------------->>>
--------------->>> Interactions: 1
--------------->>> -------------
--------------->>> - Role: CLIENT, State: WAITING_RESPONSE
--------------->>> RetransCnt: 0, SleepUntil 0, AckTimeout: 1516699926
Edit: No options not no headers
Any thoughts about supporting TCP framing described in rfc8323?
A challenge I feel from my experience of this library so far is that CoAP_onNewPacketHandler
expects an entire CoAP message, whereas a TCP being a stream, it may be needed to call CoAP_onNewPacketHandler
multiple times to incrementally process a message.
Tested the block coap "about/coap" resource, working as charm.
Is client part of block is implemented? reassembly of block payloads
at esp8266 client.
There are many linked lists in the code but all are custom made. Iterating always looks different. It would be nice to have a single heap based linked list where heap based elements can be inserted and removed. We actually have such an implementation in other projects. A first step would be to move it over to the codebase and use it in a second step.
Hello, I want to use this library on windows and I am facing an error which tells me "sched.h" doesn't exist.
I googled for this and I got that I have to use Linux but based on documentation this lib is introduced as independent from the platform which is processed on. am I missing something here?
I propose that CoAP_CreateResource(...)
(used to register resources) to have an additional opaque void* pUserData
parameter that will be included in CoAP_ResourceHandler_fPtr_t
and CoAP_ResourceNotifier_fPtr_t
. This would allow the application to register multiple resources and pass along identifying information in pUserData
to allow the apllication to quickly use without the need for a lookup table with the URI of the resource.
I'll be happy to create a PR if this idea is good. Unless another solution is preferred?
Use Case
I have a for loop that generates 100 resources, that each has small data associated with it. would be nice to pass a pointer to the data to CoAP_Res_t
(through CoAP_CreateResource
) that is then passed to a single resource handler for all 100 resources. to quickly access the requried data without needing to parse the resource URI and fetch the associated data.
I have observed that response message type set by handler is ignored and treated as CON.
To reproduce this issue:
In other words:
Expected:
client CON -> server
server ACK -> client
server NON-> client
Actual:
client CON -> server
server ACK -> client
server CON -> client
client ACK -> server
According to RFC 7252 :
5.2.2. Separate
(...)
When the server finally has obtained the resource representation, it
sends the response. When it is desired that this message is not
lost, it is sent as a Confirmable message from the server to the
client and answered by the client with an Acknowledgement, echoing
the new Message ID chosen by the server. (It may also be sent as a
Non-confirmable message; see Section 5.2.3.)
So application should be able to configure whether the response is CON or NON. I have digged into the lobaro coap lib and found out, that if request was CON and ACK has been sent, response is ALWAYS sent as CON (even if handler has changed it to the NON).
Code responsible for that:
//Set response TYPE correctly if CON request, regardless of what the handler did to this resp msg field, it can't know it better :-)
//on NON requests the handler can decide if use CON or NON in response (default is also using NON in response)
if (pIA->pReqMsg->Type == CON) {
if (pIA->ReqConfirmState ==
ACK_SEND) { //separate empty ACK has been sent before (piggyback-ack no more possible)
pIA->pRespMsg->Type = CON;
pIA->pRespMsg->MessageID = CoAP_GetNextMid(); //we must use/generate a new messageID;
} else
pIA->pRespMsg->Type = ACK; //"piggybacked ack"
}
So current implementation is not consistent with the RFC 7252.
I understand that it was done intentionally, but I believe that it is a bug,
Hi there,
When we call CoAP_CreateMessage(), we allocate some buffer for the message. After successfully allocating the buffer we check PayloadMaxSize and return null if exceeded. Should we free the buffer prior to returning or are we relying on the caller to clean up the buffer?
lobaro-coap/src/coap_message.c
Line 165 in 7f5fed4
Hello, I've been using Lobaro CoAP for a project im doing on the ESP8266. Normal responses work well and I'm now trying to get into separate responses. I am aware of the usage of the HANDLER_POSTPONE macro as a return for my request handler so that my CoAP server sends out an empty acknowledgement to the client, but my server doesnt send the test message after using a delay in my code (3 seconds delay). Can someone please explain to me how the handler for a separate response would look like with Lobaro CoAP? Thanks for your help.
Ameer
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.