mirror of
https://github.com/esphome/esphome.git
synced 2026-10-05 10:31:29 +00:00
Merge branch 'integration' into memory_api
This commit is contained in:
@@ -224,6 +224,7 @@ async def to_code(config):
|
||||
if key := encryption_config.get(CONF_KEY):
|
||||
decoded = base64.b64decode(key)
|
||||
cg.add(var.set_noise_psk(list(decoded)))
|
||||
cg.add_define("USE_API_NOISE_PSK_FROM_YAML")
|
||||
else:
|
||||
# No key provided, but encryption desired
|
||||
# This will allow a plaintext client to provide a noise key,
|
||||
|
||||
@@ -17,6 +17,16 @@ namespace esphome::api {
|
||||
// uncomment to log raw packets
|
||||
//#define HELPER_LOG_PACKETS
|
||||
|
||||
// Maximum message size limits to prevent OOM on constrained devices
|
||||
// Voice Assistant is our largest user at 1024 bytes per audio chunk
|
||||
// Using 2048 + 256 bytes overhead = 2304 bytes total to support voice and future needs
|
||||
// ESP8266 has very limited RAM and cannot support voice assistant
|
||||
#ifdef USE_ESP8266
|
||||
static constexpr uint16_t MAX_MESSAGE_SIZE = 512; // Keep small for memory constrained ESP8266
|
||||
#else
|
||||
static constexpr uint16_t MAX_MESSAGE_SIZE = 2304; // Support voice (1024) + headroom for larger messages
|
||||
#endif
|
||||
|
||||
// Forward declaration
|
||||
struct ClientInfo;
|
||||
|
||||
|
||||
@@ -184,6 +184,13 @@ APIError APINoiseFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
|
||||
return APIError::BAD_HANDSHAKE_PACKET_LEN;
|
||||
}
|
||||
|
||||
// Check against maximum message size to prevent OOM
|
||||
if (msg_size > MAX_MESSAGE_SIZE) {
|
||||
state_ = State::FAILED;
|
||||
HELPER_LOG("Bad packet: message size %u exceeds maximum %u", msg_size, MAX_MESSAGE_SIZE);
|
||||
return APIError::BAD_DATA_PACKET;
|
||||
}
|
||||
|
||||
// reserve space for body
|
||||
if (rx_buf_.size() != msg_size) {
|
||||
rx_buf_.resize(msg_size);
|
||||
|
||||
@@ -122,10 +122,10 @@ APIError APIPlaintextFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msg_size_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
|
||||
if (msg_size_varint->as_uint32() > MAX_MESSAGE_SIZE) {
|
||||
state_ = State::FAILED;
|
||||
HELPER_LOG("Bad packet: message size %" PRIu32 " exceeds maximum %u", msg_size_varint->as_uint32(),
|
||||
std::numeric_limits<uint16_t>::max());
|
||||
MAX_MESSAGE_SIZE);
|
||||
return APIError::BAD_DATA_PACKET;
|
||||
}
|
||||
rx_header_parsed_len_ = msg_size_varint->as_uint16();
|
||||
|
||||
@@ -37,12 +37,14 @@ void APIServer::setup() {
|
||||
|
||||
this->noise_pref_ = global_preferences->make_preference<SavedNoisePsk>(hash, true);
|
||||
|
||||
#ifndef USE_API_NOISE_PSK_FROM_YAML
|
||||
// Only load saved PSK if not set from YAML
|
||||
SavedNoisePsk noise_pref_saved{};
|
||||
if (this->noise_pref_.load(&noise_pref_saved)) {
|
||||
ESP_LOGD(TAG, "Loaded saved Noise PSK");
|
||||
|
||||
this->set_noise_psk(noise_pref_saved.psk);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Schedule reboot if no clients connect within timeout
|
||||
@@ -419,6 +421,12 @@ void APIServer::set_reboot_timeout(uint32_t reboot_timeout) { this->reboot_timeo
|
||||
|
||||
#ifdef USE_API_NOISE
|
||||
bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
|
||||
#ifdef USE_API_NOISE_PSK_FROM_YAML
|
||||
// When PSK is set from YAML, this function should never be called
|
||||
// but if it is, reject the change
|
||||
ESP_LOGW(TAG, "Key set in YAML");
|
||||
return false;
|
||||
#else
|
||||
auto &old_psk = this->noise_ctx_->get_psk();
|
||||
if (std::equal(old_psk.begin(), old_psk.end(), psk.begin())) {
|
||||
ESP_LOGW(TAG, "New PSK matches old");
|
||||
@@ -447,6 +455,7 @@ bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
|
||||
});
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -514,7 +514,7 @@ async def to_code_characteristic(service_var, char_conf):
|
||||
)
|
||||
if CONF_VALUE in char_conf:
|
||||
# Check if the value is templated (Lambda)
|
||||
value_data = char_conf[CONF_VALUE].get(CONF_DATA)
|
||||
value_data = char_conf[CONF_VALUE][CONF_DATA]
|
||||
if isinstance(value_data, cv.Lambda):
|
||||
# Templated value - need the full action infrastructure
|
||||
action_conf = {
|
||||
|
||||
@@ -401,6 +401,12 @@ class DriverChip:
|
||||
sequence.append((MADCTL, madctl))
|
||||
return madctl
|
||||
|
||||
def skip_command(self, command: str):
|
||||
"""
|
||||
Allow suppressing a standard command in the init sequence.
|
||||
"""
|
||||
return self.get_default(f"no_{command.lower()}", False)
|
||||
|
||||
def get_sequence(self, config) -> tuple[tuple[int, ...], int]:
|
||||
"""
|
||||
Create the init sequence for the display.
|
||||
@@ -432,7 +438,9 @@ class DriverChip:
|
||||
sequence.append((INVOFF,))
|
||||
if brightness := config.get(CONF_BRIGHTNESS, self.get_default(CONF_BRIGHTNESS)):
|
||||
sequence.append((BRIGHTNESS, brightness))
|
||||
sequence.append((SLPOUT,))
|
||||
# Add a SLPOUT command if required.
|
||||
if not self.skip_command("SLPOUT"):
|
||||
sequence.append((SLPOUT,))
|
||||
sequence.append((DISPON,))
|
||||
|
||||
# Flatten the sequence into a list of bytes, with the length of each command
|
||||
|
||||
@@ -27,7 +27,8 @@ DriverChip(
|
||||
bus_mode=TYPE_QUAD,
|
||||
brightness=0xD0,
|
||||
color_order=MODE_RGB,
|
||||
initsequence=(SLPOUT,), # Requires early SLPOUT
|
||||
no_slpout=True, # SLPOUT is in the init sequence, early
|
||||
initsequence=(SLPOUT,),
|
||||
)
|
||||
|
||||
DriverChip(
|
||||
@@ -95,6 +96,7 @@ CO5300 = DriverChip(
|
||||
brightness=0xD0,
|
||||
color_order=MODE_RGB,
|
||||
bus_mode=TYPE_QUAD,
|
||||
no_slpout=True,
|
||||
initsequence=(
|
||||
(SLPOUT,), # Requires early SLPOUT
|
||||
(PAGESEL, 0x00),
|
||||
|
||||
@@ -288,11 +288,15 @@ void Sim800LComponent::parse_cmd_(std::string message) {
|
||||
if (item == 3) { // stat
|
||||
uint8_t current_call_state = parse_number<uint8_t>(message.substr(start, end - start)).value_or(6);
|
||||
if (current_call_state != this->call_state_) {
|
||||
ESP_LOGD(TAG, "Call state is now: %d", current_call_state);
|
||||
if (current_call_state == 0)
|
||||
this->call_connected_callback_.call();
|
||||
if (current_call_state == 4) {
|
||||
ESP_LOGV(TAG, "Premature call state '4'. Ignoring, waiting for RING");
|
||||
} else {
|
||||
this->call_state_ = current_call_state;
|
||||
ESP_LOGD(TAG, "Call state is now: %d", current_call_state);
|
||||
if (current_call_state == 0)
|
||||
this->call_connected_callback_.call();
|
||||
}
|
||||
}
|
||||
this->call_state_ = current_call_state;
|
||||
break;
|
||||
}
|
||||
// item 4 = ""
|
||||
|
||||
Reference in New Issue
Block a user