@@ -231,7 +231,7 @@ static int coap_client_init_request(struct coap_client *client,
231
231
}
232
232
233
233
/* Add content format option only if there is a payload */
234
- if (req -> payload ) {
234
+ if (req -> payload != NULL || req -> payload_cb != NULL ) {
235
235
ret = coap_append_option_int (& internal_req -> request ,
236
236
COAP_OPTION_CONTENT_FORMAT , req -> fmt );
237
237
@@ -272,14 +272,94 @@ static int coap_client_init_request(struct coap_client *client,
272
272
}
273
273
}
274
274
275
- if (req -> payload ) {
275
+ if (req -> payload != NULL || req -> payload_cb != NULL ) {
276
+ const uint8_t * payload = NULL ;
277
+ bool block_transfer = false;
276
278
uint16_t payload_len ;
277
- uint16_t offset ;
278
279
279
- /* Blockwise send ongoing, add block1 */
280
- if (internal_req -> send_blk_ctx .total_size > 0 ||
281
- (req -> len > CONFIG_COAP_CLIENT_MESSAGE_SIZE )) {
280
+ /* Block transfer already in progress */
281
+ if (internal_req -> send_blk_ctx .total_size > 0 ) {
282
+ block_transfer = true;
283
+ }
284
+
285
+ if (req -> payload_cb != NULL ) {
286
+ size_t offset = 0 ;
287
+ size_t block_size = internal_req -> send_blk_ctx .total_size > 0 ?
288
+ coap_block_size_to_bytes (internal_req -> send_blk_ctx .block_size ) :
289
+ CONFIG_COAP_CLIENT_BLOCK_SIZE ;
290
+ size_t len = block_size ;
291
+ bool last_block ;
292
+
293
+ if (block_transfer ) {
294
+ offset = internal_req -> send_blk_ctx .current ;
295
+ }
296
+
297
+ ret = req -> payload_cb (offset , & payload , & len , & last_block ,
298
+ req -> user_data );
299
+ if (ret < 0 ) {
300
+ LOG_ERR ("Payload callback reported error, %d" , ret );
301
+ goto out ;
302
+ }
303
+
304
+ if (len > block_size || (len < block_size && !last_block )) {
305
+ LOG_ERR ("Invalid payload size" );
306
+ ret = - EINVAL ;
307
+ goto out ;
308
+ }
309
+
310
+ if (payload == NULL ) {
311
+ LOG_ERR ("No payload provided" );
312
+ ret = - EINVAL ;
313
+ goto out ;
314
+ }
315
+
316
+ payload_len = len ;
317
+
318
+ if (block_transfer && last_block ) {
319
+ /* If block transfer was used and it's a final
320
+ * block, adjust the total size value.
321
+ */
322
+ internal_req -> send_blk_ctx .total_size =
323
+ internal_req -> send_blk_ctx .current + len ;
324
+ }
282
325
326
+ if (!last_block ) {
327
+ /* Expecting more blocks, enable block transfer.
328
+ * Total length is yet unknown at this point,
329
+ * so use SIZE_MAX for now.
330
+ */
331
+ block_transfer = true;
332
+ req -> len = SIZE_MAX ;
333
+ }
334
+ } else {
335
+ payload = req -> payload ;
336
+ payload_len = req -> len ;
337
+
338
+ if (block_transfer ) {
339
+ /* Block transfer already in progress, adjust
340
+ * payload pointer and length.
341
+ */
342
+ uint16_t block_in_bytes = coap_block_size_to_bytes (
343
+ internal_req -> send_blk_ctx .block_size );
344
+
345
+ payload_len = internal_req -> send_blk_ctx .total_size -
346
+ internal_req -> send_blk_ctx .current ;
347
+ if (payload_len > block_in_bytes ) {
348
+ payload_len = block_in_bytes ;
349
+ }
350
+
351
+ payload = req -> payload + internal_req -> send_blk_ctx .current ;
352
+ } else if (req -> len > CONFIG_COAP_CLIENT_MESSAGE_SIZE ) {
353
+ /* Otherwise, if payload won't fit, initialize
354
+ * block transfer.
355
+ */
356
+ block_transfer = true;
357
+ payload_len = CONFIG_COAP_CLIENT_BLOCK_SIZE ;
358
+ }
359
+ }
360
+
361
+ /* Blockwise send ongoing, add block1 */
362
+ if (block_transfer ) {
283
363
if (internal_req -> send_blk_ctx .total_size == 0 ) {
284
364
coap_block_transfer_init (& internal_req -> send_blk_ctx ,
285
365
coap_client_default_block_size (),
@@ -289,6 +369,7 @@ static int coap_client_init_request(struct coap_client *client,
289
369
290
370
memcpy (internal_req -> request_tag , tag , COAP_TOKEN_MAX_LEN );
291
371
}
372
+
292
373
ret = coap_append_block1_option (& internal_req -> request ,
293
374
& internal_req -> send_blk_ctx );
294
375
@@ -314,22 +395,7 @@ static int coap_client_init_request(struct coap_client *client,
314
395
goto out ;
315
396
}
316
397
317
- if (internal_req -> send_blk_ctx .total_size > 0 ) {
318
- uint16_t block_in_bytes =
319
- coap_block_size_to_bytes (internal_req -> send_blk_ctx .block_size );
320
-
321
- payload_len = internal_req -> send_blk_ctx .total_size -
322
- internal_req -> send_blk_ctx .current ;
323
- if (payload_len > block_in_bytes ) {
324
- payload_len = block_in_bytes ;
325
- }
326
- offset = internal_req -> send_blk_ctx .current ;
327
- } else {
328
- payload_len = req -> len ;
329
- offset = 0 ;
330
- }
331
-
332
- ret = coap_packet_append_payload (& internal_req -> request , req -> payload + offset ,
398
+ ret = coap_packet_append_payload (& internal_req -> request , payload ,
333
399
payload_len );
334
400
335
401
if (ret < 0 ) {
0 commit comments