Loading...
Searching...
No Matches
transport.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024-2026 Carl Seifert
3 * SPDX-FileCopyrightText: 2024-2026 TU Dresden
4 * SPDX-License-Identifier: LGPL-2.1-only
5 */
6
7#pragma once
8
9#include <stdbool.h>
10#include <stdint.h>
11#include "iolist.h"
12
13#include "timex.h"
14#include "uri_parser.h"
15#include "modules.h"
16
17#include "net/sock.h"
18#include "net/sock/udp.h"
19
20#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT) || defined(DOXYGEN)
21# include "net/sock/async/event.h"
22# include "net/sock/util.h"
23# include "net/sock/tcp.h"
24#endif
25
26#if IS_USED(MODULE_UNICOAP_DRIVER_DTLS) || defined(DOXYGEN)
27# include "net/sock/dtls.h"
28#endif
29
30#if IS_USED(MODULE_UNICOAP_DRIVER_SLIPMUX) || defined(DOXYGEN)
31# include "slipdev.h"
32#endif
33
34/* MARK: unicoap_driver_extension_point */
35
36#include "net/unicoap/message.h"
37#include "net/unicoap/options.h"
38
45
51
52#ifdef __cplusplus
53extern "C" {
54#endif
55
56/* MARK: - CoAP URI schemes */
67#define UNICOAP_SCHEME "coap"
68
72#define UNICOAP_SCHEME_UDP "coap"
73
77#define UNICOAP_SCHEME_DTLS "coaps"
78
82#define UNICOAP_SCHEME_TCP "coap+tcp"
83
87#define UNICOAP_SCHEME_TLS "coaps+tcp"
88
92#define UNICOAP_SCHEME_WEBSOCKET "coap+ws"
93
97#define UNICOAP_SCHEME_WEBSOCKET_TLS "coaps+ws"
98
102#define UNICOAP_SCHEME_BLE_GATT "coap"
103
107#define UNICOAP_SCHEME_SLIPMUX "coap+uart"
108
115#define UNICOAP_DOMAIN_BLE ".ble.arpa"
116
117/* MARK: unicoap_driver_extension_point */
119
120/* MARK: - Endpoints */
130#define UNICOAP_PROTO_UNSPECIFIED (0)
131
135#define UNICOAP_PROTO_FLAG_RELIABLE_TRANSPORT (1)
136
142typedef enum {
145
148
151
152 /* MARK: unicoap_driver_extension_point */
153} __attribute__((__packed__)) unicoap_proto_t;
154
166{
168}
169
186{
187 switch (proto) {
190 return true;
192 return false;
193 /* If a new transport driver does not use RIOT's socket API,
194 * such as CoAP over GATT, return false here. */
195 /* MARK: unicoap_driver_extension_point */
196 default:
197 return false;
198 }
199}
200
204typedef struct {
207
208 union {
209 /* union members are guaranteed to start at offset zero */
210
211#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT) || defined(DOXYGEN)
214
215 /* _tl_ep acts as a view on both udp_ep and dtls_ep. */
216
219
222#endif /* IS_USED(MODULE_UNICOAP_SOCK_SUPPORT) || defined(DOXYGEN) */
223#if IS_USED(MODULE_UNICOAP_DRIVER_SLIPMUX) || defined(DOXYGEN)
224 slipdev_t *slipmux_ep;
225#endif /* IS_USED(MODULE_UNICOAP_DRIVER_SLIPMUX) || defined(DOXYGEN) */
226 /* MARK: unicoap_driver_extension_point */
227 };
229
241{
242 (void)endpoint;
243#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT)
244 return &endpoint->udp_ep;
245#else
246 return NULL;
247#endif
248}
249
261{
262 (void)endpoint;
263#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT)
264 return &endpoint->dtls_ep;
265#else
266 return NULL;
267#endif
268}
269
270#ifndef DOXYGEN
280static inline struct _sock_tl_ep* _unicoap_endpoint_get_tl(unicoap_endpoint_t* endpoint)
281{
282 (void)endpoint;
283# if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT)
284 return &endpoint->_tl_ep;
285# else
286 return NULL;
287# endif
288}
289#endif /* !defined(DOXYGEN) */
290
297 (void)endpoint;
298#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT)
300 (_unicoap_endpoint_get_tl(endpoint)->family == AF_INET6 ||
301 _unicoap_endpoint_get_tl(endpoint)->family == AF_UNSPEC)) {
302 return (ipv6_addr_t*)_unicoap_endpoint_get_tl(endpoint)->addr.ipv6;
303 }
304 else {
305 return NULL;
306 }
307#else
308 return NULL;
309#endif
310 /* Other drivers may also use IPv6 addresses but not sock_tl... */
311 /* MARK: unicoap_driver_extension_point */
312}
313
320 (void)endpoint;
321#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT)
323 (_unicoap_endpoint_get_tl(endpoint)->family == AF_INET ||
324 _unicoap_endpoint_get_tl(endpoint)->family == AF_UNSPEC)) {
325 return (ipv4_addr_t*)_unicoap_endpoint_get_tl(endpoint)->addr.ipv4;
326 }
327 else {
328 return NULL;
329 }
330#else
331 return NULL;
332#endif
333 /* Other drivers may also use IPv4 addresses but not sock_tl... */
334 /* MARK: unicoap_driver_extension_point */
335}
336
343 (void)endpoint;
344#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT)
346 return &_unicoap_endpoint_get_tl(endpoint)->family;
347 } else {
348 return NULL;
349 }
350#else
351 return NULL;
352#endif
353 /* Other drivers may also use 16-bit ports but not sock_tl... */
354 /* MARK: unicoap_driver_extension_point */
355}
356
362static inline uint16_t* unicoap_endpoint_get_port(unicoap_endpoint_t* endpoint) {
363 (void)endpoint;
364#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT)
366 return &_unicoap_endpoint_get_tl(endpoint)->port;
367 } else {
368 return NULL;
369 }
370#else
371 return NULL;
372#endif
373 /* Other drivers may also use 16-bit ports but not sock_tl... */
374 /* MARK: unicoap_driver_extension_point */
375}
376
382static inline uint16_t* unicoap_endpoint_get_netif_id(unicoap_endpoint_t* endpoint) {
383 (void)endpoint;
384#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT)
386 return &_unicoap_endpoint_get_tl(endpoint)->netif;
387 } else {
388 return NULL;
389 }
390#else
391 return NULL;
392#endif
393 /* Other drivers may also use 16-bit ports but not sock_tl... */
394 /* MARK: unicoap_driver_extension_point */
395}
396
397
398/* MARK: - Request destinations */
403
417
421typedef struct {
423 union {
426
428 const char* uri;
429
431 const char* host;
432 } remote;
433
434 /* Note that the string length is placed here rather than being in a union with uri and one
435 * one with host inside the remote union above. This way, the string length would be considered
436 * a separate bitfield; but the goal is to utilise the trailing 2 bytes (at least). */
437
439 uint16_t _string_length : 10;
440
441#if !defined(DOXYGEN)
442 /* Placeholder for wider type field below and future flags. */
443 uint8_t _rfu : 3;
444#endif
445
449
466
467#if !defined(DOXYGEN)
468# define _UNICOAP_DESTINATION_STRING_LENGTH_MAX ((1 << 10) - 1)
469#endif
470
486static inline unicoap_destination_t unicoap_destination_host(const char* host, size_t length)
487{
488 assert(length < _UNICOAP_DESTINATION_STRING_LENGTH_MAX);
490 .remote.host = host,
491 ._string_length = (uint16_t)length };
492}
493
506{
508 .remote.host = host,
509 ._string_length = strlen(host) };
510}
511
527static inline unicoap_destination_t unicoap_destination_uri(const char* uri, size_t length)
528{
529 assert(length < _UNICOAP_DESTINATION_STRING_LENGTH_MAX);
531 .remote.uri = uri,
532 ._string_length = (uint16_t)length };
533}
534
547{
549 .remote.uri = uri,
550 ._string_length = strlen(uri) };
551}
552
553
554/* MARK: - Conversions and Tools */
559
573int unicoap_proto_from_scheme_and_host(const char* scheme, size_t scheme_length,
574 const char* host, size_t length);
575
587 const char* scheme, const char* host)
588{
589 return unicoap_proto_from_scheme_and_host(scheme, strlen(scheme), host, strlen(host));
590}
591
601
609
619 const unicoap_endpoint_t* destination);
620
628
634#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT) || defined(DOXYGEN)
636#else
637static inline void unicoap_print_sock_tl_ep(const void* ep)
638{
639 (void)ep;
640 assert(false);
641}
642#endif
651
656/* MARK: - Sockets */
662#if IS_USED(MODULE_UNICOAP_DRIVER_UDP) || defined(DOXYGEN)
664#else
665static inline
667{
668 return NULL;
669}
670#endif
671
672#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT) || defined(DOXYGEN)
673/* sock_udp_t requires an implementation which is not present if someone uses unicoap
674 * without a driver, i.e., just message APIs. In this case, unicoap_sock_support is not imported. */
675
688# if IS_USED(MODULE_UNICOAP_DRIVER_UDP) || defined(DOXYGEN)
690# else
691static inline
693{
694 (void)socket;
695 (void)local;
696 return 0;
697}
698# endif
699
708# if IS_USED(MODULE_UNICOAP_DRIVER_UDP) || defined(DOXYGEN)
710# else
711static inline
713{
714 (void)socket;
715 return 0;
716}
717# endif
718#endif /* IS_USED(MODULE_UNICOAP_SOCK_SUPPORT) || defined(DOXYGEN) */
721
726/* MARK: - Sockets */
732#if IS_USED(MODULE_UNICOAP_DRIVER_DTLS) || defined(DOXYGEN)
734#else
735static inline
737{
738 return NULL;
739}
740#endif
741
742#if IS_USED(MODULE_UNICOAP_SOCK_SUPPORT) || defined(DOXYGEN)
743/* sock_udp_t requires an implementation which is not present if someone uses unicoap
744 * without a driver, i.e., just message APIs. In this case, unicoap_sock_support is not imported. */
745
762# if IS_USED(MODULE_UNICOAP_DRIVER_DTLS) || defined(DOXYGEN)
764 sock_udp_ep_t* local);
765# else
766static inline
767int unicoap_transport_dtls_add_socket(void* socket, void* base_socket, void* local)
768{
769 (void) socket;
770 (void) base_socket;
771 (void) local;
772 return 0;
773}
774# endif
775
787# if IS_USED(MODULE_UNICOAP_DRIVER_DTLS) || defined(DOXYGEN)
789# else
790static inline
792{
793 (void) socket;
794 return 0;
795}
796# endif
797#endif /* IS_USED(MODULE_UNICOAP_SOCK_SUPPORT) || defined(DOXYGEN) */
799
800/* MARK: - Utils */
824
825
827
832/* MARK: - Manually parsing a CoAP URI */
848 unicoap_options_t* options);
851
852#ifdef __cplusplus
853}
854#endif
#define AF_INET
internetwork address family: UDP, TCP, etc.
Definition af.h:35
#define AF_INET6
internetwork address family with IPv6: UDP, TCP, etc.
Definition af.h:37
#define AF_UNSPEC
unspecified address family (as macro)
Definition af.h:29
#define assert(cond)
abort the program if assertion is false
Definition assert.h:143
struct sock_udp sock_udp_t
forward declare for async
Definition types.h:136
struct sock_dtls sock_dtls_t
forward declare for async
Definition types.h:44
struct _sock_tl_ep sock_udp_ep_t
An end point for a UDP sock object.
Definition udp.h:292
int unicoap_uri_populate(uri_parser_result_t *parsed, unicoap_endpoint_t *endpoint, unicoap_options_t *options)
Populates endpoint and CoAP options with URI parser result.
sock_dtls_t * unicoap_transport_dtls_get_socket(void)
Returns the internal DTLS socket.
int unicoap_transport_dtls_add_socket(sock_dtls_t *socket, sock_udp_t *base_socket, sock_udp_ep_t *local)
Adds DTLS socket for client and server functionality.
sock_udp_t * unicoap_transport_udp_get_socket(void)
Returns the internal UDP socket.
int unicoap_transport_dtls_remove_socket(sock_dtls_t *socket)
Removes DTLS socket previously added manually.
int unicoap_transport_udp_add_socket(sock_udp_t *socket, sock_udp_ep_t *local)
Adds UDP socket for client and server functionality.
int unicoap_transport_udp_remove_socket(sock_udp_t *socket)
Removes UDP socket previously added manually.
unicoap_proto_t
Transport protocol CoAP is used over.
Definition transport.h:142
#define UNICOAP_PROTO_FLAG_RELIABLE_TRANSPORT
Protocol number flag indicating the transport is considered reliable on its own.
Definition transport.h:135
static unicoap_destination_t unicoap_destination_host(const char *host, size_t length)
Creates destination identifier from hostname string.
Definition transport.h:486
void unicoap_print_endpoint(const unicoap_endpoint_t *endpoint)
Prints the given CoAP endpoint.
static unicoap_destination_t unicoap_destination_uri(const char *uri, size_t length)
Creates destination identifier from URI string.
Definition transport.h:527
const char * unicoap_scheme_from_proto(unicoap_proto_t proto)
Returns scheme from protocol number.
unicoap_destination_type_t
Resource identifier type.
Definition transport.h:407
const char * unicoap_string_from_proto(unicoap_proto_t proto)
Returns scheme from protocol number.
static unicoap_destination_t unicoap_destination_uri_string(const char *uri)
Creates destination identifier from URI string.
Definition transport.h:546
static unicoap_destination_t unicoap_destination_host_string(const char *host)
Creates destination identifier from null-terminated hostname string.
Definition transport.h:505
static uint16_t * unicoap_endpoint_get_port(unicoap_endpoint_t *endpoint)
Retrieves port from endpoint, if present and supported by endpoint type.
Definition transport.h:362
static int unicoap_transport_proto_from_scheme_and_host_string(const char *scheme, const char *host)
Converts a given null-terminated scheme string like coap+tcp to the corresponding protocol identifier...
Definition transport.h:586
static sock_udp_ep_t * unicoap_endpoint_get_udp(unicoap_endpoint_t *endpoint)
Retrieves UDP endpoint from CoAP endpoint.
Definition transport.h:240
static ipv6_addr_t * unicoap_endpoint_get_ipv6_addr(unicoap_endpoint_t *endpoint)
Retrieves IPv6 address from endpoint, if present and supported by endpoint type.
Definition transport.h:296
void unicoap_print_sock_tl_ep(const struct _sock_tl_ep *ep)
Prints the given transport layer endpoint.
static bool unicoap_transport_is_reliable(unicoap_proto_t proto)
Determines whether the given transport protocol is reliable.
Definition transport.h:165
static ipv4_addr_t * unicoap_endpoint_get_ipv4_addr(unicoap_endpoint_t *endpoint)
Retrieves IPv4 address from endpoint, if present and supported by endpoint type.
Definition transport.h:319
static uint16_t * unicoap_endpoint_get_netif_id(unicoap_endpoint_t *endpoint)
Retrieves network interface ID from endpoint, if present and supported by endpoint type.
Definition transport.h:382
int unicoap_proto_from_scheme_and_host(const char *scheme, size_t scheme_length, const char *host, size_t length)
Converts a given scheme string like coap+tcp to the corresponding protocol identifier.
bool unicoap_endpoint_is_equal(const unicoap_endpoint_t *source, const unicoap_endpoint_t *destination)
Compares two endpoints.
static bool unicoap_transport_uses_sock_tl_ep(unicoap_proto_t proto)
Determines whether the given transport driver uses a transport layer socket in RIOT.
Definition transport.h:185
static int * unicoap_endpoint_get_address_family(unicoap_endpoint_t *endpoint)
Retrieves address family from endpoint, if present and supported by endpoint type.
Definition transport.h:342
bool unicoap_endpoint_is_multicast(const unicoap_endpoint_t *endpoint)
Determines whether the given endpoint is a multicast endpoint.
static unicoap_destination_t unicoap_destination_endpoint(unicoap_endpoint_t *endpoint)
Creates destination identifier from endpoint.
Definition transport.h:461
static sock_udp_ep_t * unicoap_endpoint_get_dtls(unicoap_endpoint_t *endpoint)
Retrieves DTLS endpoint from CoAP endpoint.
Definition transport.h:260
@ UNICOAP_PROTO_UDP
CoAP over UDP endpoint.
Definition transport.h:144
@ UNICOAP_PROTO_SLIPMUX
CoAP over Slipmux endpoint.
Definition transport.h:150
@ UNICOAP_PROTO_DTLS
CoAP over DTLS over UDP endpoint.
Definition transport.h:147
@ UNICOAP_DESTINATION_ENDPOINT
Endpoint.
Definition transport.h:409
@ UNICOAP_DESTINATION_HOST
Hostname.
Definition transport.h:412
@ UNICOAP_DESTINATION_URI
URI (Uniform Resource Identifier)
Definition transport.h:415
int socket(int domain, int type, int protocol)
Create an endpoint for communication.
iolist scatter / gather IO
CoAP Message API.
Common macros and compiler attributes/pragmas configuration.
Asynchronous sock using Event Queue definitions.
Options umbrella header.
SLIP device definitions.
DTLS sock definitions.
TCP sock definitions.
UDP sock definitions.
Common sock API definitions.
Common IP-based transport layer end point.
Definition sock.h:211
int family
family of sock_ip_ep_t::addr
Definition sock.h:217
Device descriptor for slipdev.
Definition slipdev.h:162
Auxiliary exchange information.
Definition transport.h:808
const unicoap_message_properties_t * properties
Message properties.
Definition transport.h:822
const unicoap_endpoint_t * local
The local CoAP endpoint in this exchange.
Definition transport.h:817
const unicoap_endpoint_t * remote
The remote CoAP endpoint in this exchange.
Definition transport.h:812
A type abstracting over CoAP resource identifiers.
Definition transport.h:421
const char * uri
URI string, if identified by UNICOAP_DESTINATION_URI.
Definition transport.h:428
const char * host
Hostname, if identified by UNICOAP_DESTINATION_HOST.
Definition transport.h:431
unicoap_endpoint_t * endpoint
Endpoint itself, if identified by UNICOAP_DESTINATION_ENDPOINT.
Definition transport.h:425
unicoap_destination_type_t type
The type of this identifier.
Definition transport.h:447
uint16_t _string_length
Number of ASCII code units (bytes)
Definition transport.h:439
A CoAP endpoint.
Definition transport.h:204
sock_udp_ep_t dtls_ep
RIOT sock DTLS endpoint.
Definition transport.h:221
struct _sock_tl_ep _tl_ep
Transport layer endpoint.
Definition transport.h:213
unicoap_proto_t proto
Protocol number.
Definition transport.h:206
sock_udp_ep_t udp_ep
RIOT sock UDP endpoint.
Definition transport.h:218
Properties of a CoAP message.
Definition message.h:297
CoAP options container.
Definition base.h:97
container that holds all results
Definition uri_parser.h:38
Utility library for comparing and computing timestamps.
Data type to represent an IPv4 address.
Definition addr.h:55
Data type to represent an IPv6 address.
Definition addr.h:64
sock utility function definitions