1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747
|
/*
* coap_session_internal.h -- Structures, Enums & Functions that are not
* exposed to application programming
*
* Copyright (C) 2010-2024 Olaf Bergmann <bergmann@tzi.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
/**
* @file coap_session_internal.h
* @brief CoAP session internal information
*/
#ifndef COAP_SESSION_INTERNAL_H_
#define COAP_SESSION_INTERNAL_H_
#include "coap_internal.h"
#include "coap_io_internal.h"
#include "coap_ws_internal.h"
#define COAP_DEFAULT_SESSION_TIMEOUT 300
#define COAP_PARTIAL_SESSION_TIMEOUT_TICKS (30 * COAP_TICKS_PER_SECOND)
#define COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS 100
/**
* @ingroup internal_api
* @defgroup session_internal Sessions
* Internal API for handling Sessions
* @{
*/
/**
* Only used for servers for hashing incoming packets. Cannot have local IP
* address as this may be an initial multicast and subsequent unicast address
*/
struct coap_addr_hash_t {
coap_address_t remote; /**< remote address and port */
uint16_t lport; /**< local port */
coap_proto_t proto; /**< CoAP protocol */
};
typedef enum {
COAP_OSCORE_B_2_NONE = 0,
COAP_OSCORE_B_2_STEP_1,
COAP_OSCORE_B_2_STEP_2,
COAP_OSCORE_B_2_STEP_3,
COAP_OSCORE_B_2_STEP_4,
COAP_OSCORE_B_2_STEP_5,
} COAP_OSCORE_B_2_STEP;
/**
* coap_ext_token_check_t values
*/
typedef enum coap_ext_token_check_t {
COAP_EXT_T_NOT_CHECKED = 0, /**< Not checked */
COAP_EXT_T_CHECKED, /**< Token size valid */
COAP_EXT_T_CHECKING, /**< Token size check request sent */
} coap_ext_token_check_t;
/**
* Abstraction of virtual session that can be attached to coap_context_t
* (client) or coap_endpoint_t (server).
*/
struct coap_session_t {
coap_proto_t proto; /**< protocol used */
coap_session_type_t type; /**< client or server side socket */
coap_session_state_t state; /**< current state of relationship with
peer */
unsigned ref; /**< reference count from queues */
size_t tls_overhead; /**< overhead of TLS layer */
size_t mtu; /**< path or CSM mtu (xmt) */
size_t csm_rcv_mtu; /**< CSM mtu (rcv) */
coap_addr_hash_t addr_hash; /**< Address hash for server incoming packets */
UT_hash_handle hh;
coap_addr_tuple_t addr_info; /**< remote/local address info */
int ifindex; /**< interface index */
coap_socket_t sock; /**< socket object for the session, if
any */
#if COAP_SERVER_SUPPORT
coap_endpoint_t *endpoint; /**< session's endpoint */
#endif /* COAP_SERVER_SUPPORT */
coap_context_t *context; /**< session's context */
void *tls; /**< security parameters */
uint16_t tx_mid; /**< the last message id that was used in
this session */
uint8_t con_active; /**< Active CON request sent */
uint8_t csm_block_supported; /**< CSM TCP blocks supported */
coap_mid_t last_ping_mid; /**< the last keepalive message id that was
used in this session */
coap_queue_t *delayqueue; /**< list of delayed messages waiting to
be sent */
coap_lg_xmit_t *lg_xmit; /**< list of large transmissions */
#if COAP_CLIENT_SUPPORT
coap_lg_crcv_t *lg_crcv; /**< Client list of expected large receives */
#endif /* COAP_CLIENT_SUPPORT */
#if COAP_SERVER_SUPPORT
coap_lg_srcv_t *lg_srcv; /**< Server list of expected large receives */
#endif /* COAP_SERVER_SUPPORT */
size_t partial_write; /**< if > 0 indicates number of bytes
already written from the pdu at the
head of sendqueue */
uint8_t read_header[8]; /**< storage space for header of incoming
message header */
size_t partial_read; /**< if > 0 indicates number of bytes
already read for an incoming message */
coap_pdu_t *partial_pdu; /**< incomplete incoming pdu */
coap_tick_t last_rx_tx;
coap_tick_t last_tx_rst;
coap_tick_t last_ping;
coap_tick_t last_pong;
coap_tick_t csm_tx;
coap_dtls_cpsk_t cpsk_setup_data; /**< client provided PSK initial setup
data */
coap_bin_const_t *psk_identity; /**< If client, this field contains the
current identity for server; When this
field is NULL, the current identity is
contained in cpsk_setup_data
If server, this field contains the client
provided identity.
Value maintained internally */
coap_bin_const_t *psk_key; /**< If client, this field contains the
current pre-shared key for server;
When this field is NULL, the current
key is contained in cpsk_setup_data
If server, this field contains the
client's current key.
Value maintained internally */
coap_bin_const_t *psk_hint; /**< If client, this field contains the
server provided identity hint.
If server, this field contains the
current hint for the client; When this
field is NULL, the current hint is
contained in context->spsk_setup_data
Value maintained internally */
void *app; /**< application-specific data */
coap_fixed_point_t ack_timeout; /**< timeout waiting for ack
(default 2.0 secs) */
coap_fixed_point_t ack_random_factor; /**< ack random factor backoff (default
1.5) */
uint16_t max_retransmit; /**< maximum re-transmit count
(default 4) */
uint16_t nstart; /**< maximum concurrent confirmable xmits
(default 1) */
coap_fixed_point_t default_leisure; /**< Mcast leisure time
(default 5.0 secs) */
uint32_t probing_rate; /**< Max transfer wait when remote is not
respoding (default 1 byte/sec) */
#if COAP_Q_BLOCK_SUPPORT
uint16_t max_payloads; /**< maximum Q-BlockX payloads before delay
(default 10) */
uint16_t non_max_retransmit; /**< maximum Q-BlockX non re-transmit count
(default 4) */
coap_fixed_point_t non_timeout; /**< Q-BlockX timeout waiting for response
(default 2.0 secs) */
coap_fixed_point_t non_receive_timeout; /**< Q-BlockX receive timeout before
requesting missing packets.
(default 4.0 secs) */
coap_fixed_point_t non_probing_wait_base; /**< Q-BlockX max wait time base
while probing
(default 247.0 secs) */
coap_fixed_point_t non_partial_timeout; /**< Q-BlockX time to wait before
discarding partial data for a body.
(default 247.0 secs) */
#endif /* COAP_Q_BLOCK_SUPPORT */
unsigned int dtls_timeout_count; /**< dtls setup retry counter */
int dtls_event; /**< Tracking any (D)TLS events on this
session */
uint32_t tx_rtag; /**< Next Request-Tag number to use */
uint32_t block_mode; /**< Zero or more COAP_BLOCK_ or'd options */
uint8_t csm_bert_rem_support; /**< CSM TCP BERT blocks supported (remote) */
uint8_t csm_bert_loc_support; /**< CSM TCP BERT blocks supported (local) */
uint8_t doing_first; /**< Set if doing client's first request */
uint8_t proxy_session; /**< Set if this is an ongoing proxy session */
uint8_t delay_recursive; /**< Set if in coap_client_delay_first() */
uint8_t no_observe_cancel; /**< Set if do not cancel observe on session
close */
uint8_t csm_not_seen; /**< Set if timeout waiting for CSM */
#if COAP_OSCORE_SUPPORT
uint8_t oscore_encryption; /**< OSCORE is used for this session */
COAP_OSCORE_B_2_STEP b_2_step; /**< Appendix B.2 negotiation step */
oscore_recipient_ctx_t *recipient_ctx; /**< OSCORE recipient context
for session */
oscore_association_t *associations; /**< OSCORE set of response
associations */
uint64_t oscore_r2; /**< R2 for RFC8613 Appendix B.2 */
#endif /* COAP_OSCORE_SUPPORT */
#if COAP_WS_SUPPORT
coap_ws_state_t *ws; /**< WS state */
coap_str_const_t *ws_host; /**< Host to use in WS Request */
#endif /* COAP_WS_SUPPORT */
#if COAP_OSCORE_SUPPORT
uint8_t done_b_1_2; /**< Have sent initial request */
#endif /* COAP_OSCORE_SUPPORT */
volatile uint8_t max_token_checked; /**< Check for max token size
coap_ext_token_check_t */
#if COAP_CLIENT_SUPPORT
uint8_t negotiated_cid; /**< Set for a client if CID negotiated */
#endif /* COAP_CLIENT_SUPPORT */
uint8_t is_dtls13; /**< Set if session is DTLS1.3 */
coap_mid_t remote_test_mid; /**< mid used for checking remote
support */
uint32_t max_token_size; /**< Largest token size supported RFC8974 */
uint64_t tx_token; /**< Next token number to use */
coap_bin_const_t *last_token; /** last token used to make a request */
coap_bin_const_t *echo; /**< Echo value to send with next request */
coap_mid_t last_ack_mid; /**< The last ACK mid that has been
been processed */
coap_mid_t last_con_mid; /**< The last CON mid that has been
been processed */
coap_response_t last_con_handler_res; /**< The result of calling the response handler
of the last CON */
#if COAP_SERVER_SUPPORT
coap_bin_const_t *client_cid; /**< Contains client CID or NULL */
#endif /* COAP_SERVER_SUPPORT */
};
#if COAP_SERVER_SUPPORT
/**
* Abstraction of virtual endpoint that can be attached to coap_context_t. The
* keys (port, bind_addr) must uniquely identify this endpoint.
*/
struct coap_endpoint_t {
struct coap_endpoint_t *next;
coap_context_t *context; /**< endpoint's context */
coap_proto_t proto; /**< protocol used on this interface */
uint16_t default_mtu; /**< default mtu for this interface */
coap_socket_t sock; /**< socket object for the interface, if
any */
coap_address_t bind_addr; /**< local interface address */
coap_session_t *sessions; /**< hash table or list of active sessions */
};
#endif /* COAP_SERVER_SUPPORT */
coap_fixed_point_t coap_multi_fixed_fixed(coap_fixed_point_t fp1,
coap_fixed_point_t fp2);
coap_fixed_point_t coap_multi_fixed_uint(coap_fixed_point_t fp1,
uint32_t u2);
coap_fixed_point_t coap_add_fixed_fixed(coap_fixed_point_t fp1,
coap_fixed_point_t fp2);
coap_fixed_point_t coap_add_fixed_uint(coap_fixed_point_t fp1,
uint32_t u2);
coap_fixed_point_t coap_sub_fixed_uint(coap_fixed_point_t fp1,
uint32_t u2);
coap_fixed_point_t coap_div_fixed_uint(coap_fixed_point_t fp1, uint32_t u2);
coap_fixed_point_t coap_get_non_timeout_random(coap_session_t *session);
coap_tick_t coap_get_non_timeout_random_ticks(coap_session_t *session);
/**
* Notify session transport has just connected and CSM exchange can now start.
*
* @param session The CoAP session.
*/
void coap_session_send_csm(coap_session_t *session);
/**
* Notify session that it has just connected or reconnected.
*
* @param session The CoAP session.
*/
void coap_session_connected(coap_session_t *session);
/**
* Notify session that it has failed. This cleans up any outstanding / queued
* transmissions, observations etc..
*
* Note: This function must be called in the locked state.
*
* @param session The CoAP session.
* @param reason The reason why the session was disconnected.
*/
void coap_session_disconnected_lkd(coap_session_t *session,
coap_nack_reason_t reason);
/**
* Send a ping message for the session.
* @param session The CoAP session.
*
* Note: This function must be called in the locked state.
*
* @return COAP_INVALID_MID if there is an error
*/
coap_mid_t coap_session_send_ping_lkd(coap_session_t *session);
/**
* Refresh the session's current Identity Hint (PSK).
* Note: A copy of @p psk_hint is maintained in the session by libcoap.
*
* @param session The current coap_session_t object.
* @param psk_hint If NULL, the Identity Hint will revert to the
* initial Identity Hint used at session setup.
*
* @return @c 1 if successful, else @c 0.
*/
int coap_session_refresh_psk_hint(coap_session_t *session,
const coap_bin_const_t *psk_hint);
/**
* Refresh the session's current pre-shared key (PSK).
* Note: A copy of @p psk_key is maintained in the session by libcoap.
*
* @param session The current coap_session_t object.
* @param psk_key If NULL, the pre-shared key will revert to the
* initial pre-shared key used at session setup.
*
* @return @c 1 if successful, else @c 0.
*/
int coap_session_refresh_psk_key(coap_session_t *session,
const coap_bin_const_t *psk_key);
/**
* Refresh the session's current pre-shared identity (PSK).
* Note: A copy of @p psk_identity is maintained in the session by libcoap.
*
* @param session The current coap_session_t object.
* @param psk_identity If NULL, the pre-shared identity will revert to the
* initial pre-shared key used as session setup.
*
* @return @c 1 if successful, else @c 0.
*/
int coap_session_refresh_psk_identity(coap_session_t *session,
const coap_bin_const_t *psk_identity);
#if COAP_SERVER_SUPPORT
/**
* Creates a new server session for the specified endpoint.
* @param ctx The CoAP context.
* @param ep An endpoint where an incoming connection request is pending.
* @param extra Available for use by any underlying network stack.
*
* @return A new CoAP session or NULL if failed. Call coap_session_release_lkd to
* add to unused queue.
*/
coap_session_t *coap_new_server_session(coap_context_t *ctx,
coap_endpoint_t *ep,
void *extra);
#endif /* COAP_SERVER_SUPPORT */
/**
* Layer function interface for layer below session accept/connect being
* established. This function initiates a CSM request for reliable protocols,
* or coap_session_connect() for un-reliable protocols.
*
* @param session Session that the lower layer accept/connect was done on.
*
*/
void coap_session_establish(coap_session_t *session);
/**
* Increment reference counter on a session.
*
* Note: This function must be called in the locked state.
*
* @param session The CoAP session.
* @return same as session
*/
coap_session_t *coap_session_reference_lkd(coap_session_t *session);
/**
* Decrement reference counter on a session.
* Note that the session may be deleted as a result and should not be used
* after this call.
*
* Note: This function must be called in the locked state.
*
* @param session The CoAP session.
*/
void coap_session_release_lkd(coap_session_t *session);
/**
* Send a pdu according to the session's protocol. This function returns
* the number of bytes that have been transmitted, or a value less than zero
* on error.
*
* @param session Session to send pdu on.
* @param pdu The pdu to send.
*
* @return The number of bytes written on success, or a value
* less than zero on error.
*/
ssize_t coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu);
ssize_t coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu,
coap_queue_t *node);
#if COAP_SERVER_SUPPORT
/**
* Lookup the server session for the packet received on an endpoint, or create
* a new one.
*
* @param endpoint Active endpoint the packet was received on.
* @param packet Received packet.
* @param now The current time in ticks.
* @return The CoAP session or @c NULL if error.
*/
coap_session_t *coap_endpoint_get_session(coap_endpoint_t *endpoint,
const coap_packet_t *packet, coap_tick_t now);
/**
* Create a new endpoint for communicating with peers.
*
* Note: This function must be called in the locked state.
*
* @param context The coap context that will own the new endpoint,
* @param listen_addr Address the endpoint will listen for incoming requests
* on or originate outgoing requests from. Use NULL to
* specify that no incoming request will be accepted and
* use a random endpoint.
* @param proto Protocol used on this endpoint,
*
* @return The new endpoint or @c NULL on failure.
*/
coap_endpoint_t *coap_new_endpoint_lkd(coap_context_t *context, const coap_address_t *listen_addr,
coap_proto_t proto);
/**
* Release an endpoint and all the structures associated with it.
*
* Note: This function must be called in the locked state.
*
* @param endpoint The endpoint to release.
*/
void coap_free_endpoint_lkd(coap_endpoint_t *endpoint);
#endif /* COAP_SERVER_SUPPORT */
/**
* Get maximum acceptable receive PDU size
*
* @param session The CoAP session.
* @return maximum PDU size, not including header (but including token).
*/
size_t coap_session_max_pdu_rcv_size(const coap_session_t *session);
/**
* Get maximum acceptable PDU size
*
* Note: This function must be called in the locked state.
*
* @param session The CoAP session.
*
* @return maximum PDU size, not including header (but including token).
*/
size_t coap_session_max_pdu_size_lkd(const coap_session_t *session);
/**
* Creates a new client session to the designated server.
*
* Note: This function must be called in the locked state.
*
* @param ctx The CoAP context.
* @param local_if Address of local interface. It is recommended to use NULL to let
* the operating system choose a suitable local interface. If an
* address is specified, the port number should be zero, which means
* that a free port is automatically selected.
* @param server The server's address. If the port number is zero, the default port
* for the protocol will be used.
* @param proto Protocol.
*
* @return A new CoAP session or NULL if failed. Call coap_session_release_lkd to free.
*/
coap_session_t *coap_new_client_session_lkd(
coap_context_t *ctx,
const coap_address_t *local_if,
const coap_address_t *server,
coap_proto_t proto
);
/**
* Creates a new client session to the designated server with PKI credentials
*
* Note: This function must be called in the locked state.
*
* @param ctx The CoAP context.
* @param local_if Address of local interface. It is recommended to use NULL to
* let the operating system choose a suitable local interface.
* If an address is specified, the port number should be zero,
* which means that a free port is automatically selected.
* @param server The server's address. If the port number is zero, the default
* port for the protocol will be used.
* @param proto CoAP Protocol.
* @param setup_data PKI parameters.
*
* @return A new CoAP session or NULL if failed. Call coap_session_release_lkd()
* to free.
*/
coap_session_t *coap_new_client_session_pki_lkd(coap_context_t *ctx,
const coap_address_t *local_if,
const coap_address_t *server,
coap_proto_t proto,
coap_dtls_pki_t *setup_data
);
/**
* Creates a new client session to the designated server with PSK credentials
*
* Note: This function must be called in the locked state.
*
* @deprecated Use coap_new_client_session_psk2_lkd() instead.
*
* @param ctx The CoAP context.
* @param local_if Address of local interface. It is recommended to use NULL to let
* the operating system choose a suitable local interface. If an
* address is specified, the port number should be zero, which means
* that a free port is automatically selected.
* @param server The server's address. If the port number is zero, the default port
* for the protocol will be used.
* @param proto Protocol.
* @param identity PSK client identity
* @param key PSK shared key
* @param key_len PSK shared key length
*
* @return A new CoAP session or NULL if failed. Call coap_session_release_lkd to free.
*/
coap_session_t *coap_new_client_session_psk_lkd(coap_context_t *ctx,
const coap_address_t *local_if,
const coap_address_t *server,
coap_proto_t proto,
const char *identity,
const uint8_t *key,
unsigned key_len
);
/**
* Creates a new client session to the designated server with PSK credentials
*
* Note: This function must be called in the locked state.
*
* @param ctx The CoAP context.
* @param local_if Address of local interface. It is recommended to use NULL to
* let the operating system choose a suitable local interface.
* If an address is specified, the port number should be zero,
* which means that a free port is automatically selected.
* @param server The server's address. If the port number is zero, the default
* port for the protocol will be used.
* @param proto CoAP Protocol.
* @param setup_data PSK parameters.
*
* @return A new CoAP session or NULL if failed. Call coap_session_release_lkd()
* to free.
*/
coap_session_t *coap_new_client_session_psk2_lkd(coap_context_t *ctx,
const coap_address_t *local_if,
const coap_address_t *server,
coap_proto_t proto,
coap_dtls_cpsk_t *setup_data
);
/**
* Create a new DTLS session for the @p session.
* Note: the @p session is released if no DTLS server session can be created.
*
* @ingroup dtls_internal
*
* @param session Session to add DTLS session to
* @param now The current time in ticks.
*
* @return CoAP session or @c NULL if error.
*/
coap_session_t *coap_session_new_dtls_session(coap_session_t *session,
coap_tick_t now);
void coap_session_free(coap_session_t *session);
void coap_session_mfree(coap_session_t *session);
void coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now);
void coap_connect_session(coap_session_t *session, coap_tick_t now);
#define COAP_SESSION_REF(s) ((s)->ref
/* RFC7252 */
#define COAP_ACK_TIMEOUT(s) ((s)->ack_timeout)
#define COAP_ACK_RANDOM_FACTOR(s) ((s)->ack_random_factor)
#define COAP_MAX_RETRANSMIT(s) ((s)->max_retransmit)
#define COAP_NSTART(s) ((s)->nstart)
#define COAP_DEFAULT_LEISURE(s) ((s)->default_leisure)
#define COAP_PROBING_RATE(s) ((s)->probing_rate)
/* RFC9177 */
#define COAP_MAX_PAYLOADS(s) ((s)->max_payloads)
#define COAP_NON_MAX_RETRANSMIT(s) ((s)->non_max_retransmit)
#define COAP_NON_TIMEOUT(s) ((s)->non_timeout)
#define COAP_NON_TIMEOUT_TICKS(s) \
(COAP_NON_TIMEOUT(s).integer_part * COAP_TICKS_PER_SECOND + \
COAP_NON_TIMEOUT(s).fractional_part * COAP_TICKS_PER_SECOND / 1000)
#define COAP_NON_RECEIVE_TIMEOUT(s) ((s)->non_receive_timeout)
#define COAP_NON_PROBING_WAIT_BASE(s) ((s)->non_probing_wait_base)
#define COAP_NON_PARTIAL_TIMEOUT(s) ((s)->non_partial_timeout)
/**
* The DEFAULT_LEISURE definition for the session (s).
*
* RFC 7252, Section 4.8
* Initial value 5.0 seconds
*/
#define COAP_DEFAULT_LEISURE_TICKS(s) \
(COAP_DEFAULT_LEISURE(s).integer_part * COAP_TICKS_PER_SECOND + \
COAP_DEFAULT_LEISURE(s).fractional_part * COAP_TICKS_PER_SECOND / 1000)
/**
* The MAX_TRANSMIT_SPAN definition for the session (s).
*
* RFC 7252, Section 4.8.2 Calculation of MAX_TRAMSMIT_SPAN
* ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT)) - 1) * ACK_RANDOM_FACTOR
*/
#define COAP_MAX_TRANSMIT_SPAN(s) \
(((s)->ack_timeout.integer_part * 1000 + (s)->ack_timeout.fractional_part) * \
((1 << ((s)->max_retransmit)) -1) * \
((s)->ack_random_factor.integer_part * 1000 + \
(s)->ack_random_factor.fractional_part) \
/ 1000000)
/**
* The MAX_TRANSMIT_WAIT definition for the session (s).
*
* RFC 7252, Section 4.8.2 Calculation of MAX_TRAMSMIT_WAIT
* ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT + 1)) - 1) * ACK_RANDOM_FACTOR
*/
#define COAP_MAX_TRANSMIT_WAIT(s) \
(((s)->ack_timeout.integer_part * 1000 + (s)->ack_timeout.fractional_part) * \
((1 << ((s)->max_retransmit + 1)) -1) * \
((s)->ack_random_factor.integer_part * 1000 + \
(s)->ack_random_factor.fractional_part) \
/ 1000000)
#define COAP_MAX_TRANSMIT_WAIT_TICKS(s) \
(COAP_MAX_TRANSMIT_WAIT(s) * COAP_TICKS_PER_SECOND)
/**
* The PROCESSING_DELAY definition for the session (s).
*
* RFC 7252, Section 4.8.2 Calculation of PROCESSING_DELAY
* PROCESSING_DELAY set to ACK_TIMEOUT
*/
#define COAP_PROCESSING_DELAY(s) \
(((s)->ack_timeout.integer_part * 1000 + (s)->ack_timeout.fractional_part + \
500) / 1000)
/**
* The MAX_RTT definition for the session (s).
*
* RFC 7252, Section 4.8.2 Calculation of MAX_RTT
* (2 * MAX_LATENCY) + PROCESSING_DELAY
*/
#define COAP_MAX_RTT(s) \
((2 * COAP_DEFAULT_MAX_LATENCY) + COAP_PROCESSING_DELAY(s))
/**
* The EXCHANGE_LIFETIME definition for the session (s).
*
* RFC 7252, Section 4.8.2 Calculation of EXCHANGE_LIFETIME
* MAX_TRANSMIT_SPAN + (2 * MAX_LATENCY) + PROCESSING_DELAY
*/
#define COAP_EXCHANGE_LIFETIME(s) \
(COAP_MAX_TRANSMIT_SPAN(s) + (2 * COAP_DEFAULT_MAX_LATENCY) + \
COAP_PROCESSING_DELAY(s))
/**
* The NON_LIFETIME definition for the session (s).
*
* RFC 7252, Section 4.8.2 Calculation of NON_LIFETIME
* MAX_TRANSMIT_SPAN + MAX_LATENCY
*/
#define COAP_NON_LIFETIME(s) \
(COAP_MAX_TRANSMIT_SPAN(s) + COAP_DEFAULT_MAX_LATENCY)
/**
* The NON_RECEIVE_TIMEOUT definition for the session (s).
*
* RFC9177 Section 6.2
* 2 * NON_TIMEOUT
*/
#define COAP_NON_RECEIVE_TIMEOUT_TICKS(s) ( \
COAP_NON_RECEIVE_TIMEOUT(s).integer_part * COAP_TICKS_PER_SECOND + \
COAP_NON_RECEIVE_TIMEOUT(s).fractional_part * COAP_TICKS_PER_SECOND / 1000)
/**
* The NON_PROBING_WAIT definition for the session (s).
*
* RFC9177 Section 6.2
* NON_PROBING_WAIT = NON_TIMEOUT * ((2 ** NON_MAX_RETRANSMIT) - 1) *
* ACK_RANDOM_FACTOR + (2 * MAX_LATENCY) + NON_TIMEOUT_RANDOM
* Default is 247-248 seconds
*/
#define COAP_NON_PROBING_WAIT(s) \
coap_add_fixed_fixed(COAP_NON_PROBING_WAIT_BASE(s), \
COAP_NON_TIMEOUT_RANDOM(s))
#define COAP_NON_PROBING_WAIT_TICKS(s) \
(COAP_NON_PROBING_WAIT(s).integer_part * COAP_TICKS_PER_SECOND + \
COAP_NON_PROBING_WAIT(s).fractional_part * COAP_TICKS_PER_SECOND / 1000)
/**
* The NON_PARTIAL_TIMEOUT definition for the session (s).
*
* RFC9177 Section 6.2
* Initial value EXCHANGE_LIFETIME (247 seconds)
*/
#define COAP_NON_PARTIAL_TIMEOUT_TICKS(s) \
(COAP_NON_PARTIAL_TIMEOUT(s).integer_part * COAP_TICKS_PER_SECOND + \
COAP_NON_PARTIAL_TIMEOUT(s).fractional_part * COAP_TICKS_PER_SECOND / 1000)
/**
* The NON_TIMEOUT_RANDOM definition for the session (s).
*
* RFC9177 Section 6.2
* Default is 2-3 seconds
*/
#define COAP_NON_TIMEOUT_RANDOM(s) \
coap_get_non_timeout_random(s)
/** @} */
#define SESSIONS_ADD(e, obj) \
HASH_ADD(hh, (e), addr_hash, sizeof((obj)->addr_hash), (obj))
#define SESSIONS_DELETE(e, obj) \
HASH_DELETE(hh, (e), (obj))
#define SESSIONS_ITER(e, el, rtmp) \
HASH_ITER(hh, (e), el, rtmp)
#define SESSIONS_ITER_SAFE(e, el, rtmp) \
for ((el) = (e); (el) && ((rtmp) = (el)->hh.next, 1); (el) = (rtmp))
#define SESSIONS_FIND(e, k, res) { \
HASH_FIND(hh, (e), &(k), sizeof(k), (res)); \
}
#endif /* COAP_SESSION_INTERNAL_H_ */
|