2024-02-23 15:30:03

by Sergey Bobrenok

[permalink] [raw]
Subject: [PATCH] main.conf: Introduce GATT.ReverseClient option

General.ReverseServiceDiscovery option is responsible for two
different things:
1. It disables SDP reverse discovering. As a side effect, some BR/EDR
profiles cannot operate properly. E.g. AVRCP-target profile needs SDP
results to determine the peer's AVRCP version.
2. It disables GATT-client creation back to the GATT connection
initiator. It may be useful for peripheral devices, especially if the
peer doesn't expect them to connect back (and currently some IOS
versions don't). This behavior was introduced in
8de73cd12 ("main.conf: Make ReverseServiceDiscovery work with LE")

For peripheral devices implementing only A2DP-sink, AVRCP-target, and
GATT profiles (e.g. BT loudspeakers), it may be useful to disable
GATT-client functionality, but still have SDP reverse discovering.

Unfortunately, splitting the General.ReverseServiceDiscovery option
into two different options will break backward compatibility on the
configuration file level. So a new configuration option has been
introduced in addition to the old one.

Signed-off-by: Sergey Bobrenok <[email protected]>
---
src/btd.h | 1 +
src/device.c | 4 ++++
src/main.c | 4 ++++
src/main.conf | 7 ++++++-
4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/btd.h b/src/btd.h
index 7166e2168..f85b119b7 100644
--- a/src/btd.h
+++ b/src/btd.h
@@ -140,6 +140,7 @@ struct btd_opts {
bt_gatt_cache_t gatt_cache;
uint16_t gatt_mtu;
uint8_t gatt_channels;
+ gboolean gatt_reverse_client;
enum mps_mode_t mps;

struct btd_avdtp_opts avdtp;
diff --git a/src/device.c b/src/device.c
index 1db96d9a6..e8d66ffe4 100644
--- a/src/device.c
+++ b/src/device.c
@@ -5452,6 +5452,10 @@ static void gatt_client_init(struct btd_device *device)
DBG("Reverse service discovery disabled: skipping GATT client");
return;
}
+ if (!device->connect && !btd_opts.gatt_reverse_client) {
+ DBG("Reverse gatt client disabled: skipping GATT client");
+ return;
+ }

device->client = bt_gatt_client_new(device->db, device->att,
device->att_mtu, 0);
diff --git a/src/main.c b/src/main.c
index b1339c230..f0c2c4311 100644
--- a/src/main.c
+++ b/src/main.c
@@ -145,6 +145,7 @@ static const char *gatt_options[] = {
"KeySize",
"ExchangeMTU",
"Channels",
+ "ReverseClient",
NULL
};

@@ -1058,6 +1059,8 @@ static void parse_gatt(GKeyFile *config)
BT_ATT_DEFAULT_LE_MTU, BT_ATT_MAX_LE_MTU);
parse_config_u8(config, "GATT", "Channels", &btd_opts.gatt_channels,
1, 5);
+ parse_config_bool(config, "GATT", "ReverseClient",
+ &btd_opts.gatt_reverse_client);
}

static void parse_csis_sirk(GKeyFile *config)
@@ -1190,6 +1193,7 @@ static void init_defaults(void)
btd_opts.gatt_cache = BT_GATT_CACHE_ALWAYS;
btd_opts.gatt_mtu = BT_ATT_MAX_LE_MTU;
btd_opts.gatt_channels = 1;
+ btd_opts.gatt_reverse_client = TRUE;

btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
diff --git a/src/main.conf b/src/main.conf
index 085c81a46..a617eec6b 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -33,7 +33,7 @@
# us. For BR/EDR this option is really only needed for qualification since the
# BITE tester doesn't like us doing reverse SDP for some test cases, for LE
# this disables the GATT client functionally so it can be used in system which
-# can only operate as peripheral.
+# can only operate as peripheral (see also GATT ReverseClient).
# Defaults to 'true'.
#ReverseServiceDiscovery = true

@@ -283,6 +283,11 @@
# Defaults to 0
#Rank = 0

+# This disables the GATT client functionally so it can be used in system which
+# can only operate as peripheral.
+# Defaults to 'true'.
+#ReverseClient = true
+
[AVDTP]
# AVDTP L2CAP Signalling Channel Mode.
# Possible values:

