From 70481429367ca00144b24f118cbfdfb28b02967d Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期三, 26 八月 2026 15:54:31 +0800
Subject: [PATCH] add sening functions
---
xiaozhi-esp32-2.2.6/main/protocols/mqtt_protocol.cc | 98 +++++++++++++++++++++++++++++++++++++------------
1 files changed, 74 insertions(+), 24 deletions(-)
diff --git a/xiaozhi-esp32-2.2.6/main/protocols/mqtt_protocol.cc b/xiaozhi-esp32-2.2.6/main/protocols/mqtt_protocol.cc
index 94d9d12..5e9341b 100644
--- a/xiaozhi-esp32-2.2.6/main/protocols/mqtt_protocol.cc
+++ b/xiaozhi-esp32-2.2.6/main/protocols/mqtt_protocol.cc
@@ -18,11 +18,11 @@
.callback = [](void* arg) {
MqttProtocol* protocol = (MqttProtocol*)arg;
auto& app = Application::GetInstance();
- if (app.GetDeviceState() == kDeviceStateIdle) {
+ if (app.GetDeviceState() == kDeviceStateIdle && Board::GetInstance().IsNetworkReady()) {
ESP_LOGI(TAG, "Reconnecting to MQTT server");
auto alive = protocol->alive_; // Capture alive flag
app.Schedule([protocol, alive]() {
- if (*alive) {
+ if (*alive && Board::GetInstance().IsNetworkReady()) {
protocol->StartMqttClient(false);
}
});
@@ -56,9 +56,25 @@
return StartMqttClient(false);
}
+void MqttProtocol::PrepareForNetworkStandby() {
+ network_standby_preparing_ = true;
+ if (reconnect_timer_ != nullptr) {
+ esp_timer_stop(reconnect_timer_);
+ }
+ audio_channel_opened_ = false;
+ udp_.reset();
+ if (mqtt_ != nullptr) {
+ mqtt_->Disconnect();
+ mqtt_.reset();
+ }
+ network_standby_preparing_ = false;
+}
+
bool MqttProtocol::StartMqttClient(bool report_error) {
if (mqtt_ != nullptr) {
ESP_LOGW(TAG, "Mqtt client already started");
+ audio_channel_opened_ = false;
+ udp_.reset();
mqtt_.reset();
}
@@ -83,6 +99,9 @@
mqtt_->SetKeepAlive(keepalive_interval);
mqtt_->OnDisconnected([this]() {
+ if (network_standby_preparing_ || !Board::GetInstance().IsNetworkReady()) {
+ return;
+ }
if (on_disconnected_ != nullptr) {
on_disconnected_();
}
@@ -143,7 +162,9 @@
}
if (!mqtt_->Connect(broker_address, broker_port, client_id, username, password)) {
ESP_LOGE(TAG, "Failed to connect to endpoint, code=%d", mqtt_->GetLastError());
- SetError(Lang::Strings::SERVER_NOT_CONNECTED);
+ if (report_error) {
+ SetError(Lang::Strings::SERVER_NOT_CONNECTED);
+ }
return false;
}
@@ -164,32 +185,60 @@
}
bool MqttProtocol::SendAudio(std::unique_ptr<AudioStreamPacket> packet) {
- std::lock_guard<std::mutex> lock(channel_mutex_);
- if (udp_ == nullptr) {
- return false;
+ bool notify_channel_closed = false;
+
+ {
+ std::lock_guard<std::mutex> lock(channel_mutex_);
+ if (udp_ == nullptr || !audio_channel_opened_) {
+ return false;
+ }
+ if (!Board::GetInstance().IsNetworkReady()) {
+ ESP_LOGW(TAG, "Network is not ready, drop UDP audio and close channel");
+ audio_channel_opened_ = false;
+ udp_.reset();
+ notify_channel_closed = true;
+ } else {
+ std::string nonce(aes_nonce_);
+ *(uint16_t*)&nonce[2] = htons(packet->payload.size());
+ *(uint32_t*)&nonce[8] = htonl(packet->timestamp);
+ *(uint32_t*)&nonce[12] = htonl(++local_sequence_);
+
+ std::string encrypted;
+ encrypted.resize(aes_nonce_.size() + packet->payload.size());
+ memcpy(encrypted.data(), nonce.data(), nonce.size());
+
+ size_t nc_off = 0;
+ uint8_t stream_block[16] = {0};
+ if (mbedtls_aes_crypt_ctr(&aes_ctx_, packet->payload.size(), &nc_off, (uint8_t*)nonce.c_str(), stream_block,
+ (uint8_t*)packet->payload.data(), (uint8_t*)&encrypted[nonce.size()]) != 0) {
+ ESP_LOGE(TAG, "Failed to encrypt audio data");
+ return false;
+ }
+
+ int ret = udp_->Send(encrypted);
+ if (ret <= 0) {
+ ESP_LOGW(TAG, "UDP audio send failed, close audio channel");
+ audio_channel_opened_ = false;
+ udp_.reset();
+ notify_channel_closed = true;
+ } else {
+ return true;
+ }
+ }
}
- std::string nonce(aes_nonce_);
- *(uint16_t*)&nonce[2] = htons(packet->payload.size());
- *(uint32_t*)&nonce[8] = htonl(packet->timestamp);
- *(uint32_t*)&nonce[12] = htonl(++local_sequence_);
-
- std::string encrypted;
- encrypted.resize(aes_nonce_.size() + packet->payload.size());
- memcpy(encrypted.data(), nonce.data(), nonce.size());
-
- size_t nc_off = 0;
- uint8_t stream_block[16] = {0};
- if (mbedtls_aes_crypt_ctr(&aes_ctx_, packet->payload.size(), &nc_off, (uint8_t*)nonce.c_str(), stream_block,
- (uint8_t*)packet->payload.data(), (uint8_t*)&encrypted[nonce.size()]) != 0) {
- ESP_LOGE(TAG, "Failed to encrypt audio data");
- return false;
+ if (notify_channel_closed && on_audio_channel_closed_ != nullptr) {
+ on_audio_channel_closed_();
}
-
- return udp_->Send(encrypted) > 0;
+ return false;
}
void MqttProtocol::CloseAudioChannel(bool send_goodbye) {
+ if (!audio_channel_opened_) {
+ return;
+ }
+ audio_channel_opened_ = false;
+
{
std::lock_guard<std::mutex> lock(channel_mutex_);
udp_.reset();
@@ -287,6 +336,7 @@
});
udp_->Connect(udp_server_, udp_port_);
+ audio_channel_opened_ = true;
if (on_audio_channel_opened_ != nullptr) {
on_audio_channel_opened_();
@@ -385,5 +435,5 @@
}
bool MqttProtocol::IsAudioChannelOpened() const {
- return udp_ != nullptr && !error_occurred_ && !IsTimeout();
+ return audio_channel_opened_ && udp_ != nullptr && !error_occurred_ && !IsTimeout();
}
--
Gitblit v1.9.1