diff --git a/components/bt/esp_ble_audio/host/common/init.c b/components/bt/esp_ble_audio/host/common/init.c index e179e1eabb6..ed38ffd8bd7 100644 --- a/components/bt/esp_ble_audio/host/common/init.c +++ b/components/bt/esp_ble_audio/host/common/init.c @@ -182,7 +182,7 @@ static const uint16_t ext_structs[] = { sizeof(struct bt_bond_info), }; -#define LEA_VERSION (0x20260514) +#define LEA_VERSION (0x20260616) struct lib_ext_cfgs { /* BLE */ @@ -2087,8 +2087,11 @@ int bt_le_audio_init(void) return err; } - printf(BT_ISO_LOG_COLOR_I "BLE Audio lib commit: [%s]" \ - BT_ISO_LOG_RESET_COLOR "\n", lib_ext_commit_get()); + esp_log_write(ESP_LOG_INFO, LEA_TAG, + BT_ISO_LOG_COLOR_I + "I (%lu) %s: BLE Audio lib commit: [%s]" + BT_ISO_LOG_RESET_COLOR "\n", + esp_log_timestamp(), LEA_TAG, lib_ext_commit_get()); err = lib_resources_init(); if (err) { diff --git a/components/bt/esp_ble_audio/lib/lib b/components/bt/esp_ble_audio/lib/lib index b9355d1a1c8..77cf36bd773 160000 --- a/components/bt/esp_ble_audio/lib/lib +++ b/components/bt/esp_ble_audio/lib/lib @@ -1 +1 @@ -Subproject commit b9355d1a1c875a3a62a067a6c232fd03fed3523c +Subproject commit 77cf36bd77300ab1c18e543dfedf359e876c3d56 diff --git a/components/bt/esp_ble_iso/host/adapter/bluedroid/gatt/gatt.c b/components/bt/esp_ble_iso/host/adapter/bluedroid/gatt/gatt.c index fa6864909aa..d06f785d947 100644 --- a/components/bt/esp_ble_iso/host/adapter/bluedroid/gatt/gatt.c +++ b/components/bt/esp_ble_iso/host/adapter/bluedroid/gatt/gatt.c @@ -78,7 +78,10 @@ struct gattc_list_node { sys_snode_t node; uint8_t type; union { - struct bt_gatt_read_params *read_params; + struct { + struct bt_gatt_read_params *params; + struct bt_gatt_read_params params_copy; + } read; struct bt_gatt_write_params *write_params; }; }; @@ -93,9 +96,13 @@ static struct gattc_list_node *gattc_list_node_alloc(uint8_t type, void *params) } op->type = type; - /* Both arms of the union are pointer-typed and same size — assigning via - * either field is equivalent. */ - op->read_params = params; + + if (type == GATTC_OP_READ) { + op->read.params_copy = *(struct bt_gatt_read_params *)params; + op->read.params = params; + } else { + op->write_params = params; + } return op; } @@ -1503,6 +1510,7 @@ static void handle_gattc_disc_cmpl_event(struct bt_le_gattc_disc_cmpl_event *eve static void handle_gattc_read_chrc_event(struct bt_le_gattc_read_chrc_event *event) { + struct bt_gatt_read_params read_copy; struct bt_gatt_read_params *params; struct gatt_conn *gatt_conn; struct gattc_list_node *op; @@ -1542,47 +1550,42 @@ static void handle_gattc_read_chrc_event(struct bt_le_gattc_read_chrc_event *eve goto end; } - params = op->read_params; + params = op->read.params; + read_copy = op->read.params_copy; free(op); - if (params == NULL || params->func == NULL) { + if (read_copy.func == NULL) { LOG_ERR("[B]GattcRdCharNoFunc"); goto end; } - if ((params->handle_count == 0 && (event->attr_handle < params->by_uuid.start_handle || - event->attr_handle > params->by_uuid.end_handle)) || - (params->handle_count == 1 && event->attr_handle != params->single.handle)) { + if ((read_copy.handle_count == 0 && + (event->attr_handle < read_copy.by_uuid.start_handle || + event->attr_handle > read_copy.by_uuid.end_handle)) || + (read_copy.handle_count == 1 && + event->attr_handle != read_copy.single.handle)) { LOG_ERR("[B]GattcRdCharInvRsp[%u][%u][%u][%u][%u]", - params->handle_count, event->attr_handle, params->by_uuid.start_handle, - params->by_uuid.end_handle, params->single.handle); - /* BTA fires READ_CHAR_EVT exactly once per read; the op was just - * popped above so no further EVT will arrive. Fire func with err - * so caller's state machine doesn't stall waiting forever. */ - params->func(conn, BT_ATT_ERR_UNLIKELY, params, NULL, 0); + read_copy.handle_count, event->attr_handle, + read_copy.by_uuid.start_handle, + read_copy.by_uuid.end_handle, read_copy.single.handle); + read_copy.func(conn, BT_ATT_ERR_UNLIKELY, params, NULL, 0); goto end; } val = event->value; vlen = event->len; - /* Long read: BTA's auto Read-Blob already fetched the full value on the - * BTU task; hand the caller only the requested [offset:] tail. */ - if (params->handle_count == 1 && params->single.offset != 0 && event->status == 0) { - off = params->single.offset; + if (read_copy.handle_count == 1 && read_copy.single.offset != 0 && + event->status == 0) { + off = read_copy.single.offset; val = (off < event->len) ? event->value + off : NULL; vlen = (off < event->len) ? (event->len - off) : 0; } - ret = params->func(conn, event->status, params, val, vlen); + ret = read_copy.func(conn, event->status, params, val, vlen); - /* (0, NULL, 0) is the success-completion signal per bt_gatt_read_func_t. - * Skip it on error paths — the error call above is already terminal; - * sending a follow-up "success" would let lib treat the read as OK and - * keep stale data. Mirrors NimBLE nrp.c, which fires func(err, NULL, 0) - * once on the default branch and never the success-completion. */ if (ret == BT_GATT_ITER_CONTINUE && event->status == 0) { - params->func(conn, 0, params, NULL, 0); + read_copy.func(conn, 0, params, NULL, 0); } end: @@ -2898,25 +2901,23 @@ int bt_le_bluedroid_gattc_read(struct bt_conn *conn, struct bt_gatt_read_params conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn->handle); - if (params->handle_count == 0) { - LOG_INF("[B]RdByTypeReq[0x%04x]", BT_UUID_16(params->by_uuid.uuid)->val); + if (op->read.params_copy.handle_count == 0) { + LOG_INF("[B]RdByTypeReq[0x%04x]", + BT_UUID_16(op->read.params_copy.by_uuid.uuid)->val); - bt_le_bluedroid_gatt_uuid_convert(params->by_uuid.uuid, &uuid); + bt_le_bluedroid_gatt_uuid_convert(op->read.params_copy.by_uuid.uuid, &uuid); - BTA_GATTC_Read_by_type(conn_id, params->by_uuid.start_handle, - params->by_uuid.end_handle, &uuid, + BTA_GATTC_Read_by_type(conn_id, + op->read.params_copy.by_uuid.start_handle, + op->read.params_copy.by_uuid.end_handle, &uuid, BTA_GATT_AUTH_REQ_NONE); } else { - LOG_INF("[B]RdReq[%u][%u]", params->single.handle, params->single.offset); + LOG_INF("[B]RdReq[%u][%u]", + op->read.params_copy.single.handle, + op->read.params_copy.single.offset); - /* A non-zero offset is a long read: the lib re-reads the remainder of - * an ASE/BASS value whose notification was MTU-truncated. BTA's - * ReadLongChar would run GATTC_Read inline on the ISO task, racing the - * BTU task that owns gatt_cb. Always issue ReadCharacteristic instead - * (GATT_READ_BY_HANDLE) — BTA auto-continues it with Read Blob on the - * BTU task to fetch the full value, and handle_gattc_read_chrc_event - * slices the requested [offset:] tail back to the caller. */ - BTA_GATTC_ReadCharacteristic(conn_id, params->single.handle, + BTA_GATTC_ReadCharacteristic(conn_id, + op->read.params_copy.single.handle, BTA_GATT_AUTH_REQ_NONE); } diff --git a/components/bt/esp_ble_iso/host/adapter/nimble/gatt/gatt.nrp.c b/components/bt/esp_ble_iso/host/adapter/nimble/gatt/gatt.nrp.c index 1561afef952..b6679b8ea53 100644 --- a/components/bt/esp_ble_iso/host/adapter/nimble/gatt/gatt.nrp.c +++ b/components/bt/esp_ble_iso/host/adapter/nimble/gatt/gatt.nrp.c @@ -48,6 +48,7 @@ struct gatt_nrp_node { } read_long; struct { + struct bt_gatt_read_params params_copy; struct bt_gatt_read_params *params; } read_single; @@ -271,15 +272,20 @@ static int gattc_nrp_read_single_cb_safe(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg) { - struct bt_gatt_read_params *read_params; + struct bt_gatt_read_params *params_copy = arg; + struct bt_gatt_read_params *original; + struct gatt_nrp_node *nrp_node; + bt_gatt_read_func_t func; struct bt_conn *conn; int rc = 0; - read_params = arg; - assert(read_params); - assert(read_params->func); - assert(read_params->handle_count == 1); - assert(read_params->single.offset == 0); + nrp_node = CONTAINER_OF(params_copy, struct gatt_nrp_node, read_single.params_copy); + original = nrp_node->read_single.params; + func = params_copy->func; + + assert(func); + assert(params_copy->handle_count == 1); + assert(params_copy->single.offset == 0); LOG_DBG("[N]GattcNrpRdSingleCb[%u][%04x]", conn_handle, error->status); @@ -292,8 +298,8 @@ static int gattc_nrp_read_single_cb_safe(uint16_t conn_handle, goto end; } - /* Shall be invoked before the read_params->func is invoked */ - bt_le_nimble_gatt_nrp_remove(conn, GATTC_NRP_READ_SINGLE, read_params, 0); + /* Frees nrp_node (and params_copy); func and original are locals. */ + bt_le_nimble_gatt_nrp_remove(conn, GATTC_NRP_READ_SINGLE, original, 0); switch (error->status) { case 0: @@ -301,27 +307,24 @@ static int gattc_nrp_read_single_cb_safe(uint16_t conn_handle, assert(attr->om); LOG_DBG("[N]GattcNrpHdl[%u][%u]Len[%u]", - attr->handle, read_params->single.handle, attr->om->om_len); + attr->handle, original->single.handle, attr->om->om_len); - if (read_params->func(conn, 0, read_params, - attr->om->om_data, - attr->om->om_len) == BT_GATT_ITER_CONTINUE) { - /* Workaround for completing the handling of ATT Read Response - * by BAP Unicast Client. - */ - read_params->func(conn, 0, read_params, NULL, 0); + if (func(conn, 0, original, + attr->om->om_data, + attr->om->om_len) == BT_GATT_ITER_CONTINUE) { + func(conn, 0, original, NULL, 0); } break; case BLE_HS_EDONE: - read_params->func(conn, 0, read_params, NULL, 0); + func(conn, 0, original, NULL, 0); break; default: LOG_WRN("[N]GattcNrpStatus[%04x]", error->status); if (error->status & BLE_HS_ERR_ATT_BASE) { - read_params->func(conn, (uint8_t)error->status, read_params, NULL, 0); + func(conn, (uint8_t)error->status, original, NULL, 0); } rc = error->status; @@ -736,6 +739,7 @@ static int gatt_nrp_insert(struct bt_conn *conn, uint8_t type, void *params) nrp_node->read_long.params = params; break; case GATTC_NRP_READ_SINGLE: + nrp_node->read_single.params_copy = *(struct bt_gatt_read_params *)params; nrp_node->read_single.params = params; break; case GATTC_NRP_WRITE_REQ: { @@ -784,9 +788,10 @@ static int gatt_nrp_insert(struct bt_conn *conn, uint8_t type, void *params) LOG_DBG("[N]GattNrpListEmpty"); if (type == GATTC_NRP_READ_BY_UUID || - type == GATTC_NRP_READ_LONG || - type == GATTC_NRP_READ_SINGLE) { + type == GATTC_NRP_READ_LONG) { rc = gattc_nrp_read(conn, params); + } else if (type == GATTC_NRP_READ_SINGLE) { + rc = gattc_nrp_read(conn, &nrp_node->read_single.params_copy); } else if (type == GATTC_NRP_WRITE_REQ) { rc = gattc_nrp_write(conn, params, nrp_node->write_req.data_copy, @@ -957,12 +962,13 @@ int bt_le_nimble_gatt_nrp_remove(struct bt_conn *conn, uint8_t type, void *param nrp_head->read_long.params->func(conn, rc, nrp_head->read_long.params, NULL, 0); } } else if (nrp_head->type == GATTC_NRP_READ_SINGLE) { - rc = gattc_nrp_read(conn, nrp_head->read_single.params); + rc = gattc_nrp_read(conn, &nrp_head->read_single.params_copy); if (rc) { LOG_ERR("[N]GattcNrpRdSingleFail[%d]", rc); - assert(nrp_head->read_single.params->func); - nrp_head->read_single.params->func(conn, rc, nrp_head->read_single.params, NULL, 0); + assert(nrp_head->read_single.params_copy.func); + nrp_head->read_single.params_copy.func(conn, rc, + nrp_head->read_single.params, NULL, 0); } } else if (nrp_head->type == GATTC_NRP_WRITE_REQ) { rc = gattc_nrp_write(conn, nrp_head->write_req.params,