base-commit: a16c2ccf9c256285188f4549b7b767cf31b100eb
--
2.43.2



2024-02-23 16:25:44

by bluez.test.bot

[permalink] [raw]
Subject: RE: main.conf: Introduce GATT.ReverseClient option

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=829144

---Test result---

Test Summary:
CheckPatch PASS 0.28 seconds
GitLint PASS 0.20 seconds
BuildEll PASS 24.09 seconds
BluezMake FAIL 86.49 seconds
MakeCheck FAIL 1099.59 seconds
MakeDistcheck PASS 164.21 seconds
CheckValgrind FAIL 64.47 seconds
CheckSmatch FAIL 151.20 seconds
bluezmakeextell FAIL 56.87 seconds
IncrementalBuild FAIL 571.27 seconds
ScanBuild FAIL 660.99 seconds

Details
##############################
Test: BluezMake - FAIL
Desc: Build BlueZ
Output:

tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12723:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12723 | int main(int argc, char *argv[])
| ^~~~
src/main.c: In function ‘parse_gatt’:
src/main.c:1063:5: error: passing argument 4 of ‘parse_config_bool’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1063 | &btd_opts.gatt_reverse_client);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| gboolean * {aka int *}
src/main.c:820:29: note: expected ‘_Bool *’ but argument is of type ‘gboolean *’ {aka ‘int *’}
820 | const char *key, bool *val)
| ^
cc1: all warnings being treated as errors
make[1]: *** [Makefile:10707: src/bluetoothd-main.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4638: all] Error 2
##############################
Test: MakeCheck - FAIL
Desc: Run Bluez Make Check
Output:

unit/test-avdtp.c: In function ‘main’:
unit/test-avdtp.c:766:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
766 | int main(int argc, char *argv[])
| ^~~~
unit/test-avrcp.c: In function ‘main’:
unit/test-avrcp.c:989:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
989 | int main(int argc, char *argv[])
| ^~~~
src/main.c: In function ‘parse_gatt’:
src/main.c:1063:5: error: passing argument 4 of ‘parse_config_bool’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1063 | &btd_opts.gatt_reverse_client);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| gboolean * {aka int *}
src/main.c:820:29: note: expected ‘_Bool *’ but argument is of type ‘gboolean *’ {aka ‘int *’}
820 | const char *key, bool *val)
| ^
cc1: all warnings being treated as errors
make[1]: *** [Makefile:10707: src/bluetoothd-main.o] Error 1
make: *** [Makefile:12155: check] Error 2
##############################
Test: CheckValgrind - FAIL
Desc: Run Bluez Make Check with Valgrind
Output:

tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12723:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12723 | int main(int argc, char *argv[])
| ^~~~
src/main.c: In function ‘parse_gatt’:
src/main.c:1063:5: error: passing argument 4 of ‘parse_config_bool’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1063 | &btd_opts.gatt_reverse_client);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| gboolean * {aka int *}
src/main.c:820:29: note: expected ‘_Bool *’ but argument is of type ‘gboolean *’ {aka ‘int *’}
820 | const char *key, bool *val)
| ^
cc1: all warnings being treated as errors
make[1]: *** [Makefile:10707: src/bluetoothd-main.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:12155: check] Error 2
##############################
Test: CheckSmatch - FAIL
Desc: Run smatch tool with source
Output:

