Coverage Report

Created: 2024-01-26 06:23

/src/libcoap/src/coap_netif.c
Line
Count
Source (jump to first uncovered line)
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
12
/**
13
 * @file coap_netif.c
14
 * @brief CoAP Netif handling functions
15
 */
16
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
0
coap_netif_available(coap_session_t *session) {
26
0
  return session->sock.flags != COAP_SOCKET_EMPTY;
27
0
}
28
29
#if COAP_SERVER_SUPPORT
30
/*
31
 * return 1 netif still in use.
32
 *        0 netif no longer available.
33
 */
34
int
35
0
coap_netif_available_ep(coap_endpoint_t *endpoint) {
36
0
  return endpoint->sock.flags != COAP_SOCKET_EMPTY;
37
0
}
38
39
int
40
coap_netif_dgrm_listen(coap_endpoint_t *endpoint,
41
0
                       const coap_address_t *listen_addr) {
42
0
  if (!coap_socket_bind_udp(&endpoint->sock, listen_addr,
43
0
                            &endpoint->bind_addr)) {
44
0
    return 0;
45
0
  }
46
0
  endpoint->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_BOUND | COAP_SOCKET_WANT_READ;
47
0
  return 1;
48
0
}
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
0
                        const coap_address_t *server, int default_port) {
55
0
  if (!coap_socket_connect_udp(&session->sock, local_if, server,
56
0
                               default_port,
57
0
                               &session->addr_info.local,
58
0
                               &session->addr_info.remote)) {
59
0
    return 0;
60
0
  }
61
0
  return 1;
62
0
}
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
 */
71
ssize_t
72
0
coap_netif_dgrm_read(coap_session_t *session, coap_packet_t *packet) {
73
0
  ssize_t bytes_read;
74
0
  int keep_errno;
75
76
0
  bytes_read = coap_socket_recv(&session->sock, packet);
77
0
  keep_errno = errno;
78
0
  if (bytes_read == -1) {
79
0
    coap_log_debug("*  %s: netif: failed to read %zd bytes (%s) state %d\n",
80
0
                   coap_session_str(session), packet->length,
81
0
                   coap_socket_strerror(), session->state);
82
0
    errno = keep_errno;
83
0
  } else if (bytes_read > 0) {
84
0
    coap_ticks(&session->last_rx_tx);
85
0
    coap_log_debug("*  %s: netif: recv %4zd bytes\n",
86
0
                   coap_session_str(session), bytes_read);
87
0
  }
88
0
  return bytes_read;
89
0
}
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
 */
98
ssize_t
99
0
coap_netif_dgrm_read_ep(coap_endpoint_t *endpoint, coap_packet_t *packet) {
100
0
  ssize_t bytes_read;
101
0
  int keep_errno;
102
103
0
  bytes_read = coap_socket_recv(&endpoint->sock, packet);
104
0
  keep_errno = errno;
105
0
  if (bytes_read == -1) {
106
0
    coap_log_debug("*  %s: netif: failed to read %zd bytes (%s)\n",
107
0
                   coap_endpoint_str(endpoint), packet->length,
108
0
                   coap_socket_strerror());
109
0
    errno = keep_errno;
110
0
  } else if (bytes_read > 0) {
111
    /* Let the caller do the logging as session available by then */
112
0
  }
113
0
  return bytes_read;
114
0
}
115
#endif /* COAP_SERVER_SUPPORT */
116
117
/*
118
 * dgram
119
 * return +ve Number of bytes written.
120
 *         -1 Error error in errno).
121
 */
