[riot-notifications] [RIOT-OS/RIOT] Completing CoAP Block implementation (#10732)

Ken Bannister notifications at github.com
Tue Jan 8 12:41:25 CET 2019

Presently, RIOT includes server side implementations of block1 and block2. We would like to add client side implementations. At the same time, we are working to complete the struct-based API as described in #9309. So, this document documents how we plan to integrate the client side implementations, including the function names. We break down the approach based on how the option is used -- read or write; and within write, for descriptive or control use.

In this document, _descriptive_ and _control_ are used as described in section 2.1 of RFC 7959:

    Where Block1 is present in a request or Block2 in a response (i.e.,
    in that message to the payload of which it pertains) it indicates a
    block-wise transfer and describes how this specific block-wise
    payload forms part of the entire body being transferred ("descriptive
    usage").  Where it is present in the opposite direction, it provides
    additional control on how that payload will be formed or was
    processed ("control usage").

Finally, the _Implementation Steps_ section describes the sequence of PRs to implement this goal. See the project page for status.

# Write Option for Descriptive Use 
In this scenario, we slice up some large content into smaller blocks and send it to the remote endpoint. We have implemented a server GET response for block2, and we wish to add a client POST/PUT request for block1.

For a block2 server response, use coap_block2_init() to read the block option in the request. No new functions needed here. This function initializes the slicer struct from the block2 option in the request.

For a block1 client request, the slicer struct for the initial request is zeroed by the client, and it is up to the client to remember the next block to request. The client may reuse the same slicer struct or create a new one with each request. However, the block option in the previous response is not required to generate the next request.

| Task | Buffer Put API | Option Add API |
| ---- | ---------------- | ---------------- |
| write option | coap_opt_put_block() | coap_opt_add_block() |
| finish options | write 0xff | coap_opt_finish() |
| write payload slice | coap_blockwise_put_(bytes\|char) | -same- |
| finalize option (more blocks?) | coap_block_finish() | -same- |

# Write Option for Control Use

## Block1 response
A server must write a block option in the response to a block1 request. The response does not include a blockwise payload, although the response to the final request may contain a payload for the overall response to the sequence. For example, `/sha256` resource in the nanocoap_server example returns the digest in the final response.

In this scenario, the application will not have a slicer struct. Instead, the server simply will take the option from the request and put it in the response. The server may request smaller blocks from the client. Create coap_opt_put_block_control() and coap_opt_add_block_control().

## Block2 request
A client must write a block2 option in the request to receive a particular block. The client initializes this option for the first request. The client likely retrieves the block option in responses, and increments the offset to request the next block. As with a Block1 response, the client uses a coap_block1_t, not a slicer struct. The client also can use the new coap_opt_put_block_control() and coap_opt_add_block_control().

# Read Option
For either block1 or block2, client or server, the user simply wants to retrieve the block into a coap_block1_t struct. Note we need to rework so the existing coap_get_block1() and coap_get_block2() to be inline. They simply return the value of a new coap_get_block() function as currently implemented in coap_get_block1().

# Implementation Steps
Each item below is a task, which will be grouped into PRs.

- [ ] Add coap_opt_put_block(). coap_opt_put_block2() already exists.

- [ ] Add coap_opt_put_block_control(). Change _sha256_handler() to use coap_opt_put_block1_control() instead of coap_put_block1_ok(), which has a bug. Also deprecate coap_put_block1_ok() and coap_put_block1().

- [ ] Create coap_opt_add_block(). Condense _slicer...() functions into _slicer2optval(). Use this new function in coap_opt_put_block() and coap_opt_add_block(). Create gcoap test app for /sha256 server.

- [ ] Create coap_opt_add_block_control(). Create gcoap_test_app for /riot/ver server.

- [ ] Create test app to POST /sha256. It uses coap_opt_put_block1(). Test against existing /sha256 handler. Create a second gcoap test app to use coap_opt_add_block1().

- [ ] Create test app to GET /.well-known/core. It uses coap_opt_put_block2_control(). Test against existing /.well-known/core. Create a second gcoap test app to use coap_opt_add_block2_control().

You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20190108/113dbde1/attachment.html>

More information about the notifications mailing list