src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:830:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1323:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1354:23: warning: Variable length array is used.
src/shared/gatt-server.c:276:25: warning: Variable length array is used.
src/shared/gatt-server.c:619:25: warning: Variable length array is used.
src/shared/gatt-server.c:718:25: warning: Variable length array is used.
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:830:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1323:31: warning: Variable length array is used.
src/shared/gatt-helpers.c:1354:23: warning: Variable length array is used.
src/shared/gatt-server.c:276:25: warning: Variable length array is used.
src/shared/gatt-server.c:619:25: warning: Variable length array is used.
src/shared/gatt-server.c:718:25: warning: Variable length array is used.
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
tools/mesh-cfgtest.c:1453:17: warning: unknown escape sequence: '\%'
tools/sco-tester.c: note: in included file:
./lib/bluetooth.h:216:15: warning: array of flexible structures
./lib/bluetooth.h:221:31: warning: array of flexible structures
tools/bneptest.c:634:39: warning: unknown escape sequence: '\%'
tools/seq2bseq.c:57:26: warning: Variable length array is used.
tools/obex-client-tool.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
android/avctp.c:505:34: warning: Variable length array is used.
android/avctp.c:556:34: warning: Variable length array is used.
unit/test-avrcp.c:373:26: warning: Variable length array is used.
unit/test-avrcp.c:398:26: warning: Variable length array is used.
unit/test-avrcp.c:414:24: warning: Variable length array is used.
android/avrcp-lib.c:1085:34: warning: Variable length array is used.
android/avrcp-lib.c:1583:34: warning: Variable length array is used.
android/avrcp-lib.c:1612:34: warning: Variable length array is used.
android/avrcp-lib.c:1638:34: warning: Variable length array is used.
src/main.c: In function ‘parse_gatt’:
src/main.c:1063:5: error: passing argument 4 of ‘parse_config_bool’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1063 | &btd_opts.gatt_reverse_client);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| gboolean * {aka int *}
src/main.c:820:29: note: expected ‘_Bool *’ but argument is of type ‘gboolean *’ {aka ‘int *’}
820 | const char *key, bool *val)
| ^
cc1: all warnings being treated as errors
make[1]: *** [Makefile:10707: src/bluetoothd-main.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4638: all] Error 2
##############################
Test: bluezmakeextell - FAIL
Desc: Build Bluez with External ELL
Output:

src/main.c: In function ‘parse_gatt’:
src/main.c:1063:5: error: passing argument 4 of ‘parse_config_bool’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1063 | &btd_opts.gatt_reverse_client);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| gboolean * {aka int *}
src/main.c:820:29: note: expected ‘_Bool *’ but argument is of type ‘gboolean *’ {aka ‘int *’}
820 | const char *key, bool *val)
| ^
cc1: all warnings being treated as errors
make[1]: *** [Makefile:10707: src/bluetoothd-main.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4638: all] Error 2
##############################
Test: IncrementalBuild - FAIL
Desc: Incremental build with the patches in the series
Output:
main.conf: Introduce GATT.ReverseClient option

tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12723:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12723 | int main(int argc, char *argv[])
| ^~~~
unit/test-avdtp.c: In function ‘main’:
unit/test-avdtp.c:766:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
766 | int main(int argc, char *argv[])
| ^~~~
unit/test-avrcp.c: In function ‘main’:
unit/test-avrcp.c:989:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
989 | int main(int argc, char *argv[])
| ^~~~
src/main.c: In function ‘parse_gatt’:
src/main.c:1063:5: error: passing argument 4 of ‘parse_config_bool’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1063 | &btd_opts.gatt_reverse_client);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| gboolean * {aka int *}
src/main.c:820:29: note: expected ‘_Bool *’ but argument is of type ‘gboolean *’ {aka ‘int *’}
820 | const char *key, bool *val)
| ^
cc1: all warnings being treated as errors
make[1]: *** [Makefile:10707: src/bluetoothd-main.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4638: all] Error 2
##############################
Test: ScanBuild - FAIL
Desc: Run Scan Build
Output:

