/src/fwupd/plugins/pixart-rf/fu-pxi-common.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2021 Jimmy Yu <Jimmy_yu@pixart.com> |
3 | | * Copyright 2021 Richard Hughes <richard@hughsie.com> |
4 | | * |
5 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
6 | | */ |
7 | | |
8 | | #include "config.h" |
9 | | |
10 | | #include "fu-pxi-common.h" |
11 | | #include "fu-pxi-struct.h" |
12 | | |
13 | | void |
14 | | fu_pxi_ota_fw_state_to_string(struct ota_fw_state *fwstate, guint idt, GString *str) |
15 | 0 | { |
16 | 0 | fwupd_codec_string_append_hex(str, idt, "Status", fwstate->status); |
17 | 0 | fwupd_codec_string_append_hex(str, idt, "NewFlow", fwstate->new_flow); |
18 | 0 | fwupd_codec_string_append_hex(str, idt, "CurrentObjectOffset", fwstate->offset); |
19 | 0 | fwupd_codec_string_append_hex(str, idt, "CurrentChecksum", fwstate->checksum); |
20 | 0 | fwupd_codec_string_append_hex(str, idt, "MaxObjectSize", fwstate->max_object_size); |
21 | 0 | fwupd_codec_string_append_hex(str, idt, "MtuSize", fwstate->mtu_size); |
22 | 0 | fwupd_codec_string_append_hex(str, |
23 | 0 | idt, |
24 | 0 | "PacketReceiptNotificationThreshold", |
25 | 0 | fwstate->prn_threshold); |
26 | 0 | fwupd_codec_string_append( |
27 | 0 | str, |
28 | 0 | idt, |
29 | 0 | "SpecCheckResult", |
30 | 0 | fu_pxi_ota_spec_check_result_to_string(fwstate->spec_check_result)); |
31 | 0 | } |
32 | | |
33 | | gboolean |
34 | | fu_pxi_ota_fw_state_parse(struct ota_fw_state *fwstate, |
35 | | const guint8 *buf, |
36 | | gsize bufsz, |
37 | | gsize offset, |
38 | | GError **error) |
39 | 0 | { |
40 | 0 | if (!fu_memread_uint8_safe(buf, bufsz, offset + 0x00, &fwstate->status, error)) |
41 | 0 | return FALSE; |
42 | 0 | if (!fu_memread_uint8_safe(buf, bufsz, offset + 0x01, &fwstate->new_flow, error)) |
43 | 0 | return FALSE; |
44 | 0 | if (!fu_memread_uint16_safe(buf, |
45 | 0 | bufsz, |
46 | 0 | offset + 0x2, |
47 | 0 | &fwstate->offset, |
48 | 0 | G_LITTLE_ENDIAN, |
49 | 0 | error)) |
50 | 0 | return FALSE; |
51 | 0 | if (!fu_memread_uint16_safe(buf, |
52 | 0 | bufsz, |
53 | 0 | offset + 0x4, |
54 | 0 | &fwstate->checksum, |
55 | 0 | G_LITTLE_ENDIAN, |
56 | 0 | error)) |
57 | 0 | return FALSE; |
58 | 0 | if (!fu_memread_uint32_safe(buf, |
59 | 0 | bufsz, |
60 | 0 | offset + 0x06, |
61 | 0 | &fwstate->max_object_size, |
62 | 0 | G_LITTLE_ENDIAN, |
63 | 0 | error)) |
64 | 0 | return FALSE; |
65 | 0 | if (!fu_memread_uint16_safe(buf, |
66 | 0 | bufsz, |
67 | 0 | offset + 0x0A, |
68 | 0 | &fwstate->mtu_size, |
69 | 0 | G_LITTLE_ENDIAN, |
70 | 0 | error)) |
71 | 0 | return FALSE; |
72 | 0 | if (!fu_memread_uint16_safe(buf, |
73 | 0 | bufsz, |
74 | 0 | offset + 0x0C, |
75 | 0 | &fwstate->prn_threshold, |
76 | 0 | G_LITTLE_ENDIAN, |
77 | 0 | error)) |
78 | 0 | return FALSE; |
79 | 0 | if (!fu_memread_uint8_safe(buf, bufsz, offset + 0x0E, &fwstate->spec_check_result, error)) |
80 | 0 | return FALSE; |
81 | | |
82 | | /* success */ |
83 | 0 | return TRUE; |
84 | 0 | } |
85 | | gboolean |
86 | | fu_pxi_composite_receiver_cmd(guint8 opcode, |
87 | | guint8 sn, |
88 | | guint8 target, |
89 | | GByteArray *wireless_mod_cmd, |
90 | | GByteArray *ota_cmd, |
91 | | GError **error) |
92 | 0 | { |
93 | 0 | guint8 checksum = 0x0; |
94 | 0 | guint8 hid_sn = sn; |
95 | 0 | guint8 len = 0x0; |
96 | 0 | guint8 ota_sn = sn + 1; |
97 | 0 | guint8 rf_cmd_code = FU_PXI_BLE_DEVICE_RF_CMD_CODE; |
98 | 0 | guint8 rid = PXI_HID_WIRELESS_DEV_OTA_REPORT_ID; |
99 | |
|
100 | 0 | if (ota_cmd == NULL) { |
101 | 0 | g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "ota cmd is NULL"); |
102 | 0 | return FALSE; |
103 | 0 | } |
104 | | |
105 | | /* append ota dispatch header */ |
106 | 0 | fu_byte_array_append_uint8(wireless_mod_cmd, opcode); /* wireless module ota op code */ |
107 | 0 | fu_byte_array_append_uint8(wireless_mod_cmd, ota_sn); /* wireless module ota command sn */ |
108 | | |
109 | | /* append ota command length and content */ |
110 | 0 | for (guint idx = 0; idx < ota_cmd->len; idx++) |
111 | 0 | fu_byte_array_append_uint8(wireless_mod_cmd, ota_cmd->data[idx]); |
112 | | |
113 | | /* append target of wireless module and hid command serial number */ |
114 | 0 | g_byte_array_prepend(wireless_mod_cmd, &target, 0x01); /* target */ |
115 | 0 | g_byte_array_prepend(wireless_mod_cmd, &hid_sn, 0x01); /* hid command sn */ |
116 | | |
117 | | /* prepend length and rf command code, the param len not include "hid_sn" byte and "target" |
118 | | * byte */ |
119 | 0 | len = wireless_mod_cmd->len - 2; |
120 | 0 | g_byte_array_prepend(wireless_mod_cmd, &len, 0x01); |
121 | 0 | g_byte_array_prepend(wireless_mod_cmd, &rf_cmd_code, 0x01); /* command code */ |
122 | | |
123 | | /* prepend checksum */ |
124 | 0 | checksum = fu_sum8(wireless_mod_cmd->data, wireless_mod_cmd->len); |
125 | 0 | g_byte_array_prepend(wireless_mod_cmd, &checksum, 0x01); |
126 | | |
127 | | /* prepend feature report id */ |
128 | 0 | g_byte_array_prepend(wireless_mod_cmd, &rid, 0x01); |
129 | 0 | return TRUE; |
130 | 0 | } |
131 | | |
132 | | gchar * |
133 | | fu_pxi_hpac_version_info_parse(const guint16 hpac_ver) |
134 | 22 | { |
135 | 22 | return g_strdup_printf("%u%u.%u%u.%u", |
136 | 22 | (guint)(hpac_ver / 10000), |
137 | 22 | (guint)((hpac_ver / 1000) % 10), |
138 | 22 | (guint)((hpac_ver / 100) % 10), |
139 | 22 | (guint)((hpac_ver / 10) % 10), |
140 | 22 | (guint)(hpac_ver % 10)); |
141 | 22 | } |