* [PATCH v3] Bluetooth: L2CAP: Fix null-ptr-deref in l2cap_sock_get_sndtimeo_cb()
From: Siwei Zhang @ 2026-04-15 20:53 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz; +Cc: linux-bluetooth, Siwei Zhang
Add the same NULL guard already present in
l2cap_sock_resume_cb() and l2cap_sock_ready_cb().
Fixes: 8d836d71e222 ("Bluetooth: Access sk_sndtimeo indirectly in l2cap_core.c")
Cc: stable@kernel.org
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
---
net/bluetooth/l2cap_sock.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 71e8c1b45bce..ac48148a7628 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1758,6 +1758,9 @@ static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;
+ if (!sk)
+ return 0;
+
return READ_ONCE(sk->sk_sndtimeo);
}
--
2.53.0
^ permalink raw reply related
* [PATCH v2 RESEND] Bluetooth: L2CAP: Fix null-ptr-deref in l2cap_sock_state_change_cb()
From: Siwei Zhang @ 2026-04-15 20:51 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz; +Cc: linux-bluetooth, Siwei Zhang
Add the same NULL guard already present in
l2cap_sock_resume_cb() and l2cap_sock_ready_cb().
Fixes: 89bc500e41fc ("Bluetooth: Add state tracking to struct l2cap_chan")
Cc: stable@kernel.org
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
---
net/bluetooth/l2cap_sock.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 71e8c1b45bce..fb3cb70a5a39 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1657,6 +1657,9 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
{
struct sock *sk = chan->data;
+ if (!sk)
+ return;
+
sk->sk_state = state;
if (err)
--
2.53.0
^ permalink raw reply related
* [PATCH v3] Bluetooth: L2CAP: Fix null-ptr-deref in l2cap_sock_new_connection_cb()
From: Siwei Zhang @ 2026-04-15 20:49 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz; +Cc: linux-bluetooth, Siwei Zhang
Add the same NULL guard already present in
l2cap_sock_resume_cb() and l2cap_sock_ready_cb().
Fixes: 80808e431e1e ("Bluetooth: Add l2cap_chan_ops abstraction")
Cc: stable@kernel.org
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
---
net/bluetooth/l2cap_sock.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 71e8c1b45bce..8994e9c5d179 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1498,6 +1498,9 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
{
struct sock *sk, *parent = chan->data;
+ if (!parent)
+ return NULL;
+
lock_sock(parent);
/* Check for backlog size */
--
2.53.0
^ permalink raw reply related
* [PATCH v2 RESEND] Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()
From: Siwei Zhang @ 2026-04-15 20:47 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz; +Cc: linux-bluetooth, Siwei Zhang
l2cap_sock_new_connection_cb() accesses l2cap_pi(sk)->chan after
release_sock(parent). Once the parent lock is released, the child
socket sk can be freed by another task.
Save the channel pointer into a local variable while the parent lock
is still held to prevent this.
Fixes: 8ffb929098a5 ("Bluetooth: Remove parent socket usage from l2cap_core.c")
Cc: stable@kernel.org
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
---
net/bluetooth/l2cap_sock.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 71e8c1b45bce..1625e4fc38d6 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1497,6 +1497,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
{
struct sock *sk, *parent = chan->data;
+ struct l2cap_chan *child_chan;
lock_sock(parent);
@@ -1520,9 +1521,11 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
bt_accept_enqueue(parent, sk, false);
+ child_chan = l2cap_pi(sk)->chan;
+
release_sock(parent);
- return l2cap_pi(sk)->chan;
+ return child_chan;
}
static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
--
2.53.0
^ permalink raw reply related
* [PATCH BlueZ v1 3/3] github: Add btsnoop-analyzer slash command workflow
From: Luiz Augusto von Dentz @ 2026-04-15 18:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260415182210.514686-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Add caller workflow for the btsnoop-analyzer reusable workflow,
enabling trace analysis from any issue comment.
---
.github/workflows/btsnoop-analyze.yml | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 .github/workflows/btsnoop-analyze.yml
diff --git a/.github/workflows/btsnoop-analyze.yml b/.github/workflows/btsnoop-analyze.yml
new file mode 100644
index 000000000000..484288c0d9b6
--- /dev/null
+++ b/.github/workflows/btsnoop-analyze.yml
@@ -0,0 +1,13 @@
+name: Analyze on mention
+
+on:
+ issue_comment:
+ types: [created]
+
+jobs:
+ analyze:
+ if: >-
+ github.event.issue.pull_request == null &&
+ contains(github.event.comment.body, '/analyze')
+ uses: Vudentz/btsnoop-analyzer/.github/workflows/analyze-on-mention.yml@master
+ secrets: inherit
--
2.53.0
^ permalink raw reply related
* [PATCH BlueZ v1 2/3] github: Make result posting robust against action failures
From: Luiz Augusto von Dentz @ 2026-04-15 18:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260415182210.514686-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Use always() conditions with file-existence checks so steps 1-4
results are posted even if the btsnoop-analyzer action fails
partway through. The error comment now only fires on actual action
failure (e.g. btmon build error), not LLM errors which are handled
gracefully by the analyzer.
---
.github/workflows/btsnoop-analyzer.yml | 34 +++++++++++++++++---------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/btsnoop-analyzer.yml b/.github/workflows/btsnoop-analyzer.yml
index 3bbd963004cb..9ecda193ceff 100644
--- a/.github/workflows/btsnoop-analyzer.yml
+++ b/.github/workflows/btsnoop-analyzer.yml
@@ -100,12 +100,14 @@ jobs:
GH_MODELS_TOKEN: ${{ secrets.GH_MODELS_TOKEN }}
- name: Post detection comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const detect = fs.readFileSync('${{ steps.analysis.outputs.detect }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.detect }}';
+ if (!fs.existsSync(path)) return;
+ const detect = fs.readFileSync(path, 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -114,12 +116,14 @@ jobs:
});
- name: Post filter comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const filter = fs.readFileSync('${{ steps.analysis.outputs.filter }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.filter }}';
+ if (!fs.existsSync(path)) return;
+ const filter = fs.readFileSync(path, 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -128,12 +132,14 @@ jobs:
});
- name: Post annotation comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const annotate = fs.readFileSync('${{ steps.analysis.outputs.annotate }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.annotate }}';
+ if (!fs.existsSync(path)) return;
+ const annotate = fs.readFileSync(path, 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -142,12 +148,14 @@ jobs:
});
- name: Post diagnostics comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const diagnose = fs.readFileSync('${{ steps.analysis.outputs.diagnose }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.diagnose }}';
+ if (!fs.existsSync(path)) return;
+ const diagnose = fs.readFileSync(path, 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -156,12 +164,14 @@ jobs:
});
- name: Post analysis comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const analysis = fs.readFileSync('${{ steps.analysis.outputs.analyze }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.analyze }}';
+ if (!fs.existsSync(path)) return;
+ const analysis = fs.readFileSync(path, 'utf8');
const footer = `\n\n---\n<sub>Analyzed by [btsnoop-analyzer](https://github.com/Vudentz/btsnoop-analyzer) using btmon from [BlueZ](https://github.com/bluez/bluez). MAC addresses ${
'${{ steps.parse.outputs.anonymize }}' === 'true'
@@ -177,7 +187,7 @@ jobs:
});
- name: Post error comment
- if: steps.parse.outputs.found == 'true' && failure()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome == 'failure'
uses: actions/github-script@v7
with:
script: |
@@ -190,7 +200,7 @@ jobs:
The automated analysis encountered an error. This could be due to:
- Unsupported trace file format
- Trace file too large to process
- - LLM API rate limiting or downtime
+ - btmon build failure
A maintainer will review your trace manually.
--
2.53.0
^ permalink raw reply related
* [PATCH BlueZ v1 1/3] github: Add YAML issue template and btsnoop-analyzer workflow
From: Luiz Augusto von Dentz @ 2026-04-15 18:22 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Replace the markdown issue template with a structured YAML form that
includes fields for description, reproduction steps, btmon trace upload,
analysis focus area selection, and privacy consent checkboxes.
Add a btsnoop-analyzer workflow that automatically analyzes btsnoop
traces attached to new issues using Vudentz/btsnoop-analyzer action,
posting results as issue comments.
---
.github/ISSUE_TEMPLATE/issue.md | 41 -----
.github/ISSUE_TEMPLATE/issue.yml | 108 +++++++++++++
.github/workflows/btsnoop-analyzer.yml | 202 +++++++++++++++++++++++++
3 files changed, 310 insertions(+), 41 deletions(-)
delete mode 100644 .github/ISSUE_TEMPLATE/issue.md
create mode 100644 .github/ISSUE_TEMPLATE/issue.yml
create mode 100644 .github/workflows/btsnoop-analyzer.yml
diff --git a/.github/ISSUE_TEMPLATE/issue.md b/.github/ISSUE_TEMPLATE/issue.md
deleted file mode 100644
index ba384e120bac..000000000000
--- a/.github/ISSUE_TEMPLATE/issue.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-name: New issue
-about: 'Report a bug or other problem'
-title: ''
-labels: ''
-assignees: ''
-
----
-
-### Description
-
-<!-- A clear and concise description of what the bug is -->
-
-<!-- A clear and concise description of what you expected to happen -->
-
-<!-- Include any other relevant details -->
-
-### To reproduce
-<!-- Steps to reproduce the issue, if possible -->
-1.
-2.
-3.
-4.
-
-### Logs
-- btmon log: <!-- Bluetooth traffic dump: (usually needed)
- 0. Power off connected device
- 1. Run: btmon -w btmon.log
- 2. Connect device, reproduce the issue
- 3. Ctrl-C btmon
- 4. Attach btmon.log to the issue -->
-- bluetoothd log: <!-- Run: journalctl -u bluetooth --boot 0 > bluetoothd.log; if relevant for issue -->
-
-<!-- Any other logs etc. relevant for the issue -->
-
-### Versions
-- BlueZ version: <!-- Run: bluetoothctl --version -->
-- Kernel version: <!-- Run: uname -r -->
-- Problematic device: <!-- Device model etc information, if relevant -->
-
-<!-- Any other relevant information on platform / hardware here -->
diff --git a/.github/ISSUE_TEMPLATE/issue.yml b/.github/ISSUE_TEMPLATE/issue.yml
new file mode 100644
index 000000000000..0f069858eeaf
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/issue.yml
@@ -0,0 +1,108 @@
+name: New issue
+description: Report a bug or other problem
+labels: []
+body:
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: |
+ A clear and concise description of the bug, what you expected
+ to happen, and any other relevant details.
+ placeholder: Describe the issue...
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduce
+ attributes:
+ label: To reproduce
+ description: Steps to reproduce the issue, if possible.
+ placeholder: |
+ 1.
+ 2.
+ 3.
+ 4.
+ validations:
+ required: false
+
+ - type: textarea
+ id: trace-file
+ attributes:
+ label: btmon trace
+ description: |
+ Drag and drop your btsnoop trace file here. If a trace is
+ attached and the privacy acknowledgment below is checked,
+ it will be automatically analyzed by
+ [btsnoop-analyzer](https://github.com/Vudentz/btsnoop-analyzer).
+
+ To capture a trace: power off the device, run `btmon -w btmon.log`,
+ reproduce the issue, then Ctrl-C btmon.
+ placeholder: Drag and drop your btmon.log file here...
+ validations:
+ required: false
+
+ - type: dropdown
+ id: focus-area
+ attributes:
+ label: Analysis focus
+ description: >
+ If you attached a btsnoop trace, what aspect should the
+ automated analysis focus on? Select "General" to auto-detect.
+ options:
+ - General (full analysis)
+ - Connection issues
+ - Controller enumeration
+ - Pairing / Security
+ - GATT discovery
+ - Audio
+ - Audio / LE Audio
+ - Audio / A2DP
+ - Audio / HFP
+ - L2CAP channel issues
+ - Advertising / Scanning
+ - Disconnection analysis
+ - Channel Sounding
+ validations:
+ required: false
+
+ - type: checkboxes
+ id: privacy
+ attributes:
+ label: Privacy
+ description: |
+ btsnoop traces contain Bluetooth MAC addresses and may contain
+ device names. By default, MAC addresses are anonymized before
+ being sent to an LLM for analysis.
+ options:
+ - label: >
+ **Skip anonymization** — Send the raw decoded trace to the
+ LLM without scrubbing MAC addresses or device names.
+ required: false
+ - label: >
+ I understand this trace will be processed by a third-party
+ LLM API and I have the right to share this data.
+ required: false
+
+ - type: textarea
+ id: logs
+ attributes:
+ label: Other logs
+ description: |
+ Attach bluetoothd or other relevant logs.
+ Run: `journalctl -u bluetooth --boot 0 > bluetoothd.log`
+ render: text
+ validations:
+ required: false
+
+ - type: textarea
+ id: versions
+ attributes:
+ label: Versions
+ description: BlueZ version, kernel version, and device information.
+ value: |
+ - BlueZ version:
+ - Kernel version:
+ - Problematic device:
+ validations:
+ required: false
diff --git a/.github/workflows/btsnoop-analyzer.yml b/.github/workflows/btsnoop-analyzer.yml
new file mode 100644
index 000000000000..3bbd963004cb
--- /dev/null
+++ b/.github/workflows/btsnoop-analyzer.yml
@@ -0,0 +1,202 @@
+name: btsnoop-analyzer
+
+on:
+ issues:
+ types: [opened, reopened]
+
+permissions:
+ issues: write
+ contents: read
+
+jobs:
+ analyze:
+ # Only run when the user acknowledged the privacy statement
+ if: contains(github.event.issue.body, 'I understand this trace will be processed')
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+
+ steps:
+ - name: Parse issue body
+ id: parse
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const body = context.payload.issue.body || '';
+
+ // Extract trace file URL from issue body
+ const urlPatterns = [
+ /https:\/\/github\.com\/[^\s)]+\.(?:log|snoop|btsnoop|cfa)/gi,
+ /https:\/\/github\.com\/user-attachments\/(?:files|assets)\/[^\s)]+/gi,
+ ];
+
+ let traceUrl = '';
+ for (const pattern of urlPatterns) {
+ const match = body.match(pattern);
+ if (match) {
+ traceUrl = match[0];
+ break;
+ }
+ }
+
+ if (!traceUrl) {
+ console.log('No trace file URL found — skipping analysis');
+ core.setOutput('found', 'false');
+ return;
+ }
+
+ // Extract description
+ const descMatch = body.match(
+ /### Description\s*\n([\s\S]*?)(?=\n###|\n\*\*|$)/i
+ );
+ const description = descMatch?.[1]?.trim() || 'No description provided';
+
+ // Extract focus area
+ const focusMatch = body.match(
+ /### Analysis focus\s*\n\s*(\S[^\n]*)/i
+ );
+ const focus = focusMatch?.[1]?.trim() || 'General (full analysis)';
+
+ // Check anonymization preference
+ const skipAnon = body.includes('[X] **Skip anonymization**') ||
+ body.includes('[x] **Skip anonymization**');
+
+ core.setOutput('found', 'true');
+ core.setOutput('trace_url', traceUrl);
+ core.setOutput('description', description);
+ core.setOutput('focus', focus);
+ core.setOutput('anonymize', skipAnon ? 'false' : 'true');
+
+ console.log(`Trace URL: ${traceUrl}`);
+ console.log(`Focus: ${focus}`);
+ console.log(`Anonymize: ${!skipAnon}`);
+
+ - name: Post "analyzing" comment
+ if: steps.parse.outputs.found == 'true'
+ uses: actions/github-script@v7
+ with:
+ script: |
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: '**btsnoop Analyzer** is processing your trace. This typically takes 1-3 minutes.\n\n_Decoding with btmon, then sending to LLM for analysis..._'
+ });
+
+ - name: Run btsnoop-analyzer
+ if: steps.parse.outputs.found == 'true'
+ id: analysis
+ uses: Vudentz/btsnoop-analyzer@master
+ with:
+ trace-url: ${{ steps.parse.outputs.trace_url }}
+ description: ${{ steps.parse.outputs.description }}
+ focus: ${{ steps.parse.outputs.focus }}
+ anonymize: ${{ steps.parse.outputs.anonymize }}
+ provider: ${{ vars.LLM_PROVIDER || 'github' }}
+ model: ${{ vars.LLM_MODEL || '' }}
+ env:
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_MODELS_TOKEN: ${{ secrets.GH_MODELS_TOKEN }}
+
+ - name: Post detection comment
+ if: steps.parse.outputs.found == 'true' && success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const detect = fs.readFileSync('${{ steps.analysis.outputs.detect }}', 'utf8');
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: detect
+ });
+
+ - name: Post filter comment
+ if: steps.parse.outputs.found == 'true' && success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const filter = fs.readFileSync('${{ steps.analysis.outputs.filter }}', 'utf8');
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: filter
+ });
+
+ - name: Post annotation comment
+ if: steps.parse.outputs.found == 'true' && success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const annotate = fs.readFileSync('${{ steps.analysis.outputs.annotate }}', 'utf8');
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: annotate
+ });
+
+ - name: Post diagnostics comment
+ if: steps.parse.outputs.found == 'true' && success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const diagnose = fs.readFileSync('${{ steps.analysis.outputs.diagnose }}', 'utf8');
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: diagnose
+ });
+
+ - name: Post analysis comment
+ if: steps.parse.outputs.found == 'true' && success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const analysis = fs.readFileSync('${{ steps.analysis.outputs.analyze }}', 'utf8');
+
+ const footer = `\n\n---\n<sub>Analyzed by [btsnoop-analyzer](https://github.com/Vudentz/btsnoop-analyzer) using btmon from [BlueZ](https://github.com/bluez/bluez). MAC addresses ${
+ '${{ steps.parse.outputs.anonymize }}' === 'true'
+ ? 'were anonymized'
+ : 'were **not** anonymized (user opted out)'
+ } before LLM processing.</sub>`;
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: analysis + footer
+ });
+
+ - name: Post error comment
+ if: steps.parse.outputs.found == 'true' && failure()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: `## Analysis Failed
+
+ The automated analysis encountered an error. This could be due to:
+ - Unsupported trace file format
+ - Trace file too large to process
+ - LLM API rate limiting or downtime
+
+ A maintainer will review your trace manually.
+
+ <details>
+ <summary>Debug info</summary>
+
+ Workflow run: https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}
+ </details>`
+ });
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v3] Bluetooth: btmtk: add event filter to filter specific event
From: kernel test robot @ 2026-04-15 18:20 UTC (permalink / raw)
To: Chris Lu, Marcel Holtmann, Johan Hedberg, Luiz Von Dentz
Cc: oe-kbuild-all, Sean Wang, Will Lee, SS Wu, Steve Lee,
linux-bluetooth, linux-kernel, linux-mediatek, Chris Lu
In-Reply-To: <20260412090242.1129701-1-chris.lu@mediatek.com>
Hi Chris,
kernel test robot noticed the following build errors:
[auto build test ERROR on bluetooth/master]
[also build test ERROR on bluetooth-next/master linus/master v7.0 next-20260414]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Chris-Lu/Bluetooth-btmtk-add-event-filter-to-filter-specific-event/20260415-122458
base: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master
patch link: https://lore.kernel.org/r/20260412090242.1129701-1-chris.lu%40mediatek.com
patch subject: [PATCH v3] Bluetooth: btmtk: add event filter to filter specific event
config: x86_64-randconfig-161-20260415 (https://download.01.org/0day-ci/archive/20260416/202604160237.pgNaPPAX-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
smatch: v0.5.0-9007-gcf3ea02b
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260416/202604160237.pgNaPPAX-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604160237.pgNaPPAX-lkp@intel.com/
All errors (new ones prefixed by >>):
ld: drivers/bluetooth/btusb.o: in function `btusb_probe':
>> drivers/bluetooth/btusb.c:4142:(.text+0x6c1a): undefined reference to `btmtk_recv_event'
vim +4142 drivers/bluetooth/btusb.c
4023
4024 static int btusb_probe(struct usb_interface *intf,
4025 const struct usb_device_id *id)
4026 {
4027 struct usb_endpoint_descriptor *ep_desc;
4028 struct gpio_desc *reset_gpio;
4029 struct btusb_data *data;
4030 struct hci_dev *hdev;
4031 unsigned ifnum_base;
4032 int i, err, priv_size;
4033
4034 BT_DBG("intf %p id %p", intf, id);
4035
4036 if ((id->driver_info & BTUSB_IFNUM_2) &&
4037 (intf->cur_altsetting->desc.bInterfaceNumber != 0) &&
4038 (intf->cur_altsetting->desc.bInterfaceNumber != 2))
4039 return -ENODEV;
4040
4041 ifnum_base = intf->cur_altsetting->desc.bInterfaceNumber;
4042
4043 if (!id->driver_info) {
4044 const struct usb_device_id *match;
4045
4046 match = usb_match_id(intf, quirks_table);
4047 if (match)
4048 id = match;
4049 }
4050
4051 if (id->driver_info == BTUSB_IGNORE)
4052 return -ENODEV;
4053
4054 if (id->driver_info & BTUSB_ATH3012) {
4055 struct usb_device *udev = interface_to_usbdev(intf);
4056
4057 /* Old firmware would otherwise let ath3k driver load
4058 * patch and sysconfig files
4059 */
4060 if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001 &&
4061 !btusb_qca_need_patch(udev))
4062 return -ENODEV;
4063 }
4064
4065 data = kzalloc_obj(*data);
4066 if (!data)
4067 return -ENOMEM;
4068
4069 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
4070 ep_desc = &intf->cur_altsetting->endpoint[i].desc;
4071
4072 if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
4073 data->intr_ep = ep_desc;
4074 continue;
4075 }
4076
4077 if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
4078 data->bulk_tx_ep = ep_desc;
4079 continue;
4080 }
4081
4082 if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
4083 data->bulk_rx_ep = ep_desc;
4084 continue;
4085 }
4086 }
4087
4088 if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
4089 kfree(data);
4090 return -ENODEV;
4091 }
4092
4093 if (id->driver_info & BTUSB_AMP) {
4094 data->cmdreq_type = USB_TYPE_CLASS | 0x01;
4095 data->cmdreq = 0x2b;
4096 } else {
4097 data->cmdreq_type = USB_TYPE_CLASS;
4098 data->cmdreq = 0x00;
4099 }
4100
4101 data->udev = interface_to_usbdev(intf);
4102 data->intf = intf;
4103
4104 INIT_WORK(&data->work, btusb_work);
4105 INIT_WORK(&data->waker, btusb_waker);
4106 INIT_DELAYED_WORK(&data->rx_work, btusb_rx_work);
4107
4108 skb_queue_head_init(&data->acl_q);
4109
4110 init_usb_anchor(&data->deferred);
4111 init_usb_anchor(&data->tx_anchor);
4112 spin_lock_init(&data->txlock);
4113
4114 init_usb_anchor(&data->intr_anchor);
4115 init_usb_anchor(&data->bulk_anchor);
4116 init_usb_anchor(&data->isoc_anchor);
4117 init_usb_anchor(&data->diag_anchor);
4118 init_usb_anchor(&data->ctrl_anchor);
4119 spin_lock_init(&data->rxlock);
4120
4121 priv_size = 0;
4122
4123 data->recv_event = hci_recv_frame;
4124 data->recv_bulk = btusb_recv_bulk;
4125
4126 if (id->driver_info & BTUSB_INTEL_COMBINED) {
4127 /* Allocate extra space for Intel device */
4128 priv_size += sizeof(struct btintel_data);
4129
4130 /* Override the rx handlers */
4131 data->recv_event = btintel_recv_event;
4132 data->recv_bulk = btusb_recv_bulk_intel;
4133 } else if (id->driver_info & BTUSB_REALTEK) {
4134 /* Allocate extra space for Realtek device */
4135 priv_size += sizeof(struct btrealtek_data);
4136
4137 data->recv_event = btusb_recv_event_realtek;
4138 } else if (id->driver_info & BTUSB_MEDIATEK) {
4139 /* Allocate extra space for Mediatek device */
4140 priv_size += sizeof(struct btmtk_data);
4141
> 4142 data->recv_event = btmtk_recv_event;
4143 }
4144
4145 data->recv_acl = hci_recv_frame;
4146
4147 hdev = hci_alloc_dev_priv(priv_size);
4148 if (!hdev) {
4149 kfree(data);
4150 return -ENOMEM;
4151 }
4152
4153 hdev->bus = HCI_USB;
4154 hci_set_drvdata(hdev, data);
4155
4156 data->hdev = hdev;
4157
4158 SET_HCIDEV_DEV(hdev, &intf->dev);
4159
4160 reset_gpio = gpiod_get_optional(&data->udev->dev, "reset",
4161 GPIOD_OUT_LOW);
4162 if (IS_ERR(reset_gpio)) {
4163 err = PTR_ERR(reset_gpio);
4164 goto out_free_dev;
4165 } else if (reset_gpio) {
4166 data->reset_gpio = reset_gpio;
4167 }
4168
4169 hdev->open = btusb_open;
4170 hdev->close = btusb_close;
4171 hdev->flush = btusb_flush;
4172 hdev->send = btusb_send_frame;
4173 hdev->notify = btusb_notify;
4174 hdev->wakeup = btusb_wakeup;
4175 hdev->hci_drv = &btusb_hci_drv;
4176
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* RE: Add initial Channel Sounding support -
From: bluez.test.bot @ 2026-04-15 18:10 UTC (permalink / raw)
To: linux-bluetooth, naga.akella
In-Reply-To: <20260415163805.564395-2-naga.akella@oss.qualcomm.com>
[-- Attachment #1: Type: text/plain, Size: 55529 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1081668
---Test result---
Test Summary:
CheckPatch PASS 2.45 seconds
GitLint PASS 0.95 seconds
BuildEll PASS 23.02 seconds
BluezMake FAIL 656.21 seconds
MakeCheck FAIL 22.08 seconds
MakeDistcheck PASS 252.93 seconds
CheckValgrind FAIL 214.22 seconds
CheckSmatch FAIL 350.94 seconds
bluezmakeextell FAIL 184.23 seconds
IncrementalBuild FAIL 681.76 seconds
ScanBuild FAIL 505.82 seconds
Details
##############################
Test: BluezMake - FAIL
Desc: Build BlueZ
Output:
tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12984:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12984 | int main(int argc, char *argv[])
| ^~~~
unit/test-avdtp.c: In function ‘main’:
unit/test-avdtp.c:766:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
766 | int main(int argc, char *argv[])
| ^~~~
unit/test-avrcp.c: In function ‘main’:
unit/test-avrcp.c:989:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
989 | int main(int argc, char *argv[])
| ^~~~
profiles/ranging/rap_hci.c:286:13: error: ‘cs_is_procedure_active’ defined but not used [-Werror=unused-function]
286 | static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
##############################
Test: MakeCheck - FAIL
Desc: Run Bluez Make Check
Output:
profiles/ranging/rap_hci.c:286:13: error: ‘cs_is_procedure_active’ defined but not used [-Werror=unused-function]
286 | static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make: *** [Makefile:10790: check] Error 2
##############################
Test: CheckValgrind - FAIL
Desc: Run Bluez Make Check with Valgrind
Output:
tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12984:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12984 | int main(int argc, char *argv[])
| ^~~~
profiles/ranging/rap_hci.c:286:13: error: ‘cs_is_procedure_active’ defined but not used [-Werror=unused-function]
286 | static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:10790: check] Error 2
##############################
Test: CheckSmatch - FAIL
Desc: Run smatch tool with source
Output:
src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:846:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1339:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1370:23: warning: Variable length array is used.
src/shared/gatt-server.c:279:25: warning: Variable length array is used.
src/shared/gatt-server.c:622:25: warning: Variable length array is used.
src/shared/gatt-server.c:720:25: warning: Variable length array is used.
src/shared/bap.c:312:25: warning: array of flexible structures
src/shared/bap.c: note: in included file:
./src/shared/ascs.h:88:25: warning: array of flexible structures
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:846:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1339:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1370:23: warning: Variable length array is used.
src/shared/gatt-server.c:279:25: warning: Variable length array is used.
src/shared/gatt-server.c:622:25: warning: Variable length array is used.
src/shared/gatt-server.c:720:25: warning: Variable length array is used.
src/shared/bap.c:312:25: warning: array of flexible structures
src/shared/bap.c: note: in included file:
./src/shared/ascs.h:88:25: warning: array of flexible structures
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
tools/mesh-cfgtest.c:1453:17: warning: unknown escape sequence: '\%'
tools/sco-tester.c: note: in included file:
./lib/bluetooth/bluetooth.h:232:15: warning: array of flexible structures
./lib/bluetooth/bluetooth.h:237:31: warning: array of flexible structures
tools/bneptest.c:634:39: warning: unknown escape sequence: '\%'
tools/seq2bseq.c:57:26: warning: Variable length array is used.
tools/obex-client-tool.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
client/btpclient/gatt.c: note: in included file:
./src/shared/btp.h:309:42: warning: array of flexible structures
src/advertising.c: note: in included file:
./src/shared/mgmt.h:95:25: error: redefinition of unsigned int enum mgmt_io_capability
src/adv_monitor.c: note: in included file:
./src/shared/mgmt.h:95:25: error: redefinition of unsigned int enum mgmt_io_capability
unit/avctp.c:505:34: warning: Variable length array is used.
unit/avctp.c:556:34: warning: Variable length array is used.
unit/test-avrcp.c:373:26: warning: Variable length array is used.
unit/test-avrcp.c:398:26: warning: Variable length array is used.
unit/test-avrcp.c:414:24: warning: Variable length array is used.
unit/avrcp-lib.c:1085:34: warning: Variable length array is used.
unit/avrcp-lib.c:1583:34: warning: Variable length array is used.
unit/avrcp-lib.c:1612:34: warning: Variable length array is used.
unit/avrcp-lib.c:1638:34: warning: Variable length array is used.
src/advertising.c: note: in included file:
./src/shared/mgmt.h:95:25: error: redefinition of unsigned int enum mgmt_io_capability
src/adv_monitor.c: note: in included file:
./src/shared/mgmt.h:95:25: error: redefinition of unsigned int enum mgmt_io_capability
mesh/mesh-io-mgmt.c:525:67: warning: Variable length array is used.
client/display.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:846:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1339:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1370:23: warning: Variable length array is used.
src/shared/gatt-server.c:279:25: warning: Variable length array is used.
src/shared/gatt-server.c:622:25: warning: Variable length array is used.
src/shared/gatt-server.c:720:25: warning: Variable length array is used.
src/shared/bap.c:312:25: warning: array of flexible structures
src/shared/bap.c: note: in included file:
./src/shared/ascs.h:88:25: warning: array of flexible structures
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
monitor/packet.c:2000:26: warning: Variable length array is used.
monitor/packet.c: note: in included file:
monitor/bt.h:3866:52: warning: array of flexible structures
monitor/bt.h:3854:40: warning: array of flexible structures
monitor/msft.c: note: in included file:
monitor/msft.h:88:44: warning: array of flexible structures
tools/rctest.c:631:33: warning: non-ANSI function declaration of function 'automated_send_recv'
tools/hex2hcd.c:136:26: warning: Variable length array is used.
tools/meshctl.c:324:33: warning: non-ANSI function declaration of function 'forget_mesh_devices'
tools/mesh-gatt/node.c:456:39: warning: non-ANSI function declaration of function 'node_get_local_node'
tools/mesh-gatt/net.c:1239:30: warning: non-ANSI function declaration of function 'get_next_seq'
tools/mesh-gatt/net.c:2193:29: warning: non-ANSI function declaration of function 'net_get_default_ttl'
tools/mesh-gatt/net.c:2207:26: warning: non-ANSI function declaration of function 'net_get_seq_num'
tools/mesh-gatt/prov.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
tools/mesh-gatt/onoff-model.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
ell/log.c:431:65: warning: non-ANSI function declaration of function 'register_debug_section'
ell/log.c:439:68: warning: non-ANSI function declaration of function 'free_debug_sections'
ell/random.c:60:42: warning: non-ANSI function declaration of function 'l_getrandom_is_supported'
ell/cipher.c:660:28: warning: non-ANSI function declaration of function 'init_supported'
ell/checksum.c:382:28: warning: non-ANSI function declaration of function 'init_supported'
ell/checksum.c:444:47: warning: non-ANSI function declaration of function 'l_checksum_cmac_aes_supported'
ell/cipher.c:519:24: warning: Variable length array is used.
ell/cert-crypto.c:36:33: warning: Variable length array is used.
ell/cert-crypto.c:142:36: warning: Variable length array is used.
ell/cert-crypto.c:198:36: warning: Variable length array is used.
ell/cert-crypto.c:251:31: warning: Variable length array is used.
ell/key.c:550:25: warning: Variable length array is used.
ell/dbus-service.c:548:49: warning: non-ANSI function declaration of function '_dbus_object_tree_new'
ell/dbus-filter.c:233:46: warning: Variable length array is used.
ell/tls.c:45:25: warning: Variable length array is used.
ell/tls.c:86:22: warning: Variable length array is used.
ell/tls.c:86:46: warning: Variable length array is used.
ell/tls.c:1819:26: warning: Variable length array is used.
ell/tls-suites.c:1079:25: warning: Variable length array is used.
ell/tls-suites.c:1081:34: warning: Variable length array is used.
ell/tls-suites.c:1084:41: warning: Variable length array is used.
ell/tls-suites.c:1133:41: warning: Variable length array is used.
emulator/btdev.c:468:29: warning: Variable length array is used.
emulator/bthost.c:703:28: warning: Variable length array is used.
emulator/bthost.c:704:32: warning: Variable length array is used.
emulator/bthost.c:944:28: warning: Variable length array is used.
emulator/bthost.c:978:28: warning: Variable length array is used.
emulator/bthost.c:979:32: warning: Variable length array is used.
attrib/gatttool.c:236:23: warning: Variable length array is used.
attrib/interactive.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
attrib/interactive.c:175:27: warning: non-ANSI function declaration of function 'disconnect_io'
attrib/interactive.c:300:23: warning: Variable length array is used.
profiles/ranging/rap_hci.c:286:13: error: ‘cs_is_procedure_active’ defined but not used [-Werror=unused-function]
286 | static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
##############################
Test: bluezmakeextell - FAIL
Desc: Build Bluez with External ELL
Output:
profiles/ranging/rap_hci.c:286:13: error: ‘cs_is_procedure_active’ defined but not used [-Werror=unused-function]
286 | static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
##############################
Test: IncrementalBuild - FAIL
Desc: Incremental build with the patches in the series
Output:
profiles/ranging/rap_hci.c:286:13: error: ‘cs_is_procedure_active’ defined but not used [-Werror=unused-function]
286 | static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
[BlueZ,v8,3/3] profiles: ranging: Add HCI LE Event Handling in Reflector role
profiles/ranging/rap_hci.c:286:13: error: ‘cs_is_procedure_active’ defined but not used [-Werror=unused-function]
286 | static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
##############################
Test: ScanBuild - FAIL
Desc: Run Scan Build
Output:
src/shared/gatt-client.c:455:21: warning: Use of memory after it is freed
gatt_db_unregister(op->client->db, op->db_id);
^~~~~~~~~~
src/shared/gatt-client.c:700:2: warning: Use of memory after it is freed
discovery_op_complete(op, false, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1000:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1106:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1300:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1365:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1640:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1645:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1701:56: warning: Use of memory after it is freed
notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2154:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2162:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3340:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3362:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
13 warnings generated.
src/shared/bap.c:1529:8: warning: Use of memory after it is freed
bap = bt_bap_ref_safe(bap);
^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2340:20: warning: Use of memory after it is freed
return queue_find(stream->bap->streams, NULL, stream);
^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/shared/gatt-client.c:455:21: warning: Use of memory after it is freed
gatt_db_unregister(op->client->db, op->db_id);
^~~~~~~~~~
src/shared/gatt-client.c:700:2: warning: Use of memory after it is freed
discovery_op_complete(op, false, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1000:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1106:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1300:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1365:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1640:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1645:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1701:56: warning: Use of memory after it is freed
notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2154:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2162:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3340:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3362:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
13 warnings generated.
tools/hciattach.c:817:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 10)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:865:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:887:8: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 10)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:909:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:930:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:974:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 6)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 warnings generated.
src/shared/bap.c:1529:8: warning: Use of memory after it is freed
bap = bt_bap_ref_safe(bap);
^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2340:20: warning: Use of memory after it is freed
return queue_find(stream->bap->streams, NULL, stream);
^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/oui.c:50:2: warning: Value stored to 'hwdb' is never read
hwdb = udev_hwdb_unref(hwdb);
^ ~~~~~~~~~~~~~~~~~~~~~
src/oui.c:53:2: warning: Value stored to 'udev' is never read
udev = udev_unref(udev);
^ ~~~~~~~~~~~~~~~~
2 warnings generated.
tools/rfcomm.c:234:3: warning: Value stored to 'i' is never read
i = execvp(cmdargv[0], cmdargv);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:234:7: warning: Null pointer passed to 1st parameter expecting 'nonnull'
i = execvp(cmdargv[0], cmdargv);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:354:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd'
if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:497:14: warning: Assigned value is garbage or undefined
req.channel = raddr.rc_channel;
^ ~~~~~~~~~~~~~~~~
tools/rfcomm.c:515:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd'
if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
tools/ciptool.c:351:7: warning: 5th function call argument is an uninitialized value
sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/sdp-xml.c:126:10: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:306:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:344:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
3 warnings generated.
tools/sdptool.c:941:26: warning: Result of 'malloc' is converted to a pointer of type 'uint32_t', which is incompatible with sizeof operand type 'int'
uint32_t *value_int = malloc(sizeof(int));
~~~~~~~~~~ ^~~~~~ ~~~~~~~~~~~
tools/sdptool.c:980:4: warning: 1st function call argument is an uninitialized value
free(allocArray[i]);
^~~~~~~~~~~~~~~~~~~
tools/sdptool.c:3777:2: warning: Potential leak of memory pointed to by 'si.name'
return add_service(0, &si);
^~~~~~~~~~~~~~~~~~~~~~~~~~
tools/sdptool.c:4112:4: warning: Potential leak of memory pointed to by 'context.svc'
return -1;
^~~~~~~~~
4 warnings generated.
tools/avtest.c:243:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:253:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:262:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:276:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:283:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:290:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:297:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:309:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:313:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:322:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:326:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:335:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:342:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:364:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:368:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:377:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:381:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:394:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:398:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:405:4: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:415:4: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:580:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:588:3: warning: Value stored to 'len' is never read
len = write(sk, buf, invalid ? 2 : 3);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/avtest.c:602:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 4 + media_transport_size);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/avtest.c:615:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:625:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:637:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:652:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:664:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:673:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:680:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:716:2: warning: Value stored to 'len' is never read
len = write(sk, buf, AVCTP_HEADER_LENGTH + sizeof(play_pressed));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 warnings generated.
tools/btproxy.c:836:15: warning: Null pointer passed to 1st parameter expecting 'nonnull'
tcp_port = atoi(optarg);
^~~~~~~~~~~~
tools/btproxy.c:839:8: warning: Null pointer passed to 1st parameter expecting 'nonnull'
if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
^~~~~~~~~~~~~~
2 warnings generated.
tools/create-image.c:76:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:84:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:92:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:105:2: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
4 warnings generated.
tools/btgatt-client.c:1822:2: warning: Value stored to 'argv' is never read
argv += optind;
^ ~~~~~~
1 warning generated.
tools/check-selftest.c:42:3: warning: Value stored to 'ptr' is never read
ptr = fgets(result, sizeof(result), fp);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/btgatt-server.c:1208:2: warning: Value stored to 'argv' is never read
argv -= optind;
^ ~~~~~~
1 warning generated.
tools/gatt-service.c:294:2: warning: 2nd function call argument is an uninitialized value
chr_write(chr, value, len);
^~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/obex-server-tool.c:133:13: warning: Null pointer passed to 1st parameter expecting 'nonnull'
data->fd = open(name, O_WRONLY | O_CREAT | O_NOCTTY, 0600);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/obex-server-tool.c:192:13: warning: Null pointer passed to 1st parameter expecting 'nonnull'
data->fd = open(name, O_RDONLY | O_NOCTTY, 0);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
client/btpclient/btpclientctl.c:402:3: warning: Value stored to 'bit' is never read
bit = 0;
^ ~
client/btpclient/btpclientctl.c:1655:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
memcpy(cp->data, ad_data, ad_len);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/sdp-client.c:353:14: warning: Access to field 'cb' results in a dereference of a null pointer
(*ctxt)->cb = cb;
~~~~~~~~~~~~^~~~
1 warning generated.
src/sdpd-request.c:209:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint16_t'
pElem = malloc(sizeof(uint16_t));
^~~~~~ ~~~~~~~~~~~~~~~~
src/sdpd-request.c:237:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint32_t'
pElem = malloc(sizeof(uint32_t));
^~~~~~ ~~~~~~~~~~~~~~~~
2 warnings generated.
src/gatt-database.c:1175:10: warning: Value stored to 'bits' during its initialization is never read
uint8_t bits[] = { BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING,
^~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/gatt-client.c:1569:2: warning: Use of memory after it is freed
notify_client_unref(client);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
unit/avrcp-lib.c:1968:3: warning: 1st function call argument is an uninitialized value
g_free(text[i]);
^~~~~~~~~~~~~~~
1 warning generated.
unit/avdtp.c:756:25: warning: Use of memory after it is freed
session->prio_queue = g_slist_remove(session->prio_queue, req);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unit/avdtp.c:763:24: warning: Use of memory after it is freed
session->req_queue = g_slist_remove(session->req_queue, req);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
profiles/audio/avdtp.c:895:25: warning: Use of memory after it is freed
session->prio_queue = g_slist_remove(session->prio_queue, req);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/audio/avdtp.c:902:24: warning: Use of memory after it is freed
session->req_queue = g_slist_remove(session->req_queue, req);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
profiles/audio/a2dp.c:442:8: warning: Use of memory after it is freed
if (!cb->resume_cb)
^~~~~~~~~~~~~
profiles/audio/a2dp.c:3354:20: warning: Access to field 'starting' results in a dereference of a null pointer (loaded from variable 'stream')
stream->starting = TRUE;
~~~~~~ ^
profiles/audio/a2dp.c:3357:8: warning: Access to field 'suspending' results in a dereference of a null pointer (loaded from variable 'stream')
if (!stream->suspending && stream->suspend_timer) {
^~~~~~~~~~~~~~~~~~
profiles/audio/a2dp.c:3417:22: warning: Access to field 'suspending' results in a dereference of a null pointer (loaded from variable 'stream')
stream->suspending = TRUE;
~~~~~~ ^
4 warnings generated.
profiles/audio/avrcp.c:1968:2: warning: Value stored to 'operands' is never read
operands += sizeof(*pdu);
^ ~~~~~~~~~~~~
1 warning generated.
attrib/gatt.c:970:2: warning: Potential leak of memory pointed to by 'long_write'
return prepare_write(long_write);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/sdpd-request.c:209:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint16_t'
pElem = malloc(sizeof(uint16_t));
^~~~~~ ~~~~~~~~~~~~~~~~
src/sdpd-request.c:237:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint32_t'
pElem = malloc(sizeof(uint32_t));
^~~~~~ ~~~~~~~~~~~~~~~~
2 warnings generated.
src/sdp-client.c:353:14: warning: Access to field 'cb' results in a dereference of a null pointer
(*ctxt)->cb = cb;
~~~~~~~~~~~~^~~~
1 warning generated.
src/gatt-database.c:1175:10: warning: Value stored to 'bits' during its initialization is never read
uint8_t bits[] = { BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING,
^~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/sdp-xml.c:126:10: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:306:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:344:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
3 warnings generated.
src/gatt-client.c:1569:2: warning: Use of memory after it is freed
notify_client_unref(client);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-header.c:95:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
memcpy(to, from, count);
^~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-transfer.c:423:7: warning: Use of memory after it is freed
if (!g_slist_find(transfers, transfer))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
mesh/main.c:162:3: warning: Value stored to 'optarg' is never read
optarg += strlen("auto");
^ ~~~~~~~~~~~~~~
1 warning generated.
lib/bluetooth/hci.c:97:4: warning: Value stored to 'ptr' is never read
ptr += sprintf(ptr, "%s", m->str);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
client/player.c:2363:8: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
if (!strcmp(ep->path, pattern))
^~~~~~~~~~~~~~~~~~~~~~~~~
client/player.c:3640:16: warning: Null pointer passed to 1st parameter expecting 'nonnull'
codec->name = strdup(name);
^~~~~~~~~~~~
2 warnings generated.
gdbus/watch.c:226:3: warning: Attempt to free released memory
g_free(l->data);
^~~~~~~~~~~~~~~
1 warning generated.
lib/bluetooth/sdp.c:509:17: warning: Dereference of undefined pointer value
uint8_t dtd = *(uint8_t *) dtds[i];
^~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:539:17: warning: Dereference of undefined pointer value
uint8_t dtd = *(uint8_t *) dtds[i];
^~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:1885:26: warning: Potential leak of memory pointed to by 'ap'
for (; pdlist; pdlist = pdlist->next) {
^~~~~~
lib/bluetooth/sdp.c:1899:6: warning: Potential leak of memory pointed to by 'pds'
ap = sdp_list_append(ap, pds);
~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:1944:10: warning: Potential leak of memory pointed to by 'u'
*seqp = sdp_list_append(*seqp, u);
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:2049:4: warning: Potential leak of memory pointed to by 'lang'
sdp_list_free(*langSeq, free);
^~~~~~~~~~~~~
lib/bluetooth/sdp.c:2138:9: warning: Potential leak of memory pointed to by 'profDesc'
return 0;
^
lib/bluetooth/sdp.c:3270:8: warning: Potential leak of memory pointed to by 'pSvcRec'
pSeq = sdp_list_append(pSeq, pSvcRec);
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:3271:9: warning: Potential leak of memory pointed to by 'pSeq'
pdata += sizeof(uint32_t);
~~~~~~^~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:4607:13: warning: Potential leak of memory pointed to by 'rec_list'
} while (scanned < attr_list_len && pdata_len > 0);
^~~~~~~
lib/bluetooth/sdp.c:4903:40: warning: Potential leak of memory pointed to by 'tseq'
for (d = sdpdata->val.dataseq; d; d = d->next) {
^
lib/bluetooth/sdp.c:4939:8: warning: Potential leak of memory pointed to by 'subseq'
tseq = sdp_list_append(tseq, subseq);
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12 warnings generated.
src/shared/gatt-client.c:455:21: warning: Use of memory after it is freed
gatt_db_unregister(op->client->db, op->db_id);
^~~~~~~~~~
src/shared/gatt-client.c:700:2: warning: Use of memory after it is freed
discovery_op_complete(op, false, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1000:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1106:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1300:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1365:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1640:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1645:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1701:56: warning: Use of memory after it is freed
notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2154:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2162:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3340:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3362:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
13 warnings generated.
src/shared/bap.c:1529:8: warning: Use of memory after it is freed
bap = bt_bap_ref_safe(bap);
^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2340:20: warning: Use of memory after it is freed
return queue_find(stream->bap->streams, NULL, stream);
^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
monitor/l2cap.c:1676:4: warning: Value stored to 'data' is never read
data += len;
^ ~~~
monitor/l2cap.c:1677:4: warning: Value stored to 'size' is never read
size -= len;
^ ~~~
2 warnings generated.
monitor/hwdb.c:59:2: warning: Value stored to 'hwdb' is never read
hwdb = udev_hwdb_unref(hwdb);
^ ~~~~~~~~~~~~~~~~~~~~~
monitor/hwdb.c:64:2: warning: Value stored to 'udev' is never read
udev = udev_unref(udev);
^ ~~~~~~~~~~~~~~~~
monitor/hwdb.c:106:2: warning: Value stored to 'hwdb' is never read
hwdb = udev_hwdb_unref(hwdb);
^ ~~~~~~~~~~~~~~~~~~~~~
monitor/hwdb.c:111:2: warning: Value stored to 'udev' is never read
udev = udev_unref(udev);
^ ~~~~~~~~~~~~~~~~
4 warnings generated.
tools/bluemoon.c:1102:8: warning: Null pointer passed to 1st parameter expecting 'nonnull'
if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
^~~~~~~~~~~~~~
1 warning generated.
tools/meshctl.c:326:19: warning: Access to field 'mesh_devices' results in a dereference of a null pointer (loaded from variable 'default_ctrl')
g_list_free_full(default_ctrl->mesh_devices, g_free);
^~~~~~~~~~~~~~~~~~~~~~~~~~
tools/meshctl.c:762:2: warning: 2nd function call argument is an uninitialized value
bt_shell_printf("Attempting to disconnect from %s\n", addr);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/meshctl.c:1957:2: warning: Value stored to 'len' is never read
len = len + extra + strlen("local_node.json");
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.
In file included from tools/mesh-gatt/crypto.c:32:
./src/shared/util.h:250:9: warning: 1st function call argument is an uninitialized value
return be32_to_cpu(get_unaligned((const uint32_t *) ptr));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:39:26: note: expanded from macro 'be32_to_cpu'
#define be32_to_cpu(val) bswap_32(val)
^~~~~~~~~~~~~
/usr/include/byteswap.h:34:21: note: expanded from macro 'bswap_32'
#define bswap_32(x) __bswap_32 (x)
^~~~~~~~~~~~~~
In file included from tools/mesh-gatt/crypto.c:32:
./src/shared/util.h:260:9: warning: 1st function call argument is an uninitialized value
return be64_to_cpu(get_unaligned((const uint64_t *) ptr));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:40:26: note: expanded from macro 'be64_to_cpu'
#define be64_to_cpu(val) bswap_64(val)
^~~~~~~~~~~~~
/usr/include/byteswap.h:37:21: note: expanded from macro 'bswap_64'
#define bswap_64(x) __bswap_64 (x)
^~~~~~~~~~~~~~
2 warnings generated.
ell/util.c:853:8: warning: The left operand of '>' is a garbage value
if (x > UINT8_MAX)
~ ^
ell/util.c:871:8: warning: The left operand of '>' is a garbage value
if (x > UINT16_MAX)
~ ^
2 warnings generated.
ell/pem.c:131:8: warning: Dereference of null pointer (loaded from variable 'eol')
if (*eol == '\r' || *eol == '\n')
^~~~
ell/pem.c:166:18: warning: Dereference of null pointer (loaded from variable 'eol')
if (buf_len && *eol == '\r' && *buf_ptr == '\n') {
^~~~
ell/pem.c:166:34: warning: Dereference of null pointer (loaded from variable 'buf_ptr')
if (buf_len && *eol == '\r' && *buf_ptr == '\n') {
^~~~~~~~
ell/pem.c:304:11: warning: 1st function call argument is an uninitialized value
result = pem_load_buffer(file.data, file.st.st_size,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ell/pem.c:469:9: warning: 1st function call argument is an uninitialized value
list = l_pem_load_certificate_list_from_data(file.data,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
ell/cert.c:645:41: warning: Access to field 'asn1_len' results in a dereference of a null pointer (loaded from variable 'cert')
key = l_key_new(L_KEY_RSA, cert->asn1, cert->asn1_len);
^~~~~~~~~~~~~~
1 warning generated.
ell/gvariant-util.c:143:18: warning: The left operand of '>' is a garbage value
if (alignment > max_alignment)
~~~~~~~~~ ^
ell/gvariant-util.c:456:5: warning: Dereference of null pointer
!children[0].fixed_size) {
^~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
emulator/serial.c:150:2: warning: Assigned value is garbage or undefined
enum btdev_type uninitialized_var(type);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/serial.c:150:36: warning: Value stored to 'type' during its initialization is never read
enum btdev_type uninitialized_var(type);
^~~~
emulator/serial.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
^ ~
emulator/serial.c:213:2: warning: Assigned value is garbage or undefined
enum btdev_type uninitialized_var(dev_type);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/serial.c:213:36: warning: Value stored to 'dev_type' during its initialization is never read
enum btdev_type uninitialized_var(dev_type);
^~~~~~~~
emulator/serial.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
^ ~
4 warnings generated.
ell/ecc-external.c:77:11: warning: Assigned value is garbage or undefined
dest[i] = src[i];
^ ~~~~~~
ell/ecc-external.c:160:18: warning: The right operand of '-' is a garbage value
diff = left[i] - right[i] - borrow;
^ ~~~~~~~~
ell/ecc-external.c:227:14: warning: 2nd function call argument is an uninitialized value
product = mul_64_64(left[i], right[k - i]);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ell/ecc-external.c:408:9: warning: Assigned value is garbage or undefined
tmp[1] = product[3];
^ ~~~~~~~~~~
ell/ecc-external.c:435:22: warning: The left operand of '&' is a garbage value
tmp[1] = product[3] & 0xffffffff00000000ull;
~~~~~~~~~~ ^
ell/ecc-external.c:483:22: warning: The left operand of '&' is a garbage value
tmp[1] = product[5] & 0xffffffff00000000ull;
~~~~~~~~~~ ^
ell/ecc-external.c:688:28: warning: The left operand of '>>' is a garbage value
tmp[i] = (product[8 + i] >> 9) | (product[9 + i] << 55);
~~~~~~~~~~~~~~ ^
7 warnings generated.
emulator/server.c:209:2: warning: Assigned value is garbage or undefined
enum btdev_type uninitialized_var(type);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/server.c:209:36: warning: Value stored to 'type' during its initialization is never read
enum btdev_type uninitialized_var(type);
^~~~
emulator/server.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
^ ~
2 warnings generated.
emulator/b1ee.c:258:3: warning: Potential leak of memory pointed to by 'server_port'
int opt;
^~~~~~~
emulator/b1ee.c:258:3: warning: Potential leak of memory pointed to by 'sniffer_port'
int opt;
^~~~~~~
emulator/b1ee.c:289:2: warning: Value stored to 'argc' is never read
argc = argc - optind;
^ ~~~~~~~~~~~~~
3 warnings generated.
gobex/gobex-header.c:95:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
memcpy(to, from, count);
^~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-transfer.c:423:7: warning: Use of memory after it is freed
if (!g_slist_find(transfers, transfer))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
attrib/gatt.c:970:2: warning: Potential leak of memory pointed to by 'long_write'
return prepare_write(long_write);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
emulator/btdev.c:6618:20: warning: Access to field 'link' results in a dereference of a null pointer (loaded from variable 'acl')
le_past_received(acl->link, pa);
^~~~~~~~~
emulator/btdev.c:6718:25: warning: Access to field 'link' results in a dereference of a null pointer (loaded from variable 'acl')
le_past_info_received(acl->link, ea);
^~~~~~~~~
2 warnings generated.
profiles/ranging/rap_hci.c:286:13: error: ‘cs_is_procedure_active’ defined but not used [-Werror=unused-function]
286 | static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
profiles/audio/media.c:1112:7: warning: Use of memory after it is freed
if (req->cb != pac_select_cb) {
^~~~~~~
1 warning generated.
make: *** [Makefile:4159: all] Error 2
https://github.com/bluez/bluez/pull/2041
---
Regards,
Linux Bluetooth
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-04-15 17:21 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1081547
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez] 89b207: shared: rap: Introduce Channel Sounding HCI raw in...
From: Bhavani @ 2026-04-15 17:21 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1081668
Home: https://github.com/bluez/bluez
Commit: 89b207a44dce45103bac2afec5856c666a6a6c70
https://github.com/bluez/bluez/commit/89b207a44dce45103bac2afec5856c666a6a6c70
Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
Date: 2026-04-15 (Wed, 15 Apr 2026)
Changed paths:
M src/shared/hci.c
M src/shared/hci.h
M src/shared/rap.c
M src/shared/rap.h
Log Message:
-----------
shared: rap: Introduce Channel Sounding HCI raw interface support
Implement stub callbacks for Channel Sounding HCI events and add the
required protocol definitions for CS configuration, procedure control,
and subevent result parsing
Add data structures to support Channel Sounding Processing
Add helper function to get hci conn info list and integrate it with RAP
Commit: ed4e66783914101e4e01e834d9d42c2f6381f3a6
https://github.com/bluez/bluez/commit/ed4e66783914101e4e01e834d9d42c2f6381f3a6
Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
Date: 2026-04-15 (Wed, 15 Apr 2026)
Changed paths:
M src/bluetooth.service.in
M src/btd.h
M src/main.c
M src/main.conf
Log Message:
-----------
main.conf: Add Channel Sounding config parsing support
Add support for parsing Channel Sounding (CS) configuration options
from the configuration file.
Add CAP_NET_RAW to CapabilityBoundingSet in bluetooth.service.
bluetoothd requires CAP_NET_RAW to receive and process HCI LE events
when running under a constrained systemd capability bounding set
Commit: fc2f649917f61268431f05bb0b6fd9749cf41eb2
https://github.com/bluez/bluez/commit/fc2f649917f61268431f05bb0b6fd9749cf41eb2
Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
Date: 2026-04-15 (Wed, 15 Apr 2026)
Changed paths:
M Makefile.plugins
M profiles/ranging/rap.c
A profiles/ranging/rap_hci.c
Log Message:
-----------
profiles: ranging: Add HCI LE Event Handling in Reflector role
Open RAW HCI Channel for CS Event Handling
Parse the following HCI LE CS Events in reflector role
and route the events to RAP Profile.
1. HCI_EVT_LE_CS_READ_RMT_SUPP_CAP_COMPLETE
2. HCI_EVT_LE_CS_CONFIG_COMPLETE
3. HCI_EVT_LE_CS_SECURITY_ENABLE_COMPLETE
4. HCI_EVT_LE_CS_PROCEDURE_ENABLE_COMPLETE
5. HCI_EVT_LE_CS_SUBEVENT_RESULT
6. HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE
Send HCI_OP_LE_CS_SET_DEFAULT_SETTINGS to the controller
with default settings selected by the user.
Map connection handle received to device connection
Compare: https://github.com/bluez/bluez/compare/89b207a44dce%5E...fc2f649917f6
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [PATCH BlueZ v8 3/3] profiles: ranging: Add HCI LE Event Handling in Reflector role
From: Naga Bhavani Akella @ 2026-04-15 16:38 UTC (permalink / raw)
To: linux-bluetooth
Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg,
prathibha.madugonde, Naga Bhavani Akella
In-Reply-To: <20260415163805.564395-1-naga.akella@oss.qualcomm.com>
Open RAW HCI Channel for CS Event Handling
Parse the following HCI LE CS Events in reflector role
and route the events to RAP Profile.
1. HCI_EVT_LE_CS_READ_RMT_SUPP_CAP_COMPLETE
2. HCI_EVT_LE_CS_CONFIG_COMPLETE
3. HCI_EVT_LE_CS_SECURITY_ENABLE_COMPLETE
4. HCI_EVT_LE_CS_PROCEDURE_ENABLE_COMPLETE
5. HCI_EVT_LE_CS_SUBEVENT_RESULT
6. HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE
Send HCI_OP_LE_CS_SET_DEFAULT_SETTINGS to the controller
with default settings selected by the user.
Map connection handle received to device connection
---
Makefile.plugins | 3 +-
profiles/ranging/rap.c | 52 ++
profiles/ranging/rap_hci.c | 1268 ++++++++++++++++++++++++++++++++++++
3 files changed, 1322 insertions(+), 1 deletion(-)
create mode 100644 profiles/ranging/rap_hci.c
diff --git a/Makefile.plugins b/Makefile.plugins
index c9efadb45..ac667beda 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -89,7 +89,8 @@ builtin_modules += battery
builtin_sources += profiles/battery/battery.c
builtin_modules += rap
-builtin_sources += profiles/ranging/rap.c
+builtin_sources += profiles/ranging/rap.c \
+ profiles/ranging/rap_hci.c
if SIXAXIS
builtin_modules += sixaxis
diff --git a/profiles/ranging/rap.c b/profiles/ranging/rap.c
index f03454c72..a473ed632 100644
--- a/profiles/ranging/rap.c
+++ b/profiles/ranging/rap.c
@@ -17,6 +17,7 @@
#include "gdbus/gdbus.h"
#include "bluetooth/bluetooth.h"
+#include "bluetooth/l2cap.h"
#include "bluetooth/uuid.h"
#include "src/plugin.h"
@@ -34,12 +35,14 @@
#include "src/shared/rap.h"
#include "attrib/att.h"
#include "src/log.h"
+#include "src/btd.h"
struct rap_data {
struct btd_device *device;
struct btd_service *service;
struct bt_rap *rap;
unsigned int ready_id;
+ struct bt_hci *hci;
};
static struct queue *sessions;
@@ -95,6 +98,14 @@ static void rap_data_free(struct rap_data *data)
}
bt_rap_ready_unregister(data->rap, data->ready_id);
+
+ if (data->hci) {
+ bt_rap_hci_sm_cleanup();
+ bt_hci_unref(data->hci);
+ }
+
+ /* Clean up HCI connection mappings */
+ bt_rap_detach_hci(data->rap);
bt_rap_unref(data->rap);
free(data);
}
@@ -173,6 +184,7 @@ static int rap_probe(struct btd_service *service)
struct btd_gatt_database *database = btd_adapter_get_database(adapter);
struct rap_data *data = btd_service_get_user_data(service);
char addr[18];
+ int16_t hci_index;
ba2str(device_get_address(device), addr);
DBG("%s", addr);
@@ -195,6 +207,19 @@ static int rap_probe(struct btd_service *service)
return -EINVAL;
}
+ hci_index = btd_adapter_get_index(adapter);
+
+ data->hci = bt_hci_new_raw_device(hci_index);
+ if (bt_rap_attach_hci(data->rap, data->hci)) {
+ DBG("HCI raw channel initialized, hci%d", hci_index);
+ bt_rap_hci_set_options(
+ btd_opts.defaults.bcs.role,
+ btd_opts.defaults.bcs.cs_sync_ant_sel,
+ btd_opts.defaults.bcs.max_tx_power);
+ } else {
+ error("HCI raw channel not available (may be in use)");
+ }
+
rap_data_add(data);
data->ready_id = bt_rap_ready_register(data->rap, rap_ready, service,
@@ -228,6 +253,10 @@ static int rap_accept(struct btd_service *service)
struct btd_device *device = btd_service_get_device(service);
struct bt_gatt_client *client = btd_device_get_gatt_client(device);
struct rap_data *data = btd_service_get_user_data(service);
+ struct bt_att *att;
+ const bdaddr_t *bdaddr;
+ uint8_t bdaddr_type;
+ uint16_t handle;
char addr[18];
ba2str(device_get_address(device), addr);
@@ -243,6 +272,29 @@ static int rap_accept(struct btd_service *service)
return -EINVAL;
}
+ /* Set up connection handle mapping for CS event routing */
+ att = bt_rap_get_att(data->rap);
+ bdaddr = device_get_address(device);
+ bdaddr_type = device_get_le_address_type(device);
+
+ if (att && data->hci) {
+ /* Use bt_hci_get_conn_handle to find the connection handle
+ * by bdaddr using HCIGETCONNLIST ioctl
+ */
+ if (bt_hci_get_conn_handle(data->hci,
+ (const uint8_t *)bdaddr, &handle)) {
+ DBG("Found conn handle 0x%04X for %s", handle, addr);
+ DBG("Setting up handle mapping: handle=0x%04X",
+ handle);
+ bt_rap_set_conn_handle(data->rap, handle,
+ (const uint8_t *)bdaddr,
+ bdaddr_type);
+ } else {
+ error("Failed to find connection handle for device %s",
+ addr);
+ }
+ }
+
btd_service_connecting_complete(service, 0);
return 0;
diff --git a/profiles/ranging/rap_hci.c b/profiles/ranging/rap_hci.c
new file mode 100644
index 000000000..71b2f088d
--- /dev/null
+++ b/profiles/ranging/rap_hci.c
@@ -0,0 +1,1268 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <string.h>
+#include <endian.h>
+
+#include "lib/bluetooth/bluetooth.h"
+#include "src/shared/util.h"
+#include "src/shared/queue.h"
+#include "src/shared/rap.h"
+#include "src/log.h"
+#include "monitor/bt.h"
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+/* Macro to sign-extend an N-bit value to 16-bit signed integer */
+#define SIGN_EXTEND_TO_16(val, bits) \
+ ((int16_t)((int32_t)((val) << (32 - (bits))) >> (32 - (bits))))
+
+/* CS State Definitions */
+enum cs_state_t {
+ CS_INIT,
+ CS_STOPPED,
+ CS_STARTED,
+ CS_WAIT_CONFIG_CMPLT,
+ CS_WAIT_SEC_CMPLT,
+ CS_WAIT_PROC_CMPLT,
+ CS_HOLD,
+ CS_UNSPECIFIED
+};
+
+const char *state_names[] = {
+ "CS_INIT",
+ "CS_STOPPED",
+ "CS_STARTED",
+ "CS_WAIT_CONFIG_CMPLT",
+ "CS_WAIT_SEC_CMPLT",
+ "CS_WAIT_PROC_CMPLT",
+ "CS_HOLD",
+ "CS_UNSPECIFIED"
+};
+
+/* Callback Function Type */
+typedef void (*cs_callback_t)(uint16_t length,
+ const void *param, void *user_data);
+
+/* State Machine Context */
+struct cs_state_machine_t {
+ enum cs_state_t current_state;
+ enum cs_state_t old_state;
+ struct bt_hci *hci;
+ struct bt_rap *rap;
+ unsigned int event_id;
+ bool initiator;
+ bool procedure_active;
+};
+
+struct cs_callback_map_t {
+ enum cs_state_t state;
+ cs_callback_t callback;
+};
+
+struct cs_callback_map_t cs_callback_map[] = {
+ { CS_WAIT_CONFIG_CMPLT, bt_rap_hci_cs_config_complete_callback },
+ { CS_WAIT_SEC_CMPLT, bt_rap_hci_cs_sec_enable_complete_callback },
+ { CS_WAIT_PROC_CMPLT, bt_rap_hci_cs_procedure_enable_complete_callback }
+};
+
+#define CS_CALLBACK_MAP_SIZE ARRAY_SIZE(cs_callback_map)
+
+struct bt_rap_hci_cs_options cs_opt;
+struct cs_state_machine_t *sm;
+
+/* Connection Handle Mapping */
+struct rap_conn_mapping {
+ uint16_t handle;
+ uint8_t bdaddr[6];
+ uint8_t bdaddr_type;
+ struct bt_att *att;
+ struct bt_rap *rap;
+};
+
+static struct queue *conn_mappings;
+
+/* Connection Mapping Helper Functions */
+static void mapping_free(void *data)
+{
+ struct rap_conn_mapping *mapping = data;
+
+ if (!mapping)
+ return;
+
+ free(mapping);
+}
+
+static bool match_mapping_handle(const void *a, const void *b)
+{
+ const struct rap_conn_mapping *mapping = a;
+ uint16_t handle = PTR_TO_UINT(b);
+
+ return mapping->handle == handle;
+}
+
+static bool match_mapping_rap(const void *a, const void *b)
+{
+ const struct rap_conn_mapping *mapping = a;
+ const struct bt_rap *rap = b;
+
+ return mapping->rap == rap;
+}
+
+static struct rap_conn_mapping *find_mapping_by_handle(uint16_t handle)
+{
+ if (!conn_mappings)
+ return NULL;
+
+ return queue_find(conn_mappings, match_mapping_handle,
+ UINT_TO_PTR(handle));
+}
+
+static bool add_conn_mapping(uint16_t handle, const uint8_t *bdaddr,
+ uint8_t bdaddr_type, struct bt_att *att,
+ struct bt_rap *rap)
+{
+ struct rap_conn_mapping *mapping;
+
+ if (!conn_mappings) {
+ conn_mappings = queue_new();
+ if (!conn_mappings)
+ return false;
+ }
+
+ /* Check if mapping already exists */
+ mapping = find_mapping_by_handle(handle);
+ if (mapping) {
+ /* Update existing mapping */
+ if (bdaddr)
+ memcpy(mapping->bdaddr, bdaddr, 6);
+ mapping->bdaddr_type = bdaddr_type;
+ mapping->att = att;
+ mapping->rap = rap;
+ return true;
+ }
+
+ /* Create new mapping */
+ mapping = new0(struct rap_conn_mapping, 1);
+ if (!mapping)
+ return false;
+
+ mapping->handle = handle;
+ if (bdaddr)
+ memcpy(mapping->bdaddr, bdaddr, 6);
+ mapping->bdaddr_type = bdaddr_type;
+ mapping->att = att;
+ mapping->rap = rap;
+
+ return queue_push_tail(conn_mappings, mapping);
+}
+
+static void remove_conn_mapping(uint16_t handle)
+{
+ struct rap_conn_mapping *mapping;
+
+ if (!conn_mappings)
+ return;
+
+ mapping = queue_remove_if(conn_mappings, match_mapping_handle,
+ UINT_TO_PTR(handle));
+ if (mapping)
+ mapping_free(mapping);
+}
+
+static void remove_rap_mappings(struct bt_rap *rap)
+{
+ if (!conn_mappings)
+ return;
+
+ queue_remove_all(conn_mappings, match_mapping_rap, rap,
+ mapping_free);
+}
+
+static struct bt_rap *resolve_handle_to_rap(uint16_t handle,
+ struct bt_hci *hci)
+{
+ struct rap_conn_mapping *mapping;
+
+ /* Try to find in mapping cache */
+ mapping = find_mapping_by_handle(handle);
+ if (mapping && mapping->rap) {
+ DBG("Found handle 0x%04X in mapping cache", handle);
+ return mapping->rap;
+ }
+
+ /* Profile layer should have called bt_rap_set_conn_handle() during
+ * connection establishment. If we reach here, the mapping was not set.
+ */
+ DBG("No mapping found for handle 0x%04X", handle);
+ DBG("Profile layer should call bt_rap_set_conn_handle() on connect");
+
+ return NULL;
+}
+
+/* State Machine Functions */
+static void cs_state_machine_init(struct cs_state_machine_t *sm,
+ struct bt_rap *rap, struct bt_hci *hci)
+{
+ if (!sm)
+ return;
+
+ memset(sm, 0, sizeof(struct cs_state_machine_t));
+ sm->current_state = CS_UNSPECIFIED;
+ sm->rap = rap;
+ sm->hci = hci;
+ sm->initiator = false;
+ sm->procedure_active = false;
+}
+
+void bt_rap_hci_sm_cleanup(void)
+{
+ if (!sm)
+ return;
+
+ if (sm->event_id)
+ bt_hci_unregister(sm->hci, sm->event_id);
+
+ sm->current_state = CS_UNSPECIFIED;
+ sm->rap = NULL;
+ sm->hci = NULL;
+ sm->procedure_active = false;
+
+ free(sm);
+}
+
+void bt_rap_hci_set_options(uint8_t role, uint8_t cs_sync_ant_sel,
+ int8_t max_tx_power)
+{
+ cs_opt.role = role;
+ cs_opt.cs_sync_ant_sel = cs_sync_ant_sel;
+ cs_opt.max_tx_power = max_tx_power;
+}
+
+/* State Transition Logic */
+static void cs_set_state(struct cs_state_machine_t *sm,
+ enum cs_state_t new_state)
+{
+ if (!sm)
+ return;
+
+ if (sm->current_state == new_state)
+ return;
+
+ /* Validate state values before array access */
+ if (sm->current_state > CS_UNSPECIFIED || new_state > CS_UNSPECIFIED) {
+ error("Invalid state transition attempted\n");
+ return;
+ }
+
+ DBG("[STATE] Transition: %s → %s\n",
+ state_names[sm->current_state],
+ state_names[new_state]);
+
+ sm->old_state = sm->current_state;
+ sm->current_state = new_state;
+}
+
+static enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
+{
+ return sm ? sm->current_state : CS_UNSPECIFIED;
+}
+
+static bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
+{
+ return sm ? sm->procedure_active : false;
+}
+
+/* HCI Event Callbacks */
+static void rap_def_settings_done_cb(const void *data, uint8_t size,
+ void *user_data)
+{
+ struct bt_hci_rsp_le_cs_set_def_settings *rp;
+ struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_rsp_le_cs_set_def_settings))
+ return;
+
+ DBG("size=0x%02X\n", size);
+
+ rp = (struct bt_hci_rsp_le_cs_set_def_settings *)data;
+
+ if (cs_get_current_state(sm) != CS_INIT) {
+ DBG("Event received in Wrong State!! Expected : CS_INIT");
+ return;
+ }
+
+ if (rp->status == 0) {
+ /* Success - proceed to configuration */
+ cs_set_state(sm, CS_WAIT_CONFIG_CMPLT);
+
+ /* Reflector role */
+ DBG("Waiting for CS Config Completed event...\n");
+ /* TODO: Initiator role - Send CS Config complete cmd */
+ } else {
+ /* Error - transition to stopped */
+ error("CS Set default setting failed with status 0x%02X\n",
+ rp->status);
+ cs_set_state(sm, CS_STOPPED);
+ }
+}
+
+static void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
+ struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete *ev)
+{
+ struct bt_hci_cmd_le_cs_set_def_settings cp;
+ unsigned int status;
+
+ memset(&cp, 0, sizeof(cp));
+
+ if (ev->handle)
+ cp.handle = ev->handle;
+ cp.role_enable = cs_opt.role;
+ cp.cs_sync_antenna_selection = cs_opt.cs_sync_ant_sel;
+ cp.max_tx_power = cs_opt.max_tx_power;
+
+ if (!sm || !sm->hci) {
+ error("Set Def Settings: sm or hci is null");
+ return;
+ }
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_SET_DEF_SETTINGS,
+ &cp, sizeof(cp), rap_def_settings_done_cb,
+ sm, NULL);
+
+ DBG("sending set default settings case, status : %d", status);
+ if (!status)
+ error("Failed to send default settings cmd");
+}
+
+static void rap_rd_rmt_supp_cap_cmplt_evt(const uint8_t *data, uint8_t size,
+ void *user_data)
+{
+ struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
+ const struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete *evt;
+ struct bt_rap *rap;
+ struct iovec iov;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete))
+ return;
+
+ /* Initialize iovec with the event data */
+ iov.iov_base = (void *)data;
+ iov.iov_len = size;
+
+ /* Pull the entire structure at once */
+ evt = util_iov_pull_mem(&iov, sizeof(*evt));
+ if (!evt) {
+ error("Failed to pull remote cap complete struct\n");
+ return;
+ }
+
+ DBG("status=0x%02X, handle=0x%04X\n", evt->status, evt->handle);
+
+ /* Check status */
+ if (evt->status != 0) {
+ error("Remote capabilities failed with status 0x%02X\n",
+ evt->status);
+ cs_set_state(sm, CS_STOPPED);
+ return;
+ }
+
+ /* Resolve handle to RAP instance */
+ rap = resolve_handle_to_rap(evt->handle, sm->hci);
+ if (!rap) {
+ DBG("[WARN] Could not resolve handle 0x%04X to RAP instance\n",
+ evt->handle);
+ /* Continue with state machine RAP for now */
+ rap = sm->rap;
+ }
+
+ DBG("num_config=%u, ",
+ evt->num_config_supported);
+ DBG("max_consecutive_proc=%u, num_antennas=%u, ",
+ evt->max_consecutive_procedures_supported,
+ evt->num_antennas_supported);
+ DBG("max_antenna_paths=%u, roles=0x%02X, modes=0x%02X\n",
+ evt->max_antenna_paths_supported,
+ evt->roles_supported,
+ evt->modes_supported);
+
+ rap_send_hci_def_settings_command(sm,
+ (struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete *)evt);
+ cs_set_state(sm, CS_INIT);
+}
+
+static void rap_cs_config_cmplt_evt(const uint8_t *data, uint8_t size,
+ void *user_data)
+{
+ struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
+ const struct bt_hci_evt_le_cs_config_complete *evt;
+ struct rap_ev_cs_config_cmplt rap_ev;
+ struct iovec iov;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_evt_le_cs_config_complete))
+ return;
+
+ /* Initialize iovec with the event data */
+ iov.iov_base = (void *)data;
+ iov.iov_len = size;
+
+ DBG("size=0x%02X\n", size);
+
+ /* State Check */
+ if (cs_get_current_state(sm) != CS_WAIT_CONFIG_CMPLT) {
+ DBG("Event received in Wrong State!! ");
+ DBG("Expected : CS_WAIT_CONFIG_CMPLT");
+ return;
+ }
+
+ /* Pull the entire structure at once */
+ evt = util_iov_pull_mem(&iov, sizeof(*evt));
+ if (!evt) {
+ error("Failed to pull config complete struct\n");
+ return;
+ }
+
+ DBG("status=0x%02X, handle=0x%04X\n", evt->status, evt->handle);
+
+ /* Check status */
+ if (evt->status != 0) {
+ error("Configuration failed with status 0x%02X\n",
+ evt->status);
+ cs_set_state(sm, CS_STOPPED);
+ return;
+ }
+
+ /* Copy fields to rap_ev structure */
+ rap_ev.status = evt->status;
+ rap_ev.conn_hdl = cpu_to_le16(evt->handle);
+ rap_ev.config_id = evt->config_id;
+ rap_ev.action = evt->action;
+ rap_ev.main_mode_type = evt->main_mode_type;
+ rap_ev.sub_mode_type = evt->sub_mode_type;
+ rap_ev.min_main_mode_steps = evt->min_main_mode_steps;
+ rap_ev.max_main_mode_steps = evt->max_main_mode_steps;
+ rap_ev.main_mode_rep = evt->main_mode_repetition;
+ rap_ev.mode_0_steps = evt->mode_0_steps;
+ rap_ev.role = evt->role;
+ rap_ev.rtt_type = evt->rtt_type;
+ rap_ev.cs_sync_phy = evt->cs_sync_phy;
+ memcpy(rap_ev.channel_map, evt->channel_map, 10);
+ rap_ev.channel_map_rep = evt->channel_map_repetition;
+ rap_ev.channel_sel_type = evt->channel_selection_type;
+ rap_ev.ch3c_shape = evt->ch3c_shape;
+ rap_ev.ch3c_jump = evt->ch3c_jump;
+ rap_ev.reserved = evt->reserved;
+ rap_ev.t_ip1_time = evt->t_ip1_time;
+ rap_ev.t_ip2_time = evt->t_ip2_time;
+ rap_ev.t_fcs_time = evt->t_fcs_time;
+ rap_ev.t_pm_time = evt->t_pm_time;
+
+ /* Store rtt_type in global options */
+ cs_opt.rtt_type = rap_ev.rtt_type;
+
+ DBG("config_id=%u, action=%u, ",
+ rap_ev.config_id, rap_ev.action);
+ DBG("main_mode=%u, sub_mode=%u, role=%u, rtt_type=%u\n",
+ rap_ev.main_mode_type, rap_ev.sub_mode_type,
+ rap_ev.role, rap_ev.rtt_type);
+
+ /* Success - proceed to Security enable complete */
+ cs_set_state(sm, CS_WAIT_SEC_CMPLT);
+
+ /* Reflector role */
+ DBG("Waiting for security enable event...\n");
+ /* TODO: Initiator role - Send CS Security enable cmd */
+
+ /* Send Callback to RAP Profile */
+ for (size_t i = 0; i < CS_CALLBACK_MAP_SIZE; i++) {
+ if (cs_callback_map[i].state == sm->old_state) {
+ cs_callback_map[i].callback(size, &rap_ev, sm->rap);
+ return;
+ }
+ }
+}
+
+static void rap_cs_sec_enable_cmplt_evt(const uint8_t *data, uint8_t size,
+ void *user_data)
+{
+ struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
+ struct rap_ev_cs_sec_enable_cmplt rap_ev;
+ struct iovec iov;
+ uint8_t status;
+ uint16_t handle;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_evt_le_cs_sec_enable_complete))
+ return;
+
+ /* Initialize iovec with the event data */
+ iov.iov_base = (void *)data;
+ iov.iov_len = size;
+
+ DBG("size=0x%02X\n", size);
+
+ /* State Check */
+ if (cs_get_current_state(sm) != CS_WAIT_SEC_CMPLT) {
+ DBG("Event received in Wrong State!! ");
+ DBG("Expected : CS_WAIT_SEC_CMPLT");
+ return;
+ }
+
+ /* Parse all fields in order using iovec */
+ if (!util_iov_pull_u8(&iov, &status)) {
+ error("Failed to parse Status\n");
+ return;
+ }
+
+ if (!util_iov_pull_le16(&iov, &handle)) {
+ error("Failed to parse Connection_Handle\n");
+ return;
+ }
+
+ rap_ev.status = status;
+ rap_ev.conn_hdl = cpu_to_le16(handle);
+
+ DBG("status=0x%02X, handle=0x%04X\n",
+ rap_ev.status, handle);
+
+ if (rap_ev.status == 0) {
+ /* Success - proceed to configuration */
+ cs_set_state(sm, CS_WAIT_PROC_CMPLT);
+
+ /* Reflector role */
+ DBG("Waiting for CS Proc complete event...\n");
+ /* TODO: Initiator - Send CS Proc Set Parameter and enable */
+ } else {
+ /* Error - transition to stopped */
+ error("Security enable failed with status 0x%02X\n",
+ rap_ev.status);
+ cs_set_state(sm, CS_STOPPED);
+ }
+
+ /* Send Callback to RAP Profile */
+ for (size_t i = 0; i < CS_CALLBACK_MAP_SIZE; i++) {
+ if (cs_callback_map[i].state == sm->old_state) {
+ cs_callback_map[i].callback(size, &rap_ev, sm->rap);
+ return;
+ }
+ }
+}
+
+static void rap_cs_proc_enable_cmplt_evt(const uint8_t *data, uint8_t size,
+ void *user_data)
+{
+ struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
+ const struct bt_hci_evt_le_cs_proc_enable_complete *evt;
+ struct rap_ev_cs_proc_enable_cmplt rap_ev;
+ struct iovec iov;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_evt_le_cs_proc_enable_complete))
+ return;
+
+ /* Initialize iovec with the event data */
+ iov.iov_base = (void *)data;
+ iov.iov_len = size;
+
+ DBG("size=0x%02X\n", size);
+
+ /* State Check */
+ if (cs_get_current_state(sm) != CS_WAIT_PROC_CMPLT) {
+ DBG("Event received in Wrong State!! ");
+ DBG("Expected : CS_WAIT_PROC_CMPLT");
+ return;
+ }
+
+ /* Pull the entire structure at once */
+ evt = util_iov_pull_mem(&iov, sizeof(*evt));
+ if (!evt) {
+ error("Failed to pull proc enable complete struct\n");
+ return;
+ }
+
+ DBG("status=0x%02X, handle=0x%04X\n", evt->status, evt->handle);
+
+ /* Check status */
+ if (evt->status != 0) {
+ error("Procedure enable failed with status 0x%02X\n",
+ evt->status);
+ cs_set_state(sm, CS_STOPPED);
+ sm->procedure_active = false;
+ return;
+ }
+
+ /* Copy fields to rap_ev structure */
+ rap_ev.status = evt->status;
+ rap_ev.conn_hdl = cpu_to_le16(evt->handle);
+ rap_ev.config_id = evt->config_id;
+ rap_ev.state = evt->state;
+ rap_ev.tone_ant_config_sel = evt->tone_antenna_config_selection;
+ rap_ev.sel_tx_pwr = evt->selected_tx_power;
+ memcpy(rap_ev.sub_evt_len, evt->subevent_len, 3);
+ rap_ev.sub_evts_per_evt = evt->subevents_per_event;
+ rap_ev.sub_evt_intrvl = evt->subevent_interval;
+ rap_ev.evt_intrvl = evt->event_interval;
+ rap_ev.proc_intrvl = evt->procedure_interval;
+ rap_ev.proc_counter = evt->procedure_count;
+ rap_ev.max_proc_len = evt->max_procedure_len;
+
+ DBG("config_id=%u, state=%u, ",
+ rap_ev.config_id, rap_ev.state);
+ DBG("sub_evts_per_evt=%u, evt_intrvl=%u, proc_intrvl=%u\n",
+ rap_ev.sub_evts_per_evt, rap_ev.evt_intrvl,
+ rap_ev.proc_intrvl);
+
+ /* Success - procedure started */
+ cs_set_state(sm, CS_STARTED);
+ sm->procedure_active = true;
+
+ /* Send Callback to RAP Profile */
+ for (size_t i = 0; i < CS_CALLBACK_MAP_SIZE; i++) {
+ if (cs_callback_map[i].state == sm->old_state) {
+ cs_callback_map[i].callback(size, &rap_ev, sm->rap);
+ return;
+ }
+ }
+}
+
+static void parse_i_q_sample(struct iovec *iov, int16_t *i_sample,
+ int16_t *q_sample)
+{
+ uint32_t buffer;
+ uint32_t i12;
+ uint32_t q12;
+
+ /* Pull 24-bit little-endian value from iovec */
+ if (!util_iov_pull_le24(iov, &buffer)) {
+ *i_sample = 0;
+ *q_sample = 0;
+ return;
+ }
+
+ /* Extract 12-bit I and Q values from 24-bit buffer */
+ i12 = buffer & 0x0FFFU; /* bits 0..11 */
+ q12 = (buffer >> 12) & 0x0FFFU; /* bits 12..23 */
+
+ /* Sign-extend 12-bit values to 16-bit using macro */
+ *i_sample = SIGN_EXTEND_TO_16(i12, 12);
+ *q_sample = SIGN_EXTEND_TO_16(q12, 12);
+}
+
+/* Parse CS Mode 0 step data */
+static void parse_mode_zero_data(struct iovec *iov,
+ struct cs_mode_zero_data *mode_data,
+ uint8_t cs_role)
+{
+ uint32_t freq_offset;
+
+ if (iov->iov_len < 3) {
+ DBG("Mode 0: too short (<3)");
+ return;
+ }
+
+ util_iov_pull_u8(iov, &mode_data->packet_quality);
+ util_iov_pull_u8(iov, &mode_data->packet_rssi_dbm);
+ util_iov_pull_u8(iov, &mode_data->packet_ant);
+ DBG("CS Step mode 0");
+
+ if (cs_role == CS_INITIATOR && iov->iov_len >= 4) {
+ util_iov_pull_le32(iov, &freq_offset);
+ mode_data->init_measured_freq_offset = freq_offset;
+ }
+}
+
+/* Parse CS Mode 1 step data */
+static void parse_mode_one_data(struct iovec *iov,
+ struct cs_mode_one_data *mode_data,
+ uint8_t cs_role, uint8_t cs_rtt_type)
+{
+ uint16_t time_val;
+
+ if (iov->iov_len < 4) {
+ DBG("Mode 1: too short (<4)");
+ return;
+ }
+
+ DBG("CS Step mode 1");
+ util_iov_pull_u8(iov, &mode_data->packet_quality);
+ util_iov_pull_u8(iov, &mode_data->packet_rssi_dbm);
+ util_iov_pull_u8(iov, &mode_data->packet_ant);
+ util_iov_pull_u8(iov, &mode_data->packet_nadm);
+
+ if (iov->iov_len >= 2) {
+ util_iov_pull_le16(iov, &time_val);
+ if (cs_role == CS_REFLECTOR)
+ mode_data->tod_toa_refl = time_val;
+ else
+ mode_data->toa_tod_init = time_val;
+ }
+
+ if ((cs_rtt_type == 0x01 || cs_rtt_type == 0x02) &&
+ iov->iov_len >= 6) {
+ int16_t i_val, q_val;
+
+ parse_i_q_sample(iov, &i_val, &q_val);
+ mode_data->packet_pct1.i_sample = i_val;
+ mode_data->packet_pct1.q_sample = q_val;
+
+ parse_i_q_sample(iov, &i_val, &q_val);
+ mode_data->packet_pct2.i_sample = i_val;
+ mode_data->packet_pct2.q_sample = q_val;
+ }
+}
+
+/* Parse CS Mode 2 step data */
+static void parse_mode_two_data(struct iovec *iov,
+ struct cs_mode_two_data *mode_data,
+ uint8_t max_paths)
+{
+ uint8_t k;
+
+ if (iov->iov_len < 1) {
+ DBG("Mode 2: too short (<1)");
+ return;
+ }
+
+ util_iov_pull_u8(iov, &mode_data->ant_perm_index);
+ DBG("CS Step mode 2, max paths : %d", max_paths);
+
+ for (k = 0; k < max_paths; k++) {
+ int16_t i_val, q_val;
+
+ if (iov->iov_len < 4) {
+ DBG("Mode 2: insufficient PCT for path %u (rem=%zu)",
+ k, iov->iov_len);
+ break;
+ }
+ parse_i_q_sample(iov, &i_val, &q_val);
+ mode_data->tone_pct[k].i_sample = i_val;
+ mode_data->tone_pct[k].q_sample = q_val;
+
+ util_iov_pull_u8(iov, &mode_data->tone_quality_indicator[k]);
+ DBG("tone_quality_indicator : %d",
+ mode_data->tone_quality_indicator[k]);
+ DBG("[i, q] : %d, %d",
+ mode_data->tone_pct[k].i_sample,
+ mode_data->tone_pct[k].q_sample);
+ }
+}
+
+/* Parse CS Mode 3 step data */
+static void parse_mode_three_data(struct iovec *iov,
+ struct cs_mode_three_data *mode_data,
+ uint8_t cs_role, uint8_t cs_rtt_type,
+ uint8_t max_paths)
+{
+ uint8_t k;
+ struct cs_mode_one_data *mode_one = &mode_data->mode_one_data;
+ struct cs_mode_two_data *mode_two = &mode_data->mode_two_data;
+
+ if (iov->iov_len < 4) {
+ DBG("Mode 3: mode1 too short (<4)");
+ return;
+ }
+
+ DBG("CS Step mode 3");
+
+ /* Parse Mode 1 portion */
+ parse_mode_one_data(iov, mode_one, cs_role, cs_rtt_type);
+
+ /* Parse Mode 2 portion */
+ if (iov->iov_len >= 1) {
+ util_iov_pull_u8(iov, &mode_two->ant_perm_index);
+ for (k = 0; k < max_paths; k++) {
+ int16_t i_val, q_val;
+
+ if (iov->iov_len < 4)
+ break;
+ parse_i_q_sample(iov, &i_val, &q_val);
+ mode_two->tone_pct[k].i_sample = i_val;
+ mode_two->tone_pct[k].q_sample = q_val;
+
+ util_iov_pull_u8(iov,
+ &mode_two->tone_quality_indicator[k]);
+ }
+ }
+}
+
+/* Parse a single CS step */
+static void parse_cs_step(struct iovec *iov, struct cs_step_data *step,
+ uint8_t cs_role, uint8_t cs_rtt_type,
+ uint8_t max_paths)
+{
+ uint8_t mode;
+ uint8_t chnl;
+ uint8_t length;
+
+ /* Check if we have enough data for the 3-byte header */
+ if (iov->iov_len < 3) {
+ DBG("Truncated header for step");
+ return;
+ }
+
+ /* Read mode, channel, and length (3-byte header) */
+ if (!util_iov_pull_u8(iov, &mode) ||
+ !util_iov_pull_u8(iov, &chnl) ||
+ !util_iov_pull_u8(iov, &length)) {
+ DBG("Failed to read header for step");
+ return;
+ }
+
+ DBG("event->step_data_len : %d", length);
+
+ step->step_mode = mode;
+ step->step_chnl = chnl;
+ step->step_data_length = length;
+
+ DBG("Step: mode=%u chnl=%u data_len=%u", mode, chnl, length);
+
+ if (iov->iov_len < length) {
+ DBG("Truncated payload for step (need %u, have %zu)",
+ length, iov->iov_len);
+ return;
+ }
+
+ /* Parse step data based on mode */
+ switch (mode) {
+ case CS_MODE_ZERO:
+ parse_mode_zero_data(iov, &step->step_mode_data.mode_zero_data,
+ cs_role);
+ break;
+ case CS_MODE_ONE:
+ parse_mode_one_data(iov, &step->step_mode_data.mode_one_data,
+ cs_role, cs_rtt_type);
+ break;
+ case CS_MODE_TWO:
+ parse_mode_two_data(iov, &step->step_mode_data.mode_two_data,
+ max_paths);
+ break;
+ case CS_MODE_THREE:
+ parse_mode_three_data(iov,
+ &step->step_mode_data.mode_three_data,
+ cs_role, cs_rtt_type, max_paths);
+ break;
+ default:
+ DBG("Unknown step mode %d", mode);
+ /* Skip the entire step data */
+ util_iov_pull(iov, length);
+ break;
+ }
+}
+
+static void rap_cs_subevt_result_evt(const uint8_t *data, uint8_t size,
+ void *user_data)
+{
+ struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
+ struct rap_ev_cs_subevent_result *rap_ev;
+ struct iovec iov;
+ uint8_t cs_role;
+ uint8_t cs_rtt_type;
+ uint8_t max_paths;
+ uint8_t steps;
+ size_t send_len = 0;
+ uint16_t handle;
+ uint8_t config_id;
+ uint16_t start_acl_conn_evt_counter;
+ uint16_t proc_counter;
+ uint16_t freq_comp;
+ uint8_t ref_pwr_lvl;
+ uint8_t proc_done_status;
+ uint8_t subevt_done_status;
+ uint8_t abort_reason;
+ uint8_t num_ant_paths;
+ uint8_t num_steps_reported;
+ uint8_t i;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_evt_le_cs_subevent_result))
+ return;
+
+ /* Initialize iovec with the event data */
+ iov.iov_base = (void *)data;
+ iov.iov_len = size;
+
+ /* Check if Procedure is active or not */
+ if (!sm->procedure_active) {
+ DBG("Received Subevent event when Procedure is inactive!");
+ return;
+ }
+
+ /* Parse header fields using iovec */
+ if (!util_iov_pull_le16(&iov, &handle)) {
+ error("Failed to parse Connection_Handle\n");
+ return;
+ }
+
+ if (!util_iov_pull_u8(&iov, &config_id) ||
+ !util_iov_pull_le16(&iov, &start_acl_conn_evt_counter) ||
+ !util_iov_pull_le16(&iov, &proc_counter) ||
+ !util_iov_pull_le16(&iov, &freq_comp) ||
+ !util_iov_pull_u8(&iov, &ref_pwr_lvl) ||
+ !util_iov_pull_u8(&iov, &proc_done_status) ||
+ !util_iov_pull_u8(&iov, &subevt_done_status) ||
+ !util_iov_pull_u8(&iov, &abort_reason) ||
+ !util_iov_pull_u8(&iov, &num_ant_paths) ||
+ !util_iov_pull_u8(&iov, &num_steps_reported)) {
+ error("Failed to parse subevent fields\n");
+ return;
+ }
+
+ cs_role = cs_opt.role;
+ cs_rtt_type = cs_opt.rtt_type;
+ max_paths = MIN((num_ant_paths + 1), CS_MAX_ANT_PATHS);
+ steps = MIN(num_steps_reported, CS_MAX_STEPS);
+ send_len = offsetof(struct rap_ev_cs_subevent_result, step_data) +
+ steps * sizeof(struct cs_step_data);
+ rap_ev = (struct rap_ev_cs_subevent_result *)malloc(send_len);
+ if (!rap_ev) {
+ error("Failed to allocate memory for subevent result\n");
+ return;
+ }
+
+ DBG("length=%u\n", size);
+ rap_ev->conn_hdl = le16_to_cpu(handle);
+ rap_ev->config_id = config_id;
+ rap_ev->start_acl_conn_evt_counter = start_acl_conn_evt_counter;
+ rap_ev->proc_counter = proc_counter;
+ rap_ev->freq_comp = freq_comp;
+ rap_ev->ref_pwr_lvl = ref_pwr_lvl;
+ rap_ev->proc_done_status = proc_done_status;
+ rap_ev->subevt_done_status = subevt_done_status;
+ rap_ev->abort_reason = abort_reason;
+ rap_ev->num_ant_paths = num_ant_paths;
+ rap_ev->num_steps_reported = steps;
+
+ if (num_steps_reported > CS_MAX_STEPS) {
+ DBG("Too many steps reported: %u (max %u)",
+ num_steps_reported, CS_MAX_STEPS);
+ goto send_event;
+ }
+
+ /* Early exit for error conditions */
+ if (rap_ev->subevt_done_status == 0xF ||
+ rap_ev->proc_done_status == 0xF) {
+ DBG("CS Procedure/Subevent aborted: ");
+ DBG("sub evt status = %d, proc status = %d, reason = %d",
+ rap_ev->subevt_done_status, rap_ev->proc_done_status,
+ rap_ev->abort_reason);
+ goto send_event;
+ }
+
+ /* Parse interleaved step data from remaining iovec data */
+ for (i = 0; i < steps; i++)
+ parse_cs_step(&iov, &rap_ev->step_data[i], cs_role, cs_rtt_type,
+ max_paths);
+
+send_event:
+ DBG("CS subevent result processed: %zu bytes, ", send_len);
+ bt_rap_hci_cs_subevent_result_callback(send_len, rap_ev, sm->rap);
+ free(rap_ev);
+}
+
+static void rap_cs_subevt_result_cont_evt(const uint8_t *data, uint8_t size,
+ void *user_data)
+{
+ struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
+ struct rap_ev_cs_subevent_result_cont *rap_ev;
+ struct iovec iov;
+ uint8_t cs_role;
+ uint8_t cs_rtt_type;
+ uint8_t max_paths;
+ uint8_t steps;
+ size_t send_len = 0;
+ uint16_t handle;
+ uint8_t config_id;
+ uint8_t proc_done_status;
+ uint8_t subevt_done_status;
+ uint8_t abort_reason;
+ uint8_t num_ant_paths;
+ uint8_t num_steps_reported;
+ uint8_t i;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_evt_le_cs_subevent_result_continue))
+ return;
+
+ /* Initialize iovec with the event data */
+ iov.iov_base = (void *)data;
+ iov.iov_len = size;
+
+ /* Check if Procedure is active or not */
+ if (!sm->procedure_active) {
+ error("Received Subevent when CS Procedure is inactive!");
+ return;
+ }
+
+ /* Parse header fields using iovec */
+ if (!util_iov_pull_le16(&iov, &handle)) {
+ error("Failed to parse Connection_Handle\n");
+ return;
+ }
+
+ if (!util_iov_pull_u8(&iov, &config_id) ||
+ !util_iov_pull_u8(&iov, &proc_done_status) ||
+ !util_iov_pull_u8(&iov, &subevt_done_status) ||
+ !util_iov_pull_u8(&iov, &abort_reason) ||
+ !util_iov_pull_u8(&iov, &num_ant_paths) ||
+ !util_iov_pull_u8(&iov, &num_steps_reported)) {
+ error("Failed to parse subevent continue fields ");
+ return;
+ }
+
+ cs_role = cs_opt.role;
+ cs_rtt_type = cs_opt.rtt_type;
+ max_paths = MIN((num_ant_paths + 1), CS_MAX_ANT_PATHS);
+ steps = MIN(num_steps_reported, CS_MAX_STEPS);
+ send_len = offsetof(struct rap_ev_cs_subevent_result_cont, step_data) +
+ steps * sizeof(struct cs_step_data);
+ rap_ev = (struct rap_ev_cs_subevent_result_cont *)malloc(send_len);
+ if (!rap_ev) {
+ error("Failed to allocate memory for subevent result\n");
+ return;
+ }
+
+ DBG("length=%u\n", size);
+ rap_ev->conn_hdl = le16_to_cpu(handle);
+ rap_ev->config_id = config_id;
+ rap_ev->proc_done_status = proc_done_status;
+ rap_ev->subevt_done_status = subevt_done_status;
+ rap_ev->abort_reason = abort_reason;
+ rap_ev->num_ant_paths = num_ant_paths;
+ rap_ev->num_steps_reported = steps;
+
+ if (num_steps_reported > CS_MAX_STEPS) {
+ DBG("Too many steps reported: %u (max %u)",
+ num_steps_reported, CS_MAX_STEPS);
+ goto send_event;
+ }
+
+ /* Early exit for error conditions */
+ if (rap_ev->subevt_done_status == 0xF ||
+ rap_ev->proc_done_status == 0xF) {
+ DBG("CS Procedure/Subevent aborted: ");
+ DBG("sub evt status = %d, proc status = %d, reason = %d",
+ rap_ev->subevt_done_status, rap_ev->proc_done_status,
+ rap_ev->abort_reason);
+ goto send_event;
+ }
+
+ /* Parse interleaved step data from remaining iovec data */
+ for (i = 0; i < steps; i++)
+ parse_cs_step(&iov, &rap_ev->step_data[i], cs_role, cs_rtt_type,
+ max_paths);
+
+send_event:
+ DBG("CS subevent result cont processed: %zu bytes, ", send_len);
+ bt_rap_hci_cs_subevent_result_cont_callback(send_len, rap_ev, sm->rap);
+ free(rap_ev);
+}
+
+/* Subevent handler function type */
+typedef void (*subevent_handler_t)(const uint8_t *data, uint8_t size,
+ void *user_data);
+
+/* Subevent table entry */
+struct subevent_entry {
+ uint8_t opcode;
+ uint8_t min_len;
+ uint8_t max_len;
+ subevent_handler_t handler;
+ const char *name;
+};
+
+/* Macro to define HCI event entries */
+#define HCI_EVT(_opcode, _struct, _handler, _name) \
+ { \
+ .opcode = _opcode, \
+ .min_len = sizeof(_struct), \
+ .max_len = 0xFF, \
+ .handler = _handler, \
+ .name = _name \
+ }
+
+/* Subevent dispatch table */
+static const struct subevent_entry subevent_table[] = {
+ HCI_EVT(BT_HCI_EVT_LE_CS_RD_REM_SUPP_CAP_COMPLETE,
+ struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete,
+ rap_rd_rmt_supp_cap_cmplt_evt,
+ "CS Read Remote Supported Capabilities Complete"),
+ HCI_EVT(BT_HCI_EVT_LE_CS_CONFIG_COMPLETE,
+ struct bt_hci_evt_le_cs_config_complete,
+ rap_cs_config_cmplt_evt,
+ "CS Config Complete"),
+ HCI_EVT(BT_HCI_EVT_LE_CS_SEC_ENABLE_COMPLETE,
+ struct bt_hci_evt_le_cs_sec_enable_complete,
+ rap_cs_sec_enable_cmplt_evt,
+ "CS Security Enable Complete"),
+ HCI_EVT(BT_HCI_EVT_LE_CS_PROC_ENABLE_COMPLETE,
+ struct bt_hci_evt_le_cs_proc_enable_complete,
+ rap_cs_proc_enable_cmplt_evt,
+ "CS Procedure Enable Complete"),
+ HCI_EVT(BT_HCI_EVT_LE_CS_SUBEVENT_RESULT,
+ struct bt_hci_evt_le_cs_subevent_result,
+ rap_cs_subevt_result_evt,
+ "CS Subevent Result"),
+ HCI_EVT(BT_HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE,
+ struct bt_hci_evt_le_cs_subevent_result_continue,
+ rap_cs_subevt_result_cont_evt,
+ "CS Subevent Result Continue")
+};
+
+#undef HCI_EVT
+
+#define SUBEVENT_TABLE_SIZE ARRAY_SIZE(subevent_table)
+
+/* HCI Event Registration */
+static void rap_handle_hci_events(const void *data, uint8_t size,
+ void *user_data)
+{
+ struct iovec iov;
+ uint8_t subevent;
+ const struct subevent_entry *entry = NULL;
+ size_t i;
+
+ /* Initialize iovec with the event data */
+ iov.iov_base = (void *)data;
+ iov.iov_len = size;
+
+ /* Pull the subevent code */
+ if (!util_iov_pull_u8(&iov, &subevent)) {
+ DBG("Failed to parse subevent code");
+ return;
+ }
+
+ /* Find the subevent in the table */
+ for (i = 0; i < SUBEVENT_TABLE_SIZE; i++) {
+ if (subevent_table[i].opcode == subevent) {
+ entry = &subevent_table[i];
+ break;
+ }
+ }
+
+ /* Check if subevent is supported */
+ if (!entry) {
+ DBG("Unknown subevent: 0x%02X", subevent);
+ return;
+ }
+
+ /* Validate payload length */
+ if (iov.iov_len < entry->min_len) {
+ DBG("%s: payload too short (%zu < %u)",
+ entry->name, iov.iov_len, entry->min_len);
+ return;
+ }
+
+ if (entry->max_len != 0xFF && iov.iov_len > entry->max_len) {
+ DBG("%s: payload too long (%zu > %u)",
+ entry->name, iov.iov_len, entry->max_len);
+ return;
+ }
+
+ /* Call the handler */
+ DBG("Handling %s (opcode=0x%02X, len=%zu)",
+ entry->name, subevent, iov.iov_len);
+
+ entry->handler(iov.iov_base, iov.iov_len, user_data);
+}
+
+static void bt_rap_hci_register_events(struct bt_rap *rap,
+ struct bt_hci *hci)
+{
+ if (!rap || !hci)
+ return;
+
+ sm = new0(struct cs_state_machine_t, 1);
+ if (!sm) {
+ error("Failed to allocate state machine\n");
+ return;
+ }
+
+ cs_state_machine_init(sm, rap, hci);
+ sm->event_id = bt_hci_register(hci, BT_HCI_EVT_LE_META_EVENT,
+ rap_handle_hci_events, sm, NULL);
+
+ DBG("bt_hci_register done, event_id : %d", sm->event_id);
+
+ if (!sm->event_id) {
+ DBG("Error: Failed to register hci le meta events ");
+ DBG("event_id=0x%02X\n", sm->event_id);
+ free(sm);
+ return;
+ }
+}
+
+bool bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci)
+{
+ if (!rap)
+ return false;
+
+ if (!hci) {
+ DBG("Failed to create HCI RAW channel ");
+ bt_hci_unref(hci);
+ return false;
+ }
+
+ bt_rap_hci_register_events(rap, hci);
+
+ return true;
+}
+
+bool bt_rap_set_conn_handle(struct bt_rap *rap, uint16_t handle,
+ const uint8_t *bdaddr, uint8_t bdaddr_type)
+{
+ struct bt_att *att;
+
+ if (!rap)
+ return false;
+
+ att = bt_rap_get_att(rap);
+ if (!att)
+ return false;
+
+ DBG("Setting connection mapping: handle=0x%04X, ", handle);
+ if (bdaddr) {
+ DBG("bdaddr=%02x:%02x:%02x:%02x:%02x:%02x type=%u",
+ bdaddr[5], bdaddr[4], bdaddr[3],
+ bdaddr[2], bdaddr[1], bdaddr[0], bdaddr_type);
+ }
+
+ return add_conn_mapping(handle, bdaddr, bdaddr_type, att, rap);
+}
+
+void bt_rap_clear_conn_handle(struct bt_rap *rap, uint16_t handle)
+{
+ if (!rap)
+ return;
+
+ DBG("Clearing connection mapping: handle=0x%04X", handle);
+ remove_conn_mapping(handle);
+}
+
+void bt_rap_detach_hci(struct bt_rap *rap)
+{
+ if (!rap)
+ return;
+
+ DBG("Detaching RAP from HCI, cleaning up mappings");
+
+ /* Remove all mappings associated with this RAP instance */
+ remove_rap_mappings(rap);
+}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH BlueZ v8 2/3] main.conf: Add Channel Sounding config parsing support
From: Naga Bhavani Akella @ 2026-04-15 16:38 UTC (permalink / raw)
To: linux-bluetooth
Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg,
prathibha.madugonde, Naga Bhavani Akella
In-Reply-To: <20260415163805.564395-1-naga.akella@oss.qualcomm.com>
Add support for parsing Channel Sounding (CS) configuration options
from the configuration file.
Add CAP_NET_RAW to CapabilityBoundingSet in bluetooth.service.
bluetoothd requires CAP_NET_RAW to receive and process HCI LE events
when running under a constrained systemd capability bounding set
---
src/bluetooth.service.in | 2 +-
src/btd.h | 7 +++
src/main.c | 132 ++++++++++++++++++++++++++++++++++++++-
src/main.conf | 24 +++++++
4 files changed, 162 insertions(+), 3 deletions(-)
diff --git a/src/bluetooth.service.in b/src/bluetooth.service.in
index 8ebe89bec..8dcbde236 100644
--- a/src/bluetooth.service.in
+++ b/src/bluetooth.service.in
@@ -10,7 +10,7 @@ ExecStart=@PKGLIBEXECDIR@/bluetoothd
NotifyAccess=main
#WatchdogSec=10
#Restart=on-failure
-CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN CAP_NET_BIND_SERVICE
LimitNPROC=1
# Filesystem lockdown
diff --git a/src/btd.h b/src/btd.h
index c84a600d1..db2e81239 100644
--- a/src/btd.h
+++ b/src/btd.h
@@ -94,11 +94,18 @@ struct btd_le_defaults {
uint8_t enable_advmon_interleave_scan;
};
+struct btd_le_bcs {
+ uint8_t role;
+ uint8_t cs_sync_ant_sel;
+ int8_t max_tx_power;
+};
+
struct btd_defaults {
uint16_t num_entries;
struct btd_br_defaults br;
struct btd_le_defaults le;
+ struct btd_le_bcs bcs;
};
struct btd_csis {
diff --git a/src/main.c b/src/main.c
index 818f7c06e..32fc2c97d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -156,6 +156,13 @@ static const char *gatt_options[] = {
NULL
};
+static const char *const bcs_options[] = {
+ "Role",
+ "CsSyncAntennaSel",
+ "MaxTxPower",
+ NULL
+};
+
static const char *csip_options[] = {
"SIRK",
"Encryption",
@@ -183,7 +190,7 @@ static const char *advmon_options[] = {
static const struct group_table {
const char *name;
- const char **options;
+ const char * const *options;
} valid_groups[] = {
{ "General", supported_options },
{ "BR", br_options },
@@ -193,6 +200,7 @@ static const struct group_table {
{ "CSIS", csip_options },
{ "AVDTP", avdtp_options },
{ "AVRCP", avrcp_options },
+ { "ChannelSounding", bcs_options },
{ "AdvMon", advmon_options },
{ }
};
@@ -356,7 +364,7 @@ static enum jw_repairing_t parse_jw_repairing(const char *jw_repairing)
static void check_options(GKeyFile *config, const char *group,
- const char **options)
+ const char * const *options)
{
char **keys;
int i;
@@ -492,6 +500,46 @@ static bool parse_config_int(GKeyFile *config, const char *group,
return true;
}
+static bool parse_config_signed_int(GKeyFile *config, const char *group,
+ const char *key, int8_t *val,
+ size_t min, size_t max)
+{
+ char *str = NULL;
+ char *endptr = NULL;
+ long tmp;
+ bool result = false;
+
+ str = g_key_file_get_string(config, group, key, NULL);
+ if (!str)
+ return false;
+
+ tmp = strtol(str, &endptr, 0);
+ if (!endptr || *endptr != '\0') {
+ warn("%s.%s = %s is not integer", group, key, str);
+ goto cleanup;
+ }
+
+ if (tmp < (long)min) {
+ warn("%s.%s = %ld is out of range (< %zu)", group, key, tmp,
+ min);
+ goto cleanup;
+ }
+
+ if (tmp > (long)max) {
+ warn("%s.%s = %ld is out of range (> %zu)", group, key, tmp,
+ max);
+ goto cleanup;
+ }
+
+ if (val)
+ *val = (int8_t)tmp;
+ result = true;
+
+cleanup:
+ g_free(str);
+ return result;
+}
+
struct config_param {
const char * const val_name;
void * const val;
@@ -1184,6 +1232,81 @@ static void parse_csis(GKeyFile *config)
0, UINT8_MAX);
}
+static bool parse_cs_role(GKeyFile *config, const char *group,
+ const char *key, uint8_t *val)
+{
+ GError *err = NULL;
+ char *str = NULL;
+ char *endptr = NULL;
+ int numeric_val;
+
+ /* Try to read as string first */
+ str = g_key_file_get_string(config, group, key, &err);
+ if (err) {
+ if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
+ DBG("%s", err->message);
+ g_error_free(err);
+ return false;
+ }
+
+ DBG("%s.%s = %s", group, key, str);
+
+ /* Check if it's a string value */
+ if (!strcmp(str, "Initiator") || !strcmp(str, "initiator")) {
+ if (val)
+ *val = 1;
+ g_free(str);
+ return true;
+ } else if (!strcmp(str, "Reflector") || !strcmp(str, "reflector")) {
+ if (val)
+ *val = 2;
+ g_free(str);
+ return true;
+ } else if (!strcmp(str, "Both") || !strcmp(str, "both")) {
+ if (val)
+ *val = 3;
+ g_free(str);
+ return true;
+ }
+
+ /* Try to parse as numeric value */
+ numeric_val = strtol(str, &endptr, 0);
+
+ if (!endptr || *endptr != '\0') {
+ error("%s.%s = %s is not a valid value. "
+ "Expected: 1/Initiator, 2/Reflector, or 3/Both",
+ group, key, str);
+ g_free(str);
+ return false;
+ }
+
+ if (numeric_val < 1 || numeric_val > 3) {
+ warn("%s.%s = %d is out of range. "
+ "Valid values: 1 (Initiator), 2 (Reflector), 3 (Both)",
+ group, key, numeric_val);
+ g_free(str);
+ return false;
+ }
+
+ if (val)
+ *val = numeric_val;
+
+ g_free(str);
+ return true;
+}
+
+static void parse_le_cs_config(GKeyFile *config)
+{
+ parse_cs_role(config, "ChannelSounding", "Role",
+ &btd_opts.defaults.bcs.role);
+ parse_config_u8(config, "ChannelSounding", "CsSyncAntennaSel",
+ &btd_opts.defaults.bcs.cs_sync_ant_sel,
+ 0x01, 0xFF);
+ parse_config_signed_int(config, "ChannelSounding",
+ "MaxTxPower", &btd_opts.defaults.bcs.max_tx_power,
+ INT8_MIN, INT8_MAX);
+}
+
static void parse_avdtp_session_mode(GKeyFile *config)
{
char *str = NULL;
@@ -1262,6 +1385,7 @@ static void parse_config(GKeyFile *config)
parse_csis(config);
parse_avdtp(config);
parse_avrcp(config);
+ parse_le_cs_config(config);
parse_advmon(config);
}
@@ -1313,6 +1437,10 @@ static void init_defaults(void)
btd_opts.advmon.rssi_sampling_period = 0xFF;
btd_opts.csis.encrypt = true;
+
+ btd_opts.defaults.bcs.role = 0x03;
+ btd_opts.defaults.bcs.cs_sync_ant_sel = 0xFF;
+ btd_opts.defaults.bcs.max_tx_power = 0x14;
}
static void log_handler(const gchar *log_domain, GLogLevelFlags log_level,
diff --git a/src/main.conf b/src/main.conf
index d31dd1b8f..fc0138bbf 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -299,6 +299,30 @@
# Default = auto
# Security = auto
+[ChannelSounding]
+# Current role of the device
+# Possible values:
+# 1 or "Initiator" - CS Initiator role,
+# Generally, CS Initiator acts as Client (Gatt role) and Central (Gap role)
+# 2 or "Reflector" - CS Reflector role,
+# Generally, CS Reflector acts as Server (Gatt role) and Peripheral (Gap role)
+# 3 or "Both" - Both Initiator and Reflector roles
+# Default: 3 (Both)
+#Role = 3
+
+# Antenna Identifier to be used
+# Possible values:
+# 0x01-0x04 (antenna identifier to be used),
+# 0xFE - Antennas to be used in repetetive order,
+# 0xFF - Host doen't have recommendation
+# Default: 0xFF (Host doesn't have recommendation)
+#CsSyncAntennaSel = 0xFF
+
+# Maximum Transmit power
+# Possible values: 0x7F-0x14 (-127dBm to 20dBm)
+# Default: 0x14 (Max Power possible)
+#MaxTxPower = 0x14
+
[CSIS]
# SIRK - Set Identification Resolution Key which is common for all the
# sets. They SIRK key is used to identify its sets. This can be any
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH BlueZ v8 1/3] shared: rap: Introduce Channel Sounding HCI raw interface support
From: Naga Bhavani Akella @ 2026-04-15 16:38 UTC (permalink / raw)
To: linux-bluetooth
Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg,
prathibha.madugonde, Naga Bhavani Akella
In-Reply-To: <20260415163805.564395-1-naga.akella@oss.qualcomm.com>
Implement stub callbacks for Channel Sounding HCI events and add the
required protocol definitions for CS configuration, procedure control,
and subevent result parsing
Add data structures to support Channel Sounding Processing
Add helper function to get hci conn info list and integrate it with RAP
---
src/shared/hci.c | 89 +++++++++++++++++++-----
src/shared/hci.h | 15 ++++
src/shared/rap.c | 50 +++++++++++++-
src/shared/rap.h | 176 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 312 insertions(+), 18 deletions(-)
diff --git a/src/shared/hci.c b/src/shared/hci.c
index 575254c09..46377fa30 100644
--- a/src/shared/hci.c
+++ b/src/shared/hci.c
@@ -20,9 +20,11 @@
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
+#include "bluetooth/hci.h"
#include "monitor/bt.h"
#include "src/shared/mainloop.h"
#include "src/shared/io.h"
@@ -30,22 +32,6 @@
#include "src/shared/queue.h"
#include "src/shared/hci.h"
-#define BTPROTO_HCI 1
-struct sockaddr_hci {
- sa_family_t hci_family;
- unsigned short hci_dev;
- unsigned short hci_channel;
-};
-#define HCI_CHANNEL_RAW 0
-#define HCI_CHANNEL_USER 1
-
-#define SOL_HCI 0
-#define HCI_FILTER 2
-struct hci_filter {
- uint32_t type_mask;
- uint32_t event_mask[2];
- uint16_t opcode;
-};
struct bt_hci {
int ref_count;
@@ -673,3 +659,74 @@ bool bt_hci_unregister(struct bt_hci *hci, unsigned int id)
return true;
}
+
+bool bt_hci_get_conn_handle(struct bt_hci *hci, const uint8_t *bdaddr,
+ uint16_t *handle)
+{
+ struct hci_conn_list_req *cl;
+ struct hci_conn_info *ci;
+ int fd, i;
+ bool found = false;
+
+ if (!hci || !bdaddr || !handle)
+ return false;
+
+ fd = io_get_fd(hci->io);
+ if (fd < 0)
+ return false;
+
+ /* Allocate buffer for connection list request */
+ cl = malloc(10 * sizeof(*ci) + sizeof(*cl));
+ if (!cl)
+ return false;
+
+ memset(cl, 0, 10 * sizeof(*ci) + sizeof(*cl));
+ cl->dev_id = 0; /* Will be filled by ioctl */
+ cl->conn_num = 10;
+
+ /* Get connection list via ioctl */
+ if (ioctl(fd, HCIGETCONNLIST, (void *) cl) < 0) {
+ free(cl);
+ return false;
+ }
+
+ /* Search for the connection with matching bdaddr */
+ ci = cl->conn_info;
+ for (i = 0; i < cl->conn_num; i++, ci++) {
+ if (memcmp(&ci->bdaddr, bdaddr, 6) == 0) {
+ *handle = ci->handle;
+ found = true;
+ break;
+ }
+ }
+
+ free(cl);
+ return found;
+}
+
+int bt_hci_get_fd(struct bt_hci *hci)
+{
+ if (!hci || !hci->io)
+ return -1;
+
+ return io_get_fd(hci->io);
+}
+
+int bt_hci_get_index(struct bt_hci *hci)
+{
+ struct sockaddr_hci addr;
+ socklen_t addr_len = sizeof(addr);
+ int fd;
+
+ if (!hci)
+ return -1;
+
+ fd = bt_hci_get_fd(hci);
+ if (fd < 0)
+ return -1;
+
+ if (getsockname(fd, (struct sockaddr *)&addr, &addr_len) < 0)
+ return -1;
+
+ return addr.hci_dev;
+}
diff --git a/src/shared/hci.h b/src/shared/hci.h
index 76ee72f54..20a12d4ae 100644
--- a/src/shared/hci.h
+++ b/src/shared/hci.h
@@ -13,6 +13,15 @@
typedef void (*bt_hci_destroy_func_t)(void *user_data);
+struct bt_hci_conn_info {
+ uint16_t handle;
+ uint8_t bdaddr[6];
+ uint8_t type;
+ uint8_t out;
+ uint16_t state;
+ uint32_t link_mode;
+};
+
struct bt_hci;
struct bt_hci *bt_hci_new(int fd);
@@ -41,3 +50,9 @@ unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
bt_hci_callback_func_t callback,
void *user_data, bt_hci_destroy_func_t destroy);
bool bt_hci_unregister(struct bt_hci *hci, unsigned int id);
+
+bool bt_hci_get_conn_handle(struct bt_hci *hci, const uint8_t *bdaddr,
+ uint16_t *handle);
+
+int bt_hci_get_fd(struct bt_hci *hci);
+int bt_hci_get_index(struct bt_hci *hci);
diff --git a/src/shared/rap.c b/src/shared/rap.c
index 39ef3f278..5745cda08 100644
--- a/src/shared/rap.c
+++ b/src/shared/rap.c
@@ -26,8 +26,8 @@
#include "src/shared/gatt-client.h"
#include "src/shared/rap.h"
-#define DBG(_rap, fmt, arg...) \
- rap_debug(_rap, "%s:%s() " fmt, __FILE__, __func__, ## arg)
+#define DBG(_rap, fmt, ...) \
+ rap_debug(_rap, "%s:%s() " fmt, __FILE__, __func__, ##__VA_ARGS__)
#define RAS_UUID16 0x185B
@@ -504,6 +504,52 @@ bool bt_rap_unregister(unsigned int id)
return true;
}
+void bt_rap_hci_cs_subevent_result_cont_callback(uint16_t length,
+ const void *param,
+ void *user_data)
+{
+ struct bt_rap *rap = user_data;
+
+ DBG(rap, "Received CS subevent CONT: len=%d", length);
+}
+
+void bt_rap_hci_cs_subevent_result_callback(uint16_t length,
+ const void *param,
+ void *user_data)
+{
+ struct bt_rap *rap = user_data;
+
+ DBG(rap, "Received CS subevent: len=%d", length);
+}
+
+void bt_rap_hci_cs_procedure_enable_complete_callback(uint16_t length,
+ const void *param,
+ void *user_data)
+{
+ struct bt_rap *rap = user_data;
+
+ DBG(rap, "Received CS procedure enable complete subevent: len=%d",
+ length);
+}
+
+void bt_rap_hci_cs_sec_enable_complete_callback(uint16_t length,
+ const void *param,
+ void *user_data)
+{
+ struct bt_rap *rap = user_data;
+
+ DBG(rap, "Received CS security enable subevent: len=%d", length);
+}
+
+void bt_rap_hci_cs_config_complete_callback(uint16_t length,
+ const void *param,
+ void *user_data)
+{
+ struct bt_rap *rap = user_data;
+
+ DBG(rap, "Received CS config complete subevent: len=%d", length);
+}
+
struct bt_rap *bt_rap_new(struct gatt_db *ldb, struct gatt_db *rdb)
{
struct bt_rap *rap;
diff --git a/src/shared/rap.h b/src/shared/rap.h
index a1d1ff2ae..5b94d28bd 100644
--- a/src/shared/rap.h
+++ b/src/shared/rap.h
@@ -9,8 +9,155 @@
#include <inttypes.h>
#include "src/shared/io.h"
+#include "bluetooth/mgmt.h"
+#include "src/shared/hci.h"
struct bt_rap;
+struct gatt_db;
+struct bt_gatt_client;
+
+/* Channel Sounding Events */
+struct bt_rap_hci_cs_options {
+ uint8_t role;
+ uint8_t cs_sync_ant_sel;
+ int8_t max_tx_power;
+ int rtt_type;
+};
+
+#define CS_MODE_ZERO 0x00
+#define CS_MODE_ONE 0x01
+#define CS_MODE_TWO 0x02
+#define CS_MODE_THREE 0x03
+
+#define CS_REFLECTOR 0x01
+#define CS_INITIATOR 0x00
+
+#define CS_MAX_ANT_PATHS 0x05
+#define CS_MAX_STEPS 0xA0
+#define CS_MAX_STEP_DATA_LEN 0xFF
+
+struct rap_ev_cs_config_cmplt {
+ uint8_t status;
+ uint16_t conn_hdl;
+ uint8_t config_id;
+ uint8_t action;
+ uint8_t main_mode_type;
+ uint8_t sub_mode_type;
+ uint8_t min_main_mode_steps;
+ uint8_t max_main_mode_steps;
+ uint8_t main_mode_rep;
+ uint8_t mode_0_steps;
+ uint8_t role;
+ uint8_t rtt_type;
+ uint8_t cs_sync_phy;
+ uint8_t channel_map[10];
+ uint8_t channel_map_rep;
+ uint8_t channel_sel_type;
+ uint8_t ch3c_shape;
+ uint8_t ch3c_jump;
+ uint8_t reserved;
+ uint8_t t_ip1_time;
+ uint8_t t_ip2_time;
+ uint8_t t_fcs_time;
+ uint8_t t_pm_time;
+} __packed;
+
+struct rap_ev_cs_sec_enable_cmplt {
+ uint8_t status;
+ uint16_t conn_hdl;
+} __packed;
+
+struct rap_ev_cs_proc_enable_cmplt {
+ uint8_t status;
+ uint16_t conn_hdl;
+ uint8_t config_id;
+ uint8_t state;
+ uint8_t tone_ant_config_sel;
+ int8_t sel_tx_pwr;
+ uint8_t sub_evt_len[3];
+ uint8_t sub_evts_per_evt;
+ uint16_t sub_evt_intrvl;
+ uint16_t evt_intrvl;
+ uint16_t proc_intrvl;
+ uint16_t proc_counter;
+ uint16_t max_proc_len;
+} __packed;
+
+#define CS_MAX_STEPS 0xA0
+
+struct pct_iq_sample {
+ int16_t i_sample;
+ int16_t q_sample;
+} __packed;
+
+struct cs_mode_zero_data {
+ uint8_t packet_quality;
+ uint8_t packet_rssi_dbm;
+ uint8_t packet_ant;
+ uint32_t init_measured_freq_offset;
+} __packed;
+
+struct cs_mode_one_data {
+ uint8_t packet_quality;
+ uint8_t packet_rssi_dbm;
+ uint8_t packet_ant;
+ uint8_t packet_nadm;
+ int16_t toa_tod_init;
+ int16_t tod_toa_refl;
+ struct pct_iq_sample packet_pct1;
+ struct pct_iq_sample packet_pct2;
+} __packed;
+
+struct cs_mode_two_data {
+ uint8_t ant_perm_index;
+ struct pct_iq_sample tone_pct[4];
+ uint8_t tone_quality_indicator[4];
+} __packed;
+
+struct cs_mode_three_data {
+ struct cs_mode_one_data mode_one_data;
+ struct cs_mode_two_data mode_two_data;
+} __packed;
+
+union cs_mode_data {
+ struct cs_mode_zero_data mode_zero_data;
+ struct cs_mode_one_data mode_one_data;
+ struct cs_mode_two_data mode_two_data;
+ struct cs_mode_three_data mode_three_data;
+};
+
+struct cs_step_data {
+ uint8_t step_mode;
+ uint8_t step_chnl;
+ uint8_t step_data_length;
+ union cs_mode_data step_mode_data;
+} __packed;
+
+struct rap_ev_cs_subevent_result {
+ uint16_t conn_hdl;
+ uint8_t config_id;
+ uint16_t start_acl_conn_evt_counter;
+ uint16_t proc_counter;
+ uint16_t freq_comp;
+ uint8_t ref_pwr_lvl;
+ uint8_t proc_done_status;
+ uint8_t subevt_done_status;
+ uint8_t abort_reason;
+ uint8_t num_ant_paths;
+ uint8_t num_steps_reported;
+ struct cs_step_data step_data[];
+} __packed;
+
+struct rap_ev_cs_subevent_result_cont {
+ uint16_t conn_hdl;
+ uint8_t config_id;
+ uint8_t proc_done_status;
+ uint8_t subevt_done_status;
+ uint8_t abort_reason;
+ uint8_t num_ant_paths;
+ uint8_t num_steps_reported;
+ struct cs_step_data step_data[];
+} __packed;
typedef void (*bt_rap_debug_func_t)(const char *str, void *user_data);
typedef void (*bt_rap_ready_func_t)(struct bt_rap *rap, void *user_data);
@@ -43,3 +190,32 @@ bool bt_rap_ready_unregister(struct bt_rap *rap, unsigned int id);
bool bt_rap_unregister(unsigned int id);
struct bt_rap *bt_rap_new(struct gatt_db *ldb, struct gatt_db *rdb);
+
+/* HCI Raw Channel Approach */
+void bt_rap_hci_cs_config_complete_callback(uint16_t length,
+ const void *param,
+ void *user_data);
+void bt_rap_hci_cs_sec_enable_complete_callback(uint16_t length,
+ const void *param,
+ void *user_data);
+void bt_rap_hci_cs_procedure_enable_complete_callback(uint16_t length,
+ const void *param,
+ void *user_data);
+void bt_rap_hci_cs_subevent_result_callback(uint16_t length,
+ const void *param,
+ void *user_data);
+void bt_rap_hci_cs_subevent_result_cont_callback(uint16_t length,
+ const void *param,
+ void *user_data);
+
+void bt_rap_hci_set_options(uint8_t role, uint8_t cs_sync_ant_sel,
+ int8_t max_tx_power);
+
+bool bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci);
+void bt_rap_detach_hci(struct bt_rap *rap);
+void bt_rap_hci_sm_cleanup(void);
+
+/* Connection handle mapping functions */
+bool bt_rap_set_conn_handle(struct bt_rap *rap, uint16_t handle,
+ const uint8_t *bdaddr, uint8_t bdaddr_type);
+void bt_rap_clear_conn_handle(struct bt_rap *rap, uint16_t handle);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH BlueZ v8 0/3] Add initial Channel Sounding support -
From: Naga Bhavani Akella @ 2026-04-15 16:38 UTC (permalink / raw)
To: linux-bluetooth
Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg,
prathibha.madugonde, Naga Bhavani Akella
This patch series introduces initial support for Bluetooth Channel
Sounding (CS) using the raw HCI interface.
This series lays the groundwork for CS support by adding commonly required
protocol definitions, configuration parsing, and event handling for
the reflector role.
The changes include:
1) Introduction of raw HCI support structures and callbacks for Channel
Sounding procedures and events. This provides the foundational data
definitions and HCI subevent handling needed by higher-level profiles
2) Addition of Channel Sounding configuration parsing from the BlueZ
configuration file.This patch also updates the systemd
service capability bounding set to include CAP_NET_RAW, which is
required for bluetoothd to receive and process LE Channel Sounding
events when running under a constrained systemd environment
3) Implementation of HCI LE Channel Sounding event handling in the
Ranging profile for the reflector role.
This includes opening a raw HCI channel,
parsing relevant CS LE events, routing them to the RAP profile
Patch overview:
1/3 shared: rap: introduce Channel Sounding HCI raw interface support
2/3 main.conf: add Channel Sounding config parsing support
3/3 profiles: ranging: add HCI LE Channel Sounding event handling
Changes in v8:
- Add static for cs_state_machine_init,
cs_set_state, cs_get_current_state,
cs_is_procedure_active, rap_send_hci_def_settings_command
Changes in v7:
- src/main.c: Add second const to bcs_options array,
updated group_table and check_options to use const char * const *
- Move endptr to start of the function parse_cs_role
- profiles/ranging/rap.c: Move hci_index declaration to
start of function for C90 compliance
-Replace inefficient loop (0x0001-0x0EFF)
with single bt_hci_get_conn_handle call in rap_accept
- src/shared/rap.h: Add forward declarations for
struct gatt_db and struct bt_gatt_client
- src/shared/hci.h: Add bt_hci_get_conn_handle, bt_hci_get_fd,
bt_hci_get_index declarations
-Remove bt_hci_get_conn_info declaration
- src/shared/hci.c: Implement bt_hci_get_conn_handle to find handle
by bdaddr using HCIGETCONNLIST,
Add helper functions bt_hci_get_fd and bt_hci_get_index
-Remove bt_hci_get_conn_info implementation
- profiles/ranging/rap_hci.c: Remove unnecessary fallback ioctl
debug code from resolve_handle_to_rap
- Add HCI_EVT macro to simplify subevent table entries,
- Add SIGN_EXTEND_TO_16 macro for bit manipulation,
refactored parse_i_q_sample to use util_iov_pull_le24 and sign-extend macro
Naga Bhavani Akella (3):
shared: rap: Introduce Channel Sounding HCI raw interface support
main.conf: Add Channel Sounding config parsing support
profiles: ranging: Add HCI LE Event Handling in Reflector role
Makefile.plugins | 3 +-
profiles/ranging/rap.c | 52 ++
profiles/ranging/rap_hci.c | 1268 ++++++++++++++++++++++++++++++++++++
src/bluetooth.service.in | 2 +-
src/btd.h | 7 +
src/main.c | 132 +++-
src/main.conf | 24 +
src/shared/hci.c | 89 ++-
src/shared/hci.h | 15 +
src/shared/rap.c | 50 +-
src/shared/rap.h | 176 +++++
11 files changed, 1796 insertions(+), 22 deletions(-)
create mode 100644 profiles/ranging/rap_hci.c
--
^ permalink raw reply
* Re: [PATCH] Bluetooth: btusb: Add Mercusys MA530 HWID 0x2c4e/0x0115 for Realtek 8761BUV
From: Paul Menzel @ 2026-04-15 15:40 UTC (permalink / raw)
To: Kryštof Korb, Michal Piernik
Cc: Marcel Holtmann, Luiz Augusto von Dentz, linux-bluetooth,
linux-kernel
In-Reply-To: <C27221DE-E632-41C9-A15E-B393B6D314EB@korb.cz>
Dear Kryštof, dear Michal,
Am 15.04.26 um 16:47 schrieb Kryštof Korb:
> Tested-by: Kryštof Korb <krystof@korb.cz>
>
> Confirmed working on a device reporting as "MERCUSYS Bluetooth Adapter"
> (USB ID 2c4e:0115, bcdDevice 2.00), retail product Mercusys MA550H.
> Same RTL8761BU chipset, identical firmware load sequence.
>
> Seems the USB ID 2c4e:0115 covers at least two distinct retail
> products (MA530 and MA550H) from the same vendor.
>
> /sys/kernel/debug/usb/devices excerpt:
> P: Vendor=2c4e ProdID=0115 Rev= 2.00
> S: Manufacturer=
> S: Product=MERCUSYS Bluetooth Adapter
> S: SerialNumber=088AF177D360
>
> dmesg:
> Bluetooth: hci0: RTL: examining hci_ver=0a hci_rev=000b lmp_ver=0a lmp_subver=8761
> Bluetooth: hci0: RTL: rom_version status=0 version=1
> Bluetooth: hci0: RTL: loading rtl_bt/rtl8761bu_fw.bin
> Bluetooth: hci0: RTL: loading rtl_bt/rtl8761bu_config.bin
> Bluetooth: hci0: RTL: cfg_sz 6, total sz 30210
> Bluetooth: hci0: RTL: fw version 0xdfc6d922
>
>> 25. 2. 2025 v 16:58, Michal Piernik <mprnk@o2.pl>:
>>
>> /sys/kernel/debug/usb/devices:
>> T: Bus=03 Lev=01 Prnt=01 Port=05 Cnt=03 Dev#= 4 Spd=12 MxCh= 0
>> D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
>> P: Vendor=2c4e ProdID=0115 Rev= 2.00
>> S: Manufacturer=
>> S: Product=Mercusys MA530 Adapter
>> S: SerialNumber=30169D905719
>> C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
>> I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>> E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
>> E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
>> E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
>> I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>> E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
>> E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
>> I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>> E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
>> E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
>> I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>> E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
>> E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
>> I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>> E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
>> E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
>> I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>> E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
>> E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
>> I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>> E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
>> E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
>>
>> dmesg:
>> [11106.761376] Bluetooth: hci0: RTL: examining hci_ver=0a hci_rev=000b lmp_ver=0a lmp_subver=8761
>> [11106.762370] Bluetooth: hci0: RTL: rom_version status=0 version=1
>> [11106.762374] Bluetooth: hci0: RTL: loading rtl_bt/rtl8761bu_fw.bin
>> [11106.762554] Bluetooth: hci0: RTL: loading rtl_bt/rtl8761bu_config.bin
>> [11106.762579] Bluetooth: hci0: RTL: cfg_sz 6, total sz 30210
>> [11106.910393] Bluetooth: hci0: RTL: fw version 0xdfc6d922
>> [11106.977569] Bluetooth: MGMT ver 1.22
>>
>> Signed-off-by: Michal Piernik <mprnk@o2.pl>
>> ---
>> drivers/bluetooth/btusb.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
>> index f5609110f..0fc1dde8f 100644
>> --- a/drivers/bluetooth/btusb.c
>> +++ b/drivers/bluetooth/btusb.c
>> @@ -739,6 +739,8 @@ static const struct usb_device_id quirks_table[] = {
>> { USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK },
>>
>> /* Additional Realtek 8761BUV Bluetooth devices */
>> + { USB_DEVICE(0x2c4e, 0x0115), .driver_info = BTUSB_REALTEK |
>> + BTUSB_WIDEBAND_SPEECH },
>> { USB_DEVICE(0x2357, 0x0604), .driver_info = BTUSB_REALTEK |
>> BTUSB_WIDEBAND_SPEECH },
The list is unsorted anyway, but I’d add it at second position.
>> { USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK |
>> --
>> 2.34.1
Could one of you please resend the patch with Kryštof’s information
added, so it gets picked up from Patchwork again.
Kind regards,
Paul
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Add Broadcom channel priority commands
From: Sasha Finkelstein @ 2026-04-15 15:31 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Sven Peter, Janne Grunau, Neal Gompa, Marcel Holtmann,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-kernel, asahi, linux-arm-kernel,
linux-bluetooth, netdev
In-Reply-To: <CABBYNZLNR8hYS9jLLKeB=M9XVvtSFtf1wi4DmcJKBbQVvHTPaw@mail.gmail.com>
On Wed, 15 Apr 2026 at 17:19, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Ok, then maybe we should decrease the priority, so it can only go up.
> That said, in a multiple connection scenario, we cannot really tell
> what should be prioritized if we cannot momentarily decrease the
> priority.
I believe that the priority is only per-connection and is not designed
to be used per-packet. On Android they change priority when an
A2DP stream starts or stops, by sending the commands from
userspace and are accepting that other things using the same hci
connection will also have high priority.
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Add Broadcom channel priority commands
From: Luiz Augusto von Dentz @ 2026-04-15 15:19 UTC (permalink / raw)
To: Sasha Finkelstein
Cc: Sven Peter, Janne Grunau, Neal Gompa, Marcel Holtmann,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-kernel, asahi, linux-arm-kernel,
linux-bluetooth, netdev
In-Reply-To: <CAMT+MTQ6orj5tpiGL9hz8m2TGiBjA-9D_0e1iLt=_dXBFHcOgg@mail.gmail.com>
Hi Sasha,
On Wed, Apr 15, 2026 at 8:34 AM Sasha Finkelstein <fnkl.kernel@gmail.com> wrote:
>
> On Tue, 14 Apr 2026 at 16:00, Luiz Augusto von Dentz
> <luiz.dentz@gmail.com> wrote:
> > > + if (sock)
> > > + set_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags);
> >
> > This is more complicated than it needs to be. I'd just add a new
> > callback, `hdev->set_priority(handle, skb->priority)`, so the driver
> > is called whenever it needs to elevate a connection's priority, that
> > said there could be cases where a connection needs its priority set
> > momentarily to transmit A2DP, followed by OBEX packets that are best
> > effort. Therefore, `hci_conn` will probably need to track the priority
> > so it can detect when it needs changing on a per skb basis.
>
> I have tested per-skb priorities, and unfortunately, this does not work.
> If something tries to send a low-priority packet (for example - a volume
> adjustment), a priority drop causes the same kind of dropout that is
> caused by scans. It appears that the only way to make this hardware work
> is to set the entire hci connection as high priority for as long as it
> is being used to transmit audio.
Ok, then maybe we should decrease the priority, so it can only go up.
That said, in a multiple connection scenario, we cannot really tell
what should be prioritized if we cannot momentarily decrease the
priority.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH v7 0/8] Add support for handling PCIe M.2 Key E connectors in devicetree
From: Herve Codina @ 2026-04-15 14:56 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Andy Shevchenko, Manivannan Sadhasivam, Manivannan Sadhasivam,
Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski,
Bartosz Golaszewski, linux-serial, linux-kernel, linux-kbuild,
platform-driver-x86, linux-pci, devicetree, linux-arm-msm,
linux-bluetooth, linux-pm, Stephan Gerhold, Dmitry Baryshkov,
linux-acpi, Hans de Goede, Bartosz Golaszewski, Luca Ceresoli
In-Reply-To: <CAGXv+5EPA29G-fsH=wWOD8AK6TZFezFhsE0NHPYj_Pt3nT+d_w@mail.gmail.com>
Hi Chen, all,
...
>
> I'm not arguing for a even more generic "M.2" connector. The "key" is
> already described in the compatible. I'm saying we should have some way
> of describing the individual interfaces (PCIe, SDIO, USB, UART, I2S, I2C)
> on the connector so further nodes or properties can be attached to them,
> either with overlays or dynamically within the kernel. Right now the
> are only described as individual ports, but we can't actually tie a
> device to a OF graph port.
>
> But maybe I'm overthinking the representation part. AFAICT for Qualcomm's
> UART-based BT bit part, Mani just had the driver create a device node
> under the UART (by traversing the OF graph to find the UART). If that's
> the desired way then the connector binding should mention it. And that
> works for me. But I think it's messier and also we're missing an
> opportunity to make the M.2 connector a standardized attachment point
> for overlays.
>
> Mani, could you also chime in a bit on what you envisioned?
>
> (Added Luca from Bootlin to CC, as I think there are parallels to the
> "Hotplug of Non-discoverable Hardware" work)
>
Related to "Hotplug of Non-discoverable Hardware",
I would add entries for busses in the connector without using an OF graph.
For I2C and later SPI, this was is done.
You already have an i2c-parent property but no node where an i2c device
can be added.
The last discussion related to hotplug, connectors and DT led to the RFC
series [1].
It is a huge series. The last patch give a real example of representation:
https://lore.kernel.org/all/20260112142009.1006236-78-herve.codina@bootlin.com/
In your case I would see some thing like:
connector {
compatible = "pcie-m2-e-connector";
vpcie3v3-supply = <&vreg_wcn_3p3>;
vpcie1v8-supply = <&vreg_l15b_1p8>;
/*
* If those GPIOs have to be used by components available in
* the connected board, a Nexus node should be used.
*/
w-disable1-gpios = <&tlmm 115 GPIO_ACTIVE_LOW>;
w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>;
viocfg-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>;
uart-wake-gpios = <&tlmm 118 GPIO_ACTIVE_LOW>;
sdio-wake-gpios = <&tlmm 119 GPIO_ACTIVE_LOW>;
sdio-reset-gpios = <&tlmm 120 GPIO_ACTIVE_LOW>;
conn-i2c {
i2c-parent = <&i2c0>;
/*
* Here i2c devices available on the board
* connected to the connector can be described.
*/
};
/* Same kind to description for other busses */
conn-pcie {
pci-parent = <&xxxxx>;
/*
* The PCIe bus has abilities to discover devices.
* Not sure this node is needed.
*
* If a PCI device need a DT description to describe
* stuffs behind the device, what has been done for LAN966x
* could be re-used [2] and [3]
*/
};
conn_uart {
uart-parent = <&uart-ctrl>;
/* uart child (maybe a serdes) should be describe here
};
...
};
Of course, some DT symbols need to be exported in order to have them usable from
the DT describing the connected board.
This notion of exported symbol is not yet available upstream and is the purpose of
the RFC series [1].
[1] https://lore.kernel.org/all/20260112142009.1006236-1-herve.codina@bootlin.com/
[2] https://elixir.bootlin.com/linux/v7.0/source/drivers/misc/lan966x_pci.c
[3] https://elixir.bootlin.com/linux/v7.0/source/drivers/misc/lan966x_pci.dtso
Feel free to ask for more specific question if needed.
Best regards,
Hervé
>
> Thanks
> ChenYu
>
>
> > > The latter part is solvable, but we likely need child nodes under the
> > > connector for the different interfaces. Properties that make sense for
> > > one type might not make sense for another.
> > >
> > > P.S. We could also just add child device nodes under the controller to
> > > put the generic properties, but that's splitting the description into
> > > multiple parts. Let's not go there if at all possible.
> >
> > --
> > With Best Regards,
> > Andy Shevchenko
> >
> >
--
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH BlueZ v4 3/3] profiles: ranging: Add HCI LE Event Handling in Reflector role
From: Naga Bhavani Akella @ 2026-04-15 14:49 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: linux-bluetooth, quic_mohamull, quic_hbandi, quic_anubhavg,
prathibha.madugonde
In-Reply-To: <CABBYNZJoF1X0Rs+CV441to=xv8--C2XOwkBSa6MigfF-+q86Mg@mail.gmail.com>
Hi Luiz,
Thank you for the review comments.
On 4/13/2026 7:38 PM, Luiz Augusto von Dentz wrote:
> Hi Naga,
>
> On Mon, Apr 13, 2026 at 6:41 AM Naga Bhavani Akella
> <naga.akella@oss.qualcomm.com> wrote:
>>
>> Open RAW HCI Channel for CS Event Handling
>> Parse the following HCI LE CS Events in reflector role
>> and route the events to RAP Profile.
>> 1. HCI_EVT_LE_CS_READ_RMT_SUPP_CAP_COMPLETE
>> 2. HCI_EVT_LE_CS_CONFIG_COMPLETE
>> 3. HCI_EVT_LE_CS_SECURITY_ENABLE_COMPLETE
>> 4. HCI_EVT_LE_CS_PROCEDURE_ENABLE_COMPLETE
>> 5. HCI_EVT_LE_CS_SUBEVENT_RESULT
>> 6. HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE
>> Send HCI_OP_LE_CS_SET_DEFAULT_SETTINGS to the controller
>> with default settings selected by the user.
>> Map connection handle received to device connection
>> ---
>> Makefile.plugins | 3 +-
>> profiles/ranging/rap.c | 83 ++-
>> profiles/ranging/rap_hci.c | 1288 ++++++++++++++++++++++++++++++++++++
>> 3 files changed, 1367 insertions(+), 7 deletions(-)
>> create mode 100644 profiles/ranging/rap_hci.c
>>
>> diff --git a/Makefile.plugins b/Makefile.plugins
>> index c9efadb45..ac667beda 100644
>> --- a/Makefile.plugins
>> +++ b/Makefile.plugins
>> @@ -89,7 +89,8 @@ builtin_modules += battery
>> builtin_sources += profiles/battery/battery.c
>>
>> builtin_modules += rap
>> -builtin_sources += profiles/ranging/rap.c
>> +builtin_sources += profiles/ranging/rap.c \
>> + profiles/ranging/rap_hci.c
>>
>> if SIXAXIS
>> builtin_modules += sixaxis
>> diff --git a/profiles/ranging/rap.c b/profiles/ranging/rap.c
>> index f03454c72..63682e318 100644
>> --- a/profiles/ranging/rap.c
>> +++ b/profiles/ranging/rap.c
>> @@ -17,6 +17,7 @@
>> #include "gdbus/gdbus.h"
>>
>> #include "bluetooth/bluetooth.h"
>> +#include "bluetooth/l2cap.h"
>> #include "bluetooth/uuid.h"
>>
>> #include "src/plugin.h"
>> @@ -34,12 +35,17 @@
>> #include "src/shared/rap.h"
>> #include "attrib/att.h"
>> #include "src/log.h"
>> +#include "src/btd.h"
>>
>> +#define USE_BT_HCI_RAW_CHANNEL 1
>
> Didn't I already comment that we shouldn't use the likes of if
> USE_BT_HCI_RAW_CHANNEL?
>
Addressed in v7.
>> struct rap_data {
>> struct btd_device *device;
>> struct btd_service *service;
>> struct bt_rap *rap;
>> unsigned int ready_id;
>> +#if USE_BT_HCI_RAW_CHANNEL
>> + struct bt_hci *hci;
>> +#endif
>> };
>>
>> static struct queue *sessions;
>> @@ -61,10 +67,10 @@ static void rap_debug(const char *str, void *user_data)
>>
>> static void rap_data_add(struct rap_data *data)
>> {
>> - DBG("%p", data);
>> + DBG("%p", (void *)data);
>>
>> if (queue_find(sessions, NULL, data)) {
>> - error("data %p already added", data);
>> + error("data %p already added", (void *)data);
>
> No idea why you are casting to void * on %p?
>
Addressed in v7.
>> return;
>> }
>>
>> @@ -95,13 +101,21 @@ static void rap_data_free(struct rap_data *data)
>> }
>>
>> bt_rap_ready_unregister(data->rap, data->ready_id);
>> +#if USE_BT_HCI_RAW_CHANNEL
>> + if (data->hci) {
>> + bt_rap_hci_sm_cleanup();
>> + bt_hci_unref(data->hci);
>> + }
>> +#endif
>> + /* Clean up HCI connection mappings */
>> + bt_rap_detach_hci(data->rap);
>> bt_rap_unref(data->rap);
>> free(data);
>> }
>>
>> static void rap_data_remove(struct rap_data *data)
>> {
>> - DBG("%p", data);
>> + DBG("%p", (void *)data);
>>
>> if (!queue_remove(sessions, data))
>> return;
>> @@ -118,7 +132,7 @@ static void rap_detached(struct bt_rap *rap, void *user_data)
>> {
>> struct rap_data *data;
>>
>> - DBG("%p", rap);
>> + DBG("%p", (void *)rap);
>>
>> data = queue_find(sessions, match_data, rap);
>> if (!data) {
>> @@ -131,7 +145,7 @@ static void rap_detached(struct bt_rap *rap, void *user_data)
>>
>> static void rap_ready(struct bt_rap *rap, void *user_data)
>> {
>> - DBG("%p", rap);
>> + DBG("%p", (void *)rap);
>> }
>>
>> static void rap_attached(struct bt_rap *rap, void *user_data)
>> @@ -140,7 +154,7 @@ static void rap_attached(struct bt_rap *rap, void *user_data)
>> struct bt_att *att;
>> struct btd_device *device;
>>
>> - DBG("%p", rap);
>> + DBG("%p", (void *)rap);
>>
>> data = queue_find(sessions, match_data, rap);
>> if (data) {
>> @@ -194,6 +208,22 @@ static int rap_probe(struct btd_service *service)
>> free(data);
>> return -EINVAL;
>> }
>> +#if USE_BT_HCI_RAW_CHANNEL
>> + int16_t hci_index = btd_adapter_get_index(adapter);
>> +
>> + data->hci = bt_hci_new_raw_device(hci_index);
>> + if (bt_rap_attach_hci(data->rap, data->hci)) {
>> + DBG("HCI raw channel initialized, hci%d", hci_index);
>> + bt_rap_hci_set_le_bcs_options(
>> + btd_opts.defaults.bcs.role,
>> + btd_opts.defaults.bcs.cs_sync_ant_sel,
>> + btd_opts.defaults.bcs.max_tx_power);
>
> BCS? Id called just bt_rap_set_options
>
Addressed in v7.
>> + } else {
>> + error("HCI raw channel not available (may be in use)");
>> + }
>> +#else /* USE_BT_HCI_RAW_CHANNEL */
>> + DBG("MGMT Events");
>> +#endif /* USE_BT_HCI_RAW_CHANNEL */
>>
>> rap_data_add(data);
>>
>> @@ -228,6 +258,10 @@ static int rap_accept(struct btd_service *service)
>> struct btd_device *device = btd_service_get_device(service);
>> struct bt_gatt_client *client = btd_device_get_gatt_client(device);
>> struct rap_data *data = btd_service_get_user_data(service);
>> + struct bt_att *att;
>> + const bdaddr_t *bdaddr;
>> + uint8_t bdaddr_type;
>> + uint16_t handle;
>> char addr[18];
>>
>> ba2str(device_get_address(device), addr);
>> @@ -243,6 +277,43 @@ static int rap_accept(struct btd_service *service)
>> return -EINVAL;
>> }
>>
>> + /* Set up connection handle mapping for CS event routing */
>> + att = bt_rap_get_att(data->rap);
>> + bdaddr = device_get_address(device);
>> + bdaddr_type = device_get_le_address_type(device);
>> +
>> + if (att && data->hci) {
>> + /* Use bt_hci_get_conn_info to find the connection handle
>> + * by iterating through all connections and matching bdaddr
>> + */
>> + struct bt_hci_conn_info conn_info;
>> + bool found = false;
>> +
>> + /* Try handles from 0x0001 to 0x0EFF
>> + * (valid LE connection handle range)
>> + */
>> + for (handle = 0x0001; handle <= 0x0EFF; handle++) {
>> + if (bt_hci_get_conn_info(data->hci, handle,
>> + &conn_info)) {
>> + /* Check if bdaddr matches */
>> + if (memcmp(conn_info.bdaddr, bdaddr, 6) == 0) {
>> + found = true;
>> + DBG("Found conn handle 0x%04X", handle);
>> + break;
>> + }
>> + }
>> + }
>
> Please no, we should use something like HCIGETCONNLIST, not mindlessly
> iterate through all handles to check the connection handle.
>
Addressed in v7.
>> +
>> + if (found) {
>> + DBG("Setting up handle mapping: handle=0x%04X", handle);
>> + bt_rap_set_conn_handle(data->rap, handle,
>> + (const uint8_t *)bdaddr,
>> + bdaddr_type);
>> + } else {
>> + error("Failed to find connection handle for device");
>> + }
>> + }
>> +
>> btd_service_connecting_complete(service, 0);
>>
>> return 0;
>> diff --git a/profiles/ranging/rap_hci.c b/profiles/ranging/rap_hci.c
>> new file mode 100644
>> index 000000000..b00719ae2
>> --- /dev/null
>> +++ b/profiles/ranging/rap_hci.c
>> @@ -0,0 +1,1288 @@
>> +// SPDX-License-Identifier: LGPL-2.1-or-later
>> +/*
>> + * BlueZ - Bluetooth protocol stack for Linux
>> + *
>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>> + */
>> +
>> +#ifdef HAVE_CONFIG_H
>> +#include <config.h>
>> +#endif
>> +
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <stdbool.h>
>> +#include <stddef.h>
>> +#include <unistd.h>
>> +#include <string.h>
>> +#include <endian.h>
>> +
>> +#include "lib/bluetooth/bluetooth.h"
>> +#include "src/shared/util.h"
>> +#include "src/shared/queue.h"
>> +#include "src/shared/rap.h"
>> +#include "src/log.h"
>> +#include "monitor/bt.h"
>> +
>> +#ifndef MIN
>> +#define MIN(a, b) ((a) < (b) ? (a) : (b))
>> +#endif
>> +
>> +/* CS State Definitions */
>> +enum cs_state_t {
>> + CS_INIT,
>> + CS_STOPPED,
>> + CS_STARTED,
>> + CS_WAIT_CONFIG_CMPLT,
>> + CS_WAIT_SEC_CMPLT,
>> + CS_WAIT_PROC_CMPLT,
>> + CS_HOLD,
>> + CS_UNSPECIFIED
>> +};
>> +
>> +const char *state_names[] = {
>> + "CS_INIT",
>> + "CS_STOPPED",
>> + "CS_STARTED",
>> + "CS_WAIT_CONFIG_CMPLT",
>> + "CS_WAIT_SEC_CMPLT",
>> + "CS_WAIT_PROC_CMPLT",
>> + "CS_HOLD",
>> + "CS_UNSPECIFIED"
>> +};
>> +
>> +/* Callback Function Type */
>> +typedef void (*cs_callback_t)(uint16_t length,
>> + const void *param, void *user_data);
>> +
>> +/* State Machine Context */
>> +struct cs_state_machine_t {
>> + enum cs_state_t current_state;
>> + enum cs_state_t old_state;
>> + struct bt_hci *hci;
>> + struct bt_rap *rap;
>> + unsigned int event_id;
>> + bool initiator;
>> + bool procedure_active;
>> +};
>> +
>> +struct cs_callback_map_t {
>> + enum cs_state_t state;
>> + cs_callback_t callback;
>> +};
>> +
>> +struct cs_callback_map_t cs_callback_map[] = {
>> + { CS_WAIT_CONFIG_CMPLT, bt_rap_hci_cs_config_complete_callback },
>> + { CS_WAIT_SEC_CMPLT, bt_rap_hci_cs_sec_enable_complete_callback },
>> + { CS_WAIT_PROC_CMPLT, bt_rap_hci_cs_procedure_enable_complete_callback }
>> +};
>> +
>> +#define CS_CALLBACK_MAP_SIZE ARRAY_SIZE(cs_callback_map)
>> +
>> +struct bt_rap_hci_cs_options cs_opt;
>> +struct cs_state_machine_t *sm;
>> +
>> +/* Connection Handle Mapping */
>> +struct rap_conn_mapping {
>> + uint16_t handle;
>> + uint8_t bdaddr[6];
>> + uint8_t bdaddr_type;
>> + struct bt_att *att;
>> + struct bt_rap *rap;
>> +};
>> +
>> +static struct queue *conn_mappings;
>> +
>> +/* Connection Mapping Helper Functions */
>> +static void mapping_free(void *data)
>> +{
>> + struct rap_conn_mapping *mapping = data;
>> +
>> + if (!mapping)
>> + return;
>> +
>> + free(mapping);
>> +}
>> +
>> +static bool match_mapping_handle(const void *a, const void *b)
>> +{
>> + const struct rap_conn_mapping *mapping = a;
>> + uint16_t handle = PTR_TO_UINT(b);
>> +
>> + return mapping->handle == handle;
>> +}
>> +
>> +static bool match_mapping_rap(const void *a, const void *b)
>> +{
>> + const struct rap_conn_mapping *mapping = a;
>> + const struct bt_rap *rap = b;
>> +
>> + return mapping->rap == rap;
>> +}
>> +
>> +static struct rap_conn_mapping *find_mapping_by_handle(uint16_t handle)
>> +{
>> + if (!conn_mappings)
>> + return NULL;
>> +
>> + return queue_find(conn_mappings, match_mapping_handle,
>> + UINT_TO_PTR(handle));
>> +}
>> +
>> +static bool add_conn_mapping(uint16_t handle, const uint8_t *bdaddr,
>> + uint8_t bdaddr_type, struct bt_att *att,
>> + struct bt_rap *rap)
>> +{
>> + struct rap_conn_mapping *mapping;
>> +
>> + if (!conn_mappings) {
>> + conn_mappings = queue_new();
>> + if (!conn_mappings)
>> + return false;
>> + }
>> +
>> + /* Check if mapping already exists */
>> + mapping = find_mapping_by_handle(handle);
>> + if (mapping) {
>> + /* Update existing mapping */
>> + if (bdaddr)
>> + memcpy(mapping->bdaddr, bdaddr, 6);
>> + mapping->bdaddr_type = bdaddr_type;
>> + mapping->att = att;
>> + mapping->rap = rap;
>> + return true;
>> + }
>> +
>> + /* Create new mapping */
>> + mapping = new0(struct rap_conn_mapping, 1);
>> + if (!mapping)
>> + return false;
>> +
>> + mapping->handle = handle;
>> + if (bdaddr)
>> + memcpy(mapping->bdaddr, bdaddr, 6);
>> + mapping->bdaddr_type = bdaddr_type;
>> + mapping->att = att;
>> + mapping->rap = rap;
>> +
>> + return queue_push_tail(conn_mappings, mapping);
>> +}
>> +
>> +static void remove_conn_mapping(uint16_t handle)
>> +{
>> + struct rap_conn_mapping *mapping;
>> +
>> + if (!conn_mappings)
>> + return;
>> +
>> + mapping = queue_remove_if(conn_mappings, match_mapping_handle,
>> + UINT_TO_PTR(handle));
>> + if (mapping)
>> + mapping_free(mapping);
>> +}
>> +
>> +static void remove_rap_mappings(struct bt_rap *rap)
>> +{
>> + if (!conn_mappings)
>> + return;
>> +
>> + queue_remove_all(conn_mappings, match_mapping_rap, rap,
>> + mapping_free);
>> +}
>> +
>> +static struct bt_rap *resolve_handle_to_rap(uint16_t handle,
>> + struct bt_hci *hci)
>> +{
>> + struct rap_conn_mapping *mapping;
>> + struct bt_hci_conn_info conn_info;
>> +
>> + /* First try to find in mapping cache */
>> + mapping = find_mapping_by_handle(handle);
>> + if (mapping && mapping->rap) {
>> + DBG("Found handle 0x%04X in mapping cache", handle);
>> + return mapping->rap;
>> + }
>> +
>> + /* Fallback: Try to get connection info via ioctl */
>> + if (hci && bt_hci_get_conn_info(hci, handle, &conn_info)) {
>> + DBG("Got connection info via ioctl for handle 0x%04X:", handle);
>> + DBG(" bdaddr=%02x:%02x:%02x:%02x:%02x:%02x link_type=0x%02x",
>> + conn_info.bdaddr[5], conn_info.bdaddr[4],
>> + conn_info.bdaddr[3], conn_info.bdaddr[2],
>> + conn_info.bdaddr[1], conn_info.bdaddr[0],
>> + conn_info.type);
>> + DBG(" Note: Cannot determine RAP instance from ioctl alone");
>
> Not sure what this is for? If it cannot be resolved with just the
> handle then why are you doing it?
>
Addressed in v7.
>> + }
>> +
>> + /* Profile layer should have called bt_rap_set_conn_handle() during
>> + * connection establishment. If we reach here, the mapping was not set.
>> + */
>> + DBG("No mapping found for handle 0x%04X", handle);
>> + DBG("Profile layer should call bt_rap_set_conn_handle() on connect");
>> +
>> + return NULL;
>> +}
>> +
>> +/* State Machine Functions */
>> +void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
>> + struct bt_hci *hci)
>> +{
>> + if (!sm)
>> + return;
>> +
>> + memset(sm, 0, sizeof(struct cs_state_machine_t));
>> + sm->current_state = CS_UNSPECIFIED;
>> + sm->rap = rap;
>> + sm->hci = hci;
>> + sm->initiator = false;
>> + sm->procedure_active = false;
>> +}
>> +
>> +void bt_rap_hci_sm_cleanup(void)
>> +{
>> + if (!sm)
>> + return;
>> +
>> + if (sm->event_id)
>> + bt_hci_unregister(sm->hci, sm->event_id);
>> +
>> + sm->current_state = CS_UNSPECIFIED;
>> + sm->rap = NULL;
>> + sm->hci = NULL;
>> + sm->procedure_active = false;
>> +
>> + free(sm);
>> +}
>> +
>> +void bt_rap_hci_set_le_bcs_options(uint8_t role, uint8_t cs_sync_ant_sel,
>> + int8_t max_tx_power)
>> +{
>> + cs_opt.role = role;
>> + cs_opt.cs_sync_ant_sel = cs_sync_ant_sel;
>> + cs_opt.max_tx_power = max_tx_power;
>> +}
>> +
>> +/* State Transition Logic */
>> +void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
>> +{
>> + if (!sm)
>> + return;
>> +
>> + if (sm->current_state == new_state)
>> + return;
>> +
>> + /* Validate state values before array access */
>> + if (sm->current_state > CS_UNSPECIFIED || new_state > CS_UNSPECIFIED) {
>> + DBG("[ERROR] Invalid state transition attempted\n");
>
> There is a error function to print errors.
>
Addressed in v7.
>> + return;
>> + }
>> +
>> + DBG("[STATE] Transition: %s → %s\n",
>> + state_names[sm->current_state],
>> + state_names[new_state]);
>> +
>> + sm->old_state = sm->current_state;
>> + sm->current_state = new_state;
>> +}
>> +
>> +enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
>> +{
>> + return sm ? sm->current_state : CS_UNSPECIFIED;
>> +}
>> +
>> +bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
>> +{
>> + return sm ? sm->procedure_active : false;
>> +}
>> +
>> +/* HCI Event Callbacks */
>> +static void rap_def_settings_done_cb(const void *data, uint8_t size,
>> + void *user_data)
>> +{
>> + struct bt_hci_rsp_le_cs_set_def_settings *rp;
>> + struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
>> +
>> + if (!sm || !data ||
>> + size < sizeof(struct bt_hci_rsp_le_cs_set_def_settings))
>> + return;
>> +
>> + DBG("[EVENT] CS default Setting Complete (size=0x%02X)\n", size);
>> +
>> + rp = (struct bt_hci_rsp_le_cs_set_def_settings *)data;
>> +
>> + if (cs_get_current_state(sm) != CS_INIT) {
>> + DBG("Event received in Wrong State!! Expected : CS_INIT");
>> + return;
>> + }
>> +
>> + if (rp->status == 0) {
>> + /* Success - proceed to configuration */
>> + cs_set_state(sm, CS_WAIT_CONFIG_CMPLT);
>> +
>> + /* Reflector role */
>> + DBG("Waiting for CS Config Completed event...\n");
>> + /* TODO: Initiator role - Send CS Config complete cmd */
>> + } else {
>> + /* Error - transition to stopped */
>> + DBG("[ERROR]CS Set default setting failed with status 0x%02X\n",
>> + rp->status);
>
> User error
>
Addressed in v7.
>> + cs_set_state(sm, CS_STOPPED);
>> + }
>> +}
>> +
>> +void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
>> + struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete *ev)
>> +{
>> + struct bt_hci_cmd_le_cs_set_def_settings cp;
>> + unsigned int status;
>> +
>> + memset(&cp, 0, sizeof(cp));
>> +
>> + if (ev->handle)
>> + cp.handle = ev->handle;
>> + cp.role_enable = cs_opt.role;
>> + cp.cs_sync_antenna_selection = cs_opt.cs_sync_ant_sel;
>> + cp.max_tx_power = cs_opt.max_tx_power;
>> +
>> + if (!sm || !sm->hci) {
>> + DBG("[ERR] Set Def Settings: sm or hci is null");
>> + return;
>> + }
>> +
>> + status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_SET_DEF_SETTINGS,
>> + &cp, sizeof(cp), rap_def_settings_done_cb,
>> + sm, NULL);
>> +
>> + DBG("sending set default settings case, status : %d", status);
>> + if (!status)
>> + DBG("Failed to send default settings cmd");
>> +}
>> +
>> +static void rap_rd_rmt_supp_cap_cmplt_evt(const uint8_t *data, uint8_t size,
>> + void *user_data)
>> +{
>> + struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
>> + const struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete *evt;
>> + struct bt_rap *rap;
>> + struct iovec iov;
>> +
>> + if (!sm || !data ||
>> + size < sizeof(struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete))
>> + return;
>> +
>> + /* Initialize iovec with the event data */
>> + iov.iov_base = (void *)data;
>> + iov.iov_len = size;
>> +
>> + /* Pull the entire structure at once */
>> + evt = util_iov_pull_mem(&iov, sizeof(*evt));
>> + if (!evt) {
>> + DBG("[ERROR] Failed to pull remote cap complete struct\n");
>> + return;
>> + }
>> +
>> + DBG("[EVENT] Remote Capabilities Complete\n");
>> + DBG("status=0x%02X, handle=0x%04X\n", evt->status, evt->handle);
>> +
>> + /* Check status */
>> + if (evt->status != 0) {
>> + DBG("[ERROR] Remote capabilities failed with status 0x%02X\n",
>> + evt->status);
>> + cs_set_state(sm, CS_STOPPED);
>> + return;
>> + }
>> +
>> + /* Resolve handle to RAP instance */
>> + rap = resolve_handle_to_rap(evt->handle, sm->hci);
>> + if (!rap) {
>> + DBG("[WARN] Could not resolve handle 0x%04X to RAP instance\n",
>> + evt->handle);
>> + /* Continue with state machine RAP for now */
>> + rap = sm->rap;
>> + }
>> +
>> + DBG("[EVENT] Remote Capabilities: num_config=%u, ",
>> + evt->num_config_supported);
>> + DBG("max_consecutive_proc=%u, num_antennas=%u, ",
>> + evt->max_consecutive_procedures_supported,
>> + evt->num_antennas_supported);
>> + DBG("max_antenna_paths=%u, roles=0x%02X, modes=0x%02X\n",
>> + evt->max_antenna_paths_supported,
>> + evt->roles_supported,
>> + evt->modes_supported);
>> +
>> + rap_send_hci_def_settings_command(sm,
>> + (struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete *)evt);
>> + cs_set_state(sm, CS_INIT);
>> +}
>> +
>> +static void rap_cs_config_cmplt_evt(const uint8_t *data, uint8_t size,
>> + void *user_data)
>> +{
>> + struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
>> + const struct bt_hci_evt_le_cs_config_complete *evt;
>> + struct rap_ev_cs_config_cmplt rap_ev;
>> + struct iovec iov;
>> +
>> + if (!sm || !data ||
>> + size < sizeof(struct bt_hci_evt_le_cs_config_complete))
>> + return;
>> +
>> + /* Initialize iovec with the event data */
>> + iov.iov_base = (void *)data;
>> + iov.iov_len = size;
>> +
>> + DBG("[EVENT] Configuration Complete (size=0x%02X)\n", size);
>> +
>> + /* State Check */
>> + if (cs_get_current_state(sm) != CS_WAIT_CONFIG_CMPLT) {
>> + DBG("Event received in Wrong State!! ");
>> + DBG("Expected : CS_WAIT_CONFIG_CMPLT");
>> + return;
>> + }
>> +
>> + /* Pull the entire structure at once */
>> + evt = util_iov_pull_mem(&iov, sizeof(*evt));
>> + if (!evt) {
>> + DBG("[ERROR] Failed to pull config complete struct\n");
>> + return;
>> + }
>> +
>> + DBG("status=0x%02X, handle=0x%04X\n", evt->status, evt->handle);
>> +
>> + /* Check status */
>> + if (evt->status != 0) {
>> + DBG("[ERROR] Configuration failed with status 0x%02X\n",
>> + evt->status);
>> + cs_set_state(sm, CS_STOPPED);
>> + return;
>> + }
>> +
>> + /* Copy fields to rap_ev structure */
>> + rap_ev.status = evt->status;
>> + rap_ev.conn_hdl = cpu_to_le16(evt->handle);
>> + rap_ev.config_id = evt->config_id;
>> + rap_ev.action = evt->action;
>> + rap_ev.main_mode_type = evt->main_mode_type;
>> + rap_ev.sub_mode_type = evt->sub_mode_type;
>> + rap_ev.min_main_mode_steps = evt->min_main_mode_steps;
>> + rap_ev.max_main_mode_steps = evt->max_main_mode_steps;
>> + rap_ev.main_mode_rep = evt->main_mode_repetition;
>> + rap_ev.mode_0_steps = evt->mode_0_steps;
>> + rap_ev.role = evt->role;
>> + rap_ev.rtt_type = evt->rtt_type;
>> + rap_ev.cs_sync_phy = evt->cs_sync_phy;
>> + memcpy(rap_ev.channel_map, evt->channel_map, 10);
>> + rap_ev.channel_map_rep = evt->channel_map_repetition;
>> + rap_ev.channel_sel_type = evt->channel_selection_type;
>> + rap_ev.ch3c_shape = evt->ch3c_shape;
>> + rap_ev.ch3c_jump = evt->ch3c_jump;
>> + rap_ev.reserved = evt->reserved;
>> + rap_ev.t_ip1_time = evt->t_ip1_time;
>> + rap_ev.t_ip2_time = evt->t_ip2_time;
>> + rap_ev.t_fcs_time = evt->t_fcs_time;
>> + rap_ev.t_pm_time = evt->t_pm_time;
>> +
>> + /* Store rtt_type in global options */
>> + cs_opt.rtt_type = rap_ev.rtt_type;
>> +
>> + DBG("[EVENT] Config Complete: config_id=%u, action=%u, ",
>> + rap_ev.config_id, rap_ev.action);
>> + DBG("main_mode=%u, sub_mode=%u, role=%u, rtt_type=%u\n",
>> + rap_ev.main_mode_type, rap_ev.sub_mode_type,
>> + rap_ev.role, rap_ev.rtt_type);
>> +
>> + /* Success - proceed to Security enable complete */
>> + cs_set_state(sm, CS_WAIT_SEC_CMPLT);
>> +
>> + /* Reflector role */
>> + DBG("Waiting for security enable event...\n");
>> + /* TODO: Initiator role - Send CS Security enable cmd */
>> +
>> + /* Send Callback to RAP Profile */
>> + for (size_t i = 0; i < CS_CALLBACK_MAP_SIZE; i++) {
>> + if (cs_callback_map[i].state == sm->old_state) {
>> + cs_callback_map[i].callback(size, &rap_ev, sm->rap);
>> + return;
>> + }
>> + }
>> +}
>> +
>> +static void rap_cs_sec_enable_cmplt_evt(const uint8_t *data, uint8_t size,
>> + void *user_data)
>> +{
>> + struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
>> + struct rap_ev_cs_sec_enable_cmplt rap_ev;
>> + struct iovec iov;
>> + uint8_t status;
>> + uint16_t handle;
>> +
>> + if (!sm || !data ||
>> + size < sizeof(struct bt_hci_evt_le_cs_sec_enable_complete))
>> + return;
>> +
>> + /* Initialize iovec with the event data */
>> + iov.iov_base = (void *)data;
>> + iov.iov_len = size;
>> +
>> + DBG("[EVENT] Security Enable Complete (size=0x%02X)\n", size);
>> +
>> + /* State Check */
>> + if (cs_get_current_state(sm) != CS_WAIT_SEC_CMPLT) {
>> + DBG("Event received in Wrong State!! ");
>> + DBG("Expected : CS_WAIT_SEC_CMPLT");
>> + return;
>> + }
>> +
>> + /* Parse all fields in order using iovec */
>> + if (!util_iov_pull_u8(&iov, &status)) {
>> + DBG("[ERROR] Failed to parse Status\n");
>> + return;
>> + }
>> +
>> + if (!util_iov_pull_le16(&iov, &handle)) {
>> + DBG("[ERROR] Failed to parse Connection_Handle\n");
>> + return;
>> + }
>> +
>> + rap_ev.status = status;
>> + rap_ev.conn_hdl = cpu_to_le16(handle);
>> +
>> + DBG("[EVENT] Security Enable: status=0x%02X, handle=0x%04X\n",
>> + rap_ev.status, handle);
>> +
>> + if (rap_ev.status == 0) {
>> + /* Success - proceed to configuration */
>> + cs_set_state(sm, CS_WAIT_PROC_CMPLT);
>> +
>> + /* Reflector role */
>> + DBG("Waiting for CS Proc complete event...\n");
>> + /* TODO: Initiator - Send CS Proc Set Parameter and enable */
>> + } else {
>> + /* Error - transition to stopped */
>> + DBG("[ERROR] Security enable failed with status 0x%02X\n",
>> + rap_ev.status);
>> + cs_set_state(sm, CS_STOPPED);
>> + }
>> +
>> + /* Send Callback to RAP Profile */
>> + for (size_t i = 0; i < CS_CALLBACK_MAP_SIZE; i++) {
>> + if (cs_callback_map[i].state == sm->old_state) {
>> + cs_callback_map[i].callback(size, &rap_ev, sm->rap);
>> + return;
>> + }
>> + }
>> +}
>> +
>> +static void rap_cs_proc_enable_cmplt_evt(const uint8_t *data, uint8_t size,
>> + void *user_data)
>> +{
>> + struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
>> + const struct bt_hci_evt_le_cs_proc_enable_complete *evt;
>> + struct rap_ev_cs_proc_enable_cmplt rap_ev;
>> + struct iovec iov;
>> +
>> + if (!sm || !data ||
>> + size < sizeof(struct bt_hci_evt_le_cs_proc_enable_complete))
>> + return;
>> +
>> + /* Initialize iovec with the event data */
>> + iov.iov_base = (void *)data;
>> + iov.iov_len = size;
>> +
>> + DBG("[EVENT] Procedure Enable Complete (size=0x%02X)\n", size);
>
> DBG already prints the function name, so printing the event name again
> sounds repetitive.
>
Addressed in v7.
>> +
>> + /* State Check */
>> + if (cs_get_current_state(sm) != CS_WAIT_PROC_CMPLT) {
>> + DBG("Event received in Wrong State!! ");
>> + DBG("Expected : CS_WAIT_PROC_CMPLT");
>> + return;
>> + }
>> +
>> + /* Pull the entire structure at once */
>> + evt = util_iov_pull_mem(&iov, sizeof(*evt));
>> + if (!evt) {
>> + DBG("[ERROR] Failed to pull proc enable complete struct\n");
>> + return;
>> + }
>> +
>> + DBG("status=0x%02X, handle=0x%04X\n", evt->status, evt->handle);
>> +
>> + /* Check status */
>> + if (evt->status != 0) {
>> + DBG("[ERROR] Procedure enable failed with status 0x%02X\n",
>> + evt->status);
>> + cs_set_state(sm, CS_STOPPED);
>> + sm->procedure_active = false;
>> + return;
>> + }
>> +
>> + /* Copy fields to rap_ev structure */
>> + rap_ev.status = evt->status;
>> + rap_ev.conn_hdl = cpu_to_le16(evt->handle);
>> + rap_ev.config_id = evt->config_id;
>> + rap_ev.state = evt->state;
>> + rap_ev.tone_ant_config_sel = evt->tone_antenna_config_selection;
>> + rap_ev.sel_tx_pwr = evt->selected_tx_power;
>> + memcpy(rap_ev.sub_evt_len, evt->subevent_len, 3);
>> + rap_ev.sub_evts_per_evt = evt->subevents_per_event;
>> + rap_ev.sub_evt_intrvl = evt->subevent_interval;
>> + rap_ev.evt_intrvl = evt->event_interval;
>> + rap_ev.proc_intrvl = evt->procedure_interval;
>> + rap_ev.proc_counter = evt->procedure_count;
>> + rap_ev.max_proc_len = evt->max_procedure_len;
>> +
>> + DBG("[EVENT] Procedure Enable: config_id=%u, state=%u, ",
>> + rap_ev.config_id, rap_ev.state);
>> + DBG("sub_evts_per_evt=%u, evt_intrvl=%u, proc_intrvl=%u\n",
>> + rap_ev.sub_evts_per_evt, rap_ev.evt_intrvl,
>> + rap_ev.proc_intrvl);
>> +
>> + /* Success - procedure started */
>> + cs_set_state(sm, CS_STARTED);
>> + sm->procedure_active = true;
>> +
>> + /* Send Callback to RAP Profile */
>> + for (size_t i = 0; i < CS_CALLBACK_MAP_SIZE; i++) {
>> + if (cs_callback_map[i].state == sm->old_state) {
>> + cs_callback_map[i].callback(size, &rap_ev, sm->rap);
>> + return;
>> + }
>> + }
>> +}
>> +
>> +static void parse_i_q_sample(struct iovec *iov, int16_t *i_sample,
>> + int16_t *q_sample)
>> +{
>> + uint8_t bytes[3];
>> + uint32_t buffer;
>> + uint32_t i12;
>> + uint32_t q12;
>> +
>> + /* Pull 3 bytes from iovec */
>> + if (!util_iov_pull_u8(iov, &bytes[0]) ||
>> + !util_iov_pull_u8(iov, &bytes[1]) ||
>> + !util_iov_pull_u8(iov, &bytes[2])) {
>> + *i_sample = 0;
>> + *q_sample = 0;
>> + return;
>> + }
>
> Oh please, use util_iov_pull_le24
>
Addressed in v7.
>> +
>> + /* Reconstruct 24-bit buffer from 3 bytes */
>> + buffer = (uint32_t)bytes[0] | ((uint32_t)bytes[1] << 8) |
>> + ((uint32_t)bytes[2] << 16);
>
> No need to do this; just use util_iov_pull_le24
>
Addressed in v7.
>> + i12 = buffer & 0x0FFFU; /* bits 0..11 */
>> + q12 = (buffer >> 12) & 0x0FFFU; /* bits 12..23 */
>>
>> + /* Sign-extend 12-bit values to 16-bit */
>> + *i_sample = (int16_t)((int32_t)(i12 << 20) >> 20);
>> + *q_sample = (int16_t)((int32_t)(q12 << 20) >> 20);
>
> This sound a little too complicated, please quote the spec why this
> needs to be done this way, also this should have a pack/unpack macro
> helps for bit manipulation.
>
Addressed in v7.
Spec statements -
Tone PCT - Phase Correction Term (24 bits, including 12 LSBs to indicate the I sample
as a signed integer and 12 MSBs to indicate the Q sample as a signed
integer)
Packet PCT - Phase Correction Term (bits 0 to 11 are the I sample with type sint12, bits 12
to 23 are the Q sample with type sint12, and bits 24 to 31 are reserved for
future use)
>> +}
>> +
>> +/* Parse CS Mode 0 step data */
>> +static void parse_mode_zero_data(struct iovec *iov,
>> + struct cs_mode_zero_data *mode_data,
>> + uint8_t cs_role)
>> +{
>> + uint32_t freq_offset;
>> +
>> + if (iov->iov_len < 3) {
>> + DBG("Mode 0: too short (<3)");
>> + return;
>> + }
>> +
>> + util_iov_pull_u8(iov, &mode_data->packet_quality);
>> + util_iov_pull_u8(iov, &mode_data->packet_rssi_dbm);
>> + util_iov_pull_u8(iov, &mode_data->packet_ant);
>> + DBG("CS Step mode 0");
>> +
>> + if (cs_role == CS_INITIATOR && iov->iov_len >= 4) {
>> + util_iov_pull_le32(iov, &freq_offset);
>> + mode_data->init_measured_freq_offset = freq_offset;
>> + }
>> +}
>> +
>> +/* Parse CS Mode 1 step data */
>> +static void parse_mode_one_data(struct iovec *iov,
>> + struct cs_mode_one_data *mode_data,
>> + uint8_t cs_role, uint8_t cs_rtt_type)
>> +{
>> + uint16_t time_val;
>> +
>> + if (iov->iov_len < 4) {
>> + DBG("Mode 1: too short (<4)");
>> + return;
>> + }
>> +
>> + DBG("CS Step mode 1");
>> + util_iov_pull_u8(iov, &mode_data->packet_quality);
>> + util_iov_pull_u8(iov, &mode_data->packet_rssi_dbm);
>> + util_iov_pull_u8(iov, &mode_data->packet_ant);
>> + util_iov_pull_u8(iov, &mode_data->packet_nadm);
>> +
>> + if (iov->iov_len >= 2) {
>> + util_iov_pull_le16(iov, &time_val);
>> + if (cs_role == CS_REFLECTOR)
>> + mode_data->tod_toa_refl = time_val;
>> + else
>> + mode_data->toa_tod_init = time_val;
>> + }
>> +
>> + if ((cs_rtt_type == 0x01 || cs_rtt_type == 0x02) &&
>> + iov->iov_len >= 6) {
>> + int16_t i_val, q_val;
>> +
>> + parse_i_q_sample(iov, &i_val, &q_val);
>> + mode_data->packet_pct1.i_sample = i_val;
>> + mode_data->packet_pct1.q_sample = q_val;
>> +
>> + parse_i_q_sample(iov, &i_val, &q_val);
>> + mode_data->packet_pct2.i_sample = i_val;
>> + mode_data->packet_pct2.q_sample = q_val;
>> + }
>> +}
>> +
>> +/* Parse CS Mode 2 step data */
>> +static void parse_mode_two_data(struct iovec *iov,
>> + struct cs_mode_two_data *mode_data,
>> + uint8_t max_paths)
>> +{
>> + uint8_t k;
>> +
>> + if (iov->iov_len < 1) {
>> + DBG("Mode 2: too short (<1)");
>> + return;
>> + }
>> +
>> + util_iov_pull_u8(iov, &mode_data->ant_perm_index);
>> + DBG("CS Step mode 2, max paths : %d", max_paths);
>> +
>> + for (k = 0; k < max_paths; k++) {
>> + int16_t i_val, q_val;
>> +
>> + if (iov->iov_len < 4) {
>> + DBG("Mode 2: insufficient PCT for path %u (rem=%zu)",
>> + k, iov->iov_len);
>> + break;
>> + }
>> + parse_i_q_sample(iov, &i_val, &q_val);
>> + mode_data->tone_pct[k].i_sample = i_val;
>> + mode_data->tone_pct[k].q_sample = q_val;
>> +
>> + util_iov_pull_u8(iov, &mode_data->tone_quality_indicator[k]);
>> + DBG("tone_quality_indicator : %d",
>> + mode_data->tone_quality_indicator[k]);
>> + DBG("[i, q] : %d, %d",
>> + mode_data->tone_pct[k].i_sample,
>> + mode_data->tone_pct[k].q_sample);
>> + }
>> +}
>> +
>> +/* Parse CS Mode 3 step data */
>> +static void parse_mode_three_data(struct iovec *iov,
>> + struct cs_mode_three_data *mode_data,
>> + uint8_t cs_role, uint8_t cs_rtt_type,
>> + uint8_t max_paths)
>> +{
>> + uint8_t k;
>> + struct cs_mode_one_data *mode_one = &mode_data->mode_one_data;
>> + struct cs_mode_two_data *mode_two = &mode_data->mode_two_data;
>> +
>> + if (iov->iov_len < 4) {
>> + DBG("Mode 3: mode1 too short (<4)");
>> + return;
>> + }
>> +
>> + DBG("CS Step mode 3");
>> +
>> + /* Parse Mode 1 portion */
>> + parse_mode_one_data(iov, mode_one, cs_role, cs_rtt_type);
>> +
>> + /* Parse Mode 2 portion */
>> + if (iov->iov_len >= 1) {
>> + util_iov_pull_u8(iov, &mode_two->ant_perm_index);
>> + for (k = 0; k < max_paths; k++) {
>> + int16_t i_val, q_val;
>> +
>> + if (iov->iov_len < 4)
>> + break;
>> + parse_i_q_sample(iov, &i_val, &q_val);
>> + mode_two->tone_pct[k].i_sample = i_val;
>> + mode_two->tone_pct[k].q_sample = q_val;
>> +
>> + util_iov_pull_u8(iov,
>> + &mode_two->tone_quality_indicator[k]);
>> + }
>> + }
>> +}
>> +
>> +/* Parse a single CS step */
>> +static void parse_cs_step(struct iovec *iov, struct cs_step_data *step,
>> + uint8_t cs_role, uint8_t cs_rtt_type,
>> + uint8_t max_paths)
>> +{
>> + uint8_t mode;
>> + uint8_t chnl;
>> + uint8_t length;
>> +
>> + /* Check if we have enough data for the 3-byte header */
>> + if (iov->iov_len < 3) {
>> + DBG("Truncated header for step");
>> + return;
>> + }
>> +
>> + /* Read mode, channel, and length (3-byte header) */
>> + if (!util_iov_pull_u8(iov, &mode) ||
>> + !util_iov_pull_u8(iov, &chnl) ||
>> + !util_iov_pull_u8(iov, &length)) {
>> + DBG("Failed to read header for step");
>> + return;
>> + }
>> +
>> + DBG("event->step_data_len : %d", length);
>> +
>> + step->step_mode = mode;
>> + step->step_chnl = chnl;
>> + step->step_data_length = length;
>> +
>> + DBG("Step: mode=%u chnl=%u data_len=%u", mode, chnl, length);
>> +
>> + if (iov->iov_len < length) {
>> + DBG("Truncated payload for step (need %u, have %zu)",
>> + length, iov->iov_len);
>> + return;
>> + }
>> +
>> + /* Parse step data based on mode */
>> + switch (mode) {
>> + case CS_MODE_ZERO:
>> + parse_mode_zero_data(iov, &step->step_mode_data.mode_zero_data,
>> + cs_role);
>> + break;
>> + case CS_MODE_ONE:
>> + parse_mode_one_data(iov, &step->step_mode_data.mode_one_data,
>> + cs_role, cs_rtt_type);
>> + break;
>> + case CS_MODE_TWO:
>> + parse_mode_two_data(iov, &step->step_mode_data.mode_two_data,
>> + max_paths);
>> + break;
>> + case CS_MODE_THREE:
>> + parse_mode_three_data(iov,
>> + &step->step_mode_data.mode_three_data,
>> + cs_role, cs_rtt_type, max_paths);
>> + break;
>> + default:
>> + DBG("Unknown step mode %d", mode);
>> + /* Skip the entire step data */
>> + util_iov_pull(iov, length);
>> + break;
>> + }
>> +}
>> +
>> +static void rap_cs_subevt_result_evt(const uint8_t *data, uint8_t size,
>> + void *user_data)
>> +{
>> + struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
>> + struct rap_ev_cs_subevent_result *rap_ev;
>> + struct iovec iov;
>> + uint8_t cs_role;
>> + uint8_t cs_rtt_type;
>> + uint8_t max_paths;
>> + uint8_t steps;
>> + size_t send_len = 0;
>> + uint16_t handle;
>> + uint8_t config_id;
>> + uint16_t start_acl_conn_evt_counter;
>> + uint16_t proc_counter;
>> + uint16_t freq_comp;
>> + uint8_t ref_pwr_lvl;
>> + uint8_t proc_done_status;
>> + uint8_t subevt_done_status;
>> + uint8_t abort_reason;
>> + uint8_t num_ant_paths;
>> + uint8_t num_steps_reported;
>> + uint8_t i;
>> +
>> + if (!sm || !data ||
>> + size < sizeof(struct bt_hci_evt_le_cs_subevent_result))
>> + return;
>> +
>> + /* Initialize iovec with the event data */
>> + iov.iov_base = (void *)data;
>> + iov.iov_len = size;
>> +
>> + /* Check if Procedure is active or not */
>> + if (!sm->procedure_active) {
>> + DBG("Received Subevent event when Procedure is inactive!");
>> + return;
>> + }
>> +
>> + /* Parse header fields using iovec */
>> + if (!util_iov_pull_le16(&iov, &handle)) {
>> + DBG("[ERROR] Failed to parse Connection_Handle\n");
>> + return;
>> + }
>> +
>> + if (!util_iov_pull_u8(&iov, &config_id) ||
>> + !util_iov_pull_le16(&iov, &start_acl_conn_evt_counter) ||
>> + !util_iov_pull_le16(&iov, &proc_counter) ||
>> + !util_iov_pull_le16(&iov, &freq_comp) ||
>> + !util_iov_pull_u8(&iov, &ref_pwr_lvl) ||
>> + !util_iov_pull_u8(&iov, &proc_done_status) ||
>> + !util_iov_pull_u8(&iov, &subevt_done_status) ||
>> + !util_iov_pull_u8(&iov, &abort_reason) ||
>> + !util_iov_pull_u8(&iov, &num_ant_paths) ||
>> + !util_iov_pull_u8(&iov, &num_steps_reported)) {
>> + DBG("[ERROR] Failed to parse subevent fields\n");
>> + return;
>> + }
>> +
>> + cs_role = cs_opt.role;
>> + cs_rtt_type = cs_opt.rtt_type;
>> + max_paths = MIN((num_ant_paths + 1), CS_MAX_ANT_PATHS);
>> + steps = MIN(num_steps_reported, CS_MAX_STEPS);
>> + send_len = offsetof(struct rap_ev_cs_subevent_result, step_data) +
>> + steps * sizeof(struct cs_step_data);
>> + rap_ev = (struct rap_ev_cs_subevent_result *)malloc(send_len);
>> + if (!rap_ev) {
>> + DBG("[ERROR] Failed to allocate memory for subevent result\n");
>> + return;
>> + }
>> +
>> + DBG("[EVENT] Subevent Result (length=%u)\n", size);
>> + rap_ev->conn_hdl = le16_to_cpu(handle);
>> + rap_ev->config_id = config_id;
>> + rap_ev->start_acl_conn_evt_counter = start_acl_conn_evt_counter;
>> + rap_ev->proc_counter = proc_counter;
>> + rap_ev->freq_comp = freq_comp;
>> + rap_ev->ref_pwr_lvl = ref_pwr_lvl;
>> + rap_ev->proc_done_status = proc_done_status;
>> + rap_ev->subevt_done_status = subevt_done_status;
>> + rap_ev->abort_reason = abort_reason;
>> + rap_ev->num_ant_paths = num_ant_paths;
>> + rap_ev->num_steps_reported = steps;
>> +
>> + if (num_steps_reported > CS_MAX_STEPS) {
>> + DBG("Too many steps reported: %u (max %u)",
>> + num_steps_reported, CS_MAX_STEPS);
>> + goto send_event;
>> + }
>> +
>> + /* Early exit for error conditions */
>> + if (rap_ev->subevt_done_status == 0xF ||
>> + rap_ev->proc_done_status == 0xF) {
>> + DBG("CS Procedure/Subevent aborted: ");
>> + DBG("sub evt status = %d, proc status = %d, reason = %d",
>> + rap_ev->subevt_done_status, rap_ev->proc_done_status,
>> + rap_ev->abort_reason);
>> + goto send_event;
>> + }
>> +
>> + /* Parse interleaved step data from remaining iovec data */
>> + for (i = 0; i < steps; i++)
>> + parse_cs_step(&iov, &rap_ev->step_data[i], cs_role, cs_rtt_type,
>> + max_paths);
>> +
>> +send_event:
>> + DBG("CS subevent result processed: %zu bytes, ", send_len);
>> + bt_rap_hci_cs_subevent_result_callback(send_len, rap_ev, sm->rap);
>> + free(rap_ev);
>> +}
>> +
>> +static void rap_cs_subevt_result_cont_evt(const uint8_t *data, uint8_t size,
>> + void *user_data)
>> +{
>> + struct cs_state_machine_t *sm = (struct cs_state_machine_t *)user_data;
>> + struct rap_ev_cs_subevent_result_cont *rap_ev;
>> + struct iovec iov;
>> + uint8_t cs_role;
>> + uint8_t cs_rtt_type;
>> + uint8_t max_paths;
>> + uint8_t steps;
>> + size_t send_len = 0;
>> + uint16_t handle;
>> + uint8_t config_id;
>> + uint8_t proc_done_status;
>> + uint8_t subevt_done_status;
>> + uint8_t abort_reason;
>> + uint8_t num_ant_paths;
>> + uint8_t num_steps_reported;
>> + uint8_t i;
>> +
>> + if (!sm || !data ||
>> + size < sizeof(struct bt_hci_evt_le_cs_subevent_result_continue))
>> + return;
>> +
>> + /* Initialize iovec with the event data */
>> + iov.iov_base = (void *)data;
>> + iov.iov_len = size;
>> +
>> + /* Check if Procedure is active or not */
>> + if (!sm->procedure_active) {
>> + DBG("Received Subevent when CS Procedure is inactive!");
>> + return;
>> + }
>> +
>> + /* Parse header fields using iovec */
>> + if (!util_iov_pull_le16(&iov, &handle)) {
>> + DBG("[ERROR] Failed to parse Connection_Handle\n");
>> + return;
>> + }
>> +
>> + if (!util_iov_pull_u8(&iov, &config_id) ||
>> + !util_iov_pull_u8(&iov, &proc_done_status) ||
>> + !util_iov_pull_u8(&iov, &subevt_done_status) ||
>> + !util_iov_pull_u8(&iov, &abort_reason) ||
>> + !util_iov_pull_u8(&iov, &num_ant_paths) ||
>> + !util_iov_pull_u8(&iov, &num_steps_reported)) {
>> + DBG("[ERROR] Failed to parse subevent continue fields ");
>> + return;
>> + }
>> +
>> + cs_role = cs_opt.role;
>> + cs_rtt_type = cs_opt.rtt_type;
>> + max_paths = MIN((num_ant_paths + 1), CS_MAX_ANT_PATHS);
>> + steps = MIN(num_steps_reported, CS_MAX_STEPS);
>> + send_len = offsetof(struct rap_ev_cs_subevent_result_cont, step_data) +
>> + steps * sizeof(struct cs_step_data);
>> + rap_ev = (struct rap_ev_cs_subevent_result_cont *)malloc(send_len);
>> + if (!rap_ev) {
>> + DBG("[ERROR] Failed to allocate memory for subevent result\n");
>> + return;
>> + }
>> +
>> + DBG("[EVENT] Subevent Result Cont (length=%u)\n", size);
>> + rap_ev->conn_hdl = le16_to_cpu(handle);
>> + rap_ev->config_id = config_id;
>> + rap_ev->proc_done_status = proc_done_status;
>> + rap_ev->subevt_done_status = subevt_done_status;
>> + rap_ev->abort_reason = abort_reason;
>> + rap_ev->num_ant_paths = num_ant_paths;
>> + rap_ev->num_steps_reported = steps;
>> +
>> + if (num_steps_reported > CS_MAX_STEPS) {
>> + DBG("Too many steps reported: %u (max %u)",
>> + num_steps_reported, CS_MAX_STEPS);
>> + goto send_event;
>> + }
>> +
>> + /* Early exit for error conditions */
>> + if (rap_ev->subevt_done_status == 0xF ||
>> + rap_ev->proc_done_status == 0xF) {
>> + DBG("CS Procedure/Subevent aborted: ");
>> + DBG("sub evt status = %d, proc status = %d, reason = %d",
>> + rap_ev->subevt_done_status, rap_ev->proc_done_status,
>> + rap_ev->abort_reason);
>> + goto send_event;
>> + }
>> +
>> + /* Parse interleaved step data from remaining iovec data */
>> + for (i = 0; i < steps; i++)
>> + parse_cs_step(&iov, &rap_ev->step_data[i], cs_role, cs_rtt_type,
>> + max_paths);
>> +
>> +send_event:
>> + DBG("CS subevent result cont processed: %zu bytes, ", send_len);
>> + bt_rap_hci_cs_subevent_result_cont_callback(send_len, rap_ev, sm->rap);
>> + free(rap_ev);
>> +}
>> +
>> +/* Subevent handler function type */
>> +typedef void (*subevent_handler_t)(const uint8_t *data, uint8_t size,
>> + void *user_data);
>> +
>> +/* Subevent table entry */
>> +struct subevent_entry {
>> + uint8_t opcode;
>> + uint8_t min_len;
>> + uint8_t max_len;
>> + subevent_handler_t handler;
>> + const char *name;
>> +};
>> +
>> +/* Subevent dispatch table */
>> +static const struct subevent_entry subevent_table[] = {
>> + {
>> + .opcode = BT_HCI_EVT_LE_CS_RD_REM_SUPP_CAP_COMPLETE,
>> + .min_len = sizeof(
>> + struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete),
>> + .max_len = 0xFF,
>> + .handler = rap_rd_rmt_supp_cap_cmplt_evt,
>> + .name = "CS Read Remote Supported Capabilities Complete"
>> + },
>
> Have a macro to define each entry, HCI_EVT(...), that way we don't
> need to enter the struct field names.
>
Addressed in v7.
>> + {
>> + .opcode = BT_HCI_EVT_LE_CS_CONFIG_COMPLETE,
>> + .min_len = sizeof(struct bt_hci_evt_le_cs_config_complete),
>> + .max_len = 0xFF,
>> + .handler = rap_cs_config_cmplt_evt,
>> + .name = "CS Config Complete"
>> + },
>> + {
>> + .opcode = BT_HCI_EVT_LE_CS_SEC_ENABLE_COMPLETE,
>> + .min_len = sizeof(struct bt_hci_evt_le_cs_sec_enable_complete),
>> + .max_len = 0xFF,
>> + .handler = rap_cs_sec_enable_cmplt_evt,
>> + .name = "CS Security Enable Complete"
>> + },
>> + {
>> + .opcode = BT_HCI_EVT_LE_CS_PROC_ENABLE_COMPLETE,
>> + .min_len = sizeof(struct bt_hci_evt_le_cs_proc_enable_complete),
>> + .max_len = 0xFF,
>> + .handler = rap_cs_proc_enable_cmplt_evt,
>> + .name = "CS Procedure Enable Complete"
>> + },
>> + {
>> + .opcode = BT_HCI_EVT_LE_CS_SUBEVENT_RESULT,
>> + .min_len = sizeof(struct bt_hci_evt_le_cs_subevent_result),
>> + .max_len = 0xFF,
>> + .handler = rap_cs_subevt_result_evt,
>> + .name = "CS Subevent Result"
>> + },
>> + {
>> + .opcode = BT_HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE,
>> + .min_len = sizeof(
>> + struct bt_hci_evt_le_cs_subevent_result_continue),
>> + .max_len = 0xFF,
>> + .handler = rap_cs_subevt_result_cont_evt,
>> + .name = "CS Subevent Result Continue"
>> + }
>> +};
>> +
>> +#define SUBEVENT_TABLE_SIZE ARRAY_SIZE(subevent_table)
>> +
>> +/* HCI Event Registration */
>> +static void rap_handle_hci_events(const void *data, uint8_t size,
>> + void *user_data)
>> +{
>> + struct iovec iov;
>> + uint8_t subevent;
>> + const struct subevent_entry *entry = NULL;
>> + size_t i;
>> +
>> + /* Initialize iovec with the event data */
>> + iov.iov_base = (void *)data;
>> + iov.iov_len = size;
>> +
>> + /* Pull the subevent code */
>> + if (!util_iov_pull_u8(&iov, &subevent)) {
>> + DBG("Failed to parse subevent code");
>> + return;
>> + }
>> +
>> + /* Find the subevent in the table */
>> + for (i = 0; i < SUBEVENT_TABLE_SIZE; i++) {
>> + if (subevent_table[i].opcode == subevent) {
>> + entry = &subevent_table[i];
>> + break;
>> + }
>> + }
>> +
>> + /* Check if subevent is supported */
>> + if (!entry) {
>> + DBG("Unknown subevent: 0x%02X", subevent);
>> + return;
>> + }
>> +
>> + /* Validate payload length */
>> + if (iov.iov_len < entry->min_len) {
>> + DBG("%s: payload too short (%zu < %u)",
>> + entry->name, iov.iov_len, entry->min_len);
>> + return;
>> + }
>> +
>> + if (entry->max_len != 0xFF && iov.iov_len > entry->max_len) {
>> + DBG("%s: payload too long (%zu > %u)",
>> + entry->name, iov.iov_len, entry->max_len);
>> + return;
>> + }
>> +
>> + /* Call the handler */
>> + DBG("Handling %s (opcode=0x%02X, len=%zu)",
>> + entry->name, subevent, iov.iov_len);
>> +
>> + entry->handler(iov.iov_base, iov.iov_len, user_data);
>> +}
>> +
>> +void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
>> +{
>> + if (!rap || !hci)
>> + return;
>> +
>> + sm = new0(struct cs_state_machine_t, 1);
>> + if (!sm) {
>> + DBG("[ERROR] Failed to allocate state machine\n");
>> + return;
>> + }
>> +
>> + cs_state_machine_init(sm, rap, hci);
>> + sm->event_id = bt_hci_register(hci, BT_HCI_EVT_LE_META_EVENT,
>> + rap_handle_hci_events, sm, NULL);
>> +
>> + DBG("bt_hci_register done, event_id : %d", sm->event_id);
>> +
>> + if (!sm->event_id) {
>> + DBG("Error: Failed to register hci le meta events ");
>> + DBG("event_id=0x%02X\n", sm->event_id);
>> + free(sm);
>> + return;
>> + }
>> +}
>> +
>> +bool bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci)
>> +{
>> + if (!rap)
>> + return false;
>> +
>> + if (!hci) {
>> + DBG("Failed to create HCI RAW channel ");
>> + bt_hci_unref(hci);
>> + return false;
>> + }
>> +
>> + bt_rap_hci_register_events(rap, hci);
>> +
>> + return true;
>> +}
>> +
>> +bool bt_rap_set_conn_handle(struct bt_rap *rap, uint16_t handle,
>> + const uint8_t *bdaddr, uint8_t bdaddr_type)
>> +{
>> + struct bt_att *att;
>> +
>> + if (!rap)
>> + return false;
>> +
>> + att = bt_rap_get_att(rap);
>> + if (!att)
>> + return false;
>> +
>> + DBG("Setting connection mapping: handle=0x%04X, ", handle);
>> + if (bdaddr) {
>> + DBG("bdaddr=%02x:%02x:%02x:%02x:%02x:%02x type=%u",
>> + bdaddr[5], bdaddr[4], bdaddr[3],
>> + bdaddr[2], bdaddr[1], bdaddr[0], bdaddr_type);
>> + }
>> +
>> + return add_conn_mapping(handle, bdaddr, bdaddr_type, att, rap);
>> +}
>> +
>> +void bt_rap_clear_conn_handle(struct bt_rap *rap, uint16_t handle)
>> +{
>> + if (!rap)
>> + return;
>> +
>> + DBG("Clearing connection mapping: handle=0x%04X", handle);
>> + remove_conn_mapping(handle);
>> +}
>> +
>> +void bt_rap_detach_hci(struct bt_rap *rap)
>> +{
>> + if (!rap)
>> + return;
>> +
>> + DBG("Detaching RAP from HCI, cleaning up mappings");
>> +
>> + /* Remove all mappings associated with this RAP instance */
>> + remove_rap_mappings(rap);
>> +}
>> --
>>
>
>
^ permalink raw reply
* Re: [PATCH] Bluetooth: btusb: Add Mercusys MA530 HWID 0x2c4e/0x0115 for Realtek 8761BUV
From: Kryštof Korb @ 2026-04-15 14:47 UTC (permalink / raw)
To: Michal Piernik
Cc: Marcel Holtmann, Luiz Augusto von Dentz, linux-bluetooth,
linux-kernel
In-Reply-To: <20250225155825.1504841-1-mprnk@o2.pl>
Tested-by: Kryštof Korb <krystof@korb.cz>
Confirmed working on a device reporting as "MERCUSYS Bluetooth Adapter"
(USB ID 2c4e:0115, bcdDevice 2.00), retail product Mercusys MA550H.
Same RTL8761BU chipset, identical firmware load sequence.
Seems the USB ID 2c4e:0115 covers at least two distinct retail
products (MA530 and MA550H) from the same vendor.
/sys/kernel/debug/usb/devices excerpt:
P: Vendor=2c4e ProdID=0115 Rev= 2.00
S: Manufacturer=
S: Product=MERCUSYS Bluetooth Adapter
S: SerialNumber=088AF177D360
dmesg:
Bluetooth: hci0: RTL: examining hci_ver=0a hci_rev=000b lmp_ver=0a lmp_subver=8761
Bluetooth: hci0: RTL: rom_version status=0 version=1
Bluetooth: hci0: RTL: loading rtl_bt/rtl8761bu_fw.bin
Bluetooth: hci0: RTL: loading rtl_bt/rtl8761bu_config.bin
Bluetooth: hci0: RTL: cfg_sz 6, total sz 30210
Bluetooth: hci0: RTL: fw version 0xdfc6d922
> 25. 2. 2025 v 16:58, Michal Piernik <mprnk@o2.pl>:
>
> /sys/kernel/debug/usb/devices:
> T: Bus=03 Lev=01 Prnt=01 Port=05 Cnt=03 Dev#= 4 Spd=12 MxCh= 0
> D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
> P: Vendor=2c4e ProdID=0115 Rev= 2.00
> S: Manufacturer=
> S: Product=Mercusys MA530 Adapter
> S: SerialNumber=30169D905719
> C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
> I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
> E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
> E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
> I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
> E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
> I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
> E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
> I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
> E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
> I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
> E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
> I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
> E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
> I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
> E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
>
> dmesg:
> [11106.761376] Bluetooth: hci0: RTL: examining hci_ver=0a hci_rev=000b lmp_ver=0a lmp_subver=8761
> [11106.762370] Bluetooth: hci0: RTL: rom_version status=0 version=1
> [11106.762374] Bluetooth: hci0: RTL: loading rtl_bt/rtl8761bu_fw.bin
> [11106.762554] Bluetooth: hci0: RTL: loading rtl_bt/rtl8761bu_config.bin
> [11106.762579] Bluetooth: hci0: RTL: cfg_sz 6, total sz 30210
> [11106.910393] Bluetooth: hci0: RTL: fw version 0xdfc6d922
> [11106.977569] Bluetooth: MGMT ver 1.22
>
> Signed-off-by: Michal Piernik <mprnk@o2.pl>
> ---
> drivers/bluetooth/btusb.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index f5609110f..0fc1dde8f 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -739,6 +739,8 @@ static const struct usb_device_id quirks_table[] = {
> { USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK },
>
> /* Additional Realtek 8761BUV Bluetooth devices */
> + { USB_DEVICE(0x2c4e, 0x0115), .driver_info = BTUSB_REALTEK |
> + BTUSB_WIDEBAND_SPEECH },
> { USB_DEVICE(0x2357, 0x0604), .driver_info = BTUSB_REALTEK |
> BTUSB_WIDEBAND_SPEECH },
> { USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK |
> --
> 2.34.1
>
>
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Add Broadcom channel priority commands
From: Sasha Finkelstein @ 2026-04-15 12:33 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Sven Peter, Janne Grunau, Neal Gompa, Marcel Holtmann,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-kernel, asahi, linux-arm-kernel,
linux-bluetooth, netdev
In-Reply-To: <CABBYNZJAEqwfTuVqbFAnx97HBSjcwn3Hb+y+r4r2C=MMPxFoDg@mail.gmail.com>
On Tue, 14 Apr 2026 at 16:00, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> > + if (sock)
> > + set_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags);
>
> This is more complicated than it needs to be. I'd just add a new
> callback, `hdev->set_priority(handle, skb->priority)`, so the driver
> is called whenever it needs to elevate a connection's priority, that
> said there could be cases where a connection needs its priority set
> momentarily to transmit A2DP, followed by OBEX packets that are best
> effort. Therefore, `hci_conn` will probably need to track the priority
> so it can detect when it needs changing on a per skb basis.
I have tested per-skb priorities, and unfortunately, this does not work.
If something tries to send a low-priority packet (for example - a volume
adjustment), a priority drop causes the same kind of dropout that is
caused by scans. It appears that the only way to make this hardware work
is to set the entire hci connection as high priority for as long as it
is being used to transmit audio.
^ permalink raw reply
* [bluetooth-next:master] BUILD SUCCESS 41388deeb99016b772801aa19ca7a3023d53826e
From: kernel test robot @ 2026-04-15 12:30 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
branch HEAD: 41388deeb99016b772801aa19ca7a3023d53826e Bluetooth: btusb: MT7925: Add VID/PID 0e8d/8c38
elapsed time: 907m
configs tested: 67
configs skipped: 1
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
alpha allyesconfig gcc-15.2.0
arc allmodconfig gcc-15.2.0
arc allnoconfig gcc-15.2.0
arc allyesconfig gcc-15.2.0
arc randconfig-001-20260415 gcc-13.4.0
arc randconfig-002-20260415 gcc-15.2.0
arm allnoconfig clang-23
arm allyesconfig gcc-15.2.0
arm64 allmodconfig clang-19
arm64 allnoconfig gcc-15.2.0
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
hexagon allmodconfig clang-17
hexagon allnoconfig clang-23
i386 allmodconfig gcc-14
i386 allnoconfig gcc-14
i386 allyesconfig gcc-14
loongarch allmodconfig clang-19
loongarch allnoconfig clang-23
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig gcc-15.2.0
m68k defconfig gcc-15.2.0
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig gcc-15.2.0
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig gcc-11.5.0
nios2 defconfig gcc-11.5.0
openrisc allmodconfig gcc-15.2.0
openrisc allnoconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig gcc-15.2.0
parisc allyesconfig gcc-15.2.0
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig gcc-15.2.0
riscv allmodconfig clang-23
riscv allnoconfig gcc-15.2.0
riscv allyesconfig clang-16
s390 allmodconfig clang-18
s390 allnoconfig clang-23
s390 allyesconfig gcc-15.2.0
sh allmodconfig gcc-15.2.0
sh allnoconfig gcc-15.2.0
sh allyesconfig gcc-15.2.0
sh defconfig gcc-15.2.0
sh polaris_defconfig gcc-15.2.0
sparc allnoconfig gcc-15.2.0
sparc64 allmodconfig clang-23
sparc64 defconfig clang-20
um allmodconfig clang-19
um allnoconfig clang-23
um allyesconfig gcc-14
um defconfig clang-23
um i386_defconfig gcc-14
um x86_64_defconfig clang-23
x86_64 allmodconfig clang-20
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 defconfig gcc-14
x86_64 rhel-9.4-rust clang-20
xtensa allnoconfig gcc-15.2.0
xtensa allyesconfig gcc-15.2.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* RE: Add initial Channel Sounding support -
From: bluez.test.bot @ 2026-04-15 12:26 UTC (permalink / raw)
To: linux-bluetooth, naga.akella
In-Reply-To: <20260415112510.195491-2-naga.akella@oss.qualcomm.com>
[-- Attachment #1: Type: text/plain, Size: 65473 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1081547
---Test result---
Test Summary:
CheckPatch PASS 2.32 seconds
GitLint PASS 0.87 seconds
BuildEll PASS 20.15 seconds
BluezMake FAIL 636.03 seconds
MakeCheck FAIL 21.16 seconds
MakeDistcheck PASS 244.58 seconds
CheckValgrind FAIL 213.29 seconds
CheckSmatch FAIL 342.71 seconds
bluezmakeextell FAIL 176.59 seconds
IncrementalBuild FAIL 681.37 seconds
ScanBuild FAIL 494.88 seconds
Details
##############################
Test: BluezMake - FAIL
Desc: Build BlueZ
Output:
tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12984:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12984 | int main(int argc, char *argv[])
| ^~~~
unit/test-avdtp.c: In function ‘main’:
unit/test-avdtp.c:766:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
766 | int main(int argc, char *argv[])
| ^~~~
unit/test-avrcp.c: In function ‘main’:
unit/test-avrcp.c:989:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
989 | int main(int argc, char *argv[])
| ^~~~
profiles/ranging/rap_hci.c:219:6: error: no previous declaration for ‘cs_state_machine_init’ [-Werror=missing-declarations]
219 | void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
| ^~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:258:6: error: no previous declaration for ‘cs_set_state’ [-Werror=missing-declarations]
258 | void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
| ^~~~~~~~~~~~
profiles/ranging/rap_hci.c:280:17: error: no previous declaration for ‘cs_get_current_state’ [-Werror=missing-declarations]
280 | enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:285:6: error: no previous declaration for ‘cs_is_procedure_active’ [-Werror=missing-declarations]
285 | bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:325:6: error: no previous declaration for ‘rap_send_hci_def_settings_command’ [-Werror=missing-declarations]
325 | void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:1186:6: error: no previous declaration for ‘bt_rap_hci_register_events’ [-Werror=missing-declarations]
1186 | void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
##############################
Test: MakeCheck - FAIL
Desc: Run Bluez Make Check
Output:
profiles/ranging/rap_hci.c:219:6: error: no previous declaration for ‘cs_state_machine_init’ [-Werror=missing-declarations]
219 | void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
| ^~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:258:6: error: no previous declaration for ‘cs_set_state’ [-Werror=missing-declarations]
258 | void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
| ^~~~~~~~~~~~
profiles/ranging/rap_hci.c:280:17: error: no previous declaration for ‘cs_get_current_state’ [-Werror=missing-declarations]
280 | enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:285:6: error: no previous declaration for ‘cs_is_procedure_active’ [-Werror=missing-declarations]
285 | bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:325:6: error: no previous declaration for ‘rap_send_hci_def_settings_command’ [-Werror=missing-declarations]
325 | void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:1186:6: error: no previous declaration for ‘bt_rap_hci_register_events’ [-Werror=missing-declarations]
1186 | void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make: *** [Makefile:10790: check] Error 2
##############################
Test: CheckValgrind - FAIL
Desc: Run Bluez Make Check with Valgrind
Output:
tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12984:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12984 | int main(int argc, char *argv[])
| ^~~~
profiles/ranging/rap_hci.c:219:6: error: no previous declaration for ‘cs_state_machine_init’ [-Werror=missing-declarations]
219 | void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
| ^~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:258:6: error: no previous declaration for ‘cs_set_state’ [-Werror=missing-declarations]
258 | void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
| ^~~~~~~~~~~~
profiles/ranging/rap_hci.c:280:17: error: no previous declaration for ‘cs_get_current_state’ [-Werror=missing-declarations]
280 | enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:285:6: error: no previous declaration for ‘cs_is_procedure_active’ [-Werror=missing-declarations]
285 | bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:325:6: error: no previous declaration for ‘rap_send_hci_def_settings_command’ [-Werror=missing-declarations]
325 | void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:1186:6: error: no previous declaration for ‘bt_rap_hci_register_events’ [-Werror=missing-declarations]
1186 | void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:10790: check] Error 2
##############################
Test: CheckSmatch - FAIL
Desc: Run smatch tool with source
Output:
src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:846:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1339:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1370:23: warning: Variable length array is used.
src/shared/gatt-server.c:279:25: warning: Variable length array is used.
src/shared/gatt-server.c:622:25: warning: Variable length array is used.
src/shared/gatt-server.c:720:25: warning: Variable length array is used.
src/shared/bap.c:312:25: warning: array of flexible structures
src/shared/bap.c: note: in included file:
./src/shared/ascs.h:88:25: warning: array of flexible structures
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:846:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1339:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1370:23: warning: Variable length array is used.
src/shared/gatt-server.c:279:25: warning: Variable length array is used.
src/shared/gatt-server.c:622:25: warning: Variable length array is used.
src/shared/gatt-server.c:720:25: warning: Variable length array is used.
src/shared/bap.c:312:25: warning: array of flexible structures
src/shared/bap.c: note: in included file:
./src/shared/ascs.h:88:25: warning: array of flexible structures
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
tools/mesh-cfgtest.c:1453:17: warning: unknown escape sequence: '\%'
tools/sco-tester.c: note: in included file:
./lib/bluetooth/bluetooth.h:232:15: warning: array of flexible structures
./lib/bluetooth/bluetooth.h:237:31: warning: array of flexible structures
tools/bneptest.c:634:39: warning: unknown escape sequence: '\%'
tools/seq2bseq.c:57:26: warning: Variable length array is used.
tools/obex-client-tool.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
client/btpclient/gatt.c: note: in included file:
./src/shared/btp.h:309:42: warning: array of flexible structures
src/advertising.c: note: in included file:
./src/shared/mgmt.h:95:25: error: redefinition of unsigned int enum mgmt_io_capability
src/adv_monitor.c: note: in included file:
./src/shared/mgmt.h:95:25: error: redefinition of unsigned int enum mgmt_io_capability
unit/avctp.c:505:34: warning: Variable length array is used.
unit/avctp.c:556:34: warning: Variable length array is used.
unit/test-avrcp.c:373:26: warning: Variable length array is used.
unit/test-avrcp.c:398:26: warning: Variable length array is used.
unit/test-avrcp.c:414:24: warning: Variable length array is used.
unit/avrcp-lib.c:1085:34: warning: Variable length array is used.
unit/avrcp-lib.c:1583:34: warning: Variable length array is used.
unit/avrcp-lib.c:1612:34: warning: Variable length array is used.
unit/avrcp-lib.c:1638:34: warning: Variable length array is used.
src/advertising.c: note: in included file:
./src/shared/mgmt.h:95:25: error: redefinition of unsigned int enum mgmt_io_capability
src/adv_monitor.c: note: in included file:
./src/shared/mgmt.h:95:25: error: redefinition of unsigned int enum mgmt_io_capability
mesh/mesh-io-mgmt.c:525:67: warning: Variable length array is used.
client/display.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:846:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1339:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1370:23: warning: Variable length array is used.
src/shared/gatt-server.c:279:25: warning: Variable length array is used.
src/shared/gatt-server.c:622:25: warning: Variable length array is used.
src/shared/gatt-server.c:720:25: warning: Variable length array is used.
src/shared/bap.c:312:25: warning: array of flexible structures
src/shared/bap.c: note: in included file:
./src/shared/ascs.h:88:25: warning: array of flexible structures
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
monitor/packet.c:2000:26: warning: Variable length array is used.
monitor/packet.c: note: in included file:
monitor/bt.h:3866:52: warning: array of flexible structures
monitor/bt.h:3854:40: warning: array of flexible structures
monitor/msft.c: note: in included file:
monitor/msft.h:88:44: warning: array of flexible structures
tools/rctest.c:631:33: warning: non-ANSI function declaration of function 'automated_send_recv'
tools/hex2hcd.c:136:26: warning: Variable length array is used.
tools/meshctl.c:324:33: warning: non-ANSI function declaration of function 'forget_mesh_devices'
tools/mesh-gatt/node.c:456:39: warning: non-ANSI function declaration of function 'node_get_local_node'
tools/mesh-gatt/net.c:1239:30: warning: non-ANSI function declaration of function 'get_next_seq'
tools/mesh-gatt/net.c:2193:29: warning: non-ANSI function declaration of function 'net_get_default_ttl'
tools/mesh-gatt/net.c:2207:26: warning: non-ANSI function declaration of function 'net_get_seq_num'
tools/mesh-gatt/prov.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
tools/mesh-gatt/onoff-model.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
ell/log.c:431:65: warning: non-ANSI function declaration of function 'register_debug_section'
ell/log.c:439:68: warning: non-ANSI function declaration of function 'free_debug_sections'
ell/random.c:60:42: warning: non-ANSI function declaration of function 'l_getrandom_is_supported'
ell/cipher.c:660:28: warning: non-ANSI function declaration of function 'init_supported'
ell/checksum.c:382:28: warning: non-ANSI function declaration of function 'init_supported'
ell/checksum.c:444:47: warning: non-ANSI function declaration of function 'l_checksum_cmac_aes_supported'
ell/cipher.c:519:24: warning: Variable length array is used.
ell/cert-crypto.c:36:33: warning: Variable length array is used.
ell/cert-crypto.c:142:36: warning: Variable length array is used.
ell/cert-crypto.c:198:36: warning: Variable length array is used.
ell/cert-crypto.c:251:31: warning: Variable length array is used.
ell/key.c:550:25: warning: Variable length array is used.
ell/dbus-service.c:548:49: warning: non-ANSI function declaration of function '_dbus_object_tree_new'
ell/dbus-filter.c:233:46: warning: Variable length array is used.
ell/tls.c:45:25: warning: Variable length array is used.
ell/tls.c:86:22: warning: Variable length array is used.
ell/tls.c:86:46: warning: Variable length array is used.
ell/tls.c:1819:26: warning: Variable length array is used.
ell/tls-suites.c:1079:25: warning: Variable length array is used.
ell/tls-suites.c:1081:34: warning: Variable length array is used.
ell/tls-suites.c:1084:41: warning: Variable length array is used.
ell/tls-suites.c:1133:41: warning: Variable length array is used.
emulator/btdev.c:468:29: warning: Variable length array is used.
emulator/bthost.c:703:28: warning: Variable length array is used.
emulator/bthost.c:704:32: warning: Variable length array is used.
emulator/bthost.c:944:28: warning: Variable length array is used.
emulator/bthost.c:978:28: warning: Variable length array is used.
emulator/bthost.c:979:32: warning: Variable length array is used.
attrib/gatttool.c:236:23: warning: Variable length array is used.
attrib/interactive.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
attrib/interactive.c:175:27: warning: non-ANSI function declaration of function 'disconnect_io'
attrib/interactive.c:300:23: warning: Variable length array is used.
profiles/ranging/rap_hci.c:219:6: error: no previous declaration for ‘cs_state_machine_init’ [-Werror=missing-declarations]
219 | void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
| ^~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:258:6: error: no previous declaration for ‘cs_set_state’ [-Werror=missing-declarations]
258 | void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
| ^~~~~~~~~~~~
profiles/ranging/rap_hci.c:280:17: error: no previous declaration for ‘cs_get_current_state’ [-Werror=missing-declarations]
280 | enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:285:6: error: no previous declaration for ‘cs_is_procedure_active’ [-Werror=missing-declarations]
285 | bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:325:6: error: no previous declaration for ‘rap_send_hci_def_settings_command’ [-Werror=missing-declarations]
325 | void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:1186:6: error: no previous declaration for ‘bt_rap_hci_register_events’ [-Werror=missing-declarations]
1186 | void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
##############################
Test: bluezmakeextell - FAIL
Desc: Build Bluez with External ELL
Output:
profiles/ranging/rap_hci.c:219:6: error: no previous declaration for ‘cs_state_machine_init’ [-Werror=missing-declarations]
219 | void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
| ^~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:258:6: error: no previous declaration for ‘cs_set_state’ [-Werror=missing-declarations]
258 | void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
| ^~~~~~~~~~~~
profiles/ranging/rap_hci.c:280:17: error: no previous declaration for ‘cs_get_current_state’ [-Werror=missing-declarations]
280 | enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:285:6: error: no previous declaration for ‘cs_is_procedure_active’ [-Werror=missing-declarations]
285 | bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:325:6: error: no previous declaration for ‘rap_send_hci_def_settings_command’ [-Werror=missing-declarations]
325 | void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:1186:6: error: no previous declaration for ‘bt_rap_hci_register_events’ [-Werror=missing-declarations]
1186 | void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
##############################
Test: IncrementalBuild - FAIL
Desc: Incremental build with the patches in the series
Output:
profiles/ranging/rap_hci.c:219:6: error: no previous declaration for ‘cs_state_machine_init’ [-Werror=missing-declarations]
219 | void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
| ^~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:258:6: error: no previous declaration for ‘cs_set_state’ [-Werror=missing-declarations]
258 | void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
| ^~~~~~~~~~~~
profiles/ranging/rap_hci.c:280:17: error: no previous declaration for ‘cs_get_current_state’ [-Werror=missing-declarations]
280 | enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:285:6: error: no previous declaration for ‘cs_is_procedure_active’ [-Werror=missing-declarations]
285 | bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:325:6: error: no previous declaration for ‘rap_send_hci_def_settings_command’ [-Werror=missing-declarations]
325 | void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:1186:6: error: no previous declaration for ‘bt_rap_hci_register_events’ [-Werror=missing-declarations]
1186 | void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
[BlueZ,v7,3/3] profiles: ranging: Add HCI LE Event Handling in Reflector role
profiles/ranging/rap_hci.c:219:6: error: no previous declaration for ‘cs_state_machine_init’ [-Werror=missing-declarations]
219 | void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
| ^~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:258:6: error: no previous declaration for ‘cs_set_state’ [-Werror=missing-declarations]
258 | void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
| ^~~~~~~~~~~~
profiles/ranging/rap_hci.c:280:17: error: no previous declaration for ‘cs_get_current_state’ [-Werror=missing-declarations]
280 | enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:285:6: error: no previous declaration for ‘cs_is_procedure_active’ [-Werror=missing-declarations]
285 | bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:325:6: error: no previous declaration for ‘rap_send_hci_def_settings_command’ [-Werror=missing-declarations]
325 | void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:1186:6: error: no previous declaration for ‘bt_rap_hci_register_events’ [-Werror=missing-declarations]
1186 | void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4159: all] Error 2
##############################
Test: ScanBuild - FAIL
Desc: Run Scan Build
Output:
src/shared/gatt-client.c:455:21: warning: Use of memory after it is freed
gatt_db_unregister(op->client->db, op->db_id);
^~~~~~~~~~
src/shared/gatt-client.c:700:2: warning: Use of memory after it is freed
discovery_op_complete(op, false, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1000:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1106:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1300:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1365:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1640:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1645:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1701:56: warning: Use of memory after it is freed
notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2154:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2162:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3340:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3362:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
13 warnings generated.
src/shared/bap.c:1529:8: warning: Use of memory after it is freed
bap = bt_bap_ref_safe(bap);
^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2340:20: warning: Use of memory after it is freed
return queue_find(stream->bap->streams, NULL, stream);
^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/shared/gatt-client.c:455:21: warning: Use of memory after it is freed
gatt_db_unregister(op->client->db, op->db_id);
^~~~~~~~~~
src/shared/gatt-client.c:700:2: warning: Use of memory after it is freed
discovery_op_complete(op, false, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1000:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1106:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1300:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1365:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1640:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1645:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1701:56: warning: Use of memory after it is freed
notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2154:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2162:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3340:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3362:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
13 warnings generated.
tools/hciattach.c:817:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 10)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:865:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:887:8: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 10)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:909:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:930:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:974:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 6)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 warnings generated.
src/shared/bap.c:1529:8: warning: Use of memory after it is freed
bap = bt_bap_ref_safe(bap);
^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2340:20: warning: Use of memory after it is freed
return queue_find(stream->bap->streams, NULL, stream);
^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/oui.c:50:2: warning: Value stored to 'hwdb' is never read
hwdb = udev_hwdb_unref(hwdb);
^ ~~~~~~~~~~~~~~~~~~~~~
src/oui.c:53:2: warning: Value stored to 'udev' is never read
udev = udev_unref(udev);
^ ~~~~~~~~~~~~~~~~
2 warnings generated.
tools/rfcomm.c:234:3: warning: Value stored to 'i' is never read
i = execvp(cmdargv[0], cmdargv);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:234:7: warning: Null pointer passed to 1st parameter expecting 'nonnull'
i = execvp(cmdargv[0], cmdargv);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:354:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd'
if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:497:14: warning: Assigned value is garbage or undefined
req.channel = raddr.rc_channel;
^ ~~~~~~~~~~~~~~~~
tools/rfcomm.c:515:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd'
if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
tools/ciptool.c:351:7: warning: 5th function call argument is an uninitialized value
sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/sdp-xml.c:126:10: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:306:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:344:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
3 warnings generated.
tools/sdptool.c:941:26: warning: Result of 'malloc' is converted to a pointer of type 'uint32_t', which is incompatible with sizeof operand type 'int'
uint32_t *value_int = malloc(sizeof(int));
~~~~~~~~~~ ^~~~~~ ~~~~~~~~~~~
tools/sdptool.c:980:4: warning: 1st function call argument is an uninitialized value
free(allocArray[i]);
^~~~~~~~~~~~~~~~~~~
tools/sdptool.c:3777:2: warning: Potential leak of memory pointed to by 'si.name'
return add_service(0, &si);
^~~~~~~~~~~~~~~~~~~~~~~~~~
tools/sdptool.c:4112:4: warning: Potential leak of memory pointed to by 'context.svc'
return -1;
^~~~~~~~~
4 warnings generated.
tools/avtest.c:243:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:253:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:262:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:276:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:283:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:290:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:297:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:309:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:313:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:322:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:326:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:335:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:342:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:364:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:368:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:377:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:381:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:394:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:398:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:405:4: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:415:4: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:580:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:588:3: warning: Value stored to 'len' is never read
len = write(sk, buf, invalid ? 2 : 3);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/avtest.c:602:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 4 + media_transport_size);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/avtest.c:615:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:625:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:637:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:652:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:664:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:673:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:680:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:716:2: warning: Value stored to 'len' is never read
len = write(sk, buf, AVCTP_HEADER_LENGTH + sizeof(play_pressed));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 warnings generated.
tools/btproxy.c:836:15: warning: Null pointer passed to 1st parameter expecting 'nonnull'
tcp_port = atoi(optarg);
^~~~~~~~~~~~
tools/btproxy.c:839:8: warning: Null pointer passed to 1st parameter expecting 'nonnull'
if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
^~~~~~~~~~~~~~
2 warnings generated.
tools/create-image.c:76:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:84:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:92:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:105:2: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
4 warnings generated.
tools/btgatt-client.c:1822:2: warning: Value stored to 'argv' is never read
argv += optind;
^ ~~~~~~
1 warning generated.
tools/check-selftest.c:42:3: warning: Value stored to 'ptr' is never read
ptr = fgets(result, sizeof(result), fp);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/btgatt-server.c:1208:2: warning: Value stored to 'argv' is never read
argv -= optind;
^ ~~~~~~
1 warning generated.
tools/gatt-service.c:294:2: warning: 2nd function call argument is an uninitialized value
chr_write(chr, value, len);
^~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/obex-server-tool.c:133:13: warning: Null pointer passed to 1st parameter expecting 'nonnull'
data->fd = open(name, O_WRONLY | O_CREAT | O_NOCTTY, 0600);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/obex-server-tool.c:192:13: warning: Null pointer passed to 1st parameter expecting 'nonnull'
data->fd = open(name, O_RDONLY | O_NOCTTY, 0);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
client/btpclient/btpclientctl.c:402:3: warning: Value stored to 'bit' is never read
bit = 0;
^ ~
client/btpclient/btpclientctl.c:1655:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
memcpy(cp->data, ad_data, ad_len);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/sdp-client.c:353:14: warning: Access to field 'cb' results in a dereference of a null pointer
(*ctxt)->cb = cb;
~~~~~~~~~~~~^~~~
1 warning generated.
src/sdpd-request.c:209:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint16_t'
pElem = malloc(sizeof(uint16_t));
^~~~~~ ~~~~~~~~~~~~~~~~
src/sdpd-request.c:237:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint32_t'
pElem = malloc(sizeof(uint32_t));
^~~~~~ ~~~~~~~~~~~~~~~~
2 warnings generated.
src/gatt-database.c:1175:10: warning: Value stored to 'bits' during its initialization is never read
uint8_t bits[] = { BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING,
^~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/gatt-client.c:1569:2: warning: Use of memory after it is freed
notify_client_unref(client);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
unit/avrcp-lib.c:1968:3: warning: 1st function call argument is an uninitialized value
g_free(text[i]);
^~~~~~~~~~~~~~~
1 warning generated.
unit/avdtp.c:756:25: warning: Use of memory after it is freed
session->prio_queue = g_slist_remove(session->prio_queue, req);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unit/avdtp.c:763:24: warning: Use of memory after it is freed
session->req_queue = g_slist_remove(session->req_queue, req);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
profiles/audio/avdtp.c:895:25: warning: Use of memory after it is freed
session->prio_queue = g_slist_remove(session->prio_queue, req);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/audio/avdtp.c:902:24: warning: Use of memory after it is freed
session->req_queue = g_slist_remove(session->req_queue, req);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
profiles/audio/a2dp.c:442:8: warning: Use of memory after it is freed
if (!cb->resume_cb)
^~~~~~~~~~~~~
profiles/audio/a2dp.c:3354:20: warning: Access to field 'starting' results in a dereference of a null pointer (loaded from variable 'stream')
stream->starting = TRUE;
~~~~~~ ^
profiles/audio/a2dp.c:3357:8: warning: Access to field 'suspending' results in a dereference of a null pointer (loaded from variable 'stream')
if (!stream->suspending && stream->suspend_timer) {
^~~~~~~~~~~~~~~~~~
profiles/audio/a2dp.c:3417:22: warning: Access to field 'suspending' results in a dereference of a null pointer (loaded from variable 'stream')
stream->suspending = TRUE;
~~~~~~ ^
4 warnings generated.
profiles/audio/avrcp.c:1968:2: warning: Value stored to 'operands' is never read
operands += sizeof(*pdu);
^ ~~~~~~~~~~~~
1 warning generated.
attrib/gatt.c:970:2: warning: Potential leak of memory pointed to by 'long_write'
return prepare_write(long_write);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/sdpd-request.c:209:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint16_t'
pElem = malloc(sizeof(uint16_t));
^~~~~~ ~~~~~~~~~~~~~~~~
src/sdpd-request.c:237:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint32_t'
pElem = malloc(sizeof(uint32_t));
^~~~~~ ~~~~~~~~~~~~~~~~
2 warnings generated.
src/sdp-client.c:353:14: warning: Access to field 'cb' results in a dereference of a null pointer
(*ctxt)->cb = cb;
~~~~~~~~~~~~^~~~
1 warning generated.
src/sdp-xml.c:126:10: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:306:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:344:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
3 warnings generated.
src/gatt-database.c:1175:10: warning: Value stored to 'bits' during its initialization is never read
uint8_t bits[] = { BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING,
^~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/gatt-client.c:1569:2: warning: Use of memory after it is freed
notify_client_unref(client);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-header.c:95:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
memcpy(to, from, count);
^~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-transfer.c:423:7: warning: Use of memory after it is freed
if (!g_slist_find(transfers, transfer))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
mesh/main.c:162:3: warning: Value stored to 'optarg' is never read
optarg += strlen("auto");
^ ~~~~~~~~~~~~~~
1 warning generated.
lib/bluetooth/hci.c:97:4: warning: Value stored to 'ptr' is never read
ptr += sprintf(ptr, "%s", m->str);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
client/player.c:2363:8: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
if (!strcmp(ep->path, pattern))
^~~~~~~~~~~~~~~~~~~~~~~~~
client/player.c:3640:16: warning: Null pointer passed to 1st parameter expecting 'nonnull'
codec->name = strdup(name);
^~~~~~~~~~~~
2 warnings generated.
gdbus/watch.c:226:3: warning: Attempt to free released memory
g_free(l->data);
^~~~~~~~~~~~~~~
1 warning generated.
lib/bluetooth/sdp.c:509:17: warning: Dereference of undefined pointer value
uint8_t dtd = *(uint8_t *) dtds[i];
^~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:539:17: warning: Dereference of undefined pointer value
uint8_t dtd = *(uint8_t *) dtds[i];
^~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:1885:26: warning: Potential leak of memory pointed to by 'ap'
for (; pdlist; pdlist = pdlist->next) {
^~~~~~
lib/bluetooth/sdp.c:1899:6: warning: Potential leak of memory pointed to by 'pds'
ap = sdp_list_append(ap, pds);
~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:1944:10: warning: Potential leak of memory pointed to by 'u'
*seqp = sdp_list_append(*seqp, u);
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:2049:4: warning: Potential leak of memory pointed to by 'lang'
sdp_list_free(*langSeq, free);
^~~~~~~~~~~~~
lib/bluetooth/sdp.c:2138:9: warning: Potential leak of memory pointed to by 'profDesc'
return 0;
^
lib/bluetooth/sdp.c:3270:8: warning: Potential leak of memory pointed to by 'pSvcRec'
pSeq = sdp_list_append(pSeq, pSvcRec);
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:3271:9: warning: Potential leak of memory pointed to by 'pSeq'
pdata += sizeof(uint32_t);
~~~~~~^~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:4607:13: warning: Potential leak of memory pointed to by 'rec_list'
} while (scanned < attr_list_len && pdata_len > 0);
^~~~~~~
lib/bluetooth/sdp.c:4903:40: warning: Potential leak of memory pointed to by 'tseq'
for (d = sdpdata->val.dataseq; d; d = d->next) {
^
lib/bluetooth/sdp.c:4939:8: warning: Potential leak of memory pointed to by 'subseq'
tseq = sdp_list_append(tseq, subseq);
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12 warnings generated.
src/shared/gatt-client.c:455:21: warning: Use of memory after it is freed
gatt_db_unregister(op->client->db, op->db_id);
^~~~~~~~~~
src/shared/gatt-client.c:700:2: warning: Use of memory after it is freed
discovery_op_complete(op, false, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1000:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1106:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1300:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1365:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1640:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1645:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1701:56: warning: Use of memory after it is freed
notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2154:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2162:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3340:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3362:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
13 warnings generated.
src/shared/bap.c:1529:8: warning: Use of memory after it is freed
bap = bt_bap_ref_safe(bap);
^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2340:20: warning: Use of memory after it is freed
return queue_find(stream->bap->streams, NULL, stream);
^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
monitor/l2cap.c:1676:4: warning: Value stored to 'data' is never read
data += len;
^ ~~~
monitor/l2cap.c:1677:4: warning: Value stored to 'size' is never read
size -= len;
^ ~~~
2 warnings generated.
monitor/hwdb.c:59:2: warning: Value stored to 'hwdb' is never read
hwdb = udev_hwdb_unref(hwdb);
^ ~~~~~~~~~~~~~~~~~~~~~
monitor/hwdb.c:64:2: warning: Value stored to 'udev' is never read
udev = udev_unref(udev);
^ ~~~~~~~~~~~~~~~~
monitor/hwdb.c:106:2: warning: Value stored to 'hwdb' is never read
hwdb = udev_hwdb_unref(hwdb);
^ ~~~~~~~~~~~~~~~~~~~~~
monitor/hwdb.c:111:2: warning: Value stored to 'udev' is never read
udev = udev_unref(udev);
^ ~~~~~~~~~~~~~~~~
4 warnings generated.
tools/bluemoon.c:1102:8: warning: Null pointer passed to 1st parameter expecting 'nonnull'
if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
^~~~~~~~~~~~~~
1 warning generated.
tools/meshctl.c:326:19: warning: Access to field 'mesh_devices' results in a dereference of a null pointer (loaded from variable 'default_ctrl')
g_list_free_full(default_ctrl->mesh_devices, g_free);
^~~~~~~~~~~~~~~~~~~~~~~~~~
tools/meshctl.c:762:2: warning: 2nd function call argument is an uninitialized value
bt_shell_printf("Attempting to disconnect from %s\n", addr);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/meshctl.c:1957:2: warning: Value stored to 'len' is never read
len = len + extra + strlen("local_node.json");
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.
In file included from tools/mesh-gatt/crypto.c:32:
./src/shared/util.h:250:9: warning: 1st function call argument is an uninitialized value
return be32_to_cpu(get_unaligned((const uint32_t *) ptr));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:39:26: note: expanded from macro 'be32_to_cpu'
#define be32_to_cpu(val) bswap_32(val)
^~~~~~~~~~~~~
/usr/include/byteswap.h:34:21: note: expanded from macro 'bswap_32'
#define bswap_32(x) __bswap_32 (x)
^~~~~~~~~~~~~~
In file included from tools/mesh-gatt/crypto.c:32:
./src/shared/util.h:260:9: warning: 1st function call argument is an uninitialized value
return be64_to_cpu(get_unaligned((const uint64_t *) ptr));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:40:26: note: expanded from macro 'be64_to_cpu'
#define be64_to_cpu(val) bswap_64(val)
^~~~~~~~~~~~~
/usr/include/byteswap.h:37:21: note: expanded from macro 'bswap_64'
#define bswap_64(x) __bswap_64 (x)
^~~~~~~~~~~~~~
2 warnings generated.
ell/util.c:853:8: warning: The left operand of '>' is a garbage value
if (x > UINT8_MAX)
~ ^
ell/util.c:871:8: warning: The left operand of '>' is a garbage value
if (x > UINT16_MAX)
~ ^
2 warnings generated.
ell/pem.c:131:8: warning: Dereference of null pointer (loaded from variable 'eol')
if (*eol == '\r' || *eol == '\n')
^~~~
ell/pem.c:166:18: warning: Dereference of null pointer (loaded from variable 'eol')
if (buf_len && *eol == '\r' && *buf_ptr == '\n') {
^~~~
ell/pem.c:166:34: warning: Dereference of null pointer (loaded from variable 'buf_ptr')
if (buf_len && *eol == '\r' && *buf_ptr == '\n') {
^~~~~~~~
ell/pem.c:304:11: warning: 1st function call argument is an uninitialized value
result = pem_load_buffer(file.data, file.st.st_size,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ell/pem.c:469:9: warning: 1st function call argument is an uninitialized value
list = l_pem_load_certificate_list_from_data(file.data,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
ell/cert.c:645:41: warning: Access to field 'asn1_len' results in a dereference of a null pointer (loaded from variable 'cert')
key = l_key_new(L_KEY_RSA, cert->asn1, cert->asn1_len);
^~~~~~~~~~~~~~
1 warning generated.
ell/gvariant-util.c:143:18: warning: The left operand of '>' is a garbage value
if (alignment > max_alignment)
~~~~~~~~~ ^
ell/gvariant-util.c:456:5: warning: Dereference of null pointer
!children[0].fixed_size) {
^~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
emulator/serial.c:150:2: warning: Assigned value is garbage or undefined
enum btdev_type uninitialized_var(type);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/serial.c:150:36: warning: Value stored to 'type' during its initialization is never read
enum btdev_type uninitialized_var(type);
^~~~
emulator/serial.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
^ ~
emulator/serial.c:213:2: warning: Assigned value is garbage or undefined
enum btdev_type uninitialized_var(dev_type);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/serial.c:213:36: warning: Value stored to 'dev_type' during its initialization is never read
enum btdev_type uninitialized_var(dev_type);
^~~~~~~~
emulator/serial.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
^ ~
4 warnings generated.
ell/ecc-external.c:77:11: warning: Assigned value is garbage or undefined
dest[i] = src[i];
^ ~~~~~~
ell/ecc-external.c:160:18: warning: The right operand of '-' is a garbage value
diff = left[i] - right[i] - borrow;
^ ~~~~~~~~
ell/ecc-external.c:227:14: warning: 2nd function call argument is an uninitialized value
product = mul_64_64(left[i], right[k - i]);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ell/ecc-external.c:408:9: warning: Assigned value is garbage or undefined
tmp[1] = product[3];
^ ~~~~~~~~~~
ell/ecc-external.c:435:22: warning: The left operand of '&' is a garbage value
tmp[1] = product[3] & 0xffffffff00000000ull;
~~~~~~~~~~ ^
ell/ecc-external.c:483:22: warning: The left operand of '&' is a garbage value
tmp[1] = product[5] & 0xffffffff00000000ull;
~~~~~~~~~~ ^
ell/ecc-external.c:688:28: warning: The left operand of '>>' is a garbage value
tmp[i] = (product[8 + i] >> 9) | (product[9 + i] << 55);
~~~~~~~~~~~~~~ ^
7 warnings generated.
emulator/server.c:209:2: warning: Assigned value is garbage or undefined
enum btdev_type uninitialized_var(type);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/server.c:209:36: warning: Value stored to 'type' during its initialization is never read
enum btdev_type uninitialized_var(type);
^~~~
emulator/server.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
^ ~
2 warnings generated.
emulator/b1ee.c:258:3: warning: Potential leak of memory pointed to by 'server_port'
int opt;
^~~~~~~
emulator/b1ee.c:258:3: warning: Potential leak of memory pointed to by 'sniffer_port'
int opt;
^~~~~~~
emulator/b1ee.c:289:2: warning: Value stored to 'argc' is never read
argc = argc - optind;
^ ~~~~~~~~~~~~~
3 warnings generated.
gobex/gobex-header.c:95:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
memcpy(to, from, count);
^~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-transfer.c:423:7: warning: Use of memory after it is freed
if (!g_slist_find(transfers, transfer))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
attrib/gatt.c:970:2: warning: Potential leak of memory pointed to by 'long_write'
return prepare_write(long_write);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
emulator/btdev.c:6618:20: warning: Access to field 'link' results in a dereference of a null pointer (loaded from variable 'acl')
le_past_received(acl->link, pa);
^~~~~~~~~
emulator/btdev.c:6718:25: warning: Access to field 'link' results in a dereference of a null pointer (loaded from variable 'acl')
le_past_info_received(acl->link, ea);
^~~~~~~~~
2 warnings generated.
profiles/ranging/rap_hci.c:219:6: error: no previous declaration for ‘cs_state_machine_init’ [-Werror=missing-declarations]
219 | void cs_state_machine_init(struct cs_state_machine_t *sm, struct bt_rap *rap,
| ^~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:258:6: error: no previous declaration for ‘cs_set_state’ [-Werror=missing-declarations]
258 | void cs_set_state(struct cs_state_machine_t *sm, enum cs_state_t new_state)
| ^~~~~~~~~~~~
profiles/ranging/rap_hci.c:280:17: error: no previous declaration for ‘cs_get_current_state’ [-Werror=missing-declarations]
280 | enum cs_state_t cs_get_current_state(struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:285:6: error: no previous declaration for ‘cs_is_procedure_active’ [-Werror=missing-declarations]
285 | bool cs_is_procedure_active(const struct cs_state_machine_t *sm)
| ^~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:325:6: error: no previous declaration for ‘rap_send_hci_def_settings_command’ [-Werror=missing-declarations]
325 | void rap_send_hci_def_settings_command(struct cs_state_machine_t *sm,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/ranging/rap_hci.c:1186:6: error: no previous declaration for ‘bt_rap_hci_register_events’ [-Werror=missing-declarations]
1186 | void bt_rap_hci_register_events(struct bt_rap *rap, struct bt_hci *hci)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8984: profiles/ranging/bluetoothd-rap_hci.o] Error 1
make[1]: *** Waiting for unfinished jobs....
profiles/audio/media.c:1112:7: warning: Use of memory after it is freed
if (req->cb != pac_select_cb) {
^~~~~~~
1 warning generated.
make: *** [Makefile:4159: all] Error 2
https://github.com/bluez/bluez/pull/2039
---
Regards,
Linux Bluetooth
^ permalink raw reply
* [bluez/bluez] 1082f4: shared: rap: Introduce Channel Sounding HCI raw in...
From: Bhavani @ 2026-04-15 11:38 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1081547
Home: https://github.com/bluez/bluez
Commit: 1082f4260f2bd1add5f08cf80e352b0ac239e092
https://github.com/bluez/bluez/commit/1082f4260f2bd1add5f08cf80e352b0ac239e092
Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
Date: 2026-04-15 (Wed, 15 Apr 2026)
Changed paths:
M src/shared/hci.c
M src/shared/hci.h
M src/shared/rap.c
M src/shared/rap.h
Log Message:
-----------
shared: rap: Introduce Channel Sounding HCI raw interface support
Implement stub callbacks for Channel Sounding HCI events and add the
required protocol definitions for CS configuration, procedure control,
and subevent result parsing
Add data structures to support Channel Sounding Processing
Add helper function to get hci conn info list and integrate it with RAP
Commit: 65412edd4e5213e695aea1501c198192bf8f95f5
https://github.com/bluez/bluez/commit/65412edd4e5213e695aea1501c198192bf8f95f5
Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
Date: 2026-04-15 (Wed, 15 Apr 2026)
Changed paths:
M src/bluetooth.service.in
M src/btd.h
M src/main.c
M src/main.conf
Log Message:
-----------
main.conf: Add Channel Sounding config parsing support
Add support for parsing Channel Sounding (CS) configuration options
from the configuration file.
Add CAP_NET_RAW to CapabilityBoundingSet in bluetooth.service.
bluetoothd requires CAP_NET_RAW to receive and process HCI LE events
when running under a constrained systemd capability bounding set
Commit: 0423d8d6f24ce4ea0f2343c6e954b98126150b5d
https://github.com/bluez/bluez/commit/0423d8d6f24ce4ea0f2343c6e954b98126150b5d
Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
Date: 2026-04-15 (Wed, 15 Apr 2026)
Changed paths:
M Makefile.plugins
M profiles/ranging/rap.c
A profiles/ranging/rap_hci.c
Log Message:
-----------
profiles: ranging: Add HCI LE Event Handling in Reflector role
Open RAW HCI Channel for CS Event Handling
Parse the following HCI LE CS Events in reflector role
and route the events to RAP Profile.
1. HCI_EVT_LE_CS_READ_RMT_SUPP_CAP_COMPLETE
2. HCI_EVT_LE_CS_CONFIG_COMPLETE
3. HCI_EVT_LE_CS_SECURITY_ENABLE_COMPLETE
4. HCI_EVT_LE_CS_PROCEDURE_ENABLE_COMPLETE
5. HCI_EVT_LE_CS_SUBEVENT_RESULT
6. HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE
Send HCI_OP_LE_CS_SET_DEFAULT_SETTINGS to the controller
with default settings selected by the user.
Map connection handle received to device connection
Compare: https://github.com/bluez/bluez/compare/1082f4260f2b%5E...0423d8d6f24c
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox