libcoap 4.3.4-develop-9f1418e
coap_netif.c
Go to the documentation of this file.
1/*
2 * coap_netif.c -- Netif functions for libcoap
3 *
4 * Copyright (C) 2023-2024 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"
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) 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 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 coap_log_debug("* %s: netif: failed to read %zd bytes (%s)\n",
109 coap_endpoint_str(endpoint), packet->length,
111 errno = keep_errno;
112 } else if (bytes_read > 0) {
113 /* Let the caller do the logging as session available by then */
114 }
115 return bytes_read;
116}
117#endif /* COAP_SERVER_SUPPORT */
118
119/*
120 * dgram
121 * return +ve Number of bytes written.
122 * -1 Error error in errno).
123 */
124ssize_t
125coap_netif_dgrm_write(coap_session_t *session, const uint8_t *data,
126 size_t datalen) {
127 ssize_t bytes_written;
128 int keep_errno;
129
130 coap_socket_t *sock = &session->sock;
131#if COAP_SERVER_SUPPORT
132 if (sock->flags == COAP_SOCKET_EMPTY) {
133 assert(session->endpoint != NULL);
134 sock = &session->endpoint->sock;
135 }
136#endif /* COAP_SERVER_SUPPORT */
137
138 bytes_written = coap_socket_send(sock, session, data, datalen);
139 keep_errno = errno;
140 if (bytes_written <= 0) {
141 coap_log_debug("* %s: netif: failed to send %zd bytes (%s) state %d\n",
142 coap_session_str(session), datalen,
143 coap_socket_strerror(), session->state);
144 errno = keep_errno;
145 } else {
146 coap_ticks(&session->last_rx_tx);
147 if (bytes_written == (ssize_t)datalen)
148 coap_log_debug("* %s: netif: sent %4zd bytes\n",
149 coap_session_str(session), bytes_written);
150 else
151 coap_log_debug("* %s: netif: sent %4zd of %4zd bytes\n",
152 coap_session_str(session), bytes_written, datalen);
153 }
154 return bytes_written;
155}
156
157#if !COAP_DISABLE_TCP
158#if COAP_SERVER_SUPPORT
159int
161 const coap_address_t *listen_addr) {
162 if (!coap_socket_bind_tcp(&endpoint->sock, listen_addr,
163 &endpoint->bind_addr)) {
164 return 0;
165 }
168 return 1;
169}
170
171int
172coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session, void *extra) {
173 if (!coap_socket_accept_tcp(&endpoint->sock, &session->sock,
174 &session->addr_info.local,
175 &session->addr_info.remote, extra)) {
176 return 0;
177 }
180 return 1;
181}
182#endif /* COAP_SERVER_SUPPORT */
183
184#if COAP_CLIENT_SUPPORT
185int
187 const coap_address_t *local_if,
188 const coap_address_t *server, int default_port) {
189 if (!coap_socket_connect_tcp1(&session->sock, local_if, server,
190 default_port,
191 &session->addr_info.local,
192 &session->addr_info.remote)) {
193 return 0;
194 }
195 return 1;
196}
197
198int
200 if (!coap_socket_connect_tcp2(&session->sock,
201 &session->addr_info.local,
202 &session->addr_info.remote)) {
203 return 0;
204 }
205 return 1;
206}
207#endif /* COAP_CLIENT_SUPPORT */
208
209/*
210 * strm
211 * return >=0 Number of bytes read.
212 * -1 Error (error in errno).
213 */
214ssize_t
215coap_netif_strm_read(coap_session_t *session, uint8_t *data, size_t datalen) {
216 ssize_t bytes_read = coap_socket_read(&session->sock, data, datalen);
217 int keep_errno = errno;
218
219 if (bytes_read >= 0) {
220 coap_log_debug("* %s: netif: recv %4zd bytes\n",
221 coap_session_str(session), bytes_read);
222 } else if (bytes_read == -1 && errno != EAGAIN) {
223 coap_log_debug("* %s: netif: failed to receive any bytes (%s) state %d\n",
224 coap_session_str(session), coap_socket_strerror(), session->state);
225 errno = keep_errno;
226 }
227 return bytes_read;
228}
229
230/*
231 * strm
232 * return +ve Number of bytes written.
233 * -1 Error (error in errno).
234 */
235ssize_t
236coap_netif_strm_write(coap_session_t *session, const uint8_t *data,
237 size_t datalen) {
238 ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
239 int keep_errno = errno;
240
241 if (bytes_written <= 0) {
242 coap_log_debug("* %s: netif: failed to send %zd bytes (%s) state %d\n",
243 coap_session_str(session), datalen,
244 coap_socket_strerror(), session->state);
245 errno = keep_errno;
246 } else {
247 coap_ticks(&session->last_rx_tx);
248 if (bytes_written == (ssize_t)datalen)
249 coap_log_debug("* %s: netif: sent %4zd bytes\n",
250 coap_session_str(session), bytes_written);
251 else
252 coap_log_debug("* %s: netif: sent %4zd of %4zd bytes\n",
253 coap_session_str(session), bytes_written, datalen);
254 }
255 return bytes_written;
256}
257#endif /* COAP_DISABLE_TCP */
258
259void
261 if (coap_netif_available(session))
262 coap_socket_close(&session->sock);
263}
264
265#if COAP_SERVER_SUPPORT
266void
268 coap_socket_close(&endpoint->sock);
269}
270#endif /* COAP_SERVER_SUPPORT */
Pulls together all the internal only header files.
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:667
void coap_socket_close(coap_socket_t *sock)
Function interface to close off a socket.
Definition: coap_io.c:365
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:773
const char * coap_socket_strerror(void)
Definition: coap_io.c:1774
ssize_t coap_socket_recv(coap_socket_t *sock, coap_packet_t *packet)
Function interface for reading data.
Definition: coap_io.c:966
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:608
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)
#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
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
#define COAP_SOCKET_CONNECTED
the socket is connected
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
CoAP session internal information.
void coap_ticks(coap_tick_t *)
Returns the current value of an internal tick counter.
#define coap_log_debug(...)
Definition: coap_debug.h:120
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.
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:125
void coap_netif_close(coap_session_t *session)
Layer function interface for Netif close for a session.
Definition: coap_netif.c:260
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.
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:236
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:215
int coap_netif_available_ep(coap_endpoint_t *endpoint)
Function interface to check whether netif for endpoint is still available.
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:200
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
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.
Definition: coap_tcp.c:291
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:161
coap_address_t remote
remote address and port
Definition: coap_io.h:56
coap_address_t local
local address and port
Definition: coap_io.h:57
Multi-purpose address abstraction.
Definition: coap_address.h:148
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
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