122
ssize_t
123
coap_netif_dgrm_write(coap_session_t *session, const uint8_t *data,
124
0
                      size_t datalen) {
125
0
  ssize_t bytes_written;
126
0
  int keep_errno;
127
128
0
  coap_socket_t *sock = &session->sock;
129
0
#if COAP_SERVER_SUPPORT
130
0
  if (sock->flags == COAP_SOCKET_EMPTY) {
131
0
    assert(session->endpoint != NULL);
132
0
    sock = &session->endpoint->sock;
133
0
  }
134
0
#endif /* COAP_SERVER_SUPPORT */
135
136
0
  bytes_written = coap_socket_send(sock, session, data, datalen);
137
0
  keep_errno = errno;
138
0
  if (bytes_written <= 0) {
139
0
    coap_log_debug("*  %s: netif: failed to send %zd bytes (%s) state %d\n",
140
0
                   coap_session_str(session), datalen,
141
0
                   coap_socket_strerror(), session->state);
142
0
    errno = keep_errno;
143
0
  } else {
144
0
    coap_ticks(&session->last_rx_tx);
145
0
    if (bytes_written == (ssize_t)datalen)
146
0
      coap_log_debug("*  %s: netif: sent %4zd bytes\n",
147
0
                     coap_session_str(session), bytes_written);
148
0
    else
149
0
      coap_log_debug("*  %s: netif: sent %4zd of %4zd bytes\n",
150
0
                     coap_session_str(session), bytes_written, datalen);
151
0
  }
152
0
  return bytes_written;
153
0
}
154
155
#if !COAP_DISABLE_TCP
156
#if COAP_SERVER_SUPPORT
157
int
158
coap_netif_strm_listen(coap_endpoint_t *endpoint,
159
0
                       const coap_address_t *listen_addr) {
160
0
  if (!coap_socket_bind_tcp(&endpoint->sock, listen_addr,
161
0
                            &endpoint->bind_addr)) {
162
0
    return 0;
163
0
  }
164
0
  endpoint->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_BOUND |
165
0
                          COAP_SOCKET_WANT_ACCEPT;
166
0
  return 1;
167
0
}
168
169
int
170
0
coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session, void *extra) {
171
0
  if (!coap_socket_accept_tcp(&endpoint->sock, &session->sock,
172
0
                              &session->addr_info.local,
173
0
                              &session->addr_info.remote, extra)) {
174
0
    return 0;
175
0
  }
176
0
  session->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_CONNECTED |
177
0
                         COAP_SOCKET_WANT_READ;
178
0
  return 1;
179
0
}
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
0
                         const coap_address_t *server, int default_port) {
187
0
  if (!coap_socket_connect_tcp1(&session->sock, local_if, server,
188
0
                                default_port,
189
0
                                &session->addr_info.local,
190
0
                                &session->addr_info.remote)) {
191
0
    return 0;
192
0
  }
193
0
  return 1;
194
0
}
195
196
int
197
0
coap_netif_strm_connect2(coap_session_t *session) {
198
0
  if (!coap_socket_connect_tcp2(&session->sock,
199
0
                                &session->addr_info.local,
200
0
                                &session->addr_info.remote)) {
201
0
    return 0;
202
0
  }
203
0
  return 1;
204
0
}
205
#endif /* COAP_CLIENT_SUPPORT */
206
207
/*
208
 * strm
209
 * return >=0 Number of bytes read.
210
 *         -1 Error (error in errno).
211
 */
212
ssize_t
213
0
coap_netif_strm_read(coap_session_t *session, uint8_t *data, size_t datalen) {
214
0
  ssize_t bytes_read = coap_socket_read(&session->sock, data, datalen);
215
0
  int keep_errno = errno;
216
217
0
  if (bytes_read >= 0) {
218
0
    coap_log_debug("*  %s: netif: recv %4zd bytes\n",
219
0
                   coap_session_str(session), bytes_read);
220
0
  } else if (bytes_read == -1 && errno != EAGAIN) {
221
0
    coap_log_debug("*  %s: netif: failed to receive any bytes (%s) state %d\n",
222
0
                   coap_session_str(session), coap_socket_strerror(), session->state);
223
0
    errno = keep_errno;
224
0
  }
225
0
  return bytes_read;
226
0
}
227
228
/*
229
 * strm
230
 * return +ve Number of bytes written.
231
 *         -1 Error (error in errno).
232
 */
233
ssize_t
234
coap_netif_strm_write(coap_session_t *session, const uint8_t *data,
235
0
                      size_t datalen) {
236
0
  ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
237
0
  int keep_errno = errno;
238
239
0
  if (bytes_written <= 0) {
240
0
    coap_log_debug("*  %s: netif: failed to send %zd bytes (%s) state %d\n",
241
0
                   coap_session_str(session), datalen,
242
0
                   coap_socket_strerror(), session->state);
243
0
    errno = keep_errno;
244
0
  } else {
245
0
    coap_ticks(&session->last_rx_tx);
246
0
    if (bytes_written == (ssize_t)datalen)
247
0
      coap_log_debug("*  %s: netif: sent %4zd bytes\n",
248
0
                     coap_session_str(session), bytes_written);
249
0
    else
250
0
      coap_log_debug("*  %s: netif: sent %4zd of %4zd bytes\n",
251
0
                     coap_session_str(session), bytes_written, datalen);
252
0
  }
253
0
  return bytes_written;
254
0
}
255
#endif /* COAP_DISABLE_TCP */
256
257
void
258
0
coap_netif_close(coap_session_t *session) {
259
0
  if (coap_netif_available(session))
260
0
    coap_socket_close(&session->sock);
261
0
}
262
263
#if COAP_SERVER_SUPPORT
264
void
265
0
coap_netif_close_ep(coap_endpoint_t *endpoint) {
266
0
  coap_socket_close(&endpoint->sock);
267
0
}
268
#endif /* COAP_SERVER_SUPPORT */