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/fileserver: add event callbacks #18414

Merged
merged 2 commits into from
Jan 17, 2023

Conversation

benpicco
Copy link
Contributor

@benpicco benpicco commented Aug 8, 2022

Contribution description

When serving updates via GCoAP fileserver it turned out to be useful to know if a node started downloading the update and when it finished doing so.

But there are probably more use cases where some action might be taken or logged based on the events on the GCoAP fileserver.

This adds 5 event types:

  • GCOAP_FILESERVER_GET_START: file download started (block 0 requested)
  • GCOAP_FILESERVER_GET_END: file download finished (last block requested)
  • GCOAP_FILESERVER_PUT_START:file upload started (block 0 uploaded)
  • GCOAP_FILESERVER_PUT_END: file upload finished (last block uploaded)
  • GCOAP_FILESERVER_DELETE:file deletion requested

Testing procedure

To be a able to test this, the new callback module is enabled for examples/gcoap_fileserver to log file events:

> ls /nvm0
./
../
LICENSE	24310 B
hello.txt	15 B
main.c	27 B
total 3 files
          
> gcoap fileserver: Download started: /nvm0/hello.txt
gcoap fileserver: Download finished: /nvm0/hello.txt
aiocoap-client coap://[fe80::748f:e6ff:fed7:426d%tapbr0]/vfs/hello.txt

Issues/PRs references

@github-actions github-actions bot added Area: build system Area: Build system Area: CoAP Area: Constrained Application Protocol implementations Area: examples Area: Example Applications Area: network Area: Networking Area: sys Area: System labels Aug 8, 2022
@chrysn
Copy link
Member

chrysn commented Aug 8, 2022

Just to get the architectural review side out -- making sure more generally useful alternatives have been considered:

  • This would hook into the specific interface between CoAP and the file service. Might it not make more sense to monitor things on the file system side, or on the CoAP side? (on the file system side it might behave like inotify, on the CoAP side like log hooks).

  • What are use cases and possible extensions of this? (An extension I could envision is that at some point one might need to know who sent the request, and thus extend gcoap_fileserver_event_ctx_t, so maybe that should be private).

On use cases, note that CoAP GET is supposed to be side effect free; now we don't, can't and won't generally enforce this in RIOT, but reacting to a GET event in any other facility than logging (at which point I'd go back whether this might not be just for logging generic CoAP requests or file system access) sounds like an invitation to do side effects, and might need a warning.

@benpicco
Copy link
Contributor Author

benpicco commented Aug 8, 2022

