Coverage Report

Created: 2026-03-11 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/libfwupdplugin/fu-usb-hid-descriptor.c
Line
Count
Source
1
/*
2
 * Copyright 2024 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
/**
8
 * FuUsbHidDescriptor:
9
 *
10
 * This object is a placeholder for the HID descriptor, and is populated with data after the
11
 * device has been opened.
12
 */
13
14
#include "config.h"
15
16
#include "fu-usb-hid-descriptor-private.h"
17
18
struct _FuUsbHidDescriptor {
19
  FuUsbDescriptor parent_instance;
20
  guint8 iface_number;
21
  gsize descriptor_length;
22
  GBytes *blob;
23
};
24
25
static void
26
fu_usb_hid_descriptor_codec_iface_init(FwupdCodecInterface *iface);
27
28
123k
G_DEFINE_TYPE_EXTENDED(FuUsbHidDescriptor,
29
123k
           fu_usb_hid_descriptor,
30
123k
           FU_TYPE_USB_DESCRIPTOR,
31
123k
           0,
32
123k
           G_IMPLEMENT_INTERFACE(FWUPD_TYPE_CODEC,
33
123k
               fu_usb_hid_descriptor_codec_iface_init));
34
123k
35
123k
static gboolean
36
123k
fu_usb_hid_descriptor_from_json(FwupdCodec *codec, FwupdJsonObject *json_obj, GError **error)
37
123k
{
38
0
  FuUsbHidDescriptor *self = FU_USB_HID_DESCRIPTOR(codec);
39
0
  const gchar *tmp;
40
41
0
  tmp = fwupd_json_object_get_string(json_obj, "Data", NULL);
42
0
  if (tmp != NULL) {
43
0
    gsize bufsz = 0;
44
0
    g_autofree guchar *buf = g_base64_decode(tmp, &bufsz);
45
0
    g_autoptr(GBytes) blob = g_bytes_new_take(g_steal_pointer(&buf), bufsz);
46
0
    fu_usb_hid_descriptor_set_blob(self, blob);
47
0
  }
48
49
  /* success */
50
0
  return TRUE;
51
0
}
52
53
static void
54
fu_usb_hid_descriptor_add_json(FwupdCodec *codec, FwupdJsonObject *json_obj, FwupdCodecFlags flags)
55
0
{
56
0
  FuUsbHidDescriptor *self = FU_USB_HID_DESCRIPTOR(codec);
57
0
  g_autofree gchar *str = NULL;
58
59
0
  if (self->blob == NULL)
60
0
    return;
61
0
  str = g_base64_encode(g_bytes_get_data(self->blob, NULL), g_bytes_get_size(self->blob));
62
0
  fwupd_json_object_add_string(json_obj, "Data", str);
63
0
}
64
65
/**
66
 * fu_usb_hid_descriptor_get_iface_number:
67
 * @self: a #FuUsbHidDescriptor
68
 *
69
 * Gets the hid descriptor interface number.
70
 *
71
 * Return value: integer
72
 *
73
 * Since: 2.0.2
74
 **/
75
guint8
76
fu_usb_hid_descriptor_get_iface_number(FuUsbHidDescriptor *self)
77
0
{
78
0
  g_return_val_if_fail(FU_IS_USB_HID_DESCRIPTOR(self), 0);
79
0
  return self->iface_number;
80
0
}
81
82
/**
83
 * fu_usb_hid_descriptor_set_iface_number:
84
 * @self: a #FuUsbHidDescriptor
85
 *
86
 * Sets the hid descriptor interface number.
87
 *
88
 * Since: 2.0.2
89
 **/
90
void
91
fu_usb_hid_descriptor_set_iface_number(FuUsbHidDescriptor *self, guint8 iface_number)
92
28.8k
{
93
28.8k
  g_return_if_fail(FU_IS_USB_HID_DESCRIPTOR(self));
94
28.8k
  self->iface_number = iface_number;
95
28.8k
}
96
97
/**
98
 * fu_usb_hid_descriptor_get_descriptor_length:
99
 * @self: a #FuUsbHidDescriptor
100
 *
101
 * Gets the HID descriptor length.
102
 *
103
 * Return value: integer
104
 *
105
 * Since: 2.0.2
106
 **/
