* [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client
@ 2024-09-17 7:42 Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 1/5] obexd: Add BIP client for AVRCP cover art download Frédéric Danis
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Frédéric Danis @ 2024-09-17 7:42 UTC (permalink / raw)
To: linux-bluetooth
If AVRCP Target supports Cover Art download its SDP record contains an
additional access protocol for OBEX with an LCAP PSM on which the OBEX
client session should connect to, with the specific OBEX target header
7163DD54-4A7E-11E2-B47C-0050C2490048.
Once the OBEX session is connected, the AVRCP track metadata will contain
an Image Handle which can be used to get the associated image using
GetImageThumbnail or GetImage with one of the description property found
with GetImageProperties.
This has been tested with iPhone 14, iPhone 15 Pro and Samsung S23.
v1 -> v2: Parse integer properties as integer instead of string
Return GetImageProperties values as aa{sv} instead of aa{ss}
Get properties for GetImage as a{sv} instead of a{ss}
Set new properties and interface as experimental
v2 -> v3: Rename obexd/client/bip-avrcp.[ch] to obexd/client/bip.[ch]
Update the AVRCP Controller version in SDP to 1.6
Add commit to support for specific headers in obex transfer
Fix memory leaks
v3 -> v4: Commits 1-4 has been merged
Change org.bluez.obex.BipAvrcp1 to org.bluez.obex.Image1
Change GetImageThumbnail to GetThumbnail
Change GetImageProperties to Properties
Change GetImage to Get
Add possible property values for the description dicts
Frédéric Danis (5):
obexd: Add BIP client for AVRCP cover art download
obexd: Add Properties to org.bluez.obex.Image
obexd: Add Get to org.bluez.obex.Image
avrcp: Update controller SDP record with cover art support
doc: Add description of org.bluez.obex.Image
Makefile.am | 9 +-
Makefile.obexd | 2 +
doc/org.bluez.obex.Client.rst | 1 +
doc/org.bluez.obex.Image.rst | 118 +++++
obexd/client/bip-common.c | 800 ++++++++++++++++++++++++++++++++++
obexd/client/bip-common.h | 24 +
obexd/client/bip.c | 440 +++++++++++++++++++
obexd/client/bip.h | 12 +
obexd/client/manager.c | 2 +
profiles/audio/avrcp.c | 12 +-
10 files changed, 1412 insertions(+), 8 deletions(-)
create mode 100644 doc/org.bluez.obex.Image.rst
create mode 100644 obexd/client/bip-common.c
create mode 100644 obexd/client/bip-common.h
create mode 100644 obexd/client/bip.c
create mode 100644 obexd/client/bip.h
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH BlueZ v4 1/5] obexd: Add BIP client for AVRCP cover art download
2024-09-17 7:42 [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client Frédéric Danis
@ 2024-09-17 7:42 ` Frédéric Danis
2024-09-17 11:31 ` Add BIP for AVRCP covert art OBEX client bluez.test.bot
2024-09-17 7:42 ` [PATCH BlueZ v4 2/5] obexd: Add Properties to org.bluez.obex.Image Frédéric Danis
` (4 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Frédéric Danis @ 2024-09-17 7:42 UTC (permalink / raw)
To: linux-bluetooth
The cover art image handle is available in the metadata of the track
when the OBEX BIP session is connected to the PSM port provided
in AVRCP SDP record and available as org.bluez.MediaPlayer property.
This service allows to get the thumbnail.
---
Makefile.obexd | 1 +
doc/org.bluez.obex.Client.rst | 1 +
obexd/client/bip.c | 171 ++++++++++++++++++++++++++++++++++
obexd/client/bip.h | 12 +++
obexd/client/manager.c | 2 +
5 files changed, 187 insertions(+)
create mode 100644 obexd/client/bip.c
create mode 100644 obexd/client/bip.h
diff --git a/Makefile.obexd b/Makefile.obexd
index 4cdce73af..866147dd1 100644
--- a/Makefile.obexd
+++ b/Makefile.obexd
@@ -81,6 +81,7 @@ obexd_src_obexd_SOURCES = $(btio_sources) $(gobex_sources) \
obexd/client/ftp.h obexd/client/ftp.c \
obexd/client/opp.h obexd/client/opp.c \
obexd/client/map.h obexd/client/map.c \
+ obexd/client/bip.h obexd/client/bip.c \
obexd/client/map-event.h obexd/client/map-event.c \
obexd/client/transfer.h obexd/client/transfer.c \
obexd/client/transport.h obexd/client/transport.c \
diff --git a/doc/org.bluez.obex.Client.rst b/doc/org.bluez.obex.Client.rst
index 5ae7cc5e8..f20dd5baa 100644
--- a/doc/org.bluez.obex.Client.rst
+++ b/doc/org.bluez.obex.Client.rst
@@ -43,6 +43,7 @@ object CreateSession(string destination, dict args)
:"opp":
:"pbap":
:"sync":
+ :"bip-avrcp":
:string Source:
diff --git a/obexd/client/bip.c b/obexd/client/bip.c
new file mode 100644
index 000000000..252bc4cec
--- /dev/null
+++ b/obexd/client/bip.c
@@ -0,0 +1,171 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2024 Collabora Ltd.
+ *
+ *
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gdbus/gdbus.h"
+#include "gobex/gobex.h"
+
+#include "obexd/src/log.h"
+#include "transfer.h"
+#include "session.h"
+#include "driver.h"
+#include "bip.h"
+
+#define OBEX_BIP_AVRCP_UUID \
+ "\x71\x63\xDD\x54\x4A\x7E\x11\xE2\xB4\x7C\x00\x50\xC2\x49\x00\x48"
+#define OBEX_BIP_AVRCP_UUID_LEN 16
+
+#define IMAGE_INTERFACE "org.bluez.obex.Image1"
+#define ERROR_INTERFACE "org.bluez.obex.Error"
+#define IMAGE_UUID "0000111A-0000-1000-8000-00805f9b34fb"
+
+#define IMG_HANDLE_TAG 0x30
+
+static DBusConnection *conn;
+
+struct bip_avrcp_data {
+ struct obc_session *session;
+};
+
+static DBusMessage *get_thumbnail(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct bip_avrcp_data *bip_avrcp = user_data;
+ const char *handle = NULL, *image_path = NULL;
+ struct obc_transfer *transfer;
+ GObexHeader *header;
+ DBusMessage *reply = NULL;
+ GError *err = NULL;
+
+ DBG("");
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &image_path,
+ DBUS_TYPE_STRING, &handle,
+ DBUS_TYPE_INVALID) == FALSE) {
+ reply = g_dbus_create_error(message,
+ ERROR_INTERFACE ".InvalidArguments", NULL);
+ return reply;
+ }
+
+ transfer = obc_transfer_get("x-bt/img-thm", NULL, image_path, &err);
+ if (transfer == NULL)
+ goto fail;
+
+ header = g_obex_header_new_unicode(IMG_HANDLE_TAG, handle);
+ obc_transfer_add_header(transfer, header);
+
+ if (!obc_session_queue(bip_avrcp->session, transfer, NULL, NULL, &err))
+ goto fail;
+
+ return obc_transfer_create_dbus_reply(transfer, message);
+
+fail:
+ reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
+ err->message);
+ g_error_free(err);
+ return reply;
+}
+
+static const GDBusMethodTable bip_avrcp_methods[] = {
+ { GDBUS_ASYNC_METHOD("GetThumbnail",
+ GDBUS_ARGS({ "file", "s" }, { "handle", "s"}),
+ GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
+ get_thumbnail) },
+ { }
+};
+
+static void bip_avrcp_free(void *data)
+{
+ struct bip_avrcp_data *bip_avrcp = data;
+
+ obc_session_unref(bip_avrcp->session);
+ g_free(bip_avrcp);
+}
+
+static int bip_avrcp_probe(struct obc_session *session)
+{
+ struct bip_avrcp_data *bip_avrcp;
+ const char *path;
+
+ path = obc_session_get_path(session);
+
+ DBG("%s", path);
+
+ bip_avrcp = g_try_new0(struct bip_avrcp_data, 1);
+ if (!bip_avrcp)
+ return -ENOMEM;
+
+ bip_avrcp->session = obc_session_ref(session);
+
+ if (!g_dbus_register_interface(conn, path, IMAGE_INTERFACE,
+ bip_avrcp_methods,
+ NULL, NULL,
+ bip_avrcp, bip_avrcp_free)) {
+ bip_avrcp_free(bip_avrcp);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void bip_avrcp_remove(struct obc_session *session)
+{
+ const char *path = obc_session_get_path(session);
+
+ DBG("%s", path);
+
+ g_dbus_unregister_interface(conn, path, IMAGE_INTERFACE);
+}
+
+static struct obc_driver bip_avrcp = {
+ .service = "BIP-AVRCP",
+ .uuid = IMAGE_UUID,
+ .target = OBEX_BIP_AVRCP_UUID,
+ .target_len = OBEX_BIP_AVRCP_UUID_LEN,
+ .probe = bip_avrcp_probe,
+ .remove = bip_avrcp_remove
+};
+
+int bip_init(void)
+{
+ int err;
+
+ DBG("");
+
+ conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+ if (!conn)
+ return -EIO;
+
+ err = obc_driver_register(&bip_avrcp);
+ if (err < 0)
+ goto failed;
+
+ return 0;
+
+failed:
+ dbus_connection_unref(conn);
+ conn = NULL;
+ return err;
+}
+
+void bip_exit(void)
+{
+ DBG("");
+
+ dbus_connection_unref(conn);
+ conn = NULL;
+
+ obc_driver_unregister(&bip_avrcp);
+}
diff --git a/obexd/client/bip.h b/obexd/client/bip.h
new file mode 100644
index 000000000..18e3360f3
--- /dev/null
+++ b/obexd/client/bip.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2024 Collabora Ltd.
+ *
+ *
+ */
+
+int bip_init(void);
+void bip_exit(void);
diff --git a/obexd/client/manager.c b/obexd/client/manager.c
index 52c00fb0c..52f4d0179 100644
--- a/obexd/client/manager.c
+++ b/obexd/client/manager.c
@@ -32,6 +32,7 @@
#include "pbap.h"
#include "sync.h"
#include "map.h"
+#include "bip.h"
#include "manager.h"
#define CLIENT_INTERFACE "org.bluez.obex.Client1"
@@ -258,6 +259,7 @@ static const struct obc_module {
{ "pbap", pbap_init, pbap_exit },
{ "sync", sync_init, sync_exit },
{ "map", map_init, map_exit },
+ { "bip", bip_init, bip_exit },
{ }
};
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* RE: Add BIP for AVRCP covert art OBEX client
2024-09-17 7:42 ` [PATCH BlueZ v4 1/5] obexd: Add BIP client for AVRCP cover art download Frédéric Danis
@ 2024-09-17 11:31 ` bluez.test.bot
0 siblings, 0 replies; 11+ messages in thread
From: bluez.test.bot @ 2024-09-17 11:31 UTC (permalink / raw)
To: linux-bluetooth, frederic.danis
[-- Attachment #1: Type: text/plain, Size: 2818 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=890843
---Test result---
Test Summary:
CheckPatch FAIL 3.73 seconds
GitLint FAIL 1.90 seconds
BuildEll PASS 25.04 seconds
BluezMake PASS 1673.62 seconds
MakeCheck PASS 13.15 seconds
MakeDistcheck PASS 191.11 seconds
CheckValgrind PASS 266.53 seconds
CheckSmatch PASS 360.24 seconds
bluezmakeextell PASS 121.89 seconds
IncrementalBuild PASS 7709.01 seconds
ScanBuild WARNING 1033.83 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,v4,2/5] obexd: Add Properties to org.bluez.obex.Image
WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#78:
[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c
/github/workspace/src/src/13805953.patch total: 0 errors, 1 warnings, 926 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/src/13805953.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v4,2/5] obexd: Add Properties to org.bluez.obex.Image
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
10: B1 Line exceeds max length (95>80): "[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c"
##############################
Test: ScanBuild - WARNING
Desc: Run Scan Build
Output:
profiles/audio/avrcp.c:1942:2: warning: Value stored to 'operands' is never read
operands += sizeof(*pdu);
^ ~~~~~~~~~~~~
1 warning generated.
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH BlueZ v4 2/5] obexd: Add Properties to org.bluez.obex.Image
2024-09-17 7:42 [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 1/5] obexd: Add BIP client for AVRCP cover art download Frédéric Danis
@ 2024-09-17 7:42 ` Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 3/5] obexd: Add Get " Frédéric Danis
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Frédéric Danis @ 2024-09-17 7:42 UTC (permalink / raw)
To: linux-bluetooth
This allows to get the different version of the image provided by
the remote device to chose the one to use with Get.
This bip-common.[ch] files are based on previous work done by
Jakub Adamek for GSoC 2011, see [1] and [2].
[1] https://www.bluez.org/gsoc-basic-image-profilebip/
[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c
---
Makefile.obexd | 1 +
obexd/client/bip-common.c | 781 ++++++++++++++++++++++++++++++++++++++
obexd/client/bip-common.h | 19 +
obexd/client/bip.c | 101 +++++
4 files changed, 902 insertions(+)
create mode 100644 obexd/client/bip-common.c
create mode 100644 obexd/client/bip-common.h
diff --git a/Makefile.obexd b/Makefile.obexd
index 866147dd1..74dd977a0 100644
--- a/Makefile.obexd
+++ b/Makefile.obexd
@@ -82,6 +82,7 @@ obexd_src_obexd_SOURCES = $(btio_sources) $(gobex_sources) \
obexd/client/opp.h obexd/client/opp.c \
obexd/client/map.h obexd/client/map.c \
obexd/client/bip.h obexd/client/bip.c \
+ obexd/client/bip-common.h obexd/client/bip-common.c \
obexd/client/map-event.h obexd/client/map-event.c \
obexd/client/transfer.h obexd/client/transfer.c \
obexd/client/transport.h obexd/client/transport.c \
diff --git a/obexd/client/bip-common.c b/obexd/client/bip-common.c
new file mode 100644
index 000000000..9e96c81d8
--- /dev/null
+++ b/obexd/client/bip-common.c
@@ -0,0 +1,781 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2024 Collabora Ltd.
+ * Based on previous work done by Jakub Adamek for GSoC 2011
+ *
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <regex.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gobex/gobex.h"
+
+#include "obexd/src/log.h"
+#include "bip-common.h"
+
+#define HANDLE_LEN 7
+#define HANDLE_LIMIT 10000000
+
+struct encconv_pair {
+ gchar *bip, *im;
+};
+
+struct encconv_pair encconv_table[] = {
+ { "JPEG", "JPEG" },
+ { "GIF", "GIF" },
+ { "WBMP", "WBMP" },
+ { "PNG", "PNG" },
+ { "JPEG2000", "JP2" },
+ { "BMP", "BMP" },
+ { }
+};
+
+static const gchar *convBIP2IM(const gchar *encoding)
+{
+ struct encconv_pair *et = encconv_table;
+
+ while (et->bip) {
+ if (g_strcmp0(encoding, et->bip) == 0)
+ return et->im;
+ et++;
+ }
+ return NULL;
+}
+
+static gboolean parse_pixel_range(const gchar *dim, unsigned int *lower_ret,
+ unsigned int *upper_ret,
+ gboolean *fixed_ratio_ret)
+{
+ static regex_t no_range;
+ static regex_t range;
+ static regex_t range_fixed;
+ static int regex_initialized;
+ unsigned int lower[2], upper[2];
+ gboolean fixed_ratio = FALSE;
+
+ if (!regex_initialized) {
+ regcomp(&no_range, "^([[:digit:]]{1,5})\\*([[:digit:]]{1,5})$",
+ REG_EXTENDED);
+ regcomp(&range, "^([[:digit:]]{1,5})\\*([[:digit:]]{1,5})"
+ "-([[:digit:]]{1,5})\\*([[:digit:]]{1,5})$",
+ REG_EXTENDED);
+ regcomp(&range_fixed, "^([[:digit:]]{1,5})\\*\\*"
+ "-([[:digit:]]{1,5})\\*([[:digit:]]{1,5})$",
+ REG_EXTENDED);
+ regex_initialized = 1;
+ }
+ if (dim == NULL)
+ return FALSE;
+ if (regexec(&no_range, dim, 0, NULL, 0) == 0) {
+ if (sscanf(dim, "%u*%u", &lower[0], &lower[1]) != 2)
+ return FALSE;
+ upper[0] = lower[0];
+ upper[1] = lower[1];
+ fixed_ratio = FALSE;
+ } else if (regexec(&range, dim, 0, NULL, 0) == 0) {
+ if (sscanf(dim, "%u*%u-%u*%u", &lower[0], &lower[1],
+ &upper[0], &upper[1]) != 4)
+ return FALSE;
+ fixed_ratio = FALSE;
+ } else if (regexec(&range_fixed, dim, 0, NULL, 0) == 0) {
+ if (sscanf(dim, "%u**-%u*%u", &lower[0], &upper[0],
+ &upper[1]) != 3)
+ return FALSE;
+ lower[1] = 0;
+ fixed_ratio = TRUE;
+ } else {
+ return FALSE;
+ }
+ if (lower[0] > 65535 || lower[1] > 65535 ||
+ upper[0] > 65535 || upper[1] > 65535)
+ return FALSE;
+ if (lower_ret == NULL || upper_ret == NULL || fixed_ratio_ret == NULL)
+ return TRUE;
+ if (upper[0] < lower[0] || upper[1] < lower[1])
+ return FALSE;
+ lower_ret[0] = lower[0];
+ lower_ret[1] = lower[1];
+ upper_ret[0] = upper[0];
+ upper_ret[1] = upper[1];
+ *fixed_ratio_ret = fixed_ratio;
+
+ return TRUE;
+}
+
+static gboolean verify_unsignednumber(const char *size)
+{
+ static regex_t unumber;
+ static int regex_initialized;
+
+ if (!regex_initialized) {
+ regcomp(&unumber, "^[[:digit:]]+$", REG_EXTENDED);
+ regex_initialized = 1;
+ }
+ if (regexec(&unumber, size, 0, NULL, 0) != 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static uint64_t parse_unsignednumber(const char *size)
+{
+ if (!verify_unsignednumber(size))
+ return 0;
+
+ return g_ascii_strtoll(size, NULL, 10);
+}
+
+char *transforms[] = {
+ "crop",
+ "stretch",
+ "fill",
+ NULL
+};
+
+static gboolean verify_transform(const char *transform)
+{
+ char **str = transforms;
+
+ while (*str != NULL) {
+ if (g_str_equal(transform, *str))
+ return TRUE;
+ str++;
+ }
+ return FALSE;
+}
+
+static char *parse_transform_list(const char *transform)
+{
+ char **args = NULL, **arg = NULL;
+ gboolean used[3] = { FALSE, FALSE, FALSE };
+
+ if (transform == NULL)
+ return NULL;
+ if (strlen(transform) == 0)
+ return NULL;
+ args = g_strsplit(transform, " ", 0);
+ for (arg = args; *arg != NULL; arg++) {
+ char *t = *arg;
+
+ if (!verify_transform(t)) {
+ g_strfreev(args);
+ return NULL;
+ }
+ switch (t[0]) {
+ case 's':
+ if (used[0])
+ goto failure;
+ used[0] = TRUE;
+ break;
+ case 'c':
+ if (used[1])
+ goto failure;
+ used[1] = TRUE;
+ break;
+ case 'f':
+ if (used[2])
+ goto failure;
+ used[2] = TRUE;
+ break;
+ }
+ }
+ g_strfreev(args);
+ return g_strdup(transform);
+failure:
+ g_strfreev(args);
+ return NULL;
+}
+
+static time_t parse_iso8601_bip(const gchar *str, int len)
+{
+ gchar *tstr;
+ struct tm tm;
+ gint nr;
+ gchar tz;
+ time_t time;
+ time_t tz_offset = 0;
+
+ if (str == NULL)
+ return -1;
+
+ memset(&tm, 0, sizeof(struct tm));
+
+ /* According to spec the time doesn't have to be null terminated */
+ if (str[len - 1] != '\0') {
+ tstr = g_malloc(len + 1);
+ strncpy(tstr, str, len);
+ tstr[len] = '\0';
+ } else
+ tstr = g_strdup(str);
+
+ nr = sscanf(tstr, "%04u%02u%02uT%02u%02u%02u%c",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
+ &tz);
+
+ g_free(tstr);
+
+ /* Fixup the tm values */
+ tm.tm_year -= 1900; /* Year since 1900 */
+ tm.tm_mon--; /* Months since January, values 0-11 */
+ tm.tm_isdst = -1; /* Daylight savings information not avail */
+
+ if (nr < 6) {
+ /* Invalid time format */
+ return -1;
+ }
+
+ time = mktime(&tm);
+
+#if defined(HAVE_TM_GMTOFF)
+ tz_offset = tm.tm_gmtoff;
+#elif defined(HAVE_TIMEZONE)
+ tz_offset = -timezone;
+ if (tm.tm_isdst > 0)
+ tz_offset += 3600;
+#endif
+
+ if (nr == 7) { /* Date/Time was in localtime (to remote device)
+ * already. Since we don't know anything about the
+ * timezone on that one we won't try to apply UTC offset
+ */
+ time += tz_offset;
+ }
+
+ return time;
+}
+
+static int parse_handle(const char *data)
+{
+ int handle;
+ char *ptr;
+
+ if (data == NULL)
+ return -1;
+ if (strlen(data) != HANDLE_LEN)
+ return -1;
+ handle = strtol(data, &ptr, 10);
+ if (ptr != data + HANDLE_LEN)
+ return -1;
+ if (handle < 0 || handle >= HANDLE_LIMIT)
+ return -1;
+ return handle;
+}
+
+struct native_prop {
+ char *encoding, *pixel;
+ uint64_t size;
+};
+
+struct variant_prop {
+ char *encoding, *pixel, *transform;
+ uint64_t maxsize;
+};
+
+struct att_prop {
+ char *content_type, *charset, *name;
+ uint64_t size;
+ time_t ctime, mtime;
+};
+
+struct prop_object {
+ char *handle, *name;
+ GSList *native, *variant, *att;
+};
+
+static void free_native_prop(struct native_prop *prop)
+{
+ DBG("");
+
+ if (prop == NULL)
+ return;
+ g_free(prop->encoding);
+ g_free(prop->pixel);
+ g_free(prop);
+}
+
+static void free_variant_prop(struct variant_prop *prop)
+{
+ DBG("");
+
+ if (prop == NULL)
+ return;
+ g_free(prop->encoding);
+ g_free(prop->pixel);
+ g_free(prop->transform);
+ g_free(prop);
+}
+
+static void free_att_prop(struct att_prop *prop)
+{
+ DBG("");
+
+ if (prop == NULL)
+ return;
+ g_free(prop->content_type);
+ g_free(prop->charset);
+ g_free(prop->name);
+ g_free(prop);
+}
+
+static void free_prop_object(struct prop_object *object)
+{
+ GSList *list;
+
+ DBG("");
+
+ if (object == NULL)
+ return;
+ for (list = object->native; list != NULL; list = g_slist_next(list))
+ free_native_prop(list->data);
+ for (list = object->variant; list != NULL; list = g_slist_next(list))
+ free_variant_prop(list->data);
+ for (list = object->att; list != NULL; list = g_slist_next(list))
+ free_att_prop(list->data);
+ g_slist_free(object->native);
+ g_slist_free(object->variant);
+ g_slist_free(object->att);
+ g_free(object->handle);
+ g_free(object->name);
+ g_free(object);
+}
+
+static gboolean parse_attrib_native(struct native_prop *prop, const gchar *key,
+ const gchar *value, GError **gerr)
+{
+ DBG("");
+
+ if (g_str_equal(key, "encoding")) {
+ if (convBIP2IM(value) == NULL)
+ goto invalid;
+ prop->encoding = g_strdup(value);
+ } else if (g_str_equal(key, "pixel")) {
+ if (!parse_pixel_range(value, NULL, NULL, NULL))
+ goto invalid;
+ prop->pixel = g_strdup(value);
+ } else if (g_str_equal(key, "size")) {
+ prop->size = parse_unsignednumber(value);
+ if (prop->size == 0)
+ goto invalid;
+ } else {
+ g_set_error(gerr, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, NULL);
+ return FALSE;
+ }
+ return TRUE;
+invalid:
+ g_set_error(gerr, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+ NULL);
+ return FALSE;
+}
+
+static gboolean parse_attrib_variant(struct variant_prop *prop,
+ const gchar *key,
+ const gchar *value, GError **gerr)
+{
+ DBG("");
+
+ if (g_str_equal(key, "encoding")) {
+ if (convBIP2IM(value) == NULL)
+ goto invalid;
+ prop->encoding = g_strdup(value);
+ } else if (g_str_equal(key, "pixel")) {
+ if (!parse_pixel_range(value, NULL, NULL, NULL))
+ goto invalid;
+ prop->pixel = g_strdup(value);
+ } else if (g_str_equal(key, "maxsize")) {
+ prop->maxsize = parse_unsignednumber(value);
+ if (prop->maxsize == 0)
+ goto invalid;
+ } else if (g_str_equal(key, "transform")) {
+ prop->transform = parse_transform_list(value);
+ if (prop->transform == NULL)
+ goto invalid;
+ } else {
+ g_set_error(gerr, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, NULL);
+ return FALSE;
+ }
+ return TRUE;
+invalid:
+ g_set_error(gerr, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+ NULL);
+ return FALSE;
+}
+
+static gboolean parse_attrib_att(struct att_prop *prop, const gchar *key,
+ const gchar *value, GError **gerr)
+{
+ DBG("");
+
+ if (g_str_equal(key, "content-type")) {
+ prop->content_type = g_strdup(value);
+ } else if (g_str_equal(key, "charset")) {
+ prop->charset = g_strdup(value);
+ } else if (g_str_equal(key, "name")) {
+ prop->name = g_strdup(value);
+ } else if (g_str_equal(key, "size")) {
+ prop->size = parse_unsignednumber(value);
+ if (prop->size == 0)
+ goto invalid;
+ } else if (g_str_equal(key, "created")) {
+ prop->ctime = parse_iso8601_bip(value, strlen(value));
+ if (prop->ctime == -1)
+ goto invalid;
+ } else if (g_str_equal(key, "modified")) {
+ prop->mtime = parse_iso8601_bip(value, strlen(value));
+ if (prop->mtime == -1)
+ goto invalid;
+ } else {
+ g_set_error(gerr, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, NULL);
+ return FALSE;
+ }
+ return TRUE;
+invalid:
+ g_set_error(gerr, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+ NULL);
+ return FALSE;
+}
+
+static struct att_prop *parse_elem_att(const gchar **names,
+ const gchar **values, GError **gerr)
+{
+ gchar **key;
+ struct att_prop *prop = g_new0(struct att_prop, 1);
+
+ DBG("");
+
+ for (key = (gchar **) names; *key; key++, values++) {
+ if (!parse_attrib_att(prop, *key, *values, gerr)) {
+ free_att_prop(prop);
+ return NULL;
+ }
+ }
+ return prop;
+}
+
+static struct variant_prop *parse_elem_variant(const gchar **names,
+ const gchar **values, GError **gerr)
+{
+ gchar **key;
+ struct variant_prop *prop = g_new0(struct variant_prop, 1);
+
+ DBG("");
+
+ for (key = (gchar **) names; *key; key++, values++) {
+ if (!parse_attrib_variant(prop, *key, *values, gerr)) {
+ free_variant_prop(prop);
+ return NULL;
+ }
+ }
+ if (prop->transform == NULL)
+ prop->transform = g_strdup("stretch crop fill");
+ return prop;
+}
+
+static struct native_prop *parse_elem_native(const gchar **names,
+ const gchar **values, GError **gerr)
+{
+ gchar **key;
+ struct native_prop *prop = g_new0(struct native_prop, 1);
+
+ DBG("");
+
+ for (key = (gchar **) names; *key; key++, values++) {
+ if (!parse_attrib_native(prop, *key, *values, gerr)) {
+ free_native_prop(prop);
+ return NULL;
+ }
+ }
+ return prop;
+}
+
+static gboolean parse_attrib_prop(struct prop_object *prop, const gchar *key,
+ const gchar *value, GError **gerr)
+{
+ DBG("");
+
+ if (g_str_equal(key, "handle")) {
+ if (parse_handle(value) < 0)
+ goto invalid;
+ prop->handle = g_strdup(value);
+ } else if (g_str_equal(key, "friendly-name")) {
+ prop->name = g_strdup(value);
+ } else if (g_str_equal(key, "version")) {
+ // pass;
+ } else {
+ g_set_error(gerr, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, NULL);
+ return FALSE;
+ }
+ return TRUE;
+invalid:
+ g_set_error(gerr, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+ NULL);
+ return FALSE;
+}
+
+static struct prop_object *parse_elem_prop(const gchar **names,
+ const gchar **values, GError **gerr)
+{
+ gchar **key;
+ struct prop_object *prop = g_new0(struct prop_object, 1);
+
+ DBG("");
+
+ for (key = (gchar **) names; *key; key++, values++) {
+ if (!parse_attrib_prop(prop, *key, *values, gerr)) {
+ free_prop_object(prop);
+ return NULL;
+ }
+ }
+ return prop;
+}
+
+static void prop_element(GMarkupParseContext *ctxt,
+ const gchar *element,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **gerr)
+{
+ struct prop_object **obj = user_data;
+
+ DBG("");
+
+ if (g_str_equal(element, "image-properties")) {
+ if (*obj != NULL) {
+ free_prop_object(*obj);
+ *obj = NULL;
+ goto invalid;
+ }
+ *obj = parse_elem_prop(names, values, gerr);
+ } else if (g_str_equal(element, "native")) {
+ struct native_prop *prop;
+
+ if (*obj == NULL)
+ goto invalid;
+ prop = parse_elem_native(names, values, gerr);
+ (*obj)->native = g_slist_append((*obj)->native, prop);
+ } else if (g_str_equal(element, "variant")) {
+ struct variant_prop *prop;
+
+ if (*obj == NULL)
+ goto invalid;
+ prop = parse_elem_variant(names, values, gerr);
+ (*obj)->variant = g_slist_append((*obj)->variant, prop);
+ } else if (g_str_equal(element, "attachment")) {
+ struct att_prop *prop;
+
+ if (*obj == NULL)
+ goto invalid;
+ prop = parse_elem_att(names, values, gerr);
+ (*obj)->att = g_slist_append((*obj)->att, prop);
+ } else {
+ if (*obj != NULL) {
+ free_prop_object(*obj);
+ *obj = NULL;
+ }
+ goto invalid;
+ }
+
+ return;
+invalid:
+ g_set_error(gerr, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+ NULL);
+}
+
+static const GMarkupParser properties_parser = {
+ prop_element,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+struct prop_object *parse_properties(char *data, unsigned int length,
+ int *err)
+{
+ struct prop_object *prop = NULL;
+ gboolean status;
+ GError *gerr = NULL;
+ GMarkupParseContext *ctxt = g_markup_parse_context_new(
+ &properties_parser, 0, &prop, NULL);
+
+ DBG("");
+
+ if (err != NULL)
+ *err = 0;
+ status = g_markup_parse_context_parse(ctxt, data, length, &gerr);
+ g_markup_parse_context_free(ctxt);
+ if (!status) {
+ if (err != NULL)
+ *err = -EINVAL;
+ free_prop_object(prop);
+ prop = NULL;
+ }
+ return prop;
+}
+
+gboolean verify_properties(struct prop_object *obj)
+{
+ GSList *list;
+
+ if (obj->handle == NULL)
+ return FALSE;
+
+ for (list = obj->native; list != NULL; list = g_slist_next(list)) {
+ struct native_prop *prop = list->data;
+
+ if (prop->encoding == NULL || prop->pixel == NULL)
+ return FALSE;
+ }
+
+ for (list = obj->variant; list != NULL; list = g_slist_next(list)) {
+ struct variant_prop *prop = list->data;
+
+ if (prop->encoding == NULL || prop->pixel == NULL)
+ return FALSE;
+ }
+
+ for (list = obj->att; list != NULL; list = g_slist_next(list)) {
+ struct att_prop *prop = list->data;
+
+ if (prop->content_type == NULL || prop->name == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void append_properties(DBusMessageIter *args, struct prop_object *obj)
+{
+ DBusMessageIter dict, iter;
+ GSList *list;
+
+ dbus_message_iter_open_container(args, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &dict);
+
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &iter);
+ g_dbus_dict_append_entry(&iter, "handle", DBUS_TYPE_STRING,
+ &obj->handle);
+ g_dbus_dict_append_entry(&iter, "name", DBUS_TYPE_STRING, &obj->name);
+ dbus_message_iter_close_container(&dict, &iter);
+
+ for (list = obj->native; list != NULL; list = g_slist_next(list)) {
+ struct native_prop *prop = list->data;
+ static char *native_str = "native";
+
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &iter);
+ g_dbus_dict_append_entry(&iter, "type", DBUS_TYPE_STRING,
+ &native_str);
+ if (prop->encoding)
+ g_dbus_dict_append_entry(&iter, "encoding",
+ DBUS_TYPE_STRING,
+ &prop->encoding);
+ if (prop->pixel)
+ g_dbus_dict_append_entry(&iter, "pixel",
+ DBUS_TYPE_STRING,
+ &prop->pixel);
+ if (prop->size)
+ g_dbus_dict_append_entry(&iter, "size",
+ DBUS_TYPE_UINT64,
+ &prop->size);
+ dbus_message_iter_close_container(&dict, &iter);
+ }
+
+ for (list = obj->variant; list != NULL; list = g_slist_next(list)) {
+ struct variant_prop *prop = list->data;
+ static char *variant_str = "variant";
+
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &iter);
+ g_dbus_dict_append_entry(&iter, "type", DBUS_TYPE_STRING,
+ &variant_str);
+ if (prop->encoding)
+ g_dbus_dict_append_entry(&iter, "encoding",
+ DBUS_TYPE_STRING,
+ &prop->encoding);
+ if (prop->pixel)
+ g_dbus_dict_append_entry(&iter, "pixel",
+ DBUS_TYPE_STRING,
+ &prop->pixel);
+ if (prop->maxsize)
+ g_dbus_dict_append_entry(&iter, "maxsize",
+ DBUS_TYPE_UINT64,
+ &prop->maxsize);
+ if (prop->transform)
+ g_dbus_dict_append_entry(&iter, "transformation",
+ DBUS_TYPE_STRING,
+ &prop->transform);
+ dbus_message_iter_close_container(&dict, &iter);
+ }
+
+ for (list = obj->att; list != NULL; list = g_slist_next(list)) {
+ struct att_prop *prop = list->data;
+ static char *attachment_str = "attachment";
+
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &iter);
+ g_dbus_dict_append_entry(&iter, "type", DBUS_TYPE_STRING,
+ &attachment_str);
+ if (prop->content_type)
+ g_dbus_dict_append_entry(&iter, "content-type",
+ DBUS_TYPE_STRING,
+ &prop->content_type);
+ if (prop->charset)
+ g_dbus_dict_append_entry(&iter, "charset",
+ DBUS_TYPE_STRING,
+ &prop->charset);
+ if (prop->name)
+ g_dbus_dict_append_entry(&iter, "name",
+ DBUS_TYPE_STRING,
+ &prop->name);
+ if (prop->size)
+ g_dbus_dict_append_entry(&iter, "size",
+ DBUS_TYPE_UINT64,
+ &prop->size);
+ if (prop->ctime)
+ g_dbus_dict_append_entry(&iter, "ctime",
+ DBUS_TYPE_UINT64,
+ &prop->ctime);
+ if (prop->mtime)
+ g_dbus_dict_append_entry(&iter, "mtime",
+ DBUS_TYPE_UINT64,
+ &prop->mtime);
+ dbus_message_iter_close_container(&dict, &iter);
+ }
+
+ dbus_message_iter_close_container(args, &dict);
+}
diff --git a/obexd/client/bip-common.h b/obexd/client/bip-common.h
new file mode 100644
index 000000000..0fee54636
--- /dev/null
+++ b/obexd/client/bip-common.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2024 Collabora Ltd.
+ *
+ *
+ */
+
+#include <glib.h>
+#include "gdbus/gdbus.h"
+
+struct prop_object;
+
+struct prop_object *parse_properties(char *data, unsigned int length,
+ int *err);
+gboolean verify_properties(struct prop_object *obj);
+void append_properties(DBusMessageIter *args, struct prop_object *obj);
diff --git a/obexd/client/bip.c b/obexd/client/bip.c
index 252bc4cec..e5ea5468c 100644
--- a/obexd/client/bip.c
+++ b/obexd/client/bip.c
@@ -20,6 +20,7 @@
#include "transfer.h"
#include "session.h"
#include "driver.h"
+#include "bip-common.h"
#include "bip.h"
#define OBEX_BIP_AVRCP_UUID \
@@ -38,6 +39,102 @@ struct bip_avrcp_data {
struct obc_session *session;
};
+static void image_properties_complete_cb(struct obc_session *session,
+ struct obc_transfer *transfer,
+ GError *err, void *user_data)
+{
+ DBusMessage *message = user_data;
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter;
+ char *contents = NULL;
+ size_t size;
+ int perr;
+ struct prop_object *prop = NULL;
+
+ if (err != NULL) {
+ reply = g_dbus_create_error(message,
+ ERROR_INTERFACE ".Failed",
+ "%s", err->message);
+ goto done;
+ }
+
+ perr = obc_transfer_get_contents(transfer, &contents, &size);
+ if (perr < 0) {
+ reply = g_dbus_create_error(message,
+ ERROR_INTERFACE ".Failed",
+ "Error reading contents: %s",
+ strerror(-perr));
+ goto done;
+ }
+
+ prop = parse_properties(contents, size, &perr);
+ if (prop == NULL) {
+ reply = g_dbus_create_error(message,
+ ERROR_INTERFACE ".Failed",
+ "Error parsing contents: %s",
+ strerror(-perr));
+ goto done;
+ }
+
+ if (!verify_properties(prop)) {
+ reply = g_dbus_create_error(message,
+ ERROR_INTERFACE ".Failed",
+ "Error verifying contents");
+ goto done;
+ }
+
+ reply = dbus_message_new_method_return(message);
+ dbus_message_iter_init_append(reply, &iter);
+ append_properties(&iter, prop);
+
+done:
+ g_dbus_send_message(conn, reply);
+ g_free(contents);
+ dbus_message_unref(message);
+}
+
+static DBusMessage *get_image_properties(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct bip_avrcp_data *bip_avrcp = user_data;
+ const char *handle = NULL;
+ struct obc_transfer *transfer;
+ GObexHeader *header;
+ DBusMessage *reply = NULL;
+ GError *err = NULL;
+
+ DBG("");
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &handle,
+ DBUS_TYPE_INVALID) == FALSE) {
+ reply = g_dbus_create_error(message,
+ ERROR_INTERFACE ".InvalidArguments", NULL);
+ return reply;
+ }
+
+ transfer = obc_transfer_get("x-bt/img-properties", NULL, NULL, &err);
+ if (transfer == NULL)
+ goto fail;
+
+ header = g_obex_header_new_unicode(IMG_HANDLE_TAG, handle);
+ obc_transfer_add_header(transfer, header);
+
+ if (!obc_session_queue(bip_avrcp->session, transfer,
+ image_properties_complete_cb, message, &err))
+ goto fail;
+
+ dbus_message_ref(message);
+
+ return NULL;
+
+fail:
+ reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
+ err->message);
+ g_error_free(err);
+ return reply;
+}
+
static DBusMessage *get_thumbnail(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
@@ -79,6 +176,10 @@ fail:
}
static const GDBusMethodTable bip_avrcp_methods[] = {
+ { GDBUS_ASYNC_METHOD("Properties",
+ GDBUS_ARGS({ "handle", "s"}),
+ GDBUS_ARGS({ "properties", "aa{sv}" }),
+ get_image_properties) },
{ GDBUS_ASYNC_METHOD("GetThumbnail",
GDBUS_ARGS({ "file", "s" }, { "handle", "s"}),
GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH BlueZ v4 3/5] obexd: Add Get to org.bluez.obex.Image
2024-09-17 7:42 [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 1/5] obexd: Add BIP client for AVRCP cover art download Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 2/5] obexd: Add Properties to org.bluez.obex.Image Frédéric Danis
@ 2024-09-17 7:42 ` Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 4/5] avrcp: Update controller SDP record with cover art support Frédéric Danis
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Frédéric Danis @ 2024-09-17 7:42 UTC (permalink / raw)
To: linux-bluetooth
Retrieves the image corresponding to the handle and the description,
as one of the descriptions retrieved by Properties, and store it in
a local file.
If the "transform" property description exists it should be set
to one of the value listed by Properties for this description.
---
obexd/client/bip-common.c | 21 ++++-
obexd/client/bip-common.h | 5 ++
obexd/client/bip.c | 168 ++++++++++++++++++++++++++++++++++++++
3 files changed, 193 insertions(+), 1 deletion(-)
diff --git a/obexd/client/bip-common.c b/obexd/client/bip-common.c
index 9e96c81d8..613b52ceb 100644
--- a/obexd/client/bip-common.c
+++ b/obexd/client/bip-common.c
@@ -49,7 +49,7 @@ static const gchar *convBIP2IM(const gchar *encoding)
return NULL;
}
-static gboolean parse_pixel_range(const gchar *dim, unsigned int *lower_ret,
+gboolean parse_pixel_range(const gchar *dim, unsigned int *lower_ret,
unsigned int *upper_ret,
gboolean *fixed_ratio_ret)
{
@@ -139,6 +139,18 @@ char *transforms[] = {
NULL
};
+gboolean verify_encoding(const char *encoding)
+{
+ struct encconv_pair *et = encconv_table;
+
+ while (et->bip) {
+ if (g_strcmp0(encoding, et->bip) == 0)
+ return TRUE;
+ et++;
+ }
+ return FALSE;
+}
+
static gboolean verify_transform(const char *transform)
{
char **str = transforms;
@@ -151,6 +163,13 @@ static gboolean verify_transform(const char *transform)
return FALSE;
}
+char *parse_transform(const char *transform)
+{
+ if (!verify_transform(transform))
+ return NULL;
+ return g_strdup(transform);
+}
+
static char *parse_transform_list(const char *transform)
{
char **args = NULL, **arg = NULL;
diff --git a/obexd/client/bip-common.h b/obexd/client/bip-common.h
index 0fee54636..6e7aac375 100644
--- a/obexd/client/bip-common.h
+++ b/obexd/client/bip-common.h
@@ -13,6 +13,11 @@
struct prop_object;
+gboolean parse_pixel_range(const gchar *dim, unsigned int *lower_ret,
+ unsigned int *upper_ret,
+ gboolean *fixed_ratio_ret);
+gboolean verify_encoding(const char *encoding);
+char *parse_transform(const char *transform);
struct prop_object *parse_properties(char *data, unsigned int length,
int *err);
gboolean verify_properties(struct prop_object *obj);
diff --git a/obexd/client/bip.c b/obexd/client/bip.c
index e5ea5468c..9d9ecec81 100644
--- a/obexd/client/bip.c
+++ b/obexd/client/bip.c
@@ -32,6 +32,14 @@
#define IMAGE_UUID "0000111A-0000-1000-8000-00805f9b34fb"
#define IMG_HANDLE_TAG 0x30
+#define IMG_DESC_TAG 0x71
+
+#define EOL_CHARS "\n"
+#define IMG_DESC_BEGIN "<image-descriptor version=\"1.0\">" EOL_CHARS
+#define IMG_BEGIN "<image encoding=\"%s\" pixel=\"%s\""
+#define IMG_TRANSFORM " transformation=\"%s\""
+#define IMG_END "/>" EOL_CHARS
+#define IMG_DESC_END "</image-descriptor>" EOL_CHARS
static DBusConnection *conn;
@@ -175,11 +183,171 @@ fail:
return reply;
}
+static gboolean parse_get_image_dict(DBusMessage *msg, char **path,
+ char **handle, char **pixel,
+ char **encoding, uint64_t *maxsize,
+ char **transform)
+{
+ DBusMessageIter iter, array;
+
+ DBG("");
+
+ *path = NULL;
+ *handle = NULL;
+ *pixel = NULL;
+ *encoding = NULL;
+ *transform = NULL;
+
+ dbus_message_iter_init(msg, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ goto failed;
+ dbus_message_iter_get_basic(&iter, path);
+ *path = g_strdup(*path);
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ goto failed;
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_get_basic(&iter, handle);
+ *handle = g_strdup(*handle);
+ dbus_message_iter_next(&iter);
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+ goto failed;
+
+ dbus_message_iter_recurse(&iter, &array);
+
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+ const char *key, *val;
+
+ dbus_message_iter_recurse(&array, &entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ return FALSE;
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+ switch (dbus_message_iter_get_arg_type(&value)) {
+ case DBUS_TYPE_STRING:
+ dbus_message_iter_get_basic(&value, &val);
+ if (g_str_equal(key, "pixel")) {
+ if (!parse_pixel_range(val, NULL, NULL, NULL))
+ goto failed;
+ *pixel = g_strdup(val);
+ } else if (g_str_equal(key, "encoding")) {
+ if (!verify_encoding(val))
+ goto failed;
+ *encoding = g_strdup(val);
+ if (*encoding == NULL)
+ goto failed;
+ } else if (g_str_equal(key, "transformation")) {
+ *transform = parse_transform(val);
+ if (*transform == NULL)
+ goto failed;
+ }
+ break;
+ case DBUS_TYPE_UINT64:
+ if (g_str_equal(key, "maxsize") == TRUE) {
+ dbus_message_iter_get_basic(&value, maxsize);
+ if (*maxsize == 0)
+ goto failed;
+ }
+ break;
+ }
+ dbus_message_iter_next(&array);
+ }
+
+ if (*pixel == NULL)
+ *pixel = strdup("");
+ if (*encoding == NULL)
+ *encoding = strdup("");
+
+ DBG("pixel: '%s' encoding: '%s' maxsize: '%lu' transform: '%s'",
+ *pixel, *encoding, *maxsize, *transform
+ );
+
+ return TRUE;
+failed:
+ g_free(*path);
+ g_free(*handle);
+ g_free(*pixel);
+ g_free(*encoding);
+ g_free(*transform);
+ return FALSE;
+}
+
+static DBusMessage *get_image(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct bip_avrcp_data *bip_avrcp = user_data;
+ char *handle = NULL, *image_path = NULL, *transform = NULL,
+ *encoding = NULL, *pixel = NULL;
+ uint64_t maxsize;
+ struct obc_transfer *transfer;
+ GObexHeader *header;
+ DBusMessage *reply = NULL;
+ GString *descriptor = NULL;
+ GError *err = NULL;
+
+ DBG("");
+
+ if (!parse_get_image_dict(message, &image_path, &handle, &pixel,
+ &encoding, &maxsize, &transform))
+ return g_dbus_create_error(message,
+ ERROR_INTERFACE ".InvalidArguments", NULL);
+
+ transfer = obc_transfer_get("x-bt/img-img", NULL, image_path, &err);
+ if (transfer == NULL) {
+ reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed",
+ "%s",
+ err->message);
+ g_error_free(err);
+ goto fail;
+ }
+
+ header = g_obex_header_new_unicode(IMG_HANDLE_TAG, handle);
+ obc_transfer_add_header(transfer, header);
+
+ descriptor = g_string_new(IMG_DESC_BEGIN);
+ g_string_append_printf(descriptor, IMG_BEGIN, encoding, pixel);
+ if (transform != NULL)
+ g_string_append_printf(descriptor, IMG_TRANSFORM, transform);
+ g_string_append(descriptor, IMG_END);
+ descriptor = g_string_append(descriptor, IMG_DESC_END);
+ header = g_obex_header_new_bytes(IMG_DESC_TAG, descriptor->str,
+ descriptor->len);
+ obc_transfer_add_header(transfer, header);
+ g_string_free(descriptor, TRUE);
+
+ if (!obc_session_queue(bip_avrcp->session, transfer, NULL, NULL,
+ &err)) {
+ reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed",
+ "%s",
+ err->message);
+ g_error_free(err);
+ goto fail;
+ }
+
+ reply = obc_transfer_create_dbus_reply(transfer, message);
+
+fail:
+ g_free(handle);
+ g_free(image_path);
+ g_free(transform);
+ g_free(encoding);
+ g_free(pixel);
+ return reply;
+}
+
static const GDBusMethodTable bip_avrcp_methods[] = {
{ GDBUS_ASYNC_METHOD("Properties",
GDBUS_ARGS({ "handle", "s"}),
GDBUS_ARGS({ "properties", "aa{sv}" }),
get_image_properties) },
+ { GDBUS_ASYNC_METHOD("Get",
+ GDBUS_ARGS({ "file", "s" }, { "handle", "s"},
+ {"properties", "a{sv}"}),
+ GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
+ get_image) },
{ GDBUS_ASYNC_METHOD("GetThumbnail",
GDBUS_ARGS({ "file", "s" }, { "handle", "s"}),
GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH BlueZ v4 4/5] avrcp: Update controller SDP record with cover art support
2024-09-17 7:42 [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client Frédéric Danis
` (2 preceding siblings ...)
2024-09-17 7:42 ` [PATCH BlueZ v4 3/5] obexd: Add Get " Frédéric Danis
@ 2024-09-17 7:42 ` Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 5/5] doc: Add description of org.bluez.obex.Image Frédéric Danis
2024-09-17 15:40 ` [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client patchwork-bot+bluetooth
5 siblings, 0 replies; 11+ messages in thread
From: Frédéric Danis @ 2024-09-17 7:42 UTC (permalink / raw)
To: linux-bluetooth
---
profiles/audio/avrcp.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index fe24b5a92..c2c901a65 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -413,12 +413,14 @@ static sdp_record_t *avrcp_ct_record(bool browsing)
sdp_record_t *record;
sdp_data_t *psm[2], *version, *features;
uint16_t lp = AVCTP_CONTROL_PSM;
- uint16_t avctp_ver = 0x0103;
+ uint16_t avctp_ver = 0x0106;
uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
- AVRCP_FEATURE_CATEGORY_2 |
- AVRCP_FEATURE_CATEGORY_3 |
- AVRCP_FEATURE_CATEGORY_4 |
- AVRCP_FEATURE_CT_GET_THUMBNAIL);
+ AVRCP_FEATURE_CATEGORY_2 |
+ AVRCP_FEATURE_CATEGORY_3 |
+ AVRCP_FEATURE_CATEGORY_4 |
+ AVRCP_FEATURE_CT_GET_IMAGE_PROP |
+ AVRCP_FEATURE_CT_GET_IMAGE |
+ AVRCP_FEATURE_CT_GET_THUMBNAIL);
record = sdp_record_alloc();
if (!record)
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH BlueZ v4 5/5] doc: Add description of org.bluez.obex.Image
2024-09-17 7:42 [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client Frédéric Danis
` (3 preceding siblings ...)
2024-09-17 7:42 ` [PATCH BlueZ v4 4/5] avrcp: Update controller SDP record with cover art support Frédéric Danis
@ 2024-09-17 7:42 ` Frédéric Danis
2024-09-17 15:40 ` [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client patchwork-bot+bluetooth
5 siblings, 0 replies; 11+ messages in thread
From: Frédéric Danis @ 2024-09-17 7:42 UTC (permalink / raw)
To: linux-bluetooth
This new interface allows to get the image referenced in the audio
metadata ImgHandle available in org.bluez.MediaPlayer track properties.
The image handle is only available in track info if an OBEX session is
connected to the ObexPort port provided in org.bluez.MediaPlayer
properties.
---
Makefile.am | 9 ++-
doc/org.bluez.obex.Image.rst | 118 +++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+), 3 deletions(-)
create mode 100644 doc/org.bluez.obex.Image.rst
diff --git a/Makefile.am b/Makefile.am
index 88044aa05..3eb0a5302 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -382,7 +382,8 @@ man_MANS += doc/org.bluez.obex.Client.5 doc/org.bluez.obex.Session.5 \
doc/org.bluez.obex.PhonebookAccess.5 \
doc/org.bluez.obex.MessageAccess.5 \
doc/org.bluez.obex.Message.5 \
- doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5
+ doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5 \
+ doc/org.bluez.obex.Image.5
endif
manual_pages += src/bluetoothd.8
manual_pages += doc/l2cap.7 doc/rfcomm.7
@@ -415,7 +416,8 @@ manual_pages += doc/org.bluez.obex.Client.5 doc/org.bluez.obex.Session.5 \
doc/org.bluez.obex.PhonebookAccess.5 \
doc/org.bluez.obex.MessageAccess.5 \
doc/org.bluez.obex.Message.5 \
- doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5
+ doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5 \
+ doc/org.bluez.obex.Image.5
EXTRA_DIST += src/genbuiltin src/bluetooth.conf \
src/main.conf profiles/network/network.conf \
@@ -497,7 +499,8 @@ EXTRA_DIST += doc/org.bluez.obex.Client.rst doc/org.bluez.obex.Session.rst \
doc/org.bluez.obex.PhonebookAccess.rst \
doc/org.bluez.obex.MessageAccess.rst \
doc/org.bluez.obex.Message.rst \
- doc/org.bluez.obex.AgentManager.rst doc/org.bluez.obex.Agent.rst
+ doc/org.bluez.obex.AgentManager.rst doc/org.bluez.obex.Agent.rst \
+ doc/org.bluez.obex.Image.rst
EXTRA_DIST += doc/pics-opp.txt doc/pixit-opp.txt \
doc/pts-opp.txt
diff --git a/doc/org.bluez.obex.Image.rst b/doc/org.bluez.obex.Image.rst
new file mode 100644
index 000000000..386805203
--- /dev/null
+++ b/doc/org.bluez.obex.Image.rst
@@ -0,0 +1,118 @@
+====================
+org.bluez.obex.Image
+====================
+
+--------------------------------------------------
+BlueZ D-Bus OBEX Image API documentation
+--------------------------------------------------
+
+:Version: BlueZ
+:Date: August 2024
+:Manual section: 5
+:Manual group: Linux System Administration
+
+Interface
+=========
+
+:Service: org.bluez.obex
+:Interface: org.bluez.obex.Image1 [experimental]
+:Object path: [Session object path]
+
+Methods
+-------
+
+object, dict Get(string targetfile, string handle, dict description)
+````````````````````````````````````````````````````````````````````
+
+ Retrieves the image corresponding to the handle and the description, as
+ one of the descriptions retrieved by GetImageProperties, and store it in
+ a local file.
+
+ If the "transform" property description exists it should be set to one
+ of the value listed by GetImageProperties for this description.
+
+ If description is an empty dict, the native image will be retrieved.
+
+ Possible errors:
+
+ :org.bluez.obex.Error.InvalidArguments:
+ :org.bluez.obex.Error.Failed:
+
+array{dict} Properties(string handle)
+`````````````````````````````````````
+
+ Retrieves the image properties corresponding to the handle.
+
+ The first dict entry is mandatory and correspond to 'handle' and 'name'
+ of the image.
+
+ The second dict entry is mandatory and correspond to the native description
+ ('type':'native') of the image.
+
+ The following dict entries are optional and correspond to variant
+ descriptions of the image. If the 'transform' entry exists in the
+ description, it lists the available possible image transformations and
+ should be set to one of them before using the description as parameter
+ to GetImage.
+
+ Possible property values:
+
+ :string type:
+
+ Type of dict properties. Mandatory for each dict.
+
+ Possible values:
+
+ :"native":
+ :"variant":
+
+ :string encoding:
+
+ File encoding format.
+
+ Possible values:
+
+ :"BMP":
+ :"GIF":
+ :"JPEG":
+ :"JPEG2000":
+ :"PNG":
+ :"WBMP":
+
+ :string pixel:
+
+ File encoding format size of form "<width>*<height>".
+
+ :uint64 size:
+
+ File size.
+
+ :uint64 maxsize:
+
+ File maximum size.
+
+ :string transformation:
+
+ List of available transformations separated by space.
+
+ Possible values:
+
+ :"crop":
+ :"fill":
+ :"stretch":
+
+ Possible errors:
+
+ :org.bluez.obex.Error.InvalidArguments:
+ :org.bluez.obex.Error.Failed:
+
+object, dict GetThumbnail(string targetfile, string handle)
+```````````````````````````````````````````````````````````
+
+ Retrieves the image thumbnail corresponding to the handle and store it in
+ a local file.
+
+ Possible errors:
+
+ :org.bluez.obex.Error.InvalidArguments:
+ :org.bluez.obex.Error.Failed:
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client
2024-09-17 7:42 [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client Frédéric Danis
` (4 preceding siblings ...)
2024-09-17 7:42 ` [PATCH BlueZ v4 5/5] doc: Add description of org.bluez.obex.Image Frédéric Danis
@ 2024-09-17 15:40 ` patchwork-bot+bluetooth
5 siblings, 0 replies; 11+ messages in thread
From: patchwork-bot+bluetooth @ 2024-09-17 15:40 UTC (permalink / raw)
To: =?utf-8?b?RnLDqWTDqXJpYyBEYW5pcyA8ZnJlZGVyaWMuZGFuaXNAY29sbGFib3JhLmNvbT4=?=
Cc: linux-bluetooth
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Tue, 17 Sep 2024 09:42:12 +0200 you wrote:
> If AVRCP Target supports Cover Art download its SDP record contains an
> additional access protocol for OBEX with an LCAP PSM on which the OBEX
> client session should connect to, with the specific OBEX target header
> 7163DD54-4A7E-11E2-B47C-0050C2490048.
>
> Once the OBEX session is connected, the AVRCP track metadata will contain
> an Image Handle which can be used to get the associated image using
> GetImageThumbnail or GetImage with one of the description property found
> with GetImageProperties.
>
> [...]
Here is the summary with links:
- [BlueZ,v4,1/5] obexd: Add BIP client for AVRCP cover art download
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=1a681aa0143e
- [BlueZ,v4,2/5] obexd: Add Properties to org.bluez.obex.Image
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=3ecf9b3398ac
- [BlueZ,v4,3/5] obexd: Add Get to org.bluez.obex.Image
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=088594d5299a
- [BlueZ,v4,4/5] avrcp: Update controller SDP record with cover art support
(no matching commit)
- [BlueZ,v4,5/5] doc: Add description of org.bluez.obex.Image
(no matching commit)
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH BlueZ v3 1/9] obexd: Add PSM support to session create
@ 2024-09-16 13:28 Frédéric Danis
2024-09-16 18:47 ` Add BIP for AVRCP covert art OBEX client bluez.test.bot
0 siblings, 1 reply; 11+ messages in thread
From: Frédéric Danis @ 2024-09-16 13:28 UTC (permalink / raw)
To: linux-bluetooth
An OBEX session can be connected to a RFCOMM channel or a L2CAP PSM.
---
doc/org.bluez.obex.Client.rst | 4 ++++
doc/org.bluez.obex.Session.rst | 5 +++++
obexd/client/manager.c | 14 ++++++++++----
obexd/client/session.c | 27 ++++++++++++++++++++++++---
obexd/client/session.h | 1 +
5 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/doc/org.bluez.obex.Client.rst b/doc/org.bluez.obex.Client.rst
index 9f77a9abc..5ae7cc5e8 100644
--- a/doc/org.bluez.obex.Client.rst
+++ b/doc/org.bluez.obex.Client.rst
@@ -52,6 +52,10 @@ object CreateSession(string destination, dict args)
Channel to be used.
+ :uint16 PSM:
+
+ L2CAP PSM to be used.
+
Possible errors:
:org.bluez.obex.Error.InvalidArguments:
diff --git a/doc/org.bluez.obex.Session.rst b/doc/org.bluez.obex.Session.rst
index 1cef9a53d..fc5f14e5d 100644
--- a/doc/org.bluez.obex.Session.rst
+++ b/doc/org.bluez.obex.Session.rst
@@ -50,6 +50,11 @@ byte Channel [readonly]
Bluetooth channel
+uint16 PSM [readonly]
+```````````````````````
+
+ Bluetooth L2CAP PSM
+
string Target [readonly]
````````````````````````
diff --git a/obexd/client/manager.c b/obexd/client/manager.c
index ad1fbb04a..52c00fb0c 100644
--- a/obexd/client/manager.c
+++ b/obexd/client/manager.c
@@ -107,7 +107,8 @@ done:
}
static int parse_device_dict(DBusMessageIter *iter,
- const char **source, const char **target, uint8_t *channel)
+ const char **source, const char **target, uint8_t *channel,
+ uint16_t *psm)
{
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
DBusMessageIter entry, value;
@@ -130,6 +131,10 @@ static int parse_device_dict(DBusMessageIter *iter,
if (g_str_equal(key, "Channel") == TRUE)
dbus_message_iter_get_basic(&value, channel);
break;
+ case DBUS_TYPE_UINT16:
+ if (g_str_equal(key, "PSM") == TRUE)
+ dbus_message_iter_get_basic(&value, psm);
+ break;
}
dbus_message_iter_next(iter);
@@ -160,6 +165,7 @@ static DBusMessage *create_session(DBusConnection *connection,
struct send_data *data;
const char *source = NULL, *dest = NULL, *target = NULL;
uint8_t channel = 0;
+ uint16_t psm = 0;
dbus_message_iter_init(message, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -175,8 +181,8 @@ static DBusMessage *create_session(DBusConnection *connection,
dbus_message_iter_recurse(&iter, &dict);
- parse_device_dict(&dict, &source, &target, &channel);
- if (dest == NULL || target == NULL)
+ parse_device_dict(&dict, &source, &target, &channel, &psm);
+ if (dest == NULL || target == NULL || (channel && psm))
return g_dbus_create_error(message,
ERROR_INTERFACE ".InvalidArguments", NULL);
@@ -188,7 +194,7 @@ static DBusMessage *create_session(DBusConnection *connection,
data->connection = dbus_connection_ref(connection);
data->message = dbus_message_ref(message);
- session = obc_session_create(source, dest, target, channel,
+ session = obc_session_create(source, dest, target, channel, psm,
dbus_message_get_sender(message),
create_callback, data);
if (session != NULL) {
diff --git a/obexd/client/session.c b/obexd/client/session.c
index 7d8ebb04e..13a834e14 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
@@ -88,6 +88,7 @@ struct obc_session {
char *source;
char *destination;
uint8_t channel;
+ uint16_t psm;
struct obc_transport *transport;
struct obc_driver *driver;
char *path; /* Session path */
@@ -471,6 +472,7 @@ static struct obc_session *session_find(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner)
{
GSList *l;
@@ -490,6 +492,9 @@ static struct obc_session *session_find(const char *source,
if (channel && session->channel != channel)
continue;
+ if (psm && session->psm != psm)
+ continue;
+
if (g_strcmp0(owner, session->owner))
continue;
@@ -541,8 +546,9 @@ static int session_connect(struct obc_session *session,
}
session->id = transport->connect(session->source, session->destination,
- driver->uuid, session->channel,
- transport_func, callback);
+ driver->uuid,
+ session->channel ? session->channel : session->psm,
+ transport_func, callback);
if (session->id == 0) {
obc_session_unref(callback->session);
g_free(callback);
@@ -558,6 +564,7 @@ struct obc_session *obc_session_create(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner,
session_callback_t function,
void *user_data)
@@ -570,7 +577,8 @@ struct obc_session *obc_session_create(const char *source,
if (destination == NULL)
return NULL;
- session = session_find(source, destination, service, channel, owner);
+ session = session_find(source, destination, service, channel, psm,
+ owner);
if (session != NULL)
goto proceed;
@@ -598,6 +606,7 @@ struct obc_session *obc_session_create(const char *source,
session->source = g_strdup(source);
session->destination = g_strdup(destination);
session->channel = channel;
+ session->psm = psm;
session->queue = g_queue_new();
session->folder = g_strdup("/");
@@ -762,6 +771,17 @@ static gboolean get_channel(const GDBusPropertyTable *property,
return TRUE;
}
+static gboolean get_psm(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct obc_session *session = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
+ &session->psm);
+
+ return TRUE;
+}
+
static const GDBusMethodTable session_methods[] = {
{ GDBUS_ASYNC_METHOD("GetCapabilities",
NULL, GDBUS_ARGS({ "capabilities", "s" }),
@@ -794,6 +814,7 @@ static const GDBusPropertyTable session_properties[] = {
{ "Source", "s", get_source, NULL, source_exists },
{ "Destination", "s", get_destination },
{ "Channel", "y", get_channel },
+ { "PSM", "q", get_psm },
{ "Target", "s", get_target, NULL, target_exists },
{ }
};
diff --git a/obexd/client/session.h b/obexd/client/session.h
index 2c646df1a..19c3f3687 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
@@ -22,6 +22,7 @@ struct obc_session *obc_session_create(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner,
session_callback_t function,
void *user_data);
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* RE: Add BIP for AVRCP covert art OBEX client
2024-09-16 13:28 [PATCH BlueZ v3 1/9] obexd: Add PSM support to session create Frédéric Danis
@ 2024-09-16 18:47 ` bluez.test.bot
0 siblings, 0 replies; 11+ messages in thread
From: bluez.test.bot @ 2024-09-16 18:47 UTC (permalink / raw)
To: linux-bluetooth, frederic.danis
[-- Attachment #1: Type: text/plain, Size: 2813 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=890683
---Test result---
Test Summary:
CheckPatch FAIL 5.53 seconds
GitLint FAIL 6.65 seconds
BuildEll PASS 24.81 seconds
BluezMake PASS 1677.20 seconds
MakeCheck PASS 13.28 seconds
MakeDistcheck PASS 186.25 seconds
CheckValgrind PASS 259.07 seconds
CheckSmatch PASS 365.98 seconds
bluezmakeextell PASS 123.65 seconds
IncrementalBuild PASS 14622.47 seconds
ScanBuild WARNING 1022.75 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,v3,6/9] obexd: Add GetImageProperties to bip-avrcp
WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#78:
[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c
/github/workspace/src/src/13805437.patch total: 0 errors, 1 warnings, 926 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/src/13805437.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v3,6/9] obexd: Add GetImageProperties to bip-avrcp
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
10: B1 Line exceeds max length (95>80): "[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c"
##############################
Test: ScanBuild - WARNING
Desc: Run Scan Build
Output:
profiles/audio/avrcp.c:1942:2: warning: Value stored to 'operands' is never read
operands += sizeof(*pdu);
^ ~~~~~~~~~~~~
1 warning generated.
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH BlueZ v2 1/7] obexd: Add PSM support to session create
@ 2024-09-12 17:49 Frédéric Danis
2024-09-12 22:37 ` Add BIP for AVRCP covert art OBEX client bluez.test.bot
0 siblings, 1 reply; 11+ messages in thread
From: Frédéric Danis @ 2024-09-12 17:49 UTC (permalink / raw)
To: linux-bluetooth
An OBEX session can be connected to a RFCOMM channel or a L2CAP PSM.
---
doc/org.bluez.obex.Client.rst | 4 ++++
doc/org.bluez.obex.Session.rst | 5 +++++
obexd/client/manager.c | 14 ++++++++++----
obexd/client/session.c | 27 ++++++++++++++++++++++++---
obexd/client/session.h | 1 +
5 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/doc/org.bluez.obex.Client.rst b/doc/org.bluez.obex.Client.rst
index 9f77a9abc..5ae7cc5e8 100644
--- a/doc/org.bluez.obex.Client.rst
+++ b/doc/org.bluez.obex.Client.rst
@@ -52,6 +52,10 @@ object CreateSession(string destination, dict args)
Channel to be used.
+ :uint16 PSM:
+
+ L2CAP PSM to be used.
+
Possible errors:
:org.bluez.obex.Error.InvalidArguments:
diff --git a/doc/org.bluez.obex.Session.rst b/doc/org.bluez.obex.Session.rst
index 1cef9a53d..fc5f14e5d 100644
--- a/doc/org.bluez.obex.Session.rst
+++ b/doc/org.bluez.obex.Session.rst
@@ -50,6 +50,11 @@ byte Channel [readonly]
Bluetooth channel
+uint16 PSM [readonly]
+```````````````````````
+
+ Bluetooth L2CAP PSM
+
string Target [readonly]
````````````````````````
diff --git a/obexd/client/manager.c b/obexd/client/manager.c
index ad1fbb04a..52c00fb0c 100644
--- a/obexd/client/manager.c
+++ b/obexd/client/manager.c
@@ -107,7 +107,8 @@ done:
}
static int parse_device_dict(DBusMessageIter *iter,
- const char **source, const char **target, uint8_t *channel)
+ const char **source, const char **target, uint8_t *channel,
+ uint16_t *psm)
{
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
DBusMessageIter entry, value;
@@ -130,6 +131,10 @@ static int parse_device_dict(DBusMessageIter *iter,
if (g_str_equal(key, "Channel") == TRUE)
dbus_message_iter_get_basic(&value, channel);
break;
+ case DBUS_TYPE_UINT16:
+ if (g_str_equal(key, "PSM") == TRUE)
+ dbus_message_iter_get_basic(&value, psm);
+ break;
}
dbus_message_iter_next(iter);
@@ -160,6 +165,7 @@ static DBusMessage *create_session(DBusConnection *connection,
struct send_data *data;
const char *source = NULL, *dest = NULL, *target = NULL;
uint8_t channel = 0;
+ uint16_t psm = 0;
dbus_message_iter_init(message, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -175,8 +181,8 @@ static DBusMessage *create_session(DBusConnection *connection,
dbus_message_iter_recurse(&iter, &dict);
- parse_device_dict(&dict, &source, &target, &channel);
- if (dest == NULL || target == NULL)
+ parse_device_dict(&dict, &source, &target, &channel, &psm);
+ if (dest == NULL || target == NULL || (channel && psm))
return g_dbus_create_error(message,
ERROR_INTERFACE ".InvalidArguments", NULL);
@@ -188,7 +194,7 @@ static DBusMessage *create_session(DBusConnection *connection,
data->connection = dbus_connection_ref(connection);
data->message = dbus_message_ref(message);
- session = obc_session_create(source, dest, target, channel,
+ session = obc_session_create(source, dest, target, channel, psm,
dbus_message_get_sender(message),
create_callback, data);
if (session != NULL) {
diff --git a/obexd/client/session.c b/obexd/client/session.c
index 7d8ebb04e..13a834e14 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
@@ -88,6 +88,7 @@ struct obc_session {
char *source;
char *destination;
uint8_t channel;
+ uint16_t psm;
struct obc_transport *transport;
struct obc_driver *driver;
char *path; /* Session path */
@@ -471,6 +472,7 @@ static struct obc_session *session_find(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner)
{
GSList *l;
@@ -490,6 +492,9 @@ static struct obc_session *session_find(const char *source,
if (channel && session->channel != channel)
continue;
+ if (psm && session->psm != psm)
+ continue;
+
if (g_strcmp0(owner, session->owner))
continue;
@@ -541,8 +546,9 @@ static int session_connect(struct obc_session *session,
}
session->id = transport->connect(session->source, session->destination,
- driver->uuid, session->channel,
- transport_func, callback);
+ driver->uuid,
+ session->channel ? session->channel : session->psm,
+ transport_func, callback);
if (session->id == 0) {
obc_session_unref(callback->session);
g_free(callback);
@@ -558,6 +564,7 @@ struct obc_session *obc_session_create(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner,
session_callback_t function,
void *user_data)
@@ -570,7 +577,8 @@ struct obc_session *obc_session_create(const char *source,
if (destination == NULL)
return NULL;
- session = session_find(source, destination, service, channel, owner);
+ session = session_find(source, destination, service, channel, psm,
+ owner);
if (session != NULL)
goto proceed;
@@ -598,6 +606,7 @@ struct obc_session *obc_session_create(const char *source,
session->source = g_strdup(source);
session->destination = g_strdup(destination);
session->channel = channel;
+ session->psm = psm;
session->queue = g_queue_new();
session->folder = g_strdup("/");
@@ -762,6 +771,17 @@ static gboolean get_channel(const GDBusPropertyTable *property,
return TRUE;
}
+static gboolean get_psm(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct obc_session *session = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
+ &session->psm);
+
+ return TRUE;
+}
+
static const GDBusMethodTable session_methods[] = {
{ GDBUS_ASYNC_METHOD("GetCapabilities",
NULL, GDBUS_ARGS({ "capabilities", "s" }),
@@ -794,6 +814,7 @@ static const GDBusPropertyTable session_properties[] = {
{ "Source", "s", get_source, NULL, source_exists },
{ "Destination", "s", get_destination },
{ "Channel", "y", get_channel },
+ { "PSM", "q", get_psm },
{ "Target", "s", get_target, NULL, target_exists },
{ }
};
diff --git a/obexd/client/session.h b/obexd/client/session.h
index 2c646df1a..19c3f3687 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
@@ -22,6 +22,7 @@ struct obc_session *obc_session_create(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner,
session_callback_t function,
void *user_data);
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* RE: Add BIP for AVRCP covert art OBEX client
2024-09-12 17:49 [PATCH BlueZ v2 1/7] obexd: Add PSM support to session create Frédéric Danis
@ 2024-09-12 22:37 ` bluez.test.bot
0 siblings, 0 replies; 11+ messages in thread
From: bluez.test.bot @ 2024-09-12 22:37 UTC (permalink / raw)
To: linux-bluetooth, frederic.danis
[-- Attachment #1: Type: text/plain, Size: 4893 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=889869
---Test result---
Test Summary:
CheckPatch FAIL 4.87 seconds
GitLint FAIL 2.45 seconds
BuildEll PASS 25.39 seconds
BluezMake PASS 1704.84 seconds
MakeCheck PASS 21.99 seconds
MakeDistcheck PASS 193.14 seconds
CheckValgrind PASS 274.95 seconds
CheckSmatch PASS 356.90 seconds
bluezmakeextell PASS 120.03 seconds
IncrementalBuild PASS 11587.97 seconds
ScanBuild WARNING 1015.75 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,v2,5/7] obexd: Add GetImageProperties to bip-avrcp
WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#78:
[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c
WARNING:ONE_SEMICOLON: Statements terminations use 1 semicolon
#366: FILE: obexd/client/bip-common.c:132:
+ return g_ascii_strtoll(size, NULL, 10);;
/github/workspace/src/src/13802399.patch total: 0 errors, 2 warnings, 926 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/src/13802399.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v2,4/7] obexd: Add BIP client for AVRCP cover art download.
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
1: T3 Title has trailing punctuation (.): "[BlueZ,v2,4/7] obexd: Add BIP client for AVRCP cover art download."
[BlueZ,v2,5/7] obexd: Add GetImageProperties to bip-avrcp
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
10: B1 Line exceeds max length (95>80): "[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c"
##############################
Test: ScanBuild - WARNING
Desc: Run Scan Build
Output:
obexd/client/bip-avrcp.c:119:3: warning: Value stored to 'reply' is never read
reply = g_dbus_create_error(message,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obexd/client/bip-avrcp.c:141:9: warning: Access to field 'message' results in a dereference of a null pointer (loaded from variable 'err')
err->message);
^~~~~~~~~~~~
obexd/client/bip-avrcp.c:162:3: warning: Value stored to 'reply' is never read
reply = g_dbus_create_error(message,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obexd/client/bip-avrcp.c:181:9: warning: Access to field 'message' results in a dereference of a null pointer (loaded from variable 'err')
err->message);
^~~~~~~~~~~~
obexd/client/bip-avrcp.c:322:10: warning: Potential leak of memory pointed to by 'encoding'
reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
^~~~~~~~~~~~~~~~~~~
obexd/client/bip-avrcp.c:322:10: warning: Potential leak of memory pointed to by 'pixel'
reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
^~~~~~~~~~~~~~~~~~~
6 warnings generated.
profiles/audio/avrcp.c:1942:2: warning: Value stored to 'operands' is never read
operands += sizeof(*pdu);
^ ~~~~~~~~~~~~
1 warning generated.
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH BlueZ 1/7] obexd: Add PSM support to session create
@ 2024-09-04 14:04 Frédéric Danis
2024-09-04 17:22 ` Add BIP for AVRCP covert art OBEX client bluez.test.bot
0 siblings, 1 reply; 11+ messages in thread
From: Frédéric Danis @ 2024-09-04 14:04 UTC (permalink / raw)
To: linux-bluetooth
An OBEX session can be connected to a RFCOMM channel or a L2CAP PSM.
---
doc/org.bluez.obex.Client.rst | 4 ++++
doc/org.bluez.obex.Session.rst | 5 +++++
obexd/client/manager.c | 14 ++++++++++----
obexd/client/session.c | 27 ++++++++++++++++++++++++---
obexd/client/session.h | 1 +
5 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/doc/org.bluez.obex.Client.rst b/doc/org.bluez.obex.Client.rst
index 9f77a9abc..5ae7cc5e8 100644
--- a/doc/org.bluez.obex.Client.rst
+++ b/doc/org.bluez.obex.Client.rst
@@ -52,6 +52,10 @@ object CreateSession(string destination, dict args)
Channel to be used.
+ :uint16 PSM:
+
+ L2CAP PSM to be used.
+
Possible errors:
:org.bluez.obex.Error.InvalidArguments:
diff --git a/doc/org.bluez.obex.Session.rst b/doc/org.bluez.obex.Session.rst
index 1cef9a53d..fc5f14e5d 100644
--- a/doc/org.bluez.obex.Session.rst
+++ b/doc/org.bluez.obex.Session.rst
@@ -50,6 +50,11 @@ byte Channel [readonly]
Bluetooth channel
+uint16 PSM [readonly]
+```````````````````````
+
+ Bluetooth L2CAP PSM
+
string Target [readonly]
````````````````````````
diff --git a/obexd/client/manager.c b/obexd/client/manager.c
index ad1fbb04a..52c00fb0c 100644
--- a/obexd/client/manager.c
+++ b/obexd/client/manager.c
@@ -107,7 +107,8 @@ done:
}
static int parse_device_dict(DBusMessageIter *iter,
- const char **source, const char **target, uint8_t *channel)
+ const char **source, const char **target, uint8_t *channel,
+ uint16_t *psm)
{
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
DBusMessageIter entry, value;
@@ -130,6 +131,10 @@ static int parse_device_dict(DBusMessageIter *iter,
if (g_str_equal(key, "Channel") == TRUE)
dbus_message_iter_get_basic(&value, channel);
break;
+ case DBUS_TYPE_UINT16:
+ if (g_str_equal(key, "PSM") == TRUE)
+ dbus_message_iter_get_basic(&value, psm);
+ break;
}
dbus_message_iter_next(iter);
@@ -160,6 +165,7 @@ static DBusMessage *create_session(DBusConnection *connection,
struct send_data *data;
const char *source = NULL, *dest = NULL, *target = NULL;
uint8_t channel = 0;
+ uint16_t psm = 0;
dbus_message_iter_init(message, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -175,8 +181,8 @@ static DBusMessage *create_session(DBusConnection *connection,
dbus_message_iter_recurse(&iter, &dict);
- parse_device_dict(&dict, &source, &target, &channel);
- if (dest == NULL || target == NULL)
+ parse_device_dict(&dict, &source, &target, &channel, &psm);
+ if (dest == NULL || target == NULL || (channel && psm))
return g_dbus_create_error(message,
ERROR_INTERFACE ".InvalidArguments", NULL);
@@ -188,7 +194,7 @@ static DBusMessage *create_session(DBusConnection *connection,
data->connection = dbus_connection_ref(connection);
data->message = dbus_message_ref(message);
- session = obc_session_create(source, dest, target, channel,
+ session = obc_session_create(source, dest, target, channel, psm,
dbus_message_get_sender(message),
create_callback, data);
if (session != NULL) {
diff --git a/obexd/client/session.c b/obexd/client/session.c
index 7d8ebb04e..13a834e14 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
@@ -88,6 +88,7 @@ struct obc_session {
char *source;
char *destination;
uint8_t channel;
+ uint16_t psm;
struct obc_transport *transport;
struct obc_driver *driver;
char *path; /* Session path */
@@ -471,6 +472,7 @@ static struct obc_session *session_find(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner)
{
GSList *l;
@@ -490,6 +492,9 @@ static struct obc_session *session_find(const char *source,
if (channel && session->channel != channel)
continue;
+ if (psm && session->psm != psm)
+ continue;
+
if (g_strcmp0(owner, session->owner))
continue;
@@ -541,8 +546,9 @@ static int session_connect(struct obc_session *session,
}
session->id = transport->connect(session->source, session->destination,
- driver->uuid, session->channel,
- transport_func, callback);
+ driver->uuid,
+ session->channel ? session->channel : session->psm,
+ transport_func, callback);
if (session->id == 0) {
obc_session_unref(callback->session);
g_free(callback);
@@ -558,6 +564,7 @@ struct obc_session *obc_session_create(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner,
session_callback_t function,
void *user_data)
@@ -570,7 +577,8 @@ struct obc_session *obc_session_create(const char *source,
if (destination == NULL)
return NULL;
- session = session_find(source, destination, service, channel, owner);
+ session = session_find(source, destination, service, channel, psm,
+ owner);
if (session != NULL)
goto proceed;
@@ -598,6 +606,7 @@ struct obc_session *obc_session_create(const char *source,
session->source = g_strdup(source);
session->destination = g_strdup(destination);
session->channel = channel;
+ session->psm = psm;
session->queue = g_queue_new();
session->folder = g_strdup("/");
@@ -762,6 +771,17 @@ static gboolean get_channel(const GDBusPropertyTable *property,
return TRUE;
}
+static gboolean get_psm(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct obc_session *session = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
+ &session->psm);
+
+ return TRUE;
+}
+
static const GDBusMethodTable session_methods[] = {
{ GDBUS_ASYNC_METHOD("GetCapabilities",
NULL, GDBUS_ARGS({ "capabilities", "s" }),
@@ -794,6 +814,7 @@ static const GDBusPropertyTable session_properties[] = {
{ "Source", "s", get_source, NULL, source_exists },
{ "Destination", "s", get_destination },
{ "Channel", "y", get_channel },
+ { "PSM", "q", get_psm },
{ "Target", "s", get_target, NULL, target_exists },
{ }
};
diff --git a/obexd/client/session.h b/obexd/client/session.h
index 2c646df1a..19c3f3687 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
@@ -22,6 +22,7 @@ struct obc_session *obc_session_create(const char *source,
const char *destination,
const char *service,
uint8_t channel,
+ uint16_t psm,
const char *owner,
session_callback_t function,
void *user_data);
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* RE: Add BIP for AVRCP covert art OBEX client
2024-09-04 14:04 [PATCH BlueZ 1/7] obexd: Add PSM support to session create Frédéric Danis
@ 2024-09-04 17:22 ` bluez.test.bot
0 siblings, 0 replies; 11+ messages in thread
From: bluez.test.bot @ 2024-09-04 17:22 UTC (permalink / raw)
To: linux-bluetooth, frederic.danis
[-- Attachment #1: Type: text/plain, Size: 37596 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=886831
---Test result---
Test Summary:
CheckPatch FAIL 4.67 seconds
GitLint FAIL 2.43 seconds
BuildEll PASS 24.63 seconds
BluezMake FAIL 102.66 seconds
MakeCheck FAIL 2010.18 seconds
MakeDistcheck FAIL 65.90 seconds
CheckValgrind FAIL 76.06 seconds
CheckSmatch FAIL 190.07 seconds
bluezmakeextell FAIL 72.02 seconds
IncrementalBuild FAIL 7943.14 seconds
ScanBuild FAIL 727.96 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,5/7] obexd: Add GetImageProperties to bip-avrcp
WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#78:
[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c
/github/workspace/src/src/13790901.patch total: 0 errors, 1 warnings, 895 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/src/13790901.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,4/7] obexd: Add BIP client for AVRCP cover art download.
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
1: T3 Title has trailing punctuation (.): "[BlueZ,4/7] obexd: Add BIP client for AVRCP cover art download."
[BlueZ,5/7] obexd: Add GetImageProperties to bip-avrcp
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
10: B1 Line exceeds max length (95>80): "[2] https://github.com/enkait/Basic-Imaging-Profile-in-obexd/blob/gsoc_final/plugins/bip_util.c"
##############################
Test: BluezMake - FAIL
Desc: Build BlueZ
Output:
tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12725:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12725 | int main(int argc, char *argv[])
| ^~~~
obexd/client/bip-common.c: In function ‘parse_properties’:
obexd/client/bip-common.c:639:12: error: ‘EINVAL’ undeclared (first use in this function)
639 | *err = -EINVAL;
| ^~~~~~
obexd/client/bip-common.c:639:12: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [Makefile:9989: obexd/client/obexd-bip-common.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4685: 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[])
| ^~~~
obexd/client/bip-common.c: In function ‘parse_properties’:
obexd/client/bip-common.c:639:12: error: ‘EINVAL’ undeclared (first use in this function)
639 | *err = -EINVAL;
| ^~~~~~
obexd/client/bip-common.c:639:12: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [Makefile:9989: obexd/client/obexd-bip-common.o] Error 1
make: *** [Makefile:12348: check] Error 2
##############################
Test: MakeDistcheck - FAIL
Desc: Run Bluez Make Distcheck
Output:
Package cups was not found in the pkg-config search path.
Perhaps you should add the directory containing `cups.pc'
to the PKG_CONFIG_PATH environment variable
No package 'cups' found
../../obexd/client/bip-common.c: In function ‘parse_properties’:
../../obexd/client/bip-common.c:639:12: error: ‘EINVAL’ undeclared (first use in this function)
639 | *err = -EINVAL;
| ^~~~~~
../../obexd/client/bip-common.c:639:12: note: each undeclared identifier is reported only once for each function it appears in
make[2]: *** [Makefile:9989: obexd/client/obexd-bip-common.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [Makefile:4685: all] Error 2
make: *** [Makefile:12269: distcheck] Error 1
##############################
Test: CheckValgrind - FAIL
Desc: Run Bluez Make Check with Valgrind
Output:
tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12725:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12725 | int main(int argc, char *argv[])
| ^~~~
obexd/client/bip-common.c: In function ‘parse_properties’:
obexd/client/bip-common.c:639:12: error: ‘EINVAL’ undeclared (first use in this function)
639 | *err = -EINVAL;
| ^~~~~~
obexd/client/bip-common.c:639:12: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [Makefile:9989: obexd/client/obexd-bip-common.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:12348: 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:278:25: warning: Variable length array is used.
src/shared/gatt-server.c:618:25: warning: Variable length array is used.
src/shared/gatt-server.c:716:25: warning: Variable length array is used.
src/shared/bap.c:288:25: warning: array of flexible structures
src/shared/bap.c: note: in included file:
./src/shared/ascs.h:88:25: warning: array of flexible structures
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
src/shared/crypto.c:271:21: warning: Variable length array is used.
src/shared/crypto.c:272:23: warning: Variable length array is used.
src/shared/gatt-helpers.c:768:31: warning: Variable length array is used.
src/shared/gatt-helpers.c: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:278:25: warning: Variable length array is used.
src/shared/gatt-server.c:618:25: warning: Variable length array is used.
src/shared/gatt-server.c:716:25: warning: Variable length array is used.
src/shared/bap.c:288:25: warning: array of flexible structures
src/shared/bap.c: note: in included file:
./src/shared/ascs.h:88:25: warning: array of flexible structures
src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h):
/usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function'
/usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction'
/usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction'
/usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction'
tools/mesh-cfgtest.c:1453:17: warning: unknown escape sequence: '\%'
tools/sco-tester.c: note: in included file:
./lib/bluetooth.h:219:15: warning: array of flexible structures
./lib/bluetooth.h:224: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.
obexd/client/bip-common.c: In function ‘parse_properties’:
obexd/client/bip-common.c:639:12: error: ‘EINVAL’ undeclared (first use in this function)
639 | *err = -EINVAL;
| ^~~~~~
obexd/client/bip-common.c:639:12: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [Makefile:9989: obexd/client/obexd-bip-common.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4685: all] Error 2
##############################
Test: bluezmakeextell - FAIL
Desc: Build Bluez with External ELL
Output:
obexd/client/bip-common.c: In function ‘parse_properties’:
obexd/client/bip-common.c:639:12: error: ‘EINVAL’ undeclared (first use in this function)
639 | *err = -EINVAL;
| ^~~~~~
obexd/client/bip-common.c:639:12: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [Makefile:9989: obexd/client/obexd-bip-common.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4685: all] Error 2
##############################
Test: IncrementalBuild - FAIL
Desc: Incremental build with the patches in the series
Output:
[BlueZ,5/7] obexd: Add GetImageProperties to bip-avrcp
tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12725:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12725 | 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[])
| ^~~~
obexd/client/bip-common.c: In function ‘parse_properties’:
obexd/client/bip-common.c:620:12: error: ‘EINVAL’ undeclared (first use in this function)
620 | *err = -EINVAL;
| ^~~~~~
obexd/client/bip-common.c:620:12: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [Makefile:9988: obexd/client/obexd-bip-common.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4684: 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:996:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1102:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1296:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1361:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1636:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1641:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2145:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2153:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3242:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3264:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
12 warnings 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:996:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1102:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1296:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1361:2: warning: Use of memory after it is freed
discovery_op_complete(op, success, att_ecode);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1636:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1641:2: warning: Use of memory after it is freed
discover_all(op);
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2145:6: warning: Use of memory after it is freed
if (read_db_hash(op)) {
^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2153:8: warning: Use of memory after it is freed
discovery_op_ref(op),
^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3242:2: warning: Use of memory after it is freed
complete_write_long_op(req, success, 0, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3264:2: warning: Use of memory after it is freed
request_unref(req);
^~~~~~~~~~~~~~~~~~
12 warnings 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/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/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.
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.
src/sdp-client.c:353:14: warning: Access to field 'cb' results in a dereference of a null pointer
(*ctxt)->cb = cb;
~~~~~~~~~~~~^~~~
1 warning generated.
src/gatt-database.c:1155:10: warning: Value stored to 'bits' during its initialization is never read
uint8_t bits[] = { BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING,
^~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-header.c:67:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
memcpy(to, from, count);
^~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-transfer.c:423:7: warning: Use of memory after it is freed
if (!g_slist_find(transfers, transfer))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
obexd/client/bip-common.c: In function ‘parse_properties’:
obexd/client/bip-common.c:620:12: error: ‘EINVAL’ undeclared (first use in this function)
620 | *err = -EINVAL;
| ^~~~~~
obexd/client/bip-common.c:620:12: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [Makefile:9988: obexd/client/obexd-bip-common.o] Error 1
make[1]: *** Waiting for unfinished jobs....
obexd/client/bip-avrcp.c:111:3: warning: Value stored to 'reply' is never read
reply = g_dbus_create_error(message,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obexd/client/bip-avrcp.c:133:9: warning: Access to field 'message' results in a dereference of a null pointer (loaded from variable 'err')
err->message);
^~~~~~~~~~~~
obexd/client/bip-avrcp.c:154:3: warning: Value stored to 'reply' is never read
reply = g_dbus_create_error(message,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obexd/client/bip-avrcp.c:173:9: warning: Access to field 'message' results in a dereference of a null pointer (loaded from variable 'err')
err->message);
^~~~~~~~~~~~
4 warnings generated.
make: *** [Makefile:4684: all] Error 2
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-09-17 15:40 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-17 7:42 [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 1/5] obexd: Add BIP client for AVRCP cover art download Frédéric Danis
2024-09-17 11:31 ` Add BIP for AVRCP covert art OBEX client bluez.test.bot
2024-09-17 7:42 ` [PATCH BlueZ v4 2/5] obexd: Add Properties to org.bluez.obex.Image Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 3/5] obexd: Add Get " Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 4/5] avrcp: Update controller SDP record with cover art support Frédéric Danis
2024-09-17 7:42 ` [PATCH BlueZ v4 5/5] doc: Add description of org.bluez.obex.Image Frédéric Danis
2024-09-17 15:40 ` [PATCH BlueZ v4 0/5] Add BIP for AVRCP covert art OBEX client patchwork-bot+bluetooth
-- strict thread matches above, loose matches on Subject: below --
2024-09-16 13:28 [PATCH BlueZ v3 1/9] obexd: Add PSM support to session create Frédéric Danis
2024-09-16 18:47 ` Add BIP for AVRCP covert art OBEX client bluez.test.bot
2024-09-12 17:49 [PATCH BlueZ v2 1/7] obexd: Add PSM support to session create Frédéric Danis
2024-09-12 22:37 ` Add BIP for AVRCP covert art OBEX client bluez.test.bot
2024-09-04 14:04 [PATCH BlueZ 1/7] obexd: Add PSM support to session create Frédéric Danis
2024-09-04 17:22 ` Add BIP for AVRCP covert art OBEX client 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