My use case is: I have multiple sensors that I want to update, since communication happens over a bus I want to update one sensor at a time to avoid contention. (The sensor network might also only be turned on for the updates when it's otherwise in an OFF state. So I want to know when all sensors have received the update to return to the original state again)

Updates are sometimes unreliable, especially with the old firmware revision. So I want to know: Was the manifest accepted (GCOAP_FILESERVER_GET_START on the ".bin" file) and finally: Did the update download successfully (GCOAP_FILESERVER_GET_END on the ".bin" file).

You are right that it would probably be better to use a second channel to communicate those events (e.g. the sensors would send them explicitly). But that won't help with sensors already deployed that don't send those yet to be implemented status messages - so server side events were an easy solution to this problem.

If more context information is required for other use cases, gcoap_fileserver_event_ctx_t can be extended without changing the API.

@benpicco benpicco requested a review from fjmolinas August 8, 2022 12:36
@fabian18
Copy link
Contributor

fabian18 commented Aug 8, 2022

The first thing I asked myself, was whether _event_cb and _event_ctx should be protected in some way by a mutex or atomic accesses because they are static variables and are read in the gcoap thread and can be written by any other thread using gcoap_fileserver_set_event_cb(), or if we just assume that they are set once, before requests are being processed.
But if they are set once, we could as well make _event_cb a classic __attribute__((weak)) hook and _event_ctx an extern variable, I guess. Any opinions on that?

@benpicco
Copy link
Contributor Author

I realized that I want to unsubscribe from those events, so I'll go with the mutex.

@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Oct 17, 2022
@benpicco benpicco removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Oct 18, 2022
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Nov 11, 2022
Copy link
Contributor

@fabian18 fabian18 left a comment

Choose a reason for hiding this comment

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

Works well with files.

2022-11-13 11:36:44,921 # gcoap fileserver: Upload started: /nvm0/send/ta/ca_anchor.der
2022-11-13 11:36:50,935 # gcoap fileserver: Upload finished: /nvm0/send/ta/ca_anchor.der
2022-11-13 11:36:50,977 # gcoap fileserver: Upload started: /nvm0/send/cp/self.der
2022-11-13 11:36:56,006 # gcoap fileserver: Upload finished: /nvm0/send/cp/self.der
2022-11-13 11:36:56,064 # gcoap fileserver: Upload started: /nvm0/send/key/pubkey.der
2022-11-13 11:36:57,292 # gcoap fileserver: Upload finished: /nvm0/send/key/pubkey.der
2022-11-13 11:36:57,348 # gcoap fileserver: Upload started: /nvm0/send/key/key.der
2022-11-13 11:36:58,986 # gcoap fileserver: Upload finished: /nvm0/send/key/key.der
2022-11-13 11:56:30,376 # gcoap fileserver: Download started: /nvm0/send/key/key.der
2022-11-13 11:56:30,476 # gcoap fileserver: Download finished: /nvm0/send/key/key.der
2022-11-13 11:57:14,149 # gcoap fileserver: Delete /nvm0/send/key/key.der
2022-11-13 11:59:07,298 # gcoap fileserver: Upload started: /nvm0/send/ta/ca_anchor.der
2022-11-13 11:59:13,227 # gcoap fileserver: Upload finished: /nvm0/send/ta/ca_anchor.der
2022-11-13 11:59:13,271 # gcoap fileserver: Upload started: /nvm0/send/cp/self.der
2022-11-13 11:59:18,292 # gcoap fileserver: Upload finished: /nvm0/send/cp/self.der
2022-11-13 11:59:18,348 # gcoap fileserver: Upload started: /nvm0/send/key/pubkey.der
2022-11-13 11:59:19,186 # gcoap fileserver: Upload finished: /nvm0/send/key/pubkey.der
2022-11-13 11:59:19,238 # gcoap fileserver: Upload started: /nvm0/send/key/.key.der
2022-11-13 11:59:20,934 # gcoap fileserver: Upload finished: /nvm0/send/key/.key.der

Someone might be wondering why it is only implemented for files?

sys/net/application_layer/gcoap/fileserver.c Show resolved Hide resolved
@benpicco
Copy link
Contributor Author

Someone might be wondering why it is only implemented for files?

I didn't see the need for it yet - should I add it anyway?

Copy link
Contributor

@fabian18 fabian18 left a comment

Choose a reason for hiding this comment

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

If there is no need for directory callbacks right now, I´d say keep it like that.
To reflect that and for extensibility, you could maybe rename some fields, if you agree.
And maybe adapt some comments here and there.

sys/include/net/gcoap/fileserver.h Outdated Show resolved Hide resolved
sys/include/net/gcoap/fileserver.h Outdated Show resolved Hide resolved
@benpicco benpicco removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jan 15, 2023
@fabian18
Copy link
Contributor

The msg_bus module just came to my mind. Have you considered this as an alternative to callbacks, since you already said that you would like to be able to "unsubscribe"? This may also be done in the future I guess.

@benpicco
Copy link
Contributor Author

This could be implemented on top, but I'd like to avoid IPC if not necessary.

@fabian18
Copy link
Contributor

Ok please squash.

@benpicco benpicco added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Jan 16, 2023
@benpicco
Copy link
Contributor Author

bors merge

@bors
Copy link
Contributor

bors bot commented Jan 17, 2023

Build succeeded:

@bors bors bot merged commit d6f44f6 into RIOT-OS:master Jan 17, 2023
@benpicco benpicco deleted the gcoap_fileserver-callback branch January 17, 2023 01:30
@benpicco
Copy link
Contributor Author

Thank you for the review!

@jia200x jia200x added this to the Release 2023.04 milestone Apr 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: build system Area: Build system Area: CoAP Area: Constrained Application Protocol implementations Area: examples Area: Example Applications Area: network Area: Networking Area: sys Area: System CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants