From patchwork Tue Nov 15 00:30:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 626226 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5B21C4332F for ; Tue, 15 Nov 2022 00:30:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235592AbiKOAan (ORCPT ); Mon, 14 Nov 2022 19:30:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37724 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229484AbiKOAam (ORCPT ); Mon, 14 Nov 2022 19:30:42 -0500 Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99176D11D for ; Mon, 14 Nov 2022 16:30:41 -0800 (PST) Received: by mail-pg1-x529.google.com with SMTP id o13so11752091pgu.7 for ; Mon, 14 Nov 2022 16:30:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=YrZksNtxMwN8zKibp2Oab3a3oHg6YCF87gJfDncnNok=; b=BzDIGm7+HtGWrFW4lhVXwmuOUURhPY0eUc2jwnoctQimeQdj4NmmNcT+lR/dYI4/ei 7prx9L3hlRBxvfswPpg3I2HGPy+pnSgBu6XdQFfZu5j5LMj+CO0SeJfdeH+zHDaQNoZw Ttn6qnUM4au1CXZX4y1ZziAdqci0DW1hNT0RFs+EQEwhaGnEN4ejh+ZlGW+gTyZpuUYI Tm8+QSOUgtkraWUPFdmaWVIzlcdZI6Qj/W71usHqGURc+EjLN9MEAjVdJG/FtS7IyZDE Zee0zFUheelz1f9JG5lo/qhxkPHxV8N5UOAdCBi4l4ix5bqBwnoIONE0fcvPEKSQelhV ojJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=YrZksNtxMwN8zKibp2Oab3a3oHg6YCF87gJfDncnNok=; b=xbL9yXOZsBNcmRc483aeF9QaNOaVbtomkpe6d6BkHsKMT5o4Ccu/ekRlmMepNofp+3 YjTDV6rV1wv5lrsxpDPmD5kDXTMCKQhcxsjxEm8nSHr+12JPmG0DHNrBCNbZnju2cE07 prhmEKu93fwcJnAfzWMn64KMFyVO5sj8b6axIZjVkoqdl73JRk+0iad8mKmHcmok7KGt zG62mIOXCiaZgzySu+Pcoi2CQHwsFUb+Or+YAnGgfBrymPGA/9fkjgCXFIp995GexHZK S8sLNrAXQ6ze9wXx7T7taN7OJgCp2011mq1wv0NbPARODX2flebSeUcRg9EiwHLokkOz N1uQ== X-Gm-Message-State: ANoB5pkAnByUVW3vebDkf1qigIXiaageOxXQmhnhXYFF9VMnJnCNbO4W f7/X3G+DK5KovIbDBsCg47fdm/CS97I= X-Google-Smtp-Source: AA0mqf4aYXAwGQk3h64ez2YuGJGkgCSc1aOdsNNvQ9vz6uOPNh3o4Fgl8Fzo7DPTomgXi/iUgikasA== X-Received: by 2002:a63:6686:0:b0:44c:bfe:9b1c with SMTP id a128-20020a636686000000b0044c0bfe9b1cmr13722585pgc.103.1668472240450; Mon, 14 Nov 2022 16:30:40 -0800 (PST) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id h3-20020a17090a3d0300b0020a28156e11sm10307888pjc.26.2022.11.14.16.30.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Nov 2022 16:30:39 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ 1/6] monitor/att: Fix not dequeing att_read on error response Date: Mon, 14 Nov 2022 16:30:33 -0800 Message-Id: <20221115003038.2134340-1-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.37.3 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz If a read/read by type fails it needs to be dequeued otherwise it can cause the next operation of the same type to return the wrong request and possible decoding as if it was a different attribute type. --- monitor/att.c | 109 +++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/monitor/att.c b/monitor/att.c index efd840d51961..d14cbd165697 100644 --- a/monitor/att.c +++ b/monitor/att.c @@ -106,27 +106,66 @@ static bool match_read_frame(const void *data, const void *match_data) return read->chan == frame->chan; } -static void print_data_list(const char *label, uint8_t length, - const struct l2cap_frame *frame) +static struct att_read *att_get_read(const struct l2cap_frame *frame) { struct packet_conn_data *conn; struct att_conn_data *data; + + conn = packet_get_conn_data(frame->handle); + if (!conn) + return NULL; + + data = conn->data; + if (!data) + return NULL; + + return queue_remove_if(data->reads, match_read_frame, (void *)frame); +} + +static void print_attribute(struct gatt_db_attribute *attr) +{ + uint16_t handle; + const bt_uuid_t *uuid; + char label[21]; + + handle = gatt_db_attribute_get_handle(attr); + if (!handle) + goto done; + + uuid = gatt_db_attribute_get_type(attr); + if (!uuid) + goto done; + + switch (uuid->type) { + case BT_UUID16: + sprintf(label, "Handle: 0x%4.4x Type", handle); + print_field("%s: %s (0x%4.4x)", label, + bt_uuid16_to_str(uuid->value.u16), + uuid->value.u16); + return; + case BT_UUID128: + sprintf(label, "Handle: 0x%4.4x Type", handle); + print_uuid(label, &uuid->value.u128, 16); + return; + case BT_UUID_UNSPEC: + case BT_UUID32: + break; + } + +done: + print_field("Handle: 0x%4.4x", handle); +} + +static void print_data_list(const char *label, uint8_t length, + const struct l2cap_frame *frame) +{ struct att_read *read; uint8_t count; if (length == 0) return; - conn = packet_get_conn_data(frame->handle); - if (conn) { - data = conn->data; - if (data) - read = queue_remove_if(data->reads, match_read_frame, - (void *)frame); - else - read = NULL; - } else - read = NULL; + read = att_get_read(frame); count = frame->size / length; @@ -271,6 +310,12 @@ static void att_error_response(const struct l2cap_frame *frame) pdu->request); print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); print_field("Error: %s (0x%2.2x)", str, pdu->error); + + /* Read/Read By Type may create a read object which needs to be dequeued + * and freed in case the operation fails. + */ + if (pdu->request == 0x08 || pdu->request == 0x0a) + free(att_get_read(frame)); } static const struct bitfield_data chrc_prop_table[] = { @@ -2662,36 +2707,6 @@ static struct gatt_db_attribute *get_attribute(const struct l2cap_frame *frame, return gatt_db_get_attribute(db, handle); } -static void print_attribute(struct gatt_db_attribute *attr) -{ - uint16_t handle = gatt_db_attribute_get_handle(attr); - const bt_uuid_t *uuid; - char label[21]; - - uuid = gatt_db_attribute_get_type(attr); - if (!uuid) - goto done; - - switch (uuid->type) { - case BT_UUID16: - sprintf(label, "Handle: 0x%4.4x Type", handle); - print_field("%s: %s (0x%4.4x)", label, - bt_uuid16_to_str(uuid->value.u16), - uuid->value.u16); - return; - case BT_UUID128: - sprintf(label, "Handle: 0x%4.4x Type", handle); - print_uuid(label, &uuid->value.u128, 16); - return; - case BT_UUID_UNSPEC: - case BT_UUID32: - break; - } - -done: - print_field("Handle: 0x%4.4x", handle); -} - static void print_handle(const struct l2cap_frame *frame, uint16_t handle, bool rsp) { @@ -2746,19 +2761,11 @@ static void att_read_req(const struct l2cap_frame *frame) static void att_read_rsp(const struct l2cap_frame *frame) { - struct packet_conn_data *conn; - struct att_conn_data *data; struct att_read *read; print_hex_field("Value", frame->data, frame->size); - conn = packet_get_conn_data(frame->handle); - if (!conn) - return; - - data = conn->data; - - read = queue_remove_if(data->reads, match_read_frame, (void *)frame); + read = att_get_read(frame); if (!read) return; From patchwork Tue Nov 15 00:30:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 624938 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1893C433FE for ; Tue, 15 Nov 2022 00:30:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235707AbiKOAao (ORCPT ); Mon, 14 Nov 2022 19:30:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231864AbiKOAan (ORCPT ); Mon, 14 Nov 2022 19:30:43 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E0A21CFFB for ; Mon, 14 Nov 2022 16:30:42 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id b1-20020a17090a7ac100b00213fde52d49so12345354pjl.3 for ; Mon, 14 Nov 2022 16:30:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=NNiMOLVQp06Z6ykn1e6kwojsIWfRd4etqlKeAPwou0A=; b=j9DRTU6vWZR/1alwXhsTLKC/dSELy02lAqZiJs6F9J3Dkrk048vX7fVBbyH+vb/aPQ MB0+7bw11LnTjO8zBZCiP0j2hXAS0JF61XJIExFTRhWbxdmXbXUuk81j2VmGAAnpuRMd YXSuMl4Vpeh6OKdQua9mzCx9e1xkuam8mmsogHbXsv4iNJjlq3Tdx0UMLei0ClaySiv2 AMQBw2BojmL+jXTuo6AiMtHHx2F47HH8JkzekVp62vycgCRnRV8PJdmZMt/7BBbd/pUY 53Z0Czfc1xNRV3XjsOeKMNFZ4Oz8ffyCh1aTBpXVllOdVTo43vMUBdb/3lEma8LMNBEu Q6Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NNiMOLVQp06Z6ykn1e6kwojsIWfRd4etqlKeAPwou0A=; b=r9gU3kDvZnHLqLKrTugWy6oomdEpZAz0r6tSe8KoQWPWExv6M7i0iBTrEcj+gpzLvo BcwVtk1sZG8XhvneaBJyb+EzYte7SPGnSzk/TuNr4Cp/4Juhm9z/TrD8EOCv9PIiL55D 1TGl/v8SrHznqTI8MvCNf9n08rQcRp7DJl116uX7Bf/GQ5B/F30vbY3MQyyjQf0PhJLN elUyreIWreQt+JqLrCdCEqxQsPSbdZf7EcsFRsOhahjYC4QKwyWbBvMaPwqdumMYFibs Jn5oWvjFpCgXrmOGQf65Mb54trMWnY0qjFrpgUps5AjlRZAj+v17XaKdrVKnkvwgr5zV v4/w== X-Gm-Message-State: ANoB5pkuTv9hATF2P9Enrx4VTDWBUrJBjd0/hciF6jWtWqPp/vwbeq1j DLETwonwnRVMjWtkRyqwc9I9xN6ctVk= X-Google-Smtp-Source: AA0mqf41d2Xy9iBefH66nMhNV3uwJZA0uDUJyIFa88FUVLKhIz28QmnVm0IsS+wnytQ6SeILIQBtog== X-Received: by 2002:a17:902:da90:b0:186:8518:6c95 with SMTP id j16-20020a170902da9000b0018685186c95mr1550505plx.149.1668472241755; Mon, 14 Nov 2022 16:30:41 -0800 (PST) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id h3-20020a17090a3d0300b0020a28156e11sm10307888pjc.26.2022.11.14.16.30.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Nov 2022 16:30:41 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ 2/6] shared/util: Add iovec helpers Date: Mon, 14 Nov 2022 16:30:34 -0800 Message-Id: <20221115003038.2134340-2-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221115003038.2134340-1-luiz.dentz@gmail.com> References: <20221115003038.2134340-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This adds iovec helpers functions. --- src/shared/util.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++ src/shared/util.h | 10 +++++ 2 files changed, 113 insertions(+) diff --git a/src/shared/util.c b/src/shared/util.c index 0a0308cb0786..333023e0dcac 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -189,6 +189,109 @@ void util_clear_uid(uint64_t *bitmap, uint8_t id) *bitmap &= ~(((uint64_t)1) << (id - 1)); } +struct iovec *util_iov_dup(const struct iovec *iov, size_t cnt) +{ + struct iovec *dup; + size_t i; + + if (!iov) + return NULL; + + dup = new0(struct iovec, cnt); + + for (i = 0; i < cnt; i++) + util_iov_memcpy(&dup[i], iov[i].iov_base, iov[i].iov_len); + + return dup; +} + +int util_iov_memcmp(const struct iovec *iov1, const struct iovec *iov2) +{ + if (!iov1) + return 1; + + if (!iov2) + return -1; + + if (iov1->iov_len != iov2->iov_len) + return iov1->iov_len - iov2->iov_len; + + return memcmp(iov1->iov_base, iov2->iov_base, iov1->iov_len); +} + +void util_iov_memcpy(struct iovec *iov, void *src, size_t len) +{ + if (!iov) + return; + + iov->iov_base = realloc(iov->iov_base, len); + iov->iov_len = len; + memcpy(iov->iov_base, src, len); +} + +void util_iov_free(struct iovec *iov, size_t cnt) +{ + size_t i; + + if (!iov) + return; + + for (i = 0; i < cnt; i++) + free(iov[i].iov_base); + + free(iov); +} + +void *util_iov_push(struct iovec *iov, size_t len) +{ + void *data; + + if (!iov) + return NULL; + + data = iov->iov_base + iov->iov_len; + iov->iov_len += len; + + return data; +} + +void *util_iov_push_mem(struct iovec *iov, size_t len, const void *data) +{ + void *p; + + p = util_iov_push(iov, len); + if (!p) + return NULL; + + memcpy(p, data, len); + + return p; +} + +void *util_iov_pull(struct iovec *iov, size_t len) +{ + if (!iov) + return NULL; + + if (iov->iov_len < len) + return NULL; + + iov->iov_base += len; + iov->iov_len -= len; + + return iov->iov_base; +} + +void *util_iov_pull_mem(struct iovec *iov, size_t len) +{ + void *data = iov->iov_base; + + if (util_iov_pull(iov, len)) + return data; + + return NULL; +} + static const struct { uint16_t uuid; const char *str; diff --git a/src/shared/util.h b/src/shared/util.h index 554481e1e1ea..dc84f963588f 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -15,6 +15,7 @@ #include #include #include +#include #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define BIT(n) (1 << (n)) @@ -109,6 +110,15 @@ ssize_t util_getrandom(void *buf, size_t buflen, unsigned int flags); uint8_t util_get_uid(uint64_t *bitmap, uint8_t max); void util_clear_uid(uint64_t *bitmap, uint8_t id); +struct iovec *util_iov_dup(const struct iovec *iov, size_t cnt); +int util_iov_memcmp(const struct iovec *iov1, const struct iovec *iov2); +void util_iov_memcpy(struct iovec *iov, void *src, size_t len); +void *util_iov_push(struct iovec *iov, size_t len); +void *util_iov_push_mem(struct iovec *iov, size_t len, const void *data); +void *util_iov_pull(struct iovec *iov, size_t len); +void *util_iov_pull_mem(struct iovec *iov, size_t len); +void util_iov_free(struct iovec *iov, size_t cnt); + const char *bt_uuid16_to_str(uint16_t uuid); const char *bt_uuid32_to_str(uint32_t uuid); const char *bt_uuid128_to_str(const uint8_t uuid[16]); From patchwork Tue Nov 15 00:30:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 626225 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14A36C4332F for ; Tue, 15 Nov 2022 00:30:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237247AbiKOAaw (ORCPT ); Mon, 14 Nov 2022 19:30:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231602AbiKOAaq (ORCPT ); Mon, 14 Nov 2022 19:30:46 -0500 Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DA2961D0DB for ; Mon, 14 Nov 2022 16:30:44 -0800 (PST) Received: by mail-pg1-x52e.google.com with SMTP id 136so11776653pga.1 for ; Mon, 14 Nov 2022 16:30:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Klz1V5+/kIG/8boWajkUG+hO/oaRhLwe6+96Y8lDrmU=; b=BFEW+a14CLoCeWm/bKNakhvvLnHYHUlGy48eszsRFqwL4COAHzqlKjqJprwisHLzxz Ae/n7RpS/75Vnqoyu3gNARmE1OItuOXVS431kOHU16IeEZ6YVHojGzt9mw6Ye3X8MWYp fQZ+S66FV1ieVZ0EFOmoHJ1m1UX+2O9EcWDgMl03ouYrpH2SNE2ZZjHJt1z/bTu/z6Pw F1oWL8jHujCOfiHDRdVdIW75FUyaB+ZusT41+7xBwrEvkq7QugJQELDbbrAT/sVGZsjh 8pcPKw3vr5ZUXxLW9ivW8uUzlWF96QsQtPnYYBon7htUSM8/Oq73ZY4AV2cCQJetBW0C yyLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Klz1V5+/kIG/8boWajkUG+hO/oaRhLwe6+96Y8lDrmU=; b=YUaolrxFGrmsT2ejCsEOlkHfs7pyqJoQenf+K5X3TdgVtf835yy8org1cvUJ/rtLLW Fty8aEi0pF2lVG7gYjms15nCy2umwn6ny3by/CnRtRbY11VB9G+y6G4ByI0ctguaqkBl Sie75EP8OxhvXRVKbv/OpSuT8MgS50sadsLfvTjmHGRzkJYSS1KXzOhGM1zdRejy8pAR r2qVQXYh91IJyMIfTyweMVEMmV1QIYYVDiS/YRKF6W3U9IfbXx1HpDLPmN1wR2xqMeu9 M2GLW4pjnP/HKhFEsRJSA1bngTScz6LWPqvrkCP51fp/iQExuXH0WitQxo1MpjIfhB2q NlXA== X-Gm-Message-State: ANoB5pmLOmAGPxr+yx+ucBoBbwtrZ+NQWnnkNbSXJYmMpFlAmtSxRCYT 86sqtlT6MmGd7BMa+DZtkKv8rOASUzw= X-Google-Smtp-Source: AA0mqf6PTby+CxxvlTAdjgpuN5/M5ABq04cbHgNNbcTe/3qloB778RYPgFnWFDdRwj4bjWOiNwxMoQ== X-Received: by 2002:a63:5203:0:b0:46e:f23a:e9aa with SMTP id g3-20020a635203000000b0046ef23ae9aamr13392207pgb.428.1668472243532; Mon, 14 Nov 2022 16:30:43 -0800 (PST) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id h3-20020a17090a3d0300b0020a28156e11sm10307888pjc.26.2022.11.14.16.30.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Nov 2022 16:30:42 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ 3/6] shared/bap: Make use of util_iov helpers Date: Mon, 14 Nov 2022 16:30:35 -0800 Message-Id: <20221115003038.2134340-3-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221115003038.2134340-1-luiz.dentz@gmail.com> References: <20221115003038.2134340-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This make use of util_iov helpers instead of reimplementing them. --- src/shared/bap.c | 183 +++++++++++++---------------------------------- 1 file changed, 51 insertions(+), 132 deletions(-) diff --git a/src/shared/bap.c b/src/shared/bap.c index c3c0d596fe91..25369e619051 100644 --- a/src/shared/bap.c +++ b/src/shared/bap.c @@ -262,76 +262,6 @@ static bool bap_db_match(const void *data, const void *match_data) return (bdb->db == db); } -static void *iov_add(struct iovec *iov, size_t len) -{ - void *data; - - data = iov->iov_base + iov->iov_len; - iov->iov_len += len; - - return data; -} - -static void *iov_add_mem(struct iovec *iov, size_t len, const void *d) -{ - void *data; - - data = iov->iov_base + iov->iov_len; - iov->iov_len += len; - - memcpy(data, d, len); - - return data; -} - -static void iov_free(void *data) -{ - struct iovec *iov = data; - - if (!iov) - return; - - free(iov->iov_base); - free(iov); -} - -static void iov_memcpy(struct iovec *iov, void *src, size_t len) -{ - iov->iov_base = realloc(iov->iov_base, len); - iov->iov_len = len; - memcpy(iov->iov_base, src, len); -} - -static int iov_memcmp(struct iovec *iov1, struct iovec *iov2) -{ - if (!iov1) - return 1; - - if (!iov2) - return -1; - - if (iov1->iov_len != iov2->iov_len) - return iov1->iov_len - iov2->iov_len; - - return memcmp(iov1->iov_base, iov2->iov_base, iov1->iov_len); -} - -static struct iovec *iov_dup(struct iovec *iov, size_t len) -{ - struct iovec *dup; - size_t i; - - if (!iov) - return NULL; - - dup = new0(struct iovec, len); - - for (i = 0; i < len; i++) - iov_memcpy(&dup[i], iov[i].iov_base, iov[i].iov_len); - - return dup; -} - unsigned int bt_bap_pac_register(bt_bap_pac_func_t added, bt_bap_pac_func_t removed, void *user_data, bt_bap_destroy_func_t destroy) @@ -407,27 +337,27 @@ static void pac_foreach(void *data, void *user_data) struct bt_pac_metadata *meta; if (!iov->iov_len) { - rsp = iov_add(iov, sizeof(*rsp)); + rsp = util_iov_push(iov, sizeof(*rsp)); rsp->num_pac = 0; } else rsp = iov->iov_base; rsp->num_pac++; - p = iov_add(iov, sizeof(*p)); + p = util_iov_push(iov, sizeof(*p)); p->codec.id = pac->codec.id; if (pac->data) { p->cc_len = pac->data->iov_len; - iov_add_mem(iov, p->cc_len, pac->data->iov_base); + util_iov_push_mem(iov, p->cc_len, pac->data->iov_base); } else p->cc_len = 0; - meta = iov_add(iov, sizeof(*meta)); + meta = util_iov_push(iov, sizeof(*meta)); if (pac->metadata) { meta->len = pac->metadata->iov_len; - iov_add_mem(iov, meta->len, pac->metadata->iov_base); + util_iov_push_mem(iov, meta->len, pac->metadata->iov_base); } else meta->len = 0; } @@ -814,19 +744,6 @@ static void ase_new(struct bt_ascs *ascs, int i) ascs->ase[i] = ase; } -static void *iov_pull_mem(struct iovec *iov, size_t len) -{ - void *data = iov->iov_base; - - if (iov->iov_len < len) - return NULL; - - iov->iov_base += len; - iov->iov_len -= len; - - return data; -} - static bool bap_codec_equal(const struct bt_bap_codec *c1, const struct bt_bap_codec *c2) { @@ -852,7 +769,7 @@ static struct bt_bap_stream *bap_stream_new(struct bt_bap *bap, ep->stream = stream; stream->lpac = lpac; stream->rpac = rpac; - stream->cc = iov_dup(data, 1); + stream->cc = util_iov_dup(data, 1); stream->client = client; queue_push_tail(bap->streams, stream); @@ -1050,8 +967,8 @@ static void bap_stream_free(void *data) queue_foreach(stream->links, bap_stream_unlink, stream); queue_destroy(stream->links, NULL); stream_io_unref(stream->io); - iov_free(stream->cc); - iov_free(stream->meta); + util_iov_free(stream->cc, 1); + util_iov_free(stream->meta, 1); free(stream); } @@ -1454,13 +1371,13 @@ static uint8_t stream_config(struct bt_bap_stream *stream, struct iovec *cc, /* TODO: Wait for pac->ops response */ ascs_ase_rsp_success(rsp, stream->ep->id); - if (!iov_memcmp(stream->cc, cc)) { + if (!util_iov_memcmp(stream->cc, cc)) { stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG); return 0; } - iov_free(stream->cc); - stream->cc = iov_dup(cc, 1); + util_iov_free(stream->cc, 1); + stream->cc = util_iov_dup(cc, 1); if (pac->ops && pac->ops->config) pac->ops->config(stream, cc, NULL, ep_config_cb, @@ -1497,7 +1414,7 @@ static uint8_t ep_config(struct bt_bap_endpoint *ep, struct bt_bap *bap, if (iov->iov_len < req->cc_len) return BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN; - cc.iov_base = iov_pull_mem(iov, req->cc_len); + cc.iov_base = util_iov_pull_mem(iov, req->cc_len); cc.iov_len = req->cc_len; if (!bap_print_cc(cc.iov_base, cc.iov_len, bap->debug_func, @@ -1548,7 +1465,7 @@ static uint8_t ascs_config(struct bt_ascs *ascs, struct bt_bap *bap, struct bt_bap_endpoint *ep; struct bt_ascs_config *req; - req = iov_pull_mem(iov, sizeof(*req)); + req = util_iov_pull_mem(iov, sizeof(*req)); DBG(bap, "codec 0x%02x phy 0x%02x latency %u", req->codec.id, req->phy, req->latency); @@ -1616,7 +1533,7 @@ static uint8_t ascs_qos(struct bt_ascs *ascs, struct bt_bap *bap, struct bt_ascs_qos *req; struct bt_bap_qos qos; - req = iov_pull_mem(iov, sizeof(*req)); + req = util_iov_pull_mem(iov, sizeof(*req)); memset(&qos, 0, sizeof(qos)); @@ -1653,8 +1570,8 @@ static uint8_t stream_enable(struct bt_bap_stream *stream, struct iovec *meta, ascs_ase_rsp_success(rsp, stream->ep->id); - iov_free(stream->meta); - stream->meta = iov_dup(meta, 1); + util_iov_free(stream->meta, 1); + stream->meta = util_iov_dup(meta, 1); stream_set_state(stream, BT_BAP_STREAM_STATE_ENABLING); @@ -1677,7 +1594,7 @@ static bool bap_print_ltv(const char *label, void *data, size_t len, util_debug(func, user_data, "Length %zu", iov.iov_len); for (i = 0; iov.iov_len > 1; i++) { - struct bt_ltv *ltv = iov_pull_mem(&iov, sizeof(*ltv)); + struct bt_ltv *ltv = util_iov_pull_mem(&iov, sizeof(*ltv)); uint8_t *data; if (!ltv) { @@ -1689,7 +1606,7 @@ static bool bap_print_ltv(const char *label, void *data, size_t len, util_debug(func, user_data, "%s #%u: len %u type %u", label, i, ltv->len, ltv->type); - data = iov_pull_mem(&iov, ltv->len - 1); + data = util_iov_pull_mem(&iov, ltv->len - 1); if (!data) { util_debug(func, user_data, "Unable to parse %s", label); @@ -1728,7 +1645,7 @@ static uint8_t ep_enable(struct bt_bap_endpoint *ep, struct bt_bap *bap, return 0; } - meta.iov_base = iov_pull_mem(iov, req->meta.len); + meta.iov_base = util_iov_pull_mem(iov, req->meta.len); meta.iov_len = req->meta.len; if (!bap_print_metadata(meta.iov_base, meta.iov_len, bap->debug_func, @@ -1756,7 +1673,7 @@ static uint8_t ascs_enable(struct bt_ascs *ascs, struct bt_bap *bap, struct bt_bap_endpoint *ep; struct bt_ascs_enable *req; - req = iov_pull_mem(iov, sizeof(*req)); + req = util_iov_pull_mem(iov, sizeof(*req)); ep = bap_get_endpoint_id(bap, bap->ldb, req->meta.ase); if (!ep) { @@ -1820,7 +1737,7 @@ static uint8_t ascs_start(struct bt_ascs *ascs, struct bt_bap *bap, struct bt_bap_endpoint *ep; struct bt_ascs_start *req; - req = iov_pull_mem(iov, sizeof(*req)); + req = util_iov_pull_mem(iov, sizeof(*req)); ep = bap_get_endpoint_id(bap, bap->ldb, req->ase); if (!ep) { @@ -1892,7 +1809,7 @@ static uint8_t ascs_disable(struct bt_ascs *ascs, struct bt_bap *bap, struct bt_bap_endpoint *ep; struct bt_ascs_disable *req; - req = iov_pull_mem(iov, sizeof(*req)); + req = util_iov_pull_mem(iov, sizeof(*req)); ep = bap_get_endpoint_id(bap, bap->ldb, req->ase); if (!ep) { @@ -1967,7 +1884,7 @@ static uint8_t ascs_stop(struct bt_ascs *ascs, struct bt_bap *bap, struct bt_bap_endpoint *ep; struct bt_ascs_stop *req; - req = iov_pull_mem(iov, sizeof(*req)); + req = util_iov_pull_mem(iov, sizeof(*req)); ep = bap_get_endpoint_id(bap, bap->ldb, req->ase); if (!ep) { @@ -1995,8 +1912,8 @@ static uint8_t stream_metadata(struct bt_bap_stream *stream, struct iovec *meta, ascs_ase_rsp_success(rsp, stream->ep->id); - iov_free(stream->meta); - stream->meta = iov_dup(meta, 1); + util_iov_free(stream->meta, 1); + stream->meta = util_iov_dup(meta, 1); return 0; } @@ -2032,7 +1949,7 @@ static uint8_t ascs_metadata(struct bt_ascs *ascs, struct bt_bap *bap, struct bt_bap_endpoint *ep; struct bt_ascs_metadata *req; - req = iov_pull_mem(iov, sizeof(*req)); + req = util_iov_pull_mem(iov, sizeof(*req)); ep = bap_get_endpoint_id(bap, bap->ldb, req->ase); if (!ep) { @@ -2076,7 +1993,7 @@ static uint8_t ascs_release(struct bt_ascs *ascs, struct bt_bap *bap, struct bt_bap_endpoint *ep; struct bt_ascs_release *req; - req = iov_pull_mem(iov, sizeof(*req)); + req = util_iov_pull_mem(iov, sizeof(*req)); ep = bap_get_endpoint_id(bap, bap->ldb, req->ase); if (!ep) { @@ -2177,7 +2094,7 @@ static void ascs_ase_cp_write(struct gatt_db_attribute *attrib, return; } - hdr = iov_pull_mem(&iov, sizeof(*hdr)); + hdr = util_iov_pull_mem(&iov, sizeof(*hdr)); rsp = ascs_ase_cp_rsp_new(hdr->op); for (handler = handlers; handler && handler->str; handler++) { @@ -2214,7 +2131,7 @@ respond: gatt_db_attribute_notify(attrib, rsp->iov_base, rsp->iov_len, att); gatt_db_attribute_write_result(attrib, id, ret); - iov_free(rsp); + util_iov_free(rsp, 1); } static struct bt_ascs *ascs_new(struct gatt_db *db) @@ -2333,8 +2250,8 @@ static struct bt_bap_pac *bap_pac_new(struct bt_bap_db *bdb, const char *name, pac->name = name ? strdup(name) : NULL; pac->type = type; pac->codec = *codec; - pac->data = iov_dup(data, 1); - pac->metadata = iov_dup(metadata, 1); + pac->data = util_iov_dup(data, 1); + pac->metadata = util_iov_dup(metadata, 1); if (qos) pac->qos = *qos; @@ -2347,8 +2264,8 @@ static void bap_pac_free(void *data) struct bt_bap_pac *pac = data; free(pac->name); - iov_free(pac->metadata); - iov_free(pac->data); + util_iov_free(pac->metadata, 1); + util_iov_free(pac->data, 1); free(pac); } @@ -2769,7 +2686,7 @@ static void bap_parse_pacs(struct bt_bap *bap, uint8_t type, }; int i; - rsp = iov_pull_mem(&iov, sizeof(*rsp)); + rsp = util_iov_pull_mem(&iov, sizeof(*rsp)); if (!rsp) { DBG(bap, "Unable to parse PAC"); return; @@ -2784,7 +2701,7 @@ static void bap_parse_pacs(struct bt_bap *bap, uint8_t type, struct bt_pac_metadata *meta; struct iovec data, metadata; - p = iov_pull_mem(&iov, sizeof(*p)); + p = util_iov_pull_mem(&iov, sizeof(*p)); if (!p) { DBG(bap, "Unable to parse PAC"); return; @@ -2796,13 +2713,13 @@ static void bap_parse_pacs(struct bt_bap *bap, uint8_t type, bap->debug_data)) return; - cc = iov_pull_mem(&iov, p->cc_len); + cc = util_iov_pull_mem(&iov, p->cc_len); if (!cc) { DBG(bap, "Unable to parse PAC codec capabilities"); return; } - meta = iov_pull_mem(&iov, sizeof(*meta)); + meta = util_iov_pull_mem(&iov, sizeof(*meta)); if (!meta) { DBG(bap, "Unable to parse PAC metadata"); return; @@ -2814,7 +2731,7 @@ static void bap_parse_pacs(struct bt_bap *bap, uint8_t type, metadata.iov_len = meta->len; metadata.iov_base = meta->data; - iov_pull_mem(&iov, meta->len); + util_iov_pull_mem(&iov, meta->len); pac = bap_pac_new(bap->rdb, NULL, type, &p->codec, NULL, &data, &metadata); @@ -3089,7 +3006,7 @@ static void ep_status_config(struct bt_bap *bap, struct bt_bap_endpoint *ep, uint32_t pd_min, pd_max, ppd_min, ppd_max; int i; - cfg = iov_pull_mem(iov, sizeof(*cfg)); + cfg = util_iov_pull_mem(iov, sizeof(*cfg)); if (!cfg) { DBG(bap, "Unable to parse Config Status"); return; @@ -3113,14 +3030,14 @@ static void ep_status_config(struct bt_bap *bap, struct bt_bap_endpoint *ep, } for (i = 0; iov->iov_len >= sizeof(*cc); i++) { - cc = iov_pull_mem(iov, sizeof(*cc)); + cc = util_iov_pull_mem(iov, sizeof(*cc)); if (!cc) break; DBG(bap, "Codec Config #%u: type 0x%02x len %u", i, cc->type, cc->len); - iov_pull_mem(iov, cc->len - 1); + util_iov_pull_mem(iov, cc->len - 1); } /* Any previously applied codec configuration may be cached by the @@ -3160,7 +3077,7 @@ static void ep_status_config(struct bt_bap *bap, struct bt_bap_endpoint *ep, if (!ep->stream->cc) ep->stream->cc = new0(struct iovec, 1); - iov_memcpy(ep->stream->cc, cfg->cc, cfg->cc_len); + util_iov_memcpy(ep->stream->cc, cfg->cc, cfg->cc_len); } static void bap_stream_config_cfm_cb(struct bt_bap_stream *stream, int err) @@ -3200,7 +3117,7 @@ static void ep_status_qos(struct bt_bap *bap, struct bt_bap_endpoint *ep, uint16_t sdu; uint16_t latency; - qos = iov_pull_mem(iov, sizeof(*qos)); + qos = util_iov_pull_mem(iov, sizeof(*qos)); if (!qos) { DBG(bap, "Unable to parse QoS Status"); return; @@ -3236,7 +3153,7 @@ static void ep_status_metadata(struct bt_bap *bap, struct bt_bap_endpoint *ep, { struct bt_ascs_ase_status_metadata *meta; - meta = iov_pull_mem(iov, sizeof(*meta)); + meta = util_iov_pull_mem(iov, sizeof(*meta)); if (!meta) { DBG(bap, "Unable to parse Metadata Status"); return; @@ -3255,7 +3172,7 @@ static void bap_ep_set_status(struct bt_bap *bap, struct bt_bap_endpoint *ep, .iov_len = length, }; - rsp = iov_pull_mem(&iov, sizeof(*rsp)); + rsp = util_iov_pull_mem(&iov, sizeof(*rsp)); if (!rsp) return; @@ -3391,7 +3308,8 @@ static void append_group(void *data, void *user_data) size_t i; for (i = 0; i < req->len; i++) - iov_add_mem(iov, req->iov[i].iov_len, req->iov[i].iov_base); + util_iov_push_mem(iov, req->iov[i].iov_len, + req->iov[i].iov_base); } static bool bap_send(struct bt_bap *bap, struct bt_bap_req *req) @@ -3414,10 +3332,11 @@ static bool bap_send(struct bt_bap *bap, struct bt_bap_req *req) hdr.op = req->op; hdr.num = 1 + queue_length(req->group); - iov_add_mem(&iov, sizeof(hdr), &hdr); + util_iov_push_mem(&iov, sizeof(hdr), &hdr); for (i = 0; i < req->len; i++) - iov_add_mem(&iov, req->iov[i].iov_len, req->iov[i].iov_base); + util_iov_push_mem(&iov, req->iov[i].iov_len, + req->iov[i].iov_base); /* Append the request group with the same opcode */ queue_foreach(req->group, append_group, &iov); @@ -4011,7 +3930,7 @@ static struct bt_bap_req *bap_req_new(struct bt_bap_stream *stream, req->id = ++id; req->stream = stream; req->op = op; - req->iov = iov_dup(iov, len); + req->iov = util_iov_dup(iov, len); req->len = len; req->func = func; req->user_data = user_data; From patchwork Tue Nov 15 00:30:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 626224 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C365C433FE for ; Tue, 15 Nov 2022 00:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231602AbiKOAay (ORCPT ); Mon, 14 Nov 2022 19:30:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231379AbiKOAax (ORCPT ); Mon, 14 Nov 2022 19:30:53 -0500 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8643ED11D for ; Mon, 14 Nov 2022 16:30:52 -0800 (PST) Received: by mail-pg1-x533.google.com with SMTP id 130so11764941pgc.5 for ; Mon, 14 Nov 2022 16:30:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=VHrC1F4+KBRIi+HxhoVrcBzerWPZKq0dFT3HGWGGLfA=; b=EfehzetrgJb3bXqNWZIPZsh3Wck0iKDlzNkHmqqy7bgHyVg4+YjTCVnCWyWVNoRHxr LZsGiQya/PFdhw9H5Sr1ruXBrNnw75WEWPYDl0LWGqq2j7ccKoOPd7Srvh+XfXZkuw61 HvWUATUfXgbs50axDf0W+n2kO9bNCieUgs6373DABC2b4EyWBcuN5dScHo2pxZ6HyaOJ vzwSfRWYYQulqyrDUI+CKFeTsnl/SyDQidikCOtTnMMdfi/XD4DNXEmAyLkafrEMlOPq O84Vuenee1Gj9svRyU++GOjW5Demubgorl51rnVdBi4CCFgm2/0jnQPKefRWdJ3mzmBm cj3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VHrC1F4+KBRIi+HxhoVrcBzerWPZKq0dFT3HGWGGLfA=; b=PhY0WeBpug2xukWxyVwhEOcVHaFPFIojncH73SpytaiA6b3mQx8Lfv62QRUjUPJC9m Y1hbNNPAU9IuONivgZuz9alUfB8MVw/XbVkGal36RoVp6QDdVppDX7G3c3k0h1qpLvJM jYLBJjdmMCPLxIUXZLnCnOyDiak3otPjzDdqwDVyKHp+lQSQ0pgYBVo8U7BeXTUEwWmW //CLuiXsHrFcSQiVmbwaGlXnqXJUtnjZcMuynBdONlodNgzX5dJLJ/nVOHyi8lxoIfA6 64g4kJMESGDizl1d75wL2+5UjHqc/eZjgNgD//XrP7f4eyt1XgR6egC5d0EsZ5u00880 +8nw== X-Gm-Message-State: ANoB5pkfdUTLR7XtDPnfxON8sbP2Ffh7qhEfxnBfsIyijMNTQnieS8rA rzNVh+eLZuOuH/CupvZpI61a/9hYOes= X-Google-Smtp-Source: AA0mqf626L8alM7Im4VmsmTy1x5fvBzBaNTCzQfxeypFasiU0BV8KP2cHtUXKKPucfAtfxCVWvblXw== X-Received: by 2002:a63:310a:0:b0:46f:3a91:361c with SMTP id x10-20020a63310a000000b0046f3a91361cmr173755pgx.261.1668472245113; Mon, 14 Nov 2022 16:30:45 -0800 (PST) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id h3-20020a17090a3d0300b0020a28156e11sm10307888pjc.26.2022.11.14.16.30.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Nov 2022 16:30:44 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ 4/6] shared/tester: Add tester_io_set_complete_func Date: Mon, 14 Nov 2022 16:30:36 -0800 Message-Id: <20221115003038.2134340-4-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221115003038.2134340-1-luiz.dentz@gmail.com> References: <20221115003038.2134340-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This adds tester_io_set_complete_func which can be used to set a callback when all iovec has been sent/received. --- src/shared/tester.c | 16 ++++++++++++++++ src/shared/tester.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/shared/tester.c b/src/shared/tester.c index e88dfabdc37c..1feaba48335c 100644 --- a/src/shared/tester.c +++ b/src/shared/tester.c @@ -89,6 +89,7 @@ struct test_case { tester_data_func_t test_func; tester_data_func_t teardown_func; tester_data_func_t post_teardown_func; + tester_data_func_t io_complete_func; gdouble start_time; gdouble end_time; unsigned int timeout; @@ -913,6 +914,9 @@ static bool test_io_send(struct io *io, void *user_data) g_assert_cmpint(len, ==, iov->iov_len); + if (!test->iovcnt && test->io_complete_func) + test->io_complete_func(test->test_data); + return false; } @@ -937,10 +941,15 @@ static bool test_io_recv(struct io *io, void *user_data) g_assert_cmpint(len, ==, iov->iov_len); + if (memcmp(buf, iov->iov_base, len)) + tester_monitor('!', 0x0004, 0x0000, iov->iov_base, len); + g_assert(memcmp(buf, iov->iov_base, len) == 0); if (test->iovcnt) io_set_write_handler(io, test_io_send, NULL, NULL); + else if (test->io_complete_func) + test->io_complete_func(test->test_data); return true; } @@ -1004,6 +1013,13 @@ void tester_io_send(void) io_set_write_handler(ios[1], test_io_send, NULL, NULL); } +void tester_io_set_complete_func(tester_data_func_t func) +{ + struct test_case *test = tester_get_test(); + + test->io_complete_func = func; +} + int tester_run(void) { int ret; diff --git a/src/shared/tester.h b/src/shared/tester.h index c28f61e7fd6b..49610185a444 100644 --- a/src/shared/tester.h +++ b/src/shared/tester.h @@ -78,3 +78,4 @@ void tester_wait(unsigned int seconds, tester_wait_func_t func, struct io *tester_setup_io(const struct iovec *iov, int iovcnt); void tester_io_send(void); +void tester_io_set_complete_func(tester_data_func_t func); From patchwork Tue Nov 15 00:30:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 624937 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69ECAC43219 for ; Tue, 15 Nov 2022 00:30:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231808AbiKOAax (ORCPT ); Mon, 14 Nov 2022 19:30:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37902 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235917AbiKOAaw (ORCPT ); Mon, 14 Nov 2022 19:30:52 -0500 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2612A1758B for ; Mon, 14 Nov 2022 16:30:51 -0800 (PST) Received: by mail-pl1-x629.google.com with SMTP id io19so11650889plb.8 for ; Mon, 14 Nov 2022 16:30:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=UiyFT+n+qVI/WESmarfkamwzmvVYckxgQ1AedNoQGr8=; b=GGtmP5Umreh6wnFVD1F9g7836/E2eBRk9rCv5stHJtA5kHx/0NBBOAUhM1BxVsIZ/j 3vPz9pgWJhQKd4cFCszNk0/thkLRe0T6PEAYZZ3zS1Hh7kT0JfXP1A2awfBN3hKwiNal seEKd6Tu2jV5ymGsv47BygifnAWDKQ+9od3zVxkDGYTNW+FkC9oHmCBJs7Blgz7JpydC 3QVoCjRMRfc2KCubrS+9t9cEtyQqNdnvOltXPDj/6I+fue9A57s/fwr4/hmBZJ8W/xZ2 1kbV+S2EQl+EQ4hoEs6uhfF+Pp82loel4X/M1EHE0McOobGiaK+Fa66VBL6syi5XsdMv ld2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UiyFT+n+qVI/WESmarfkamwzmvVYckxgQ1AedNoQGr8=; b=irPBlRtOXPP/pxKAJvkkyTknKjocJKsNdrxdtfwmFVfyk3NCHf2y/3k4hWJCVbS2T1 sx55USN4/ftmfw3TYOUvUWzvLKxq3FeJ1u5eztS07sjVEwXAYhRBTKehtMPWDJ+Uq5hr L/UIyCdLwjP1mZ9Ee8sMdTiUoNNOMrnaUzH4JZBKYKrVRaA2gC9kGX7WqWtr8pXoZhB6 kMnuP/z7IOAADdIV4Wpnb/wLDDzdPCgjaoQdywD4P57gD/mZa1QIALuLV/lE3UQfI4qj 94hrb2D2D6fplbfALzEkAdCAcQWndmsryLvv7NO8AMAFVDYazUUXi/yfRLWmjYB8fj+o ltlw== X-Gm-Message-State: ANoB5pm9bs1JxF5M8Lg1DewKECs0UYUBizQwIumDmXbEh/76iM2Ekgtm rOUo78O0S82pxhZP4i8GpxHdLS8eAcw= X-Google-Smtp-Source: AA0mqf6/m9t+JfbY1tLJf5QDOhE/eAXL8ZyFKCHuHtBockXXI9y+uQ+ddKG8CXRizrnifgFgdZtvbQ== X-Received: by 2002:a17:90b:d95:b0:20d:23ee:c041 with SMTP id bg21-20020a17090b0d9500b0020d23eec041mr15662592pjb.140.1668472250150; Mon, 14 Nov 2022 16:30:50 -0800 (PST) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id h3-20020a17090a3d0300b0020a28156e11sm10307888pjc.26.2022.11.14.16.30.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Nov 2022 16:30:49 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ 5/6] shared/bap: Fix crash when canceling requests Date: Mon, 14 Nov 2022 16:30:37 -0800 Message-Id: <20221115003038.2134340-5-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221115003038.2134340-1-luiz.dentz@gmail.com> References: <20221115003038.2134340-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz If bt_bap_unref/bap_free is called while there is an ongoing pending request it may endup calling into bap_notify_ready which will try to notify ready callbacks while holding a reference, but in case the reference is already 0 that means it would switch to 1 and back 0 causing a double free. To prevent that bap_notify_ready now checks that the reference is not 0 with use of bt_bap_ref_safe. --- src/shared/bap.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/shared/bap.c b/src/shared/bap.c index 25369e619051..21aa8aa6c5ca 100644 --- a/src/shared/bap.c +++ b/src/shared/bap.c @@ -2638,6 +2638,14 @@ struct bt_bap *bt_bap_ref(struct bt_bap *bap) return bap; } +static struct bt_bap *bt_bap_ref_safe(struct bt_bap *bap) +{ + if (!bap || !bap->ref_count) + return NULL; + + return bt_bap_ref(bap); +} + void bt_bap_unref(struct bt_bap *bap) { if (!bap) @@ -2656,7 +2664,8 @@ static void bap_notify_ready(struct bt_bap *bap) if (!queue_isempty(bap->pending)) return; - bt_bap_ref(bap); + if (!bt_bap_ref_safe(bap)) + return; for (entry = queue_get_entries(bap->ready_cbs); entry; entry = entry->next) { From patchwork Tue Nov 15 00:30:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 624936 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B282C4332F for ; Tue, 15 Nov 2022 00:30:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232137AbiKOAaz (ORCPT ); Mon, 14 Nov 2022 19:30:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232089AbiKOAay (ORCPT ); Mon, 14 Nov 2022 19:30:54 -0500 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F333A1758B for ; Mon, 14 Nov 2022 16:30:52 -0800 (PST) Received: by mail-pj1-x102a.google.com with SMTP id d13-20020a17090a3b0d00b00213519dfe4aso12364901pjc.2 for ; Mon, 14 Nov 2022 16:30:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=2PVqJU8D0u3Vt6JBa/jWX2Ee3j2Z/ScRjgf8mzBKGpY=; b=DsgafJst1Bdtg/z3quPrM1sem6mRLzNpFVqTZqPcG+owe9kO49+QfWqHhH1yj1C21o MZu+8mODEuiffWNjf5OLqhVUF4hP7uM9xdeiWWPpeV+jEQaYHEeZgjXzNfZayvIzB4iq j4Q/pWV84qXTOSJA3WOf1DfW2eg1tcyson4ZUcwrkwvO2HyXKfBQdaUbYd5MIvuOF8H6 EpN9/O3WNVh79lplaJIS+D+UaD4k53hejXVlTAV5ACAR2AafZtnJkuL5WHky9akoHd5p WlFgMVNMr3wDuP8XSAx9YmhEl3QAn1hFXi8Txm2c8uu6A7QmZFdPZ1XscZD8Wcq7JzNf ldEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2PVqJU8D0u3Vt6JBa/jWX2Ee3j2Z/ScRjgf8mzBKGpY=; b=l/flOsKI9+aH7AAjDnm0cZ6nr8XatYCJP061PrWqInFeN8DhgtfE9jdmuY4TUTz5+H 9ThNYm+Jqkr0QE71ZRRMfZ7P7UlFfTLofIwvvQkwFoRRG7nTMrRyN2n/paYLi7Ft/dLj 0FvUB3OQOr0h2a6DXUKbnJYXXtMcUMD3boKzvGG6N7WSPs4/8DM2lOhm0UPnBFCoMJTX LLux78aHkuuzBGNdyD1eZkDvBM311lp2YqRbyQQhJ5L4Ibn/iOHJ9qb46DL7ieqY8N+a fkek8i5Q+1czqcw6WKBWxTLt3IWWi+6b4gY0Xr7sfxykKg8l9W0ZbGDgZlXCDOlYHPvP oaVA== X-Gm-Message-State: ANoB5pmi0jXON9CIS/+wMr0BlhkaRUkOy00jJIHggY7veDNKy8YqOiqG P3OW6W/aLPTG8TirEeaJ97rHHgfxvs0= X-Google-Smtp-Source: AA0mqf5EbNRVyLKpcNP1iiUuPsklWyTe0tH9xvfc+aUDh82j9rYN96yXVIFVuR5yEA7wYpjrjS9A1w== X-Received: by 2002:a17:90a:a410:b0:211:7e51:9d65 with SMTP id y16-20020a17090aa41000b002117e519d65mr15479943pjp.220.1668472251465; Mon, 14 Nov 2022 16:30:51 -0800 (PST) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id h3-20020a17090a3d0300b0020a28156e11sm10307888pjc.26.2022.11.14.16.30.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Nov 2022 16:30:50 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ 6/6] unit: Introduce test-bap Date: Mon, 14 Nov 2022 16:30:38 -0800 Message-Id: <20221115003038.2134340-6-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221115003038.2134340-1-luiz.dentz@gmail.com> References: <20221115003038.2134340-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz Test Summary ------------ BAP/UCL/DISC/BV-01-C Passed BAP/UCL/DISC/BV-02-C Passed BAP/UCL/DISC/BV-06-C Passed BAP/UCL/DISC/BV-05-C Passed BAP/UCL/DISC/BV-03-C Passed BAP/UCL/DISC/BV-04-C Passed Total: 6, Passed: 6 (100.0%), Failed: 0, Not Run: 0 --- Makefile.am | 6 + unit/test-bap.c | 568 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 574 insertions(+) create mode 100644 unit/test-bap.c diff --git a/Makefile.am b/Makefile.am index 7041f8eeb52b..aa3a5e053cd8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -569,6 +569,12 @@ unit_test_gattrib_LDADD = lib/libbluetooth-internal.la \ src/libshared-glib.la \ $(GLIB_LIBS) $(DBUS_LIBS) -ldl -lrt +unit_tests += unit/test-bap + +unit_test_bap_SOURCES = unit/test-bap.c +unit_test_bap_LDADD = src/libshared-glib.la \ + lib/libbluetooth-internal.la $(GLIB_LIBS) + if MIDI unit_tests += unit/test-midi unit_test_midi_CPPFLAGS = $(AM_CPPFLAGS) $(ALSA_CFLAGS) -DMIDI_TEST diff --git a/unit/test-bap.c b/unit/test-bap.c new file mode 100644 index 000000000000..afeefac84091 --- /dev/null +++ b/unit/test-bap.c @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2022 Intel Corporation. + * + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include + +#include "lib/bluetooth.h" +#include "lib/uuid.h" +#include "src/shared/util.h" +#include "src/shared/io.h" +#include "src/shared/tester.h" +#include "src/shared/queue.h" +#include "src/shared/att.h" +#include "src/shared/gatt-db.h" +#include "src/shared/gatt-client.h" +#include "src/shared/bap.h" + +struct test_data { + struct bt_gatt_client *client; + struct bt_bap *bap; + size_t iovcnt; + struct iovec *iov; +}; + +#define iov_data(args...) ((const struct iovec[]) { args }) + +#define define_test(name, function, args...) \ + do { \ + const struct iovec iov[] = { args }; \ + static struct test_data data; \ + data.iovcnt = ARRAY_SIZE(iov_data(args)); \ + data.iov = util_iov_dup(iov, ARRAY_SIZE(iov_data(args))); \ + tester_add(name, &data, test_setup, function, \ + test_teardown); \ + } while (0) + +static void client_ready_cb(bool success, uint8_t att_ecode, void *user_data) +{ + if (!success) + tester_setup_failed(); + else + tester_setup_complete(); +} + +/* GATT Discover All procedure */ +static const struct iovec setup_data[] = { + /* ATT: Exchange MTU Response (0x03) len 2 + * Server RX MTU: 64 + */ + IOV_DATA(0x02, 0x40, 0x00), + /* ATT: Exchange MTU Request (0x02) len 2 + * Client RX MTU: 64 + */ + IOV_DATA(0x03, 0x40, 0x00), + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0xffff + * Attribute type: Server Supported Features (0x2b3a) + */ + IOV_DATA(0x08, 0x01, 0x00, 0xff, 0xff, 0x3a, 0x2b), + /* ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x0001 + * Error: Attribute Not Found (0x0a) + */ + IOV_DATA(0x01, 0x08, 0x01, 0x00, 0x0a), + /* + * ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0001-0xffff + * Attribute group type: Primary Service (0x2800) + */ + IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), + /* + * ATT: Read By Group Type Response (0x11) len 37 + * Attribute data length: 6 + * Attribute group list: 2 entries + * Handle range: 0x0001-0x0013 + * UUID: Published Audio Capabilities (0x1850) + * Handle range: 0x0014-0x0023 + * UUID: Audio Stream Control (0x184e) + */ + IOV_DATA(0x11, 0x06, + 0x01, 0x00, 0x13, 0x00, 0x50, 0x18, + 0x14, 0x00, 0x23, 0x00, 0x4e, 0x18), + /* ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0024-0xffff + * Attribute group type: Primary Service (0x2800) + */ + IOV_DATA(0x10, 0x24, 0x00, 0xff, 0xff, 0x00, 0x28), + /* ATT: Error Response (0x01) len 4 + * Read By Group Type Request (0x10) + * Handle: 0x0024 + * Error: Attribute Not Found (0x0a) + */ + IOV_DATA(0x01, 0x10, 0x24, 0x00, 0x0a), + /* ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0001-0xffff + * Attribute group type: Secondary Service (0x2801) + */ + IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x01, 0x28), + /* ATT: Error Response (0x01) len 4 + * Read By Group Type Request (0x10) + * Handle: 0x0001 + * Error: Attribute Not Found (0x0a) + */ + IOV_DATA(0x01, 0x10, 0x01, 0x00, 0x0a), + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0x0023 + * Attribute group type: Include (0x2802) + */ + IOV_DATA(0x08, 0x01, 0x00, 0x23, 0x00, 0x02, 0x28), + /* ATT: Error Response (0x01) len 4 + * Read By Group Type Request (0x10) + * Handle: 0x0001 + * Error: Attribute Not Found (0x0a) + */ + IOV_DATA(0x01, 0x08, 0x01, 0x00, 0x0a), + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0x0023 + * Attribute type: Characteristic (0x2803) + */ + IOV_DATA(0x08, 0x01, 0x00, 0x23, 0x00, 0x03, 0x28), + /* ATT: Read By Type Response (0x09) len 57 + * Attribute data length: 7 + * Attribute data list: 8 entries + * Handle: 0x0002 + * Value: 120300c92b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x0003 + * Value UUID: Sink PAC (0x2bc9) + * Handle: 0x0005 + * Value: 120600ca2b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x0006 + * Value UUID: Sink Audio Locations (0x2bca) + * Handle: 0x0008 + * Value: 120900cb2b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x0009 + * Value UUID: Source PAC (0x2bcb) + * Handle: 0x000b + * Value: 120c00cc2b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x000c + * Value UUID: Source Audio Locations (0x2bcc) + * Handle: 0x000e + * Value: 120f00cd2b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x000f + * Value UUID: Available Audio Contexts (0x2bcd) + * Handle: 0x0011 + * Value: 121200ce2b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x0012 + * Value UUID: Supported Audio Contexts (0x2bce) + * Handle: 0x0015 + * Value: 121600c42b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x0016 + * Value UUID: Sink ASE (0x2bc4) + * Handle: 0x0018 + * Value: 121900c42b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x0019 + * Value UUID: Sink ASE (0x2bc4) + */ + IOV_DATA(0x09, 0x07, + 0x02, 0x00, 0x12, 0x03, 0x00, 0xc9, 0x2b, + 0x05, 0x00, 0x12, 0x06, 0x00, 0xca, 0x2b, + 0x08, 0x00, 0x12, 0x09, 0x00, 0xcb, 0x2b, + 0x0b, 0x00, 0x12, 0x0c, 0x00, 0xcc, 0x2b, + 0x0e, 0x00, 0x12, 0x0f, 0x00, 0xcd, 0x2b, + 0x11, 0x00, 0x12, 0x12, 0x00, 0xce, 0x2b, + 0x15, 0x00, 0x12, 0x16, 0x00, 0xc4, 0x2b, + 0x18, 0x00, 0x12, 0x19, 0x00, 0xc4, 0x2b), + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0x0023 + * Attribute type: Characteristic (0x2803) + */ + IOV_DATA(0x08, 0x19, 0x00, 0x23, 0x00, 0x03, 0x28), + /* ATT: Read By Type Response (0x09) len 22 + * Attribute data length: 7 + * Attribute data list: 3 entries + * Handle: 0x001b + * Value: 121c00c52b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x001c + * Value UUID: Source ASE (0x2bc5) + * Handle: 0x001e + * Value: 121f00c52b + * Properties: 0x12 + * Read (0x02) + * Notify (0x10) + * Value Handle: 0x001f + * Value UUID: Source ASE (0x2bc5) + * Handle: 0x0021 + * Value: 182200c62b + * Properties: 0x18 + * Write (0x08) + * Notify (0x10) + * Value Handle: 0x0022 + * Value UUID: ASE Control Point (0x2bc6) + */ + IOV_DATA(0x09, 0x07, + 0x1b, 0x00, 0x12, 0x1c, 0x00, 0xc5, 0x2b, + 0x1e, 0x00, 0x12, 0x1f, 0x00, 0xc5, 0x2b, + 0x21, 0x00, 0x18, 0x22, 0x00, 0xc6, 0x2b), + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0022-0x0023 + * Attribute type: Characteristic (0x2803) + */ + IOV_DATA(0x08, 0x22, 0x00, 0x23, 0x00, 0x03, 0x28), + /* ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x0022 + * Error: Attribute Not Found (0x0a) + */ + IOV_DATA(0x01, 0x08, 0x23, 0x00, 0x0a), + /* ACL Data TX: Handle 42 flags 0x00 dlen 11 + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0xffff + * Attribute type: Database Hash (0x2b2a) + */ + IOV_DATA(0x08, 0x01, 0x00, 0xff, 0xff, 0x2a, 0x2b), + /* ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x0001 + * Error: Attribute Not Found (0x0a) + */ + IOV_DATA(0x01, 0x08, 0x01, 0x00, 0x0a), +}; + +static void print_debug(const char *str, void *user_data) +{ + const char *prefix = user_data; + + if (tester_use_debug()) + tester_debug("%s%s", prefix, str); +} + +static void test_setup(const void *user_data) +{ + struct test_data *data = (void *)user_data; + struct bt_att *att; + struct gatt_db *db; + struct io *io; + + io = tester_setup_io(setup_data, ARRAY_SIZE(setup_data)); + g_assert(io); + + att = bt_att_new(io_get_fd(io), false); + g_assert(att); + + bt_att_set_debug(att, BT_ATT_DEBUG, print_debug, "bt_att:", NULL); + + db = gatt_db_new(); + g_assert(db); + + data->client = bt_gatt_client_new(db, att, 64, 0); + g_assert(data->client); + + bt_gatt_client_set_debug(data->client, print_debug, "bt_gatt_client:", + NULL); + + bt_gatt_client_ready_register(data->client, client_ready_cb, data, + NULL); + + bt_att_unref(att); + gatt_db_unref(db); +} + +static void test_complete_cb(const void *user_data) +{ + tester_test_passed(); +} + +static void test_client(const void *user_data) +{ + struct test_data *data = (void *)user_data; + struct io *io; + struct gatt_db *db; + + io = tester_setup_io(data->iov, data->iovcnt); + g_assert(io); + + tester_io_set_complete_func(test_complete_cb); + + db = gatt_db_new(); + g_assert(db); + + data->bap = bt_bap_new(db, bt_gatt_client_get_db(data->client)); + g_assert(data->bap); + + bt_bap_set_debug(data->bap, print_debug, "bt_bap:", NULL); + + bt_bap_attach(data->bap, data->client); +} + +static void test_teardown(const void *user_data) +{ + struct test_data *data = (void *)user_data; + + bt_bap_unref(data->bap); + bt_gatt_client_unref(data->client); + util_iov_free(data->iov, data->iovcnt); + + tester_teardown_complete(); +} + +/* ATT: Read Request (0x0a) len 2 + * Handle: 0x0003 Type: Sink PAC (0x2bc9) + * ATT: Read Response (0x0b) len 24 + * Value: 010600000000100301ff0002020302030305041e00f00000 + * Handle: 0x0003 Type: Sink PAC (0x2bc9) + * Number of PAC(s): 1 + * PAC #0: + * Codec: LC3 (0x06) + * Codec Specific Capabilities #0: len 0x03 type 0x01 + * Sampling Frequencies: 0x00ff + * 8 Khz (0x0001) + * 11.25 Khz (0x0002) + * 16 Khz (0x0004) + * 22.05 Khz (0x0008) + * 24 Khz (0x0010) + * 32 Khz (0x0020) + * 44.1 Khz (0x0040) + * 48 Khz (0x0080) + * Codec Specific Capabilities #1: len 0x02 type 0x02 + * Frame Duration: 0x0003 + * 7.5 ms (0x01) + * 10 ms (0x02) + * Codec Specific Capabilities #2: len 0x02 type 0x03 + * Audio Channel Count: 0x03 + * 1 channel (0x01) + * 2 channels (0x02) + * Codec Specific Capabilities #3: len 0x05 type 0x04 + * Frame Length: 30 (0x001e) - 240 (0x00f0) + * ATT: Read Request (0x0a) len 2 + * Handle: 0x0006 Type: Sink Audio Location (0x2bca) + * ATT: Read Response (0x0b) len 4 + * Value: 03000000 + * Handle: 0x0006 Type: Sink Audio Locations (0x2bca) + * Location: 0x00000003 + * Front Left (0x00000001) + * Front Right (0x00000002) + */ +#define DISC_SINK_PAC \ + IOV_DATA(0x0a, 0x03, 0x00), \ + IOV_DATA(0x0b, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x01, \ + 0xff, 0x00, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x05, 0x04, \ + 0x1e, 0x00, 0xf0, 0x00, 0x00), \ + IOV_DATA(0x0a, 0x06, 0x00), \ + IOV_DATA(0x0b, 0x03, 0x00, 0x00, 0x00) + +/* ATT: Read Request (0x0a) len 2 + * Handle: 0x0009 Type: Source PAC (0x2bcb) + * ATT: Read Response (0x0b) len 24 + * Value: 010600000000100301ff0002020302030305041e00f00000 + * Handle: 0x0009 Type: Source PAC (0x2bcb) + * Number of PAC(s): 1 + * PAC #0: + * Codec: LC3 (0x06) + * Codec Specific Capabilities #0: len 0x03 type 0x01 + * Sampling Frequencies: 0x00ff + * 8 Khz (0x0001) + * 11.25 Khz (0x0002) + * 16 Khz (0x0004) + * 22.05 Khz (0x0008) + * 24 Khz (0x0010) + * 32 Khz (0x0020) + * 44.1 Khz (0x0040) + * 48 Khz (0x0080) + * Codec Specific Capabilities #1: len 0x02 type 0x02 + * Frame Duration: 0x0003 + * 7.5 ms (0x01) + * 10 ms (0x02) + * Codec Specific Capabilities #2: len 0x02 type 0x03 + * Audio Channel Count: 0x03 + * 1 channel (0x01) + * 2 channels (0x02) + * Codec Specific Capabilities #3: len 0x05 type 0x04 + * Frame Length: 30 (0x001e) - 240 (0x00f0) + * ATT: Read Request (0x0a) len 2 + * Handle: 0x000c Type: Source Audio Location (0x2bcc) + * ATT: Read Response (0x0b) len 4 + * Value: 03000000 + * Handle: 0x000c Type: Source Audio Locations (0x2bcc) + * Location: 0x00000003 + * Front Left (0x00000001) + * Front Right (0x00000002) + */ +#define DISC_SOURCE_PAC \ + DISC_SINK_PAC, \ + IOV_DATA(0x0a, 0x09, 0x00), \ + IOV_DATA(0x0b, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x01, \ + 0xff, 0x00, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x05, 0x04, \ + 0x1e, 0x00, 0xf0, 0x00, 0x00), \ + IOV_DATA(0x0a, 0x0c, 0x00), \ + IOV_DATA(0x0b, 0x03, 0x00, 0x00, 0x00) + +/* ATT: Read Request (0x0a) len 2 + * Handle: 0x000f Type: Available Audio Contexts (0x2bcd) + * ATT: Read Response (0x0b) len 4 + * Value: ff0f0e00 + * Handle: 0x000f Type: Available Audio Contexts (0x2bcd) + */ +#define DISC_CTX \ + DISC_SOURCE_PAC, \ + IOV_DATA(0x0a, 0x0f, 0x00), \ + IOV_DATA(0x0b, 0xff, 0x0f, 0x0e, 0x00) + +/* ATT: Read Request (0x0a) len 2 + * Handle: 0x0012 Type: Supported Audio Contexts (0x2bce) + * ATT: Read Response (0x0b) len 4 + * Value: ff0f0e00 + * Handle: 0x0012 Type: Supported Audio Contexts (0x2bce) + */ +#define DISC_SUP_CTX \ + DISC_CTX, \ + IOV_DATA(0x0a, 0x12, 0x00), \ + IOV_DATA(0x0b, 0xff, 0x0f, 0x0e, 0x00) + +/* ATT: Read Request (0x0a) len 2 + * Handle: 0x0016 Type: Sink ASE (0x2bc4) + * ATT: Read Response (0x0b) len 4 + * Value: 0100 + * Handle: 0x0016 Type: Sink ASE (0x2bc4) + * ATT: Write Request (0x12) len 4 + * Handle: 0x0017 Type: Client Characteristic Configuration (0x2902) + * Data: 0100 + * Notification (0x01) + * ATT: Write Response (0x13) len 0 + * ATT: Read Request (0x0a) len 2 + * Handle: 0x0019 Type: Sink ASE (0x2bc4) + * ATT: Read Response (0x0b) len 4 + * Value: 0200 + * Handle: 0x0019 Type: Sink ASE (0x2bc4) + * ATT: Write Request (0x12) len 4 + * Handle: 0x001a Type: Client Characteristic Configuration (0x2902) + * Data: 0100 + * Notification (0x01) + * ATT: Write Response (0x13) len 0 + */ +#define DISC_SINK_ASE \ + DISC_SUP_CTX, \ + IOV_DATA(0x0a, 0x16, 0x00), \ + IOV_DATA(0x0b, 0x01, 0x00), \ + IOV_DATA(0x12, 0x17, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x0a, 0x19, 0x00), \ + IOV_DATA(0x0b, 0x02, 0x00), \ + IOV_DATA(0x12, 0x1a, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13) + +/* ATT: Read Request (0x0a) len 2 + * Handle: 0x001c Type: Source ASE (0x2bc5) + * ATT: Read Response (0x0b) len 4 + * Value: 0300 + * Handle: 0x001c Type: Source ASE (0x2bc5) + * ATT: Write Request (0x12) len 4 + * Handle: 0x001d Type: Client Characteristic Configuration (0x2902) + * Data: 0100 + * Notification (0x01) + * ATT: Write Response (0x13) len 0 + * ATT: Read Request (0x0a) len 2 + * Handle: 0x001f Type: Source ASE (0x2bc5) + * ATT: Read Response (0x0b) len 4 + * Value: 0400 + * Handle: 0x001f Type: Source ASE (0x2bc5) + * ATT: Write Request (0x12) len 4 + * Handle: 0x0020 Type: Client Characteristic Configuration (0x2902) + * Data: 0100 + * Notification (0x01) + * ATT: Write Response (0x13) len 0 + * ATT: Write Request (0x12) len 4 + * Handle: 0x0023 Type: Client Characteristic Configuration (0x2902) + * Data: 0100 + * Notification (0x01) + * ATT: Write Response (0x13) len 0 + */ +#define DISC_SOURCE_ASE \ + DISC_SINK_ASE, \ + IOV_DATA(0x0a, 0x1c, 0x00), \ + IOV_DATA(0x0b, 0x03, 0x00), \ + IOV_DATA(0x12, 0x1d, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x0a, 0x1f, 0x00), \ + IOV_DATA(0x0b, 0x04, 0x00), \ + IOV_DATA(0x12, 0x20, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x12, 0x23, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13) + +static void test_disc(void) +{ + /* The IUT discovers the characteristics specified in the PAC + * Characteristic and Location Characteristic columns in Table 4.4. + * The IUT reads the values of the characteristics specified in the PAC + * Characteristic and Location Characteristic columns. + */ + define_test("BAP/UCL/DISC/BV-01-C", test_client, DISC_SINK_PAC); + define_test("BAP/UCL/DISC/BV-02-C", test_client, DISC_SOURCE_PAC); + + /* BAP/UCL/DISC/BV-06-C [Discover Available Audio Contexts] + * + * The IUT successfully reads the value of the Available Audio Contexts + * characteristic on the LowerTester. + */ + define_test("BAP/UCL/DISC/BV-06-C", test_client, DISC_CTX); + + /* BAP/UCL/DISC/BV-05-C [Discover Supported Audio Contexts] + * + * The IUT successfully reads the value of the Supported Audio Contexts + * characteristic on the Lower Tester. + */ + define_test("BAP/UCL/DISC/BV-05-C", test_client, DISC_SUP_CTX); + + /* BAP/UCL/DISC/BV-03-C [Discover Sink ASE_ID] + * BAP/UCL/DISC/BV-04-C [Discover Source ASE_ID] + * + * The IUT successfully reads the ASE_ID values of each discovered ASE + * characteristic on the LowerTester. + */ + define_test("BAP/UCL/DISC/BV-03-C", test_client, DISC_SINK_ASE); + define_test("BAP/UCL/DISC/BV-04-C", test_client, DISC_SOURCE_ASE); +} + +int main(int argc, char *argv[]) +{ + tester_init(&argc, &argv); + + test_disc(); + + return tester_run(); +}