bluez/client/print.c
Luiz Augusto von Dentz b22859e3cc client/print: Add decoding for UUID properties
This adds proper decoding for UUID properties with usage of
bt_uuidstr_to_str so it can print the 'friendly' name as bellow:

bluetoothctl# transport.show /org/bluez/hci0/dev_94_DB_56_F7_F2_88/sep4/fd0
Transport /org/bluez/hci0/dev_94_DB_56_F7_F2_88/sep4/fd0
	UUID: Audio Source              (0000110a-0000-1000-8000-00805f9b34fb)
...
2024-09-18 15:26:18 -04:00

239 lines
5.4 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2020 Intel Corporation. All rights reserved.
*
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include "gdbus/gdbus.h"
#include "src/shared/util.h"
#include "src/shared/shell.h"
#include "print.h"
static void print_fixed_iter(const char *label, const char *name,
DBusMessageIter *iter)
{
dbus_bool_t *valbool;
dbus_uint32_t *valu32;
dbus_uint16_t *valu16;
dbus_int16_t *vals16;
unsigned char *byte;
int len;
switch (dbus_message_iter_get_arg_type(iter)) {
case DBUS_TYPE_BOOLEAN:
dbus_message_iter_get_fixed_array(iter, &valbool, &len);
if (len <= 0)
return;
bt_shell_printf("%s%s:\n", label, name);
bt_shell_hexdump((void *)valbool, len * sizeof(*valbool));
break;
case DBUS_TYPE_UINT32:
dbus_message_iter_get_fixed_array(iter, &valu32, &len);
if (len <= 0)
return;
bt_shell_printf("%s%s:\n", label, name);
bt_shell_hexdump((void *)valu32, len * sizeof(*valu32));
break;
case DBUS_TYPE_UINT16:
dbus_message_iter_get_fixed_array(iter, &valu16, &len);
if (len <= 0)
return;
bt_shell_printf("%s%s:\n", label, name);
bt_shell_hexdump((void *)valu16, len * sizeof(*valu16));
break;
case DBUS_TYPE_INT16:
dbus_message_iter_get_fixed_array(iter, &vals16, &len);
if (len <= 0)
return;
bt_shell_printf("%s%s:\n", label, name);
bt_shell_hexdump((void *)vals16, len * sizeof(*vals16));
break;
case DBUS_TYPE_BYTE:
dbus_message_iter_get_fixed_array(iter, &byte, &len);
if (len <= 0)
return;
bt_shell_printf("%s%s:\n", label, name);
bt_shell_hexdump((void *)byte, len * sizeof(*byte));
break;
default:
return;
};
}
void print_iter(const char *label, const char *name, DBusMessageIter *iter)
{
dbus_bool_t valbool;
dbus_uint32_t valu32;
dbus_uint16_t valu16;
dbus_int16_t vals16;
unsigned char byte;
const char *valstr;
DBusMessageIter subiter;
char *entry;
if (iter == NULL) {
bt_shell_printf("%s%s is nil\n", label, name);
return;
}
switch (dbus_message_iter_get_arg_type(iter)) {
case DBUS_TYPE_INVALID:
bt_shell_printf("%s%s is invalid\n", label, name);
break;
case DBUS_TYPE_STRING:
if (!strcasecmp(name, "UUID")) {
dbus_message_iter_get_basic(iter, &valstr);
print_uuid(label, name, valstr);
break;
}
/* fall through */
case DBUS_TYPE_OBJECT_PATH:
dbus_message_iter_get_basic(iter, &valstr);
bt_shell_printf("%s%s: %s\n", label, name, valstr);
break;
case DBUS_TYPE_BOOLEAN:
dbus_message_iter_get_basic(iter, &valbool);
bt_shell_printf("%s%s: %s\n", label, name,
valbool == TRUE ? "yes" : "no");
break;
case DBUS_TYPE_UINT32:
dbus_message_iter_get_basic(iter, &valu32);
bt_shell_printf("%s%s: 0x%08x (%d)\n", label, name, valu32,
valu32);
break;
case DBUS_TYPE_UINT16:
dbus_message_iter_get_basic(iter, &valu16);
bt_shell_printf("%s%s: 0x%04x (%d)\n", label, name, valu16,
valu16);
break;
case DBUS_TYPE_INT16:
dbus_message_iter_get_basic(iter, &vals16);
bt_shell_printf("%s%s: 0x%04x (%d)\n", label, name, vals16,
vals16);
break;
case DBUS_TYPE_BYTE:
dbus_message_iter_get_basic(iter, &byte);
bt_shell_printf("%s%s: 0x%02x (%d)\n", label, name, byte, byte);
break;
case DBUS_TYPE_VARIANT:
dbus_message_iter_recurse(iter, &subiter);
print_iter(label, name, &subiter);
break;
case DBUS_TYPE_ARRAY:
dbus_message_iter_recurse(iter, &subiter);
if (dbus_type_is_fixed(
dbus_message_iter_get_arg_type(&subiter))) {
print_fixed_iter(label, name, &subiter);
break;
}
while (dbus_message_iter_get_arg_type(&subiter) !=
DBUS_TYPE_INVALID) {
print_iter(label, name, &subiter);
dbus_message_iter_next(&subiter);
}
break;
case DBUS_TYPE_DICT_ENTRY:
dbus_message_iter_recurse(iter, &subiter);
if (dbus_message_iter_get_arg_type(&subiter) ==
DBUS_TYPE_STRING) {
dbus_message_iter_get_basic(&subiter, &valstr);
entry = g_strconcat(name, ".", valstr, NULL);
} else {
entry = g_strconcat(name, ".Key", NULL);
print_iter(label, entry, &subiter);
g_free(entry);
entry = g_strconcat(name, ".Value", NULL);
}
dbus_message_iter_next(&subiter);
print_iter(label, entry, &subiter);
g_free(entry);
break;
default:
bt_shell_printf("%s%s has unsupported type\n", label, name);
break;
}
}
void print_property_with_label(GDBusProxy *proxy, const char *name,
const char *label)
{
DBusMessageIter iter;
if (g_dbus_proxy_get_property(proxy, name, &iter) == FALSE)
return;
print_iter("\t", label ? label : name, &iter);
}
void print_property(GDBusProxy *proxy, const char *name)
{
print_property_with_label(proxy, name, NULL);
}
void print_uuid(const char *label, const char *name, const char *uuid)
{
const char *text;
text = bt_uuidstr_to_str(uuid);
if (text) {
char str[26];
unsigned int n;
str[sizeof(str) - 1] = '\0';
n = snprintf(str, sizeof(str), "%s", text);
if (n > sizeof(str) - 1) {
str[sizeof(str) - 2] = '.';
str[sizeof(str) - 3] = '.';
if (str[sizeof(str) - 4] == ' ')
str[sizeof(str) - 4] = '.';
n = sizeof(str) - 1;
}
bt_shell_printf("%s%s: %s%*c(%s)\n", label, name, str, 26 - n,
' ', uuid);
} else
bt_shell_printf("%s%s: %*c(%s)\n", label, name, 26, ' ', uuid);
}