libcoap 4.3.5-develop-490e4e0
Loading...
Searching...
No Matches
coap_netif.c
Go to the documentation of this file.
1/*
2 * coap_netif.c -- Netif functions for libcoap
3 *
4 * Copyright (C) 2023-2025 Jon Shallow <supjps-libcoap@jpshallow.com>
5 *
6 * SPDX-License-Identifier: BSD-2-Clause
7 *
8 * This file is part of the CoAP library libcoap. Please see README for terms
9 * of use.
10 */
11
19
20/*
21 * return 1 netif still in use.
22 * 0 netif no longer available.
23 */
24int
26 return session->sock.flags != COAP_SOCKET_EMPTY;
27}
28
29#if COAP_SERVER_SUPPORT
30/*
31 * return 1 netif still in use.
32 * 0 netif no longer available.
33 */
34int
36 return endpoint->sock.flags != COAP_SOCKET_EMPTY;
37}
38
39int
41 const coap_address_t *listen_addr) {
42 if (!coap_socket_bind_udp(&endpoint->sock, listen_addr,
43 &endpoint->bind_addr)) {
44 return 0;
45 }
47 return 1;
48}
49#endif /* COAP_SERVER_SUPPORT */
50
51#if COAP_CLIENT_SUPPORT
52int
54 const coap_address_t *server, int default_port) {
55 if (!coap_socket_connect_udp(&session->sock, local_if, server,
56 default_port,
57 &session->addr_info.local,
58 &session->addr_info.remote)) {
59 return 0;
60 }
61 return 1;
62}
63#endif /* COAP_CLIENT_SUPPORT */
64
65/*
66 * dgram
67 * return +ve Number of bytes written.
68 * -1 Error error in errno).
69 * -2 ICMP error response
70 */
71ssize_t
73 ssize_t bytes_read;
74 int keep_errno;
75
76 bytes_read = coap_socket_recv(&session->sock, packet);
77 keep_errno = errno;
78 if (bytes_read == -1) {
79 coap_log_debug("* %s: netif: failed to read %zd bytes (%s (%d)) state %d\n",
80 coap_session_str(session), packet->length,
81 coap_socket_strerror(), keep_errno, session->state);
82 errno = keep_errno;
83 } else if (bytes_read > 0) {
84 coap_ticks(&session->last_rx_tx);
85 memcpy(&session->addr_info, &packet->addr_info,
86 sizeof(session->addr_info));
87 coap_log_debug("* %s: netif: recv %4zd bytes\n",
88 coap_session_str(session), bytes_read);
89 }
90 return bytes_read;
91}
92
93#if COAP_SERVER_SUPPORT
94/*
95 * dgram
96 * return +ve Number of bytes written.
97 * -1 Error error in errno).
98 * -2 ICMP error response
99 */
100ssize_t
102 ssize_t bytes_read;
103 int keep_errno;
104
105 bytes_read = coap_socket_recv(&endpoint->sock, packet);
106 keep_errno = errno;
107 if (bytes_read == -1) {
108 if (errno != EAGAIN) {
109 coap_log_debug("* %s: netif: failed to read %zd bytes (%s)\n",
110 coap_endpoint_str(endpoint), packet->length,
112 errno = keep_errno;
113 }
114 } else if (bytes_read > 0) {
115 /* Let the caller do the logging as session available by then */
116 }
117 return bytes_read;
118}
119#endif /* COAP_SERVER_SUPPORT */
120
121/*
122 * dgram
123 * return +ve Number of bytes written.
124 * -1 Error error in errno).
125 */
126ssize_t
127coap_netif_dgrm_write(coap_session_t *session, const uint8_t *data,
128 size_t datalen) {
129 ssize_t bytes_written;
130 int keep_errno;
131
132 coap_socket_t *sock = &session->sock;
133#if COAP_SERVER_SUPPORT
134 if (sock->flags == COAP_SOCKET_EMPTY) {
135 if (session->endpoint != NULL)
136 sock = &session->endpoint->sock;
137 }
138#endif /* COAP_SERVER_SUPPORT */
139
140 bytes_written = coap_socket_send(sock, session, data, datalen);
141 keep_errno = errno;
142 if (bytes_written <= 0) {
143 coap_log_debug("* %s: netif: failed to send %zd bytes (%s (%d)) state %d\n",
144 coap_session_str(session), datalen,
145 coap_socket_strerror(), errno, session->state);
146 errno = keep_errno;
147 } else {
148 coap_ticks(&session->last_rx_tx);
149 if (bytes_written == (ssize_t)datalen)
150 coap_log_debug("* %s: netif: sent %4zd bytes\n",
151 coap_session_str(session), bytes_written);
152 else
153 coap_log_debug("* %s: netif: sent %4zd of %4zd bytes\n",
154 coap_session_str(session), bytes_written, datalen);
155 }
156 return bytes_written;
157}
158
159void
164
165#if !COAP_DISABLE_TCP
166#if COAP_SERVER_SUPPORT
167int
169 const coap_address_t *listen_addr) {
170 if (!coap_socket_bind_tcp(&endpoint->sock, listen_addr,
171 &endpoint->bind_addr)) {
172 return 0;
173 }
176 return 1;
177}
178
179int
180coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session, void *extra) {
181 if (!coap_socket_accept_tcp(&endpoint->sock, &session->sock,
182 &session->addr_info.local,
183 &session->addr_info.remote, extra)) {
184 return 0;
185 }
188 return 1;
189}
190#endif /* COAP_SERVER_SUPPORT */
191
192#if COAP_CLIENT_SUPPORT
193int
195 const coap_address_t *local_if,
196 const coap_address_t *server, int default_port) {
197 if (!coap_socket_connect_tcp1(&session->sock, local_if, server,
198 default_port,
199 &session->addr_info.local,
200 &session->addr_info.remote)) {
201 return 0;
202 }
203 return 1;
204}
205
206int
208 if (!coap_socket_connect_tcp2(&session->sock,
209 &session->addr_info.local,
210 &session->addr_info.remote)) {
211 return 0;
212 }
213 return 1;
214}
215#endif /* COAP_CLIENT_SUPPORT */
216
217/*
218 * strm
219 * return >=0 Number of bytes read.
220 * -1 Error (error in errno).
221 */
222ssize_t
223coap_netif_strm_read(coap_session_t *session, uint8_t *data, size_t datalen) {
224 ssize_t bytes_read = coap_socket_read(&session->sock, data, datalen);
225 int keep_errno = errno;
226
227 if (bytes_read >= 0) {
228 coap_log_debug("* %s: netif: recv %4zd bytes\n",
229 coap_session_str(session), bytes_read);
230 } else if (bytes_read == -1 && errno != EAGAIN) {
231 coap_log_debug("* %s: netif: failed to receive any bytes (%s) state %d\n",
232 coap_session_str(session), coap_socket_strerror(), session->state);
233 errno = keep_errno;
234 }
235 return bytes_read;
236}
237
238/*
239 * strm
240 * return +ve Number of bytes written.
241 * -1 Error (error in errno).
242 */
243ssize_t
244coap_netif_strm_write(coap_session_t *session, const uint8_t *data,
245 size_t datalen) {
246 ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
247 int keep_errno = errno;
248
249 if (bytes_written <= 0) {
250 coap_log_debug("* %s: netif: failed to send %zd bytes (%s) state %d\n",
251 coap_session_str(session), datalen,
252 coap_socket_strerror(), session->state);
253 errno = keep_errno;
254 } else {
255 coap_ticks(&session->last_rx_tx);
256 if (bytes_written == (ssize_t)datalen)
257 coap_log_debug("* %s: netif: sent %4zd bytes\n",
258 coap_session_str(session), bytes_written);
259 else
260 coap_log_debug("* %s: netif: sent %4zd of %4zd bytes\n",
261 coap_session_str(session), bytes_written, datalen);
262 }
263 return bytes_written;
264}
265
266void
271#endif /* COAP_DISABLE_TCP */
272
273#if COAP_SERVER_SUPPORT
274void
276 if (COAP_PROTO_NOT_RELIABLE(endpoint->proto)) {
277 coap_socket_dgrm_close(&endpoint->sock);
278#if ! COAP_DISABLE_TCP
279 } else {
280 coap_socket_strm_close(&endpoint->sock);
281#endif /* ! COAP_DISABLE_TCP */
282 }
283}
284#endif /* COAP_SERVER_SUPPORT */
const char * coap_socket_strerror(void)
Definition coap_io.c:814
#define COAP_SOCKET_WANT_ACCEPT
non blocking server socket is waiting for accept
#define COAP_SOCKET_NOT_EMPTY
the socket is not empty
#define COAP_SOCKET_BOUND
the socket is bound
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
#define COAP_SOCKET_CONNECTED
the socket is connected
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
Library specific build wrapper for coap_internal.h.
CoAP session internal information.
void coap_ticks(coap_tick_t *t)
Returns the current value of an internal tick counter.
Definition coap_time.c:90
int coap_socket_connect_udp(coap_socket_t *sock, const coap_address_t *local_if, const coap_address_t *server, int default_port, coap_address_t *local_addr, coap_address_t *remote_addr)
Create a new UDP socket and 'connect' it to the address tuple.
ssize_t coap_socket_recv(coap_socket_t *sock, coap_packet_t *packet)
Function interface for reading data.
ssize_t coap_socket_send(coap_socket_t *sock, coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for data transmission.
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Create a new UDP socket and then listen for new incoming UDP sessions to the specified IP address and...
void coap_socket_dgrm_close(coap_socket_t *sock)
Function interface to close off a datagram socket.
#define coap_log_debug(...)
Definition coap_debug.h:126
const char * coap_endpoint_str(const coap_endpoint_t *endpoint)
Get endpoint description.
const char * coap_session_str(const coap_session_t *session)
Get session description.
void coap_netif_dgrm_close(coap_session_t *session)
Layer function interface for netif datagram close for a session.
Definition coap_netif.c:160
int coap_netif_strm_connect2(coap_session_t *session)
Layer function interface for Netif stream connect (tcp).
ssize_t coap_netif_dgrm_write(coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for netif datagram data transmission.
Definition coap_netif.c:127
int coap_netif_dgrm_listen(coap_endpoint_t *endpoint, const coap_address_t *listen_addr)
Layer function interface for Netif datagram listem (udp).
ssize_t coap_netif_dgrm_read(coap_session_t *session, coap_packet_t *packet)
Function interface for layer data datagram receiving for sessions.
Definition coap_netif.c:72
void coap_netif_close_ep(coap_endpoint_t *endpoint)
Layer function interface for Netif close for a endpoint.
int coap_netif_strm_connect1(coap_session_t *session, const coap_address_t *local_if, const coap_address_t *server, int default_port)
Layer function interface for Netif stream connect (tcp).
ssize_t coap_netif_dgrm_read_ep(coap_endpoint_t *endpoint, coap_packet_t *packet)
Function interface for layer data datagram receiving for endpoints.
int coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session, void *extra)
Layer function interface for Netif stream accept.
void coap_netif_strm_close(coap_session_t *session)
Layer function interface for netif stream close for a session.
Definition coap_netif.c:267
int coap_netif_strm_listen(coap_endpoint_t *endpoint, const coap_address_t *listen_addr)
Layer function interface for Netif stream listem (tcp).
ssize_t coap_netif_strm_write(coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for netif stream data transmission.
Definition coap_netif.c:244
int coap_netif_dgrm_connect(coap_session_t *session, const coap_address_t *local_if, const coap_address_t *server, int default_port)
Layer function interface for Netif datagram connect (udp).
int coap_netif_available(coap_session_t *session)
Function interface to check whether netif for session is still available.
Definition coap_netif.c:25
ssize_t coap_netif_strm_read(coap_session_t *session, uint8_t *data, size_t datalen)
Function interface for layer data stream receiving.
Definition coap_netif.c:223
int coap_netif_available_ep(coap_endpoint_t *endpoint)
Function interface to check whether netif for endpoint is still available.
#define COAP_PROTO_NOT_RELIABLE(p)
int coap_socket_bind_tcp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Create a new TCP socket and then listen for new incoming TCP sessions.
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
Function interface for data stream receiving off a socket.
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
Function interface for data stream sending off a socket.
int coap_socket_connect_tcp1(coap_socket_t *sock, const coap_address_t *local_if, const coap_address_t *server, int default_port, coap_address_t *local_addr, coap_address_t *remote_addr)
Create a new TCP socket and initiate the connection.
int coap_socket_accept_tcp(coap_socket_t *server, coap_socket_t *new_client, coap_address_t *local_addr, coap_address_t *remote_addr, void *extra)
Accept a new incoming TCP session.
void coap_socket_strm_close(coap_socket_t *sock)
Function interface to close off a stream socket.
int coap_socket_connect_tcp2(coap_socket_t *sock, coap_address_t *local_addr, coap_address_t *remote_addr)
Complete the TCP Connection.
coap_address_t remote
remote address and port
Definition coap_io.h:60
coap_address_t local
local address and port
Definition coap_io.h:61
Multi-purpose address abstraction.
Abstraction of virtual endpoint that can be attached to coap_context_t.
coap_address_t bind_addr
local interface address
coap_socket_t sock
socket object for the interface, if any
coap_proto_t proto
protocol used on this interface
size_t length
length of payload
coap_addr_tuple_t addr_info
local and remote addresses
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
coap_endpoint_t * endpoint
session's endpoint
coap_socket_t sock
socket object for the session, if any
coap_session_state_t state
current state of relationship with peer
coap_addr_tuple_t addr_info
remote/local address info
coap_socket_flags_t flags
1 or more of COAP_SOCKET* flag values