/src/fwupd/plugins/pixart-rf/fu-pixart-rf-common.c
Line | Count | Source |
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-pixart-rf-common.h" |
11 | | #include "fu-pixart-rf-struct.h" |
12 | | |
13 | | void |
14 | | fu_pixart_rf_ota_fw_state_to_string(FuPixartRfOtaFwState *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_pixart_rf_ota_spec_check_result_to_string(fwstate->spec_check_result)); |
31 | 0 | } |
32 | | |
33 | | gboolean |
34 | | fu_pixart_rf_ota_fw_state_parse(FuPixartRfOtaFwState *fwstate, |
35 | | const guint8 *buf, |
36 | | gsize bufsz, |
37 | | gsize offset, |
38 | | GError **error) |
39 | 0 | { |
40 | 0 | g_autoptr(FuStructPixartRfOtaFwState) st = NULL; |
41 | |
|
42 | 0 | st = fu_struct_pixart_rf_ota_fw_state_parse(buf, bufsz, offset, error); |
43 | 0 | if (st == NULL) |
44 | 0 | return FALSE; |
45 | 0 | fwstate->status = fu_struct_pixart_rf_ota_fw_state_get_status(st); |
46 | 0 | fwstate->new_flow = fu_struct_pixart_rf_ota_fw_state_get_new_flow(st); |
47 | 0 | fwstate->offset = fu_struct_pixart_rf_ota_fw_state_get_offset(st); |
48 | 0 | fwstate->checksum = fu_struct_pixart_rf_ota_fw_state_get_checksum(st); |
49 | 0 | fwstate->max_object_size = fu_struct_pixart_rf_ota_fw_state_get_max_object_size(st); |
50 | 0 | fwstate->mtu_size = fu_struct_pixart_rf_ota_fw_state_get_mtu_size(st); |
51 | 0 | fwstate->prn_threshold = fu_struct_pixart_rf_ota_fw_state_get_prn_threshold(st); |
52 | 0 | fwstate->spec_check_result = fu_struct_pixart_rf_ota_fw_state_get_spec_check_result(st); |
53 | | |
54 | | /* success */ |
55 | 0 | return TRUE; |
56 | 0 | } |
57 | | gboolean |
58 | | fu_pixart_rf_composite_receiver_cmd(guint8 opcode, |
59 | | guint8 sn, |
60 | | guint8 target, |
61 | | GByteArray *wireless_mod_cmd, |
62 | | GByteArray *ota_cmd, |
63 | | GError **error) |
64 | 0 | { |
65 | 0 | guint8 checksum = 0x0; |
66 | 0 | guint8 hid_sn = sn; |
67 | 0 | guint8 len = 0x0; |
68 | 0 | guint8 ota_sn = sn + 1; |
69 | 0 | guint8 rf_cmd_code = FU_PIXART_RF_BLE_DEVICE_RF_CMD_CODE; |
70 | 0 | guint8 rid = PIXART_RF_HID_WIRELESS_DEV_OTA_REPORT_ID; |
71 | |
|
72 | 0 | if (ota_cmd == NULL) { |
73 | 0 | g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "ota cmd is NULL"); |
74 | 0 | return FALSE; |
75 | 0 | } |
76 | | |
77 | | /* append ota dispatch header */ |
78 | 0 | fu_byte_array_append_uint8(wireless_mod_cmd, opcode); /* wireless module ota op code */ |
79 | 0 | fu_byte_array_append_uint8(wireless_mod_cmd, ota_sn); /* wireless module ota command sn */ |
80 | | |
81 | | /* append ota command length and content */ |
82 | 0 | for (guint idx = 0; idx < ota_cmd->len; idx++) |
83 | 0 | fu_byte_array_append_uint8(wireless_mod_cmd, ota_cmd->data[idx]); |
84 | | |
85 | | /* append target of wireless module and hid command serial number */ |
86 | 0 | g_byte_array_prepend(wireless_mod_cmd, &target, 0x01); /* target */ |
87 | 0 | g_byte_array_prepend(wireless_mod_cmd, &hid_sn, 0x01); /* hid command sn */ |
88 | | |
89 | | /* prepend length and rf command code, the param len not include "hid_sn" byte and "target" |
90 | | * byte */ |
91 | 0 | len = wireless_mod_cmd->len - 2; |
92 | 0 | g_byte_array_prepend(wireless_mod_cmd, &len, 0x01); |
93 | 0 | g_byte_array_prepend(wireless_mod_cmd, &rf_cmd_code, 0x01); /* command code */ |
94 | | |
95 | | /* prepend checksum */ |
96 | 0 | checksum = fu_sum8(wireless_mod_cmd->data, wireless_mod_cmd->len); |
97 | 0 | g_byte_array_prepend(wireless_mod_cmd, &checksum, 0x01); |
98 | | |
99 | | /* prepend feature report id */ |
100 | 0 | g_byte_array_prepend(wireless_mod_cmd, &rid, 0x01); |
101 | 0 | return TRUE; |
102 | 0 | } |
103 | | |
104 | | gchar * |
105 | | fu_pixart_rf_hpac_version_info_parse(const guint16 hpac_ver) |
106 | 0 | { |
107 | 0 | return g_strdup_printf("%u%u.%u%u.%u", |
108 | 0 | (guint)(hpac_ver / 10000), |
109 | 0 | (guint)((hpac_ver / 1000) % 10), |
110 | 0 | (guint)((hpac_ver / 100) % 10), |
111 | 0 | (guint)((hpac_ver / 10) % 10), |
112 | 0 | (guint)(hpac_ver % 10)); |
113 | 0 | } |