src/shared/gatt-client.c:451:21: warning: Use of memory after it is freed
gatt_db_unregister(op->client->db, op->db_id);
^~~~~~~~~~
src/shared/gatt-client.c:696:2: warning: Use of memory after it is freed
discovery_op_complete(op, false, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:993:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1099:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1291:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1356:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1631:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1636:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2140:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2148:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3237:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3259:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
12 warnings generated.
src/shared/bap.c:1145:2: warning: Use of memory after it is freed
DBG(stream->bap, "stream %p", stream);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:40:2: note: expanded from macro 'DBG'
bap_debug(_bap, "%s:%s() " fmt, __FILE__, __func__, ## arg)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:1698:3: warning: Use of memory after it is freed
stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/shared/shell.c:1228:13: warning: Access to field 'options' results in a dereference of a null pointer (loaded from variable 'opt')
if (c != opt->options[index - offset].val) {
^~~~~~~~~~~~
1 warning generated.
src/shared/gatt-client.c:451:21: warning: Use of memory after it is freed
gatt_db_unregister(op->client->db, op->db_id);
^~~~~~~~~~
src/shared/gatt-client.c:696:2: warning: Use of memory after it is freed
discovery_op_complete(op, false, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:993:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1099:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1291:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1356:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1631:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1636:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2140:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2148:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3237:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3259:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
12 warnings generated.
src/shared/bap.c:1145:2: warning: Use of memory after it is freed
DBG(stream->bap, "stream %p", stream);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:40:2: note: expanded from macro 'DBG'
bap_debug(_bap, "%s:%s() " fmt, __FILE__, __func__, ## arg)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:1698:3: warning: Use of memory after it is freed
stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/shared/shell.c:1228:13: warning: Access to field 'options' results in a dereference of a null pointer (loaded from variable 'opt')
if (c != opt->options[index - offset].val) {
^~~~~~~~~~~~
1 warning generated.
tools/hciattach.c:816:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 10)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:864:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:886:8: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 10)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:908:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:929:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 4)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:973:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
if ((n = read_hci_event(fd, resp, 6)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 warnings generated.
src/oui.c:50:2: warning: Value stored to 'hwdb' is never read
hwdb = udev_hwdb_unref(hwdb);
^ ~~~~~~~~~~~~~~~~~~~~~
src/oui.c:53:2: warning: Value stored to 'udev' is never read
udev = udev_unref(udev);
^ ~~~~~~~~~~~~~~~~
2 warnings generated.
tools/hcidump.c:180:9: warning: Potential leak of memory pointed to by 'dp'
if (fds[i].fd == sock)
^~~
tools/hcidump.c:248:17: warning: Assigned value is garbage or undefined
dh->ts_sec = htobl(frm.ts.tv_sec);
^ ~~~~~~~~~~~~~~~~~~~~
tools/hcidump.c:326:9: warning: 1st function call argument is an uninitialized value
if (be32toh(dp.flags) & 0x02) {
^~~~~~~~~~~~~~~~~
/usr/include/endian.h:46:22: note: expanded from macro 'be32toh'
# define be32toh(x) __bswap_32 (x)
^~~~~~~~~~~~~~
tools/hcidump.c:341:20: warning: 1st function call argument is an uninitialized value
frm.data_len = be32toh(dp.len);
^~~~~~~~~~~~~~~
/usr/include/endian.h:46:22: note: expanded from macro 'be32toh'
# define be32toh(x) __bswap_32 (x)
^~~~~~~~~~~~~~
tools/hcidump.c:346:14: warning: 1st function call argument is an uninitialized value
opcode = be32toh(dp.flags) & 0xffff;
^~~~~~~~~~~~~~~~~
/usr/include/endian.h:46:22: note: expanded from macro 'be32toh'
# define be32toh(x) __bswap_32 (x)
^~~~~~~~~~~~~~
tools/hcidump.c:384:17: warning: Assigned value is garbage or undefined
frm.data_len = btohs(dh.len);
^ ~~~~~~~~~~~~~
tools/hcidump.c:394:11: warning: Assigned value is garbage or undefined
frm.len = frm.data_len;
^ ~~~~~~~~~~~~
tools/hcidump.c:398:9: warning: 1st function call argument is an uninitialized value
ts = be64toh(ph.ts);
^~~~~~~~~~~~~~
/usr/include/endian.h:51:22: note: expanded from macro 'be64toh'
# define be64toh(x) __bswap_64 (x)
^~~~~~~~~~~~~~
tools/hcidump.c:403:13: warning: 1st function call argument is an uninitialized value
frm.in = be32toh(dp.flags) & 0x01;
^~~~~~~~~~~~~~~~~
/usr/include/endian.h:46:22: note: expanded from macro 'be32toh'
# define be32toh(x) __bswap_32 (x)
^~~~~~~~~~~~~~
tools/hcidump.c:408:11: warning: Assigned value is garbage or undefined
frm.in = dh.in;
^ ~~~~~
tools/hcidump.c:437:7: warning: Null pointer passed to 1st parameter expecting 'nonnull'
fd = open(file, open_flags, 0644);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 warnings generated.
tools/rfcomm.c:234:3: warning: Value stored to 'i' is never read
i = execvp(cmdargv[0], cmdargv);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:234:7: warning: Null pointer passed to 1st parameter expecting 'nonnull'
i = execvp(cmdargv[0], cmdargv);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:354:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd'
if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:497:14: warning: Assigned value is garbage or undefined
req.channel = raddr.rc_channel;
^ ~~~~~~~~~~~~~~~~
tools/rfcomm.c:515:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd'
if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
src/sdp-xml.c:126:10: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:300:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
src/sdp-xml.c:338:11: warning: Assigned value is garbage or undefined
buf[1] = data[i + 1];
^ ~~~~~~~~~~~
3 warnings generated.
tools/ciptool.c:350:7: warning: 5th function call argument is an uninitialized value
sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/sdptool.c:941:26: warning: Result of 'malloc' is converted to a pointer of type 'uint32_t', which is incompatible with sizeof operand type 'int'
uint32_t *value_int = malloc(sizeof(int));
~~~~~~~~~~ ^~~~~~ ~~~~~~~~~~~
tools/sdptool.c:980:4: warning: 1st function call argument is an uninitialized value
free(allocArray[i]);
^~~~~~~~~~~~~~~~~~~
tools/sdptool.c:3777:2: warning: Potential leak of memory pointed to by 'si.name'
return add_service(0, &si);
^~~~~~~~~~~~~~~~~~~~~~~~~~
tools/sdptool.c:4112:4: warning: Potential leak of memory pointed to by 'context.svc'
return -1;
^~~~~~~~~
4 warnings generated.
tools/avtest.c:225:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:235:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:244:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:258:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:265:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:272:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:279:5: warning: Value stored to 'len' is never read
len = write(sk, buf,
^ ~~~~~~~~~~~~~~
tools/avtest.c:291:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:295:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:304:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:308:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:317:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:324:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:346:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:350:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:359:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:363:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:376:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 4);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:380:5: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:387:4: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:397:4: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:562:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:570:3: warning: Value stored to 'len' is never read
len = write(sk, buf, invalid ? 2 : 3);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/avtest.c:584:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 4 + sizeof(media_transport));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/avtest.c:597:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:607:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:619:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:634:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:646:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:655:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 3);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:662:3: warning: Value stored to 'len' is never read
len = write(sk, buf, 2);
^ ~~~~~~~~~~~~~~~~~
tools/avtest.c:698:2: warning: Value stored to 'len' is never read
len = write(sk, buf, AVCTP_HEADER_LENGTH + sizeof(play_pressed));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 warnings generated.
tools/btproxy.c:836:15: warning: Null pointer passed to 1st parameter expecting 'nonnull'
tcp_port = atoi(optarg);
^~~~~~~~~~~~
tools/btproxy.c:839:8: warning: Null pointer passed to 1st parameter expecting 'nonnull'
if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
^~~~~~~~~~~~~~
2 warnings generated.
tools/create-image.c:76:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:84:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:92:3: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
tools/create-image.c:105:2: warning: Value stored to 'fd' is never read
fd = -1;
^ ~~
4 warnings generated.
tools/btgatt-client.c:1824:2: warning: Value stored to 'argv' is never read
argv += optind;
^ ~~~~~~
1 warning generated.
tools/btgatt-server.c:1212:2: warning: Value stored to 'argv' is never read
argv -= optind;
^ ~~~~~~
1 warning generated.
tools/check-selftest.c:42:3: warning: Value stored to 'ptr' is never read
ptr = fgets(result, sizeof(result), fp);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/gatt-service.c:294:2: warning: 2nd function call argument is an uninitialized value
chr_write(chr, value, len);
^~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/obex-server-tool.c:133:13: warning: Null pointer passed to 1st parameter expecting 'nonnull'
data->fd = open(name, O_WRONLY | O_CREAT | O_NOCTTY, 0600);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/obex-server-tool.c:192:13: warning: Null pointer passed to 1st parameter expecting 'nonnull'
data->fd = open(name, O_RDONLY | O_NOCTTY, 0);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
tools/test-runner.c:945:2: warning: 2nd function call argument is an uninitialized value
printf("Running command %s\n", cmdname ? cmdname : argv[0]);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/btpclientctl.c:402:3: warning: Value stored to 'bit' is never read
bit = 0;
^ ~
tools/btpclientctl.c:1655:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
memcpy(cp->data, ad_data, ad_len);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/sdpd-request.c:211:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint16_t'
pElem = malloc(sizeof(uint16_t));
^~~~~~ ~~~~~~~~~~~~~~~~
src/sdpd-request.c:239:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint32_t'
pElem = malloc(sizeof(uint32_t));
^~~~~~ ~~~~~~~~~~~~~~~~
2 warnings generated.
android/avrcp-lib.c:1968:3: warning: 1st function call argument is an uninitialized value
g_free(text[i]);
^~~~~~~~~~~~~~~
1 warning generated.
profiles/health/hdp.c:644:3: warning: Use of memory after it is freed
hdp_tmp_dc_data_unref(dc_data);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/health/hdp.c:800:19: warning: Use of memory after it is freed
path = g_strdup(chan->path);
^~~~~~~~~~
profiles/health/hdp.c:1779:6: warning: Use of memory after it is freed
hdp_tmp_dc_data_ref(hdp_conn),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/health/hdp.c:1836:30: warning: Use of memory after it is freed
reply = g_dbus_create_error(data->msg, ERROR_INTERFACE ".HealthError",
^~~~~~~~~
4 warnings generated.
profiles/health/hdp_util.c:1052:2: warning: Use of memory after it is freed
conn_data->func(conn_data->data, gerr);
^~~~~~~~~~~~~~~
1 warning generated.
attrib/gatt.c:970:2: warning: Potential leak of memory pointed to by 'long_write'
return prepare_write(long_write);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/main.c: In function ‘parse_gatt’:
src/main.c:1063:5: error: passing argument 4 of ‘parse_config_bool’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1063 | &btd_opts.gatt_reverse_client);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| gboolean * {aka int *}
src/main.c:820:29: note: expected ‘_Bool *’ but argument is of type ‘gboolean *’ {aka ‘int *’}
820 | const char *key, bool *val)
| ^
cc1: all warnings being treated as errors
make[1]: *** [Makefile:10707: src/bluetoothd-main.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4638: all] Error 2


---
Regards,
Linux Bluetooth

2024-02-27 17:16:30

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH] main.conf: Introduce GATT.ReverseClient option

Hi Sergey,

On Fri, Feb 23, 2024 at 10:30 AM Sergey Bobrenok
<[email protected]> wrote:
>
> General.ReverseServiceDiscovery option is responsible for two
> different things:
> 1. It disables SDP reverse discovering. As a side effect, some BR/EDR
> profiles cannot operate properly. E.g. AVRCP-target profile needs SDP
> results to determine the peer's AVRCP version.
> 2. It disables GATT-client creation back to the GATT connection
> initiator. It may be useful for peripheral devices, especially if the
> peer doesn't expect them to connect back (and currently some IOS
> versions don't). This behavior was introduced in
> 8de73cd12 ("main.conf: Make ReverseServiceDiscovery work with LE")
>
> For peripheral devices implementing only A2DP-sink, AVRCP-target, and
> GATT profiles (e.g. BT loudspeakers), it may be useful to disable
> GATT-client functionality, but still have SDP reverse discovering.
>
> Unfortunately, splitting the General.ReverseServiceDiscovery option
> into two different options will break backward compatibility on the
> configuration file level. So a new configuration option has been
> introduced in addition to the old one.

While I agree we need some option to handle such cases where the
remote end don't expects us to act as GATT Client the option name
shall probably be just to disable the GATT client entirely not just
reverse discovery so it an independent which affects
ReverseServiceDiscovery implicitly otherwise there is a dependency on
one another which may lead to confusions like setting
ReverseServiceDiscovery=false and then ReverseClient=true would have
no effect.

> Signed-off-by: Sergey Bobrenok <[email protected]>
> ---
> src/btd.h | 1 +
> src/device.c | 4 ++++
> src/main.c | 4 ++++
> src/main.conf | 7 ++++++-
> 4 files changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/src/btd.h b/src/btd.h
> index 7166e2168..f85b119b7 100644
> --- a/src/btd.h
> +++ b/src/btd.h
> @@ -140,6 +140,7 @@ struct btd_opts {
> bt_gatt_cache_t gatt_cache;
> uint16_t gatt_mtu;
> uint8_t gatt_channels;
> + gboolean gatt_reverse_client;
> enum mps_mode_t mps;
>
> struct btd_avdtp_opts avdtp;
> diff --git a/src/device.c b/src/device.c
> index 1db96d9a6..e8d66ffe4 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -5452,6 +5452,10 @@ static void gatt_client_init(struct btd_device *device)
> DBG("Reverse service discovery disabled: skipping GATT client");
> return;
> }
> + if (!device->connect && !btd_opts.gatt_reverse_client) {
> + DBG("Reverse gatt client disabled: skipping GATT client");
> + return;
> + }
>
> device->client = bt_gatt_client_new(device->db, device->att,
> device->att_mtu, 0);
> diff --git a/src/main.c b/src/main.c
> index b1339c230..f0c2c4311 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -145,6 +145,7 @@ static const char *gatt_options[] = {
> "KeySize",
> "ExchangeMTU",
> "Channels",
> + "ReverseClient",
> NULL
> };
>
> @@ -1058,6 +1059,8 @@ static void parse_gatt(GKeyFile *config)
> BT_ATT_DEFAULT_LE_MTU, BT_ATT_MAX_LE_MTU);
> parse_config_u8(config, "GATT", "Channels", &btd_opts.gatt_channels,
> 1, 5);
> + parse_config_bool(config, "GATT", "ReverseClient",
> + &btd_opts.gatt_reverse_client);
> }
>
> static void parse_csis_sirk(GKeyFile *config)
> @@ -1190,6 +1193,7 @@ static void init_defaults(void)
> btd_opts.gatt_cache = BT_GATT_CACHE_ALWAYS;
> btd_opts.gatt_mtu = BT_ATT_MAX_LE_MTU;
> btd_opts.gatt_channels = 1;
> + btd_opts.gatt_reverse_client = TRUE;
>
> btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
> btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
> diff --git a/src/main.conf b/src/main.conf
> index 085c81a46..a617eec6b 100644
> --- a/src/main.conf
> +++ b/src/main.conf
> @@ -33,7 +33,7 @@
> # us. For BR/EDR this option is really only needed for qualification since the
> # BITE tester doesn't like us doing reverse SDP for some test cases, for LE
> # this disables the GATT client functionally so it can be used in system which
> -# can only operate as peripheral.
> +# can only operate as peripheral (see also GATT ReverseClient).
> # Defaults to 'true'.
> #ReverseServiceDiscovery = true
>
> @@ -283,6 +283,11 @@
> # Defaults to 0
> #Rank = 0
>
> +# This disables the GATT client functionally so it can be used in system which
> +# can only operate as peripheral.
> +# Defaults to 'true'.
> +#ReverseClient = true

