zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.13k stars 6.22k forks source link

net: coap_client: streaming blockwise payloads #59571

Open bdunlay opened 1 year ago

bdunlay commented 1 year ago

Is your enhancement proposal related to a problem? Please describe.

How can clients stream large payloads in blockwise uploads that otherwise could not fit in memory alone?

Today, the CoAP client initiates blockwise uploads strictly when the payload is larger than the configurable CONFIG_COAP_CLIENT_MESSAGE_SIZE, iterating on blocks of a fixed size offset in a buffer pointer. The payload pointer and size are provided in the initiating request.

Users may wish to not hold large payloads in memory, and instead stream them chunk by chunk.

Describe the solution you'd like

One solution might be to add a new member to the coap_client_request struct, something like coap_client_get_payload_t below, which if assigned would fill a buffer to a maximum length and return the number of bytes written. The payload would be written directly to the TX buffer.

/* returns >= 0 for number of bytes written, < 0 for error */
typedef int (*coap_get_payload_t)(uint8_t *payload, size_t len, void *user_data);

Example:

int get_my_payload(uint8_t *payload, size_t len, void *user_data) {
    struct my_ctx *ctx = user_data;
    return fs_read(ctx->my_file, payload, len);    
}

struct coap_client_request req = {
    .payload_cb = get_my_payload,
    .payload = NULL,
    .len = my_file.size,
    .user_data = ctx,
    ...
};

Describe alternatives you've considered

n/a

boaks commented 6 months ago

Today, the CoAP client initiates blockwise uploads

from other implementations (java Eclipse/Californium) this may be considered with two different modes/approaches:

AFAIK, both works with the zephyr coap-client as well. You may just provider the block-options by the application and transfer then the payload split in small chunks.

Anyway two words from a couple of years experience: