This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF9160 CoAP blockwise transfer

Hello,

we are developing a customer product based on the nRF9160 and Nordic's NCS v1.4.2 where we need to send battery test data every 30s (~ 1kB, PUT method). The communication is done with CoAP (on top of an UDP socket) and works fine.

To improve the network communication, we want to switch to a block wise transfer option now (128byte blocks). But we are a bit lost where we need to set or add which functions to take our existing CoAP message and split it into several blocks. We have read the Zephyr CoAP documentation, but since this is only an API description and not a straight forward "how to" guide, we stuck at this topic.

The code we have right now (and works) looks like this:

#define MAX_COAP_MSG_LEN              1024

int16_t rslt = 0;
uint16_t packet_id = 0;
struct coap_packet request;
uint8_t data[MAX_COAP_MSG_LEN];
uint8_t payload[924];

char uri_path1[] = "mqtt";
char uri_path2[] = "batterytest";
char uri_path3[] = "";

char uri_query1[] = "c=testname";
char uri_query2[] = "u=testuser";
char uri_query3[] = "p=testpassword";
packet_id = coap_next_id();


rslt = coap_packet_init(&request, data, MAX_COAP_MSG_LEN, 1, COAP_TYPE_CON, 0, NULL, COAP_METHOD_PUT, packet_id);
  
rslt = coap_packet_append_option(&request, COAP_OPTION_URI_PATH, uri_path1, strlen(uri_path1));
rslt = coap_packet_append_option(&request, COAP_OPTION_URI_PATH, uri_path2, strlen(uri_path2));
rslt = coap_packet_append_option(&request, COAP_OPTION_URI_PATH, uri_path3, strlen(uri_path3));
  
rslt = coap_packet_append_option(&request, COAP_OPTION_URI_QUERY, uri_query1, strlen(uri_query1));
rslt = coap_packet_append_option(&request, COAP_OPTION_URI_QUERY, uri_query2, strlen(uri_query2));
rslt = coap_packet_append_option(&request, COAP_OPTION_URI_QUERY, uri_query3, strlen(uri_query3));
  
rslt = coap_packet_append_payload_marker(&request); 
rslt = coap_packet_append_payload(&request, (uint8_t *)payload, sizeof(payload) - 1);

rslt = send(sock, request.data, request.offset, 0);

From Zephyrs CoAP API reference we saw that there are functions like coap_block_transfer_init() and coap_append_block1_option() but we do not know how we add this to our existing code.

We found samples how to receive large data from a CoAP server in block wise mode, but not how to send (PUT method) large data to a server in block wise mode.

Questions:

  • Q1: In which function can we put our existing coap_packet to split it into blocks?
  • Q2: Does the OS send every block automatically or do we have to send each block manually until all blocks are send? How is that done?

It would be nice if anyone would have a code snippet which shows how to send CoAP packet in a block wise manner. Otherwise, some advice which functions to use would be also nice.

Thanks in advance! 

Thomas

  • Hi,

    The application have to handle the blockwise transfer itself.

    This means that you have to append the relevant options, and split the body yourself. You can use the coap_block_size_to_bytes() function to help calculate how many bytes to append to the message.

    You also have to manage sending and/or receiving every block yourself. This is generally done by sending/receiving a request for each block.

    You can find the specification for how block transfers are done here: CoAP Block Transfers.

    For code samples, you can look at large_get() in zephyr/samples/net/sockets/coap_server/src/coap-server.c, send_large_coap_request in zephyr/sampls/net/sockets/coap_client/src/coap-client.c and the CoAP implementation of the download_client in nrf/subsys/net/lib/download_client/src/coap.c.

    Best regards,

    Didrik

  • Hi Didrik,

    thank you for your reply.

    We managed to get the block wise transfer to work.

    The route of the confusion was that we thought the CoAP libraries does the splitting of the CoAP messaged automatically. That would have been very confienient, but in the end we did this manually by our own.

    Thanks again for your help!

    Thomas

Related