Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcoap: rebase networking on sock #6117

Merged
merged 5 commits into from
Jan 21, 2017
Merged

gcoap: rebase networking on sock #6117

merged 5 commits into from
Jan 21, 2017

Conversation

kb2ma
Copy link
Member

@kb2ma kb2ma commented Nov 14, 2016

gcoap has been based on the GNRC stack, but sock is the preferred, stack-agnostic API for applications. This PR updates gcoap to use it.

Highlights:

  • Modified gcoap.c _event_loop() to create a remote-less sock. Listen on this sock indefinitely if not expecting a response. Otherwise, periodically poll for an IPC msg to timeout waiting for a response. I left a debug message in _listen() for now to make it easy to see when sock_udp_recv() is called.
  • To send a message, use the new gcoap_req_send2(), with the sock remote endpoint parameter. Post a msg to the sock mbox to interrupt listening, to set the response timeout. gcoap_req_send() now is deprecated, and simply creates the sock endpoint from the provided address and port, and forwards to gcoap_req_send2().
  • Moved gcoap.c to sys/net. Moved and renamed coap.h to net/application_layer/coap/gcoap.h. Kept net/gnrc/application_layer/coap/coap.h as a shim that references the new header file. I need to mark it as deprecated though.

Let me know if there is a better way to reach the goal. Otherwise, it needs a little polishing and documentation update. I also need to figure out what the 'g' in gcoap stands for now. :-)

Thanks to @miri64 for the reference in the code docs to her thesis and defense slides. They helped a lot to understand the networking stack rationale.

@miri64 miri64 added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation GNRC Area: network Area: Networking State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet labels Nov 17, 2016
@miri64 miri64 self-assigned this Nov 17, 2016
@miri64 miri64 added this to the Release 2017.01 milestone Nov 17, 2016
@miri64
Copy link
Member

miri64 commented Nov 17, 2016

I probably can find this out reading the code, but can you also highlight how this approach now differs from using pure nanocoap+sock? AFAIK it also brings client and server functionalities with it, so what does this implementation now bring that the other solution does not.

@kb2ma
Copy link
Member Author

kb2ma commented Nov 17, 2016

Rebased and compressed commits. Updated the overview documentation to focus on gcoap features .

For reviewers, the core changes are in commit eb6b87e. You'll see the documentation updates in gcoap.h, and the implementation changes in gcoap.c.

Thanks for asking about gcoap vs. nanocoap. This is similar to the issue #6038 that @cgundogan raised about the number of CoAP examples. So, maybe we can reuse this response there. @kaspar030, please jump in if I have described nanocoap incorrectly. I'm just trying to provide a clear comparison. :-)

The description below is copied from the gcoap Status page. It's kind of long -- focus on the bullets if it's too much.

Features

In general, gcoap provides a higher-level interface to CoAP than nanocoap. The main differences are gcoap's single CoAP messaging hub approach, and also a consistent, well-documented API for client requests and server responses.

Single CoAP messaging hub:

  1. For server use, allows an external module/application to register handlers for an array of incoming request paths.
  2. For client use, supports waiting for a response to multiple outstanding requests.
  3. Runs in a dedicated thread and supports non-blocking timeout handling for a request. A single instance handles both server and client use.
  4. In effect, provides a single listening port, which supports RFC 6282 UDP port compression.

In other words, gcoap provides a single, reusable access point for CoAP messaging. On the server side, I was inspired by the Python microframeworks like Bottle or Flask. gcoap provides gcoap_register_listener() for an application to register resources. In contrast, as a server nanocoap appears to be designed for a server per application. All resource callbacks must be specified within a single const array in the nanocoap_server example in RIOT. On the client side, gcoap tracks a configurable number of open requests in an array. In contrast, nanocoap is focused on handling one request at a time in the nanocoap_get() function in nanocoap_sock.c.

gcoap's timeout capability for a client request provides for lightweight confirmable messaging without specifically supporting the CON message type yet. nanocoap already provides CON messaging.

Simple high-level API

  1. A simple, no-payload request/response is a single function call.
  2. A payload-based request/response includes an ...init(), write the payload, and ...finish().
  3. Consistent API between request and response.
  4. User is never expected to write a CoAP option, at the cost of an extra memmove().

The contrast between gcoap and nanocoap APIs is not that great. However, gcoap is well-documented in the RIOT Modules>Networking>CoAP source documentation (moved there in this PR). nanocoap recently added a coap_reply_simple(), which also writes the content format option.

@kaspar030
Copy link
Contributor

please jump in if I have described nanocoap incorrectly. I'm just trying
to provide a clear comparison. :-)

You summed it up pretty well. ;)

I designed nanocoap to be pretty minimal. So it'll never have any
register methods like gcoap has.

