net/gcoap: Make references to coap_resource_t all const in gcoap#7237
net/gcoap: Make references to coap_resource_t all const in gcoap#7237kb2ma merged 2 commits intoRIOT-OS:masterfrom
Conversation
|
@pekkanikander, thanks for the thoughtful and creative PR. It's really helpful to see how applications are using gcoap. In addition to this PR, I reviewed the PRs you created in the sock/nanocoap repository, #12 and #15. I also reviewed the application you are creating. I see two issues here -- further development of gcoap resource handling, and ensuring access to coap_resource_t is const. The second issue seems straightforward, and I think should be addressed in a separate PR. Read on for my thoughts on how to develop resource handling, and a potential implementation. Looking forward to further discussion. Resource handler developmentI see your PR developing the resource handler in two ways:
On the first point, I agree with your discussion with @kaspar030 of 'prefix handlers', where the last segment in a URL is considered a wildcard. gcoap's request handler would match on the prefix, and the final, differentiating segment would be available at runtime. The handler function then could adapt its response internally. I think this approach provides nice advantages:
Given the usefulness of prefix handlers, do we also really need to add data to the resource struct and pass the struct to the handler? I recommend we implement prefix handlers and see if there is a case for additional data. If there is such a case, I would advocate for making that data explicit in the coap_resource_t, maybe as a union of a void* and an int. I also would make the resource available to the handler explicitly as an attribute of the passed coap_pkt_t. Prefix handler implementationBelow is an outline for implementation of prefix handlers. (1). Identify a resource with a wildcard segment Use an asterisk in the resource definition to indicate a final wildcard segment, like:
As you say in nanocoap #12, this idea could be extended so a search for a path with a specific final segment would be preferred. In other words, there could be two resources, with paths like: The second resource is preferred when exactly matching that URL. In any case, gcoap's (2). Add a function in nanocoap for the handler to retrieve the differentiating segment of the request url, like:
where the segment parameter is the address of a char* variable from the sender, and the return value is the length of the segment. This function uses the coap_pkt_t url attribute parsed out of the incoming request buffer. (3). Store the differentiating segment/parameter in an observe request. We can add an attribute to gcoap_observe_memo_t, with a macro for the maximum length of the segment to store, like:
The value would be populated when the resource for the observe request includes a wildcard. |
|
@pekkanikander @kb2ma how do we proceed here: continue? close? have someone to take this work up? |
|
What is the current status of the nanocoap and g_coap rewrite? Sorry that I haven't been following. If that is stable now and committed, I could have another look at this and rewrite. |
|
AFAIK a lot of bugfixing and rework is going on. @kb2ma can explain better. |
|
#8513 added an opaque pointer attribute to the resource, and this pointer is available as a parameter to the handler function. Does that cover what is requested here? |
|
@tcschmidt @kb2ma I'm planning to have a look at this on the forthcoming week. |
f126bd9 to
558f411
Compare
coap_resource_t all const in gcoap
coap_resource_t all const in gcoap|
I checked this. This now boils down to simply making the |
|
Glad to hear we're almost there. I'll give it a try. |
kb2ma
left a comment
There was a problem hiding this comment.
This change tests OK for me. I agree that gcoap has no need to modify the resources, so it makes sense to announce that programmatically. As you say, it is likely that the resource is defined as const by the calling application in the first place. Also, this PR doesn't break existing applications. Nice commit comment!
I have one request concerning integration with uses of gcoap in the repository. Please add a commit to remove casts to coap_resource_t* when initializing the listener, as you did for the gcoap _default_listener. I see these in the gcoap CLI example, the rdcli_simple example, and in the gcoap unit tests.
A CoAP resource is a primary object between the application
and CoAP library. The Library needs the paths, methods,
and handlers from it, so that it can call the right handler.
However, it never needs to change any of them.
The application also needs the resources. The application
may want to declare the resources as const, since it may
want to store them in flash.
558f411 to
33c8459
Compare
|
@kb2ma Removed the type casts as you requested. Also rebased. |
|
Thanks for seeing this through, @pekkanikander. Looks good to me. |
The
coap_resource_tdata structures are a major interface between the application using CoAP and the CoAP library. The application defines the resources, and the library uses arrays of resources to find the right resource and call its handler. (At this point that takes place only for handling requests, but in the future we will try to extend this also to CoAP observe notifications.) However, it is useful if the application can extend thecoap_resource_tdata structure with extra, application specific information.Prior to 95543a3, extending the
coap_resource_tdata structures would have required to create a separate data structure for each resource. Commit 95543a3 adds an layer of indirection, where the application constructs arrays of pointers tocoap_resource_tdata structures instead of having mere arrays ofcoap_resource_t. This allows each of thecoap_resource_tstructs to be of any size, allowing the application to add more information into the structs.Commit f126bd9 is a separate but related. It simply changes all
coap_resource_tpointers within the library to point toconststructs. That allows the application to store the resources either in flash or SRAM, as it desires, without needing to use type casts.