blob: 8d721e21df4ba2df6008df24d0726cf7ed680b08 [file] [log] [blame]
// 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:
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);
}