Loading...
Searching...
No Matches
coap_netif.c
Go to the documentation of this file.
/*
* coap_netif.c -- Netif functions for libcoap
*
* Copyright (C) 2023-2024 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#include "coap3/coap_libcoap_build.h"
#include "coap3/coap_session_internal.h"
/*
* return 1 netif still in use.
* 0 netif no longer available.
*/
int
coap_netif_available(coap_session_t *session) {
return session->sock.flags != COAP_SOCKET_EMPTY;
}
#if COAP_SERVER_SUPPORT
/*
* return 1 netif still in use.
* 0 netif no longer available.
*/
int
coap_netif_available_ep(coap_endpoint_t *endpoint) {
return endpoint->sock.flags != COAP_SOCKET_EMPTY;
}
int
coap_netif_dgrm_listen(coap_endpoint_t *endpoint,
const coap_address_t *listen_addr) {
if (!coap_socket_bind_udp(&endpoint->sock, listen_addr,
&endpoint->bind_addr)) {
return 0;
}
endpoint->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_BOUND | COAP_SOCKET_WANT_READ;
return 1;
}
#endif /* COAP_SERVER_SUPPORT */
#if COAP_CLIENT_SUPPORT
int
coap_netif_dgrm_connect(coap_session_t *session, const coap_address_t *local_if,
const coap_address_t *server, int default_port) {
if (!coap_socket_connect_udp(&session->sock, local_if, server,
default_port,
&session->addr_info.local,
&session->addr_info.remote)) {
return 0;
}
return 1;
}
#endif /* COAP_CLIENT_SUPPORT */
/*
* dgram
* return +ve Number of bytes written.
* -1 Error error in errno).
* -2 ICMP error response
*/
ssize_t
coap_netif_dgrm_read(coap_session_t *session, coap_packet_t *packet) {
ssize_t bytes_read;
int keep_errno;
bytes_read = coap_socket_recv(&session->sock, packet);
keep_errno = errno;
if (bytes_read == -1) {
coap_log_debug("* %s: netif: failed to read %zd bytes (%s) state %d\n",
coap_session_str(session), packet->length,
coap_socket_strerror(), session->state);
errno = keep_errno;
} else if (bytes_read > 0) {
coap_ticks(&session->last_rx_tx);
memcpy(&session->addr_info, &packet->addr_info,
sizeof(session->addr_info));
coap_log_debug("* %s: netif: recv %4zd bytes\n",
coap_session_str(session), bytes_read);
}
return bytes_read;
}
#if COAP_SERVER_SUPPORT
/*
* dgram
* return +ve Number of bytes written.
* -1 Error error in errno).
* -2 ICMP error response
*/
ssize_t
coap_netif_dgrm_read_ep(coap_endpoint_t *endpoint, coap_packet_t *packet) {
ssize_t bytes_read;
int keep_errno;
bytes_read = coap_socket_recv(&endpoint->sock, packet);
keep_errno = errno;
if (bytes_read == -1) {
coap_log_debug("* %s: netif: failed to read %zd bytes (%s)\n",
coap_endpoint_str(endpoint), packet->length,
coap_socket_strerror());
errno = keep_errno;
} else if (bytes_read > 0) {
/* Let the caller do the logging as session available by then */
}
return bytes_read;
}
#endif /* COAP_SERVER_SUPPORT */
/*
* dgram
* return +ve Number of bytes written.
* -1 Error error in errno).
*/
ssize_t
coap_netif_dgrm_write(coap_session_t *session, const uint8_t *data,
size_t datalen) {
ssize_t bytes_written;
int keep_errno;
coap_socket_t *sock = &session->sock;
#if COAP_SERVER_SUPPORT
if (sock->flags == COAP_SOCKET_EMPTY) {
assert(session->endpoint != NULL);
sock = &session->endpoint->sock;
}
#endif /* COAP_SERVER_SUPPORT */
bytes_written = coap_socket_send(sock, session, data, datalen);
keep_errno = errno;
if (bytes_written <= 0) {
coap_log_debug("* %s: netif: failed to send %zd bytes (%s) state %d\n",
coap_session_str(session), datalen,
coap_socket_strerror(), session->state);
errno = keep_errno;
} else {
coap_ticks(&session->last_rx_tx);
if (bytes_written == (ssize_t)datalen)
coap_log_debug("* %s: netif: sent %4zd bytes\n",
coap_session_str(session), bytes_written);
else
coap_log_debug("* %s: netif: sent %4zd of %4zd bytes\n",
coap_session_str(session), bytes_written, datalen);
}
return bytes_written;
}
#if !COAP_DISABLE_TCP
#if COAP_SERVER_SUPPORT
int
coap_netif_strm_listen(coap_endpoint_t *endpoint,
const coap_address_t *listen_addr) {
if (!coap_socket_bind_tcp(&endpoint->sock, listen_addr,
&endpoint->bind_addr)) {
return 0;
}
endpoint->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_BOUND |
COAP_SOCKET_WANT_ACCEPT;
return 1;
}
int
coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session, void *extra) {
if (!coap_socket_accept_tcp(&endpoint->sock, &session->sock,
&session->addr_info.local,
&session->addr_info.remote, extra)) {
return 0;
}
session->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_CONNECTED |
COAP_SOCKET_WANT_READ;
return 1;
}
#endif /* COAP_SERVER_SUPPORT */
#if COAP_CLIENT_SUPPORT
int
coap_netif_strm_connect1(coap_session_t *session,
const coap_address_t *local_if,
const coap_address_t *server, int default_port) {
if (!coap_socket_connect_tcp1(&session->sock, local_if, server,
default_port,
&session->addr_info.local,
&session->addr_info.remote)) {
return 0;
}
return 1;
}
int
coap_netif_strm_connect2(coap_session_t *session) {
if (!coap_socket_connect_tcp2(&session->sock,
&session->addr_info.local,
&session->addr_info.remote)) {
return 0;
}
return 1;
}
#endif /* COAP_CLIENT_SUPPORT */
/*
* strm
* return >=0 Number of bytes read.
* -1 Error (error in errno).
*/
ssize_t
coap_netif_strm_read(coap_session_t *session, uint8_t *data, size_t datalen) {
ssize_t bytes_read = coap_socket_read(&session->sock, data, datalen);
int keep_errno = errno;
if (bytes_read >= 0) {
coap_log_debug("* %s: netif: recv %4zd bytes\n",
coap_session_str(session), bytes_read);
} else if (bytes_read == -1 && errno != EAGAIN) {
coap_log_debug("* %s: netif: failed to receive any bytes (%s) state %d\n",
coap_session_str(session), coap_socket_strerror(), session->state);
errno = keep_errno;
}
return bytes_read;
}
/*
* strm
* return +ve Number of bytes written.
* -1 Error (error in errno).
*/
ssize_t
coap_netif_strm_write(coap_session_t *session, const uint8_t *data,
size_t datalen) {
ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
int keep_errno = errno;
if (bytes_written <= 0) {
coap_log_debug("* %s: netif: failed to send %zd bytes (%s) state %d\n",
coap_session_str(session), datalen,
coap_socket_strerror(), session->state);
errno = keep_errno;
} else {
coap_ticks(&session->last_rx_tx);
if (bytes_written == (ssize_t)datalen)
coap_log_debug("* %s: netif: sent %4zd bytes\n",
coap_session_str(session), bytes_written);
else
coap_log_debug("* %s: netif: sent %4zd of %4zd bytes\n",
coap_session_str(session), bytes_written, datalen);
}
return bytes_written;
}
#endif /* COAP_DISABLE_TCP */
void
coap_netif_close(coap_session_t *session) {
if (coap_netif_available(session))
coap_socket_close(&session->sock);
}
#if COAP_SERVER_SUPPORT
void
coap_netif_close_ep(coap_endpoint_t *endpoint) {
coap_socket_close(&endpoint->sock);
}
#endif /* COAP_SERVER_SUPPORT */
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:677
coap_socket_close
void coap_socket_close(coap_socket_t *sock)
Function interface to close off a socket.
Definition coap_io.c:375
coap_socket_strerror
const char * coap_socket_strerror(void)
Definition coap_io.c:1900
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:1021
coap_socket_send
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.
Definition coap_io.c:824
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:618
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:80
COAP_SOCKET_NOT_EMPTY
#define COAP_SOCKET_NOT_EMPTY
the socket is not empty
Definition coap_io_internal.h:75
COAP_SOCKET_BOUND
#define COAP_SOCKET_BOUND
the socket is bound
Definition coap_io_internal.h:76
COAP_SOCKET_WANT_READ
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
Definition coap_io_internal.h:78
coap_socket_bind_udp
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
COAP_SOCKET_CONNECTED
#define COAP_SOCKET_CONNECTED
the socket is connected
Definition coap_io_internal.h:77
COAP_SOCKET_EMPTY
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
Definition coap_io_internal.h:74
coap_libcoap_build.h
Library specific build wrapper for coap_internal.h.
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:2234
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:125
coap_netif_close
void coap_netif_close(coap_session_t *session)
Layer function interface for Netif close for a session.
Definition coap_netif.c:260
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_accept
int coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session, void *extra)
Layer function interface for Netif stream accept.
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:236
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:215
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:200
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, void *extra)
Accept a new incoming TCP session.
Definition coap_tcp.c:291
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:161
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:148
coap_endpoint_t
Abstraction of virtual endpoint that can be attached to coap_context_t.
Definition coap_session_internal.h:232
coap_endpoint_t::bind_addr
coap_address_t bind_addr
local interface address
Definition coap_session_internal.h:239
coap_endpoint_t::sock
coap_socket_t sock
socket object for the interface, if any
Definition coap_session_internal.h:237
coap_packet_t
Definition coap_io_internal.h:225
coap_packet_t::length
size_t length
length of payload
Definition coap_io_internal.h:228
coap_packet_t::addr_info
coap_addr_tuple_t addr_info
local and remote addresses
Definition coap_io_internal.h:226
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:38
coap_socket_t::flags
coap_socket_flags_t flags
1 or more of COAP_SOCKET* flag values
Definition coap_io_internal.h:59