Skip to content

net/gcoap: Make references to coap_resource_t all const in gcoap#7237

Merged
kb2ma merged 2 commits intoRIOT-OS:masterfrom
Ell-i:feature-gcoap-extra-indirection
Aug 8, 2018
Merged

net/gcoap: Make references to coap_resource_t all const in gcoap#7237
kb2ma merged 2 commits intoRIOT-OS:masterfrom
Ell-i:feature-gcoap-extra-indirection

Conversation

@pekkanikander
Copy link
Copy Markdown
Contributor

@pekkanikander pekkanikander commented Jun 25, 2017

The coap_resource_t data 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 the coap_resource_t data structure with extra, application specific information.

Prior to 95543a3, extending the coap_resource_t data 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 to coap_resource_t data structures instead of having mere arrays of coap_resource_t. This allows each of the coap_resource_t structs 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_t pointers within the library to point to const structs. That allows the application to store the resources either in flash or SRAM, as it desires, without needing to use type casts.

@pekkanikander pekkanikander changed the title Make coap_resource_t handling more flexible net/coap: make coap_resource_t handling more flexible Jun 25, 2017
@miri64 miri64 requested a review from kb2ma June 25, 2017 11:47
@miri64 miri64 added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: network Area: Networking labels Jun 25, 2017
@aabadie aabadie modified the milestone: Release 2017.07 Jun 26, 2017
@kb2ma
Copy link
Copy Markdown
Member

kb2ma commented Jun 29, 2017

@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 development

I see your PR developing the resource handler in two ways:

  1. Map multiple parameterized paths to a single resource handler. Your example includes resources with final segments like A1, A2, A3, etc., which all use the same handler function.

  2. Extend the resource type with resource-specific data, which is matched to the parameterized path and passed to the handler function. This data is passed by including the resource struct as a parameter to the function via the pointer-to-resource-pointer.

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:

  1. Compresses the definition of resources down to a single entry to match a single resource handler function.

  2. Localizes parsing/handling of the incoming path. First the prefix is matched in the generic _handle_req() and _find_resource() functions. Then the final, parameterized segment of the path is mapped in the handler function.

  3. The previous advantage reduces the need to extend the resource type with the parameter-specific data. The handler function can look up or otherwise provide the parameter-specific data without the need to define it in the resource struct.

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 implementation

Below 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:

/foo/*

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:

/foo/*
/foo/bar

The second resource is preferred when exactly matching that URL. In any case, gcoap's _find_resource() function would be updated for wildcard handling.

(2). Add a function in nanocoap for the handler to retrieve the differentiating segment of the request url, like:

ssize_t coap_get_url_segment(coap_pkt_t *pdu, unsigned index, char **segment)

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:

char url_param_segment[GCOAP_PARAM_SEGMENT_MAXLEN];

The value would be populated when the resource for the observe request includes a wildcard.

@tcschmidt
Copy link
Copy Markdown
Member

@pekkanikander @kb2ma how do we proceed here: continue? close? have someone to take this work up?

@pekkanikander
Copy link
Copy Markdown
Contributor Author

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.

@tcschmidt
Copy link
Copy Markdown
Member

AFAIK a lot of bugfixing and rework is going on. @kb2ma can explain better.

@kb2ma
Copy link
Copy Markdown
Member

kb2ma commented Jun 22, 2018

#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?

@pekkanikander
Copy link
Copy Markdown
Contributor Author

@tcschmidt @kb2ma I'm planning to have a look at this on the forthcoming week.

@pekkanikander pekkanikander force-pushed the feature-gcoap-extra-indirection branch from f126bd9 to 558f411 Compare July 8, 2018 18:25
@pekkanikander pekkanikander changed the title net/coap: make coap_resource_t handling more flexible net/gcoap: @pekkanikander Make references to coap_resource_t all const in gcoap Jul 8, 2018
@pekkanikander pekkanikander changed the title net/gcoap: @pekkanikander Make references to coap_resource_t all const in gcoap net/gcoap: Make references to coap_resource_t all const in gcoap Jul 8, 2018
@pekkanikander
Copy link
Copy Markdown
Contributor Author

I checked this. This now boils down to simply making the coap_resource_t references to const. This is now updated to master and seems to compile. However, I haven't done any extensive testing beyond compiling.

@kb2ma
Copy link
Copy Markdown
Member

kb2ma commented Jul 9, 2018

Glad to hear we're almost there. I'll give it a try.

Copy link
Copy Markdown
Member

@kb2ma kb2ma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@pekkanikander pekkanikander force-pushed the feature-gcoap-extra-indirection branch from 558f411 to 33c8459 Compare July 30, 2018 06:02
@pekkanikander
Copy link
Copy Markdown
Contributor Author

@kb2ma Removed the type casts as you requested. Also rebased.

@kb2ma kb2ma added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Aug 8, 2018
@kb2ma
Copy link
Copy Markdown
Member

kb2ma commented Aug 8, 2018

Thanks for seeing this through, @pekkanikander. Looks good to me.

@kb2ma kb2ma merged commit 3f3df74 into RIOT-OS:master Aug 8, 2018
@jia200x jia200x added this to the Release 2018.10 milestone Oct 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants