libcoap 4.3.2rc2

coap_netif.c
Go to the documentation of this file.
1/*
2 * coap_netif.c -- Netif functions for libcoap
3 *
4 * Copyright (C) 2023 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
17#include "coap3/coap_internal.h"
18#include "coap3/coap_session_internal.h"
19
20/*
21 * return 1 netif still in use.
22 * 0 netif no longer available.
23 */
24 int
25 coap_netif_available(coap_session_t *session) {
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 */
34 int
35 coap_netif_available_ep(coap_endpoint_t *endpoint) {
36 return endpoint->sock.flags != COAP_SOCKET_EMPTY;
37}
38
39 int
40 coap_netif_dgrm_listen(coap_endpoint_t *endpoint,
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 }
46 endpoint->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_BOUND | COAP_SOCKET_WANT_READ;
47 return 1;
48}
49#endif /* COAP_SERVER_SUPPORT */
50
51#if COAP_CLIENT_SUPPORT
52 int
53 coap_netif_dgrm_connect(coap_session_t *session, const coap_address_t *local_if,
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
72 coap_netif_dgrm_read(coap_session_t *session, coap_packet_t *packet) {
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) state %d\n",
80 coap_session_str(session), packet->length,
81 coap_socket_strerror(), session->state);
82 errno = keep_errno;
83 } else if (bytes_read > 0) {
84 coap_ticks(&session->last_rx_tx);
85 coap_log_debug("* %s: netif: recv %4zd bytes\n",
86 coap_session_str(session), bytes_read);
87 }
88 return bytes_read;
89}
90
91#if COAP_SERVER_SUPPORT
92/*
93 * dgram
94 * return +ve Number of bytes written.
95 * -1 Error error in errno).
96 * -2 ICMP error response
97 */
98ssize_t
99 coap_netif_dgrm_read_ep(coap_endpoint_t *endpoint, coap_packet_t *packet) {
100 ssize_t bytes_read;
101 int keep_errno;
102
103 bytes_read = coap_socket_recv(&endpoint->sock, packet);
104 keep_errno = errno;
105 if (bytes_read == -1) {
106 coap_log_debug("* %s: netif: failed to read %zd bytes (%s)\n",
107 coap_endpoint_str(endpoint), packet->length,
108 coap_socket_strerror());
109 errno = keep_errno;
110 } else if (bytes_read > 0) {
111 /* Let the caller do the logging as session available by then */
112 }
113 return bytes_read;
114}
115#endif /* COAP_SERVER_SUPPORT */
116
117/*
118 * dgram
119 * return +ve Number of bytes written.
120 * -1 Error error in errno).
121 */
122ssize_t
123 coap_netif_dgrm_write(coap_session_t *session, const uint8_t *data,
124 size_t datalen) {
125 ssize_t bytes_written;
126 int keep_errno;
127
128 coap_socket_t *sock = &session->sock;
129#if COAP_SERVER_SUPPORT
130 if (sock->flags == COAP_SOCKET_EMPTY) {
131 assert(session->endpoint != NULL);
132 sock = &session->endpoint->sock;
133 }
134#endif /* COAP_SERVER_SUPPORT */
135
136 bytes_written = coap_socket_send(sock, session, data, datalen);
137 keep_errno = errno;
138 if (bytes_written <= 0) {
139 coap_log_debug("* %s: netif: failed to send %zd bytes (%s) state %d\n",
140 coap_session_str(session), datalen,
141 coap_socket_strerror(), session->state);
142 errno = keep_errno;
143 } else {
144 coap_ticks(&session->last_rx_tx);
145 if (bytes_written == (ssize_t)datalen)
146 coap_log_debug("* %s: netif: sent %4zd bytes\n",
147 coap_session_str(session), bytes_written);
148 else
149 coap_log_debug("* %s: netif: sent %4zd of %4zd bytes\n",
150 coap_session_str(session), bytes_written, datalen);
151 }
152 return bytes_written;
153}
154
155#if !COAP_DISABLE_TCP
156#if COAP_SERVER_SUPPORT
157 int
158 coap_netif_strm_listen(coap_endpoint_t *endpoint,
159 const coap_address_t *listen_addr) {
160 if (!coap_socket_bind_tcp(&endpoint->sock, listen_addr,
161 &endpoint->bind_addr)) {
162 return 0;
163 }
164 endpoint->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_BOUND |
165 COAP_SOCKET_WANT_ACCEPT;
166 return 1;
167}
168
169 int
170 coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session) {
171 if (!coap_socket_accept_tcp(&endpoint->sock, &session->sock,
172 &session->addr_info.local,
173 &session->addr_info.remote)) {
174 return 0;
175 }
176 session->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_CONNECTED |
177 COAP_SOCKET_WANT_READ;
178 return 1;
179}
180#endif /* COAP_SERVER_SUPPORT */
181
182#if COAP_CLIENT_SUPPORT
183 int
184 coap_netif_strm_connect1(coap_session_t *session,
185 const coap_address_t *local_if,
186 const coap_address_t *server, int default_port) {
187 if (!coap_socket_connect_tcp1(&session->sock, local_if, server,
188 default_port,
189 &session->addr_info.local,
190 &session->addr_info.remote)) {
191 return 0;
192 }
193 return 1;
194}
195
196 int
197 coap_netif_strm_connect2(coap_session_t *session) {
198 if (!coap_socket_connect_tcp2(&session->sock,
199 &session->addr_info.local,
200 &session->addr_info.remote)) {
201 return 0;
202 }
203 return 1;
204}
205#endif /* COAP_CLIENT_SUPPORT */
206
207/*
208 * strm
209 * return >=0 Number of bytes read.
210 * -1 Error (error in errno).
211 */
212ssize_t
213 coap_netif_strm_read(coap_session_t *session, uint8_t *data, size_t datalen) {
214 ssize_t bytes_read = coap_socket_read(&session->sock, data, datalen);
215 int keep_errno = errno;
216
217 if (bytes_read >= 0) {
218 coap_log_debug("* %s: netif: recv %4zd bytes\n",
219 coap_session_str(session), bytes_read);
220 } else if (bytes_read == -1 && errno != EAGAIN) {
221 coap_log_debug("* %s: netif: failed to receive any bytes (%s) state %d\n",
222 coap_session_str(session), coap_socket_strerror(), session->state);
223 errno = keep_errno;
224 }
225 return bytes_read;
226}
227
228/*
229 * strm
230 * return +ve Number of bytes written.
231 * -1 Error (error in errno).
232 */
233ssize_t
234 coap_netif_strm_write(coap_session_t *session, const uint8_t *data,
235 size_t datalen) {
236 ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
237 int keep_errno = errno;
238
239 if (bytes_written <= 0) {
240 coap_log_debug("* %s: netif: failed to send %zd bytes (%s) state %d\n",
241 coap_session_str(session), datalen,
242 coap_socket_strerror(), session->state);
243 errno = keep_errno;
244 } else {
245 coap_ticks(&session->last_rx_tx);
246 if (bytes_written == (ssize_t)datalen)
247 coap_log_debug("* %s: netif: sent %4zd bytes\n",
248 coap_session_str(session), bytes_written);
249 else
250 coap_log_debug("* %s: netif: sent %4zd of %4zd bytes\n",
251 coap_session_str(session), bytes_written, datalen);
252 }
253 return bytes_written;
254}
255#endif /* COAP_DISABLE_TCP */
256
257 void
258 coap_netif_close(coap_session_t *session) {
259 if (coap_netif_available(session))
260 coap_socket_close(&session->sock);
261}
262
263#if COAP_SERVER_SUPPORT
264 void
265 coap_netif_close_ep(coap_endpoint_t *endpoint) {
266 coap_socket_close(&endpoint->sock);
267}
268#endif /* COAP_SERVER_SUPPORT */
coap_internal.h
Pulls together all the internal only header files.
coap_socket_read
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.
Definition: coap_io.c:692
coap_socket_close
void coap_socket_close(coap_socket_t *sock)
Function interface to close off a socket.
Definition: coap_io.c:400
coap_socket_send
ssize_t coap_socket_send(coap_socket_t *sock, const coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for data transmission.
Definition: coap_io.c:798
coap_socket_strerror
const char * coap_socket_strerror(void)
Definition: coap_io.c:1768
coap_socket_recv
ssize_t coap_socket_recv(coap_socket_t *sock, coap_packet_t *packet)
Function interface for reading data.
Definition: coap_io.c:991
coap_socket_write
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.
Definition: coap_io.c:633
coap_socket_bind_udp
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Definition: coap_io.c:92
coap_socket_connect_udp
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)
COAP_SOCKET_WANT_ACCEPT
#define COAP_SOCKET_WANT_ACCEPT
non blocking server socket is waiting for accept
Definition: coap_io_internal.h:67
COAP_SOCKET_NOT_EMPTY
#define COAP_SOCKET_NOT_EMPTY
the socket is not empty
Definition: coap_io_internal.h:62
COAP_SOCKET_BOUND
#define COAP_SOCKET_BOUND
the socket is bound
Definition: coap_io_internal.h:63
COAP_SOCKET_WANT_READ
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
Definition: coap_io_internal.h:65
COAP_SOCKET_CONNECTED
#define COAP_SOCKET_CONNECTED
the socket is connected
Definition: coap_io_internal.h:64
COAP_SOCKET_EMPTY
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
Definition: coap_io_internal.h:61
coap_session_internal.h
CoAP session internal information.
coap_ticks
void coap_ticks(coap_tick_t *)
Returns the current value of an internal tick counter.
coap_log_debug
#define coap_log_debug(...)
Definition: coap_debug.h:120
coap_endpoint_str
const char * coap_endpoint_str(const coap_endpoint_t *endpoint)
Get endpoint description.
coap_session_str
const char * coap_session_str(const coap_session_t *session)
Get session description.
Definition: coap_session.c:1881
coap_netif_strm_connect2
int coap_netif_strm_connect2(coap_session_t *session)
Layer function interface for Netif stream connect (tcp).
coap_netif_dgrm_write
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:123
coap_netif_close
void coap_netif_close(coap_session_t *session)
Layer function interface for Netif close for a session.
Definition: coap_netif.c:258
coap_netif_dgrm_listen
int coap_netif_dgrm_listen(coap_endpoint_t *endpoint, const coap_address_t *listen_addr)
Layer function interface for Netif datagram listem (udp).
coap_netif_dgrm_read
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
coap_netif_close_ep
void coap_netif_close_ep(coap_endpoint_t *endpoint)
Layer function interface for Netif close for a endpoint.
coap_netif_strm_connect1
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).
coap_netif_dgrm_read_ep
ssize_t coap_netif_dgrm_read_ep(coap_endpoint_t *endpoint, coap_packet_t *packet)
Function interface for layer data datagram receiving for endpoints.
coap_netif_strm_listen
int coap_netif_strm_listen(coap_endpoint_t *endpoint, const coap_address_t *listen_addr)
Layer function interface for Netif stream listem (tcp).
coap_netif_strm_write
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:234
coap_netif_strm_accept
int coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session)
Layer function interface for Netif stream accept.
coap_netif_dgrm_connect
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).
coap_netif_available
int coap_netif_available(coap_session_t *session)
Function interface to check whether netif for session is still available.
Definition: coap_netif.c:25
coap_netif_strm_read
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:213
coap_netif_available_ep
int coap_netif_available_ep(coap_endpoint_t *endpoint)
Function interface to check whether netif for endpoint is still available.
coap_socket_bind_tcp
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.
Definition: coap_tcp.c:204
coap_socket_connect_tcp1
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.
Definition: coap_tcp.c:43
coap_socket_accept_tcp
int coap_socket_accept_tcp(coap_socket_t *server, coap_socket_t *new_client, coap_address_t *local_addr, coap_address_t *remote_addr)
Accept a new incoming TCP session.
Definition: coap_tcp.c:299
coap_socket_connect_tcp2
int coap_socket_connect_tcp2(coap_socket_t *sock, coap_address_t *local_addr, coap_address_t *remote_addr)
Complete the TCP Connection.
Definition: coap_tcp.c:165
coap_addr_tuple_t::remote
coap_address_t remote
remote address and port
Definition: coap_io.h:56
coap_addr_tuple_t::local
coap_address_t local
local address and port
Definition: coap_io.h:57
coap_address_t
Multi-purpose address abstraction.
Definition: coap_address.h:109
coap_endpoint_t
Abstraction of virtual endpoint that can be attached to coap_context_t.
Definition: coap_session_internal.h:219
coap_endpoint_t::bind_addr
coap_address_t bind_addr
local interface address
Definition: coap_session_internal.h:226
coap_endpoint_t::sock
coap_socket_t sock
socket object for the interface, if any
Definition: coap_session_internal.h:224
coap_packet_t
Definition: coap_io_internal.h:207
coap_packet_t::length
size_t length
length of payload
Definition: coap_io_internal.h:210
coap_session_t
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
Definition: coap_session_internal.h:68
coap_session_t::endpoint
coap_endpoint_t * endpoint
session's endpoint
Definition: coap_session_internal.h:84
coap_session_t::last_rx_tx
coap_tick_t last_rx_tx
Definition: coap_session_internal.h:111
coap_session_t::sock
coap_socket_t sock
socket object for the session, if any
Definition: coap_session_internal.h:81
coap_session_t::state
coap_session_state_t state
current state of relationship with peer
Definition: coap_session_internal.h:71
coap_session_t::addr_info
coap_addr_tuple_t addr_info
remote/local address info
Definition: coap_session_internal.h:79
coap_socket_t
Definition: coap_io_internal.h:34
coap_socket_t::flags
coap_socket_flags_t flags
1 or more of COAP_SOCKET* flag values
Definition: coap_io_internal.h:46