122 lines
4.2 KiB
C++
122 lines
4.2 KiB
C++
#include "esp_mqtt.h"
|
|
#include <esp_crt_bundle.h>
|
|
#include <esp_log.h>
|
|
|
|
static const char *TAG = "esp_mqtt";
|
|
|
|
EspMqtt::EspMqtt() {
|
|
event_group_handle_ = xEventGroupCreate();
|
|
}
|
|
|
|
EspMqtt::~EspMqtt() {
|
|
if (event_group_handle_ != nullptr) {
|
|
Disconnect();
|
|
}
|
|
|
|
vEventGroupDelete(event_group_handle_);
|
|
}
|
|
|
|
bool EspMqtt::Connect(const std::string broker_address, int broker_port, const std::string client_id, const std::string username, const std::string password) {
|
|
if (mqtt_client_handle_ != nullptr) {
|
|
Disconnect();
|
|
}
|
|
|
|
esp_mqtt_client_config_t mqtt_config = {};
|
|
mqtt_config.broker.address.hostname = broker_address.c_str();
|
|
mqtt_config.broker.address.port = broker_port;
|
|
if (broker_port == 8883) {
|
|
mqtt_config.broker.address.transport = MQTT_TRANSPORT_OVER_SSL;
|
|
mqtt_config.broker.verification.crt_bundle_attach = esp_crt_bundle_attach;
|
|
} else {
|
|
mqtt_config.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
|
|
}
|
|
mqtt_config.credentials.client_id = client_id.c_str();
|
|
mqtt_config.credentials.username = username.c_str();
|
|
mqtt_config.credentials.authentication.password = password.c_str();
|
|
mqtt_config.session.keepalive = keep_alive_seconds_;
|
|
|
|
mqtt_client_handle_ = esp_mqtt_client_init(&mqtt_config);
|
|
esp_mqtt_client_register_event(mqtt_client_handle_, MQTT_EVENT_ANY, [](void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
|
|
((EspMqtt*)handler_args)->MqttEventCallback(base, event_id, event_data);
|
|
}, this);
|
|
esp_mqtt_client_start(mqtt_client_handle_);
|
|
|
|
auto bits = xEventGroupWaitBits(event_group_handle_, MQTT_CONNECTED_EVENT | MQTT_DISCONNECTED_EVENT | MQTT_ERROR_EVENT,
|
|
pdTRUE, pdFALSE, pdMS_TO_TICKS(MQTT_CONNECT_TIMEOUT_MS));
|
|
connected_ = (bits & MQTT_CONNECTED_EVENT) != 0;
|
|
return connected_;
|
|
}
|
|
|
|
void EspMqtt::MqttEventCallback(esp_event_base_t base, int32_t event_id, void *event_data) {
|
|
auto event = (esp_mqtt_event_t*)event_data;
|
|
switch (event_id) {
|
|
case MQTT_EVENT_CONNECTED:
|
|
xEventGroupSetBits(event_group_handle_, MQTT_CONNECTED_EVENT);
|
|
break;
|
|
case MQTT_EVENT_DISCONNECTED:
|
|
connected_ = false;
|
|
xEventGroupSetBits(event_group_handle_, MQTT_DISCONNECTED_EVENT);
|
|
break;
|
|
case MQTT_EVENT_DATA: {
|
|
auto topic = std::string(event->topic, event->topic_len);
|
|
auto payload = std::string(event->data, event->data_len);
|
|
if (event->data_len == event->total_data_len) {
|
|
if (on_message_callback_) {
|
|
on_message_callback_(topic, payload);
|
|
}
|
|
} else {
|
|
message_payload_.append(payload);
|
|
if (message_payload_.size() >= event->total_data_len && on_message_callback_) {
|
|
on_message_callback_(topic, message_payload_);
|
|
message_payload_.clear();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case MQTT_EVENT_BEFORE_CONNECT:
|
|
break;
|
|
case MQTT_EVENT_SUBSCRIBED:
|
|
break;
|
|
case MQTT_EVENT_ERROR:
|
|
xEventGroupSetBits(event_group_handle_, MQTT_ERROR_EVENT);
|
|
ESP_LOGI(TAG, "MQTT error occurred: %s", esp_err_to_name(event->error_handle->esp_tls_last_esp_err));
|
|
break;
|
|
default:
|
|
ESP_LOGI(TAG, "Unhandled event id %ld", event_id);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EspMqtt::Disconnect() {
|
|
esp_mqtt_client_stop(mqtt_client_handle_);
|
|
esp_mqtt_client_destroy(mqtt_client_handle_);
|
|
mqtt_client_handle_ = nullptr;
|
|
connected_ = false;
|
|
xEventGroupClearBits(event_group_handle_, MQTT_CONNECTED_EVENT | MQTT_DISCONNECTED_EVENT | MQTT_ERROR_EVENT);
|
|
}
|
|
|
|
bool EspMqtt::Publish(const std::string topic, const std::string payload, int qos) {
|
|
if (!connected_) {
|
|
return false;
|
|
}
|
|
return esp_mqtt_client_publish(mqtt_client_handle_, topic.c_str(), payload.data(), payload.size(), qos, 0) == 0;
|
|
}
|
|
|
|
bool EspMqtt::Subscribe(const std::string topic, int qos) {
|
|
if (!connected_) {
|
|
return false;
|
|
}
|
|
return esp_mqtt_client_subscribe_single(mqtt_client_handle_, topic.c_str(), qos) == 0;
|
|
}
|
|
|
|
bool EspMqtt::Unsubscribe(const std::string topic) {
|
|
if (!connected_) {
|
|
return false;
|
|
}
|
|
return esp_mqtt_client_unsubscribe(mqtt_client_handle_, topic.c_str()) == 0;
|
|
}
|
|
|
|
bool EspMqtt::IsConnected() {
|
|
return connected_;
|
|
}
|