Like explained above I'd suggest we go with just a Client setting here.

> [AVDTP]
> # AVDTP L2CAP Signalling Channel Mode.
> # Possible values:
>
> base-commit: a16c2ccf9c256285188f4549b7b767cf31b100eb
> --
> 2.43.2
>
>


--
Luiz Augusto von Dentz

2024-03-14 10:18:58

by Sergey Bobrenok

[permalink] [raw]
Subject: [PATCH v2] main.conf: Introduce GATT.Client option

General.ReverseServiceDiscovery option is responsible for two
different things:
1. It disables SDP reverse discovering. As a side effect, some BR/EDR
profiles cannot operate properly. E.g. AVRCP-target profile needs SDP
results to determine the peer's AVRCP version.
2. It disables GATT-client creation back to the GATT connection
initiator. It may be useful for peripheral devices, especially if the
peer doesn't expect them to connect back (and currently some IOS
versions don't). This behavior was introduced in
8de73cd12 ("main.conf: Make ReverseServiceDiscovery work with LE")

For peripheral devices implementing only A2DP-sink, AVRCP-target, and
GATT profiles (e.g. BT loudspeakers), it may be useful to disable
GATT-client functionality, but still have SDP reverse discovering.

Unfortunately, splitting the General.ReverseServiceDiscovery option
into two different options will break backward compatibility on the
configuration file level. So a new configuration option has been
introduced in addition to the old one.