My plans for the future of nanocoap are (so far):

  • add blockwise transfers
  • add a more generic client request function (allow POST/PUT/DELETE/...,
    implement non-piggybacked ACK/data, ...)
  • implement OBSERVE for both client and server
  • allow one handler entry to handle a whole subtree (e.g., /saul/*)
  • allow more than one server context
  • obviously, support DTLS

@kb2ma kb2ma mentioned this pull request Nov 29, 2016
@kb2ma kb2ma changed the title gcoap: WIP rebase networking on sock gcoap: rebase networking on sock Dec 5, 2016
@kb2ma
Copy link
Member Author

kb2ma commented Dec 5, 2016

I refined the introductory documentation in gcoap.h, squashed, and rebased. I also have been testing the implementation, and it works as expected. I think it's ready to merge, so I removed the WIP in the title. Please remove that label, too.

@kb2ma
Copy link
Member Author

kb2ma commented Dec 15, 2016

@miri64, is there an issue blocking merge of this PR? FWIW, I created some functional tests with Pexpect to convince myself that gcoap works with ongoing client and server exchanges.

@miri64
Copy link
Member

miri64 commented Dec 15, 2016

@miri64, is there an issue blocking merge of this PR?

At the moment just time to review it. Will try to find some.

* @return < 0 on error
*/
int gcoap_req_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code,
char *path);
Copy link
Member

Choose a reason for hiding this comment

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

Here and below: I don't understand your indentation pattern. But since we seem to have no convention about this, I'm fine in general

Copy link
Member Author

@kb2ma kb2ma Jan 10, 2017

Choose a reason for hiding this comment

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

The main goal is readability. If the declaration extends beyond approx. 80 chars, I right-align the following parameters below the last one on the first line. I think this block-like look is easier to read than wrapping the following parameters starting under the first parameter on the first line.

#ifdef __cplusplus
}
#endif
#include "net/gcoap.h"
Copy link
Member

Choose a reason for hiding this comment

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

Is this file still required? I would completely remove it.

Copy link
Member Author

@kb2ma kb2ma Jan 10, 2017

Choose a reason for hiding this comment

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

No, coap.h is not required any longer -- it's only there for backwards compatibility. I didn't want to break code for existing users out of the box. I included a 'deprecated' comment above, but I'm happy to remove the file. I don't expect that there are hordes of gcoap users, but is there a policy on when to deprecate?

FWIW, for the same reason I also retained gcoap_req_send(), which uses an ipv6_addr_t and an int port for the destination. I created gcoap_req_send2(), which uses a sock_udp_ep_t. Let me know if I should make any changes there.

@kb2ma kb2ma force-pushed the gcoap/sock branch 2 times, most recently from fe53fd2 to ef2d660 Compare January 15, 2017 22:14
@kb2ma
Copy link
Member Author

kb2ma commented Jan 15, 2017

@miri64, I removed net/gnrc/coap.h in commit ef2d660. I'm glad you brought up this subject. You'll see in that commit that I also changed several #include's that referenced the old header file. I should have done that with the original commits.

I also would appreciate any insights on deprecation policy, as I mentioned above in my inline responses to your review. Maybe it would be a better question for the riot-devel list.

@miri64
Copy link
Member

miri64 commented Jan 16, 2017

Still WIP? Otherwise, I'm fine with the code and want to test sometime this week (most likely at the interim H&A on Wednesday).

@kb2ma
Copy link
Member Author

kb2ma commented Jan 16, 2017

Glad to hear it! No longer WIP, as mentioned above. I'll keep in mind that you might be testing Wednesday so I can respond quickly if questions arise.

@miri64 miri64 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet labels Jan 16, 2017
@PeterKietzmann
Copy link
Member

@miri64 any news?

@miri64
Copy link
Member

miri64 commented Jan 20, 2017

@miri64 any news?

Sorry, didn't think about testing this at H'n'A. Will do, but needs rebase ;-)

Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

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

I was able to send GET requests and receive replies from another examples/gcoap application. Since this only changes how gcoap accesses GNRC this is sufficient enough for me

@kb2ma
Copy link
Member Author

kb2ma commented Jan 20, 2017

Excellent! In a few hours I will rebase and verify all is well. Unless I hear otherwise, I do not plan to squash the latest commit, which removes the obsolete coap.h include file. Leaving this commit will help make the change explicit to any current gcoap users.

@kb2ma
Copy link
Member Author

kb2ma commented Jan 21, 2017

Murdock and CI are happy now. Rebased, fixed and squashed a few issues:

@miri64
Copy link
Member

miri64 commented Jan 21, 2017

and go

@miri64 miri64 merged commit 85d8397 into RIOT-OS:master Jan 21, 2017
@kb2ma kb2ma deleted the gcoap/sock branch February 4, 2019 17:05
@danpetry danpetry modified the milestone: Release 2019.04 Mar 12, 2019
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.

5 participants