blob: 036b678c20dcc0276758fdddf93b3aac6c84c005 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fidl/fuchsia.hardware.adc/cpp/wire.h>
#include <fidl/fuchsia.hardware.temperature/cpp/wire.h>
#include <fidl/fuchsia.hardware.trippoint/cpp/wire.h>
#include <lib/fdio/directory.h>
#include <stdio.h>
#include <string.h>
constexpr char kUsageMessage[] = R"""(Usage: temperature-cli <device> <command>
resolution - Get adc resolution (for adc class device)
read - read adc sample (for adc class device)
readnorm - read normalized adc sample [0.0-1.0] (for adc class device)
trippoint - Get/set trippoint. Follow with multiple sets of index:type,configuration.
No spaces allowed.
index must be an integer.
type is allowed to be "above", "below".
configuration can be a float, interpreted as temperature in celsius, or "cleared".
wait - Wait for a trippoint to be triggered
name - Get sensor name (for temperature class device)
trip - Use debug service to trip a trippoint
Example:
temperature-cli /svc/fuchsia.hardware.temperature/<instance_name>/<ServiceMemberName>
temperature-cli /svc/fuchsia.hardware.temperature/<instance_name>/<ServiceMemberName> name
- or -
temperature-cli /dev/class/adc/000 read
temperature-cli /dev/class/adc/000 resolution
- or -
temperature-cli /svc/fuchsia.hardware.trippoint.Service/<instance_name>/<ServiceMemberName> trippoint
temperature-cli /svc/fuchsia.hardware.trippoint.Service/<instance_name>/<ServiceMemberName> trippoint 0:below,4.2 1:above,50.1 2:above,cleared
temperature-cli /svc/fuchsia.hardware.trippoint.Service/<instance_name>/<ServiceMemberName> wait
temperature-cli /svc/fuchsia.hardware.trippoint.Service/<instance_name>/<ServiceMemberName> name
- or -
temperature-cli /svc/fuchsia.hardware.trippoint.DebugService/<instance_name>/<ServiceMemberName> trip 1
)""";
namespace FidlTemperature = fuchsia_hardware_temperature;
namespace FidlAdc = fuchsia_hardware_adc;
namespace FidlTrippoint = fuchsia_hardware_trippoint;
std::string ToString(const FidlTrippoint::wire::TripPointType& type) {
switch (type) {
case FidlTrippoint::TripPointType::kOneshotTempAbove:
return "OneshotTempAbove";
case FidlTrippoint::TripPointType::kOneshotTempBelow:
return "OneshotTempBelow";
default:
return "Unknown";
}
}
std::string ToString(const FidlTrippoint::wire::TripPointValue& value) {
switch (value.Which()) {
case FidlTrippoint::wire::TripPointValue::Tag::kClearedTripPoint:
return "ClearedTripPoint";
case FidlTrippoint::wire::TripPointValue::Tag::kOneshotTempAboveTripPoint:
return "OneshotTempAboveTripPoint(" +
std::to_string(value.oneshot_temp_above_trip_point().critical_temperature_celsius) +
")";
case FidlTrippoint::wire::TripPointValue::Tag::kOneshotTempBelowTripPoint:
return "OneshotTempBelowTripPoint(" +
std::to_string(value.oneshot_temp_below_trip_point().critical_temperature_celsius) +
")";
default:
return "Unknown";
}
}
void print_trippoint(
const fidl::VectorView<FidlTrippoint::wire::TripPointDescriptor>& descriptors) {
for (const auto& trippoint : descriptors) {
printf("{\n");
printf(" .index = %d,\n", trippoint.index);
printf(" .type = %s,\n", ToString(trippoint.type).c_str());
printf(" .configuration = %s,\n", ToString(trippoint.configuration).c_str());
printf("},\n");
}
}
std::vector<FidlTrippoint::wire::TripPointDescriptor> parse_set_trippoints_args(int argc,
char** argv) {
assert(argc > 3);
std::vector<FidlTrippoint::wire::TripPointDescriptor> descriptors;
for (int i = 3; i < argc; i++) {
// Parse string
std::string trippoint = argv[i];
auto delim = trippoint.find(':');
if (delim == std::string::npos) {
return {};
}
std::string index = trippoint.substr(0, delim);
trippoint.erase(0, delim + 1);
delim = trippoint.find(',');
if (delim == std::string::npos) {
return {};
}
std::string type = trippoint.substr(0, delim);
trippoint.erase(0, delim + 1);
std::string configuration = trippoint;
constexpr std::string kCleared = "cleared";
FidlTrippoint::wire::TripPointDescriptor desc;
if (type == "above") {
desc = {
.type = FidlTrippoint::wire::TripPointType::kOneshotTempAbove,
.index = static_cast<uint32_t>(atoi(index.data())),
.configuration = configuration == kCleared
? FidlTrippoint::wire::TripPointValue::WithClearedTripPoint(
FidlTrippoint::wire::ClearedTripPoint())
: FidlTrippoint::wire::TripPointValue::WithOneshotTempAboveTripPoint(
FidlTrippoint::wire::OneshotTempAboveTripPoint(
static_cast<float>(atof(configuration.data()))))};
} else if (type == "below") {
desc = {
.type = FidlTrippoint::wire::TripPointType::kOneshotTempBelow,
.index = static_cast<uint32_t>(atoi(index.data())),
.configuration = configuration == kCleared
? FidlTrippoint::wire::TripPointValue::WithClearedTripPoint(
FidlTrippoint::wire::ClearedTripPoint())
: FidlTrippoint::wire::TripPointValue::WithOneshotTempBelowTripPoint(
FidlTrippoint::wire::OneshotTempBelowTripPoint(
static_cast<float>(atof(configuration.data()))))};
} else {
printf("%s", kUsageMessage);
return {};
}
descriptors.emplace_back(desc);
}
return descriptors;
}
int main(int argc, char** argv) {
if (argc < 2) {
printf("%s", kUsageMessage);
return 0;
}
zx::channel local, remote;
zx_status_t status = zx::channel::create(0, &local, &remote);
if (status != ZX_OK) {
printf("Failed to create channel: status = %d\n", status);
return -1;
}
status = fdio_service_connect(argv[1], remote.release());
if (status != ZX_OK) {
printf("Failed to open sensor: status = %d\n", status);
return -1;
}
if (argc < 3) {
fidl::WireSyncClient<FidlTemperature::Device> client(
fidl::ClientEnd<FidlTemperature::Device>(std::move(local)));
auto response = client->GetTemperatureCelsius();
if (response.ok()) {
if (!response->status) {
printf("temperature = %f\n", response->temp);
} else {
printf("GetTemperatureCelsius failed: status = %d\n", response->status);
}
}
} else {
if (strcmp(argv[2], "resolution") == 0) {
fidl::WireSyncClient<FidlAdc::Device> client(
fidl::ClientEnd<FidlAdc::Device>(std::move(local)));
auto response = client->GetResolution();
if (response.ok()) {
if (response->is_error()) {
printf("GetResolution failed: status = %d\n", response->error_value());
} else {
printf("adc resolution = %u\n", response->value()->resolution);
}
} else {
printf("GetResolution fidl call failed: status = %d\n", response.status());
}
} else if (strcmp(argv[2], "read") == 0) {
fidl::WireSyncClient<FidlAdc::Device> client(
fidl::ClientEnd<FidlAdc::Device>(std::move(local)));
auto response = client->GetSample();
if (response.ok()) {
if (response->is_error()) {
printf("GetSample failed: status = %d\n", response->error_value());
} else {
printf("Value = %u\n", response->value()->value);
}
} else {
printf("GetSample fidl call failed: status = %d\n", response.status());
}
} else if (strcmp(argv[2], "readnorm") == 0) {
fidl::WireSyncClient<FidlAdc::Device> client(
fidl::ClientEnd<FidlAdc::Device>(std::move(local)));
auto response = client->GetNormalizedSample();
if (response.ok()) {
if (response->is_error()) {
printf("GetSampleNormalized failed: status = %d\n", response->error_value());
} else {
printf("Value = %f\n", response->value()->value);
}
} else {
printf("GetSampleNormalized fidl call failed: status = %d\n", response.status());
}
} else if (strcmp(argv[2], "trippoint") == 0) {
fidl::WireSyncClient<FidlTrippoint::TripPoint> client(
fidl::ClientEnd<FidlTrippoint::TripPoint>(std::move(local)));
if (argc == 3) {
auto response = client->GetTripPointDescriptors();
if (response.ok()) {
if (response->is_error()) {
printf("GetTripPointDescriptors failed: status = %d\n", response->error_value());
} else {
print_trippoint(response->value()->descriptors);
}
} else {
printf("GetTripPointDescriptors fidl call failed: status = %d\n", response.status());
}
} else {
std::vector descriptors = parse_set_trippoints_args(argc, argv);
if (descriptors.empty()) {
printf("Invalid trippoints list\n");
return 1;
}
auto fidl_descriptors =
fidl::VectorView<FidlTrippoint::wire::TripPointDescriptor>::FromExternal(descriptors);
printf("Setting trippoints:\n");
print_trippoint(fidl_descriptors);
auto response = client->SetTripPoints(fidl_descriptors);
if (response.ok()) {
if (response->is_error()) {
printf("SetTripPoints failed: status = %d\n", response->error_value());
}
} else {
printf("SetTripPoints fidl call failed: status = %d\n", response.status());
}
}
} else if (strcmp(argv[2], "wait") == 0) {
fidl::WireSyncClient<FidlTrippoint::TripPoint> client(
fidl::ClientEnd<FidlTrippoint::TripPoint>(std::move(local)));
auto response = client->WaitForAnyTripPoint();
if (response.ok()) {
if (response->is_error()) {
printf("WaitForAnyTripPoint failed: status = %d\n", response->error_value());
} else {
printf("TripPoint indexed %d was tripped. Measured temperature was %f C\n",
response->value()->result.index,
response->value()->result.measured_temperature_celsius);
}
} else {
printf("WaitForAnyTripPoint fidl call failed: status = %d\n", response.status());
}
} else if (strcmp(argv[2], "name") == 0) {
fidl::WireSyncClient<FidlTemperature::Device> client(
fidl::ClientEnd<FidlTemperature::Device>(std::move(local)));
auto response = client->GetSensorName();
if (response.ok()) {
printf("Sensor Name = %s\n",
std::string(response->name.data(), response->name.size()).c_str());
} else {
printf("GetSensorName fidl call failed: status = %d\n", response.status());
}
} else if (strcmp(argv[2], "trip") == 0) {
fidl::WireSyncClient<FidlTrippoint::Debug> client(
fidl::ClientEnd<FidlTrippoint::Debug>(std::move(local)));
auto response = client->Trip(atoi(argv[3]));
if (!response.ok()) {
printf("Trip fidl call failed: status = %d\n", response.status());
}
} else {
printf("%s", kUsageMessage);
return 1;
}
}
return 0;
}