net: lib: coap: Introduce net mgmt events for CoAP

Allow users to register net mgmt events callbacks for CoAP events.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
This commit is contained in:
Pieter De Gendt 2023-11-29 16:53:09 +01:00 committed by Fabio Baltieri
parent f712441840
commit 5182dd24c6
3 changed files with 153 additions and 4 deletions

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2023 Basalte bv
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief CoAP Events code public header
*/
#ifndef ZEPHYR_INCLUDE_NET_COAP_MGMT_H_
#define ZEPHYR_INCLUDE_NET_COAP_MGMT_H_
#include <zephyr/net/net_mgmt.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief CoAP Manager Events
* @defgroup coap_mgmt CoAP Manager Events
* @ingroup networking
* @{
*/
/** @cond INTERNAL_HIDDEN */
/* CoAP events */
#define _NET_COAP_LAYER NET_MGMT_LAYER_L4
#define _NET_COAP_CODE 0x1c0
#define _NET_COAP_IF_BASE (NET_MGMT_EVENT_BIT | \
NET_MGMT_LAYER(_NET_COAP_LAYER) | \
NET_MGMT_LAYER_CODE(_NET_COAP_CODE))
struct coap_service;
struct coap_resource;
struct coap_observer;
/** @endcond */
enum net_event_coap_cmd {
/* Service events */
NET_EVENT_COAP_CMD_SERVICE_STARTED = 1,
NET_EVENT_COAP_CMD_SERVICE_STOPPED,
/* Observer events */
NET_EVENT_COAP_CMD_OBSERVER_ADDED,
NET_EVENT_COAP_CMD_OBSERVER_REMOVED,
};
/**
* @brief coap_mgmt event raised when a service has started
*/
#define NET_EVENT_COAP_SERVICE_STARTED \
(_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_SERVICE_STARTED)
/**
* @brief coap_mgmt event raised when a service has stopped
*/
#define NET_EVENT_COAP_SERVICE_STOPPED \
(_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_SERVICE_STOPPED)
/**
* @brief coap_mgmt event raised when an observer has been added to a resource
*/
#define NET_EVENT_COAP_OBSERVER_ADDED \
(_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_OBSERVER_ADDED)
/**
* @brief coap_mgmt event raised when an observer has been removed from a resource
*/
#define NET_EVENT_COAP_OBSERVER_REMOVED \
(_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_OBSERVER_REMOVED)
/**
* @brief CoAP Service event structure.
*/
struct net_event_coap_service {
/* The CoAP service for which the event is emitted */
const struct coap_service *service;
};
/**
* @brief CoAP Observer event structure.
*/
struct net_event_coap_observer {
/* The CoAP resource for which the event is emitted */
struct coap_resource *resource;
/* The observer that is added/removed */
struct coap_observer *observer;
};
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* ZEPHYR_INCLUDE_NET_COAP_MGMT_H_ */

View file

@ -23,6 +23,7 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL);
#include <zephyr/net/net_ip.h> #include <zephyr/net/net_ip.h>
#include <zephyr/net/net_core.h> #include <zephyr/net/net_core.h>
#include <zephyr/net/coap.h> #include <zephyr/net/coap.h>
#include <zephyr/net/coap_mgmt.h>
#define COAP_PATH_ELEM_DELIM '/' #define COAP_PATH_ELEM_DELIM '/'
#define COAP_PATH_ELEM_QUERY '?' #define COAP_PATH_ELEM_QUERY '?'
@ -1844,6 +1845,25 @@ void coap_observer_init(struct coap_observer *observer,
net_ipaddr_copy(&observer->addr, addr); net_ipaddr_copy(&observer->addr, addr);
} }
static inline void coap_observer_raise_event(struct coap_resource *resource,
struct coap_observer *observer,
uint32_t mgmt_event)
{
#ifdef CONFIG_NET_MGMT_EVENT_INFO
const struct net_event_coap_observer net_event = {
.resource = resource,
.observer = observer,
};
net_mgmt_event_notify_with_info(mgmt_event, NULL, (void *)&net_event, sizeof(net_event));
#else
ARG_UNUSED(resource);
ARG_UNUSED(observer);
net_mgmt_event_notify(mgmt_event, NULL);
#endif
}
bool coap_register_observer(struct coap_resource *resource, bool coap_register_observer(struct coap_resource *resource,
struct coap_observer *observer) struct coap_observer *observer)
{ {
@ -1856,13 +1876,21 @@ bool coap_register_observer(struct coap_resource *resource,
resource->age = 2; resource->age = 2;
} }
coap_observer_raise_event(resource, observer, NET_EVENT_COAP_OBSERVER_ADDED);
return first; return first;
} }
bool coap_remove_observer(struct coap_resource *resource, bool coap_remove_observer(struct coap_resource *resource,
struct coap_observer *observer) struct coap_observer *observer)
{ {
return sys_slist_find_and_remove(&resource->observers, &observer->list); if (!sys_slist_find_and_remove(&resource->observers, &observer->list)) {
return false;
}
coap_observer_raise_event(resource, observer, NET_EVENT_COAP_OBSERVER_REMOVED);
return true;
} }
static bool sockaddr_equal(const struct sockaddr *a, static bool sockaddr_equal(const struct sockaddr *a,

View file

@ -14,6 +14,7 @@ LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL);
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/net/coap.h> #include <zephyr/net/coap.h>
#include <zephyr/net/coap_link_format.h> #include <zephyr/net/coap_link_format.h>
#include <zephyr/net/coap_mgmt.h>
#include <zephyr/net/coap_service.h> #include <zephyr/net/coap_service.h>
#ifdef CONFIG_ARCH_POSIX #ifdef CONFIG_ARCH_POSIX
#include <fcntl.h> #include <fcntl.h>
@ -345,6 +346,21 @@ static inline bool coap_service_in_section(const struct coap_service *service)
STRUCT_SECTION_END(coap_service) > service; STRUCT_SECTION_END(coap_service) > service;
} }
static inline void coap_service_raise_event(const struct coap_service *service, uint32_t mgmt_event)
{
#if defined(CONFIG_NET_MGMT_EVENT_INFO)
const struct net_event_coap_service net_event = {
.service = service,
};
net_mgmt_event_notify_with_info(mgmt_event, NULL, (void *)&net_event, sizeof(net_event));
#else
ARG_UNUSED(service);
net_mgmt_event_notify(mgmt_event, NULL);
#endif
}
int coap_service_start(const struct coap_service *service) int coap_service_start(const struct coap_service *service)
{ {
int ret; int ret;
@ -446,6 +462,8 @@ end:
coap_server_update_services(); coap_server_update_services();
coap_service_raise_event(service, NET_EVENT_COAP_SERVICE_STARTED);
return ret; return ret;
close: close:
@ -469,17 +487,18 @@ int coap_service_stop(const struct coap_service *service)
k_mutex_lock(&lock, K_FOREVER); k_mutex_lock(&lock, K_FOREVER);
if (service->data->sock_fd < 0) { if (service->data->sock_fd < 0) {
ret = -EALREADY; k_mutex_unlock(&lock);
goto end; return -EALREADY;
} }
/* Closing a socket will trigger a poll event */ /* Closing a socket will trigger a poll event */
ret = zsock_close(service->data->sock_fd); ret = zsock_close(service->data->sock_fd);
service->data->sock_fd = -1; service->data->sock_fd = -1;
end:
k_mutex_unlock(&lock); k_mutex_unlock(&lock);
coap_service_raise_event(service, NET_EVENT_COAP_SERVICE_STOPPED);
return ret; return ret;
} }