[riot-notifications] [RIOT-OS/RIOT] net/gcoap: add context struct for request handler (#13819)

Hauke Petersen notifications at github.com
Wed May 20 16:16:36 CEST 2020


Yapp, a more comprehensive solution is always most welcome - I kind of hate you for going this path :-) But seriously, I agree that we can probably do better here if we think about this some more.

So when I understand #13942 correctly, the `slicer` struct is used when sending out data, correct? And the `gcoap_req_ctx_t` struct is used when handling incoming CoAP packets. So I take it, that all/most? of the additional fields are valid in one or the other direction?! Maybe we can decouple `nanocoap` and `gcoap` by doing the following:
- in `nanocoap`: add an additional, generic `void *` pointer to `coap_pkt_t`, possibly '#ifdef'd for `gcoap` and potentially other high-level 'users' of nanocoaop. Let's call it `ext` for now
- in `gcoap`: add three separate structs:
  1. one for holding data that is of interested for incoming packets, e.g. the remote endpoint, a pointer to the ressource itself, etc (like `gcoap_req_ctx_t` in this PR). Also the `observe_value` that is now part of `coap_pkt_t` could be a candidate field for this.
  2. one for holding data that is useful when preparing data that is send (`gcoap_tx_txt_t`?). This struct could hold context data for preparing packets that are to be send, e.g. a reference to the `slicer` struct?
  3. one to rule them all, ähm, one to tie them together, e.g. `gcoap_ctx_t`. This struct holds a union that opts for one of the two structs above, and in addition it could have a bitmap style field so that the implementation can check at runtime which of the contexts is active.

All of these three structs can be extended at anytime, without any API braking, right? Also, any changes in these structs do not require any changes to `nanocoap` (`coap_pkt_t`) anymore, subsequently decoupling `nanocoap` and `gcoap` better. 

Furthermore there is no (or at least less) wasted memory for fields that have only validity in send/receive direction.

In terms of usability, we might then also provide some kind of user facing functions that accesses the given context. E.g. in a ressource handler implementation, instead of using something like
```c
ssize_t _some_ressource_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
 {
    // try to get the remote endpoint
    sock_udp_ep_t *ep = pkt->ext->req_ctx->remote;
....
}
```
we might want to do something like
```c
ssize_t _some_ressource_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
 {
    // try to get the remote endpoint
    gcoap_req_ctx_t *rc = gcoap_get_req_ctx(pkt);   // -> this would return NULL if called from the wrong context...
    sock_udp_ep_t *ep = rc->remote;
....
}
```

Does this make sense? And did I miss something here? Looking forward to advancing on this!


-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/13819#issuecomment-631501369
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20200520/c13ee71f/attachment.htm>


More information about the notifications mailing list