51 for (uint8_t i = 0; i < client_count; i++) {
52 uint16_t client = clients[i];
58 bool require_ack = entry->indicate;
61 ESP_LOGW(TAG,
"INDICATE acknowledgment is not yet supported (i.e. it works as a NOTIFY)");
65 length, this->value_.data(), require_ack);
67 ESP_LOGE(TAG,
"esp_ble_gatts_send_indicate failed %d", err);
174 esp_ble_gatts_cb_param_t *param) {
176 case ESP_GATTS_ADD_CHAR_EVT: {
178 this->
handle_ = param->add_char.attr_handle;
181 descriptor->do_create(
this);
188 case ESP_GATTS_READ_EVT: {
189 if (param->read.handle != this->handle_)
192 if (!param->read.need_rsp)
204 const uint16_t offset = param->read.is_long ? param->read.offset : 0;
205 esp_gatt_status_t
status = ESP_GATT_OK;
206 esp_gatt_rsp_t response;
207 response.attr_value.offset = offset;
209 if (offset > this->
value_.size()) {
210 status = ESP_GATT_INVALID_OFFSET;
211 response.attr_value.len = 0;
213 size_t remaining = this->
value_.size() - offset;
214 if (remaining > ESP_GATT_MAX_ATTR_LEN) {
215 ESP_LOGW(TAG,
"Characteristic length %u exceeds buffer size of %u, truncating",
216 static_cast<unsigned>(remaining), ESP_GATT_MAX_ATTR_LEN);
217 remaining = ESP_GATT_MAX_ATTR_LEN;
219 response.attr_value.len = remaining;
220 memcpy(response.attr_value.value, this->value_.data() + offset, remaining);
223 response.attr_value.handle = this->
handle_;
224 response.attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
227 esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id,
status, &response);
229 ESP_LOGE(TAG,
"esp_ble_gatts_send_response failed: %d", err);
233 case ESP_GATTS_WRITE_EVT: {
234 if (this->
handle_ != param->write.handle)
237 esp_gatt_status_t
status = ESP_GATT_OK;
239 if (param->write.is_prep) {
240 const size_t offset = param->write.offset;
241 const size_t write_len = param->write.len;
242 const size_t new_size = offset + write_len;
248 if (offset != this->
value_.size()) {
249 status = ESP_GATT_INVALID_OFFSET;
250 }
else if (new_size > ESP_GATT_MAX_ATTR_LEN) {
251 status = ESP_GATT_INVALID_ATTR_LEN;
253 if (this->
value_.size() < new_size) {
254 this->
value_.resize(new_size);
256 memcpy(this->
value_.data() + offset, param->write.value, write_len);
262 if (param->write.need_rsp) {
263 esp_gatt_rsp_t response;
265 response.attr_value.len = param->write.len;
266 response.attr_value.handle = this->
handle_;
267 response.attr_value.offset = param->write.offset;
268 response.attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
269 memcpy(response.attr_value.value, param->write.value, param->write.len);
272 esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id,
status, &response);
275 ESP_LOGE(TAG,
"esp_ble_gatts_send_response failed: %d", err);
279 if (!param->write.is_prep) {
288 case ESP_GATTS_EXEC_WRITE_EVT: {
292 if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
297 esp_err_t err = esp_ble_gatts_send_response(gatts_if, param->exec_write.conn_id, param->exec_write.trans_id,
298 ESP_GATT_OK,
nullptr);
300 ESP_LOGE(TAG,
"esp_ble_gatts_send_response failed: %d", err);
309 descriptor->gatts_event_handler(event, gatts_if, param);