Skip to content

Conversation

chrysn
Copy link
Member

@chrysn chrysn commented Jun 30, 2020

Contribution description

This is currently a first sketch to get separate responses working, and will be evolved along the outline of #14393 later on.

Right now it is just application code (doing things manually), and while most of the following work will be finding suitable helpers to make that cleaner, the two wrong parts here are:

  • The handler signature is abused to feed the request address to the handler through the data pointer.
  • The generated message ID is 4, while it should really be counted through.

Testing procedure

Run the gcoap example as a server. From a client, GET the /riot/board+block and /riot/board+nonblock resources. (For now, running this more than two times in a row will fill up the retransmission buffers; that can be mitigated by enhancements to #14178 later.)

From a second client, GET /riot/board while one of the long-running requests is pending and observe that while the nonblocking is being requested, that new request can still be served. Request nonblocking in the same situation to see that this application limits the concurrent blocking requests to 1 with a 5.03 response.

Issues/PRs references

Requires: #14178
Closes: #14393

chrysn added 6 commits May 30, 2020 15:56
This generalizes the existing code for answering CoAP pings into general
message-layer responses. Such responses are now also sent as a reaction
to CON responses, which can otherwise follow the same code path as
existing other responses.

As a side effect, issues that would crop up when responding to odd empty
requests that have token length set are resolved.

Contributes-To: RIOT-OS#14169
Simplify the code path and give consistent debug messages.
The actual implementation will follow in a separate commit, this does
the groundwork and sets the intention.
This introduces an additional state to the COAP_MEMO_* series to avoid
enlarging the memo struct needlessly. While they are documented
publicly, practically only the COAP_MEMO_TIMEOUT and COAP_MEMO_RESPONSE
are used in communication with the application, as a
gcoap_request_memo_t is only handed out in that state.
@chrysn chrysn marked this pull request as draft June 30, 2020 08:33
@chrysn chrysn self-assigned this Jun 30, 2020
@chrysn chrysn added Area: CoAP Area: Constrained Application Protocol implementations Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet labels Jun 30, 2020
@chrysn chrysn mentioned this pull request Jul 1, 2020
6 tasks
Copy link
Member

@cgundogan cgundogan left a comment

Choose a reason for hiding this comment

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

Just a few minor remarks, since this PR is still in draft state. Do you envision the current design choice (separate responses on application level) to be merged, or would you work on a tighter integration with gcoap?

Comment on lines +238 to +256
static ssize_t _riot_board_handler_blocking(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx)
{
(void)ctx;
gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
coap_opt_add_format(pdu, COAP_FORMAT_TEXT);
size_t resp_len = coap_opt_finish(pdu, COAP_OPT_FINISH_PAYLOAD);

xtimer_sleep(3);

/* write the RIOT board name in the response buffer */
if (pdu->payload_len >= strlen(RIOT_BOARD)) {
memcpy(pdu->payload, RIOT_BOARD, strlen(RIOT_BOARD));
return resp_len + strlen(RIOT_BOARD);
}
else {
puts("gcoap_cli: msg buffer too small");
return gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This code is almost identical to the handler in https://github.com/RIOT-OS/RIOT/pull/14395/files#diff-1ad46e1aa545fa54a91a5563e03a4ee8R220. The only addition is the sleep call .. can we deduplicate?

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably, yes -- but this now serves primarily for demonstration during development, we may want to have different examples anyway on the long run.

*/
pdu->hdr = (coap_hdr_t *)buf;

/* generate token */
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/* generate token */
/* generate message id */

?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes (but I'm not pulling it in yet as this is from copy-pasting, so there's another occurrence somewhere...)

pdu->hdr = (coap_hdr_t *)buf;

/* generate token */
uint16_t msgid = 4; /* FIXME determined by random dice roll as we can't access gcoap internals */
Copy link
Member

Choose a reason for hiding this comment

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

Would we need to expose the message id generation code in gcoap in order to fix this later? Then again, if we move the separate response generation into gcoap (if we decide to), then we do not need this line here anymore.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, and that's one of the open items. I don't expect gcoap to handle all of the separate response process as a framework, but we may instead of exposing the msgid-take-and-increment have a "prepare header with a new message ID"-ish function.

puts("gcoap_cli: msg buffer too small");
pdu->hdr->code = COAP_CODE_INTERNAL_SERVER_ERROR;
/* unwinding the TEXXT option*/
resp_len = resp_len - 1;
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, this is not very intuitive .. could you also add something along the lines:

/* ... unwinding the TEXT option added by coap_opt_finish(..., COAP_OPT_FINISH_PAYLOAD); ... */

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's even wrong; as opt_finish adds one byte payload marker and there's another something to unwind from the coap_opt_add_format, it's gotta be more.

The better thing to do would be to get (extract, or better add a function to expose) the length that coap_opt_finish(pdu, COAP_OPT_FINISH_NO_PAYLOAD) would return at the current stage of writing, and store that to roll back.

@chrysn
Copy link
Member Author

chrysn commented Oct 14, 2020

I think it's best if that stays an application choice. Those applications that take longer (than, say, a few milliseconds) to prepare their response need to hand off request processing to their own thread anyway, lest they block gcoap and thus any coap processing completely. (This is different from the large computer situation where the coap server would run on threads or async tasks, and messages would be processed concurrently with the handler). This is not ideal, but a consequence of how gcoap handles things. (Some automagic would make sense in a completely different CoAP server where requests are processed into IPC messages and handed to a thread that's not the server for processing, but gcoap is not such a server).

Co-authored-by: Cenk Gündoğan <mail+dev@gundogan.net>
@stale
Copy link

stale bot commented Jun 2, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Jun 2, 2021
@Jnae
Copy link
Contributor

Jnae commented Jun 8, 2021

Is this PR still active and if yes, what remains to be done? I would be interested in this feature.

@stale stale bot removed the State: stale State: The issue / PR has no activity for >185 days label Jun 8, 2021
@chrysn
Copy link
Member Author

chrysn commented Jun 8, 2021 via email

@Jnae
Copy link
Contributor

Jnae commented Jun 8, 2021

Great! I think I don't have a very good use case - a blocking call is fine, only an empty ACK needs to be sent before processing. (Before I saw the PR I had the idea that the ACK could be sent before the actual handler is already called, to take some work from the application and to make sure it is sent as soon as possible).

@chrysn
Copy link
Member Author

chrysn commented Jun 8, 2021 via email

@stale
Copy link

stale bot commented Mar 2, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Mar 2, 2022
@chrysn
Copy link
Member Author

chrysn commented Mar 2, 2022

Thanks for the reminder stalebot, I'll see when I can continue here.

@stale stale bot removed the State: stale State: The issue / PR has no activity for >185 days label Mar 2, 2022
@stale
Copy link

stale bot commented Sep 21, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@chrysn chrysn added State: don't stale State: Tell state-bot to ignore this issue and removed State: don't stale State: Tell state-bot to ignore this issue labels Sep 21, 2022
@chrysn
Copy link
Member Author

chrysn commented Sep 21, 2022

This will need porting to ztimer.

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 State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet 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.

Gcoap can not send separate responses
4 participants