Signed-off-by: Sergey Bobrenok <[email protected]>
---
Changes v1 -> v2:
- replace gboolean with bool
- rename ReverseClient option to Client
---
src/btd.h | 1 +
src/device.c | 4 ++++
src/main.c | 3 +++
src/main.conf | 7 ++++++-
4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/btd.h b/src/btd.h
index 7166e2168..8c80059ac 100644
--- a/src/btd.h
+++ b/src/btd.h
@@ -140,6 +140,7 @@ struct btd_opts {
bt_gatt_cache_t gatt_cache;
uint16_t gatt_mtu;
uint8_t gatt_channels;
+ bool gatt_client;
enum mps_mode_t mps;

struct btd_avdtp_opts avdtp;
diff --git a/src/device.c b/src/device.c
index aecceb100..294869aac 100644
--- a/src/device.c
+++ b/src/device.c
@@ -5511,6 +5511,10 @@ static void gatt_client_init(struct btd_device *device)
DBG("Reverse service discovery disabled: skipping GATT client");
return;
}
+ if (!device->connect && !btd_opts.gatt_client) {
+ DBG("GATT client disabled: skipping GATT client");
+ return;
+ }

device->client = bt_gatt_client_new(device->db, device->att,
device->att_mtu, 0);
diff --git a/src/main.c b/src/main.c
index b1339c230..f774670e4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -145,6 +145,7 @@ static const char *gatt_options[] = {
"KeySize",
"ExchangeMTU",
"Channels",
+ "Client",
NULL
};

