summaryrefslogtreecommitdiff
path: root/futility/updater_dut.c
blob: 102859aeac458e1c511c0c31200b389a67c882ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* Copyright 2023 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * The DUT interface helper functions for the firmware updater.
 */

#include <assert.h>
#ifdef HAVE_CROSID
#include <crosid.h>
#endif
#include "crossystem.h"
#include "updater.h"

/**
 * dut_get_manifest_key() - Wrapper to get the firmware manifest key from crosid
 *
 * @manifest_key_out - Output parameter of the firmware manifest key.
 *
 * Returns:
 * - <0 if libcrosid is unavailable or there was an error reading
 *   device data
 * - >=0 (the matched device index) success
 */
int dut_get_manifest_key(char **manifest_key_out, struct updater_config *cfg)
{
	if (cfg->dut_is_remote) {
		WARN("Cannot retrieve the remote DUT manifest info. "
		     "Please specify the DUT type by --model.\n");
		return -1;
	}
#ifdef HAVE_CROSID
	return crosid_get_firmware_manifest_key(manifest_key_out);
#else
	ERROR("This version of futility was compiled without libcrosid "
	      "(perhaps compiled outside of the Chrome OS build system?) and "
	      "the update command is not fully supported.  Either compile "
	      "from the Chrome OS build, or pass --model to manually specify "
	      "the machine model.\n");
	return -1;
#endif
}

int dut_set_property_string(const char *key, const char *value,
			    struct updater_config *cfg)
{
	if (cfg->dut_is_remote) {
		WARN("Ignored setting property %s on a remote DUT.\n", key);
		return -1;
	}
	return VbSetSystemPropertyString(key, value);
}

const char *dut_get_property_string(const char *key, char *dest, size_t size,
				    struct updater_config *cfg)
{
	if (cfg->dut_is_remote) {
		WARN("Ignored getting property %s on a remote DUT.\n", key);
		return NULL;
	}
	return VbGetSystemPropertyString(key, dest, size);
}

int dut_set_property_int(const char *key, const int value,
			 struct updater_config *cfg)
{
	if (cfg->dut_is_remote) {
		WARN("Ignored setting property %s on a remote DUT.\n", key);
		return -1;
	}
	return VbSetSystemPropertyInt(key, value);
}

int dut_get_property_int(const char *key, struct updater_config *cfg)
{
	if (cfg->dut_is_remote) {
		WARN("Ignored getting property %s on a remote DUT.\n", key);
		return -1;
	}
	return VbGetSystemPropertyInt(key);
}

/* An helper function to return "mainfw_act" system property.  */
static int dut_get_mainfw_act(struct updater_config *cfg)
{
	char buf[VB_MAX_STRING_PROPERTY];

	if (!dut_get_property_string("mainfw_act", buf, sizeof(buf), cfg))
		return SLOT_UNKNOWN;

	if (strcmp(buf, FWACT_A) == 0)
		return SLOT_A;
	else if (strcmp(buf, FWACT_B) == 0)
		return SLOT_B;

	return SLOT_UNKNOWN;
}

/* A helper function to return the "tpm_fwver" system property. */
static int dut_get_tpm_fwver(struct updater_config *cfg)
{
	return dut_get_property_int("tpm_fwver", cfg);
}

/* A helper function to return the "hardware write protection" status. */
static int dut_get_wp_hw(struct updater_config *cfg)
{
	/* wpsw refers to write protection 'switch', not 'software'. */
	return dut_get_property_int("wpsw_cur", cfg) ? WP_ENABLED : WP_DISABLED;
}

static int dut_get_platform_version(struct updater_config *cfg)
{
	return dut_get_property_int("board_id", cfg);
}

/* Helper function to return host software write protection status. */
static int dut_get_wp_sw(struct updater_config *cfg)
{
	assert(cfg->image.programmer);
	return flashrom_get_wp(cfg->image.programmer, -1);
}

/* Helper functions to use or configure the DUT properties. */

/*
 * Gets the DUT system property by given type.
 * If the property was not loaded yet, invoke the property getter function
 * and cache the result.
 * Returns the property value.
 */
int dut_get_property(enum dut_property_type property_type,
		     struct updater_config *cfg)
{
	struct dut_property *prop;

	assert(property_type < DUT_PROP_MAX);
	prop = &cfg->dut_properties[property_type];
	if (!prop->initialized) {
		prop->initialized = 1;
		prop->value = prop->getter(cfg);
	}
	return prop->value;
}

void dut_init_properties(struct dut_property *props, int num)
{
	memset(props, 0, num * sizeof(*props));
	assert(num >= DUT_PROP_MAX);
	props[DUT_PROP_MAINFW_ACT].getter = dut_get_mainfw_act;
	props[DUT_PROP_TPM_FWVER].getter = dut_get_tpm_fwver;
	props[DUT_PROP_PLATFORM_VER].getter = dut_get_platform_version;
	props[DUT_PROP_WP_HW].getter = dut_get_wp_hw;
	props[DUT_PROP_WP_SW].getter = dut_get_wp_sw;
}