diff --git a/examples/coap-client.c b/examples/coap-client.c index b215f6e0..3e624a49 100644 --- a/examples/coap-client.c +++ b/examples/coap-client.c @@ -357,6 +357,8 @@ event_handler(coap_session_t *session COAP_UNUSED, case COAP_EVENT_SESSION_CONNECTED: case COAP_EVENT_SESSION_FAILED: case COAP_EVENT_PARTIAL_BLOCK: + case COAP_EVENT_SERVER_SESSION_NEW: + case COAP_EVENT_SERVER_SESSION_DEL: default: break; } diff --git a/examples/coap-server.c b/examples/coap-server.c index a2bed7d4..f4849efe 100644 --- a/examples/coap-server.c +++ b/examples/coap-server.c @@ -1632,6 +1632,8 @@ proxy_event_handler(coap_session_t *session, case COAP_EVENT_SESSION_CONNECTED: case COAP_EVENT_SESSION_FAILED: case COAP_EVENT_PARTIAL_BLOCK: + case COAP_EVENT_SERVER_SESSION_NEW: + case COAP_EVENT_SERVER_SESSION_DEL: default: break; } diff --git a/include/coap3/coap_event.h b/include/coap3/coap_event.h index 81c96c64..4cf9104b 100644 --- a/include/coap3/coap_event.h +++ b/include/coap3/coap_event.h @@ -56,7 +56,32 @@ typedef enum coap_event_t { /** * (Q-)BLOCK receive errors */ - COAP_EVENT_PARTIAL_BLOCK = 0x3001 + COAP_EVENT_PARTIAL_BLOCK = 0x3001, + +/** + * @defgroup srv_sess_state_events Server session state management events + * @{ + */ + +/** + * Called in the CoAP IO loop if a new *server-side* session is created due + * to an incoming connection. + * + * Note that the session might not be a fully established connection yet, + * it might also refer to, e.g., a DTLS session in a handshake stage. + */ + COAP_EVENT_SERVER_SESSION_NEW = 0x4001, + +/** + * Called in the CoAP IO loop if a server session is deleted (e.g., due to + * inactivity or because the maximum number of idle sessions was exceeded). + * + * The session will still contain valid data when the event handler is + * called. + */ + COAP_EVENT_SERVER_SESSION_DEL = 0x4002 + +/** @} */ } coap_event_t; /** diff --git a/man/coap_handler.txt.in b/man/coap_handler.txt.in index cd39c8dd..273dfb8e 100644 --- a/man/coap_handler.txt.in +++ b/man/coap_handler.txt.in @@ -207,6 +207,15 @@ COAP_EVENT_TCP_FAILED 0x1003 COAP_EVENT_SESSION_CONNECTED 0x2001 COAP_EVENT_SESSION_CLOSED 0x2002 COAP_EVENT_SESSION_FAILED 0x2003 +/** + * (Q-)BLOCK receive errors + */ +COAP_EVENT_PARTIAL_BLOCK 0x3001 +/** + * Server session state management events + */ +COAP_EVENT_SERVER_SESSION_NEW 0x4001 +COAP_EVENT_SERVER_SESSION_DEL 0x4002 ---- EXAMPLES diff --git a/src/coap_io.c b/src/coap_io.c index a8a6486f..d51febc6 100644 --- a/src/coap_io.c +++ b/src/coap_io.c @@ -1121,6 +1121,7 @@ coap_io_prepare_io(coap_context_t *ctx, s->delayqueue == NULL && (s->last_rx_tx + session_timeout <= now || s->state == COAP_SESSION_STATE_NONE)) { + coap_handle_event(ctx, COAP_EVENT_SERVER_SESSION_DEL, s); coap_session_free(s); } else { if (s->type == COAP_SESSION_TYPE_SERVER && s->ref == 0 && s->delayqueue == NULL) { diff --git a/src/coap_session.c b/src/coap_session.c index 0db7944b..390cc360 100644 --- a/src/coap_session.c +++ b/src/coap_session.c @@ -635,11 +635,13 @@ coap_endpoint_get_session(coap_endpoint_t *endpoint, if (endpoint->context->max_idle_sessions > 0 && num_idle >= endpoint->context->max_idle_sessions) { + coap_handle_event(oldest->context, COAP_EVENT_SERVER_SESSION_DEL, oldest); coap_session_free(oldest); } else if (oldest_hs) { coap_log(LOG_WARNING, "***%s: Incomplete session timed out\n", coap_session_str(oldest_hs)); + coap_handle_event(oldest_hs->context, COAP_EVENT_SERVER_SESSION_DEL, oldest_hs); coap_session_free(oldest_hs); } @@ -700,6 +702,7 @@ coap_endpoint_get_session(coap_endpoint_t *endpoint, return NULL; } } + session = coap_make_session(endpoint->proto, COAP_SESSION_TYPE_SERVER, &addr_hash, &packet->addr_info.local, &packet->addr_info.remote, @@ -714,6 +717,7 @@ coap_endpoint_get_session(coap_endpoint_t *endpoint, SESSIONS_ADD(endpoint->sessions, session); coap_log(LOG_DEBUG, "***%s: session %p: new incoming session\n", coap_session_str(session), (void *)session); + coap_handle_event(session->context, COAP_EVENT_SERVER_SESSION_NEW, session); } return session; } @@ -1251,6 +1255,9 @@ coap_session_t *coap_new_server_session( coap_session_str(session), (void *)session); /* Returned session may already have been released and is now NULL */ session = coap_session_accept(session); + if(session) { + coap_handle_event(session->context, COAP_EVENT_SERVER_SESSION_NEW, session); + } } return session;