@@ -1058,6 +1059,7 @@ static void parse_gatt(GKeyFile *config)
BT_ATT_DEFAULT_LE_MTU, BT_ATT_MAX_LE_MTU);
parse_config_u8(config, "GATT", "Channels", &btd_opts.gatt_channels,
1, 5);
+ parse_config_bool(config, "GATT", "Client", &btd_opts.gatt_client);
}

static void parse_csis_sirk(GKeyFile *config)
@@ -1190,6 +1192,7 @@ static void init_defaults(void)
btd_opts.gatt_cache = BT_GATT_CACHE_ALWAYS;
btd_opts.gatt_mtu = BT_ATT_MAX_LE_MTU;
btd_opts.gatt_channels = 1;
+ btd_opts.gatt_client = true;

btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
diff --git a/src/main.conf b/src/main.conf
index 085c81a46..815f1c0f8 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -33,7 +33,7 @@
# us. For BR/EDR this option is really only needed for qualification since the
# BITE tester doesn't like us doing reverse SDP for some test cases, for LE
# this disables the GATT client functionally so it can be used in system which
-# can only operate as peripheral.
+# can only operate as peripheral (see also GATT Client option).
# Defaults to 'true'.
#ReverseServiceDiscovery = true

@@ -283,6 +283,11 @@
# Defaults to 0
#Rank = 0

