From patchwork Mon Jun 12 13:32:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nitin Jadhav X-Patchwork-Id: 13276530 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 B5DA1C7EE25 for ; Mon, 12 Jun 2023 13:33:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234600AbjFLNdq (ORCPT ); Mon, 12 Jun 2023 09:33:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58732 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233368AbjFLNdp (ORCPT ); Mon, 12 Jun 2023 09:33:45 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on2049.outbound.protection.outlook.com [40.107.7.49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3BB55F1 for ; Mon, 12 Jun 2023 06:33:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gUBc+01Uxdpuzninj+kBCRcLFmHPHRkxB4EBY8J/5fyEzuchCnh4oLMxzseVX0Cwi8vRGmqQBfz+tQ7e7Xjs9rv29ffox5MMc2glyQ6JGmlkdQpw3UfQ/gTJYtyz5nJ07e/cauqGRRlh8hdlK4kOIs7jbY5ESo/cQ2fUCa/SdKsSF2O7xixCbYfgrnqGWi2hgmGOUuvEXwsZLTWTDw4Vd+JUMYK9KhCxd4fxUMCpO1qfz8HD9GfEh2W0+qQ+Y+kTDmJ5wc8gHANVghPZJV7xHPKhhJiUnVDp1omCh5Y5NfJBI/wl4LG1Zge/nHrFUyXy+JV2P4PGVjjN7GB0VlrYMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=fO3jTnAmM88LAZH+zjV7RwZRJJsbDjwWt2P9vEDH9CM=; b=GC415UFvCeohDCUVBuP69zcXnfX3ZSaGtaZdn7yOnbxMDZ1Ncj6GIyF0XF3VEZkKgsYUzaUE+mk2Z3nKaHcCn6IpsadV19aiUYf2bKF9nLOEtiL/O2TniBcAX0/5qYLKMgNfaXv0nqvD0r2Tt5pIkxVah3sKpQS7YYAWPKVl/TGhxQgTJbtHat9o1wlm6ns2bCa6TrsLaI4rQV/mv8XL7JxCSskVfbQeFdBk14rqV2X+MQBLq5Kcs1U0UCTvMp4VweNP8omxHLCQIbrZAr7B6nzts0Myl+8tUdazi+u3kfTdxnqcmN0epvUPBsTk4fYogJkmzOigPbI4fGpl9qKWlQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fO3jTnAmM88LAZH+zjV7RwZRJJsbDjwWt2P9vEDH9CM=; b=g+ee3IjtCPlkZWQMftUuaI9cj2iYcpgjgCNO8BBF7UYdSXpjEDaohHnKMtZ/epbAfl4bPAOLoCCnOknycQ4BjHGAZjEzq4TQZLhLE+QwqAHGLbAzHzzKFLIEtaluk6x8sBdJemX/lruZOA8NKRNnm386MdDNx3pfFRmRq1fVWqE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AS8PR04MB9126.eurprd04.prod.outlook.com (2603:10a6:20b:449::16) by AM9PR04MB9002.eurprd04.prod.outlook.com (2603:10a6:20b:409::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6477.29; Mon, 12 Jun 2023 13:33:42 +0000 Received: from AS8PR04MB9126.eurprd04.prod.outlook.com ([fe80::ad2c:857b:a144:9af4]) by AS8PR04MB9126.eurprd04.prod.outlook.com ([fe80::ad2c:857b:a144:9af4%3]) with mapi id 15.20.6455.030; Mon, 12 Jun 2023 13:33:42 +0000 From: Nitin Jadhav To: linux-bluetooth@vger.kernel.org Cc: devyani.godbole@nxp.com, mihai-octavian.urzica@nxp.com, silviu.barbulescu@nxp.com, nitin.jadhav@nxp.com Subject: [PATCH BlueZ v5 1/3] lib/uuid.h: Add VOCS characteristic uuid(s) Date: Mon, 12 Jun 2023 19:02:49 +0530 Message-Id: <20230612133251.194-2-nitin.jadhav@nxp.com> X-Mailer: git-send-email 2.33.1.windows.1 In-Reply-To: <20230612133251.194-1-nitin.jadhav@nxp.com> References: <20230612133251.194-1-nitin.jadhav@nxp.com> X-ClientProxiedBy: SI2PR01CA0023.apcprd01.prod.exchangelabs.com (2603:1096:4:192::17) To AS8PR04MB9126.eurprd04.prod.outlook.com (2603:10a6:20b:449::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8PR04MB9126:EE_|AM9PR04MB9002:EE_ X-MS-Office365-Filtering-Correlation-Id: 63c8bcda-69c9-4855-8058-08db6b49a31d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Ydr4WUa3lkvgFrEfh2k1IH5OvFgJN1NpJlhhF8QgTBdUf0WSukhK/9NUOMPtG9cMeunPORobqTorEmmfuAndk6U+JvDa7TcHoESDBRnZSI725vHFhBGrQDxqib/PCNU14S71zuFG66bCTv4N2vhEz46C91H2MbDHQlzUg8ehJvSBeqGWjS7Pxp3QWk6JAxW4Z6ge6T/dzeH8vdCyeqfOVOuQ2bkLQ3kMNjhxlvgcU6B7l3MXsK4n2kEFWShVcmTXEjyuStEaOVYFEYBGPgb10gO64tXy3mx2jmh98aF8yPxpNhNjENnXTTVsHIArBb1Sa3X5Rb0QEyCexG/596t4tgWJNzRQ4zv7Gidh3k0HbpAAOMNZXjEn36vMfVXLTqf+k4U2ggO6Le5OiIOA5sPZ5v6+3ecpa3a2t4G7f9jVnDmaRU5wOoCDw72IcYnyX0DA+iT/lJ0M85fgCw3oIzMKrijw4vhI6r+Ta0FsSUfbGdSuZV0w3p7qjmU46tIM+A1SpHasIHrCXCodEDU++8NlGb5Z9GSpH69zCtnAdvBDRPTHKtoUGkcZV+XyQ+NijYR80BA2bKdx5xXJIDDrRRH8cO/GvHUfXnA8QC8axrXApqp14daRY5JuGvquLhuomc+i X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AS8PR04MB9126.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(4636009)(396003)(136003)(346002)(376002)(366004)(39860400002)(451199021)(52116002)(6486002)(36756003)(2616005)(38350700002)(38100700002)(86362001)(6506007)(6512007)(1076003)(26005)(186003)(4744005)(2906002)(5660300002)(44832011)(8936002)(8676002)(316002)(41300700001)(6916009)(4326008)(66946007)(66556008)(66476007)(478600001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: nfkCL6c80+6Us+3JY6GtabrEnSFZTKHLcN+KNCBDVA1o1uHlynEaAoMNTHE3/hMLlTEZvuspGKRA5YS63CXfEmN8L51nBcQm0bAj7gVArfl89GDOix1VqATa5EOgwazLdwtRWlr2qOKxYELbY/bwoNOnB0XaOaCZu9EGs1qwbfbI42WC7HH7A0VHX/Bvl7f7FZECitkjLRNTbx71IPmYiMGvfDBVr1Dx0AfqgZR0xT0jrnL1S918O10wOzGrePvp1FqfI2bcDocoN3zkrGW7CidkbkDQtgi5Us7Y+7dJXvdsKhFAjlX64NYMPfmboU9RqoXzzfGMF9Eqs/FEhOke22kVkKRQKHNI9olWUQnV6QaN/8azC+Y8IL8uv7lrnDnApX6BTHmh7y0zdhVqN4I3WMWBt+bDfZHsHENnBzcbMXa3a2xjcGRcQDYiG5wUCBCd3IGDcLovvoG0Ztt9iJVv4LVjv0vn6TfXkZLmbO5DmAbf/AohlQNBfXdsI8DyVFOLt6OsG/rHGjCG4bSfxtbaqWwkKdtxk+ZIQhbYyETYXPJ8bu1gRDzqPRlEIHQnT9N9lRx5+PtEKwLolAS996QmvKiv335xEAesXQnMnPqLk+OIlxsEI1WBhqVgX4mAKdiQSMoXkTVUHUxQcokDuXgCLi1oGrjxIFNgV2bSFI77dPmO351Yh0rRv1jfxUxOKnWzvSgyQygj3q7vxlqflBQszXqSxxg1Ah7hnvOBljjr+RHk6RrNhXa9AYNsVGeIepo77ONz1P/wQCRZyEfe9gYLe2Qooy4vy2wtSpDfAGZgBFZdbKZf/ds9AzB5vOfF0O93Gj4E8viLh4wrGxhIx01oIC5f0S5sry0gyjL00NxIfrKPWyB8MnfrPBzmOibIjikWAuvcHLiK2ofVNdmmdgf7rj5yPV9EWYifJa0P3CZQ13YKsRB8QHlaNnkEbwR8EvIlgY+dTn1x2QCIpSFr9dD9VoEx+oGnD79jvU3xbYE74ExGYWzUZXR9DkCj1QkZJz8T7K+1izqTc/FRn2FYpu0+cYsfJLJAcGbJ+v3sEwtGZhoFbnvpO2Bq8gKiC671MiTvRA8zlmcJucR36s1Kwn1j5tqwcMSMDfuuBOdaw8AK+pRe/o8h+pePciR2zXA1Xynmt4JHvtQLQOFhma3GF1Ye1TekHaDO7oZ2mD2JbetzHoPwvw5DDGTo8iIM0qTd4occY/+qWAILUZ5d3Ob0VWk9wjl8/8zQqMFnxkiu7yksP2o1FQiLXdciYO6H/2uNfb/nALugCp5T9tZOIAf7kDHQX9c/WLDZJpZgjEmccVbXom3fx6mkfAF8X7wq5bkWW90fy7Ja5Qs4GJIGiN3P73qmgJ+ii74CifNJoRgwujoiaPO2q3ObCO5uk91xldpSmhj79TVs9WXjGHUY2xteoyKvQgSM045VMUDrieGedQuhk2HvENTioMwVG289Ry3ismcLWLU9fRdSjskgmikNnkZsiaJWRfRu+42m37iIqStVrfKjF6TIZlmcvnJ7SuiTi8aeY5Co1vFIWuzZew3X3o2vip/v86HwtxCqU2YCe+07YkGN1fAulbDDKmClt5m41IaF X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 63c8bcda-69c9-4855-8058-08db6b49a31d X-MS-Exchange-CrossTenant-AuthSource: AS8PR04MB9126.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2023 13:33:41.9858 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: TZyg25qLDj0zV5jWULPfANBAZ/VHrlAvsvGKkLQIYwO7p2s6+AgMj3l3iIqUJVd6o1QfuReSLGU3Hma6rF8voA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM9PR04MB9002 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org --- lib/uuid.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/uuid.h b/lib/uuid.h index 5cdfedb4b..cd3b3655f 100644 --- a/lib/uuid.h +++ b/lib/uuid.h @@ -179,6 +179,11 @@ extern "C" { #define VOL_CP_CHRC_UUID 0x2B7E #define VOL_FLAG_CHRC_UUID 0x2B7F +#define VOCS_STATE_CHAR_UUID 0x2B80 +#define VOCS_AUDIO_LOC_CHRC_UUID 0x2B81 +#define VOCS_CP_CHRC_UUID 0x2B82 +#define VOCS_AUDIO_OP_DESC_CHAR_UUID 0x2B83 + #define GMCS_UUID 0x1849 #define MEDIA_PLAYER_NAME_CHRC_UUID 0x2b93 #define MEDIA_TRACK_CHNGD_CHRC_UUID 0x2b96 From patchwork Mon Jun 12 13:32:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nitin Jadhav X-Patchwork-Id: 13276531 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 9A526C7EE25 for ; Mon, 12 Jun 2023 13:33:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235916AbjFLNdw (ORCPT ); Mon, 12 Jun 2023 09:33:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233368AbjFLNdv (ORCPT ); Mon, 12 Jun 2023 09:33:51 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on2071.outbound.protection.outlook.com [40.107.7.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD704E9 for ; Mon, 12 Jun 2023 06:33:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LiSffE6gleAV995Q7VC+kCrNmBb6c/T7ZwyENwxM/57NHOn9yym5bn+EWeG3DdcUmwfJ9AinNkrbWnNTDcLLko80p+s/Kf432rpL8T9sjHCTS3f83ntLYdpp77JW58nV4WuGPxM6feB2EJjfAo++H3vsIOZEwGgKZxvqfj4MHJPVx9xSHQQtVkwwE8nRnoZFIHlNvSJNkakJw1/Kb+Pc0jgvgVHj6ksRTDISUFGQkvUhYC7uk7er53cX57a/XVtoGslQPpv9GGXtyBnLPKwLSoZVUkgvg0KS1rivO/GpixAjQXHA7bTdMbyk9f6bp5hBUpxkS2vaEDy02GQr0nWfEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=lS2yyTLi1/F1hBcA9t8xKpPDVB2p85oYdfrFpEXyPek=; b=Wk19QZjMS0UghN59LOqa38MizLb3dHj0JMheUJ20gYMS4UsQkXZ+dbyv14waU+2A49wRGxnR2TRoFfye3F1wipjgzlMmtKhb/ZdtkjRdICYlYZ7exjtx9ctByGXn3JKZNmgSlWfojlzXMIwjsNXppi96qXW8U7hkXaYOC4dlFPNE8miRpxPf04yrDARej+TtqawgoqbT/t8AtbznBOqnyqwa/yfA9F2B9ci9FQMJzfTxK/KO3YcnsjCKo9ivK3V/ve5yBKbQDR8PtwyzoZfsRBeEpAeSrojdhlJn2+HHtBS4sVmEmyMhH4+IyA0wMVIsKERWSCJ645LUFROVdlVOmQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=lS2yyTLi1/F1hBcA9t8xKpPDVB2p85oYdfrFpEXyPek=; b=Vue8NXX0t1S+gWwb+VLUaeUhAyHJAZv4wqoYVZqLTb1zm6nWnvUpeQT7kIO2W4VwNMlCqzx6i1CV/gxCvW4+xQ9ycH8wSj+Q/HeqANl5+EcM0l7Kq5vjbD/WxhfV0XzWfnScqfJg0qMGI8ywPW4N8XB3P2HFeYc53Qxczm6ObVU= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AS8PR04MB9126.eurprd04.prod.outlook.com (2603:10a6:20b:449::16) by AM9PR04MB9002.eurprd04.prod.outlook.com (2603:10a6:20b:409::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6477.29; Mon, 12 Jun 2023 13:33:46 +0000 Received: from AS8PR04MB9126.eurprd04.prod.outlook.com ([fe80::ad2c:857b:a144:9af4]) by AS8PR04MB9126.eurprd04.prod.outlook.com ([fe80::ad2c:857b:a144:9af4%3]) with mapi id 15.20.6455.030; Mon, 12 Jun 2023 13:33:46 +0000 From: Nitin Jadhav To: linux-bluetooth@vger.kernel.org Cc: devyani.godbole@nxp.com, mihai-octavian.urzica@nxp.com, silviu.barbulescu@nxp.com, nitin.jadhav@nxp.com Subject: [PATCH BlueZ v5 2/3] shared/vcp: Add initial code for handling VOCS Date: Mon, 12 Jun 2023 19:02:50 +0530 Message-Id: <20230612133251.194-3-nitin.jadhav@nxp.com> X-Mailer: git-send-email 2.33.1.windows.1 In-Reply-To: <20230612133251.194-1-nitin.jadhav@nxp.com> References: <20230612133251.194-1-nitin.jadhav@nxp.com> X-ClientProxiedBy: SI2PR01CA0023.apcprd01.prod.exchangelabs.com (2603:1096:4:192::17) To AS8PR04MB9126.eurprd04.prod.outlook.com (2603:10a6:20b:449::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8PR04MB9126:EE_|AM9PR04MB9002:EE_ X-MS-Office365-Filtering-Correlation-Id: 997ad669-5e83-43de-42e1-08db6b49a5a8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: T7X78DgKiTZ5ETWgxqTLZwGftSesoAArp+PZnP3mfAKRju1a6Gr/tRbx6LTBaJXuvSm5cwAZ7LdO7bTWZ0oYLUQ52HTXm1XY3MOGQWz+I8/tYyF3JoSfXLKrckny1Gw4Jbmis7p0FslZK0xK0tJ9K6k4syEOd8cFOwQVzlrpFnMxEAnPPK0xlH2ui72H714QN+N8oCggLeyv9Y351Izs0ZEGqkaLtFS1T9bg6bvh7+mASgbQ00fAOPpYtGAgL4lZDzmv4SRoU8LoZ1wUKTwmiqEk94//NZ38k5c5gtMspOr9+D4/v4VxrHUqZyufIgm8XPxiBV1J9Dc+24Y62Mtzk2eXsMRl4bcRoAESzBpDQyth6axcx8s+QDGidKlpLU88j1er7Oq0n8iRL+44XIPMfpCr+6taaR3fV9Rt5ehDLPH9qOYDg8XeomMWycZHZ75X6EoFvb64lZ5JY13H6zfzOIJz/44pPpk439SMWvibwZnhSihNMs/IaE9AQLywNgnUStU1vDgR4uBo5Dm/EBVqUeFDS6ohCS96HPzcRtD7YibOQIhjr6hQ0I3uIVu1lssu0XqrfH6TP6RUT/9VlV/hOVBx2KMxRT9JRRYsD0MS8TFVmHCQvgzQ+pXDlt0vy9TS X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AS8PR04MB9126.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(4636009)(396003)(136003)(346002)(376002)(366004)(39860400002)(451199021)(52116002)(6486002)(6666004)(36756003)(83380400001)(2616005)(38350700002)(38100700002)(86362001)(6506007)(6512007)(1076003)(26005)(186003)(30864003)(2906002)(5660300002)(44832011)(8936002)(8676002)(316002)(41300700001)(6916009)(4326008)(66946007)(66556008)(66476007)(478600001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Bor/DFbZfTiQClL81KvLRibDeWty3OQMdd5i9j1u6um1wLYYLtN3bWt7fyKXbEflmVtOHUNhAeEkbu6JLySs4wzum4nSlYspyKePgo5fikrUg2RB8SBW6qXPdydUwb69P7hnsPeVDvQ9t9BuY2tOdMWRmYfCc9VUmzVuXlkbIaiuYyNIGP2xyawzOob57/ppXXs6+WoukUYnRhYEP6xsof6P9Tc3/rsr7bzEnQvyjyYPeLsUHt8SbRlckaEpTOsCoP+IsSbAvPSDM6iPCKO5yW6fH7k27/t7D63bDrXiybRdkkUGpean96O3UkoiA5BEJaL2AcfTohfUH1M3iARulJ3DouXKcQOxlwLDtWsnL40dcSYbLJmCSAG8B6mXGjS0Jk2UX63mh5Du3pd+e75UPT6m0qbvYC9LV/nQTRAD6KRQwO4COvvxWF3xEf9HzHe/f3FSpFL1PnLLrn/5iFx/LH3O2bbUAkKKvUiIubbxajifaoUkQLFYJpQRepWbtpH0ZzmQkSxPILacRIfmlkdZBHFBsfjiuTFrxMK1LpK6eq8fVGg9gJJND/7K7k+vYt5yI08R7/Wsulp0rX+4p0kYqUx8E0oVyDyBV51z+TbOFgVkHLZov3yURgTnDO1wDD35M96Nr91tLopk2yttKNs6aGpCB7wvPm4K/5d2mKlCXUgY4EzIXdFCcJB/mCI4P1Uzu2drOEJ1hF/+3RGKjN3tDhvcapNM4c3l04AT3ssei4B78NW8F7+hZm4wbSRPN0B39grCjFIDfh88S5KVAuvwdP81LQblT/5LRUEUDasVUBXHJGrtzE0FM2iGcRlfaOc3MEWlFyGO73biaV/CcTX6yV6I33ZVN5LXJT/c2xagVJmf5rK39nA3KTIitIh4Kdfpc7nnxVlE6Qc9xVkgFawjOwTGGb/gmnDA3UqIUI5y67XkSG2LYrcP1ex0ahUAtZ5D4XTR6HYD2ui2JbNcLCUnWwYherAPuRi6BBuP1VJKM5zZbRQUbK0qGzlnV5gdUpqvwgQ4IBaioC8a5SfbLwgSjhG++z1csKlV7SbL9+V7IHtQLP/df9CHFi/P6FChlWYAvjfuHUc2HiRHBOIemHUJuve+JBwt+qJuEliTnYvzvjDUrpJaM2fEf/9uY+e7qt++ldumTr0xrjit+zDwWq7u8Izwz36i+9Bq05Dsf/4o9glSs0L/9R0UPl4j6yOc3JerXH5VgEOSjv+4ldFgOJSyMFSeF7UwSvt8Y8VO71Tn3oRD8dJqqgvCPjLDAfF/yFxoeBvhFjRiqntfo8dS7jaNfj1duPyL7HSxB2bKiKJl0LHHTCu9CcHljaxOJoTEtdsquTZ+sa47A7iXHFSUVoVF6GF2AfC66GupG4garNJJPFeA+xP5AHQs5OgZuVBaH256lR5JqBxv7GPGFRoQwnmfttJIItYSzweVgBulyOHk5C+TN3h/MiKUE0NLpg8J+YiWVfJUT7IKYzZXIz7O9+cQzKUFeMFqZPW7kKFtYTHZXXqEx07k9sUs9Jj/3Sc7l05QLrNj43sVlDC3HFordeg452t35q9RsLeD3JrqYzVJl8dDDnzJJ+i8fQE5aGwjIPku X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 997ad669-5e83-43de-42e1-08db6b49a5a8 X-MS-Exchange-CrossTenant-AuthSource: AS8PR04MB9126.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2023 13:33:46.1689 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0Z/qnFI+iHpE8QgLI66ae5SS8IBC3omV3nlK3UQPcQ7xogrDgvdbLgCh5wrGkpkIzQQnG7i+U4aftOSD5CetVQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM9PR04MB9002 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Summary: - This adds implementation for VOCS service and characteristics - Implementation based on VOCS_v1.0.pdf specification - Tested using PTS with reference to VOCS.TS.p1.pdf --- v2: Corrected prefixs and cosmetic changes (Luiz Augusto von Dentz) v3: Commit message modified and fixed long line length warning (Paul Menzel) v4: Used BIT macro to set bit of audio location macros (Luiz Augusto von Dentz) v5: Resolved Scan Build warning (tedd_an/ScanBuild) --- src/shared/vcp.c | 550 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 550 insertions(+) diff --git a/src/shared/vcp.c b/src/shared/vcp.c index 5459cf892..92f21fd0b 100644 --- a/src/shared/vcp.c +++ b/src/shared/vcp.c @@ -36,9 +36,40 @@ #define BT_ATT_ERROR_INVALID_CHANGE_COUNTER 0x80 #define BT_ATT_ERROR_OPCODE_NOT_SUPPORTED 0x81 +#define BT_VCP_NA BIT(0) +#define BT_VCP_FRONT_LEFT BIT(1) +#define BT_VCP_FRONT_RIGHT BIT(2) +#define BT_VCP_FRONT_CENTER BIT(3) +#define BT_VCP_LOW_FRQ_EFF_1 BIT(4) +#define BT_VCP_BACK_LEFT BIT(5) +#define BT_VCP_BACK_RIGHT BIT(6) +#define BT_VCP_FRONT_LEFT_CENTER BIT(7) +#define BT_VCP_FRONT_RIGHT_CENTER BIT(8) +#define BT_VCP_BACK_CENTER BIT(9) +#define BT_VCP_LOW_FRQ_EFF_2 BIT(10) +#define BT_VCP_SIDE_LEFT BIT(11) +#define BT_VCP_SIDE_RIGHT BIT(12) +#define BT_VCP_TOP_FRONT_LEFT BIT(13) +#define BT_VCP_TOP_FRONT_RIGHT BIT(14) +#define BT_VCP_TOP_FRONT_CENTER BIT(15) +#define BT_VCP_TOP_CENTER BIT(16) +#define BT_VCP_TOP_BACK_LEFT BIT(17) +#define BT_VCP_TOP_BACK_RIGHT BIT(18) +#define BT_VCP_TOP_SIDE_LEFT BIT(19) +#define BT_VCP_TOP_SIDE_RIGHT BIT(20) +#define BT_VCP_TOP_BACK_CENTER BIT(21) +#define BT_VCP_BOTTOM_FRONT_CENTER BIT(22) +#define BT_VCP_BOTTOM_FRONT_LEFT BIT(23) +#define BT_VCP_BOTTOM_FRONT_RIGHT BIT(24) +#define BT_VCP_FRONT_LEFT_WIDE BIT(25) +#define BT_VCP_FRONT_RIGHT_WIDE BIT(26) +#define BT_VCP_LEFT_SURROUND BIT(27) +#define BT_VCP_RIGHT_SURROUND BIT(28) + struct bt_vcp_db { struct gatt_db *db; struct bt_vcs *vcs; + struct bt_vocs *vocs; }; typedef void (*vcp_func_t)(struct bt_vcp *vcp, bool success, uint8_t att_ecode, @@ -57,11 +88,21 @@ struct bt_vcs_param { uint8_t change_counter; } __packed; +struct bt_vocs_param { + uint8_t op; + uint8_t change_counter; +} __packed; + struct bt_vcs_ab_vol { uint8_t change_counter; uint8_t vol_set; } __packed; +struct bt_vocs_set_vol_off { + uint8_t change_counter; + uint8_t set_vol_offset; +} __packed; + struct bt_vcp_cb { unsigned int id; bt_vcp_func_t attached; @@ -89,6 +130,10 @@ struct bt_vcp { unsigned int vstate_id; unsigned int vflag_id; + unsigned int state_id; + unsigned int audio_loc_id; + unsigned int ao_dec_id; + struct queue *notify; struct queue *pending; @@ -120,6 +165,27 @@ struct bt_vcs { struct gatt_db_attribute *vf_ccc; }; +/* Contains local bt_vcp_db */ +struct vol_offset_state { + uint16_t vol_offset; + uint8_t counter; +} __packed; + +struct bt_vocs { + struct bt_vcp_db *vdb; + struct vol_offset_state *vostate; + uint32_t vocs_audio_loc; + char *vocs_ao_dec; + struct gatt_db_attribute *service; + struct gatt_db_attribute *vos; + struct gatt_db_attribute *vos_ccc; + struct gatt_db_attribute *voal; + struct gatt_db_attribute *voal_ccc; + struct gatt_db_attribute *vo_cp; + struct gatt_db_attribute *voaodec; + struct gatt_db_attribute *voaodec_ccc; +}; + static struct queue *vcp_db; static struct queue *vcp_cbs; static struct queue *sessions; @@ -159,6 +225,17 @@ static struct vol_state *vdb_get_vstate(struct bt_vcp_db *vdb) return NULL; } +static struct vol_offset_state *vdb_get_vostate(struct bt_vcp_db *vdb) +{ + if (!vdb->vocs) + return NULL; + + if (vdb->vocs->vostate) + return vdb->vocs->vostate; + + return NULL; +} + static struct bt_vcs *vcp_get_vcs(struct bt_vcp *vcp) { if (!vcp) @@ -173,6 +250,20 @@ static struct bt_vcs *vcp_get_vcs(struct bt_vcp *vcp) return vcp->rdb->vcs; } +static struct bt_vocs *vcp_get_vocs(struct bt_vcp *vcp) +{ + if (!vcp) + return NULL; + + if (vcp->rdb->vocs) + return vcp->rdb->vocs; + + vcp->rdb->vocs = new0(struct bt_vocs, 1); + vcp->rdb->vocs->vdb = vcp->rdb; + + return vcp->rdb->vocs; +} + static void vcp_detached(void *data, void *user_data) { struct bt_vcp_cb *cb = data; @@ -202,6 +293,7 @@ static void vcp_db_free(void *data) gatt_db_unref(vdb->db); free(vdb->vcs); + free(vdb->vocs); free(vdb); } @@ -583,6 +675,45 @@ static uint8_t vcs_mute(struct bt_vcs *vcs, struct bt_vcp *vcp, return 0; } +static uint8_t vocs_set_vol_offset(struct bt_vocs *vocs, struct bt_vcp *vcp, + struct iovec *iov) +{ + struct bt_vcp_db *vdb; + struct vol_offset_state *vstate; + struct bt_vocs_set_vol_off *req; + + DBG(vcp, "Set Volume Offset"); + + vdb = vcp_get_vdb(vcp); + if (!vdb) { + DBG(vcp, "error: VDB not available"); + return 0; + } + + vstate = vdb_get_vostate(vdb); + if (!vstate) { + DBG(vcp, "error: VSTATE not available"); + return 0; + } + + req = iov_pull_mem(iov, sizeof(*req)); + if (!req) + return 0; + + if (req->change_counter != vstate->counter) { + DBG(vcp, "Change Counter Mismatch Volume not decremented!"); + return BT_ATT_ERROR_INVALID_CHANGE_COUNTER; + } + + vstate->vol_offset = req->set_vol_offset; + vstate->counter = -~vstate->counter; /*Increment Change Counter*/ + + gatt_db_attribute_notify(vdb->vocs->vos, (void *)vstate, + sizeof(struct vol_offset_state), + bt_vcp_get_att(vcp)); + return 0; +} + #define BT_VCS_REL_VOL_DOWN 0x00 #define BT_VCS_REL_VOL_UP 0x01 #define BT_VCS_UNMUTE_REL_VOL_DOWN 0x02 @@ -591,6 +722,8 @@ static uint8_t vcs_mute(struct bt_vcs *vcs, struct bt_vcp *vcp, #define BT_VCS_UNMUTE 0x05 #define BT_VCS_MUTE 0x06 +#define BT_VOCS_SET_VOL_OFFSET 0x01 + #define VCS_OP(_str, _op, _size, _func) \ { \ .str = _str, \ @@ -623,6 +756,26 @@ struct vcs_op_handler { {} }; +#define VOCS_OP(_str, _op, _size, _func) \ + { \ + .str = _str, \ + .op = _op, \ + .size = _size, \ + .func = _func, \ + } + +struct vocs_op_handler { + const char *str; + uint8_t op; + size_t size; + uint8_t (*func)(struct bt_vocs *vocs, struct bt_vcp *vcp, + struct iovec *iov); +} vocp_handlers[] = { + VOCS_OP("Set Volume Offset", BT_VOCS_SET_VOL_OFFSET, + sizeof(uint8_t), vocs_set_vol_offset), + {} +}; + static void vcs_cp_write(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, const uint8_t *value, size_t len, @@ -683,6 +836,66 @@ respond: gatt_db_attribute_write_result(attrib, id, ret); } +static void vocs_cp_write(struct gatt_db_attribute *attrib, + unsigned int id, uint16_t offset, + const uint8_t *value, size_t len, + uint8_t opcode, struct bt_att *att, + void *user_data) +{ + struct bt_vocs *vocs = user_data; + struct bt_vcp *vcp = vcp_get_session(att, vocs->vdb->db); + struct iovec iov = { + .iov_base = (void *) value, + .iov_len = len, + }; + uint8_t *vcp_op; + struct vocs_op_handler *handler; + uint8_t ret = BT_ATT_ERROR_REQUEST_NOT_SUPPORTED; + + DBG(vcp, "VOCP Control Point Write"); + + if (offset) { + DBG(vcp, "invalid offset %d", offset); + ret = BT_ATT_ERROR_INVALID_OFFSET; + goto respond; + } + + if (len < sizeof(*vcp_op)) { + DBG(vcp, "invalid len %ld < %ld sizeof(*param)", len, + sizeof(*vcp_op)); + ret = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN; + goto respond; + } + + vcp_op = iov_pull_mem(&iov, sizeof(*vcp_op)); + + for (handler = vocp_handlers; handler && handler->str; handler++) { + if (handler->op != *vcp_op) + continue; + + if (iov.iov_len < handler->size) { + DBG(vcp, "invalid len %ld < %ld handler->size", len, + handler->size); + ret = BT_ATT_ERROR_OPCODE_NOT_SUPPORTED; + goto respond; + } + + break; + } + + if (handler && handler->str) { + DBG(vcp, "%s", handler->str); + + ret = handler->func(vocs, vcp, &iov); + } else { + DBG(vcp, "Unknown opcode 0x%02x", *vcp_op); + ret = BT_ATT_ERROR_OPCODE_NOT_SUPPORTED; + } + +respond: + gatt_db_attribute_write_result(attrib, id, ret); +} + static void vcs_state_read(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, uint8_t opcode, struct bt_att *att, @@ -698,6 +911,21 @@ static void vcs_state_read(struct gatt_db_attribute *attrib, iov.iov_len); } +static void vocs_state_read(struct gatt_db_attribute *attrib, + unsigned int id, uint16_t offset, + uint8_t opcode, struct bt_att *att, + void *user_data) +{ + struct bt_vocs *vocs = user_data; + struct iovec iov; + + iov.iov_base = vocs->vostate; + iov.iov_len = sizeof(*vocs->vostate); + + gatt_db_attribute_read_result(attrib, id, 0, iov.iov_base, + iov.iov_len); +} + static void vcs_flag_read(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, uint8_t opcode, struct bt_att *att, @@ -713,6 +941,36 @@ static void vcs_flag_read(struct gatt_db_attribute *attrib, iov.iov_len); } +static void vocs_voal_read(struct gatt_db_attribute *attrib, + unsigned int id, uint16_t offset, + uint8_t opcode, struct bt_att *att, + void *user_data) +{ + struct bt_vocs *vocs = user_data; + struct iovec iov; + + iov.iov_base = &vocs->vocs_audio_loc; + iov.iov_len = sizeof(vocs->vocs_audio_loc); + + gatt_db_attribute_read_result(attrib, id, 0, iov.iov_base, + iov.iov_len); +} + +static void vocs_voaodec_read(struct gatt_db_attribute *attrib, + unsigned int id, uint16_t offset, + uint8_t opcode, struct bt_att *att, + void *user_data) +{ + struct bt_vocs *vocs = user_data; + struct iovec iov; + + iov.iov_base = &vocs->vocs_ao_dec; + iov.iov_len = strlen(vocs->vocs_ao_dec); + + gatt_db_attribute_read_result(attrib, id, 0, iov.iov_base, + iov.iov_len); +} + static struct bt_vcs *vcs_new(struct gatt_db *db) { struct bt_vcs *vcs; @@ -771,6 +1029,74 @@ static struct bt_vcs *vcs_new(struct gatt_db *db) return vcs; } +static struct bt_vocs *vocs_new(struct gatt_db *db) +{ + struct bt_vocs *vocs; + struct vol_offset_state *vostate; + bt_uuid_t uuid; + + if (!db) + return NULL; + + vocs = new0(struct bt_vocs, 1); + + vostate = new0(struct vol_offset_state, 1); + + vocs->vostate = vostate; + vocs->vocs_audio_loc = BT_VCP_FRONT_LEFT; + vocs->vocs_ao_dec = "Left Speaker"; + + /* Populate DB with VOCS attributes */ + bt_uuid16_create(&uuid, VOL_OFFSET_CS_UUID); + vocs->service = gatt_db_add_service(db, &uuid, true, 9); + + bt_uuid16_create(&uuid, VOCS_STATE_CHAR_UUID); + vocs->vos = gatt_db_service_add_characteristic(vocs->service, + &uuid, + BT_ATT_PERM_READ, + BT_GATT_CHRC_PROP_READ | + BT_GATT_CHRC_PROP_NOTIFY, + vocs_state_read, NULL, + vocs); + + vocs->vos_ccc = gatt_db_service_add_ccc(vocs->service, + BT_ATT_PERM_READ | BT_ATT_PERM_WRITE); + + bt_uuid16_create(&uuid, VOCS_AUDIO_LOC_CHRC_UUID); + vocs->voal = gatt_db_service_add_characteristic(vocs->service, + &uuid, + BT_ATT_PERM_READ, + BT_GATT_CHRC_PROP_READ | + BT_GATT_CHRC_PROP_NOTIFY, + vocs_voal_read, NULL, + vocs); + + vocs->voal_ccc = gatt_db_service_add_ccc(vocs->service, + BT_ATT_PERM_READ | BT_ATT_PERM_WRITE); + + bt_uuid16_create(&uuid, VOCS_CP_CHRC_UUID); + vocs->vo_cp = gatt_db_service_add_characteristic(vocs->service, + &uuid, + BT_ATT_PERM_WRITE, + BT_GATT_CHRC_PROP_WRITE, + NULL, vocs_cp_write, + vocs); + + bt_uuid16_create(&uuid, VOCS_AUDIO_OP_DESC_CHAR_UUID); + vocs->voaodec = gatt_db_service_add_characteristic(vocs->service, + &uuid, + BT_ATT_PERM_READ, + BT_GATT_CHRC_PROP_READ | + BT_GATT_CHRC_PROP_NOTIFY, + vocs_voaodec_read, NULL, + vocs); + + vocs->voaodec_ccc = gatt_db_service_add_ccc(vocs->service, + BT_ATT_PERM_READ | BT_ATT_PERM_WRITE); + + return vocs; +} + static struct bt_vcp_db *vcp_db_new(struct gatt_db *db) { struct bt_vcp_db *vdb; @@ -787,6 +1113,9 @@ static struct bt_vcp_db *vcp_db_new(struct gatt_db *db) vdb->vcs = vcs_new(db); vdb->vcs->vdb = vdb; + vdb->vocs = vocs_new(db); + vdb->vocs->vdb = vdb; + queue_push_tail(vcp_db, vdb); return vdb; @@ -911,6 +1240,47 @@ static void vcp_vstate_notify(struct bt_vcp *vcp, uint16_t value_handle, DBG(vcp, "Vol Counter 0x%x", vstate.counter); } +static void vcp_voffset_state_notify(struct bt_vcp *vcp, uint16_t value_handle, + const uint8_t *value, uint16_t length, + void *user_data) +{ + struct vol_offset_state vostate; + + memcpy(&vostate, value, sizeof(struct vol_offset_state)); + + DBG(vcp, "Vol Offset 0x%x", vostate.vol_offset); + DBG(vcp, "Vol Offset Counter 0x%x", vostate.counter); +} + +static void vcp_audio_loc_notify(struct bt_vcp *vcp, uint16_t value_handle, + const uint8_t *value, uint16_t length, + void *user_data) +{ + uint32_t *vocs_audio_loc_n = malloc(sizeof(uint32_t)); + *vocs_audio_loc_n = 0; + + if (value != NULL) + memcpy(vocs_audio_loc_n, value, sizeof(uint32_t)); + + DBG(vcp, "VOCS Audio Location 0x%x", *vocs_audio_loc_n); + + free(vocs_audio_loc_n); +} + + +static void vcp_audio_descriptor_notify(struct bt_vcp *vcp, + uint16_t value_handle, + const uint8_t *value, + uint16_t length, + void *user_data) +{ + char vocs_audio_dec_n[256] = {'\0'}; + + memcpy(vocs_audio_dec_n, value, length); + + DBG(vcp, "VOCS Audio Descriptor 0x%s", *vocs_audio_dec_n); +} + static void vcp_vflag_notify(struct bt_vcp *vcp, uint16_t value_handle, const uint8_t *value, uint16_t length, void *user_data) @@ -972,6 +1342,86 @@ static void read_vol_state(struct bt_vcp *vcp, bool success, uint8_t att_ecode, DBG(vcp, "Vol Counter:%x", vs->counter); } +static void read_vol_offset_state(struct bt_vcp *vcp, bool success, + uint8_t att_ecode, + const uint8_t *value, uint16_t length, + void *user_data) +{ + struct vol_offset_state *vos; + struct iovec iov = { + .iov_base = (void *) value, + .iov_len = length, + }; + + if (!success) { + DBG(vcp, "Unable to read Vol Offset State: error 0x%02x", + att_ecode); + return; + } + + vos = iov_pull_mem(&iov, sizeof(*vos)); + if (!vos) { + DBG(vcp, "Unable to get Vol Offset State"); + return; + } + + DBG(vcp, "Vol Set:%x", vos->vol_offset); + DBG(vcp, "Vol Counter:%x", vos->counter); +} + +static void read_vocs_audio_location(struct bt_vcp *vcp, bool success, + uint8_t att_ecode, + const uint8_t *value, uint16_t length, + void *user_data) +{ + uint32_t *vocs_audio_loc; + struct iovec iov = { + .iov_base = (void *) value, + .iov_len = length, + }; + + if (!success) { + DBG(vcp, "Unable to read VOCS Audio Location: error 0x%02x", + att_ecode); + return; + } + + vocs_audio_loc = iov_pull_mem(&iov, sizeof(uint32_t)); + if (!*vocs_audio_loc) { + DBG(vcp, "Unable to get VOCS Audio Location"); + return; + } + + DBG(vcp, "VOCS Audio Loc:%x", *vocs_audio_loc); +} + + +static void read_vocs_audio_descriptor(struct bt_vcp *vcp, bool success, + uint8_t att_ecode, + const uint8_t *value, uint16_t length, + void *user_data) +{ + char *vocs_ao_dec_r; + struct iovec iov = { + .iov_base = (void *) value, + .iov_len = length, + }; + + if (!success) { + DBG(vcp, "Unable to read VOCS Audio Descriptor: error 0x%02x", + att_ecode); + return; + } + + vocs_ao_dec_r = iov_pull_mem(&iov, length); + if (!*vocs_ao_dec_r) { + DBG(vcp, "Unable to get VOCS Audio Descriptor"); + return; + } + + DBG(vcp, "VOCS Audio Descriptor:%s", *vocs_ao_dec_r); +} + static void vcp_pending_destroy(void *data) { struct bt_vcp_pending *pending = data; @@ -1128,6 +1578,90 @@ static void foreach_vcs_char(struct gatt_db_attribute *attr, void *user_data) } } +static void foreach_vocs_char(struct gatt_db_attribute *attr, void *user_data) +{ + struct bt_vcp *vcp = user_data; + uint16_t value_handle; + bt_uuid_t uuid, uuid_vostate, uuid_audio_loc, uuid_vo_cp, + uuid_audio_op_decs; + struct bt_vocs *vocs; + + if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, + NULL, NULL, &uuid)) + return; + + bt_uuid16_create(&uuid_vostate, VOCS_STATE_CHAR_UUID); + bt_uuid16_create(&uuid_audio_loc, VOCS_AUDIO_LOC_CHRC_UUID); + bt_uuid16_create(&uuid_vo_cp, VOCS_CP_CHRC_UUID); + bt_uuid16_create(&uuid_audio_op_decs, VOCS_AUDIO_OP_DESC_CHAR_UUID); + + if (!bt_uuid_cmp(&uuid, &uuid_vostate)) { + DBG(vcp, "VOCS Vol state found: handle 0x%04x", value_handle); + + vocs = vcp_get_vocs(vcp); + if (!vocs || vocs->vos) + return; + + vocs->vos = attr; + + vcp_read_value(vcp, value_handle, read_vol_offset_state, vcp); + + vcp->state_id = vcp_register_notify(vcp, value_handle, + vcp_voffset_state_notify, NULL); + + return; + } + + if (!bt_uuid_cmp(&uuid, &uuid_audio_loc)) { + DBG(vcp, "VOCS Volume Audio Location found: handle 0x%04x", + value_handle); + + vocs = vcp_get_vocs(vcp); + if (!vocs || vocs->voal) + return; + + vocs->voal = attr; + + vcp_read_value(vcp, value_handle, read_vocs_audio_location, + vcp); + + vcp->audio_loc_id = vcp_register_notify(vcp, value_handle, + vcp_audio_loc_notify, NULL); + + return; + } + + if (!bt_uuid_cmp(&uuid, &uuid_vo_cp)) { + DBG(vcp, "VOCS Volume CP found: handle 0x%04x", value_handle); + + vocs = vcp_get_vocs(vcp); + if (!vocs || vocs->vo_cp) + return; + + vocs->vo_cp = attr; + + return; + } + + if (!bt_uuid_cmp(&uuid, &uuid_audio_op_decs)) { + DBG(vcp, "VOCS Vol Audio Descriptor found: handle 0x%04x", + value_handle); + + vocs = vcp_get_vocs(vcp); + if (!vocs || vocs->voaodec) + return; + + vocs->voaodec = attr; + + vcp_read_value(vcp, value_handle, read_vocs_audio_descriptor, + vcp); + vcp->ao_dec_id = vcp_register_notify(vcp, value_handle, + vcp_audio_descriptor_notify, NULL); + + } + +} + static void foreach_vcs_service(struct gatt_db_attribute *attr, void *user_data) { @@ -1141,6 +1675,19 @@ static void foreach_vcs_service(struct gatt_db_attribute *attr, gatt_db_service_foreach_char(attr, foreach_vcs_char, vcp); } +static void foreach_vocs_service(struct gatt_db_attribute *attr, + void *user_data) +{ + struct bt_vcp *vcp = user_data; + struct bt_vocs *vocs = vcp_get_vocs(vcp); + + vocs->service = attr; + + gatt_db_service_set_claimed(attr, true); + + gatt_db_service_foreach_char(attr, foreach_vocs_char, vcp); +} + bool bt_vcp_attach(struct bt_vcp *vcp, struct bt_gatt_client *client) { bt_uuid_t uuid; @@ -1163,6 +1710,9 @@ bool bt_vcp_attach(struct bt_vcp *vcp, struct bt_gatt_client *client) bt_uuid16_create(&uuid, VCS_UUID); gatt_db_foreach_service(vcp->ldb->db, &uuid, foreach_vcs_service, vcp); + bt_uuid16_create(&uuid, VOL_OFFSET_CS_UUID); + gatt_db_foreach_service(vcp->ldb->db, &uuid, foreach_vocs_service, vcp); + return true; } From patchwork Mon Jun 12 13:32:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nitin Jadhav X-Patchwork-Id: 13276532 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 78C74C7EE23 for ; Mon, 12 Jun 2023 13:33:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236337AbjFLNdx (ORCPT ); Mon, 12 Jun 2023 09:33:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58800 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235960AbjFLNdw (ORCPT ); Mon, 12 Jun 2023 09:33:52 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on2071.outbound.protection.outlook.com [40.107.7.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 758B9FB for ; Mon, 12 Jun 2023 06:33:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HDCsqokBi/N42U8KvPARc8bvJT2EMclYzhtJi6WECTEy0zHrORmGagM1Opg16dp+86kXaatqro2V9vMcO1FSSCJem+F1dcsVgXa8im6H1btK/0XG2LWnDocUVrqVTEu6VemzHHkebHf9WdKzapekYgUaZQ98roEfakqPCpHv/dJolaUz6h+BlxRBulHxUVmIYQFhKvYpJqMih4x8tyQDzZfVpVbLEhcgz6QqyTixQGhLA8bR5QGF8f0pGW+b6oPFypTETS3KgPAkq2o2CFn+CdhPZGTdVf+TejwGFLYi7CvXIxDgE1ceieL2GmiPLQTMDNb9Juj2x5Sm0uPVKdxiMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=+5yhFzmI5hxrAXsqUptywBBym8iemfMW4SCPR7Ir9WI=; b=gp1CVG2NE0hPAOXZn7KHgFlpxG/8BFyedxl9eMnb602W87HIPLOfVIqgN/QGzTXZF7dvPLejM32PKGONgW2wxBHIaL2F0ECuhGxqUPV8vQr2+46Fjp6IVTBMT4GsvqwqX52Qrpi1kI4JU8WdqlUDZyU8PbRZjI3ZNFxVg2L6yZXUiDOBG1vvQWTsuPWxHgg30lbX4Ju9i8XNZT62IzVTvygOQ4Qr3o9v8/fLofAnNxsUI1TdUwR9AvqPlB/FwL9sJm8qFOCjLB6lJxFNvz31ph3/qwt1ide1aE4jAxI+K3Zy9mkFgtIbE+qc0JKci4ZGWD4k/8ST+3Z5SV4eyKhjFQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+5yhFzmI5hxrAXsqUptywBBym8iemfMW4SCPR7Ir9WI=; b=Z4i+Wgk4gQ5hnZSuHms8KegMKWPmKw3HpFNOf+Yx4UsnrAmlWb6kocjWeAObcy0wA9584stuyWe+EKlDFsFIWHOrEuPkY3UXDKCuzCHdJqEZJ5i8oBI0BHicHtNDtjiSpgD4GHPH7jj7Z3eI8yjS6Vf6VhzrCaDNljI/A4BiNJY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AS8PR04MB9126.eurprd04.prod.outlook.com (2603:10a6:20b:449::16) by AM9PR04MB9002.eurprd04.prod.outlook.com (2603:10a6:20b:409::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6477.29; Mon, 12 Jun 2023 13:33:50 +0000 Received: from AS8PR04MB9126.eurprd04.prod.outlook.com ([fe80::ad2c:857b:a144:9af4]) by AS8PR04MB9126.eurprd04.prod.outlook.com ([fe80::ad2c:857b:a144:9af4%3]) with mapi id 15.20.6455.030; Mon, 12 Jun 2023 13:33:50 +0000 From: Nitin Jadhav To: linux-bluetooth@vger.kernel.org Cc: devyani.godbole@nxp.com, mihai-octavian.urzica@nxp.com, silviu.barbulescu@nxp.com, nitin.jadhav@nxp.com Subject: [PATCH BlueZ v5 3/3] shared/vcp.c: Make VOCS as an included service of VCS Date: Mon, 12 Jun 2023 19:02:51 +0530 Message-Id: <20230612133251.194-4-nitin.jadhav@nxp.com> X-Mailer: git-send-email 2.33.1.windows.1 In-Reply-To: <20230612133251.194-1-nitin.jadhav@nxp.com> References: <20230612133251.194-1-nitin.jadhav@nxp.com> X-ClientProxiedBy: SI2PR01CA0023.apcprd01.prod.exchangelabs.com (2603:1096:4:192::17) To AS8PR04MB9126.eurprd04.prod.outlook.com (2603:10a6:20b:449::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8PR04MB9126:EE_|AM9PR04MB9002:EE_ X-MS-Office365-Filtering-Correlation-Id: 05d5265b-a5d0-4e72-a345-08db6b49a830 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: kWhTjkHxylSj/+uF9ogsCJxePcm69grf6rq0M7QQGMi7oJE9fmFmY6jjRAwylcvUEtKw37QuUCYeu8LLpGApYczD6MyaOCkBgGCBRTn0aetRtPKzCapG2frC4/hDxJgpe+LI7qqhExuM0Kw9uVR+OTFHticc1HG3414W6Gnf9EY92K/RaBa75GBbGO+PHNv0jNIV92t64KWH5HQu3W3ngZ0ZsSJMsSG2uQIRI7+HqcBgHAQxgzzGfec6FvTehskHkd67Wz95+ifTTFFxnwAm0OVjZS2XbWK/0y+keR8WO7gZvc82VWPqJ16XEOCzBv+6+kYMefkPS193S3g/EV+UiGQ/xoN4M3PwpT/JUB0PM+PHyQsTz2Udi4MdELCJSjw/fUTLbpYndFbQ2NNxGRHuBNkMJin23jby1rxo44SJS4rpN28b+W9phRtsj9MMRbC91hpd6qQxUiqglL2Bm/TCvCH8svALpqrkAkKEtrkP3Ux2ZPSPbjZZkEEkIOoDcCmCwy7f/RvybIW6wHay8gB8mNM20TBsZl9QxifZHtiaIUatngRqio3DluEWO65lYN2Is7OdblmaGPEfFL2trsk/sl3OeyxHCHfrrvsnQ2Lc/NOjH7dIoU+ZvUceL7kMzh6P X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AS8PR04MB9126.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(4636009)(396003)(136003)(346002)(376002)(366004)(39860400002)(451199021)(52116002)(6486002)(36756003)(83380400001)(2616005)(38350700002)(38100700002)(86362001)(6506007)(6512007)(1076003)(26005)(186003)(2906002)(5660300002)(44832011)(8936002)(8676002)(316002)(41300700001)(6916009)(4326008)(66946007)(66556008)(66476007)(478600001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: vVJqJHrwUSDrLuXzPF3BayXii1VcgufOQx3pNfgzXimtdtv5C6UtLeYk6f8F2ovG88MElv2xGEsxwE4qbC31uKrd8Ijzo2ajdv8nK91qVlOfeN6Q72JSCsZ7dsUgj8/YdYjt2qUh4g3gkm78KGeXNfb0PtBo45VakiEzynF3/b6+JvsXus5VJcYs6RYmvVyaDB2a0aMK5m3b2pxEqGS3VgbehTB/hvgXkw29nQwqugq6DgB1fIhHlg1qpd6rJXAqIRpYyiNh1OdnpJ8b/3O2dzosI0rw9Wl2XsWNGzmyJxtuJvGkGBYqo28ESD2nS6dKc6h8CM21OQVp/PaE/tiQK5z0r4Ilw1TWv0BJmrZDFaVOnCXpF8XpNZt30X8sAG2nKUu8gKyczvQ9Nm5fsPQRtr1MnJzx/9r9nNhEqpX3tDECu166fy6BW5NZjHwAv6tfjNeixK2qXsr/yxkA9UFuaFG3afguJuAMZ6EEi+vHP4Y1FLmcmHx0p/NOf6kUr4OeRnuWIXvXj+hyWhKtXBdkxImjV9jfJprklrYd0mpyddvXgT0DiO4z9OFUlFQc16AFRgGwBufoaloYg67a+wrmJPcYqj7eyn3XJPv6s7+8kDTeKoaF6kVTES7u4ZVU5eKtIklj7ZwSy8Vuw1hPjvEIoj739VbuGGtNsEV2FpD124vHGmMqyvQyc4heW0RiN58FKzWbqQ4jJcKk1XWw9gFJz3cyJUJEEv+p71U3ka8FzTDlZNnlCYKRWc3VVNP6VVbvRCWwypMhr0Fv6jNFkCyI4pMolzNmNK1vQqJ356oNjdtxP2QpjiGl8kbyb7zwBA6N03bTcUeHCW6LbOdw00gODqeAU+RbZ1aGVOcTG4+I2yur3u0MyTzng3YT2Ey4yJ/wCJ36jjd/ma3IS9RLuMpdsNjxVUM/ss+w2hKR1/D3TwFllCwSXLVmyh3Yg/pJ8/kcgFfFlJZ6FfX6ToICcZLcDlXAdM2NVHmqdcOeABQboTP20KpALgaMPA5kpup1Rf86q4s001aw+WTsb0w3AzKO8m3MkL4NAO1xGP6fqYi/uCcD2jqKBj0ygTMvP0kGkuZBjrxRAmuxuldwKUx5v07pS1EfW7NH31iSebtAM3RF2S+a7ATEunq3x3HkhuRg6wqP/bPjGW3E2GH8Nab4FhLcMMo689BBc3r4v1Dq0aZgZlsqhLln1VO7/B52JXzvkADKWSygUNOU25K7zhr7bjUfTvCU8ZrCIH2J6zOmOiL9LblwwM2H2ocQhs5XQlblnv8polcGuIaE1TYkTuA43puuJ65RF9E56ZwezeoK9/SgLeK3+apttvCo0IxOGWwSw4Vuy9n/EK8ltT7Ca550eAwKKDBQWa79SLXO07udNuVhIlseoXkdsFzRupwm3as5kf9urtixEBngPee/fh2S3C8TIDo3K6/2yFAk48GF7vXm4548L0fVcMBurHGbgHr8VmEf+bR0NdXZOhnGIa5fjNWxDyvXPahnEvH78PnXoSTYY8ZN43KyONM4zGijoP0ShyFxJXeWMmChk5rsJwp3FyONXD8BpbP51xTJrQaSNLFqKjef+PUsJ5cSV9ZTf+4cT037 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 05d5265b-a5d0-4e72-a345-08db6b49a830 X-MS-Exchange-CrossTenant-AuthSource: AS8PR04MB9126.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2023 13:33:50.4429 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: tODjJjUe5Gc/I//KrXsWRf94N+o63cMzrLdLDZh0HbKl4iOn8NgPCJaLaow1EJgRCgE+y0DogypS7LBNZF7E1w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM9PR04MB9002 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Fixed the following issue observed during PTS testing - Specified Upper and Lower Limit for Volume offset - Corrected the number of handles for VOCS - VOCS is made as included service of VCS (VOCS is secondary service and VSC is primary service) --- v2: Cosmetic Changes (Bluez Test Bot) v5: Resolved GitLint warning (tedd_an/GitLint) --- src/shared/vcp.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/shared/vcp.c b/src/shared/vcp.c index 92f21fd0b..74bd01729 100644 --- a/src/shared/vcp.c +++ b/src/shared/vcp.c @@ -32,9 +32,13 @@ #define VCP_STEP_SIZE 1 +#define VOCS_VOL_OFFSET_UPPER_LIMIT 255 +#define VOCS_VOL_OFFSET_LOWER_LIMIT -255 + /* Apllication Error Code */ #define BT_ATT_ERROR_INVALID_CHANGE_COUNTER 0x80 #define BT_ATT_ERROR_OPCODE_NOT_SUPPORTED 0x81 +#define BT_ATT_ERROR_VALUE_OUT_OF_RANGE 0x82 #define BT_VCP_NA BIT(0) #define BT_VCP_FRONT_LEFT BIT(1) @@ -100,7 +104,7 @@ struct bt_vcs_ab_vol { struct bt_vocs_set_vol_off { uint8_t change_counter; - uint8_t set_vol_offset; + int16_t set_vol_offset; } __packed; struct bt_vcp_cb { @@ -167,7 +171,7 @@ struct bt_vcs { /* Contains local bt_vcp_db */ struct vol_offset_state { - uint16_t vol_offset; + int16_t vol_offset; uint8_t counter; } __packed; @@ -705,6 +709,11 @@ static uint8_t vocs_set_vol_offset(struct bt_vocs *vocs, struct bt_vcp *vcp, return BT_ATT_ERROR_INVALID_CHANGE_COUNTER; } + if (req->set_vol_offset > VOCS_VOL_OFFSET_UPPER_LIMIT || + req->set_vol_offset < VOCS_VOL_OFFSET_LOWER_LIMIT) { + DBG(vcp, "error: Value Out of Range"); + return BT_ATT_ERROR_VALUE_OUT_OF_RANGE; + } vstate->vol_offset = req->set_vol_offset; vstate->counter = -~vstate->counter; /*Increment Change Counter*/ @@ -971,7 +980,7 @@ static void vocs_voaodec_read(struct gatt_db_attribute *attrib, iov.iov_len); } -static struct bt_vcs *vcs_new(struct gatt_db *db) +static struct bt_vcs *vcs_new(struct gatt_db *db, struct bt_vcp_db *vdb) { struct bt_vcs *vcs; struct vol_state *vstate; @@ -990,6 +999,8 @@ static struct bt_vcs *vcs_new(struct gatt_db *db) /* Populate DB with VCS attributes */ bt_uuid16_create(&uuid, VCS_UUID); vcs->service = gatt_db_add_service(db, &uuid, true, 9); + gatt_db_service_add_included(vcs->service, vdb->vocs->service); + gatt_db_service_set_active(vdb->vocs->service, true); bt_uuid16_create(&uuid, VOL_STATE_CHRC_UUID); vcs->vs = gatt_db_service_add_characteristic(vcs->service, @@ -1048,7 +1059,8 @@ static struct bt_vocs *vocs_new(struct gatt_db *db) /* Populate DB with VOCS attributes */ bt_uuid16_create(&uuid, VOL_OFFSET_CS_UUID); - vocs->service = gatt_db_add_service(db, &uuid, true, 9); + + vocs->service = gatt_db_add_service(db, &uuid, false, 12); bt_uuid16_create(&uuid, VOCS_STATE_CHAR_UUID); vocs->vos = gatt_db_service_add_characteristic(vocs->service, @@ -1110,11 +1122,10 @@ static struct bt_vcp_db *vcp_db_new(struct gatt_db *db) if (!vcp_db) vcp_db = queue_new(); - vdb->vcs = vcs_new(db); - vdb->vcs->vdb = vdb; - vdb->vocs = vocs_new(db); vdb->vocs->vdb = vdb; + vdb->vcs = vcs_new(db, vdb); + vdb->vcs->vdb = vdb; queue_push_tail(vcp_db, vdb);