SatCat5
coap_reader.h
Go to the documentation of this file.
1 // Copyright 2024-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
31 
32 #pragma once
33 
34 #include <satcat5/coap_constants.h>
35 #include <satcat5/io_readable.h>
36 #include <satcat5/utils.h>
37 
38 // Maximum length of an assembled Uri-Path string, ignoring other Uri- options
39 // and an implicit leading /. Example: 'resource1/resource2/res3'
40 #ifndef SATCAT5_COAP_MAX_URI_PATH_LEN
41 #define SATCAT5_COAP_MAX_URI_PATH_LEN 64
42 #endif
43 
44 namespace satcat5 {
45  namespace coap {
48  class Option final : public satcat5::io::LimitedRead {
49  public:
51  u16 id() const { return m_id; }
53  u16 len() const { return m_len; }
54 
57  unsigned value_str(char* dst);
59  u64 value_uint();
60 
63  bool is_critical() const { return m_id & 0x0001; }
64  bool is_unsafe() const { return m_id & 0x0002; }
65  bool no_cache_key() const { return (m_id & 0x001E) == 0x001C; }
67 
68  private:
69  // These methods should only be accessed by coap::ReadHeader.
71  constexpr explicit Option(satcat5::io::Readable* src)
72  : LimitedRead(src, 0), m_id(0), m_len(0) {}
73  inline Option* reset(unsigned len)
74  { m_len = len; read_reset(len); return this; }
75  u16 m_id, m_len;
76  };
77 
80  class ReadHeader {
81  public:
83  explicit ReadHeader(satcat5::io::Readable* src);
84 
85  // Forbid unsafe assignment and copy operators.
86  ReadHeader(const ReadHeader&) = delete;
87  ReadHeader& operator=(const ReadHeader&) = delete;
88 
91  bool next_option();
92 
96 
98  inline void read_finalize()
99  { m_src->read_finalize(); }
100 
101  // Accessors for the message header and parsing state.
102  inline bool error() const
103  { return m_state == State::ERROR; }
104  inline Code error_code() const
105  { return m_error_code; }
106  inline const char* error_msg() const
107  { return m_error_msg; }
108  inline u8 version() const
109  { return m_type & 0xC0; }
110  inline u8 type() const
111  { return m_type & 0x30; }
112  inline u8 tkl() const
113  { return m_type & 0x0F; }
114  inline Code code() const
115  { return m_code; }
116  inline u16 msg_id() const
117  { return m_id; }
118  inline u64 token() const
119  { return m_token; }
120  inline bool is_request() const
121  { return type() == TYPE_CON || type() == TYPE_NON; }
122  inline bool is_response() const
123  { return type() == TYPE_ACK; }
124  inline satcat5::coap::Option& option()
125  { return m_opt;}
126 
127  protected:
129  enum class State {OPTIONS, DATA, ERROR};
130 
132  u16 read_var_int(u8 nybb);
133 
135  inline void set_error(Code code, const char* msg = "")
136  { m_state = State::ERROR; m_error_code = code; m_error_msg = msg; }
137 
140 
141  // Reader state and error information if triggered.
144  const char* m_error_msg;
145 
146  // Header fields
147  const u8 m_type;
149  const u16 m_id;
150  u64 m_token;
151 
154  };
155 
163  public:
166  explicit Reader(satcat5::io::Readable* src);
167 
168  // Forbid unsafe assignment and copy operators.
169  Reader(const Reader&) = delete;
170  Reader& operator=(const Reader&) = delete;
171 
175  { return m_uri_path_wridx == 0 ?
177  inline satcat5::util::optional<u16> format() const // Content-Format
178  { return m_format; }
179  inline satcat5::util::optional<u64> size1() const // Size1
180  { return m_size1; }
181  inline satcat5::util::optional<u64> block() const // Block1 & Block2 combined
182  { return m_block1 ? m_block1 : m_block2; } // TODO: Deprecate these?
183  inline u16 block_size() const
184  { return m_block1 ? block1_size() : block2_size(); }
185  inline bool block_more() const
186  { return m_block1 ? block1_more() : block2_more(); }
187  inline u32 block_num() const
188  { return m_block1 ? block1_num() : block2_num(); }
189  inline satcat5::util::optional<u64> block1() const // Block1 only
190  { return m_block1; }
191  inline u16 block1_size() const
192  { return 1 << ((m_block1.value() & 0x7) + 4); }
193  inline bool block1_more() const
194  { return (m_block1.value() & 0x8) >> 3; }
195  inline u32 block1_num() const
196  { return (m_block1.value() & 0xFFFFFFF0) >> 4; }
197  inline satcat5::util::optional<u64> block2() // Block2 only
198  { return m_block2; }
199  inline u16 block2_size() const
200  { return 1 << ((m_block2.value() & 0x7) + 4); }
201  inline bool block2_more() const
202  { return (m_block2.value() & 0x8) >> 3; }
203  inline u32 block2_num() const
204  { return (m_block2.value() & 0xFFFFFFF0) >> 4; }
206 
207  protected:
209  void append_uri_path();
210 
214  void read_options();
215 
220  virtual void read_user_option() = 0;
221 
223  char m_uri_path[SATCAT5_COAP_MAX_URI_PATH_LEN + 1];
224  unsigned m_uri_path_wridx;
229  };
230 
234  class ReadSimple final : public satcat5::coap::Reader {
235  public:
238  : Reader(src) { read_options(); }
239 
240  protected:
243  void read_user_option() override;
244  };
245  }
246 }
Accessor for a single CoAP option field.
Definition: coap_reader.h:48
bool no_cache_key() const
Option bit mapping indicates relevant properties (Section 5.4.6).
Definition: coap_reader.h:65
u16 len() const
Option Number (RFC-7252, Section 3.1).
Definition: coap_reader.h:53
bool is_critical() const
Option bit mapping indicates relevant properties (Section 5.4.6).
Definition: coap_reader.h:63
u16 id() const
Option Number (RFC-7252, Section 3.1).
Definition: coap_reader.h:51
unsigned value_str(char *dst)
Access the Option Value as a UTF-8 string ("string").
Definition: coap_reader.cc:15
u64 value_uint()
Access the Option Value as an unsigned integer ("uint").
Definition: coap_reader.cc:22
bool is_unsafe() const
Option bit mapping indicates relevant properties (Section 5.4.6).
Definition: coap_reader.h:64
Parser for CoAP message headers only.
Definition: coap_reader.h:80
satcat5::coap::Code m_code
Status code x.yy.
Definition: coap_reader.h:148
Code m_error_code
Error code, or Empty to Reset.
Definition: coap_reader.h:143
bool is_response() const
< ACK request?
Definition: coap_reader.h:122
u8 type() const
< Type (T)
Definition: coap_reader.h:110
satcat5::coap::Option m_opt
Contents of the current option.
Definition: coap_reader.h:153
bool error() const
< Error during parsing?
Definition: coap_reader.h:102
bool next_option()
Consume current option and advance to the next one.
Definition: coap_reader.cc:59
u64 m_token
Token (0-8 bytes)
Definition: coap_reader.h:150
const u16 m_id
Message ID.
Definition: coap_reader.h:149
u8 tkl() const
< Token length (TKL)
Definition: coap_reader.h:112
const char * error_msg() const
< Optional message
Definition: coap_reader.h:106
satcat5::io::Readable *const m_src
Source buffer of CoAP message.
Definition: coap_reader.h:139
Code code() const
< Response code (CODE)
Definition: coap_reader.h:114
void set_error(Code code, const char *msg="")
Set error code and stop further parsing.
Definition: coap_reader.h:135
u16 read_var_int(u8 nybb)
Read variable-length integer from Option header.
Definition: coap_reader.cc:96
void read_finalize()
Forward read_finalize() to the inner source.
Definition: coap_reader.h:98
const u8 m_type
Version, type, TKL.
Definition: coap_reader.h:147
const char * m_error_msg
Diagnostic Payload for error.
Definition: coap_reader.h:144
satcat5::io::Readable * read_data()
Access the message payload.
Definition: coap_reader.cc:90
Code error_code() const
< Code for the error
Definition: coap_reader.h:104
ReadHeader(satcat5::io::Readable *src)
Create this object and read the message header only.
Definition: coap_reader.cc:31
bool is_request() const
< CON or NON request?
Definition: coap_reader.h:120
u64 token() const
< Token value
Definition: coap_reader.h:118
u8 version() const
< Version (Ver)
Definition: coap_reader.h:108
u16 msg_id() const
< Message ID
Definition: coap_reader.h:116
State
List of possible parser states.
Definition: coap_reader.h:129
State m_state
Parser state.
Definition: coap_reader.h:142
Wrapper for coap::ReadOptions that automatically parses options, rejecting any message with unrecogni...
Definition: coap_reader.h:234
ReadSimple(satcat5::io::Readable *src)
Wrapper object automatically reads header and options.
Definition: coap_reader.h:237
void read_user_option() override
The default implementation simply rejects any unsupported "Critical" Option as defined in RFC 7252,...
Definition: coap_reader.cc:162
Base-class for parsing CoAP message headers and options.
Definition: coap_reader.h:162
void read_options()
Read all option headers, storing supported option fields.
Definition: coap_reader.cc:116
satcat5::util::optional< u64 > size1() const
Accessors for parsed options.
Definition: coap_reader.h:179
bool block1_more() const
Accessors for parsed options.
Definition: coap_reader.h:193
bool block2_more() const
Accessors for parsed options.
Definition: coap_reader.h:201
unsigned m_uri_path_wridx
Index into m_uri_path
Definition: coap_reader.h:224
satcat5::util::optional< u64 > m_block2
Block2.
Definition: coap_reader.h:227
satcat5::util::optional< const char * > uri_path() const
Accessors for parsed options.
Definition: coap_reader.h:174
u32 block1_num() const
Accessors for parsed options.
Definition: coap_reader.h:195
u16 block_size() const
Accessors for parsed options.
Definition: coap_reader.h:183
satcat5::util::optional< u64 > block2()
Accessors for parsed options.
Definition: coap_reader.h:197
satcat5::util::optional< u64 > m_size1
Size1.
Definition: coap_reader.h:228
bool block_more() const
Accessors for parsed options.
Definition: coap_reader.h:185
char m_uri_path[SATCAT5_COAP_MAX_URI_PATH_LEN+1]
URI path for this request.
Definition: coap_reader.h:223
u16 block1_size() const
Accessors for parsed options.
Definition: coap_reader.h:191
u16 block2_size() const
Accessors for parsed options.
Definition: coap_reader.h:199
u32 block_num() const
Accessors for parsed options.
Definition: coap_reader.h:187
void append_uri_path()
Uri-Path string builder.
Definition: coap_reader.cc:148
satcat5::util::optional< u64 > m_block1
Block1.
Definition: coap_reader.h:226
satcat5::util::optional< u64 > block1() const
Accessors for parsed options.
Definition: coap_reader.h:189
satcat5::util::optional< u16 > format() const
Accessors for parsed options.
Definition: coap_reader.h:177
satcat5::util::optional< u16 > m_format
Content-Format.
Definition: coap_reader.h:225
satcat5::util::optional< u64 > block() const
Accessors for parsed options.
Definition: coap_reader.h:181
Reader(satcat5::io::Readable *src)
Create this object and read the message header.
Definition: coap_reader.cc:107
virtual void read_user_option()=0
Handler called for each option with an unknown ID.
u32 block2_num() const
Accessors for parsed options.
Definition: coap_reader.h:203
Limited read of next N bytes.
Definition: io_readable.h:255
void read_reset(unsigned rem)
Children may reset the number of remaining bytes.
Definition: io_readable.h:281
constexpr LimitedRead(satcat5::io::Readable *src, unsigned maxrd)
Explicitly set maximum read length in bytes.
Definition: io_readable.h:261
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
Constants relating to the Constrained Applications Protocol (CoAP)
"Readable" I/O interface core definitions
CoAP message header CODE field (Section 12.1).
An optional field that may be filled or empty.
Definition: utils.h:53
T value() const
Fetch the inner value.
Definition: utils.h:64
Miscellaneous mathematical utility functions.