1c87c5fbaSopenharmony_ci// -*- mode:doc; -*- 2c87c5fbaSopenharmony_ci// vim: set syntax=asciidoc tw=0 3c87c5fbaSopenharmony_ci 4c87c5fbaSopenharmony_cicoap_cache(3) 5c87c5fbaSopenharmony_ci============= 6c87c5fbaSopenharmony_ci:doctype: manpage 7c87c5fbaSopenharmony_ci:man source: coap_cache 8c87c5fbaSopenharmony_ci:man version: @PACKAGE_VERSION@ 9c87c5fbaSopenharmony_ci:man manual: libcoap Manual 10c87c5fbaSopenharmony_ci 11c87c5fbaSopenharmony_ciNAME 12c87c5fbaSopenharmony_ci---- 13c87c5fbaSopenharmony_cicoap_cache, 14c87c5fbaSopenharmony_cicoap_cache_derive_key, 15c87c5fbaSopenharmony_cicoap_cache_derive_key_w_ignore, 16c87c5fbaSopenharmony_cicoap_delete_cache_key, 17c87c5fbaSopenharmony_cicoap_cache_ignore_options, 18c87c5fbaSopenharmony_cicoap_new_cache_entry, 19c87c5fbaSopenharmony_cicoap_delete_cache_entry, 20c87c5fbaSopenharmony_cicoap_cache_get_by_key, 21c87c5fbaSopenharmony_cicoap_cache_get_by_pdu, 22c87c5fbaSopenharmony_cicoap_cache_get_pdu, 23c87c5fbaSopenharmony_cicoap_cache_set_app_data, 24c87c5fbaSopenharmony_cicoap_cache_get_app_data 25c87c5fbaSopenharmony_ci- Work with CoAP cache functions 26c87c5fbaSopenharmony_ci 27c87c5fbaSopenharmony_ciSYNOPSIS 28c87c5fbaSopenharmony_ci-------- 29c87c5fbaSopenharmony_ci*#include <coap@LIBCOAP_API_VERSION@/coap.h>* 30c87c5fbaSopenharmony_ci 31c87c5fbaSopenharmony_ci*coap_cache_key_t *coap_cache_derive_key(const coap_session_t *_session_, 32c87c5fbaSopenharmony_ciconst coap_pdu_t *_pdu_, coap_cache_session_based_t _session_based_);* 33c87c5fbaSopenharmony_ci 34c87c5fbaSopenharmony_ci*coap_cache_key_t *coap_cache_derive_key_w_ignore( 35c87c5fbaSopenharmony_ciconst coap_session_t *_session_, const coap_pdu_t *_pdu_, 36c87c5fbaSopenharmony_cicoap_cache_session_based_t _session_based_, 37c87c5fbaSopenharmony_ciconst uint16_t *_ignore_options_, size_t _ignore_count_);* 38c87c5fbaSopenharmony_ci 39c87c5fbaSopenharmony_ci*void coap_delete_cache_key(coap_cache_key_t *_cache_key_);* 40c87c5fbaSopenharmony_ci 41c87c5fbaSopenharmony_ci*int coap_cache_ignore_options(coap_context_t *_context_, 42c87c5fbaSopenharmony_ciconst uint16_t *_options_, size_t _count_);* 43c87c5fbaSopenharmony_ci 44c87c5fbaSopenharmony_ci*coap_cache_entry_t *coap_new_cache_entry(coap_session_t *_session_, 45c87c5fbaSopenharmony_ciconst coap_pdu_t *_pdu_, coap_cache_record_pdu_t _record_pdu_, 46c87c5fbaSopenharmony_cicoap_cache_session_based_t _session_based_, unsigned int _idle_timeout_);* 47c87c5fbaSopenharmony_ci 48c87c5fbaSopenharmony_ci*void coap_delete_cache_entry(coap_context_t *_context_, 49c87c5fbaSopenharmony_cicoap_cache_entry_t *_cache_entry_);* 50c87c5fbaSopenharmony_ci 51c87c5fbaSopenharmony_ci*coap_cache_entry_t *coap_cache_get_by_key(coap_context_t *_context_, 52c87c5fbaSopenharmony_ciconst coap_cache_key_t *_cache_key_);* 53c87c5fbaSopenharmony_ci 54c87c5fbaSopenharmony_ci*coap_cache_entry_t *coap_cache_get_by_pdu(coap_session_t *_session_, 55c87c5fbaSopenharmony_ciconst coap_pdu_t *_pdu_, coap_cache_session_based_t _session_based_);* 56c87c5fbaSopenharmony_ci 57c87c5fbaSopenharmony_ci*const coap_pdu_t *coap_cache_get_pdu(const coap_cache_entry_t *_cache_entry_);* 58c87c5fbaSopenharmony_ci 59c87c5fbaSopenharmony_ci*void coap_cache_set_app_data(coap_cache_entry_t *_cache_entry_, void *_data_, 60c87c5fbaSopenharmony_cicoap_cache_app_data_free_callback_t _callback_);* 61c87c5fbaSopenharmony_ci 62c87c5fbaSopenharmony_ci*void *coap_cache_get_app_data(const coap_cache_entry_t *_cache_entry_);* 63c87c5fbaSopenharmony_ci 64c87c5fbaSopenharmony_ciFor specific (D)TLS library support, link with 65c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*, 66c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls* 67c87c5fbaSopenharmony_cior *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*. Otherwise, link with 68c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@* to get the default (D)TLS library support. 69c87c5fbaSopenharmony_ci 70c87c5fbaSopenharmony_ciDESCRIPTION 71c87c5fbaSopenharmony_ci----------- 72c87c5fbaSopenharmony_ci 73c87c5fbaSopenharmony_ciThe CoAP Cache provides support for two opaque objects that can be used for 74c87c5fbaSopenharmony_citracking requests and responses. 75c87c5fbaSopenharmony_ci 76c87c5fbaSopenharmony_ciThe first is the ability to derive a Cache Key from the cacheable parts of a 77c87c5fbaSopenharmony_ciCoAP PDU as defined in 78c87c5fbaSopenharmony_ci"https://rfc-editor.org/rfc/rfc7252#section-5.6[RFC7252 5.6. Caching]" 79c87c5fbaSopenharmony_ciupdated by 80c87c5fbaSopenharmony_ci"https://rfc-editor.org/rfc/rfc7641#section-2[RFC7641 2. The Observe Option]" 81c87c5fbaSopenharmony_ciand 82c87c5fbaSopenharmony_ci"https://rfc-editor.org/rfc/rfc8132#section-2[RFC8132 2. Fetch Method]". 83c87c5fbaSopenharmony_ci 84c87c5fbaSopenharmony_ciThe Cache Key is a SHA256 digest if libcoap was built with TLS support, 85c87c5fbaSopenharmony_ciotherwise it uses the internal coap_hash() function, using the information 86c87c5fbaSopenharmony_ciabstracted from the PDU and (optionally) the CoAP session. 87c87c5fbaSopenharmony_ci 88c87c5fbaSopenharmony_ciThis Cache Key can then be used to match against incoming PDUs and then 89c87c5fbaSopenharmony_ciappropriate action logic can take place. 90c87c5fbaSopenharmony_ci 91c87c5fbaSopenharmony_ciThere is support for excluding specific CoAP options from the Cache Key. 92c87c5fbaSopenharmony_ciExamples could be to exclude CoAP BLOCK1 and BLOCK2 Options for the client or 93c87c5fbaSopenharmony_ciserver for ease of tracking a large PUT or GET response, but to not exclude 94c87c5fbaSopenharmony_cithese CoAP options in a proxy where it makes sense to cache the individual 95c87c5fbaSopenharmony_ciblocks. 96c87c5fbaSopenharmony_ci 97c87c5fbaSopenharmony_ciThe second is providing Cache Entries (which can be looked up by PDU and hence 98c87c5fbaSopenharmony_ciby Cache Key) which hold additional information to make information tracking 99c87c5fbaSopenharmony_cisimpler. These Cache Entries are automatically deleted when a session closes 100c87c5fbaSopenharmony_cior a context is deleted. These Cache Entries are maintained on a hashed list 101c87c5fbaSopenharmony_cifor speed of lookup. 102c87c5fbaSopenharmony_ci 103c87c5fbaSopenharmony_ciThe following enums are defined. 104c87c5fbaSopenharmony_ci 105c87c5fbaSopenharmony_ci[source, c] 106c87c5fbaSopenharmony_ci---- 107c87c5fbaSopenharmony_citypedef enum coap_cache_session_based_t { 108c87c5fbaSopenharmony_ci COAP_CACHE_NOT_SESSION_BASED, 109c87c5fbaSopenharmony_ci COAP_CACHE_IS_SESSION_BASED 110c87c5fbaSopenharmony_ci} coap_cache_session_based_t; 111c87c5fbaSopenharmony_ci 112c87c5fbaSopenharmony_citypedef enum coap_cache_record_pdu_t { 113c87c5fbaSopenharmony_ci COAP_CACHE_NOT_RECORD_PDU, 114c87c5fbaSopenharmony_ci COAP_CACHE_RECORD_PDU 115c87c5fbaSopenharmony_ci} coap_cache_record_pdu_t; 116c87c5fbaSopenharmony_ci---- 117c87c5fbaSopenharmony_ci 118c87c5fbaSopenharmony_ciFUNCTIONS 119c87c5fbaSopenharmony_ci--------- 120c87c5fbaSopenharmony_ci 121c87c5fbaSopenharmony_ci*Function: coap_cache_derive_key()* 122c87c5fbaSopenharmony_ci 123c87c5fbaSopenharmony_ciThe *coap_cache_derive_key*() function abstracts all the non NoCacheKey CoAP 124c87c5fbaSopenharmony_cioptions, ignores the CoAP Observe option and includes a FETCH body from _pdu_. 125c87c5fbaSopenharmony_ciIf _session_based_ is COAP_CACHE_IS_SESSION_BASED, then _session_ pointer is 126c87c5fbaSopenharmony_cialso included. CoAP options can be specifically ignored by the use of 127c87c5fbaSopenharmony_ci*coap_cache_ignore_options*(). A digest is then built from all of the 128c87c5fbaSopenharmony_ciinformation and returned. NULL is returned on error. 129c87c5fbaSopenharmony_ci 130c87c5fbaSopenharmony_ci*Function: coap_cache_derive_key_w_ignore()* 131c87c5fbaSopenharmony_ci 132c87c5fbaSopenharmony_ciThe *coap_cache_derive_key_w_ignore*() function abstracts all the non 133c87c5fbaSopenharmony_ciNoCacheKey CoAP options, ignores the CoAP Observe option and includes a FETCH 134c87c5fbaSopenharmony_cibody from _pdu_. Further options to ignore are specified by the _ignore_count_ 135c87c5fbaSopenharmony_ciof _ignore_options_. If _session_based_ is COAP_CACHE_IS_SESSION_BASED, then 136c87c5fbaSopenharmony_ci_session_ pointer is also included. A digest is then built from all of the 137c87c5fbaSopenharmony_ciinformation and returned. NULL is returned on error. 138c87c5fbaSopenharmony_ci 139c87c5fbaSopenharmony_ci*Function: coap_delete_cache_key()* 140c87c5fbaSopenharmony_ci 141c87c5fbaSopenharmony_ciThe *coap_delete_cache_key*() function deletes the _cache_key_ that was 142c87c5fbaSopenharmony_cireturned from a *coap_cache_derive_key*() or 143c87c5fbaSopenharmony_ci*coap_cache_derive_key_w_ignore*() call. 144c87c5fbaSopenharmony_ci 145c87c5fbaSopenharmony_ci*Function: coap_cache_ignore_options()* 146c87c5fbaSopenharmony_ci 147c87c5fbaSopenharmony_ciThe *coap_cache_ignore_options*() function is used to store in _context_ a 148c87c5fbaSopenharmony_cilist of _count_ options held in _options_. The specified _options_ will not 149c87c5fbaSopenharmony_cibe included in the data used for the *coap_cache_derive_key*() function. 150c87c5fbaSopenharmony_ci 151c87c5fbaSopenharmony_ci*Function: coap_new_cache_entry()* 152c87c5fbaSopenharmony_ci 153c87c5fbaSopenharmony_ciThe *coap_new_cache_entry*() function will create a new Cache Entry based on 154c87c5fbaSopenharmony_cithe Cache Key derived from the _pdu_, _session_based_ and _session_. If 155c87c5fbaSopenharmony_ci_record_pdu_ is COAP_CACHE_RECORD_PDU, then a copy of the _pdu_ is stored in 156c87c5fbaSopenharmony_cithe Cache Entry for subsequent retrieval. The Cache Entry can also store 157c87c5fbaSopenharmony_ciapplication specific data (*coap_cache_set_app_data*() and 158c87c5fbaSopenharmony_ci*coap_cache_get_app_data*()). _idle_timeout_ in seconds defines the length of 159c87c5fbaSopenharmony_citime not being used before it gets deleted. If _idle_timeout_ is set to 160c87c5fbaSopenharmony_ci0, then the Cache Entry will not get idle expired. The created Cache 161c87c5fbaSopenharmony_ciEntry is returned, or NULL on error. 162c87c5fbaSopenharmony_ci 163c87c5fbaSopenharmony_ci*Function: coap_delete_cache_entry()* 164c87c5fbaSopenharmony_ci 165c87c5fbaSopenharmony_ciThe *coap_delete_cache_entry*() function can be used to delete the Cache Entry 166c87c5fbaSopenharmony_ci_cache_entry_ held within _context_. This will remove the Cache Entry from 167c87c5fbaSopenharmony_cithe hash lookup list and 168c87c5fbaSopenharmony_cifree off any internally held data. If the Cache Entry is session based, then 169c87c5fbaSopenharmony_ciit will automatically get deleted when the session is freed off or when the 170c87c5fbaSopenharmony_ciidle timeout expires. 171c87c5fbaSopenharmony_ci 172c87c5fbaSopenharmony_ci*Function: coap_cache_get_by_key()* 173c87c5fbaSopenharmony_ci 174c87c5fbaSopenharmony_ciThe *coap_cache_get_by_key*() function will locate the Cache Entry held in the 175c87c5fbaSopenharmony_ci_context_ environment that has Cache Key _cache_key_. Returns NULL if the 176c87c5fbaSopenharmony_ciCache Key was not found. 177c87c5fbaSopenharmony_ci 178c87c5fbaSopenharmony_ci*Function: coap_cache_get_by_pdu()* 179c87c5fbaSopenharmony_ci 180c87c5fbaSopenharmony_ciThe *coap_cache_get_by_pdu*() function will locate the Cache Entry held in the 181c87c5fbaSopenharmony_ci_session_ environment that has a Cache Key derived from the _pdu_ and 182c87c5fbaSopenharmony_ciwhether _session_based_ or not. This function calls *coap_cache_derive_key*() 183c87c5fbaSopenharmony_ciinternally, and so normally *coap_cache_ignore_options*() would have 184c87c5fbaSopenharmony_cipreviously been called with COAP_OPTION_BLOCK1 or COAP_OPTION_BLOCK2 to 185c87c5fbaSopenharmony_ciignore the values held within these options. 186c87c5fbaSopenharmony_ci 187c87c5fbaSopenharmony_ci*Function: coap_cache_get_pdu()* 188c87c5fbaSopenharmony_ci 189c87c5fbaSopenharmony_ciThe *coap_cache_get_pdu*() function returns the PDU that was stored with the 190c87c5fbaSopenharmony_ciCache Entry when it was created with *coap_new_cache_entry*() and _record_pdu_ 191c87c5fbaSopenharmony_ciwas set to COAP_CACHE_RECORD_PDU. If a PDU was not initially stored, NULL is 192c87c5fbaSopenharmony_cireturned. + 193c87c5fbaSopenharmony_ci*NOTE:* A copy of the returned PDU must be taken for use in sending a CoAP 194c87c5fbaSopenharmony_cipacket using *coap_pdu_duplicate*(). 195c87c5fbaSopenharmony_ci 196c87c5fbaSopenharmony_ci*Function: coap_cache_set_app_data()* 197c87c5fbaSopenharmony_ci 198c87c5fbaSopenharmony_ciThe *coap_cache_set_app_data*() function is used to associate _data_ with the 199c87c5fbaSopenharmony_ci_cache_entry_. If _callback_ is not NULL, it points to a function to free off 200c87c5fbaSopenharmony_ci_data_ when the _cache_entry_ is deleted. If any data has been previously 201c87c5fbaSopenharmony_cistored in the _cache_entry_, the pointer to the old data will get overwritten, 202c87c5fbaSopenharmony_cibut the old data will not get freed off. 203c87c5fbaSopenharmony_ci 204c87c5fbaSopenharmony_ciThe _callback_ handler function prototype is defined as: 205c87c5fbaSopenharmony_ci[source, c] 206c87c5fbaSopenharmony_ci---- 207c87c5fbaSopenharmony_citypedef void (*coap_cache_app_data_free_callback_t)(void *data); 208c87c5fbaSopenharmony_ci---- 209c87c5fbaSopenharmony_ciwhere _data_ is passed into the callback function whenever the Cache Entry is 210c87c5fbaSopenharmony_cideleted. 211c87c5fbaSopenharmony_ci 212c87c5fbaSopenharmony_ci*Function: coap_cache_get_app_data()* 213c87c5fbaSopenharmony_ci 214c87c5fbaSopenharmony_ciThe *coap_cache_get_app_data*() function is used to get the previously stored 215c87c5fbaSopenharmony_ci_data_ in the _cache_entry_. 216c87c5fbaSopenharmony_ci 217c87c5fbaSopenharmony_ciRETURN VALUES 218c87c5fbaSopenharmony_ci------------- 219c87c5fbaSopenharmony_ci*coap_cache_derive_key*() and *coap_cache_derive_key_w_ignore*() 220c87c5fbaSopenharmony_cireturns a newly created Cache Key or NULL if there is a creation failure. 221c87c5fbaSopenharmony_ci 222c87c5fbaSopenharmony_ci*coap_cache_ignore_options*() returns 1 if success, 0 on failure. 223c87c5fbaSopenharmony_ci 224c87c5fbaSopenharmony_ci*coap_new_cache_entry*(), *coap_cache_get_by_key*() and 225c87c5fbaSopenharmony_ci*coap_cache_get_by_pdu*() return the Cache Entry or NULL if there 226c87c5fbaSopenharmony_ciis a failure. 227c87c5fbaSopenharmony_ci 228c87c5fbaSopenharmony_ci*coap_cache_get_pdu*() returns the PDU that is held within the Cache Entry or 229c87c5fbaSopenharmony_ciNULL if there is no PDU available. 230c87c5fbaSopenharmony_ci 231c87c5fbaSopenharmony_ci*coap_cache_get_app_data*() returns the application data value 232c87c5fbaSopenharmony_cipreviously set by the *coap_cache_set_app_data*() function or NULL. 233c87c5fbaSopenharmony_ci 234c87c5fbaSopenharmony_ciEXAMPLES 235c87c5fbaSopenharmony_ci-------- 236c87c5fbaSopenharmony_ci*PUT Handler supporting BLOCK1* 237c87c5fbaSopenharmony_ci 238c87c5fbaSopenharmony_ci[source, c] 239c87c5fbaSopenharmony_ci---- 240c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 241c87c5fbaSopenharmony_ci 242c87c5fbaSopenharmony_cistatic coap_binary_t *example_data_ptr = NULL; 243c87c5fbaSopenharmony_cistatic int example_data_media_type = COAP_MEDIATYPE_TEXT_PLAIN; 244c87c5fbaSopenharmony_ci 245c87c5fbaSopenharmony_cistatic void 246c87c5fbaSopenharmony_cicache_free_app_data(void *data) { 247c87c5fbaSopenharmony_ci coap_binary_t *bdata = (coap_binary_t*)data; 248c87c5fbaSopenharmony_ci coap_delete_binary(bdata); 249c87c5fbaSopenharmony_ci} 250c87c5fbaSopenharmony_ci 251c87c5fbaSopenharmony_ci/* 252c87c5fbaSopenharmony_ci * Large Data PUT handler 253c87c5fbaSopenharmony_ci */ 254c87c5fbaSopenharmony_ci 255c87c5fbaSopenharmony_cistatic void 256c87c5fbaSopenharmony_cihnd_put_example_data(coap_context_t *ctx, 257c87c5fbaSopenharmony_ci coap_resource_t *resource, 258c87c5fbaSopenharmony_ci coap_session_t *session, 259c87c5fbaSopenharmony_ci coap_pdu_t *request, 260c87c5fbaSopenharmony_ci coap_binary_t *token, 261c87c5fbaSopenharmony_ci coap_string_t *query, 262c87c5fbaSopenharmony_ci coap_pdu_t *response 263c87c5fbaSopenharmony_ci) { 264c87c5fbaSopenharmony_ci size_t size; 265c87c5fbaSopenharmony_ci const uint8_t *data; 266c87c5fbaSopenharmony_ci coap_opt_iterator_t opt_iter; 267c87c5fbaSopenharmony_ci coap_opt_t *option; 268c87c5fbaSopenharmony_ci size_t offset; 269c87c5fbaSopenharmony_ci size_t total; 270c87c5fbaSopenharmony_ci coap_binary_t *data_so_far; 271c87c5fbaSopenharmony_ci 272c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 273c87c5fbaSopenharmony_ci (void)ctx; 274c87c5fbaSopenharmony_ci (void)token; 275c87c5fbaSopenharmony_ci (void)query; 276c87c5fbaSopenharmony_ci 277c87c5fbaSopenharmony_ci if (coap_get_data_large(request, &size, &data, &offset, &total) && 278c87c5fbaSopenharmony_ci size != total) { 279c87c5fbaSopenharmony_ci /* 280c87c5fbaSopenharmony_ci * A part of the data has been received (COAP_BLOCK_SINGLE_BODY not set). 281c87c5fbaSopenharmony_ci * However, total unfortunately is only an indication, so it is not safe to 282c87c5fbaSopenharmony_ci * allocate a block based on total. As per 283c87c5fbaSopenharmony_ci * https://rfc-editor.org/rfc/rfc7959#section-4 284c87c5fbaSopenharmony_ci * o In a request carrying a Block1 Option, to indicate the current 285c87c5fbaSopenharmony_ci * estimate the client has of the total size of the resource 286c87c5fbaSopenharmony_ci * representation, measured in bytes ("size indication"). 287c87c5fbaSopenharmony_ci * 288c87c5fbaSopenharmony_ci * coap_cache_ignore_options() must have previously been called with at 289c87c5fbaSopenharmony_ci * least COAP_OPTION_BLOCK1 set as the option value will change per block. 290c87c5fbaSopenharmony_ci */ 291c87c5fbaSopenharmony_ci coap_cache_entry_t *cache_entry = coap_cache_get_by_pdu(session, 292c87c5fbaSopenharmony_ci request, 293c87c5fbaSopenharmony_ci COAP_CACHE_IS_SESSION_BASED); 294c87c5fbaSopenharmony_ci 295c87c5fbaSopenharmony_ci if (offset == 0) { 296c87c5fbaSopenharmony_ci if (!cache_entry) { 297c87c5fbaSopenharmony_ci /* 298c87c5fbaSopenharmony_ci * Set idle_timeout parameter to COAP_MAX_TRANSMIT_WAIT if you want 299c87c5fbaSopenharmony_ci * early removal on transmission failure. 0 means only delete when 300c87c5fbaSopenharmony_ci * the session is deleted as session_based is set here. 301c87c5fbaSopenharmony_ci */ 302c87c5fbaSopenharmony_ci cache_entry = coap_new_cache_entry(session, request, 303c87c5fbaSopenharmony_ci COAP_CACHE_NOT_RECORD_PDU, 304c87c5fbaSopenharmony_ci COAP_CACHE_IS_SESSION_BASED, 0); 305c87c5fbaSopenharmony_ci } 306c87c5fbaSopenharmony_ci else { 307c87c5fbaSopenharmony_ci data_so_far = coap_cache_get_app_data(cache_entry); 308c87c5fbaSopenharmony_ci if (data_so_far) { 309c87c5fbaSopenharmony_ci coap_delete_binary(data_so_far); 310c87c5fbaSopenharmony_ci data_so_far = NULL; 311c87c5fbaSopenharmony_ci } 312c87c5fbaSopenharmony_ci coap_cache_set_app_data(cache_entry, NULL, NULL); 313c87c5fbaSopenharmony_ci } 314c87c5fbaSopenharmony_ci } 315c87c5fbaSopenharmony_ci if (!cache_entry) { 316c87c5fbaSopenharmony_ci if (offset == 0) { 317c87c5fbaSopenharmony_ci coap_log_warn("Unable to create a new cache entry\n"); 318c87c5fbaSopenharmony_ci } 319c87c5fbaSopenharmony_ci else { 320c87c5fbaSopenharmony_ci coap_log_warn( 321c87c5fbaSopenharmony_ci "No cache entry available for the non-first BLOCK\n"); 322c87c5fbaSopenharmony_ci } 323c87c5fbaSopenharmony_ci coap_pdu_set_code(response, COAP_RESPONSE_CODE_INTERNAL_ERROR); 324c87c5fbaSopenharmony_ci return; 325c87c5fbaSopenharmony_ci } 326c87c5fbaSopenharmony_ci 327c87c5fbaSopenharmony_ci if (size) { 328c87c5fbaSopenharmony_ci /* Add in the new data to cache entry */ 329c87c5fbaSopenharmony_ci data_so_far = coap_cache_get_app_data(cache_entry); 330c87c5fbaSopenharmony_ci data_so_far = coap_block_build_body(data_so_far, size, data, 331c87c5fbaSopenharmony_ci offset, total); 332c87c5fbaSopenharmony_ci /* Yes, data_so_far can be NULL if error */ 333c87c5fbaSopenharmony_ci coap_cache_set_app_data(cache_entry, data_so_far, cache_free_app_data); 334c87c5fbaSopenharmony_ci } 335c87c5fbaSopenharmony_ci if (offset + size == total) { 336c87c5fbaSopenharmony_ci /* All the data is now in */ 337c87c5fbaSopenharmony_ci data_so_far = coap_cache_get_app_data(cache_entry); 338c87c5fbaSopenharmony_ci coap_cache_set_app_data(cache_entry, NULL, NULL); 339c87c5fbaSopenharmony_ci } 340c87c5fbaSopenharmony_ci else { 341c87c5fbaSopenharmony_ci /* Give us the next block response */ 342c87c5fbaSopenharmony_ci coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTINUE); 343c87c5fbaSopenharmony_ci return; 344c87c5fbaSopenharmony_ci } 345c87c5fbaSopenharmony_ci } 346c87c5fbaSopenharmony_ci else { 347c87c5fbaSopenharmony_ci /* single body of data received */ 348c87c5fbaSopenharmony_ci data_so_far = coap_new_binary(size); 349c87c5fbaSopenharmony_ci if (data_so_far) { 350c87c5fbaSopenharmony_ci memcpy(data_so_far->s, data, size); 351c87c5fbaSopenharmony_ci } 352c87c5fbaSopenharmony_ci } 353c87c5fbaSopenharmony_ci 354c87c5fbaSopenharmony_ci if (example_data_ptr) { 355c87c5fbaSopenharmony_ci /* pre-existed response */ 356c87c5fbaSopenharmony_ci coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED); 357c87c5fbaSopenharmony_ci coap_delete_binary(example_data_ptr); 358c87c5fbaSopenharmony_ci } 359c87c5fbaSopenharmony_ci else 360c87c5fbaSopenharmony_ci /* just generated response */ 361c87c5fbaSopenharmony_ci coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED); 362c87c5fbaSopenharmony_ci 363c87c5fbaSopenharmony_ci example_data_ptr = data_so_far; 364c87c5fbaSopenharmony_ci if ((option = coap_check_option(request, COAP_OPTION_CONTENT_FORMAT, 365c87c5fbaSopenharmony_ci &opt_iter)) != NULL) { 366c87c5fbaSopenharmony_ci example_data_media_type = 367c87c5fbaSopenharmony_ci coap_decode_var_bytes (coap_opt_value (option), 368c87c5fbaSopenharmony_ci coap_opt_length (option)); 369c87c5fbaSopenharmony_ci } 370c87c5fbaSopenharmony_ci else { 371c87c5fbaSopenharmony_ci example_data_media_type = COAP_MEDIATYPE_TEXT_PLAIN; 372c87c5fbaSopenharmony_ci } 373c87c5fbaSopenharmony_ci 374c87c5fbaSopenharmony_ci coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED); 375c87c5fbaSopenharmony_ci coap_resource_notify_observers(resource, NULL); 376c87c5fbaSopenharmony_ci} 377c87c5fbaSopenharmony_ci 378c87c5fbaSopenharmony_ciint 379c87c5fbaSopenharmony_cimain(int argc, char* argv[]) { 380c87c5fbaSopenharmony_ci coap_context_t *ctx = NULL; /* Set up as normal */ 381c87c5fbaSopenharmony_ci /* ... */ 382c87c5fbaSopenharmony_ci uint16_t cache_ignore_options[] = { COAP_OPTION_BLOCK1, 383c87c5fbaSopenharmony_ci COAP_OPTION_BLOCK2 }; 384c87c5fbaSopenharmony_ci 385c87c5fbaSopenharmony_ci /* Initialize libcoap library */ 386c87c5fbaSopenharmony_ci coap_startup(); 387c87c5fbaSopenharmony_ci 388c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 389c87c5fbaSopenharmony_ci (void)argc; 390c87c5fbaSopenharmony_ci (void)argv; 391c87c5fbaSopenharmony_ci 392c87c5fbaSopenharmony_ci /* ... */ 393c87c5fbaSopenharmony_ci 394c87c5fbaSopenharmony_ci /** Define the options to ignore when setting up cache-keys */ 395c87c5fbaSopenharmony_ci coap_cache_ignore_options(ctx, cache_ignore_options, 396c87c5fbaSopenharmony_ci sizeof(cache_ignore_options)/sizeof(cache_ignore_options[0])); 397c87c5fbaSopenharmony_ci 398c87c5fbaSopenharmony_ci /* ... */ 399c87c5fbaSopenharmony_ci coap_cleanup(); 400c87c5fbaSopenharmony_ci 401c87c5fbaSopenharmony_ci} 402c87c5fbaSopenharmony_ci---- 403c87c5fbaSopenharmony_ci 404c87c5fbaSopenharmony_ciSEE ALSO 405c87c5fbaSopenharmony_ci-------- 406c87c5fbaSopenharmony_ci*coap_block*(3), *coap_init*(3), *coap_pdu_setup*(3), *coap_resource*(3) 407c87c5fbaSopenharmony_ciand *coap_string*(3) 408c87c5fbaSopenharmony_ci 409c87c5fbaSopenharmony_ciFURTHER INFORMATION 410c87c5fbaSopenharmony_ci------------------- 411c87c5fbaSopenharmony_ciSee 412c87c5fbaSopenharmony_ci 413c87c5fbaSopenharmony_ci"https://rfc-editor.org/rfc/rfc7252[RFC7252: The Constrained Application Protocol (CoAP)]" 414c87c5fbaSopenharmony_ci 415c87c5fbaSopenharmony_ci"https://rfc-editor.org/rfc/rfc7959[RFC7959: Block-Wise Transfers in the Constrained Application Protocol (CoAP)]" 416c87c5fbaSopenharmony_ci 417c87c5fbaSopenharmony_cifor further information. 418c87c5fbaSopenharmony_ci 419c87c5fbaSopenharmony_ciBUGS 420c87c5fbaSopenharmony_ci---- 421c87c5fbaSopenharmony_ciPlease report bugs on the mailing list for libcoap: 422c87c5fbaSopenharmony_cilibcoap-developers@lists.sourceforge.net or raise an issue on GitHub at 423c87c5fbaSopenharmony_cihttps://github.com/obgm/libcoap/issues 424c87c5fbaSopenharmony_ci 425c87c5fbaSopenharmony_ciAUTHORS 426c87c5fbaSopenharmony_ci------- 427c87c5fbaSopenharmony_ciThe libcoap project <libcoap-developers@lists.sourceforge.net> 428