Register CoAP resources and handle requests asynchronously.
More...
Register CoAP resources and handle requests asynchronously.
Module. Specify USEMODULE += unicoap_server in your application's Makefile.
A CoAP resource behaves similar to an HTTP endpoint.
Registering a Resource
You can either declare a resource using static cross-file arrays (1) or manually at runtime (2).
This technique requires the CoAP Resource Declarations module. The identifier you specify with the UNICOAP_RESOURCE macro just needs to be unique, but isn't used otherwise. You will need to specify a path and a set of allowed request methods using UNICOAP_METHODS.
.handler = my_request_handler,
}
@ UNICOAP_METHOD_GET
GET request (no paylod)
@ UNICOAP_METHOD_PUT
PUT request (update resource with payload)
#define UNICOAP_RESOURCE(name)
Declares a static CoAP resource.
#define UNICOAP_METHODS(first_method,...)
Macro that builds a bit field where the i-th bit indicates the i-th request method 0....
#define UNICOAP_PATH(...)
Constructs a path.
Alternatively, you can create a new listener and manually add resources as follows. Listeners are groups of resources. Internally, all statically declared resources form a built-in listener.
{
.handler = my_request_handler,
}
};
.resources = my_resources,
};
#define ARRAY_SIZE(a)
Calculate the number of elements in a static array.
int unicoap_resource_match_request_default(const unicoap_listener_t *listener, const unicoap_resource_t **resource_ptr, const unicoap_message_t *request, const unicoap_endpoint_t *endpoint)
Default request-resource matcher for listeners.
void unicoap_listener_register(unicoap_listener_t *listener)
Makes unicoap listen for resources contained in listener.
struct unicoap_listener unicoap_listener_t
Typealias for unicoap_listener.
struct unicoap_resource unicoap_resource_t
CoAP resource.
int unicoap_listener_deregister(unicoap_listener_t *listener)
Removes listener from unicoap.
Constrained RESTful Environments (CoRE) resource
By default, unicoap registers a /.well-known/core resource, providing a list of available resources. CONFIG_UNICOAP_WELL_KNOWN_CORE allows you to customize the default behavior.
You can also customize the link encoding per listener. By default, listeners with the unicoap_listener_t::link_encoder property unset, use the built-in link encoder.
Request-resource matching
unicoap determines whether a request matches a resource in the following order. unicoap iterates over all listeners and then over all resources registered with that listener. The order of listeners follows the registration order, except the first listener is the built-in listener that handles /.well-known/core and the second may be the XFA resources listener, if present. Once a matching resource is found, no further ones are checked.
Resources that do not specify the current mode of transport in their protocol set, are not considered. In this case, unicoap behaves as if the resource does not exist. To restrict a resource to a subset of transports, set unicoap_resource_t::protocols to a value produced by UNICOAP_PROTOCOLS. Please note that unicoap considers an unset protocols property to mean "All protocols". If you want to make this explicit, use UNICOAP_PROTOCOLS_ALLOW_ALL or UNICOAP_PROTOCOLS_ALLOW_NONE.
The server then checks the path of the resource. If you supplied the UNICOAP_RESOURCE_FLAG_MATCH_SUBTREE flag, a resource registered for /foo/bar will also match subpaths such as /foo/bar/zoo and /foo/bar/zoo/loo. Then, unicoap checks whether the request method is in the set of allowed methods you specified. If the method does not match, and none of the other resources indicate a match, a Method Not Allowed CoAP response is sent. If no matching resource is found, a Not Found CoAP response is returned.
If the built-in behavior does not fit your scenario, you can customize the matching algorithm per listener. To do this, set the unicoap_listener_t::request_matcher property. By default, if this property is unset, the built-in matcher will be used.
Handling requests
When registering a resource, you must specify a request handler, even if the resource's content is statically known. To define a handler, implement a function that adheres to the signature of unicoap_request_handler_t.
Auxiliary Information
In the handler, you are given access to an auxiliary information object (aux), letting you retrieve the transport used, and both the local and client endpoint. This may be helpful if you are using a driver able to receive messages at different addresses (e.g., multiple sockets, ports, or multicast addresses). The aux also provides access to the token, and transport-specific data, such as the message ID and type if UDP or DTLS is used.
Responding
There are multiple techniques for responding.
Return status code: If you don't want to send a response payload and have no options you may want to set, you can just return a unicoap_status_t. Note that this requires you to complete all request processing before. If this is not desirable, e.g., if you are performing sensitive operations that would open a timing side channel, consider using one of the other techniques.
int my_request_handler(
) {
}
@ UNICOAP_STATUS_NOT_IMPLEMENTED
5.01 Not Implemented
Auxiliary exchange information.
Request context used to send a response to a given request.
Call send: Initialize a response message with the status code, and optionally, also payload and options. You can repurpose the memory used by the message parameter for the response, but you must not write into the payload buffer or mutate options. If you do want to send options, please allocate options using UNICOAP_OPTIONS_ALLOC. Then, pass the message and the response context you were given as part of the handler parameters to unicoap_send_response. Finally, you may inspect any errors that may have occurred while sending the response or continue processing the request. You may also directly return the result of unicoap_send_response. Please be aware any processing performed inside this handler is executed in the server's processing loop and will thus block it. Given an expensive operation, we encourage you to switch to the third technique. Nevertheless, this should be the preferred response technique for most applications. unicoap_send_response can fail, and you are responsible for handling that error. You may retry to send it, or to send an Internal Server Error or similar codes instead.
int my_request_handler(
) {
}
@ UNICOAP_STATUS_CONTENT
2.05 Content
int unicoap_send_response(unicoap_message_t *response, unicoap_request_context_t *context)
Sends a response to a request identifier by the given context.
- Defer the response: This technique is not available yet.
|
| static bool | unicoap_path_is_root (const unicoap_pathspec_t *path) |
| | Determines whether the given path is the root path.
|
| |
| size_t | unicoap_path_component_count (const unicoap_pathspec_t *path) |
| | Counts path components in path.
|
| |
| bool | unicoap_path_is_equal (const unicoap_pathspec_t *lhs, const unicoap_pathspec_t *rhs) |
| | Compares two path objects.
|
| |
| bool | unicoap_path_matches_options (const unicoap_pathspec_t *path, const unicoap_options_t *options, bool match_subtree) |
| | Compares Uri-Path options against path object.
|
| |
| bool | unicoap_path_matches_string (const unicoap_pathspec_t *path, const char *string, size_t string_length, bool match_subtree) |
| | Compares UTF-8 string path against path object.
|
| |
| ssize_t | unicoap_path_stringify (const unicoap_pathspec_t *path, char *buffer, size_t capacity) |
| | Writes path into buffer, with path components separated by /
|
| |
| void | unicoap_print_path (const unicoap_pathspec_t *path) |
| | Prints given path object as serialized path.
|
| |
| #define | UNICOAP_PATH(...) |
| | Constructs a path.
|
| |
| #define | UNICOAP_PATH_ROOT ((unicoap_pathspec_t) { ._components = NULL }) |
| | The root path /
|
| |
| #define | UNICOAP_PATH_RESOURCE_DISCOVERY UNICOAP_PATH(".well-known", "core") |
| | The path for resource discovery (/.well-known/core)
|
| |
◆ UNICOAP_IGNORING_REQUEST
| #define UNICOAP_IGNORING_REQUEST (-2042) |
◆ UNICOAP_METHOD_FLAG
| #define UNICOAP_METHOD_FLAG |
( |
| method | ) |
|
Value:
A bit set at the position dictated by method.
- Parameters
-
| method | The method to turn into a flag |
- Returns
1 << method
Definition at line 670 of file server.h.
◆ UNICOAP_METHODS
| #define UNICOAP_METHODS |
( |
| first_method, |
|
|
| ... ) |
Value:
#define UNICOAP_BITFIELD(...)
Creates a bitfield where each argument i indicates the i-th bit is to be set.
Macro that builds a bit field where the i-th bit indicates the i-th request method 0.0i
- See also
- unicoap_resource_t::flags
Use this macro to create a bitfield of allowed methods for a given CoAP resource:
You can also use regular bitwise operators, such as OR, AND, XOR, and NOT. UNICOAP_METHODS is a homomorphism preserving the | operator.
==
@ UNICOAP_METHOD_POST
POST request (resource processes payload)
Definition at line 691 of file server.h.
◆ UNICOAP_METHODS_ALL
| #define UNICOAP_METHODS_ALL (0xff) |
◆ UNICOAP_PATH
| #define UNICOAP_PATH |
( |
| ... | ) |
|
Value:
_UNICOAP_TRY_CHECK_PATH_COMPONENTS(__VA_ARGS__) ? NULL : NULL } })
An immutable path object.
Constructs a path.
- Parameters
-
| ... | Path components as string literals |
You must not pass a NULL path component.
UNICOAP_PATH("foo", "bar") corresponds to /foo/bar. To create the root path /, use UNICOAP_PATH_ROOT instead.
Definition at line 90 of file server.h.
◆ UNICOAP_PATH_RESOURCE_DISCOVERY
| #define UNICOAP_PATH_RESOURCE_DISCOVERY UNICOAP_PATH(".well-known", "core") |
The path for resource discovery (/.well-known/core)
Definition at line 99 of file server.h.
◆ UNICOAP_PATH_ROOT
The root path /
Definition at line 95 of file server.h.
◆ UNICOAP_PROTOCOL_FLAG
| #define UNICOAP_PROTOCOL_FLAG |
( |
| proto | ) |
|
Value:
A bit set at the position dictated by proto.
- Parameters
-
| proto | The protocol number to turn into a flag |
- Returns
1 << proto
Definition at line 713 of file server.h.
◆ UNICOAP_PROTOCOLS
| #define UNICOAP_PROTOCOLS |
( |
| first_proto, |
|
|
| ... ) |
Value:
Macro creating a bit field describing the specified protocols.
- See also
- unicoap_resource_t::flags
Use this macro to create a bitfield of allowed protocols for a given CoAP resource:
#define UNICOAP_PROTOCOLS(first_proto,...)
Macro creating a bit field describing the specified protocols.
@ UNICOAP_PROTO_UDP
CoAP over UDP endpoint.
Definition at line 726 of file server.h.
◆ UNICOAP_PROTOCOLS_ALLOW_ALL
| #define UNICOAP_PROTOCOLS_ALLOW_ALL (0) |
◆ UNICOAP_PROTOCOLS_ALLOW_NONE
| #define UNICOAP_PROTOCOLS_ALLOW_NONE (1) |
◆ unicoap_link_encoder_t
Handler function to write a resource link.
- Parameters
-
| [in] | resource | Resource for link |
| [out] | buffer | Buffer on which to write |
| [in] | capacity | Remaining length for buffer |
| [in] | context | Contextual information on what/how to write |
- Return values
-
| Number | of bytes written to buffer |
| `-1` | on error |
Definition at line 496 of file server.h.
◆ unicoap_listener_t
◆ unicoap_method_set_t
◆ unicoap_proto_set_t
◆ unicoap_request_handler_t
Resource request handler.
This handler is called whenever a request reaches the given resource. If you use a certain handler for more than one resource, you may want to read unicoap_request_context_t::resource.
- Parameters
-
| [in] | request | Request, safe to mutate and send response with mutated message. |
| [in] | aux | Auxiliary data associated with the request |
| [in] | ctx | Request context, use to send response. |
| [in] | arg | Argument specified in resource definition |
If you do not call unicoap_send_response and return a negative value from the handler, an Internal Server Error response will be sent.
- Returns
0, status code or errno.
- Return values
-
| UNICOAP_IGNORING_REQUEST | iff you don't want to respond |
| unicoap_status_t | for an otherwise empty response |
Definition at line 246 of file server.h.
◆ unicoap_request_matcher_t
Handler function for the request matcher strategy.
- Parameters
-
| [in] | listener | Listener |
| [out] | resource | Matching resource |
| [in] | request | Request message |
| [in] | endpoint | Remote endpoint the request originates from |
- Return values
-
| Zero | if resource is found and matcher determined request matches resource definition |
| Non-zero | CoAP status code appropriate for the mismatch |
Definition at line 537 of file server.h.
◆ unicoap_resource_t
CoAP resource.
Definition at line 202 of file server.h.
◆ unicoap_resource_flags_t
Flags for enabling advanced features in server exchanges.
Specify these flags when creating a unicoap_resource_t to modify transmission, block-wise, or resource observation behavior.
| Enumerator |
|---|
| UNICOAP_RESOURCE_FLAG_RELIABLE | Sets the type of the message to confirmable (CON), if an unreliable transport is used.
This flag is ignored with reliable transports. For unreliable transports, a message sent with this flag will require an acknowledgement to be sent from the CoAP peer.
|
| UNICOAP_RESOURCE_FLAG_MATCH_SUBTREE | Makes this resource match paths located in the subtree of the given path.
Example: A request with path /laniakea/milky-way/solar-system/pluto would match a resource with this flag and path /laniakea/milky-way.
|
Definition at line 310 of file server.h.
◆ unicoap_listener_deregister()
Removes listener from unicoap.
- Precondition
listener is a valid pointer to a single listener
- Parameters
-
| [in] | listener | Listener containing the resources. |
- Returns
- Negative integer on error, zero on success.
- Return values
-
| `-ENOENT` | if the given listener is not registered with unicoap. |
◆ unicoap_listener_register()
Makes unicoap listen for resources contained in listener.
- Precondition
listener is a valid pointer to a single listener (that is, listener->next == NULL). You must ensure the memory pointed at remains initialized until the listener is deregistered. This may never happen or happen implicitly when unicoap is deinitialized. We recommend you statically allocate the listener and its resources.
- Note
- If you are tempted to register a pre-linked chain of listeners, consider placing all their resources in the resources array of a single listener instead.
- Parameters
-
| [in] | listener | Listener containing the resources. |
◆ unicoap_match_proto()
Returns whether the given proto is allowed according to the protocols argument.
- Parameters
-
| protocols | Protocols bit field, each set bit's position corresponds to a proto allowed |
| proto | Proto to be checked |
- See also
- UNICOAP_PROTOCOLS_ALLOW_ALL
Definition at line 745 of file server.h.
◆ unicoap_path_component_count()
Counts path components in path.
- Parameters
-
| [in] | path | Path whose components to count |
- Returns
- Returns the number of path components in
path
A path component is the sequence of characters between slashes in a URI path, excluding the / separator, and excluding any null-terminators.
- Note
- Note that for root paths, this function will return zero.
◆ unicoap_path_is_equal()
Compares two path objects.
- Parameters
-
| [in] | lhs | Left-hand side path |
| [in] | rhs | Right-hand side path |
- Returns
- A boolean value determining whether the two paths object correspond to the same path
◆ unicoap_path_is_root()
Determines whether the given path is the root path.
- Parameters
-
| [in] | path | Path to check for root equality |
- Returns
- A boolean value indicating whether the given
path corresponds to /.
Definition at line 106 of file server.h.
◆ unicoap_path_matches_options()
Compares Uri-Path options against path object.
- Parameters
-
| [in] | path | Path object to match against |
| [in] | options | Options object with Uri-Path options |
| match_subtree | A boolean determining whether the aggregate path of Uri-Path options is permitted to be longer than the given path. If false, both path and options must have exactly the same number of path components (or Uri-Path options, respectively). |
- Returns
- A boolean value indicating whether the two paths match.
◆ unicoap_path_matches_string()
| bool unicoap_path_matches_string |
( |
const unicoap_pathspec_t * | path, |
|
|
const char * | string, |
|
|
size_t | string_length, |
|
|
bool | match_subtree ) |
Compares UTF-8 string path against path object.
- Parameters
-
| [in] | path | Path object to match against |
| [in] | string | String path, not necessarily null-terminated, with path components separated by possibly multiple slash separators (/) |
| string_length | Number of UTF-8 code units aka. bytes in string (excluding terminator) |
| match_subtree | A boolean determining whether string is permitted to have more path components than the given path. If false, both path and string must have exactly the same number of path components. |
This function ignores trailing slashes in string
◆ unicoap_path_stringify()
| ssize_t unicoap_path_stringify |
( |
const unicoap_pathspec_t * | path, |
|
|
char * | buffer, |
|
|
size_t | capacity ) |
Writes path into buffer, with path components separated by /
- Parameters
-
| [in] | path | Path object to serialize |
| [out] | buffer | UTF-8 buffer to write path string into |
| capacity | Number of free UTF-8 code units (bytes) available in buffer |
- Note
- This function does not null-terminate.
The resulting path string will always begin with a leading slash. A root path will result in a path string consisting of just the component separator /.
- Returns
- Number of UTF-8 code units (bytes) used to represent the serialized path or negative error number
- Return values
-
| `-ENOBUFS` | if buffer lacks capacity to store path |
◆ unicoap_print_methods()
Prints methods bitfield.
- Parameters
-
| methods | Set of CoAP methods |
◆ unicoap_print_path()
Prints given path object as serialized path.
- Parameters
-
| [in] | path | Path object to serialize and print |
- Note
- The path can be of arbitrary length.
◆ unicoap_print_protocols()
Prints protocols bitfield.
- Parameters
-
| protocols | Set of allowed transports |
◆ unicoap_print_resource()
Prints CoAP resource definition properties.
- Parameters
-
◆ unicoap_print_resource_flags()
Prints resource flags.
- Parameters
-
◆ unicoap_resource_core_link_format_build()
| ssize_t unicoap_resource_core_link_format_build |
( |
char * | buffer, |
|
|
size_t | capacity, |
|
|
unicoap_proto_t | proto ) |
Builds a string in Constrained RESTful Environments (CoRE) Link Format.
You use this method to build a stringified list of resources registered with unicoap. To register a resource, use unicoap_listener_register or CoAP Resource Declarations. The string generated contains only resources available using the specified transport. When handling a request destined for /.well-known/core, you should call this method with the transport you received the request over.
Example:
</sensors/temp>;rt="temperature-c",
</sensors/light>;rt="light-lux"
- See also
- Constrained RESTful Environments (CoRE) Link Format
- Parameters
-
| [in,out] | buffer | The buffer that will contain the built string in CoRE Link Format |
| capacity | The capacity buffer in bytes |
| proto | The unicoap protocol number of the transport |
- Returns
- Length of encoded resource list in bytes or negative integer on error
◆ unicoap_resource_encode_link()
Encodes given resource in Constrained RESTful Environments (CoRE) Link Format.
- Parameters
-
| [in] | resource | The CoAP resource to encode |
| [out] | buffer | Pointer to where encoded resource string will be written |
| capacity | The capacity of buffer in bytes |
| [in,out] | context | Encoding context |
- Precondition
buffer must no be NULL.
- Returns
- Length of encoded resource string in bytes or negative integer on error
- Return values
-
| `ENOBUFS` | Buffer too small to encode resources in link format. |
◆ unicoap_resource_match_method()
Returns whether the method is allowed according to the given methods.
- Parameters
-
| methods | Methods bit field, each set bit's position corresponds to a method allowed |
| method | Method to be checked |
Definition at line 703 of file server.h.
◆ unicoap_resource_match_path_options()
Determines whether the complete Uri-Path matches the resources path.
- Parameters
-
| [in] | resource | Resource to check for matching path |
| [in] | options | Options to read URI path from |
This function obeys the UNICOAP_RESOURCE_FLAG_MATCH_SUBTREE flag.
- Returns
- A boolean value indicating whether the given resource matches the path in
options.
Definition at line 653 of file server.h.
◆ unicoap_resource_match_path_string()
| static bool unicoap_resource_match_path_string |
( |
const unicoap_resource_t * | resource, |
|
|
const char * | path, |
|
|
size_t | length ) |
|
inlinestatic |
◆ unicoap_response_is_optional()
Determines if the client is interested in a response.
- Parameters
-
| [in] | options | Request options |
| status | The CoAP status code you would respond with |
- Return values
-
| `false` | if a response with that status code must be sent |
| `true` | if sending a response with that status code is not mandatory |
◆ unicoap_response_status_from_errno()
Maps a given errno to a CoAP response status code.
- Parameters
-
| _errno | Error number such as -ENOENT |
- Returns
- Status code
◆ unicoap_send_response()
Sends a response to a request identifier by the given context.
Consumes response .
- Warning
- You MUST NOT call this method after having deferred a response.
- Parameters
-
| [in,out] | response | Response message to send |
| [in,out] | context | Request context to respond in |
This function's return value can be used as a return value in unicoap_request_handler_t. If this function fails, you may retry or send another response instead. You can call this method in the given context for as long as it keeps failing. Once it succeeds, the context is consumed and is longer eligible for further send_response calls.
- Return values
-
| Zero | on success. |
| Negative | integer on error |