SatCat5
coap_client.cc
1 // Copyright 2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
6 #include <satcat5/coap_client.h>
7 #include <satcat5/coap_reader.h>
8 #include <satcat5/coap_writer.h>
9 #include <satcat5/io_cbor.h>
10 #include <satcat5/udp_dispatch.h>
11 
13 
14 SimpleClient::SimpleClient(satcat5::net::Dispatch* iface)
15  : Endpoint(iface)
16  , m_rcvd(16) // Up to 16 packets
17  , m_msg_id(0) // Initial message ID
18 {
19  // Nothing else to initialize.
20 }
21 
23  const char* uri, satcat5::io::Readable* data, u16 fmt)
24 {
25  // User needs to call connect() first.
26  if (!m_prefer) return false;
27 
28  // Every request needs a unique ID.
29  ++m_msg_id;
30 
31  // Write header with all requested options and data.
32  // TODO: Can we add an API for additional options?
33  satcat5::coap::Writer wr(m_prefer->open_request());
34  if (!wr.ready()) return false;
35  wr.write_header(satcat5::coap::TYPE_CON, code, m_msg_id, m_msg_id);
36  if (uri) wr.write_uri(satcat5::coap::OPTION_URI_PATH, uri);
37  if (data) {
39  data->copy_to(wr.write_data());
40  data->read_finalize();
41  }
42  return wr.write_finalize();
43 }
44 
46  const char* uri, const char* data, u16 fmt)
47 {
48  satcat5::io::ArrayRead rd(data, strlen(data));
49  return request(code, uri, &rd, fmt);
50 }
51 
53  const char* uri, satcat5::cbor::CborWriter& cbor)
54 {
55 #if SATCAT5_CBOR_ENABLE
56  // TODO: Automatically add the CBOR format tag?
57  return request(code, uri, cbor.get_buffer(), satcat5::coap::FORMAT_CBOR);
58 #else
59  return false; // CBOR disabled -> Abort.
60 #endif
61 }
62 
64  if (m_rcvd.get_read_ready() == 0) return nullptr;
65  return &m_rcvd;
66 }
67 
69  if (m_rcvd.get_read_ready() == 0) return nullptr;
71  return rd.read_data();
72 }
73 
75  if (m_rcvd.get_read_ready() == 0) return false;
76  m_rcvd.read_finalize();
77  return true;
78 }
79 
81  // Flush any partial data in the buffer.
82  m_rcvd.write_abort();
83 
84  // Copy the message contents to the "m_rcvd" buffer.
85  // (Include tags of interest. Expand this list as needed.)
86  satcat5::coap::Writer wr(&m_rcvd);
87  wr.write_header(msg->code(), obj);
88  if (msg->format()) {
90  }
91  msg->read_data()->copy_to(wr.write_data());
92  wr.write_finalize();
93 }
94 
95 satcat5::coap::SimpleClientSpp::SimpleClientSpp(
96  satcat5::ccsds_spp::Dispatch* iface, u16 apid)
97  : SimpleClient(iface)
98  , ManageSpp(this, apid)
99 {
100  // Point-to-point link, no connection setup required.
101  set_connection(&m_connection);
102 }
103 
104 satcat5::coap::SimpleClientUdp::SimpleClientUdp(
105  satcat5::udp::Dispatch* iface)
106  : SimpleClient(iface)
107  , ManageUdp(this)
108  , m_connection(this, iface)
109 {
110  // Nothing else to initialize.
111 }
Creates an ephemeral writer for the Concise Binary Object Representation (CBOR, IETF RFC8949),...
Definition: io_cbor.h:91
satcat5::io::Readable * get_buffer()
Get encoded data as a Readable, useful if no dst was given.
Definition: io_cbor.cc:56
Implemention of "net::Dispatch" API for CCSDS-SPP packets.
Definition: ccsds_spp.h:199
CoAP request/response handling for a single client-server connection.
satcat5::io::Writeable * open_request()
If able, send a request to the current remote server.
CoAP endpoint (i.e., client, server, or combined client+server).
Definition: coap_endpoint.h:41
void set_connection(satcat5::coap::Connection *obj)
Set the preferred connection for outgoing requests.
Definition: coap_endpoint.h:58
Connection manager for CoAP endpoints using CCSDS-SPP.
Code code() const
< Response code (CODE)
Definition: coap_reader.h:114
satcat5::io::Readable * read_data()
Access the message payload.
Definition: coap_reader.cc:90
Wrapper for coap::ReadOptions that automatically parses options, rejecting any message with unrecogni...
Definition: coap_reader.h:234
Base-class for parsing CoAP message headers and options.
Definition: coap_reader.h:162
satcat5::util::optional< u16 > format() const
Accessors for parsed options.
Definition: coap_reader.h:177
Simplified CoAP client that writes responses to a PacketBuffer.
Definition: coap_client.h:17
satcat5::io::Readable * response_data()
Read the contents of the next CoAP response.
Definition: coap_client.cc:68
bool request(satcat5::coap::Code code, const char *uri, const char *data, u16 fmt=satcat5::coap::FORMAT_TEXT)
Create and send a CoAP request, with optional data.
Definition: coap_client.cc:45
bool response_discard()
Discard the contents of the next CoAP response.
Definition: coap_client.cc:74
satcat5::io::Readable * response_all()
Read full header and contents of the next CoAP response.
Definition: coap_client.cc:63
void coap_response(satcat5::coap::Connection *obj, satcat5::coap::Reader *msg) override
Save the incoming response message.
Definition: coap_client.cc:80
Message formatting for the Constrained Applications Protocol (CoAP).
Definition: coap_writer.h:26
bool write_uri(u16 id, const char *str)
Convert a URI to consecutive Uri-Path options.
Definition: coap_writer.cc:70
bool ready() const
Is this object ready for writing? Note: This is the only safe method if m_dst is null.
Definition: coap_writer.h:37
bool write_finalize()
After the last option, finish with an empty message.
Definition: coap_writer.h:67
bool write_option(u16 id, unsigned len, const void *data)
Write option(s) one at a time, in various formats.
Definition: coap_writer.cc:49
satcat5::io::Writeable * write_data()
After the last option, start writing message data.
Definition: coap_writer.cc:88
bool write_header(u8 type, Code code, u16 msg_id, u64 token=0, u8 tkl=0)
Always start by writing the header, with optional token.
Definition: coap_writer.cc:25
Ephemeral Readable interface for a simple array.
Definition: io_readable.h:206
unsigned get_read_ready() const override
How many bytes can be read without blocking?
Definition: pkt_buffer.cc:177
void write_abort() override
If possible, abort the current partially-written packet.
Definition: pkt_buffer.cc:89
void read_finalize() override
Consume any remaining bytes in this frame, if applicable.
Definition: pkt_buffer.cc:266
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
virtual void read_finalize()
Consume any remaining bytes in this frame, if applicable.
Definition: io_readable.cc:270
unsigned copy_to(satcat5::io::Writeable *dst)
Copy data to a Writeable object, without finalizing.
Definition: io_readable.cc:214
The "Dispatch" is a generic interface that knows how to read a designated protocol layer and sort inc...
Definition: net_dispatch.h:36
Dispatcher sorts incoming UDP messages by port index.
Definition: udp_dispatch.h:20
constexpr u16 FORMAT_CBOR
application/cbor (RFC8949)
constexpr u16 OPTION_URI_PATH
Option: Uri-Path.
constexpr u16 OPTION_FORMAT
Option: Content-Format.
Message parsing for the Constrained Applications Protocol (CoAP)
CBOR (IETF RFC8949) Readable/Writeable interface.
CoAP message header CODE field (Section 12.1).
T value() const
Fetch the inner value.
Definition: utils.h:64