mirror of
https://github.com/esphome/esphome.git
synced 2024-12-28 16:31:44 +01:00
Enqueue services to BLE Server
This commit is contained in:
parent
4282918581
commit
05617fa9d9
7 changed files with 53 additions and 51 deletions
|
@ -186,6 +186,7 @@ async def to_code(config):
|
|||
desc_var = cg.new_Pvariable(descriptor[CONF_ID], parse_uuid(descriptor[CONF_UUID]), max_length)
|
||||
if CONF_VALUE in descriptor:
|
||||
cg.add(desc_var.set_value(parse_value(descriptor[CONF_VALUE])))
|
||||
cg.add(var.enqueue_start_service(service_var))
|
||||
cg.add_define("USE_ESP32_BLE_SERVER")
|
||||
if CORE.using_esp_idf:
|
||||
add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True)
|
||||
|
|
|
@ -289,7 +289,7 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|||
}
|
||||
|
||||
if (!param->write.is_prep) {
|
||||
this->on_write_(this->value_);
|
||||
if (this->on_write_) this->on_write_(this->value_);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -300,7 +300,7 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|||
break;
|
||||
this->write_event_ = false;
|
||||
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
|
||||
this->on_write_(this->value_);
|
||||
if (this->on_write_) this->on_write_(this->value_);
|
||||
}
|
||||
esp_err_t err =
|
||||
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, nullptr);
|
||||
|
|
|
@ -38,9 +38,25 @@ void BLEServer::loop() {
|
|||
return;
|
||||
}
|
||||
switch (this->state_) {
|
||||
case RUNNING:
|
||||
return;
|
||||
|
||||
case RUNNING: {
|
||||
if (this->services_to_start_.empty()) break;
|
||||
uint16_t index_to_remove = 0;
|
||||
// Iterate over the services to start
|
||||
for (unsigned i = 0; i < this->services_to_start_.size(); i++) {
|
||||
BLEService *service = this->services_to_start_[i];
|
||||
if (service->is_created()) {
|
||||
service->start();
|
||||
} else {
|
||||
index_to_remove = i + 1;
|
||||
}
|
||||
}
|
||||
// Remove the services that have been started
|
||||
if (index_to_remove > 0) {
|
||||
this->services_to_start_.erase(this->services_to_start_.begin(),
|
||||
this->services_to_start_.begin() + index_to_remove - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INIT: {
|
||||
esp_err_t err = esp_ble_gatts_app_register(0);
|
||||
if (err != ESP_OK) {
|
||||
|
@ -66,14 +82,11 @@ void BLEServer::loop() {
|
|||
break;
|
||||
}
|
||||
case STARTING_SERVICE: {
|
||||
if (!this->device_information_service_->is_created()) {
|
||||
break;
|
||||
}
|
||||
if (this->device_information_service_->is_running()) {
|
||||
this->state_ = RUNNING;
|
||||
this->restart_advertising_();
|
||||
ESP_LOGD(TAG, "BLE server setup successfully");
|
||||
} else if (!this->device_information_service_->is_starting()) {
|
||||
} else if (this->device_information_service_->is_created()) {
|
||||
this->device_information_service_->start();
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -46,6 +46,7 @@ class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEv
|
|||
BLEService *create_service(ESPBTUUID uuid, bool advertise = false, uint16_t num_handles = 15);
|
||||
void remove_service(ESPBTUUID uuid, uint8_t inst_id = 0);
|
||||
BLEService *get_service(ESPBTUUID uuid, uint8_t inst_id = 0);
|
||||
void enqueue_start_service(BLEService *service) { this->services_to_start_.push_back(service); }
|
||||
|
||||
esp_gatt_if_t get_gatts_if() { return this->gatts_if_; }
|
||||
uint32_t get_connected_client_count() { return this->connected_clients_; }
|
||||
|
@ -73,6 +74,7 @@ class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEv
|
|||
uint32_t connected_clients_{0};
|
||||
std::unordered_map<uint16_t, void *> clients_;
|
||||
std::unordered_map<std::string, BLEService *> services_;
|
||||
std::vector<BLEService *> services_to_start_;
|
||||
BLEService *device_information_service_;
|
||||
|
||||
enum State : uint8_t {
|
||||
|
|
|
@ -52,16 +52,16 @@ void BLEService::do_create(BLEServer *server) {
|
|||
esp_err_t err = esp_ble_gatts_create_service(server->get_gatts_if(), &srvc_id, this->num_handles_);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_ble_gatts_create_service failed: %d", err);
|
||||
this->init_state_ = FAILED;
|
||||
this->state_ = FAILED;
|
||||
return;
|
||||
}
|
||||
this->init_state_ = CREATING;
|
||||
this->state_ = CREATING;
|
||||
}
|
||||
|
||||
void BLEService::do_delete() {
|
||||
if (this->init_state_ == DELETING || this->init_state_ == DELETED)
|
||||
if (this->state_ == DELETING || this->state_ == DELETED)
|
||||
return;
|
||||
this->init_state_ = DELETING;
|
||||
this->state_ = DELETING;
|
||||
this->created_characteristic_count_ = 0;
|
||||
this->last_created_characteristic_ = nullptr;
|
||||
this->stop_();
|
||||
|
@ -86,18 +86,12 @@ bool BLEService::do_create_characteristics_() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void BLEService::enqueue_start() {
|
||||
if (this->init_state_ == CREATED)
|
||||
this->start();
|
||||
else
|
||||
this->should_start_ = true;
|
||||
}
|
||||
|
||||
void BLEService::start() {
|
||||
if (this->do_create_characteristics_())
|
||||
return;
|
||||
should_start_ = true;
|
||||
|
||||
this->state_ = STARTING;
|
||||
esp_err_t err = esp_ble_gatts_start_service(this->handle_);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_ble_gatts_start_service failed: %d", err);
|
||||
|
@ -105,7 +99,6 @@ void BLEService::start() {
|
|||
}
|
||||
if (this->advertise_)
|
||||
esp32_ble::global_ble->advertising_add_service_uuid(this->uuid_);
|
||||
this->running_state_ = STARTING;
|
||||
}
|
||||
|
||||
void BLEService::stop() {
|
||||
|
@ -114,9 +107,9 @@ void BLEService::stop() {
|
|||
}
|
||||
|
||||
void BLEService::stop_() {
|
||||
if (this->running_state_ == STOPPING || this->running_state_ == STOPPED)
|
||||
if (this->state_ == STOPPING || this->state_ == STOPPED)
|
||||
return;
|
||||
this->running_state_ = STOPPING;
|
||||
this->state_ = STOPPING;
|
||||
esp_err_t err = esp_ble_gatts_stop_service(this->handle_);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_ble_gatts_stop_service failed: %d", err);
|
||||
|
@ -126,17 +119,16 @@ void BLEService::stop_() {
|
|||
esp32_ble::global_ble->advertising_remove_service_uuid(this->uuid_);
|
||||
}
|
||||
|
||||
bool BLEService::is_created() { return this->init_state_ == CREATED; }
|
||||
bool BLEService::is_failed() {
|
||||
if (this->init_state_ == FAILED)
|
||||
if (this->state_ == FAILED)
|
||||
return true;
|
||||
bool failed = false;
|
||||
for (auto *characteristic : this->characteristics_)
|
||||
failed |= characteristic->is_failed();
|
||||
|
||||
if (failed)
|
||||
this->init_state_ = FAILED;
|
||||
return this->init_state_ == FAILED;
|
||||
this->state_ = FAILED;
|
||||
return this->state_ == FAILED;
|
||||
}
|
||||
|
||||
void BLEService::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
||||
|
@ -146,7 +138,7 @@ void BLEService::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t g
|
|||
if (this->uuid_ == ESPBTUUID::from_uuid(param->create.service_id.id.uuid) &&
|
||||
this->inst_id_ == param->create.service_id.id.inst_id) {
|
||||
this->handle_ = param->create.service_handle;
|
||||
this->init_state_ = CREATED;
|
||||
this->state_ = CREATED;
|
||||
if (this->should_start_)
|
||||
this->start();
|
||||
}
|
||||
|
@ -154,18 +146,18 @@ void BLEService::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t g
|
|||
}
|
||||
case ESP_GATTS_DELETE_EVT:
|
||||
if (param->del.service_handle == this->handle_) {
|
||||
this->init_state_ = DELETED;
|
||||
this->state_ = DELETED;
|
||||
}
|
||||
break;
|
||||
case ESP_GATTS_START_EVT: {
|
||||
if (param->start.service_handle == this->handle_) {
|
||||
this->running_state_ = RUNNING;
|
||||
this->state_ = RUNNING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_GATTS_STOP_EVT: {
|
||||
if (param->start.service_handle == this->handle_) {
|
||||
this->running_state_ = STOPPED;
|
||||
this->state_ = STOPPED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -42,20 +42,18 @@ class BLEService {
|
|||
void do_delete();
|
||||
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
||||
|
||||
void enqueue_start();
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
bool is_created();
|
||||
bool is_failed();
|
||||
|
||||
bool is_running() { return this->running_state_ == RUNNING; }
|
||||
bool is_starting() { return this->running_state_ == STARTING; }
|
||||
bool is_deleted() { return this->init_state_ == DELETED; }
|
||||
bool is_created() { return this->state_ == CREATED; }
|
||||
bool is_running() { return this->state_ == RUNNING; }
|
||||
bool is_starting() { return this->state_ == STARTING; }
|
||||
bool is_deleted() { return this->state_ == DELETED; }
|
||||
void on_client_connect(const std::function<void(const uint16_t)> &&func) { this->on_client_connect_ = func; }
|
||||
void on_client_disconnect(const std::function<void(const uint16_t)> &&func) { this->on_client_disconnect_ = func; }
|
||||
void emit_client_connect(const uint16_t conn_id) { this->on_client_connect_(conn_id); }
|
||||
void emit_client_disconnect(const uint16_t conn_id) { this->on_client_disconnect_(conn_id); }
|
||||
void emit_client_connect(const uint16_t conn_id) { if (this->on_client_connect_ && this->is_running()) this->on_client_connect_(conn_id); }
|
||||
void emit_client_disconnect(const uint16_t conn_id) { if (this->on_client_disconnect_ && this->is_running()) this->on_client_disconnect_(conn_id); }
|
||||
|
||||
protected:
|
||||
std::vector<BLECharacteristic *> characteristics_;
|
||||
|
@ -74,22 +72,18 @@ class BLEService {
|
|||
bool do_create_characteristics_();
|
||||
void stop_();
|
||||
|
||||
enum InitState : uint8_t {
|
||||
enum State : uint8_t {
|
||||
FAILED = 0x00,
|
||||
INIT,
|
||||
CREATING,
|
||||
CREATING_DEPENDENTS,
|
||||
CREATED,
|
||||
DELETING,
|
||||
DELETED,
|
||||
} init_state_{INIT};
|
||||
|
||||
enum RunningState : uint8_t {
|
||||
STARTING,
|
||||
RUNNING,
|
||||
STOPPING,
|
||||
STOPPED,
|
||||
} running_state_{STOPPED};
|
||||
DELETING,
|
||||
DELETED,
|
||||
} state_{INIT};
|
||||
};
|
||||
|
||||
} // namespace esp32_ble_server
|
||||
|
|
|
@ -88,15 +88,15 @@ void ESP32ImprovComponent::loop() {
|
|||
case improv::STATE_STOPPED:
|
||||
this->set_status_indicator_state_(false);
|
||||
|
||||
if (this->service_->is_created() && this->should_start_ && this->setup_complete_) {
|
||||
if (this->service_->is_running()) {
|
||||
if (this->should_start_ && this->setup_complete_) {
|
||||
if (this->service_->is_created()) {
|
||||
this->service_->start();
|
||||
} else if (this->service_->is_running()) {
|
||||
esp32_ble::global_ble->advertising_start();
|
||||
|
||||
this->set_state_(improv::STATE_AWAITING_AUTHORIZATION);
|
||||
this->set_error_(improv::ERROR_NONE);
|
||||
ESP_LOGD(TAG, "Service started!");
|
||||
} else {
|
||||
this->service_->start();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue