// 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 #endif #define _GNU_SOURCE #include #include #include #include #include #include #include #include #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: 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\n", label, name, valu32); break; case DBUS_TYPE_UINT16: dbus_message_iter_get_basic(iter, &valu16); bt_shell_printf("%s%s: 0x%04x\n", label, name, valu16); break; case DBUS_TYPE_INT16: dbus_message_iter_get_basic(iter, &vals16); bt_shell_printf("%s%s: %d\n", label, name, 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); 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); }