+# This enables the GATT client functionally, so it can be disabled in system
+# which can only operate as a peripheral.
+# Defaults to 'true'.
+#Client = true
+
[AVDTP]
# AVDTP L2CAP Signalling Channel Mode.
# Possible values:

base-commit: 3ad367874630bb62719ea02184a473cb1efeca34
--
2.34.1


2024-03-20 09:30:42

by patchwork-bot+bluetooth

[permalink] [raw]
Subject: Re: [PATCH v2] main.conf: Introduce GATT.Client option

Hello:

This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <[email protected]>:

On Thu, 14 Mar 2024 13:17:08 +0300 you wrote:
> General.ReverseServiceDiscovery option is responsible for two
> different things:
> 1. It disables SDP reverse discovering. As a side effect, some BR/EDR
> profiles cannot operate properly. E.g. AVRCP-target profile needs SDP
> results to determine the peer's AVRCP version.
> 2. It disables GATT-client creation back to the GATT connection
> initiator. It may be useful for peripheral devices, especially if the
> peer doesn't expect them to connect back (and currently some IOS
> versions don't). This behavior was introduced in
> 8de73cd12 ("main.conf: Make ReverseServiceDiscovery work with LE")
>
> [...]

Here is the summary with links:
- [v2] main.conf: Introduce GATT.Client option
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=6c039398fee2

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html