1 /* 2 * coap_net_internal.h -- CoAP context internal information 3 * exposed to application programming 4 * 5 * Copyright (C) 2010-2023 Olaf Bergmann <bergmann@tzi.org> 6 * 7 * SPDX-License-Identifier: BSD-2-Clause 8 * 9 * This file is part of the CoAP library libcoap. Please see README for terms 10 * of use. 11 */ 12 13 /** 14 * @file coap_net_internal.h 15 * @brief CoAP context internal information 16 */ 17 18 #ifndef COAP_NET_INTERNAL_H_ 19 #define COAP_NET_INTERNAL_H_ 20 21 #include "coap_internal.h" 22 #include "coap_subscribe.h" 23 24 /** 25 * @ingroup internal_api 26 * @defgroup context_internal Context Handling 27 * Internal API for Context Handling 28 * @{ 29 */ 30 31 /** 32 * Queue entry 33 */ 34 struct coap_queue_t { 35 struct coap_queue_t *next; 36 coap_tick_t t; /**< when to send PDU for the next time */ 37 unsigned char retransmit_cnt; /**< retransmission counter, will be removed 38 * when zero */ 39 uint8_t is_mcast; /**< Set if this is a queued mcast response */ 40 unsigned int timeout; /**< the randomized timeout value */ 41 coap_session_t *session; /**< the CoAP session */ 42 coap_mid_t id; /**< CoAP message id */ 43 coap_pdu_t *pdu; /**< the CoAP PDU to send */ 44 }; 45 46 /** 47 * The CoAP stack's global state is stored in a coap_context_t object. 48 */ 49 struct coap_context_t { 50 coap_opt_filter_t known_options; 51 #if COAP_SERVER_SUPPORT 52 coap_resource_t *resources; /**< hash table or list of known 53 resources */ 54 coap_resource_t *unknown_resource; /**< can be used for handling 55 unknown resources */ 56 coap_resource_t *proxy_uri_resource; /**< can be used for handling 57 proxy URI resources */ 58 coap_resource_release_userdata_handler_t release_userdata; 59 /**< function to release user_data 60 when resource is deleted */ 61 #endif /* COAP_SERVER_SUPPORT */ 62 63 #if COAP_ASYNC_SUPPORT 64 /** 65 * list of asynchronous message ids */ 66 coap_async_t *async_state; 67 #endif /* COAP_ASYNC_SUPPORT */ 68 69 /** 70 * The time stamp in the first element of the sendqeue is relative 71 * to sendqueue_basetime. */ 72 coap_tick_t sendqueue_basetime; 73 coap_queue_t *sendqueue; 74 #if COAP_SERVER_SUPPORT 75 coap_endpoint_t *endpoint; /**< the endpoints used for listening */ 76 #endif /* COAP_SERVER_SUPPORT */ 77 #if COAP_CLIENT_SUPPORT 78 coap_session_t *sessions; /**< client sessions */ 79 #endif /* COAP_CLIENT_SUPPORT */ 80 81 #ifdef WITH_CONTIKI 82 struct uip_udp_conn *conn; /**< uIP connection object */ 83 struct ctimer prepare_timer; /**< fires when it's time to call 84 coap_io_prepare_io */ 85 #endif /* WITH_CONTIKI */ 86 87 #ifdef WITH_LWIP 88 coap_lwip_input_wait_handler_t input_wait; /** Input wait / timeout handler if set */ 89 void *input_arg; /** argument to pass it input handler */ 90 uint8_t timer_configured; /**< Set to 1 when a retransmission is 91 * scheduled using lwIP timers for this 92 * context, otherwise 0. */ 93 #endif /* WITH_LWIP */ 94 #if COAP_OSCORE_SUPPORT 95 struct oscore_ctx_t *p_osc_ctx; /**< primary oscore context */ 96 #endif /* COAP_OSCORE_SUPPORT */ 97 98 #if COAP_CLIENT_SUPPORT 99 coap_response_handler_t response_handler; /**< Called when a response is 100 received */ 101 #endif /* COAP_CLIENT_SUPPORT */ 102 coap_nack_handler_t nack_handler; /**< Called when a response issue has 103 occurred */ 104 coap_ping_handler_t ping_handler; /**< Called when a CoAP ping is received */ 105 coap_pong_handler_t pong_handler; /**< Called when a ping response 106 is received */ 107 108 #if COAP_SERVER_SUPPORT 109 coap_observe_added_t observe_added; /**< Called when there is a new observe 110 subscription request */ 111 coap_observe_deleted_t observe_deleted; /**< Called when there is a observe 112 subscription de-register request */ 113 void *observe_user_data; /**< App provided data for use in observe_added or 114 observe_deleted */ 115 uint32_t observe_save_freq; /**< How frequently to update observe value */ 116 coap_track_observe_value_t track_observe_value; /**< Callback to save observe 117 value when updated */ 118 coap_dyn_resource_added_t dyn_resource_added; /**< Callback to save dynamic 119 resource when created */ 120 coap_resource_deleted_t resource_deleted; /**< Invoked when resource 121 is deleted */ 122 #if COAP_WITH_OBSERVE_PERSIST 123 coap_bin_const_t *dyn_resource_save_file; /** Where dynamic resource requests 124 that create resources are 125 tracked */ 126 coap_bin_const_t *obs_cnt_save_file; /** Where resource observe counters are 127 tracked */ 128 coap_bin_const_t *observe_save_file; /** Where observes are tracked */ 129 coap_pdu_t *unknown_pdu; /** PDU used for unknown resource request */ 130 coap_session_t *unknown_session; /** Session used for unknown resource request */ 131 #endif /* COAP_WITH_OBSERVE_PERSIST */ 132 #endif /* COAP_SERVER_SUPPORT */ 133 134 /** 135 * Callback function that is used to signal events to the 136 * application. This field is set by coap_set_event_handler(). 137 */ 138 coap_event_handler_t handle_event; 139 140 void *dtls_context; 141 142 #if COAP_SERVER_SUPPORT 143 coap_dtls_spsk_t spsk_setup_data; /**< Contains the initial PSK server setup 144 data */ 145 #endif /* COAP_SERVER_SUPPORT */ 146 147 unsigned int session_timeout; /**< Number of seconds of inactivity after 148 which an unused session will be closed. 149 0 means use default. */ 150 unsigned int max_idle_sessions; /**< Maximum number of simultaneous unused 151 sessions per endpoint. 0 means no 152 maximum. */ 153 unsigned int max_handshake_sessions; /**< Maximum number of simultaneous 154 negotating sessions per endpoint. 0 155 means use default. */ 156 unsigned int ping_timeout; /**< Minimum inactivity time before 157 sending a ping message. 0 means 158 disabled. */ 159 unsigned int csm_timeout; /**< Timeout for waiting for a CSM from 160 the remote side. 0 means disabled. */ 161 uint32_t csm_max_message_size; /**< Value for CSM Max-Message-Size */ 162 uint64_t etag; /**< Next ETag to use */ 163 164 #if COAP_SERVER_SUPPORT 165 coap_cache_entry_t *cache; /**< CoAP cache-entry cache */ 166 uint16_t *cache_ignore_options; /**< CoAP options to ignore when creating a 167 cache-key */ 168 size_t cache_ignore_count; /**< The number of CoAP options to ignore 169 when creating a cache-key */ 170 #endif /* COAP_SERVER_SUPPORT */ 171 void *app; /**< application-specific data */ 172 uint32_t max_token_size; /**< Largest token size supported RFC8974 */ 173 #ifdef COAP_EPOLL_SUPPORT 174 int epfd; /**< External FD for epoll */ 175 int eptimerfd; /**< Internal FD for timeout */ 176 coap_tick_t next_timeout; /**< When the next timeout is to occur */ 177 #else /* ! COAP_EPOLL_SUPPORT */ 178 fd_set readfds, writefds, exceptfds; /**< Used for select call 179 in coap_io_process_with_fds() */ 180 coap_socket_t *sockets[64]; /**< Track different socket information 181 in coap_io_process_with_fds */ 182 unsigned int num_sockets; /**< Number of sockets being tracked */ 183 #endif /* ! COAP_EPOLL_SUPPORT */ 184 #if COAP_SERVER_SUPPORT 185 uint8_t observe_pending; /**< Observe response pending */ 186 uint8_t observe_no_clear; /**< Observe 4.04 not to be sent on deleting 187 resource */ 188 uint8_t mcast_per_resource; /**< Mcast controlled on a per resource 189 basis */ 190 #endif /* COAP_SERVER_SUPPORT */ 191 uint8_t block_mode; /**< Zero or more COAP_BLOCK_ or'd options */ 192 }; 193 194 /** 195 * Adds @p node to given @p queue, ordered by variable t in @p node. 196 * 197 * @param queue Queue to add to. 198 * @param node Node entry to add to Queue. 199 * 200 * @return @c 1 added to queue, @c 0 failure. 201 */ 202 int coap_insert_node(coap_queue_t **queue, coap_queue_t *node); 203 204 /** 205 * Destroys specified @p node. 206 * 207 * @param node Node entry to remove. 208 * 209 * @return @c 1 node deleted from queue, @c 0 failure. 210 */ 211 int coap_delete_node(coap_queue_t *node); 212 213 /** 214 * Removes all items from given @p queue and frees the allocated storage. 215 * 216 * Internal function. 217 * 218 * @param queue The queue to delete. 219 */ 220 void coap_delete_all(coap_queue_t *queue); 221 222 /** 223 * Creates a new node suitable for adding to the CoAP sendqueue. 224 * 225 * @return New node entry, or @c NULL if failure. 226 */ 227 coap_queue_t *coap_new_node(void); 228 229 /** 230 * Set sendqueue_basetime in the given context object @p ctx to @p now. This 231 * function returns the number of elements in the queue head that have timed 232 * out. 233 */ 234 unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now); 235 236 /** 237 * Returns the next pdu to send without removing from sendqeue. 238 */ 239 coap_queue_t *coap_peek_next(coap_context_t *context); 240 241 /** 242 * Returns the next pdu to send and removes it from the sendqeue. 243 */ 244 coap_queue_t *coap_pop_next(coap_context_t *context); 245 246 /** 247 * Handles retransmissions of confirmable messages 248 * 249 * @param context The CoAP context. 250 * @param node The node to retransmit. 251 * 252 * @return The message id of the sent message or @c 253 * COAP_INVALID_MID on error. 254 */ 255 coap_mid_t coap_retransmit(coap_context_t *context, coap_queue_t *node); 256 257 /** 258 * Parses and interprets a CoAP datagram with context @p ctx. This function 259 * returns @c 0 if the datagram was handled, or a value less than zero on 260 * error. 261 * 262 * @param ctx The current CoAP context. 263 * @param session The current CoAP session. 264 * @param data The received packet'd data. 265 * @param data_len The received packet'd data length. 266 * 267 * @return @c 0 if message was handled successfully, or less than zero on 268 * error. 269 */ 270 int coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, uint8_t *data, size_t data_len); 271 272 /** 273 * This function removes the element with given @p id from the list given list. 274 * If @p id was found, @p node is updated to point to the removed element. Note 275 * that the storage allocated by @p node is @b not released. The caller must do 276 * this manually using coap_delete_node(). This function returns @c 1 if the 277 * element with id @p id was found, @c 0 otherwise. For a return value of @c 0, 278 * the contents of @p node is undefined. 279 * 280 * @param queue The queue to search for @p id. 281 * @param session The session to look for. 282 * @param id The message id to look for. 283 * @param node If found, @p node is updated to point to the removed node. You 284 * must release the storage pointed to by @p node manually. 285 * 286 * @return @c 1 if @p id was found, @c 0 otherwise. 287 */ 288 int coap_remove_from_queue(coap_queue_t **queue, 289 coap_session_t *session, 290 coap_mid_t id, 291 coap_queue_t **node); 292 293 coap_mid_t coap_wait_ack(coap_context_t *context, coap_session_t *session, 294 coap_queue_t *node); 295 296 /** 297 * Cancels all outstanding messages for session @p session that have the specified 298 * token. 299 * 300 * @param context The context in use. 301 * @param session Session of the messages to remove. 302 * @param token Message token. 303 */ 304 void coap_cancel_all_messages(coap_context_t *context, 305 coap_session_t *session, 306 coap_bin_const_t *token); 307 308 /** 309 * Cancels all outstanding messages for session @p session. 310 * 311 * @param context The context in use. 312 * @param session Session of the messages to remove. 313 * @param reason The reasion for the session cancellation 314 */ 315 void coap_cancel_session_messages(coap_context_t *context, 316 coap_session_t *session, 317 coap_nack_reason_t reason); 318 319 /** 320 * Dispatches the PDUs from the receive queue in given context. 321 */ 322 void coap_dispatch(coap_context_t *context, coap_session_t *session, 323 coap_pdu_t *pdu); 324 325 /** 326 * Verifies that @p pdu contains no unknown critical options. Options must be 327 * registered at @p ctx, using the function coap_register_option(). A basic set 328 * of options is registered automatically by coap_new_context(). This function 329 * returns @c 1 if @p pdu is ok, @c 0 otherwise. The given filter object @p 330 * unknown will be updated with the unknown options. As only @c COAP_MAX_OPT 331 * options can be signalled this way, remaining options must be examined 332 * manually. 333 * 334 * @code 335 coap_opt_filter_t f = COAP_OPT_NONE; 336 coap_opt_iterator_t opt_iter; 337 338 if (coap_option_check_critical(session, pdu, f) == 0) { 339 coap_option_iterator_init(pdu, &opt_iter, f); 340 341 while (coap_option_next(&opt_iter)) { 342 if (opt_iter.type & 0x01) { 343 ... handle unknown critical option in opt_iter ... 344 } 345 } 346 } 347 @endcode 348 * 349 * @param session The current session. 350 * @param pdu The PDU to check. 351 * @param unknown The output filter that will be updated to indicate the 352 * unknown critical options found in @p pdu. 353 * 354 * @return @c 1 if everything was ok, @c 0 otherwise. 355 */ 356 int coap_option_check_critical(coap_session_t *session, 357 coap_pdu_t *pdu, 358 coap_opt_filter_t *unknown); 359 360 /** 361 * Creates a new response for given @p request with the contents of @c 362 * .well-known/core. The result is NULL on error or a newly allocated PDU that 363 * must be either sent with coap_sent() or released by coap_delete_pdu(). 364 * 365 * @param context The current coap context to use. 366 * @param session The CoAP session. 367 * @param request The request for @c .well-known/core . 368 * 369 * @return A new 2.05 response for @c .well-known/core or NULL on error. 370 */ 371 coap_pdu_t *coap_wellknown_response(coap_context_t *context, 372 coap_session_t *session, 373 coap_pdu_t *request); 374 375 /** 376 * Calculates the initial timeout based on the session CoAP transmission 377 * parameters 'ack_timeout', 'ack_random_factor', and COAP_TICKS_PER_SECOND. 378 * The calculation requires 'ack_timeout' and 'ack_random_factor' to be in 379 * Qx.FRAC_BITS fixed point notation, whereas the passed parameter @p r 380 * is interpreted as the fractional part of a Q0.MAX_BITS random value. 381 * 382 * @param session session timeout is associated with 383 * @param r random value as fractional part of a Q0.MAX_BITS fixed point 384 * value 385 * @return COAP_TICKS_PER_SECOND * 'ack_timeout' * 386 * (1 + ('ack_random_factor' - 1) * r) 387 */ 388 unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r); 389 390 /** 391 * Sends a CoAP message to given peer. The memory that is 392 * allocated for the pdu will be released by coap_send_internal(). 393 * The caller must not use the pdu after calling coap_send_internal(). 394 * 395 * If the response body is split into multiple payloads using blocks, libcoap 396 * will handle asking for the subsequent blocks and any necessary recovery 397 * needed. 398 * 399 * @param session The CoAP session. 400 * @param pdu The CoAP PDU to send. 401 * 402 * @return The message id of the sent message or @c 403 * COAP_INVALID_MID on error. 404 */ 405 coap_mid_t coap_send_internal(coap_session_t *session, coap_pdu_t *pdu); 406 407 /** 408 * Delay the sending of the first client request until some other negotiation 409 * has completed. 410 * 411 * @param session The CoAP session. 412 * 413 * @return @c 1 if everything was ok, @c 0 otherwise. 414 */ 415 int coap_client_delay_first(coap_session_t *session); 416 417 /** @} */ 418 419 extern int coap_started; 420 421 #endif /* COAP_NET_INTERNAL_H_ */ 422