mirror of
https://github.com/esphome/esphome.git
synced 2026-10-21 05:26:46 +00:00
Modify the message decoder to avoid std::string
This commit is contained in:
@@ -153,7 +153,7 @@ template<uint32_t OPERANDS> bool Decoder::do_operand_() {
|
||||
}
|
||||
}
|
||||
|
||||
#define APPEND_LINE(...) (length_ = buf_append_printf(line_.data(), line_.size(), length_, __VA_ARGS__))
|
||||
#define APPEND_LINE(...) (length_ = buf_append_printf(line_, size_, length_, __VA_ARGS__))
|
||||
|
||||
/**
|
||||
* List of specialised operand decode functions, one function per operand type.
|
||||
@@ -441,16 +441,19 @@ const char *Decoder::find_opcode_name_(uint32_t opcode) const {
|
||||
bool Decoder::append_operand_(const char *word, uint8_t offset_incr /* default 1 */) {
|
||||
APPEND_LINE("[%s]", word);
|
||||
offset_ += offset_incr;
|
||||
return (length_ < line_.size()) && (offset_ < frame_.size());
|
||||
return (length_ < size_) && (offset_ < frame_.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry function 'decode' to call for full decode of a CEC frame
|
||||
*/
|
||||
const char *Decoder::decode() {
|
||||
// prepare text buffer as empty
|
||||
length_ = 0; // currently accumulated length of text of operands
|
||||
line_[length_] = 0; // initialise operand text to empty string
|
||||
int Decoder::decode() {
|
||||
// prepare text buffer state variables for an empty line
|
||||
length_ = 0; // currently accumulated length of text of operands
|
||||
line_[length_] = '\0'; // initialise output text to empty string
|
||||
|
||||
if (!line_ || !size_)
|
||||
return 0;
|
||||
|
||||
// print src and dest fields into 'line_'
|
||||
address_decode_();
|
||||
@@ -473,7 +476,7 @@ const char *Decoder::decode() {
|
||||
OperandDecode_f f = frametype->decode_f_;
|
||||
(this->*f)(); // call one of the above 'do_operand_<xx>' methods
|
||||
}
|
||||
return line_.data();
|
||||
return length_;
|
||||
}
|
||||
|
||||
} // namespace hdmi_cec
|
||||
|
||||
@@ -53,8 +53,15 @@ template<typename KeyT, typename ValueT, unsigned int SIZE> class LookupTable {
|
||||
*/
|
||||
class Decoder {
|
||||
public:
|
||||
Decoder(const Frame &frame) : frame_(frame), length_(0), offset_(2) {}
|
||||
const char *decode();
|
||||
Decoder(const Frame &frame, char *line, unsigned int size)
|
||||
: frame_(frame), line_(line), size_(size), length_(0), offset_(2) {}
|
||||
|
||||
/**
|
||||
* Create a one-line textual representation of the Frame content for logging and debugging
|
||||
* Store the text in the earlier provided 'line' buffer
|
||||
* @return the length of the written text, excluding the terminating null character
|
||||
*/
|
||||
int decode();
|
||||
|
||||
protected:
|
||||
const char *find_opcode_name_(uint32_t opcode) const;
|
||||
@@ -80,9 +87,10 @@ class Decoder {
|
||||
using VendorIdTable = LookupTable<uint32_t, const char *, 28>;
|
||||
|
||||
const Frame &frame_;
|
||||
std::array<char, 256> line_; // to hold the text of the decoded frame
|
||||
unsigned int length_; // currently accumulated length of output text in 'line'
|
||||
unsigned int offset_; // current offset in frame to process next operand byte(s) (frame[0] and [1] are skipped)
|
||||
char *const line_; // buffer to hold the text of the decoded frame
|
||||
const unsigned int size_; // size of the 'line_' buffer
|
||||
unsigned int length_; // currently accumulated length of output text in 'line'
|
||||
unsigned int offset_; // current offset in frame to process next operand byte(s) (frame[0] and [1] are skipped)
|
||||
|
||||
/**
|
||||
* The HDMI CEC standard specifies a set of distinct operand (parameter) types,
|
||||
|
||||
@@ -46,25 +46,22 @@ void Frame::set_header(uint8_t initiator_addr, uint8_t target_addr) {
|
||||
size_ = 1;
|
||||
}
|
||||
|
||||
std::string Frame::to_string() const {
|
||||
static constexpr unsigned int HEX_LINE_SIZE = Frame::MAX_LENGTH * 3 + 1;
|
||||
char hex_line[HEX_LINE_SIZE];
|
||||
int Frame::to_text(char *line, unsigned int size) const {
|
||||
unsigned int offset = 0;
|
||||
for (int i = 0; i < size_; i++) {
|
||||
offset = buf_append_printf(hex_line, HEX_LINE_SIZE, offset, "%02X:", data_[i]);
|
||||
offset = buf_append_printf(line, size, offset, "%02X:", data_[i]);
|
||||
}
|
||||
// clear last printed ':'
|
||||
if (offset > 0)
|
||||
hex_line[offset - 1] = '\0';
|
||||
std::string result{hex_line};
|
||||
line[--offset] = '\0';
|
||||
|
||||
#ifdef HDMI_CEC_USE_DECODER
|
||||
Decoder decoder(*this);
|
||||
result += " => ";
|
||||
result += decoder.decode();
|
||||
offset = buf_append_printf(line, size, offset, " => ");
|
||||
Decoder decoder(*this, line + offset, size - offset);
|
||||
offset += decoder.decode();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
return offset;
|
||||
}
|
||||
|
||||
void HDMICEC::setup() {
|
||||
@@ -110,8 +107,11 @@ void HDMICEC::handle_received_message_(const Frame *frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto frame_str = frame->to_string();
|
||||
ESP_LOGD(TAG, "Received: %s", frame_str.c_str());
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
|
||||
std::array<char, 256> line;
|
||||
frame->to_text(line.data(), (unsigned int) (line.size()));
|
||||
ESP_LOGD(TAG, "Received: %s", line.data());
|
||||
#endif
|
||||
|
||||
std::vector<uint8_t> data(frame->size() - 1);
|
||||
for (int i = 1; i < frame->size(); i++)
|
||||
@@ -362,9 +362,15 @@ void CECTransmit::transmit_message() {
|
||||
// Launch the transmit of the frame that is on the front of the queue
|
||||
transmit_state_ = TransmitState::BUSY;
|
||||
transmit_attempts_++;
|
||||
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
|
||||
if (transmit_attempts_ <= 1) {
|
||||
ESP_LOGD(TAG, "Sending: %s", (frame->to_string()).c_str());
|
||||
std::array<char, 256> line;
|
||||
frame->to_text(line.data(), (unsigned int) (line.size()));
|
||||
ESP_LOGD(TAG, "Sending: %s", line.data());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset info from receiver on progress of this transmit
|
||||
// (The receiver will see this transmit and keep track of acknowledge bits.)
|
||||
n_bytes_received_ = 0;
|
||||
@@ -573,7 +579,7 @@ void IRAM_ATTR CECTransmit::got_byte_eom_ack(bool eom, bool ack) {
|
||||
if (eom) {
|
||||
// some bus transfer ended. When the bus is free for a little while, we are allowed to transmit.
|
||||
required_idle_period_ = SIGNAL_FREE_TIME_AFTER_RECEIVE;
|
||||
ATOMIC_SET(receiver_is_busy_, false);
|
||||
ATOMIC_SET(receiver_is_busy_, false); // unblock the transmitter
|
||||
ATOMIC_SET(eom_received_, true); // atomic write to synchronize/commit above increments to the transmitter thread
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,15 @@ class Frame {
|
||||
data_[size_++] = data;
|
||||
}
|
||||
}
|
||||
std::string to_string() const; // NOLINT
|
||||
|
||||
/**
|
||||
* Create a one-line textual representation of the Frame content for logging and debugging
|
||||
* @param line: a buffer in which the text is to be written
|
||||
* @param size: The size of this buffer not to exceed with text
|
||||
* @return the length of the written text, excluding the terminating null character
|
||||
*/
|
||||
int to_text(char *line, unsigned int size) const;
|
||||
|
||||
constexpr static unsigned int MAX_LENGTH = 16;
|
||||
constexpr static unsigned int MAX_PAYLOAD_LENGTH = MAX_LENGTH - 1; // subtract 1 byte for the src&dst field
|
||||
|
||||
|
||||
Reference in New Issue
Block a user