• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * coap_context_internal.h -- Structures, Enums & Functions that are not
3  * exposed to application programming
4  *
5  * Copyright (C) 2010-2021 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 net internal information
16  */
17 
18 #ifndef COAP_NET_INTERNAL_H_
19 #define COAP_NET_INTERNAL_H_
20 
21 /**
22  * @defgroup context_internal Context Handling (Internal)
23  * CoAP Context Structures, Enums and Functions that are not exposed to
24  * applications
25  * @{
26  */
27 
28 /**
29  * Queue entry
30  */
31 struct coap_queue_t {
32   struct coap_queue_t *next;
33   coap_tick_t t;                /**< when to send PDU for the next time */
34   unsigned char retransmit_cnt; /**< retransmission counter, will be removed
35                                  *    when zero */
36   unsigned int timeout;         /**< the randomized timeout value */
37   coap_session_t *session;      /**< the CoAP session */
38   coap_mid_t id;                /**< CoAP message id */
39   coap_pdu_t *pdu;              /**< the CoAP PDU to send */
40 };
41 
42 /**
43  * The CoAP stack's global state is stored in a coap_context_t object.
44  */
45 struct coap_context_t {
46   coap_opt_filter_t known_options;
47   coap_resource_t *resources; /**< hash table or list of known
48                                    resources */
49   coap_resource_t *unknown_resource; /**< can be used for handling
50                                           unknown resources */
51   coap_resource_t *proxy_uri_resource; /**< can be used for handling
52                                             proxy URI resources */
53   coap_resource_release_userdata_handler_t release_userdata;
54                                         /**< function to  release user_data
55                                              when resource is deleted */
56 
57 #ifndef WITHOUT_ASYNC
58   /**
59    * list of asynchronous message ids */
60   coap_async_t *async_state;
61 #endif /* WITHOUT_ASYNC */
62 
63   /**
64    * The time stamp in the first element of the sendqeue is relative
65    * to sendqueue_basetime. */
66   coap_tick_t sendqueue_basetime;
67   coap_queue_t *sendqueue;
68   coap_endpoint_t *endpoint;      /**< the endpoints used for listening  */
69   coap_session_t *sessions;       /**< client sessions */
70 
71 #ifdef WITH_CONTIKI
72   struct uip_udp_conn *conn;      /**< uIP connection object */
73   struct etimer retransmit_timer; /**< fires when the next packet must be
74                                        sent */
75   struct etimer notify_timer;     /**< used to check resources periodically */
76 #endif /* WITH_CONTIKI */
77 
78 #ifdef WITH_LWIP
79   uint8_t timer_configured;       /**< Set to 1 when a retransmission is
80                                    *   scheduled using lwIP timers for this
81                                    *   context, otherwise 0. */
82 #endif /* WITH_LWIP */
83 
84   coap_response_handler_t response_handler;
85   coap_nack_handler_t nack_handler;
86   coap_ping_handler_t ping_handler;
87   coap_pong_handler_t pong_handler;
88 
89   /**
90    * Callback function that is used to signal events to the
91    * application.  This field is set by coap_set_event_handler().
92    */
93   coap_event_handler_t handle_event;
94 
95   ssize_t (*network_send)(coap_socket_t *sock, const coap_session_t *session,
96                           const uint8_t *data, size_t datalen);
97 
98   ssize_t (*network_read)(coap_socket_t *sock, coap_packet_t *packet);
99 
100   size_t(*get_client_psk)(const coap_session_t *session, const uint8_t *hint,
101                           size_t hint_len, uint8_t *identity,
102                           size_t *identity_len, size_t max_identity_len,
103                           uint8_t *psk, size_t max_psk_len);
104   size_t(*get_server_psk)(const coap_session_t *session,
105                           const uint8_t *identity, size_t identity_len,
106                           uint8_t *psk, size_t max_psk_len);
107   size_t(*get_server_hint)(const coap_session_t *session, uint8_t *hint,
108                           size_t max_hint_len);
109 
110   void *dtls_context;
111 
112   coap_dtls_spsk_t spsk_setup_data;  /**< Contains the initial PSK server setup
113                                           data */
114 
115   unsigned int session_timeout;    /**< Number of seconds of inactivity after
116                                         which an unused session will be closed.
117                                         0 means use default. */
118   unsigned int max_idle_sessions;  /**< Maximum number of simultaneous unused
119                                         sessions per endpoint. 0 means no
120                                         maximum. */
121   unsigned int max_handshake_sessions; /**< Maximum number of simultaneous
122                                             negotating sessions per endpoint. 0
123                                             means use default. */
124   unsigned int ping_timeout;           /**< Minimum inactivity time before
125                                             sending a ping message. 0 means
126                                             disabled. */
127   unsigned int csm_timeout;           /**< Timeout for waiting for a CSM from
128                                            the remote side. 0 means disabled. */
129   uint8_t observe_pending;         /**< Observe response pending */
130   uint8_t block_mode;              /**< Zero or more COAP_BLOCK_ or'd options */
131   uint64_t etag;                   /**< Next ETag to use */
132 
133   coap_cache_entry_t *cache;       /**< CoAP cache-entry cache */
134   uint16_t *cache_ignore_options;  /**< CoAP options to ignore when creating a
135                                         cache-key */
136   size_t cache_ignore_count;       /**< The number of CoAP options to ignore
137                                         when creating a cache-key */
138   void *app;                       /**< application-specific data */
139 #ifdef COAP_EPOLL_SUPPORT
140   int epfd;                        /**< External FD for epoll */
141   int eptimerfd;                   /**< Internal FD for timeout */
142   coap_tick_t next_timeout;        /**< When the next timeout is to occur */
143 #endif /* COAP_EPOLL_SUPPORT */
144 };
145 
146 /**
147  * Adds @p node to given @p queue, ordered by variable t in @p node.
148  *
149  * @param queue Queue to add to.
150  * @param node Node entry to add to Queue.
151  *
152  * @return @c 1 added to queue, @c 0 failure.
153  */
154 int coap_insert_node(coap_queue_t **queue, coap_queue_t *node);
155 
156 /**
157  * Destroys specified @p node.
158  *
159  * @param node Node entry to remove.
160  *
161  * @return @c 1 node deleted from queue, @c 0 failure.
162  */
163 int coap_delete_node(coap_queue_t *node);
164 
165 /**
166  * Removes all items from given @p queue and frees the allocated storage.
167  *
168  * Internal function.
169  *
170  * @param queue The queue to delete.
171  */
172 void coap_delete_all(coap_queue_t *queue);
173 
174 /**
175  * Creates a new node suitable for adding to the CoAP sendqueue.
176  *
177  * @return New node entry, or @c NULL if failure.
178  */
179 coap_queue_t *coap_new_node(void);
180 
181 /**
182  * Set sendqueue_basetime in the given context object @p ctx to @p now. This
183  * function returns the number of elements in the queue head that have timed
184  * out.
185  */
186 unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now);
187 
188 /**
189  * Returns the next pdu to send without removing from sendqeue.
190  */
191 coap_queue_t *coap_peek_next( coap_context_t *context );
192 
193 /**
194  * Returns the next pdu to send and removes it from the sendqeue.
195  */
196 coap_queue_t *coap_pop_next( coap_context_t *context );
197 
198 /**
199  * Handles retransmissions of confirmable messages
200  *
201  * @param context      The CoAP context.
202  * @param node         The node to retransmit.
203  *
204  * @return             The message id of the sent message or @c
205  *                     COAP_INVALID_MID on error.
206  */
207 coap_mid_t coap_retransmit(coap_context_t *context, coap_queue_t *node);
208 
209 /**
210  * Parses and interprets a CoAP datagram with context @p ctx. This function
211  * returns @c 0 if the datagram was handled, or a value less than zero on
212  * error.
213  *
214  * @param ctx    The current CoAP context.
215  * @param session The current CoAP session.
216  * @param data The received packet'd data.
217  * @param data_len The received packet'd data length.
218  *
219  * @return       @c 0 if message was handled successfully, or less than zero on
220  *               error.
221  */
222 int coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, uint8_t *data, size_t data_len);
223 
224 /**
225  * This function removes the element with given @p id from the list given list.
226  * If @p id was found, @p node is updated to point to the removed element. Note
227  * that the storage allocated by @p node is @b not released. The caller must do
228  * this manually using coap_delete_node(). This function returns @c 1 if the
229  * element with id @p id was found, @c 0 otherwise. For a return value of @c 0,
230  * the contents of @p node is undefined.
231  *
232  * @param queue The queue to search for @p id.
233  * @param session The session to look for.
234  * @param id    The message id to look for.
235  * @param node  If found, @p node is updated to point to the removed node. You
236  *              must release the storage pointed to by @p node manually.
237  *
238  * @return      @c 1 if @p id was found, @c 0 otherwise.
239  */
240 int coap_remove_from_queue(coap_queue_t **queue,
241                            coap_session_t *session,
242                            coap_mid_t id,
243                            coap_queue_t **node);
244 
245 coap_mid_t
246 coap_wait_ack( coap_context_t *context, coap_session_t *session,
247                coap_queue_t *node);
248 
249 /**
250  * Cancels all outstanding messages for session @p session that have the specified
251  * token.
252  *
253  * @param context      The context in use.
254  * @param session      Session of the messages to remove.
255  * @param token        Message token.
256  * @param token_length Actual length of @p token.
257  */
258 void coap_cancel_all_messages(coap_context_t *context,
259                               coap_session_t *session,
260                               const uint8_t *token,
261                               size_t token_length);
262 
263 /**
264 * Cancels all outstanding messages for session @p session.
265 *
266 * @param context      The context in use.
267 * @param session      Session of the messages to remove.
268 * @param reason       The reasion for the session cancellation
269 */
270 void
271 coap_cancel_session_messages(coap_context_t *context,
272                              coap_session_t *session,
273                              coap_nack_reason_t reason);
274 
275 /**
276  * Dispatches the PDUs from the receive queue in given context.
277  */
278 void coap_dispatch(coap_context_t *context, coap_session_t *session,
279                    coap_pdu_t *pdu);
280 
281 /**
282  * Verifies that @p pdu contains no unknown critical options. Options must be
283  * registered at @p ctx, using the function coap_register_option(). A basic set
284  * of options is registered automatically by coap_new_context(). This function
285  * returns @c 1 if @p pdu is ok, @c 0 otherwise. The given filter object @p
286  * unknown will be updated with the unknown options. As only @c COAP_MAX_OPT
287  * options can be signalled this way, remaining options must be examined
288  * manually.
289  *
290  * @code
291   coap_opt_filter_t f = COAP_OPT_NONE;
292   coap_opt_iterator_t opt_iter;
293 
294   if (coap_option_check_critical(ctx, pdu, f) == 0) {
295     coap_option_iterator_init(pdu, &opt_iter, f);
296 
297     while (coap_option_next(&opt_iter)) {
298       if (opt_iter.type & 0x01) {
299         ... handle unknown critical option in opt_iter ...
300       }
301     }
302   }
303    @endcode
304  *
305  * @param ctx      The context where all known options are registered.
306  * @param pdu      The PDU to check.
307  * @param unknown  The output filter that will be updated to indicate the
308  *                 unknown critical options found in @p pdu.
309  *
310  * @return         @c 1 if everything was ok, @c 0 otherwise.
311  */
312 int coap_option_check_critical(coap_context_t *ctx,
313                                coap_pdu_t *pdu,
314                                coap_opt_filter_t *unknown);
315 
316 /**
317  * Creates a new response for given @p request with the contents of @c
318  * .well-known/core. The result is NULL on error or a newly allocated PDU that
319  * must be either sent with coap_sent() or released by coap_delete_pdu().
320  *
321  * @param context The current coap context to use.
322  * @param session The CoAP session.
323  * @param request The request for @c .well-known/core .
324  *
325  * @return        A new 2.05 response for @c .well-known/core or NULL on error.
326  */
327 coap_pdu_t *coap_wellknown_response(coap_context_t *context,
328                                     coap_session_t *session,
329                                     coap_pdu_t *request);
330 
331 /**
332  * Calculates the initial timeout based on the session CoAP transmission
333  * parameters 'ack_timeout', 'ack_random_factor', and COAP_TICKS_PER_SECOND.
334  * The calculation requires 'ack_timeout' and 'ack_random_factor' to be in
335  * Qx.FRAC_BITS fixed point notation, whereas the passed parameter @p r
336  * is interpreted as the fractional part of a Q0.MAX_BITS random value.
337  *
338  * @param session session timeout is associated with
339  * @param r  random value as fractional part of a Q0.MAX_BITS fixed point
340  *           value
341  * @return   COAP_TICKS_PER_SECOND * 'ack_timeout' *
342  *           (1 + ('ack_random_factor' - 1) * r)
343  */
344 unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r);
345 
346 /**
347  * Sends a CoAP message to given peer. The memory that is
348  * allocated for the pdu will be released by coap_send_internal().
349  * The caller must not use the pdu after calling coap_send_internal().
350  *
351  * If the response body is split into multiple payloads using blocks, libcoap
352  * will handle asking for the subsequent blocks and any necessary recovery
353  * needed.
354  *
355  * @param session   The CoAP session.
356  * @param pdu       The CoAP PDU to send.
357  *
358  * @return          The message id of the sent message or @c
359  *                  COAP_INVALID_MID on error.
360  */
361 coap_mid_t coap_send_internal(coap_session_t *session, coap_pdu_t *pdu);
362 
363 /** @} */
364 
365 #endif /* COAP_NET_INTERNAL_H_ */
366 
367