13 namespace ble_client {
19 static const char *
const TAG;
28 esp_ble_gattc_cb_param_t *param)
override {
29 if (event == ESP_GATTC_SEARCH_CMPL_EVT) {
30 this->node_state = espbt::ClientState::ESTABLISHED;
42 esp_ble_gattc_cb_param_t *param)
override {
46 case ESP_GATTC_SEARCH_CMPL_EVT: {
47 this->node_state = espbt::ClientState::ESTABLISHED;
50 case ESP_GATTC_CLOSE_EVT: {
65 void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
override {
66 if (event == ESP_GAP_BLE_PASSKEY_REQ_EVT && this->parent_->check_addr(param->ble_security.auth_cmpl.bd_addr))
75 void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
override {
76 if (event == ESP_GAP_BLE_PASSKEY_NOTIF_EVT && this->parent_->check_addr(param->ble_security.auth_cmpl.bd_addr)) {
77 this->trigger(param->ble_security.key_notif.passkey);
86 void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
override {
87 if (event == ESP_GAP_BLE_NC_REQ_EVT && this->parent_->check_addr(param->ble_security.auth_cmpl.bd_addr)) {
88 this->trigger(param->ble_security.key_notif.passkey);
98 ble_client_ = ble_client;
110 this->value_template_ = std::move(func);
111 has_simple_value_ =
false;
115 this->value_simple_ = value;
116 has_simple_value_ =
true;
122 this->num_running_++;
123 this->var_ = std::make_tuple(
x...);
124 auto value = this->has_simple_value_ ? this->value_simple_ : this->value_template_(
x...);
127 this->play_next_(
x...);
139 bool write(
const std::vector<uint8_t> &value) {
140 if (this->node_state != espbt::ClientState::ESTABLISHED) {
141 esph_log_w(
Automation::TAG,
"Cannot write to BLE characteristic - not connected");
145 esp_err_t err = esp_ble_gattc_write_char(this->parent()->get_gattc_if(), this->parent()->get_conn_id(),
146 this->char_handle_, value.size(),
const_cast<uint8_t *
>(value.data()),
147 this->write_type_, ESP_GATT_AUTH_REQ_NONE);
149 esph_log_e(
Automation::TAG,
"Error writing to characteristic: %s!", esp_err_to_name(err));
156 esp_ble_gattc_cb_param_t *param)
override {
158 case ESP_GATTC_WRITE_CHAR_EVT:
160 if (param->write.handle == this->char_handle_)
161 this->parent()->run_later([
this]() { this->play_next_tuple_(this->var_); });
163 case ESP_GATTC_DISCONNECT_EVT:
164 if (this->num_running_ != 0)
165 this->stop_complex();
167 case ESP_GATTC_SEARCH_CMPL_EVT: {
168 auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
169 if (chr ==
nullptr) {
170 esph_log_w(
"ble_write_action",
"Characteristic %s was not found in service %s",
171 this->char_uuid_.to_string().c_str(), this->service_uuid_.to_string().c_str());
174 this->char_handle_ = chr->handle;
175 this->char_props_ = chr->properties;
176 if (this->char_props_ & ESP_GATT_CHAR_PROP_BIT_WRITE) {
177 this->write_type_ = ESP_GATT_WRITE_TYPE_RSP;
179 }
else if (this->char_props_ & ESP_GATT_CHAR_PROP_BIT_WRITE_NR) {
180 this->write_type_ = ESP_GATT_WRITE_TYPE_NO_RSP;
183 esph_log_e(
Automation::TAG,
"Characteristic %s does not allow writing", this->char_uuid_.to_string().c_str());
186 this->node_state = espbt::ClientState::ESTABLISHED;
187 esph_log_d(
Automation::TAG,
"Found characteristic %s on device %s", this->char_uuid_.to_string().c_str(),
188 ble_client_->address_str().c_str());
198 bool has_simple_value_ =
true;
199 std::vector<uint8_t> value_simple_;
200 std::function<std::vector<uint8_t>(Ts...)> value_template_{};
203 std::tuple<Ts...> var_{};
204 uint16_t char_handle_{};
205 esp_gatt_char_prop_t char_props_{};
206 esp_gatt_write_type_t write_type_{};
215 if (has_simple_value_) {
216 passkey = this->value_simple_;
218 passkey = this->value_template_(
x...);
220 if (passkey > 999999)
222 esp_bd_addr_t remote_bda;
223 memcpy(remote_bda, parent_->get_remote_bda(),
sizeof(esp_bd_addr_t));
224 esp_ble_passkey_reply(remote_bda,
true, passkey);
228 this->value_template_ = std::move(func);
229 has_simple_value_ =
false;
233 this->value_simple_ = value;
234 has_simple_value_ =
true;
239 bool has_simple_value_ =
true;
240 uint32_t value_simple_{0};
241 std::function<uint32_t(Ts...)> value_template_{};
249 esp_bd_addr_t remote_bda;
250 memcpy(remote_bda, parent_->get_remote_bda(),
sizeof(esp_bd_addr_t));
251 if (has_simple_value_) {
252 esp_ble_confirm_reply(remote_bda, this->value_simple_);
254 esp_ble_confirm_reply(remote_bda, this->value_template_(
x...));
259 this->value_template_ = std::move(func);
260 has_simple_value_ =
false;
264 this->value_simple_ = value;
265 has_simple_value_ =
true;
270 bool has_simple_value_ =
true;
271 bool value_simple_{
false};
272 std::function<bool(Ts...)> value_template_{};
280 esp_bd_addr_t remote_bda;
281 memcpy(remote_bda, parent_->get_remote_bda(),
sizeof(esp_bd_addr_t));
282 esp_ble_remove_bond_device(remote_bda);
293 ble_client_ = ble_client;
296 esp_ble_gattc_cb_param_t *param)
override {
297 if (this->num_running_ == 0)
300 case ESP_GATTC_SEARCH_CMPL_EVT:
301 this->node_state = espbt::ClientState::ESTABLISHED;
302 this->parent()->run_later([
this]() { this->play_next_tuple_(this->var_); });
305 case ESP_GATTC_DISCONNECT_EVT:
306 this->stop_complex();
320 if (this->num_running_ != 0) {
321 this->stop_complex();
324 this->num_running_++;
325 if (this->node_state == espbt::ClientState::ESTABLISHED) {
326 this->play_next_(
x...);
328 this->var_ = std::make_tuple(
x...);
329 this->ble_client_->connect();
335 std::tuple<Ts...> var_{};
342 ble_client_ = ble_client;
345 esp_ble_gattc_cb_param_t *param)
override {
346 if (this->num_running_ == 0)
349 case ESP_GATTC_CLOSE_EVT:
350 case ESP_GATTC_DISCONNECT_EVT:
351 this->parent()->run_later([
this]() { this->play_next_tuple_(this->var_); });
362 this->num_running_++;
364 this->play_next_(
x...);
366 this->var_ = std::make_tuple(
x...);
367 this->ble_client_->disconnect();
373 std::tuple<Ts...> var_{};
void set_service_uuid16(uint16_t uuid)
BLEClientNumericComparisonReplyAction(BLEClient *ble_client)
void play_complex(Ts... x) override
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override
void set_char_uuid32(uint32_t uuid)
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override
std::string format_hex_pretty(const uint8_t *data, size_t length)
Format the byte array data of length len in pretty-printed, human-readable hex.
BLEClientPasskeyNotificationTrigger(BLEClient *parent)
BLEClientRemoveBondAction(BLEClient *ble_client)
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override
void set_value_simple(const bool &value)
void play_complex(Ts... x) override
BLEClientDisconnectAction(BLEClient *ble_client)
BLEClientPasskeyRequestTrigger(BLEClient *parent)
bool write(const std::vector< uint8_t > &value)
Note about logging: the esph_log_X macros are used here because the CI checks complain about use of t...
void set_service_uuid128(uint8_t *uuid)
void set_value_simple(const std::vector< uint8_t > &value)
void set_value_simple(const uint32_t &value)
void set_char_uuid128(uint8_t *uuid)
void set_service_uuid32(uint32_t uuid)
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override
BLEClientConnectTrigger(BLEClient *parent)
BLEClientConnectAction(BLEClient *ble_client)
void play(Ts... x) override
void play(Ts... x) override
void set_value_template(std::function< std::vector< uint8_t >(Ts...)> func)
void play_complex(Ts... x) override
BLEClientDisconnectTrigger(BLEClient *parent)
void play(Ts... x) override
void set_value_template(std::function< uint32_t(Ts...)> func)
BLEClientNumericComparisonRequestTrigger(BLEClient *parent)
static ESPBTUUID from_uint32(uint32_t uuid)
void play(Ts... x) override
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override
static ESPBTUUID from_uint16(uint16_t uuid)
void play(Ts... x) override
static const char *const TAG
void register_ble_node(BLEClientNode *node)
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override
Implementation of SPI Controller mode.
static ESPBTUUID from_raw(const uint8_t *data)
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override
void play(Ts... x) override
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override
BLEClientWriteAction(BLEClient *ble_client)
BLEClientPasskeyReplyAction(BLEClient *ble_client)
void set_char_uuid16(uint16_t uuid)
void set_value_template(std::function< bool(Ts...)> func)