107
gsize
108
fu_usb_hid_descriptor_get_descriptor_length(FuUsbHidDescriptor *self)
109
0
{
110
0
  g_return_val_if_fail(FU_IS_USB_HID_DESCRIPTOR(self), 0);
111
0
  return self->descriptor_length;
112
0
}
113
114
/**
115
 * fu_usb_hid_descriptor_get_blob:
116
 * @self: a #FuUsbHidDescriptor
117
 *
118
 * Gets the HID descriptor binary blob.
119
 *
120
 * Return value: (transfer none): The descriptor data
121
 *
122
 * Since: 2.0.2
123
 **/
124
GBytes *
125
fu_usb_hid_descriptor_get_blob(FuUsbHidDescriptor *self)
126
0
{
127
0
  g_return_val_if_fail(FU_IS_USB_HID_DESCRIPTOR(self), NULL);
128
0
  return self->blob;
129
0
}
130
131
/**
132
 * fu_usb_hid_descriptor_set_blob:
133
 * @self: a #FuUsbHidDescriptor
134
 *
135
 * Sets the HID descriptor binary blob.
136
 *
137
 * Since: 2.0.2
138
 **/
139
void
140
fu_usb_hid_descriptor_set_blob(FuUsbHidDescriptor *self, GBytes *blob)
141
0
{
142
0
  g_return_if_fail(FU_IS_USB_HID_DESCRIPTOR(self));
143
0
  if (self->blob != NULL)
144
0
    g_bytes_unref(self->blob);
145
0
  self->blob = g_bytes_ref(blob);
146
0
}
147
148
static gboolean
149
fu_usb_hid_descriptor_parse(FuFirmware *firmware,
150
          GInputStream *stream,
151
          FuFirmwareParseFlags flags,
152
          GError **error)
153
31.6k
{
154
31.6k
  FuUsbHidDescriptor *self = FU_USB_HID_DESCRIPTOR(firmware);
155
31.6k
  g_autoptr(FuUsbHidDescriptorHdr) st = NULL;
156
157
  /* parse */
158
31.6k
  st = fu_usb_hid_descriptor_hdr_parse_stream(stream, 0x0, error);
159
31.6k
  if (st == NULL)
160
16
    return FALSE;
161
31.6k
  self->descriptor_length = fu_usb_hid_descriptor_hdr_get_class_descriptor_length(st);
162
163
  /* success */
164
31.6k
  return TRUE;
165
31.6k
}
166
167
static void
168
fu_usb_hid_descriptor_codec_iface_init(FwupdCodecInterface *iface)
169
1
{
170
1
  iface->add_json = fu_usb_hid_descriptor_add_json;
171
1
  iface->from_json = fu_usb_hid_descriptor_from_json;
172
1
}
173
174
static void
175
fu_usb_hid_descriptor_init(FuUsbHidDescriptor *self)
176
31.6k
{
177
31.6k
}
178
179
static void
180
fu_usb_hid_descriptor_finalize(GObject *object)
181
31.6k
{
182
31.6k
  FuUsbHidDescriptor *self = FU_USB_HID_DESCRIPTOR(object);
183
31.6k
  if (self->blob != NULL)
184
0
    g_bytes_unref(self->blob);
185
31.6k
  G_OBJECT_CLASS(fu_usb_hid_descriptor_parent_class)->finalize(object);
186
31.6k
}
187
188
static void
189
fu_usb_hid_descriptor_class_init(FuUsbHidDescriptorClass *klass)
190
1
{
191
1
  GObjectClass *object_class = G_OBJECT_CLASS(klass);
192
1
  FuFirmwareClass *firmware_class = FU_FIRMWARE_CLASS(klass);
193
1
  object_class->finalize = fu_usb_hid_descriptor_finalize;
194
1
  firmware_class->parse = fu_usb_hid_descriptor_parse;
195
1
}