| // Copyright 2022 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 <ctype.h> |
| #include <dirent.h> |
| #include <fcntl.h> |
| #include <fidl/examples.i2c.temperature/cpp/wire.h> |
| #include <getopt.h> |
| #include <lib/fdio/directory.h> |
| #include <libgen.h> |
| #include <stdbool.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/types.h> |
| |
| constexpr char kDevicePath[] = "/dev/i2c-temperature-controller/i2c-temperature"; |
| |
| int usage(const char* cmd) { |
| fprintf(stderr, |
| "\nInteract with the temperature sensor device:\n" |
| " %s read Reads the current temperature value\n" |
| " %s reset Reset the temperature sensor\n" |
| " %s help Print this message\n", |
| cmd, cmd, cmd); |
| return -1; |
| } |
| |
| // Returns "true" if the argument matches the prefix. |
| // In this case, moves the argument past the prefix. |
| bool prefix_match(const char** arg, const char* prefix) { |
| if (!strncmp(*arg, prefix, strlen(prefix))) { |
| *arg += strlen(prefix); |
| return true; |
| } |
| return false; |
| } |
| |
| // Open a FIDL client connection to the examples.i2c.temperature/Device |
| fidl::WireSyncClient<examples_i2c_temperature::Device> OpenDevice() { |
| int device = open(kDevicePath, O_RDWR); |
| if (device < 0) { |
| fprintf(stderr, "Failed to open temperature device: %s\n", strerror(errno)); |
| return {}; |
| } |
| fidl::ClientEnd<examples_i2c_temperature::Device> client_end; |
| zx_status_t st = fdio_get_service_handle(device, client_end.channel().reset_and_get_address()); |
| if (st != ZX_OK) { |
| fprintf(stderr, "Failed to get service handle: %s\n", zx_status_get_string(st)); |
| return {}; |
| } |
| return fidl::WireSyncClient(std::move(client_end)); |
| } |
| |
| // Send a command to measure the temperature and print the result. |
| // Returns 0 on success. |
| int read_temperature() { |
| auto client = OpenDevice(); |
| if (!client.is_valid()) { |
| return -1; |
| } |
| |
| auto temperature_result = client->ReadTemperature(); |
| if (!temperature_result.ok()) { |
| fprintf(stderr, "Error: failed to read temperature result: %s\n", |
| zx_status_get_string(temperature_result.status())); |
| return -1; |
| } |
| |
| printf("Current temperature: %f\n", temperature_result->value()->temperature); |
| return 0; |
| } |
| |
| // Send a command to reset the temperature sensor. |
| // Returns 0 on success. |
| int reset_temperature() { |
| auto client = OpenDevice(); |
| if (!client.is_valid()) { |
| return -1; |
| } |
| |
| auto reset_result = client->ResetSensor(); |
| if (!reset_result.ok()) { |
| fprintf(stderr, "Error: failed to reset temperature sensor: %s\n", |
| zx_status_get_string(reset_result.status())); |
| return -1; |
| } |
| |
| printf("Sensor reset successfully\n"); |
| return 0; |
| } |
| |
| int main(int argc, char* argv[]) { |
| const char* cmd = basename(argv[0]); |
| |
| // If no arguments passed, bail out after dumping |
| // usage information. |
| if (argc < 2) { |
| return usage(cmd); |
| } |
| |
| const char* arg = argv[1]; |
| if (prefix_match(&arg, "read")) { |
| return read_temperature(); |
| } else if (prefix_match(&arg, "reset")) { |
| return reset_temperature(); |
| } |
| return usage(cmd); |
| } |