blob: 52758223b84623423f210db8cc6e04ed0653a89b [file] [log] [blame]
// Copyright 2019 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 "src/ui/lib/hid-input-report/sensor.h"
#include <stdint.h>
#include <zircon/compiler.h>
#include <hid-parser/parser.h>
#include <hid-parser/report.h>
#include <hid-parser/units.h>
#include <hid-parser/usages.h>
#include "src/ui/lib/hid-input-report/axis.h"
#include "src/ui/lib/hid-input-report/device.h"
namespace hid_input_report {
namespace {
constexpr hid::usage::Sensor supported_usages[] = {
hid::usage::Sensor::kAccelerationAxisX, hid::usage::Sensor::kAccelerationAxisY,
hid::usage::Sensor::kAccelerationAxisZ, hid::usage::Sensor::kMagneticFluxAxisX,
hid::usage::Sensor::kMagneticFluxAxisY, hid::usage::Sensor::kMagneticFluxAxisZ,
hid::usage::Sensor::kAngularVelocityX, hid::usage::Sensor::kAngularVelocityY,
hid::usage::Sensor::kAngularVelocityZ, hid::usage::Sensor::kLightIlluminance,
hid::usage::Sensor::kLightRedLight, hid::usage::Sensor::kLightBlueLight,
hid::usage::Sensor::kLightGreenLight,
};
bool is_supported_usage(hid::usage::Sensor usage) {
for (size_t i = 0; i < countof(supported_usages); i++) {
if (usage == supported_usages[i]) {
return true;
}
}
return false;
}
} // namespace
ParseResult Sensor::ParseReportDescriptor(const hid::ReportDescriptor& hid_report_descriptor) {
hid::Attributes values[kSensorMaxValues] = {};
size_t num_values = 0;
SensorDescriptor descriptor = {};
for (size_t i = 0; i < hid_report_descriptor.input_count; i++) {
const hid::ReportField& field = hid_report_descriptor.input_fields[i];
if (field.attr.usage.page != static_cast<uint32_t>(hid::usage::Page::kSensor)) {
continue;
}
if (!is_supported_usage(static_cast<hid::usage::Sensor>(field.attr.usage.usage))) {
continue;
}
if (num_values == kSensorMaxValues) {
return kParseTooManyItems;
}
values[num_values] = field.attr;
descriptor.values[num_values].type = static_cast<hid::usage::Sensor>(field.attr.usage.usage);
SetAxisFromAttribute(values[num_values], &descriptor.values[num_values].axis);
num_values++;
}
// No error, write to class members.
descriptor.num_values = num_values;
descriptor_ = descriptor;
num_values_ = num_values;
for (size_t i = 0; i < num_values; i++) {
values_[i] = values[i];
}
report_size_ = hid_report_descriptor.input_byte_sz;
report_id_ = hid_report_descriptor.report_id;
return kParseOk;
}
ReportDescriptor Sensor::GetDescriptor() {
ReportDescriptor report_descriptor = {};
report_descriptor.descriptor = descriptor_;
return report_descriptor;
}
ParseResult Sensor::ParseReport(const uint8_t* data, size_t len, Report* report) {
SensorReport sensor_report = {};
if (len != report_size_) {
return kParseReportSizeMismatch;
}
for (size_t i = 0; i < num_values_; i++) {
double value_out;
if (hid::ExtractAsUnitType(data, len, values_[i], &value_out)) {
sensor_report.values[i] = static_cast<int64_t>(value_out);
}
}
sensor_report.num_values = num_values_;
// Now that we can't fail, set the real report.
report->report = sensor_report;
return kParseOk;
}
} // namespace hid_input_report