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

Completing CoAP Block implementation #10732

Closed
6 tasks done
kb2ma opened this issue Jan 8, 2019 · 5 comments
Closed
6 tasks done

Completing CoAP Block implementation #10732

kb2ma opened this issue Jan 8, 2019 · 5 comments
Assignees
Labels
Area: CoAP Area: Constrained Application Protocol implementations Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Comments

@kb2ma
Copy link
Member

kb2ma commented Jan 8, 2019

Presently, nanocoap 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 Packet Write API as described in #9309 to make the block implementation available to gcoap as well. So, this document describes 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 tasks to implement this goal.

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 with the Buffer API, and we wish to add a client POST/PUT request for block1. See block_post_cmd() in block_client.c for an example that now implements the sequence described here for block1.

To begin a block2 server response, we 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, we still need to init the slicer struct with the block size, so the client uses the new function, client_block_slicer_init(). The client likely reuses this call with each block to increment the block number to send. The block option in the previous response is not required to generate the next request.

Below are the remaining API calls. We need to implement coap_opt_put_block() for block1, and coap_opt_add_block() for block1 and block2.

Task Buffer API Packet 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) coap_blockwise_put_(bytes|char)
finalize option (more blocks?) coap_block_finish() coap_block_finish()

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

See block_get_cmd() in block_client.c for an example that now implements this description for the Buffer API.

A client may write a block2 option in the request to request blockwise responses. We use the new coap_block_object_init() function to initialize a coap_block1_t struct for this option. The client then likely retrieves the block option in responses, and increments the block number to request the next block. 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 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 test app to POST /sha256 to nanocoap_server. It uses coap_opt_put_block1(). Create test app to GET /riot/ver from nanocoap_server. It uses coap_opt_put_block2_control().

  • 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 a second gcoap test app to use coap_opt_add_block1() and coap_opt_add_block2_control().

@kb2ma kb2ma added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: CoAP Area: Constrained Application Protocol implementations labels Jan 8, 2019
@kb2ma kb2ma self-assigned this Jan 8, 2019
@kb2ma
Copy link
Member Author

kb2ma commented Feb 15, 2019

@kaspar030, @bergzand, @haukepetersen, @smlng, @aabadie:

I just posted #11024, which completes the block implementation for the Buffer API. I would appreciate your help with reviews for the sequence of PRs below. The marked checkboxes in the description for this issue reflect this work. I would love to merge these in time for IETF 104 towards the end of March.

@kb2ma
Copy link
Member Author

kb2ma commented Feb 24, 2019

Added two more PRs to complete this issue:

@kb2ma
Copy link
Member Author

kb2ma commented Jul 3, 2019

Suggestions to @fjmolinas or whoever reviews the remaining PRs:

  • Read through the PR descriptions to get an overview of the sequence. Check out the example apps and documentation mentioned there.
  • Checkout the branch in the last PR, net/coap: Block optimizations #11057, to understand how the implementations ultimately work. There were optimizations in that PR that change some internals. No sense in getting hung up on intermediate work in earlier PRs.

Thanks for taking the time!

@benpicco
Copy link
Contributor

Since all PRs have been merged now, can this issue be closed?

@kb2ma
Copy link
Member Author

kb2ma commented Nov 17, 2019

Closing, but added some notes to nanocoap roadmap about deprecation of obsolete blockwise API functions and struct name.

@kb2ma kb2ma closed this as completed Nov 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: CoAP Area: Constrained Application Protocol implementations Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

No branches or pull requests

2 participants