1
0
mirror of https://github.com/esphome/esphome.git synced 2025-02-24 13:58:14 +00:00
0hax 5624fafb3a
Fix handling of timestamps in Teleinfo component. (#2392)
* teleinfo: avoid a buffer overflow.

When reading tag or values, data is written to the buffer even if the
size if bigger than the buffer. Add a new 'max_len' argument to
get_field() to avoid this error.

Signed-off-by: 0hax <0hax@protonmail.com>

* teleinfo: read extra timestamp field for some tags.

Some tags has an extra timestamp field that need to be read before the
actual data.
The code is inspired by Jpsy work:

29339c14f9

Signed-off-by: 0hax <0hax@protonmail.com>

* teleinfo: increase MAX_BUF_SIZE to suffice for 3-phase Linky in Standard mode.

* teleinfo: handle DATE tag correctly.

The DATE tag is special due its format and need to be handled
separately.
Fix from DrCoolzic.

Signed-off-by: 0hax <0hax@protonmail.com>

Co-authored-by: Jörg Wagner <jwagner@digilog.de>
2021-09-27 22:32:08 +02:00

53 lines
1.4 KiB
C++

#pragma once
#include "esphome/core/component.h"
#include "esphome/components/uart/uart.h"
namespace esphome {
namespace teleinfo {
/*
* 198 bytes should be enough to contain a full session in historical mode with
* three phases. But go with 1024 just to be sure.
*/
static const uint8_t MAX_TAG_SIZE = 64;
static const uint16_t MAX_VAL_SIZE = 256;
static const uint16_t MAX_BUF_SIZE = 2048;
static const uint16_t MAX_TIMESTAMP_SIZE = 14;
class TeleInfoListener {
public:
std::string tag;
virtual void publish_val(const std::string &val){};
};
class TeleInfo : public PollingComponent, public uart::UARTDevice {
public:
TeleInfo(bool historical_mode);
void register_teleinfo_listener(TeleInfoListener *listener);
void loop() override;
void setup() override;
void update() override;
void dump_config() override;
std::vector<TeleInfoListener *> teleinfo_listeners_{};
protected:
uint32_t baud_rate_;
int checksum_area_end_;
int separator_;
char buf_[MAX_BUF_SIZE];
uint32_t buf_index_{0};
char tag_[MAX_TAG_SIZE];
char val_[MAX_VAL_SIZE];
char timestamp_[MAX_TIMESTAMP_SIZE];
enum State {
OFF,
ON,
START_FRAME_RECEIVED,
END_FRAME_RECEIVED,
} state_{OFF};
bool read_chars_until_(bool drop, uint8_t c);
bool check_crc_(const char *grp, const char *grp_end);
void publish_value_(const std::string &tag, const std::string &val);
};
} // namespace teleinfo
} // namespace esphome