* [PATCH bluez v7 0/3] Add implementation of bearer connect/disconnect
@ 2025-11-27 9:54 Ye He via B4 Relay
2025-11-27 9:54 ` [PATCH bluez v7 1/3] profiles: Add bearer field to btd_profile Ye He via B4 Relay
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Ye He via B4 Relay @ 2025-11-27 9:54 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Ye He
Signed-off-by: Ye He <ye.he@amlogic.com>
---
Changes in v7:
- Specify the bearer type explicitly in the shell command, instead of passing
- it as a parameter.
- Link to v6: https://patch.msgid.link/20251126-bearer-impl-v6-0-e93fd41f10b6@amlogic.com
Changes in v6:
- Fix coding style warnings.
- Link to v5: https://patch.msgid.link/20251125-bearer-impl-v5-0-ce1ce5ad19d9@amlogic.com
Changes in v5:
- Split adding bearer field to btd_profile into a standalone patch.
- Link to v4: https://patch.msgid.link/20251121-bearer-impl-v4-1-b52149dfd9a6@amlogic.com
Changes in v4:
- Add a bearer field to btd_profile to indicate which bearer type the profile
- belongs to, thus we can distinct the services per bearer.
- Link to v3: https://patch.msgid.link/20251118-bearer-impl-v3-1-dadcd8b0c75d@amlogic.com
Changes in v3:
- Move the modification logic from the device to bearer, and add
- some helper functions to the device.
- Link to v2: https://patch.msgid.link/20251113-bearer-impl-v2-1-c3e825cc6758@amlogic.com
Changes in v2:
- Fix build error & warning.
- Link to v1: https://patch.msgid.link/20251111-bearer-impl-v1-1-f41585144218@amlogic.com
---
Ye He (3):
profiles: Add bearer field to btd_profile
bearer: Implement Connect/Disconnect methods
client: Add shell cmd for bearer connect/disconnect
client/bluetoothctl.rst | 49 ++++++++++++
client/main.c | 152 +++++++++++++++++++++++++++++++++++
profiles/audio/a2dp.c | 5 +-
profiles/audio/asha.c | 1 +
profiles/audio/avrcp.c | 2 +
profiles/audio/bap.c | 2 +
profiles/audio/bass.c | 1 +
profiles/audio/ccp.c | 1 +
profiles/audio/csip.c | 2 +
profiles/audio/mcp.c | 1 +
profiles/audio/micp.c | 1 +
profiles/audio/vcp.c | 1 +
profiles/battery/battery.c | 1 +
profiles/deviceinfo/deviceinfo.c | 1 +
profiles/gap/gas.c | 1 +
profiles/health/hdp_manager.c | 2 +
profiles/input/hog.c | 1 +
profiles/input/manager.c | 1 +
profiles/midi/midi.c | 1 +
profiles/network/manager.c | 3 +
profiles/scanparam/scan.c | 1 +
src/bearer.c | 167 ++++++++++++++++++++++++++++++++++++++-
src/device.c | 129 +++++++++++++++++++++++++-----
src/device.h | 17 ++++
src/profile.h | 10 +++
25 files changed, 529 insertions(+), 24 deletions(-)
---
base-commit: 5e41d1e1d361e7288964e4c2c5ed90736025662f
change-id: 20251111-bearer-impl-5f7e396174aa
Best regards,
--
Ye He <ye.he@amlogic.com>
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH bluez v7 1/3] profiles: Add bearer field to btd_profile
2025-11-27 9:54 [PATCH bluez v7 0/3] Add implementation of bearer connect/disconnect Ye He via B4 Relay
@ 2025-11-27 9:54 ` Ye He via B4 Relay
2025-11-27 11:00 ` Add implementation of bearer connect/disconnect bluez.test.bot
2025-11-27 9:54 ` [PATCH bluez v7 2/3] bearer: Implement Connect/Disconnect methods Ye He via B4 Relay
2025-11-27 9:54 ` [PATCH bluez v7 3/3] client: Add shell cmd for bearer connect/disconnect Ye He via B4 Relay
2 siblings, 1 reply; 10+ messages in thread
From: Ye He via B4 Relay @ 2025-11-27 9:54 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Ye He
From: Ye He <ye.he@amlogic.com>
Add bearer filed into btd_profile to indicates which bearer
type this profile belongs to. Thus we can distinct the services
per bearer.
Signed-off-by: Ye He <ye.he@amlogic.com>
---
profiles/audio/a2dp.c | 5 +++--
profiles/audio/asha.c | 1 +
profiles/audio/avrcp.c | 2 ++
profiles/audio/bap.c | 2 ++
profiles/audio/bass.c | 1 +
profiles/audio/ccp.c | 1 +
profiles/audio/csip.c | 2 ++
profiles/audio/mcp.c | 1 +
profiles/audio/micp.c | 1 +
profiles/audio/vcp.c | 1 +
profiles/battery/battery.c | 1 +
profiles/deviceinfo/deviceinfo.c | 1 +
profiles/gap/gas.c | 1 +
profiles/health/hdp_manager.c | 2 ++
profiles/input/hog.c | 1 +
profiles/input/manager.c | 1 +
profiles/midi/midi.c | 1 +
profiles/network/manager.c | 3 +++
profiles/scanparam/scan.c | 1 +
src/profile.h | 10 ++++++++++
20 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index d8f24eaebc745a6d91a8207f6595f0b90d982c39..7a37003a2b25a9e931b8efdfc974368f5ab2bac8 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -3757,8 +3757,9 @@ static void media_server_remove(struct btd_adapter *adapter)
static struct btd_profile a2dp_source_profile = {
.name = "a2dp-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
-
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = A2DP_SOURCE_UUID,
+
.device_probe = a2dp_source_probe,
.device_remove = a2dp_source_remove,
@@ -3773,7 +3774,7 @@ static struct btd_profile a2dp_source_profile = {
static struct btd_profile a2dp_sink_profile = {
.name = "a2dp-sink",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
-
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = A2DP_SINK_UUID,
.device_probe = a2dp_sink_probe,
.device_remove = a2dp_sink_remove,
diff --git a/profiles/audio/asha.c b/profiles/audio/asha.c
index e870ea06f03ac1c20e5b29fb158c815aa2ce756c..8e625fdca32ff0b40efd43e394b34559627bde8c 100644
--- a/profiles/audio/asha.c
+++ b/profiles/audio/asha.c
@@ -499,6 +499,7 @@ static int asha_source_disconnect(struct btd_service *service)
static struct btd_profile asha_source_profile = {
.name = "asha-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = ASHA_PROFILE_UUID,
.experimental = true,
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 21bc80bbd095da49788a87357fd67c8e96ab779d..e6f7e1bfde9879ab6bf028e16384d474332fe805 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -4868,6 +4868,7 @@ done:
static struct btd_profile avrcp_target_profile = {
.name = "audio-avrcp-target",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = AVRCP_TARGET_UUID,
.device_probe = avrcp_target_probe,
@@ -4951,6 +4952,7 @@ done:
static struct btd_profile avrcp_controller_profile = {
.name = "avrcp-controller",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = AVRCP_REMOTE_UUID,
.device_probe = avrcp_controller_probe,
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 85bba9543974e5bf2a1ff6380c36e518ebc095ac..a03a120ddaaed7e261d40ac06a8f9502c52772bc 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -3865,6 +3865,7 @@ static void bap_adapter_remove(struct btd_profile *p,
static struct btd_profile bap_profile = {
.name = "bap",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = PACS_UUID_STR,
.device_probe = bap_probe,
.device_remove = bap_remove,
@@ -3879,6 +3880,7 @@ static struct btd_profile bap_profile = {
static struct btd_profile bap_bcast_profile = {
.name = "bcaa",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BCAAS_UUID_STR,
.device_probe = bap_bcast_probe,
.device_remove = bap_bcast_remove,
diff --git a/profiles/audio/bass.c b/profiles/audio/bass.c
index 9ace372376f9452050724360c2c28e7cdcf1391b..8886a27d99b63b37e2937d8d70f71dfeda3d9ef2 100644
--- a/profiles/audio/bass.c
+++ b/profiles/audio/bass.c
@@ -2172,6 +2172,7 @@ static void bass_server_remove(struct btd_profile *p,
static struct btd_profile bass_service = {
.name = "bass",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BASS_UUID_STR,
.device_probe = bass_probe,
.device_remove = bass_remove,
diff --git a/profiles/audio/ccp.c b/profiles/audio/ccp.c
index 8aa537b044e13b6d6a773645b420161bedca13ef..fb85045bb8ba1ec47a33856af1129d0ef78bf500 100644
--- a/profiles/audio/ccp.c
+++ b/profiles/audio/ccp.c
@@ -208,6 +208,7 @@ ccp_server_remove(struct btd_profile *p,
static struct btd_profile ccp_profile = {
.name = "ccp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GTBS_UUID_STR,
.device_probe = ccp_probe,
.device_remove = ccp_remove,
diff --git a/profiles/audio/csip.c b/profiles/audio/csip.c
index b8f29ddf852231d89760d6fe7ca2cfd684236570..d766c3da951899d990aa59132b820737604b1b7c 100644
--- a/profiles/audio/csip.c
+++ b/profiles/audio/csip.c
@@ -303,6 +303,7 @@ static void csip_remove(struct btd_service *service)
static struct btd_profile csip_profile = {
.name = "csip",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = CSIS_UUID_STR,
.device_probe = csip_probe,
@@ -442,6 +443,7 @@ static void csis_server_remove(struct btd_profile *p,
static struct btd_profile csis_profile = {
.name = "csis",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.local_uuid = CSIS_UUID_STR,
.adapter_probe = csis_server_probe,
diff --git a/profiles/audio/mcp.c b/profiles/audio/mcp.c
index 6651b0897e6f631906b1467f5a479737541da286..8d4eed64399195533ac13fd075d7196a35cf2113 100644
--- a/profiles/audio/mcp.c
+++ b/profiles/audio/mcp.c
@@ -383,6 +383,7 @@ static void media_control_server_remove(struct btd_profile *p,
static struct btd_profile mcp_profile = {
.name = "mcp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GMCS_UUID_STR,
.device_probe = mcp_probe,
.device_remove = mcp_remove,
diff --git a/profiles/audio/micp.c b/profiles/audio/micp.c
index f1fb133897320677225a1c8bee06b4a1214f14fa..475f32daf75c06dc28ca72420a80e30802e5a3e9 100644
--- a/profiles/audio/micp.c
+++ b/profiles/audio/micp.c
@@ -300,6 +300,7 @@ static void micp_server_remove(struct btd_profile *p,
static struct btd_profile micp_profile = {
.name = "micp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = MICS_UUID_STR,
.device_probe = micp_probe,
diff --git a/profiles/audio/vcp.c b/profiles/audio/vcp.c
index 8949c71858e53448ee01c5c4261082f3912a759c..471ad59250386941c377e2f81e911467d7023cce 100644
--- a/profiles/audio/vcp.c
+++ b/profiles/audio/vcp.c
@@ -328,6 +328,7 @@ static void vcp_server_remove(struct btd_profile *p,
static struct btd_profile vcp_profile = {
.name = "vcp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = VCS_UUID_STR,
.device_probe = vcp_probe,
diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 050234a0fa03813dc9e1b8302689fc68ec254184..2fe1f4aca2cf7b21e52bec989711741d6d7e25b5 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -327,6 +327,7 @@ static int batt_disconnect(struct btd_service *service)
static struct btd_profile batt_profile = {
.name = "batt-profile",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BATTERY_UUID,
.device_probe = batt_probe,
.device_remove = batt_remove,
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
index f5adb101e312108be8dae20c75cc74e1ff7eaabf..e77bb50b457a28f08f3e9d2ecf8d81d80da86106 100644
--- a/profiles/deviceinfo/deviceinfo.c
+++ b/profiles/deviceinfo/deviceinfo.c
@@ -137,6 +137,7 @@ static int deviceinfo_disconnect(struct btd_service *service)
static struct btd_profile deviceinfo_profile = {
.name = "deviceinfo",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = DEVICE_INFORMATION_UUID,
.device_probe = deviceinfo_probe,
.device_remove = deviceinfo_remove,
diff --git a/profiles/gap/gas.c b/profiles/gap/gas.c
index dd45554d43ebc267d40a8fe4a8fab48f602bf6bc..0f41c9e6c2a5c7d980509ae66d8d7d7c2678fd21 100644
--- a/profiles/gap/gas.c
+++ b/profiles/gap/gas.c
@@ -366,6 +366,7 @@ static int gap_disconnect(struct btd_service *service)
static struct btd_profile gap_profile = {
.name = "gap-profile",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GAP_UUID,
.device_probe = gap_probe,
.device_remove = gap_remove,
diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index d1e627a3382a01bdd5002bcc0da01da35e872da1..72b69428036df77e2cdb224f186fb13191f955ed 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
@@ -57,6 +57,7 @@ static void hdp_driver_remove(struct btd_service *service)
static struct btd_profile hdp_source_profile = {
.name = "hdp-source",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = HDP_SOURCE_UUID,
.device_probe = hdp_driver_probe,
@@ -68,6 +69,7 @@ static struct btd_profile hdp_source_profile = {
static struct btd_profile hdp_sink_profile = {
.name = "hdp-sink",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = HDP_SINK_UUID,
.device_probe = hdp_driver_probe,
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index 1f5b82b774353244067e460f49aaccd09e26dcc8..f50a0f217f7f732f82645e289419e51ee6412917 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -215,6 +215,7 @@ static int hog_disconnect(struct btd_service *service)
static struct btd_profile hog_profile = {
.name = "input-hog",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = HOG_UUID,
.device_probe = hog_probe,
.device_remove = hog_remove,
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index b0e415f6706c54e7c96199d3bb5e483d0927153f..0fcd6728c2fca83f03f7333f50102658553403e7 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -45,6 +45,7 @@ static void hid_server_remove(struct btd_profile *p,
static struct btd_profile input_profile = {
.name = "input-hid",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = HID_UUID,
.remote_uuid = HID_UUID,
diff --git a/profiles/midi/midi.c b/profiles/midi/midi.c
index 90e00a5f58361f1da57a71f393e581da5128310c..ea4719b95b23aa97850de362da9012728427f08e 100644
--- a/profiles/midi/midi.c
+++ b/profiles/midi/midi.c
@@ -458,6 +458,7 @@ static int midi_disconnect(struct btd_service *service)
static struct btd_profile midi_profile = {
.name = "MIDI GATT Driver",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = MIDI_UUID,
.priority = BTD_PROFILE_PRIORITY_HIGH,
.auto_connect = true,
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 51f382529df27600d1a4fd806cb656d7f1a682af..693547d45fbc5b2f227fed832b4efb8fb87c2d59 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -120,6 +120,7 @@ static void nap_server_remove(struct btd_profile *p,
static struct btd_profile panu_profile = {
.name = "network-panu",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = NAP_UUID,
.remote_uuid = PANU_UUID,
.device_probe = connection_register,
@@ -132,6 +133,7 @@ static struct btd_profile panu_profile = {
static struct btd_profile gn_profile = {
.name = "network-gn",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = PANU_UUID,
.remote_uuid = GN_UUID,
.device_probe = connection_register,
@@ -144,6 +146,7 @@ static struct btd_profile gn_profile = {
static struct btd_profile nap_profile = {
.name = "network-nap",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = PANU_UUID,
.remote_uuid = NAP_UUID,
.device_probe = connection_register,
diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c
index 1c531773740c847e970ac45b7fbda2c0c9501ded..a66f80eabf3ef63e35cfd5e8da30e4aa18420b94 100644
--- a/profiles/scanparam/scan.c
+++ b/profiles/scanparam/scan.c
@@ -259,6 +259,7 @@ static int scan_param_probe(struct btd_service *service)
static struct btd_profile scan_profile = {
.name = "Scan Parameters Client Driver",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = SCAN_PARAMETERS_UUID,
.device_probe = scan_param_probe,
.device_remove = scan_param_remove,
diff --git a/src/profile.h b/src/profile.h
index 424ce55ad65748ead13b1a38d67fbad6beb2b828..1281d8d9a0daa5de6578a5ae6df8fc211269d409 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -12,12 +12,22 @@
#define BTD_PROFILE_PRIORITY_MEDIUM 1
#define BTD_PROFILE_PRIORITY_HIGH 2
+#define BTD_PROFILE_BEARER_ANY 0
+#define BTD_PROFILE_BEARER_LE 1
+#define BTD_PROFILE_BEARER_BREDR 2
+
struct btd_service;
struct btd_profile {
const char *name;
int priority;
+ /* Indicates which bearer type this profile belongs to. Some profiles
+ * may exist in both BR/EDR and LE, in which case they should be
+ * registered with BTD_PROFILE_BEARER_ANY.
+ */
+ int bearer;
+
const char *local_uuid;
const char *remote_uuid;
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH bluez v7 2/3] bearer: Implement Connect/Disconnect methods
2025-11-27 9:54 [PATCH bluez v7 0/3] Add implementation of bearer connect/disconnect Ye He via B4 Relay
2025-11-27 9:54 ` [PATCH bluez v7 1/3] profiles: Add bearer field to btd_profile Ye He via B4 Relay
@ 2025-11-27 9:54 ` Ye He via B4 Relay
2025-11-27 9:54 ` [PATCH bluez v7 3/3] client: Add shell cmd for bearer connect/disconnect Ye He via B4 Relay
2 siblings, 0 replies; 10+ messages in thread
From: Ye He via B4 Relay @ 2025-11-27 9:54 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Ye He
From: Ye He <ye.he@amlogic.com>
This patch provides implementations for the Connect and Disconnect
methods of the org.bluez.Bearer.LE1 and org.bluez.Bearer.BREDR1
interfaces.
Signed-off-by: Ye He <ye.he@amlogic.com>
---
src/bearer.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/device.c | 129 ++++++++++++++++++++++++++++++++++++++-------
src/device.h | 17 ++++++
3 files changed, 291 insertions(+), 22 deletions(-)
diff --git a/src/bearer.c b/src/bearer.c
index 9723b59e2e7b39b2974e258363aa0ace95862651..784c9536dea5cd5aedccac05b5042927a59df8ba 100644
--- a/src/bearer.c
+++ b/src/bearer.c
@@ -25,23 +25,43 @@
#include "bluetooth/bluetooth.h"
#include "bluetooth/mgmt.h"
+#include "bluetooth/uuid.h"
#include "gdbus/gdbus.h"
#include "src/shared/util.h"
+#include "src/shared/queue.h"
+#include "src/shared/timeout.h"
#include "log.h"
#include "error.h"
#include "adapter.h"
#include "device.h"
+#include "profile.h"
+#include "service.h"
#include "dbus-common.h"
#include "bearer.h"
+#define DISCONNECT_TIMER 2
+
struct btd_bearer {
struct btd_device *device;
uint8_t type;
const char *path;
+ unsigned int disconn_timer;
+ struct queue *disconnects; /* disconnects message */
+
+ /* Connect() is defined as a single in-flight operation. To preserve
+ * the API semantics of org.bluez.Device1.Connect(), we do not queue
+ * additional connect messages.
+ */
+ DBusMessage *connect; /* connect message */
};
+static void bearer_free_dbus_message(void *data)
+{
+ dbus_message_unref((DBusMessage *)data);
+}
+
static void bearer_free(void *data)
{
struct btd_bearer *bearer = data;
@@ -49,17 +69,128 @@ static void bearer_free(void *data)
free(bearer);
}
+static void bearer_disconnect_service(struct btd_service *service,
+ void *user_data)
+{
+ uint8_t bdaddr_type = *(uint8_t *)user_data;
+ struct btd_profile *profile = btd_service_get_profile(service);
+ struct btd_device *device = btd_service_get_device(service);
+
+ if (!profile || !device)
+ return;
+
+ if (bdaddr_type == BDADDR_BREDR) {
+ if (profile->bearer == BTD_PROFILE_BEARER_LE)
+ return;
+ } else {
+ if (profile->bearer == BTD_PROFILE_BEARER_BREDR)
+ return;
+ }
+
+ DBG("Disconnecting profile %s for bearer addr type %u",
+ profile->name ?: "(unknown)", bdaddr_type);
+
+ btd_service_disconnect(service);
+}
+
+
+static bool bearer_disconnect_link(gpointer user_data)
+{
+ struct btd_bearer *bearer = user_data;
+ struct btd_device *device = bearer->device;
+
+ bearer->disconn_timer = 0;
+
+ if (btd_device_bdaddr_type_connected(device, bearer->type))
+ btd_adapter_disconnect_device(device_get_adapter(device),
+ device_get_address(device),
+ bearer->type);
+ return FALSE;
+}
+
static DBusMessage *bearer_connect(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
- /* TODO */
+ struct btd_bearer *bearer = user_data;
+ struct btd_device *device = bearer->device;
+ int err;
+
+ if (btd_device_bdaddr_type_connected(device, bearer->type)) {
+ if (msg)
+ return btd_error_already_connected(msg);
+ return NULL;
+ }
+
+ if (device_is_bonding(device, NULL)) {
+ if (msg)
+ return btd_error_in_progress(msg);
+ return NULL;
+ }
+
+ if (device_is_connecting(device) ||
+ bearer->connect) {
+ if (msg)
+ return btd_error_in_progress(msg);
+ return NULL;
+ }
+
+ if (msg)
+ bearer->connect = dbus_message_ref(msg);
+
+ if (bearer->type == BDADDR_BREDR)
+ return device_connect_profiles(device, BDADDR_BREDR,
+ msg, NULL);
+ else {
+ btd_device_set_temporary(device, false);
+ err = device_connect_le(device);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+ }
+
return NULL;
}
static DBusMessage *bearer_disconnect(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
- /* TODO */
+ struct btd_bearer *bearer = user_data;
+ struct btd_device *device = bearer->device;
+
+ if (!btd_device_bdaddr_type_connected(device, bearer->type)) {
+ if (msg)
+ return btd_error_not_connected(msg);
+ return NULL;
+ }
+
+ /* org.bluez.Device1.Disconnect() is in progress. Since it tears down
+ * both LE and BR/EDR bearers, it takes precedence over bearer-level
+ * disconnects. Ignore any bearer-specific disconnect requests here.
+ */
+ if (device_is_disconnecting(device)) {
+ if (msg)
+ return btd_error_in_progress(msg);
+ return NULL;
+ }
+
+ if (msg)
+ queue_push_tail(bearer->disconnects, dbus_message_ref(msg));
+
+ device_cancel_bonding(device, MGMT_STATUS_DISCONNECTED);
+
+ device_cancel_browse(device, bearer->type);
+
+ btd_device_foreach_service(device, bearer_disconnect_service,
+ &bearer->type);
+
+ device_remove_pending_services(device, bearer->type);
+
+ if (bearer->disconn_timer)
+ return NULL;
+
+ bearer->disconn_timer = timeout_add_seconds(DISCONNECT_TIMER,
+ bearer_disconnect_link,
+ bearer, NULL);
+
return NULL;
}
@@ -151,6 +282,7 @@ struct btd_bearer *btd_bearer_new(struct btd_device *device, uint8_t type)
bearer->device = device;
bearer->type = type;
bearer->path = device_get_path(device);
+ bearer->disconnects = queue_new();
if (!g_dbus_register_interface(btd_get_dbus_connection(),
bearer->path, bearer_interface(type),
@@ -174,6 +306,16 @@ void btd_bearer_destroy(struct btd_bearer *bearer)
return;
}
+ if (bearer->disconnects) {
+ queue_destroy(bearer->disconnects, bearer_free_dbus_message);
+ bearer->disconnects = NULL;
+ }
+
+ if (bearer->connect) {
+ dbus_message_unref(bearer->connect);
+ bearer->connect = NULL;
+ }
+
g_dbus_unregister_interface(btd_get_dbus_connection(), bearer->path,
bearer_interface(bearer->type));
}
@@ -203,6 +345,13 @@ void btd_bearer_connected(struct btd_bearer *bearer)
if (!bearer || !bearer->path)
return;
+ if (bearer->connect) {
+ g_dbus_send_reply(btd_get_dbus_connection(), bearer->connect,
+ DBUS_TYPE_INVALID);
+ dbus_message_unref(bearer->connect);
+ bearer->connect = NULL;
+ }
+
g_dbus_emit_property_changed(btd_get_dbus_connection(), bearer->path,
bearer_interface(bearer->type),
"Connected");
@@ -212,10 +361,24 @@ void btd_bearer_disconnected(struct btd_bearer *bearer, uint8_t reason)
{
const char *name;
const char *message;
+ DBusMessage *msg;
+ const struct queue_entry *entry;
if (!bearer || !bearer->path)
return;
+ if (!btd_device_is_connected(bearer->device))
+ device_disconnect_watches_callback(bearer->device);
+
+ while (!queue_isempty(bearer->disconnects)) {
+ entry = queue_get_entries(bearer->disconnects);
+ msg = entry->data;
+ g_dbus_send_reply(btd_get_dbus_connection(), msg,
+ DBUS_TYPE_INVALID);
+ queue_remove(bearer->disconnects, msg);
+ dbus_message_unref(msg);
+ }
+
g_dbus_emit_property_changed(btd_get_dbus_connection(), bearer->path,
bearer_interface(bearer->type),
"Connected");
diff --git a/src/device.c b/src/device.c
index 91b6cc0c65eaae8058cd445c0942ffee57289f0d..145004cea9bf06d9fb811f971f1786ddcefd8e7a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2022,6 +2022,28 @@ static void dev_disconn_service(gpointer a, gpointer b)
btd_service_disconnect(a);
}
+void device_disconnect_watches_callback(struct btd_device *device)
+{
+ if (!device || !device->watches)
+ return;
+
+ while (device->watches) {
+ struct btd_disconnect_data *data = device->watches->data;
+
+ if (data->watch)
+ /* temporary is set if device is going to be removed */
+ data->watch(device, device->temporary,
+ data->user_data);
+
+ /* Check if the watch has been removed by callback function */
+ if (!g_slist_find(device->watches, data))
+ continue;
+
+ device->watches = g_slist_remove(device->watches, data);
+ g_free(data);
+ }
+}
+
void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
{
if (device->bonding)
@@ -2063,21 +2085,7 @@ void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
g_slist_free(device->pending);
device->pending = NULL;
- while (device->watches) {
- struct btd_disconnect_data *data = device->watches->data;
-
- if (data->watch)
- /* temporary is set if device is going to be removed */
- data->watch(device, device->temporary,
- data->user_data);
-
- /* Check if the watch has been removed by callback function */
- if (!g_slist_find(device->watches, data))
- continue;
-
- device->watches = g_slist_remove(device->watches, data);
- g_free(data);
- }
+ device_disconnect_watches_callback(device);
if (!btd_device_is_connected(device)) {
if (msg)
@@ -2095,6 +2103,11 @@ bool device_is_disconnecting(struct btd_device *device)
return device->disconn_timer > 0;
}
+bool device_is_connecting(struct btd_device *device)
+{
+ return device->connect != NULL;
+}
+
static void add_set(void *data, void *user_data)
{
struct sirk_info *sirk = data;
@@ -2712,8 +2725,8 @@ int btd_device_connect_services(struct btd_device *dev, GSList *services)
return connect_next(dev);
}
-static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type,
- DBusMessage *msg, const char *uuid)
+DBusMessage *device_connect_profiles(struct btd_device *dev,
+ uint8_t bdaddr_type, DBusMessage *msg, const char *uuid)
{
struct bearer_state *state = get_state(dev, bdaddr_type);
int err;
@@ -2826,7 +2839,7 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
return NULL;
}
- return connect_profiles(dev, bdaddr_type, msg, NULL);
+ return device_connect_profiles(dev, bdaddr_type, msg, NULL);
}
static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
@@ -2848,7 +2861,7 @@ static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
return btd_error_invalid_args_str(msg,
ERR_BREDR_CONN_INVALID_ARGUMENTS);
- reply = connect_profiles(dev, BDADDR_BREDR, msg, uuid);
+ reply = device_connect_profiles(dev, BDADDR_BREDR, msg, uuid);
free(uuid);
return reply;
@@ -3421,7 +3434,7 @@ static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
}
}
-static void device_cancel_bonding(struct btd_device *device, uint8_t status)
+void device_cancel_bonding(struct btd_device *device, uint8_t status)
{
struct bonding_req *bonding = device->bonding;
DBusMessage *reply;
@@ -6629,6 +6642,39 @@ static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
return err;
}
+static gboolean device_is_browsing(struct btd_device *device,
+ uint8_t bdaddr_type)
+{
+ if (!device->browse)
+ return FALSE;
+
+ if (bdaddr_type == BDADDR_BREDR && device->browse->type == BROWSE_SDP)
+ return TRUE;
+
+ if (bdaddr_type != BDADDR_BREDR && device->browse->type == BROWSE_GATT)
+ return TRUE;
+
+ return FALSE;
+}
+
+void device_cancel_browse(struct btd_device *device, uint8_t bdaddr_type)
+{
+ struct btd_adapter *adapter = device->adapter;
+
+ DBG("");
+
+ if (!device_is_browsing(device, bdaddr_type))
+ return;
+
+ if (bdaddr_type == BDADDR_BREDR)
+ bt_cancel_discovery(btd_adapter_get_address(adapter),
+ &device->bdaddr);
+ else
+ attio_cleanup(device);
+
+ browse_request_free(device->browse);
+}
+
int device_discover_services(struct btd_device *device)
{
int err;
@@ -8088,3 +8134,46 @@ void btd_device_foreach_service_data(struct btd_device *dev, bt_ad_func_t func,
{
bt_ad_foreach_service_data(dev->ad, func, data);
}
+
+
+void btd_device_foreach_service(struct btd_device *dev,
+ btd_device_service_func_t func,
+ void *user_data)
+{
+ GSList *l;
+
+ for (l = dev->services; l; l = l->next)
+ func(l->data, user_data);
+}
+
+void device_remove_pending_services(struct btd_device *dev,
+ uint8_t bdaddr_type)
+{
+ GSList *l = dev->pending;
+ GSList *next;
+ struct btd_service *service;
+ struct btd_profile *profile;
+
+ while (l) {
+ next = l->next;
+ service = l->data;
+
+ profile = btd_service_get_profile(service);
+ if (!profile)
+ goto next;
+
+ if (bdaddr_type == BDADDR_BREDR) {
+ if (profile->bearer == BTD_PROFILE_BEARER_LE)
+ goto next;
+ } else {
+ if (profile->bearer == BTD_PROFILE_BEARER_BREDR)
+ goto next;
+ }
+
+ /* Matched: remove from pending list */
+ dev->pending = g_slist_remove(dev->pending, service);
+
+next:
+ l = next;
+ }
+}
diff --git a/src/device.h b/src/device.h
index 6ed8affa0d4a9274d30cac9b48e8a6826edefd64..c7b8b2a16eb993758afc85b291cea31ef46f2d8f 100644
--- a/src/device.h
+++ b/src/device.h
@@ -120,6 +120,7 @@ void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
gboolean device_is_bonding(struct btd_device *device, const char *sender);
void device_bonding_attempt_failed(struct btd_device *device, uint8_t status);
void device_bonding_failed(struct btd_device *device, uint8_t status);
+void device_cancel_bonding(struct btd_device *device, uint8_t status);
struct btd_adapter_pin_cb_iter *device_bonding_iter(struct btd_device *device);
int device_bonding_attempt_retry(struct btd_device *device);
long device_bonding_last_duration(struct btd_device *device);
@@ -134,6 +135,9 @@ int device_notify_pincode(struct btd_device *device, gboolean secure,
const char *pincode);
void device_cancel_authentication(struct btd_device *device, gboolean aborted);
gboolean device_is_authenticating(struct btd_device *device);
+
+void device_cancel_browse(struct btd_device *device, uint8_t bdaddr_type);
+
void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type,
uint32_t flags);
void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type,
@@ -141,6 +145,7 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type,
uint8_t reason);
void device_request_disconnect(struct btd_device *device, DBusMessage *msg);
bool device_is_disconnecting(struct btd_device *device);
+bool device_is_connecting(struct btd_device *device);
void device_set_ltk(struct btd_device *device, const uint8_t val[16],
bool central, uint8_t enc_size);
bool btd_device_get_ltk(struct btd_device *device, uint8_t val[16],
@@ -170,6 +175,7 @@ guint device_add_disconnect_watch(struct btd_device *device,
disconnect_watch watch, void *user_data,
GDestroyNotify destroy);
void device_remove_disconnect_watch(struct btd_device *device, guint id);
+void device_disconnect_watches_callback(struct btd_device *device);
int device_get_appearance(struct btd_device *device, uint16_t *value);
void device_set_appearance(struct btd_device *device, uint16_t value);
@@ -184,6 +190,9 @@ void btd_device_set_pnpid(struct btd_device *device, uint16_t source,
int device_connect_le(struct btd_device *dev);
+DBusMessage *device_connect_profiles(struct btd_device *dev,
+ uint8_t bdaddr_type, DBusMessage *msg, const char *uuid);
+
typedef void (*device_svc_cb_t) (struct btd_device *dev, int err,
void *user_data);
@@ -225,3 +234,11 @@ void btd_device_set_conn_param(struct btd_device *device, uint16_t min_interval,
void btd_device_foreach_service_data(struct btd_device *dev,
bt_device_ad_func_t func,
void *data);
+
+typedef void (*btd_device_service_func_t)(struct btd_service *service,
+ void *user_data);
+void btd_device_foreach_service(struct btd_device *dev,
+ btd_device_service_func_t func,
+ void *user_data);
+void device_remove_pending_services(struct btd_device *dev,
+ uint8_t bdaddr_type);
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH bluez v7 3/3] client: Add shell cmd for bearer connect/disconnect
2025-11-27 9:54 [PATCH bluez v7 0/3] Add implementation of bearer connect/disconnect Ye He via B4 Relay
2025-11-27 9:54 ` [PATCH bluez v7 1/3] profiles: Add bearer field to btd_profile Ye He via B4 Relay
2025-11-27 9:54 ` [PATCH bluez v7 2/3] bearer: Implement Connect/Disconnect methods Ye He via B4 Relay
@ 2025-11-27 9:54 ` Ye He via B4 Relay
2025-11-27 15:28 ` Luiz Augusto von Dentz
2 siblings, 1 reply; 10+ messages in thread
From: Ye He via B4 Relay @ 2025-11-27 9:54 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Ye He
From: Ye He <ye.he@amlogic.com>
This patch adds shell command for bearer connect/disconnect.
Signed-off-by: Ye He <ye.he@amlogic.com>
---
client/bluetoothctl.rst | 49 ++++++++++++++++
client/main.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 201 insertions(+)
diff --git a/client/bluetoothctl.rst b/client/bluetoothctl.rst
index 0187e877d60b28eb1e735181b3203e60da821e6f..87aae8995a29749ffa09bbfefbd74c41f242fedc 100644
--- a/client/bluetoothctl.rst
+++ b/client/bluetoothctl.rst
@@ -296,6 +296,55 @@ needed.
:Usage: **> disconnect <dev> [uuid]**
+le-connect
+----------
+
+Connect device over le.
+
+This command initiates a le connection to a remote device.
+
+An active scan report is required before the connection can be
+established. If no advertising report is received before the timeout,
+a le-connection-abort-by-local error will be issued.
+
+:Usage: > le-connect <dev>
+:Example: > le-connect 1C:48:F9:9D:81:5C
+
+le-disconnect
+-------------
+
+Disconnect device over le.
+
+By default this command disconnects all profiles/services associated with the le
+connection, and then terminates the le link.
+
+:Usage: > le-disconnect <dev>
+:Example: > le-disconnect 1C:48:F9:9D:81:5C
+
+bredr-connect
+-------------
+
+Connect device over bredr.
+
+This command initiates a bredr connection to a remote device.
+
+By default, it establishes the bredr connection and then connects all profiles
+that marked as auto-connectable.
+
+:Usage: > bredr-connect <dev>
+:Example: > bredr-connect 1C:48:F9:9D:81:5C
+
+bredr-disconnect
+----------------
+
+Disconnect device over bredr.
+
+By default this command disconnects all profiles associated with the bredr
+connection, and then terminates the bredr link.
+
+:Usage: > bredr-disconnect <dev>
+:Example: > bredr-disconnect 1C:48:F9:9D:81:5C
+
info
----
diff --git a/client/main.c b/client/main.c
index 0a928efaa9bb0d2a806895ff8f8c0c7c0d2493bd..45ebea44f9eda80f939b9f8324fb60064f28eb50 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2303,6 +2303,106 @@ static void cmd_disconn(int argc, char *argv[])
proxy_address(proxy));
}
+static void bearer_connect_reply(DBusMessage *message, void *user_data)
+{
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message) == TRUE) {
+ bt_shell_printf("Failed to connect: %s %s\n", error.name,
+ error.message);
+ dbus_error_free(&error);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ bt_shell_printf("Connection successful\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void bearer_disconn_reply(DBusMessage *message, void *user_data)
+{
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message) == TRUE) {
+ bt_shell_printf("Failed to disconnect: %s %s\n", error.name,
+ error.message);
+ dbus_error_free(&error);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ bt_shell_printf("Disconnection successful\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_bearer_method_handler(int argc, char *argv[],
+ const char *iface,
+ const char *method)
+{
+ GDBusProxy *device;
+ GDBusProxy *bearer;
+
+ if (!check_default_ctrl())
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+
+ device = find_proxy_by_address(default_ctrl->devices, argv[1]);
+ if (!device) {
+ bt_shell_printf("Device %s not available\n", argv[1]);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ bearer = find_proxies_by_iface(default_ctrl->bearers,
+ g_dbus_proxy_get_path(device),
+ iface);
+ if (!bearer) {
+ bt_shell_printf("%s is not available on %s\n",
+ iface, argv[1]);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (!g_dbus_proxy_method_call(bearer, method, NULL,
+ strcmp(method, "Connect") == 0 ?
+ bearer_connect_reply :
+ bearer_disconn_reply,
+ NULL, NULL)) {
+ bt_shell_printf("Failed to call %s\n", method);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ bt_shell_printf("Attempting to %s %s on %s\n",
+ method,
+ argv[1],
+ iface);
+}
+
+static void cmd_le_connect(int argc, char *argv[])
+{
+ cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.LE1",
+ "Connect");
+}
+
+static void cmd_le_disconnect(int argc, char *argv[])
+{
+ cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.LE1",
+ "Disconnect");
+}
+
+static void cmd_bredr_connect(int argc, char *argv[])
+{
+ cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.BREDR1",
+ "Connect");
+}
+
+static void cmd_bredr_disconnect(int argc, char *argv[])
+{
+ cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.BREDR1",
+ "Disconnect");
+}
+
static void cmd_wake(int argc, char *argv[])
{
GDBusProxy *proxy;
@@ -2789,6 +2889,47 @@ static char *dev_set_generator(const char *text, int state)
return set_generator(text, state);
}
+static char *bearer_dev_generator(const char *text, int state,
+ const char *iface)
+{
+ char *addr;
+ GDBusProxy *device;
+ GDBusProxy *bearer;
+
+ if (!iface)
+ return NULL;
+
+ addr = dev_generator(text, state);
+ if (!addr)
+ return NULL;
+
+ device = find_proxy_by_address(default_ctrl->devices, addr);
+ if (!device)
+ goto failed;
+
+ bearer = find_proxies_by_iface(default_ctrl->bearers,
+ g_dbus_proxy_get_path(device),
+ iface);
+ if (!bearer)
+ goto failed;
+
+ return addr;
+
+failed:
+ g_free(addr);
+ return NULL;
+}
+
+static char *le_dev_generator(const char *text, int state)
+{
+ return bearer_dev_generator(text, state, "org.bluez.Bearer.LE1");
+}
+
+static char *bredr_dev_generator(const char *text, int state)
+{
+ return bearer_dev_generator(text, state, "org.bluez.Bearer.BREDR1");
+}
+
static char *attribute_generator(const char *text, int state)
{
return gatt_attribute_generator(text, state);
@@ -3528,6 +3669,17 @@ static const struct bt_shell_menu main_menu = {
{ "disconnect", "[dev] [uuid]", cmd_disconn,
"Disconnect a device or optionally disconnect "
"a single profile only", dev_generator },
+ { "le-connect", "<dev>", cmd_le_connect,
+ "Connect le on a device", le_dev_generator },
+ { "le-disconnect", "<dev>", cmd_le_disconnect,
+ "Disconnect le on a device",
+ le_dev_generator },
+ { "bredr-connect", "<dev>", cmd_bredr_connect,
+ "Connect bredr on a device",
+ bredr_dev_generator },
+ { "bredr-disconnect", "<dev>", cmd_bredr_disconnect,
+ "Disconnect bredr on a device",
+ bredr_dev_generator },
{ "wake", "[dev] [on/off]", cmd_wake, "Get/Set wake support",
dev_generator },
{ "bearer", "<dev> [last-seen/bredr/le]", cmd_bearer,
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH bluez v7 3/3] client: Add shell cmd for bearer connect/disconnect
2025-11-27 9:54 ` [PATCH bluez v7 3/3] client: Add shell cmd for bearer connect/disconnect Ye He via B4 Relay
@ 2025-11-27 15:28 ` Luiz Augusto von Dentz
2025-11-28 2:00 ` Ye He
0 siblings, 1 reply; 10+ messages in thread
From: Luiz Augusto von Dentz @ 2025-11-27 15:28 UTC (permalink / raw)
To: ye.he; +Cc: Linux Bluetooth
Hi,
On Thu, Nov 27, 2025 at 4:54 AM Ye He via B4 Relay
<devnull+ye.he.amlogic.com@kernel.org> wrote:
>
> From: Ye He <ye.he@amlogic.com>
>
> This patch adds shell command for bearer connect/disconnect.
>
> Signed-off-by: Ye He <ye.he@amlogic.com>
> ---
> client/bluetoothctl.rst | 49 ++++++++++++++++
> client/main.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 201 insertions(+)
>
> diff --git a/client/bluetoothctl.rst b/client/bluetoothctl.rst
> index 0187e877d60b28eb1e735181b3203e60da821e6f..87aae8995a29749ffa09bbfefbd74c41f242fedc 100644
> --- a/client/bluetoothctl.rst
> +++ b/client/bluetoothctl.rst
> @@ -296,6 +296,55 @@ needed.
>
> :Usage: **> disconnect <dev> [uuid]**
>
> +le-connect
> +----------
> +
> +Connect device over le.
> +
> +This command initiates a le connection to a remote device.
> +
> +An active scan report is required before the connection can be
> +established. If no advertising report is received before the timeout,
> +a le-connection-abort-by-local error will be issued.
> +
> +:Usage: > le-connect <dev>
> +:Example: > le-connect 1C:48:F9:9D:81:5C
> +
> +le-disconnect
> +-------------
> +
> +Disconnect device over le.
> +
> +By default this command disconnects all profiles/services associated with the le
> +connection, and then terminates the le link.
> +
> +:Usage: > le-disconnect <dev>
> +:Example: > le-disconnect 1C:48:F9:9D:81:5C
> +
> +bredr-connect
> +-------------
> +
> +Connect device over bredr.
> +
> +This command initiates a bredr connection to a remote device.
> +
> +By default, it establishes the bredr connection and then connects all profiles
> +that marked as auto-connectable.
> +
> +:Usage: > bredr-connect <dev>
> +:Example: > bredr-connect 1C:48:F9:9D:81:5C
> +
> +bredr-disconnect
> +----------------
> +
> +Disconnect device over bredr.
> +
> +By default this command disconnects all profiles associated with the bredr
> +connection, and then terminates the bredr link.
> +
> +:Usage: > bredr-disconnect <dev>
> +:Example: > bredr-disconnect 1C:48:F9:9D:81:5C
I really meant le and bredr submenus though, not just prefixes, so we
can later expand the bearer specific functionality as needed.
> info
> ----
>
> diff --git a/client/main.c b/client/main.c
> index 0a928efaa9bb0d2a806895ff8f8c0c7c0d2493bd..45ebea44f9eda80f939b9f8324fb60064f28eb50 100644
> --- a/client/main.c
> +++ b/client/main.c
> @@ -2303,6 +2303,106 @@ static void cmd_disconn(int argc, char *argv[])
> proxy_address(proxy));
> }
>
> +static void bearer_connect_reply(DBusMessage *message, void *user_data)
> +{
> + DBusError error;
> +
> + dbus_error_init(&error);
> +
> + if (dbus_set_error_from_message(&error, message) == TRUE) {
> + bt_shell_printf("Failed to connect: %s %s\n", error.name,
> + error.message);
> + dbus_error_free(&error);
> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
> + }
> +
> + bt_shell_printf("Connection successful\n");
> +
> + return bt_shell_noninteractive_quit(EXIT_SUCCESS);
> +}
> +
> +static void bearer_disconn_reply(DBusMessage *message, void *user_data)
> +{
> + DBusError error;
> +
> + dbus_error_init(&error);
> +
> + if (dbus_set_error_from_message(&error, message) == TRUE) {
> + bt_shell_printf("Failed to disconnect: %s %s\n", error.name,
> + error.message);
> + dbus_error_free(&error);
> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
> + }
> +
> + bt_shell_printf("Disconnection successful\n");
> +
> + return bt_shell_noninteractive_quit(EXIT_SUCCESS);
> +}
> +
> +static void cmd_bearer_method_handler(int argc, char *argv[],
> + const char *iface,
> + const char *method)
> +{
> + GDBusProxy *device;
> + GDBusProxy *bearer;
> +
> + if (!check_default_ctrl())
> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
> +
> + device = find_proxy_by_address(default_ctrl->devices, argv[1]);
> + if (!device) {
> + bt_shell_printf("Device %s not available\n", argv[1]);
> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
> + }
> +
> + bearer = find_proxies_by_iface(default_ctrl->bearers,
> + g_dbus_proxy_get_path(device),
> + iface);
> + if (!bearer) {
> + bt_shell_printf("%s is not available on %s\n",
> + iface, argv[1]);
> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
> + }
> +
> + if (!g_dbus_proxy_method_call(bearer, method, NULL,
> + strcmp(method, "Connect") == 0 ?
> + bearer_connect_reply :
> + bearer_disconn_reply,
> + NULL, NULL)) {
> + bt_shell_printf("Failed to call %s\n", method);
> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
> + }
> +
> + bt_shell_printf("Attempting to %s %s on %s\n",
> + method,
> + argv[1],
> + iface);
> +}
> +
> +static void cmd_le_connect(int argc, char *argv[])
> +{
> + cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.LE1",
> + "Connect");
> +}
> +
> +static void cmd_le_disconnect(int argc, char *argv[])
> +{
> + cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.LE1",
> + "Disconnect");
> +}
> +
> +static void cmd_bredr_connect(int argc, char *argv[])
> +{
> + cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.BREDR1",
> + "Connect");
> +}
> +
> +static void cmd_bredr_disconnect(int argc, char *argv[])
> +{
> + cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.BREDR1",
> + "Disconnect");
> +}
> +
> static void cmd_wake(int argc, char *argv[])
> {
> GDBusProxy *proxy;
> @@ -2789,6 +2889,47 @@ static char *dev_set_generator(const char *text, int state)
> return set_generator(text, state);
> }
>
> +static char *bearer_dev_generator(const char *text, int state,
> + const char *iface)
> +{
> + char *addr;
> + GDBusProxy *device;
> + GDBusProxy *bearer;
> +
> + if (!iface)
> + return NULL;
> +
> + addr = dev_generator(text, state);
> + if (!addr)
> + return NULL;
> +
> + device = find_proxy_by_address(default_ctrl->devices, addr);
> + if (!device)
> + goto failed;
> +
> + bearer = find_proxies_by_iface(default_ctrl->bearers,
> + g_dbus_proxy_get_path(device),
> + iface);
> + if (!bearer)
> + goto failed;
> +
> + return addr;
> +
> +failed:
> + g_free(addr);
> + return NULL;
> +}
> +
> +static char *le_dev_generator(const char *text, int state)
> +{
> + return bearer_dev_generator(text, state, "org.bluez.Bearer.LE1");
> +}
> +
> +static char *bredr_dev_generator(const char *text, int state)
> +{
> + return bearer_dev_generator(text, state, "org.bluez.Bearer.BREDR1");
> +}
> +
> static char *attribute_generator(const char *text, int state)
> {
> return gatt_attribute_generator(text, state);
> @@ -3528,6 +3669,17 @@ static const struct bt_shell_menu main_menu = {
> { "disconnect", "[dev] [uuid]", cmd_disconn,
> "Disconnect a device or optionally disconnect "
> "a single profile only", dev_generator },
> + { "le-connect", "<dev>", cmd_le_connect,
> + "Connect le on a device", le_dev_generator },
> + { "le-disconnect", "<dev>", cmd_le_disconnect,
> + "Disconnect le on a device",
> + le_dev_generator },
> + { "bredr-connect", "<dev>", cmd_bredr_connect,
> + "Connect bredr on a device",
> + bredr_dev_generator },
> + { "bredr-disconnect", "<dev>", cmd_bredr_disconnect,
> + "Disconnect bredr on a device",
> + bredr_dev_generator },
> { "wake", "[dev] [on/off]", cmd_wake, "Get/Set wake support",
> dev_generator },
> { "bearer", "<dev> [last-seen/bredr/le]", cmd_bearer,
>
> --
> 2.42.0
>
>
>
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH bluez v7 3/3] client: Add shell cmd for bearer connect/disconnect
2025-11-27 15:28 ` Luiz Augusto von Dentz
@ 2025-11-28 2:00 ` Ye He
0 siblings, 0 replies; 10+ messages in thread
From: Ye He @ 2025-11-28 2:00 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: Linux Bluetooth
Hi Luiz,
> [ EXTERNAL EMAIL ]
>
> Hi,
>
> On Thu, Nov 27, 2025 at 4:54 AM Ye He via B4 Relay
> <devnull+ye.he.amlogic.com@kernel.org> wrote:
>> From: Ye He <ye.he@amlogic.com>
>>
>> This patch adds shell command for bearer connect/disconnect.
>>
>> Signed-off-by: Ye He <ye.he@amlogic.com>
>> ---
>> client/bluetoothctl.rst | 49 ++++++++++++++++
>> client/main.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 201 insertions(+)
>>
>> diff --git a/client/bluetoothctl.rst b/client/bluetoothctl.rst
>> index 0187e877d60b28eb1e735181b3203e60da821e6f..87aae8995a29749ffa09bbfefbd74c41f242fedc 100644
>> --- a/client/bluetoothctl.rst
>> +++ b/client/bluetoothctl.rst
>> @@ -296,6 +296,55 @@ needed.
>>
>> :Usage: **> disconnect <dev> [uuid]**
>>
>> +le-connect
>> +----------
>> +
>> +Connect device over le.
>> +
>> +This command initiates a le connection to a remote device.
>> +
>> +An active scan report is required before the connection can be
>> +established. If no advertising report is received before the timeout,
>> +a le-connection-abort-by-local error will be issued.
>> +
>> +:Usage: > le-connect <dev>
>> +:Example: > le-connect 1C:48:F9:9D:81:5C
>> +
>> +le-disconnect
>> +-------------
>> +
>> +Disconnect device over le.
>> +
>> +By default this command disconnects all profiles/services associated with the le
>> +connection, and then terminates the le link.
>> +
>> +:Usage: > le-disconnect <dev>
>> +:Example: > le-disconnect 1C:48:F9:9D:81:5C
>> +
>> +bredr-connect
>> +-------------
>> +
>> +Connect device over bredr.
>> +
>> +This command initiates a bredr connection to a remote device.
>> +
>> +By default, it establishes the bredr connection and then connects all profiles
>> +that marked as auto-connectable.
>> +
>> +:Usage: > bredr-connect <dev>
>> +:Example: > bredr-connect 1C:48:F9:9D:81:5C
>> +
>> +bredr-disconnect
>> +----------------
>> +
>> +Disconnect device over bredr.
>> +
>> +By default this command disconnects all profiles associated with the bredr
>> +connection, and then terminates the bredr link.
>> +
>> +:Usage: > bredr-disconnect <dev>
>> +:Example: > bredr-disconnect 1C:48:F9:9D:81:5C
> I really meant le and bredr submenus though, not just prefixes, so we
> can later expand the bearer specific functionality as needed.
Sorry for misunderstanding that. Using sub-menu indeed provides better
extensibility.
I will rework it in the next version.
>> info
>> ----
>>
>> diff --git a/client/main.c b/client/main.c
>> index 0a928efaa9bb0d2a806895ff8f8c0c7c0d2493bd..45ebea44f9eda80f939b9f8324fb60064f28eb50 100644
>> --- a/client/main.c
>> +++ b/client/main.c
>> @@ -2303,6 +2303,106 @@ static void cmd_disconn(int argc, char *argv[])
>> proxy_address(proxy));
>> }
>>
>> +static void bearer_connect_reply(DBusMessage *message, void *user_data)
>> +{
>> + DBusError error;
>> +
>> + dbus_error_init(&error);
>> +
>> + if (dbus_set_error_from_message(&error, message) == TRUE) {
>> + bt_shell_printf("Failed to connect: %s %s\n", error.name,
>> + error.message);
>> + dbus_error_free(&error);
>> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
>> + }
>> +
>> + bt_shell_printf("Connection successful\n");
>> +
>> + return bt_shell_noninteractive_quit(EXIT_SUCCESS);
>> +}
>> +
>> +static void bearer_disconn_reply(DBusMessage *message, void *user_data)
>> +{
>> + DBusError error;
>> +
>> + dbus_error_init(&error);
>> +
>> + if (dbus_set_error_from_message(&error, message) == TRUE) {
>> + bt_shell_printf("Failed to disconnect: %s %s\n", error.name,
>> + error.message);
>> + dbus_error_free(&error);
>> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
>> + }
>> +
>> + bt_shell_printf("Disconnection successful\n");
>> +
>> + return bt_shell_noninteractive_quit(EXIT_SUCCESS);
>> +}
>> +
>> +static void cmd_bearer_method_handler(int argc, char *argv[],
>> + const char *iface,
>> + const char *method)
>> +{
>> + GDBusProxy *device;
>> + GDBusProxy *bearer;
>> +
>> + if (!check_default_ctrl())
>> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
>> +
>> + device = find_proxy_by_address(default_ctrl->devices, argv[1]);
>> + if (!device) {
>> + bt_shell_printf("Device %s not available\n", argv[1]);
>> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
>> + }
>> +
>> + bearer = find_proxies_by_iface(default_ctrl->bearers,
>> + g_dbus_proxy_get_path(device),
>> + iface);
>> + if (!bearer) {
>> + bt_shell_printf("%s is not available on %s\n",
>> + iface, argv[1]);
>> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
>> + }
>> +
>> + if (!g_dbus_proxy_method_call(bearer, method, NULL,
>> + strcmp(method, "Connect") == 0 ?
>> + bearer_connect_reply :
>> + bearer_disconn_reply,
>> + NULL, NULL)) {
>> + bt_shell_printf("Failed to call %s\n", method);
>> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
>> + }
>> +
>> + bt_shell_printf("Attempting to %s %s on %s\n",
>> + method,
>> + argv[1],
>> + iface);
>> +}
>> +
>> +static void cmd_le_connect(int argc, char *argv[])
>> +{
>> + cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.LE1",
>> + "Connect");
>> +}
>> +
>> +static void cmd_le_disconnect(int argc, char *argv[])
>> +{
>> + cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.LE1",
>> + "Disconnect");
>> +}
>> +
>> +static void cmd_bredr_connect(int argc, char *argv[])
>> +{
>> + cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.BREDR1",
>> + "Connect");
>> +}
>> +
>> +static void cmd_bredr_disconnect(int argc, char *argv[])
>> +{
>> + cmd_bearer_method_handler(argc, argv, "org.bluez.Bearer.BREDR1",
>> + "Disconnect");
>> +}
>> +
>> static void cmd_wake(int argc, char *argv[])
>> {
>> GDBusProxy *proxy;
>> @@ -2789,6 +2889,47 @@ static char *dev_set_generator(const char *text, int state)
>> return set_generator(text, state);
>> }
>>
>> +static char *bearer_dev_generator(const char *text, int state,
>> + const char *iface)
>> +{
>> + char *addr;
>> + GDBusProxy *device;
>> + GDBusProxy *bearer;
>> +
>> + if (!iface)
>> + return NULL;
>> +
>> + addr = dev_generator(text, state);
>> + if (!addr)
>> + return NULL;
>> +
>> + device = find_proxy_by_address(default_ctrl->devices, addr);
>> + if (!device)
>> + goto failed;
>> +
>> + bearer = find_proxies_by_iface(default_ctrl->bearers,
>> + g_dbus_proxy_get_path(device),
>> + iface);
>> + if (!bearer)
>> + goto failed;
>> +
>> + return addr;
>> +
>> +failed:
>> + g_free(addr);
>> + return NULL;
>> +}
>> +
>> +static char *le_dev_generator(const char *text, int state)
>> +{
>> + return bearer_dev_generator(text, state, "org.bluez.Bearer.LE1");
>> +}
>> +
>> +static char *bredr_dev_generator(const char *text, int state)
>> +{
>> + return bearer_dev_generator(text, state, "org.bluez.Bearer.BREDR1");
>> +}
>> +
>> static char *attribute_generator(const char *text, int state)
>> {
>> return gatt_attribute_generator(text, state);
>> @@ -3528,6 +3669,17 @@ static const struct bt_shell_menu main_menu = {
>> { "disconnect", "[dev] [uuid]", cmd_disconn,
>> "Disconnect a device or optionally disconnect "
>> "a single profile only", dev_generator },
>> + { "le-connect", "<dev>", cmd_le_connect,
>> + "Connect le on a device", le_dev_generator },
>> + { "le-disconnect", "<dev>", cmd_le_disconnect,
>> + "Disconnect le on a device",
>> + le_dev_generator },
>> + { "bredr-connect", "<dev>", cmd_bredr_connect,
>> + "Connect bredr on a device",
>> + bredr_dev_generator },
>> + { "bredr-disconnect", "<dev>", cmd_bredr_disconnect,
>> + "Disconnect bredr on a device",
>> + bredr_dev_generator },
>> { "wake", "[dev] [on/off]", cmd_wake, "Get/Set wake support",
>> dev_generator },
>> { "bearer", "<dev> [last-seen/bredr/le]", cmd_bearer,
>>
>> --
>> 2.42.0
>>
>>
>>
>
> --
> Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH bluez v9 1/3] profiles: Add bearer field to btd_profile
@ 2025-12-02 8:40 Ye He via B4 Relay
2025-12-02 9:34 ` Add implementation of bearer connect/disconnect bluez.test.bot
0 siblings, 1 reply; 10+ messages in thread
From: Ye He via B4 Relay @ 2025-12-02 8:40 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Ye He
From: Ye He <ye.he@amlogic.com>
Add bearer filed into btd_profile to indicates which bearer
type this profile belongs to. Thus we can distinct the services
per bearer.
Signed-off-by: Ye He <ye.he@amlogic.com>
---
profiles/audio/a2dp.c | 5 +++--
profiles/audio/asha.c | 1 +
profiles/audio/avrcp.c | 2 ++
profiles/audio/bap.c | 2 ++
profiles/audio/bass.c | 1 +
profiles/audio/ccp.c | 1 +
profiles/audio/csip.c | 2 ++
profiles/audio/mcp.c | 1 +
profiles/audio/micp.c | 1 +
profiles/audio/vcp.c | 1 +
profiles/battery/battery.c | 1 +
profiles/deviceinfo/deviceinfo.c | 1 +
profiles/gap/gas.c | 1 +
profiles/health/hdp_manager.c | 2 ++
profiles/input/hog.c | 1 +
profiles/input/manager.c | 1 +
profiles/midi/midi.c | 1 +
profiles/network/manager.c | 3 +++
profiles/scanparam/scan.c | 1 +
src/profile.h | 10 ++++++++++
20 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index d8f24eaebc745a6d91a8207f6595f0b90d982c39..7a37003a2b25a9e931b8efdfc974368f5ab2bac8 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -3757,8 +3757,9 @@ static void media_server_remove(struct btd_adapter *adapter)
static struct btd_profile a2dp_source_profile = {
.name = "a2dp-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
-
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = A2DP_SOURCE_UUID,
+
.device_probe = a2dp_source_probe,
.device_remove = a2dp_source_remove,
@@ -3773,7 +3774,7 @@ static struct btd_profile a2dp_source_profile = {
static struct btd_profile a2dp_sink_profile = {
.name = "a2dp-sink",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
-
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = A2DP_SINK_UUID,
.device_probe = a2dp_sink_probe,
.device_remove = a2dp_sink_remove,
diff --git a/profiles/audio/asha.c b/profiles/audio/asha.c
index e870ea06f03ac1c20e5b29fb158c815aa2ce756c..8e625fdca32ff0b40efd43e394b34559627bde8c 100644
--- a/profiles/audio/asha.c
+++ b/profiles/audio/asha.c
@@ -499,6 +499,7 @@ static int asha_source_disconnect(struct btd_service *service)
static struct btd_profile asha_source_profile = {
.name = "asha-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = ASHA_PROFILE_UUID,
.experimental = true,
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 21bc80bbd095da49788a87357fd67c8e96ab779d..e6f7e1bfde9879ab6bf028e16384d474332fe805 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -4868,6 +4868,7 @@ done:
static struct btd_profile avrcp_target_profile = {
.name = "audio-avrcp-target",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = AVRCP_TARGET_UUID,
.device_probe = avrcp_target_probe,
@@ -4951,6 +4952,7 @@ done:
static struct btd_profile avrcp_controller_profile = {
.name = "avrcp-controller",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = AVRCP_REMOTE_UUID,
.device_probe = avrcp_controller_probe,
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 85bba9543974e5bf2a1ff6380c36e518ebc095ac..a03a120ddaaed7e261d40ac06a8f9502c52772bc 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -3865,6 +3865,7 @@ static void bap_adapter_remove(struct btd_profile *p,
static struct btd_profile bap_profile = {
.name = "bap",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = PACS_UUID_STR,
.device_probe = bap_probe,
.device_remove = bap_remove,
@@ -3879,6 +3880,7 @@ static struct btd_profile bap_profile = {
static struct btd_profile bap_bcast_profile = {
.name = "bcaa",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BCAAS_UUID_STR,
.device_probe = bap_bcast_probe,
.device_remove = bap_bcast_remove,
diff --git a/profiles/audio/bass.c b/profiles/audio/bass.c
index 9ace372376f9452050724360c2c28e7cdcf1391b..8886a27d99b63b37e2937d8d70f71dfeda3d9ef2 100644
--- a/profiles/audio/bass.c
+++ b/profiles/audio/bass.c
@@ -2172,6 +2172,7 @@ static void bass_server_remove(struct btd_profile *p,
static struct btd_profile bass_service = {
.name = "bass",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BASS_UUID_STR,
.device_probe = bass_probe,
.device_remove = bass_remove,
diff --git a/profiles/audio/ccp.c b/profiles/audio/ccp.c
index 8aa537b044e13b6d6a773645b420161bedca13ef..fb85045bb8ba1ec47a33856af1129d0ef78bf500 100644
--- a/profiles/audio/ccp.c
+++ b/profiles/audio/ccp.c
@@ -208,6 +208,7 @@ ccp_server_remove(struct btd_profile *p,
static struct btd_profile ccp_profile = {
.name = "ccp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GTBS_UUID_STR,
.device_probe = ccp_probe,
.device_remove = ccp_remove,
diff --git a/profiles/audio/csip.c b/profiles/audio/csip.c
index b8f29ddf852231d89760d6fe7ca2cfd684236570..d766c3da951899d990aa59132b820737604b1b7c 100644
--- a/profiles/audio/csip.c
+++ b/profiles/audio/csip.c
@@ -303,6 +303,7 @@ static void csip_remove(struct btd_service *service)
static struct btd_profile csip_profile = {
.name = "csip",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = CSIS_UUID_STR,
.device_probe = csip_probe,
@@ -442,6 +443,7 @@ static void csis_server_remove(struct btd_profile *p,
static struct btd_profile csis_profile = {
.name = "csis",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.local_uuid = CSIS_UUID_STR,
.adapter_probe = csis_server_probe,
diff --git a/profiles/audio/mcp.c b/profiles/audio/mcp.c
index 6651b0897e6f631906b1467f5a479737541da286..8d4eed64399195533ac13fd075d7196a35cf2113 100644
--- a/profiles/audio/mcp.c
+++ b/profiles/audio/mcp.c
@@ -383,6 +383,7 @@ static void media_control_server_remove(struct btd_profile *p,
static struct btd_profile mcp_profile = {
.name = "mcp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GMCS_UUID_STR,
.device_probe = mcp_probe,
.device_remove = mcp_remove,
diff --git a/profiles/audio/micp.c b/profiles/audio/micp.c
index f1fb133897320677225a1c8bee06b4a1214f14fa..475f32daf75c06dc28ca72420a80e30802e5a3e9 100644
--- a/profiles/audio/micp.c
+++ b/profiles/audio/micp.c
@@ -300,6 +300,7 @@ static void micp_server_remove(struct btd_profile *p,
static struct btd_profile micp_profile = {
.name = "micp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = MICS_UUID_STR,
.device_probe = micp_probe,
diff --git a/profiles/audio/vcp.c b/profiles/audio/vcp.c
index 8949c71858e53448ee01c5c4261082f3912a759c..471ad59250386941c377e2f81e911467d7023cce 100644
--- a/profiles/audio/vcp.c
+++ b/profiles/audio/vcp.c
@@ -328,6 +328,7 @@ static void vcp_server_remove(struct btd_profile *p,
static struct btd_profile vcp_profile = {
.name = "vcp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = VCS_UUID_STR,
.device_probe = vcp_probe,
diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 050234a0fa03813dc9e1b8302689fc68ec254184..2fe1f4aca2cf7b21e52bec989711741d6d7e25b5 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -327,6 +327,7 @@ static int batt_disconnect(struct btd_service *service)
static struct btd_profile batt_profile = {
.name = "batt-profile",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BATTERY_UUID,
.device_probe = batt_probe,
.device_remove = batt_remove,
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
index f5adb101e312108be8dae20c75cc74e1ff7eaabf..e77bb50b457a28f08f3e9d2ecf8d81d80da86106 100644
--- a/profiles/deviceinfo/deviceinfo.c
+++ b/profiles/deviceinfo/deviceinfo.c
@@ -137,6 +137,7 @@ static int deviceinfo_disconnect(struct btd_service *service)
static struct btd_profile deviceinfo_profile = {
.name = "deviceinfo",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = DEVICE_INFORMATION_UUID,
.device_probe = deviceinfo_probe,
.device_remove = deviceinfo_remove,
diff --git a/profiles/gap/gas.c b/profiles/gap/gas.c
index dd45554d43ebc267d40a8fe4a8fab48f602bf6bc..0f41c9e6c2a5c7d980509ae66d8d7d7c2678fd21 100644
--- a/profiles/gap/gas.c
+++ b/profiles/gap/gas.c
@@ -366,6 +366,7 @@ static int gap_disconnect(struct btd_service *service)
static struct btd_profile gap_profile = {
.name = "gap-profile",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GAP_UUID,
.device_probe = gap_probe,
.device_remove = gap_remove,
diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index d1e627a3382a01bdd5002bcc0da01da35e872da1..72b69428036df77e2cdb224f186fb13191f955ed 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
@@ -57,6 +57,7 @@ static void hdp_driver_remove(struct btd_service *service)
static struct btd_profile hdp_source_profile = {
.name = "hdp-source",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = HDP_SOURCE_UUID,
.device_probe = hdp_driver_probe,
@@ -68,6 +69,7 @@ static struct btd_profile hdp_source_profile = {
static struct btd_profile hdp_sink_profile = {
.name = "hdp-sink",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = HDP_SINK_UUID,
.device_probe = hdp_driver_probe,
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index 1f5b82b774353244067e460f49aaccd09e26dcc8..f50a0f217f7f732f82645e289419e51ee6412917 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -215,6 +215,7 @@ static int hog_disconnect(struct btd_service *service)
static struct btd_profile hog_profile = {
.name = "input-hog",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = HOG_UUID,
.device_probe = hog_probe,
.device_remove = hog_remove,
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index b0e415f6706c54e7c96199d3bb5e483d0927153f..0fcd6728c2fca83f03f7333f50102658553403e7 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -45,6 +45,7 @@ static void hid_server_remove(struct btd_profile *p,
static struct btd_profile input_profile = {
.name = "input-hid",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = HID_UUID,
.remote_uuid = HID_UUID,
diff --git a/profiles/midi/midi.c b/profiles/midi/midi.c
index 90e00a5f58361f1da57a71f393e581da5128310c..ea4719b95b23aa97850de362da9012728427f08e 100644
--- a/profiles/midi/midi.c
+++ b/profiles/midi/midi.c
@@ -458,6 +458,7 @@ static int midi_disconnect(struct btd_service *service)
static struct btd_profile midi_profile = {
.name = "MIDI GATT Driver",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = MIDI_UUID,
.priority = BTD_PROFILE_PRIORITY_HIGH,
.auto_connect = true,
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 51f382529df27600d1a4fd806cb656d7f1a682af..693547d45fbc5b2f227fed832b4efb8fb87c2d59 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -120,6 +120,7 @@ static void nap_server_remove(struct btd_profile *p,
static struct btd_profile panu_profile = {
.name = "network-panu",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = NAP_UUID,
.remote_uuid = PANU_UUID,
.device_probe = connection_register,
@@ -132,6 +133,7 @@ static struct btd_profile panu_profile = {
static struct btd_profile gn_profile = {
.name = "network-gn",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = PANU_UUID,
.remote_uuid = GN_UUID,
.device_probe = connection_register,
@@ -144,6 +146,7 @@ static struct btd_profile gn_profile = {
static struct btd_profile nap_profile = {
.name = "network-nap",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = PANU_UUID,
.remote_uuid = NAP_UUID,
.device_probe = connection_register,
diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c
index 1c531773740c847e970ac45b7fbda2c0c9501ded..a66f80eabf3ef63e35cfd5e8da30e4aa18420b94 100644
--- a/profiles/scanparam/scan.c
+++ b/profiles/scanparam/scan.c
@@ -259,6 +259,7 @@ static int scan_param_probe(struct btd_service *service)
static struct btd_profile scan_profile = {
.name = "Scan Parameters Client Driver",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = SCAN_PARAMETERS_UUID,
.device_probe = scan_param_probe,
.device_remove = scan_param_remove,
diff --git a/src/profile.h b/src/profile.h
index 424ce55ad65748ead13b1a38d67fbad6beb2b828..1281d8d9a0daa5de6578a5ae6df8fc211269d409 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -12,12 +12,22 @@
#define BTD_PROFILE_PRIORITY_MEDIUM 1
#define BTD_PROFILE_PRIORITY_HIGH 2
+#define BTD_PROFILE_BEARER_ANY 0
+#define BTD_PROFILE_BEARER_LE 1
+#define BTD_PROFILE_BEARER_BREDR 2
+
struct btd_service;
struct btd_profile {
const char *name;
int priority;
+ /* Indicates which bearer type this profile belongs to. Some profiles
+ * may exist in both BR/EDR and LE, in which case they should be
+ * registered with BTD_PROFILE_BEARER_ANY.
+ */
+ int bearer;
+
const char *local_uuid;
const char *remote_uuid;
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH bluez v8 1/3] profiles: Add bearer field to btd_profile
@ 2025-12-01 8:28 Ye He via B4 Relay
2025-12-01 9:33 ` Add implementation of bearer connect/disconnect bluez.test.bot
0 siblings, 1 reply; 10+ messages in thread
From: Ye He via B4 Relay @ 2025-12-01 8:28 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Ye He
From: Ye He <ye.he@amlogic.com>
Add bearer filed into btd_profile to indicates which bearer
type this profile belongs to. Thus we can distinct the services
per bearer.
Signed-off-by: Ye He <ye.he@amlogic.com>
---
profiles/audio/a2dp.c | 5 +++--
profiles/audio/asha.c | 1 +
profiles/audio/avrcp.c | 2 ++
profiles/audio/bap.c | 2 ++
profiles/audio/bass.c | 1 +
profiles/audio/ccp.c | 1 +
profiles/audio/csip.c | 2 ++
profiles/audio/mcp.c | 1 +
profiles/audio/micp.c | 1 +
profiles/audio/vcp.c | 1 +
profiles/battery/battery.c | 1 +
profiles/deviceinfo/deviceinfo.c | 1 +
profiles/gap/gas.c | 1 +
profiles/health/hdp_manager.c | 2 ++
profiles/input/hog.c | 1 +
profiles/input/manager.c | 1 +
profiles/midi/midi.c | 1 +
profiles/network/manager.c | 3 +++
profiles/scanparam/scan.c | 1 +
src/profile.h | 10 ++++++++++
20 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index d8f24eaebc745a6d91a8207f6595f0b90d982c39..7a37003a2b25a9e931b8efdfc974368f5ab2bac8 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -3757,8 +3757,9 @@ static void media_server_remove(struct btd_adapter *adapter)
static struct btd_profile a2dp_source_profile = {
.name = "a2dp-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
-
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = A2DP_SOURCE_UUID,
+
.device_probe = a2dp_source_probe,
.device_remove = a2dp_source_remove,
@@ -3773,7 +3774,7 @@ static struct btd_profile a2dp_source_profile = {
static struct btd_profile a2dp_sink_profile = {
.name = "a2dp-sink",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
-
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = A2DP_SINK_UUID,
.device_probe = a2dp_sink_probe,
.device_remove = a2dp_sink_remove,
diff --git a/profiles/audio/asha.c b/profiles/audio/asha.c
index e870ea06f03ac1c20e5b29fb158c815aa2ce756c..8e625fdca32ff0b40efd43e394b34559627bde8c 100644
--- a/profiles/audio/asha.c
+++ b/profiles/audio/asha.c
@@ -499,6 +499,7 @@ static int asha_source_disconnect(struct btd_service *service)
static struct btd_profile asha_source_profile = {
.name = "asha-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = ASHA_PROFILE_UUID,
.experimental = true,
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 21bc80bbd095da49788a87357fd67c8e96ab779d..e6f7e1bfde9879ab6bf028e16384d474332fe805 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -4868,6 +4868,7 @@ done:
static struct btd_profile avrcp_target_profile = {
.name = "audio-avrcp-target",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = AVRCP_TARGET_UUID,
.device_probe = avrcp_target_probe,
@@ -4951,6 +4952,7 @@ done:
static struct btd_profile avrcp_controller_profile = {
.name = "avrcp-controller",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = AVRCP_REMOTE_UUID,
.device_probe = avrcp_controller_probe,
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 85bba9543974e5bf2a1ff6380c36e518ebc095ac..a03a120ddaaed7e261d40ac06a8f9502c52772bc 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -3865,6 +3865,7 @@ static void bap_adapter_remove(struct btd_profile *p,
static struct btd_profile bap_profile = {
.name = "bap",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = PACS_UUID_STR,
.device_probe = bap_probe,
.device_remove = bap_remove,
@@ -3879,6 +3880,7 @@ static struct btd_profile bap_profile = {
static struct btd_profile bap_bcast_profile = {
.name = "bcaa",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BCAAS_UUID_STR,
.device_probe = bap_bcast_probe,
.device_remove = bap_bcast_remove,
diff --git a/profiles/audio/bass.c b/profiles/audio/bass.c
index 9ace372376f9452050724360c2c28e7cdcf1391b..8886a27d99b63b37e2937d8d70f71dfeda3d9ef2 100644
--- a/profiles/audio/bass.c
+++ b/profiles/audio/bass.c
@@ -2172,6 +2172,7 @@ static void bass_server_remove(struct btd_profile *p,
static struct btd_profile bass_service = {
.name = "bass",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BASS_UUID_STR,
.device_probe = bass_probe,
.device_remove = bass_remove,
diff --git a/profiles/audio/ccp.c b/profiles/audio/ccp.c
index 8aa537b044e13b6d6a773645b420161bedca13ef..fb85045bb8ba1ec47a33856af1129d0ef78bf500 100644
--- a/profiles/audio/ccp.c
+++ b/profiles/audio/ccp.c
@@ -208,6 +208,7 @@ ccp_server_remove(struct btd_profile *p,
static struct btd_profile ccp_profile = {
.name = "ccp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GTBS_UUID_STR,
.device_probe = ccp_probe,
.device_remove = ccp_remove,
diff --git a/profiles/audio/csip.c b/profiles/audio/csip.c
index b8f29ddf852231d89760d6fe7ca2cfd684236570..d766c3da951899d990aa59132b820737604b1b7c 100644
--- a/profiles/audio/csip.c
+++ b/profiles/audio/csip.c
@@ -303,6 +303,7 @@ static void csip_remove(struct btd_service *service)
static struct btd_profile csip_profile = {
.name = "csip",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = CSIS_UUID_STR,
.device_probe = csip_probe,
@@ -442,6 +443,7 @@ static void csis_server_remove(struct btd_profile *p,
static struct btd_profile csis_profile = {
.name = "csis",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.local_uuid = CSIS_UUID_STR,
.adapter_probe = csis_server_probe,
diff --git a/profiles/audio/mcp.c b/profiles/audio/mcp.c
index 6651b0897e6f631906b1467f5a479737541da286..8d4eed64399195533ac13fd075d7196a35cf2113 100644
--- a/profiles/audio/mcp.c
+++ b/profiles/audio/mcp.c
@@ -383,6 +383,7 @@ static void media_control_server_remove(struct btd_profile *p,
static struct btd_profile mcp_profile = {
.name = "mcp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GMCS_UUID_STR,
.device_probe = mcp_probe,
.device_remove = mcp_remove,
diff --git a/profiles/audio/micp.c b/profiles/audio/micp.c
index f1fb133897320677225a1c8bee06b4a1214f14fa..475f32daf75c06dc28ca72420a80e30802e5a3e9 100644
--- a/profiles/audio/micp.c
+++ b/profiles/audio/micp.c
@@ -300,6 +300,7 @@ static void micp_server_remove(struct btd_profile *p,
static struct btd_profile micp_profile = {
.name = "micp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = MICS_UUID_STR,
.device_probe = micp_probe,
diff --git a/profiles/audio/vcp.c b/profiles/audio/vcp.c
index 8949c71858e53448ee01c5c4261082f3912a759c..471ad59250386941c377e2f81e911467d7023cce 100644
--- a/profiles/audio/vcp.c
+++ b/profiles/audio/vcp.c
@@ -328,6 +328,7 @@ static void vcp_server_remove(struct btd_profile *p,
static struct btd_profile vcp_profile = {
.name = "vcp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = VCS_UUID_STR,
.device_probe = vcp_probe,
diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 050234a0fa03813dc9e1b8302689fc68ec254184..2fe1f4aca2cf7b21e52bec989711741d6d7e25b5 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -327,6 +327,7 @@ static int batt_disconnect(struct btd_service *service)
static struct btd_profile batt_profile = {
.name = "batt-profile",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BATTERY_UUID,
.device_probe = batt_probe,
.device_remove = batt_remove,
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
index f5adb101e312108be8dae20c75cc74e1ff7eaabf..e77bb50b457a28f08f3e9d2ecf8d81d80da86106 100644
--- a/profiles/deviceinfo/deviceinfo.c
+++ b/profiles/deviceinfo/deviceinfo.c
@@ -137,6 +137,7 @@ static int deviceinfo_disconnect(struct btd_service *service)
static struct btd_profile deviceinfo_profile = {
.name = "deviceinfo",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = DEVICE_INFORMATION_UUID,
.device_probe = deviceinfo_probe,
.device_remove = deviceinfo_remove,
diff --git a/profiles/gap/gas.c b/profiles/gap/gas.c
index dd45554d43ebc267d40a8fe4a8fab48f602bf6bc..0f41c9e6c2a5c7d980509ae66d8d7d7c2678fd21 100644
--- a/profiles/gap/gas.c
+++ b/profiles/gap/gas.c
@@ -366,6 +366,7 @@ static int gap_disconnect(struct btd_service *service)
static struct btd_profile gap_profile = {
.name = "gap-profile",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GAP_UUID,
.device_probe = gap_probe,
.device_remove = gap_remove,
diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index d1e627a3382a01bdd5002bcc0da01da35e872da1..72b69428036df77e2cdb224f186fb13191f955ed 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
@@ -57,6 +57,7 @@ static void hdp_driver_remove(struct btd_service *service)
static struct btd_profile hdp_source_profile = {
.name = "hdp-source",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = HDP_SOURCE_UUID,
.device_probe = hdp_driver_probe,
@@ -68,6 +69,7 @@ static struct btd_profile hdp_source_profile = {
static struct btd_profile hdp_sink_profile = {
.name = "hdp-sink",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = HDP_SINK_UUID,
.device_probe = hdp_driver_probe,
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index 1f5b82b774353244067e460f49aaccd09e26dcc8..f50a0f217f7f732f82645e289419e51ee6412917 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -215,6 +215,7 @@ static int hog_disconnect(struct btd_service *service)
static struct btd_profile hog_profile = {
.name = "input-hog",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = HOG_UUID,
.device_probe = hog_probe,
.device_remove = hog_remove,
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index b0e415f6706c54e7c96199d3bb5e483d0927153f..0fcd6728c2fca83f03f7333f50102658553403e7 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -45,6 +45,7 @@ static void hid_server_remove(struct btd_profile *p,
static struct btd_profile input_profile = {
.name = "input-hid",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = HID_UUID,
.remote_uuid = HID_UUID,
diff --git a/profiles/midi/midi.c b/profiles/midi/midi.c
index 90e00a5f58361f1da57a71f393e581da5128310c..ea4719b95b23aa97850de362da9012728427f08e 100644
--- a/profiles/midi/midi.c
+++ b/profiles/midi/midi.c
@@ -458,6 +458,7 @@ static int midi_disconnect(struct btd_service *service)
static struct btd_profile midi_profile = {
.name = "MIDI GATT Driver",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = MIDI_UUID,
.priority = BTD_PROFILE_PRIORITY_HIGH,
.auto_connect = true,
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 51f382529df27600d1a4fd806cb656d7f1a682af..693547d45fbc5b2f227fed832b4efb8fb87c2d59 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -120,6 +120,7 @@ static void nap_server_remove(struct btd_profile *p,
static struct btd_profile panu_profile = {
.name = "network-panu",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = NAP_UUID,
.remote_uuid = PANU_UUID,
.device_probe = connection_register,
@@ -132,6 +133,7 @@ static struct btd_profile panu_profile = {
static struct btd_profile gn_profile = {
.name = "network-gn",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = PANU_UUID,
.remote_uuid = GN_UUID,
.device_probe = connection_register,
@@ -144,6 +146,7 @@ static struct btd_profile gn_profile = {
static struct btd_profile nap_profile = {
.name = "network-nap",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = PANU_UUID,
.remote_uuid = NAP_UUID,
.device_probe = connection_register,
diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c
index 1c531773740c847e970ac45b7fbda2c0c9501ded..a66f80eabf3ef63e35cfd5e8da30e4aa18420b94 100644
--- a/profiles/scanparam/scan.c
+++ b/profiles/scanparam/scan.c
@@ -259,6 +259,7 @@ static int scan_param_probe(struct btd_service *service)
static struct btd_profile scan_profile = {
.name = "Scan Parameters Client Driver",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = SCAN_PARAMETERS_UUID,
.device_probe = scan_param_probe,
.device_remove = scan_param_remove,
diff --git a/src/profile.h b/src/profile.h
index 424ce55ad65748ead13b1a38d67fbad6beb2b828..1281d8d9a0daa5de6578a5ae6df8fc211269d409 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -12,12 +12,22 @@
#define BTD_PROFILE_PRIORITY_MEDIUM 1
#define BTD_PROFILE_PRIORITY_HIGH 2
+#define BTD_PROFILE_BEARER_ANY 0
+#define BTD_PROFILE_BEARER_LE 1
+#define BTD_PROFILE_BEARER_BREDR 2
+
struct btd_service;
struct btd_profile {
const char *name;
int priority;
+ /* Indicates which bearer type this profile belongs to. Some profiles
+ * may exist in both BR/EDR and LE, in which case they should be
+ * registered with BTD_PROFILE_BEARER_ANY.
+ */
+ int bearer;
+
const char *local_uuid;
const char *remote_uuid;
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH bluez v6 1/3] profiles: Add bearer field to btd_profile
@ 2025-11-26 5:21 Ye He via B4 Relay
2025-11-26 6:24 ` Add implementation of bearer connect/disconnect bluez.test.bot
0 siblings, 1 reply; 10+ messages in thread
From: Ye He via B4 Relay @ 2025-11-26 5:21 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Ye He
From: Ye He <ye.he@amlogic.com>
Add bearer filed into btd_profile to indicates which bearer
type this profile belongs to. Thus we can distinct the services
per bearer.
Signed-off-by: Ye He <ye.he@amlogic.com>
---
profiles/audio/a2dp.c | 5 +++--
profiles/audio/asha.c | 1 +
profiles/audio/avrcp.c | 2 ++
profiles/audio/bap.c | 2 ++
profiles/audio/bass.c | 1 +
profiles/audio/ccp.c | 1 +
profiles/audio/csip.c | 2 ++
profiles/audio/mcp.c | 1 +
profiles/audio/micp.c | 1 +
profiles/audio/vcp.c | 1 +
profiles/battery/battery.c | 1 +
profiles/deviceinfo/deviceinfo.c | 1 +
profiles/gap/gas.c | 1 +
profiles/health/hdp_manager.c | 2 ++
profiles/input/hog.c | 1 +
profiles/input/manager.c | 1 +
profiles/midi/midi.c | 1 +
profiles/network/manager.c | 3 +++
profiles/scanparam/scan.c | 1 +
src/profile.h | 10 ++++++++++
20 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index d8f24eaebc745a6d91a8207f6595f0b90d982c39..7a37003a2b25a9e931b8efdfc974368f5ab2bac8 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -3757,8 +3757,9 @@ static void media_server_remove(struct btd_adapter *adapter)
static struct btd_profile a2dp_source_profile = {
.name = "a2dp-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
-
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = A2DP_SOURCE_UUID,
+
.device_probe = a2dp_source_probe,
.device_remove = a2dp_source_remove,
@@ -3773,7 +3774,7 @@ static struct btd_profile a2dp_source_profile = {
static struct btd_profile a2dp_sink_profile = {
.name = "a2dp-sink",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
-
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = A2DP_SINK_UUID,
.device_probe = a2dp_sink_probe,
.device_remove = a2dp_sink_remove,
diff --git a/profiles/audio/asha.c b/profiles/audio/asha.c
index e870ea06f03ac1c20e5b29fb158c815aa2ce756c..8e625fdca32ff0b40efd43e394b34559627bde8c 100644
--- a/profiles/audio/asha.c
+++ b/profiles/audio/asha.c
@@ -499,6 +499,7 @@ static int asha_source_disconnect(struct btd_service *service)
static struct btd_profile asha_source_profile = {
.name = "asha-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = ASHA_PROFILE_UUID,
.experimental = true,
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 21bc80bbd095da49788a87357fd67c8e96ab779d..e6f7e1bfde9879ab6bf028e16384d474332fe805 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -4868,6 +4868,7 @@ done:
static struct btd_profile avrcp_target_profile = {
.name = "audio-avrcp-target",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = AVRCP_TARGET_UUID,
.device_probe = avrcp_target_probe,
@@ -4951,6 +4952,7 @@ done:
static struct btd_profile avrcp_controller_profile = {
.name = "avrcp-controller",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = AVRCP_REMOTE_UUID,
.device_probe = avrcp_controller_probe,
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 85bba9543974e5bf2a1ff6380c36e518ebc095ac..a03a120ddaaed7e261d40ac06a8f9502c52772bc 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -3865,6 +3865,7 @@ static void bap_adapter_remove(struct btd_profile *p,
static struct btd_profile bap_profile = {
.name = "bap",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = PACS_UUID_STR,
.device_probe = bap_probe,
.device_remove = bap_remove,
@@ -3879,6 +3880,7 @@ static struct btd_profile bap_profile = {
static struct btd_profile bap_bcast_profile = {
.name = "bcaa",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BCAAS_UUID_STR,
.device_probe = bap_bcast_probe,
.device_remove = bap_bcast_remove,
diff --git a/profiles/audio/bass.c b/profiles/audio/bass.c
index 9ace372376f9452050724360c2c28e7cdcf1391b..8886a27d99b63b37e2937d8d70f71dfeda3d9ef2 100644
--- a/profiles/audio/bass.c
+++ b/profiles/audio/bass.c
@@ -2172,6 +2172,7 @@ static void bass_server_remove(struct btd_profile *p,
static struct btd_profile bass_service = {
.name = "bass",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BASS_UUID_STR,
.device_probe = bass_probe,
.device_remove = bass_remove,
diff --git a/profiles/audio/ccp.c b/profiles/audio/ccp.c
index 8aa537b044e13b6d6a773645b420161bedca13ef..fb85045bb8ba1ec47a33856af1129d0ef78bf500 100644
--- a/profiles/audio/ccp.c
+++ b/profiles/audio/ccp.c
@@ -208,6 +208,7 @@ ccp_server_remove(struct btd_profile *p,
static struct btd_profile ccp_profile = {
.name = "ccp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GTBS_UUID_STR,
.device_probe = ccp_probe,
.device_remove = ccp_remove,
diff --git a/profiles/audio/csip.c b/profiles/audio/csip.c
index b8f29ddf852231d89760d6fe7ca2cfd684236570..d766c3da951899d990aa59132b820737604b1b7c 100644
--- a/profiles/audio/csip.c
+++ b/profiles/audio/csip.c
@@ -303,6 +303,7 @@ static void csip_remove(struct btd_service *service)
static struct btd_profile csip_profile = {
.name = "csip",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = CSIS_UUID_STR,
.device_probe = csip_probe,
@@ -442,6 +443,7 @@ static void csis_server_remove(struct btd_profile *p,
static struct btd_profile csis_profile = {
.name = "csis",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.local_uuid = CSIS_UUID_STR,
.adapter_probe = csis_server_probe,
diff --git a/profiles/audio/mcp.c b/profiles/audio/mcp.c
index 6651b0897e6f631906b1467f5a479737541da286..8d4eed64399195533ac13fd075d7196a35cf2113 100644
--- a/profiles/audio/mcp.c
+++ b/profiles/audio/mcp.c
@@ -383,6 +383,7 @@ static void media_control_server_remove(struct btd_profile *p,
static struct btd_profile mcp_profile = {
.name = "mcp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GMCS_UUID_STR,
.device_probe = mcp_probe,
.device_remove = mcp_remove,
diff --git a/profiles/audio/micp.c b/profiles/audio/micp.c
index f1fb133897320677225a1c8bee06b4a1214f14fa..475f32daf75c06dc28ca72420a80e30802e5a3e9 100644
--- a/profiles/audio/micp.c
+++ b/profiles/audio/micp.c
@@ -300,6 +300,7 @@ static void micp_server_remove(struct btd_profile *p,
static struct btd_profile micp_profile = {
.name = "micp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = MICS_UUID_STR,
.device_probe = micp_probe,
diff --git a/profiles/audio/vcp.c b/profiles/audio/vcp.c
index 8949c71858e53448ee01c5c4261082f3912a759c..471ad59250386941c377e2f81e911467d7023cce 100644
--- a/profiles/audio/vcp.c
+++ b/profiles/audio/vcp.c
@@ -328,6 +328,7 @@ static void vcp_server_remove(struct btd_profile *p,
static struct btd_profile vcp_profile = {
.name = "vcp",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = VCS_UUID_STR,
.device_probe = vcp_probe,
diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 050234a0fa03813dc9e1b8302689fc68ec254184..2fe1f4aca2cf7b21e52bec989711741d6d7e25b5 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -327,6 +327,7 @@ static int batt_disconnect(struct btd_service *service)
static struct btd_profile batt_profile = {
.name = "batt-profile",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = BATTERY_UUID,
.device_probe = batt_probe,
.device_remove = batt_remove,
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
index f5adb101e312108be8dae20c75cc74e1ff7eaabf..e77bb50b457a28f08f3e9d2ecf8d81d80da86106 100644
--- a/profiles/deviceinfo/deviceinfo.c
+++ b/profiles/deviceinfo/deviceinfo.c
@@ -137,6 +137,7 @@ static int deviceinfo_disconnect(struct btd_service *service)
static struct btd_profile deviceinfo_profile = {
.name = "deviceinfo",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = DEVICE_INFORMATION_UUID,
.device_probe = deviceinfo_probe,
.device_remove = deviceinfo_remove,
diff --git a/profiles/gap/gas.c b/profiles/gap/gas.c
index dd45554d43ebc267d40a8fe4a8fab48f602bf6bc..0f41c9e6c2a5c7d980509ae66d8d7d7c2678fd21 100644
--- a/profiles/gap/gas.c
+++ b/profiles/gap/gas.c
@@ -366,6 +366,7 @@ static int gap_disconnect(struct btd_service *service)
static struct btd_profile gap_profile = {
.name = "gap-profile",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = GAP_UUID,
.device_probe = gap_probe,
.device_remove = gap_remove,
diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index d1e627a3382a01bdd5002bcc0da01da35e872da1..72b69428036df77e2cdb224f186fb13191f955ed 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
@@ -57,6 +57,7 @@ static void hdp_driver_remove(struct btd_service *service)
static struct btd_profile hdp_source_profile = {
.name = "hdp-source",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = HDP_SOURCE_UUID,
.device_probe = hdp_driver_probe,
@@ -68,6 +69,7 @@ static struct btd_profile hdp_source_profile = {
static struct btd_profile hdp_sink_profile = {
.name = "hdp-sink",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.remote_uuid = HDP_SINK_UUID,
.device_probe = hdp_driver_probe,
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index 1f5b82b774353244067e460f49aaccd09e26dcc8..f50a0f217f7f732f82645e289419e51ee6412917 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -215,6 +215,7 @@ static int hog_disconnect(struct btd_service *service)
static struct btd_profile hog_profile = {
.name = "input-hog",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = HOG_UUID,
.device_probe = hog_probe,
.device_remove = hog_remove,
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index b0e415f6706c54e7c96199d3bb5e483d0927153f..0fcd6728c2fca83f03f7333f50102658553403e7 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -45,6 +45,7 @@ static void hid_server_remove(struct btd_profile *p,
static struct btd_profile input_profile = {
.name = "input-hid",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = HID_UUID,
.remote_uuid = HID_UUID,
diff --git a/profiles/midi/midi.c b/profiles/midi/midi.c
index 90e00a5f58361f1da57a71f393e581da5128310c..ea4719b95b23aa97850de362da9012728427f08e 100644
--- a/profiles/midi/midi.c
+++ b/profiles/midi/midi.c
@@ -458,6 +458,7 @@ static int midi_disconnect(struct btd_service *service)
static struct btd_profile midi_profile = {
.name = "MIDI GATT Driver",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = MIDI_UUID,
.priority = BTD_PROFILE_PRIORITY_HIGH,
.auto_connect = true,
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 51f382529df27600d1a4fd806cb656d7f1a682af..693547d45fbc5b2f227fed832b4efb8fb87c2d59 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -120,6 +120,7 @@ static void nap_server_remove(struct btd_profile *p,
static struct btd_profile panu_profile = {
.name = "network-panu",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = NAP_UUID,
.remote_uuid = PANU_UUID,
.device_probe = connection_register,
@@ -132,6 +133,7 @@ static struct btd_profile panu_profile = {
static struct btd_profile gn_profile = {
.name = "network-gn",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = PANU_UUID,
.remote_uuid = GN_UUID,
.device_probe = connection_register,
@@ -144,6 +146,7 @@ static struct btd_profile gn_profile = {
static struct btd_profile nap_profile = {
.name = "network-nap",
+ .bearer = BTD_PROFILE_BEARER_BREDR,
.local_uuid = PANU_UUID,
.remote_uuid = NAP_UUID,
.device_probe = connection_register,
diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c
index 1c531773740c847e970ac45b7fbda2c0c9501ded..a66f80eabf3ef63e35cfd5e8da30e4aa18420b94 100644
--- a/profiles/scanparam/scan.c
+++ b/profiles/scanparam/scan.c
@@ -259,6 +259,7 @@ static int scan_param_probe(struct btd_service *service)
static struct btd_profile scan_profile = {
.name = "Scan Parameters Client Driver",
+ .bearer = BTD_PROFILE_BEARER_LE,
.remote_uuid = SCAN_PARAMETERS_UUID,
.device_probe = scan_param_probe,
.device_remove = scan_param_remove,
diff --git a/src/profile.h b/src/profile.h
index 424ce55ad65748ead13b1a38d67fbad6beb2b828..1281d8d9a0daa5de6578a5ae6df8fc211269d409 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -12,12 +12,22 @@
#define BTD_PROFILE_PRIORITY_MEDIUM 1
#define BTD_PROFILE_PRIORITY_HIGH 2
+#define BTD_PROFILE_BEARER_ANY 0
+#define BTD_PROFILE_BEARER_LE 1
+#define BTD_PROFILE_BEARER_BREDR 2
+
struct btd_service;
struct btd_profile {
const char *name;
int priority;
+ /* Indicates which bearer type this profile belongs to. Some profiles
+ * may exist in both BR/EDR and LE, in which case they should be
+ * registered with BTD_PROFILE_BEARER_ANY.
+ */
+ int bearer;
+
const char *local_uuid;
const char *remote_uuid;
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-12-02 9:34 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-27 9:54 [PATCH bluez v7 0/3] Add implementation of bearer connect/disconnect Ye He via B4 Relay
2025-11-27 9:54 ` [PATCH bluez v7 1/3] profiles: Add bearer field to btd_profile Ye He via B4 Relay
2025-11-27 11:00 ` Add implementation of bearer connect/disconnect bluez.test.bot
2025-11-27 9:54 ` [PATCH bluez v7 2/3] bearer: Implement Connect/Disconnect methods Ye He via B4 Relay
2025-11-27 9:54 ` [PATCH bluez v7 3/3] client: Add shell cmd for bearer connect/disconnect Ye He via B4 Relay
2025-11-27 15:28 ` Luiz Augusto von Dentz
2025-11-28 2:00 ` Ye He
-- strict thread matches above, loose matches on Subject: below --
2025-12-02 8:40 [PATCH bluez v9 1/3] profiles: Add bearer field to btd_profile Ye He via B4 Relay
2025-12-02 9:34 ` Add implementation of bearer connect/disconnect bluez.test.bot
2025-12-01 8:28 [PATCH bluez v8 1/3] profiles: Add bearer field to btd_profile Ye He via B4 Relay
2025-12-01 9:33 ` Add implementation of bearer connect/disconnect bluez.test.bot
2025-11-26 5:21 [PATCH bluez v6 1/3] profiles: Add bearer field to btd_profile Ye He via B4 Relay
2025-11-26 6:24 ` Add implementation of bearer connect/disconnect bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox